From 17da57e9899201400c5b42a89892a007f9b7578c Mon Sep 17 00:00:00 2001 From: dak664 Date: Fri, 19 Jun 2009 17:11:28 +0000 Subject: [PATCH] All static strings to flash, add wildcard to file-stats cgi --- .../apps/raven-webserver/http-strings.c | 2 + .../apps/raven-webserver/httpd-cgi.c | 161 ++++---- .../avr-raven/apps/raven-webserver/httpd-fs.c | 81 ++-- .../avr-raven/apps/raven-webserver/httpd-fs.h | 20 +- .../apps/raven-webserver/httpd-fsdata.c | 390 +++++++----------- .../apps/raven-webserver/httpd-fsdata.h | 6 +- .../avr-raven/apps/raven-webserver/httpd.c | 154 ++++--- .../avr-raven/apps/raven-webserver/httpd.h | 3 +- .../apps/raven-webserver/webserver-nogui.c | 4 +- 9 files changed, 396 insertions(+), 425 deletions(-) diff --git a/platform/avr-raven/apps/raven-webserver/http-strings.c b/platform/avr-raven/apps/raven-webserver/http-strings.c index f6b86dae6..c78c70aa5 100644 --- a/platform/avr-raven/apps/raven-webserver/http-strings.c +++ b/platform/avr-raven/apps/raven-webserver/http-strings.c @@ -1,3 +1,4 @@ +#if 0 /*This file not used when strings reside in flash memory only*/ const char http_http[8] = /* "http://" */ {0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, }; @@ -100,3 +101,4 @@ const char http_text[6] = const char http_txt[5] = /* ".txt" */ {0x2e, 0x74, 0x78, 0x74, }; +#endif diff --git a/platform/avr-raven/apps/raven-webserver/httpd-cgi.c b/platform/avr-raven/apps/raven-webserver/httpd-cgi.c index 57ce361ff..e6d21d81a 100644 --- a/platform/avr-raven/apps/raven-webserver/httpd-cgi.c +++ b/platform/avr-raven/apps/raven-webserver/httpd-cgi.c @@ -28,7 +28,7 @@ * * This file is part of the uIP TCP/IP stack. * - * $Id: httpd-cgi.c,v 1.1 2009/03/12 19:15:25 adamdunkels Exp $ + * $Id: httpd-cgi.c,v 1.2 2009/06/19 17:11:28 dak664 Exp $ * */ @@ -49,61 +49,35 @@ #include "httpd.h" #include "httpd-cgi.h" #include "httpd-fs.h" +#include "httpd-fsdata.h" -#include "lib/petsciiconv.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]; +/*cgi function names*/ +#if HTTPD_FS_STATISTICS +static const char file_name[] PROGMEM = "file-stats"; +#endif +static const char tcp_name[] PROGMEM = "tcp-connections"; +static const char proc_name[] PROGMEM = "processes"; +static const char sensor_name[] PROGMEM = "sensors"; +/*Process states for processes cgi*/ +static const char closed[] PROGMEM = "CLOSED"; +static const char syn_rcvd[] PROGMEM = "SYN-RCVD"; +static const char syn_sent[] PROGMEM = "SYN-SENT"; +static const char established[] PROGMEM = "ESTABLISHED"; +static const char fin_wait_1[] PROGMEM = "FIN-WAIT-1"; +static const char fin_wait_2[] PROGMEM = "FIN-WAIT-2"; +static const char closing[] PROGMEM = "CLOSING"; +static const char time_wait[] PROGMEM = "TIME-WAIT"; +static const char last_ack[] PROGMEM = "LAST-ACK"; +static const char none[] PROGMEM = "NONE"; +static const char running[] PROGMEM = "RUNNING"; +static const char called[] PROGMEM = "CALLED"; static const char *states[] = { closed, syn_rcvd, @@ -118,6 +92,8 @@ static const char *states[] = { running, called}; + char sensor_temperature[12]; + uint8_t sprint_ip6(uip_ip6addr_t addr, char * result); @@ -142,30 +118,53 @@ httpd_cgi(char *name) /* 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) { + if(strncmp_P(name, f->name, strlen_P(f->name)) == 0) { return f->function; } } return nullfunction; } + +#if HTTPD_FS_STATISTICS +static char *thisfilename; /*---------------------------------------------------------------------------*/ static unsigned short generate_file_stats(void *arg) { - char *f = (char *)arg; - int i; char tmp[20]; -// for (i=0;i<20;i++) if (pgm_read_byte(f++)==' ') break; //skip file-stats string - for (i=0;i<19;i++) { - tmp[i]=pgm_read_byte(f++); //transfer "/filename" to RAM - if (tmp[i]==' ') { - tmp[i]=0; - break; - } + struct httpd_fsdata_file_noconst *f,fram; + u16_t i,numprinted; + + /* Transfer arg from flash file to RAM */ + memcpy_P_trim(tmp, (char *)arg); + + /* Count for this page, with common page footer */ + if (tmp[0]=='.') { + return snprintf_P((char *)uip_appdata, uip_mss(), + PSTR("



