mirror of https://github.com/sipwise/jitsi.git
Initial commit to support provisioning. It provides the DHCP provisioning discovery method, the provisioning URL can also be retrieved from configuration.
parent
5024715207
commit
3d77efb36f
Binary file not shown.
@ -0,0 +1,252 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.impl.provdisc.dhcp;
|
||||
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
|
||||
import net.java.sip.communicator.service.provdisc.event.*;
|
||||
import net.java.sip.communicator.service.netaddr.*;
|
||||
import net.java.sip.communicator.util.*;
|
||||
|
||||
import org.dhcp4java.*;
|
||||
|
||||
/**
|
||||
* Class that will perform DHCP provisioning discovery.
|
||||
*
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public class DHCPProvisioningDiscover
|
||||
implements Runnable
|
||||
{
|
||||
/**
|
||||
* Logger.
|
||||
*/
|
||||
private final Logger logger
|
||||
= Logger.getLogger(DHCPProvisioningDiscover.class);
|
||||
|
||||
/**
|
||||
* UDP socket.
|
||||
*/
|
||||
private DatagramSocket socket = null;
|
||||
|
||||
/**
|
||||
* Listening port of the client. Note that the socket will send packet to
|
||||
* DHCP server on port - 1.
|
||||
*/
|
||||
private int port = 6768;
|
||||
|
||||
/**
|
||||
* Option code of the specific provisioning option.
|
||||
*/
|
||||
private byte option = (byte)120;
|
||||
|
||||
/**
|
||||
* DHCP timeout (in milliseconds).
|
||||
*/
|
||||
private static final int DHCP_TIMEOUT = 5000;
|
||||
|
||||
/**
|
||||
* List of <tt>ProvisioningListener</tt> that will be notified when
|
||||
* a provisioning URL is retrieved.
|
||||
*/
|
||||
private List<DiscoveryListener> listeners =
|
||||
new ArrayList<DiscoveryListener>();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param port port on which we will bound and listen for DHCP response
|
||||
* @param option code of the specific provisioning option
|
||||
* @throws Exception if anything goes wrong during initialization
|
||||
*/
|
||||
public DHCPProvisioningDiscover(int port, byte option) throws Exception
|
||||
{
|
||||
this.port = port;
|
||||
this.option = option;
|
||||
socket = new DatagramSocket(port);
|
||||
|
||||
/* set timeout so that we will not blocked forever if we
|
||||
* have no response from DHCP server
|
||||
*/
|
||||
socket.setSoTimeout(DHCP_TIMEOUT);
|
||||
}
|
||||
|
||||
/**
|
||||
* It sends a DHCPINFORM message from all interfaces and wait for a
|
||||
* response. Thread stops after first successful answer that contains
|
||||
* specific option and thus the provisioning URL.
|
||||
*
|
||||
* @return provisioning URL
|
||||
*/
|
||||
public String discoverProvisioningURL()
|
||||
{
|
||||
DHCPPacket inform = new DHCPPacket();
|
||||
byte macAddress[] = null;
|
||||
byte zeroIPAddress[] = {0x00, 0x00, 0x00, 0x00};
|
||||
byte broadcastIPAddr[] = {(byte)255, (byte)255, (byte)255, (byte)255};
|
||||
DHCPOption dhcpOpts[] = new DHCPOption[1];
|
||||
int xid = new Random().nextInt();
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
inform.setOp(DHCPConstants.BOOTREQUEST);
|
||||
inform.setHtype(DHCPConstants.HTYPE_ETHER);
|
||||
inform.setHlen((byte) 6);
|
||||
inform.setHops((byte) 0);
|
||||
inform.setXid(xid);
|
||||
inform.setSecs((short) 0);
|
||||
inform.setFlags((short) 0);
|
||||
inform.setYiaddr(InetAddress.getByAddress(zeroIPAddress));
|
||||
inform.setSiaddr(InetAddress.getByAddress(zeroIPAddress));
|
||||
inform.setGiaddr(InetAddress.getByAddress(zeroIPAddress));
|
||||
inform.setChaddr(macAddress);
|
||||
inform.setDhcp(true);
|
||||
inform.setDHCPMessageType(DHCPConstants.DHCPINFORM);
|
||||
|
||||
dhcpOpts[0] = new DHCPOption(
|
||||
DHCPConstants.DHO_DHCP_PARAMETER_REQUEST_LIST,
|
||||
new byte[] {option});
|
||||
|
||||
inform.setOptions(dhcpOpts);
|
||||
|
||||
Enumeration<NetworkInterface> en =
|
||||
NetworkInterface.getNetworkInterfaces();
|
||||
|
||||
while(en.hasMoreElements())
|
||||
{
|
||||
NetworkInterface iface = en.nextElement();
|
||||
|
||||
Enumeration<InetAddress> enAddr = iface.getInetAddresses();
|
||||
while(enAddr.hasMoreElements())
|
||||
{
|
||||
InetAddress addr = enAddr.nextElement();
|
||||
|
||||
/* just take IPv4 address */
|
||||
if(addr instanceof Inet4Address)
|
||||
{
|
||||
NetworkAddressManagerService netaddr =
|
||||
ProvisioningDiscoveryDHCPActivator.
|
||||
getNetworkAddressManagerService();
|
||||
|
||||
if(!addr.isLoopbackAddress())
|
||||
{
|
||||
macAddress = netaddr.getHardwareAddress(iface);
|
||||
DHCPPacket p = inform.clone();
|
||||
|
||||
p.setCiaddr(addr);
|
||||
p.setChaddr(macAddress);
|
||||
|
||||
byte msg[] = inform.serialize();
|
||||
DatagramPacket pkt = new DatagramPacket(msg,
|
||||
msg.length,
|
||||
InetAddress.getByAddress(broadcastIPAddr),
|
||||
port - 1);
|
||||
|
||||
socket.send(pkt);
|
||||
msg = null;
|
||||
pkt = null;
|
||||
p = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* now see if we receive DHCP ACK response and if it contains
|
||||
* our custom option
|
||||
*/
|
||||
boolean found = false;
|
||||
|
||||
try
|
||||
{
|
||||
DatagramPacket pkt2 = new DatagramPacket(new byte[1500], 1500);
|
||||
|
||||
while(!found)
|
||||
{
|
||||
/* we timeout after 5 seconds if no DHCP response are
|
||||
* received
|
||||
*/
|
||||
socket.receive(pkt2);
|
||||
DHCPPacket dhcp = DHCPPacket.getPacket(pkt2);
|
||||
|
||||
if(dhcp.getXid() != xid)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
DHCPOption optProvisioning = dhcp.getOption(option);
|
||||
|
||||
/* notify */
|
||||
if(optProvisioning != null)
|
||||
{
|
||||
found = true;
|
||||
return new String(optProvisioning.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(SocketTimeoutException est)
|
||||
{
|
||||
logger.warn("Timeout, no DHCP answer received", est);
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
logger.warn("Exception occurred during DHCP discover", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Thread entry point. It runs <tt>discoverProvisioningURL</tt> in a
|
||||
* separate thread.
|
||||
*/
|
||||
public void run()
|
||||
{
|
||||
String url = discoverProvisioningURL();
|
||||
|
||||
if(url != null)
|
||||
{
|
||||
/* as we run in an asynchronous manner, notify the listener */
|
||||
DiscoveryEvent evt = new DiscoveryEvent(this, url);
|
||||
|
||||
for(DiscoveryListener listener : listeners)
|
||||
{
|
||||
listener.notifyProvisioningURL(evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener that will be notified when the
|
||||
* <tt>discoverProvisioningURL</tt> has finished.
|
||||
*
|
||||
* @param listener <tt>ProvisioningListener</tt> to add
|
||||
*/
|
||||
public void addDiscoveryListener(DiscoveryListener listener)
|
||||
{
|
||||
if(!listeners.contains(listener))
|
||||
{
|
||||
listeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener that will be notified when the
|
||||
* <tt>discoverProvisioningURL</tt> has finished.
|
||||
*
|
||||
* @param listener <tt>ProvisioningListener</tt> to add
|
||||
*/
|
||||
public void removeDiscoveryListener(DiscoveryListener listener)
|
||||
{
|
||||
if(listeners.contains(listener))
|
||||
{
|
||||
listeners.remove(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.impl.provdisc.dhcp;
|
||||
|
||||
import org.osgi.framework.*;
|
||||
|
||||
import net.java.sip.communicator.service.provdisc.*;
|
||||
import net.java.sip.communicator.service.netaddr.*;
|
||||
import net.java.sip.communicator.util.*;
|
||||
|
||||
/**
|
||||
* Implements <tt>BundleActivator</tt> for the DHCP provisioning bundle.
|
||||
*
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public class ProvisioningDiscoveryDHCPActivator
|
||||
implements BundleActivator
|
||||
{
|
||||
/**
|
||||
* <tt>Logger</tt> used by this <tt>DHCPProvisioningDiscoveryActivator</tt>
|
||||
* instance for logging output.
|
||||
*/
|
||||
private final Logger logger
|
||||
= Logger.getLogger(ProvisioningDiscoveryDHCPActivator.class);
|
||||
|
||||
/**
|
||||
* DHCP provisioning service.
|
||||
*/
|
||||
private static ProvisioningDiscoveryServiceDHCPImpl provisioningService =
|
||||
new ProvisioningDiscoveryServiceDHCPImpl();
|
||||
|
||||
/**
|
||||
* A reference to the currently valid {@link NetworkAddressManagerService}.
|
||||
*/
|
||||
private static NetworkAddressManagerService
|
||||
networkAddressManagerService = null;
|
||||
|
||||
/**
|
||||
* Bundle context from OSGi.
|
||||
*/
|
||||
private static BundleContext bundleContext = null;
|
||||
|
||||
/**
|
||||
* Starts the DHCP provisioning service
|
||||
*
|
||||
* @param bundleContext the <tt>BundleContext</tt> as provided by the OSGi
|
||||
* framework.
|
||||
* @throws Exception if anything goes wrong
|
||||
*/
|
||||
public void start(BundleContext bundleContext)
|
||||
throws Exception
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("DHCP provisioning discovery Service [STARTED]");
|
||||
|
||||
bundleContext.registerService(
|
||||
ProvisioningDiscoveryService.class.getName(),
|
||||
provisioningService,
|
||||
null);
|
||||
|
||||
ProvisioningDiscoveryDHCPActivator.bundleContext = bundleContext;
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("DHCP provisioning discovery Service [REGISTERED]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the DHCP provisioning service.
|
||||
*
|
||||
* @param bundleContext the <tt>BundleContext</tt> as provided by the OSGi
|
||||
* framework.
|
||||
* @throws Exception if anything goes wrong
|
||||
*/
|
||||
public void stop(BundleContext bundleContext) throws Exception
|
||||
{
|
||||
ProvisioningDiscoveryDHCPActivator.bundleContext = null;
|
||||
|
||||
if (logger.isInfoEnabled())
|
||||
logger.info("DHCP provisioning discovery Service ...[STOPPED]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to a NetworkAddressManagerService implementation
|
||||
* currently registered in the bundle context or null if no such
|
||||
* implementation was found.
|
||||
*
|
||||
* @return a currently valid implementation of the
|
||||
* NetworkAddressManagerService .
|
||||
*/
|
||||
public static NetworkAddressManagerService getNetworkAddressManagerService()
|
||||
{
|
||||
if(networkAddressManagerService == null)
|
||||
{
|
||||
ServiceReference confReference
|
||||
= bundleContext.getServiceReference(
|
||||
NetworkAddressManagerService.class.getName());
|
||||
networkAddressManagerService = (NetworkAddressManagerService)
|
||||
bundleContext.getService(confReference);
|
||||
}
|
||||
return networkAddressManagerService;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.impl.provdisc.dhcp;
|
||||
|
||||
import net.java.sip.communicator.service.provdisc.*;
|
||||
import net.java.sip.communicator.service.provdisc.event.*;
|
||||
import net.java.sip.communicator.util.*;
|
||||
|
||||
/**
|
||||
* Class that uses DHCP to retrieve provisioning URL. Basically it sends a
|
||||
* DHCPINFORM message with a custom option code in parameters list.
|
||||
*
|
||||
* Note that DHCP server have to understand this option and thus configured to
|
||||
* answer with a HTTP/HTTPS URL.
|
||||
*
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public class ProvisioningDiscoveryServiceDHCPImpl
|
||||
extends AbstractProvisioningDiscoveryService
|
||||
implements DiscoveryListener
|
||||
{
|
||||
/**
|
||||
* Logger.
|
||||
*/
|
||||
private final Logger logger
|
||||
= Logger.getLogger(ProvisioningDiscoveryServiceDHCPImpl.class);
|
||||
|
||||
/**
|
||||
* DHCP provisioning discover object.
|
||||
*/
|
||||
private DHCPProvisioningDiscover discover = null;
|
||||
|
||||
/**
|
||||
* Name of the method used to retrieve provisioning URL.
|
||||
*/
|
||||
private static final String METHOD_NAME = "DHCP";
|
||||
|
||||
/**
|
||||
* Get the name of the method name used to retrieve provisioning URL.
|
||||
*
|
||||
* @return method name
|
||||
*/
|
||||
public String getMethodName()
|
||||
{
|
||||
return METHOD_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public ProvisioningDiscoveryServiceDHCPImpl()
|
||||
{
|
||||
try
|
||||
{
|
||||
discover = new DHCPProvisioningDiscover(6768, (byte)120);
|
||||
discover.addDiscoveryListener(this);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
logger.warn("Cannot create DHCP client socket", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch a discovery for a provisioning URL. This method is synchronous and
|
||||
* may block for some time. Note that you don't have to call
|
||||
* <tt>startDiscovery</tt> method prior to this one to retrieve URL.
|
||||
*
|
||||
* @return provisioning URL
|
||||
*/
|
||||
public String discoverURL()
|
||||
{
|
||||
if(discover != null)
|
||||
{
|
||||
return discover.discoverProvisioningURL();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch a discovery for a provisioning URL by sending a DHCP Inform
|
||||
* with parameter list option containing a custom option code.
|
||||
*
|
||||
* This method is asynchronous, the response will be notified to any
|
||||
* <tt>ProvisioningListener</tt> registered.
|
||||
*/
|
||||
public void startDiscovery()
|
||||
{
|
||||
if(discover != null)
|
||||
{
|
||||
new Thread(discover).start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the provisioning URL.
|
||||
*
|
||||
* @param event provisioning event
|
||||
*/
|
||||
public void notifyProvisioningURL(DiscoveryEvent event)
|
||||
{
|
||||
fireDiscoveryEvent(event);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
Bundle-Activator: net.java.sip.communicator.impl.provdisc.dhcp.ProvisioningDiscoveryDHCPActivator
|
||||
Bundle-Name: DHCP provisioning discovery
|
||||
Bundle-Description: A bundle providing support for DHCP provisioning discovery
|
||||
Bundle-Vendor: sip-communicator.org
|
||||
Bundle-Version: 0.0.1
|
||||
System-Bundle: yes
|
||||
Import-Package: org.osgi.framework,
|
||||
net.java.sip.communicator.service.provdisc,
|
||||
net.java.sip.communicator.service.provdisc.event,
|
||||
net.java.sip.communicator.service.netaddr,
|
||||
net.java.sip.communicator.util
|
||||
@ -0,0 +1,800 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.plugin.provisioning;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import javax.swing.*;
|
||||
|
||||
import net.java.sip.communicator.service.configuration.*;
|
||||
import net.java.sip.communicator.service.credentialsstorage.*;
|
||||
import net.java.sip.communicator.service.certificate.*;
|
||||
import net.java.sip.communicator.service.netaddr.*;
|
||||
import net.java.sip.communicator.service.protocol.*;
|
||||
import net.java.sip.communicator.service.provdisc.*;
|
||||
import net.java.sip.communicator.util.*;
|
||||
import net.java.sip.communicator.util.swing.*;
|
||||
|
||||
import org.osgi.framework.*;
|
||||
|
||||
/**
|
||||
* Activator the provisioning system. It will gather provisioning URL depending
|
||||
* on the configuration (DHCP, manual, ...), retrieve configuration file and
|
||||
* push properties to the <tt>ConfigurationService</tt>.
|
||||
*/
|
||||
public class ProvisioningPluginActivator
|
||||
implements BundleActivator
|
||||
{
|
||||
/**
|
||||
* Logger of this class
|
||||
*/
|
||||
private static final Logger logger
|
||||
= Logger.getLogger(ProvisioningPluginActivator.class);
|
||||
|
||||
/**
|
||||
* The current BundleContext.
|
||||
*/
|
||||
private static BundleContext bundleContext = null;
|
||||
|
||||
/**
|
||||
* Name of the provisioning URL in the configuration service.
|
||||
*/
|
||||
private static final String PROPERTY_PROVISIONING_URL
|
||||
= "net.java.sip.communicator.plugin.provisioning.URL";
|
||||
|
||||
/**
|
||||
* Name of the username for the HTTP authentication.
|
||||
*/
|
||||
private static final String PROPERTY_HTTP_USERNAME
|
||||
= "net.java.sip.communicator.plugin.provisioning.auth.http.USERNAME";
|
||||
|
||||
/**
|
||||
* Name of the password for the HTTP authentication.
|
||||
*/
|
||||
private static final String PROPERTY_HTTP_PASSWORD
|
||||
= "net.java.sip.communicator.plugin.provisioning.auth.http";
|
||||
|
||||
/**
|
||||
* Name of the provisioning username in the configuration service
|
||||
* authentication).
|
||||
*/
|
||||
private static final String PROPERTY_PROVISIONING_USERNAME
|
||||
= "net.java.sip.communicator.plugin.provisioning.auth.access.USERNAME";
|
||||
|
||||
/**
|
||||
* Name of the provisioning password in the configuration service (HTTP
|
||||
* authentication).
|
||||
*/
|
||||
private static final String PROPERTY_PROVISIONING_PASSWORD
|
||||
= "net.java.sip.communicator.plugin.provisioning.auth.access";
|
||||
|
||||
/**
|
||||
* Name of the property that contains the provisioning method (i.e. DHCP,
|
||||
* DNS, manual, ...).
|
||||
*/
|
||||
private static final String PROVISIONING_METHOD_PROP
|
||||
= "net.java.sip.communicator.plugin.provisioning.METHOD";
|
||||
|
||||
/**
|
||||
* A reference to the ConfigurationService implementation instance that
|
||||
* is currently registered with the bundle context.
|
||||
*/
|
||||
private static ConfigurationService configurationService = null;
|
||||
|
||||
/**
|
||||
* A reference to the CredentialsStorageService implementation instance
|
||||
* that is registered with the bundle context.
|
||||
*/
|
||||
private static CredentialsStorageService credentialsService = null;
|
||||
|
||||
/**
|
||||
* The service we use to interact with user for SSL certificate stuff.
|
||||
*/
|
||||
private static CertificateVerificationService certVerification = null;
|
||||
|
||||
/**
|
||||
* A reference to the NetworkAddressManagerService implementation instance
|
||||
* that is registered with the bundle context.
|
||||
*/
|
||||
private static NetworkAddressManagerService netaddrService = null;
|
||||
|
||||
/**
|
||||
* User credentials to access URL (protected by HTTP authentication) if any.
|
||||
*/
|
||||
private static UserCredentials userCredentials = null;
|
||||
|
||||
/**
|
||||
* User credentials that user have to provide to the provisioning server
|
||||
* if any.
|
||||
*/
|
||||
private static UserCredentials provCredentials = null;
|
||||
|
||||
/**
|
||||
* HTTP method to request a page.
|
||||
*/
|
||||
private String method = "POST";
|
||||
|
||||
/**
|
||||
* Starts this bundle
|
||||
*
|
||||
* @param bundleContext BundleContext
|
||||
* @throws Exception if anything goes wrong during the start of the bundle
|
||||
*/
|
||||
public void start(BundleContext bundleContext) throws Exception
|
||||
{
|
||||
String url = null;
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Provisioning discovery [STARTED]");
|
||||
|
||||
ProvisioningPluginActivator.bundleContext = bundleContext;
|
||||
|
||||
String method = getConfigurationService().getString(
|
||||
PROVISIONING_METHOD_PROP);
|
||||
|
||||
if(method == null || method.equals("NONE"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ServiceReference serviceReferences[] = bundleContext.
|
||||
getServiceReferences(ProvisioningDiscoveryService.class.getName(),
|
||||
null);
|
||||
|
||||
/* search the provisioning discovery implementation that correspond to
|
||||
* the method name
|
||||
*/
|
||||
if(serviceReferences != null)
|
||||
{
|
||||
for(ServiceReference ref : serviceReferences)
|
||||
{
|
||||
ProvisioningDiscoveryService provdisc =
|
||||
(ProvisioningDiscoveryService)bundleContext.getService(ref);
|
||||
|
||||
if(provdisc.getMethodName().equals(method))
|
||||
{
|
||||
/* may block for sometime depending on the method used */
|
||||
url = provdisc.discoverURL();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(url == null)
|
||||
{
|
||||
/* try to see if provisioning URL is stored in properties */
|
||||
url = getConfigurationService().getString(
|
||||
PROPERTY_PROVISIONING_URL);
|
||||
}
|
||||
|
||||
if(url != null)
|
||||
{
|
||||
File file = retrieveConfigurationFile(url);
|
||||
|
||||
if(file != null)
|
||||
{
|
||||
updateConfiguration(file);
|
||||
|
||||
/* store the provisioning URL in local configuration in case
|
||||
* the provisioning discovery failed (DHCP/DNS unavailable, ...)
|
||||
*/
|
||||
getConfigurationService().setProperty(
|
||||
PROPERTY_PROVISIONING_URL, url);
|
||||
}
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Provisioning discovery [REGISTERED]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops this bundle
|
||||
*
|
||||
* @param bundleContext BundleContext
|
||||
* @throws Exception if anything goes wrong during the stop of the bundle
|
||||
*/
|
||||
public void stop(BundleContext bundleContext) throws Exception
|
||||
{
|
||||
ProvisioningPluginActivator.bundleContext = null;
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Provisioning discovery [STOPPED]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure HTTP connection to provide HTTP authentication and SSL
|
||||
* truster.
|
||||
*
|
||||
* @param url provisioning URL
|
||||
* @param connection the <tt>URLConnection</tt>
|
||||
*/
|
||||
private void configureHTTPConnection(URL url, HttpURLConnection connection)
|
||||
{
|
||||
try
|
||||
{
|
||||
connection.setRequestMethod(method);
|
||||
|
||||
if(method.equals("POST"))
|
||||
{
|
||||
connection.setRequestProperty("Content-Type",
|
||||
"application/x-www-form-urlencoded");
|
||||
}
|
||||
|
||||
if(connection instanceof HttpsURLConnection)
|
||||
{
|
||||
CertificateVerificationService vs =
|
||||
getCertificateVerificationService();
|
||||
|
||||
int port = url.getPort();
|
||||
|
||||
/* if we do not specify port in the URL (http://domain.org:port)
|
||||
* we have to set up the default port of HTTP (80) or
|
||||
* HTTPS (443).
|
||||
*/
|
||||
if(port == -1)
|
||||
{
|
||||
if(url.getProtocol().equals("http"))
|
||||
{
|
||||
port = 80;
|
||||
}
|
||||
else if(url.getProtocol().equals("https"))
|
||||
{
|
||||
port = 443;
|
||||
}
|
||||
}
|
||||
|
||||
((HttpsURLConnection)connection).setSSLSocketFactory(
|
||||
vs.getSSLContext(
|
||||
url.getHost(), port).getSocketFactory());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.warn("Failed to initialize secure connection", e);
|
||||
}
|
||||
|
||||
Authenticator.setDefault(new Authenticator()
|
||||
{
|
||||
protected PasswordAuthentication getPasswordAuthentication()
|
||||
{
|
||||
// if there is something save return it
|
||||
ConfigurationService config = getConfigurationService();
|
||||
CredentialsStorageService credStorage =
|
||||
getCredentialsStorageService();
|
||||
|
||||
String uName
|
||||
= (String) config.getProperty(
|
||||
PROPERTY_HTTP_USERNAME);
|
||||
|
||||
if(uName != null)
|
||||
{
|
||||
String pass = credStorage.loadPassword(
|
||||
PROPERTY_HTTP_PASSWORD);
|
||||
|
||||
if(pass != null)
|
||||
return new PasswordAuthentication(uName,
|
||||
pass.toCharArray());
|
||||
}
|
||||
|
||||
if(userCredentials != null)
|
||||
{
|
||||
return new PasswordAuthentication(
|
||||
userCredentials.getUserName(),
|
||||
userCredentials.getPassword());
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle authentication with the provisioning server.
|
||||
*/
|
||||
private void handleProvisioningAuth()
|
||||
{
|
||||
ConfigurationService configService = getConfigurationService();
|
||||
CredentialsStorageService credService =
|
||||
getCredentialsStorageService();
|
||||
|
||||
String username = configService.getString(
|
||||
PROPERTY_PROVISIONING_USERNAME);
|
||||
String password = credService.loadPassword(
|
||||
PROPERTY_PROVISIONING_PASSWORD);
|
||||
|
||||
if(username != null && password != null)
|
||||
{
|
||||
/* we have already the credentials stored so return them */
|
||||
provCredentials = new UserCredentials();
|
||||
provCredentials.setUserName(username);
|
||||
provCredentials.setPassword(password.toCharArray());
|
||||
provCredentials.setPasswordPersistent(true);
|
||||
return;
|
||||
}
|
||||
|
||||
AuthenticationWindow authWindow = new AuthenticationWindow(
|
||||
"provisioning", true, null);
|
||||
|
||||
authWindow.setVisible(true);
|
||||
|
||||
if(!authWindow.isCanceled())
|
||||
{
|
||||
provCredentials = new UserCredentials();
|
||||
provCredentials.setUserName(authWindow.getUserName());
|
||||
provCredentials.setPassword(authWindow.getPassword());
|
||||
provCredentials.setPasswordPersistent(authWindow.isRememberPassword());
|
||||
|
||||
if(provCredentials.getUserName() == null)
|
||||
{
|
||||
provCredentials = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
provCredentials = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve configuration file from provisioning URL.
|
||||
* This method is blocking until configuration file is retrieved from the
|
||||
* network or if an exception happen
|
||||
*
|
||||
* @param url provisioning URL
|
||||
* @return provisioning file downloaded
|
||||
*/
|
||||
private File retrieveConfigurationFile(String url)
|
||||
{
|
||||
File tmpFile = null;
|
||||
|
||||
try
|
||||
{
|
||||
String arg = null;
|
||||
String args[] = null;
|
||||
final File temp = File.createTempFile("provisioning",
|
||||
".properties");
|
||||
|
||||
tmpFile = temp;
|
||||
|
||||
if(url.contains("?"))
|
||||
{
|
||||
/* do not handle URL of type http://domain/index.php? (no
|
||||
* parameters)
|
||||
*/
|
||||
if((url.indexOf('?') + 1) != url.length())
|
||||
{
|
||||
arg = url.substring(url.indexOf('?') + 1);
|
||||
args = arg.split("&");
|
||||
}
|
||||
url = url.substring(0, url.indexOf('?'));
|
||||
}
|
||||
|
||||
URL u = new URL(url);
|
||||
URLConnection uc = u.openConnection();
|
||||
OutputStreamWriter out = null;
|
||||
|
||||
if(uc instanceof HttpURLConnection)
|
||||
{
|
||||
configureHTTPConnection(u, (HttpURLConnection)uc);
|
||||
((HttpURLConnection)uc).setInstanceFollowRedirects(false);
|
||||
uc.setDoInput(true);
|
||||
uc.setDoOutput(true);
|
||||
out = new OutputStreamWriter(uc.getOutputStream());
|
||||
|
||||
/* send out (via GET or POST) */
|
||||
StringBuffer content = new StringBuffer();
|
||||
InetAddress ipaddr = getNetworkAddressManagerService().
|
||||
getLocalHost(InetAddress.getByName(u.getHost()));
|
||||
|
||||
if(args != null && args.length > 0)
|
||||
{
|
||||
for(String s : args)
|
||||
{
|
||||
if(s.equals("username"))
|
||||
{
|
||||
if(provCredentials == null)
|
||||
{
|
||||
handleProvisioningAuth();
|
||||
}
|
||||
|
||||
if(provCredentials == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
content.append("username=" +
|
||||
URLEncoder.encode(
|
||||
provCredentials.getUserName(),
|
||||
"UTF-8"));
|
||||
}
|
||||
else if(s.equals("password"))
|
||||
{
|
||||
if(provCredentials == null)
|
||||
{
|
||||
handleProvisioningAuth();
|
||||
}
|
||||
|
||||
if(provCredentials == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
content.append("&password=" +
|
||||
URLEncoder.encode(
|
||||
provCredentials.
|
||||
getPasswordAsString(),
|
||||
"UTF-8"));
|
||||
}
|
||||
else if(s.equals("osname"))
|
||||
{
|
||||
content.append("&osname=" + URLEncoder.encode(
|
||||
System.getProperty("os.name"), "UTF-8"));
|
||||
}
|
||||
else if(s.equals("build"))
|
||||
{
|
||||
content.append("&build=" + URLEncoder.encode(
|
||||
System.getProperty("sip-communicator.version"),
|
||||
"UTF-8"));
|
||||
}
|
||||
else if(s.equals("ipaddr"))
|
||||
{
|
||||
content.append("&ipaddr=" + URLEncoder.encode(
|
||||
ipaddr.getHostAddress(), "UTF-8"));
|
||||
}
|
||||
else if(s.equals("hwaddr"))
|
||||
{
|
||||
String hwaddr = null;
|
||||
|
||||
if(ipaddr != null)
|
||||
{
|
||||
/* find the hardware address of the interface
|
||||
* that has this IP address
|
||||
*/
|
||||
Enumeration<NetworkInterface> en =
|
||||
NetworkInterface.getNetworkInterfaces();
|
||||
|
||||
while(en.hasMoreElements())
|
||||
{
|
||||
NetworkInterface iface = en.nextElement();
|
||||
|
||||
Enumeration<InetAddress> enInet =
|
||||
iface.getInetAddresses();
|
||||
|
||||
while(enInet.hasMoreElements())
|
||||
{
|
||||
InetAddress inet = enInet.nextElement();
|
||||
|
||||
if(inet.equals(ipaddr))
|
||||
{
|
||||
byte hw[] =
|
||||
getNetworkAddressManagerService().
|
||||
getHardwareAddress(iface);
|
||||
StringBuffer buf =
|
||||
new StringBuffer();
|
||||
|
||||
for(byte h : hw)
|
||||
{
|
||||
int hi = h >= 0 ? h : h + 256;
|
||||
String t = new String(
|
||||
(hi <= 0xf) ? "0" : "");
|
||||
t += Integer.toHexString(hi);
|
||||
buf.append(t);
|
||||
buf.append("-");
|
||||
}
|
||||
|
||||
buf.deleteCharAt(buf.length() - 1);
|
||||
|
||||
hwaddr = buf.toString();
|
||||
content.append("&hwaddr=" +
|
||||
URLEncoder.encode(
|
||||
hwaddr, "UTF-8"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out.write(content.toString());
|
||||
out.flush();
|
||||
|
||||
int responseCode = ((HttpURLConnection)uc).getResponseCode();
|
||||
|
||||
if(responseCode == HttpURLConnection.HTTP_UNAUTHORIZED)
|
||||
{
|
||||
AuthenticationWindow authWindow = new AuthenticationWindow(
|
||||
u.getHost(), true, null);
|
||||
|
||||
authWindow.setVisible(true);
|
||||
|
||||
userCredentials = new UserCredentials();
|
||||
userCredentials.setUserName(authWindow.getUserName());
|
||||
userCredentials.setPassword(authWindow.getPassword());
|
||||
userCredentials.setPasswordPersistent(
|
||||
authWindow.isRememberPassword());
|
||||
|
||||
if(userCredentials.getUserName() == null)
|
||||
{
|
||||
userCredentials = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmpFile.delete();
|
||||
return retrieveConfigurationFile(url);
|
||||
}
|
||||
}
|
||||
else if(responseCode == HttpURLConnection.HTTP_MOVED_PERM ||
|
||||
responseCode == HttpURLConnection.HTTP_MOVED_TEMP)
|
||||
{
|
||||
String loc =
|
||||
((HttpURLConnection)uc).getHeaderField("Location");
|
||||
|
||||
if(loc != null && (loc.startsWith("http://") ||
|
||||
loc.startsWith("https://")))
|
||||
{
|
||||
tmpFile.delete();
|
||||
/* TODO detect loops */
|
||||
return retrieveConfigurationFile(loc);
|
||||
}
|
||||
}
|
||||
else if(responseCode == HttpURLConnection.HTTP_OK)
|
||||
{
|
||||
if(userCredentials != null &&
|
||||
userCredentials.getUserName() != null &&
|
||||
userCredentials.isPasswordPersistent())
|
||||
{
|
||||
// if save password is checked save the pass
|
||||
getConfigurationService().setProperty(
|
||||
PROPERTY_HTTP_USERNAME,
|
||||
userCredentials.getUserName());
|
||||
getCredentialsStorageService().storePassword(
|
||||
PROPERTY_HTTP_PASSWORD,
|
||||
userCredentials.getPasswordAsString());
|
||||
}
|
||||
|
||||
if(provCredentials != null &&
|
||||
provCredentials.getUserName() != null &&
|
||||
provCredentials.isPasswordPersistent())
|
||||
{
|
||||
getConfigurationService().setProperty(
|
||||
PROPERTY_PROVISIONING_USERNAME,
|
||||
provCredentials.getUserName());
|
||||
getCredentialsStorageService().storePassword(
|
||||
PROPERTY_PROVISIONING_PASSWORD,
|
||||
provCredentials.getPasswordAsString());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
InputStream in = uc.getInputStream();
|
||||
|
||||
// Chain a ProgressMonitorInputStream to the
|
||||
// URLConnection's InputStream
|
||||
final ProgressMonitorInputStream pin
|
||||
= new ProgressMonitorInputStream(null, u.toString(), in);
|
||||
|
||||
// Set the maximum value of the ProgressMonitor
|
||||
ProgressMonitor pm = pin.getProgressMonitor();
|
||||
pm.setMaximum(uc.getContentLength());
|
||||
|
||||
final BufferedOutputStream bout
|
||||
= new BufferedOutputStream(new FileOutputStream(temp));
|
||||
|
||||
try
|
||||
{
|
||||
int read = -1;
|
||||
byte[] buff = new byte[1024];
|
||||
|
||||
while((read = pin.read(buff)) != -1)
|
||||
{
|
||||
bout.write(buff, 0, read);
|
||||
}
|
||||
|
||||
pin.close();
|
||||
bout.flush();
|
||||
bout.close();
|
||||
out.close();
|
||||
|
||||
return temp;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.error("Error saving", e);
|
||||
|
||||
try
|
||||
{
|
||||
pin.close();
|
||||
bout.close();
|
||||
out.close();
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (logger.isInfoEnabled())
|
||||
logger.info("Error retrieving provisioning file!", e);
|
||||
tmpFile.delete();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update configuration with properties retrieved from provisioning URL.
|
||||
*
|
||||
* @param file provisioning file
|
||||
*/
|
||||
private void updateConfiguration(final File file)
|
||||
{
|
||||
Properties fileProps = new Properties();
|
||||
InputStream in = null;
|
||||
|
||||
try
|
||||
{
|
||||
in = new BufferedInputStream(new FileInputStream(file));
|
||||
fileProps.load(in);
|
||||
|
||||
Iterator<Map.Entry<Object, Object> > it
|
||||
= fileProps.entrySet().iterator();
|
||||
|
||||
while(it.hasNext())
|
||||
{
|
||||
Map.Entry<Object, Object> entry = it.next();
|
||||
|
||||
String key = (String)entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
|
||||
if(value instanceof String)
|
||||
{
|
||||
if(((String)value).equals("${null}"))
|
||||
{
|
||||
getConfigurationService().removeProperty(key);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* password => credentials storage service */
|
||||
if(key.endsWith(".PASSWORD"))
|
||||
{
|
||||
getCredentialsStorageService().storePassword(
|
||||
key.substring(0, key.lastIndexOf(".")),
|
||||
(String)value);
|
||||
}
|
||||
else
|
||||
{
|
||||
getConfigurationService().setProperty(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/* save the "new" configuration */
|
||||
getConfigurationService().storeConfiguration();
|
||||
try
|
||||
{
|
||||
getConfigurationService().reloadConfiguration();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
logger.error("Cannot reload configuration");
|
||||
}
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
logger.warn("Error during load of provisioning file");
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
in.close();
|
||||
file.delete();
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the certificate verification service impl.
|
||||
* @return the CertificateVerification service.
|
||||
*/
|
||||
private static CertificateVerificationService
|
||||
getCertificateVerificationService()
|
||||
{
|
||||
if(certVerification == null)
|
||||
{
|
||||
ServiceReference certVerifyReference
|
||||
= bundleContext.getServiceReference(
|
||||
CertificateVerificationService.class.getName());
|
||||
if(certVerifyReference != null)
|
||||
certVerification
|
||||
= (CertificateVerificationService)bundleContext.getService(
|
||||
certVerifyReference);
|
||||
}
|
||||
|
||||
return certVerification;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to a ConfigurationService implementation currently
|
||||
* registered in the bundle context or null if no such implementation was
|
||||
* found.
|
||||
*
|
||||
* @return a currently valid implementation of the ConfigurationService.
|
||||
*/
|
||||
public static ConfigurationService getConfigurationService()
|
||||
{
|
||||
if (configurationService == null)
|
||||
{
|
||||
ServiceReference confReference
|
||||
= bundleContext.getServiceReference(
|
||||
ConfigurationService.class.getName());
|
||||
configurationService
|
||||
= (ConfigurationService)bundleContext.getService(confReference);
|
||||
}
|
||||
return configurationService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to a CredentialsStorageService implementation
|
||||
* currently registered in the bundle context or null if no such
|
||||
* implementation was found.
|
||||
*
|
||||
* @return a currently valid implementation of the
|
||||
* CredentialsStorageService.
|
||||
*/
|
||||
public static CredentialsStorageService getCredentialsStorageService()
|
||||
{
|
||||
if (credentialsService == null)
|
||||
{
|
||||
ServiceReference credentialsReference
|
||||
= bundleContext.getServiceReference(
|
||||
CredentialsStorageService.class.getName());
|
||||
credentialsService
|
||||
= (CredentialsStorageService) bundleContext
|
||||
.getService(credentialsReference);
|
||||
}
|
||||
return credentialsService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to a NetworkAddressManagerService implementation
|
||||
* currently registered in the bundle context or null if no such
|
||||
* implementation was found.
|
||||
*
|
||||
* @return a currently valid implementation of the
|
||||
* NetworkAddressManagerService.
|
||||
*/
|
||||
public static NetworkAddressManagerService getNetworkAddressManagerService()
|
||||
{
|
||||
if (netaddrService == null)
|
||||
{
|
||||
ServiceReference netaddrReference
|
||||
= bundleContext.getServiceReference(
|
||||
NetworkAddressManagerService.class.getName());
|
||||
netaddrService
|
||||
= (NetworkAddressManagerService) bundleContext
|
||||
.getService(netaddrReference);
|
||||
}
|
||||
return netaddrService;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
Bundle-Activator: net.java.sip.communicator.plugin.provisioning.ProvisioningPluginActivator
|
||||
Bundle-Name: ProvisioningPlugin
|
||||
Bundle-Description: A bundle that implements the Provisioning Plugin Package.
|
||||
Bundle-Vendor: sip-communicator.org
|
||||
Bundle-Version: 0.0.1
|
||||
System-Bundle: yes
|
||||
Import-Package: org.osgi.framework,
|
||||
net.java.sip.communicator.service.configuration,
|
||||
net.java.sip.communicator.service.credentialsstorage,
|
||||
net.java.sip.communicator.service.protocol,
|
||||
net.java.sip.communicator.service.provdisc,
|
||||
net.java.sip.communicator.service.certificate,
|
||||
net.java.sip.communicator.service.netaddr,
|
||||
net.java.sip.communicator.util,
|
||||
net.java.sip.communicator.util.swing,
|
||||
javax.net.ssl,
|
||||
javax.swing,
|
||||
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.service.provdisc;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import net.java.sip.communicator.service.provdisc.event.*;
|
||||
|
||||
/**
|
||||
* Abstract base class of ProvisioningDiscoveryService that ease implementation
|
||||
*
|
||||
* @author seb
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractProvisioningDiscoveryService
|
||||
implements ProvisioningDiscoveryService
|
||||
{
|
||||
/**
|
||||
* List of <tt>ProvisioningListener</tt> that will be notified when
|
||||
* a provisioning URL is retrieved.
|
||||
*/
|
||||
private List<DiscoveryListener> listeners =
|
||||
new ArrayList<DiscoveryListener>();
|
||||
|
||||
/**
|
||||
* Get the name of the method name used to retrieve provisioning URL.
|
||||
*
|
||||
* @return method name
|
||||
*/
|
||||
public abstract String getMethodName();
|
||||
|
||||
/**
|
||||
* Launch a discovery for a provisioning URL.
|
||||
*
|
||||
* This method is asynchronous, the response will be notified to any
|
||||
* <tt>ProvisioningListener</tt> registered.
|
||||
*/
|
||||
public abstract void startDiscovery();
|
||||
|
||||
/**
|
||||
* Launch a discovery for a provisioning URL. This method is synchronous and
|
||||
* may block for some time.
|
||||
*
|
||||
* @return provisioning URL
|
||||
*/
|
||||
public abstract String discoverURL();
|
||||
|
||||
/**
|
||||
* Add a listener that will be notified when the
|
||||
* <tt>discoverProvisioningURL</tt> has finished.
|
||||
*
|
||||
* @param listener <tt>ProvisioningListener</tt> to add
|
||||
*/
|
||||
public void addDiscoveryListener(DiscoveryListener listener)
|
||||
{
|
||||
if(!listeners.contains(listener))
|
||||
{
|
||||
listeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener that will be notified when the
|
||||
* <tt>discoverProvisioningURL</tt> has finished.
|
||||
*
|
||||
* @param listener <tt>ProvisioningListener</tt> to add
|
||||
*/
|
||||
public void removeDiscoveryListener(DiscoveryListener listener)
|
||||
{
|
||||
if(listeners.contains(listener))
|
||||
{
|
||||
listeners.remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify all listeners about a <tt>DiscoveryEvent</tt>.
|
||||
*
|
||||
* @param event <tt>DiscoveryEvent</tt> that contains provisioning URL
|
||||
*/
|
||||
public void fireDiscoveryEvent(DiscoveryEvent event)
|
||||
{
|
||||
for(DiscoveryListener listener : listeners)
|
||||
{
|
||||
listener.notifyProvisioningURL(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.service.provdisc;
|
||||
|
||||
import net.java.sip.communicator.service.provdisc.event.*;
|
||||
|
||||
/**
|
||||
* Service that allow to retrieve a provisioning URL to configure
|
||||
* SIP Communicator. Implementations (not exhaustive) could use DHCP,
|
||||
* DNS (A, AAAA, SRV, TXT) or mDNS (Bonjour).
|
||||
*
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public interface ProvisioningDiscoveryService
|
||||
{
|
||||
/**
|
||||
* Get the name of the method name used to retrieve provisioning URL.
|
||||
*
|
||||
* @return method name
|
||||
*/
|
||||
public String getMethodName();
|
||||
|
||||
/**
|
||||
* Launch a discovery for a provisioning URL.
|
||||
*
|
||||
* This method is asynchronous, the response will be notified to any
|
||||
* <tt>ProvisioningListener</tt> registered.
|
||||
*/
|
||||
public void startDiscovery();
|
||||
|
||||
/**
|
||||
* Launch a discovery for a provisioning URL. This method is synchronous and
|
||||
* may block for some time.
|
||||
*
|
||||
* @return provisioning URL
|
||||
*/
|
||||
public String discoverURL();
|
||||
|
||||
/**
|
||||
* Add a listener that will be notified when the
|
||||
* <tt>startDiscovery</tt> has finished.
|
||||
*
|
||||
* @param listener <tt>ProvisioningListener</tt> to add
|
||||
*/
|
||||
public void addDiscoveryListener(DiscoveryListener listener);
|
||||
|
||||
/**
|
||||
* Add a listener that will be notified when the
|
||||
* <tt>discoverProvisioningURL</tt> has finished.
|
||||
*
|
||||
* @param listener <tt>ProvisioningListener</tt> to add
|
||||
*/
|
||||
public void removeDiscoveryListener(DiscoveryListener listener);
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.service.provdisc.event;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Event representing that a provisioning URL has been retrieved.
|
||||
*
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public class DiscoveryEvent extends EventObject
|
||||
{
|
||||
/**
|
||||
* Serial version UID.
|
||||
*/
|
||||
private static final long serialVersionUID = 0L;
|
||||
|
||||
/**
|
||||
* Provisioning URL.
|
||||
*/
|
||||
private String url = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param source object that have created this event
|
||||
* @param url provisioning URL
|
||||
*/
|
||||
public DiscoveryEvent(Object source, String url)
|
||||
{
|
||||
super(source);
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the provisioning URL.
|
||||
*
|
||||
* @return provisioning URL
|
||||
*/
|
||||
public String getProvisioningURL()
|
||||
{
|
||||
return url;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.service.provdisc.event;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Listener that will be notified when a provisioning URL is retrieved by the
|
||||
* <tt>ProvisioningDiscoveryService</tt>.
|
||||
*
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public interface DiscoveryListener extends EventListener
|
||||
{
|
||||
/**
|
||||
* Notify the provisioning URL.
|
||||
*
|
||||
* @param event provisioning event
|
||||
*/
|
||||
public void notifyProvisioningURL(DiscoveryEvent event);
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
Bundle-Name: Provisioning Discovery Service
|
||||
Bundle-Description: Provisioning Discovery Service.
|
||||
Bundle-Vendor: sip-communicator.org
|
||||
Bundle-Version: 0.0.1
|
||||
System-Bundle: yes
|
||||
Export-Package: net.java.sip.communicator.service.provdisc,
|
||||
net.java.sip.communicator.service.provdisc.event
|
||||
Loading…
Reference in new issue