48 #include "contiki-net.h"
50 #include "httpd-cgi.h"
52 #include "httpd-fsdata.h"
57 #define DEBUGLOGIC 0 //See httpd.c, if 1 must also set it there!
59 #define uip_mss(...) 512
60 #define uip_appdata TCPBUF
61 extern char TCPBUF[512];
69 static struct httpd_cgi_call *calls =
NULL;
72 #if HTTPD_FS_STATISTICS
73 static const char file_name[] HTTPD_STRING_ATTR =
"file-stats";
75 static const char tcp_name[] HTTPD_STRING_ATTR =
"tcp-connections";
76 static const char proc_name[] HTTPD_STRING_ATTR =
"processes";
77 static const char sensor_name[] HTTPD_STRING_ATTR =
"sensors";
78 static const char adrs_name[] HTTPD_STRING_ATTR =
"addresses";
79 static const char nbrs_name[] HTTPD_STRING_ATTR =
"neighbors";
80 static const char rtes_name[] HTTPD_STRING_ATTR =
"routes";
83 static const char closed[] HTTPD_STRING_ATTR =
"CLOSED";
84 static const char syn_rcvd[] HTTPD_STRING_ATTR =
"SYN-RCVD";
85 static const char syn_sent[] HTTPD_STRING_ATTR =
"SYN-SENT";
86 static const char established[] HTTPD_STRING_ATTR =
"ESTABLISHED";
87 static const char fin_wait_1[] HTTPD_STRING_ATTR =
"FIN-WAIT-1";
88 static const char fin_wait_2[] HTTPD_STRING_ATTR =
"FIN-WAIT-2";
89 static const char closing[] HTTPD_STRING_ATTR =
"CLOSING";
90 static const char time_wait[] HTTPD_STRING_ATTR =
"TIME-WAIT";
91 static const char last_ack[] HTTPD_STRING_ATTR =
"LAST-ACK";
92 static const char none[] HTTPD_STRING_ATTR =
"NONE";
93 static const char running[] HTTPD_STRING_ATTR =
"RUNNING";
94 static const char called[] HTTPD_STRING_ATTR =
"CALLED";
95 static const char *states[] = {
109 static char sensor_temperature[12]=
"Not Enabled";
110 static char sensor_extvoltage[12]=
"Not Enabled";
111 static unsigned long last_tempupdate,last_extvoltageupdate;
112 extern unsigned long seconds, sleepseconds;
114 extern unsigned long radioontime;
115 static unsigned long savedradioontime;
116 extern uint8_t RF230_radio_on, rf230_last_rssi;
117 extern uint16_t RF230_sendpackets,RF230_receivepackets,RF230_sendfail,RF230_receivefail;
122 web_set_temp(
char *s)
124 strcpy(sensor_temperature, s);
126 last_tempupdate=seconds;
129 web_set_voltage(
char *s)
131 strcpy(sensor_extvoltage, s);
133 last_extvoltageupdate=seconds;
138 PT_THREAD(nullfunction(
struct httpd_state *s,
char *ptr))
145 httpd_cgi(
char *name)
147 struct httpd_cgi_call *f;
150 for(f = calls; f !=
NULL; f = f->next) {
151 if(httpd_strncmp(name, f->name, httpd_strlen(f->name)) == 0) {
158 #if HTTPD_FS_STATISTICS
159 static char *thisfilename;
161 static unsigned short
162 generate_file_stats(
void *arg)
164 static const char httpd_cgi_filestat1[] HTTPD_STRING_ATTR =
"<p class=right><br><br><i>This page has been sent %u times</i></div></body></html>";
165 static const char httpd_cgi_filestat2[] HTTPD_STRING_ATTR =
"<tr><td><a href=\"%s\">%s</a></td><td>%d</td>";
166 static const char httpd_cgi_filestat3[] HTTPD_STRING_ATTR =
"%5u";
168 struct httpd_fsdata_file_noconst *f,fram;
170 unsigned short numprinted;
173 httpd_fs_cpy(&tmp, (
char *)arg, 20);
177 numprinted=httpd_snprintf((
char *)
uip_appdata,
uip_mss(), httpd_cgi_filestat1, httpd_fs_open(thisfilename, 0));
181 }
else if (tmp[0]==
'*') {
183 for(f = (
struct httpd_fsdata_file_noconst *)httpd_fs_get_root();
185 f = (
struct httpd_fsdata_file_noconst *)fram.next) {
188 httpd_memcpy(&fram,f,
sizeof(fram));
191 httpd_fs_cpy(&tmp, fram.name,
sizeof(tmp));
192 #if HTTPD_FS_STATISTICS==1
193 numprinted+=httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_filestat2, tmp, tmp, f->count);
194 #elif HTTPD_FS_STATISTICS==2
195 numprinted+=httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_filestat2, tmp, tmp, httpd_filecount[i]);
202 numprinted=httpd_snprintf((
char *)
uip_appdata,
uip_mss(), httpd_cgi_filestat3, httpd_fs_open(tmp, 0));
211 PT_THREAD(file_stats(
struct httpd_state *s,
char *ptr))
216 thisfilename=&s->filename[0];
224 static unsigned short
225 make_tcp_stats(
void *arg)
227 static const char httpd_cgi_tcpstat1[] HTTPD_STRING_ATTR =
"<tr align=\"center\"><td>%d</td><td>";
228 static const char httpd_cgi_tcpstat2[] HTTPD_STRING_ATTR =
"-%u</td><td>%s</td><td>%u</td><td>%u</td><td>%c %c</td></tr>\r\n";
230 struct httpd_state *s = (
struct httpd_state *)arg;
234 conn = &uip_conns[s->u.count];
238 httpd_strcpy(tstate,states[conn->
tcpstateflags & UIP_TS_MASK]);
239 numprinted += httpd_snprintf((
char *)
uip_appdata + numprinted,
uip_mss() - numprinted,
245 (uip_outstanding(conn))?
'*':
' ',
252 PT_THREAD(tcp_stats(
struct httpd_state *s,
char *ptr))
257 for(s->u.count = 0; s->u.count <
UIP_CONNS; ++s->u.count) {
258 if((uip_conns[s->u.count].tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) {
266 static unsigned short
267 make_processes(
void *p)
269 static const char httpd_cgi_proc[] HTTPD_STRING_ATTR =
"<tr align=\"center\"><td>%p</td><td>%s</td><td>%p</td><td>%s</td></tr>\r\n";
270 char name[40],tstate[20];
272 strncpy(name, PROCESS_NAME_STRING((
struct process *)p), 40);
273 petsciiconv_toascii(name, 40);
274 httpd_strcpy(tstate,states[9 + ((
struct process *)p)->state]);
276 *(
char *)(&(((
struct process *)p)->thread)),
282 PT_THREAD(processes(
struct httpd_state *s,
char *ptr))
285 for(s->u.ptr = PROCESS_LIST(); s->u.ptr !=
NULL; s->u.ptr = ((
struct process *)s->u.ptr)->next) {
291 static const char httpd_cgi_addrh[] HTTPD_STRING_ATTR =
"<code>";
292 static const char httpd_cgi_addrf[] HTTPD_STRING_ATTR =
"</code>[Room for %u more]";
293 static const char httpd_cgi_addrb[] HTTPD_STRING_ATTR =
"<br>";
294 static const char httpd_cgi_addrn[] HTTPD_STRING_ATTR =
"(none)<br>";
299 static unsigned short
300 make_addresses(
void *p)
305 for (i=0; i<UIP_DS6_ADDR_NB;i++) {
306 if (uip_ds6_if.addr_list[i].isused) {
308 numprinted += httpd_cgi_sprint_ip6(uip_ds6_if.addr_list[i].ipaddr,
uip_appdata + numprinted);
309 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_addrb);
313 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_addrf, UIP_DS6_ADDR_NB-j);
318 PT_THREAD(addresses(
struct httpd_state *s,
char *ptr))
327 static unsigned short
328 make_neighbors(
void *p)
333 for (i=0; i<UIP_DS6_NBR_NB;i++) {
334 if (uip_ds6_nbr_cache[i].isused) {
336 numprinted += httpd_cgi_sprint_ip6(uip_ds6_nbr_cache[i].ipaddr,
uip_appdata + numprinted);
337 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_addrb);
341 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_addrf,UIP_DS6_NBR_NB-j);
346 PT_THREAD(neighbors(
struct httpd_state *s,
char *ptr))
355 static unsigned short
358 static const char httpd_cgi_rtes1[] HTTPD_STRING_ATTR =
"(%u (via ";
359 static const char httpd_cgi_rtes2[] HTTPD_STRING_ATTR =
") %lus<br>";
360 static const char httpd_cgi_rtes3[] HTTPD_STRING_ATTR =
")<br>";
364 for (i=0; i<UIP_DS6_ROUTE_NB;i++) {
365 if (uip_ds6_routing_table[i].isused) {
367 numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].ipaddr,
uip_appdata + numprinted);
368 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_rtes1, uip_ds6_routing_table[i].length);
369 numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].nexthop,
uip_appdata + numprinted);
370 if(uip_ds6_routing_table[i].state.lifetime < 3600) {
371 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_rtes2, uip_ds6_routing_table[i].state.lifetime);
373 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_rtes3);
377 if (j==0) numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_addrn);
378 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_addrf,UIP_DS6_ROUTE_NB-j);
383 PT_THREAD(routes(
struct httpd_state *s,
char *ptr))
392 static unsigned short
393 generate_sensor_readings(
void *arg)
398 static const char httpd_cgi_sensor0[] HTTPD_STRING_ATTR =
"[Updated %d seconds ago]<br><br>";
401 static const char httpd_cgi_sensr12[] HTTPD_STRING_ATTR =
"<em>Temperature:</em> %s <em>Battery:<em> %s<br>";
402 static const char httpd_cgi_sensor3[] HTTPD_STRING_ATTR =
"<em>Elapsed timer :</em> %02d:%02d:%02d<br>";
403 static const char httpd_cgi_sensor4[] HTTPD_STRING_ATTR =
"<em>Sleeping time :</em> %02d:%02d:%02d (%d%%)<br>";
406 if (last_tempupdate) {
407 numprinted =httpd_snprintf((
char *)
uip_appdata,
uip_mss(), httpd_cgi_sensor0,seconds-last_tempupdate);
411 numprinted+=httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_sensr12, sensor_temperature,sensor_extvoltage);
419 while (ADCSRA&(1<<ADSC));
421 while (ADCSRA&(1<<ADSC));
428 savedradioontime = radioontime;
434 numprinted+=httpd_snprintf((
char *)
uip_appdata + numprinted,
uip_mss() - numprinted, httpd_cgi_sensor3, h,m,s);
436 p1=100UL*sleepseconds/seconds;
438 s=sleepseconds-h*3600;
441 numprinted+=httpd_snprintf((
char *)
uip_appdata + numprinted,
uip_mss() - numprinted, httpd_cgi_sensor4, h,m,s,p1);
447 static unsigned short
448 generate_radio_stats(
void *arg)
453 static const char httpd_cgi_sensor10[] HTTPD_STRING_ATTR =
"<em>Radio on time :</em> %02d:%02d:%02d (%d.%02d%%)<br>";
454 static const char httpd_cgi_sensor11[] HTTPD_STRING_ATTR =
"<em>Packets:</em> Tx=%5d Rx=%5d TxL=%5d RxL=%5d RSSI=%2ddBm\n";
456 s=(10000UL*savedradioontime)/seconds;
459 h=savedradioontime/3600;
460 s=savedradioontime-h*3600;
468 numprinted+=httpd_snprintf((
char *)
uip_appdata + numprinted,
uip_mss() - numprinted, httpd_cgi_sensor11,\
469 RF230_sendpackets,RF230_receivepackets,RF230_sendfail,RF230_receivefail,-92+rf230_last_rssi);
474 numprinted+=httpd_snprintf((
char *)
uip_appdata + numprinted,
uip_mss() - numprinted, httpd_cgi_sensor11,\
475 RF230_sendpackets,RF230_receivepackets,RF230_sendfail,RF230_receivefail,p1);
483 PT_THREAD(sensor_readings(
struct httpd_state *s,
char *ptr))
497 httpd_cgi_add(
struct httpd_cgi_call *c)
499 struct httpd_cgi_call *l;
505 for(l = calls; l->next !=
NULL; l = l->next);
511 #if HTTPD_FS_STATISTICS
512 HTTPD_CGI_CALL( file, file_name, file_stats);
514 HTTPD_CGI_CALL( tcp, tcp_name, tcp_stats );
515 HTTPD_CGI_CALL( proc, proc_name, processes );
516 HTTPD_CGI_CALL( adrs, adrs_name, addresses );
517 HTTPD_CGI_CALL( nbrs, nbrs_name, neighbors );
518 HTTPD_CGI_CALL( rtes, rtes_name, routes );
519 HTTPD_CGI_CALL(sensors, sensor_name, sensor_readings);
524 #if HTTPD_FS_STATISTICS
525 httpd_cgi_add( &file);
527 httpd_cgi_add( &tcp);
528 httpd_cgi_add( &proc);
529 httpd_cgi_add( &adrs);
530 httpd_cgi_add( &nbrs);
531 httpd_cgi_add( &rtes);
532 httpd_cgi_add(&sensors);
536 uint8_t httpd_cgi_sprint_ip6(uip_ip6addr_t addr,
char * result)
538 unsigned char zerocnt = 0;
539 unsigned char numprinted = 0;
540 char * starting = result;
544 while (numprinted < 8)
548 if ((addr.u16[i] == 0) && (zerocnt == 0))
552 while(addr.u16[zerocnt + i] == 0)
565 numprinted += zerocnt;
570 result += sprintf(result,
"%x", (
unsigned int)(uip_ntohs(addr.u16[i])));
580 return (result - starting);