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:
Mon Feb 02 03:03:08 2015 +0000
Revision:
38:962d71d6dd0e
Parent:
36:5ca4a8b8d888
Refresh update, bug fix, mbed application board compatibility.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WiredHome 4:178df829d62b 1 /** @file main.cpp contains the main program that a user would write.
WiredHome 4:178df829d62b 2 * see the documentation above "main"
WiredHome 4:178df829d62b 3 */
WiredHome 38:962d71d6dd0e 4 #include "mbed.h" // testing ver 92, last stable v89
WiredHome 35:87d3577800dc 5 #include "RawSerial.h"
WiredHome 30:4717cc1f970e 6
WiredHome 4:178df829d62b 7 // My components
WiredHome 38:962d71d6dd0e 8 #include "IniManager.h"
WiredHome 29:14c47d31a9dc 9 #include "Utility.h" // a couple of simple helper functions
WiredHome 33:41ac99847df8 10 #include "WiflyInterface.h" // ver 53, derived from mbed official ver 4
WiredHome 32:34dae3cae1b0 11 #include "SW_HTTPServer.h" // ver 31, derived from nweb
WiredHome 10:b0b6da272a7b 12 #include "DynamicPages.h" // my dynamically generated pages
WiredHome 38:962d71d6dd0e 13 #include "SecurePage.h" // my secure pages
WiredHome 38:962d71d6dd0e 14 #include "ServerConfig.h" // various configuration options
WiredHome 38:962d71d6dd0e 15 #include "DynamicFileIn.h" // Upload a file to the server
WiredHome 38:962d71d6dd0e 16 //#include "MSCFileSystem.h" // ver 1, this and SDFileSystem
WiredHome 38:962d71d6dd0e 17 //#include "SDFileSystem.h" // ver 1, this and MSCFileSystem
WiredHome 35:87d3577800dc 18
WiredHome 35:87d3577800dc 19 #define MBED_APP_BOARD 1 /* http://mbed.org/components/mbed-Application-Board/ */
WiredHome 35:87d3577800dc 20 #define SMART_BOARD 2 /* http://mbed.org/users/WiredHome/notebook/SmartBoard-baseboard/ */
WiredHome 35:87d3577800dc 21
WiredHome 35:87d3577800dc 22 #define HW_ADAPTER MBED_APP_BOARD /* Which board are we compiling against? SMART_BOARD or MBED_APP_BOARD */
WiredHome 15:1f2b62130ffb 23
WiredHome 38:962d71d6dd0e 24 #if HW_ADAPTER == MBED_APP_BOARD
WiredHome 38:962d71d6dd0e 25 #include "C12832.h"
WiredHome 38:962d71d6dd0e 26
WiredHome 38:962d71d6dd0e 27 C12832 lcd(p5, p7, p6, p8, p11);
WiredHome 38:962d71d6dd0e 28 #endif
WiredHome 38:962d71d6dd0e 29
WiredHome 10:b0b6da272a7b 30 #define HTTP_SERVER_PORT 80
WiredHome 4:178df829d62b 31
WiredHome 35:87d3577800dc 32 RawSerial pc(USBTX, USBRX);
WiredHome 11:183b3893eb7d 33
WiredHome 38:962d71d6dd0e 34 LocalFileSystem local("local"); // some place to hold settings and maybe the static web pages
WiredHome 38:962d71d6dd0e 35 //MSCFileSystem msc("msc"); // Mass Storage on USB
WiredHome 38:962d71d6dd0e 36 //SDFileSystem sd(p5, p6, p7, p8, "sd"); // for the static web pages
WiredHome 38:962d71d6dd0e 37 #define WEBROOT "/local"
WiredHome 38:962d71d6dd0e 38
WiredHome 38:962d71d6dd0e 39 PwmOut signOfLife(LED1);
WiredHome 38:962d71d6dd0e 40
WiredHome 38:962d71d6dd0e 41 Timer onceinawhile;
WiredHome 38:962d71d6dd0e 42
WiredHome 38:962d71d6dd0e 43 /// ShowSignOfLife
WiredHome 38:962d71d6dd0e 44 ///
WiredHome 38:962d71d6dd0e 45 /// Pulse an LED to indicate a sign of life of the program.
WiredHome 38:962d71d6dd0e 46 /// also has some moderate entertainment value.
WiredHome 38:962d71d6dd0e 47 ///
WiredHome 38:962d71d6dd0e 48 void ShowSignOfLife() {
WiredHome 38:962d71d6dd0e 49 #define PI 3.14159265359
WiredHome 38:962d71d6dd0e 50 static Timer activityTimer;
WiredHome 38:962d71d6dd0e 51 static unsigned int activityStart;
WiredHome 38:962d71d6dd0e 52 static bool init;
WiredHome 38:962d71d6dd0e 53 //static float currentBrightness = 0.0;
WiredHome 38:962d71d6dd0e 54 static int degrees = 0;
WiredHome 38:962d71d6dd0e 55 float v;
WiredHome 38:962d71d6dd0e 56 //static bool rampUp = true;
WiredHome 38:962d71d6dd0e 57
WiredHome 38:962d71d6dd0e 58 if (!init) {
WiredHome 38:962d71d6dd0e 59 activityTimer.start();
WiredHome 38:962d71d6dd0e 60 activityStart = (unsigned int) activityTimer.read_ms();
WiredHome 38:962d71d6dd0e 61 init = true;
WiredHome 38:962d71d6dd0e 62 }
WiredHome 38:962d71d6dd0e 63 if ((unsigned int)activityTimer.read_ms() - activityStart > 20) {
WiredHome 38:962d71d6dd0e 64
WiredHome 38:962d71d6dd0e 65 v = sin(degrees * PI / 180);
WiredHome 38:962d71d6dd0e 66 if (v < 0)
WiredHome 38:962d71d6dd0e 67 v = 0;
WiredHome 38:962d71d6dd0e 68 signOfLife = v;
WiredHome 38:962d71d6dd0e 69 degrees += 2;
WiredHome 38:962d71d6dd0e 70 activityStart = (unsigned int) activityTimer.read_ms();
WiredHome 38:962d71d6dd0e 71 }
WiredHome 38:962d71d6dd0e 72 }
WiredHome 38:962d71d6dd0e 73
WiredHome 38:962d71d6dd0e 74 // A time-bound hook on startup to permit the user to access the wifly module
WiredHome 38:962d71d6dd0e 75 //
WiredHome 38:962d71d6dd0e 76 void WiFlyShell(Wifly & wifly, PC & pc)
WiredHome 38:962d71d6dd0e 77 {
WiredHome 38:962d71d6dd0e 78 Timer userTimer;
WiredHome 38:962d71d6dd0e 79 const int baudrates[] = {2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400};
WiredHome 38:962d71d6dd0e 80 static int i = 0;
WiredHome 38:962d71d6dd0e 81
WiredHome 38:962d71d6dd0e 82 pc.printf("Pausing 5 sec for shell access to WiFly (press <enter>).\r\n");
WiredHome 38:962d71d6dd0e 83 userTimer.start();
WiredHome 38:962d71d6dd0e 84 do {
WiredHome 38:962d71d6dd0e 85 if (pc.readable()) {
WiredHome 38:962d71d6dd0e 86 bool loop = true;
WiredHome 38:962d71d6dd0e 87 int c = pc.getc();
WiredHome 38:962d71d6dd0e 88 pc.printf("Shell opened to WiFly module: <esc> to exit,\r\n ctrl-B to reboot, ctrl-C to step baud\r\n");
WiredHome 38:962d71d6dd0e 89 while (loop) {
WiredHome 38:962d71d6dd0e 90 if (pc.readable()) {
WiredHome 38:962d71d6dd0e 91 int c = pc.getc();
WiredHome 38:962d71d6dd0e 92 switch (c) {
WiredHome 38:962d71d6dd0e 93 case '\x1B': // <ESC>
WiredHome 38:962d71d6dd0e 94 loop = false;
WiredHome 38:962d71d6dd0e 95 break;
WiredHome 38:962d71d6dd0e 96 case '\x02': // Ctrl-B
WiredHome 38:962d71d6dd0e 97 wifly.reboot();
WiredHome 38:962d71d6dd0e 98 break;
WiredHome 38:962d71d6dd0e 99 case '\x03': // Ctrl-C
WiredHome 38:962d71d6dd0e 100 pc.printf("Setting to %d baud.\r\n", baudrates[i]);
WiredHome 38:962d71d6dd0e 101 wifly.baud(baudrates[i]);
WiredHome 38:962d71d6dd0e 102 i++;
WiredHome 38:962d71d6dd0e 103 if (i >= (sizeof(baudrates)/sizeof(baudrates[0])))
WiredHome 38:962d71d6dd0e 104 i = 0;
WiredHome 38:962d71d6dd0e 105 break;
WiredHome 38:962d71d6dd0e 106 default:
WiredHome 38:962d71d6dd0e 107 wifly.putc(c);
WiredHome 38:962d71d6dd0e 108 break;
WiredHome 38:962d71d6dd0e 109 }
WiredHome 38:962d71d6dd0e 110 }
WiredHome 38:962d71d6dd0e 111 if (wifly.readable())
WiredHome 38:962d71d6dd0e 112 pc.putc(wifly.getc());
WiredHome 38:962d71d6dd0e 113 }
WiredHome 38:962d71d6dd0e 114 }
WiredHome 38:962d71d6dd0e 115 } while (userTimer.read_ms() < 5000);
WiredHome 38:962d71d6dd0e 116 pc.printf(" WiFly shell closed.\r\n");
WiredHome 38:962d71d6dd0e 117 }
WiredHome 11:183b3893eb7d 118
WiredHome 11:183b3893eb7d 119
WiredHome 38:962d71d6dd0e 120 /// Smart-WiFly-WebServer is the creation of a web server using a WiFly module.
WiredHome 38:962d71d6dd0e 121 ///
WiredHome 38:962d71d6dd0e 122 /// This is a working version, but it is not using the standardized wifly
WiredHome 38:962d71d6dd0e 123 /// library, which would not work for me... I had to make a number
WiredHome 38:962d71d6dd0e 124 /// of changes to get it to work well. After trying to minmimize those
WiredHome 38:962d71d6dd0e 125 /// changes, additional improvements became more and more clumsy, so
WiredHome 38:962d71d6dd0e 126 /// I have now been working to refactor where it makes sense, even as
WiredHome 38:962d71d6dd0e 127 /// it further deviates from the mbed-library version.
WiredHome 38:962d71d6dd0e 128 ///
WiredHome 38:962d71d6dd0e 129 /// I created this because I couldn't find one that worked and wanted to
WiredHome 38:962d71d6dd0e 130 /// learn the WiFly module. There are a lot of possible improvements:
WiredHome 38:962d71d6dd0e 131 /// @li I think I'm not using the Socket interface as fully as I should.
WiredHome 38:962d71d6dd0e 132 /// @li I would like it to be faster (the interface from mbed to wifly is
WiredHome 38:962d71d6dd0e 133 /// limited to 230400 baud before it drops chars. HW handshake could
WiredHome 38:962d71d6dd0e 134 /// improve this, but the HW handshake pins on the LPC1768 are not
WiredHome 38:962d71d6dd0e 135 /// both brought out.
WiredHome 38:962d71d6dd0e 136 /// @li I would like to integrate this with the rtos.
WiredHome 38:962d71d6dd0e 137 /// @li If a page has multiple components (e.g. images), it appears
WiredHome 38:962d71d6dd0e 138 /// unreliable. It doesn't see the request for the extra component.
WiredHome 38:962d71d6dd0e 139 /// A poor workaround, for images, is to use a javascript to post-
WiredHome 38:962d71d6dd0e 140 /// load them. This is fundamentally a constraint of the WiFly module.
WiredHome 38:962d71d6dd0e 141 ///
WiredHome 38:962d71d6dd0e 142 /// history:
WiredHome 38:962d71d6dd0e 143 /// @li 20130602 added .txt to the supported types (e.g. robots.txt), so
WiredHome 38:962d71d6dd0e 144 /// revised the credentials to .crd, which is an unsupported type
WiredHome 38:962d71d6dd0e 145 /// therefore won't be delivered to the user.
WiredHome 38:962d71d6dd0e 146 ///
WiredHome 38:962d71d6dd0e 147 /// @note Copyright &copy; 2013 by Smartware Computing, all rights reserved.
WiredHome 38:962d71d6dd0e 148 /// Individuals may use this application for evaluation or non-commercial
WiredHome 38:962d71d6dd0e 149 /// purposes. Within this restriction, changes may be made to this application
WiredHome 38:962d71d6dd0e 150 /// as long as this copyright notice is retained. The user shall make
WiredHome 38:962d71d6dd0e 151 /// clear that their work is a derived work, and not the original.
WiredHome 38:962d71d6dd0e 152 /// Users of this application and sources accept this application "as is" and
WiredHome 38:962d71d6dd0e 153 /// shall hold harmless Smartware Computing, for any undesired results while
WiredHome 38:962d71d6dd0e 154 /// using this application - whether real or imagined.
WiredHome 38:962d71d6dd0e 155 ///
WiredHome 38:962d71d6dd0e 156 /// @author David Smart, Smartware Computing
WiredHome 38:962d71d6dd0e 157 ///
WiredHome 10:b0b6da272a7b 158 int main()
WiredHome 10:b0b6da272a7b 159 {
WiredHome 38:962d71d6dd0e 160 char ssid[60], pass[60];
WiredHome 38:962d71d6dd0e 161 INI ini("/local/config.ini"); // handles the credentials
WiredHome 38:962d71d6dd0e 162
WiredHome 35:87d3577800dc 163 pc.baud(460800); // I like a snappy terminal, so crank it up!
WiredHome 14:85c805890454 164 pc.printf("\r\nSmart WiFly - Build " __DATE__ " " __TIME__ "\r\n");
WiredHome 4:178df829d62b 165
WiredHome 38:962d71d6dd0e 166 if (!ini.ReadString("Wifi", "ssid", ssid, sizeof(ssid))
WiredHome 38:962d71d6dd0e 167 || !ini.ReadString("Wifi", "pass", pass, sizeof(pass))) {
WiredHome 38:962d71d6dd0e 168 pc.printf("**** ERROR, credentials not found. ****\r\n");
WiredHome 38:962d71d6dd0e 169 wait(1.0);
WiredHome 38:962d71d6dd0e 170 error(" Waiting for user to fix this problem. \r\n"); // flash and die
WiredHome 38:962d71d6dd0e 171 }
WiredHome 38:962d71d6dd0e 172
WiredHome 35:87d3577800dc 173 // first signals are tx, rx, reset, status pins.
WiredHome 35:87d3577800dc 174 #if HW_ADAPTER == MBED_APP_BOARD
WiredHome 38:962d71d6dd0e 175 WiflyInterface wifly( p9, p10, p30, p29, ssid, pass, WPA);
WiredHome 35:87d3577800dc 176 #elif HW_ADAPTER == SMART_BOARD
WiredHome 38:962d71d6dd0e 177 WiflyInterface wifly(p28, p27, p23, p24, ssid, pass, WPA);
WiredHome 35:87d3577800dc 178 #endif
WiredHome 4:178df829d62b 179
WiredHome 15:1f2b62130ffb 180 // Bring the WiFly interface online
WiredHome 11:183b3893eb7d 181 do {
WiredHome 10:b0b6da272a7b 182 wifly.init(); // start it up as a client of my network using DHCP
WiredHome 38:962d71d6dd0e 183 wifly.baud(230400); // Only 230K w/o HW flow control
WiredHome 35:87d3577800dc 184 if (0 == wifly.connect())
WiredHome 10:b0b6da272a7b 185 break;
WiredHome 10:b0b6da272a7b 186 pc.printf(" Failed to connect, retrying...\r\n");
WiredHome 10:b0b6da272a7b 187 wait(1.0);
WiredHome 4:178df829d62b 188 wifly.reset();
WiredHome 10:b0b6da272a7b 189 } while (1);
WiredHome 38:962d71d6dd0e 190
WiredHome 35:87d3577800dc 191 // Let the human know it is ready - if they are watching
WiredHome 35:87d3577800dc 192 pc.printf("Connect to this server at http://%s:%d\r\n", wifly.getIPAddress(), HTTP_SERVER_PORT);
WiredHome 4:178df829d62b 193
WiredHome 38:962d71d6dd0e 194 #if HW_ADAPTER == MBED_APP_BOARD
WiredHome 38:962d71d6dd0e 195 lcd.cls();
WiredHome 38:962d71d6dd0e 196 lcd.locate(0,3);
WiredHome 38:962d71d6dd0e 197 lcd.printf("mbed application board!\r\n");
WiredHome 38:962d71d6dd0e 198 lcd.printf("http://%s:%d", wifly.getIPAddress(), HTTP_SERVER_PORT);
WiredHome 38:962d71d6dd0e 199 #endif
WiredHome 38:962d71d6dd0e 200
WiredHome 12:479ff89c190b 201 // Now let's instantiate the web server - along with a few settings:
WiredHome 12:479ff89c190b 202 // the Wifly object, the port of interest (typically 80),
WiredHome 35:87d3577800dc 203 // file system path to the static pages, if any.
WiredHome 12:479ff89c190b 204 // the maximum parameters per transaction (in the query string),
WiredHome 12:479ff89c190b 205 // the maximum number of dynamic pages that can be registered,
WiredHome 12:479ff89c190b 206 // the serial port back thru USB (for development/logging)
WiredHome 38:962d71d6dd0e 207 HTTPServer svr(HTTP_SERVER_PORT, WEBROOT, 15, 30, 10, &pc);
WiredHome 10:b0b6da272a7b 208
WiredHome 4:178df829d62b 209 // But for even more fun, I'm registering a few dynamic pages
WiredHome 15:1f2b62130ffb 210 // You see the handlers for in DynamicPages.cpp.
WiredHome 4:178df829d62b 211 // Here you can see the path to place on the URL.
WiredHome 4:178df829d62b 212 // ex. http://192.168.1.140/dyn
WiredHome 38:962d71d6dd0e 213 //svr.RegisterHandler("/", SuperSimpleDynamicPage);
WiredHome 35:87d3577800dc 214 svr.RegisterHandler("/dyn", SimpleDynamicPage);
WiredHome 35:87d3577800dc 215 svr.RegisterHandler("/led", SimpleDynamicForm);
WiredHome 38:962d71d6dd0e 216
WiredHome 38:962d71d6dd0e 217 svr.RegisterHandler("/dyn1", SimpleDynamicPage);
WiredHome 38:962d71d6dd0e 218 svr.RegisterHandler("/dyn2", SimpleDynamicForm);
WiredHome 38:962d71d6dd0e 219 svr.RegisterHandler("/pass", SimpleSecurityCheck);
WiredHome 38:962d71d6dd0e 220 svr.RegisterHandler("/config", ServerConfig);
WiredHome 38:962d71d6dd0e 221 svr.RegisterHandler("/FileIn", DynamicFileIn);
WiredHome 35:87d3577800dc 222
WiredHome 38:962d71d6dd0e 223 onceinawhile.start();
WiredHome 10:b0b6da272a7b 224 while (true) {
WiredHome 38:962d71d6dd0e 225 if (onceinawhile.read_ms() >= 200)
WiredHome 38:962d71d6dd0e 226 {
WiredHome 38:962d71d6dd0e 227 onceinawhile.reset();
WiredHome 38:962d71d6dd0e 228 //pc.printf("Largest free mem block is %d\r\n", Free());
WiredHome 38:962d71d6dd0e 229 ShowSignOfLife();
WiredHome 38:962d71d6dd0e 230 }
WiredHome 33:41ac99847df8 231 svr.Poll(); // non-blocking, but also not deterministic
WiredHome 38:962d71d6dd0e 232 if (pc.readable())
WiredHome 38:962d71d6dd0e 233 WiFlyShell(wifly, pc); // allow shell access at runtime (if user taps a key)
WiredHome 10:b0b6da272a7b 234 }
WiredHome 4:178df829d62b 235 }
WiredHome 24:849cbe0b36ac 236