@@ -51,31 +51,31 @@ extern "C" {
5151#define SSDP_METHOD_SIZE 10
5252#define SSDP_URI_SIZE 2
5353#define SSDP_BUFFER_SIZE 64
54- #define SSDP_MULTICAST_TTL 1
54+ #define SSDP_MULTICAST_TTL 2
5555static const IPAddress SSDP_MULTICAST_ADDR (239 , 255 , 255 , 250 );
5656
5757
5858
59- static const char * _ssdp_response_template =
59+ static const char * _ssdp_response_template =
6060 " HTTP/1.1 200 OK\r\n "
6161 " EXT:\r\n "
6262 " ST: upnp:rootdevice\r\n " ;
6363
64- static const char * _ssdp_notify_template =
64+ static const char * _ssdp_notify_template =
6565 " NOTIFY * HTTP/1.1\r\n "
6666 " HOST: 239.255.255.250:1900\r\n "
6767 " NT: upnp:rootdevice\r\n "
6868 " NTS: ssdp:alive\r\n " ;
6969
70- static const char * _ssdp_packet_template =
70+ static const char * _ssdp_packet_template =
7171 " %s" // _ssdp_response_template / _ssdp_notify_template
7272 " CACHE-CONTROL: max-age=%u\r\n " // SSDP_INTERVAL
7373 " SERVER: Arduino/1.0 UPNP/1.1 %s/%s\r\n " // _modelName, _modelNumber
7474 " USN: uuid:%s\r\n " // _uuid
7575 " LOCATION: http://%u.%u.%u.%u:%u/%s\r\n " // WiFi.localIP(), _port, _schemaURL
7676 " \r\n " ;
7777
78- static const char * _ssdp_schema_template =
78+ static const char * _ssdp_schema_template =
7979 " HTTP/1.1 200 OK\r\n "
8080 " Content-Type: text/xml\r\n "
8181 " Connection: close\r\n "
@@ -89,7 +89,7 @@ static const char* _ssdp_schema_template =
8989 " </specVersion>"
9090 " <URLBase>http://%u.%u.%u.%u:%u/</URLBase>" // WiFi.localIP(), _port
9191 " <device>"
92- " <deviceType>urn:schemas-upnp-org:device:Basic:1 </deviceType>"
92+ " <deviceType>%s </deviceType>"
9393 " <friendlyName>%s</friendlyName>"
9494 " <presentationURL>%s</presentationURL>"
9595 " <serialNumber>%s</serialNumber>"
@@ -128,6 +128,7 @@ SSDPClass::SSDPClass() :
128128_server(0 ),
129129_timer(new SSDPTimer),
130130_port(80 ),
131+ _ttl(SSDP_MULTICAST_TTL),
131132_respondToPort(0 ),
132133_pending(false ),
133134_delay(0 ),
@@ -136,6 +137,7 @@ _notify_time(0)
136137{
137138 _uuid[0 ] = ' \0 ' ;
138139 _modelNumber[0 ] = ' \0 ' ;
140+ sprintf (_deviceType, " urn:schemas-upnp-org:device:Basic:1" );
139141 _friendlyName[0 ] = ' \0 ' ;
140142 _presentationURL[0 ] = ' \0 ' ;
141143 _serialNumber[0 ] = ' \0 ' ;
@@ -152,11 +154,11 @@ SSDPClass::~SSDPClass(){
152154
153155bool SSDPClass::begin (){
154156 _pending = false ;
155-
157+
156158 uint32_t chipId = ESP.getChipId ();
157159 sprintf (_uuid, " 38323636-4558-4dda-9188-cda0e6%02x%02x%02x" ,
158160 (uint16_t ) ((chipId >> 16 ) & 0xff ),
159- (uint16_t ) ((chipId >> 8 ) & 0xff ),
161+ (uint16_t ) ((chipId >> 8 ) & 0xff ),
160162 (uint16_t ) chipId & 0xff );
161163
162164#ifdef DEBUG_SSDP
@@ -179,13 +181,13 @@ bool SSDPClass::begin(){
179181 DEBUGV (" SSDP failed to join igmp group" );
180182 return false ;
181183 }
182-
184+
183185 if (!_server->listen (*IP_ADDR_ANY, SSDP_PORT)) {
184186 return false ;
185187 }
186188
187189 _server->setMulticastInterface (ifaddr);
188- _server->setMulticastTTL (SSDP_MULTICAST_TTL );
190+ _server->setMulticastTTL (_ttl );
189191 _server->onRx (std::bind (&SSDPClass::_update, this ));
190192 if (!_server->connect (multicast_addr, SSDP_PORT)) {
191193 return false ;
@@ -199,8 +201,8 @@ bool SSDPClass::begin(){
199201void SSDPClass::_send (ssdp_method_t method){
200202 char buffer[1460 ];
201203 uint32_t ip = WiFi.localIP ();
202-
203- int len = snprintf (buffer, sizeof (buffer),
204+
205+ int len = snprintf (buffer, sizeof (buffer),
204206 _ssdp_packet_template,
205207 (method == NONE)?_ssdp_response_template:_ssdp_notify_template,
206208 SSDP_INTERVAL,
@@ -239,6 +241,7 @@ void SSDPClass::schema(WiFiClient client){
239241 uint32_t ip = WiFi.localIP ();
240242 client.printf (_ssdp_schema_template,
241243 IP2STR (&ip), _port,
244+ _deviceType,
242245 _friendlyName,
243246 _presentationURL,
244247 _serialNumber,
@@ -268,7 +271,7 @@ void SSDPClass::_update(){
268271 uint8_t cr = 0 ;
269272
270273 char buffer[SSDP_BUFFER_SIZE] = {0 };
271-
274+
272275 while (_server->getSize () > 0 ){
273276 char c = _server->read ();
274277
@@ -279,18 +282,18 @@ void SSDPClass::_update(){
279282 if (c == ' ' ){
280283 if (strcmp (buffer, " M-SEARCH" ) == 0 ) method = SEARCH;
281284 else if (strcmp (buffer, " NOTIFY" ) == 0 ) method = NOTIFY;
282-
285+
283286 if (method == NONE) state = ABORT;
284- else state = URI;
287+ else state = URI;
285288 cursor = 0 ;
286289
287290 } else if (cursor < SSDP_METHOD_SIZE - 1 ){ buffer[cursor++] = c; buffer[cursor] = ' \0 ' ; }
288291 break ;
289292 case URI:
290293 if (c == ' ' ){
291294 if (strcmp (buffer, " *" )) state = ABORT;
292- else state = PROTO;
293- cursor = 0 ;
295+ else state = PROTO;
296+ cursor = 0 ;
294297 } else if (cursor < SSDP_URI_SIZE - 1 ){ buffer[cursor++] = c; buffer[cursor] = ' \0 ' ; }
295298 break ;
296299 case PROTO:
@@ -304,8 +307,8 @@ void SSDPClass::_update(){
304307 case VALUE:
305308 if (cr == 2 ){
306309 switch (header){
307- case START:
308- break ;
310+ case START:
311+ break ;
309312 case MAN:
310313#ifdef DEBUG_SSDP
311314 DEBUG_SSDP.printf (" MAN: %s\n " , (char *)buffer);
@@ -318,6 +321,12 @@ void SSDPClass::_update(){
318321 DEBUG_SSDP.printf (" REJECT: %s\n " , (char *)buffer);
319322#endif
320323 }
324+ // if the search type matches our type, we should respond instead of ABORT
325+ if (strcmp (buffer, _deviceType) == 0 ){
326+ _pending = true ;
327+ _process_time = millis ();
328+ state = KEY;
329+ }
321330 break ;
322331 case MX:
323332 _delay = random (0 , atoi (buffer)) * 1000L ;
@@ -331,7 +340,7 @@ void SSDPClass::_update(){
331340 else if (strcmp (buffer, " ST" ) == 0 ) header = ST;
332341 else if (strcmp (buffer, " MX" ) == 0 ) header = MX;
333342 }
334-
343+
335344 if (cursor < SSDP_BUFFER_SIZE - 1 ){ buffer[cursor++] = c; buffer[cursor] = ' \0 ' ; }
336345 }
337346 break ;
@@ -365,6 +374,10 @@ void SSDPClass::setHTTPPort(uint16_t port){
365374 _port = port;
366375}
367376
377+ void SSDPClass::setDeviceType (const char *deviceType){
378+ strlcpy (_deviceType, deviceType, sizeof (_deviceType));
379+ }
380+
368381void SSDPClass::setName (const char *name){
369382 strlcpy (_friendlyName, name, sizeof (_friendlyName));
370383}
@@ -377,6 +390,10 @@ void SSDPClass::setSerialNumber(const char *serialNumber){
377390 strlcpy (_serialNumber, serialNumber, sizeof (_serialNumber));
378391}
379392
393+ void SSDPClass::setSerialNumber (const uint32_t serialNumber){
394+ snprintf (_serialNumber, sizeof (uint32_t )*2 +1 , " %08X" , serialNumber);
395+ }
396+
380397void SSDPClass::setModelName (const char *name){
381398 strlcpy (_modelName, name, sizeof (_modelName));
382399}
@@ -397,6 +414,10 @@ void SSDPClass::setManufacturerURL(const char *url){
397414 strlcpy (_manufacturerURL, url, sizeof (_manufacturerURL));
398415}
399416
417+ void SSDPClass::setTTL (const uint8_t ttl){
418+ _ttl = ttl;
419+ }
420+
400421void SSDPClass::_onTimerStatic (SSDPClass* self) {
401422 self->_update ();
402423}
0 commit comments