From 47a46ded918c6d1eabeac32428bacc94030957c5 Mon Sep 17 00:00:00 2001 From: julienabeille Date: Tue, 14 Oct 2008 10:14:13 +0000 Subject: [PATCH] webserver app for RAVEN platform --- apps/raven-webserver/Makefile.webserver | 6 + apps/raven-webserver/http-strings | 35 + apps/raven-webserver/http-strings.c | 102 +++ apps/raven-webserver/http-strings.h | 34 + apps/raven-webserver/httpd-cfs.c | 244 +++++++ apps/raven-webserver/httpd-cfs.h | 56 ++ apps/raven-webserver/httpd-cgi.c | 330 +++++++++ apps/raven-webserver/httpd-cgi.h | 59 ++ apps/raven-webserver/httpd-fs.c | 128 ++++ apps/raven-webserver/httpd-fs.h | 65 ++ apps/raven-webserver/httpd-fs/404.html | 8 + apps/raven-webserver/httpd-fs/files.shtml | 24 + apps/raven-webserver/httpd-fs/footer.html | 2 + apps/raven-webserver/httpd-fs/header.html | 29 + apps/raven-webserver/httpd-fs/index.html | 41 ++ apps/raven-webserver/httpd-fs/processes.shtml | 5 + apps/raven-webserver/httpd-fs/sensor.shtml | 5 + apps/raven-webserver/httpd-fs/style.css | 239 +++++++ apps/raven-webserver/httpd-fs/tcp.shtml | 5 + apps/raven-webserver/httpd-fs/upload.html | 8 + apps/raven-webserver/httpd-fsdata.c | 666 ++++++++++++++++++ apps/raven-webserver/httpd-fsdata.h | 64 ++ apps/raven-webserver/httpd.c | 364 ++++++++++ apps/raven-webserver/httpd.h | 63 ++ apps/raven-webserver/webserver-dsc.c | 73 ++ apps/raven-webserver/webserver-dsc.h | 42 ++ apps/raven-webserver/webserver-nogui.c | 83 +++ apps/raven-webserver/webserver-nogui.h | 46 ++ apps/raven-webserver/webserver.c | 127 ++++ apps/raven-webserver/webserver.h | 45 ++ 30 files changed, 2998 insertions(+) create mode 100644 apps/raven-webserver/Makefile.webserver create mode 100644 apps/raven-webserver/http-strings create mode 100644 apps/raven-webserver/http-strings.c create mode 100644 apps/raven-webserver/http-strings.h create mode 100644 apps/raven-webserver/httpd-cfs.c create mode 100644 apps/raven-webserver/httpd-cfs.h create mode 100644 apps/raven-webserver/httpd-cgi.c create mode 100644 apps/raven-webserver/httpd-cgi.h create mode 100644 apps/raven-webserver/httpd-fs.c create mode 100644 apps/raven-webserver/httpd-fs.h create mode 100644 apps/raven-webserver/httpd-fs/404.html create mode 100644 apps/raven-webserver/httpd-fs/files.shtml create mode 100644 apps/raven-webserver/httpd-fs/footer.html create mode 100644 apps/raven-webserver/httpd-fs/header.html create mode 100644 apps/raven-webserver/httpd-fs/index.html create mode 100644 apps/raven-webserver/httpd-fs/processes.shtml create mode 100644 apps/raven-webserver/httpd-fs/sensor.shtml create mode 100644 apps/raven-webserver/httpd-fs/style.css create mode 100644 apps/raven-webserver/httpd-fs/tcp.shtml create mode 100644 apps/raven-webserver/httpd-fs/upload.html create mode 100644 apps/raven-webserver/httpd-fsdata.c create mode 100644 apps/raven-webserver/httpd-fsdata.h create mode 100644 apps/raven-webserver/httpd.c create mode 100644 apps/raven-webserver/httpd.h create mode 100644 apps/raven-webserver/webserver-dsc.c create mode 100644 apps/raven-webserver/webserver-dsc.h create mode 100644 apps/raven-webserver/webserver-nogui.c create mode 100644 apps/raven-webserver/webserver-nogui.h create mode 100644 apps/raven-webserver/webserver.c create mode 100644 apps/raven-webserver/webserver.h diff --git a/apps/raven-webserver/Makefile.webserver b/apps/raven-webserver/Makefile.webserver new file mode 100644 index 000000000..fb39f3545 --- /dev/null +++ b/apps/raven-webserver/Makefile.webserver @@ -0,0 +1,6 @@ +webserver_src = webserver-nogui.c httpd.c http-strings.c psock.c memb.c \ + httpd-fs.c httpd-cgi.c +webserver_dsc = webserver-dsc.c + +#$(CONTIKI)/apps/webserver/http-strings.c: $(CONTIKI)/apps/webserver/http-strings +# cd $(CONTIKI)/apps/webserver/; $(CONTIKI)/tools/makestrings $< diff --git a/apps/raven-webserver/http-strings b/apps/raven-webserver/http-strings new file mode 100644 index 000000000..3e86d8af5 --- /dev/null +++ b/apps/raven-webserver/http-strings @@ -0,0 +1,35 @@ +http_http "http://" +http_200 "200 " +http_301 "301 " +http_302 "302 " +http_get "GET " +http_10 "HTTP/1.0" +http_11 "HTTP/1.1" +http_content_type "content-type: " +http_texthtml "text/html" +http_location "location: " +http_host "host: " +http_crnl "\r\n" +http_index_html "/index.html" +http_404_html "/404.html" +http_referer "Referer:" +http_header_200 "HTTP/1.0 200 OK\r\nServer: Contiki/2.0 http://www.sics.se/contiki/\r\nConnection: close\r\n" +http_header_404 "HTTP/1.0 404 Not found\r\nServer: Contiki/2.0 http://www.sics.se/contiki/\r\nConnection: close\r\n" +http_content_type_plain "Content-type: text/plain\r\n\r\n" +http_content_type_html "Content-type: text/html\r\n\r\n" +http_content_type_css "Content-type: text/css\r\n\r\n" +http_content_type_text "Content-type: text/text\r\n\r\n" +http_content_type_png "Content-type: image/png\r\n\r\n" +http_content_type_gif "Content-type: image/gif\r\n\r\n" +http_content_type_jpg "Content-type: image/jpeg\r\n\r\n" +http_content_type_binary "Content-type: application/octet-stream\r\n\r\n" +http_html ".html" +http_shtml ".shtml" +http_htm ".htm" +http_css ".css" +http_png ".png" +http_gif ".gif" +http_jpg ".jpg" +http_text ".text" +http_txt ".txt" + diff --git a/apps/raven-webserver/http-strings.c b/apps/raven-webserver/http-strings.c new file mode 100644 index 000000000..f6b86dae6 --- /dev/null +++ b/apps/raven-webserver/http-strings.c @@ -0,0 +1,102 @@ +const char http_http[8] = +/* "http://" */ +{0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, }; +const char http_200[5] = +/* "200 " */ +{0x32, 0x30, 0x30, 0x20, }; +const char http_301[5] = +/* "301 " */ +{0x33, 0x30, 0x31, 0x20, }; +const char http_302[5] = +/* "302 " */ +{0x33, 0x30, 0x32, 0x20, }; +const char http_get[5] = +/* "GET " */ +{0x47, 0x45, 0x54, 0x20, }; +const char http_10[9] = +/* "HTTP/1.0" */ +{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, }; +const char http_11[9] = +/* "HTTP/1.1" */ +{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, }; +const char http_content_type[15] = +/* "content-type: " */ +{0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, }; +const char http_texthtml[10] = +/* "text/html" */ +{0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, }; +const char http_location[11] = +/* "location: " */ +{0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, }; +const char http_host[7] = +/* "host: " */ +{0x68, 0x6f, 0x73, 0x74, 0x3a, 0x20, }; +const char http_crnl[3] = +/* "\r\n" */ +{0xd, 0xa, }; +const char http_index_html[12] = +/* "/index.html" */ +{0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, }; +const char http_404_html[10] = +/* "/404.html" */ +{0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, }; +const char http_referer[9] = +/* "Referer:" */ +{0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, 0x3a, }; +const char http_header_200[86] = +/* "HTTP/1.0 200 OK\r\nServer: Contiki/2.0 http://www.sics.se/contiki/\r\nConnection: close\r\n" */ +{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x2f, 0x32, 0x2e, 0x30, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x2f, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, }; +const char http_header_404[93] = +/* "HTTP/1.0 404 Not found\r\nServer: Contiki/2.0 http://www.sics.se/contiki/\r\nConnection: close\r\n" */ +{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34, 0x30, 0x34, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x2f, 0x32, 0x2e, 0x30, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x2f, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, }; +const char http_content_type_plain[29] = +/* "Content-type: text/plain\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_html[28] = +/* "Content-type: text/html\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_css [27] = +/* "Content-type: text/css\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_text[28] = +/* "Content-type: text/text\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x74, 0x65, 0x78, 0x74, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_png [28] = +/* "Content-type: image/png\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_gif [28] = +/* "Content-type: image/gif\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_jpg [29] = +/* "Content-type: image/jpeg\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x65, 0x67, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_binary[43] = +/* "Content-type: application/octet-stream\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xd, 0xa, 0xd, 0xa, }; +const char http_html[6] = +/* ".html" */ +{0x2e, 0x68, 0x74, 0x6d, 0x6c, }; +const char http_shtml[7] = +/* ".shtml" */ +{0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, }; +const char http_htm[5] = +/* ".htm" */ +{0x2e, 0x68, 0x74, 0x6d, }; +const char http_css[5] = +/* ".css" */ +{0x2e, 0x63, 0x73, 0x73, }; +const char http_png[5] = +/* ".png" */ +{0x2e, 0x70, 0x6e, 0x67, }; +const char http_gif[5] = +/* ".gif" */ +{0x2e, 0x67, 0x69, 0x66, }; +const char http_jpg[5] = +/* ".jpg" */ +{0x2e, 0x6a, 0x70, 0x67, }; +const char http_text[6] = +/* ".text" */ +{0x2e, 0x74, 0x65, 0x78, 0x74, }; +const char http_txt[5] = +/* ".txt" */ +{0x2e, 0x74, 0x78, 0x74, }; diff --git a/apps/raven-webserver/http-strings.h b/apps/raven-webserver/http-strings.h new file mode 100644 index 000000000..0c6405f2e --- /dev/null +++ b/apps/raven-webserver/http-strings.h @@ -0,0 +1,34 @@ +extern const char http_http[8]; +extern const char http_200[5]; +extern const char http_301[5]; +extern const char http_302[5]; +extern const char http_get[5]; +extern const char http_10[9]; +extern const char http_11[9]; +extern const char http_content_type[15]; +extern const char http_texthtml[10]; +extern const char http_location[11]; +extern const char http_host[7]; +extern const char http_crnl[3]; +extern const char http_index_html[12]; +extern const char http_404_html[10]; +extern const char http_referer[9]; +extern const char http_header_200[86]; +extern const char http_header_404[93]; +extern const char http_content_type_plain[29]; +extern const char http_content_type_html[28]; +extern const char http_content_type_css [27]; +extern const char http_content_type_text[28]; +extern const char http_content_type_png [28]; +extern const char http_content_type_gif [28]; +extern const char http_content_type_jpg [29]; +extern const char http_content_type_binary[43]; +extern const char http_html[6]; +extern const char http_shtml[7]; +extern const char http_htm[5]; +extern const char http_css[5]; +extern const char http_png[5]; +extern const char http_gif[5]; +extern const char http_jpg[5]; +extern const char http_text[6]; +extern const char http_txt[5]; diff --git a/apps/raven-webserver/httpd-cfs.c b/apps/raven-webserver/httpd-cfs.c new file mode 100644 index 000000000..5cec4d5af --- /dev/null +++ b/apps/raven-webserver/httpd-cfs.c @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2004, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: httpd-cfs.c,v 1.1 2008/10/14 10:14:13 julienabeille Exp $ + */ + +#include + +#include "contiki-net.h" + +#include "webserver.h" +#include "cfs/cfs.h" +#include "lib/petsciiconv.h" +#include "http-strings.h" + +#include "httpd-cfs.h" + +#ifndef WEBSERVER_CONF_CFS_CONNS +#define CONNS 4 +#else /* WEBSERVER_CONF_CFS_CONNS */ +#define CONNS WEBSERVER_CONF_CFS_CONNS +#endif /* WEBSERVER_CONF_CFS_CONNS */ + +#define STATE_WAITING 0 +#define STATE_OUTPUT 1 + +#define SEND_STRING(s, str) PSOCK_SEND(s, (uint8_t *)str, strlen(str)) +MEMB(conns, struct httpd_state, CONNS); + +#define ISO_nl 0x0a +#define ISO_space 0x20 +#define ISO_period 0x2e +#define ISO_slash 0x2f + +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_file(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sout); + + do { + /* Read data from file system into buffer */ + s->len = cfs_read(s->fd, s->outputbuf, sizeof(s->outputbuf)); + + /* If there is data in the buffer, send it */ + if(s->len > 0) { + PSOCK_SEND(&s->sout, (uint8_t *)s->outputbuf, s->len); + } else { + break; + } + } while(s->len > 0); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_headers(struct httpd_state *s, const char *statushdr)) +{ + char *ptr; + + PSOCK_BEGIN(&s->sout); + + SEND_STRING(&s->sout, statushdr); + + ptr = strrchr(s->filename, ISO_period); + if(ptr == NULL) { + SEND_STRING(&s->sout, http_content_type_plain); + } else if(strncmp(http_html, ptr, 5) == 0) { + SEND_STRING(&s->sout, http_content_type_html); + } else if(strncmp(http_css, ptr, 4) == 0) { + SEND_STRING(&s->sout, http_content_type_css); + } else if(strncmp(http_png, ptr, 4) == 0) { + SEND_STRING(&s->sout, http_content_type_png); + } else if(strncmp(http_jpg, ptr, 4) == 0) { + SEND_STRING(&s->sout, http_content_type_jpg); + } else { + SEND_STRING(&s->sout, http_content_type_binary); + } + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_output(struct httpd_state *s)) +{ + PT_BEGIN(&s->outputpt); + + petsciiconv_topetscii(s->filename, sizeof(s->filename)); + s->fd = cfs_open(s->filename, CFS_READ); + petsciiconv_toascii(s->filename, sizeof(s->filename)); + if(s->fd < 0) { + s->fd = cfs_open("notfound.html", CFS_READ); + if(s->fd < 0) { + uip_abort(); + memb_free(&conns, s); + webserver_log_file(&uip_conn->ripaddr, "reset (no notfound.html)"); + PT_EXIT(&s->outputpt); + } + PT_WAIT_THREAD(&s->outputpt, + send_headers(s, http_header_404)); + } else { + PT_WAIT_THREAD(&s->outputpt, + send_headers(s, http_header_200)); + } + PT_WAIT_THREAD(&s->outputpt, send_file(s)); + cfs_close(s->fd); + s->fd = -1; + PSOCK_CLOSE(&s->sout); + PT_END(&s->outputpt); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_input(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sin); + + PSOCK_READTO(&s->sin, ISO_space); + + if(strncmp(s->inputbuf, http_get, 4) != 0) { + PSOCK_CLOSE_EXIT(&s->sin); + } + PSOCK_READTO(&s->sin, ISO_space); + + if(s->inputbuf[0] != ISO_slash) { + PSOCK_CLOSE_EXIT(&s->sin); + } + + if(s->inputbuf[1] == ISO_space) { + strncpy(s->filename, &http_index_html[1], sizeof(s->filename)); + } else { + s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0; + strncpy(s->filename, &s->inputbuf[1], sizeof(s->filename)); + } + + petsciiconv_topetscii(s->filename, sizeof(s->filename)); + webserver_log_file(&uip_conn->ripaddr, s->filename); + petsciiconv_toascii(s->filename, sizeof(s->filename)); + s->state = STATE_OUTPUT; + + while(1) { + PSOCK_READTO(&s->sin, ISO_nl); + + if(strncmp(s->inputbuf, http_referer, 8) == 0) { + s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0; + petsciiconv_topetscii(s->inputbuf, PSOCK_DATALEN(&s->sin) - 2); + webserver_log(s->inputbuf); + } + } + + PSOCK_END(&s->sin); +} +/*---------------------------------------------------------------------------*/ +static void +handle_connection(struct httpd_state *s) +{ + handle_input(s); + if(s->state == STATE_OUTPUT) { + handle_output(s); + } +} +/*---------------------------------------------------------------------------*/ +void +httpd_appcall(void *state) +{ + struct httpd_state *s = (struct httpd_state *)state; + + if(uip_closed() || uip_aborted() || uip_timedout()) { + if(s != NULL) { + if(s->fd >= 0) { + cfs_close(s->fd); + s->fd = -1; + } + memb_free(&conns, s); + } + } else if(uip_connected()) { + s = (struct httpd_state *)memb_alloc(&conns); + if(s == NULL) { + uip_abort(); + webserver_log_file(&uip_conn->ripaddr, "reset (no memory block)"); + return; + } + tcp_markconn(uip_conn, s); + PSOCK_INIT(&s->sin, (uint8_t *)s->inputbuf, sizeof(s->inputbuf) - 1); + PSOCK_INIT(&s->sout, (uint8_t *)s->inputbuf, sizeof(s->inputbuf) - 1); + PT_INIT(&s->outputpt); + s->fd = -1; + s->state = STATE_WAITING; + timer_set(&s->timer, CLOCK_SECOND * 10); + handle_connection(s); + } else if(s != NULL) { + if(uip_poll()) { + if(timer_expired(&s->timer)) { + uip_abort(); + if(s->fd >= 0) { + cfs_close(s->fd); + s->fd = -1; + } + memb_free(&conns, s); + webserver_log_file(&uip_conn->ripaddr, "reset (timeout)"); + } + } else { + timer_reset(&s->timer); + } + handle_connection(s); + } else { + uip_abort(); + } +} +/*---------------------------------------------------------------------------*/ +void +httpd_init(void) +{ + tcp_listen(HTONS(80)); + memb_init(&conns); +} +/*---------------------------------------------------------------------------*/ diff --git a/apps/raven-webserver/httpd-cfs.h b/apps/raven-webserver/httpd-cfs.h new file mode 100644 index 000000000..002627dad --- /dev/null +++ b/apps/raven-webserver/httpd-cfs.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2001, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: httpd-cfs.h,v 1.1 2008/10/14 10:14:13 julienabeille Exp $ + * + */ + +#ifndef __HTTPD_CFS_H__ +#define __HTTPD_CFS_H__ + +#include "contiki-net.h" + +struct httpd_state { + struct timer timer; + struct psock sin, sout; + struct pt outputpt; + char inputbuf[50]; + char outputbuf[UIP_TCP_MSS]; + char filename[20]; + char state; + int fd; + int len; +}; + + +void httpd_init(void); +void httpd_appcall(void *state); + +#endif /* __HTTPD_CFS_H__ */ diff --git a/apps/raven-webserver/httpd-cgi.c b/apps/raven-webserver/httpd-cgi.c new file mode 100644 index 000000000..2dddba109 --- /dev/null +++ b/apps/raven-webserver/httpd-cgi.c @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2001, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: httpd-cgi.c,v 1.1 2008/10/14 10:14:13 julienabeille Exp $ + * + */ + +/* + * This file includes functions that are called by the web server + * scripts. The functions takes no argument, and the return value is + * interpreted as follows. A zero means that the function did not + * complete and should be invoked for the next packet as well. A + * non-zero value indicates that the function has completed and that + * the web server should move along to the next script line. + * + */ + +#include +#include + +#include "contiki-net.h" +#include "httpd.h" +#include "httpd-cgi.h" +#include "httpd-fs.h" + +#include "lib/petsciiconv.h" + +#include "sensors.h" + +static struct httpd_cgi_call *calls = NULL; + +static const char closed[] = /* "CLOSED",*/ +{0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0}; +static const char syn_rcvd[] = /* "SYN-RCVD",*/ +{0x53, 0x59, 0x4e, 0x2d, 0x52, 0x43, 0x56, + 0x44, 0}; +static const char syn_sent[] = /* "SYN-SENT",*/ +{0x53, 0x59, 0x4e, 0x2d, 0x53, 0x45, 0x4e, + 0x54, 0}; +static const char established[] = /* "ESTABLISHED",*/ +{0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x49, + 0x53, 0x48, 0x45, 0x44, 0}; +static const char fin_wait_1[] = /* "FIN-WAIT-1",*/ +{0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, + 0x54, 0x2d, 0x31, 0}; +static const char fin_wait_2[] = /* "FIN-WAIT-2",*/ +{0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, + 0x54, 0x2d, 0x32, 0}; +static const char closing[] = /* "CLOSING",*/ +{0x43, 0x4c, 0x4f, 0x53, 0x49, + 0x4e, 0x47, 0}; +static const char time_wait[] = /* "TIME-WAIT,"*/ +{0x54, 0x49, 0x4d, 0x45, 0x2d, 0x57, 0x41, + 0x49, 0x54, 0}; +static const char last_ack[] = /* "LAST-ACK"*/ +{0x4c, 0x41, 0x53, 0x54, 0x2d, 0x41, 0x43, + 0x4b, 0}; +static const char none[] = /* "NONE"*/ +{0x4e, 0x4f, 0x4e, 0x45, 0}; +static const char running[] = /* "RUNNING"*/ +{0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, + 0}; +static const char called[] = /* "CALLED"*/ +{0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0}; +static const char file_name[] = /* "file-stats"*/ +{0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, + 0x61, 0x74, 0x73, 0}; +static const char tcp_name[] = /* "tcp-connections"*/ +{0x74, 0x63, 0x70, 0x2d, 0x63, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0}; +static const char proc_name[] = /* "processes"*/ +{0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x65, 0x73, 0}; + +static const char sensor_name[] = "sensors"; + +char sensor_temperature[12]; + +static const char *states[] = { + closed, + syn_rcvd, + syn_sent, + established, + fin_wait_1, + fin_wait_2, + closing, + time_wait, + last_ack, + none, + running, + called}; + + uint8_t sprint_ip6(uip_ip6addr_t addr, char * result); + + +void +web_set_temp(char *s) +{ + strcpy(sensor_temperature, s); +} + +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(nullfunction(struct httpd_state *s, char *ptr)) +{ + PSOCK_BEGIN(&s->sout); + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +httpd_cgifunction +httpd_cgi(char *name) +{ + struct httpd_cgi_call *f; + + /* Find the matching name in the table, return the function. */ + for(f = calls; f != NULL; f = f->next) { + if(strncmp(f->name, name, strlen(f->name)) == 0) { + return f->function; + } + } + return nullfunction; +} +/*---------------------------------------------------------------------------*/ +static unsigned short +generate_file_stats(void *arg) +{ + char *f = (char *)arg; + return snprintf((char *)uip_appdata, uip_mss(), "%5u", httpd_fs_count(f)); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(file_stats(struct httpd_state *s, char *ptr)) +{ + PSOCK_BEGIN(&s->sout); + + PSOCK_GENERATOR_SEND(&s->sout, generate_file_stats, (void *) (strchr(ptr, ' ') + 1)); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static unsigned short +make_tcp_stats(void *arg) +{ + struct uip_conn *conn; + struct httpd_state *s = (struct httpd_state *)arg; + + uint16_t numprinted; + + conn = &uip_conns[s->u.count]; + + numprinted = snprintf((char *)uip_appdata, uip_mss(), + "%d", + htons(conn->lport)); + + numprinted += sprint_ip6(conn->ripaddr, uip_appdata + numprinted); + numprinted += snprintf((char *)uip_appdata + numprinted, uip_mss() - numprinted, + "-%u%s%u%u%c %c\r\n", + htons(conn->rport), + states[conn->tcpstateflags & UIP_TS_MASK], + conn->nrtx, + conn->timer, + (uip_outstanding(conn))? '*':' ', + (uip_stopped(conn))? '!':' '); + + return numprinted; +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(tcp_stats(struct httpd_state *s, char *ptr)) +{ + + PSOCK_BEGIN(&s->sout); + + for(s->u.count = 0; s->u.count < UIP_CONNS; ++s->u.count) { + if((uip_conns[s->u.count].tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) { + PSOCK_GENERATOR_SEND(&s->sout, make_tcp_stats, s); + } + } + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static unsigned short +make_processes(void *p) +{ + char name[40]; + + strncpy(name, ((struct process *)p)->name, 40); + petsciiconv_toascii(name, 40); + + return snprintf((char *)uip_appdata, uip_mss(), + "%p%s%p%s\r\n", + p, name, + *((char **)&(((struct process *)p)->thread)), + states[9 + ((struct process *)p)->state]); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(processes(struct httpd_state *s, char *ptr)) +{ + PSOCK_BEGIN(&s->sout); + for(s->u.ptr = PROCESS_LIST(); s->u.ptr != NULL; s->u.ptr = ((struct process *)s->u.ptr)->next) { + PSOCK_GENERATOR_SEND(&s->sout, make_processes, s->u.ptr); + } + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static unsigned short +generate_sensor_readings(void *arg) +{ + return snprintf((char *)uip_appdata, uip_mss(), "Temperature: %s\n", sensor_temperature); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(sensor_readings(struct httpd_state *s, char *ptr)) +{ + PSOCK_BEGIN(&s->sout); + + PSOCK_GENERATOR_SEND(&s->sout, generate_sensor_readings, s); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +void +httpd_cgi_add(struct httpd_cgi_call *c) +{ + struct httpd_cgi_call *l; + + c->next = NULL; + if(calls == NULL) { + calls = c; + } else { + for(l = calls; l->next != NULL; l = l->next); + l->next = c; + } +} +/*---------------------------------------------------------------------------*/ + +HTTPD_CGI_CALL(file, file_name, file_stats); +HTTPD_CGI_CALL(tcp, tcp_name, tcp_stats); +HTTPD_CGI_CALL(proc, proc_name, processes); +HTTPD_CGI_CALL(sensors, sensor_name, sensor_readings); + +void +httpd_cgi_init(void) +{ + httpd_cgi_add(&file); + httpd_cgi_add(&tcp); + httpd_cgi_add(&proc); + httpd_cgi_add(&sensors); +} +/*---------------------------------------------------------------------------*/ + + + +uint8_t sprint_ip6(uip_ip6addr_t addr, char * result) + { + unsigned char zerocnt = 0; + unsigned char numprinted = 0; + char * starting = result; + + unsigned char i = 0; + + while (numprinted < 8) + { + //Address is zero, have we used our ability to + //replace a bunch with : yet? + if ((addr.u16[i] == 0) && (zerocnt == 0)) + { + //How mant zeros? + zerocnt = 0; + while(addr.u16[zerocnt + i] == 0) + zerocnt++; + + //just one, don't waste our zeros... + if (zerocnt == 1) + { + *result++ = '0'; + numprinted++; + break; + } + + //Cool - can replace a bunch of zeros + i += zerocnt; + numprinted += zerocnt; + } + //Normal address, just print it + else + { + result += sprintf(result, "%x", (unsigned int)(ntohs(addr.u16[i]))); + i++; + numprinted++; + } + + //Don't print : on last one + if (numprinted != 8) + *result++ = ':'; + } + + return (result - starting); + } + diff --git a/apps/raven-webserver/httpd-cgi.h b/apps/raven-webserver/httpd-cgi.h new file mode 100644 index 000000000..8df1b48d5 --- /dev/null +++ b/apps/raven-webserver/httpd-cgi.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2001, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: httpd-cgi.h,v 1.1 2008/10/14 10:14:13 julienabeille Exp $ + * + */ + +#ifndef __HTTPD_CGI_H__ +#define __HTTPD_CGI_H__ + +#include "contiki.h" +#include "httpd.h" + +typedef PT_THREAD((* httpd_cgifunction)(struct httpd_state *, char *)); + +httpd_cgifunction httpd_cgi(char *name); + +struct httpd_cgi_call { + struct httpd_cgi_call *next; + const char *name; + httpd_cgifunction function; +}; + +void httpd_cgi_add(struct httpd_cgi_call *c); + +#define HTTPD_CGI_CALL(name, str, function) \ +static struct httpd_cgi_call name = {NULL, str, function} + +void httpd_cgi_init(void); +void web_set_temp(char *s); + +#endif /* __HTTPD_CGI_H__ */ diff --git a/apps/raven-webserver/httpd-fs.c b/apps/raven-webserver/httpd-fs.c new file mode 100644 index 000000000..d6d6c6569 --- /dev/null +++ b/apps/raven-webserver/httpd-fs.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + * $Id: httpd-fs.c,v 1.1 2008/10/14 10:14:13 julienabeille Exp $ + */ + +#include "contiki-net.h" +#include "httpd.h" +#include "httpd-fs.h" +#include "httpd-fsdata.h" + +#include "httpd-fsdata.c" + +#if HTTPD_FS_STATISTICS +static u16_t count[HTTPD_FS_NUMFILES]; +#endif /* HTTPD_FS_STATISTICS */ + +/*-----------------------------------------------------------------------------------*/ +static u8_t +httpd_fs_strcmp(const char *str1, const char *str2) +{ + u8_t i; + i = 0; + +loop: + if( pgm_read_byte(str2 + i) == 0 || + str1[i] == '\r' || + str1[i] == '\n') { + return 0; + } + + if(str1[i] != pgm_read_byte(str2 + i)) { + return 1; + } + + ++i; + goto loop; +} +/*-----------------------------------------------------------------------------------*/ +int +httpd_fs_open(const char *name, struct httpd_fs_file *file) +{ +#if HTTPD_FS_STATISTICS + u16_t i = 0; +#endif /* HTTPD_FS_STATISTICS */ + struct httpd_fsdata_file_noconst *f; + + for(f = (struct httpd_fsdata_file_noconst *)HTTPD_FS_ROOT; + f != NULL; + f = (struct httpd_fsdata_file_noconst *)f->next) { + + if(httpd_fs_strcmp(name, f->name) == 0) { + file->data = f->data; + file->len = f->len; +#if HTTPD_FS_STATISTICS + ++count[i]; +#endif /* HTTPD_FS_STATISTICS */ + return 1; + } +#if HTTPD_FS_STATISTICS + ++i; +#endif /* HTTPD_FS_STATISTICS */ + + } + return 0; +} +/*-----------------------------------------------------------------------------------*/ +void +httpd_fs_init(void) +{ +#if HTTPD_FS_STATISTICS + u16_t i; + for(i = 0; i < HTTPD_FS_NUMFILES; i++) { + count[i] = 0; + } +#endif /* HTTPD_FS_STATISTICS */ +} +/*-----------------------------------------------------------------------------------*/ +#if HTTPD_FS_STATISTICS +u16_t +httpd_fs_count(char *name) +{ + struct httpd_fsdata_file_noconst *f; + u16_t i; + + i = 0; + for(f = (struct httpd_fsdata_file_noconst *)HTTPD_FS_ROOT; + f != NULL; + f = (struct httpd_fsdata_file_noconst *)f->next) { + + if(httpd_fs_strcmp(name, f->name) == 0) { + return count[i]; + } + ++i; + } + return 0; +} +#endif /* HTTPD_FS_STATISTICS */ +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/raven-webserver/httpd-fs.h b/apps/raven-webserver/httpd-fs.h new file mode 100644 index 000000000..903e026fe --- /dev/null +++ b/apps/raven-webserver/httpd-fs.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + * $Id: httpd-fs.h,v 1.1 2008/10/14 10:14:13 julienabeille Exp $ + */ +#ifndef __HTTPD_FS_H__ +#define __HTTPD_FS_H__ + +#include "contiki-net.h" + +#define HTTPD_FS_STATISTICS 1 + +#include + +struct httpd_fs_file { + char *data; + int len; +}; + +/* file must be allocated by caller and will be filled in + by the function. */ +int httpd_fs_open(const char *name, struct httpd_fs_file *file); + +#ifdef HTTPD_FS_STATISTICS +#if HTTPD_FS_STATISTICS == 1 +u16_t httpd_fs_count(char *name); +#endif /* HTTPD_FS_STATISTICS */ +#endif /* HTTPD_FS_STATISTICS */ + +void httpd_fs_init(void); + +#define httpd_fs_cpy memcpy_P +#define httpd_fs_strchr strchr_P +#define httpd_fs_getchar(x) pgm_read_byte(x) + +#endif /* __HTTPD_FS_H__ */ diff --git a/apps/raven-webserver/httpd-fs/404.html b/apps/raven-webserver/httpd-fs/404.html new file mode 100644 index 000000000..a17711d02 --- /dev/null +++ b/apps/raven-webserver/httpd-fs/404.html @@ -0,0 +1,8 @@ + + +
+

