An example demonstrating SSDP Discovery and a companion Web Server.

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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers WebPages.cpp Source File

WebPages.cpp

00001 
00002 #include "mbed.h"
00003 
00004 #include "EthernetInterface.h"
00005 #include "WebPages.h"
00006 
00007 extern EthernetInterface eth;
00008 extern const char * BUILD_DATE;
00009 extern const char * PROG_NAME;
00010 extern const char * My_Name;
00011 extern const char * My_SerialNum;
00012 extern int Server_Port;
00013 
00014 
00015 // ##########################################
00016 // This test version controls the LEDs
00017 //
00018 DigitalOut leds[4] = { LED1, LED2, LED3, LED4 };
00019 
00020 
00021 static const char hdrTypeHTML_NoCache[] = 
00022     "Content-Type: text/html\r\n"
00023     "Cache-Control: no-cache\r\n";
00024 
00025 
00026 // sprintf(buf, ROOTPAGE, "NodeName", "NodeName", "BuildDate", 
00027 static const char ROOTPAGE[] =
00028     "<!DOCTYPE html>\r\n"
00029     "<html><head><title>%s</title>\r\n"
00030     "</head>\r\n"
00031     "<body>\r\n"
00032     "<h1>%s</h1>"
00033     "This project demonstrates the Smartware web server and the Smartware SSDP discovery server.\n"
00034     "You should be able to scan the network (e.g. in Windows Explorer) and find this device.\n"
00035     "Then you can click on it to open this web page to interact with it.\n"
00036     "<br/><br/>Build %s<br/><br/>\n"
00037     "<font size='+5'>\n"
00038     "<table><tr>\n"
00039     "<td>"
00040     "<button onclick=\"window.location.href='/?LED=1&CMD=1'\">LED 1 On</button><br/>\n"
00041     "<button onclick=\"window.location.href='/?LED=1&CMD=0'\">LED 1 Off</button><br/>\n"
00042     "</td><td>"
00043     "<button onclick=\"window.location.href='/?LED=2&CMD=1'\">LED 2 On</button><br/>\n"
00044     "<button onclick=\"window.location.href='/?LED=2&CMD=0'\">LED 2 Off</button><br/>\n"
00045     "</td><td>"
00046     "<button onclick=\"window.location.href='/?LED=3&CMD=1'\">LED 3 On</button><br/>\n"
00047     "<button onclick=\"window.location.href='/?LED=3&CMD=0'\">LED 3 Off</button><br/>\n"
00048     "</td><td>"
00049     "<button onclick=\"window.location.href='/?LED=4&CMD=1'\">LED 4 On</button><br/>\n"
00050     "<button onclick=\"window.location.href='/?LED=4&CMD=0'\">LED 4 Off</button><br/>\n"
00051     "</td>"
00052     "</tr></table>\n"
00053     "</font>\n"
00054     "<form method='get'>\n"
00055     "<table>\n"
00056     "<tr><td>Set LED</td>\n"
00057     "<td><select name='LED'>\n"
00058     "   <option value='1'>1</option>\n"
00059     "   <option value='2'>2</option>\n"
00060     "   <option value='3'>3</option>\n"
00061     "   <option value='4'>4</option>\n"
00062     " </select>\n"
00063     " \n"
00064     " <select name='CMD'>\n"
00065     "   <option value='0'>Off</option>\n"
00066     "   <option value='1'>On</option>\n"
00067     " </select>\n"
00068     "</td></tr>\n"
00069     "<tr><td>&nbsp;</td><td><input type='submit' value='Apply'></td></tr>\n"
00070     "</table>\n"
00071     "</form>\n"
00072     "</body>\n"
00073     "</html>\n"
00074     "";
00075 
00076 
00077 // The /setup.xml file
00078 //
00079 // sprintf(buf, SETUP_TEMPLATE, "FriendlyName", "udn_hexstring", "serialNum", "ip.ad.dr", portNum);
00080 static const char SETUP_TEMPLATE[] =
00081     "<?xml version=\"1.0\"?>\n"
00082     "<root xmlns=\"urn:Belkin:device-1-0\">\n"
00083     " <specVersion>\n"
00084     "  <major>1</major>\n"
00085     "  <minor>0</minor>\n"
00086     " </specVersion>\n"
00087     " <device>\n"
00088     "  <deviceType>urn:Belkin:device:controllee:1</deviceType>\n"
00089     "  <friendlyName>%s</friendlyName>\n"
00090     "  <manufacturer>Belkin International Inc.</manufacturer>\n"            ///< must be "Belkin..." for Alexa discovery
00091     "  <manufacturerURL>http://www.smart-family.net</manufacturerURL>\n"    ///<
00092     "  <modelDescription>Special thing</modelDescription>\n"   ///<
00093     "  <modelName>Smart Node</modelName>\n"                                ///<
00094     "  <modelNumber>1.0.0</modelNumber>\n"
00095 #if 0
00096     "  <modelURL>http://www.smart-family.net</modelURL>\n"                  ///< This causes it to fail to send completely
00097 #endif
00098     "  <UDN>uuid:Socket-1_0-%s</UDN>\n"
00099     "  <serialNumber>%s</serialNumber>\n"
00100     "  <iconList>\n"
00101     "   <mimetype>jpg</mimetype>\n"
00102     "   <width>100</width>\n"
00103     "   <height>100</height>\n"
00104     "   <depth>100</depth>\n"
00105     "   <url>icon.jpg</url>\n"
00106     "  </iconList>\n"
00107     "  <presentationURL>http://%s:%d</presentationURL>\n"
00108 #if 0
00109     "  <serviceList>\n"
00110     "   <service>\n"
00111     "    <serviceType>urn:Belkin:service:WiFiSetup:1</serviceType>\n"
00112     "    <serviceId>urn:Belkin:serviceId:WiFiSetup1</serviceId>\n"
00113     "    <controlURL>/upnp/control/WiFiSetup1</controlURL>\n"
00114     "    <eventSubURL>/upnp/event/WiFiSetup1</eventSubURL>\n"
00115     "    <SCPDURL>/setupservice.xml</SCPDURL>\n"
00116     "   </service>\n"
00117     "   <service>\n"
00118     "    <serviceType>urn:Belkin:service:timesync:1</serviceType>\n"
00119     "    <serviceId>urn:Belkin:serviceId:timesync1</serviceId>\n"
00120     "    <controlURL>/upnp/control/timesync1</controlURL>\n"
00121     "    <eventSubURL>/upnp/event/timesync1</eventSubURL>\n"
00122     "    <SCPDURL>/timesyncservice.xml</SCPDURL>\n"
00123     "   </service>\n"
00124     "   <service>\n"
00125     "    <serviceType>urn:Belkin:service:basicevent:1</serviceType>\n"
00126     "    <serviceId>urn:Belkin:serviceId:basicevent1</serviceId>\n"
00127     "    <controlURL>/upnp/control/basicevent1</controlURL>\n"
00128     "    <eventSubURL>/upnp/event/basicevent1</eventSubURL>\n"
00129     "    <SCPDURL>/eventservice.xml</SCPDURL>\n"
00130     "   </service>\n"
00131     "   <service>\n"
00132     "    <serviceType>urn:Belkin:service:firmwareupdate:1</serviceType>\n"
00133     "    <serviceId>urn:Belkin:serviceId:firmwareupdate1</serviceId>\n"
00134     "    <controlURL>/upnp/control/firmwareupdate1</controlURL>\n"
00135     "    <eventSubURL>/upnp/event/firmwareupdate1</eventSubURL>\n"
00136     "    <SCPDURL>/firmwareupdate.xml</SCPDURL>\n"
00137     "   </service>\n"
00138     "   <service>\n"
00139     "    <serviceType>urn:Belkin:service:rules:1</serviceType>\n"
00140     "    <serviceId>urn:Belkin:serviceId:rules1</serviceId>\n"
00141     "    <controlURL>/upnp/control/rules1</controlURL>\n"
00142     "    <eventSubURL>/upnp/event/rules1</eventSubURL>\n"
00143     "    <SCPDURL>/rulesservice.xml</SCPDURL>\n"
00144     "   </service>\n"
00145     "   <service>\n"
00146     "    <serviceType>urn:Belkin:service:metainfo:1</serviceType>\n"
00147     "    <serviceId>urn:Belkin:serviceId:metainfo1</serviceId>\n"
00148     "    <controlURL>/upnp/control/metainfo1</controlURL>\n"
00149     "    <eventSubURL>/upnp/event/metainfo1</eventSubURL>\n"
00150     "    <SCPDURL>/metainfoservice.xml</SCPDURL>\n"
00151     "   </service>\n"
00152     "   <service>\n"
00153     "    <serviceType>urn:Belkin:service:remoteaccess:1</serviceType>\n"
00154     "    <serviceId>urn:Belkin:serviceId:remoteaccess1</serviceId>\n"
00155     "    <controlURL>/upnp/control/remoteaccess1</controlURL>\n"
00156     "    <eventSubURL>/upnp/event/remoteaccess1</eventSubURL>\n"
00157     "    <SCPDURL>/remoteaccess.xml</SCPDURL>\n"
00158     "   </service>\n"
00159     "   <service>\n"
00160     "    <serviceType>urn:Belkin:service:deviceinfo:1</serviceType>\n"
00161     "    <serviceId>urn:Belkin:serviceId:deviceinfo1</serviceId>\n"
00162     "    <controlURL>/upnp/control/deviceinfo1</controlURL>\n"
00163     "    <eventSubURL>/upnp/event/deviceinfo1</eventSubURL>\n"
00164     "    <SCPDURL>/deviceinfoservice.xml</SCPDURL>\n"
00165     "   </service>\n"
00166     "   <service>\n"
00167     "    <serviceType>urn:Belkin:service:smartsetup:1</serviceType>\n"
00168     "    <serviceId>urn:Belkin:serviceId:smartsetup1</serviceId>\n"
00169     "    <controlURL>/upnp/control/smartsetup1</controlURL>\n"
00170     "    <eventSubURL>/upnp/event/smartsetup1</eventSubURL>\n"
00171     "    <SCPDURL>/smartsetup.xml</SCPDURL>\n"
00172     "   </service>\n"
00173     "   <service>\n"
00174     "    <serviceType>urn:Belkin:service:manufacture:1</serviceType>\n"
00175     "    <serviceId>urn:Belkin:serviceId:manufacture1</serviceId>\n"
00176     "    <controlURL>/upnp/control/manufacture1</controlURL>\n"
00177     "    <eventSubURL>/upnp/event/manufacture1</eventSubURL>\n"
00178     "    <SCPDURL>/manufacture.xml</SCPDURL>\n"
00179     "   </service>\n"
00180     "  </serviceList>\n"
00181 #endif
00182     " </device>\n"
00183     "</root>\n";
00184 
00185 
00186 HTTPServer::CallBackResults Setup_xml(HTTPServer *svr, HTTPServer::CallBackType type, char * path,
00187                        const HTTPServer::namevalue *queryParams, int queryParamCount)
00188 {
00189     char BigBuffer[sizeof(SETUP_TEMPLATE) + 150];
00190     HTTPServer::CallBackResults ret = HTTPServer::ACCEPT_ERROR;
00191     switch (type) {
00192         case HTTPServer::SEND_PAGE:
00193             svr->header(HTTPServer::OK, "OK", hdrTypeHTML_NoCache);
00194             sprintf(BigBuffer, SETUP_TEMPLATE, 
00195                 My_Name, eth.getMACAddress(), My_SerialNum,
00196                 eth.getIPAddress(), Server_Port);
00197             svr->send(BigBuffer);
00198             ret = HTTPServer::ACCEPT_COMPLETE;
00199             break;
00200         case HTTPServer::CONTENT_LENGTH_REQUEST:
00201             ret = HTTPServer::ACCEPT_COMPLETE;
00202             break;
00203         case HTTPServer::DATA_TRANSFER:
00204             ret = HTTPServer::ACCEPT_COMPLETE;
00205             break;
00206         default:
00207             ret = HTTPServer::ACCEPT_ERROR;
00208             break;
00209     }
00210     return ret;
00211 }
00212 
00213 
00214 
00215 HTTPServer::CallBackResults RootPage(HTTPServer *svr, HTTPServer::CallBackType type, char * path,
00216                        const HTTPServer::namevalue *queryParams, int queryParamCount)
00217 {
00218     #define bufSize (sizeof(ROOTPAGE) + 100)
00219     char * BigBuffer = (char *)malloc(bufSize);
00220     HTTPServer::CallBackResults ret = HTTPServer::ACCEPT_ERROR;
00221     if (!BigBuffer) {
00222         printf("cannot allocate %d bytes\n", bufSize);
00223         return ret;
00224     }
00225     
00226     int led, cmd;
00227     int mask = 0;
00228     for (int i=0; i<queryParamCount; i++) {
00229         if (strcmp(queryParams[i].name, "LED") == 0) {
00230             led = atoi(queryParams[i].value);
00231             mask |= 1;
00232         } else if (strcmp(queryParams[i].name, "CMD") == 0) {
00233             cmd = atoi(queryParams[i].value);
00234             mask |= 2;
00235         }
00236     }
00237     if (mask == 3) {
00238         switch (led) {
00239             case 1:
00240             case 2:
00241             case 3:
00242             case 4:
00243                 leds[led - 1] = cmd;
00244                 break;
00245             default:
00246                 break;
00247         }
00248     }
00249     
00250     switch (type) {
00251         case HTTPServer::SEND_PAGE:
00252             svr->header(HTTPServer::OK, "OK", hdrTypeHTML_NoCache);
00253             snprintf(BigBuffer, bufSize, ROOTPAGE, PROG_NAME, PROG_NAME, BUILD_DATE);            
00254             svr->send(BigBuffer);
00255             ret = HTTPServer::ACCEPT_COMPLETE;
00256             break;
00257         case HTTPServer::CONTENT_LENGTH_REQUEST:
00258             ret = HTTPServer::ACCEPT_COMPLETE;
00259             break;
00260         case HTTPServer::DATA_TRANSFER:
00261             ret = HTTPServer::ACCEPT_COMPLETE;
00262             break;
00263         default:
00264             ret = HTTPServer::ACCEPT_ERROR;
00265             break;
00266     }
00267     if (BigBuffer)
00268         free(BigBuffer);
00269     return ret;
00270 }