mirror of
https://github.com/bwssytems/ha-bridge.git
synced 2025-12-16 18:24:36 +00:00
Changed handling of upnp rsponses from the upnp listener and the
huemulator udp calls to use the same response port.
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -5,7 +5,7 @@
|
||||
|
||||
<groupId>com.bwssystems.HABridge</groupId>
|
||||
<artifactId>ha-bridge</artifactId>
|
||||
<version>3.1.0j</version>
|
||||
<version>3.1.0k</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>HA Bridge</name>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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://"))
|
||||
{
|
||||
|
||||
@@ -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<NetworkInterface> 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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user