404 - file not found

+

Go here instead.

+
+ + \ No newline at end of file diff --git a/apps/raven-webserver/httpd-fs/files.shtml b/apps/raven-webserver/httpd-fs/files.shtml new file mode 100644 index 000000000..7f985db53 --- /dev/null +++ b/apps/raven-webserver/httpd-fs/files.shtml @@ -0,0 +1,24 @@ +%!: /header.html +

File statistics


+ + + + + + + + + + + + + +
/index.html%! file-stats /index.html +
/files.shtml%! file-stats /files.shtml +
/tcp.shtml%! file-stats /tcp.shtml +
/processes.shtml%! file-stats /processes.shtml +
/style.css%! file-stats /contiki.css +
/404.html%! file-stats /404.html +
/img/screenshot.png%! file-stats /img/screenshot.png +
+%!: /footer.html \ No newline at end of file diff --git a/apps/raven-webserver/httpd-fs/footer.html b/apps/raven-webserver/httpd-fs/footer.html new file mode 100644 index 000000000..1fd5f4f29 --- /dev/null +++ b/apps/raven-webserver/httpd-fs/footer.html @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/apps/raven-webserver/httpd-fs/header.html b/apps/raven-webserver/httpd-fs/header.html new file mode 100644 index 000000000..ed782924e --- /dev/null +++ b/apps/raven-webserver/httpd-fs/header.html @@ -0,0 +1,29 @@ + + + + Welcome to the Contiki-demo server! + + + + + + +
+

