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.
main.cpp@9:13e4749ddfa2, 2020-01-12 (annotated)
- Committer:
- WiredHome
- Date:
- Sun Jan 12 23:03:03 2020 +0000
- Revision:
- 9:13e4749ddfa2
- Parent:
- 8:0b1efcef5e50
Minor changes for debug only.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
WiredHome | 0:de1dfa2ab813 | 1 | // |
WiredHome | 0:de1dfa2ab813 | 2 | // A simple SSDP example |
WiredHome | 0:de1dfa2ab813 | 3 | // |
WiredHome | 8:0b1efcef5e50 | 4 | #include "mbed.h" // testing mbed v128, mbed-rtos v121 |
WiredHome | 0:de1dfa2ab813 | 5 | #include "EthernetInterface.h" // ver 55 |
WiredHome | 0:de1dfa2ab813 | 6 | #include "SW_HTTPServer.h" // ver 50 |
WiredHome | 0:de1dfa2ab813 | 7 | #include "TimeInterface.h" // ver 23 |
WiredHome | 0:de1dfa2ab813 | 8 | #include "Watchdog.h" // ver 6 |
WiredHome | 0:de1dfa2ab813 | 9 | #include "SW_String.h" // ver 1 |
WiredHome | 0:de1dfa2ab813 | 10 | #include "SSDP.h" // ver 0 |
WiredHome | 0:de1dfa2ab813 | 11 | |
WiredHome | 0:de1dfa2ab813 | 12 | #include "WebPages.h" // Private handler for web queries |
WiredHome | 0:de1dfa2ab813 | 13 | |
WiredHome | 8:0b1efcef5e50 | 14 | extern "C" void mbed_reset(); |
WiredHome | 8:0b1efcef5e50 | 15 | |
WiredHome | 0:de1dfa2ab813 | 16 | RawSerial pc(USBTX, USBRX); |
WiredHome | 0:de1dfa2ab813 | 17 | |
WiredHome | 0:de1dfa2ab813 | 18 | EthernetInterface eth; |
WiredHome | 0:de1dfa2ab813 | 19 | TimeInterface ntp(ð); |
WiredHome | 0:de1dfa2ab813 | 20 | Watchdog wd; |
WiredHome | 0:de1dfa2ab813 | 21 | time_t lastboottime; |
WiredHome | 0:de1dfa2ab813 | 22 | |
WiredHome | 4:5da66fab599c | 23 | PwmOut signOfLife(LED4); // LED sign of life. 100% WD reset, 20% restart, sine-wave: running |
WiredHome | 4:5da66fab599c | 24 | |
WiredHome | 0:de1dfa2ab813 | 25 | //FlashFileSystem flash("flash"); // static files here for reliability and speed |
WiredHome | 0:de1dfa2ab813 | 26 | LocalFileSystem local("local"); // some place to hold settings and maybe the static web pages |
WiredHome | 0:de1dfa2ab813 | 27 | const char * Server_Root = "/local"; |
WiredHome | 0:de1dfa2ab813 | 28 | |
WiredHome | 0:de1dfa2ab813 | 29 | // public for the WebPages handler to see |
WiredHome | 0:de1dfa2ab813 | 30 | // |
WiredHome | 0:de1dfa2ab813 | 31 | const char * BUILD_DATE = __DATE__ " " __TIME__; |
WiredHome | 0:de1dfa2ab813 | 32 | const char * PROG_NAME = "SSDP Server"; |
WiredHome | 9:13e4749ddfa2 | 33 | const char * My_Name = "MBED SSDP Node"; |
WiredHome | 0:de1dfa2ab813 | 34 | const char * My_SerialNum = "0000001"; |
WiredHome | 4:5da66fab599c | 35 | int Server_Port = 80; |
WiredHome | 0:de1dfa2ab813 | 36 | // end public information |
WiredHome | 0:de1dfa2ab813 | 37 | |
WiredHome | 0:de1dfa2ab813 | 38 | |
WiredHome | 4:5da66fab599c | 39 | |
WiredHome | 4:5da66fab599c | 40 | |
WiredHome | 4:5da66fab599c | 41 | /// ShowSignOfLife |
WiredHome | 4:5da66fab599c | 42 | /// |
WiredHome | 4:5da66fab599c | 43 | /// Pulse an LED to indicate a sign of life of the program. |
WiredHome | 4:5da66fab599c | 44 | /// This also has some moderate entertainment value. |
WiredHome | 4:5da66fab599c | 45 | /// |
WiredHome | 4:5da66fab599c | 46 | void ShowSignOfLife(int degreeIncrement = 1) |
WiredHome | 4:5da66fab599c | 47 | { |
WiredHome | 4:5da66fab599c | 48 | #define PI 3.14159265359 |
WiredHome | 4:5da66fab599c | 49 | static int degrees = 0; |
WiredHome | 4:5da66fab599c | 50 | float v; |
WiredHome | 4:5da66fab599c | 51 | |
WiredHome | 4:5da66fab599c | 52 | degrees += degreeIncrement; |
WiredHome | 4:5da66fab599c | 53 | v = sin(degrees * PI / 180)/2 + 0.5; |
WiredHome | 4:5da66fab599c | 54 | signOfLife = v; // a little dimmer |
WiredHome | 4:5da66fab599c | 55 | } |
WiredHome | 4:5da66fab599c | 56 | |
WiredHome | 0:de1dfa2ab813 | 57 | int main() { |
WiredHome | 0:de1dfa2ab813 | 58 | pc.baud(460800); |
WiredHome | 0:de1dfa2ab813 | 59 | pc.printf("\r\n%s Build %s\r\n", PROG_NAME, BUILD_DATE); |
WiredHome | 4:5da66fab599c | 60 | lastboottime = ntp.timelocal(); |
WiredHome | 0:de1dfa2ab813 | 61 | if (wd.WatchdogCausedReset()) { |
WiredHome | 0:de1dfa2ab813 | 62 | pc.printf("**** Watchdog Event caused reset at %s ****\r\n", ntp.ctime(&lastboottime)); |
WiredHome | 0:de1dfa2ab813 | 63 | } |
WiredHome | 0:de1dfa2ab813 | 64 | wd.Configure(45); // very generous, but this is a network appliance, so a bit less deterministic. |
WiredHome | 0:de1dfa2ab813 | 65 | |
WiredHome | 7:776244e5765a | 66 | int eRes = eth.init(); //Use DHCP |
WiredHome | 9:13e4749ddfa2 | 67 | if (eRes < 0) { |
WiredHome | 9:13e4749ddfa2 | 68 | printf("eth.init() returned %d, rebooting in 5 s.\r\n", eRes); |
WiredHome | 9:13e4749ddfa2 | 69 | wait(5.0); |
WiredHome | 8:0b1efcef5e50 | 70 | mbed_reset(); |
WiredHome | 9:13e4749ddfa2 | 71 | } |
WiredHome | 7:776244e5765a | 72 | eRes = eth.connect(); |
WiredHome | 9:13e4749ddfa2 | 73 | if (eRes < 0) { |
WiredHome | 9:13e4749ddfa2 | 74 | printf("eth.connect() returned %d, rebooting in 5 s.\r\n", eRes); |
WiredHome | 9:13e4749ddfa2 | 75 | wait(5.0); |
WiredHome | 8:0b1efcef5e50 | 76 | mbed_reset(); |
WiredHome | 9:13e4749ddfa2 | 77 | } |
WiredHome | 7:776244e5765a | 78 | printf("IP: %s\r\n", eth.getIPAddress()); |
WiredHome | 0:de1dfa2ab813 | 79 | //Thread thr(SSDPListener, NULL, osPriorityLow); |
WiredHome | 0:de1dfa2ab813 | 80 | HTTPServer svr(Server_Port, Server_Root, 15, 30, 20, 50, &pc); |
WiredHome | 0:de1dfa2ab813 | 81 | svr.RegisterHandler("/", RootPage); |
WiredHome | 0:de1dfa2ab813 | 82 | svr.RegisterHandler("/setup.xml", Setup_xml); |
WiredHome | 4:5da66fab599c | 83 | SSDP ssdp(My_Name, eth.getMACAddress(), eth.getIPAddress(), Server_Port); |
WiredHome | 4:5da66fab599c | 84 | |
WiredHome | 9:13e4749ddfa2 | 85 | bool setTheClock = true; // prime it |
WiredHome | 4:5da66fab599c | 86 | |
WiredHome | 0:de1dfa2ab813 | 87 | while (1) { |
WiredHome | 0:de1dfa2ab813 | 88 | wd.Service(); |
WiredHome | 0:de1dfa2ab813 | 89 | svr.Poll(); // non-blocking, but also not deterministic |
WiredHome | 0:de1dfa2ab813 | 90 | Thread::yield(); |
WiredHome | 4:5da66fab599c | 91 | ShowSignOfLife(10); |
WiredHome | 9:13e4749ddfa2 | 92 | if (setTheClock) { |
WiredHome | 9:13e4749ddfa2 | 93 | setTheClock = false; |
WiredHome | 9:13e4749ddfa2 | 94 | // Could read these from non-volatile |
WiredHome | 9:13e4749ddfa2 | 95 | ntp.set_dst("3/11,2:00","11/4,2:00"); // mm/dd,hh:mm |
WiredHome | 9:13e4749ddfa2 | 96 | ntp.set_tzo_min(-360); |
WiredHome | 9:13e4749ddfa2 | 97 | int res = ntp.setTime("pool.ntp.org"); |
WiredHome | 9:13e4749ddfa2 | 98 | if (res == 0) { |
WiredHome | 9:13e4749ddfa2 | 99 | pc.printf("Time was just set\r\n"); |
WiredHome | 9:13e4749ddfa2 | 100 | } |
WiredHome | 9:13e4749ddfa2 | 101 | } |
WiredHome | 4:5da66fab599c | 102 | static time_t tLast; |
WiredHome | 4:5da66fab599c | 103 | time_t tNow = ntp.timelocal(); |
WiredHome | 4:5da66fab599c | 104 | if (tNow != tLast) { |
WiredHome | 9:13e4749ddfa2 | 105 | printf("time is %s\r\n", ntp.ctime(&tNow)); |
WiredHome | 4:5da66fab599c | 106 | tLast = tNow; |
WiredHome | 9:13e4749ddfa2 | 107 | //printf("Mem: %5d, %5d %5d\n", Thread::used_stack(), Thread::max_stack(), Thread::stack_size()); |
WiredHome | 4:5da66fab599c | 108 | } |
WiredHome | 0:de1dfa2ab813 | 109 | } |
WiredHome | 0:de1dfa2ab813 | 110 | } |