A sample program demonstrating a small but powerful web server using the Wifly module. This uses several libraries from others, but has a custom version of the WiflyInterface library, with numerous improvement to the mbed standard library.

Dependencies:   SW_HTTPServer WiflyInterface mbed C12832 IniManager

Here's the code

But you also might want to check out the SmartBoard-WiFly project page.

Basic Web Server

  • Serves static files from the selected file system. This is a compile-time setting, and a typical configuration supports gif, jpg, jpeg, ico, png, zip, gz, tar, txt, pdf, htm, and html.
  • It is designed to be small, thereby better supporting the limited resources of an embedded environment.

Advanced Web Services

  • Serves dynamically generated pages, where your software registers for a path, and then everything to that path activates your handler. Your handler then defines the header and body response.
  • Dynamic handlers can process GET query parameters (e.g. /dyn1?sky=blue&grass=green).
  • Dynamic handlers can process POST query parameters, as delivered from submission of a form.
  • Dynamic handlers can protect a resource with user:password access.

Run-Time Configurations

  • File System Support - using either the "local" file system supported by the magic chip, or from either an SD-Card or a USB flash drive.
  • Configurable to the maximum number of dynamic handlers (minimize memory requirements).
  • Configurable to the maximum number of name=value pairs for dynamic handlers (minimize memory requirements).

Compile-Time Configurations

  • Default filename for URL ending in '/' - default is 'index.htm'.
  • Configurable buffer sizes permit minimizing RAM requirements.
  • Configurable header response information.
  • Configurable for which serial port is used to communicate to the WiFly module.
  • Improved security option - to disable telnet access.

Diagnostics

  • API to determine the largest header (to more efficiently size the buffers).
  • API to gather the run-time characteristics - header processing time and content delivery time.

Limitations / Constraints

Known Issues

These are known issues, not yet resolved.

  1. Occasionally fails to serve a page - one test will constantly reload a web page every 30 seconds. It may run for hours, or minutes, then fail to load. Behaviors then are:
    • Hit the reload button in the browser and away it goes.
    • Hit the reload and you'll see the Wifly LEDs energize from the request, but no response by the web server. It appears that the embedded code does not "accept()" the connection in the TCP Socket Server.
      • In this case, the Wifly module has gone through an internal watchdog reset and the configuration parameters are such that it does not gracefully recover. Microchip is aware of this issue, but has not solved it.

Wifly Limitations

  • Single thread - it doesn't respond to overlapping requests (e.g. an embedded image may be requested before the main page completes transfer - the request is lost and the image not shown).
  • Single client - goes along with the single thread, but it doesn't support more than one client at a time.

Smart-Wifly-WebServer

  • Dynamic memory allocation - it does use dynamic memory allocation, which would be discouraged/avoided in many embedded systems. Here it uses it in parsing a request and it releases those resources upon completion of that request. If there is no other dynamic allocation that persists beyond a transaction, it should not cause memory fragmentation. Note that with multi-threading (if this is implemented with an OS), you then have race conditions that could cause fragmentation.

Web Server

Here's the web server in action. A combination of static pages served from the file system and dynamically generated pages.

/media/uploads/WiredHome/swsvr_1.pngPart of the main demo page,
which basically has all the
specifications, configurations, and limitations.
/media/uploads/WiredHome/swsvr_2.pngA zoomed out view of the same page.
/media/uploads/WiredHome/swsvr_3.pngIt would be possible to configure
the server via the web.
/media/uploads/WiredHome/swsvr_4.pngOne of the dynamically generated pages.
This one has parsed the query parameters.
/media/uploads/WiredHome/swsvr_5.pngA simple form which has a dynamic handler on the back end.
Here it takes the value associated with "leds"
and uses that to set the 4 LEDs on the mbed module.
/media/uploads/WiredHome/swsvr_6.pngA dynamic handler can require authentication.
/media/uploads/WiredHome/swsvr_7.pngSuccess!

