An example demonstrating SSDP Discovery and a companion Web Server.

Dependencies:   mbed mbed-rtos Watchdog SW_HTTPServer SW_String EthernetInterface TimeInterface SSDP

This example program provides a framework -by- example.

It makes itself discoverable to the network using SSDP. From there, it is easy to access the embedded web server to interact with the embedded node.

The example, built on the LPC1768, provides interaction to turn the LEDs on and off via a web page that is discovered using the SSDP protocol.

It also picks up time via an NTP server.

Committer:
WiredHome
Date:
Tue Jul 03 02:10:23 2018 +0000
Revision:
0:de1dfa2ab813
Child:
1:016d4400254b
An example program demonstrating the SSDP-based discovery and a companion Web Server to interact with the mbed device. Scan the network (e.g. in Windows Explorer) to identify the node. Click to open its web page to interact with it.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WiredHome 0:de1dfa2ab813 1
WiredHome 0:de1dfa2ab813 2 #include "mbed.h"
WiredHome 0:de1dfa2ab813 3
WiredHome 0:de1dfa2ab813 4 #include "EthernetInterface.h"
WiredHome 0:de1dfa2ab813 5 #include "WebPages.h"
WiredHome 0:de1dfa2ab813 6
WiredHome 0:de1dfa2ab813 7 extern EthernetInterface eth;
WiredHome 0:de1dfa2ab813 8 extern const char * BUILD_DATE;
WiredHome 0:de1dfa2ab813 9 extern const char * PROG_NAME;
WiredHome 0:de1dfa2ab813 10 extern const char * My_Name;
WiredHome 0:de1dfa2ab813 11 extern const char * My_SerialNum;
WiredHome 0:de1dfa2ab813 12 const int Server_Port = 80;
WiredHome 0:de1dfa2ab813 13
WiredHome 0:de1dfa2ab813 14
WiredHome 0:de1dfa2ab813 15 // ##########################################
WiredHome 0:de1dfa2ab813 16 // This test version controls the LEDs
WiredHome 0:de1dfa2ab813 17 //
WiredHome 0:de1dfa2ab813 18 DigitalOut leds[4] = { LED1, LED2, LED3, LED4 };
WiredHome 0:de1dfa2ab813 19
WiredHome 0:de1dfa2ab813 20
WiredHome 0:de1dfa2ab813 21 static const char hdrTypeHTML_NoCache[] =
WiredHome 0:de1dfa2ab813 22 "Content-Type: text/html\r\n"
WiredHome 0:de1dfa2ab813 23 "Cache-Control: no-cache\r\n";
WiredHome 0:de1dfa2ab813 24
WiredHome 0:de1dfa2ab813 25
WiredHome 0:de1dfa2ab813 26 // sprintf(buf, ROOTPAGE, "NodeName", "NodeName", "BuildDate",
WiredHome 0:de1dfa2ab813 27 static const char * ROOTPAGE =
WiredHome 0:de1dfa2ab813 28 "<!DOCTYPE html>\r\n"
WiredHome 0:de1dfa2ab813 29 "<html><head><title>%s</title>\r\n"
WiredHome 0:de1dfa2ab813 30 "</head>\r\n"
WiredHome 0:de1dfa2ab813 31 "<body>\r\n"
WiredHome 0:de1dfa2ab813 32 "<h1>%s</h1>"
WiredHome 0:de1dfa2ab813 33 "This project demonstrates the Smartware web server and the Smartware SSDP discovery server.\n"
WiredHome 0:de1dfa2ab813 34 "You should be able to scan the network (e.g. in Windows Explorer) and find this device.\n"
WiredHome 0:de1dfa2ab813 35 "Then you can click on it to open this web page to interact with it.\n"
WiredHome 0:de1dfa2ab813 36 "<br/><br/>\n"
WiredHome 0:de1dfa2ab813 37 "<form method='get'>\n"
WiredHome 0:de1dfa2ab813 38 "<table>\n"
WiredHome 0:de1dfa2ab813 39 "<tr><td>Build</td><td>%s</td></tr>\n"
WiredHome 0:de1dfa2ab813 40 "<tr><td>Set LED</td>\n"
WiredHome 0:de1dfa2ab813 41 "<td><select name='LED'>\n"
WiredHome 0:de1dfa2ab813 42 " <option value='1'>1</option>\n"
WiredHome 0:de1dfa2ab813 43 " <option value='2'>2</option>\n"
WiredHome 0:de1dfa2ab813 44 " <option value='3'>3</option>\n"
WiredHome 0:de1dfa2ab813 45 " <option value='4'>4</option>\n"
WiredHome 0:de1dfa2ab813 46 " </select>\n"
WiredHome 0:de1dfa2ab813 47 " \n"
WiredHome 0:de1dfa2ab813 48 " <select name='CMD'>\n"
WiredHome 0:de1dfa2ab813 49 " <option value='0'>Off</option>\n"
WiredHome 0:de1dfa2ab813 50 " <option value='1'>On</option>\n"
WiredHome 0:de1dfa2ab813 51 " </select>\n"
WiredHome 0:de1dfa2ab813 52 "</td></tr>\n"
WiredHome 0:de1dfa2ab813 53 "<tr><td>&nbsp;</td><td><input type='submit' value='Apply'></td></tr>\n"
WiredHome 0:de1dfa2ab813 54 "</table>\n"
WiredHome 0:de1dfa2ab813 55 "</form>\n"
WiredHome 0:de1dfa2ab813 56 "</body>\n"
WiredHome 0:de1dfa2ab813 57 "</html>\n"
WiredHome 0:de1dfa2ab813 58 "";
WiredHome 0:de1dfa2ab813 59
WiredHome 0:de1dfa2ab813 60
WiredHome 0:de1dfa2ab813 61 // The /setup.xml file
WiredHome 0:de1dfa2ab813 62 //
WiredHome 0:de1dfa2ab813 63 // sprintf(buf, SETUP_TEMPLATE, "FriendlyName", "udn_hexstring", "serialNum", "ip.ad.dr", portNum);
WiredHome 0:de1dfa2ab813 64 static const char * SETUP_TEMPLATE =
WiredHome 0:de1dfa2ab813 65 "<?xml version=\"1.0\"?>\n"
WiredHome 0:de1dfa2ab813 66 "<root xmlns=\"urn:Belkin:device-1-0\">\n"
WiredHome 0:de1dfa2ab813 67 " <specVersion>\n"
WiredHome 0:de1dfa2ab813 68 " <major>1</major>\n"
WiredHome 0:de1dfa2ab813 69 " <minor>0</minor>\n"
WiredHome 0:de1dfa2ab813 70 " </specVersion>\n"
WiredHome 0:de1dfa2ab813 71 " <device>\n"
WiredHome 0:de1dfa2ab813 72 " <deviceType>urn:Belkin:device:controllee:1</deviceType>\n"
WiredHome 0:de1dfa2ab813 73 " <friendlyName>%s</friendlyName>\n"
WiredHome 0:de1dfa2ab813 74 " <manufacturer>Belkin International Inc.</manufacturer>\n" ///< must be "Belkin..." for Alexa discovery
WiredHome 0:de1dfa2ab813 75 " <manufacturerURL>http://www.smart-family.net</manufacturerURL>\n" ///<
WiredHome 0:de1dfa2ab813 76 " <modelDescription>Special thing</modelDescription>\n" ///<
WiredHome 0:de1dfa2ab813 77 " <modelName>Smart Node</modelName>\n" ///<
WiredHome 0:de1dfa2ab813 78 " <modelNumber>1.0.0</modelNumber>\n"
WiredHome 0:de1dfa2ab813 79 #if 0
WiredHome 0:de1dfa2ab813 80 " <modelURL>http://www.smart-family.net</modelURL>\n" ///< This causes it to fail to send completely
WiredHome 0:de1dfa2ab813 81 #endif
WiredHome 0:de1dfa2ab813 82 " <UDN>uuid:Socket-1_0-%s</UDN>\n"
WiredHome 0:de1dfa2ab813 83 " <serialNumber>%s</serialNumber>\n"
WiredHome 0:de1dfa2ab813 84 " <iconList>\n"
WiredHome 0:de1dfa2ab813 85 " <mimetype>jpg</mimetype>\n"
WiredHome 0:de1dfa2ab813 86 " <width>100</width>\n"
WiredHome 0:de1dfa2ab813 87 " <height>100</height>\n"
WiredHome 0:de1dfa2ab813 88 " <depth>100</depth>\n"
WiredHome 0:de1dfa2ab813 89 " <url>icon.jpg</url>\n"
WiredHome 0:de1dfa2ab813 90 " </iconList>\n"
WiredHome 0:de1dfa2ab813 91 " <presentationURL>http://%s:%d</presentationURL>\n"
WiredHome 0:de1dfa2ab813 92 #if 0
WiredHome 0:de1dfa2ab813 93 " <serviceList>\n"
WiredHome 0:de1dfa2ab813 94 " <service>\n"
WiredHome 0:de1dfa2ab813 95 " <serviceType>urn:Belkin:service:WiFiSetup:1</serviceType>\n"
WiredHome 0:de1dfa2ab813 96 " <serviceId>urn:Belkin:serviceId:WiFiSetup1</serviceId>\n"
WiredHome 0:de1dfa2ab813 97 " <controlURL>/upnp/control/WiFiSetup1</controlURL>\n"
WiredHome 0:de1dfa2ab813 98 " <eventSubURL>/upnp/event/WiFiSetup1</eventSubURL>\n"
WiredHome 0:de1dfa2ab813 99 " <SCPDURL>/setupservice.xml</SCPDURL>\n"
WiredHome 0:de1dfa2ab813 100 " </service>\n"
WiredHome 0:de1dfa2ab813 101 " <service>\n"
WiredHome 0:de1dfa2ab813 102 " <serviceType>urn:Belkin:service:timesync:1</serviceType>\n"
WiredHome 0:de1dfa2ab813 103 " <serviceId>urn:Belkin:serviceId:timesync1</serviceId>\n"
WiredHome 0:de1dfa2ab813 104 " <controlURL>/upnp/control/timesync1</controlURL>\n"
WiredHome 0:de1dfa2ab813 105 " <eventSubURL>/upnp/event/timesync1</eventSubURL>\n"
WiredHome 0:de1dfa2ab813 106 " <SCPDURL>/timesyncservice.xml</SCPDURL>\n"
WiredHome 0:de1dfa2ab813 107 " </service>\n"
WiredHome 0:de1dfa2ab813 108 " <service>\n"
WiredHome 0:de1dfa2ab813 109 " <serviceType>urn:Belkin:service:basicevent:1</serviceType>\n"
WiredHome 0:de1dfa2ab813 110 " <serviceId>urn:Belkin:serviceId:basicevent1</serviceId>\n"
WiredHome 0:de1dfa2ab813 111 " <controlURL>/upnp/control/basicevent1</controlURL>\n"
WiredHome 0:de1dfa2ab813 112 " <eventSubURL>/upnp/event/basicevent1</eventSubURL>\n"
WiredHome 0:de1dfa2ab813 113 " <SCPDURL>/eventservice.xml</SCPDURL>\n"
WiredHome 0:de1dfa2ab813 114 " </service>\n"
WiredHome 0:de1dfa2ab813 115 " <service>\n"
WiredHome 0:de1dfa2ab813 116 " <serviceType>urn:Belkin:service:firmwareupdate:1</serviceType>\n"
WiredHome 0:de1dfa2ab813 117 " <serviceId>urn:Belkin:serviceId:firmwareupdate1</serviceId>\n"
WiredHome 0:de1dfa2ab813 118 " <controlURL>/upnp/control/firmwareupdate1</controlURL>\n"
WiredHome 0:de1dfa2ab813 119 " <eventSubURL>/upnp/event/firmwareupdate1</eventSubURL>\n"
WiredHome 0:de1dfa2ab813 120 " <SCPDURL>/firmwareupdate.xml</SCPDURL>\n"
WiredHome 0:de1dfa2ab813 121 " </service>\n"
WiredHome 0:de1dfa2ab813 122 " <service>\n"
WiredHome 0:de1dfa2ab813 123 " <serviceType>urn:Belkin:service:rules:1</serviceType>\n"
WiredHome 0:de1dfa2ab813 124 " <serviceId>urn:Belkin:serviceId:rules1</serviceId>\n"
WiredHome 0:de1dfa2ab813 125 " <controlURL>/upnp/control/rules1</controlURL>\n"
WiredHome 0:de1dfa2ab813 126 " <eventSubURL>/upnp/event/rules1</eventSubURL>\n"
WiredHome 0:de1dfa2ab813 127 " <SCPDURL>/rulesservice.xml</SCPDURL>\n"
WiredHome 0:de1dfa2ab813 128 " </service>\n"
WiredHome 0:de1dfa2ab813 129 " <service>\n"
WiredHome 0:de1dfa2ab813 130 " <serviceType>urn:Belkin:service:metainfo:1</serviceType>\n"
WiredHome 0:de1dfa2ab813 131 " <serviceId>urn:Belkin:serviceId:metainfo1</serviceId>\n"
WiredHome 0:de1dfa2ab813 132 " <controlURL>/upnp/control/metainfo1</controlURL>\n"
WiredHome 0:de1dfa2ab813 133 " <eventSubURL>/upnp/event/metainfo1</eventSubURL>\n"
WiredHome 0:de1dfa2ab813 134 " <SCPDURL>/metainfoservice.xml</SCPDURL>\n"
WiredHome 0:de1dfa2ab813 135 " </service>\n"
WiredHome 0:de1dfa2ab813 136 " <service>\n"
WiredHome 0:de1dfa2ab813 137 " <serviceType>urn:Belkin:service:remoteaccess:1</serviceType>\n"
WiredHome 0:de1dfa2ab813 138 " <serviceId>urn:Belkin:serviceId:remoteaccess1</serviceId>\n"
WiredHome 0:de1dfa2ab813 139 " <controlURL>/upnp/control/remoteaccess1</controlURL>\n"
WiredHome 0:de1dfa2ab813 140 " <eventSubURL>/upnp/event/remoteaccess1</eventSubURL>\n"
WiredHome 0:de1dfa2ab813 141 " <SCPDURL>/remoteaccess.xml</SCPDURL>\n"
WiredHome 0:de1dfa2ab813 142 " </service>\n"
WiredHome 0:de1dfa2ab813 143 " <service>\n"
WiredHome 0:de1dfa2ab813 144 " <serviceType>urn:Belkin:service:deviceinfo:1</serviceType>\n"
WiredHome 0:de1dfa2ab813 145 " <serviceId>urn:Belkin:serviceId:deviceinfo1</serviceId>\n"
WiredHome 0:de1dfa2ab813 146 " <controlURL>/upnp/control/deviceinfo1</controlURL>\n"
WiredHome 0:de1dfa2ab813 147 " <eventSubURL>/upnp/event/deviceinfo1</eventSubURL>\n"
WiredHome 0:de1dfa2ab813 148 " <SCPDURL>/deviceinfoservice.xml</SCPDURL>\n"
WiredHome 0:de1dfa2ab813 149 " </service>\n"
WiredHome 0:de1dfa2ab813 150 " <service>\n"
WiredHome 0:de1dfa2ab813 151 " <serviceType>urn:Belkin:service:smartsetup:1</serviceType>\n"
WiredHome 0:de1dfa2ab813 152 " <serviceId>urn:Belkin:serviceId:smartsetup1</serviceId>\n"
WiredHome 0:de1dfa2ab813 153 " <controlURL>/upnp/control/smartsetup1</controlURL>\n"
WiredHome 0:de1dfa2ab813 154 " <eventSubURL>/upnp/event/smartsetup1</eventSubURL>\n"
WiredHome 0:de1dfa2ab813 155 " <SCPDURL>/smartsetup.xml</SCPDURL>\n"
WiredHome 0:de1dfa2ab813 156 " </service>\n"
WiredHome 0:de1dfa2ab813 157 " <service>\n"
WiredHome 0:de1dfa2ab813 158 " <serviceType>urn:Belkin:service:manufacture:1</serviceType>\n"
WiredHome 0:de1dfa2ab813 159 " <serviceId>urn:Belkin:serviceId:manufacture1</serviceId>\n"
WiredHome 0:de1dfa2ab813 160 " <controlURL>/upnp/control/manufacture1</controlURL>\n"
WiredHome 0:de1dfa2ab813 161 " <eventSubURL>/upnp/event/manufacture1</eventSubURL>\n"
WiredHome 0:de1dfa2ab813 162 " <SCPDURL>/manufacture.xml</SCPDURL>\n"
WiredHome 0:de1dfa2ab813 163 " </service>\n"
WiredHome 0:de1dfa2ab813 164 " </serviceList>\n"
WiredHome 0:de1dfa2ab813 165 #endif
WiredHome 0:de1dfa2ab813 166 " </device>\n"
WiredHome 0:de1dfa2ab813 167 "</root>\n";
WiredHome 0:de1dfa2ab813 168
WiredHome 0:de1dfa2ab813 169
WiredHome 0:de1dfa2ab813 170 HTTPServer::CallBackResults Setup_xml(HTTPServer *svr, HTTPServer::CallBackType type, char * path,
WiredHome 0:de1dfa2ab813 171 const HTTPServer::namevalue *queryParams, int queryParamCount)
WiredHome 0:de1dfa2ab813 172 {
WiredHome 0:de1dfa2ab813 173 char BigBuffer[1000];
WiredHome 0:de1dfa2ab813 174 HTTPServer::CallBackResults ret = HTTPServer::ACCEPT_ERROR;
WiredHome 0:de1dfa2ab813 175 printf("Setup.xml responder\n");
WiredHome 0:de1dfa2ab813 176 switch (type) {
WiredHome 0:de1dfa2ab813 177 case HTTPServer::SEND_PAGE:
WiredHome 0:de1dfa2ab813 178 svr->header(HTTPServer::OK, "OK", hdrTypeHTML_NoCache);
WiredHome 0:de1dfa2ab813 179 sprintf(BigBuffer, SETUP_TEMPLATE,
WiredHome 0:de1dfa2ab813 180 My_Name, eth.getMACAddress(), My_SerialNum,
WiredHome 0:de1dfa2ab813 181 eth.getIPAddress(), Server_Port);
WiredHome 0:de1dfa2ab813 182 svr->send(BigBuffer);
WiredHome 0:de1dfa2ab813 183 ret = HTTPServer::ACCEPT_COMPLETE;
WiredHome 0:de1dfa2ab813 184 break;
WiredHome 0:de1dfa2ab813 185 case HTTPServer::CONTENT_LENGTH_REQUEST:
WiredHome 0:de1dfa2ab813 186 ret = HTTPServer::ACCEPT_COMPLETE;
WiredHome 0:de1dfa2ab813 187 break;
WiredHome 0:de1dfa2ab813 188 case HTTPServer::DATA_TRANSFER:
WiredHome 0:de1dfa2ab813 189 ret = HTTPServer::ACCEPT_COMPLETE;
WiredHome 0:de1dfa2ab813 190 break;
WiredHome 0:de1dfa2ab813 191 default:
WiredHome 0:de1dfa2ab813 192 ret = HTTPServer::ACCEPT_ERROR;
WiredHome 0:de1dfa2ab813 193 break;
WiredHome 0:de1dfa2ab813 194 }
WiredHome 0:de1dfa2ab813 195 return ret;
WiredHome 0:de1dfa2ab813 196 }
WiredHome 0:de1dfa2ab813 197
WiredHome 0:de1dfa2ab813 198
WiredHome 0:de1dfa2ab813 199
WiredHome 0:de1dfa2ab813 200 HTTPServer::CallBackResults RootPage(HTTPServer *svr, HTTPServer::CallBackType type, char * path,
WiredHome 0:de1dfa2ab813 201 const HTTPServer::namevalue *queryParams, int queryParamCount)
WiredHome 0:de1dfa2ab813 202 {
WiredHome 0:de1dfa2ab813 203 char BigBuffer[1000];
WiredHome 0:de1dfa2ab813 204 HTTPServer::CallBackResults ret = HTTPServer::ACCEPT_ERROR;
WiredHome 0:de1dfa2ab813 205 printf("RootPage responder\n");
WiredHome 0:de1dfa2ab813 206
WiredHome 0:de1dfa2ab813 207 int led, cmd;
WiredHome 0:de1dfa2ab813 208 int mask = 0;
WiredHome 0:de1dfa2ab813 209 for (int i=0; i<queryParamCount; i++) {
WiredHome 0:de1dfa2ab813 210 if (strcmp(queryParams[i].name, "LED") == 0) {
WiredHome 0:de1dfa2ab813 211 led = atoi(queryParams[i].value);
WiredHome 0:de1dfa2ab813 212 mask |= 1;
WiredHome 0:de1dfa2ab813 213 } else if (strcmp(queryParams[i].name, "CMD") == 0) {
WiredHome 0:de1dfa2ab813 214 cmd = atoi(queryParams[i].value);
WiredHome 0:de1dfa2ab813 215 mask |= 2;
WiredHome 0:de1dfa2ab813 216 }
WiredHome 0:de1dfa2ab813 217 }
WiredHome 0:de1dfa2ab813 218 if (mask == 3) {
WiredHome 0:de1dfa2ab813 219 switch (led) {
WiredHome 0:de1dfa2ab813 220 case 1:
WiredHome 0:de1dfa2ab813 221 case 2:
WiredHome 0:de1dfa2ab813 222 case 3:
WiredHome 0:de1dfa2ab813 223 case 4:
WiredHome 0:de1dfa2ab813 224 leds[led - 1] = cmd;
WiredHome 0:de1dfa2ab813 225 break;
WiredHome 0:de1dfa2ab813 226 default:
WiredHome 0:de1dfa2ab813 227 break;
WiredHome 0:de1dfa2ab813 228 }
WiredHome 0:de1dfa2ab813 229 }
WiredHome 0:de1dfa2ab813 230
WiredHome 0:de1dfa2ab813 231 switch (type) {
WiredHome 0:de1dfa2ab813 232 case HTTPServer::SEND_PAGE:
WiredHome 0:de1dfa2ab813 233 svr->header(HTTPServer::OK, "OK", hdrTypeHTML_NoCache);
WiredHome 0:de1dfa2ab813 234 sprintf(BigBuffer, ROOTPAGE, PROG_NAME, PROG_NAME, BUILD_DATE);
WiredHome 0:de1dfa2ab813 235 svr->send(BigBuffer);
WiredHome 0:de1dfa2ab813 236 ret = HTTPServer::ACCEPT_COMPLETE;
WiredHome 0:de1dfa2ab813 237 break;
WiredHome 0:de1dfa2ab813 238 case HTTPServer::CONTENT_LENGTH_REQUEST:
WiredHome 0:de1dfa2ab813 239 ret = HTTPServer::ACCEPT_COMPLETE;
WiredHome 0:de1dfa2ab813 240 break;
WiredHome 0:de1dfa2ab813 241 case HTTPServer::DATA_TRANSFER:
WiredHome 0:de1dfa2ab813 242 ret = HTTPServer::ACCEPT_COMPLETE;
WiredHome 0:de1dfa2ab813 243 break;
WiredHome 0:de1dfa2ab813 244 default:
WiredHome 0:de1dfa2ab813 245 ret = HTTPServer::ACCEPT_ERROR;
WiredHome 0:de1dfa2ab813 246 break;
WiredHome 0:de1dfa2ab813 247 }
WiredHome 0:de1dfa2ab813 248 return ret;
WiredHome 0:de1dfa2ab813 249 }