diff --git a/pom.xml b/pom.xml index bd88630bc..5faf6eafc 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,6 @@ UTF-8 4.1.42.Final - @@ -135,9 +134,9 @@ - javax.jmdns + org.jmdns jmdns - 3.4.1 + 3.5.6 diff --git a/src/main/java/io/github/hapjava/server/impl/HomekitRoot.java b/src/main/java/io/github/hapjava/server/impl/HomekitRoot.java index dd34844e5..fba9d7b7b 100644 --- a/src/main/java/io/github/hapjava/server/impl/HomekitRoot.java +++ b/src/main/java/io/github/hapjava/server/impl/HomekitRoot.java @@ -9,6 +9,7 @@ import io.github.hapjava.server.impl.jmdns.JmdnsHomekitAdvertiser; import java.io.IOException; import java.net.InetAddress; +import javax.jmdns.JmDNS; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,6 +54,11 @@ public class HomekitRoot { this.registry = new HomekitRegistry(label); } + HomekitRoot(String label, HomekitWebHandler webHandler, JmDNS jmdns, HomekitAuthInfo authInfo) + throws IOException { + this(label, webHandler, authInfo, new JmdnsHomekitAdvertiser(jmdns)); + } + /** * Add an accessory to be handled and advertised by this root. Any existing HomeKit connections * will be terminated to allow the clients to reconnect and see the updated accessory list. When diff --git a/src/main/java/io/github/hapjava/server/impl/HomekitServer.java b/src/main/java/io/github/hapjava/server/impl/HomekitServer.java index f323fa60b..d348ca682 100644 --- a/src/main/java/io/github/hapjava/server/impl/HomekitServer.java +++ b/src/main/java/io/github/hapjava/server/impl/HomekitServer.java @@ -8,6 +8,7 @@ import java.net.InetAddress; import java.security.InvalidAlgorithmParameterException; import java.util.concurrent.ExecutionException; +import javax.jmdns.JmDNS; /** * The main entry point for hap-java. Creating an instance of this class will listen for HomeKit @@ -28,6 +29,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. @@ -41,9 +43,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 * @@ -55,6 +72,16 @@ public HomekitServer(InetAddress localAddress, int port) throws IOException { this(localAddress, port, Runtime.getRuntime().availableProcessors()); } + /** + * Constructor + * + * @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 * @@ -84,7 +111,11 @@ public void stop() { public HomekitStandaloneAccessoryServer createStandaloneAccessory( HomekitAuthInfo authInfo, HomekitAccessory accessory) throws IOException, ExecutionException, InterruptedException { - 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); + } } /** @@ -114,7 +145,12 @@ public HomekitRoot createBridge( String firmwareRevision, String hardwareRevision) 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, firmwareRevision, hardwareRevision)); diff --git a/src/main/java/io/github/hapjava/server/impl/HomekitStandaloneAccessoryServer.java b/src/main/java/io/github/hapjava/server/impl/HomekitStandaloneAccessoryServer.java index e9b09145b..5eecfe45c 100644 --- a/src/main/java/io/github/hapjava/server/impl/HomekitStandaloneAccessoryServer.java +++ b/src/main/java/io/github/hapjava/server/impl/HomekitStandaloneAccessoryServer.java @@ -7,6 +7,7 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.util.concurrent.ExecutionException; +import javax.jmdns.JmDNS; /** * A server for exposing standalone HomeKit accessory (as opposed to a Bridge accessory which @@ -30,6 +31,16 @@ public class HomekitStandaloneAccessoryServer { root.addAccessory(accessory); } + HomekitStandaloneAccessoryServer( + HomekitAccessory accessory, + HomekitWebHandler webHandler, + JmDNS jmdns, + HomekitAuthInfo authInfo) + throws UnknownHostException, IOException, ExecutionException, InterruptedException { + root = new HomekitRoot(accessory.getName().get(), 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/io/github/hapjava/server/impl/jmdns/JmdnsHomekitAdvertiser.java b/src/main/java/io/github/hapjava/server/impl/jmdns/JmdnsHomekitAdvertiser.java index 8e3daf616..a178d2cfc 100644 --- a/src/main/java/io/github/hapjava/server/impl/jmdns/JmdnsHomekitAdvertiser.java +++ b/src/main/java/io/github/hapjava/server/impl/jmdns/JmdnsHomekitAdvertiser.java @@ -27,6 +27,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); } @@ -57,7 +61,7 @@ public synchronized void advertise( } public synchronized void stop() { - jmdns.unregisterAllServices(); + unregisterService(); } public synchronized void setDiscoverable(boolean discoverable) throws IOException { @@ -65,7 +69,7 @@ public synchronized void setDiscoverable(boolean discoverable) throws IOExceptio this.discoverable = discoverable; if (isAdvertising) { logger.trace("Re-creating service due to change in discoverability to " + discoverable); - jmdns.unregisterAllServices(); + unregisterService(); registerService(); } } @@ -76,14 +80,22 @@ public synchronized void setConfigurationIndex(int revision) throws IOException this.configurationIndex = revision; if (isAdvertising) { logger.trace("Re-creating service due to change in configuration index to " + revision); - jmdns.unregisterAllServices(); + unregisterService(); registerService(); } } } + private void unregisterService() { + jmdns.unregisterService(buildServiceInfo()); + } + private void registerService() throws IOException { logger.info("Registering " + SERVICE_TYPE + " on port " + port); + jmdns.registerService(buildServiceInfo()); + } + + private ServiceInfo buildServiceInfo() { logger.trace("MAC:" + mac + " Setup Id:" + setupId); Map props = new HashMap<>(); props.put("sf", discoverable ? "1" : "0"); @@ -94,6 +106,6 @@ 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); } }