webserver app for RAVEN platform

This commit is contained in:
julienabeille 2008-10-14 10:14:13 +00:00
parent 9b2961046a
commit 47a46ded91
30 changed files with 2998 additions and 0 deletions

View File

@ -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 $<

View File

@ -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"

View File

@ -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, };

View File

@ -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];

View File

@ -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 <adam@sics.se>
*
* $Id: httpd-cfs.c,v 1.1 2008/10/14 10:14:13 julienabeille Exp $
*/
#include <string.h>
#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);
}
/*---------------------------------------------------------------------------*/

View File

@ -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__ */

View File

@ -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 <stdio.h>
#include <string.h>
#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(),
"<tr align=\"center\"><td>%d</td><td>",
htons(conn->lport));
numprinted += sprint_ip6(conn->ripaddr, uip_appdata + numprinted);
numprinted += snprintf((char *)uip_appdata + numprinted, uip_mss() - numprinted,
"-%u</td><td>%s</td><td>%u</td><td>%u</td><td>%c %c</td></tr>\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(),
"<tr align=\"center\"><td>%p</td><td>%s</td><td>%p</td><td>%s</td></tr>\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(), "<em>Temperature:</em> %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);
}

View File

@ -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__ */

View File

@ -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 <adam@sics.se>
*
* $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 */
/*-----------------------------------------------------------------------------------*/

View File

@ -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 <adam@sics.se>
*
* $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 <avr/pgmspace.h>
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__ */

View File

@ -0,0 +1,8 @@
<html>
<body bgcolor="white">
<center>
<h1>404 - file not found</h1>
<h3>Go <a href="/">here</a> instead.</h3>
</center>
</body>
</html>

View File

@ -0,0 +1,24 @@
%!: /header.html
<h1>File statistics</h1><br><table width="100%">
<tr><td><a href="/index.html">/index.html</a></td>
<td>%! file-stats /index.html
</td></tr>
<tr><td><a href="/files.shtml">/files.shtml</a></td>
<td>%! file-stats /files.shtml
</td></tr>
<tr><td><a href="/tcp.shtml">/tcp.shtml</a></td>
<td>%! file-stats /tcp.shtml
</td></tr>
<tr><td><a href="/processes.shtml">/processes.shtml</a></td>
<td>%! file-stats /processes.shtml
</td></tr>
<tr><td><a href="/style.css">/style.css</a></td>
<td>%! file-stats /contiki.css
</td></tr>
<tr><td><a href="/404.html">/404.html</a></td>
<td>%! file-stats /404.html
</td></tr>
<tr><td><a href="/img/screenshot.png">/img/screenshot.png</a></td>
<td>%! file-stats /img/screenshot.png
</td></tr></table>
%!: /footer.html

View File

@ -0,0 +1,2 @@
</body>
</html>

View File

@ -0,0 +1,29 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Welcome to the Contiki-demo server!</title>
<link rel="stylesheet" type="text/css" href="/style.css">
</head>
<body bgcolor="#fffeec" text="black">
<div class="menublock">
<div class="menu">
<p class="border-title">Menu</p>
<p class="menu">
<a href="/">Front page</a><br>
<a href="files.shtml">File statistics</a><br>
<a href="tcp.shtml">Network connections</a><br>
<a href="processes.shtml">System processes</a><br>
<a href="sensor.shtml">Sensor Readings</a>
</p>
</div>
</div>
<div class="contentblock">
<p class="border-title">
Welcome to the <a href="http://www.sics.se/contiki/">Contiki</a>
web server!
</p>

View File

@ -0,0 +1,41 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Welcome to the Contiki web server!</title>
<link rel="stylesheet" type="text/css" href="/style.css">
</head>
<body bgcolor="#fffeec" text="black">
<div class="menublock">
<div class="menu">
<p class="border-title">Menu</p>
<p class="menu">
<a href="/">Front page</a><br>
<a href="files.shtml">File statistics</a><br>
<a href="tcp.shtml">Network connections</a><br>
<a href="processes.shtml">System processes</a><br>
<a href="sensor.shtml">Sensor Readings</a>
</p>
</div>
</div>
<div class="contentblock">
<p class="border-title">
Welcome to the <a href="http://www.sics.se/contiki/">Contiki</a>
web server!
</p>
<p class="intro">
The web pages you are watching are served by a web
server running under the <a
href="http://www.sics.se/contiki/">Contiki operating
system</a>.
</p>
</body>
</html>

View File

@ -0,0 +1,5 @@
%!: /header.html
<h1>System processes</h1><br><table width="100%">
<tr><th>ID</th><th>Name</th><th>Thread</th><th>Process state</th></tr>
%! processes
%!: /footer.html

View File

@ -0,0 +1,5 @@
%!: /header.html
<h1>Sensor Readings</h1><br>
%! sensors
%!: /footer.html

View File

@ -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;
}

View File

@ -0,0 +1,5 @@
%!: /header.html
<h1>Current connections</h1><br><table width="100%">
<tr><th>Local</th><th>Remote</th><th>State</th><th>Retransmissions</th><th>Timer</th><th>Flags</th></tr>
%! tcp-connections
%!: /footer.html

View File

@ -0,0 +1,8 @@
<html>
<body>
<form action="upload.html" enctype="multipart/form-data" method="post">
<input name="userfile" type="file" size="50" />
<input value="Upload" type="submit" />
</form>
</body>
</html>

View File

@ -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

View File

@ -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 <adam@sics.se>
*
* $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__ */

View File

@ -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 <adam@sics.se>
*
* $Id: httpd.c,v 1.1 2008/10/14 10:14:13 julienabeille Exp $
*/
#include <string.h>
#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();
}
/*---------------------------------------------------------------------------*/

View File

@ -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__ */

View File

@ -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);
/*-----------------------------------------------------------------------------------*/

View File

@ -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__ */

View File

@ -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 <string.h>
#include <stdio.h>
#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, "");
}
/*---------------------------------------------------------------------------*/

View File

@ -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__ */

View File

@ -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 <string.h>
#include <stdio.h>
#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);
}
/*-----------------------------------------------------------------------------------*/

View File

@ -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__ */