+ Welcome to the Contiki + web server! +

diff --git a/apps/raven-webserver/httpd-fs/index.html b/apps/raven-webserver/httpd-fs/index.html new file mode 100644 index 000000000..5386ec193 --- /dev/null +++ b/apps/raven-webserver/httpd-fs/index.html @@ -0,0 +1,41 @@ + + + + Welcome to the Contiki web server! + + + + + + +
+

+ Welcome to the Contiki + web server! +

+ +

+ The web pages you are watching are served by a web + server running under the Contiki operating + system. +

+ + + + + diff --git a/apps/raven-webserver/httpd-fs/processes.shtml b/apps/raven-webserver/httpd-fs/processes.shtml new file mode 100644 index 000000000..e1cb48451 --- /dev/null +++ b/apps/raven-webserver/httpd-fs/processes.shtml @@ -0,0 +1,5 @@ +%!: /header.html +

System processes


+ +%! processes +%!: /footer.html diff --git a/apps/raven-webserver/httpd-fs/sensor.shtml b/apps/raven-webserver/httpd-fs/sensor.shtml new file mode 100644 index 000000000..6233d01b4 --- /dev/null +++ b/apps/raven-webserver/httpd-fs/sensor.shtml @@ -0,0 +1,5 @@ +%!: /header.html +

