50 #include "dev/watchdog.h" 55 #if MAC_CONF_WITH_TSCH 62 #if ROUTING_CONF_RPL_LITE 63 #include "net/routing/rpl-lite/rpl.h" 64 #elif ROUTING_CONF_RPL_CLASSIC 65 #include "net/routing/rpl-classic/rpl.h" 70 #define PING_TIMEOUT (5 * CLOCK_SECOND) 72 static struct uip_icmp6_echo_reply_notification echo_reply_notification;
73 static shell_output_func *curr_ping_output_func = NULL;
74 static struct process *curr_ping_process;
75 static uint8_t curr_ping_ttl;
76 static uint16_t curr_ping_datalen;
78 static shell_command_6top_sub_cmd_t sixtop_sub_cmd = NULL;
80 static struct shell_command_set_t builtin_shell_command_set;
81 LIST(shell_command_sets);
84 ds6_nbr_state_to_str(uint8_t state)
101 #if ROUTING_CONF_RPL_LITE 107 case DAG_INITIALIZED:
108 return "Initialized";
121 rpl_mop_to_str(
int mop)
124 case RPL_MOP_NO_DOWNWARD_ROUTES:
125 return "No downward routes";
126 case RPL_MOP_NON_STORING:
127 return "Non-storing";
128 case RPL_MOP_STORING_NO_MULTICAST:
130 case RPL_MOP_STORING_MULTICAST:
131 return "Storing+multicast";
138 rpl_ocp_to_str(
int ocp)
151 PT_THREAD(cmd_rpl_nbr(
struct pt *pt, shell_output_func
output,
char *args))
156 SHELL_OUTPUT(output,
"RPL neighbors: none\n");
159 SHELL_OUTPUT(output,
"RPL neighbors:\n");
163 SHELL_OUTPUT(output,
"%s\n", buf);
164 nbr = nbr_table_next(rpl_neighbors, nbr);
172 PT_THREAD(cmd_rpl_status(
struct pt *pt, shell_output_func output,
char *args))
176 SHELL_OUTPUT(output,
"RPL status:\n");
177 if(!curr_instance.used) {
178 SHELL_OUTPUT(output,
"-- Instance: None\n");
180 SHELL_OUTPUT(output,
"-- Instance: %u\n", curr_instance.instance_id);
182 SHELL_OUTPUT(output,
"-- DAG root\n");
184 SHELL_OUTPUT(output,
"-- DAG node\n");
186 SHELL_OUTPUT(output,
"-- DAG: ");
187 shell_output_6addr(output, &curr_instance.dag.dag_id);
188 SHELL_OUTPUT(output,
", version %u\n", curr_instance.dag.version);
189 SHELL_OUTPUT(output,
"-- Prefix: ");
190 shell_output_6addr(output, &curr_instance.dag.prefix_info.prefix);
191 SHELL_OUTPUT(output,
"/%u\n", curr_instance.dag.prefix_info.length);
192 SHELL_OUTPUT(output,
"-- MOP: %s\n", rpl_mop_to_str(curr_instance.mop));
193 SHELL_OUTPUT(output,
"-- OF: %s\n", rpl_ocp_to_str(curr_instance.of->ocp));
194 SHELL_OUTPUT(output,
"-- Hop rank increment: %u\n", curr_instance.min_hoprankinc);
195 SHELL_OUTPUT(output,
"-- Default lifetime: %lu seconds\n",
RPL_LIFETIME(curr_instance.default_lifetime));
197 SHELL_OUTPUT(output,
"-- State: %s\n", rpl_state_to_str(curr_instance.dag.state));
198 SHELL_OUTPUT(output,
"-- Preferred parent: ");
199 if(curr_instance.dag.preferred_parent) {
201 SHELL_OUTPUT(output,
" (last DTSN: %u)\n", curr_instance.dag.preferred_parent->dtsn);
203 SHELL_OUTPUT(output,
"None\n");
205 SHELL_OUTPUT(output,
"-- Rank: %u\n", curr_instance.dag.rank);
206 SHELL_OUTPUT(output,
"-- Lowest rank: %u (%u)\n", curr_instance.dag.lowest_rank, curr_instance.max_rankinc);
207 SHELL_OUTPUT(output,
"-- DTSN out: %u\n", curr_instance.dtsn_out);
208 SHELL_OUTPUT(output,
"-- DAO sequence: last sent %u, last acked %u\n",
209 curr_instance.dag.dao_last_seqno, curr_instance.dag.dao_last_acked_seqno);
210 SHELL_OUTPUT(output,
"-- Trickle timer: current %u, min %u, max %u, redundancy %u\n",
211 curr_instance.dag.dio_intcurrent, curr_instance.dio_intmin,
212 curr_instance.dio_intmin + curr_instance.dio_intdoubl, curr_instance.dio_redundancy);
221 echo_reply_handler(uip_ipaddr_t *source, uint8_t ttl, uint8_t *data, uint16_t datalen)
223 if(curr_ping_output_func != NULL) {
224 curr_ping_output_func = NULL;
226 curr_ping_datalen = datalen;
232 PT_THREAD(cmd_ping(
struct pt *pt, shell_output_func output,
char *args))
234 static uip_ipaddr_t remote_addr;
235 static struct etimer timeout_timer;
240 SHELL_ARGS_INIT(args, next_args);
243 SHELL_ARGS_NEXT(args, next_args);
245 SHELL_OUTPUT(output,
"Destination IPv6 address is not specified\n");
248 SHELL_OUTPUT(output,
"Invalid IPv6 address: %s\n", args);
252 SHELL_OUTPUT(output,
"Pinging ");
253 shell_output_6addr(output, &remote_addr);
254 SHELL_OUTPUT(output,
"\n");
258 curr_ping_output_func =
output;
263 if(curr_ping_output_func != NULL) {
264 SHELL_OUTPUT(output,
"Timeout\n");
265 curr_ping_output_func = NULL;
267 SHELL_OUTPUT(output,
"Received ping reply from ");
268 shell_output_6addr(output, &remote_addr);
269 SHELL_OUTPUT(output,
", len %u, ttl %u, delay %lu ms\n",
277 shell_output_log_levels(shell_output_func output)
280 SHELL_OUTPUT(output,
"Log levels:\n");
281 while(all_modules[i].name != NULL) {
282 SHELL_OUTPUT(output,
"-- %-10s: %u (%s)\n",
284 *all_modules[i].curr_log_level,
291 PT_THREAD(cmd_log(
struct pt *pt, shell_output_func output,
char *args))
293 static int prev_level;
301 SHELL_ARGS_INIT(args, next_args);
304 SHELL_ARGS_NEXT(args, next_args);
307 if(module == NULL || (strcmp(
"all", module) && prev_level == -1)) {
308 SHELL_OUTPUT(output,
"Invalid first argument: %s\n", module)
309 shell_output_log_levels(output);
314 SHELL_ARGS_NEXT(args, next_args);
318 level = (int)strtol(args, &ptr, 10);
320 if((level == 0 && args == ptr)
321 || level < LOG_LEVEL_NONE || level > LOG_LEVEL_DBG) {
322 SHELL_OUTPUT(output,
"Invalid second argument: %s\n", args);
327 if(level != prev_level) {
329 #if MAC_CONF_WITH_TSCH && TSCH_LOG_PER_SLOT 330 if(!strcmp(module,
"mac") || !strcmp(module,
"all")) {
331 if(level >= LOG_LEVEL_DBG) {
333 SHELL_OUTPUT(output,
"TSCH logging started\n");
336 SHELL_OUTPUT(output,
"TSCH logging stopped\n");
342 shell_output_log_levels(output);
348 PT_THREAD(cmd_help(
struct pt *pt, shell_output_func output,
char *args))
350 struct shell_command_set_t *
set;
351 const struct shell_command_t *cmd;
354 SHELL_OUTPUT(output,
"Available commands:\n");
357 for(cmd = set->commands; cmd->name != NULL; ++cmd) {
358 SHELL_OUTPUT(output,
"%s\n", cmd->help);
364 #if UIP_CONF_IPV6_RPL 367 PT_THREAD(cmd_rpl_set_root(
struct pt *pt, shell_output_func output,
char *args))
370 static uip_ipaddr_t prefix;
375 SHELL_ARGS_INIT(args, next_args);
378 SHELL_ARGS_NEXT(args, next_args);
380 if(!strcmp(args,
"1")) {
382 }
else if(!strcmp(args,
"0")) {
385 SHELL_OUTPUT(output,
"Invalid argument: %s\n", args);
390 SHELL_ARGS_NEXT(args, next_args);
393 SHELL_OUTPUT(output,
"Invalid Prefix: %s\n", args);
397 uip_ip6addr(&prefix, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0);
402 SHELL_OUTPUT(output,
"Setting as DAG root with prefix ");
403 shell_output_6addr(output, &prefix);
404 SHELL_OUTPUT(output,
"/64\n");
408 SHELL_OUTPUT(output,
"Node is already a DAG root\n");
412 SHELL_OUTPUT(output,
"Setting as non-root node: leaving DAG\n");
415 SHELL_OUTPUT(output,
"Node is not a DAG root\n");
423 PT_THREAD(cmd_rpl_global_repair(
struct pt *pt, shell_output_func output,
char *args))
427 SHELL_OUTPUT(output,
"Triggering routing global repair\n")
428 NETSTACK_ROUTING.global_repair("Shell");
434 PT_THREAD(cmd_rpl_local_repair(struct pt *pt, shell_output_func output,
char *args))
438 SHELL_OUTPUT(output,
"Triggering routing local repair\n");
444 #if ROUTING_CONF_RPL_LITE 446 PT_THREAD(cmd_rpl_refresh_routes(
struct pt *pt, shell_output_func output,
char *args))
450 SHELL_OUTPUT(output,
"Triggering routes refresh\n")
459 PT_THREAD(cmd_ipaddr(
struct pt *pt, shell_output_func output,
char *args))
466 SHELL_OUTPUT(output,
"Node IPv6 addresses:\n");
467 for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
471 SHELL_OUTPUT(output,
"-- ");
472 shell_output_6addr(output, &
uip_ds6_if.addr_list[i].ipaddr);
473 SHELL_OUTPUT(output,
"\n");
482 PT_THREAD(cmd_ip_neighbors(
struct pt *pt, shell_output_func output,
char *args))
488 nbr = uip_ds6_nbr_head();
490 SHELL_OUTPUT(output,
"Node IPv6 neighbors: none\n");
494 SHELL_OUTPUT(output,
"Node IPv6 neighbors:\n");
496 SHELL_OUTPUT(output,
"-- ");
497 shell_output_6addr(output, uip_ds6_nbr_get_ipaddr(nbr));
498 SHELL_OUTPUT(output,
" <-> ");
500 SHELL_OUTPUT(output,
", router %u, state %s ",
501 nbr->isrouter, ds6_nbr_state_to_str(nbr->state));
502 SHELL_OUTPUT(output,
"\n");
503 nbr = uip_ds6_nbr_next(nbr);
509 #if MAC_CONF_WITH_TSCH 512 PT_THREAD(cmd_tsch_set_coordinator(
struct pt *pt, shell_output_func output,
char *args))
515 static int is_secured;
520 SHELL_ARGS_INIT(args, next_args);
523 SHELL_ARGS_NEXT(args, next_args);
525 if(!strcmp(args,
"1")) {
527 }
else if(!strcmp(args,
"0")) {
530 SHELL_OUTPUT(output,
"Invalid first argument: %s\n", args);
535 SHELL_ARGS_NEXT(args, next_args);
537 if(!strcmp(args,
"1")) {
538 #if LLSEC802154_ENABLED 541 SHELL_OUTPUT(output,
"Security is not compiled in.\n");
544 }
else if(!strcmp(args,
"0")) {
547 SHELL_OUTPUT(output,
"Invalid second argument: %s\n", args);
554 SHELL_OUTPUT(output,
"Setting as TSCH %s (%s)\n",
555 is_on ?
"coordinator" :
"non-coordinator", is_secured ?
"secured" :
"non-secured");
564 PT_THREAD(cmd_tsch_status(
struct pt *pt, shell_output_func output,
char *args))
568 SHELL_OUTPUT(output,
"TSCH status:\n");
570 SHELL_OUTPUT(output,
"-- Is coordinator: %u\n", tsch_is_coordinator);
571 SHELL_OUTPUT(output,
"-- Is associated: %u\n", tsch_is_associated);
572 if(tsch_is_associated) {
574 SHELL_OUTPUT(output,
"-- PAN ID: 0x%x\n", frame802154_get_pan_id());
575 SHELL_OUTPUT(output,
"-- Is PAN secured: %u\n", tsch_is_pan_secured);
576 SHELL_OUTPUT(output,
"-- Join priority: %u\n", tsch_join_priority);
577 SHELL_OUTPUT(output,
"-- Time source: ");
580 SHELL_OUTPUT(output,
"\n");
582 SHELL_OUTPUT(output,
"none\n");
584 SHELL_OUTPUT(output,
"-- Last synchronized: %lu seconds ago\n", (
clock_time() - last_sync_time) /
CLOCK_SECOND);
593 PT_THREAD(cmd_routes(
struct pt *pt, shell_output_func output,
char *args))
600 SHELL_OUTPUT(output,
"Default route:\n");
601 default_route = uip_ds6_defrt_lookup(uip_ds6_defrt_choose());
602 if(default_route != NULL) {
603 SHELL_OUTPUT(output,
"-- ");
604 shell_output_6addr(output, &default_route->ipaddr);
605 if(default_route->lifetime.interval != 0) {
606 SHELL_OUTPUT(output,
" (lifetime: %lu seconds)\n", (
unsigned long)default_route->lifetime.interval);
608 SHELL_OUTPUT(output,
" (lifetime: infinite)\n");
611 SHELL_OUTPUT(output,
"-- None\n");
614 #if UIP_CONF_IPV6_RPL 620 while(link != NULL) {
623 SHELL_OUTPUT(output,
"-- %s\n", buf);
627 SHELL_OUTPUT(output,
"No routing links\n");
631 #if (UIP_MAX_ROUTES != 0) 632 if(uip_ds6_route_num_routes() > 0) {
635 SHELL_OUTPUT(output,
"Routing entries (%u in total):\n", uip_ds6_route_num_routes());
636 route = uip_ds6_route_head();
637 while(route != NULL) {
638 SHELL_OUTPUT(output,
"-- ");
639 shell_output_6addr(output, &route->ipaddr);
640 SHELL_OUTPUT(output,
" via ");
641 shell_output_6addr(output, uip_ds6_route_nexthop(route));
642 if((
unsigned long)route->state.lifetime != 0xFFFFFFFF) {
643 SHELL_OUTPUT(output,
" (lifetime: %lu seconds)\n", (
unsigned long)route->state.lifetime);
645 SHELL_OUTPUT(output,
" (lifetime: infinite)\n");
647 route = uip_ds6_route_next(route);
650 SHELL_OUTPUT(output,
"No routing entries\n");
658 PT_THREAD(cmd_reboot(
struct pt *pt, shell_output_func output,
char *args))
661 SHELL_OUTPUT(output,
"rebooting\n");
665 #if MAC_CONF_WITH_TSCH 668 PT_THREAD(cmd_tsch_schedule(
struct pt *pt, shell_output_func output,
char *args))
681 SHELL_OUTPUT(output,
"TSCH schedule: no slotframe\n");
683 SHELL_OUTPUT(output,
"TSCH schedule:\n");
687 SHELL_OUTPUT(output,
"-- Slotframe: handle %u, size %u, links:\n", sf->handle, sf->size.val);
690 SHELL_OUTPUT(output,
"---- Options %02x, type %u, timeslot %u, channel offset %u, address ",
691 l->link_options, l->link_type, l->timeslot, l->channel_offset);
693 SHELL_OUTPUT(output,
"\n");
706 shell_commands_set_6top_sub_cmd(shell_command_6top_sub_cmd_t sub_cmd)
708 sixtop_sub_cmd = sub_cmd;
712 PT_THREAD(cmd_6top(
struct pt *pt, shell_output_func output,
char *args))
718 SHELL_ARGS_INIT(args, next_args);
720 if(sixtop_sub_cmd == NULL) {
721 SHELL_OUTPUT(output,
"6top command is unavailable:\n");
723 SHELL_OUTPUT(output,
"6top: ");
724 sixtop_sub_cmd(output, args);
726 SHELL_ARGS_NEXT(args, next_args);
736 list_add(shell_command_sets, &builtin_shell_command_set);
743 shell_command_set_register(
struct shell_command_set_t *
set)
749 shell_command_set_deregister(
struct shell_command_set_t *
set)
758 const struct shell_command_t *
759 shell_command_lookup(
const char *name)
761 struct shell_command_set_t *
set;
762 const struct shell_command_t *cmd;
767 for(cmd = set->commands; cmd->name != NULL; ++cmd) {
768 if(!strcmp(cmd->name, name)) {
776 const struct shell_command_t builtin_shell_commands[] = {
777 {
"help", cmd_help,
"'> help': Shows this help" },
778 {
"reboot", cmd_reboot,
"'> reboot': Reboot the board by watchdog_reboot()" },
779 {
"ip-addr", cmd_ipaddr,
"'> ip-addr': Shows all IPv6 addresses" },
780 {
"ip-nbr", cmd_ip_neighbors,
"'> ip-nbr': Shows all IPv6 neighbors" },
781 {
"log", cmd_log,
"'> log module level': Sets log level (0--4) for a given module (or \"all\"). For module \"mac\", level 4 also enables per-slot logging." },
782 {
"ping", cmd_ping,
"'> ping addr': Pings the IPv6 address 'addr'" },
783 #if UIP_CONF_IPV6_RPL 784 {
"rpl-set-root", cmd_rpl_set_root,
"'> rpl-set-root 0/1 [prefix]': Sets node as root (1) or not (0). A /64 prefix can be optionally specified." },
785 {
"rpl-local-repair", cmd_rpl_local_repair,
"'> rpl-local-repair': Triggers a RPL local repair" },
786 #if ROUTING_CONF_RPL_LITE 787 {
"rpl-refresh-routes", cmd_rpl_refresh_routes,
"'> rpl-refresh-routes': Refreshes all routes through a DTSN increment" },
789 {
"rpl-global-repair", cmd_rpl_global_repair,
"'> rpl-global-repair': Triggers a RPL global repair" },
791 #if ROUTING_CONF_RPL_LITE 792 {
"rpl-status", cmd_rpl_status,
"'> rpl-status': Shows a summary of the current RPL state" },
793 {
"rpl-nbr", cmd_rpl_nbr,
"'> rpl-nbr': Shows the RPL neighbor table" },
795 {
"routes", cmd_routes,
"'> routes': Shows the route entries" },
796 #if MAC_CONF_WITH_TSCH 797 {
"tsch-set-coordinator", cmd_tsch_set_coordinator,
"'> tsch-set-coordinator 0/1 [0/1]': Sets node as coordinator (1) or not (0). Second, optional parameter: enable (1) or disable (0) security." },
798 {
"tsch-schedule", cmd_tsch_schedule,
"'> tsch-schedule': Shows the current TSCH schedule" },
799 {
"tsch-status", cmd_tsch_status,
"'> tsch-status': Shows a summary of the current TSCH state" },
802 {
"6top", cmd_6top,
"'> 6top help': Shows 6top command usage" },
804 { NULL, NULL, NULL },
807 static struct shell_command_set_t builtin_shell_command_set = {
809 .commands = builtin_shell_commands,
#define uip_ip6addr(addr, addr0, addr1, addr2, addr3, addr4, addr5, addr6, addr7)
Construct an IPv6 address from eight 16-bit words.
An entry in the default router list.
Header file for ICMPv6 message and error handing (RFC 4443)
Main header file for the Contiki shell
uip_ipaddr_t * rpl_neighbor_get_ipaddr(rpl_nbr_t *nbr)
Returns a neighbor's (link-local) IPv6 address.
void shell_commands_init(void)
Initializes Shell-commands module.
static uip_ds6_nbr_t * nbr
Pointer to llao option in uip_buf.
struct tsch_slotframe * tsch_schedule_slotframe_next(struct tsch_slotframe *sf)
Access the next item in the list of slotframes.
int uip_sr_num_nodes(void)
Tells how many nodes are currently stored in the graph.
void list_push(list_t list, void *item)
Add an item to the start of the list.
void shell_output_lladdr(shell_output_func output, const linkaddr_t *lladdr)
Prints a link-layer address.
void tsch_log_init(void)
Initialize log module.
watchdog_reboot()
Keeps control until the WDT throws a reset signal.
bool list_contains(list_t list, void *item)
Check if the list contains an item.
TSCH neighbor information.
802.15.4e slotframe (contains links)
Main header file for the Contiki shell
#define PT_BEGIN(pt)
Declare the start of a protothread inside the C function implementing the protothread.
struct tsch_neighbor * tsch_queue_get_time_source(void)
Get the TSCH time source (we currently assume there is only one)
Common functionality of 802.15.4-compliant llsec_drivers.
#define PT_WAIT_UNTIL(pt, condition)
Block and wait until condition is true.
#define RPL_LIFETIME(lifetime)
Compute lifetime, accounting for the lifetime unit.
#define ICMP6_ECHO_REQUEST
Echo request.
int(* root_start)(void)
Set the node as root and start a network.
int rpl_neighbor_count(void)
Returns the number of nodes in the RPL neighbor table.
static uint8_t output(const linkaddr_t *localdest)
Take an IP packet and format it to be sent on an 802.15.4 network using 6lowpan.
Header file for IPv6-related data structures.
void tsch_log_stop(void)
Stop logging module.
void(* root_set_prefix)(uip_ipaddr_t *prefix, uip_ipaddr_t *iid)
Set the prefix, for nodes that will operate as root.
uip_sr_node_t * uip_sr_node_next(uip_sr_node_t *item)
Returns the next element of the non-storing node list.
#define PROCESS_CURRENT()
Get a pointer to the currently running process.
An entry in the routing table.
void log_set_level(const char *module, int level)
Sets a log level at run-time.
#define CLOCK_SECOND
A second, measured in system clock time.
Header file for the IP address manipulation library.
void uip_icmp6_echo_reply_callback_add(struct uip_icmp6_echo_reply_notification *n, uip_icmp6_echo_reply_callback_t c)
Add a callback function for ping replies.
#define PT_END(pt)
Declare the end of a protothread.
Linked list manipulation routines.
int(* node_is_root)(void)
Tells whether the node is a network root or not.
void process_poll(struct process *p)
Request a process to be polled.
void * list_head(list_t list)
Get a pointer to the first element of a list.
uip_sr_node_t * uip_sr_node_head(void)
Returns the head of the non-storing node list.
rpl_dag_state
RPL DAG states.
Routing driver header file
All information related to a RPL neighbor.
Main API declarations for TSCH.
clock_time_t clock_time(void)
Get the current clock time.
int etimer_expired(struct etimer *et)
Check if an event timer has expired.
int tsch_is_locked(void)
Checks if the TSCH lock is set.
struct tsch_slotframe * tsch_schedule_slotframe_head(void)
Access the first item in the list of slotframes.
long int tsch_adaptive_timesync_get_drift_ppm(void)
Gives the estimated clock drift w.r.t.
#define PT_EXIT(pt)
Exit the protothread.
#define ADDR_TENTATIVE
Possible states for the an address (RFC 4862)
#define PT_THREAD(name_args)
Declaration of a protothread.
#define NBR_INCOMPLETE
Possible states for the nbr cache entries.
void(* leave_network)(void)
Leave the network the node is part of.
void list_add(list_t list, void *item)
Add an item at the end of a list.
void list_init(list_t list)
Initialize a list.
int uip_sr_link_snprint(char *buf, int buflen, uip_sr_node_t *link)
Print a textual description of a source routing link.
Header file for the uIP TCP/IP stack.
const char * log_level_to_str(int level)
Returns a textual description of a log level.
int log_get_level(const char *module)
Returns the current log level.
#define LIST(name)
Declare a linked list.
uip_ds6_netif_t uip_ds6_if
The single interface.
void rpl_refresh_routes(const char *str)
Triggers a route fresh via DTSN increment.
void(* local_repair)(const char *str)
Triggers a RPL local topology repair.
void tsch_set_pan_secured(int enable)
Enable/disable security.
An IEEE 802.15.4-2015 TSCH link (also called cell or slot)
void uip_icmp6_send(const uip_ipaddr_t *dest, int type, int code, int payload_len)
Send an icmpv6 message.
#define uiplib_ipaddrconv
Convert a textual representation of an IP address to a numerical representation.
Header file for the logging system
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
void list_remove(list_t list, void *item)
Remove a specific element from a list.
void * list_item_next(void *item)
Get the next item following this item.
int rpl_neighbor_snprint(char *buf, int buflen, rpl_nbr_t *nbr)
Print a textual description of RPL neighbor into a string.
A node in a source routing graph, stored at the root and representing all child-parent relationship...
void tsch_set_coordinator(int enable)
Set the node as PAN coordinator.
An entry in the nbr cache.