SSDP Server - working version provides SSDP based network discovery, and with a companion web server, may provide other functionalities.
Dependents: X10Svr SSDP_Server
Diff: SSDP.cpp
- Revision:
- 2:3d6d70556fca
- Parent:
- 1:def15d0b2fae
- Child:
- 3:85fa421bbcc2
--- a/SSDP.cpp Tue Jul 03 00:46:34 2018 +0000 +++ b/SSDP.cpp Tue Jul 10 03:08:15 2018 +0000 @@ -6,8 +6,9 @@ // #include "SSDP.h" #include "EthernetInterface.h" +#include "SW_String.h" -//#define DEBUG "SSDP" //Debug is disabled by default +#define DEBUG "SSDP" //Debug is disabled by default #include <cstdio> #if (defined(DEBUG) && !defined(TARGET_LPC11U24)) @@ -24,6 +25,7 @@ static const char* MCAST_GRP = "239.255.255.250"; static const int MCAST_PORT = 1900; +static Thread * pThr; // sprintf(buffer, SSDP_HTTP, "myIPString", myPort, "myIdentity", "myIdentity"); // Requires IP address as a string @@ -78,20 +80,30 @@ Endpoint client; char buffer[256]; while (true) { - INFO("Wait for packet..."); + //INFO("Wait for packet..."); int n = server.receiveFrom(client, buffer, sizeof(buffer)-1); buffer[n] = '\0'; if (n) { char * p = buffer; - volatile int delay = 1; + volatile int delay = 0; + uint8_t mask = 0x00; // fragments we found in the received packet + //INFO("SSDP\n%s", buffer); while (*p) { char * e = strstr(p, "\r\n"); if (e && (e - buffer) < n) { *e = '\0'; - if (strstr(p, "MX: ")) { + if (sw_stristr(p, "M-SEARCH * HTTP/1.1")) { + mask |= 0x01; // M-SEARCH * HTTP/1.1 + } else if (sw_stristr(p, "MAN:") && sw_stristr(p,"\"ssdp:discover\"")) { + mask |= 0x02; // MAN: "ssdp:discover" + } else if (sw_stristr(p, "MX:")) { + mask |= 0x04; // MX: \d delay = atoi(p + 3); - } else if (strstr(p, "HOST: ")) { + } else if (sw_stristr(p, "ST:") && sw_stristr(p, "upnp:rootdevice")) { + mask |= 0x08; + } else if (sw_stristr(p, "HOST: ")) { + mask |= 0x10; // HOST: 239.255.255.250:49152 char * pColon = strchr(p+6, ':'); if (pColon) { pColon = '\0'; @@ -101,13 +113,23 @@ } p++; } - char * out_buffer = (char *)malloc(strlen(SSDP_HTTP) + SSDP_HTTP_OVERHEAD); - if (out_buffer) { - sprintf(out_buffer, SSDP_HTTP, cfg->ipAddr, cfg->port, cfg->ident, cfg->ident); - // It would be polite to delay, but the recommendation is from 1 to 2 seconds - // Thread::wait(delay * 1000); - server.sendTo(client, out_buffer, strlen(out_buffer)); - free(out_buffer); + //INFO("*********** %02X", mask); + if ((mask & 0x1F) == 0x1F) { + char * out_buffer = (char *)malloc(strlen(SSDP_HTTP) + SSDP_HTTP_OVERHEAD); + + if (out_buffer) { + sprintf(out_buffer, SSDP_HTTP, cfg->ipAddr, cfg->port, cfg->ident, cfg->ident); + // It would be polite to delay, but the recommendation is from 1 to 2 seconds. + // Send the response twice, to improve reliability of node discovery + for (int i=0; i<2; i++) { + server.sendTo(client, out_buffer, strlen(out_buffer)); + //Thread::wait(150); + } + free(out_buffer); + INFO("SSDPListener: stack-used: %d, total: %d", pThr->max_stack(), pThr->stack_size()); + } else { + ERR("Can't get memory for response"); + } } } } @@ -215,5 +237,5 @@ } void SSDP::StartListener() { - pThr = new Thread(SSDPListener, (void *)&_config, osPriorityLow); + pThr = new Thread(SSDPListener, (void *)&_config, osPriorityLow, 768); }