Updated logging for upnp listener and description service. Added method

in huemulator for "/*" which was present in the armzilla version for the
Harmony Hub. Updated the readme.
This commit is contained in:
Admin
2015-09-11 16:01:38 -05:00
parent 9666273840
commit 416b4d3fda
6 changed files with 71 additions and 14 deletions

View File

@@ -20,7 +20,7 @@ The server defaults to the first available address on the host. Replace the -Dup
The server defaults to running on port 8080. If you're already running a server (like openHAB) on 8080, -Dserver.port=`<port>` on the command line.
### -Dupnp.device.db=`<filepath>`
The default location for the db to contain the devices as they are added is "data/devices.db". If you would like a different filename or directory, specify -Dupnp.devices.db=`<directory>/<filename> or <filename>` if it is the same directory.
### -Dupnp.resonse.port=`<port>`
### -Dupnp.response.port=`<port>`
The upnp response port that will be used. The default is 50000.
### -Dupnp.strict=`<true|false>`
Upnp has been very closed on this platform to try and respond as a hue and there is now a setting to control if it is more open or strict, Add -Dupnp.strict=`<true|false>` to your command line to have the emulator respond to what it thinks is an echo to a hue or any other device. The default is upnp.strict=false.

View File

@@ -5,7 +5,7 @@
<groupId>com.bwssystems.HABridge</groupId>
<artifactId>ha-bridge</artifactId>
<version>0.4.3</version>
<version>0.4.4</version>
<packaging>jar</packaging>
<name>HA Bridge</name>

View File

