diff --git a/pom.xml b/pom.xml
index c20860c..8cf2371 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
com.bwssystems.HABridge
ha-bridge
- 3.1.0j
+ 3.1.0k
jar
HA Bridge
diff --git a/src/main/java/com/bwssystems/HABridge/HABridge.java b/src/main/java/com/bwssystems/HABridge/HABridge.java
index 928570c..ae4ab4f 100644
--- a/src/main/java/com/bwssystems/HABridge/HABridge.java
+++ b/src/main/java/com/bwssystems/HABridge/HABridge.java
@@ -13,6 +13,7 @@ import com.bwssystems.NestBridge.NestHome;
import com.bwssystems.hal.HalHome;
import com.bwssystems.harmony.HarmonyHome;
import com.bwssystems.hue.HueHome;
+import com.bwssystems.util.UDPDatagramSender;
public class HABridge {
@@ -39,6 +40,7 @@ public class HABridge {
HueHome hueHome;
HalHome halHome;
HueMulator theHueMulator;
+ UDPDatagramSender udpSender;
UpnpSettingsResource theSettingResponder;
UpnpListener theUpnpListener;
SystemControl theSystem;
@@ -72,29 +74,37 @@ public class HABridge {
halHome = new HalHome(bridgeSettings.getBridgeSettingsDescriptor());
// setup the class to handle the resource setup rest api
theResources = new DeviceResource(bridgeSettings.getBridgeSettingsDescriptor(), harmonyHome, nestHome, hueHome, halHome);
- // setup the class to handle the hue emulator rest api
- theHueMulator = new HueMulator(bridgeSettings.getBridgeSettingsDescriptor(), theResources.getDeviceRepository(), harmonyHome, nestHome, hueHome);
- theHueMulator.setupServer();
// setup the class to handle the upnp response rest api
theSettingResponder = new UpnpSettingsResource(bridgeSettings.getBridgeSettingsDescriptor());
theSettingResponder.setupServer();
- // wait for the sparkjava initialization of the rest api classes to be complete
- awaitInitialization();
-
- // start the upnp ssdp discovery listener
- theUpnpListener = new UpnpListener(bridgeSettings.getBridgeSettingsDescriptor(), bridgeSettings.getBridgeControl());
- if(theUpnpListener.startListening())
- log.info("HA Bridge (v" + theVersion.getVersion() + ") reinitialization requessted....");
- else
- bridgeSettings.getBridgeControl().setStop(true);
- if(bridgeSettings.getBridgeSettingsDescriptor().isSettingsChanged())
- bridgeSettings.save(bridgeSettings.getBridgeSettingsDescriptor());
+ // setup the UDP Datagram socket to be used by the HueMulator and the upnpListener
+ udpSender = UDPDatagramSender.createUDPDatagramSender(bridgeSettings.getBridgeSettingsDescriptor().getUpnpResponsePort());
+ if(udpSender == null) {
+ bridgeSettings.getBridgeControl().setStop(true);
+ }
+ else {
+ // setup the class to handle the hue emulator rest api
+ theHueMulator = new HueMulator(bridgeSettings.getBridgeSettingsDescriptor(), theResources.getDeviceRepository(), harmonyHome, nestHome, hueHome, udpSender);
+ theHueMulator.setupServer();
+ // wait for the sparkjava initialization of the rest api classes to be complete
+ awaitInitialization();
+
+ // start the upnp ssdp discovery listener
+ theUpnpListener = new UpnpListener(bridgeSettings.getBridgeSettingsDescriptor(), bridgeSettings.getBridgeControl(), udpSender);
+ if(theUpnpListener.startListening())
+ log.info("HA Bridge (v" + theVersion.getVersion() + ") reinitialization requessted....");
+ else
+ bridgeSettings.getBridgeControl().setStop(true);
+ if(bridgeSettings.getBridgeSettingsDescriptor().isSettingsChanged())
+ bridgeSettings.save(bridgeSettings.getBridgeSettingsDescriptor());
+ }
bridgeSettings.getBridgeControl().setReinit(false);
stop();
nestHome.closeTheNest();
nestHome = null;
harmonyHome.shutdownHarmonyHubs();
harmonyHome = null;
+ udpSender.closeResponseSocket();
}
log.info("HA Bridge (v" + theVersion.getVersion() + ") exiting....");
System.exit(0);
diff --git a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java
index a93d7d5..60bca51 100644
--- a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java
+++ b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java
@@ -27,6 +27,7 @@ import com.bwssystems.hue.HueHome;
import com.bwssystems.hue.HueUtil;
import com.bwssystems.nest.controller.Nest;
import com.bwssystems.util.JsonTransformer;
+import com.bwssystems.util.UDPDatagramSender;
import com.google.gson.Gson;
import net.java.dev.eval.Expression;
@@ -60,8 +61,6 @@ import java.io.DataOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
-import java.net.DatagramPacket;
-import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
import java.nio.charset.Charset;
@@ -99,12 +98,13 @@ public class HueMulator implements HueErrorStringSet {
private SSLConnectionSocketFactory sslsf;
private RequestConfig globalConfig;
private BridgeSettingsDescriptor bridgeSettings;
+ private UDPDatagramSender theUDPDatagramSender;
private byte[] sendData;
private String hueUser;
private String errorString;
- public HueMulator(BridgeSettingsDescriptor theBridgeSettings, DeviceRepository aDeviceRepository, HarmonyHome theHarmonyHome, NestHome aNestHome, HueHome aHueHome){
+ public HueMulator(BridgeSettingsDescriptor theBridgeSettings, DeviceRepository aDeviceRepository, HarmonyHome theHarmonyHome, NestHome aNestHome, HueHome aHueHome, UDPDatagramSender aUdpDatagramSender) {
httpClient = HttpClients.createDefault();
// Trust own CA and all self-signed certs
sslcontext = SSLContexts.createDefault();
@@ -136,6 +136,7 @@ public class HueMulator implements HueErrorStringSet {
else
this.myHueHome = null;
bridgeSettings = theBridgeSettings;
+ theUDPDatagramSender = aUdpDatagramSender;
hueUser = null;
errorString = null;
}
@@ -905,10 +906,7 @@ public class HueMulator implements HueErrorStringSet {
}
if(callItems[i].getItem().contains("udp://")) {
log.debug("executing HUE api request to UDP: " + callItems[i].getItem());
- DatagramSocket responseSocket = new DatagramSocket(Integer.parseInt(port));
- DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, Integer.parseInt(port));
- responseSocket.send(sendPacket);
- responseSocket.close();
+ theUDPDatagramSender.sendUDPResponse(new String(sendData), IPAddress, Integer.parseInt(port));
}
else if(callItems[i].getItem().contains("tcp://"))
{
diff --git a/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java b/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java
index 3ed7b79..dba4225 100644
--- a/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java
+++ b/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java
@@ -7,6 +7,7 @@ import com.bwssystems.HABridge.BridgeControlDescriptor;
import com.bwssystems.HABridge.BridgeSettingsDescriptor;
import com.bwssystems.HABridge.Configuration;
import com.bwssystems.HABridge.api.hue.HuePublicConfig;
+import com.bwssystems.util.UDPDatagramSender;
import java.io.IOException;
import java.net.*;
@@ -17,7 +18,7 @@ import org.apache.http.conn.util.*;
public class UpnpListener {
private Logger log = LoggerFactory.getLogger(UpnpListener.class);
- private int upnpResponsePort;
+ private UDPDatagramSender theUDPDatagramSender;
private int httpServerPort;
private String responseAddress;
private boolean strict;
@@ -92,9 +93,9 @@ public class UpnpListener {
"ST: urn:schemas-upnp-org:device:basic:1\r\n" +
"USN: uuid:Socket-1_0-221438K0100073::urn:Belkin:device:**\r\n\r\n";
*/
- public UpnpListener(BridgeSettingsDescriptor theSettings, BridgeControlDescriptor theControl) {
+ public UpnpListener(BridgeSettingsDescriptor theSettings, BridgeControlDescriptor theControl, UDPDatagramSender aUdpDatagramSender) {
super();
- upnpResponsePort = theSettings.getUpnpResponsePort();
+ theUDPDatagramSender = aUdpDatagramSender;
httpServerPort = Integer.valueOf(theSettings.getServerPort());
responseAddress = theSettings.getUpnpConfigAddress();
strict = theSettings.isUpnpStrict();
@@ -106,33 +107,9 @@ public class UpnpListener {
@SuppressWarnings("resource")
public boolean startListening(){
log.info("UPNP Discovery Listener starting....");
- DatagramSocket responseSocket = null;
MulticastSocket upnpMulticastSocket = null;
Enumeration ifs = null;
- boolean portLoopControl = true;
- int retryCount = 0;
- while(portLoopControl) {
- try {
- responseSocket = new DatagramSocket(upnpResponsePort);
- if(retryCount > 0)
- log.info("Upnp Response Port issue, found open port: " + upnpResponsePort);
- portLoopControl = false;
- } catch(SocketException e) {
- if(retryCount == 0)
- log.warn("Upnp Response Port is in use, starting loop to find open port for 20 tries - configured port is: " + upnpResponsePort);
- if(retryCount >= 20) {
- portLoopControl = false;
- log.error("Upnp Response Port issue, could not find open port - last port tried: " + upnpResponsePort + " with message: " + e.getMessage());
- return false;
- }
- }
- if(portLoopControl) {
- retryCount++;
- upnpResponsePort++;
- }
- }
-
try {
upnpMulticastSocket = new MulticastSocket(Configuration.UPNP_DISCOVERY_PORT);
} catch(IOException e){
@@ -189,7 +166,7 @@ public class UpnpListener {
upnpMulticastSocket.receive(packet);
if (isSSDPDiscovery(packet)) {
try {
- sendUpnpResponse(responseSocket, packet.getAddress(), packet.getPort());
+ sendUpnpResponse(packet.getAddress(), packet.getPort());
} catch (IOException e) {
if(e.getMessage().equalsIgnoreCase("Host is down"))
log.warn("UpnpListener encountered an error sending upnp response packet as requesting host is now not available. IP: " + packet.getAddress().getHostAddress());
@@ -213,7 +190,6 @@ public class UpnpListener {
}
}
upnpMulticastSocket.close();
- responseSocket.close();
if (bridgeControl.isReinit())
log.info("UPNP Discovery Listener - ended, restart found");
if (bridgeControl.isStop())
@@ -265,7 +241,7 @@ public class UpnpListener {
return false;
}
- protected void sendUpnpResponse(DatagramSocket socket, InetAddress requester, int sourcePort) throws IOException {
+ protected void sendUpnpResponse(InetAddress requester, int sourcePort) throws IOException {
String discoveryResponse = null;
String bridgeIdMac = null;
if(discoveryTemplateLatest) {
@@ -280,7 +256,6 @@ public class UpnpListener {
}
else
log.debug("sendUpnpResponse discovery template with address: " + responseAddress + " and port: " + httpServerPort);
- DatagramPacket response = new DatagramPacket(discoveryResponse.getBytes(), discoveryResponse.length(), requester, sourcePort);
- socket.send(response);
+ theUDPDatagramSender.sendUDPResponse(discoveryResponse, requester, sourcePort);
}
}