@@ -51,31 +51,31 @@ extern "C" {
51
51
#define SSDP_METHOD_SIZE 10
52
52
#define SSDP_URI_SIZE 2
53
53
#define SSDP_BUFFER_SIZE 64
54
- #define SSDP_MULTICAST_TTL 1
54
+ #define SSDP_MULTICAST_TTL 2
55
55
static const IPAddress SSDP_MULTICAST_ADDR (239 , 255 , 255 , 250 );
56
56
57
57
58
58
59
- static const char * _ssdp_response_template =
59
+ static const char * _ssdp_response_template =
60
60
" HTTP/1.1 200 OK\r\n "
61
61
" EXT:\r\n "
62
62
" ST: upnp:rootdevice\r\n " ;
63
63
64
- static const char * _ssdp_notify_template =
64
+ static const char * _ssdp_notify_template =
65
65
" NOTIFY * HTTP/1.1\r\n "
66
66
" HOST: 239.255.255.250:1900\r\n "
67
67
" NT: upnp:rootdevice\r\n "
68
68
" NTS: ssdp:alive\r\n " ;
69
69
70
- static const char * _ssdp_packet_template =
70
+ static const char * _ssdp_packet_template =
71
71
" %s" // _ssdp_response_template / _ssdp_notify_template
72
72
" CACHE-CONTROL: max-age=%u\r\n " // SSDP_INTERVAL
73
73
" SERVER: Arduino/1.0 UPNP/1.1 %s/%s\r\n " // _modelName, _modelNumber
74
74
" USN: uuid:%s\r\n " // _uuid
75
75
" LOCATION: http://%u.%u.%u.%u:%u/%s\r\n " // WiFi.localIP(), _port, _schemaURL
76
76
" \r\n " ;
77
77
78
- static const char * _ssdp_schema_template =
78
+ static const char * _ssdp_schema_template =
79
79
" HTTP/1.1 200 OK\r\n "
80
80
" Content-Type: text/xml\r\n "
81
81
" Connection: close\r\n "
@@ -89,7 +89,7 @@ static const char* _ssdp_schema_template =
89
89
" </specVersion>"
90
90
" <URLBase>http://%u.%u.%u.%u:%u/</URLBase>" // WiFi.localIP(), _port
91
91
" <device>"
92
- " <deviceType>urn:schemas-upnp-org:device:Basic:1 </deviceType>"
92
+ " <deviceType>%s </deviceType>"
93
93
" <friendlyName>%s</friendlyName>"
94
94
" <presentationURL>%s</presentationURL>"
95
95
" <serialNumber>%s</serialNumber>"
@@ -128,6 +128,7 @@ SSDPClass::SSDPClass() :
128
128
_server(0 ),
129
129
_timer(new SSDPTimer),
130
130
_port(80 ),
131
+ _ttl(SSDP_MULTICAST_TTL),
131
132
_respondToPort(0 ),
132
133
_pending(false ),
133
134
_delay(0 ),
@@ -136,6 +137,7 @@ _notify_time(0)
136
137
{
137
138
_uuid[0 ] = ' \0 ' ;
138
139
_modelNumber[0 ] = ' \0 ' ;
140
+ sprintf (_deviceType, " urn:schemas-upnp-org:device:Basic:1" );
139
141
_friendlyName[0 ] = ' \0 ' ;
140
142
_presentationURL[0 ] = ' \0 ' ;
141
143
_serialNumber[0 ] = ' \0 ' ;
@@ -152,11 +154,11 @@ SSDPClass::~SSDPClass(){
152
154
153
155
bool SSDPClass::begin (){
154
156
_pending = false ;
155
-
157
+
156
158
uint32_t chipId = ESP.getChipId ();
157
159
sprintf (_uuid, " 38323636-4558-4dda-9188-cda0e6%02x%02x%02x" ,
158
160
(uint16_t ) ((chipId >> 16 ) & 0xff ),
159
- (uint16_t ) ((chipId >> 8 ) & 0xff ),
161
+ (uint16_t ) ((chipId >> 8 ) & 0xff ),
160
162
(uint16_t ) chipId & 0xff );
161
163
162
164
#ifdef DEBUG_SSDP
@@ -179,13 +181,13 @@ bool SSDPClass::begin(){
179
181
DEBUGV (" SSDP failed to join igmp group" );
180
182
return false ;
181
183
}
182
-
184
+
183
185
if (!_server->listen (*IP_ADDR_ANY, SSDP_PORT)) {
184
186
return false ;
185
187
}
186
188
187
189
_server->setMulticastInterface (ifaddr);
188
- _server->setMulticastTTL (SSDP_MULTICAST_TTL );
190
+ _server->setMulticastTTL (_ttl );
189
191
_server->onRx (std::bind (&SSDPClass::_update, this ));
190
192
if (!_server->connect (multicast_addr, SSDP_PORT)) {
191
193
return false ;
@@ -199,8 +201,8 @@ bool SSDPClass::begin(){
199
201
void SSDPClass::_send (ssdp_method_t method){
200
202
char buffer[1460 ];
201
203
uint32_t ip = WiFi.localIP ();
202
-
203
- int len = snprintf (buffer, sizeof (buffer),
204
+
205
+ int len = snprintf (buffer, sizeof (buffer),
204
206
_ssdp_packet_template,
205
207
(method == NONE)?_ssdp_response_template:_ssdp_notify_template,
206
208
SSDP_INTERVAL,
@@ -239,6 +241,7 @@ void SSDPClass::schema(WiFiClient client){
239
241
uint32_t ip = WiFi.localIP ();
240
242
client.printf (_ssdp_schema_template,
241
243
IP2STR (&ip), _port,
244
+ _deviceType,
242
245
_friendlyName,
243
246
_presentationURL,
244
247
_serialNumber,
@@ -268,7 +271,7 @@ void SSDPClass::_update(){
268
271
uint8_t cr = 0 ;
269
272
270
273
char buffer[SSDP_BUFFER_SIZE] = {0 };
271
-
274
+
272
275
while (_server->getSize () > 0 ){
273
276
char c = _server->read ();
274
277
@@ -279,18 +282,18 @@ void SSDPClass::_update(){
279
282
if (c == ' ' ){
280
283
if (strcmp (buffer, " M-SEARCH" ) == 0 ) method = SEARCH;
281
284
else if (strcmp (buffer, " NOTIFY" ) == 0 ) method = NOTIFY;
282
-
285
+
283
286
if (method == NONE) state = ABORT;
284
- else state = URI;
287
+ else state = URI;
285
288
cursor = 0 ;
286
289
287
290
} else if (cursor < SSDP_METHOD_SIZE - 1 ){ buffer[cursor++] = c; buffer[cursor] = ' \0 ' ; }
288
291
break ;
289
292
case URI:
290
293
if (c == ' ' ){
291
294
if (strcmp (buffer, " *" )) state = ABORT;
292
- else state = PROTO;
293
- cursor = 0 ;
295
+ else state = PROTO;
296
+ cursor = 0 ;
294
297
} else if (cursor < SSDP_URI_SIZE - 1 ){ buffer[cursor++] = c; buffer[cursor] = ' \0 ' ; }
295
298
break ;
296
299
case PROTO:
@@ -304,8 +307,8 @@ void SSDPClass::_update(){
304
307
case VALUE:
305
308
if (cr == 2 ){
306
309
switch (header){
307
- case START:
308
- break ;
310
+ case START:
311
+ break ;
309
312
case MAN:
310
313
#ifdef DEBUG_SSDP
311
314
DEBUG_SSDP.printf (" MAN: %s\n " , (char *)buffer);
@@ -318,6 +321,12 @@ void SSDPClass::_update(){
318
321
DEBUG_SSDP.printf (" REJECT: %s\n " , (char *)buffer);
319
322
#endif
320
323
}
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
+ }
321
330
break ;
322
331
case MX:
323
332
_delay = random (0 , atoi (buffer)) * 1000L ;
@@ -331,7 +340,7 @@ void SSDPClass::_update(){
331
340
else if (strcmp (buffer, " ST" ) == 0 ) header = ST;
332
341
else if (strcmp (buffer, " MX" ) == 0 ) header = MX;
333
342
}
334
-
343
+
335
344
if (cursor < SSDP_BUFFER_SIZE - 1 ){ buffer[cursor++] = c; buffer[cursor] = ' \0 ' ; }
336
345
}
337
346
break ;
@@ -365,6 +374,10 @@ void SSDPClass::setHTTPPort(uint16_t port){
365
374
_port = port;
366
375
}
367
376
377
+ void SSDPClass::setDeviceType (const char *deviceType){
378
+ strlcpy (_deviceType, deviceType, sizeof (_deviceType));
379
+ }
380
+
368
381
void SSDPClass::setName (const char *name){
369
382
strlcpy (_friendlyName, name, sizeof (_friendlyName));
370
383
}
@@ -377,6 +390,10 @@ void SSDPClass::setSerialNumber(const char *serialNumber){
377
390
strlcpy (_serialNumber, serialNumber, sizeof (_serialNumber));
378
391
}
379
392
393
+ void SSDPClass::setSerialNumber (const uint32_t serialNumber){
394
+ snprintf (_serialNumber, sizeof (uint32_t )*2 +1 , " %08X" , serialNumber);
395
+ }
396
+
380
397
void SSDPClass::setModelName (const char *name){
381
398
strlcpy (_modelName, name, sizeof (_modelName));
382
399
}
@@ -397,6 +414,10 @@ void SSDPClass::setManufacturerURL(const char *url){
397
414
strlcpy (_manufacturerURL, url, sizeof (_manufacturerURL));
398
415
}
399
416
417
+ void SSDPClass::setTTL (const uint8_t ttl){
418
+ _ttl = ttl;
419
+ }
420
+
400
421
void SSDPClass::_onTimerStatic (SSDPClass* self) {
401
422
self->_update ();
402
423
}
0 commit comments