47 #include "contiki-net.h"
49 #include "httpd-cgi.h"
51 #include "httpd-fsdata.h"
56 #define DEBUGLOGIC 0 //See httpd.c, if 1 must also set it there!
58 #define uip_mss(...) 512
59 #define uip_appdata TCPBUF
60 extern char TCPBUF[512];
68 static struct httpd_cgi_call *calls =
NULL;
71 #if HTTPD_FS_STATISTICS
72 static const char file_name[] HTTPD_STRING_ATTR =
"file-stats";
74 static const char tcp_name[] HTTPD_STRING_ATTR =
"tcp-connections";
75 static const char proc_name[] HTTPD_STRING_ATTR =
"processes";
76 static const char sensor_name[] HTTPD_STRING_ATTR =
"sensors";
77 static const char adrs_name[] HTTPD_STRING_ATTR =
"addresses";
78 static const char nbrs_name[] HTTPD_STRING_ATTR =
"neighbors";
79 static const char rtes_name[] HTTPD_STRING_ATTR =
"routes";
82 static const char closed[] HTTPD_STRING_ATTR =
"CLOSED";
83 static const char syn_rcvd[] HTTPD_STRING_ATTR =
"SYN-RCVD";
84 static const char syn_sent[] HTTPD_STRING_ATTR =
"SYN-SENT";
85 static const char established[] HTTPD_STRING_ATTR =
"ESTABLISHED";
86 static const char fin_wait_1[] HTTPD_STRING_ATTR =
"FIN-WAIT-1";
87 static const char fin_wait_2[] HTTPD_STRING_ATTR =
"FIN-WAIT-2";
88 static const char closing[] HTTPD_STRING_ATTR =
"CLOSING";
89 static const char time_wait[] HTTPD_STRING_ATTR =
"TIME-WAIT";
90 static const char last_ack[] HTTPD_STRING_ATTR =
"LAST-ACK";
91 static const char none[] HTTPD_STRING_ATTR =
"NONE";
92 static const char running[] HTTPD_STRING_ATTR =
"RUNNING";
93 static const char called[] HTTPD_STRING_ATTR =
"CALLED";
94 static const char *states[] = {
108 static char sensor_temperature[12]=
"Not Enabled";
109 static char sensor_extvoltage[12]=
"Not Enabled";
110 static unsigned long last_tempupdate,last_extvoltageupdate;
111 extern unsigned long seconds, sleepseconds;
113 extern unsigned long radioontime;
114 static unsigned long savedradioontime;
115 extern uint8_t RF230_radio_on, rf230_last_rssi;
116 extern uint16_t RF230_sendpackets,RF230_receivepackets,RF230_sendfail,RF230_receivefail;
121 web_set_temp(
char *s)
123 strcpy(sensor_temperature, s);
125 last_tempupdate=seconds;
128 web_set_voltage(
char *s)
130 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>";
296 static unsigned short
297 make_addresses(
void *p)
302 for (i=0; i<UIP_DS6_ADDR_NB;i++) {
303 if (uip_ds6_if.addr_list[i].isused) {
305 numprinted += httpd_cgi_sprint_ip6(uip_ds6_if.addr_list[i].ipaddr,
uip_appdata + numprinted);
306 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_addrb);
310 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_addrf, UIP_DS6_ADDR_NB-j);
315 PT_THREAD(addresses(
struct httpd_state *s,
char *ptr))
324 static unsigned short
325 make_neighbors(
void *p)
332 for(nbr = nbr_table_head(ds6_neighbors);
334 nbr = nbr_table_next(ds6_neighbors, nbr)) {
336 numprinted += httpd_cgi_sprint_ip6(nbr->ipaddr,
uip_appdata + numprinted);
337 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,NBR_TABLE_MAX_NEIGHBORS-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>";
365 for(r = uip_ds6_route_head();
367 r = uip_ds6_route_next(r)) {
369 numprinted += httpd_cgi_sprint_ip6(r->ipaddr,
uip_appdata + numprinted);
370 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_rtes1, r->length);
371 numprinted += httpd_cgi_sprint_ip6(uip_ds6_route_nexthop(r),
uip_appdata + numprinted);
372 if(r->state.lifetime < 3600) {
373 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_rtes2, r->state.lifetime);
375 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_rtes3);
378 if (j==0) numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_addrn);
379 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_addrf,UIP_DS6_ROUTE_NB-j);
384 PT_THREAD(routes(
struct httpd_state *s,
char *ptr))
393 static unsigned short
394 generate_sensor_readings(
void *arg)
399 static const char httpd_cgi_sensor0[] HTTPD_STRING_ATTR =
"[Updated %d seconds ago]<br><br>";
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>";
407 if (last_tempupdate) {
408 numprinted =httpd_snprintf((
char *)
uip_appdata,
uip_mss(), httpd_cgi_sensor0,seconds-last_tempupdate);
412 numprinted+=httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_sensr12, sensor_temperature,sensor_extvoltage);
420 while (ADCSRA&(1<<ADSC));
422 while (ADCSRA&(1<<ADSC));
429 savedradioontime = radioontime;
435 numprinted+=httpd_snprintf((
char *)
uip_appdata + numprinted,
uip_mss() - numprinted, httpd_cgi_sensor3, h,m,s);
437 p1=100UL*sleepseconds/seconds;
439 s=sleepseconds-h*3600;
442 numprinted+=httpd_snprintf((
char *)
uip_appdata + numprinted,
uip_mss() - numprinted, httpd_cgi_sensor4, h,m,s,p1);
448 static unsigned short
449 generate_radio_stats(
void *arg)
454 static const char httpd_cgi_sensor10[] HTTPD_STRING_ATTR =
"<em>Radio on time :</em> %02d:%02d:%02d (%d.%02d%%)<br>";
455 static const char httpd_cgi_sensor11[] HTTPD_STRING_ATTR =
"<em>Packets:</em> Tx=%5d Rx=%5d TxL=%5d RxL=%5d RSSI=%2ddBm\n";
457 s=(10000UL*savedradioontime)/seconds;
460 h=savedradioontime/3600;
461 s=savedradioontime-h*3600;
469 numprinted+=httpd_snprintf((
char *)
uip_appdata + numprinted,
uip_mss() - numprinted, httpd_cgi_sensor11,\
470 RF230_sendpackets,RF230_receivepackets,RF230_sendfail,RF230_receivefail,-92+rf230_last_rssi);
475 numprinted+=httpd_snprintf((
char *)
uip_appdata + numprinted,
uip_mss() - numprinted, httpd_cgi_sensor11,\
476 RF230_sendpackets,RF230_receivepackets,RF230_sendfail,RF230_receivefail,p1);
484 PT_THREAD(sensor_readings(
struct httpd_state *s,
char *ptr))
498 httpd_cgi_add(
struct httpd_cgi_call *c)
500 struct httpd_cgi_call *l;
506 for(l = calls; l->next !=
NULL; l = l->next);
512 #if HTTPD_FS_STATISTICS
513 HTTPD_CGI_CALL( file, file_name, file_stats);
515 HTTPD_CGI_CALL( tcp, tcp_name, tcp_stats );
516 HTTPD_CGI_CALL( proc, proc_name, processes );
517 HTTPD_CGI_CALL( adrs, adrs_name, addresses );
518 HTTPD_CGI_CALL( nbrs, nbrs_name, neighbors );
519 HTTPD_CGI_CALL( rtes, rtes_name, routes );
520 HTTPD_CGI_CALL(sensors, sensor_name, sensor_readings);
525 #if HTTPD_FS_STATISTICS
526 httpd_cgi_add( &file);
528 httpd_cgi_add( &tcp);
529 httpd_cgi_add( &proc);
530 httpd_cgi_add( &adrs);
531 httpd_cgi_add( &nbrs);
532 httpd_cgi_add( &rtes);
533 httpd_cgi_add(&sensors);
537 uint8_t httpd_cgi_sprint_ip6(uip_ip6addr_t addr,
char * result)
539 unsigned char zerocnt = 0;
540 unsigned char numprinted = 0;
541 char * starting = result;
545 while (numprinted < 8)
549 if ((addr.u16[i] == 0) && (zerocnt == 0))
553 while(addr.u16[zerocnt + i] == 0)
566 numprinted += zerocnt;
571 result += sprintf(result,
"%x", (
unsigned int)(uip_ntohs(addr.u16[i])));
581 return (result - starting);
#define UIP_CONNS
The maximum number of simultaneously open TCP connections.
An entry in the routing table.
radio_status_t radio_get_rssi_value(uint8_t *rssi)
This function returns the Received Signal Strength Indication.
#define PSOCK_BEGIN(psock)
Start the protosocket protothread in a function.
Representation of a uIP TCP connection.
uint8_t nrtx
The number of retransmissions for the last segment sent.
#define uip_mss()
Get the current maximum segment size that can be sent on the current connection.
uint16_t lport
The local TCP port, in network byte order.
#define NULL
The null pointer.
uint8_t timer
The retransmission timer.
#define PT_THREAD(name_args)
Declaration of a protothread.
uint16_t rport
The local remote TCP port, in network byte order.
PETSCII/ASCII conversion functions.
#define PSOCK_GENERATOR_SEND(psock, generator, arg)
Generate data with a function and send it.
CCIF uint16_t uip_htons(uint16_t val)
Convert a 16-bit quantity from host byte order to network byte order.
#define PSOCK_END(psock)
Declare the end of a protosocket's protothread.
uint8_t tcpstateflags
TCP state and flags.
Interface structure (contains all the interface variables)
#define uip_stopped(conn)
Find out if the current connection has been previously stopped with uip_stop().
uip_ipaddr_t ripaddr
The IP address of the remote host.
uip_appdata
Pointer to the application data in the packet buffer.
An entry in the nbr cache.