diff --git a/pom.xml b/pom.xml index bd96a4976..a4e943288 100644 --- a/pom.xml +++ b/pom.xml @@ -87,9 +87,9 @@ - javax.jmdns + org.jmdns jmdns - 3.4.1 + 3.5.5 diff --git a/src/main/java/com/beowulfe/hap/HomekitRoot.java b/src/main/java/com/beowulfe/hap/HomekitRoot.java index 324228616..e3fb1e169 100644 --- a/src/main/java/com/beowulfe/hap/HomekitRoot.java +++ b/src/main/java/com/beowulfe/hap/HomekitRoot.java @@ -8,6 +8,7 @@ import com.beowulfe.hap.impl.jmdns.JmdnsHomekitAdvertiser; import java.io.IOException; import java.net.InetAddress; +import javax.jmdns.JmDNS; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,6 +40,11 @@ public class HomekitRoot { this(label, webHandler, authInfo, new JmdnsHomekitAdvertiser(localhost)); } + HomekitRoot(String label, HomekitWebHandler webHandler, JmDNS jmdns, HomekitAuthInfo authInfo) + throws IOException { + this(label, webHandler, authInfo, new JmdnsHomekitAdvertiser(jmdns)); + } + HomekitRoot( String label, HomekitWebHandler webHandler, diff --git a/src/main/java/com/beowulfe/hap/HomekitServer.java b/src/main/java/com/beowulfe/hap/HomekitServer.java index 5c70c8e02..bb4b742d8 100644 --- a/src/main/java/com/beowulfe/hap/HomekitServer.java +++ b/src/main/java/com/beowulfe/hap/HomekitServer.java @@ -7,6 +7,7 @@ import java.math.BigInteger; import java.net.InetAddress; import java.security.InvalidAlgorithmParameterException; +import javax.jmdns.JmDNS; /** * The main entry point for hap-java. Creating an instance of this class will listen for Homekit @@ -27,6 +28,7 @@ public class HomekitServer { private final HomekitHttpServer http; private final InetAddress localAddress; + private final JmDNS jmdns; /** * Constructor. Contains an argument indicating the number of threads to use in the http server. @@ -40,9 +42,24 @@ public class HomekitServer { */ public HomekitServer(InetAddress localAddress, int port, int nThreads) throws IOException { this.localAddress = localAddress; + this.jmdns = null; http = new HomekitHttpServer(localAddress, port, nThreads); } + /** + * Constructor + * + * @param jmdns mdns service to register with + * @param port local port to bind to + * @param nThreads number of threads to use in the http server + * @throws IOException when the server cannot bind to the supplied port + */ + public HomekitServer(JmDNS jmdns, int port, int nThreads) throws IOException { + this.jmdns = jmdns; + this.localAddress = null; + http = new HomekitHttpServer(jmdns.getInetAddress(), port, nThreads); + } + /** * Constructor * @@ -57,7 +74,18 @@ public HomekitServer(InetAddress localAddress, int port) throws IOException { /** * Constructor * - * @param port local port to bind to. + * @param jmdns mdns service to register with + * @param port local port to bind to + * @throws IOException when the server cannot bind to the supplied port + */ + public HomekitServer(JmDNS jmdns, int port) throws IOException { + this(jmdns, port, Runtime.getRuntime().availableProcessors()); + } + + /** + * Constructor + * + * @param port local port to bind to * @throws IOException when the server cannot bind to the supplied port */ public HomekitServer(int port) throws IOException { @@ -82,7 +110,11 @@ public void stop() { */ public HomekitStandaloneAccessoryServer createStandaloneAccessory( HomekitAuthInfo authInfo, HomekitAccessory accessory) throws IOException { - return new HomekitStandaloneAccessoryServer(accessory, http, localAddress, authInfo); + if (jmdns != null) { + return new HomekitStandaloneAccessoryServer(accessory, http, jmdns, authInfo); + } else { + return new HomekitStandaloneAccessoryServer(accessory, http, localAddress, authInfo); + } } /** @@ -108,7 +140,12 @@ public HomekitRoot createBridge( String model, String serialNumber) throws IOException { - HomekitRoot root = new HomekitRoot(label, http, localAddress, authInfo); + HomekitRoot root; + if (jmdns != null) { + root = new HomekitRoot(label, http, jmdns, authInfo); + } else { + root = new HomekitRoot(label, http, localAddress, authInfo); + } root.addAccessory(new HomekitBridge(label, serialNumber, model, manufacturer)); return root; } diff --git a/src/main/java/com/beowulfe/hap/HomekitStandaloneAccessoryServer.java b/src/main/java/com/beowulfe/hap/HomekitStandaloneAccessoryServer.java index 3b631f276..251a4f3c5 100644 --- a/src/main/java/com/beowulfe/hap/HomekitStandaloneAccessoryServer.java +++ b/src/main/java/com/beowulfe/hap/HomekitStandaloneAccessoryServer.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; +import javax.jmdns.JmDNS; /** * A server for exposing standalone Homekit accessory (as opposed to a Bridge accessory which @@ -27,6 +28,16 @@ public class HomekitStandaloneAccessoryServer { root.addAccessory(accessory); } + HomekitStandaloneAccessoryServer( + HomekitAccessory accessory, + HomekitWebHandler webHandler, + JmDNS jmdns, + HomekitAuthInfo authInfo) + throws UnknownHostException, IOException { + root = new HomekitRoot(accessory.getLabel(), webHandler, jmdns, authInfo); + root.addAccessory(accessory); + } + /** Begins advertising and handling requests for this accessory. */ public void start() { root.start(); diff --git a/src/main/java/com/beowulfe/hap/impl/jmdns/JmdnsHomekitAdvertiser.java b/src/main/java/com/beowulfe/hap/impl/jmdns/JmdnsHomekitAdvertiser.java index 8eea15ce8..62fadc681 100644 --- a/src/main/java/com/beowulfe/hap/impl/jmdns/JmdnsHomekitAdvertiser.java +++ b/src/main/java/com/beowulfe/hap/impl/jmdns/JmdnsHomekitAdvertiser.java @@ -24,6 +24,10 @@ public class JmdnsHomekitAdvertiser { private int port; private int configurationIndex; + public JmdnsHomekitAdvertiser(JmDNS jmdns) { + this.jmdns = jmdns; + } + public JmdnsHomekitAdvertiser(InetAddress localAddress) throws UnknownHostException, IOException { jmdns = JmDNS.create(localAddress); } @@ -53,15 +57,17 @@ public synchronized void advertise(String label, String mac, int port, int confi } public synchronized void stop() { - jmdns.unregisterAllServices(); + unregisterService(); } public synchronized void setDiscoverable(boolean discoverable) throws IOException { if (this.discoverable != discoverable) { + if (isAdvertising) { + unregisterService(); + } this.discoverable = discoverable; if (isAdvertising) { logger.info("Re-creating service due to change in discoverability to " + discoverable); - jmdns.unregisterAllServices(); registerService(); } } @@ -69,10 +75,12 @@ public synchronized void setDiscoverable(boolean discoverable) throws IOExceptio public synchronized void setConfigurationIndex(int revision) throws IOException { if (this.configurationIndex != revision) { + if (isAdvertising) { + unregisterService(); + } this.configurationIndex = revision; if (isAdvertising) { logger.info("Re-creating service due to change in configuration index to " + revision); - jmdns.unregisterAllServices(); registerService(); } } @@ -80,6 +88,14 @@ public synchronized void setConfigurationIndex(int revision) throws IOException private void registerService() throws IOException { logger.info("Registering " + SERVICE_TYPE + " on port " + port); + jmdns.registerService(buildServiceInfo()); + } + + private void unregisterService() { + jmdns.unregisterService(buildServiceInfo()); + } + + private ServiceInfo buildServiceInfo() { Map props = new HashMap<>(); props.put("sf", discoverable ? "1" : "0"); props.put("id", mac); @@ -88,6 +104,7 @@ private void registerService() throws IOException { props.put("s#", "1"); props.put("ff", "0"); props.put("ci", "1"); - jmdns.registerService(ServiceInfo.create(SERVICE_TYPE, label, port, 1, 1, props)); + + return ServiceInfo.create(SERVICE_TYPE, label, port, 1, 1, props); } }