mirror of
https://github.com/bwssytems/ha-bridge.git
synced 2025-12-16 18:24:36 +00:00
Update handling of upnp and updated how unique ids are generated
This commit is contained in:
@@ -57,20 +57,20 @@ Then locate the jar and start the server with:
|
|||||||
ATTENTION: Due to port 80 being the default, Linux restricts this to super user. Use the instructions below.
|
ATTENTION: Due to port 80 being the default, Linux restricts this to super user. Use the instructions below.
|
||||||
|
|
||||||
```
|
```
|
||||||
java -jar ha-bridge-5.3.1RC2.jar
|
java -jar ha-bridge-5.3.1RC3.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
## Manual installation of ha-bridge and setup of systemd service
|
## Manual installation of ha-bridge and setup of systemd service
|
||||||
Next gen Linux systems (this includes the Raspberry Pi), use systemd to run and manage services.
|
Next gen Linux systems (this includes the Raspberry Pi), use systemd to run and manage services.
|
||||||
Here is a link on how to use systemd: https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units
|
Here is a link on how to use systemd: https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units
|
||||||
|
|
||||||
Create the directory and make sure that ha-bridge-5.3.1RC2.jar is in your /home/pi/ha-bridge directory.
|
Create the directory and make sure that ha-bridge-5.3.1RC3.jar is in your /home/pi/ha-bridge directory.
|
||||||
|
|
||||||
```
|
```
|
||||||
pi@raspberrypi:~ $ mkdir ha-bridge
|
pi@raspberrypi:~ $ mkdir ha-bridge
|
||||||
pi@raspberrypi:~ $ cd ha-bridge
|
pi@raspberrypi:~ $ cd ha-bridge
|
||||||
|
|
||||||
pi@raspberrypi:~/ha-bridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v5.3.1RC2/ha-bridge-5.3.1RC2.jar
|
pi@raspberrypi:~/ha-bridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v5.3.1RC3/ha-bridge-5.3.1RC3.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
Create the ha-bridge.service unit file:
|
Create the ha-bridge.service unit file:
|
||||||
@@ -89,7 +89,7 @@ After=network.target
|
|||||||
Type=simple
|
Type=simple
|
||||||
|
|
||||||
WorkingDirectory=/home/pi/ha-bridge
|
WorkingDirectory=/home/pi/ha-bridge
|
||||||
ExecStart=/usr/bin/java -jar -Dconfig.file=/home/pi/ha-bridge/data/habridge.config /home/pi/ha-bridge/ha-bridge-5.3.1RC2.jar
|
ExecStart=/usr/bin/java -jar -Dconfig.file=/home/pi/ha-bridge/data/habridge.config /home/pi/ha-bridge/ha-bridge-5.3.1RC3.jar
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|||||||
6
pom.xml
6
pom.xml
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<groupId>com.bwssystems.HABridge</groupId>
|
<groupId>com.bwssystems.HABridge</groupId>
|
||||||
<artifactId>ha-bridge</artifactId>
|
<artifactId>ha-bridge</artifactId>
|
||||||
<version>5.3.1RC1</version>
|
<version>5.3.1RC3</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>HA Bridge</name>
|
<name>HA Bridge</name>
|
||||||
@@ -172,7 +172,7 @@
|
|||||||
<configuration>
|
<configuration>
|
||||||
<rules>
|
<rules>
|
||||||
<requireMavenVersion>
|
<requireMavenVersion>
|
||||||
<!-- Change this to Version 3.3 for Java 1.8 and Raspberry PI compilation -->
|
<!-- Change this to Version 3.3 for Java 1.8 and Raspberry PI compilation, Java 11 is 3.6 -->
|
||||||
<version>3.6</version>
|
<version>3.6</version>
|
||||||
</requireMavenVersion>
|
</requireMavenVersion>
|
||||||
</rules>
|
</rules>
|
||||||
@@ -184,7 +184,7 @@
|
|||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.8.1</version>
|
<version>3.8.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<!-- Comment this release line out for Java 1.8 and Raspberry PI compilation -->
|
<!-- Comment this release line out for Java 1.8 and Raspberry PI compilation -->
|
||||||
<release>11</release>
|
<release>11</release>
|
||||||
<!-- Uncomment the next two lines for Java 1.8 and Raspberry PI compilation -->
|
<!-- Uncomment the next two lines for Java 1.8 and Raspberry PI compilation -->
|
||||||
<!-- <source>1.8</source> -->
|
<!-- <source>1.8</source> -->
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ public class BridgeSettings extends BackupHandler {
|
|||||||
theBridgeSettings = new Gson().fromJson(jsonContent, BridgeSettingsDescriptor.class);
|
theBridgeSettings = new Gson().fromJson(jsonContent, BridgeSettingsDescriptor.class);
|
||||||
theBridgeSettings.setConfigfile(aPath.toString());
|
theBridgeSettings.setConfigfile(aPath.toString());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("Issue loading values from file: " + aPath.toUri().toString() + ", Gson convert failed.");
|
log.warn("Issue loading values from file: " + aPath.toUri().toString() + ", Gson convert failed. Using default settings.");
|
||||||
theBridgeSettings = new BridgeSettingsDescriptor();
|
theBridgeSettings = new BridgeSettingsDescriptor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,6 +132,9 @@ public class BridgeSettingsDescriptor {
|
|||||||
@SerializedName("haaddressessecured")
|
@SerializedName("haaddressessecured")
|
||||||
@Expose
|
@Expose
|
||||||
private boolean haaddressessecured;
|
private boolean haaddressessecured;
|
||||||
|
@SerializedName("upnpadvanced")
|
||||||
|
@Expose
|
||||||
|
private boolean upnpadvanced;
|
||||||
// @SerializedName("activeloggers")
|
// @SerializedName("activeloggers")
|
||||||
// @Expose
|
// @Expose
|
||||||
// private List<NameValue> activeloggers;
|
// private List<NameValue> activeloggers;
|
||||||
@@ -192,6 +195,8 @@ public class BridgeSettingsDescriptor {
|
|||||||
this.upnporiginal = false;
|
this.upnporiginal = false;
|
||||||
this.seedid = 100;
|
this.seedid = 100;
|
||||||
this.haaddressessecured = false;
|
this.haaddressessecured = false;
|
||||||
|
this.configfile = Configuration.CONFIG_FILE;
|
||||||
|
this.upnpadvanced = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUpnpConfigAddress() {
|
public String getUpnpConfigAddress() {
|
||||||
@@ -847,4 +852,12 @@ public class BridgeSettingsDescriptor {
|
|||||||
public void setHaaddressessecured(boolean haaddressessecured) {
|
public void setHaaddressessecured(boolean haaddressessecured) {
|
||||||
this.haaddressessecured = haaddressessecured;
|
this.haaddressessecured = haaddressessecured;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isUpnpadvanced() {
|
||||||
|
return upnpadvanced;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUpnpadvanced(boolean upnpadvanced) {
|
||||||
|
this.upnpadvanced = upnpadvanced;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package com.bwssystems.HABridge.api.hue;
|
|||||||
|
|
||||||
public class HueConstants {
|
public class HueConstants {
|
||||||
public final static String HUB_VERSION = "9999999999";
|
public final static String HUB_VERSION = "9999999999";
|
||||||
public final static String API_VERSION = "1.19.0";
|
public final static String API_VERSION = "1.17.0";
|
||||||
public final static String MODEL_ID = "BSB002";
|
public final static String MODEL_ID = "BSB002";
|
||||||
public final static String UUID_PREFIX = "2f402f80-da50-11e1-9b23-";
|
public final static String UUID_PREFIX = "2f402f80-da50-11e1-9b23-";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ import com.google.gson.JsonSyntaxException;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is an in memory list to manage the configured devices and saves the list as a JSON string to a file for later
|
* This is an in memory list to manage the configured devices and saves the list as a JSON string to a file for later
|
||||||
@@ -188,7 +190,7 @@ public class DeviceRepository extends BackupHandler {
|
|||||||
nextId++;
|
nextId++;
|
||||||
}
|
}
|
||||||
if (descriptors[i].getUniqueid() == null || descriptors[i].getUniqueid().length() == 0) {
|
if (descriptors[i].getUniqueid() == null || descriptors[i].getUniqueid().length() == 0) {
|
||||||
descriptors[i].setUniqueid("00:11:22:33:44:55:66:" + hueUniqueId(Integer.valueOf(descriptors[i].getId())));
|
descriptors[i].setUniqueid(hueUniqueId(Integer.valueOf(descriptors[i].getId())));
|
||||||
}
|
}
|
||||||
put(descriptors[i].getId(), descriptors[i]);
|
put(descriptors[i].getId(), descriptors[i]);
|
||||||
theNames = theNames + " " + descriptors[i].getName() + ", ";
|
theNames = theNames + " " + descriptors[i].getName() + ", ";
|
||||||
@@ -206,11 +208,10 @@ public class DeviceRepository extends BackupHandler {
|
|||||||
DeviceDescriptor theDevice;
|
DeviceDescriptor theDevice;
|
||||||
boolean findNext = true;
|
boolean findNext = true;
|
||||||
|
|
||||||
|
|
||||||
nextId = seedId;
|
nextId = seedId;
|
||||||
while(deviceIterator.hasNext()) {
|
while (deviceIterator.hasNext()) {
|
||||||
theDevice = deviceIterator.next();
|
theDevice = deviceIterator.next();
|
||||||
if(theDevice.isLockDeviceId()) {
|
if (theDevice.isLockDeviceId()) {
|
||||||
lockedIds.add(theDevice.getId());
|
lockedIds.add(theDevice.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -220,15 +221,15 @@ public class DeviceRepository extends BackupHandler {
|
|||||||
theDevice = deviceIterator.next();
|
theDevice = deviceIterator.next();
|
||||||
if (!theDevice.isLockDeviceId()) {
|
if (!theDevice.isLockDeviceId()) {
|
||||||
findNext = true;
|
findNext = true;
|
||||||
while(findNext) {
|
while (findNext) {
|
||||||
if(lockedIds.contains(String.valueOf(nextId))) {
|
if (lockedIds.contains(String.valueOf(nextId))) {
|
||||||
nextId++;
|
nextId++;
|
||||||
} else {
|
} else {
|
||||||
findNext = false;
|
findNext = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
theDevice.setId(String.valueOf(nextId));
|
theDevice.setId(String.valueOf(nextId));
|
||||||
theDevice.setUniqueid("00:11:22:33:44:55:66:" + hueUniqueId(nextId));
|
theDevice.setUniqueid(hueUniqueId(nextId));
|
||||||
nextId++;
|
nextId++;
|
||||||
}
|
}
|
||||||
newdevices.put(theDevice.getId(), theDevice);
|
newdevices.put(theDevice.getId(), theDevice);
|
||||||
@@ -297,27 +298,51 @@ public class DeviceRepository extends BackupHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String hueUniqueId(Integer anId) {
|
private String hueUniqueId(Integer anId) {
|
||||||
String theUniqueId;
|
String theUniqueId = null;
|
||||||
Integer newValue;
|
Integer newValue;
|
||||||
String hexValueLeft;
|
String hexValueLeft;
|
||||||
String hexValueRight;
|
String hexValueRight;
|
||||||
|
|
||||||
newValue = anId % 256;
|
MessageDigest md = null;
|
||||||
if (newValue <= 0)
|
|
||||||
newValue = 1;
|
|
||||||
else if (newValue > 255)
|
|
||||||
newValue = 255;
|
|
||||||
hexValueLeft = HexLibrary.byteToHex(newValue.byteValue());
|
|
||||||
newValue = anId / 256;
|
|
||||||
newValue = newValue % 256;
|
|
||||||
if (newValue < 0)
|
|
||||||
newValue = 0;
|
|
||||||
else if (newValue > 255)
|
|
||||||
newValue = 255;
|
|
||||||
hexValueRight = HexLibrary.byteToHex(newValue.byteValue());
|
|
||||||
|
|
||||||
theUniqueId = String.format("%s-%s", hexValueLeft, hexValueRight).toUpperCase();
|
try {
|
||||||
|
md = MessageDigest.getInstance("MD5");
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
log.warn("Cannot get MD5 utility to hash unique ids.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(md != null) {
|
||||||
|
md.update(anId.toString().getBytes());
|
||||||
|
byte[] digest = md.digest();
|
||||||
|
theUniqueId = String.format("%s:%s:%s:%s:%s:%s:%s-%s",
|
||||||
|
HexLibrary.encodeHexString(digest).substring(0, 2),
|
||||||
|
HexLibrary.encodeHexString(digest).substring(2, 4),
|
||||||
|
HexLibrary.encodeHexString(digest).substring(4, 6),
|
||||||
|
HexLibrary.encodeHexString(digest).substring(6, 8),
|
||||||
|
HexLibrary.encodeHexString(digest).substring(8, 10),
|
||||||
|
HexLibrary.encodeHexString(digest).substring(10, 12),
|
||||||
|
HexLibrary.encodeHexString(digest).substring(12, 14),
|
||||||
|
HexLibrary.encodeHexString(digest).substring(14, 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(theUniqueId == null) {
|
||||||
|
newValue = anId % 256;
|
||||||
|
if (newValue <= 0)
|
||||||
|
newValue = 1;
|
||||||
|
else if (newValue > 255)
|
||||||
|
newValue = 255;
|
||||||
|
hexValueLeft = HexLibrary.byteToHex(newValue.byteValue());
|
||||||
|
newValue = anId / 256;
|
||||||
|
newValue = newValue % 256;
|
||||||
|
if (newValue < 0)
|
||||||
|
newValue = 0;
|
||||||
|
else if (newValue > 255)
|
||||||
|
newValue = 255;
|
||||||
|
hexValueRight = HexLibrary.byteToHex(newValue.byteValue());
|
||||||
|
|
||||||
|
theUniqueId = String.format("11:22:33:44:55:66:%s-%s", hexValueLeft, hexValueRight).toUpperCase();
|
||||||
|
}
|
||||||
return theUniqueId;
|
return theUniqueId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ public class UpnpListener {
|
|||||||
private String upnpConfigIP;
|
private String upnpConfigIP;
|
||||||
// private boolean strict;
|
// private boolean strict;
|
||||||
private boolean upnpOriginal;
|
private boolean upnpOriginal;
|
||||||
|
private boolean upnpAdvanced;
|
||||||
private boolean traceupnp;
|
private boolean traceupnp;
|
||||||
private boolean useUpnpIface;
|
private boolean useUpnpIface;
|
||||||
private BridgeControlDescriptor bridgeControl;
|
private BridgeControlDescriptor bridgeControl;
|
||||||
@@ -38,31 +39,37 @@ public class UpnpListener {
|
|||||||
private String httpType;
|
private String httpType;
|
||||||
private HuePublicConfig aHueConfig;
|
private HuePublicConfig aHueConfig;
|
||||||
private Integer theUpnpSendDelay;
|
private Integer theUpnpSendDelay;
|
||||||
|
|
||||||
|
/* This is the minimum response needed, all others are for the advanced setting */
|
||||||
private String responseTemplate1 = "HTTP/1.1 200 OK\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n"
|
private String responseTemplate1 = "HTTP/1.1 200 OK\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n"
|
||||||
+ "EXT:\r\n" + "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/"
|
+ "EXT:\r\n" + "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/"
|
||||||
+ HueConstants.API_VERSION + "\r\n" + "hue-bridgeid: %s\r\n" + "ST: upnp:rootdevice\r\n" + "USN: uuid:"
|
+ HueConstants.API_VERSION + "\r\n" + "hue-bridgeid: %s\r\n" + "ST: urn:schemas-upnp-org:device:basic:1\r\n"
|
||||||
+ HueConstants.UUID_PREFIX + "%s::upnp:rootdevice\r\n\r\n";
|
+ "USN: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n\r\n";
|
||||||
|
|
||||||
|
/* These next 2 templates are for the advanced upnp option */
|
||||||
private String responseTemplate2 = "HTTP/1.1 200 OK\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n"
|
private String responseTemplate2 = "HTTP/1.1 200 OK\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n"
|
||||||
+ "EXT:\r\n" + "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/"
|
+ "EXT:\r\n" + "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/"
|
||||||
+ HueConstants.API_VERSION + "\r\n" + "hue-bridgeid: %s\r\n" + "ST: uuid:" + HueConstants.UUID_PREFIX
|
+ HueConstants.API_VERSION + "\r\n" + "hue-bridgeid: %s\r\n" + "ST: uuid:" + HueConstants.UUID_PREFIX
|
||||||
+ "%s\r\n" + "USN: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n\r\n";
|
+ "%s\r\n" + "USN: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n\r\n";
|
||||||
private String responseTemplate3 = "HTTP/1.1 200 OK\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n"
|
private String responseTemplate3 = "HTTP/1.1 200 OK\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n"
|
||||||
+ "EXT:\r\n" + "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/"
|
+ "EXT:\r\n" + "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/"
|
||||||
+ HueConstants.API_VERSION + "\r\n" + "hue-bridgeid: %s\r\n" + "ST: urn:schemas-upnp-org:device:basic:1\r\n"
|
+ HueConstants.API_VERSION + "\r\n" + "hue-bridgeid: %s\r\n" + "ST: upnp:rootdevice\r\n" + "USN: uuid:"
|
||||||
+ "USN: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n\r\n";
|
+ HueConstants.UUID_PREFIX + "%s::upnp:rootdevice\r\n\r\n";
|
||||||
|
|
||||||
|
|
||||||
|
/* These notify templates are for the advanced upnp option */
|
||||||
private String notifyTemplate1 = "NOTIFY * HTTP/1.1\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n"
|
private String notifyTemplate1 = "NOTIFY * HTTP/1.1\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n"
|
||||||
+ "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/"
|
+ "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/"
|
||||||
+ HueConstants.API_VERSION + "\r\n" + "NTS: ssdp:alive\r\n" + "hue-bridgeid: %s\r\n" + "NT: uuid:"
|
+ HueConstants.API_VERSION + "\r\n" + "NTS: ssdp:alive\r\n" + "hue-bridgeid: %s\r\n" + "NT: uuid:"
|
||||||
+ HueConstants.UUID_PREFIX + "%s\r\n" + "USN: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n\r\n";
|
+ HueConstants.UUID_PREFIX + "%s\r\n" + "USN: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n\r\n";
|
||||||
|
|
||||||
private String notifyTemplate2 = "NOTIFY * HTTP/1.1\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n"
|
private String notifyTemplate2 = "NOTIFY * HTTP/1.1\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n"
|
||||||
+ "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/"
|
+ "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/"
|
||||||
+ HueConstants.API_VERSION + "\r\n" + "NTS: ssdp:alive\r\n" + "hue-bridgeid: %s\r\n"
|
+ HueConstants.API_VERSION + "\r\n" + "NTS: ssdp:alive\r\n" + "hue-bridgeid: %s\r\n"
|
||||||
+ "NT: upnp:rootdevice\r\n" + "USN: uuid:" + HueConstants.UUID_PREFIX + "%s::upnp:rootdevice\r\n\r\n";
|
+ "NT: upnp:rootdevice\r\n" + "USN: uuid:" + HueConstants.UUID_PREFIX + "%s::upnp:rootdevice\r\n\r\n";
|
||||||
|
|
||||||
private String notifyTemplate3 = "NOTIFY * HTTP/1.1\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n"
|
private String notifyTemplate3 = "NOTIFY * HTTP/1.1\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n"
|
||||||
+ "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/"
|
+ "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/"
|
||||||
+ HueConstants.API_VERSION + "\r\n" + "NTS: ssdp:alive\r\n" + "hue-bridgeid: %s\r\n"
|
+ HueConstants.API_VERSION + "\r\n" + "NTS: ssdp:alive\r\n" + "hue-bridgeid: %s\r\n"
|
||||||
+ "NT: urn:schemas-upnp-org:device:basic:1\r\n" + "USN: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n\r\n";
|
+ "NT: urn:schemas-upnp-org:device:basic:1\r\n" + "USN: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n\r\n";
|
||||||
|
|
||||||
@@ -75,6 +82,7 @@ public class UpnpListener {
|
|||||||
upnpConfigIP = theSettings.getBridgeSettingsDescriptor().getUpnpConfigAddress();
|
upnpConfigIP = theSettings.getBridgeSettingsDescriptor().getUpnpConfigAddress();
|
||||||
// strict = theSettings.isUpnpStrict();
|
// strict = theSettings.isUpnpStrict();
|
||||||
upnpOriginal = theSettings.getBridgeSettingsDescriptor().isUpnporiginal();
|
upnpOriginal = theSettings.getBridgeSettingsDescriptor().isUpnporiginal();
|
||||||
|
upnpAdvanced = theSettings.getBridgeSettingsDescriptor().isUpnpadvanced();
|
||||||
traceupnp = theSettings.getBridgeSettingsDescriptor().isTraceupnp();
|
traceupnp = theSettings.getBridgeSettingsDescriptor().isTraceupnp();
|
||||||
useUpnpIface = theSettings.getBridgeSettingsDescriptor().isUseupnpiface();
|
useUpnpIface = theSettings.getBridgeSettingsDescriptor().isUseupnpiface();
|
||||||
theUpnpSendDelay = theSettings.getBridgeSettingsDescriptor().getUpnpsenddelay();
|
theUpnpSendDelay = theSettings.getBridgeSettingsDescriptor().getUpnpsenddelay();
|
||||||
@@ -192,10 +200,13 @@ public class UpnpListener {
|
|||||||
log.info("UPNP Discovery Listener running and ready....");
|
log.info("UPNP Discovery Listener running and ready....");
|
||||||
boolean loopControl = true;
|
boolean loopControl = true;
|
||||||
boolean error = false;
|
boolean error = false;
|
||||||
try {
|
|
||||||
upnpMulticastSocket.setSoTimeout((int) Configuration.UPNP_NOTIFY_TIMEOUT);
|
if(upnpAdvanced) {
|
||||||
} catch (SocketException e1) {
|
try {
|
||||||
log.warn("Could not sent soTimeout on multi-cast socket");
|
upnpMulticastSocket.setSoTimeout((int) Configuration.UPNP_NOTIFY_TIMEOUT);
|
||||||
|
} catch (SocketException e1) {
|
||||||
|
log.warn("Could not sent soTimeout on multi-cast socket");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Instant current, previous;
|
// Instant current, previous;
|
||||||
// previous = Instant.now();
|
// previous = Instant.now();
|
||||||
@@ -326,37 +337,39 @@ public class UpnpListener {
|
|||||||
+ " with discovery responseTemplate1 is <<<" + discoveryResponse + ">>>");
|
+ " with discovery responseTemplate1 is <<<" + discoveryResponse + ">>>");
|
||||||
sendUDPResponse(discoveryResponse.getBytes(), requester, sourcePort);
|
sendUDPResponse(discoveryResponse.getBytes(), requester, sourcePort);
|
||||||
|
|
||||||
try {
|
if(upnpAdvanced) {
|
||||||
Thread.sleep(theUpnpSendDelay);
|
try {
|
||||||
} catch (InterruptedException e) {
|
Thread.sleep(theUpnpSendDelay);
|
||||||
// noop
|
} catch (InterruptedException e) {
|
||||||
}
|
// noop
|
||||||
discoveryResponse = String.format(responseTemplate2, Configuration.UPNP_MULTICAST_ADDRESS,
|
}
|
||||||
Configuration.UPNP_DISCOVERY_PORT, httpType, httpLocationAddress, httpServerPort, bridgeId,
|
discoveryResponse = String.format(responseTemplate2, Configuration.UPNP_MULTICAST_ADDRESS,
|
||||||
bridgeSNUUID, bridgeSNUUID);
|
Configuration.UPNP_DISCOVERY_PORT, httpType, httpLocationAddress, httpServerPort, bridgeId,
|
||||||
if (traceupnp) {
|
bridgeSNUUID, bridgeSNUUID);
|
||||||
log.info("Traceupnp: send upnp discovery template 2 with response address: " + httpLocationAddress + ":"
|
if (traceupnp) {
|
||||||
+ httpServerPort + " to address: " + requester.getHostAddress() + ":" + sourcePort);
|
log.info("Traceupnp: send upnp discovery template 2 with response address: " + httpLocationAddress + ":"
|
||||||
}
|
+ httpServerPort + " to address: " + requester.getHostAddress() + ":" + sourcePort);
|
||||||
log.debug("sendUpnpResponse to address: " + requester.getHostAddress() + ":" + sourcePort
|
}
|
||||||
+ " discovery responseTemplate2 is <<<" + discoveryResponse + ">>>");
|
log.debug("sendUpnpResponse to address: " + requester.getHostAddress() + ":" + sourcePort
|
||||||
sendUDPResponse(discoveryResponse.getBytes(), requester, sourcePort);
|
+ " discovery responseTemplate2 is <<<" + discoveryResponse + ">>>");
|
||||||
|
sendUDPResponse(discoveryResponse.getBytes(), requester, sourcePort);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Thread.sleep(theUpnpSendDelay);
|
Thread.sleep(theUpnpSendDelay);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
// noop
|
// noop
|
||||||
|
}
|
||||||
|
discoveryResponse = String.format(responseTemplate3, Configuration.UPNP_MULTICAST_ADDRESS,
|
||||||
|
Configuration.UPNP_DISCOVERY_PORT, httpType, httpLocationAddress, httpServerPort, bridgeId,
|
||||||
|
bridgeSNUUID);
|
||||||
|
if (traceupnp) {
|
||||||
|
log.info("Traceupnp: send upnp discovery template 3 with response address: " + httpLocationAddress + ":"
|
||||||
|
+ httpServerPort + " to address: " + requester.getHostAddress() + ":" + sourcePort);
|
||||||
|
}
|
||||||
|
log.debug("sendUpnpResponse to address: " + requester.getHostAddress() + ":" + sourcePort
|
||||||
|
+ " discovery responseTemplate3 is <<<" + discoveryResponse + ">>>");
|
||||||
|
sendUDPResponse(discoveryResponse.getBytes(), requester, sourcePort);
|
||||||
}
|
}
|
||||||
discoveryResponse = String.format(responseTemplate3, Configuration.UPNP_MULTICAST_ADDRESS,
|
|
||||||
Configuration.UPNP_DISCOVERY_PORT, httpType, httpLocationAddress, httpServerPort, bridgeId,
|
|
||||||
bridgeSNUUID);
|
|
||||||
if (traceupnp) {
|
|
||||||
log.info("Traceupnp: send upnp discovery template 3 with response address: " + httpLocationAddress + ":"
|
|
||||||
+ httpServerPort + " to address: " + requester.getHostAddress() + ":" + sourcePort);
|
|
||||||
}
|
|
||||||
log.debug("sendUpnpResponse to address: " + requester.getHostAddress() + ":" + sourcePort
|
|
||||||
+ " discovery responseTemplate3 is <<<" + discoveryResponse + ">>>");
|
|
||||||
sendUDPResponse(discoveryResponse.getBytes(), requester, sourcePort);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendUDPResponse(byte[] udpMessage, InetAddress requester, int sourcePort) throws IOException {
|
private void sendUDPResponse(byte[] udpMessage, InetAddress requester, int sourcePort) throws IOException {
|
||||||
|
|||||||
@@ -55,10 +55,12 @@ public class UpnpSettingsResource {
|
|||||||
+ "<depth>24</depth>\n"
|
+ "<depth>24</depth>\n"
|
||||||
+ "<url>hue_logo_3.png</url>\n"
|
+ "<url>hue_logo_3.png</url>\n"
|
||||||
+ "</icon>\n"
|
+ "</icon>\n"
|
||||||
+ "</iconList>\n"
|
+ "</iconList>\n";
|
||||||
+ "</device>\n"
|
|
||||||
+ "</root>\n";
|
|
||||||
|
|
||||||
|
private String hueTemplate_end = "</device>\n"
|
||||||
|
+ "</root>\n";
|
||||||
|
|
||||||
|
/* not utilizing this section any more
|
||||||
private String hueTemplate_mid_orig = "<serviceList>\n"
|
private String hueTemplate_mid_orig = "<serviceList>\n"
|
||||||
+ "<service>\n"
|
+ "<service>\n"
|
||||||
+ "<serviceType>(null)</serviceType>\n"
|
+ "<serviceType>(null)</serviceType>\n"
|
||||||
@@ -68,7 +70,7 @@ public class UpnpSettingsResource {
|
|||||||
+ "<SCPDURL>(null)</SCPDURL>\n"
|
+ "<SCPDURL>(null)</SCPDURL>\n"
|
||||||
+ "</service>\n"
|
+ "</service>\n"
|
||||||
+ "</serviceList>\n";
|
+ "</serviceList>\n";
|
||||||
|
*/
|
||||||
|
|
||||||
public UpnpSettingsResource(BridgeSettings theBridgeSettings) {
|
public UpnpSettingsResource(BridgeSettings theBridgeSettings) {
|
||||||
super();
|
super();
|
||||||
@@ -92,16 +94,24 @@ public class UpnpSettingsResource {
|
|||||||
String hueTemplate = null;
|
String hueTemplate = null;
|
||||||
if(theSettings.isUpnporiginal()) {
|
if(theSettings.isUpnporiginal()) {
|
||||||
httpLocationAddr = theSettings.getUpnpConfigAddress();
|
httpLocationAddr = theSettings.getUpnpConfigAddress();
|
||||||
hueTemplate = hueTemplate_pre + hueTemplate_mid_orig + hueTemplate_post;
|
hueTemplate = hueTemplate_pre + hueTemplate_end;
|
||||||
} else {
|
} else if(!theSettings.isUpnpadvanced()) {
|
||||||
|
|
||||||
if(theSettings.isUseupnpiface()) {
|
if(theSettings.isUseupnpiface()) {
|
||||||
httpLocationAddr = theSettings.getUpnpConfigAddress();
|
httpLocationAddr = theSettings.getUpnpConfigAddress();
|
||||||
} else {
|
} else {
|
||||||
log.debug("Get Outbound address for ip:" + request.ip() + " and port:" + request.port());
|
log.debug("Get Outbound address for ip:" + request.ip() + " and port:" + request.port());
|
||||||
httpLocationAddr = AddressUtil.getOutboundAddress(request.ip(), request.port()).getHostAddress();
|
httpLocationAddr = AddressUtil.getOutboundAddress(request.ip(), request.port()).getHostAddress();
|
||||||
}
|
}
|
||||||
hueTemplate = hueTemplate_pre + hueTemplate_post;
|
hueTemplate = hueTemplate_pre + hueTemplate_end;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if(theSettings.isUseupnpiface()) {
|
||||||
|
httpLocationAddr = theSettings.getUpnpConfigAddress();
|
||||||
|
} else {
|
||||||
|
log.debug("Get Outbound address for ip:" + request.ip() + " and port:" + request.port());
|
||||||
|
httpLocationAddr = AddressUtil.getOutboundAddress(request.ip(), request.port()).getHostAddress();
|
||||||
|
}
|
||||||
|
hueTemplate = hueTemplate_pre + hueTemplate_post + hueTemplate_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
String bridgeIdMac = HuePublicConfig.createConfig("temp", httpLocationAddr, HueConstants.HUB_VERSION, theSettings.getHubmac()).getSNUUIDFromMac();
|
String bridgeIdMac = HuePublicConfig.createConfig("temp", httpLocationAddr, HueConstants.HUB_VERSION, theSettings.getHubmac()).getSNUUIDFromMac();
|
||||||
|
|||||||
@@ -824,6 +824,11 @@
|
|||||||
<td><input type="checkbox" ng-model="bridge.settings.upnporiginal" ng-true-value=true
|
<td><input type="checkbox" ng-model="bridge.settings.upnporiginal" ng-true-value=true
|
||||||
ng-false-value=false> {{bridge.settings.upnporiginal}}</td>
|
ng-false-value=false> {{bridge.settings.upnporiginal}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>UPNP Advanced (use multiple responses and notifies)</td>
|
||||||
|
<td><input type="checkbox" ng-model="bridge.settings.upnpadvanced" ng-true-value=true
|
||||||
|
ng-false-value=false> {{bridge.settings.upnpadvanced}}</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Trace UPNP Calls</td>
|
<td>Trace UPNP Calls</td>
|
||||||
<td><input type="checkbox" ng-model="bridge.settings.traceupnp" ng-true-value=true
|
<td><input type="checkbox" ng-model="bridge.settings.traceupnp" ng-true-value=true
|
||||||
|
|||||||
Reference in New Issue
Block a user