diff --git a/src/main/java/io/github/hapjava/server/HomekitAccessoryCategories.java b/src/main/java/io/github/hapjava/server/HomekitAccessoryCategories.java new file mode 100644 index 000000000..05768a947 --- /dev/null +++ b/src/main/java/io/github/hapjava/server/HomekitAccessoryCategories.java @@ -0,0 +1,40 @@ +package io.github.hapjava.server; + +public final class HomekitAccessoryCategories { + public static final int OTHER = 1; + public static final int BRIDGES = 2; + public static final int FANS = 3; + public static final int GARAGE_DOOR_OPENERS = 4; + public static final int LIGHTING = 5; + public static final int LOCKS = 6; + public static final int OUTLETS = 7; + public static final int SWITCHES = 8; + public static final int THERMOSTATS = 9; + public static final int SENSORS = 10; + public static final int SECURITY_SYSTEMS = 11; + public static final int DOORS = 12; + public static final int WINDOWS = 13; + public static final int WINDOW_COVERINGS = 14; + public static final int PROGRAMMABLE_SWITCHES = 15; + public static final int RANGE_EXTENDER = 16; + public static final int IP_CAMERAS = 17; + public static final int VIDEO_DOORBELLS = 18; + public static final int AIR_PURIFIERS = 19; + public static final int HEATERS = 20; + public static final int AIR_CONDITIONERS = 21; + public static final int HUMIDIFIERS = 22; + public static final int DEHUMIDIFIERS = 23; + public static final int APPLE_TV = 24; + public static final int HOMEPOD = 25; + public static final int SPEAKER = 26; + public static final int AIRPORT = 27; + public static final int SPRINKLERS = 28; + public static final int FAUCETS = 29; + public static final int SHOWER_SYSTEMS = 30; + public static final int TELEVISION = 31; + public static final int REMOTES = 32; + public static final int ROUTER = 33; + public static final int AUDIO_RECEIVER = 34; + public static final int TV_SET_TOP_BOX = 35; + public static final int TV_STREAMING_STICK = 36; +} 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 e619fa1e7..ca182f812 100644 --- a/src/main/java/io/github/hapjava/server/impl/HomekitRoot.java +++ b/src/main/java/io/github/hapjava/server/impl/HomekitRoot.java @@ -2,6 +2,7 @@ import io.github.hapjava.accessories.Bridge; import io.github.hapjava.accessories.HomekitAccessory; +import io.github.hapjava.server.HomekitAccessoryCategories; import io.github.hapjava.server.HomekitAuthInfo; import io.github.hapjava.server.HomekitWebHandler; import io.github.hapjava.server.impl.connections.HomekitClientConnectionFactoryImpl; @@ -25,24 +26,36 @@ public class HomekitRoot { private static final Logger logger = LoggerFactory.getLogger(HomekitRoot.class); - + private static final int DEFAULT_ACCESSORY_CATEGORY = HomekitAccessoryCategories.OTHER; private final JmdnsHomekitAdvertiser advertiser; private final HomekitWebHandler webHandler; private final HomekitAuthInfo authInfo; private final String label; + private final int category; private final HomekitRegistry registry; private final SubscriptionManager subscriptions = new SubscriptionManager(); private boolean started = false; private int configurationIndex = 1; HomekitRoot( - String label, HomekitWebHandler webHandler, InetAddress localhost, HomekitAuthInfo authInfo) + String label, HomekitWebHandler webHandler, InetAddress host, HomekitAuthInfo authInfo) + throws IOException { + this(label, DEFAULT_ACCESSORY_CATEGORY, webHandler, authInfo, new JmdnsHomekitAdvertiser(host)); + } + + HomekitRoot( + String label, + int category, + HomekitWebHandler webHandler, + InetAddress host, + HomekitAuthInfo authInfo) throws IOException { - this(label, webHandler, authInfo, new JmdnsHomekitAdvertiser(localhost)); + this(label, category, webHandler, authInfo, new JmdnsHomekitAdvertiser(host)); } HomekitRoot( String label, + int category, HomekitWebHandler webHandler, HomekitAuthInfo authInfo, JmdnsHomekitAdvertiser advertiser) @@ -51,14 +64,25 @@ public class HomekitRoot { this.webHandler = webHandler; this.authInfo = authInfo; this.label = label; + this.category = category; this.registry = new HomekitRegistry(label); } - HomekitRoot(String label, HomekitWebHandler webHandler, JmDNS jmdns, HomekitAuthInfo authInfo) + HomekitRoot( + String label, + int category, + HomekitWebHandler webHandler, + JmDNS jmdns, + HomekitAuthInfo authInfo) throws IOException { - this(label, webHandler, authInfo, new JmdnsHomekitAdvertiser(jmdns)); + this(label, category, webHandler, authInfo, new JmdnsHomekitAdvertiser(jmdns)); } + HomekitRoot(String label, HomekitWebHandler webHandler, JmDNS jmdns, HomekitAuthInfo authInfo) + throws IOException { + this( + label, DEFAULT_ACCESSORY_CATEGORY, 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 @@ -127,7 +151,12 @@ public void start() { try { refreshAuthInfo(); advertiser.advertise( - label, authInfo.getMac(), port, configurationIndex, authInfo.getSetupId()); + label, + category, + authInfo.getMac(), + port, + configurationIndex, + authInfo.getSetupId()); } catch (Exception e) { throw new RuntimeException(e); } 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 d348ca682..af129a7a8 100644 --- a/src/main/java/io/github/hapjava/server/impl/HomekitServer.java +++ b/src/main/java/io/github/hapjava/server/impl/HomekitServer.java @@ -139,6 +139,7 @@ public HomekitStandaloneAccessoryServer createStandaloneAccessory( public HomekitRoot createBridge( HomekitAuthInfo authInfo, String label, + int category, String manufacturer, String model, String serialNumber, @@ -147,9 +148,9 @@ public HomekitRoot createBridge( throws IOException { HomekitRoot root; if (jmdns != null) { - root = new HomekitRoot(label, http, jmdns, authInfo); + root = new HomekitRoot(label, category, http, jmdns, authInfo); } else { - root = new HomekitRoot(label, http, localAddress, authInfo); + root = new HomekitRoot(label, category, http, localAddress, authInfo); } root.addAccessory( new HomekitBridge( diff --git a/src/main/java/io/github/hapjava/server/impl/http/impl/AccessoryHandler.java b/src/main/java/io/github/hapjava/server/impl/http/impl/AccessoryHandler.java index 0e1bf1146..6b840c713 100644 --- a/src/main/java/io/github/hapjava/server/impl/http/impl/AccessoryHandler.java +++ b/src/main/java/io/github/hapjava/server/impl/http/impl/AccessoryHandler.java @@ -72,9 +72,9 @@ private void sendResponse( HttpVersion.HTTP_1_1, status, Unpooled.copiedBuffer(responseBody.getBytes(StandardCharsets.UTF_8))); - response.headers().set(HttpHeaders.Names.CONTENT_TYPE, "text/plain"); - response.headers().set(HttpHeaders.Names.CONTENT_LENGTH, response.content().readableBytes()); - response.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE); + response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain"); + response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes()); + response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE); ctx.write(response); ctx.flush(); } diff --git a/src/main/java/io/github/hapjava/server/impl/http/impl/DefaultHttpRequestImpl.java b/src/main/java/io/github/hapjava/server/impl/http/impl/DefaultHttpRequestImpl.java index 48a3ceb35..a124705f1 100644 --- a/src/main/java/io/github/hapjava/server/impl/http/impl/DefaultHttpRequestImpl.java +++ b/src/main/java/io/github/hapjava/server/impl/http/impl/DefaultHttpRequestImpl.java @@ -13,7 +13,7 @@ public DefaultHttpRequestImpl(io.netty.handler.codec.http.HttpRequest request) { @Override public String getUri() { - return request.getUri(); + return request.uri(); } @Override @@ -23,7 +23,7 @@ public byte[] getBody() { @Override public HttpMethod getMethod() { - io.netty.handler.codec.http.HttpMethod method = request.getMethod(); + io.netty.handler.codec.http.HttpMethod method = request.method(); if (method.equals(io.netty.handler.codec.http.HttpMethod.GET)) { return HttpMethod.GET; } else if (method.equals(io.netty.handler.codec.http.HttpMethod.POST)) { diff --git a/src/main/java/io/github/hapjava/server/impl/http/impl/NettyResponseUtil.java b/src/main/java/io/github/hapjava/server/impl/http/impl/NettyResponseUtil.java index fba52eef5..9e7963fb3 100644 --- a/src/main/java/io/github/hapjava/server/impl/http/impl/NettyResponseUtil.java +++ b/src/main/java/io/github/hapjava/server/impl/http/impl/NettyResponseUtil.java @@ -4,7 +4,8 @@ import io.netty.buffer.Unpooled; import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.FullHttpResponse; -import io.netty.handler.codec.http.HttpHeaders; +import io.netty.handler.codec.http.HttpHeaderNames; +import io.netty.handler.codec.http.HttpHeaderValues; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpVersion; import java.util.Map.Entry; @@ -25,8 +26,8 @@ public static FullHttpResponse createResponse(HttpResponse homekitResponse) { for (Entry header : homekitResponse.getHeaders().entrySet()) { response.headers().add(header.getKey(), header.getValue()); } - response.headers().set(HttpHeaders.Names.CONTENT_LENGTH, response.content().readableBytes()); - response.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE); + response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes()); + response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE); return response; } } 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 04016561e..1535a490a 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,7 @@ public class JmdnsHomekitAdvertiser { private int port; private int configurationIndex; private ServiceInfo serviceInfo; + private int category; public JmdnsHomekitAdvertiser(JmDNS jmdns) { this.jmdns = jmdns; @@ -37,7 +38,8 @@ public JmdnsHomekitAdvertiser(InetAddress localAddress) throws UnknownHostExcept } public synchronized void advertise( - String label, String mac, int port, int configurationIndex, String setupId) throws Exception { + String label, int category, String mac, int port, int configurationIndex, String setupId) + throws Exception { if (isAdvertising) { throw new IllegalStateException("HomeKit advertiser is already running"); } @@ -45,6 +47,7 @@ public synchronized void advertise( this.mac = mac; this.port = port; this.setupId = setupId; + this.category = category; this.configurationIndex = configurationIndex; logger.trace("Advertising accessory " + label); @@ -114,7 +117,9 @@ private ServiceInfo buildServiceInfo() { props.put("c#", Integer.toString(configurationIndex)); props.put("s#", "1"); props.put("ff", "0"); - props.put("ci", "1"); + props.put("ci", Integer.toString(category)); + props.put("pv", "1.1"); + return ServiceInfo.create(SERVICE_TYPE, label, port, 1, 1, props); } } diff --git a/src/test/java/io/github/hapjava/server/impl/HomekitRootTest.java b/src/test/java/io/github/hapjava/server/impl/HomekitRootTest.java index 719fea9d1..3ac40288a 100644 --- a/src/test/java/io/github/hapjava/server/impl/HomekitRootTest.java +++ b/src/test/java/io/github/hapjava/server/impl/HomekitRootTest.java @@ -8,6 +8,7 @@ import static org.mockito.Mockito.when; import io.github.hapjava.accessories.HomekitAccessory; +import io.github.hapjava.server.HomekitAccessoryCategories; import io.github.hapjava.server.HomekitAuthInfo; import io.github.hapjava.server.HomekitWebHandler; import io.github.hapjava.server.impl.http.HomekitClientConnectionFactory; @@ -38,7 +39,8 @@ public void setup() throws Exception { when(webHandler.start(any())).thenReturn(CompletableFuture.completedFuture(PORT)); advertiser = mock(JmdnsHomekitAdvertiser.class); authInfo = mock(HomekitAuthInfo.class); - root = new HomekitRoot(LABEL, webHandler, authInfo, advertiser); + root = + new HomekitRoot(LABEL, HomekitAccessoryCategories.OTHER, webHandler, authInfo, advertiser); } @Test @@ -78,7 +80,7 @@ public void testAdvertiserStarts() throws Exception { when(authInfo.getSetupId()).thenReturn(SETUPID); root.start(); - verify(advertiser).advertise(eq(LABEL), eq(mac), eq(PORT), eq(1), eq(SETUPID)); + verify(advertiser).advertise(eq(LABEL), eq(1), eq(mac), eq(PORT), eq(1), eq(SETUPID)); } @Test diff --git a/src/test/java/io/github/hapjava/server/impl/jmdns/JmdnsHomekitAdvertiserTest.java b/src/test/java/io/github/hapjava/server/impl/jmdns/JmdnsHomekitAdvertiserTest.java index 1c04b2868..870bd739b 100644 --- a/src/test/java/io/github/hapjava/server/impl/jmdns/JmdnsHomekitAdvertiserTest.java +++ b/src/test/java/io/github/hapjava/server/impl/jmdns/JmdnsHomekitAdvertiserTest.java @@ -61,6 +61,6 @@ private ServiceInfo getArgumentFromUnregister() { } private void advertise() throws Exception { - subject.advertise("test", "00:00:00:00:00:00", 1234, 1, "1"); + subject.advertise("test", 1, "00:00:00:00:00:00", 1234, 1, "1"); } }