Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2001, Adam Dunkels. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. The name of the author may not be used to endorse or promote 00014 * products derived from this software without specific prior 00015 * written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 00018 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00019 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 00021 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00023 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00024 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00025 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00026 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00027 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00028 * 00029 * This file is part of the uIP TCP/IP stack. 00030 * 00031 * $Id: httpd-cgi.c,v 1.13 2010/12/23 19:41:07 dak664 Exp $ 00032 * 00033 */ 00034 /* Line endings in git repository are LF instead of CR-LF ? */ 00035 /* 00036 * This file includes functions that are called by the web server 00037 * scripts. The functions takes no argument, and the return value is 00038 * interpreted as follows. A zero means that the function did not 00039 * complete and should be invoked for the next packet as well. A 00040 * non-zero value indicates that the function has completed and that 00041 * the web server should move along to the next script line. 00042 * 00043 */ 00044 00045 #include <stdio.h> 00046 #include <string.h> 00047 00048 #include "contiki-net.h" 00049 #include "httpd.h" 00050 #include "httpd-cgi.h" 00051 #include "httpd-fs.h" 00052 #include "httpd-fsdata.h" 00053 #include "lib/petsciiconv.h" 00054 00055 #include "sensors.h" 00056 00057 #define DEBUGLOGIC 0 //See httpd.c, if 1 must also set it there! 00058 #if DEBUGLOGIC 00059 #define uip_mss(...) 512 00060 #define uip_appdata TCPBUF 00061 extern char TCPBUF[512]; 00062 #endif 00063 00064 /* RADIOSTATS must also be set in clock.c and the radio driver */ 00065 #if RF230BB 00066 #define RADIOSTATS 1 00067 #endif 00068 00069 static struct httpd_cgi_call *calls = NULL; 00070 00071 /*cgi function names*/ 00072 #if HTTPD_FS_STATISTICS 00073 static const char file_name[] HTTPD_STRING_ATTR = "file-stats"; 00074 #endif 00075 static const char tcp_name[] HTTPD_STRING_ATTR = "tcp-connections"; 00076 static const char proc_name[] HTTPD_STRING_ATTR = "processes"; 00077 static const char sensor_name[] HTTPD_STRING_ATTR = "sensors"; 00078 static const char adrs_name[] HTTPD_STRING_ATTR = "addresses"; 00079 static const char nbrs_name[] HTTPD_STRING_ATTR = "neighbors"; 00080 static const char rtes_name[] HTTPD_STRING_ATTR = "routes"; 00081 00082 /*Process states for processes cgi*/ 00083 static const char closed[] HTTPD_STRING_ATTR = "CLOSED"; 00084 static const char syn_rcvd[] HTTPD_STRING_ATTR = "SYN-RCVD"; 00085 static const char syn_sent[] HTTPD_STRING_ATTR = "SYN-SENT"; 00086 static const char established[] HTTPD_STRING_ATTR = "ESTABLISHED"; 00087 static const char fin_wait_1[] HTTPD_STRING_ATTR = "FIN-WAIT-1"; 00088 static const char fin_wait_2[] HTTPD_STRING_ATTR = "FIN-WAIT-2"; 00089 static const char closing[] HTTPD_STRING_ATTR = "CLOSING"; 00090 static const char time_wait[] HTTPD_STRING_ATTR = "TIME-WAIT"; 00091 static const char last_ack[] HTTPD_STRING_ATTR = "LAST-ACK"; 00092 static const char none[] HTTPD_STRING_ATTR = "NONE"; 00093 static const char running[] HTTPD_STRING_ATTR = "RUNNING"; 00094 static const char called[] HTTPD_STRING_ATTR = "CALLED"; 00095 static const char *states[] = { 00096 closed, 00097 syn_rcvd, 00098 syn_sent, 00099 established, 00100 fin_wait_1, 00101 fin_wait_2, 00102 closing, 00103 time_wait, 00104 last_ack, 00105 none, 00106 running, 00107 called}; 00108 00109 static char sensor_temperature[12]="Not Enabled"; 00110 static char sensor_extvoltage[12]="Not Enabled"; 00111 static unsigned long last_tempupdate,last_extvoltageupdate; 00112 extern unsigned long seconds, sleepseconds; 00113 #if RADIOSTATS 00114 extern unsigned long radioontime; 00115 static unsigned long savedradioontime; 00116 extern uint8_t RF230_radio_on, rf230_last_rssi; 00117 extern uint16_t RF230_sendpackets,RF230_receivepackets,RF230_sendfail,RF230_receivefail; 00118 #endif 00119 00120 00121 void 00122 web_set_temp(char *s) 00123 { 00124 strcpy(sensor_temperature, s); 00125 // printf_P(PSTR("got temp")); 00126 last_tempupdate=seconds; 00127 } 00128 void 00129 web_set_voltage(char *s) 00130 { 00131 strcpy(sensor_extvoltage, s); 00132 // printf_P(PSTR("got volts")); 00133 last_extvoltageupdate=seconds; 00134 } 00135 00136 /*---------------------------------------------------------------------------*/ 00137 static 00138 PT_THREAD(nullfunction(struct httpd_state *s, char *ptr)) 00139 { 00140 PSOCK_BEGIN(&s->sout); 00141 PSOCK_END(&s->sout); 00142 } 00143 /*---------------------------------------------------------------------------*/ 00144 httpd_cgifunction 00145 httpd_cgi(char *name) 00146 { 00147 struct httpd_cgi_call *f; 00148 00149 /* Find the matching name in the table, return the function. */ 00150 for(f = calls; f != NULL; f = f->next) { 00151 if(httpd_strncmp(name, f->name, httpd_strlen(f->name)) == 0) { 00152 return f->function; 00153 } 00154 } 00155 return nullfunction; 00156 } 00157 00158 #if HTTPD_FS_STATISTICS 00159 static char *thisfilename; 00160 /*---------------------------------------------------------------------------*/ 00161 static unsigned short 00162 generate_file_stats(void *arg) 00163 { 00164 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>"; 00165 static const char httpd_cgi_filestat2[] HTTPD_STRING_ATTR = "<tr><td><a href=\"%s\">%s</a></td><td>%d</td>"; 00166 static const char httpd_cgi_filestat3[] HTTPD_STRING_ATTR = "%5u"; 00167 char tmp[20]; 00168 struct httpd_fsdata_file_noconst *f,fram; 00169 uint16_t i; 00170 unsigned short numprinted; 00171 00172 /* Transfer arg from whichever flash that contains the html file to RAM */ 00173 httpd_fs_cpy(&tmp, (char *)arg, 20); 00174 00175 /* Count for this page, with common page footer */ 00176 if (tmp[0]=='.') { 00177 numprinted=httpd_snprintf((char *)uip_appdata, uip_mss(), httpd_cgi_filestat1, httpd_fs_open(thisfilename, 0)); 00178 00179 /* Count for all files */ 00180 /* Note buffer will overflow if there are too many files! */ 00181 } else if (tmp[0]=='*') { 00182 i=0;numprinted=0; 00183 for(f = (struct httpd_fsdata_file_noconst *)httpd_fs_get_root(); 00184 f != NULL; 00185 f = (struct httpd_fsdata_file_noconst *)fram.next) { 00186 00187 /* Get the linked list file entry into RAM from from wherever it is*/ 00188 httpd_memcpy(&fram,f,sizeof(fram)); 00189 00190 /* Get the file name from whatever memory it is in */ 00191 httpd_fs_cpy(&tmp, fram.name, sizeof(tmp)); 00192 #if HTTPD_FS_STATISTICS==1 00193 numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_filestat2, tmp, tmp, f->count); 00194 #elif HTTPD_FS_STATISTICS==2 00195 numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_filestat2, tmp, tmp, httpd_filecount[i]); 00196 #endif 00197 i++; 00198 } 00199 00200 /* Count for specified file */ 00201 } else { 00202 numprinted=httpd_snprintf((char *)uip_appdata, uip_mss(), httpd_cgi_filestat3, httpd_fs_open(tmp, 0)); 00203 } 00204 #if DEBUGLOGIC 00205 return 0; 00206 #endif 00207 return numprinted; 00208 } 00209 /*---------------------------------------------------------------------------*/ 00210 static 00211 PT_THREAD(file_stats(struct httpd_state *s, char *ptr)) 00212 { 00213 00214 PSOCK_BEGIN(&s->sout); 00215 00216 thisfilename=&s->filename[0]; //temporary way to pass filename to generate_file_stats 00217 00218 PSOCK_GENERATOR_SEND(&s->sout, generate_file_stats, (void *) ptr); 00219 00220 PSOCK_END(&s->sout); 00221 } 00222 #endif /*HTTPD_FS_STATISTICS*/ 00223 /*---------------------------------------------------------------------------*/ 00224 static unsigned short 00225 make_tcp_stats(void *arg) 00226 { 00227 static const char httpd_cgi_tcpstat1[] HTTPD_STRING_ATTR = "<tr align=\"center\"><td>%d</td><td>"; 00228 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"; 00229 struct uip_conn *conn; 00230 struct httpd_state *s = (struct httpd_state *)arg; 00231 char tstate[20]; 00232 uint16_t numprinted; 00233 00234 conn = &uip_conns[s->u.count]; 00235 00236 numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(), httpd_cgi_tcpstat1, uip_htons(conn->lport)); 00237 numprinted += httpd_cgi_sprint_ip6(conn->ripaddr, uip_appdata + numprinted); 00238 httpd_strcpy(tstate,states[conn->tcpstateflags & UIP_TS_MASK]); 00239 numprinted += httpd_snprintf((char *)uip_appdata + numprinted, uip_mss() - numprinted, 00240 httpd_cgi_tcpstat2, 00241 uip_htons(conn->rport), 00242 tstate, 00243 conn->nrtx, 00244 conn->timer, 00245 (uip_outstanding(conn))? '*':' ', 00246 (uip_stopped(conn))? '!':' '); 00247 00248 return numprinted; 00249 } 00250 /*---------------------------------------------------------------------------*/ 00251 static 00252 PT_THREAD(tcp_stats(struct httpd_state *s, char *ptr)) 00253 { 00254 00255 PSOCK_BEGIN(&s->sout); 00256 00257 for(s->u.count = 0; s->u.count < UIP_CONNS; ++s->u.count) { 00258 if((uip_conns[s->u.count].tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) { 00259 PSOCK_GENERATOR_SEND(&s->sout, make_tcp_stats, s); 00260 } 00261 } 00262 00263 PSOCK_END(&s->sout); 00264 } 00265 /*---------------------------------------------------------------------------*/ 00266 static unsigned short 00267 make_processes(void *p) 00268 { 00269 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"; 00270 char name[40],tstate[20]; 00271 00272 strncpy(name, PROCESS_NAME_STRING((struct process *)p), 40); 00273 petsciiconv_toascii(name, 40); 00274 httpd_strcpy(tstate,states[9 + ((struct process *)p)->state]); 00275 return httpd_snprintf((char *)uip_appdata, uip_mss(), httpd_cgi_proc, p, name, 00276 *(char *)(&(((struct process *)p)->thread)), 00277 00278 tstate); 00279 } 00280 /*---------------------------------------------------------------------------*/ 00281 static 00282 PT_THREAD(processes(struct httpd_state *s, char *ptr)) 00283 { 00284 PSOCK_BEGIN(&s->sout); 00285 for(s->u.ptr = PROCESS_LIST(); s->u.ptr != NULL; s->u.ptr = ((struct process *)s->u.ptr)->next) { 00286 PSOCK_GENERATOR_SEND(&s->sout, make_processes, s->u.ptr); 00287 } 00288 PSOCK_END(&s->sout); 00289 } 00290 /*---------------------------------------------------------------------------*/ 00291 static const char httpd_cgi_addrh[] HTTPD_STRING_ATTR = "<code>"; 00292 static const char httpd_cgi_addrf[] HTTPD_STRING_ATTR = "</code>[Room for %u more]"; 00293 static const char httpd_cgi_addrb[] HTTPD_STRING_ATTR = "<br>"; 00294 static const char httpd_cgi_addrn[] HTTPD_STRING_ATTR = "(none)<br>"; 00295 extern uip_ds6_nbr_t uip_ds6_nbr_cache[]; 00296 extern uip_ds6_route_t uip_ds6_routing_table[]; 00297 extern uip_ds6_netif_t uip_ds6_if; 00298 00299 static unsigned short 00300 make_addresses(void *p) 00301 { 00302 uint8_t i,j=0; 00303 uint16_t numprinted; 00304 numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh); 00305 for (i=0; i<UIP_DS6_ADDR_NB;i++) { 00306 if (uip_ds6_if.addr_list[i].isused) { 00307 j++; 00308 numprinted += httpd_cgi_sprint_ip6(uip_ds6_if.addr_list[i].ipaddr, uip_appdata + numprinted); 00309 numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrb); 00310 } 00311 } 00312 //if (j==0) numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrn); 00313 numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrf, UIP_DS6_ADDR_NB-j); 00314 return numprinted; 00315 } 00316 /*---------------------------------------------------------------------------*/ 00317 static 00318 PT_THREAD(addresses(struct httpd_state *s, char *ptr)) 00319 { 00320 PSOCK_BEGIN(&s->sout); 00321 00322 PSOCK_GENERATOR_SEND(&s->sout, make_addresses, s->u.ptr); 00323 00324 PSOCK_END(&s->sout); 00325 } 00326 /*---------------------------------------------------------------------------*/ 00327 static unsigned short 00328 make_neighbors(void *p) 00329 { 00330 uint8_t i,j=0; 00331 uint16_t numprinted; 00332 numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh); 00333 for (i=0; i<UIP_DS6_NBR_NB;i++) { 00334 if (uip_ds6_nbr_cache[i].isused) { 00335 j++; 00336 numprinted += httpd_cgi_sprint_ip6(uip_ds6_nbr_cache[i].ipaddr, uip_appdata + numprinted); 00337 numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrb); 00338 } 00339 } 00340 //if (j==0) numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrn); 00341 numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrf,UIP_DS6_NBR_NB-j); 00342 return numprinted; 00343 } 00344 /*---------------------------------------------------------------------------*/ 00345 static 00346 PT_THREAD(neighbors(struct httpd_state *s, char *ptr)) 00347 { 00348 PSOCK_BEGIN(&s->sout); 00349 00350 PSOCK_GENERATOR_SEND(&s->sout, make_neighbors, s->u.ptr); 00351 00352 PSOCK_END(&s->sout); 00353 } 00354 /*---------------------------------------------------------------------------*/ 00355 static unsigned short 00356 make_routes(void *p) 00357 { 00358 static const char httpd_cgi_rtes1[] HTTPD_STRING_ATTR = "(%u (via "; 00359 static const char httpd_cgi_rtes2[] HTTPD_STRING_ATTR = ") %lus<br>"; 00360 static const char httpd_cgi_rtes3[] HTTPD_STRING_ATTR = ")<br>"; 00361 uint8_t i,j=0; 00362 uint16_t numprinted; 00363 numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh); 00364 for (i=0; i<UIP_DS6_ROUTE_NB;i++) { 00365 if (uip_ds6_routing_table[i].isused) { 00366 j++; 00367 numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].ipaddr, uip_appdata + numprinted); 00368 numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes1, uip_ds6_routing_table[i].length); 00369 numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].nexthop, uip_appdata + numprinted); 00370 if(uip_ds6_routing_table[i].state.lifetime < 3600) { 00371 numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes2, uip_ds6_routing_table[i].state.lifetime); 00372 } else { 00373 numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes3); 00374 } 00375 } 00376 } 00377 if (j==0) numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrn); 00378 numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrf,UIP_DS6_ROUTE_NB-j); 00379 return numprinted; 00380 } 00381 /*---------------------------------------------------------------------------*/ 00382 static 00383 PT_THREAD(routes(struct httpd_state *s, char *ptr)) 00384 { 00385 PSOCK_BEGIN(&s->sout); 00386 00387 PSOCK_GENERATOR_SEND(&s->sout, make_routes, s->u.ptr); 00388 00389 PSOCK_END(&s->sout); 00390 } 00391 /*---------------------------------------------------------------------------*/ 00392 static unsigned short 00393 generate_sensor_readings(void *arg) 00394 { 00395 uint16_t numprinted; 00396 uint16_t h,m,s; 00397 uint8_t p1; 00398 static const char httpd_cgi_sensor0[] HTTPD_STRING_ATTR = "[Updated %d seconds ago]<br><br>"; 00399 // static const char httpd_cgi_sensor1[] HTTPD_STRING_ATTR = "<em>Temperature:</em> %s<br>"; 00400 // static const char httpd_cgi_sensor2[] HTTPD_STRING_ATTR = "<em>Battery:</em> %s<br>"; 00401 static const char httpd_cgi_sensr12[] HTTPD_STRING_ATTR = "<em>Temperature:</em> %s <em>Battery:<em> %s<br>"; 00402 static const char httpd_cgi_sensor3[] HTTPD_STRING_ATTR = "<em>Elapsed timer :</em> %02d:%02d:%02d<br>"; 00403 static const char httpd_cgi_sensor4[] HTTPD_STRING_ATTR = "<em>Sleeping time :</em> %02d:%02d:%02d (%d%%)<br>"; 00404 00405 numprinted=0; 00406 if (last_tempupdate) { 00407 numprinted =httpd_snprintf((char *)uip_appdata, uip_mss(), httpd_cgi_sensor0,seconds-last_tempupdate); 00408 } 00409 00410 // numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_sensor1, sensor_temperature); 00411 numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_sensr12, sensor_temperature,sensor_extvoltage); 00412 00413 #if 0 00414 //Measuring AVcc might be useful to check on battery condition but on ext power it's always 3v3 00415 ADMUX =0x1E; //Select AREF as reference, measure 1.1 volt bandgap reference. 00416 //ADMUX =0x5E; //Select AVCC as reference, measure 1.1 volt bandgap reference. 00417 ADCSRA=0x07; //Enable ADC, not free running, interrupt disabled, clock divider 128 (62 KHz@ 8 MHz) 00418 ADCSRA|=1<<ADSC; //Start throwaway conversion 00419 while (ADCSRA&(1<<ADSC)); //Wait till done 00420 ADCSRA|=1<<ADSC; //Start another conversion 00421 while (ADCSRA&(1<<ADSC)); //Wait till done 00422 h=1131632UL/ADC; //Get supply voltage 00423 #endif 00424 00425 // numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_sensor2, sensor_extvoltage); 00426 #if RADIOSTATS 00427 /* Remember radioontime for display below - slow connection might make it report longer than cpu ontime! */ 00428 savedradioontime = radioontime; 00429 #endif 00430 h=seconds/3600; 00431 s=seconds-h*3600; 00432 m=s/60; 00433 s=s-m*60; 00434 numprinted+=httpd_snprintf((char *)uip_appdata + numprinted, uip_mss() - numprinted, httpd_cgi_sensor3, h,m,s); 00435 if (sleepseconds) { 00436 p1=100UL*sleepseconds/seconds; 00437 h=sleepseconds/3600; 00438 s=sleepseconds-h*3600; 00439 m=s/60; 00440 s=s-m*60; 00441 numprinted+=httpd_snprintf((char *)uip_appdata + numprinted, uip_mss() - numprinted, httpd_cgi_sensor4, h,m,s,p1); 00442 } 00443 return numprinted; 00444 } 00445 #if RADIOSTATS 00446 /*---------------------------------------------------------------------------*/ 00447 static unsigned short 00448 generate_radio_stats(void *arg) 00449 { 00450 uint16_t numprinted; 00451 uint16_t h,m,s; 00452 uint8_t p1,p2; 00453 static const char httpd_cgi_sensor10[] HTTPD_STRING_ATTR = "<em>Radio on time :</em> %02d:%02d:%02d (%d.%02d%%)<br>"; 00454 static const char httpd_cgi_sensor11[] HTTPD_STRING_ATTR = "<em>Packets:</em> Tx=%5d Rx=%5d TxL=%5d RxL=%5d RSSI=%2ddBm\n"; 00455 00456 s=(10000UL*savedradioontime)/seconds; 00457 p1=s/100; 00458 p2=s-p1*100; 00459 h=savedradioontime/3600; 00460 s=savedradioontime-h*3600; 00461 m=s/60; 00462 s=s-m*60; 00463 00464 numprinted =httpd_snprintf((char *)uip_appdata , uip_mss() , httpd_cgi_sensor10,\ 00465 h,m,s,p1,p2); 00466 00467 #if RF230BB 00468 numprinted+=httpd_snprintf((char *)uip_appdata + numprinted, uip_mss() - numprinted, httpd_cgi_sensor11,\ 00469 RF230_sendpackets,RF230_receivepackets,RF230_sendfail,RF230_receivefail,-92+rf230_last_rssi); 00470 #else 00471 p1=0; 00472 radio_get_rssi_value(&p1); 00473 p1 = -91*3(p1-1); 00474 numprinted+=httpd_snprintf((char *)uip_appdata + numprinted, uip_mss() - numprinted, httpd_cgi_sensor11,\ 00475 RF230_sendpackets,RF230_receivepackets,RF230_sendfail,RF230_receivefail,p1); 00476 #endif 00477 00478 return numprinted; 00479 } 00480 #endif 00481 /*---------------------------------------------------------------------------*/ 00482 static 00483 PT_THREAD(sensor_readings(struct httpd_state *s, char *ptr)) 00484 { 00485 PSOCK_BEGIN(&s->sout); 00486 00487 PSOCK_GENERATOR_SEND(&s->sout, generate_sensor_readings, s); 00488 #if RADIOSTATS 00489 PSOCK_GENERATOR_SEND(&s->sout, generate_radio_stats, s); 00490 #endif 00491 00492 00493 PSOCK_END(&s->sout); 00494 } 00495 /*---------------------------------------------------------------------------*/ 00496 void 00497 httpd_cgi_add(struct httpd_cgi_call *c) 00498 { 00499 struct httpd_cgi_call *l; 00500 00501 c->next = NULL; 00502 if(calls == NULL) { 00503 calls = c; 00504 } else { 00505 for(l = calls; l->next != NULL; l = l->next); 00506 l->next = c; 00507 } 00508 } 00509 /*---------------------------------------------------------------------------*/ 00510 00511 #if HTTPD_FS_STATISTICS 00512 HTTPD_CGI_CALL( file, file_name, file_stats); 00513 #endif 00514 HTTPD_CGI_CALL( tcp, tcp_name, tcp_stats ); 00515 HTTPD_CGI_CALL( proc, proc_name, processes ); 00516 HTTPD_CGI_CALL( adrs, adrs_name, addresses ); 00517 HTTPD_CGI_CALL( nbrs, nbrs_name, neighbors ); 00518 HTTPD_CGI_CALL( rtes, rtes_name, routes ); 00519 HTTPD_CGI_CALL(sensors, sensor_name, sensor_readings); 00520 00521 void 00522 httpd_cgi_init(void) 00523 { 00524 #if HTTPD_FS_STATISTICS 00525 httpd_cgi_add( &file); 00526 #endif 00527 httpd_cgi_add( &tcp); 00528 httpd_cgi_add( &proc); 00529 httpd_cgi_add( &adrs); 00530 httpd_cgi_add( &nbrs); 00531 httpd_cgi_add( &rtes); 00532 httpd_cgi_add(&sensors); 00533 } 00534 /*---------------------------------------------------------------------------*/ 00535 00536 uint8_t httpd_cgi_sprint_ip6(uip_ip6addr_t addr, char * result) 00537 { 00538 unsigned char zerocnt = 0; 00539 unsigned char numprinted = 0; 00540 char * starting = result; 00541 00542 unsigned char i = 0; 00543 00544 while (numprinted < 8) 00545 { 00546 //Address is zero, have we used our ability to 00547 //replace a bunch with : yet? 00548 if ((addr.u16[i] == 0) && (zerocnt == 0)) 00549 { 00550 //How mant zeros? 00551 zerocnt = 0; 00552 while(addr.u16[zerocnt + i] == 0) 00553 zerocnt++; 00554 00555 //just one, don't waste our zeros... 00556 if (zerocnt == 1) 00557 { 00558 *result++ = '0'; 00559 numprinted++; 00560 break; 00561 } 00562 00563 //Cool - can replace a bunch of zeros 00564 i += zerocnt; 00565 numprinted += zerocnt; 00566 } 00567 //Normal address, just print it 00568 else 00569 { 00570 result += sprintf(result, "%x", (unsigned int)(uip_ntohs(addr.u16[i]))); 00571 i++; 00572 numprinted++; 00573 } 00574 00575 //Don't print : on last one 00576 if (numprinted != 8) 00577 *result++ = ':'; 00578 } 00579 00580 return (result - starting); 00581 } 00582