@@ -100,6 +100,31 @@ public class HueMulator {
return "[{\"success\":{\"username\":\"" + newUser + "\"}}]";
} );
// http://ip_address:port/api/* with body of user request returns json object for a success of user add - This method is for Harmony Hub
post(HUE_CONTEXT + "/*", "application/json", (request, response) -> {
UserCreateRequest aNewUser = null;
String newUser = null;
String aDeviceType = null;
log.info("HH trace: hue api user create requested: " + request.body() + " from " + request.ip());
if(request.body() != null && !request.body().isEmpty()) {
aNewUser = new Gson().fromJson(request.body(), UserCreateRequest.class);
newUser = aNewUser.getUsername();
aDeviceType = aNewUser.getDevicetype();
}
if(newUser == null)
newUser = "lightssystem";
if(aDeviceType == null)
aDeviceType = "<not given>";
log.debug("HH trace: hue api user create requested for device type: " + aDeviceType + " and username: " + newUser);
response.type("application/json; charset=utf-8");
response.status(HttpStatus.SC_OK);
return "[{\"success\":{\"username\":\"" + newUser + "\"}}]";
} );
// http://ip_address:port/api/{userId} returns json objects for the full state
get(HUE_CONTEXT + "/:userid", "application/json", (request, response) -> {
String userId = request.params(":userid");

View File

@@ -40,7 +40,7 @@ public class UpnpListener {
}
public void startListening(){
log.info("UPNP Discovery Listener started....");
log.info("UPNP Discovery Listener starting....");
try (DatagramSocket responseSocket = new DatagramSocket(upnpResponsePort);
MulticastSocket upnpMulticastSocket = new MulticastSocket(UPNP_DISCOVERY_PORT);) {
@@ -55,7 +55,10 @@ public class UpnpListener {
while (addrs.hasMoreElements()) {
InetAddress addr = addrs.nextElement();
log.debug(name + " ... has addr " + addr);
if(traceupnp)
log.info("Traceupnp: " + name + " ... has addr " + addr);
else
log.debug(name + " ... has addr " + addr);
if (InetAddressUtils.isIPv4Address(addr.getHostAddress())) {
IPsPerNic++;
}
@@ -63,10 +66,15 @@ public class UpnpListener {
log.debug("Checking " + name + " to our interface set");
if (IPsPerNic > 0) {
upnpMulticastSocket.joinGroup(socketAddress, xface);
log.debug("Adding " + name + " to our interface set");
if(traceupnp)
log.info("Traceupnp: Adding " + name + " to our interface set");
else
log.debug("Adding " + name + " to our interface set");
}
}
log.info("UPNP Discovery Listener running and ready....");
while(true){ //trigger shutdown here
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
@@ -74,9 +82,9 @@ public class UpnpListener {
String packetString = new String(packet.getData());
if(packetString != null && packetString.contains("M-SEARCH")) {
if(traceupnp)
log.info("Trace SSDP packet from " + packet.getAddress().getHostAddress() + ":" + packet.getPort() + " body : " + packetString);
log.info("Traceupnp: SSDP packet from " + packet.getAddress().getHostAddress() + ":" + packet.getPort() + ", body: " + packetString);
else
log.debug("Got SSDP packet from " + packet.getAddress().getHostAddress() + ":" + packet.getPort() + " body : " + packetString);
log.debug("Got SSDP packet from " + packet.getAddress().getHostAddress() + ":" + packet.getPort() + ", body: " + packetString);
}
if(isSSDPDiscovery(packetString)){
sendUpnpResponse(responseSocket, packet.getAddress(), packet.getPort());
@@ -84,7 +92,7 @@ public class UpnpListener {
}
} catch (IOException e) {
log.error("UpnpListener encountered an error. Shutting down", e);
log.error("UpnpListener encountered an error opening sockets. Shutting down", e);
}
log.info("UPNP Discovery Listener Stopped");
@@ -100,11 +108,23 @@ public class UpnpListener {
// log.debug("Check if this is a MAN ssdp-discover packet for a upnp basic device: " + body);
//Only respond to discover request for upnp basic device from echo, the others are for the wemo
if(body != null && body.contains("M-SEARCH") && body.contains("\"ssdp:discover\"")){
if(strict && body.startsWith("M-SEARCH * HTTP/1.1") && body.contains("MAN: \"ssdp:discover\"") && body.contains("ST: urn:schemas-upnp-org:device:basic:1"))
if(traceupnp)
log.info("Traceupnp: isSSDPDiscovery found message to be an M-SEARCH message.");
if(strict && body.startsWith("M-SEARCH * HTTP/1.1") && body.contains("MAN: \"ssdp:discover\"") && (body.contains("ST: urn:schemas-upnp-org:device:basic:1") || body.contains("ST: upnp:rootdevice") || body.contains("ST: ssdp:all")))
{
if(traceupnp)
log.info("Traceupnp: isSSDPDiscovery found message to be valid under strict rules - strict: " + strict + ", vTwo.Compatibility: " + vTwoCompatibility);
return true;
}
else if (!strict || vTwoCompatibility)
{
if(traceupnp)
log.info("Traceupnp: isSSDPDiscovery found message to be valid under loose rules - strict: " + strict + ", vTwo.Compatibility: " + vTwoCompatibility);
return true;
}
}
if(traceupnp)
log.info("Traceupnp: isSSDPDiscovery found message to not be valid - strict: " + strict + ", vTwo.Compatibility: " + vTwoCompatibility);
return false;
}
@@ -129,7 +149,10 @@ public class UpnpListener {
discoveryResponse = String.format(discoveryTemplateVTwo, responseAddress, httpServerPort, getRandomUUIDString());
else
discoveryResponse = String.format(discoveryTemplate, responseAddress, httpServerPort, getRandomUUIDString());
log.debug("sndUpnpResponse: " + discoveryResponse);
if(traceupnp)
log.info("Traceupnp: sendUpnpResponse: " + discoveryResponse);
else
log.debug("sendUpnpResponse: " + discoveryResponse);
DatagramPacket response = new DatagramPacket(discoveryResponse.getBytes(), discoveryResponse.length(), requester, sourcePort);
socket.send(response);
}

View File

@@ -15,6 +15,8 @@ public class UpnpSettingsResource {
private static final String UPNP_CONTEXT = "/upnp";
private Logger log = LoggerFactory.getLogger(UpnpSettingsResource.class);
private BridgeSettings theSettings;
private String hueTemplate = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" + "<root xmlns=\"urn:schemas-upnp-org:device-1-0\">\n"
+ "<specVersion>\n" + "<major>1</major>\n" + "<minor>0</minor>\n" + "</specVersion>\n"
@@ -87,21 +89,28 @@ public class UpnpSettingsResource {
public UpnpSettingsResource(BridgeSettings theSettings) {
super();
setupListener(theSettings);
this.theSettings = theSettings;
setupListener(this.theSettings);
}
private void setupListener (BridgeSettings theSettings) {
log.info("Hue description service started....");
// http://ip_adress:port/description.xml which returns the xml configuration for the hue emulator
get("/description.xml", "application/xml; charset=utf-8", (request, response) -> {
log.debug("upnp device settings requested: " + request.params(":id") + " from " + request.ip());
if(theSettings.isTraceupnp())
log.info("Traceupnp: upnp device settings requested: " + request.params(":id") + " from " + request.ip() + ":" + request.port());
else
log.debug("upnp device settings requested: " + request.params(":id") + " from " + request.ip() + ":" + request.port());
String portNumber = Integer.toString(request.port());
String filledTemplate = null;
if(theSettings.isVtwocompatibility())
filledTemplate = String.format(hueTemplateVTwo, theSettings.getUpnpConfigAddress(), portNumber, theSettings.getUpnpConfigAddress());
else
filledTemplate = String.format(hueTemplate, theSettings.getUpnpConfigAddress(), portNumber, theSettings.getUpnpConfigAddress());
log.debug("upnp device settings response: " + filledTemplate);
if(theSettings.isTraceupnp())
log.info("Traceupnp: upnp device settings response: " + filledTemplate);
else
log.debug("upnp device settings response: " + filledTemplate);
// response.header("Cache-Control", "no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
// response.header("Pragma", "no-cache");
// response.header("Expires", "Mon, 1 Aug 2011 09:00:00 GMT");

View File

@@ -36,7 +36,7 @@
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li><a href="http://www.bwssystems.com" target="_blank">Developed by BWS Systems</a></li>
<li><a href="http://www.amazon.com/echo" target="_blank">Amazon Echo</a></li>
<li><a href="#">HA Bridge Version 0.4.3</a></li>
<li><a href="#">HA Bridge Version 0.4.4</a></li>
</ul>
</li>
</ul>