/* * Jitsi, the OpenSource Java VoIP and Instant Messaging client. * * Copyright @ 2015 Atlassian Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.java.sip.communicator.impl.provdisc.mdns; import java.io.*; import java.util.*; import javax.jmdns.*; import net.java.sip.communicator.service.provdisc.event.*; import net.java.sip.communicator.util.*; /** * Class that will perform mDNS provisioning discovery. * * @author Sebastien Vincent */ public class MDNSProvisioningDiscover implements Runnable { /** * Logger. */ private final Logger logger = Logger.getLogger(MDNSProvisioningDiscover.class); /** * MDNS timeout (in milliseconds). */ private static final int MDNS_TIMEOUT = 2000; /** * List of <tt>ProvisioningListener</tt> that will be notified when * a provisioning URL is retrieved. */ private List<DiscoveryListener> listeners = new ArrayList<DiscoveryListener>(); /** * Reference to JmDNS singleton. */ private JmDNS jmdns = null; /** * Constructor. */ public MDNSProvisioningDiscover() { } /** * 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); } } } /** * It sends a mDNS to retrieve provisioning URL and wait for a response. * Thread stops after first successful answer that contains the provisioning * URL. * * @return provisioning URL or null if no provisioning URL was discovered */ public String discoverProvisioningURL() { StringBuffer url = new StringBuffer(); try { jmdns = JmDNS.create(); } catch(IOException e) { logger.info("Failed to create JmDNS", e); return null; } ServiceInfo info = jmdns.getServiceInfo("_https._tcp.local", "Provisioning URL", MDNS_TIMEOUT); if(info == null) { /* try HTTP */ info = jmdns.getServiceInfo("_http._tcp.local", "Provisioning URL", MDNS_TIMEOUT); } if(info != null && info.getName().equals("Provisioning URL")) { String protocol = info.getApplication(); url.append(info.getURL(protocol)); Enumeration<String> en = info.getPropertyNames(); if(en.hasMoreElements()) { url.append("?"); } /* add the parameters */ while(en.hasMoreElements()) { String tmp = en.nextElement(); /* take all other parameters except "path" */ if(tmp.equals("path")) { continue; } url.append(tmp); url.append("="); url.append(info.getPropertyString(tmp)); if(en.hasMoreElements()) { url.append("&"); } } } /* close jmdns */ try { jmdns.close(); jmdns = null; } catch(Exception e) { logger.warn("Failed to close JmDNS", e); } return (url.toString().length() > 0) ? url.toString() : null; } /** * 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); } } }