Example of HTTPServer with additional features: * SNTPClient, DST rules * Link status indication * Local or SDCard-based WebServer * RPC-able class * Static and Dynamic HTML page
Diff: main.cpp
- Revision:
- 0:886e4b3119ad
- Child:
- 1:ec4170739967
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sun Jan 03 07:00:43 2010 +0000 @@ -0,0 +1,225 @@ +// Written by IVA2K +// +// Example of HTTPServer with additional features: +// * SNTP Client (Simple NTP) +// * Link status indication (LED4 or RJ45 socket LED on MBED-BoB2-mod) +// * Local file system (create index.htm page on MBED!) +// * SD-based WebServer +// * RPC-able class (myrpc, allows remote function call that blinks LED1 N times) +// * Static HTML page +// * Dynamic HTML page +// +// Instructions: +// 1 Plug MBED into MBED-BoB2 (or other ETH connector breakout) +// 2 Plug ETH connector into your network (needs DHCP to get IP address and Internet connection) +// 3 Power up MBED using USB cable +// 4 Install MBED serial driver (http://mbed.org/handbook/SerialPC) +// 5 Copy compiled .bin to your MBED (make sure target device selected in the compiler is correct) +// 6 Open terminal on the mbed serial port +// 7 Push MBED reset button +// 8 Terminal will display info message with mac address, followed by IP address (if connection succeeds) +// in the following items, replace 10.0.0.321 with actual MBED IP address from the terminal +// 9 Open browser and enter the following URL: +// http://10.0.0.321/rpc/myrpc1/blink,10 +// 10 MBED will blink the LED 10 times +// 11 Open browser and enter the following URL: +// http://10.0.0.321/rpc/myrpc1/gettime +// 12 The browser will show date and time from the MBED synchronized to NTP server +// 13 Open browser and enter the following URL: +// http://10.0.0.321/static.htm +// 14 The browser will show static HTML page +// 15 Open browser and enter the following URL: +// http://10.0.0.321/dynamic.htm +// 16 The browser will show dynamic HTML page +// 17 Create a simple index.htm page on the MBED +// 18 Open browser and enter the following URL: +// http://10.0.0.321 +// 19 The browser will show index HTML page +// 20 Create a simple index.htm page on a micro SD card, plug the card into MBED-BoB2 +// 21 Open browser and enter the following URL: +// http://10.0.0.321 +// 22 The browser will show index HTML page from SD card +// 23 Optionally, create file "sntp.ini" on MBED or SD card. Copy-paste SNTP configuration from the terminal into this file and modify to your needs. +// +// Notes: there are still some bugs in HTTPServer code. +// To help fight some of them, copy a valid favicon.ico (a 16x16 icon) file to MBED. +// + +#include "mbed.h" +#include "SDFileSystem.h" +#include "HTTPServer.h" +#include "HTTPRPC.h" +#include "HTTPFS.h" +#include "HTTPStaticPage.h" +#include "HTTPDynamicPage.h" +#include "HTTPLinkStatus.h" +#include "SNTPClient.h" + +#define CLS "\033[2J" + +const char content[] = +"<HTML>" +"<HEAD>" +"<title>Static Page</title>" +"</HEAD>" +"<BODY>" +"<H1>Hello World</H1>" +"<p>Page generated statically from code.</p>" +"</BODY></HTML>" +; + +#define MAX_DYNAMIC_CONTENT_LEN 2048 +char dynamic_content[MAX_DYNAMIC_CONTENT_LEN]; + +const char content_fmt[] = +"<HTML>" +"<HEAD>" +"<title>Dynamic Page</title>" +"</HEAD>" +"<BODY>" +"<H1>Hello World</H1>" +"<p>Page generated dynamically from code.</p>" +"<p>URL=%s</p>" +"<p>Header Fields=%s</p>" +"</BODY></HTML>" +; + +DigitalOut led1(LED1, "led1"); +DigitalOut led2(LED2, "led2"); +DigitalOut led3(LED3, "led3"); +DigitalOut led4(LED4, "led4"); +DigitalIn sw1(p9, "sw1"); +DigitalIn sw2(p10, "sw2"); +LocalFileSystem local("local"); +SDFileSystem sd(p5, p6, p7, p8, "sd"); // MBED-BoB2 + +#include "myrpc.h" +myrpc myrpc1(LED1, "myrpc1"); + +extern Ethernet eth; // eth is defined elsewhere, avoid compiler error. +Serial pc(USBTX, USBRX); +int gDebug=1; +float gWait = 0.005; // Main loop wait timeout + +HTTPStatus myDynamicPage(HTTPConnection *con, HTTPDynamicPageData *pd) { +#if 0 + // Static example. With this, we don't really need HTTPStaticPage + pd->size = 0; // let it measure our page + pd->page = (char*)content; // Nothing dynamic about that yet, but we can now get loose here. + pd->page_free = NULL; // No mem free() needed +#elif 0 + // Dynamic example, static buffer + pd->size = sprintf(dynamic_content, content_fmt, con->getURL(), con->getHeaderFields()); + pd->page = (char*)dynamic_content; + pd->page_free = NULL; // No mem free() needed +if(pd->size > sizeof(dynamic_content)) printf("ASSERTION FAILED: %s:%d\r\n", __FILE__, __LINE__); // Buffer overrun +#else + // Dynamic example, dynamic buffer + int size = sizeof(content_fmt) + 512; // Just guess how much the data will expand + char *buf = (char *)malloc(size); + if (buf) { + pd->size = sprintf(buf, content_fmt, con->getURL(), con->getHeaderFields()); + pd->page = buf; + pd->page_free = &free; // Use free() when done +if(pd->size > size) printf("ASSERTION FAILED: %s:%d\r\n", __FILE__, __LINE__); // Buffer overrun +#endif + } + return HTTP_OK; +} + +int main(void) { + char mac[6]; + int sw1_old=0, sw2_old=0; + bool use_sd = false; + + led1=1; + led2=1; + led3=1; + led4=1; + + // Start RTC + time_t seconds = time(NULL); + if (seconds == (unsigned)-1 || seconds == 0) { + seconds = 1256729737; // Set RTC time to Wed, 28 Oct 2009 11:35:37 + set_time(seconds); + printf("RTC initialized, start time %d seconds\r\n", seconds); + } + + char *hostname = "mbed"; + HTTPServer http(hostname); // Use DHCP + http.timeout(10000); // Sets the timout for a HTTP request. The timout is the time which is allowed to spent between two incomming TCP packets. If the time is passed the connection will be closed. + + eth.address(mac); + pc.printf(CLS "\r\n\r\nHTTPServer \"%s\" started\r\nMAC %02X:%02X:%02X:%02X:%02X:%02X\r\n%s", + hostname, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], + gDebug?"Debug is ON\r\n":"" + ); + + Base::add_rpc_class<AnalogIn>(); + Base::add_rpc_class<AnalogOut>(); + Base::add_rpc_class<DigitalIn>(); + Base::add_rpc_class<DigitalOut>(); + Base::add_rpc_class<PwmOut>(); + Base::add_rpc_class<Timer>(); + Base::add_rpc_class<SPI>(); + Base::add_rpc_class<BusOut>(); + Base::add_rpc_class<BusIn>(); + Base::add_rpc_class<myrpc>(); + led1=0; + + // Check if we can use SD card for the web server + FILE *fp = fopen("/sd/index.htm", "r"); + if (fp == NULL) { + if (gDebug) printf("DEBUG: No SD card found or no index.htm file - using LocalFilesystem for WebServer.\r\n"); + } else { + use_sd = true; + fclose(fp); + if (gDebug) printf("DEBUG: Found SD card with index.htm file - using SD for WebServer.\r\n"); + } + + if (0 != SNTPReadIniFile("/sd/sntp.ini") ) + SNTPReadIniFile("/local/sntp.ini"); + SNTPWriteIniFile(stdout); + + + http.addHandler(new HTTPLinkStatus("/", +#if 0 + p25, p26, // MBED-BoB2-mods +#else + LED3, LED4, +#endif + 0.1, + /*do_urlfile*/ true, /*do_link_printf*/ true, /*do_log_printf*/ false, + /*log_file*/ ( (gDebug>1) ? (use_sd ? "/sd/httpd.log" : "/local/httpd.log") : NULL) + )); // Should be the first handler to get a preview of all requests + http.addHandler(new HTTPRPC()); + led2=0; + + // Static/Dynamic pages must be installed before FileSystem on / + http.addHandler(new HTTPStaticPage("/static.htm", content, strlen(content))); + http.addHandler(new HTTPDynamicPage("/dynamic.htm", &myDynamicPage)); + http.addHandler(new HTTPFileSystemHandler("/", use_sd ? "/sd/" : "/local/")); + led3=0; + +// FIXME: BUG If eth is not plugged, http.bind() hangs! + http.bind(); + + SNTPClientInit(); + led4 = 0; + + pc.printf("\r"); // Add linefeed for stupid Hyperterminal + while(1) { + http.poll(); // Have to call this method at least every 250ms to let the http server run. + if (sw1 & !sw1_old) { + printf("SW1\r\n"); + } + if (sw2 && !sw2_old) { + printf(CLS "SW2\r\n"); + } + sw1_old = sw1; + sw2_old = sw2; + wait(gWait); + } +} + +//END \ No newline at end of file