From 07f6e10c1cf25cbfdab315681725e6fa713a3636 Mon Sep 17 00:00:00 2001 From: David Kopf Date: Fri, 2 Mar 2012 16:01:12 -0500 Subject: [PATCH] Add display options to border router web page, default now uses stack instead of static buffer. Turn radio off until prefix is acquired. --- core/net/mac/contikimac.c | 6 + .../ipv6/rpl-border-router/border-router.c | 139 ++++++++++++++++-- 2 files changed, 130 insertions(+), 15 deletions(-) diff --git a/core/net/mac/contikimac.c b/core/net/mac/contikimac.c index c65a975c9..81640793e 100644 --- a/core/net/mac/contikimac.c +++ b/core/net/mac/contikimac.c @@ -535,6 +535,12 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, struct rdc_buf_ struct hdr *chdr; #endif /* WITH_CONTIKIMAC_HEADER */ + /* Exit if RDC and radio were explicitly turned off */ + if (!contikimac_is_on && !contikimac_keep_radio_on) { + PRINTF("contikimac: radio is turned off\n"); + return MAC_TX_ERR_FATAL; + } + if(packetbuf_totlen() == 0) { PRINTF("contikimac: send_packet data len 0\n"); return MAC_TX_ERR_FATAL; diff --git a/examples/ipv6/rpl-border-router/border-router.c b/examples/ipv6/rpl-border-router/border-router.c index 418425ff9..33d9f754b 100644 --- a/examples/ipv6/rpl-border-router/border-router.c +++ b/examples/ipv6/rpl-border-router/border-router.c @@ -74,6 +74,13 @@ AUTOSTART_PROCESSES(&border_router_process,&webserver_nogui_process); #else /* Use simple webserver with only one page */ #include "httpd-simple.h" + +#define WEBSERVER_CONF_LOADTIME 0 +#define WEBSERVER_CONF_FILESTATS 0 +#define WEBSERVER_CONF_NEIGHBOR_STATUS 0 +#define WEBSERVER_CONF_ROUTE_LINKS 0 +#define BUF_USES_STACK 1 + PROCESS(webserver_nogui_process, "Web server"); PROCESS_THREAD(webserver_nogui_process, ev, data) { @@ -92,11 +99,19 @@ AUTOSTART_PROCESSES(&border_router_process,&webserver_nogui_process); static const char *TOP = "ContikiRPL\n"; static const char *BOTTOM = "\n"; -static char buf[128]; +#if BUF_USES_STACK +static char *bufptr, *bufend; +#define ADD(...) do { \ + bufptr += snprintf(bufptr, bufend - bufptr, __VA_ARGS__); \ + } while(0) +#else +static char buf[256]; static int blen; #define ADD(...) do { \ blen += snprintf(&buf[blen], sizeof(buf) - blen, __VA_ARGS__); \ } while(0) +#endif + /*---------------------------------------------------------------------------*/ static void ipaddr_add(const uip_ipaddr_t *addr) @@ -106,15 +121,12 @@ ipaddr_add(const uip_ipaddr_t *addr) for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { a = (addr->u8[i] << 8) + addr->u8[i + 1]; if(a == 0 && f >= 0) { - if(f++ == 0 && sizeof(buf) - blen >= 2) { - buf[blen++] = ':'; - buf[blen++] = ':'; - } + if(f++ == 0) ADD("::"); } else { if(f > 0) { f = -1; - } else if(i > 0 && blen < sizeof(buf)) { - buf[blen++] = ':'; + } else if(i > 0) { + ADD(":"); } ADD("%x", a); } @@ -125,46 +137,130 @@ static PT_THREAD(generate_routes(struct httpd_state *s)) { static int i; +#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
");
   for(i = 0; i < UIP_DS6_NBR_NB; i++) {
     if(uip_ds6_nbr_cache[i].isused) {
+
+#if WEBSERVER_CONF_NEIGHBOR_STATUS
+#if BUF_USES_STACK
+{char* j=bufptr+25;
       ipaddr_add(&uip_ds6_nbr_cache[i].ipaddr);
+      while (bufptr < j) ADD(" ");
+      switch (uip_ds6_nbr_cache[i].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(&uip_ds6_nbr_cache[i].ipaddr);
+      while (blen < j) ADD(" ");
+      switch (uip_ds6_nbr_cache[i].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(&uip_ds6_nbr_cache[i].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("
Routes
");
   SEND_STRING(&s->sout, buf);
+#if BUF_USES_STACK
+  bufptr = buf; bufend = bufptr + sizeof(buf);
+#else
   blen = 0;
+#endif
   for(i = 0; i < UIP_DS6_ROUTE_NB; i++) {
     if(uip_ds6_routing_table[i].isused) {
+#if BUF_USES_STACK
+#if WEBSERVER_CONF_ROUTE_LINKS
+      ADD("");
+      ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
+      ADD("");
+#else
+      ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
+#endif
+#else
+#if WEBSERVER_CONF_ROUTE_LINKS
+      ADD("");
+      SEND_STRING(&s->sout, buf); //TODO: why tunslip6 needs an output here, wpcapslip does not
+      blen = 0;
+      ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
+      ADD("");
+#else
+      ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
+#endif
+#endif
       ADD("/%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) {
+      if(1 || (uip_ds6_routing_table[i].state.lifetime < 600)) {
         ADD(") %lus\n", uip_ds6_routing_table[i].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("
"); -//if(blen > 0) { - SEND_STRING(&s->sout, buf); -// blen = 0; -//} +#if WEBSERVER_CONF_FILESTATS + static uint16_t numtimes; + ADD("
This page sent %u times",++numtimes); +#endif + +#if WEBSERVER_CONF_LOADTIME + numticks = clock_time() - numticks + 1; + ADD(" (%u.%02u sec)",numticks/CLOCK_SECOND,(100*(numticks%CLOCK_SECOND))/CLOCK_SECOND)); +#endif + + SEND_STRING(&s->sout, buf); SEND_STRING(&s->sout, BOTTOM); PSOCK_END(&s->sout); @@ -173,6 +269,7 @@ PT_THREAD(generate_routes(struct httpd_state *s)) httpd_simple_script_t httpd_simple_get_script(const char *name) { + return generate_routes; } @@ -226,19 +323,26 @@ PROCESS_THREAD(border_router_process, ev, data) PROCESS_BEGIN(); +/* While waiting for the prefix to be sent through the SLIP connection, the future + * border router can join an existing DAG as a parent or child, or acquire a default + * router that will later take precedence over the SLIP fallback interface. + * Prevent that by turning the radio off until we are initialized as a DAG root. + */ prefix_set = 0; + NETSTACK_MAC.off(0); PROCESS_PAUSE(); SENSORS_ACTIVATE(button_sensor); PRINTF("RPL-Border router started\n"); - +#if 0 /* The border router runs with a 100% duty cycle in order to ensure high packet reception rates. Note if the MAC RDC is not turned off now, aggressive power management of the cpu will interfere with establishing the SLIP connection */ NETSTACK_MAC.off(1); +#endif /* Request prefix until it has been received */ while(!prefix_set) { @@ -253,6 +357,11 @@ PROCESS_THREAD(border_router_process, ev, data) PRINTF("created a new RPL dag\n"); } + /* Now turn the radio on, but disable radio duty cycling. + * Since we are the DAG root, reception delays would constrain mesh throughbut. + */ + NETSTACK_MAC.off(1); + #if DEBUG || 1 print_local_addresses(); #endif