esp8266 / Arduino

ESP8266 core for Arduino
GNU Lesser General Public License v2.1
15.88k stars 13.35k forks source link

ESP8266SSDP Search Terms for response do not include all valid responses #4216

Open CZEMacLeod opened 6 years ago

CZEMacLeod commented 6 years ago

Basic Infos

Hardware

Hardware: ESP-07 Core Version: 2.4.0

Description

In the ESP8266SSDP library the update method checks the search term (ST) header before deciding whether to respond. It appears to reject searches for ssdp:all and only respond if the deviceType matches. This does not gel with the documentation I have read at e.g. How a UPnP Search works My understanding is it should respond to ssdp:all, deviceType, uuid and upnp:rootdevice

void SSDPClass::_update()case VALUE:

case ST:
                // if the search type matches all, root, our type, or our id, we should respond instead of ABORT
                if(strcmp(buffer, "ssdp:all") || strcmp(buffer, "upnp:rootdevice") || strcasecmp(buffer, _deviceType) == 0 || strcasecmp(buffer, _uuid) == 0) {
                    _pending = true;
                    _process_time = millis();
                    state = KEY;
                }
                break;

If my understanding of this function is wrong, can you explain why and if the above is 'correct' should I submit a PR?

Pablo2048 commented 6 years ago

Hi CZEMacLeod, just a small correction: if(strcmp_P(buffer,PSTR( "ssdp:all")) == 0 || strcmp_P(buffer, PSTR("upnp:rootdevice")) == 0 || strcasecmp(buffer, _deviceType) == 0 || strcasecmp(buffer, _uuid) == 0) try to put all constant strings into PROGMEM to save RAM...

CZEMacLeod commented 6 years ago

@Pablo2048 Good catch - interesting to note that is missed in the existing code

                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){
                  _pending = true;
                  _process_time = millis();
                  state = KEY;
                }
                break;

Also I changed #define SSDP_UUID_SIZE 42 SSDPClass::begin() sprintf(_uuid, "uuid:38323636-4558-4dda-9188-cda0e6%02x%02x%02x" _ssdp_packet_template "USN: %s\r\n" // _uuid and _ssdp_schema_template "<UDN>%s</UDN>" to match up.

devyte commented 6 years ago

@CZEMacLeod please make a PR with your proposal. I have to take a look at SSDP at some point anyways, probably for 2.6.0.