SSDP Server - working version provides SSDP based network discovery, and with a companion web server, may provide other functionalities.

Dependents:   X10Svr SSDP_Server

Files at this revision

API Documentation at this revision

Comitter:
WiredHome
Date:
Tue Jul 10 03:08:15 2018 +0000
Parent:
1:def15d0b2fae
Child:
3:85fa421bbcc2
Commit message:
Improve SSDP query detection from the header

Changed in this revision

SSDP.cpp Show annotated file Show diff for this revision Revisions of this file
SSDP.h Show annotated file Show diff for this revision Revisions of this file
--- 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);
 }
--- a/SSDP.h	Tue Jul 03 00:46:34 2018 +0000
+++ b/SSDP.h	Tue Jul 10 03:08:15 2018 +0000
@@ -133,5 +133,5 @@
     
     SSDP_Config_T _config;       ///< the configuration
 
-    Thread * pThr;
+    //Thread * pThr;
 };
\ No newline at end of file