diff --git a/os/net/ipv6/uip-sr.c b/os/net/ipv6/uip-sr.c index 15b123552..a82491827 100644 --- a/os/net/ipv6/uip-sr.c +++ b/os/net/ipv6/uip-sr.c @@ -41,6 +41,7 @@ #include "contiki.h" #include "net/ipv6/uip-sr.h" +#include "net/ipv6/uiplib.h" #include "net/routing/routing.h" #include "lib/list.h" #include "lib/memb.h" @@ -246,4 +247,49 @@ uip_sr_free_all(void) num_nodes--; } } +/*---------------------------------------------------------------------------*/ +int +uip_sr_link_snprint(char *buf, int buflen, uip_sr_node_t *link) +{ + int index = 0; + uip_ipaddr_t child_ipaddr; + uip_ipaddr_t parent_ipaddr; + + NETSTACK_ROUTING.get_sr_node_ipaddr(&child_ipaddr, link); + NETSTACK_ROUTING.get_sr_node_ipaddr(&parent_ipaddr, link->parent); + + index += uiplib_ipaddr_snprint(buf+index, buflen-index, &child_ipaddr); + if(index >= buflen) { + return index; + } + + if(link->parent == NULL) { + index += snprintf(buf+index, buflen-index, " (DODAG root)"); + if(index >= buflen) { + return index; + } + } else { + index += snprintf(buf+index, buflen-index, " to "); + if(index >= buflen) { + return index; + } + index += uiplib_ipaddr_snprint(buf+index, buflen-index, &parent_ipaddr); + if(index >= buflen) { + return index; + } + } + if(link->lifetime != UIP_SR_INFINITE_LIFETIME) { + index += snprintf(buf+index, buflen-index, + " (lifetime: %lu seconds)", (unsigned long)link->lifetime); + if(index >= buflen) { + return index; + } + } else { + index += snprintf(buf+index, buflen-index, " (lifetime: infinite)"); + if(index >= buflen) { + return index; + } + } + return index; +} /** @} */ diff --git a/os/net/ipv6/uip-sr.h b/os/net/ipv6/uip-sr.h index 7224cea14..01ed57c1c 100644 --- a/os/net/ipv6/uip-sr.h +++ b/os/net/ipv6/uip-sr.h @@ -180,6 +180,17 @@ void uip_sr_init(void); */ void uip_sr_free_all(void); +/** +* Print a textual description of a source routing link +* +* \param buf The buffer where to write content +* \param buflen The buffer len +* \param link A pointer to the source routing link +* \return Identical to snprintf: number of bytes written excluding ending null +* byte. A value >= buflen if the buffer was too small. +*/ +int uip_sr_link_snprint(char *buf, int buflen, uip_sr_node_t *link); + /** @} */ #endif /* UIP_SR_H */ diff --git a/os/net/routing/rpl-lite/rpl-dag-root.c b/os/net/routing/rpl-lite/rpl-dag-root.c index 0d5cebe92..c96fd6656 100644 --- a/os/net/routing/rpl-lite/rpl-dag-root.c +++ b/os/net/routing/rpl-lite/rpl-dag-root.c @@ -42,12 +42,35 @@ #include "net/routing/rpl-lite/rpl.h" #include "net/ipv6/uip-ds6-route.h" +#include "net/ipv6/uip-sr.h" /* Log configuration */ #include "sys/log.h" #define LOG_MODULE "RPL" #define LOG_LEVEL LOG_LEVEL_RPL +/*---------------------------------------------------------------------------*/ +void +rpl_dag_root_print_links(const char *str) +{ + if(rpl_dag_root_is_root()) { + if(uip_sr_num_nodes() > 0) { + uip_sr_node_t *link; + /* Our routing links */ + LOG_INFO("links: %u routing links in total (%s)\n", uip_sr_num_nodes(), str); + link = uip_sr_node_head(); + while(link != NULL) { + char buf[100]; + uip_sr_link_snprint(buf, sizeof(buf), link); + LOG_INFO("links: %s\n", buf); + link = uip_sr_node_next(link); + } + LOG_INFO("links: end of list\n"); + } else { + LOG_INFO("No routing links\n"); + } + } +} /*---------------------------------------------------------------------------*/ static void set_global_address(uip_ipaddr_t *prefix, uip_ipaddr_t *iid) diff --git a/os/net/routing/rpl-lite/rpl-dag-root.h b/os/net/routing/rpl-lite/rpl-dag-root.h index af0048c4d..71b999765 100644 --- a/os/net/routing/rpl-lite/rpl-dag-root.h +++ b/os/net/routing/rpl-lite/rpl-dag-root.h @@ -63,6 +63,12 @@ int rpl_dag_root_start(void); * \return 1 if we are dag root, 0 otherwise */ int rpl_dag_root_is_root(void); +/** + * Prints a summary of all routing links + * + * \param str A descriptive text on the caller +*/ +void rpl_dag_root_print_links(const char *str); /** @} */ diff --git a/os/net/routing/rpl-lite/rpl-neighbor.c b/os/net/routing/rpl-lite/rpl-neighbor.c index b33e4dad7..5f2f7f69a 100644 --- a/os/net/routing/rpl-lite/rpl-neighbor.c +++ b/os/net/routing/rpl-lite/rpl-neighbor.c @@ -94,10 +94,6 @@ rpl_neighbor_snprint(char *buf, int buflen, rpl_nbr_t *nbr) const struct link_stats *stats = rpl_neighbor_get_link_stats(nbr); clock_time_t clock_now = clock_time(); - index += snprintf(buf+index, buflen-index, "nbr: "); - if(index >= buflen) { - return index; - } index += uiplib_ipaddr_snprint(buf+index, buflen-index, rpl_neighbor_get_ipaddr(nbr)); if(index >= buflen) { return index; @@ -157,7 +153,7 @@ rpl_neighbor_print_list(const char *str) while(nbr != NULL) { char buf[120]; rpl_neighbor_snprint(buf, sizeof(buf), nbr); - LOG_INFO("%s\n", buf); + LOG_INFO("nbr: %s\n", buf); nbr = nbr_table_next(rpl_neighbors, nbr); } LOG_INFO("nbr: end of list\n"); diff --git a/os/net/routing/rpl-lite/rpl-timers.c b/os/net/routing/rpl-lite/rpl-timers.c index 6fb00ca17..c41b92948 100644 --- a/os/net/routing/rpl-lite/rpl-timers.c +++ b/os/net/routing/rpl-lite/rpl-timers.c @@ -521,6 +521,7 @@ handle_periodic_timer(void *ptr) if(LOG_INFO_ENABLED) { rpl_neighbor_print_list("Periodic"); + rpl_dag_root_print_links("Periodic"); } ctimer_reset(&periodic_timer); diff --git a/os/services/shell/shell-commands.c b/os/services/shell/shell-commands.c index fedbc06c6..f2f036eda 100644 --- a/os/services/shell/shell-commands.c +++ b/os/services/shell/shell-commands.c @@ -615,24 +615,9 @@ PT_THREAD(cmd_routes(struct pt *pt, shell_output_func output, char *args)) SHELL_OUTPUT(output, "Routing links (%u in total):\n", uip_sr_num_nodes()); link = uip_sr_node_head(); while(link != NULL) { - uip_ipaddr_t child_ipaddr; - uip_ipaddr_t parent_ipaddr; - NETSTACK_ROUTING.get_sr_node_ipaddr(&child_ipaddr, link); - NETSTACK_ROUTING.get_sr_node_ipaddr(&parent_ipaddr, link->parent); - SHELL_OUTPUT(output, "-- "); - shell_output_6addr(output, &child_ipaddr); - if(link->parent == NULL) { - memset(&parent_ipaddr, 0, sizeof(parent_ipaddr)); - SHELL_OUTPUT(output, " (DODAG root)"); - } else { - SHELL_OUTPUT(output, " to "); - shell_output_6addr(output, &parent_ipaddr); - } - if(link->lifetime != UIP_SR_INFINITE_LIFETIME) { - SHELL_OUTPUT(output, " (lifetime: %lu seconds)\n", (unsigned long)link->lifetime); - } else { - SHELL_OUTPUT(output, " (lifetime: infinite)\n"); - } + char buf[100]; + uip_sr_link_snprint(buf, sizeof(buf), link); + SHELL_OUTPUT(output, "-- %s\n", buf); link = uip_sr_node_next(link); } } else {