Sensor Readings


+%! sensors +%!: /footer.html + diff --git a/apps/raven-webserver/httpd-fs/style.css b/apps/raven-webserver/httpd-fs/style.css new file mode 100644 index 000000000..6a181276d --- /dev/null +++ b/apps/raven-webserver/httpd-fs/style.css @@ -0,0 +1,239 @@ +h1 +{ + text-align: center; + font-size:14pt; + font-family:arial,helvetica; + font-weight:bold; + padding:10px; +} + +body +{ + + background-color: #fffeec; + color:black; + + font-size:8pt; + font-family:arial,helvetica; +} + +.wrap { + width: 98%; + margin: 0 auto; + text-align: left; + font-family:arial,helvetica; +} + +.menublock +{ + margin: 4px; + width:15%; + float:left; + + padding:10px; + + border: solid 1px; + background-color: #fffcd2; + text-align:left; + + font-size:9pt; + font-family:arial,helvetica; +} + +.contentblock +{ + margin: 4px; + width:50%; + float:left; + + padding:10px; + + border: 1px dotted; + background-color: white; + + font-size:8pt; + font-family:arial,helvetica; + +} + +.newsblock +{ + margin: 4px; + width:24%; + float:left; + + + padding:10px; + + border: solid 1px; + background-color: #fffcd2; + text-align:left; + font-size:8pt; + font-family:arial,helvetica; +} + +.printable +{ + margin: 4px; + width:24%; + float:left; + + + padding:10px; + + border: 0; + background-color: #fffeec; + text-align:right; + font-size:8pt; + font-family:arial,helvetica; +} + +div.rfig +{ + border: solid 1px; + + text-align: left; + + padding: 10px; + margin:10px; + + font-size:8pt; + + float:right; +} + +pre.example +{ + border: solid 1px; + padding: 10px; + margin:10px; + text-align: left; + font-size:8pt; + font-family:arial,helvetica; + white-space:pre; +} + + +p.intro +{ + margin-left:20px; + margin-right:20px; + + font-size:10pt; +/* font-weight:bold; */ + font-family:arial,helvetica; +} + +p.clink +{ + font-size:12pt; + font-family:courier,monospace; + text-align:center; +} + +p.clink9 +{ + font-size:9pt; + font-family:courier,monospace; + text-align:center; +} + +p.related +{ + font-size:10pt; + font-family:arial,helvetica; + text-align:center; +} + + + +img.right +{ + float:right; + margin:10px; +} + +img.left +{ + float:left; + margin:10px; +} + +p.fig +{ + border: solid 1px; + + text-align: center; + + padding: 10px; + margin:10px; + + font-size:7pt; +} + +p.rfig +{ + border: solid 1px; + + text-align: center; + + padding: 10px; + margin:10px; + + font-size:7pt; + + float:right; +} + + +p.lfig +{ + border: solid 1px; + + text-align: center; + + padding: 10px; + margin:10px; + + font-size:7pt; + + float:left; +} + +p +{ + padding-left:10px; +} + +p.mailaddr +{ + padding-left:10px; + font-size:7pt; + font-family:courier,terminal; + text-align:right; +} + +p.right +{ + text-align:right; +} + +p.border-title +{ + text-align:center; + + font-size:14pt; + + padding:0px; + margin:4px; + margin-bottom:10px; + + color: black; + background-color: #fffcba; + border: solid 1px; + +} + + + + diff --git a/apps/raven-webserver/httpd-fs/tcp.shtml b/apps/raven-webserver/httpd-fs/tcp.shtml new file mode 100644 index 000000000..4c4bffe97 --- /dev/null +++ b/apps/raven-webserver/httpd-fs/tcp.shtml @@ -0,0 +1,5 @@ +%!: /header.html +

Current connections


IDNameThreadProcess state
+ +%! tcp-connections +%!: /footer.html \ No newline at end of file diff --git a/apps/raven-webserver/httpd-fs/upload.html b/apps/raven-webserver/httpd-fs/upload.html new file mode 100644 index 000000000..575dbf8f1 --- /dev/null +++ b/apps/raven-webserver/httpd-fs/upload.html @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/apps/raven-webserver/httpd-fsdata.c b/apps/raven-webserver/httpd-fsdata.c new file mode 100644 index 000000000..2c1dae14a --- /dev/null +++ b/apps/raven-webserver/httpd-fsdata.c @@ -0,0 +1,666 @@ +static const char data_processes_shtml[] PROGMEM = { + /* /processes.shtml */ + 0x2f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x68, 0x31, + 0x3e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x3c, 0x2f, 0x68, + 0x31, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, + 0x31, 0x30, 0x30, 0x25, 0x22, 0x3e, 0xa, 0x3c, 0x74, 0x72, + 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x49, 0x44, 0x3c, 0x2f, 0x74, + 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x4e, 0x61, 0x6d, 0x65, + 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x54, + 0x68, 0x72, 0x65, 0x61, 0x64, 0x3c, 0x2f, 0x74, 0x68, 0x3e, + 0x3c, 0x74, 0x68, 0x3e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x3c, 0x2f, 0x74, + 0x68, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x25, 0x21, + 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, + 0xa, 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x66, 0x6f, 0x6f, 0x74, + 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0}; + +static const char data_header_html[] PROGMEM = { + /* /header.html */ + 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, + 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, + 0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, + 0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, + 0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, + 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, + 0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, + 0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, + 0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, + 0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, + 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x74, 0x6f, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x69, + 0x6b, 0x69, 0x2d, 0x64, 0x65, 0x6d, 0x6f, 0x20, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x21, 0x3c, 0x2f, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x3e, 0xa, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x6c, + 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x73, + 0x74, 0x79, 0x6c, 0x65, 0x73, 0x68, 0x65, 0x65, 0x74, 0x22, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, + 0x74, 0x2f, 0x63, 0x73, 0x73, 0x22, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2e, + 0x63, 0x73, 0x73, 0x22, 0x3e, 0x20, 0x20, 0xa, 0x20, 0x20, + 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20, 0x20, + 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x23, 0x66, 0x66, 0x66, 0x65, + 0x65, 0x63, 0x22, 0x20, 0x74, 0x65, 0x78, 0x74, 0x3d, 0x22, + 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x22, 0x3e, 0xa, 0xa, 0x20, + 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6e, 0x75, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x22, 0x3e, 0xa, 0xa, 0x20, 0x20, 0x3c, 0x64, + 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x6d, 0x65, 0x6e, 0x75, 0x22, 0x3e, 0xa, 0x20, 0x20, 0x3c, + 0x70, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x69, 0x74, 0x6c, + 0x65, 0x22, 0x3e, 0x4d, 0x65, 0x6e, 0x75, 0x3c, 0x2f, 0x70, + 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x70, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6e, 0x75, 0x22, 0x3e, + 0xa, 0x20, 0x20, 0xa, 0x20, 0x20, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x22, 0x3e, 0x46, 0x72, + 0x6f, 0x6e, 0x74, 0x20, 0x70, 0x61, 0x67, 0x65, 0x3c, 0x2f, + 0x61, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0xa, 0x20, 0x20, 0x3c, + 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x66, 0x69, + 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, + 0x3e, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, + 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x61, 0x3e, + 0x3c, 0x62, 0x72, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x74, 0x63, 0x70, 0x2e, + 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x4e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x61, 0x3e, + 0x3c, 0x62, 0x72, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x70, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x65, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, + 0x6c, 0x22, 0x3e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, + 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0xa, 0x20, 0x20, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x73, + 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x2e, 0x73, 0x68, 0x74, 0x6d, + 0x6c, 0x22, 0x3e, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x20, + 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x3c, 0x2f, + 0x61, 0x3e, 0xa, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x70, 0x3e, + 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa, + 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa, 0xa, + 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3e, 0xa, 0x20, + 0x20, 0x3c, 0x70, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x69, + 0x74, 0x6c, 0x65, 0x22, 0x3e, 0xa, 0x20, 0x20, 0x57, 0x65, + 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, + 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, + 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x2f, 0x22, + 0x3e, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x3c, 0x2f, + 0x61, 0x3e, 0x20, 0xa, 0x20, 0x20, 0x77, 0x65, 0x62, 0x20, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x21, 0xa, 0x20, 0x20, + 0x3c, 0x2f, 0x70, 0x3e, 0xa, 0}; + +static const char data_files_shtml[] PROGMEM = { + /* /files.shtml */ + 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x20, 0x3c, 0x68, + 0x31, 0x3e, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, + 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x68, + 0x31, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, + 0x31, 0x30, 0x30, 0x25, 0x22, 0x3e, 0xa, 0x20, 0x3c, 0x74, + 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x2f, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0xa, 0x20, + 0x3c, 0x74, 0x64, 0x3e, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, + 0x65, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, 0x2f, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, + 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, + 0xa, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, + 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x66, + 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, + 0x22, 0x3e, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, + 0x68, 0x74, 0x6d, 0x6c, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, + 0x74, 0x64, 0x3e, 0xa, 0x3c, 0x74, 0x64, 0x3e, 0x25, 0x21, + 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x61, 0x74, + 0x73, 0x20, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, + 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, + 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x3c, 0x74, 0x72, 0x3e, + 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x2f, 0x74, 0x63, 0x70, 0x2e, 0x73, 0x68, + 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x2f, 0x74, 0x63, 0x70, 0x2e, + 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, + 0x2f, 0x74, 0x64, 0x3e, 0xa, 0x3c, 0x74, 0x64, 0x3e, 0x25, + 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x61, + 0x74, 0x73, 0x20, 0x2f, 0x74, 0x63, 0x70, 0x2e, 0x73, 0x68, + 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, + 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x3c, 0x74, 0x72, 0x3e, 0x3c, + 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x2f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x65, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, + 0x2f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, + 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x3c, 0x2f, 0x61, 0x3e, + 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0xa, 0x3c, 0x74, 0x64, 0x3e, + 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, + 0x61, 0x74, 0x73, 0x20, 0x2f, 0x70, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x65, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, + 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, + 0x3e, 0xa, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, + 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0x22, + 0x3e, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2e, 0x63, 0x73, + 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, + 0xa, 0x3c, 0x74, 0x64, 0x3e, 0x25, 0x21, 0x20, 0x66, 0x69, + 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, 0x2f, + 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x2e, 0x63, 0x73, + 0x73, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, + 0x72, 0x3e, 0xa, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, + 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, + 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, + 0x3e, 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, + 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0xa, + 0x3c, 0x74, 0x64, 0x3e, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, + 0x65, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, 0x2f, 0x34, + 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x2f, + 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x3c, + 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x69, 0x6d, 0x67, + 0x2f, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x73, 0x68, 0x6f, + 0x74, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x3e, 0x2f, 0x69, 0x6d, + 0x67, 0x2f, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x73, 0x68, + 0x6f, 0x74, 0x2e, 0x70, 0x6e, 0x67, 0x3c, 0x2f, 0x61, 0x3e, + 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0xa, 0x3c, 0x74, 0x64, 0x3e, + 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, + 0x61, 0x74, 0x73, 0x20, 0x2f, 0x69, 0x6d, 0x67, 0x2f, 0x73, + 0x63, 0x72, 0x65, 0x65, 0x6e, 0x73, 0x68, 0x6f, 0x74, 0x2e, + 0x70, 0x6e, 0x67, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, + 0x2f, 0x74, 0x72, 0x3e, 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x3e, 0xa, 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x66, 0x6f, + 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0}; + +static const char data_index_html[] PROGMEM = { + /* /index.html */ + 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, + 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, + 0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, + 0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, + 0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, + 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, + 0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, + 0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, + 0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, + 0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, + 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x74, 0x6f, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x69, + 0x6b, 0x69, 0x20, 0x77, 0x65, 0x62, 0x20, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x21, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, + 0x65, 0x3e, 0xa, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x6c, 0x69, + 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x73, 0x68, 0x65, 0x65, 0x74, 0x22, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, + 0x2f, 0x63, 0x73, 0x73, 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2e, 0x63, + 0x73, 0x73, 0x22, 0x3e, 0x20, 0x20, 0xa, 0x20, 0x20, 0x3c, + 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20, 0x20, 0x3c, + 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3d, 0x22, 0x23, 0x66, 0x66, 0x66, 0x65, 0x65, + 0x63, 0x22, 0x20, 0x74, 0x65, 0x78, 0x74, 0x3d, 0x22, 0x62, + 0x6c, 0x61, 0x63, 0x6b, 0x22, 0x3e, 0xa, 0xa, 0x20, 0x20, + 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x6d, 0x65, 0x6e, 0x75, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x22, 0x3e, 0xa, 0xa, 0x20, 0x20, 0x3c, 0x64, 0x69, + 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, + 0x65, 0x6e, 0x75, 0x22, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x70, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x69, 0x74, 0x6c, 0x65, + 0x22, 0x3e, 0x4d, 0x65, 0x6e, 0x75, 0x3c, 0x2f, 0x70, 0x3e, + 0xa, 0x20, 0x20, 0x3c, 0x70, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6e, 0x75, 0x22, 0x3e, 0xa, + 0x20, 0x20, 0xa, 0x20, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, + 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x22, 0x3e, 0x46, 0x72, 0x6f, + 0x6e, 0x74, 0x20, 0x70, 0x61, 0x67, 0x65, 0x3c, 0x2f, 0x61, + 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x61, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x66, 0x69, 0x6c, + 0x65, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, + 0x46, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, + 0x73, 0x74, 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, + 0x62, 0x72, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x74, 0x63, 0x70, 0x2e, 0x73, + 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x4e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, + 0x62, 0x72, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x70, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x65, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, + 0x22, 0x3e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x70, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x3c, 0x2f, + 0x61, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0xa, 0x20, 0x20, 0x3c, + 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x73, 0x65, + 0x6e, 0x73, 0x6f, 0x72, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, + 0x22, 0x3e, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x20, 0x52, + 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x3c, 0x2f, 0x61, + 0x3e, 0xa, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x70, 0x3e, 0xa, + 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa, 0x20, + 0x20, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa, 0xa, 0x20, + 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3e, 0xa, 0x20, 0x20, + 0x3c, 0x70, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x22, 0x3e, 0xa, 0x20, 0x20, 0x57, 0x65, 0x6c, + 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, + 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, + 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x2f, + 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x2f, 0x22, 0x3e, + 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x3c, 0x2f, 0x61, + 0x3e, 0x20, 0xa, 0x20, 0x20, 0x77, 0x65, 0x62, 0x20, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x21, 0xa, 0x20, 0x20, 0x3c, + 0x2f, 0x70, 0x3e, 0xa, 0x9, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0xa, 0x9, 0x20, 0x20, 0x3c, 0x70, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x69, 0x6e, 0x74, 0x72, 0x6f, + 0x22, 0x3e, 0xa, 0x9, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, + 0x65, 0x20, 0x77, 0x65, 0x62, 0x20, 0x70, 0x61, 0x67, 0x65, + 0x73, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, + 0x77, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x61, + 0x72, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x20, + 0x62, 0x79, 0x20, 0x61, 0x20, 0x77, 0x65, 0x62, 0xa, 0x9, + 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x20, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x75, + 0x6e, 0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x3c, + 0x61, 0xa, 0x9, 0x20, 0x20, 0x20, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, + 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x2f, + 0x22, 0x3e, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x20, + 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0xa, + 0x9, 0x20, 0x20, 0x20, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x3c, 0x2f, 0x61, 0x3e, 0x2e, 0xa, 0x9, 0x20, 0x20, + 0x3c, 0x2f, 0x70, 0x3e, 0xa, 0xa, 0x9, 0x20, 0x20, 0xa, + 0x9, 0x20, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x62, 0x6f, 0x64, + 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, + 0xa, 0}; + +static const char data_style_css[] PROGMEM = { + /* /style.css */ + 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0, + 0x68, 0x31, 0x20, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x74, 0x65, + 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x20, + 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0xa, 0x20, 0x20, + 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, + 0x31, 0x34, 0x70, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66, 0x6f, + 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, + 0x61, 0x72, 0x69, 0x61, 0x6c, 0x2c, 0x68, 0x65, 0x6c, 0x76, + 0x65, 0x74, 0x69, 0x63, 0x61, 0x3b, 0xa, 0x20, 0x20, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x62, 0x6f, 0x6c, 0x64, 0x3b, 0xa, 0x20, 0x20, 0x70, + 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x31, 0x30, 0x70, + 0x78, 0x3b, 0x20, 0xa, 0x7d, 0xa, 0xa, 0x62, 0x6f, 0x64, + 0x79, 0xa, 0x7b, 0xa, 0xa, 0x20, 0x20, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x66, 0x66, 0x65, + 0x65, 0x63, 0x3b, 0xa, 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x3b, 0xa, 0xa, + 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, + 0x65, 0x3a, 0x38, 0x70, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, + 0x3a, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x2c, 0x68, 0x65, 0x6c, + 0x76, 0x65, 0x74, 0x69, 0x63, 0x61, 0x3b, 0xa, 0x7d, 0xa, + 0xa, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x20, 0x7b, 0xa, 0x20, + 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x39, 0x38, + 0x25, 0x3b, 0xa, 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x3a, 0x20, 0x30, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x3b, + 0xa, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, + 0x69, 0x67, 0x6e, 0x3a, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x3b, + 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61, + 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x61, 0x72, 0x69, 0x61, 0x6c, + 0x2c, 0x68, 0x65, 0x6c, 0x76, 0x65, 0x74, 0x69, 0x63, 0x61, + 0x3b, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xa, + 0x7d, 0xa, 0xa, 0x2e, 0x6d, 0x65, 0x6e, 0x75, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x6d, 0x61, + 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x34, 0x70, 0x78, 0x3b, + 0xa, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x31, + 0x35, 0x25, 0x3b, 0xa, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, + 0x74, 0x3a, 0x6c, 0x65, 0x66, 0x74, 0x3b, 0xa, 0xa, 0x20, + 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x31, + 0x30, 0x70, 0x78, 0x3b, 0xa, 0x9, 0xa, 0x20, 0x20, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x20, 0x73, 0x6f, 0x6c, + 0x69, 0x64, 0x20, 0x31, 0x70, 0x78, 0x3b, 0xa, 0x20, 0x20, + 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, + 0x66, 0x66, 0x63, 0x64, 0x32, 0x3b, 0xa, 0x20, 0x20, 0x74, + 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, + 0x6c, 0x65, 0x66, 0x74, 0x3b, 0xa, 0x20, 0x20, 0xa, 0x20, + 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, + 0x3a, 0x39, 0x70, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66, 0x6f, + 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, + 0x61, 0x72, 0x69, 0x61, 0x6c, 0x2c, 0x68, 0x65, 0x6c, 0x76, + 0x65, 0x74, 0x69, 0x63, 0x61, 0x3b, 0x20, 0x20, 0xa, 0x7d, + 0xa, 0xa, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0xa, 0x7b, 0x20, 0x20, 0xa, + 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, + 0x34, 0x70, 0x78, 0x3b, 0xa, 0x20, 0x20, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x3a, 0x35, 0x30, 0x25, 0x3b, 0xa, 0x20, 0x20, + 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x6c, 0x65, 0x66, 0x74, + 0x3b, 0xa, 0xa, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x3a, 0x31, 0x30, 0x70, 0x78, 0x3b, 0xa, 0xa, + 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x20, + 0x31, 0x70, 0x78, 0x20, 0x64, 0x6f, 0x74, 0x74, 0x65, 0x64, + 0x3b, 0xa, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x20, 0x77, 0x68, 0x69, 0x74, 0x65, 0x3b, 0xa, 0xa, + 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, + 0x65, 0x3a, 0x38, 0x70, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, + 0x3a, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x2c, 0x68, 0x65, 0x6c, + 0x76, 0x65, 0x74, 0x69, 0x63, 0x61, 0x3b, 0x20, 0x20, 0xa, + 0xa, 0x7d, 0xa, 0xa, 0x2e, 0x6e, 0x65, 0x77, 0x73, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x34, 0x70, 0x78, + 0x3b, 0xa, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, + 0x32, 0x34, 0x25, 0x3b, 0xa, 0x20, 0x20, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x3a, 0x6c, 0x65, 0x66, 0x74, 0x3b, 0xa, 0xa, + 0xa, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x3a, 0x31, 0x30, 0x70, 0x78, 0x3b, 0xa, 0xa, 0x20, 0x20, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x20, 0x73, 0x6f, + 0x6c, 0x69, 0x64, 0x20, 0x31, 0x70, 0x78, 0x3b, 0xa, 0x20, + 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, + 0x66, 0x66, 0x66, 0x63, 0x64, 0x32, 0x3b, 0xa, 0x20, 0x20, + 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, + 0x3a, 0x6c, 0x65, 0x66, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x38, + 0x70, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, + 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x61, 0x72, + 0x69, 0x61, 0x6c, 0x2c, 0x68, 0x65, 0x6c, 0x76, 0x65, 0x74, + 0x69, 0x63, 0x61, 0x3b, 0xa, 0x7d, 0xa, 0xa, 0x2e, 0x70, + 0x72, 0x69, 0x6e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0xa, 0x7b, + 0xa, 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, + 0x20, 0x34, 0x70, 0x78, 0x3b, 0xa, 0x20, 0x20, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3a, 0x32, 0x34, 0x25, 0x3b, 0xa, 0x20, + 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x6c, 0x65, 0x66, + 0x74, 0x3b, 0xa, 0xa, 0xa, 0x20, 0x20, 0x70, 0x61, 0x64, + 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x31, 0x30, 0x70, 0x78, 0x3b, + 0xa, 0xa, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x3a, 0x20, 0x30, 0x3b, 0xa, 0x20, 0x20, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x66, 0x66, 0x65, + 0x65, 0x63, 0x3b, 0xa, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, + 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, + 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x38, 0x70, 0x74, 0x3b, + 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61, + 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x61, 0x72, 0x69, 0x61, 0x6c, + 0x2c, 0x68, 0x65, 0x6c, 0x76, 0x65, 0x74, 0x69, 0x63, 0x61, + 0x3b, 0xa, 0x7d, 0xa, 0xa, 0x64, 0x69, 0x76, 0x2e, 0x72, + 0x66, 0x69, 0x67, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x3a, 0x20, 0x73, 0x6f, 0x6c, 0x69, + 0x64, 0x20, 0x31, 0x70, 0x78, 0x3b, 0x20, 0xa, 0xa, 0x20, + 0x20, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, + 0x6e, 0x3a, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x3b, 0xa, 0xa, + 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, + 0x20, 0x31, 0x30, 0x70, 0x78, 0x3b, 0xa, 0x20, 0x20, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x31, 0x30, 0x70, 0x78, + 0x3b, 0xa, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, + 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x38, 0x70, 0x74, 0x3b, 0xa, + 0xa, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x3b, 0xa, 0x7d, 0xa, 0xa, 0x70, + 0x72, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0xa, 0x7b, 0xa, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x3a, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x31, + 0x70, 0x78, 0x3b, 0x20, 0xa, 0x20, 0x20, 0x70, 0x61, 0x64, + 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x31, 0x30, 0x70, 0x78, + 0x3b, 0xa, 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, + 0x3a, 0x31, 0x30, 0x70, 0x78, 0x3b, 0xa, 0x20, 0x20, 0x74, + 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, + 0x20, 0x6c, 0x65, 0x66, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x38, + 0x70, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, + 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x61, 0x72, + 0x69, 0x61, 0x6c, 0x2c, 0x68, 0x65, 0x6c, 0x76, 0x65, 0x74, + 0x69, 0x63, 0x61, 0x3b, 0xa, 0x20, 0x20, 0x77, 0x68, 0x69, + 0x74, 0x65, 0x2d, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3a, 0x70, + 0x72, 0x65, 0x3b, 0x20, 0x20, 0xa, 0x7d, 0xa, 0xa, 0xa, + 0x70, 0x2e, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0xa, 0x7b, 0xa, + 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, + 0x65, 0x66, 0x74, 0x3a, 0x32, 0x30, 0x70, 0x78, 0x3b, 0xa, + 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x32, 0x30, 0x70, 0x78, 0x3b, + 0xa, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, + 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x30, 0x70, 0x74, 0x3b, 0xa, + 0x2f, 0x2a, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x62, 0x6f, 0x6c, 0x64, + 0x3b, 0x20, 0x2a, 0x2f, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, + 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x61, + 0x72, 0x69, 0x61, 0x6c, 0x2c, 0x68, 0x65, 0x6c, 0x76, 0x65, + 0x74, 0x69, 0x63, 0x61, 0x3b, 0x20, 0x20, 0xa, 0x7d, 0xa, + 0xa, 0x70, 0x2e, 0x63, 0x6c, 0x69, 0x6e, 0x6b, 0xa, 0x7b, + 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, + 0x7a, 0x65, 0x3a, 0x31, 0x32, 0x70, 0x74, 0x3b, 0xa, 0x20, + 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, + 0x6c, 0x79, 0x3a, 0x63, 0x6f, 0x75, 0x72, 0x69, 0x65, 0x72, + 0x2c, 0x6d, 0x6f, 0x6e, 0x6f, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x3b, 0x20, 0x20, 0xa, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, + 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x63, 0x65, 0x6e, + 0x74, 0x65, 0x72, 0x3b, 0xa, 0x7d, 0xa, 0xa, 0x70, 0x2e, + 0x63, 0x6c, 0x69, 0x6e, 0x6b, 0x39, 0xa, 0x7b, 0xa, 0x20, + 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, + 0x3a, 0x39, 0x70, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66, 0x6f, + 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, + 0x63, 0x6f, 0x75, 0x72, 0x69, 0x65, 0x72, 0x2c, 0x6d, 0x6f, + 0x6e, 0x6f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3b, 0x20, 0x20, + 0xa, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, + 0x69, 0x67, 0x6e, 0x3a, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, + 0x3b, 0xa, 0x7d, 0xa, 0xa, 0x70, 0x2e, 0x72, 0x65, 0x6c, + 0x61, 0x74, 0x65, 0x64, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, + 0x30, 0x70, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, + 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x61, + 0x72, 0x69, 0x61, 0x6c, 0x2c, 0x68, 0x65, 0x6c, 0x76, 0x65, + 0x74, 0x69, 0x63, 0x61, 0x3b, 0x20, 0x20, 0xa, 0x20, 0x20, + 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, + 0x3a, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0xa, 0x7d, + 0xa, 0xa, 0xa, 0xa, 0x69, 0x6d, 0x67, 0x2e, 0x72, 0x69, + 0x67, 0x68, 0x74, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x66, 0x6c, + 0x6f, 0x61, 0x74, 0x3a, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3b, + 0xa, 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, + 0x31, 0x30, 0x70, 0x78, 0x3b, 0xa, 0x7d, 0xa, 0xa, 0x69, + 0x6d, 0x67, 0x2e, 0x6c, 0x65, 0x66, 0x74, 0xa, 0x7b, 0xa, + 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x6c, 0x65, + 0x66, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, + 0x69, 0x6e, 0x3a, 0x31, 0x30, 0x70, 0x78, 0x3b, 0xa, 0x7d, + 0xa, 0xa, 0x70, 0x2e, 0x66, 0x69, 0x67, 0xa, 0x7b, 0xa, + 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x20, + 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x31, 0x70, 0x78, 0x3b, + 0x20, 0xa, 0xa, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2d, + 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x20, 0x63, 0x65, 0x6e, + 0x74, 0x65, 0x72, 0x3b, 0xa, 0xa, 0x20, 0x20, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x31, 0x30, 0x70, + 0x78, 0x3b, 0xa, 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x3a, 0x31, 0x30, 0x70, 0x78, 0x3b, 0xa, 0xa, 0x20, + 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, + 0x3a, 0x37, 0x70, 0x74, 0x3b, 0xa, 0x7d, 0xa, 0xa, 0x70, + 0x2e, 0x72, 0x66, 0x69, 0x67, 0xa, 0x7b, 0xa, 0x20, 0x20, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x20, 0x73, 0x6f, + 0x6c, 0x69, 0x64, 0x20, 0x31, 0x70, 0x78, 0x3b, 0x20, 0xa, + 0xa, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, + 0x69, 0x67, 0x6e, 0x3a, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, + 0x72, 0x3b, 0xa, 0xa, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, + 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x31, 0x30, 0x70, 0x78, 0x3b, + 0xa, 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, + 0x31, 0x30, 0x70, 0x78, 0x3b, 0xa, 0xa, 0x20, 0x20, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x37, + 0x70, 0x74, 0x3b, 0xa, 0xa, 0x20, 0x20, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x3a, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3b, 0xa, + 0x7d, 0xa, 0xa, 0xa, 0x70, 0x2e, 0x6c, 0x66, 0x69, 0x67, + 0xa, 0x7b, 0xa, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x3a, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x31, + 0x70, 0x78, 0x3b, 0x20, 0xa, 0xa, 0x20, 0x20, 0x74, 0x65, + 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x20, + 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0xa, 0xa, 0x20, + 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, + 0x31, 0x30, 0x70, 0x78, 0x3b, 0xa, 0x20, 0x20, 0x6d, 0x61, + 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x31, 0x30, 0x70, 0x78, 0x3b, + 0xa, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, + 0x69, 0x7a, 0x65, 0x3a, 0x37, 0x70, 0x74, 0x3b, 0xa, 0xa, + 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x6c, 0x65, + 0x66, 0x74, 0x3b, 0xa, 0x7d, 0xa, 0xa, 0x70, 0xa, 0x7b, + 0xa, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x31, 0x30, 0x70, 0x78, + 0x3b, 0xa, 0x7d, 0xa, 0xa, 0x70, 0x2e, 0x6d, 0x61, 0x69, + 0x6c, 0x61, 0x64, 0x64, 0x72, 0xa, 0x7b, 0xa, 0x20, 0x20, + 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x6c, 0x65, + 0x66, 0x74, 0x3a, 0x31, 0x30, 0x70, 0x78, 0x3b, 0xa, 0x20, + 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, + 0x3a, 0x37, 0x70, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66, 0x6f, + 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, + 0x63, 0x6f, 0x75, 0x72, 0x69, 0x65, 0x72, 0x2c, 0x74, 0x65, + 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x3b, 0xa, 0x20, 0x20, + 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, + 0x3a, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3b, 0x20, 0xa, 0x7d, + 0xa, 0xa, 0x70, 0x2e, 0x72, 0x69, 0x67, 0x68, 0x74, 0xa, + 0x7b, 0xa, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, + 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x3b, 0x20, 0xa, 0x7d, 0xa, 0xa, 0x70, 0x2e, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x69, 0x74, 0x6c, 0x65, + 0xa, 0x7b, 0xa, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2d, + 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x63, 0x65, 0x6e, 0x74, + 0x65, 0x72, 0x3b, 0xa, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, + 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x34, 0x70, + 0x74, 0x3b, 0xa, 0xa, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, + 0x69, 0x6e, 0x67, 0x3a, 0x30, 0x70, 0x78, 0x3b, 0xa, 0x20, + 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x34, 0x70, + 0x78, 0x3b, 0xa, 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x31, + 0x30, 0x70, 0x78, 0x3b, 0xa, 0xa, 0x20, 0x20, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x62, 0x6c, 0x61, 0x63, 0x6b, + 0x3b, 0xa, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x20, 0x23, 0x66, 0x66, 0x66, 0x63, 0x62, 0x61, 0x3b, + 0xa, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, + 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x31, 0x70, 0x78, + 0x3b, 0xa, 0xa, 0x7d, 0x20, 0xa, 0xa, 0xa, 0xa, 0xa, +0}; + +static const char data_footer_html[] PROGMEM = { + /* /footer.html */ + 0x2f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x20, 0x20, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, + 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0}; + +static const char data_tcp_shtml[] PROGMEM = { + /* /tcp.shtml */ + 0x2f, 0x74, 0x63, 0x70, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x68, 0x31, + 0x3e, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x3c, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3d, 0x22, 0x31, 0x30, 0x30, 0x25, 0x22, 0x3e, 0xa, + 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x4c, 0x6f, + 0x63, 0x61, 0x6c, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, + 0x68, 0x3e, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x3c, 0x2f, + 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, + 0x3e, 0x52, 0x65, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x74, 0x68, + 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x54, 0x69, 0x6d, 0x65, 0x72, + 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x46, + 0x6c, 0x61, 0x67, 0x73, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, + 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x25, 0x21, 0x20, 0x74, 0x63, + 0x70, 0x2d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0xa, 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x66, + 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, +0}; + +static const char data_404_html[] PROGMEM = { + /* /404.html */ + 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x20, 0x20, 0x3c, + 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65, 0x22, + 0x3e, 0xa, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x63, 0x65, 0x6e, + 0x74, 0x65, 0x72, 0x3e, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d, + 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, + 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, + 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x33, + 0x3e, 0x47, 0x6f, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x2f, 0x22, 0x3e, 0x68, 0x65, 0x72, 0x65, + 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65, + 0x61, 0x64, 0x2e, 0x3c, 0x2f, 0x68, 0x33, 0x3e, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, + 0x72, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x62, 0x6f, 0x64, + 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, +0}; + +static const char data_sensor_shtml[] PROGMEM = { + /* /sensor.shtml */ + 0x2f, 0x73, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x68, 0x31, + 0x3e, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x20, 0x52, 0x65, + 0x61, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x3c, 0x2f, 0x68, 0x31, + 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0xa, 0x25, 0x21, 0x20, 0x73, + 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x73, 0xa, 0x25, 0x21, 0x3a, + 0x20, 0x2f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x68, + 0x74, 0x6d, 0x6c, 0xa, 0xa, 0}; + +static const char data_upload_html[] PROGMEM = { + /* /upload.html */ + 0x2f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x3c, 0x62, 0x6f, + 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x66, 0x6f, 0x72, 0x6d, 0x20, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x75, 0x70, + 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, + 0x20, 0x65, 0x6e, 0x63, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, + 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x2f, + 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x22, + 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x70, + 0x6f, 0x73, 0x74, 0x22, 0x3e, 0xa, 0x3c, 0x69, 0x6e, 0x70, + 0x75, 0x74, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x75, + 0x73, 0x65, 0x72, 0x66, 0x69, 0x6c, 0x65, 0x22, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x3d, 0x22, 0x66, 0x69, 0x6c, 0x65, 0x22, + 0x20, 0x73, 0x69, 0x7a, 0x65, 0x3d, 0x22, 0x35, 0x30, 0x22, + 0x20, 0x2f, 0x3e, 0xa, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, + 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x55, 0x70, + 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x3d, 0x22, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x22, 0x20, + 0x2f, 0x3e, 0xa, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e, + 0xa, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, + 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0}; + +const struct httpd_fsdata_file file_processes_shtml[] = {{NULL, data_processes_shtml, data_processes_shtml + 17, sizeof(data_processes_shtml) - 17}}; + +const struct httpd_fsdata_file file_header_html[] = {{file_processes_shtml, data_header_html, data_header_html + 13, sizeof(data_header_html) - 13}}; + +const struct httpd_fsdata_file file_files_shtml[] = {{file_header_html, data_files_shtml, data_files_shtml + 13, sizeof(data_files_shtml) - 13}}; + +const struct httpd_fsdata_file file_index_html[] = {{file_files_shtml, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12}}; + +const struct httpd_fsdata_file file_style_css[] = {{file_index_html, data_style_css, data_style_css + 11, sizeof(data_style_css) - 11}}; + +const struct httpd_fsdata_file file_footer_html[] = {{file_style_css, data_footer_html, data_footer_html + 13, sizeof(data_footer_html) - 13}}; + +const struct httpd_fsdata_file file_tcp_shtml[] = {{file_footer_html, data_tcp_shtml, data_tcp_shtml + 11, sizeof(data_tcp_shtml) - 11}}; + +const struct httpd_fsdata_file file_404_html[] = {{file_tcp_shtml, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10}}; + +const struct httpd_fsdata_file file_sensor_shtml[] = {{file_404_html, data_sensor_shtml, data_sensor_shtml + 14, sizeof(data_sensor_shtml) - 14}}; + +const struct httpd_fsdata_file file_upload_html[] = {{file_sensor_shtml, data_upload_html, data_upload_html + 13, sizeof(data_upload_html) - 13}}; + +#define HTTPD_FS_ROOT file_upload_html + +#define HTTPD_FS_NUMFILES 10 diff --git a/apps/raven-webserver/httpd-fsdata.h b/apps/raven-webserver/httpd-fsdata.h new file mode 100644 index 000000000..21202674f --- /dev/null +++ b/apps/raven-webserver/httpd-fsdata.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + * $Id: httpd-fsdata.h,v 1.1 2008/10/14 10:14:13 julienabeille Exp $ + */ +#ifndef __HTTPD_FSDATA_H__ +#define __HTTPD_FSDATA_H__ + +#include "contiki-net.h" + +struct httpd_fsdata_file { + const struct httpd_fsdata_file *next; + const char *name; + const char *data; + const int len; +#ifdef HTTPD_FS_STATISTICS +#if HTTPD_FS_STATISTICS == 1 + u16_t count; +#endif /* HTTPD_FS_STATISTICS */ +#endif /* HTTPD_FS_STATISTICS */ +}; + +struct httpd_fsdata_file_noconst { + struct httpd_fsdata_file *next; + char *name; + char *data; + int len; +#ifdef HTTPD_FS_STATISTICS +#if HTTPD_FS_STATISTICS == 1 + u16_t count; +#endif /* HTTPD_FS_STATISTICS */ +#endif /* HTTPD_FS_STATISTICS */ +}; + +#endif /* __HTTPD_FSDATA_H__ */ diff --git a/apps/raven-webserver/httpd.c b/apps/raven-webserver/httpd.c new file mode 100644 index 000000000..f93cd1bdb --- /dev/null +++ b/apps/raven-webserver/httpd.c @@ -0,0 +1,364 @@ +/* + * Copyright (c) 2004, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: httpd.c,v 1.1 2008/10/14 10:14:13 julienabeille Exp $ + */ + +#include + +#include "contiki-net.h" + +#include "webserver.h" +#include "httpd-fs.h" +#include "httpd-cgi.h" +#include "lib/petsciiconv.h" +#include "http-strings.h" + +#include "httpd.h" + +#ifndef WEBSERVER_CONF_CGI_CONNS +#define CONNS 4 +#else /* WEBSERVER_CONF_CGI_CONNS */ +#define CONNS WEBSERVER_CONF_CGI_CONNS +#endif /* WEBSERVER_CONF_CGI_CONNS */ + +#define STATE_WAITING 0 +#define STATE_OUTPUT 1 + +#define SEND_STRING(s, str) PSOCK_SEND(s, (uint8_t *)str, (unsigned int)strlen(str)) +MEMB(conns, struct httpd_state, CONNS); + +#define ISO_nl 0x0a +#define ISO_space 0x20 +#define ISO_bang 0x21 +#define ISO_percent 0x25 +#define ISO_period 0x2e +#define ISO_slash 0x2f +#define ISO_colon 0x3a + +/*---------------------------------------------------------------------------*/ +static unsigned short +generate(void *state) +{ + struct httpd_state *s = (struct httpd_state *)state; + + if(s->file.len > uip_mss()) { + s->len = uip_mss(); + } else { + s->len = s->file.len; + } + + httpd_fs_cpy(uip_appdata, s->file.data, s->len); + + return s->len; +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_file(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sout); + + do { + PSOCK_GENERATOR_SEND(&s->sout, generate, s); + s->file.len -= s->len; + s->file.data += s->len; + } while(s->file.len > 0); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_part_of_file(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sout); + + static int oldfilelen, oldlen; + static char * olddata; + + //Store stuff that gets clobbered... + oldfilelen = s->file.len; + oldlen = s->len; + olddata = s->file.data; + + //How much to send + s->file.len = s->len; + + do { + PSOCK_GENERATOR_SEND(&s->sout, generate, s); + s->file.len -= s->len; + s->file.data += s->len; + } while(s->file.len > 0); + + s->len = oldlen; + s->file.len = oldfilelen; + s->file.data = olddata; + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static void +next_scriptstate(struct httpd_state *s) +{ + char *p; + + if((p = (char *)httpd_fs_strchr(s->scriptptr, ISO_nl)) != NULL) { + p += 1; + s->scriptlen -= (unsigned short)(p - s->scriptptr); + s->scriptptr = p; + } else { + s->scriptlen = 0; + } + /* char *p; + p = strchr(s->scriptptr, ISO_nl) + 1; + s->scriptlen -= (unsigned short)(p - s->scriptptr); + s->scriptptr = p;*/ +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_script(struct httpd_state *s)) +{ + char *ptr; + + char filenamebuf[25]; + + PT_BEGIN(&s->scriptpt); + + while(s->file.len > 0) { + + /* Check if we should start executing a script. */ + if(httpd_fs_getchar(s->file.data) == ISO_percent && + httpd_fs_getchar(s->file.data + 1) == ISO_bang) { + s->scriptptr = s->file.data + 3; + s->scriptlen = s->file.len - 3; + + memcpy_P(filenamebuf, s->scriptptr, 25); + + if(httpd_fs_getchar(s->scriptptr - 1) == ISO_colon) { + httpd_fs_open(filenamebuf + 1, &s->file); + PT_WAIT_THREAD(&s->scriptpt, send_file(s)); + } else { + PT_WAIT_THREAD(&s->scriptpt, + httpd_cgi(filenamebuf)(s, s->scriptptr)); + } + next_scriptstate(s); + + /* The script is over, so we reset the pointers and continue + sending the rest of the file. */ + s->file.data = s->scriptptr; + s->file.len = s->scriptlen; + } else { + /* See if we find the start of script marker in the block of HTML + to be sent. */ + + if(s->file.len > uip_mss()) { + s->len = uip_mss(); + } else { + s->len = s->file.len; + } + + if(httpd_fs_getchar(s->file.data) == ISO_percent) { + ptr = (char *) httpd_fs_strchr(s->file.data + 1, ISO_percent); + } else { + ptr = (char *) httpd_fs_strchr(s->file.data, ISO_percent); + } + if(ptr != NULL && + ptr != s->file.data) { + s->len = (int)(ptr - s->file.data); + if(s->len >= uip_mss()) { + s->len = uip_mss(); + } + } + PT_WAIT_THREAD(&s->scriptpt, send_part_of_file(s)); + s->file.data += s->len; + s->file.len -= s->len; + } + } + + PT_END(&s->scriptpt); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_headers(struct httpd_state *s, const char *statushdr)) +{ + char *ptr; + + PSOCK_BEGIN(&s->sout); + + SEND_STRING(&s->sout, statushdr); + + ptr = strrchr(s->filename, ISO_period); + if(ptr == NULL) { + SEND_STRING(&s->sout, http_content_type_binary); + } else if(strncmp(http_html, ptr, 5) == 0 || + strncmp(http_shtml, ptr, 6) == 0) { + SEND_STRING(&s->sout, http_content_type_html); + } else if(strncmp(http_css, ptr, 4) == 0) { + SEND_STRING(&s->sout, http_content_type_css); + } else if(strncmp(http_png, ptr, 4) == 0) { + SEND_STRING(&s->sout, http_content_type_png); + } else if(strncmp(http_gif, ptr, 4) == 0) { + SEND_STRING(&s->sout, http_content_type_gif); + } else if(strncmp(http_jpg, ptr, 4) == 0) { + SEND_STRING(&s->sout, http_content_type_jpg); + } else { + SEND_STRING(&s->sout, http_content_type_plain); + } + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_output(struct httpd_state *s)) +{ + char *ptr; + + PT_BEGIN(&s->outputpt); + + if(!httpd_fs_open(s->filename, &s->file)) { + httpd_fs_open(http_404_html, &s->file); + PT_WAIT_THREAD(&s->outputpt, + send_headers(s, + http_header_404)); + PT_WAIT_THREAD(&s->outputpt, + send_file(s)); + } else { + PT_WAIT_THREAD(&s->outputpt, + send_headers(s, + http_header_200)); + ptr = strchr(s->filename, ISO_period); + if(ptr != NULL && strncmp(ptr, http_shtml, 6) == 0) { + PT_INIT(&s->scriptpt); + PT_WAIT_THREAD(&s->outputpt, handle_script(s)); + } else { + PT_WAIT_THREAD(&s->outputpt, + send_file(s)); + } + } + PSOCK_CLOSE(&s->sout); + PT_END(&s->outputpt); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_input(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sin); + + PSOCK_READTO(&s->sin, ISO_space); + + if(strncmp(s->inputbuf, http_get, 4) != 0) { + PSOCK_CLOSE_EXIT(&s->sin); + } + PSOCK_READTO(&s->sin, ISO_space); + + if(s->inputbuf[0] != ISO_slash) { + PSOCK_CLOSE_EXIT(&s->sin); + } + + if(s->inputbuf[1] == ISO_space) { + strncpy(s->filename, http_index_html, sizeof(s->filename)); + } else { + s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0; + strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename)); + } + + webserver_log_file(&uip_conn->ripaddr, s->filename); + + s->state = STATE_OUTPUT; + + while(1) { + PSOCK_READTO(&s->sin, ISO_nl); + + if(strncmp(s->inputbuf, http_referer, 8) == 0) { + s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0; + petsciiconv_topetscii(s->inputbuf, PSOCK_DATALEN(&s->sin) - 2); + webserver_log(s->inputbuf); + } + } + + PSOCK_END(&s->sin); +} +/*---------------------------------------------------------------------------*/ +static void +handle_connection(struct httpd_state *s) +{ + handle_input(s); + if(s->state == STATE_OUTPUT) { + handle_output(s); + } +} +/*---------------------------------------------------------------------------*/ +void +httpd_appcall(void *state) +{ + struct httpd_state *s = (struct httpd_state *)state; + + if(uip_closed() || uip_aborted() || uip_timedout()) { + if(s != NULL) { + memb_free(&conns, s); + } + } else if(uip_connected()) { + s = (struct httpd_state *)memb_alloc(&conns); + if(s == NULL) { + uip_abort(); + return; + } + tcp_markconn(uip_conn, s); + PSOCK_INIT(&s->sin, (uint8_t *)s->inputbuf, sizeof(s->inputbuf) - 1); + PSOCK_INIT(&s->sout, (uint8_t *)s->inputbuf, sizeof(s->inputbuf) - 1); + PT_INIT(&s->outputpt); + s->state = STATE_WAITING; + /* timer_set(&s->timer, CLOCK_SECOND * 100);*/ + s->timer = 0; + handle_connection(s); + } else if(s != NULL) { + if(uip_poll()) { + ++s->timer; + if(s->timer >= 20) { + uip_abort(); + memb_free(&conns, s); + } + } else { + s->timer = 0; + } + handle_connection(s); + } else { + uip_abort(); + } +} +/*---------------------------------------------------------------------------*/ +void +httpd_init(void) +{ + tcp_listen(HTONS(80)); + memb_init(&conns); + httpd_cgi_init(); +} +/*---------------------------------------------------------------------------*/ diff --git a/apps/raven-webserver/httpd.h b/apps/raven-webserver/httpd.h new file mode 100644 index 000000000..e957f9416 --- /dev/null +++ b/apps/raven-webserver/httpd.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2001-2005, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: httpd.h,v 1.1 2008/10/14 10:14:13 julienabeille Exp $ + * + */ + +#ifndef __HTTPD_H__ +#define __HTTPD_H__ + + +#include "contiki-net.h" +#include "httpd-fs.h" + +struct httpd_state { + unsigned char timer; + struct psock sin, sout; + struct pt outputpt, scriptpt; + char inputbuf[50]; + char filename[20]; + char state; + struct httpd_fs_file file; + int len; + char *scriptptr; + int scriptlen; + union { + unsigned short count; + void *ptr; + } u; +}; + + +void httpd_init(void); +void httpd_appcall(void *state); + +#endif /* __HTTPD_H__ */ diff --git a/apps/raven-webserver/webserver-dsc.c b/apps/raven-webserver/webserver-dsc.c new file mode 100644 index 000000000..f99a1ad1a --- /dev/null +++ b/apps/raven-webserver/webserver-dsc.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki desktop environment + * + * $Id: webserver-dsc.c,v 1.1 2008/10/14 10:14:13 julienabeille Exp $ + * + */ + +#include "sys/dsc.h" + +/*-----------------------------------------------------------------------------------*/ +#if CTK_CONF_ICON_BITMAPS +static unsigned char webservericon_bitmap[3*3*8] = { + 0x00, 0x7f, 0x40, 0x41, 0x44, 0x48, 0x40, 0x50, + 0x00, 0xff, 0x5a, 0x00, 0x00, 0x00, 0x3c, 0x81, + 0x00, 0xfe, 0x02, 0x82, 0x22, 0x12, 0x02, 0x0a, + + 0x41, 0x60, 0x42, 0x62, 0x62, 0x42, 0x60, 0x41, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, + 0x82, 0x06, 0x42, 0x46, 0x46, 0x42, 0x06, 0x82, + + 0x50, 0x40, 0x48, 0x44, 0x41, 0x40, 0x7e, 0x00, + 0xc5, 0x34, 0x3c, 0x52, 0x7a, 0x7e, 0xa1, 0xfd, + 0x0a, 0x02, 0x12, 0x22, 0x82, 0x02, 0x7e, 0x00 +}; +#endif /* CTK_CONF_ICON_BITMAPS */ + +#if CTK_CONF_ICON_TEXTMAPS +static char webservericon_textmap[9] = { + '+', '-', '+', + '|', ')', '|', + '+', '-', '+' +}; +#endif /* CTK_CONF_ICON_TEXTMAPS */ + +#if CTK_CONF_ICONS +static struct ctk_icon webserver_icon = + {CTK_ICON("Web server", webservericon_bitmap, webservericon_textmap)}; +#endif /* CTK_CONF_ICONS */ +/*-----------------------------------------------------------------------------------*/ +DSC(webserver_dsc, + "The Contiki web server", + "webserver.prg", + webserver_process, + &webserver_icon); +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/raven-webserver/webserver-dsc.h b/apps/raven-webserver/webserver-dsc.h new file mode 100644 index 000000000..ae669c231 --- /dev/null +++ b/apps/raven-webserver/webserver-dsc.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki desktop environment + * + * $Id: webserver-dsc.h,v 1.1 2008/10/14 10:14:13 julienabeille Exp $ + * + */ +#ifndef __WEBSERVER_DSC_H__ +#define __WEBSERVER_DSC_H__ + +#include "sys/dsc.h" + +DSC_HEADER(webserver_dsc); + +#endif /* __WEBSERVER_DSC_H__ */ diff --git a/apps/raven-webserver/webserver-nogui.c b/apps/raven-webserver/webserver-nogui.c new file mode 100644 index 000000000..78f18e45e --- /dev/null +++ b/apps/raven-webserver/webserver-nogui.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2002, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki OS. + * + * $Id: webserver-nogui.c,v 1.1 2008/10/14 10:14:13 julienabeille Exp $ + * + */ + +#include +#include + +#include "contiki.h" +#include "sys/log.h" + +#include "http-strings.h" +#include "webserver-nogui.h" +#include "httpd.h" + +PROCESS(webserver_nogui_process, "Web server"); + +AUTOSTART_PROCESSES(&webserver_nogui_process); + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(webserver_nogui_process, ev, data) +{ + PROCESS_BEGIN(); + + httpd_init(); + + while(1) { + PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event); + httpd_appcall(data); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +void +webserver_log_file(uip_ipaddr_t *requester, char *file) +{ +#if LOG_CONF_ENABLED + char buf[18]; + + /* Print out IP address of requesting host. */ + sprintf(buf, "%d.%d.%d.%d: ", requester->u8[0], requester->u8[1], + requester->u8[2], requester->u8[3]); + log_message(buf, file); +#endif /* LOG_CONF_ENABLED */ +} +/*---------------------------------------------------------------------------*/ +void +webserver_log(char *msg) +{ + log_message(msg, ""); +} +/*---------------------------------------------------------------------------*/ diff --git a/apps/raven-webserver/webserver-nogui.h b/apps/raven-webserver/webserver-nogui.h new file mode 100644 index 000000000..a0e5c958b --- /dev/null +++ b/apps/raven-webserver/webserver-nogui.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2002, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki OS + * + * $Id: webserver-nogui.h,v 1.1 2008/10/14 10:14:13 julienabeille Exp $ + * + */ +#ifndef __WEBSERVER_NOGUI_H__ +#define __WEBSERVER_NOGUI_H__ + +#include "contiki-net.h" + +PROCESS_NAME(webserver_nogui_process); +PROCESS_NAME(raven_lcd_process); + +void webserver_log(char *msg); +void webserver_log_file(uip_ipaddr_t *requester, char *file); + +#endif /* __WEBSERVER_H__ */ diff --git a/apps/raven-webserver/webserver.c b/apps/raven-webserver/webserver.c new file mode 100644 index 000000000..add9f23d4 --- /dev/null +++ b/apps/raven-webserver/webserver.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2002, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki desktop environment for the C64. + * + * $Id: webserver.c,v 1.1 2008/10/14 10:14:13 julienabeille Exp $ + * + */ + +#include +#include + +#include "contiki.h" +#include "ctk/ctk.h" + +#include "http-strings.h" +#include "webserver.h" +#include "httpd.h" + +/* The main window. */ +static struct ctk_window mainwindow; + +static struct ctk_label message = + {CTK_LABEL(0, 0, 15, 1, "Latest requests")}; + +PROCESS(webserver_process, "Web server"); + +AUTOSTART_PROCESSES(&webserver_process); + +#define LOG_WIDTH 38 +#define LOG_HEIGHT 16 +static char log[LOG_WIDTH*LOG_HEIGHT]; + +static struct ctk_label loglabel = +{CTK_LABEL(0, 1, LOG_WIDTH, LOG_HEIGHT, log)}; +/*-----------------------------------------------------------------------------------*/ +PROCESS_THREAD(webserver_process, ev, data) +{ + PROCESS_BEGIN(); + + ctk_window_new(&mainwindow, LOG_WIDTH, LOG_HEIGHT+1, "Web server"); + + CTK_WIDGET_ADD(&mainwindow, &message); + CTK_WIDGET_ADD(&mainwindow, &loglabel); + + httpd_init(); + + ctk_window_open(&mainwindow); + + while(1) { + PROCESS_WAIT_EVENT(); + + if(ev == ctk_signal_window_close || + ev == PROCESS_EVENT_EXIT) { + ctk_window_close(&mainwindow); + process_exit(&webserver_process); + LOADER_UNLOAD(); + } else if(ev == tcpip_event) { + httpd_appcall(data); + } + } + + PROCESS_END(); +} +/*-----------------------------------------------------------------------------------*/ +void +webserver_log_file(uip_ipaddr_t *requester, char *file) +{ + int size; + + /* Scroll previous entries upwards */ + memcpy(log, &log[LOG_WIDTH], LOG_WIDTH * (LOG_HEIGHT - 1)); + + /* Print out IP address of requesting host. */ + size = sprintf(&log[LOG_WIDTH * (LOG_HEIGHT - 1)], + "%d.%d.%d.%d: ", + requester->u8[0], + requester->u8[1], + requester->u8[2], + requester->u8[3]); + + /* Copy filename into last line. */ + strncpy(&log[LOG_WIDTH * (LOG_HEIGHT - 1) + size], file, LOG_WIDTH - size); + + /* Update log display. */ + CTK_WIDGET_REDRAW(&loglabel); +} +/*-----------------------------------------------------------------------------------*/ +void +webserver_log(char *msg) +{ + /* Scroll previous entries upwards */ + memcpy(log, &log[LOG_WIDTH], LOG_WIDTH * (LOG_HEIGHT - 1)); + + /* Copy filename into last line. */ + strncpy(&log[LOG_WIDTH * (LOG_HEIGHT - 1)], msg, LOG_WIDTH); + + /* Update log display. */ + CTK_WIDGET_REDRAW(&loglabel); +} +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/raven-webserver/webserver.h b/apps/raven-webserver/webserver.h new file mode 100644 index 000000000..632a6b9dd --- /dev/null +++ b/apps/raven-webserver/webserver.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2002, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki operating system + * + * $Id: webserver.h,v 1.1 2008/10/14 10:14:13 julienabeille Exp $ + * + */ +#ifndef __WEBSERVER_H__ +#define __WEBSERVER_H__ + +#include "contiki-net.h" + +PROCESS_NAME(webserver_process); + +void webserver_log(char *msg); +void webserver_log_file(uip_ipaddr_t *requester, char *file); + +#endif /* __WEBSERVER_H__ */
LocalRemoteStateRetransmissionsTimerFlags