Skip to content

Commit 430331a

Browse files
committed
adding a few new features to the packet format
* can now specify the TTL programmatically * can now define the device type urn (up to 64 chars) ** still defaults to `Basic:1` * can now set the serial number using a `uint32_t`, formatted as %08X
1 parent dba2f92 commit 430331a

File tree

2 files changed

+40
-18
lines changed

2 files changed

+40
-18
lines changed

libraries/ESP8266SSDP/ESP8266SSDP.cpp

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,26 +56,26 @@ 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:
@@ -331,7 +334,7 @@ void SSDPClass::_update(){
331334
else if(strcmp(buffer, "ST") == 0) header = ST;
332335
else if(strcmp(buffer, "MX") == 0) header = MX;
333336
}
334-
337+
335338
if(cursor < SSDP_BUFFER_SIZE - 1){ buffer[cursor++] = c; buffer[cursor] = '\0'; }
336339
}
337340
break;
@@ -365,6 +368,10 @@ void SSDPClass::setHTTPPort(uint16_t port){
365368
_port = port;
366369
}
367370

371+
void SSDPClass::setDeviceType(const char *deviceType){
372+
strlcpy(_deviceType, deviceType, sizeof(_deviceType));
373+
}
374+
368375
void SSDPClass::setName(const char *name){
369376
strlcpy(_friendlyName, name, sizeof(_friendlyName));
370377
}
@@ -377,6 +384,10 @@ void SSDPClass::setSerialNumber(const char *serialNumber){
377384
strlcpy(_serialNumber, serialNumber, sizeof(_serialNumber));
378385
}
379386

387+
void SSDPClass::setSerialNumber(const uint32_t serialNumber){
388+
snprintf(_serialNumber, sizeof(uint32_t), "%08X", serialNumber);
389+
}
390+
380391
void SSDPClass::setModelName(const char *name){
381392
strlcpy(_modelName, name, sizeof(_modelName));
382393
}
@@ -397,6 +408,10 @@ void SSDPClass::setManufacturerURL(const char *url){
397408
strlcpy(_manufacturerURL, url, sizeof(_manufacturerURL));
398409
}
399410

411+
void SSDPClass::setTTL(const uint8_t ttl){
412+
_ttl = ttl;
413+
}
414+
400415
void SSDPClass::_onTimerStatic(SSDPClass* self) {
401416
self->_update();
402417
}

libraries/ESP8266SSDP/ESP8266SSDP.h

Lines changed: 8 additions & 1 deletion
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)