Dependencies:   mbed lwip

Files at this revision

API Documentation at this revision

Comitter:
iva2k
Date:
Thu Dec 10 08:59:18 2009 +0000
Commit message:

Changed in this revision

HTTPDynamicPage.h Show annotated file Show diff for this revision Revisions of this file
lwip.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r b0aa20381646 HTTPDynamicPage.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPDynamicPage.h	Thu Dec 10 08:59:18 2009 +0000
@@ -0,0 +1,96 @@
+#ifndef HTTPDYNAMICPAGE_H
+#define HTTPDYNAMICPAGE_H
+
+#include "HTTPServer.h"
+
+/**
+ * A datastorage helper for the HTTPDynamicPage class.
+ * Stores dynamically created page data and the size left to upload.
+ */
+class HTTPDynamicPageData : public HTTPData {
+  public:
+    HTTPDynamicPageData()
+     : page_free(NULL), page(NULL), size(0), _left(0) {}
+    virtual ~HTTPDynamicPageData() {
+      if (page_free && page) {
+          page_free(page);
+      }
+    }
+
+    /** Pointer to garbage collection function (for freeing page data)
+     * Should be set by callback function to a suitable free() if page is dynamically allocated
+     */
+    void (*page_free)(void *page);
+    
+    /** Pointer to the page data */
+    char *page;
+    
+    /** Page data size
+     * As long as the page is NULL terminated you don't have to tell the data length.
+     * But if you want to send binary data you should tell us the size.
+     */
+    int size;
+
+    /** Page data size left for the upload */
+    int _left;
+};
+
+/**
+ * This class Provide a Handler to send Static HTTP Pages from the bin file.
+ */
+class HTTPDynamicPage : public HTTPHandler {
+  public:
+    /**
+     * Constructor takes the page path and the page callback function.
+     */
+    HTTPDynamicPage(const char *path, HTTPStatus page_fnc(HTTPConnection *con, HTTPDynamicPageData *pd))
+     : HTTPHandler(path), _page_fnc(page_fnc) {
+    }
+
+    HTTPDynamicPage(HTTPServer *server, const char *path, HTTPStatus page_fnc(HTTPConnection *con, HTTPDynamicPageData *pd))
+     : HTTPHandler(path), _page_fnc(page_fnc) {
+      server->addHandler(this);
+    }
+
+  private:
+    /**
+     * This Dynamic Page is requested!
+     * Prepare a datastorage helper "HTTPDynamicPageData", create the page and store in helper, then initialize remaining data size.
+     * And return HTTP_OK if all ok.
+     */
+    virtual HTTPStatus init(HTTPConnection *con) const {
+      HTTPDynamicPageData *data = new HTTPDynamicPageData();
+      con->data = data;
+      HTTPStatus status = _page_fnc(con, data);    // assigns data->page, data->size and optionally data->page_free
+      if (!data->size && data->page)
+          data->size = strlen(data->page);
+      data->_left = data->size;
+      con->setLength(data->size);
+      return status;
+    }
+
+    /**
+     * Send the maximum data out to the client. 
+     * If the file is complete transmitted close connection by returning HTTP_SuccessEnded
+     */
+    virtual HTTPHandle send(HTTPConnection *con, int maximum) const {
+      HTTPDynamicPageData *data = static_cast<HTTPDynamicPageData *>(con->data);
+      int len = min(maximum, data->_left);
+      err_t err;
+
+      do {
+        err = con->write((void*)&data->page[data->size - data->_left], len, 1);
+        if (err == ERR_MEM) {
+          len >>= 1;
+        }
+      } while(err == ERR_MEM && len > 1);
+      if (err == ERR_OK) {
+        data->_left -= len;
+      }
+      return (data->_left) ? HTTP_Success : HTTP_SuccessEnded;
+    }
+
+    HTTPStatus (*_page_fnc)(HTTPConnection *con, HTTPDynamicPageData *pd);
+};
+
+#endif
diff -r 000000000000 -r b0aa20381646 lwip.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwip.lib	Thu Dec 10 08:59:18 2009 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_unsupported/code/lwip/
\ No newline at end of file
diff -r 000000000000 -r b0aa20381646 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Dec 10 08:59:18 2009 +0000
@@ -0,0 +1,127 @@
+#include "mbed.h"
+#include "HTTPServer.h"
+#include "HTTPFS.h"
+#include "HTTPDynamicPage.h"
+
+#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");
+
+#define LED_ETH_LINK(val) do { led4=val; } while (0)
+
+extern Ethernet eth;        // eth is defined elsewhere, avoid compiler error.
+Serial pc(USBTX, USBRX);
+Ticker eth_timer;
+
+void eth_link_status() {
+    static bool first = true;           // Avoid duplicate IP report on the very first pass
+    static int eth_link = -1;           // Last state of eth link
+    static unsigned int old_ip = 0;     // Last IP address
+    int new_link = eth.link();
+    if (eth_link != new_link) {
+        if (new_link) {
+            // From http://mbed.org/forum/post/909/
+            NetServer *net = NetServer::get();
+            struct ip_addr ip = net->getIPAddr();
+//            struct ip_addr gw = net->getGateway();
+//            struct ip_addr nm = net->getNetmask();
+//            struct ip_addr dns = net->getDNS1();
+            if (!first) printf("IP: %hhu.%hhu.%hhu.%hhu\r\n", (ip.addr)&0xFF, (ip.addr>>8)&0xFF, (ip.addr>>16)&0xFF, (ip.addr>>24)&0xFF);
+            first = false;
+            if (1 && ip.addr != old_ip) {
+                // Create a link file to our IP.
+                FILE *fp = fopen("/local/Start.url", "w");  // Create link to own IP
+                if (fp) {
+                    fprintf(fp, "[InternetShortcut]\r\nURL=http://%hhu.%hhu.%hhu.%hhu/\r\n", (ip.addr)&0xFF, (ip.addr>>8)&0xFF, (ip.addr>>16)&0xFF, (ip.addr>>24)&0xFF);
+                    fclose(fp);
+                    old_ip = ip.addr;
+                }
+            }
+            
+        }
+        else {
+            printf("IP: <link down>\r\n");
+        }
+        LED_ETH_LINK(new_link);
+        eth_link = new_link;
+    }
+}
+
+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];
+
+    led1=1;
+    led2=1;
+    led3=1;
+    led4=1;
+
+    char *hostname = "mbed";
+    HTTPServer http(hostname);    // Use DHCP
+    http.timeout(60000);    // Sets the timout for a HTTP request.  The timout is the time wich is allowed to spent between two incomming TCP packets.  If the time is passed the connection will be closed.
+
+    eth.address(mac);
+    pc.printf("\r\n\r\nHTTPServer \"%s\" started\r\nMAC %02X:%02X:%02X:%02X:%02X:%02X\r\n",
+        hostname, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+
+    led1=0;
+
+    led2=0;
+
+    http.addHandler(new HTTPDynamicPage("/dynamic.htm", &myDynamicPage));
+    led3=0;
+
+// FIXME: BUG If eth is not plugged, http.bind() hangs for awhile!
+    http.bind();
+
+    led4 = 0;
+    eth_timer.attach(&eth_link_status, 0.1);
+    while(1) {
+        http.poll();    // Have to call this method at least every 250ms to let the http server run.
+        wait(0.100);
+    }
+}
+
+//END
\ No newline at end of file
diff -r 000000000000 -r b0aa20381646 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Thu Dec 10 08:59:18 2009 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/49a220cc26e0