But I've now gone so far beyond that in the current version. Here's what this one can do:

  1. It serves static web pages from a file system. I've only tested with the local file system and an SD card, but should work for any, so long as you remember that the local file system can't read subdirectories.
  2. It can serve dynamically generated web pages. This lets you accept name=value pairs using the URL (using either a GET or POST method). It can also accept them from forms. The demo lets you control the 4 LEDs from a form.
  3. As safely as possible it retrieves your credentials to the Wi-Fi Access Point. After using them, it overwrites that ram so they can't be as easily extracted.
  4. I made a large number of changes to the Wifly driver. It had too short of a timeout and I found quite a number of optimizations for performance and robustness.
  5. I have the start on a security feature - you can configure a resource to require user credentials to access it. The browser typically provides a username and password dialog. Take care however, as it does not support a secure (https) connection, so the credentials are not as securely transferred as I would like.

Optimizations I'd like to do:

  1. speed it up - I'm running the mbed to wifly module interface at 230K, which is about the top speed w/o flow control. There are other places where some time delays remain - I have eliminated a number of them.
  2. make it non-blocking, so other work can happen.
  3. integrate it with the rtos
  4. When a web page has referenced resources (e.g. an image tag), it rarely loads the image on the first try. I think the request for the resource comes in while it is still in the WiflyInterface cleaning up from the last connection. The Wifly module supports only a single connection at a time. I worked around this with a small bit of javascript to load the images after the web page.

But all in all I think it is a good start.

Program prerequisite

Here's the link to the program, but when you open it up, note a few very important items.

  1. Port Numbers listed in the constructor match the SmartBoard Baseboard.
  2. I sped up the communication baud rate to the mbed from the default 9600. Match your terminal program accordingly.
  3. Download this zip. Place it and an unzipped copy into the mbed local file system. These are the demo files.
  4. The typical ssid and password are not shown. See below to set yours.

ssid and password

You need to create a simple text file on your mbed root folder named "config.ini". The easiest way perhaps is to create "config.txt", add the information shown below and then rename it. This will be read at startup to connect you to the network. Something quite simple, like this:

[Wifi]
ssid=your_ssid
pass=your_pass_code

The program

And the program.

Import programSmart-WiFly-WebServer

A sample program demonstrating a small but powerful web server using the Wifly module. This uses several libraries from others, but has a custom version of the WiflyInterface library, with numerous improvement to the mbed standard library.

