33 #include <util/delay.h>
34 #define delay_us( us ) ( _delay_us( ( us ) ) )
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";
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);
125 last_tempupdate=seconds;
128 web_set_voltage(
char *s)
130 strcpy(sensor_extvoltage, s);
131 last_extvoltageupdate=seconds;
136 PT_THREAD(nullfunction(
struct httpd_state *s,
char *ptr))
143 httpd_cgi(
char *name)
145 struct httpd_cgi_call *f;
148 for(f = calls; f !=
NULL; f = f->next) {
149 if(httpd_strncmp(name, f->name, httpd_strlen(f->name)) == 0) {
156 #if HTTPD_FS_STATISTICS
157 static char *thisfilename;
159 static unsigned short
160 generate_file_stats(
void *arg)
162 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>";
163 static const char httpd_cgi_filestat2[] HTTPD_STRING_ATTR =
"<tr><td><a href=\"%s\">%s</a></td><td>%d</td>";
164 static const char httpd_cgi_filestat3[] HTTPD_STRING_ATTR =
"%5u";
166 struct httpd_fsdata_file_noconst *f,fram;
168 unsigned short numprinted;
171 httpd_fs_cpy(&tmp, (
char *)arg, 20);
175 numprinted=httpd_snprintf((
char *)
uip_appdata,
uip_mss(), httpd_cgi_filestat1, httpd_fs_open(thisfilename, 0));
179 }
else if (tmp[0]==
'*') {
181 for(f = (
struct httpd_fsdata_file_noconst *)httpd_fs_get_root();
183 f = (
struct httpd_fsdata_file_noconst *)fram.next) {
186 httpd_memcpy(&fram,f,
sizeof(fram));
189 httpd_fs_cpy(&tmp, fram.name,
sizeof(tmp));
190 #if HTTPD_FS_STATISTICS==1
191 numprinted+=httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_filestat2, tmp, tmp, f->count);
192 #elif HTTPD_FS_STATISTICS==2
193 numprinted+=httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_filestat2, tmp, tmp, httpd_filecount[i]);
200 numprinted=httpd_snprintf((
char *)
uip_appdata,
uip_mss(), httpd_cgi_filestat3, httpd_fs_open(tmp, 0));
209 PT_THREAD(file_stats(
struct httpd_state *s,
char *ptr))
214 thisfilename=&s->filename[0];
222 static unsigned short
223 make_tcp_stats(
void *arg)
225 static const char httpd_cgi_tcpstat1[] HTTPD_STRING_ATTR =
"<tr align=\"center\"><td>%d</td><td>";
226 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";
228 struct httpd_state *s = (
struct httpd_state *)arg;
232 conn = &uip_conns[s->u.count];
236 httpd_strcpy(tstate,states[conn->
tcpstateflags & UIP_TS_MASK]);
237 numprinted += httpd_snprintf((
char *)
uip_appdata + numprinted,
uip_mss() - numprinted,
243 (uip_outstanding(conn))?
'*':
' ',
250 PT_THREAD(tcp_stats(
struct httpd_state *s,
char *ptr))
255 for(s->u.count = 0; s->u.count <
UIP_CONNS; ++s->u.count) {
256 if((uip_conns[s->u.count].tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) {
264 static unsigned short
265 make_processes(
void *p)
267 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";
268 char name[40],tstate[20];
270 strncpy(name, PROCESS_NAME_STRING((
struct process *)p), 40);
271 petsciiconv_toascii(name, 40);
272 httpd_strcpy(tstate,states[9 + ((
struct process *)p)->state]);
274 *(
char *)(&(((
struct process *)p)->thread)),
280 PT_THREAD(processes(
struct httpd_state *s,
char *ptr))
283 for(s->u.ptr = PROCESS_LIST(); s->u.ptr !=
NULL; s->u.ptr = ((
struct process *)s->u.ptr)->next) {
289 static const char httpd_cgi_addrh[] HTTPD_STRING_ATTR =
"<code>";
290 static const char httpd_cgi_addrf[] HTTPD_STRING_ATTR =
"</code>[Room for %u more]";
291 static const char httpd_cgi_addrb[] HTTPD_STRING_ATTR =
"<br>";
292 static const char httpd_cgi_addrn[] HTTPD_STRING_ATTR =
"(none)<br>";
295 static unsigned short
296 make_addresses(
void *p)
301 for (i=0; i<UIP_DS6_ADDR_NB;i++) {
302 if (uip_ds6_if.addr_list[i].isused) {
304 numprinted += httpd_cgi_sprint_ip6(uip_ds6_if.addr_list[i].ipaddr,
uip_appdata + numprinted);
305 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_addrb);
309 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_addrf, UIP_DS6_ADDR_NB-j);
314 PT_THREAD(addresses(
struct httpd_state *s,
char *ptr))
323 static unsigned short
324 make_neighbors(
void *p)
330 for(nbr = nbr_table_head(ds6_neighbors);
332 nbr = nbr_table_next(ds6_neighbors, nbr)) {
334 numprinted += httpd_cgi_sprint_ip6(nbr->ipaddr,
uip_appdata + numprinted);
335 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_addrb);
338 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_addrf,NBR_TABLE_MAX_NEIGHBORS-j);
343 PT_THREAD(neighbors(
struct httpd_state *s,
char *ptr))
352 static unsigned short
355 static const char httpd_cgi_rtes1[] HTTPD_STRING_ATTR =
"(%u (via ";
356 static const char httpd_cgi_rtes2[] HTTPD_STRING_ATTR =
") %lus<br>";
357 static const char httpd_cgi_rtes3[] HTTPD_STRING_ATTR =
")<br>";
362 for(r = uip_ds6_route_head();
364 r = uip_ds6_route_next(r)) {
366 numprinted += httpd_cgi_sprint_ip6(r->ipaddr,
uip_appdata + numprinted);
367 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_rtes1, r->length);
368 numprinted += httpd_cgi_sprint_ip6(uip_ds6_route_nexthop(r),
uip_appdata + numprinted);
369 if(r->state.lifetime < 3600) {
370 numprinted += httpd_snprintf((
char *)
uip_appdata+numprinted,
uip_mss()-numprinted, httpd_cgi_rtes2, r->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);
#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.