This page has been sent %u times"), httpd_fs_open(thisfilename, 0)); + + /* Count for all files */ + /* Note buffer will overflow if there are too many files! */ + } else if (tmp[0]=='*') { + i=0;numprinted=0; + for(f = (struct httpd_fsdata_file_noconst *)httpd_get_root(); + f != NULL; + f = (struct httpd_fsdata_file_noconst *)fram.next) { + memcpy_P(&fram,f,sizeof(fram)); + memcpy_P(&tmp,fram.name,sizeof(tmp)); + numprinted+=snprintf_P((char *)uip_appdata + numprinted, uip_mss() - numprinted, +#if HTTPD_FS_STATISTICS==1 + PSTR("%s%d"),tmp,tmp,f->count); +#elif HTTPD_FS_STATISTICS==2 + PSTR("%s%d"),tmp,tmp,httpd_filecount[i++]); +#endif + } + return numprinted; + + /* Count for specified file */ + } else { + return snprintf_P((char *)uip_appdata, uip_mss(), PSTR("%5u"), httpd_fs_open(tmp, 0)); } -// return sprintf_P((char *)uip_appdata, PSTR( "%s"), tmp); //show file name for debugging - return snprintf_P((char *)uip_appdata, uip_mss(), PSTR("%5u"), httpd_fs_count(tmp)); -// return snprintf_P((char *)uip_appdata, uip_mss(), PSTR("%5u"), httpd_fs_count(f)); } /*---------------------------------------------------------------------------*/ static @@ -174,31 +173,33 @@ PT_THREAD(file_stats(struct httpd_state *s, char *ptr)) PSOCK_BEGIN(&s->sout); - //while (pgm_read_byte(ptr++)!=' ') {}; //skip to "/filename" after the script invokation + thisfilename=&s->filename[0]; //temporary way to pass filename to generate_file_stats PSOCK_GENERATOR_SEND(&s->sout, generate_file_stats, (void *) (strchr_P(ptr, ' ') + 1)); PSOCK_END(&s->sout); } +#endif /*HTTPD_FS_STATISTICS*/ /*---------------------------------------------------------------------------*/ static unsigned short make_tcp_stats(void *arg) { struct uip_conn *conn; struct httpd_state *s = (struct httpd_state *)arg; - + char tstate[20]; uint16_t numprinted; conn = &uip_conns[s->u.count]; - numprinted = snprintf((char *)uip_appdata, uip_mss(), - "%d", + numprinted = snprintf_P((char *)uip_appdata, uip_mss(), + PSTR("%d"), htons(conn->lport)); - numprinted += sprint_ip6(conn->ripaddr, uip_appdata + numprinted); - numprinted += snprintf((char *)uip_appdata + numprinted, uip_mss() - numprinted, - "-%u%s%u%u%c %c\r\n", + numprinted += sprint_ip6(conn->ripaddr, uip_appdata + numprinted); + strcpy_P(tstate,states[conn->tcpstateflags & UIP_TS_MASK]); + numprinted += snprintf_P((char *)uip_appdata + numprinted, uip_mss() - numprinted, + PSTR("-%u%s%u%u%c %c\r\n"), htons(conn->rport), - states[conn->tcpstateflags & UIP_TS_MASK], + tstate, conn->nrtx, conn->timer, (uip_outstanding(conn))? '*':' ', @@ -225,16 +226,18 @@ PT_THREAD(tcp_stats(struct httpd_state *s, char *ptr)) static unsigned short make_processes(void *p) { - char name[40]; + char name[40],tstate[20]; strncpy(name, ((struct process *)p)->name, 40); - petsciiconv_toascii(name, 40); - +//petsciiconv_toascii(name, 40); + strcpy_P(tstate,states[9 + ((struct process *)p)->state]); return snprintf_P((char *)uip_appdata, uip_mss(), - PSTR("%p%s%p%s\r\n"), - p, name, - *((char **)&(((struct process *)p)->thread)), - states[9 + ((struct process *)p)->state]); + PSTR("%p%s%p%s\r\n"), + p, name, +// *((char **)&(((struct process *)p)->thread)), + *(char *)(&(((struct process *)p)->thread)), + + tstate); } /*---------------------------------------------------------------------------*/ static @@ -279,7 +282,9 @@ httpd_cgi_add(struct httpd_cgi_call *c) } /*---------------------------------------------------------------------------*/ +#if HTTPD_FS_STATISTICS HTTPD_CGI_CALL(file, file_name, file_stats); +#endif HTTPD_CGI_CALL(tcp, tcp_name, tcp_stats); HTTPD_CGI_CALL(proc, proc_name, processes); HTTPD_CGI_CALL(sensors, sensor_name, sensor_readings); @@ -287,7 +292,9 @@ HTTPD_CGI_CALL(sensors, sensor_name, sensor_readings); void httpd_cgi_init(void) { +#if HTTPD_FS_STATISTICS httpd_cgi_add(&file); +#endif httpd_cgi_add(&tcp); httpd_cgi_add(&proc); httpd_cgi_add(&sensors); diff --git a/platform/avr-raven/apps/raven-webserver/httpd-fs.c b/platform/avr-raven/apps/raven-webserver/httpd-fs.c index 48556d16f..d0c856508 100644 --- a/platform/avr-raven/apps/raven-webserver/httpd-fs.c +++ b/platform/avr-raven/apps/raven-webserver/httpd-fs.c @@ -30,7 +30,7 @@ * * Author: Adam Dunkels * - * $Id: httpd-fs.c,v 1.1 2009/03/12 19:15:25 adamdunkels Exp $ + * $Id: httpd-fs.c,v 1.2 2009/06/19 17:11:28 dak664 Exp $ */ #include "contiki-net.h" @@ -40,64 +40,59 @@ #include "httpd-fsdata.c" -#if HTTPD_FS_STATISTICS -static u16_t count[HTTPD_FS_NUMFILES]; +#if HTTPD_FS_STATISTICS==2 +u16_t httpd_filecount[HTTPD_FS_NUMFILES]; #endif /* HTTPD_FS_STATISTICS */ /*-----------------------------------------------------------------------------------*/ -static u8_t -httpd_fs_strcmp(const char *str1, const char *str2) +void * +httpd_get_root() { - 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; + return (void *)HTTPD_FS_ROOT; } /*-----------------------------------------------------------------------------------*/ -int +u16_t 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; + struct httpd_fsdata_file_noconst *f,fram; 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 */ + f = (struct httpd_fsdata_file_noconst *)fram.next) { + memcpy_P(&fram,f,sizeof(fram)); + if(strcmp_P(name, fram.name) == 0) { + if (file) { + file->data = fram.data; + file->len = fram.len; +#if HTTPD_FS_STATISTICS==1 + f->count++; + } + return f->count; + } + ++i +#elif HTTPD_FS_STATISTICS==2 + ++httpd_filecount[i]; + } + return httpd_filecount[i]; + } + ++i; +#else + } return 1; } -#if HTTPD_FS_STATISTICS - ++i; -#endif /* HTTPD_FS_STATISTICS */ - +#endif /*HTTPD_FS_STATISTICS*/ } return 0; + } /*-----------------------------------------------------------------------------------*/ void httpd_fs_init(void) { -#if HTTPD_FS_STATISTICS +#if HTTPD_FS_STATISTICS && 0 //count will already be zero at boot u16_t i; for(i = 0; i < HTTPD_FS_NUMFILES; i++) { count[i] = 0; @@ -105,20 +100,24 @@ httpd_fs_init(void) #endif /* HTTPD_FS_STATISTICS */ } /*-----------------------------------------------------------------------------------*/ -#if HTTPD_FS_STATISTICS +#if HTTPD_FS_STATISTICS && 0 //Not needed, httpd_fs_open returns count u16_t httpd_fs_count(char *name) { - struct httpd_fsdata_file_noconst *f; + struct httpd_fsdata_file_noconst *f,fram; 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) { + f = (struct httpd_fsdata_file_noconst *)fram.next) { + memcpy_P(&fram,f,sizeof(fram)); + if(strcmp_P(name, fram.name) == 0) { +#if HTTPD_FS_STATISTICS==1 + return f->count; +#elif HTTPD_FS_STATISTICS==2 return count[i]; +#endif } ++i; } diff --git a/platform/avr-raven/apps/raven-webserver/httpd-fs.h b/platform/avr-raven/apps/raven-webserver/httpd-fs.h index 87376114f..f6d91525e 100644 --- a/platform/avr-raven/apps/raven-webserver/httpd-fs.h +++ b/platform/avr-raven/apps/raven-webserver/httpd-fs.h @@ -30,14 +30,19 @@ * * Author: Adam Dunkels * - * $Id: httpd-fs.h,v 1.1 2009/03/12 19:15:25 adamdunkels Exp $ + * $Id: httpd-fs.h,v 1.2 2009/06/19 17:11:28 dak664 Exp $ */ #ifndef __HTTPD_FS_H__ #define __HTTPD_FS_H__ #include "contiki-net.h" -#define HTTPD_FS_STATISTICS 1 +//#define HTTPD_FS_STATISTICS 1 //Puts count in file system +#define HTTPD_FS_STATISTICS 2 //Puts count in RAM array + +#if HTTPD_FS_STATISTICS==2 +extern u16_t httpd_filecount[]; +#endif /* HTTPD_FS_STATISTICS */ #include @@ -47,14 +52,11 @@ struct httpd_fs_file { }; /* 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); + by the function. If NULL, just file stats are returned.*/ +u16_t 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 */ +/* Returns root of http pages in flash */ +void * httpd_get_root(); void httpd_fs_init(void); diff --git a/platform/avr-raven/apps/raven-webserver/httpd-fsdata.c b/platform/avr-raven/apps/raven-webserver/httpd-fsdata.c index 1757f5c78..680a0d9d8 100644 --- a/platform/avr-raven/apps/raven-webserver/httpd-fsdata.c +++ b/platform/avr-raven/apps/raven-webserver/httpd-fsdata.c @@ -1,23 +1,19 @@ 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}; + 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62, 0x6f, 0x64, + 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3d, + 0x22, 0x77, 0x68, 0x69, 0x74, 0x65, 0x22, 0x3e, 0x3c, 0x63, + 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 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, 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, 0x3c, 0x2f, 0x63, 0x65, + 0x6e, 0x74, 0x65, 0x72, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, + 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0}; static const char data_favicon_png[] PROGMEM = { /* /favicon.png */ @@ -68,94 +64,24 @@ static const char data_files_shtml[] PROGMEM = { 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, 0xd, 0xa, 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, 0x3c, 0x74, - 0x64, 0x3e, 0xd, 0xa, 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, 0xd, - 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, - 0x3e, 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, 0x3c, 0x74, 0x64, 0x3e, 0xd, 0xa, 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, 0xd, 0xa, 0x3c, 0x2f, 0x74, - 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 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, 0x3c, 0x74, 0x64, 0x3e, 0xd, - 0xa, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, - 0x74, 0x61, 0x74, 0x73, 0x20, 0x2f, 0x74, 0x63, 0x70, 0x2e, - 0x73, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 0x3c, 0x2f, 0x74, - 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 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, 0x3c, 0x74, 0x64, - 0x3e, 0xd, 0xa, 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, 0xd, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, - 0x3c, 0x2f, 0x74, 0x72, 0x3e, 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, 0x3c, 0x74, 0x64, 0x3e, 0xd, 0xa, 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, 0xd, 0xa, 0x3c, 0x2f, 0x74, - 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 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, 0x3c, 0x74, 0x64, 0x3e, 0xd, 0xa, 0x25, - 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x61, - 0x74, 0x73, 0x20, 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, - 0x6d, 0x6c, 0xd, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, - 0x2f, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, - 0x64, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, - 0x22, 0x2f, 0x72, 0x6f, 0x62, 0x6f, 0x74, 0x73, 0x2e, 0x74, - 0x78, 0x74, 0x22, 0x3e, 0x2f, 0x72, 0x6f, 0x62, 0x6f, 0x74, - 0x73, 0x2e, 0x74, 0x78, 0x74, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, - 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0xd, 0xa, + 0x31, 0x30, 0x30, 0x25, 0x22, 0x3e, 0x3c, 0x74, 0x72, 0x20, + 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x22, 0x6c, 0x65, 0x66, + 0x74, 0x22, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x4e, 0x61, 0x6d, + 0x65, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x3c, 0x2f, + 0x74, 0x68, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xd, 0xa, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, - 0x61, 0x74, 0x73, 0x20, 0x2f, 0x72, 0x6f, 0x62, 0x6f, 0x74, - 0x73, 0x2e, 0x74, 0x78, 0x74, 0xd, 0xa, 0x3c, 0x2f, 0x74, - 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 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, 0x3c, 0x74, 0x64, 0x3e, 0xd, 0xa, 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, 0xd, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, - 0x2f, 0x74, 0x72, 0x3e, 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x3e, 0xd, 0xa, 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x66, - 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, - 0xd, 0xa, 0}; + 0x61, 0x74, 0x73, 0x20, 0x2a, 0xd, 0xa, 0x3c, 0x2f, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x3e, 0xd, 0xa, 0x25, 0x21, 0x3a, + 0x20, 0x2f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x68, + 0x74, 0x6d, 0x6c, 0xd, 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}; + 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, + 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, +0}; static const char data_header_html[] PROGMEM = { /* /header.html */ @@ -182,123 +108,114 @@ static const char data_header_html[] PROGMEM = { 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, 0xd, 0xa, 0x3c, - 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, - 0x69, 0x63, 0x6f, 0x6e, 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, - 0x3d, 0x22, 0x66, 0x61, 0x76, 0x69, 0x63, 0x6f, 0x6e, 0x2e, - 0x70, 0x6e, 0x67, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, - 0x22, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, - 0x22, 0x3e, 0xd, 0xa, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, - 0x3e, 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, 0xd, 0xa, - 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, - 0x3d, 0x22, 0x6d, 0x65, 0x6e, 0x75, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x22, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, - 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6e, 0x75, 0x22, - 0x3e, 0xd, 0xa, 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, 0x3c, 0x70, 0x20, 0x63, 0x6c, - 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6e, 0x75, 0x22, - 0x3e, 0xd, 0xa, 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, 0xd, 0xa, 0x3c, 0x61, 0x20, 0x68, 0x72, + 0x63, 0x73, 0x73, 0x22, 0x3e, 0x3c, 0x6c, 0x69, 0x6e, 0x6b, + 0x20, 0x72, 0x65, 0x6c, 0x3d, 0x22, 0x69, 0x63, 0x6f, 0x6e, + 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x66, 0x61, + 0x76, 0x69, 0x63, 0x6f, 0x6e, 0x2e, 0x70, 0x6e, 0x67, 0x22, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x69, 0x6d, 0x61, + 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0x22, 0x3e, 0xd, 0xa, + 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 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, 0xd, 0xa, 0x3c, 0x64, 0x69, 0x76, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, + 0x6e, 0x75, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3e, 0x3c, + 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x6d, 0x65, 0x6e, 0x75, 0x22, 0x3e, 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, 0x3c, + 0x70, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, + 0x65, 0x6e, 0x75, 0x22, 0x3e, 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, 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, - 0xd, 0xa, 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, 0xd, - 0xa, 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, 0xd, 0xa, 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, 0xd, 0xa, 0x3c, 0x2f, 0x70, - 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x64, - 0x69, 0x76, 0x3e, 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, 0xd, - 0xa, 0x3c, 0x70, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, - 0x22, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x69, - 0x74, 0x6c, 0x65, 0x22, 0x3e, 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, - 0x77, 0x65, 0x62, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x21, 0x3c, 0x2f, 0x70, 0x3e, 0xd, 0xa, 0}; + 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, 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, 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, 0x3c, + 0x2f, 0x70, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, + 0x2f, 0x64, 0x69, 0x76, 0x3e, 0xd, 0xa, 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, 0x3c, 0x70, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x22, 0x3e, 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, 0x77, 0x65, 0x62, 0x20, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x21, 0x3c, 0x2f, 0x70, 0x3e, 0xd, 0xa, 0}; static const char data_index_html[] PROGMEM = { /* /index.html */ 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0xd, 0xa, 0x3c, 0x70, 0x20, 0x63, 0x6c, - 0x61, 0x73, 0x73, 0x3d, 0x22, 0x69, 0x6e, 0x74, 0x72, 0x6f, - 0x22, 0x3e, 0xd, 0xa, 0x54, 0x68, 0x65, 0x73, 0x65, 0x20, - 0x70, 0x61, 0x67, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, - 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x20, 0x77, 0x65, 0x62, - 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, 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, - 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x3c, 0x2f, 0x61, - 0x3e, 0x2e, 0xd, 0xa, 0x3c, 0x2f, 0x70, 0x3e, 0x3c, 0x62, - 0x72, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x69, 0x3e, 0x54, - 0x68, 0x69, 0x73, 0x20, 0x70, 0x61, 0x67, 0x65, 0x20, 0x68, - 0x61, 0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x73, 0x65, - 0x6e, 0x74, 0xd, 0xa, 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, 0xd, - 0xa, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x2e, 0x3c, 0x2f, - 0x69, 0x3e, 0xd, 0xa, 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x66, - 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, + 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 0x3c, 0x70, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x69, 0x6e, + 0x74, 0x72, 0x6f, 0x22, 0x3e, 0x54, 0x68, 0x65, 0x73, 0x65, + 0x20, 0x70, 0x61, 0x67, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, + 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x20, 0x77, 0x65, + 0x62, 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, 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, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x3c, 0x2f, + 0x61, 0x3e, 0x2e, 0xd, 0xa, 0x25, 0x21, 0x20, 0x66, 0x69, + 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, 0x2e, 0}; 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, + 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xd, 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, 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}; + 0x68, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xd, 0xa, 0x25, + 0x21, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, + 0x73, 0xd, 0xa, 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x3e, 0xd, 0xa, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, + 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, 0x2e, 0xd, 0xa, +0}; static const char data_robots_txt[] PROGMEM = { /* /robots.txt */ 0x2f, 0x72, 0x6f, 0x62, 0x6f, 0x74, 0x73, 0x2e, 0x74, 0x78, 0x74, 0, 0x75, 0x73, 0x65, 0x72, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x3a, 0x20, 0x2a, 0xa, 0x44, 0x69, 0x73, 0x61, 0x6c, 0x6c, - 0x6f, 0x77, 0x3a, 0x20, 0x2f, 0}; + 0x3a, 0x20, 0x2a, 0xd, 0xa, 0x44, 0x69, 0x73, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x3a, 0x20, 0x2f, 0}; static const char data_sensor_shtml[] PROGMEM = { /* /sensor.shtml */ @@ -309,9 +226,8 @@ static const char data_sensor_shtml[] PROGMEM = { 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0xd, 0xa, 0x25, 0x21, 0x20, 0x73, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x73, 0xd, 0xa, - 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x66, 0x6f, 0x6f, 0x74, 0x65, - 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 0xd, 0xa, -0}; + 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, + 0x61, 0x74, 0x73, 0x20, 0x2e, 0}; static const char data_style_css[] PROGMEM = { /* /style.css */ @@ -527,12 +443,12 @@ 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, + 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xd, 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, 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, @@ -543,59 +459,59 @@ static const char data_tcp_shtml[] PROGMEM = { 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}; + 0x2f, 0x74, 0x72, 0x3e, 0xd, 0xa, 0x25, 0x21, 0x20, 0x74, + 0x63, 0x70, 0x2d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0xd, 0xa, 0x3c, 0x2f, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x3e, 0xd, 0xa, 0x25, 0x21, 0x20, 0x66, + 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, + 0x2e, 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}; + 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62, 0x6f, 0x64, + 0x79, 0x3e, 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, 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, + 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, 0x3c, 0x2f, + 0x66, 0x6f, 0x72, 0x6d, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, + 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0}; -const struct httpd_fsdata_file file_404_html[] = {{NULL, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10}}; +const struct httpd_fsdata_file file_404_html[] PROGMEM = {{NULL, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10}}; -const struct httpd_fsdata_file file_favicon_png[] = {{file_404_html, data_favicon_png, data_favicon_png + 13, sizeof(data_favicon_png) - 13}}; +const struct httpd_fsdata_file file_favicon_png[] PROGMEM = {{file_404_html, data_favicon_png, data_favicon_png + 13, sizeof(data_favicon_png) - 13}}; -const struct httpd_fsdata_file file_files_shtml[] = {{file_favicon_png, data_files_shtml, data_files_shtml + 13, sizeof(data_files_shtml) - 13}}; +const struct httpd_fsdata_file file_files_shtml[] PROGMEM = {{file_favicon_png, data_files_shtml, data_files_shtml + 13, sizeof(data_files_shtml) - 13}}; -const struct httpd_fsdata_file file_footer_html[] = {{file_files_shtml, data_footer_html, data_footer_html + 13, sizeof(data_footer_html) - 13}}; +const struct httpd_fsdata_file file_footer_html[] PROGMEM = {{file_files_shtml, data_footer_html, data_footer_html + 13, sizeof(data_footer_html) - 13}}; -const struct httpd_fsdata_file file_header_html[] = {{file_footer_html, data_header_html, data_header_html + 13, sizeof(data_header_html) - 13}}; +const struct httpd_fsdata_file file_header_html[] PROGMEM = {{file_footer_html, data_header_html, data_header_html + 13, sizeof(data_header_html) - 13}}; -const struct httpd_fsdata_file file_index_html[] = {{file_header_html, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12}}; +const struct httpd_fsdata_file file_index_html[] PROGMEM = {{file_header_html, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12}}; -const struct httpd_fsdata_file file_processes_shtml[] = {{file_index_html, data_processes_shtml, data_processes_shtml + 17, sizeof(data_processes_shtml) - 17}}; +const struct httpd_fsdata_file file_processes_shtml[] PROGMEM = {{file_index_html, data_processes_shtml, data_processes_shtml + 17, sizeof(data_processes_shtml) - 17}}; -const struct httpd_fsdata_file file_robots_txt[] = {{file_processes_shtml, data_robots_txt, data_robots_txt + 12, sizeof(data_robots_txt) - 12}}; +const struct httpd_fsdata_file file_robots_txt[] PROGMEM = {{file_processes_shtml, data_robots_txt, data_robots_txt + 12, sizeof(data_robots_txt) - 12}}; -const struct httpd_fsdata_file file_sensor_shtml[] = {{file_robots_txt, data_sensor_shtml, data_sensor_shtml + 14, sizeof(data_sensor_shtml) - 14}}; +const struct httpd_fsdata_file file_sensor_shtml[] PROGMEM = {{file_robots_txt, data_sensor_shtml, data_sensor_shtml + 14, sizeof(data_sensor_shtml) - 14}}; -const struct httpd_fsdata_file file_style_css[] = {{file_sensor_shtml, data_style_css, data_style_css + 11, sizeof(data_style_css) - 11}}; +const struct httpd_fsdata_file file_style_css[] PROGMEM = {{file_sensor_shtml, data_style_css, data_style_css + 11, sizeof(data_style_css) - 11}}; -const struct httpd_fsdata_file file_tcp_shtml[] = {{file_style_css, data_tcp_shtml, data_tcp_shtml + 11, sizeof(data_tcp_shtml) - 11}}; +const struct httpd_fsdata_file file_tcp_shtml[] PROGMEM = {{file_style_css, data_tcp_shtml, data_tcp_shtml + 11, sizeof(data_tcp_shtml) - 11}}; -const struct httpd_fsdata_file file_upload_html[] = {{file_tcp_shtml, data_upload_html, data_upload_html + 13, sizeof(data_upload_html) - 13}}; +const struct httpd_fsdata_file file_upload_html[] PROGMEM = {{file_tcp_shtml, data_upload_html, data_upload_html + 13, sizeof(data_upload_html) - 13}}; #define HTTPD_FS_ROOT file_upload_html diff --git a/platform/avr-raven/apps/raven-webserver/httpd-fsdata.h b/platform/avr-raven/apps/raven-webserver/httpd-fsdata.h index 5f4377484..9da15d820 100644 --- a/platform/avr-raven/apps/raven-webserver/httpd-fsdata.h +++ b/platform/avr-raven/apps/raven-webserver/httpd-fsdata.h @@ -30,7 +30,7 @@ * * Author: Adam Dunkels * - * $Id: httpd-fsdata.h,v 1.1 2009/03/12 19:15:25 adamdunkels Exp $ + * $Id: httpd-fsdata.h,v 1.2 2009/06/19 17:11:28 dak664 Exp $ */ #ifndef __HTTPD_FSDATA_H__ #define __HTTPD_FSDATA_H__ @@ -42,11 +42,9 @@ struct httpd_fsdata_file { 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 { @@ -54,11 +52,9 @@ struct httpd_fsdata_file_noconst { char *name; char *data; int len; -#ifdef HTTPD_FS_STATISTICS #if HTTPD_FS_STATISTICS == 1 u16_t count; #endif /* HTTPD_FS_STATISTICS */ -#endif /* HTTPD_FS_STATISTICS */ }; #endif /* __HTTPD_FSDATA_H__ */ diff --git a/platform/avr-raven/apps/raven-webserver/httpd.c b/platform/avr-raven/apps/raven-webserver/httpd.c index 1c441f105..e65938fb2 100644 --- a/platform/avr-raven/apps/raven-webserver/httpd.c +++ b/platform/avr-raven/apps/raven-webserver/httpd.c @@ -30,7 +30,7 @@ * * Author: Adam Dunkels * - * $Id: httpd.c,v 1.1 2009/03/12 19:15:25 adamdunkels Exp $ + * $Id: httpd.c,v 1.2 2009/06/19 17:11:28 dak664 Exp $ */ #include @@ -40,8 +40,8 @@ #include "webserver.h" #include "httpd-fs.h" #include "httpd-cgi.h" -#include "lib/petsciiconv.h" -#include "http-strings.h" +//#include "lib/petsciiconv.h" +//#include "http-strings.h" #include "httpd.h" @@ -54,10 +54,12 @@ #define STATE_WAITING 0 #define STATE_OUTPUT 1 -#define SEND_STRING(s, str) PSOCK_SEND(s, (uint8_t *)str, (unsigned int)strlen(str)) +//#define SEND_STRING(s, str) PSOCK_SEND(s, (uint8_t *)str, (unsigned int)strlen(str)) MEMB(conns, struct httpd_state, CONNS); +#define ISO_tab 0x09 #define ISO_nl 0x0a +#define ISO_cr 0x0d #define ISO_space 0x20 #define ISO_bang 0x21 #define ISO_percent 0x25 @@ -144,6 +146,23 @@ next_scriptstate(struct httpd_state *s) s->scriptptr = p;*/ } +/*---------------------------------------------------------------------------*/ +void +memcpy_P_trim(char *toram, char *fromflash) +{ + uint8_t i; + for (i=0;i<19;) { + toram[i]=pgm_read_byte_near(fromflash++); + if (toram[i]==ISO_tab) {if (i) break; else continue;} //skip leading tabs + if (toram[i]==ISO_space) {if (i) break; else continue;} //skip leading spaces + if (toram[i]==ISO_nl) break; //nl is preferred delimiter + if (toram[i]==ISO_cr) break; //some editors insert cr + if (toram[i]==0) break; //files are terminated with null + i++; + } + toram[i]=0; + + } /*---------------------------------------------------------------------------*/ static char filenamebuf[25],*pptr;//See below! static @@ -161,11 +180,10 @@ PT_THREAD(handle_script(struct httpd_state *s)) 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); + memcpy_P_trim(filenamebuf,s->scriptptr); if(httpd_fs_getchar(s->scriptptr - 1) == ISO_colon) { - httpd_fs_open(filenamebuf + 1, &s->file); + httpd_fs_open(filenamebuf, &s->file); PT_WAIT_THREAD(&s->scriptpt, send_file(s)); } else { PT_WAIT_THREAD(&s->scriptpt, @@ -182,7 +200,7 @@ PT_THREAD(handle_script(struct httpd_state *s)) to be sent. */ if(s->file.len > uip_mss()) { - s->len = uip_mss(); + s->len = uip_mss(); } else { s->len = s->file.len; } @@ -192,47 +210,82 @@ PT_THREAD(handle_script(struct httpd_state *s)) } else { pptr = (char *) httpd_fs_strchr(s->file.data, ISO_percent); } - if(pptr != NULL && - pptr != s->file.data) { - s->len = (int)(pptr - s->file.data); - if(s->len >= uip_mss()) { - s->len = uip_mss(); - } + if(pptr != NULL && pptr != s->file.data) { + s->len = (int)(pptr - 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 unsigned short +generate_status_P(void *pstr) +{ + uint8_t slen=strlen_P(pstr); + memcpy_P(uip_appdata, PSTR("HTTP/1.0 "), 9); + memcpy_P(uip_appdata+9, pstr, slen); + slen+=9; + memcpy_P(uip_appdata+slen, PSTR("\r\nServer: Contiki/2.0 http://www.sics.se/contiki/\r\nConnection: close\r\n"), 70); + return slen+70; +} +/*---------------------------------------------------------------------------*/ +static unsigned short +generate_header_P(void *pstr) +{ + uint8_t slen=strlen_P(pstr); + memcpy_P(uip_appdata,PSTR("Content-type: "),14); + memcpy_P(uip_appdata+14, pstr, slen); + slen+=14; + memcpy_P(uip_appdata+slen,PSTR("\r\n\r\n"),4); + return slen+4; +} +/*---------------------------------------------------------------------------*/ + +char http_htm[10] PROGMEM ="text/html"; +char http_css[ 9] PROGMEM ="text/css"; +char http_png[10] PROGMEM ="image/png"; +char http_gif[10] PROGMEM ="image/gif"; +char http_jpg[11] PROGMEM ="image/jpeg"; +char http_txt[11] PROGMEM ="text/plain"; +char http_shtml[ 6] PROGMEM =".shtml"; +char index_html[12] PROGMEM ="/index.html"; + static -PT_THREAD(send_headers(struct httpd_state *s, const char *statushdr)) +PT_THREAD(send_headers(struct httpd_state *s, char *statushdr)) { char *ptr; - PSOCK_BEGIN(&s->sout); - SEND_STRING(&s->sout, statushdr); + PSOCK_GENERATOR_SEND(&s->sout,generate_status_P,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); + + if (pgm_read_byte_near(statushdr)=='4') { + PSOCK_GENERATOR_SEND(&s->sout, generate_header_P, http_htm); + } else if(ptr == NULL) { + PSOCK_GENERATOR_SEND(&s->sout, generate_header_P,PSTR("application/octet-stream")); } else { - SEND_STRING(&s->sout, http_content_type_plain); + ptr++; + if(strncmp_P(ptr, &http_htm[5],3)== 0 ||strncmp_P(ptr, &http_shtml[1], 4) == 0) { + PSOCK_GENERATOR_SEND(&s->sout, generate_header_P, http_htm ); + } else if(strcmp_P(ptr, &http_css[5]) == 0) { + PSOCK_GENERATOR_SEND(&s->sout, generate_header_P, http_css ); + } else if(strcmp_P(ptr, &http_png[6]) == 0) { + PSOCK_GENERATOR_SEND(&s->sout, generate_header_P, http_png ); + } else if(strcmp_P(ptr, &http_gif[6])== 0) { + PSOCK_GENERATOR_SEND(&s->sout, generate_header_P, http_gif ); + } else if(strcmp_P(ptr, PSTR("jpg")) == 0) { + PSOCK_GENERATOR_SEND(&s->sout, generate_header_P, http_jpg ); + } else { + PSOCK_GENERATOR_SEND(&s->sout, generate_header_P, http_txt); + } } PSOCK_END(&s->sout); } @@ -243,40 +296,36 @@ PT_THREAD(handle_output(struct httpd_state *s)) char *ptr; PT_BEGIN(&s->outputpt); - +// strcpy(s->filename,"/index.html"); //for debugging 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)); + strcpy_P(s->filename, PSTR("/404.html")); + httpd_fs_open(s->filename, &s->file); + PT_WAIT_THREAD(&s->outputpt, send_headers(s, PSTR("404 Not found"))); + PT_WAIT_THREAD(&s->outputpt, send_file(s)); } else { - PT_WAIT_THREAD(&s->outputpt, - send_headers(s, - http_header_200)); + PT_WAIT_THREAD(&s->outputpt, send_headers(s, PSTR("200 OK"))); ptr = strchr(s->filename, ISO_period); - if(ptr != NULL && strncmp(ptr, http_shtml, 6) == 0 || strcmp_P(s->filename,PSTR("/index.html")) ==0) { -// if(ptr != NULL && strncmp(ptr, http_shtml, 6) == 0 ) { + if((ptr != NULL && strncmp_P(ptr, http_shtml, 6) == 0) || strcmp_P(s->filename,index_html)==0) { PT_INIT(&s->scriptpt); PT_WAIT_THREAD(&s->outputpt, handle_script(s)); } else { - PT_WAIT_THREAD(&s->outputpt, - send_file(s)); + PT_WAIT_THREAD(&s->outputpt, send_file(s)); } } PSOCK_CLOSE(&s->sout); PT_END(&s->outputpt); } /*---------------------------------------------------------------------------*/ +char http_get[4] PROGMEM ="GET "; +char http_ref[8] PROGMEM ="Referer:"; 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) { + + if(strncmp_P(s->inputbuf, http_get, 4) != 0) { PSOCK_CLOSE_EXIT(&s->sin); } PSOCK_READTO(&s->sin, ISO_space); @@ -286,26 +335,25 @@ PT_THREAD(handle_input(struct httpd_state *s)) } if(s->inputbuf[1] == ISO_space) { - strncpy(s->filename, http_index_html, sizeof(s->filename)); + strcpy_P(s->filename, index_html); } 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) { + if(strncmp_P(s->inputbuf, http_ref, 8) == 0) { s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0; - petsciiconv_topetscii(s->inputbuf, PSOCK_DATALEN(&s->sin) - 2); +// petsciiconv_topetscii(s->inputbuf, PSOCK_DATALEN(&s->sin) - 2); webserver_log(s->inputbuf); } } - PSOCK_END(&s->sin); } /*---------------------------------------------------------------------------*/ diff --git a/platform/avr-raven/apps/raven-webserver/httpd.h b/platform/avr-raven/apps/raven-webserver/httpd.h index bb82b901d..b34814d26 100644 --- a/platform/avr-raven/apps/raven-webserver/httpd.h +++ b/platform/avr-raven/apps/raven-webserver/httpd.h @@ -28,7 +28,7 @@ * * This file is part of the uIP TCP/IP stack. * - * $Id: httpd.h,v 1.1 2009/03/12 19:15:25 adamdunkels Exp $ + * $Id: httpd.h,v 1.2 2009/06/19 17:11:28 dak664 Exp $ * */ @@ -59,5 +59,6 @@ struct httpd_state { void httpd_init(void); void httpd_appcall(void *state); +void memcpy_P_trim(char *toram, char *fromflash); #endif /* __HTTPD_H__ */ diff --git a/platform/avr-raven/apps/raven-webserver/webserver-nogui.c b/platform/avr-raven/apps/raven-webserver/webserver-nogui.c index 290e68415..1ed255ef6 100644 --- a/platform/avr-raven/apps/raven-webserver/webserver-nogui.c +++ b/platform/avr-raven/apps/raven-webserver/webserver-nogui.c @@ -29,7 +29,7 @@ * * This file is part of the Contiki OS. * - * $Id: webserver-nogui.c,v 1.1 2009/03/12 19:15:25 adamdunkels Exp $ + * $Id: webserver-nogui.c,v 1.2 2009/06/19 17:11:28 dak664 Exp $ * */ @@ -69,7 +69,7 @@ webserver_log_file(uip_ipaddr_t *requester, char *file) char buf[18]; /* Print out IP address of requesting host. */ - sprintf(buf, "%d.%d.%d.%d: ", requester->u8[0], requester->u8[1], + sprintf_P(buf, PSTR("%d.%d.%d.%d: "), requester->u8[0], requester->u8[1], requester->u8[2], requester->u8[3]); log_message(buf, file); #endif /* LOG_CONF_ENABLED */