Committer:
WiredHome
Date:
Sun May 11 21:20:00 2014 +0000
Revision:
34:77d0f63f612a
Parent:
31:c9136c0f4024
Child:
37:8ced9a7fe3fd
Updated examples, particular focus on POST method.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WiredHome 7:72b5df2fac93 1 /// Demonstration of dynamic page creation using the Smartware Web Server
WiredHome 11:183b3893eb7d 2 ///
WiredHome 11:183b3893eb7d 3 /// There are a few samples here of the dynamically generated web pages.
WiredHome 11:183b3893eb7d 4 /// Read the header above each one for more details.
WiredHome 11:183b3893eb7d 5 ///
WiredHome 3:b3e21f3306a1 6 #include "mbed.h"
WiredHome 3:b3e21f3306a1 7
WiredHome 3:b3e21f3306a1 8 #include "SW_HTTPServer.h"
WiredHome 3:b3e21f3306a1 9 #include "DynamicPages.h"
WiredHome 34:77d0f63f612a 10
WiredHome 34:77d0f63f612a 11 //#define DEBUG "DYN_"
WiredHome 3:b3e21f3306a1 12 #include "Utility.h"
WiredHome 15:1f2b62130ffb 13
WiredHome 3:b3e21f3306a1 14
WiredHome 11:183b3893eb7d 15 BusOut leds(LED4,LED3,LED2,LED1); // dynamic page "/dyn2" lets you control these
WiredHome 3:b3e21f3306a1 16
WiredHome 34:77d0f63f612a 17 static char * pPath = NULL;
WiredHome 34:77d0f63f612a 18
WiredHome 3:b3e21f3306a1 19
WiredHome 4:178df829d62b 20 /// SimplyDynamicPage1
WiredHome 4:178df829d62b 21 ///
WiredHome 14:85c805890454 22 /// This web page is generated dynamically as a kind of "bare minimum".
WiredHome 11:183b3893eb7d 23 /// It doesn't do much.
WiredHome 11:183b3893eb7d 24 ///
WiredHome 11:183b3893eb7d 25 /// You can see in main how this page was registered.
WiredHome 4:178df829d62b 26 ///
WiredHome 34:77d0f63f612a 27 HTTPServer::CallBackResults SuperSimpleDynamicPage(HTTPServer *svr, HTTPServer::CallBackType type,
WiredHome 34:77d0f63f612a 28 const char * path, const HTTPServer::namevalue *params, int paramcount)
WiredHome 14:85c805890454 29 {
WiredHome 29:14c47d31a9dc 30 HTTPServer::CallBackResults ret = HTTPServer::ACCEPT_ERROR;
WiredHome 16:ab1867ffcf94 31 char contentlen[30];
WiredHome 20:0ae416ce9eaf 32 #ifdef INCLUDE_GETREMOTE
WiredHome 16:ab1867ffcf94 33 char remoteIP[36];
WiredHome 20:0ae416ce9eaf 34 #endif
WiredHome 16:ab1867ffcf94 35 char buf[250];
WiredHome 14:85c805890454 36
WiredHome 4:178df829d62b 37 switch (type) {
WiredHome 4:178df829d62b 38 case HTTPServer::SEND_PAGE:
WiredHome 16:ab1867ffcf94 39 // This sample drops it all into a local buffer, computes the length,
WiredHome 16:ab1867ffcf94 40 // and passes that along as well. This can help the other end with efficiency.
WiredHome 16:ab1867ffcf94 41 strcpy(buf, "<html><head><title>Dynamic Page</title></head>\r\n");
WiredHome 16:ab1867ffcf94 42 strcat(buf, "<body>\r\n");
WiredHome 16:ab1867ffcf94 43 strcat(buf, "<h1>Smart WiFly Web Server</h1>\r\n");
WiredHome 16:ab1867ffcf94 44 strcat(buf, "This page was generated dynamically.<br/>\r\n");
WiredHome 20:0ae416ce9eaf 45 #ifdef INCLUDE_GETREMOTE
WiredHome 20:0ae416ce9eaf 46 svr->GetRemoteAddr(remoteIP, sizeof(remoteIP));
WiredHome 16:ab1867ffcf94 47 strcat(buf, "Client IP Address: ");
WiredHome 16:ab1867ffcf94 48 strcat(buf, remoteIP);
WiredHome 16:ab1867ffcf94 49 strcat(buf, "<br/>\r\n");
WiredHome 20:0ae416ce9eaf 50 #endif
WiredHome 16:ab1867ffcf94 51 strcat(buf, "<a href='/'>back to main</a></body></html>\r\n");
WiredHome 16:ab1867ffcf94 52 sprintf(contentlen, "Content-Length: %d\r\n", strlen(buf));
WiredHome 16:ab1867ffcf94 53 // Now the actual header response
WiredHome 16:ab1867ffcf94 54 svr->header(200, "OK", "Content-Type: text/html\r\n", contentlen);
WiredHome 16:ab1867ffcf94 55 // and data are sent
WiredHome 16:ab1867ffcf94 56 svr->send(buf);
WiredHome 29:14c47d31a9dc 57 ret = HTTPServer::ACCEPT_COMPLETE;
WiredHome 4:178df829d62b 58 break;
WiredHome 4:178df829d62b 59 case HTTPServer::CONTENT_LENGTH_REQUEST:
WiredHome 29:14c47d31a9dc 60 ret = HTTPServer::ACCEPT_COMPLETE;
WiredHome 4:178df829d62b 61 break;
WiredHome 4:178df829d62b 62 case HTTPServer::DATA_TRANSFER:
WiredHome 29:14c47d31a9dc 63 ret = HTTPServer::ACCEPT_COMPLETE;
WiredHome 4:178df829d62b 64 break;
WiredHome 4:178df829d62b 65 default:
WiredHome 29:14c47d31a9dc 66 ret = HTTPServer::ACCEPT_ERROR;
WiredHome 4:178df829d62b 67 break;
WiredHome 4:178df829d62b 68 }
WiredHome 4:178df829d62b 69 return ret;
WiredHome 4:178df829d62b 70 }
WiredHome 4:178df829d62b 71
WiredHome 4:178df829d62b 72
WiredHome 3:b3e21f3306a1 73 /// SimplyDynamicPage
WiredHome 3:b3e21f3306a1 74 ///
WiredHome 14:85c805890454 75 /// This web page is generated dynamically and fills in part of the information from
WiredHome 11:183b3893eb7d 76 /// data extracted from the URL as a query string. It also shows some additional
WiredHome 11:183b3893eb7d 77 /// information - memory stats, server stats and so forth.
WiredHome 3:b3e21f3306a1 78 ///
WiredHome 3:b3e21f3306a1 79 /// You can see in main how this page was registered.
WiredHome 3:b3e21f3306a1 80 ///
WiredHome 34:77d0f63f612a 81 HTTPServer::CallBackResults SimpleDynamicPage(HTTPServer *svr, HTTPServer::CallBackType type,
WiredHome 34:77d0f63f612a 82 const char * path, const HTTPServer::namevalue *params, int paramcount)
WiredHome 14:85c805890454 83 {
WiredHome 31:c9136c0f4024 84 static unsigned int pageCounter = 0;
WiredHome 3:b3e21f3306a1 85 char buf[100];
WiredHome 29:14c47d31a9dc 86 HTTPServer::CallBackResults ret = HTTPServer::ACCEPT_ERROR;
WiredHome 4:178df829d62b 87 HTTPServer::SW_PerformanceData perfData;
WiredHome 34:77d0f63f612a 88 Wifly * w = svr->GetWifly()->getInstance();
WiredHome 14:85c805890454 89
WiredHome 3:b3e21f3306a1 90 switch (type) {
WiredHome 3:b3e21f3306a1 91 case HTTPServer::SEND_PAGE:
WiredHome 4:178df829d62b 92 if (strcmp("true", svr->GetParameter("Reset")) == 0)
WiredHome 4:178df829d62b 93 svr->ResetPerformanceData();
WiredHome 4:178df829d62b 94 // Send the header
WiredHome 3:b3e21f3306a1 95 svr->header(200, "OK", "Content-Type: text/html\r\n");
WiredHome 14:85c805890454 96
WiredHome 4:178df829d62b 97 // Send top of the page
WiredHome 16:ab1867ffcf94 98 svr->send(
WiredHome 31:c9136c0f4024 99 "<html><head><title>Dynamic Page</title><meta http-equiv='refresh' content='15'></head>\r\n"
WiredHome 16:ab1867ffcf94 100 "<body>\r\n"
WiredHome 16:ab1867ffcf94 101 "<h1>Smart WiFly Web Server</h1>\r\n"
WiredHome 16:ab1867ffcf94 102 "This page was generated dynamically. Create your own name=value pairs on the URL "
WiredHome 31:c9136c0f4024 103 "which uses the GET method.<br/>\r\n");
WiredHome 4:178df829d62b 104
WiredHome 31:c9136c0f4024 105 sprintf(buf, "This page has been accessed %d times.<br/>\r\n", ++pageCounter);
WiredHome 31:c9136c0f4024 106 svr->send(buf);
WiredHome 31:c9136c0f4024 107
WiredHome 4:178df829d62b 108 // Show Passed-in parameters
WiredHome 31:c9136c0f4024 109 svr->send("<h2>Query Parameters:</h2><blockquote>\r\n");
WiredHome 3:b3e21f3306a1 110 sprintf(buf, "%d parameters passed to {%s}:<br/>\r\n", paramcount, path);
WiredHome 3:b3e21f3306a1 111 svr->send(buf);
WiredHome 3:b3e21f3306a1 112 // show each of the parameters passed on the URL
WiredHome 3:b3e21f3306a1 113 for (int i=0; i<paramcount; i++) {
WiredHome 3:b3e21f3306a1 114 sprintf(buf, "%d: %s = %s<br/>\r\n", i, params[i].name, params[i].value);
WiredHome 3:b3e21f3306a1 115 svr->send(buf);
WiredHome 3:b3e21f3306a1 116 }
WiredHome 4:178df829d62b 117 svr->send("</blockquote>\r\n");
WiredHome 4:178df829d62b 118
WiredHome 4:178df829d62b 119 // Show Memory Stats
WiredHome 16:ab1867ffcf94 120 svr->send(
WiredHome 16:ab1867ffcf94 121 "<h2>System Statistics:</h2><blockquote>\r\n"
WiredHome 16:ab1867ffcf94 122 "<table border='1'><tr><td>Parameter</td><td>Description</td></tr>\r\n");
WiredHome 7:72b5df2fac93 123 sprintf(buf,"<tr><td align='right'>%d</td><td>Free memory</td></tr>\r\n", Free());
WiredHome 7:72b5df2fac93 124 svr->send(buf);
WiredHome 7:72b5df2fac93 125 sprintf(buf,"<tr><td align='right'>%d</td><td>Max Header size</td></tr>\r\n", svr->GetMaxHeaderSize());
WiredHome 4:178df829d62b 126 svr->send(buf);
WiredHome 34:77d0f63f612a 127 sprintf(buf,"<tr><td align='right'>%3.2f</td><td>Wifly SW version</td></tr>\r\n", w->getWiflyVersion());
WiredHome 16:ab1867ffcf94 128 svr->send(buf);
WiredHome 34:77d0f63f612a 129 sprintf(buf,"<tr><td align='right'><font size='-1'>%s</font></td><td>Wifly Version Information</td></tr>\r\n", w->getWiflyVersionString());
WiredHome 7:72b5df2fac93 130 svr->send(buf);
WiredHome 7:72b5df2fac93 131 svr->send("</table>\r\n");
WiredHome 4:178df829d62b 132 svr->send("</blockquote>\r\n");
WiredHome 4:178df829d62b 133
WiredHome 7:72b5df2fac93 134 // Show Web Server Performance metrics
WiredHome 4:178df829d62b 135 svr->GetPerformanceData(&perfData);
WiredHome 7:72b5df2fac93 136 svr->send("<h2>Web Server Performance Metrics</h2><blockquote>\r\n");
WiredHome 4:178df829d62b 137 svr->send("<table border='1'><tr><td>avg time (uS)</td><td>samples</td><td>max time (uS)</td><td>description</td></tr>\r\n");
WiredHome 16:ab1867ffcf94 138
WiredHome 4:178df829d62b 139 sprintf(buf, "<tr><td align='right'>%d</td><td align='right'>%d</td><td align='right'>%d</td><td>%s</td></tr>\r\n",
WiredHome 16:ab1867ffcf94 140 (unsigned long)(perfData.ConnectionAccepted.TotalTime_us / perfData.ConnectionAccepted.Samples),
WiredHome 16:ab1867ffcf94 141 perfData.ConnectionAccepted.Samples,
WiredHome 16:ab1867ffcf94 142 (unsigned long)(perfData.ConnectionAccepted.MaxTime_us),
WiredHome 16:ab1867ffcf94 143 "Connection Accepted");
WiredHome 4:178df829d62b 144 svr->send(buf);
WiredHome 16:ab1867ffcf94 145
WiredHome 16:ab1867ffcf94 146 sprintf(buf, "<tr><td align='right'>%d</td><td align='right'>%d</td><td align='right'>%d</td><td>%s</td></tr>\r\n",
WiredHome 16:ab1867ffcf94 147 (unsigned long)(perfData.HeaderParsed.TotalTime_us / perfData.HeaderParsed.Samples),
WiredHome 16:ab1867ffcf94 148 perfData.HeaderParsed.Samples,
WiredHome 16:ab1867ffcf94 149 (unsigned long)(perfData.HeaderParsed.MaxTime_us),
WiredHome 16:ab1867ffcf94 150 "Header Parsed");
WiredHome 16:ab1867ffcf94 151 svr->send(buf);
WiredHome 16:ab1867ffcf94 152
WiredHome 4:178df829d62b 153 sprintf(buf, "<tr><td align='right'>%d</td><td align='right'>%d</td><td align='right'>%d</td><td>%s</td></tr>\r\n",
WiredHome 16:ab1867ffcf94 154 (unsigned long)(perfData.ResponseSent.TotalTime_us / perfData.ResponseSent.Samples),
WiredHome 16:ab1867ffcf94 155 perfData.ResponseSent.Samples,
WiredHome 16:ab1867ffcf94 156 (unsigned long)(perfData.ResponseSent.MaxTime_us),
WiredHome 16:ab1867ffcf94 157 "Response Sent");
WiredHome 4:178df829d62b 158 svr->send(buf);
WiredHome 16:ab1867ffcf94 159
WiredHome 16:ab1867ffcf94 160 sprintf(buf, "<tr><td align='right'>%d</td><td align='right'>%d</td><td align='right'>%d</td><td>%s</td></tr>\r\n",
WiredHome 16:ab1867ffcf94 161 (unsigned long)(perfData.ConnectionClosed.TotalTime_us / perfData.ConnectionClosed.Samples),
WiredHome 16:ab1867ffcf94 162 perfData.ConnectionClosed.Samples,
WiredHome 16:ab1867ffcf94 163 (unsigned long)(perfData.ConnectionClosed.MaxTime_us),
WiredHome 16:ab1867ffcf94 164 "Connection Closed");
WiredHome 16:ab1867ffcf94 165 svr->send(buf);
WiredHome 16:ab1867ffcf94 166
WiredHome 16:ab1867ffcf94 167 svr->send(
WiredHome 16:ab1867ffcf94 168 "<tr><td colspan='3'>&nbsp;</td><td><a href='?Reset=false'>Reload</a>"
WiredHome 16:ab1867ffcf94 169 " <a href='?Reset=true'>Reset Metrics</a></td></tr>\r\n"
WiredHome 16:ab1867ffcf94 170 "</table>\r\n"
WiredHome 16:ab1867ffcf94 171 "</blockquote>\r\n");
WiredHome 4:178df829d62b 172
WiredHome 4:178df829d62b 173 // Send bottom of the page
WiredHome 4:178df829d62b 174 svr->send("<br/><a href='/'>back to main</a></body></html>\r\n");
WiredHome 29:14c47d31a9dc 175 ret = HTTPServer::ACCEPT_COMPLETE;
WiredHome 3:b3e21f3306a1 176 break;
WiredHome 3:b3e21f3306a1 177 case HTTPServer::CONTENT_LENGTH_REQUEST:
WiredHome 29:14c47d31a9dc 178 ret = HTTPServer::ACCEPT_COMPLETE;
WiredHome 3:b3e21f3306a1 179 break;
WiredHome 3:b3e21f3306a1 180 case HTTPServer::DATA_TRANSFER:
WiredHome 29:14c47d31a9dc 181 ret = HTTPServer::ACCEPT_COMPLETE;
WiredHome 3:b3e21f3306a1 182 break;
WiredHome 3:b3e21f3306a1 183 default:
WiredHome 29:14c47d31a9dc 184 ret = HTTPServer::ACCEPT_ERROR;
WiredHome 3:b3e21f3306a1 185 break;
WiredHome 3:b3e21f3306a1 186 }
WiredHome 3:b3e21f3306a1 187 return ret;
WiredHome 3:b3e21f3306a1 188 }
WiredHome 3:b3e21f3306a1 189
WiredHome 3:b3e21f3306a1 190 /// SimplyDynamicForm
WiredHome 3:b3e21f3306a1 191 ///
WiredHome 14:85c805890454 192 /// This web page is generated dynamically and fills in part of the information from
WiredHome 3:b3e21f3306a1 193 /// data extracted from the URL. It also generates a web form, and allows you to
WiredHome 14:85c805890454 194 /// update the data in the form using the POST method. This one also updates the
WiredHome 11:183b3893eb7d 195 /// leds on the mbed module based on the form submission, so demonstrates a very
WiredHome 11:183b3893eb7d 196 /// simple interaction with the hardware.
WiredHome 3:b3e21f3306a1 197 ///
WiredHome 3:b3e21f3306a1 198 /// You can see in main how this page was registered.
WiredHome 3:b3e21f3306a1 199 ///
WiredHome 34:77d0f63f612a 200 HTTPServer::CallBackResults SimpleDynamicForm(HTTPServer *svr, HTTPServer::CallBackType type,
WiredHome 34:77d0f63f612a 201 const char * path, const HTTPServer::namevalue *params, int paramcount)
WiredHome 14:85c805890454 202 {
WiredHome 3:b3e21f3306a1 203 char buf[100];
WiredHome 34:77d0f63f612a 204 int iPP = 0;
WiredHome 29:14c47d31a9dc 205 HTTPServer::CallBackResults ret = HTTPServer::ACCEPT_ERROR;
WiredHome 14:85c805890454 206
WiredHome 34:77d0f63f612a 207 INFO("SimpleDynamicForm('', %d, %s, '', %d)", type, path, paramcount);
WiredHome 3:b3e21f3306a1 208 switch (type) {
WiredHome 3:b3e21f3306a1 209 case HTTPServer::SEND_PAGE:
WiredHome 34:77d0f63f612a 210 INFO("send page");
WiredHome 3:b3e21f3306a1 211 // set the LEDs based on a passed in parameter.
WiredHome 34:77d0f63f612a 212 if (pPath) {
WiredHome 34:77d0f63f612a 213 INFO("Parse(%s)", pPath);
WiredHome 34:77d0f63f612a 214 iPP = svr->ParseParameters((char *)pPath);
WiredHome 34:77d0f63f612a 215 } else {
WiredHome 34:77d0f63f612a 216 INFO(" no pPath");
WiredHome 34:77d0f63f612a 217 }
WiredHome 34:77d0f63f612a 218 if (svr->GetParameter("leds")) {
WiredHome 34:77d0f63f612a 219 leds = atoi(svr->GetParameter("leds"));
WiredHome 34:77d0f63f612a 220 }
WiredHome 3:b3e21f3306a1 221 // send the header
WiredHome 3:b3e21f3306a1 222 svr->header(200, "OK", svr->GetSupportedType(".htm")); //svr->header(200, "OK", "Content-Type: text/html\r\n");
WiredHome 3:b3e21f3306a1 223 // send some data
WiredHome 3:b3e21f3306a1 224 svr->send("<html><head><title>Dynamic Page</title></head>\r\n");
WiredHome 3:b3e21f3306a1 225 svr->send("<body>\r\n");
WiredHome 11:183b3893eb7d 226 svr->send("<h1>Smart WiFly Web Server</h1>\r\n");
WiredHome 34:77d0f63f612a 227 svr->send("These forms were generated dynamically. You can add name=value pairs on the URL "
WiredHome 34:77d0f63f612a 228 "which will show up in the forms. Try both the POST and GET methods. \r\n");
WiredHome 34:77d0f63f612a 229 svr->send("Hint: <a href='?leds=7&car=jag&sky=blue'>?leds=7&car=jag&sky=blue</a>"
WiredHome 34:77d0f63f612a 230 " turns on 3 of the 4 blue leds on the mbed.<br/>\r\n");
WiredHome 34:77d0f63f612a 231 sprintf(buf, "%d GET parameters passed to {%s}:<br/>\r\n", paramcount, path);
WiredHome 3:b3e21f3306a1 232 svr->send(buf);
WiredHome 34:77d0f63f612a 233
WiredHome 34:77d0f63f612a 234 svr->send("<table><tr><td><b>Post Form</b></td><td><b>Get Form</b></td></tr>\r\n");
WiredHome 34:77d0f63f612a 235 svr->send("<tr>");
WiredHome 34:77d0f63f612a 236
WiredHome 34:77d0f63f612a 237 if (iPP && paramcount == 0)
WiredHome 34:77d0f63f612a 238 paramcount = iPP;
WiredHome 34:77d0f63f612a 239 for (int i=0; i<2; i++) {
WiredHome 34:77d0f63f612a 240 // each form Post : Get
WiredHome 34:77d0f63f612a 241 sprintf(buf, "<td><form method='%s' action='%s'>\r\n", (i==0) ? "Post" : "Get", path);
WiredHome 34:77d0f63f612a 242 //sprintf(buf, "<form method='post' enctype='multipart/form-data' action='%s'>\r\n", path); // not supported
WiredHome 3:b3e21f3306a1 243 svr->send(buf);
WiredHome 34:77d0f63f612a 244 // show the parameters in a nice format
WiredHome 34:77d0f63f612a 245 svr->send("<table>\r\n");
WiredHome 34:77d0f63f612a 246 for (int i=0; i<paramcount; i++) {
WiredHome 34:77d0f63f612a 247 sprintf(buf, "<tr><td>%d</td><td>%s</td><td><input type='text' name='%s' value='%s'></td></tr>\r\n", i, params[i].name, params[i].name, params[i].value);
WiredHome 34:77d0f63f612a 248 svr->send(buf);
WiredHome 34:77d0f63f612a 249 }
WiredHome 34:77d0f63f612a 250 svr->send("<tr><td colspan='2'>&nbsp;</td><td><input type='submit' value='submit'><input type='reset' value='clear'>"
WiredHome 34:77d0f63f612a 251 " <a href='/'>Back to main</a></td></tr>\r\n");
WiredHome 34:77d0f63f612a 252 svr->send("</table>\r\n");
WiredHome 34:77d0f63f612a 253 svr->send("</form></td>\r\n");
WiredHome 3:b3e21f3306a1 254 }
WiredHome 34:77d0f63f612a 255 svr->send("</tr></table>\r\n");
WiredHome 34:77d0f63f612a 256
WiredHome 3:b3e21f3306a1 257 // see how we're doing with free memory
WiredHome 34:77d0f63f612a 258 svr->send("</body></html>\r\n");
WiredHome 34:77d0f63f612a 259 if (pPath) {
WiredHome 34:77d0f63f612a 260 free(pPath);
WiredHome 34:77d0f63f612a 261 pPath = NULL;
WiredHome 34:77d0f63f612a 262 }
WiredHome 29:14c47d31a9dc 263 ret = HTTPServer::ACCEPT_COMPLETE;
WiredHome 3:b3e21f3306a1 264 break;
WiredHome 3:b3e21f3306a1 265 case HTTPServer::CONTENT_LENGTH_REQUEST:
WiredHome 34:77d0f63f612a 266 INFO("cont len req");
WiredHome 29:14c47d31a9dc 267 ret = HTTPServer::ACCEPT_COMPLETE;
WiredHome 3:b3e21f3306a1 268 break;
WiredHome 3:b3e21f3306a1 269 case HTTPServer::DATA_TRANSFER:
WiredHome 34:77d0f63f612a 270 INFO("data transfer");
WiredHome 34:77d0f63f612a 271 pPath = (char *)malloc(strlen(path));
WiredHome 34:77d0f63f612a 272 if (pPath) {
WiredHome 34:77d0f63f612a 273 strcpy(pPath, path);
WiredHome 34:77d0f63f612a 274 INFO(" pPath %s", pPath);
WiredHome 34:77d0f63f612a 275 }
WiredHome 34:77d0f63f612a 276 INFO(" dt exit.");
WiredHome 34:77d0f63f612a 277 ret = HTTPServer::ACCEPT_COMPLETE;
WiredHome 34:77d0f63f612a 278 break;
WiredHome 34:77d0f63f612a 279 case HTTPServer::DATA_TRANSFER_END:
WiredHome 34:77d0f63f612a 280 INFO("data transfer end");
WiredHome 29:14c47d31a9dc 281 ret = HTTPServer::ACCEPT_COMPLETE;
WiredHome 3:b3e21f3306a1 282 break;
WiredHome 3:b3e21f3306a1 283 default:
WiredHome 34:77d0f63f612a 284 INFO("error");
WiredHome 34:77d0f63f612a 285 if (pPath) {
WiredHome 34:77d0f63f612a 286 free(pPath);
WiredHome 34:77d0f63f612a 287 pPath = NULL;
WiredHome 34:77d0f63f612a 288 }
WiredHome 29:14c47d31a9dc 289 ret = HTTPServer::ACCEPT_ERROR;
WiredHome 3:b3e21f3306a1 290 break;
WiredHome 3:b3e21f3306a1 291 }
WiredHome 3:b3e21f3306a1 292 return ret;
WiredHome 3:b3e21f3306a1 293 }
WiredHome 7:72b5df2fac93 294