diff --git a/libraries/ESP8266SSDP/ESP8266SSDP.cpp b/libraries/ESP8266SSDP/ESP8266SSDP.cpp
index ee1a78530..afae3e9fe 100644
--- a/libraries/ESP8266SSDP/ESP8266SSDP.cpp
+++ b/libraries/ESP8266SSDP/ESP8266SSDP.cpp
@@ -51,23 +51,23 @@ extern "C" {
#define SSDP_METHOD_SIZE 10
#define SSDP_URI_SIZE 2
#define SSDP_BUFFER_SIZE 64
-#define SSDP_MULTICAST_TTL 1
+#define SSDP_MULTICAST_TTL 2
static const IPAddress SSDP_MULTICAST_ADDR(239, 255, 255, 250);
-static const char* _ssdp_response_template =
+static const char* _ssdp_response_template =
"HTTP/1.1 200 OK\r\n"
"EXT:\r\n"
"ST: upnp:rootdevice\r\n";
-static const char* _ssdp_notify_template =
+static const char* _ssdp_notify_template =
"NOTIFY * HTTP/1.1\r\n"
"HOST: 239.255.255.250:1900\r\n"
"NT: upnp:rootdevice\r\n"
"NTS: ssdp:alive\r\n";
-static const char* _ssdp_packet_template =
+static const char* _ssdp_packet_template =
"%s" // _ssdp_response_template / _ssdp_notify_template
"CACHE-CONTROL: max-age=%u\r\n" // SSDP_INTERVAL
"SERVER: Arduino/1.0 UPNP/1.1 %s/%s\r\n" // _modelName, _modelNumber
@@ -75,7 +75,7 @@ static const char* _ssdp_packet_template =
"LOCATION: http://%u.%u.%u.%u:%u/%s\r\n" // WiFi.localIP(), _port, _schemaURL
"\r\n";
-static const char* _ssdp_schema_template =
+static const char* _ssdp_schema_template =
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/xml\r\n"
"Connection: close\r\n"
@@ -89,7 +89,7 @@ static const char* _ssdp_schema_template =
""
"http://%u.%u.%u.%u:%u/" // WiFi.localIP(), _port
""
- "urn:schemas-upnp-org:device:Basic:1"
+ "%s"
"%s"
"%s"
"%s"
@@ -128,6 +128,7 @@ SSDPClass::SSDPClass() :
_server(0),
_timer(new SSDPTimer),
_port(80),
+_ttl(SSDP_MULTICAST_TTL),
_respondToPort(0),
_pending(false),
_delay(0),
@@ -136,6 +137,7 @@ _notify_time(0)
{
_uuid[0] = '\0';
_modelNumber[0] = '\0';
+ sprintf(_deviceType, "urn:schemas-upnp-org:device:Basic:1");
_friendlyName[0] = '\0';
_presentationURL[0] = '\0';
_serialNumber[0] = '\0';
@@ -152,11 +154,11 @@ SSDPClass::~SSDPClass(){
bool SSDPClass::begin(){
_pending = false;
-
+
uint32_t chipId = ESP.getChipId();
sprintf(_uuid, "38323636-4558-4dda-9188-cda0e6%02x%02x%02x",
(uint16_t) ((chipId >> 16) & 0xff),
- (uint16_t) ((chipId >> 8) & 0xff),
+ (uint16_t) ((chipId >> 8) & 0xff),
(uint16_t) chipId & 0xff );
#ifdef DEBUG_SSDP
@@ -179,13 +181,13 @@ bool SSDPClass::begin(){
DEBUGV("SSDP failed to join igmp group");
return false;
}
-
+
if (!_server->listen(*IP_ADDR_ANY, SSDP_PORT)) {
return false;
}
_server->setMulticastInterface(ifaddr);
- _server->setMulticastTTL(SSDP_MULTICAST_TTL);
+ _server->setMulticastTTL(_ttl);
_server->onRx(std::bind(&SSDPClass::_update, this));
if (!_server->connect(multicast_addr, SSDP_PORT)) {
return false;
@@ -199,8 +201,8 @@ bool SSDPClass::begin(){
void SSDPClass::_send(ssdp_method_t method){
char buffer[1460];
uint32_t ip = WiFi.localIP();
-
- int len = snprintf(buffer, sizeof(buffer),
+
+ int len = snprintf(buffer, sizeof(buffer),
_ssdp_packet_template,
(method == NONE)?_ssdp_response_template:_ssdp_notify_template,
SSDP_INTERVAL,
@@ -239,6 +241,7 @@ void SSDPClass::schema(WiFiClient client){
uint32_t ip = WiFi.localIP();
client.printf(_ssdp_schema_template,
IP2STR(&ip), _port,
+ _deviceType,
_friendlyName,
_presentationURL,
_serialNumber,
@@ -268,7 +271,7 @@ void SSDPClass::_update(){
uint8_t cr = 0;
char buffer[SSDP_BUFFER_SIZE] = {0};
-
+
while(_server->getSize() > 0){
char c = _server->read();
@@ -279,9 +282,9 @@ void SSDPClass::_update(){
if(c == ' '){
if(strcmp(buffer, "M-SEARCH") == 0) method = SEARCH;
else if(strcmp(buffer, "NOTIFY") == 0) method = NOTIFY;
-
+
if(method == NONE) state = ABORT;
- else state = URI;
+ else state = URI;
cursor = 0;
} else if(cursor < SSDP_METHOD_SIZE - 1){ buffer[cursor++] = c; buffer[cursor] = '\0'; }
@@ -289,8 +292,8 @@ void SSDPClass::_update(){
case URI:
if(c == ' '){
if(strcmp(buffer, "*")) state = ABORT;
- else state = PROTO;
- cursor = 0;
+ else state = PROTO;
+ cursor = 0;
} else if(cursor < SSDP_URI_SIZE - 1){ buffer[cursor++] = c; buffer[cursor] = '\0'; }
break;
case PROTO:
@@ -304,8 +307,8 @@ void SSDPClass::_update(){
case VALUE:
if(cr == 2){
switch(header){
- case START:
- break;
+ case START:
+ break;
case MAN:
#ifdef DEBUG_SSDP
DEBUG_SSDP.printf("MAN: %s\n", (char *)buffer);
@@ -318,6 +321,12 @@ void SSDPClass::_update(){
DEBUG_SSDP.printf("REJECT: %s\n", (char *)buffer);
#endif
}
+ // if the search type matches our type, we should respond instead of ABORT
+ if(strcmp(buffer, _deviceType) == 0){
+ _pending = true;
+ _process_time = millis();
+ state = KEY;
+ }
break;
case MX:
_delay = random(0, atoi(buffer)) * 1000L;
@@ -331,7 +340,7 @@ void SSDPClass::_update(){
else if(strcmp(buffer, "ST") == 0) header = ST;
else if(strcmp(buffer, "MX") == 0) header = MX;
}
-
+
if(cursor < SSDP_BUFFER_SIZE - 1){ buffer[cursor++] = c; buffer[cursor] = '\0'; }
}
break;
@@ -365,6 +374,10 @@ void SSDPClass::setHTTPPort(uint16_t port){
_port = port;
}
+void SSDPClass::setDeviceType(const char *deviceType){
+ strlcpy(_deviceType, deviceType, sizeof(_deviceType));
+}
+
void SSDPClass::setName(const char *name){
strlcpy(_friendlyName, name, sizeof(_friendlyName));
}
@@ -377,6 +390,10 @@ void SSDPClass::setSerialNumber(const char *serialNumber){
strlcpy(_serialNumber, serialNumber, sizeof(_serialNumber));
}
+void SSDPClass::setSerialNumber(const uint32_t serialNumber){
+ snprintf(_serialNumber, sizeof(uint32_t)*2+1, "%08X", serialNumber);
+}
+
void SSDPClass::setModelName(const char *name){
strlcpy(_modelName, name, sizeof(_modelName));
}
@@ -397,6 +414,10 @@ void SSDPClass::setManufacturerURL(const char *url){
strlcpy(_manufacturerURL, url, sizeof(_manufacturerURL));
}
+void SSDPClass::setTTL(const uint8_t ttl){
+ _ttl = ttl;
+}
+
void SSDPClass::_onTimerStatic(SSDPClass* self) {
self->_update();
}
diff --git a/libraries/ESP8266SSDP/ESP8266SSDP.h b/libraries/ESP8266SSDP/ESP8266SSDP.h
index d931a8df4..22ba088b9 100644
--- a/libraries/ESP8266SSDP/ESP8266SSDP.h
+++ b/libraries/ESP8266SSDP/ESP8266SSDP.h
@@ -37,6 +37,7 @@ class UdpContext;
#define SSDP_UUID_SIZE 37
#define SSDP_SCHEMA_URL_SIZE 64
+#define SSDP_DEVICE_TYPE_SIZE 64
#define SSDP_FRIENDLY_NAME_SIZE 64
#define SSDP_SERIAL_NUMBER_SIZE 32
#define SSDP_PRESENTATION_URL_SIZE 128
@@ -64,6 +65,8 @@ class SSDPClass{
void schema(WiFiClient client);
+ void setDeviceType(const String& deviceType) { setDeviceType(deviceType.c_str()); }
+ void setDeviceType(const char *deviceType);
void setName(const String& name) { setName(name.c_str()); }
void setName(const char *name);
void setURL(const String& url) { setURL(url.c_str()); }
@@ -72,6 +75,7 @@ class SSDPClass{
void setSchemaURL(const char *url);
void setSerialNumber(const String& serialNumber) { setSerialNumber(serialNumber.c_str()); }
void setSerialNumber(const char *serialNumber);
+ void setSerialNumber(const uint32_t serialNumber);
void setModelName(const String& name) { setModelName(name.c_str()); }
void setModelName(const char *name);
void setModelNumber(const String& num) { setModelNumber(num.c_str()); }
@@ -83,6 +87,7 @@ class SSDPClass{
void setManufacturerURL(const String& url) { setManufacturerURL(url.c_str()); }
void setManufacturerURL(const char *url);
void setHTTPPort(uint16_t port);
+ void setTTL(uint8_t ttl);
protected:
void _send(ssdp_method_t method);
@@ -93,6 +98,7 @@ class SSDPClass{
UdpContext* _server;
SSDPTimer* _timer;
uint16_t _port;
+ uint8_t _ttl;
IPAddress _respondToAddr;
uint16_t _respondToPort;
@@ -101,9 +107,10 @@ class SSDPClass{
unsigned short _delay;
unsigned long _process_time;
unsigned long _notify_time;
-
+
char _schemaURL[SSDP_SCHEMA_URL_SIZE];
char _uuid[SSDP_UUID_SIZE];
+ char _deviceType[SSDP_DEVICE_TYPE_SIZE];
char _friendlyName[SSDP_FRIENDLY_NAME_SIZE];
char _serialNumber[SSDP_SERIAL_NUMBER_SIZE];
char _presentationURL[SSDP_PRESENTATION_URL_SIZE];