34 #include <util/delay.h>
35 #define delay_us( us ) ( _delay_us( ( us ) ) )
49 #include "contiki-net.h"
51 #include "httpd-cgi.h"
53 #include "httpd-fsdata.h"
58 #define DEBUGLOGIC 0 //See httpd.c, if 1 must also set it there!
60 #define uip_mss(...) 512
61 #define uip_appdata TCPBUF
62 extern char TCPBUF[512];
70 static struct httpd_cgi_call *calls =
NULL;
73 #if HTTPD_FS_STATISTICS
74 static const char file_name[] HTTPD_STRING_ATTR =
"file-stats";
76 static const char tcp_name[] HTTPD_STRING_ATTR =
"tcp-connections";
77 static const char proc_name[] HTTPD_STRING_ATTR =
"processes";
78 static const char sensor_name[] HTTPD_STRING_ATTR =
"sensors";
79 static const char adrs_name[] HTTPD_STRING_ATTR =
"addresses";
80 static const char nbrs_name[] HTTPD_STRING_ATTR =
"neighbors";
81 static const char rtes_name[] HTTPD_STRING_ATTR =
"routes";
84 static const char closed[] HTTPD_STRING_ATTR =
"CLOSED";
85 static const char syn_rcvd[] HTTPD_STRING_ATTR =
"SYN-RCVD";
86 static const char syn_sent[] HTTPD_STRING_ATTR =
"SYN-SENT";
87 static const char established[] HTTPD_STRING_ATTR =
"ESTABLISHED";
88 static const char fin_wait_1[] HTTPD_STRING_ATTR =
"FIN-WAIT-1";
89 static const char fin_wait_2[] HTTPD_STRING_ATTR =
"FIN-WAIT-2";
90 static const char closing[] HTTPD_STRING_ATTR =
"CLOSING";
91 static const char time_wait[] HTTPD_STRING_ATTR =
"TIME-WAIT";
92 static const char last_ack[] HTTPD_STRING_ATTR =
"LAST-ACK";
93 static const char none[] HTTPD_STRING_ATTR =
"NONE";
94 static const char running[] HTTPD_STRING_ATTR =
"RUNNING";
95 static const char called[] HTTPD_STRING_ATTR =
"CALLED";
96 static const char *states[] = {
110 static char sensor_temperature[12]=
"Not Enabled";
111 static char sensor_extvoltage[12]=
"Not Enabled";
113 extern unsigned long seconds, sleepseconds;
115 extern unsigned long radioontime;
116 static unsigned long savedradioontime;
117 extern uint8_t RF230_radio_on, rf230_last_rssi;
118 extern uint16_t RF230_sendpackets,RF230_receivepackets,RF230_sendfail,RF230_receivefail;
123 web_set_temp(
char *s)
125 strcpy(sensor_temperature, s);
126 last_tempupdate=seconds;
129 web_set_voltage(
char *s)
131 strcpy(sensor_extvoltage, s);
132 last_extvoltageupdate=seconds;
137 PT_THREAD(nullfunction(
struct httpd_state *s,
char *ptr))
144 httpd_cgi(
char *name)
146 struct httpd_cgi_call *f;
149 for(f = calls; f !=
NULL; f = f->next) {
150 if(httpd_strncmp(name, f->name, httpd_strlen(f->name)) == 0) {
157 #if HTTPD_FS_STATISTICS
158 static char *thisfilename;
160 static unsigned short
161 generate_file_stats(
void *arg)
163 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>";
164 static const char httpd_cgi_filestat2[] HTTPD_STRING_ATTR =
"<tr><td><a href=\"%s\">%s</a></td><td>%d</td>";
165 static const char httpd_cgi_filestat3[] HTTPD_STRING_ATTR =
"%5u";
167 struct httpd_fsdata_file_noconst *f,fram;
169 unsigned short numprinted;
172 httpd_fs_cpy(&tmp, (
char *)arg, 20);
176 numprinted=httpd_snprintf((
char *)
uip_appdata,
uip_mss(), httpd_cgi_filestat1, httpd_fs_open(thisfilename, 0));
180 }
else if (tmp[0]==
'*') {
182 for(f = (
struct httpd_fsdata_file_noconst *)httpd_fs_get_root();
184 f = (
struct httpd_fsdata_file_noconst *)fram.next) {
187 httpd_memcpy(&fram,f,
sizeof(fram));
190 httpd_fs_cpy(&tmp, fram.name,
sizeof(tmp));
191 #if HTTPD_FS_STATISTICS==1
192 numprinted+=httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_filestat2, tmp, tmp, f->count);
193 #elif HTTPD_FS_STATISTICS==2
194 numprinted+=httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_filestat2, tmp, tmp, httpd_filecount[i]);
201 numprinted=httpd_snprintf((
char *)
uip_appdata,
uip_mss(), httpd_cgi_filestat3, httpd_fs_open(tmp, 0));
210 PT_THREAD(file_stats(
struct httpd_state *s,
char *ptr))
215 thisfilename=&s->filename[0];
223 static unsigned short
224 make_tcp_stats(
void *arg)
226 static const char httpd_cgi_tcpstat1[] HTTPD_STRING_ATTR =
"<tr align=\"center\"><td>%d</td><td>";
227 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";
229 struct httpd_state *s = (
struct httpd_state *)arg;
233 conn = &uip_conns[s->u.count];
237 httpd_strcpy(tstate,states[conn->
tcpstateflags & UIP_TS_MASK]);
238 numprinted += httpd_snprintf((
char *)
uip_appdata + numprinted,
uip_mss() - numprinted,
244 (uip_outstanding(conn))?
'*':
' ',
251 PT_THREAD(tcp_stats(
struct httpd_state *s,
char *ptr))
256 for(s->u.count = 0; s->u.count <
UIP_CONNS; ++s->u.count) {
257 if((uip_conns[s->u.count].tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) {
265 static unsigned short
266 make_processes(
void *p)
268 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";
269 char name[40],tstate[20];
271 strncpy(name, PROCESS_NAME_STRING((
struct process *)p), 40);
272 petsciiconv_toascii(name, 40);
273 httpd_strcpy(tstate,states[9 + ((
struct process *)p)->state]);
275 *(
char *)(&(((
struct process *)p)->thread)),
281 PT_THREAD(processes(
struct httpd_state *s,
char *ptr))
284 for(s->u.ptr = PROCESS_LIST(); s->u.ptr !=
NULL; s->u.ptr = ((
struct process *)s->u.ptr)->next) {
290 static const char httpd_cgi_addrh[] HTTPD_STRING_ATTR =
"<code>";
291 static const char httpd_cgi_addrf[] HTTPD_STRING_ATTR =
"</code>[Room for %u more]";
292 static const char httpd_cgi_addrb[] HTTPD_STRING_ATTR =
"<br>";
293 static const char httpd_cgi_addrn[] HTTPD_STRING_ATTR =
"(none)<br>";
298 static unsigned short
299 make_addresses(
void *p)
304 for (i=0; i<UIP_DS6_ADDR_NB;i++) {
305 if (uip_ds6_if.addr_list[i].isused) {
307 numprinted += httpd_cgi_sprint_ip6(uip_ds6_if.addr_list[i].ipaddr,
uip_appdata + numprinted);
308 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_addrb);
312 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_addrf, UIP_DS6_ADDR_NB-j);
317 PT_THREAD(addresses(
struct httpd_state *s,
char *ptr))
326 static unsigned short
327 make_neighbors(
void *p)
332 for (i=0; i<UIP_DS6_NBR_NB;i++) {
333 if (uip_ds6_nbr_cache[i].isused) {
335 numprinted += httpd_cgi_sprint_ip6(uip_ds6_nbr_cache[i].ipaddr,
uip_appdata + numprinted);
336 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_addrb);
340 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_addrf,UIP_DS6_NBR_NB-j);
345 PT_THREAD(neighbors(
struct httpd_state *s,
char *ptr))
354 static unsigned short
357 static const char httpd_cgi_rtes1[] HTTPD_STRING_ATTR =
"(%u (via ";
358 static const char httpd_cgi_rtes2[] HTTPD_STRING_ATTR =
") %lus<br>";
359 static const char httpd_cgi_rtes3[] HTTPD_STRING_ATTR =
")<br>";
363 for (i=0; i<UIP_DS6_ROUTE_NB;i++) {
364 if (uip_ds6_routing_table[i].isused) {
366 numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].ipaddr,
uip_appdata + numprinted);
367 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_rtes1, uip_ds6_routing_table[i].length);
368 numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].nexthop,
uip_appdata + numprinted);
369 if(uip_ds6_routing_table[i].state.lifetime < 3600) {
370 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_rtes2, uip_ds6_routing_table[i].state.lifetime);
372 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_rtes3);
376 if (j==0) numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_addrn);
377 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_addrf,UIP_DS6_ROUTE_NB-j);
382 PT_THREAD(routes(
struct httpd_state *s,
char *ptr))
391 static unsigned short
392 generate_sensor_readings(
void *arg)
400 static const char httpd_cgi_sensor1_printf[] HTTPD_STRING_ATTR =
"%d.%d C";
401 static const char httpd_cgi_sensor2_printf[] HTTPD_STRING_ATTR =
"%d mv";
402 static const char httpd_cgi_sensr12[] HTTPD_STRING_ATTR =
"<em>Temperature:</em> %s <em>Battery:<em> %s<br>";
403 static const char httpd_cgi_sensor3[] HTTPD_STRING_ATTR =
"<em>Elapsed timer :</em> %02d:%02d:%02d<br>";
404 static const char httpd_cgi_sensor4[] HTTPD_STRING_ATTR =
"<em>Sleeping time :</em> %02d:%02d:%02d (%d%%)<br>";
422 while (ADCSRA&(1<<ADSC));
424 while (ADCSRA&(1<<ADSC));
430 httpd_snprintf(sensor_temperature,
sizeof(sensor_temperature),httpd_cgi_sensor1_printf,m,s);
435 for ( p1=16; p1<31; p1++) {
438 if ((BATMON&(1<<BATMON_OK))==0)
break;
440 h=2550-75*16-75+75*p1;
441 httpd_snprintf(sensor_extvoltage,
sizeof(sensor_extvoltage),httpd_cgi_sensor2_printf,h);
443 numprinted+=httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_sensr12, sensor_temperature,sensor_extvoltage);
448 savedradioontime = radioontime;
454 numprinted+=httpd_snprintf((
char *)
uip_appdata + numprinted,
uip_mss() - numprinted, httpd_cgi_sensor3, h,m,s);
456 p1=100UL*sleepseconds/seconds;
458 s=sleepseconds-h*3600;
461 numprinted+=httpd_snprintf((
char *)
uip_appdata + numprinted,
uip_mss() - numprinted, httpd_cgi_sensor4, h,m,s,p1);
467 static unsigned short
468 generate_radio_stats(
void *arg)
473 static const char httpd_cgi_sensor10[] HTTPD_STRING_ATTR =
"<em>Radio on time :</em> %02d:%02d:%02d (%d.%02d%%)<br>";
474 static const char httpd_cgi_sensor11[] HTTPD_STRING_ATTR =
"<em>Packets:</em> Tx=%5d Rx=%5d TxL=%5d RxL=%5d RSSI=%2ddBm\n";
476 s=(10000UL*savedradioontime)/seconds;
479 h=savedradioontime/3600;
480 s=savedradioontime-h*3600;
488 numprinted+=httpd_snprintf((
char *)
uip_appdata + numprinted,
uip_mss() - numprinted, httpd_cgi_sensor11,\
489 RF230_sendpackets,RF230_receivepackets,RF230_sendfail,RF230_receivefail,-92+rf230_last_rssi);
494 numprinted+=httpd_snprintf((
char *)
uip_appdata + numprinted,
uip_mss() - numprinted, httpd_cgi_sensor11,\
495 RF230_sendpackets,RF230_receivepackets,RF230_sendfail,RF230_receivefail,p1);
503 PT_THREAD(sensor_readings(
struct httpd_state *s,
char *ptr))
517 httpd_cgi_add(
struct httpd_cgi_call *c)
519 struct httpd_cgi_call *l;
525 for(l = calls; l->next !=
NULL; l = l->next);
531 #if HTTPD_FS_STATISTICS
532 HTTPD_CGI_CALL( file, file_name, file_stats);
534 HTTPD_CGI_CALL( tcp, tcp_name, tcp_stats );
535 HTTPD_CGI_CALL( proc, proc_name, processes );
536 HTTPD_CGI_CALL( adrs, adrs_name, addresses );
537 HTTPD_CGI_CALL( nbrs, nbrs_name, neighbors );
538 HTTPD_CGI_CALL( rtes, rtes_name, routes );
539 HTTPD_CGI_CALL(sensors, sensor_name, sensor_readings);
544 #if HTTPD_FS_STATISTICS
545 httpd_cgi_add( &file);
547 httpd_cgi_add( &tcp);
548 httpd_cgi_add( &proc);
549 httpd_cgi_add( &adrs);
550 httpd_cgi_add( &nbrs);
551 httpd_cgi_add( &rtes);
552 httpd_cgi_add(&sensors);
556 uint8_t httpd_cgi_sprint_ip6(uip_ip6addr_t addr,
char * result)
558 unsigned char zerocnt = 0;
559 unsigned char numprinted = 0;
560 char * starting = result;
564 while (numprinted < 8)
568 if ((addr.u16[i] == 0) && (zerocnt == 0))
572 while(addr.u16[zerocnt + i] == 0)
585 numprinted += zerocnt;
590 result += sprintf(result,
"%x", (
unsigned int)(uip_ntohs(addr.u16[i])));
600 return (result - starting);