From 5852151447559ca15256b61264940202dda6fc50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laercio=20Mendon=C3=A7a?= Date: Sun, 29 Jul 2018 13:18:56 -0300 Subject: [PATCH 1/3] Include SetUUID for SSDP Inclusion of the SetUUID Method for Custom UUID --- libraries/ESP8266SSDP/ESP8266SSDP.cpp | 263 ++++++++++++++------------ libraries/ESP8266SSDP/ESP8266SSDP.h | 11 +- libraries/ESP8266SSDP/keywords.txt | 2 + 3 files changed, 145 insertions(+), 131 deletions(-) diff --git a/libraries/ESP8266SSDP/ESP8266SSDP.cpp b/libraries/ESP8266SSDP/ESP8266SSDP.cpp index 2c9739709c..de583f7efe 100644 --- a/libraries/ESP8266SSDP/ESP8266SSDP.cpp +++ b/libraries/ESP8266SSDP/ESP8266SSDP.cpp @@ -34,9 +34,9 @@ License (MIT license): #include "debug.h" extern "C" { - #include "osapi.h" - #include "ets_sys.h" - #include "user_interface.h" +#include "osapi.h" +#include "ets_sys.h" +#include "user_interface.h" } #include "lwip/opt.h" @@ -45,8 +45,7 @@ extern "C" { #include "lwip/igmp.h" #include "lwip/mem.h" #include "include/UdpContext.h" - -// #define DEBUG_SSDP Serial +//#define DEBUG_SSDP Serial #define SSDP_INTERVAL 1200 #define SSDP_PORT 1900 @@ -56,8 +55,6 @@ extern "C" { #define SSDP_MULTICAST_TTL 2 static const IPAddress SSDP_MULTICAST_ADDR(239, 255, 255, 250); - - static const char _ssdp_response_template[] PROGMEM = "HTTP/1.1 200 OK\r\n" "EXT:\r\n"; @@ -84,39 +81,23 @@ static const char _ssdp_schema_template[] PROGMEM = "\r\n" "" "" - "" - "1" - "0" - "" - "http://%u.%u.%u.%u:%u/" // WiFi.localIP(), _port - "" - "%s" - "%s" - "%s" - "%s" - "%s" - "%s" - "%s" - "%s" - "%s" - "uuid:%s" - "" -// "" -// "" -// "image/png" -// "48" -// "48" -// "24" -// "icon48.png" -// "" -// "" -// "image/png" -// "120" -// "120" -// "24" -// "icon120.png" -// "" -// "" + "" + "1" + "0" + "" + "http://%u.%u.%u.%u:%u/" // WiFi.localIP(), _port + "" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "%s" + "UUID: %s" + "" "\r\n" "\r\n"; @@ -126,15 +107,15 @@ struct SSDPTimer { }; SSDPClass::SSDPClass() : -_server(0), -_timer(new SSDPTimer), -_port(80), -_ttl(SSDP_MULTICAST_TTL), -_respondToPort(0), -_pending(false), -_delay(0), -_process_time(0), -_notify_time(0) + _server(0), + _timer(new SSDPTimer), + _port(80), + _ttl(SSDP_MULTICAST_TTL), + _respondToPort(0), + _pending(false), + _delay(0), + _process_time(0), + _notify_time(0) { _uuid[0] = '\0'; _modelNumber[0] = '\0'; @@ -149,19 +130,20 @@ _notify_time(0) sprintf(_schemaURL, "ssdp/schema.xml"); } -SSDPClass::~SSDPClass(){ +SSDPClass::~SSDPClass() { delete _timer; } -bool SSDPClass::begin(){ +bool SSDPClass::begin() { _pending = false; - - uint32_t chipId = ESP.getChipId(); - sprintf(_uuid, "38323636-4558-4dda-9188-cda0e6%02x%02x%02x", + if (strcmp(_uuid,"") == 0) { + 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 & 0xff ); - + (uint16_t) ((chipId >> 8) & 0xff), + (uint16_t) chipId & 0xff ); + } + #ifdef DEBUG_SSDP DEBUG_SSDP.printf("SSDP UUID: %s\n", (char *)_uuid); #endif @@ -199,29 +181,30 @@ bool SSDPClass::begin(){ return true; } -void SSDPClass::_send(ssdp_method_t method){ +void SSDPClass::_send(ssdp_method_t method) { char buffer[1460]; IPAddress ip = WiFi.localIP(); - char valueBuffer[strlen_P(_ssdp_notify_template)+1]; - strcpy_P(valueBuffer, (method == NONE)?_ssdp_response_template:_ssdp_notify_template); + char valueBuffer[strlen_P(_ssdp_notify_template) + 1]; + strcpy_P(valueBuffer, (method == NONE) ? _ssdp_response_template : _ssdp_notify_template); int len = snprintf_P(buffer, sizeof(buffer), - _ssdp_packet_template, - valueBuffer, - SSDP_INTERVAL, - _modelName, _modelNumber, - _uuid, - (method == NONE)?"ST":"NT", - _deviceType, - ip[0], ip[1], ip[2], ip[3], _port, _schemaURL - ); + _ssdp_packet_template, + valueBuffer, + SSDP_INTERVAL, + _modelName, + _modelNumber, + _uuid, + (method == NONE) ? "ST" : "NT", + _deviceType, + ip[0], ip[1], ip[2], ip[3], _port, _schemaURL + ); _server->append(buffer, len); ip_addr_t remoteAddr; uint16_t remotePort; - if(method == NONE) { + if (method == NONE) { remoteAddr.addr = _respondToAddr; remotePort = _respondToPort; #ifdef DEBUG_SSDP @@ -243,27 +226,27 @@ void SSDPClass::_send(ssdp_method_t method){ _server->send(&remoteAddr, remotePort); } -void SSDPClass::schema(WiFiClient client){ +void SSDPClass::schema(WiFiClient client) { IPAddress ip = WiFi.localIP(); - char buffer[strlen_P(_ssdp_schema_template)+1]; + char buffer[strlen_P(_ssdp_schema_template) + 1]; strcpy_P(buffer, _ssdp_schema_template); client.printf(buffer, - ip[0], ip[1], ip[2], ip[3], _port, - _deviceType, - _friendlyName, - _presentationURL, - _serialNumber, - _modelName, - _modelNumber, - _modelURL, - _manufacturer, - _manufacturerURL, - _uuid - ); + ip[0], ip[1], ip[2], ip[3], _port, + _deviceType, + _friendlyName, + _presentationURL, + _serialNumber, + _modelName, + _modelNumber, + _modelURL, + _manufacturer, + _manufacturerURL, + _uuid + ); } -void SSDPClass::_update(){ - if(!_pending && _server->next()) { +void SSDPClass::_update() { + if (!_pending && _server->next()) { ssdp_method_t method = NONE; _respondToAddr = _server->getRemoteAddress(); @@ -280,40 +263,58 @@ void SSDPClass::_update(){ char buffer[SSDP_BUFFER_SIZE] = {0}; - while(_server->getSize() > 0){ + while (_server->getSize() > 0) { char c = _server->read(); (c == '\r' || c == '\n') ? cr++ : cr = 0; - switch(state){ + switch (state) { case METHOD: - if(c == ' '){ - if(strcmp(buffer, "M-SEARCH") == 0) method = SEARCH; + if (c == ' ') { + if (strcmp(buffer, "M-SEARCH") == 0) method = SEARCH; - if(method == NONE) state = ABORT; + if (method == NONE) state = ABORT; else state = URI; cursor = 0; - } else if(cursor < SSDP_METHOD_SIZE - 1){ buffer[cursor++] = c; buffer[cursor] = '\0'; } + } else if (cursor < SSDP_METHOD_SIZE - 1) { + buffer[cursor++] = c; + buffer[cursor] = '\0'; + } break; case URI: - if(c == ' '){ - if(strcmp(buffer, "*")) state = ABORT; + if (c == ' ') { + if (strcmp(buffer, "*")) state = ABORT; else state = PROTO; cursor = 0; - } else if(cursor < SSDP_URI_SIZE - 1){ buffer[cursor++] = c; buffer[cursor] = '\0'; } + } else if (cursor < SSDP_URI_SIZE - 1) { + buffer[cursor++] = c; + buffer[cursor] = '\0'; + } break; case PROTO: - if(cr == 2){ state = KEY; cursor = 0; } + if (cr == 2) { + state = KEY; + cursor = 0; + } break; case KEY: - if(cr == 4){ _pending = true; _process_time = millis(); } - else if(c == ' '){ cursor = 0; state = VALUE; } - else if(c != '\r' && c != '\n' && c != ':' && cursor < SSDP_BUFFER_SIZE - 1){ buffer[cursor++] = c; buffer[cursor] = '\0'; } + if (cr == 4) { + _pending = true; + _process_time = millis(); + } + else if (c == ' ') { + cursor = 0; + state = VALUE; + } + else if (c != '\r' && c != '\n' && c != ':' && cursor < SSDP_BUFFER_SIZE - 1) { + buffer[cursor++] = c; + buffer[cursor] = '\0'; + } break; case VALUE: - if(cr == 2){ - switch(header){ + if (cr == 2) { + switch (header) { case START: break; case MAN: @@ -322,14 +323,14 @@ void SSDPClass::_update(){ #endif break; case ST: - if(strcmp(buffer, "ssdp:all")){ + if (strcmp(buffer, "ssdp:all")) { state = ABORT; #ifdef DEBUG_SSDP DEBUG_SSDP.printf("REJECT: %s\n", (char *)buffer); #endif } // if the search type matches our type, we should respond instead of ABORT - if(strcasecmp(buffer, _deviceType) == 0){ + if (strcasecmp(buffer, _deviceType) == 0) { _pending = true; _process_time = millis(); state = KEY; @@ -340,15 +341,22 @@ void SSDPClass::_update(){ break; } - if(state != ABORT){ state = KEY; header = START; cursor = 0; } - } else if(c != '\r' && c != '\n'){ - if(header == START){ - if(strncmp(buffer, "MA", 2) == 0) header = MAN; - else if(strcmp(buffer, "ST") == 0) header = ST; - else if(strcmp(buffer, "MX") == 0) header = MX; + if (state != ABORT) { + state = KEY; + header = START; + cursor = 0; + } + } else if (c != '\r' && c != '\n') { + if (header == START) { + if (strncmp(buffer, "MA", 2) == 0) header = MAN; + 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'; } + if (cursor < SSDP_BUFFER_SIZE - 1) { + buffer[cursor++] = c; + buffer[cursor] = '\0'; + } } break; case ABORT: @@ -358,7 +366,7 @@ void SSDPClass::_update(){ } } - if(_pending && (millis() - _process_time) > _delay){ + if (_pending && (millis() - _process_time) > _delay) { _pending = false; _delay = 0; _send(NONE); } else if(_notify_time == 0 || (millis() - _notify_time) > (SSDP_INTERVAL * 1000L)){ @@ -373,55 +381,60 @@ void SSDPClass::_update(){ } -void SSDPClass::setSchemaURL(const char *url){ +void SSDPClass::setSchemaURL(const char *url) { strlcpy(_schemaURL, url, sizeof(_schemaURL)); } -void SSDPClass::setHTTPPort(uint16_t port){ +void SSDPClass::setHTTPPort(uint16_t port) { _port = port; } -void SSDPClass::setDeviceType(const char *deviceType){ +void SSDPClass::setDeviceType(const char *deviceType) { strlcpy(_deviceType, deviceType, sizeof(_deviceType)); } -void SSDPClass::setName(const char *name){ +void SSDPClass::setUUID(const char *uuid) { + strlcpy(_uuid, uuid, sizeof(_uuid)); +} + +void SSDPClass::setName(const char *name) { strlcpy(_friendlyName, name, sizeof(_friendlyName)); } -void SSDPClass::setURL(const char *url){ +void SSDPClass::setURL(const char *url) { strlcpy(_presentationURL, url, sizeof(_presentationURL)); } -void SSDPClass::setSerialNumber(const char *serialNumber){ +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::setSerialNumber(const uint32_t serialNumber) { + snprintf(_serialNumber, sizeof(uint32_t) * 2 + 1, "%08X", serialNumber); } -void SSDPClass::setModelName(const char *name){ +void SSDPClass::setModelName(const char *name) { strlcpy(_modelName, name, sizeof(_modelName)); } -void SSDPClass::setModelNumber(const char *num){ +void SSDPClass::setModelNumber(const char *num) { strlcpy(_modelNumber, num, sizeof(_modelNumber)); } -void SSDPClass::setModelURL(const char *url){ +void SSDPClass::setModelURL(const char *url) { strlcpy(_modelURL, url, sizeof(_modelURL)); } -void SSDPClass::setManufacturer(const char *name){ +void SSDPClass::setManufacturer(const char *name) { strlcpy(_manufacturer, name, sizeof(_manufacturer)); } -void SSDPClass::setManufacturerURL(const char *url){ +void SSDPClass::setManufacturerURL(const char *url) { strlcpy(_manufacturerURL, url, sizeof(_manufacturerURL)); } -void SSDPClass::setTTL(const uint8_t ttl){ + +void SSDPClass::setTTL(const uint8_t ttl) { _ttl = ttl; } diff --git a/libraries/ESP8266SSDP/ESP8266SSDP.h b/libraries/ESP8266SSDP/ESP8266SSDP.h index 74d8bbacf4..9c1411f239 100644 --- a/libraries/ESP8266SSDP/ESP8266SSDP.h +++ b/libraries/ESP8266SSDP/ESP8266SSDP.h @@ -39,7 +39,7 @@ class UdpContext; #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_SERIAL_NUMBER_SIZE 37 #define SSDP_PRESENTATION_URL_SIZE 128 #define SSDP_MODEL_NAME_SIZE 64 #define SSDP_MODEL_URL_SIZE 128 @@ -60,20 +60,19 @@ class SSDPClass{ public: SSDPClass(); ~SSDPClass(); - bool begin(); - 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 setUUID(const String& uuid) { setUUID(uuid.c_str()); } + void setUUID(const char *uuid); + void setName(const String& name) { setName(name.c_str()); } void setName(const char *name); void setURL(const String& url) { setURL(url.c_str()); } void setURL(const char *url); void setSchemaURL(const String& url) { setSchemaURL(url.c_str()); } void setSchemaURL(const char *url); - void setSerialNumber(const String& serialNumber) { setSerialNumber(serialNumber.c_str()); } + 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()); } diff --git a/libraries/ESP8266SSDP/keywords.txt b/libraries/ESP8266SSDP/keywords.txt index 241d341454..0517c93b13 100644 --- a/libraries/ESP8266SSDP/keywords.txt +++ b/libraries/ESP8266SSDP/keywords.txt @@ -15,6 +15,7 @@ SSDP KEYWORD1 begin KEYWORD2 schema KEYWORD2 +setUUID KEYWORD2 setName KEYWORD2 setURL KEYWORD2 setHTTPPort KEYWORD2 @@ -30,6 +31,7 @@ setManufacturerURL KEYWORD2 # Constants (LITERAL1) ####################################### SSDP_INTERVAL LITERAL1 +SSDP_UUID LITERAL1 SSDP_PORT LITERAL1 SSDP_METHOD_SIZE LITERAL1 SSDP_URI_SIZE LITERAL1 From e9ea054a778dbfd6c1f3658dc2390b4f280bd198 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laercio=20Mendon=C3=A7a?= Date: Sun, 29 Jul 2018 23:27:37 -0300 Subject: [PATCH 2/3] Ajusts PR --- libraries/ESP8266SSDP/ESP8266SSDP.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/ESP8266SSDP/ESP8266SSDP.h b/libraries/ESP8266SSDP/ESP8266SSDP.h index 9c1411f239..990199e27d 100644 --- a/libraries/ESP8266SSDP/ESP8266SSDP.h +++ b/libraries/ESP8266SSDP/ESP8266SSDP.h @@ -64,8 +64,11 @@ class SSDPClass{ void schema(WiFiClient client); void setDeviceType(const String& deviceType) { setDeviceType(deviceType.c_str()); } void setDeviceType(const char *deviceType); + + /*To define a custom UUID, you must call the method before begin(). Otherwise an automatic UUID based on CHIPID will be generated.*/ void setUUID(const String& uuid) { setUUID(uuid.c_str()); } void setUUID(const char *uuid); + void setName(const String& name) { setName(name.c_str()); } void setName(const char *name); void setURL(const String& url) { setURL(url.c_str()); } From 6f35401f23c18c4e723c37ba5b13ff6f23dbf1c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laercio=20Mendon=C3=A7a?= Date: Mon, 30 Jul 2018 01:12:40 -0300 Subject: [PATCH 3/3] Include IconList Object on XML --- libraries/ESP8266SSDP/ESP8266SSDP.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/libraries/ESP8266SSDP/ESP8266SSDP.cpp b/libraries/ESP8266SSDP/ESP8266SSDP.cpp index de583f7efe..66c2ac9489 100644 --- a/libraries/ESP8266SSDP/ESP8266SSDP.cpp +++ b/libraries/ESP8266SSDP/ESP8266SSDP.cpp @@ -98,6 +98,22 @@ static const char _ssdp_schema_template[] PROGMEM = "%s" "UUID: %s" "" + //"" + //"" + //"image/png" + //"48" + //"48" + //"24" + //"icon48.png" + //"" + //"" + //"image/png" + //"120" + //"120" + //"24" + //"icon120.png" + //"" + //"" "\r\n" "\r\n";