/*---------------------------------------------------------------------------*/ static PT_THREAD(generate_routes(struct httpd_state *s)) { static int i; static uip_ds6_route_t *r; static uip_ds6_nbr_t *nbr; PSOCK_BEGIN(&s->sout); SEND_STRING(&s->sout, TOP); blen = 0; ADD("Neighbors<pre>"); for(nbr = nbr_table_head(ds6_neighbors); nbr != NULL; nbr = nbr_table_next(ds6_neighbors, nbr)) { ipaddr_add(&nbr->ipaddr); ADD("\n"); if(blen > sizeof(buf) - 45) { SEND_STRING(&s->sout, buf); blen = 0; } } ADD("</pre>Routes<pre>"); SEND_STRING(&s->sout, buf); blen = 0; for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) { ipaddr_add(&r->ipaddr); ADD("/%u (via ", r->length); ipaddr_add(uip_ds6_route_nexthop(r)); if(r->state.lifetime < 600) { ADD(") %lus\n", (unsigned long)r->state.lifetime); } else { ADD(")\n"); } SEND_STRING(&s->sout, buf); blen = 0; } ADD("</pre>"); //if(blen > 0) { SEND_STRING(&s->sout, buf); // blen = 0; //} if(sensor_count > 0) { ADD("</pre>Sensors<pre>"); SEND_STRING(&s->sout, buf); blen = 0; for(i = 0; i < sensor_count; i++) { ADD("%s\n", sensors[i]); SEND_STRING(&s->sout, buf); blen = 0; } ADD("</pre>"); SEND_STRING(&s->sout, buf); } SEND_STRING(&s->sout, BOTTOM); PSOCK_END(&s->sout); }
/*---------------------------------------------------------------------------*/ static PT_THREAD(generate_routes(struct httpd_state *s)) { static uip_ds6_route_t *r; static uip_ds6_nbr_t *nbr; #if BUF_USES_STACK char buf[256]; #endif #if WEBSERVER_CONF_LOADTIME static clock_time_t numticks; numticks = clock_time(); #endif PSOCK_BEGIN(&s->sout); SEND_STRING(&s->sout, TOP); #if BUF_USES_STACK bufptr = buf;bufend=bufptr+sizeof(buf); #else blen = 0; #endif ADD("Neighbors<pre>"); for(nbr = nbr_table_head(ds6_neighbors); nbr != NULL; nbr = nbr_table_next(ds6_neighbors, nbr)) { #if WEBSERVER_CONF_NEIGHBOR_STATUS #if BUF_USES_STACK {char* j=bufptr+25; ipaddr_add(&nbr->ipaddr); while (bufptr < j) ADD(" "); switch (nbr->state) { case NBR_INCOMPLETE: ADD(" INCOMPLETE");break; case NBR_REACHABLE: ADD(" REACHABLE");break; case NBR_STALE: ADD(" STALE");break; case NBR_DELAY: ADD(" DELAY");break; case NBR_PROBE: ADD(" NBR_PROBE");break; } } #else {uint8_t j=blen+25; ipaddr_add(&nbr->ipaddr); while (blen < j) ADD(" "); switch (nbr->state) { case NBR_INCOMPLETE: ADD(" INCOMPLETE");break; case NBR_REACHABLE: ADD(" REACHABLE");break; case NBR_STALE: ADD(" STALE");break; case NBR_DELAY: ADD(" DELAY");break; case NBR_PROBE: ADD(" NBR_PROBE");break; } } #endif #else ipaddr_add(&nbr->ipaddr); #endif ADD("\n"); #if BUF_USES_STACK if(bufptr > bufend - 45) { SEND_STRING(&s->sout, buf); bufptr = buf; bufend = bufptr + sizeof(buf); } #else if(blen > sizeof(buf) - 45) { SEND_STRING(&s->sout, buf); blen = 0; } #endif } ADD("</pre>Routes<pre>"); SEND_STRING(&s->sout, buf); #if BUF_USES_STACK bufptr = buf; bufend = bufptr + sizeof(buf); #else blen = 0; #endif for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) { #if BUF_USES_STACK #if WEBSERVER_CONF_ROUTE_LINKS ADD("<a href=http://["); ipaddr_add(&r->ipaddr); ADD("]/status.shtml>"); ipaddr_add(&r->ipaddr); ADD("</a>"); #else ipaddr_add(&r->ipaddr); #endif #else #if WEBSERVER_CONF_ROUTE_LINKS ADD("<a href=http://["); ipaddr_add(&r->ipaddr); ADD("]/status.shtml>"); SEND_STRING(&s->sout, buf); //TODO: why tunslip6 needs an output here, wpcapslip does not blen = 0; ipaddr_add(&r->ipaddr); ADD("</a>"); #else ipaddr_add(&r->ipaddr); #endif #endif ADD("/%u (via ", r->length); ipaddr_add(uip_ds6_route_nexthop(r)); if(1 || (r->state.lifetime < 600)) { ADD(") %lus\n", (unsigned long)r->state.lifetime); } else { ADD(")\n"); } SEND_STRING(&s->sout, buf); #if BUF_USES_STACK bufptr = buf; bufend = bufptr + sizeof(buf); #else blen = 0; #endif } ADD("</pre>"); #if WEBSERVER_CONF_FILESTATS static uint16_t numtimes; ADD("<br><i>This page sent %u times</i>",++numtimes); #endif #if WEBSERVER_CONF_LOADTIME numticks = clock_time() - numticks + 1; ADD(" <i>(%lu.%02lu sec)</i>",numticks/CLOCK_SECOND,((100*(numticks%CLOCK_SECOND))/CLOCK_SECOND)); #endif SEND_STRING(&s->sout, buf); SEND_STRING(&s->sout, BOTTOM); PSOCK_END(&s->sout); }
/*-------------------------------------------------------------------------*/ int main(void) { initialize(); while(1) { process_run(); watchdog_periodic(); #if 0 /* Various entry points for debugging in the AVR Studio simulator. * Set as next statement and step into the routine. */ NETSTACK_RADIO.send(packetbuf_hdrptr(), 42); process_poll(&rf230_process); packetbuf_clear(); len = rf230_read(packetbuf_dataptr(), PACKETBUF_SIZE); packetbuf_set_datalen(42); NETSTACK_RDC.input(); #endif #if 0 /* Clock.c can trigger a periodic PLL calibration in the RF230BB driver. * This can show when that happens. */ extern uint8_t rf230_calibrated; if (rf230_calibrated) { PRINTF("\nRF230 calibrated!\n"); rf230_calibrated=0; } #endif #if TESTRTIMER /* Timeout can be increased up to 8 seconds maximum. * A one second cycle is convenient for triggering the various debug printouts. * The triggers are staggered to avoid printing everything at once. * My raven is 6% slow. */ if (rtimerflag) { rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL); rtimerflag=0; #if STAMPS if ((rtime%STAMPS)==0) { PRINTF("%us ",rtime); } #endif rtime+=1; #if PINGS if ((rtime%PINGS)==1) { PRINTF("**Ping\n"); raven_ping6(); } #endif #if ROUTES if ((rtime%ROUTES)==2) { //#if UIP_CONF_IPV6_RPL //#include "rpl.h" extern uip_ds6_nbr_t uip_ds6_nbr_cache[]; extern uip_ds6_route_t uip_ds6_routing_table[]; extern uip_ds6_netif_t uip_ds6_if; uint8_t i,j; PRINTF("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB); for (i=0;i<UIP_DS6_ADDR_NB;i++) { if (uip_ds6_if.addr_list[i].isused) { ipaddr_add(&uip_ds6_if.addr_list[i].ipaddr); PRINTF("\n"); } } PRINTF("\nNeighbors [%u max]\n",UIP_DS6_NBR_NB); for(i = 0,j=1; i < UIP_DS6_NBR_NB; i++) { if(uip_ds6_nbr_cache[i].isused) { ipaddr_add(&uip_ds6_nbr_cache[i].ipaddr); PRINTF("\n"); j=0; } } if (j) PRINTF(" <none>"); PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) { if(uip_ds6_routing_table[i].isused) { ipaddr_add(&uip_ds6_routing_table[i].ipaddr); PRINTF("/%u (via ", uip_ds6_routing_table[i].length); ipaddr_add(&uip_ds6_routing_table[i].nexthop); // if(uip_ds6_routing_table[i].state.lifetime < 600) { PRINTF(") %lus\n", uip_ds6_routing_table[i].state.lifetime); // } else { // PRINTF(")\n"); // } j=0; } } if (j) PRINTF(" <none>"); PRINTF("\n---------\n"); } #endif #if STACKMONITOR if ((rtime%STACKMONITOR)==3) { extern uint16_t __bss_end; uint16_t p=(uint16_t)&__bss_end; do { if (*(uint16_t *)p != 0x4242) { PRINTF("Never-used stack > %d bytes\n",p-(uint16_t)&__bss_end); break; } p+=10; } while (p<RAMEND-10); } #endif } #endif /* TESTRTIMER */ //Use with RF230BB DEBUGFLOW to show path through driver #if RF230BB&&0 extern uint8_t debugflowsize,debugflow[]; if (debugflowsize) { debugflow[debugflowsize]=0; PRINTF("%s",debugflow); debugflowsize=0; } #endif #if RF230BB&&0 if (rf230processflag) { PRINTF("rf230p%d",rf230processflag); rf230processflag=0; } #endif #if RF230BB&&0 if (rf230_interrupt_flag) { // if (rf230_interrupt_flag!=11) { PRINTF("**RI%u",rf230_interrupt_flag); // } rf230_interrupt_flag=0; } #endif } return 0; }
void menu_process(char c) { static enum menustate_enum /* Defines an enumeration type */ { normal, channel, txpower } menustate = normal; static char channel_string[3]; static uint8_t channel_string_i;// = 0; int tempchannel; if (menustate == channel) { switch(c) { case '\r': case '\n': if (channel_string_i) { channel_string[channel_string_i] = 0; tempchannel = atoi(channel_string); if ((tempchannel < 11) || (tempchannel > 26)) { PRINTF_P(PSTR("\n\rInvalid input\n\r")); } else { rf230_set_channel(tempchannel); #if CONTIKI_CONF_SETTINGS_MANAGER if(settings_set_uint8(SETTINGS_KEY_CHANNEL, tempchannel) == SETTINGS_STATUS_OK) { PRINTF_P(PSTR("\n\rChannel changed to %d and stored in EEPROM.\n\r"), tempchannel); } else { PRINTF_P(PSTR("\n\rChannel changed to %d, but unable to store in EEPROM!\n\r"), tempchannel); } #else PRINTF_P(PSTR("\n\rChannel changed to %d.\n\r"), tempchannel); #endif } } else { PRINTF_P(PSTR("\n\rChannel unchanged.\n\r")); } menustate = normal; break; case '\b': if (channel_string_i) { channel_string_i--; PRINTF_P(PSTR("\b \b")); } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (channel_string_i > 1) { // This time the user has gone too far. // Beep at them. putc('\a', stdout); break; } putc(c, stdout); channel_string[channel_string_i] = c; channel_string_i++; break; default: break; } } else if (menustate == txpower) { switch(c) { case '\r': case '\n': if (channel_string_i) { channel_string[channel_string_i] = 0; tempchannel = atoi(channel_string); if ((tempchannel < 0) || (tempchannel > 15)) { PRINTF_P(PSTR("\n\rInvalid input\n\r")); } else { PRINTF_P(PSTR(" ")); //for some reason needs a print here to clear the string input... rf230_set_txpower(tempchannel); #if CONTIKI_CONF_SETTINGS_MANAGER if(settings_set_uint8(SETTINGS_KEY_TXPOWER, tempchannel) == SETTINGS_STATUS_OK) { PRINTF_P(PSTR("\n\rTransmit power changed to %d, and stored in EEPROM.\n\r"), tempchannel); } else { PRINTF_P(PSTR("\n\rTransmit power changed to %d, but unable to store in EEPROM!\n\r"), tempchannel); } #else PRINTF_P(PSTR("\n\rTransmit power changed to %d.\n\r"), tempchannel); #endif } } else { PRINTF_P(PSTR("\n\rTransmit power unchanged.\n\r")); } menustate = normal; break; case '\b': if (channel_string_i) { channel_string_i--; PRINTF_P(PSTR("\b \b")); } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (channel_string_i > 1) { // This time the user has gone too far. // Beep at them. putc('\a', stdout); break; } putc(c, stdout); channel_string[channel_string_i] = c; channel_string_i++; break; default: break; } } else { uint8_t i; switch(c) { case '\r': case '\n': break; case 'h': case '?': menu_print(); break; case 'd': if (mx_console_mode.debugOn) { PRINTF_P(PSTR("Node does not output debug strings\n\r")); mx_console_mode.debugOn = 0; } else { PRINTF_P(PSTR("Node now outputs debug strings\n\r")); mx_console_mode.debugOn = 1; } break; case 'c': PRINTF_P(PSTR("\nSelect 802.15.4 Channel in range 11-26 [%d]: "), rf230_get_channel()); menustate = channel; channel_string_i = 0; break; case 'p': PRINTF_P(PSTR("\nSelect transmit power (0=+3dBm 15=-17.2dBm) [%d]: "), rf230_get_txpower()); menustate = txpower; channel_string_i = 0; break; #if UIP_CONF_IPV6_RPL #include "rpl.h" extern uip_ds6_nbr_t uip_ds6_nbr_cache[]; extern uip_ds6_netif_t uip_ds6_if; case 'N': { uint8_t i,j; PRINTF_P(PSTR("\n\rAddresses [%u max]\n\r"),UIP_DS6_ADDR_NB); for (i=0;i<UIP_DS6_ADDR_NB;i++) { if (uip_ds6_if.addr_list[i].isused) { ipaddr_add(&uip_ds6_if.addr_list[i].ipaddr); PRINTF_P(PSTR("\n\r")); } } PRINTF_P(PSTR("\n\rNeighbors [%u max]\n\r"),UIP_DS6_NBR_NB); for(i = 0,j=1; i < UIP_DS6_NBR_NB; i++) { if(uip_ds6_nbr_cache[i].isused) { ipaddr_add(&uip_ds6_nbr_cache[i].ipaddr); PRINTF_P(PSTR("\n\r")); j=0; } } if (j) PRINTF_P(PSTR(" <none>")); PRINTF_P(PSTR("\n\rRoutes [%u max]\n\r"),UIP_DS6_ROUTE_NB); { uip_ds6_route_t *r; j = 1; for(r = uip_ds6_route_list_head(); r != NULL; r = list_item_next(r)) { ipaddr_add(&r->ipaddr); PRINTF_P(PSTR("/%u (via "), r->length); ipaddr_add(&r->nexthop); if(r->state.lifetime < 600) { PRINTF_P(PSTR(") %lus\n\r"), r->state.lifetime); } else { PRINTF_P(PSTR(")\n\r")); } j = 0; } } if (j) PRINTF_P(PSTR(" <none>")); PRINTF_P(PSTR("\n\r---------\n\r")); break; } case 'G': PRINTF_P(PSTR("Global repair returns %d\n\r"),rpl_repair_root(RPL_DEFAULT_INSTANCE)); break; case 'L': rpl_local_repair(rpl_get_any_dag()); PRINTF_P(PSTR("Local repair initiated\n\r")); break; #endif case 'm': PRINTF_P(PSTR("Currently running on\n\r")); PRINTF_P(PSTR(" * %s\n\r"), CONTIKI_VERSION_STRING); PRINTF_P(PSTR(" * NETSTACK_MAC: %s, NETSTACK_RDC: %s\n\r"), NETSTACK_MAC.name, NETSTACK_RDC.name); #if 1 { int i; PRINTF_P(PSTR(" * Address: ")); for (i = 0; i < 6; i += 2) { PRINTF_P(PSTR("%02x%02x:"), uip_lladdr.addr[i], uip_lladdr.addr[i + 1]); } PRINTF_P(PSTR("%02x%02x\n\r"), uip_lladdr.addr[6], uip_lladdr.addr[7]); } #endif #if UIP_CONF_IPV6_RPL PRINTF_P(PSTR(" * RPL Enabled\n\r")); #endif #if UIP_CONF_ROUTER PRINTF_P(PSTR(" * Routing Enabled\n\r")); #endif #if CONVERTTXPOWER PRINTF_P(PSTR(" * Operates on channel %d with TX power "),rf230_get_channel()); printtxpower(); PRINTF_P(PSTR("\n\r")); #else //just show the raw value PRINTF_P(PSTR(" * Operates on channel %d\n\r"), rf230_get_channel()); PRINTF_P(PSTR(" * TX Power(0=+3dBm, 15=-17.2dBm): %d\n\r"), rf230_get_txpower()); #endif if (rf230_smallest_rssi) { PRINTF_P(PSTR(" * Current/Last/Smallest RSSI: %d/%d/%ddBm\n\r"), -91+(rf230_rssi()-1), -91+(rf230_last_rssi-1),-91+(rf230_smallest_rssi-1)); rf230_smallest_rssi=0; } else { PRINTF_P(PSTR(" * Current/Last/Smallest RSSI: %d/%d/--dBm\n\r"), -91+(rf230_rssi()-1), -91+(rf230_last_rssi-1)); } #if CONFIG_STACK_MONITOR /* See contiki-raven-main.c for initialization of the magic numbers */ { extern uint16_t __bss_end; uint16_t p=(uint16_t)&__bss_end; do { if (*(uint16_t *)p != 0x4242) { printf_P(PSTR(" * Never-used stack > %d bytes\n\r"),p-(uint16_t)&__bss_end); break; } p+=100; } while (p<RAMEND-100); } #endif break; case 'e': PRINTF_P(PSTR("Energy Scan:\n")); { uint8_t i; uint16_t j; uint8_t previous_channel = rf230_get_channel(); int8_t RSSI, maxRSSI[17]; uint16_t accRSSI[17]; bzero((void*)accRSSI,sizeof(accRSSI)); bzero((void*)maxRSSI,sizeof(maxRSSI)); for(j=0;j<(1<<12);j++) { for(i=11;i<=26;i++) { rf230_listen_channel(i); _delay_us(3*10); RSSI = rf230_rssi(); //multiplies rssi register by 3 for consistency with energy-detect register maxRSSI[i-11]=Max(maxRSSI[i-11],RSSI); accRSSI[i-11]+=RSSI; } if(j&(1<<7)) { leds_on(LEDS_RED); if(!(j&((1<<7)-1))) { PRINTF_P(PSTR(".")); } } else { leds_off(LEDS_RED); } watchdog_periodic(); } rf230_set_channel(previous_channel); PRINTF_P(PSTR("\n")); for(i=11;i<=26;i++) { uint8_t activity=Min(maxRSSI[i-11],accRSSI[i-11]/(1<<7)); PRINTF_P(PSTR(" %d: %02ddB "),i, -91+(maxRSSI[i-11]-1)); for(;activity--;maxRSSI[i-11]--) { PRINTF_P(PSTR("#")); } for(;maxRSSI[i-11]>0;maxRSSI[i-11]--) { PRINTF_P(PSTR(":")); } PRINTF_P(PSTR("\n")); } } PRINTF_P(PSTR("Done.\n")); break; case 'R': PRINTF_P(PSTR("Resetting...\n\r")); leds_on(LEDS_ALL); for(i = 0; i < 20; i++) _delay_ms(100); watchdog_reboot(); break; default: PRINTF_P(PSTR("%c is not a valid option! h for menu\n\r"), c); break; } } }
static PT_THREAD(generate_network(struct httpd_state *s)) { static int i; static uip_ds6_route_t *r; static uip_ds6_defrt_t *dr; static uip_ds6_nbr_t *nbr; #if CETIC_6LBR_WITH_MULTICAST static uip_mcast6_route_t *mcast_route; #endif #if RPL_WITH_NON_STORING static rpl_ns_node_t *link; #endif PSOCK_BEGIN(&s->sout); add("<br /><h2>Addresses</h2><pre>"); SEND_STRING(&s->sout, buf); reset_buf(); for(i = 0; i < UIP_DS6_ADDR_NB; i++) { if(uip_ds6_if.addr_list[i].isused) { ipaddr_add(&uip_ds6_if.addr_list[i].ipaddr); add(" "); add_address_type(uip_ds6_if.addr_list[i].type); add(" "); add_address_state(uip_ds6_if.addr_list[i].state); if(!uip_ds6_if.addr_list[i].isinfinite) { add(" %u s", stimer_remaining(&uip_ds6_if.addr_list[i].vlifetime)); } add("\n"); SEND_STRING(&s->sout, buf); reset_buf(); } } add("</pre><h2>Multicast groups</h2><pre>"); for(i = 0; i < UIP_DS6_MADDR_NB; i++) { if(uip_ds6_if.maddr_list[i].isused) { ipaddr_add(&uip_ds6_if.maddr_list[i].ipaddr); add("\n"); SEND_STRING(&s->sout, buf); reset_buf(); } } add("</pre><h2>Prefixes</h2><pre>"); for(i = 0; i < UIP_DS6_PREFIX_NB; i++) { if(uip_ds6_prefix_list[i].isused) { ipaddr_add(&uip_ds6_prefix_list[i].ipaddr); #if UIP_CONF_ROUTER if(uip_ds6_prefix_list[i].advertise) { add(" Adv"); } #else if(uip_ds6_prefix_list[i].isinfinite) { add(" Inf"); } #endif add("\n"); } } SEND_STRING(&s->sout, buf); reset_buf(); #if CETIC_6LBR_WITH_IP64 if((nvm_data.global_flags & CETIC_GLOBAL_IP64) != 0) { add("</pre><h2>IP64</h2><pre>"); if((nvm_data.eth_ip64_flags & CETIC_6LBR_IP64_DHCP) == 0 || ip64_hostaddr_is_configured()) { add("Address : "); ip4addr_add(ip64_get_hostaddr()); add("<br />"); add("Netmask : "); ip4addr_add(ip64_get_netmask()); add("<br />"); add("Gateway : "); ip4addr_add(ip64_get_draddr()); add("<br />"); if((nvm_data.eth_ip64_flags & CETIC_6LBR_IP64_DHCP) != 0) { add("DHCP Server : "); ip4addr_add_u8(cetic_6lbr_ip64_dhcp_state->serverid); add("<br />"); add("DHCP lease time : %d s<br />", uip_ntohs(cetic_6lbr_ip64_dhcp_state->lease_time[0])*65536ul + uip_ntohs(cetic_6lbr_ip64_dhcp_state->lease_time[1])); } } else { add("Waiting configuration<br />"); } SEND_STRING(&s->sout, buf); reset_buf(); } #endif add("</pre><h2>Neighbors</h2><pre>"); for(nbr = nbr_table_head(ds6_neighbors); nbr != NULL; nbr = nbr_table_next(ds6_neighbors, nbr)) { if ((nvm_data.global_flags & CETIC_GLOBAL_DISABLE_CONFIG) == 0) { add("[<a href=\"nbr-rm?"); ipaddr_add(&nbr->ipaddr); add("\">del</a>] "); } #if CETIC_6LBR_NODE_CONFIG_HAS_NAME if ( node_config_loaded ) { add("%s : ", node_config_get_name(node_config_find_by_lladdr(uip_ds6_nbr_get_ll(nbr)))); } #endif ipaddr_add(&nbr->ipaddr); add(" "); lladdr_add(uip_ds6_nbr_get_ll(nbr)); add(" "); add_network_cases(nbr->state); #if UIP_SWITCH_LOOKUP if(nbr->ifindex != NETWORK_ITF_UNKNOWN) { add(" if:%u", nbr->ifindex); } #endif add("\n"); SEND_STRING(&s->sout, buf); reset_buf(); } add("</pre><h2>Routes</h2><pre>"); SEND_STRING(&s->sout, buf); reset_buf(); for(r = uip_ds6_route_head(), i = 0; r != NULL; r = uip_ds6_route_next(r), ++i) { if ((nvm_data.global_flags & CETIC_GLOBAL_DISABLE_CONFIG) == 0) { add("[<a href=\"route-rm?"); ipaddr_add(&r->ipaddr); add("\">del</a>] "); } #if CETIC_6LBR_NODE_CONFIG_HAS_NAME if ( node_config_loaded ) { add("%s (", node_config_get_name(node_config_find_by_ip(&r->ipaddr))); ipaddr_add(&r->ipaddr); add("/%u) via ", r->length); } else { ipaddr_add(&r->ipaddr); add("/%u via ", r->length); } if ( node_config_loaded ) { add("%s (", node_config_get_name(node_config_find_by_ip(uip_ds6_route_nexthop(r)))); ipaddr_add(uip_ds6_route_nexthop(r)); add(")"); } else { ipaddr_add(uip_ds6_route_nexthop(r)); } #else ipaddr_add(&r->ipaddr); add("/%u via ", r->length); ipaddr_add(uip_ds6_route_nexthop(r)); #endif #if CETIC_6LBR_WITH_RPL if(r->state.lifetime != RPL_ROUTE_INFINITE_LIFETIME) { #else if(r->neighbor_routes != NULL) { #endif add(" %lu s\n", r->state.lifetime); } else { add("Inf\n"); } SEND_STRING(&s->sout, buf); reset_buf(); } #if RPL_WITH_NON_STORING add("</pre><h2>Links</h2><pre>"); for(link = rpl_ns_node_head(); link != NULL; link = rpl_ns_node_next(link)) { if(link->parent != NULL) { uip_ipaddr_t child_ipaddr; uip_ipaddr_t parent_ipaddr; rpl_ns_get_node_global_addr(&child_ipaddr, link); rpl_ns_get_node_global_addr(&parent_ipaddr, link->parent); #if CETIC_6LBR_NODE_CONFIG_HAS_NAME if ( node_config_loaded ) { add("%s (", node_config_get_name(node_config_find_by_ip(&child_ipaddr))); ipaddr_add(&child_ipaddr); add(") via "); } else { ipaddr_add(&child_ipaddr); add(" via "); } if ( node_config_loaded ) { add("%s (", node_config_get_name(node_config_find_by_ip(&parent_ipaddr))); ipaddr_add(&parent_ipaddr); add(")"); } else { ipaddr_add(&parent_ipaddr); } #else ipaddr_add(&child_ipaddr); add(" via "); ipaddr_add(&parent_ipaddr); #endif add(" %lu s\n", link->lifetime); SEND_STRING(&s->sout, buf); reset_buf(); } } #endif #if CETIC_6LBR_WITH_MULTICAST add("</pre><h2>Routed multicast groups</h2><pre>"); for(mcast_route = uip_mcast6_route_list_head(), i = 0; mcast_route != NULL; mcast_route = list_item_next(mcast_route), ++i) { if ((nvm_data.global_flags & CETIC_GLOBAL_DISABLE_CONFIG) == 0) { add("[<a href=\"mcast-rm?"); ipaddr_add(&mcast_route->group); add("\">del</a>] "); } ipaddr_add(&mcast_route->group); add(" %lu s\n", mcast_route->lifetime); SEND_STRING(&s->sout, buf); reset_buf(); } #endif add("</pre><h2>Default Routers</h2><pre>"); for(dr = uip_ds6_defrt_head(); dr != NULL; dr = list_item_next(r)) { ipaddr_add(&dr->ipaddr); if(dr->isinfinite) { add(" Inf"); } else { add(" %u s", stimer_remaining(&dr->lifetime)); } add("\n"); SEND_STRING(&s->sout, buf); reset_buf(); } #if UIP_CONF_DS6_ROUTE_INFORMATION add("</pre><h2>Route info</h2><pre>"); for(i = 0; i < UIP_DS6_ROUTE_INFO_NB; i++) { if(uip_ds6_route_info_list[i].isused) { ipaddr_add(&uip_ds6_route_info_list[i].ipaddr); add("/%u (%x) %u s\n", uip_ds6_route_info_list[i].length, uip_ds6_route_info_list[i].flags, uip_ds6_route_info_list[i].lifetime); } } SEND_STRING(&s->sout, buf); reset_buf(); #endif add("</pre><h2>DNS server</h2><pre>"); //Note: Currently we assume only one DNS server uip_ipaddr_t * dns = uip_nameserver_get(0); if(!uip_is_addr_unspecified(dns)) { ipaddr_add(dns); add(" %u s\n", uip_nameserver_next_expiration()); } SEND_STRING(&s->sout, buf); reset_buf(); #if CETIC_6LBR_WITH_IP64 if((nvm_data.global_flags & CETIC_GLOBAL_IP64) != 0) { add("</pre><h2>IP64 connections mapping</h2><pre>"); static struct ip64_addrmap_entry *m; for(m = ip64_addrmap_list(); m != NULL; m = list_item_next(m)) { if(timer_expired(&m->timer)) continue; ipaddr_add(&m->ip6addr); add("%%%d (%d)", m->ip6port, m->protocol); if(m->ip6to4 && m->ip4to6) { add(" <-> "); } else if(m->ip6to4) { add(" -> "); } else { add(" <- "); } ip4addr_add(&m->ip4addr); add("%%%d : %d (%x) %us\n", m->ip4port, m->mapped_port, m->flags, (m->timer.interval - (clock_time() - m->timer.start)) / CLOCK_SECOND); SEND_STRING(&s->sout, buf); reset_buf(); } } #endif #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0 add("</pre><h2>6LoWPAN Prefix contexts</h2><pre>"); for(i = 0; i < SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS; i++) { if(addr_contexts[i].used == 1) { add("%d : ", addr_contexts[i].number); ipaddr_add_u8_len(addr_contexts[i].prefix, 8); add("\n"); } } add("</pre><br />"); SEND_STRING(&s->sout, buf); reset_buf(); #endif #if CETIC_6LBR_TRANSPARENTBRIDGE add("<h2>HW Prefixes cache</h2><pre>"); for(i = 0; i < prefixCounter; i++) { add("%02x:%02x:%02x\n", prefixBuffer[i][0], prefixBuffer[i][1], prefixBuffer[i][2]); } SEND_STRING(&s->sout, buf); add("</pre><br />"); reset_buf(); #endif PSOCK_END(&s->sout); } static void add_network_cases(const uint8_t state) { switch (state) { case NBR_INCOMPLETE: add("Incomplete"); break; case NBR_REACHABLE: add("Reachable"); break; case NBR_STALE: add("Stale"); break; case NBR_DELAY: add("Delay"); break; case NBR_PROBE: add("Probe"); break; } } static httpd_cgi_call_t * webserver_network_route_add(struct httpd_state *s) { #if UIP_DS6_STATIC_ROUTES uip_ds6_route_t *route; uip_ipaddr_t ipaddr; uint8_t length; uip_ipaddr_t nexthop; char *p; char *sep; webserver_result_title = "Network"; webserver_result_text = "Add route: Route not created"; do { if(!s->query) break; p = s->query; sep = index(p, '='); if(sep == NULL) break; *sep = 0; if(strcmp(p, "target") != 0) break; p = sep + 1; sep = index(p, '&'); if(sep == NULL) break; *sep = 0; if(uiplib_ipaddrconv(p, &ipaddr) == 0) break; p = sep + 1; sep = index(p, '='); if(sep == NULL) break; *sep = 0; if(strcmp(p, "length") != 0) break; p = sep + 1; sep = index(p, '&'); if(sep == NULL) break; *sep = 0; length = atoi(p); p = sep + 1; sep = index(p, '='); if(sep == NULL) break; *sep = 0; if(strcmp(p, "nexthop") != 0) break; p = sep + 1; if(uiplib_ipaddrconv(p, &nexthop) == 0) break; route = uip_ds6_route_add_static(&ipaddr, length, &nexthop); if(route) { webserver_result_text = "Route created"; } } while (0); #else webserver_result_title = "Network"; webserver_result_text = "Add route: not supported"; #endif return &webserver_result_page; }
int ipaddr_update(const char* ifacename, int ifindex, const char* addr, unsigned long pref, unsigned long valid, int prefixLength) { return ipaddr_add(ifacename, ifindex, addr, pref, valid, prefixLength); }
static PT_THREAD(generate_sensors_info(struct httpd_state *s)) { static int i; PSOCK_BEGIN(&s->sout); add("<br /><h2>Sensors list</h2>"); add ("<table>" "<theader><tr class=\"row_first\"><td>Node</td><td>Type</td><td>Web</td><td>Coap</td><td>Parent</td><td>Up PRR</td><td>Down PRR</td><td>Last seen</td><td>Status</td></tr></theader>" "<tbody>"); SEND_STRING(&s->sout, buf); reset_buf(); for(i = 0; i < UIP_DS6_ROUTE_NB; i++) { if(node_info_table[i].isused) { add("<tr><td>"); add("<a href=\"sensor?ip="); ipaddr_add(&node_info_table[i].ipaddr); #if CETIC_NODE_CONFIG_HAS_NAME if ( node_config_loaded ) { add("\">%s (", node_config_get_name(node_config_find_by_ip(&node_info_table[i].ipaddr))); ipaddr_add(&node_info_table[i].ipaddr); add(")</a></td>"); } else #endif { add("\">"); ipaddr_add(&node_info_table[i].ipaddr); add("</a></td>"); } if(0) { } else if(node_info_table[i].ipaddr.u8[8] == 0x02 && node_info_table[i].ipaddr.u8[9] == 0x12 && (node_info_table[i].ipaddr.u8[10] == 0x74 || node_info_table[i].ipaddr.u8[10] == 0x75)) { add("<td>Moteiv Telos</td>"); } else if(node_info_table[i].ipaddr.u8[8] == 0x02 && node_info_table[i].ipaddr.u8[9] == 0x1A && node_info_table[i].ipaddr.u8[10] == 0x4C) { add("<td>Crossbow Sky</td>"); } else if(node_info_table[i].ipaddr.u8[8] == 0xC3 && node_info_table[i].ipaddr.u8[9] == 0x0C && node_info_table[i].ipaddr.u8[10] == 0x00) { add("<td>Zolertia Z1</td>"); } else if(node_info_table[i].ipaddr.u8[8] == 0x02 && node_info_table[i].ipaddr.u8[9] == 0x80 && node_info_table[i].ipaddr.u8[10] == 0xE1) { add("<td>STMicro</td>"); } else if(node_info_table[i].ipaddr.u8[8] == 0x02 && node_info_table[i].ipaddr.u8[9] == 0x12 && node_info_table[i].ipaddr.u8[10] == 0x4B) { add("<td>TI</td>"); } else if(node_info_table[i].ipaddr.u8[8] == 0x02 && node_info_table[i].ipaddr.u8[9] == 0x50 && node_info_table[i].ipaddr.u8[10] == 0xC2 && node_info_table[i].ipaddr.u8[11] == 0xA8 && (node_info_table[i].ipaddr.u8[12] & 0XF0) == 0xC0) { add("<td>Redwire Econotag I</td>"); } else if(node_info_table[i].ipaddr.u8[8] == 0x02 && node_info_table[i].ipaddr.u8[9] == 0x05 && node_info_table[i].ipaddr.u8[10] == 0x0C && node_info_table[i].ipaddr.u8[11] == 0x2A && node_info_table[i].ipaddr.u8[12] == 0x8C) { add("<td>Redwire Econotag I</td>"); } else if(node_info_table[i].ipaddr.u8[8] == 0xEE && node_info_table[i].ipaddr.u8[9] == 0x47 && node_info_table[i].ipaddr.u8[10] == 0x3C) { if(node_info_table[i].ipaddr.u8[11] == 0x4D && node_info_table[i].ipaddr.u8[12] == 0x12) { add("<td>Redwire M12</td>"); } else { add("<td>Redwire Unknown</td>"); } } else if((node_info_table[i].ipaddr.u8[8] & 0x02) == 0) { add("<td>User defined</td>"); } else { add("<td>Unknown</td>"); } SEND_STRING(&s->sout, buf); reset_buf(); #if CETIC_6LBR_IP64 && CETIC_NODE_CONFIG if(ip64_addr_is_ip64(&UIP_IP_BUF->srcipaddr)) { node_config_t * config = node_config_find_by_ip(&node_info_table[i].ipaddr); if(config && (nvm_data.eth_ip64_flags & CETIC_6LBR_IP64_SPECIAL_PORTS) != 0) { add("<td><a href=\"http://"); ip4addr_add(ip64_get_hostaddr()); add(":%d/\">web</a></td>", config->http_port); add("<td><a href=\"coap://"); ip4addr_add(ip64_get_hostaddr()); add(":%d/\">coap</a></td>", config->coap_port); } else { add("<td></td><td></td>"); } } else #endif { add("<td><a href=\"http://["); ipaddr_add(&node_info_table[i].ipaddr); add("]/\">web</a></td>"); add("<td><a href=\"coap://["); ipaddr_add(&node_info_table[i].ipaddr); add("]:5683/\">coap</a></td>"); } if(node_info_table[i].messages_received > 0) { add("<td>"); if((node_info_table[i].flags & NODE_INFO_PARENT_VALID) != 0) { #if CETIC_NODE_CONFIG_HAS_NAME if (node_config_loaded) { add("%s (", node_config_get_name(node_config_find_by_ip(&node_info_table[i].ip_parent))); ipaddr_add(&node_info_table[i].ip_parent); add(")"); } else { ipaddr_add(&node_info_table[i].ip_parent); } #else ipaddr_add(&node_info_table[i].ip_parent); #endif } add("</td>"); if((node_info_table[i].flags & NODE_INFO_UPSTREAM_VALID) != 0) { add("<td>%.1f%%</td>", 100.0 * (node_info_table[i].messages_sent - node_info_table[i].up_messages_lost)/node_info_table[i].messages_sent); } else { add("<td></td>"); } if((node_info_table[i].flags & NODE_INFO_DOWNSTREAM_VALID) != 0) { add("<td>%.1f%%</td>", 100.0 * (node_info_table[i].messages_sent - node_info_table[i].down_messages_lost)/node_info_table[i].messages_sent); } else { add("<td></td>"); } } else { add("<td></td><td></td><td></td>"); } add("<td>%d</td>", (clock_time() - node_info_table[i].last_seen) / CLOCK_SECOND); add("<td>%s</td>", node_info_flags_text(node_info_table[i].flags)); add("</tr>"); SEND_STRING(&s->sout, buf); reset_buf(); } } add("</tbody></table><br />"); add("<br /><h2>Actions</h2>"); add("<form action=\"reset-stats-all\" method=\"get\">"); add("<input type=\"submit\" value=\"Reset all statistics\"/></form><br />"); SEND_STRING(&s->sout, buf); reset_buf(); PSOCK_END(&s->sout); }