Skip to content

Commit fe55854

Browse files
committed
Merge pull request #1399 from wyattearp/master
Custom Device Type, Appropriate Responses, Custom TTL, and uint32_t Serial Number
2 parents 4710220 + e34ded1 commit fe55854

File tree

2 files changed

+49
-21
lines changed

2 files changed

+49
-21
lines changed

libraries/ESP8266SSDP/ESP8266SSDP.cpp

+41-20
Original file line numberDiff line numberDiff line change
@@ -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
5555
static 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

153155
bool 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(){
199201
void 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+
368381
void 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+
380397
void 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+
400421
void SSDPClass::_onTimerStatic(SSDPClass* self) {
401422
self->_update();
402423
}

libraries/ESP8266SSDP/ESP8266SSDP.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class UdpContext;
3737

3838
#define SSDP_UUID_SIZE 37
3939
#define SSDP_SCHEMA_URL_SIZE 64
40+
#define SSDP_DEVICE_TYPE_SIZE 64
4041
#define SSDP_FRIENDLY_NAME_SIZE 64
4142
#define SSDP_SERIAL_NUMBER_SIZE 32
4243
#define SSDP_PRESENTATION_URL_SIZE 128
@@ -64,6 +65,8 @@ class SSDPClass{
6465

6566
void schema(WiFiClient client);
6667

68+
void setDeviceType(const String& deviceType) { setDeviceType(deviceType.c_str()); }
69+
void setDeviceType(const char *deviceType);
6770
void setName(const String& name) { setName(name.c_str()); }
6871
void setName(const char *name);
6972
void setURL(const String& url) { setURL(url.c_str()); }
@@ -72,6 +75,7 @@ class SSDPClass{
7275
void setSchemaURL(const char *url);
7376
void setSerialNumber(const String& serialNumber) { setSerialNumber(serialNumber.c_str()); }
7477
void setSerialNumber(const char *serialNumber);
78+
void setSerialNumber(const uint32_t serialNumber);
7579
void setModelName(const String& name) { setModelName(name.c_str()); }
7680
void setModelName(const char *name);
7781
void setModelNumber(const String& num) { setModelNumber(num.c_str()); }
@@ -83,6 +87,7 @@ class SSDPClass{
8387
void setManufacturerURL(const String& url) { setManufacturerURL(url.c_str()); }
8488
void setManufacturerURL(const char *url);
8589
void setHTTPPort(uint16_t port);
90+
void setTTL(uint8_t ttl);
8691

8792
protected:
8893
void _send(ssdp_method_t method);
@@ -93,6 +98,7 @@ class SSDPClass{
9398
UdpContext* _server;
9499
SSDPTimer* _timer;
95100
uint16_t _port;
101+
uint8_t _ttl;
96102

97103
IPAddress _respondToAddr;
98104
uint16_t _respondToPort;
@@ -101,9 +107,10 @@ class SSDPClass{
101107
unsigned short _delay;
102108
unsigned long _process_time;
103109
unsigned long _notify_time;
104-
110+
105111
char _schemaURL[SSDP_SCHEMA_URL_SIZE];
106112
char _uuid[SSDP_UUID_SIZE];
113+
char _deviceType[SSDP_DEVICE_TYPE_SIZE];
107114
char _friendlyName[SSDP_FRIENDLY_NAME_SIZE];
108115
char _serialNumber[SSDP_SERIAL_NUMBER_SIZE];
109116
char _presentationURL[SSDP_PRESENTATION_URL_SIZE];

0 commit comments

Comments
 (0)