2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.io.hueemulation.internal.upnp;
15 import java.io.IOException;
16 import java.net.Inet6Address;
17 import java.net.InetAddress;
18 import java.net.UnknownHostException;
19 import java.nio.channels.Selector;
20 import java.util.concurrent.CompletableFuture;
21 import java.util.function.Consumer;
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.openhab.io.hueemulation.internal.HueEmulationConfig;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
30 * The upnp server runtime configuration. Based on a {@link HueEmulationConfig} and determined ip address and port.
31 * This extends {@link Thread}, because a runtime configuration is always valid for exactly one thread to be started
34 * @author David Graeff - Initial contribution
37 class HueEmulationConfigWithRuntime extends Thread implements Runnable {
39 private final Logger logger = LoggerFactory.getLogger(HueEmulationConfigWithRuntime.class);
41 final @NonNullByDefault({}) HueEmulationConfig config;
42 final InetAddress address;
43 final String addressString;
44 final InetAddress multicastAddress;
47 final CompletableFuture<@Nullable HueEmulationConfigWithRuntime> future = new CompletableFuture<>();
48 final Consumer<HueEmulationConfigWithRuntime> r;
51 public @Nullable Selector asyncIOselector;
52 private boolean hasAlreadyBeenStarted = false;
54 HueEmulationConfigWithRuntime(Consumer<HueEmulationConfigWithRuntime> r, HueEmulationConfig config,
55 String addrString, InetAddress MULTI_ADDR_IPV4, InetAddress MULTI_ADDR_IPV6) throws UnknownHostException {
56 super("HueEmulation UPNP Server");
60 address = InetAddress.getByName(addrString);
61 if (address instanceof Inet6Address) {
62 addressString = "[" + address.getHostAddress().split("%")[0] + "]";
63 multicastAddress = MULTI_ADDR_IPV6;
65 addressString = address.getHostAddress();
66 multicastAddress = MULTI_ADDR_IPV4;
69 port = config.discoveryHttpPort == 0 ? Integer.getInteger("org.osgi.service.http.port", 8080)
70 : config.discoveryHttpPort;
73 HueEmulationConfigWithRuntime(Consumer<HueEmulationConfigWithRuntime> r, @Nullable HueEmulationConfig config,
74 InetAddress MULTI_ADDR_IPV4, InetAddress MULTI_ADDR_IPV6) throws UnknownHostException {
75 super("HueEmulation UPNP Server");
79 address = InetAddress.getByName("localhost");
80 if (address instanceof Inet6Address) {
81 addressString = "[" + address.getHostAddress().split("%")[0] + "]";
82 multicastAddress = MULTI_ADDR_IPV6;
84 addressString = address.getHostAddress();
85 multicastAddress = MULTI_ADDR_IPV4;
90 String getMulticastAddress() {
91 if (multicastAddress instanceof Inet6Address) {
92 return "[" + multicastAddress.getHostAddress().split("%")[0] + "]";
94 return multicastAddress.getHostAddress();
98 public synchronized CompletableFuture<@Nullable HueEmulationConfigWithRuntime> startNow() {
99 if (hasAlreadyBeenStarted) {
100 logger.debug("Cannot restart thread");
103 hasAlreadyBeenStarted = true;
113 public void dispose() {
114 Selector selector = asyncIOselector;
115 if (selector != null) {
118 } catch (IOException ignored) {
123 } catch (InterruptedException ignore) {
124 Thread.currentThread().interrupt();
126 asyncIOselector = null;