commit
fd5ebc8d42
81
apps/shell/serial-shell.c
Normal file
81
apps/shell/serial-shell.c
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* A shell back-end for the serial port
|
||||
* \author
|
||||
* Adam Dunkels <adam@sics.se>
|
||||
* Simon Duquennoy <simon.duquennoy@inria.fr>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup shell
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "contiki.h"
|
||||
#include "dev/serial-line.h"
|
||||
#include "sys/log.h"
|
||||
#include "shell.h"
|
||||
#include "serial-shell.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS(serial_shell_process, "Contiki serial shell");
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
serial_shell_output(const char *str) {
|
||||
printf("%s", str);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(serial_shell_process, ev, data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
|
||||
shell_init();
|
||||
|
||||
while(1) {
|
||||
static struct pt shell_input_pt;
|
||||
PROCESS_WAIT_EVENT_UNTIL(ev == serial_line_event_message && data != NULL);
|
||||
PROCESS_PT_SPAWN(&shell_input_pt, shell_input(&shell_input_pt, serial_shell_output, data));
|
||||
}
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
serial_shell_init(void)
|
||||
{
|
||||
process_start(&serial_shell_process, NULL);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
49
apps/shell/serial-shell.h
Normal file
49
apps/shell/serial-shell.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* A shell back-end for the serial port
|
||||
* \author
|
||||
* Adam Dunkels <adam@sics.se>
|
||||
* Simon Duquennoy <simon.duquennoy@inria.fr>
|
||||
*/
|
||||
|
||||
#ifndef SERIAL_SHELL_H_
|
||||
#define SERIAL_SHELL_H_
|
||||
|
||||
/**
|
||||
* Initializes Serial Shell module
|
||||
*/
|
||||
void serial_shell_init(void);
|
||||
|
||||
#endif /* SERIAL_SHELL_H_ */
|
626
apps/shell/shell-commands.c
Normal file
626
apps/shell/shell-commands.c
Normal file
@ -0,0 +1,626 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Inria.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* The Contiki shell commands
|
||||
* \author
|
||||
* Simon Duquennoy <simon.duquennoy@inria.fr>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup shell
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "contiki.h"
|
||||
#include "shell.h"
|
||||
#include "shell-commands.h"
|
||||
#include "sys/log.h"
|
||||
#include "net/ip/uip.h"
|
||||
#include "net/ip/uiplib.h"
|
||||
#include "net/ipv6/uip-icmp6.h"
|
||||
#include "net/ipv6/uip-ds6.h"
|
||||
#include "net/mac/tsch/tsch.h"
|
||||
#include "net/mac/tsch/tsch-adaptive-timesync.h"
|
||||
#include "net/mac/tsch/tsch-queue.h"
|
||||
#include "net/mac/tsch/tsch-log.h"
|
||||
#include "net/mac/tsch/tsch-private.h"
|
||||
#if UIP_CONF_IPV6_RPL_LITE == 1
|
||||
#include "net/rpl-lite/rpl.h"
|
||||
#else /* UIP_CONF_IPV6_RPL_LITE == 1 */
|
||||
#include "net/rpl/rpl.h"
|
||||
#include "net/rpl/rpl-private.h"
|
||||
#endif /* UIP_CONF_IPV6_RPL_LITE == 1 */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define PING_TIMEOUT (5 * CLOCK_SECOND)
|
||||
|
||||
static struct uip_icmp6_echo_reply_notification echo_reply_notification;
|
||||
static shell_output_func *curr_ping_output_func = NULL;
|
||||
static struct process *curr_ping_process;
|
||||
static uint8_t curr_ping_ttl;
|
||||
static uint16_t curr_ping_datalen;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static const char *
|
||||
ds6_nbr_state_to_str(uint8_t state)
|
||||
{
|
||||
switch(state) {
|
||||
case NBR_INCOMPLETE:
|
||||
return "Incomplete";
|
||||
case NBR_REACHABLE:
|
||||
return "Reachable";
|
||||
case NBR_STALE:
|
||||
return "Stale";
|
||||
case NBR_DELAY:
|
||||
return "Delay";
|
||||
case NBR_PROBE:
|
||||
return "Probe";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static const char *
|
||||
rpl_state_to_str(enum rpl_dag_state state)
|
||||
{
|
||||
switch(state) {
|
||||
case DAG_INITIALIZED:
|
||||
return "Initialized";
|
||||
case DAG_JOINED:
|
||||
return "Joined";
|
||||
case DAG_REACHABLE:
|
||||
return "Reachable";
|
||||
case DAG_POISONING:
|
||||
return "Poisoning";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static const char *
|
||||
rpl_mop_to_str(int mop)
|
||||
{
|
||||
switch(mop) {
|
||||
case RPL_MOP_NO_DOWNWARD_ROUTES:
|
||||
return "No downward routes";
|
||||
case RPL_MOP_NON_STORING:
|
||||
return "Non-storing";
|
||||
case RPL_MOP_STORING_NO_MULTICAST:
|
||||
return "Storing";
|
||||
case RPL_MOP_STORING_MULTICAST:
|
||||
return "Storing+multicast";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static const char *
|
||||
rpl_ocp_to_str(int ocp)
|
||||
{
|
||||
switch(ocp) {
|
||||
case RPL_OCP_OF0:
|
||||
return "OF0";
|
||||
case RPL_OCP_MRHOF:
|
||||
return "MRHOF";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
echo_reply_handler(uip_ipaddr_t *source, uint8_t ttl, uint8_t *data, uint16_t datalen)
|
||||
{
|
||||
if(curr_ping_output_func != NULL) {
|
||||
curr_ping_output_func = NULL;
|
||||
curr_ping_ttl = ttl;
|
||||
curr_ping_datalen = datalen;
|
||||
process_poll(curr_ping_process);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static
|
||||
PT_THREAD(cmd_ping(struct pt *pt, shell_output_func output, char *args))
|
||||
{
|
||||
static uip_ipaddr_t remote_addr;
|
||||
static struct etimer timeout_timer;
|
||||
char *next_args;
|
||||
|
||||
PT_BEGIN(pt);
|
||||
|
||||
SHELL_ARGS_INIT(args, next_args);
|
||||
|
||||
/* Get argument (remote IPv6) */
|
||||
SHELL_ARGS_NEXT(args, next_args);
|
||||
if(uiplib_ipaddrconv(args, &remote_addr) == 0) {
|
||||
SHELL_OUTPUT(output, "Invalid IPv6: %s\n", args);
|
||||
PT_EXIT(pt);
|
||||
}
|
||||
|
||||
SHELL_OUTPUT(output, "Pinging ");
|
||||
shell_output_6addr(output, &remote_addr);
|
||||
SHELL_OUTPUT(output, "\n");
|
||||
|
||||
/* Send ping request */
|
||||
curr_ping_process = PROCESS_CURRENT();
|
||||
curr_ping_output_func = output;
|
||||
etimer_set(&timeout_timer, PING_TIMEOUT);
|
||||
uip_icmp6_send(&remote_addr, ICMP6_ECHO_REQUEST, 0, 4);
|
||||
PT_WAIT_UNTIL(pt, curr_ping_output_func == NULL || etimer_expired(&timeout_timer));
|
||||
|
||||
if(curr_ping_output_func != NULL) {
|
||||
SHELL_OUTPUT(output, "Timeout\n");
|
||||
curr_ping_output_func = NULL;
|
||||
} else {
|
||||
SHELL_OUTPUT(output, "Received ping reply from ");
|
||||
shell_output_6addr(output, &remote_addr);
|
||||
SHELL_OUTPUT(output, ", len %u, ttl %u, delay %lu ms\n",
|
||||
curr_ping_datalen, curr_ping_ttl, (1000*(clock_time() - timeout_timer.timer.start))/CLOCK_SECOND);
|
||||
}
|
||||
|
||||
PT_END(pt);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static
|
||||
PT_THREAD(cmd_rpl_set_root(struct pt *pt, shell_output_func output, char *args))
|
||||
{
|
||||
static int is_on;
|
||||
static uip_ipaddr_t prefix;
|
||||
char *next_args;
|
||||
|
||||
PT_BEGIN(pt);
|
||||
|
||||
SHELL_ARGS_INIT(args, next_args);
|
||||
|
||||
/* Get first arg (0/1) */
|
||||
SHELL_ARGS_NEXT(args, next_args);
|
||||
|
||||
if(!strcmp(args, "1")) {
|
||||
is_on = 1;
|
||||
} else if(!strcmp(args, "0")) {
|
||||
is_on = 0;
|
||||
} else {
|
||||
SHELL_OUTPUT(output, "Invalid argument: %s\n", args);
|
||||
PT_EXIT(pt);
|
||||
}
|
||||
|
||||
/* Get first second arg (prefix) */
|
||||
SHELL_ARGS_NEXT(args, next_args);
|
||||
if(args != NULL) {
|
||||
if(uiplib_ipaddrconv(args, &prefix) == 0) {
|
||||
SHELL_OUTPUT(output, "Invalid Prefix: %s\n", args);
|
||||
PT_EXIT(pt);
|
||||
}
|
||||
} else {
|
||||
uip_ip6addr(&prefix, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
if(is_on) {
|
||||
if(!rpl_dag_root_is_root()) {
|
||||
SHELL_OUTPUT(output, "Setting as DAG root with prefix ");
|
||||
shell_output_6addr(output, &prefix);
|
||||
SHELL_OUTPUT(output, "\n");
|
||||
rpl_dag_root_init(&prefix, NULL);
|
||||
rpl_dag_root_init_dag_immediately();
|
||||
} else {
|
||||
SHELL_OUTPUT(output, "Node is already a DAG root\n");
|
||||
}
|
||||
} else {
|
||||
if(rpl_dag_root_is_root()) {
|
||||
SHELL_OUTPUT(output, "Setting as non-root node: leaving DAG\n");
|
||||
rpl_dag_poison_and_leave();
|
||||
} else {
|
||||
SHELL_OUTPUT(output, "Node is not a DAG root\n");
|
||||
}
|
||||
}
|
||||
|
||||
PT_END(pt);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
shell_output_log_levels(shell_output_func output)
|
||||
{
|
||||
int i = 0;
|
||||
SHELL_OUTPUT(output, "Log levels:\n");
|
||||
while(all_modules[i].name != NULL) {
|
||||
SHELL_OUTPUT(output, "-- %-10s: %s\n",
|
||||
all_modules[i].name,
|
||||
log_level_to_str(*all_modules[i].curr_log_level));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static
|
||||
PT_THREAD(cmd_log(struct pt *pt, shell_output_func output, char *args))
|
||||
{
|
||||
static int prev_level;
|
||||
static int level;
|
||||
char *next_args;
|
||||
char *ptr;
|
||||
char *module;
|
||||
|
||||
PT_BEGIN(pt);
|
||||
|
||||
SHELL_ARGS_INIT(args, next_args);
|
||||
|
||||
/* Get and parse argument: module name */
|
||||
SHELL_ARGS_NEXT(args, next_args);
|
||||
module = args;
|
||||
prev_level = log_get_level(module);
|
||||
if(module == NULL || (strcmp("all", module) && prev_level == -1)) {
|
||||
SHELL_OUTPUT(output, "Invalid first argument: %s\n", module)
|
||||
shell_output_log_levels(output);
|
||||
PT_EXIT(pt);
|
||||
}
|
||||
|
||||
/* Get and parse argument: log level */
|
||||
SHELL_ARGS_NEXT(args, next_args);
|
||||
if(args == NULL) {
|
||||
level = -1;
|
||||
} else {
|
||||
level = (int)strtol(args, &ptr, 10);
|
||||
}
|
||||
if((level == 0 && args == ptr)
|
||||
|| level < LOG_LEVEL_NONE || level > LOG_LEVEL_DBG) {
|
||||
SHELL_OUTPUT(output, "Invalid second argument: %s\n", args);
|
||||
PT_EXIT(pt);
|
||||
}
|
||||
|
||||
/* Set log level */
|
||||
if(level != prev_level) {
|
||||
log_set_level(module, level);
|
||||
if(!strcmp(module, "mac") || !strcmp(module, "all")) {
|
||||
if(level >= LOG_LEVEL_DBG) {
|
||||
tsch_log_init();
|
||||
SHELL_OUTPUT(output, "TSCH logging started\n");
|
||||
} else {
|
||||
tsch_log_stop();
|
||||
SHELL_OUTPUT(output, "TSCH logging stopped\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shell_output_log_levels(output);
|
||||
|
||||
PT_END(pt);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static
|
||||
PT_THREAD(cmd_help(struct pt *pt, shell_output_func output, char *args))
|
||||
{
|
||||
struct shell_command_t *cmd_ptr;
|
||||
|
||||
PT_BEGIN(pt);
|
||||
|
||||
SHELL_OUTPUT(output, "Available commands:\n");
|
||||
cmd_ptr = shell_commands;
|
||||
while(cmd_ptr->name != NULL) {
|
||||
SHELL_OUTPUT(output, "%s\n", cmd_ptr->help);
|
||||
cmd_ptr++;
|
||||
}
|
||||
|
||||
PT_END(pt);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static
|
||||
PT_THREAD(cmd_rpl_global_repair(struct pt *pt, shell_output_func output, char *args))
|
||||
{
|
||||
PT_BEGIN(pt);
|
||||
|
||||
SHELL_OUTPUT(output, "Triggering RPL global repair\n")
|
||||
rpl_global_repair();
|
||||
|
||||
PT_END(pt);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static
|
||||
PT_THREAD(cmd_rpl_local_repair(struct pt *pt, shell_output_func output, char *args))
|
||||
{
|
||||
PT_BEGIN(pt);
|
||||
|
||||
SHELL_OUTPUT(output, "Triggering RPL local repair\n");
|
||||
rpl_local_repair("Shell");
|
||||
|
||||
PT_END(pt);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static
|
||||
PT_THREAD(cmd_ipaddr(struct pt *pt, shell_output_func output, char *args))
|
||||
{
|
||||
int i;
|
||||
uint8_t state;
|
||||
|
||||
PT_BEGIN(pt);
|
||||
|
||||
SHELL_OUTPUT(output, "Node IPv6 addresses:\n");
|
||||
for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
|
||||
state = uip_ds6_if.addr_list[i].state;
|
||||
if(uip_ds6_if.addr_list[i].isused &&
|
||||
(state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) {
|
||||
SHELL_OUTPUT(output, "-- ");
|
||||
shell_output_6addr(output, &uip_ds6_if.addr_list[i].ipaddr);
|
||||
SHELL_OUTPUT(output, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
PT_END(pt);
|
||||
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static
|
||||
PT_THREAD(cmd_ip_neighbors(struct pt *pt, shell_output_func output, char *args))
|
||||
{
|
||||
uip_ds6_nbr_t *nbr;
|
||||
|
||||
PT_BEGIN(pt);
|
||||
|
||||
nbr = uip_ds6_nbr_head();
|
||||
if(nbr == NULL) {
|
||||
SHELL_OUTPUT(output, "Node IPv6 neighbors: none\n");
|
||||
PT_EXIT(pt);
|
||||
}
|
||||
|
||||
SHELL_OUTPUT(output, "Node IPv6 neighbors:\n");
|
||||
while(nbr != NULL) {
|
||||
SHELL_OUTPUT(output, "-- ");
|
||||
shell_output_6addr(output, uip_ds6_nbr_get_ipaddr(nbr));
|
||||
SHELL_OUTPUT(output, " <-> ");
|
||||
shell_output_lladdr(output, (linkaddr_t *)uip_ds6_nbr_get_ll(nbr));
|
||||
SHELL_OUTPUT(output, ", router %u, state %s ",
|
||||
nbr->isrouter, ds6_nbr_state_to_str(nbr->state));
|
||||
SHELL_OUTPUT(output, "\n");
|
||||
nbr = uip_ds6_nbr_next(nbr);
|
||||
}
|
||||
|
||||
PT_END(pt);
|
||||
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static
|
||||
PT_THREAD(cmd_tsch_status(struct pt *pt, shell_output_func output, char *args))
|
||||
{
|
||||
PT_BEGIN(pt);
|
||||
|
||||
SHELL_OUTPUT(output, "TSCH status:\n");
|
||||
|
||||
SHELL_OUTPUT(output, "-- Is coordinator: %u\n", tsch_is_coordinator);
|
||||
SHELL_OUTPUT(output, "-- Is associated: %u\n", tsch_is_associated);
|
||||
if(tsch_is_associated) {
|
||||
struct tsch_neighbor *n = tsch_queue_get_time_source();
|
||||
SHELL_OUTPUT(output, "-- PAN ID: 0x%x\n", frame802154_get_pan_id());
|
||||
SHELL_OUTPUT(output, "-- Is PAN secured: %u\n", tsch_is_pan_secured);
|
||||
SHELL_OUTPUT(output, "-- Join priority: %u\n", tsch_join_priority);
|
||||
SHELL_OUTPUT(output, "-- Time source: ");
|
||||
if(n != NULL) {
|
||||
shell_output_lladdr(output, &n->addr);
|
||||
SHELL_OUTPUT(output, "\n");
|
||||
} else {
|
||||
SHELL_OUTPUT(output, "none\n");
|
||||
}
|
||||
SHELL_OUTPUT(output, "-- Last synchronized: %lu seconds ago\n", (clock_time() - last_sync_time) / CLOCK_SECOND);
|
||||
SHELL_OUTPUT(output, "-- Drift w.r.t. coordinator: %ld ppm\n", tsch_adaptive_timesync_get_drift_ppm());
|
||||
}
|
||||
|
||||
PT_END(pt);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static
|
||||
PT_THREAD(cmd_rpl_status(struct pt *pt, shell_output_func output, char *args))
|
||||
{
|
||||
PT_BEGIN(pt);
|
||||
|
||||
SHELL_OUTPUT(output, "RPL status:\n");
|
||||
if(!curr_instance.used) {
|
||||
SHELL_OUTPUT(output, "-- Instance: None\n");
|
||||
} else {
|
||||
SHELL_OUTPUT(output, "-- Instance: %u\n", curr_instance.instance_id);
|
||||
if(rpl_dag_root_is_root()) {
|
||||
SHELL_OUTPUT(output, "-- DAG root\n");
|
||||
} else {
|
||||
SHELL_OUTPUT(output, "-- DAG node\n");
|
||||
}
|
||||
SHELL_OUTPUT(output, "-- DAG: ");
|
||||
shell_output_6addr(output, &curr_instance.dag.dag_id);
|
||||
SHELL_OUTPUT(output, ", version %u\n", curr_instance.dag.version);
|
||||
SHELL_OUTPUT(output, "-- Prefix: ");
|
||||
shell_output_6addr(output, &curr_instance.dag.prefix_info.prefix);
|
||||
SHELL_OUTPUT(output, "/%u\n", curr_instance.dag.prefix_info.length);
|
||||
SHELL_OUTPUT(output, "-- MOP: %s\n", rpl_mop_to_str(curr_instance.mop));
|
||||
SHELL_OUTPUT(output, "-- OF: %s\n", rpl_ocp_to_str(curr_instance.of->ocp));
|
||||
SHELL_OUTPUT(output, "-- Hop rank increment: %u\n", curr_instance.min_hoprankinc);
|
||||
SHELL_OUTPUT(output, "-- Default lifetime: %lu seconds\n", RPL_LIFETIME(curr_instance.default_lifetime));
|
||||
|
||||
SHELL_OUTPUT(output, "-- State: %s\n", rpl_state_to_str(curr_instance.dag.state));
|
||||
SHELL_OUTPUT(output, "-- Preferred parent: ");
|
||||
shell_output_6addr(output, rpl_neighbor_get_ipaddr(curr_instance.dag.preferred_parent));
|
||||
SHELL_OUTPUT(output, "\n");
|
||||
SHELL_OUTPUT(output, "-- Rank: %u\n", curr_instance.dag.rank);
|
||||
SHELL_OUTPUT(output, "-- Lowest rank: %u (%u)\n", curr_instance.dag.lowest_rank, curr_instance.max_rankinc);
|
||||
SHELL_OUTPUT(output, "-- DTSN out: %u\n", curr_instance.dtsn_out);
|
||||
SHELL_OUTPUT(output, "-- DAO sequence: last sent %u, last acked %u\n",
|
||||
curr_instance.dag.dao_last_seqno, curr_instance.dag.dao_last_acked_seqno);
|
||||
SHELL_OUTPUT(output, "-- Trickle timer: current %u, min %u, max %u, redundancy %u\n",
|
||||
curr_instance.dag.dio_intcurrent, curr_instance.dio_intmin,
|
||||
curr_instance.dio_intmin + curr_instance.dio_intdoubl, curr_instance.dio_redundancy);
|
||||
|
||||
}
|
||||
|
||||
PT_END(pt);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static
|
||||
PT_THREAD(cmd_routes(struct pt *pt, shell_output_func output, char *args))
|
||||
{
|
||||
uip_ds6_defrt_t *default_route;
|
||||
#if RPL_WITH_NON_STORING
|
||||
rpl_ns_node_t *link;
|
||||
#endif /* RPL_WITH_NON_STORING */
|
||||
#if RPL_WITH_STORING
|
||||
uip_ds6_route_t *route;
|
||||
#endif /* RPL_WITH_STORING */
|
||||
|
||||
PT_BEGIN(pt);
|
||||
|
||||
/* Our default route */
|
||||
SHELL_OUTPUT(output, "Default route:\n");
|
||||
default_route = uip_ds6_defrt_lookup(uip_ds6_defrt_choose());
|
||||
if(default_route != NULL) {
|
||||
SHELL_OUTPUT(output, "-- ");
|
||||
shell_output_6addr(output, &default_route->ipaddr);
|
||||
if(default_route->lifetime.interval != 0) {
|
||||
SHELL_OUTPUT(output, " (lifetime: %lu seconds)\n", (unsigned long)default_route->lifetime.interval);
|
||||
} else {
|
||||
SHELL_OUTPUT(output, " (lifetime: infinite)\n");
|
||||
}
|
||||
} else {
|
||||
SHELL_OUTPUT(output, "-- None\n");
|
||||
}
|
||||
|
||||
#if RPL_WITH_NON_STORING
|
||||
if(rpl_ns_num_nodes() > 0) {
|
||||
/* Our routing links */
|
||||
SHELL_OUTPUT(output, "Routing links (%u in total):\n", rpl_ns_num_nodes());
|
||||
link = rpl_ns_node_head();
|
||||
while(link != 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);
|
||||
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 != RPL_ROUTE_INFINITE_LIFETIME) {
|
||||
SHELL_OUTPUT(output, " (lifetime: %lu seconds)\n", (unsigned long)link->lifetime);
|
||||
} else {
|
||||
SHELL_OUTPUT(output, " (lifetime: infinite)\n");
|
||||
}
|
||||
link = rpl_ns_node_next(link);
|
||||
}
|
||||
} else {
|
||||
SHELL_OUTPUT(output, "No routing links\n");
|
||||
}
|
||||
#endif /* RPL_WITH_NON_STORING */
|
||||
|
||||
#if RPL_WITH_STORING
|
||||
if(uip_ds6_route_num_routes() > 0) {
|
||||
/* Our routing entries */
|
||||
SHELL_OUTPUT(output, "Routing entries (%u in total):\n", uip_ds6_route_num_routes());
|
||||
route = uip_ds6_route_head();
|
||||
while(route != NULL) {
|
||||
SHELL_OUTPUT(output, "-- ");
|
||||
shell_output_6addr(output, &route->ipaddr);
|
||||
SHELL_OUTPUT(output, " via ");
|
||||
shell_output_6addr(output, uip_ds6_route_nexthop(route));
|
||||
if((unsigned long)route->state.lifetime != RPL_ROUTE_INFINITE_LIFETIME) {
|
||||
SHELL_OUTPUT(output, " (lifetime: %lu seconds)\n", (unsigned long)route->state.lifetime);
|
||||
} else {
|
||||
SHELL_OUTPUT(output, " (lifetime: infinite)\n");
|
||||
}
|
||||
route = uip_ds6_route_next(route);
|
||||
}
|
||||
} else {
|
||||
SHELL_OUTPUT(output, "No routing entries\n");
|
||||
}
|
||||
#endif /* RPL_WITH_STORING */
|
||||
|
||||
PT_END(pt);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static
|
||||
PT_THREAD(cmd_tsch_schedule(struct pt *pt, shell_output_func output, char *args))
|
||||
{
|
||||
struct tsch_slotframe *sf;
|
||||
|
||||
PT_BEGIN(pt);
|
||||
|
||||
if(tsch_is_locked()) {
|
||||
PT_EXIT(pt);
|
||||
}
|
||||
|
||||
sf = tsch_schedule_slotframe_head();
|
||||
|
||||
if(sf == NULL) {
|
||||
SHELL_OUTPUT(output, "TSCH schedule: no slotframe\n");
|
||||
} else {
|
||||
SHELL_OUTPUT(output, "TSCH schedule:\n");
|
||||
while(sf != NULL) {
|
||||
struct tsch_link *l = list_head(sf->links_list);
|
||||
|
||||
SHELL_OUTPUT(output, "-- Slotframe: handle %u, size %u, links:\n", sf->handle, sf->size.val);
|
||||
|
||||
while(l != NULL) {
|
||||
SHELL_OUTPUT(output, "---- Options %02x, type %u, timeslot %u, channel offset %u, address ",
|
||||
l->link_options, l->link_type, l->timeslot, l->channel_offset);
|
||||
shell_output_lladdr(output, &l->addr);
|
||||
SHELL_OUTPUT(output, "\n");
|
||||
l = list_item_next(l);
|
||||
}
|
||||
|
||||
sf = tsch_schedule_slotframe_next(sf);
|
||||
}
|
||||
}
|
||||
PT_END(pt);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
shell_commands_init(void)
|
||||
{
|
||||
/* Set up Ping Reply callback */
|
||||
uip_icmp6_echo_reply_callback_add(&echo_reply_notification,
|
||||
echo_reply_handler);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
struct shell_command_t shell_commands[] = {
|
||||
{ "help", cmd_help, "'> help': Shows this help" },
|
||||
{ "ip-addr", cmd_ipaddr, "'> ip-addr': Shows all IPv6 addresses" },
|
||||
{ "ip-nbr", cmd_ip_neighbors, "'> ip-nbr': Shows all IPv6 neighbors" },
|
||||
{ "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." },
|
||||
{ "ping", cmd_ping, "'> ping addr': Pings the IPv6 address 'addr'" },
|
||||
{ "rpl-set-root", cmd_rpl_set_root, "'> rpl-set-root 0/1 [prefix]': Sets node as root (on) or not (off). A /64 prefix can be optionally specified." },
|
||||
{ "rpl-status", cmd_rpl_status, "'> rpl-status': Shows a summary of the current RPL state" },
|
||||
{ "rpl-global-repair", cmd_rpl_global_repair, "'> rpl-global-repair': Triggers a RPL global repair" },
|
||||
{ "rpl-local-repair", cmd_rpl_local_repair, "'> rpl-local-repair': Triggers a RPL local repair" },
|
||||
{ "routes", cmd_routes, "'> routes': Shows the route entries" },
|
||||
{ "tsch-schedule", cmd_tsch_schedule, "'> tsch-schedule': Shows the current TSCH schedule" },
|
||||
{ "tsch-status", cmd_tsch_status, "'> tsch-status': Shows a summary of the current TSCH state" },
|
||||
{ NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
/** @} */
|
66
apps/shell/shell-commands.h
Normal file
66
apps/shell/shell-commands.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Inria.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Main header file for the Contiki shell
|
||||
* \author
|
||||
* Simon Duquennoy <simon.duquennoy@inria.fr>
|
||||
*/
|
||||
|
||||
/** \addtogroup apps
|
||||
* @{ */
|
||||
|
||||
#ifndef _SHELL_COMMANDS_H_
|
||||
#define _SHELL_COMMANDS_H_
|
||||
|
||||
/* Command handling function type */
|
||||
typedef char (shell_commands_func)(struct pt *pt, shell_output_func output, char *args);
|
||||
|
||||
/* Command structure */
|
||||
struct shell_command_t {
|
||||
const char *name;
|
||||
shell_commands_func *func;
|
||||
const char *help;
|
||||
};
|
||||
|
||||
/* The set of supported commands */
|
||||
extern struct shell_command_t shell_commands[];
|
||||
|
||||
/**
|
||||
* Initializes Shell-commands module
|
||||
*/
|
||||
void shell_commands_init(void);
|
||||
|
||||
#endif /* _SHELL_COMMANDS_H_ */
|
||||
|
||||
/** @} */
|
152
apps/shell/shell.c
Normal file
152
apps/shell/shell.c
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Inria.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* The shell application
|
||||
* \author
|
||||
* Simon Duquennoy <simon.duquennoy@inria.fr>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup shell
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "contiki.h"
|
||||
#include "shell.h"
|
||||
#include "shell-commands.h"
|
||||
#include "net/ip/uip.h"
|
||||
#include "net/ip/ip64-addr.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
shell_output_6addr(shell_output_func output, const uip_ipaddr_t *ipaddr)
|
||||
{
|
||||
uint16_t a;
|
||||
unsigned int i;
|
||||
int f;
|
||||
|
||||
if(ipaddr == NULL) {
|
||||
SHELL_OUTPUT(output, "(NULL IP addr)");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ip64_addr_is_ipv4_mapped_addr(ipaddr)) {
|
||||
/* Printing IPv4-mapped addresses is done according to RFC 4291 */
|
||||
SHELL_OUTPUT(output, "::FFFF:%u.%u.%u.%u", ipaddr->u8[12], ipaddr->u8[13], ipaddr->u8[14], ipaddr->u8[15]);
|
||||
} else {
|
||||
for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) {
|
||||
a = (ipaddr->u8[i] << 8) + ipaddr->u8[i + 1];
|
||||
if(a == 0 && f >= 0) {
|
||||
if(f++ == 0) {
|
||||
SHELL_OUTPUT(output, "::");
|
||||
}
|
||||
} else {
|
||||
if(f > 0) {
|
||||
f = -1;
|
||||
} else if(i > 0) {
|
||||
SHELL_OUTPUT(output, ":");
|
||||
}
|
||||
SHELL_OUTPUT(output, "%x", a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
shell_output_lladdr(shell_output_func output, const linkaddr_t *lladdr)
|
||||
{
|
||||
if(lladdr == NULL) {
|
||||
SHELL_OUTPUT(output, "(NULL LL addr)");
|
||||
return;
|
||||
} else {
|
||||
unsigned int i;
|
||||
for(i = 0; i < LINKADDR_SIZE; i++) {
|
||||
if(i > 0 && i % 2 == 0) {
|
||||
SHELL_OUTPUT(output, ".");
|
||||
}
|
||||
SHELL_OUTPUT(output, "%02x", lladdr->u8[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
output_prompt(shell_output_func output)
|
||||
{
|
||||
shell_output_lladdr(output, &linkaddr_node_addr);
|
||||
SHELL_OUTPUT(output, "> ");
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PT_THREAD(shell_input(struct pt *pt, shell_output_func output, const char *cmd))
|
||||
{
|
||||
static char *args;
|
||||
static struct shell_command_t *cmd_ptr;
|
||||
|
||||
PT_BEGIN(pt);
|
||||
|
||||
/* Shave off any leading spaces. */
|
||||
while(*cmd == ' ') {
|
||||
cmd++;
|
||||
}
|
||||
|
||||
/* Look for arguments */
|
||||
args = strchr(cmd, ' ');
|
||||
if(args != NULL) {
|
||||
*args = '\0';
|
||||
args++;
|
||||
}
|
||||
|
||||
/* Lookup for command */
|
||||
cmd_ptr = shell_commands;
|
||||
while(cmd_ptr->name != NULL) {
|
||||
if(strcmp(cmd, cmd_ptr->name) == 0) {
|
||||
static struct pt cmd_pt;
|
||||
PT_SPAWN(pt, &cmd_pt, cmd_ptr->func(&cmd_pt, output, args));
|
||||
goto done;
|
||||
}
|
||||
cmd_ptr++;
|
||||
}
|
||||
|
||||
SHELL_OUTPUT(output, "Command not found. Type 'help' for a list of commands\n");
|
||||
|
||||
done:
|
||||
output_prompt(output);
|
||||
PT_END(pt);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
shell_init(void)
|
||||
{
|
||||
shell_commands_init();
|
||||
}
|
||||
/** @} */
|
108
apps/shell/shell.h
Normal file
108
apps/shell/shell.h
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Inria.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Main header file for the Contiki shell
|
||||
* \author
|
||||
* Simon Duquennoy <simon.duquennoy@inria.fr>
|
||||
*/
|
||||
|
||||
/** \addtogroup apps
|
||||
* @{ */
|
||||
|
||||
#ifndef SHELL_H_
|
||||
#define SHELL_H_
|
||||
|
||||
#include "net/ip/uip.h"
|
||||
#include "net/linkaddr.h"
|
||||
#include "sys/process.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/* Helper macros to parse arguments */
|
||||
#define SHELL_ARGS_INIT(args, next_args) (next_args) = (args);
|
||||
|
||||
#define SHELL_ARGS_NEXT(args, next_args) do { \
|
||||
(args) = (next_args); \
|
||||
if((args) != NULL) { \
|
||||
if(*(args) == '\0') { \
|
||||
(args) = NULL; \
|
||||
} else { \
|
||||
(next_args) = strchr((args), ' '); \
|
||||
if((next_args) != NULL) { \
|
||||
*(next_args) = '\0'; \
|
||||
(next_args)++; \
|
||||
} \
|
||||
} \
|
||||
} else { \
|
||||
(next_args) = NULL; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* Printf-formatted output via a given output function */
|
||||
#define SHELL_OUTPUT(output_func, format, ...) do { \
|
||||
char buffer[128]; \
|
||||
snprintf(buffer, sizeof(buffer), format, ##__VA_ARGS__); \
|
||||
(output_func)(buffer); \
|
||||
} while(0);
|
||||
|
||||
typedef void (shell_output_func)(const char *str);
|
||||
|
||||
/**
|
||||
* Initializes Shell module
|
||||
*/
|
||||
void shell_init(void);
|
||||
|
||||
/**
|
||||
* \brief A protothread that is spawned by a Shell driver when receiving a new line.
|
||||
*/
|
||||
PT_THREAD(shell_input(struct pt *pt, shell_output_func output, const char *cmd));
|
||||
|
||||
/**
|
||||
* Prints an IPv6 address
|
||||
*
|
||||
* \param output The output function
|
||||
* \param ipaddr The IPv6 to printed
|
||||
*/
|
||||
void shell_output_6addr(shell_output_func output, const uip_ipaddr_t *ipaddr);
|
||||
|
||||
/**
|
||||
* Prints a link-layer address
|
||||
*
|
||||
* \param output The output function
|
||||
* \param lladdr The link-layer to be printed
|
||||
*/
|
||||
void shell_output_lladdr(shell_output_func output, const linkaddr_t *lladdr);
|
||||
|
||||
#endif /* SHELL_H_ */
|
||||
|
||||
/** @} */
|
@ -45,6 +45,11 @@ typedef uint32_t rtimer_clock_t;
|
||||
/* 192us as in datasheet but ACKs are not always received, so adjusted to 250us */
|
||||
#define RADIO_DELAY_BEFORE_RX ((unsigned)US_TO_RTIMERTICKS(250))
|
||||
#define RADIO_DELAY_BEFORE_DETECT 0
|
||||
#ifndef TSCH_CONF_BASE_DRIFT_PPM
|
||||
/* The drift compared to "true" 10ms slots.
|
||||
* Enable adaptive sync to enable compensation for this. */
|
||||
#define TSCH_CONF_BASE_DRIFT_PPM -977
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name Serial Boot Loader Backdoor configuration
|
||||
|
@ -92,10 +92,12 @@ vsnprintf(char *str, size_t n, const char *fmt, __VALIST va)
|
||||
ch = *(fmt++);
|
||||
lz = 1;
|
||||
}
|
||||
if(ch >= '0' && ch <= '9') {
|
||||
if(ch == '-' || (ch >= '0' && ch <= '9')) {
|
||||
w = 0;
|
||||
while(ch >= '0' && ch <= '9') {
|
||||
while(ch == '-' || (ch >= '0' && ch <= '9')) {
|
||||
if(ch != '-') {
|
||||
w = (((w << 2) + w) << 1) + ch - '0';
|
||||
}
|
||||
ch = *fmt++;
|
||||
}
|
||||
}
|
||||
|
@ -84,6 +84,11 @@ typedef uint32_t rtimer_clock_t;
|
||||
/* 192us as in datasheet but ACKs are not always received, so adjusted to 250us */
|
||||
#define RADIO_DELAY_BEFORE_RX ((unsigned)US_TO_RTIMERTICKS(250))
|
||||
#define RADIO_DELAY_BEFORE_DETECT 0
|
||||
#ifndef TSCH_CONF_BASE_DRIFT_PPM
|
||||
/* The drift compared to "true" 10ms slots.
|
||||
* Enable adaptive sync to enable compensation for this. */
|
||||
#define TSCH_CONF_BASE_DRIFT_PPM -977
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name Serial Boot Loader Backdoor configuration
|
||||
|
@ -82,6 +82,11 @@ typedef uint32_t rtimer_clock_t;
|
||||
/* 192us as in datasheet but ACKs are not always received, so adjusted to 250us */
|
||||
#define RADIO_DELAY_BEFORE_RX ((unsigned)US_TO_RTIMERTICKS(250))
|
||||
#define RADIO_DELAY_BEFORE_DETECT 0
|
||||
#ifndef TSCH_CONF_BASE_DRIFT_PPM
|
||||
/* The drift compared to "true" 10ms slots.
|
||||
* Enable adaptive sync to enable compensation for this. */
|
||||
#define TSCH_CONF_BASE_DRIFT_PPM -977
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name Serial Boot Loader Backdoor configuration
|
||||
|
@ -58,7 +58,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "TCP/IP"
|
||||
#define LOG_LEVEL TCPIP_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_TCPIP
|
||||
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[UIP_LLIPH_LEN + uip_ext_len])
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
@ -672,6 +672,15 @@ tcpip_ipv6_output(void)
|
||||
goto send_packet;
|
||||
}
|
||||
|
||||
/* We first check if the destination address is one of ours. There is no
|
||||
* loopback interface -- instead, process this directly as incoming. */
|
||||
if(uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr)) {
|
||||
LOG_INFO("output: sending to ourself\n");
|
||||
packet_input();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Look for a next hop */
|
||||
if((nexthop = get_nexthop(&ipaddr)) == NULL) {
|
||||
goto exit;
|
||||
}
|
||||
|
@ -81,7 +81,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "6LoWPAN"
|
||||
#define LOG_LEVEL SICSLOWPAN_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_6LOWPAN
|
||||
|
||||
#ifdef SICSLOWPAN_CONF_COMPRESSION
|
||||
#define SICSLOWPAN_COMPRESSION SICSLOWPAN_CONF_COMPRESSION
|
||||
@ -1726,6 +1726,11 @@ input(void)
|
||||
/* The MAC puts the 15.4 payload inside the packetbuf data buffer */
|
||||
packetbuf_ptr = packetbuf_dataptr();
|
||||
|
||||
if(packetbuf_datalen() == 0) {
|
||||
LOG_WARN("empty packet\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* This is default uip_buf since we assume that this is not fragmented */
|
||||
buffer = (uint8_t *)UIP_IP_BUF;
|
||||
|
||||
|
@ -55,7 +55,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "IPv6 Nbr"
|
||||
#define LOG_LEVEL IPV6_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_IPV6
|
||||
|
||||
#ifdef UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED
|
||||
#define NEIGHBOR_STATE_CHANGED(n) UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED(n)
|
||||
@ -161,6 +161,18 @@ uip_ds6_nbr_num(void)
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_ds6_nbr_t *
|
||||
uip_ds6_nbr_head(void)
|
||||
{
|
||||
return nbr_table_head(ds6_neighbors);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_ds6_nbr_t *
|
||||
uip_ds6_nbr_next(uip_ds6_nbr_t *nbr)
|
||||
{
|
||||
return nbr_table_next(ds6_neighbors, nbr);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_ds6_nbr_t *
|
||||
uip_ds6_nbr_lookup(const uip_ipaddr_t *ipaddr)
|
||||
{
|
||||
uip_ds6_nbr_t *nbr = nbr_table_head(ds6_neighbors);
|
||||
|
@ -97,6 +97,8 @@ const uip_lladdr_t *uip_ds6_nbr_lladdr_from_ipaddr(const uip_ipaddr_t *ipaddr);
|
||||
void uip_ds6_link_callback(int status, int numtx);
|
||||
void uip_ds6_neighbor_periodic(void);
|
||||
int uip_ds6_nbr_num(void);
|
||||
uip_ds6_nbr_t *uip_ds6_nbr_head(void);
|
||||
uip_ds6_nbr_t *uip_ds6_nbr_next(uip_ds6_nbr_t *nbr);
|
||||
|
||||
#if UIP_ND6_SEND_NS
|
||||
/**
|
||||
|
@ -49,7 +49,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "IPv6 Route"
|
||||
#define LOG_LEVEL IPV6_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_IPV6
|
||||
|
||||
/* A configurable function called after adding a new neighbor as next hop */
|
||||
#ifdef NETSTACK_CONF_ROUTING_NEIGHBOR_ADDED_CALLBACK
|
||||
|
@ -54,7 +54,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "IPv6 DS"
|
||||
#define LOG_LEVEL IPV6_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_IPV6
|
||||
|
||||
struct etimer uip_ds6_timer_periodic; /**< Timer for maintenance of data structures */
|
||||
|
||||
|
@ -50,7 +50,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "ICMPv6"
|
||||
#define LOG_LEVEL IPV6_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_IPV6
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
@ -268,6 +268,9 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) {
|
||||
void
|
||||
uip_icmp6_send(const uip_ipaddr_t *dest, int type, int code, int payload_len)
|
||||
{
|
||||
LOG_INFO("Sending ICMPv6 packet to ");
|
||||
LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
|
||||
LOG_INFO_(", type %u, code %u, len %u\n", type, code, payload_len);
|
||||
|
||||
UIP_IP_BUF->vtc = 0x60;
|
||||
UIP_IP_BUF->tcflow = 0;
|
||||
|
@ -78,7 +78,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "IPv6 NDP"
|
||||
#define LOG_LEVEL IPV6_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_IPV6
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/** @{ */
|
||||
|
@ -96,7 +96,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "IPv6"
|
||||
#define LOG_LEVEL IPV6_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_IPV6
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -41,7 +41,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "Websocket"
|
||||
#define LOG_LEVEL IPV6_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_IPV6
|
||||
|
||||
enum {
|
||||
STATE_WAITING_FOR_HEADER,
|
||||
|
@ -40,7 +40,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "Websocket"
|
||||
#define LOG_LEVEL IPV6_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_IPV6
|
||||
|
||||
PROCESS(websocket_process, "Websockets process");
|
||||
|
||||
|
@ -58,7 +58,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "CSMA"
|
||||
#define LOG_LEVEL MAC_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_MAC
|
||||
|
||||
/* Constants of the IEEE 802.15.4 standard */
|
||||
|
||||
|
@ -47,7 +47,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "CSMA"
|
||||
#define LOG_LEVEL MAC_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_MAC
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
|
@ -43,7 +43,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "Frame 15.4"
|
||||
#define LOG_LEVEL FRAMER_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_FRAMER
|
||||
|
||||
/* c.f. IEEE 802.15.4e Table 4b */
|
||||
enum ieee802154e_header_ie_id {
|
||||
|
@ -46,7 +46,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "Frame 15.4"
|
||||
#define LOG_LEVEL FRAMER_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_FRAMER
|
||||
|
||||
/** \brief The sequence number (0x00 - 0xff) added to the transmitted
|
||||
* data or MAC command frame. The default is a random value within
|
||||
|
@ -35,7 +35,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "MAC"
|
||||
#define LOG_LEVEL MAC_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_MAC
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -59,6 +59,12 @@ static uint32_t asn_since_last_learning;
|
||||
/* Units in which drift is stored: ppm * 256 */
|
||||
#define TSCH_DRIFT_UNIT (1000L * 1000 * 256)
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
long int
|
||||
tsch_adaptive_timesync_get_drift_ppm(void)
|
||||
{
|
||||
return (long int)drift_ppm / 256;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Add a value to a moving average estimator */
|
||||
static int32_t
|
||||
@ -101,7 +107,7 @@ timesync_learn_drift_ticks(uint32_t time_delta_asn, int32_t drift_ticks)
|
||||
|
||||
TSCH_LOG_ADD(tsch_log_message,
|
||||
snprintf(log->message, sizeof(log->message),
|
||||
"drift %ld", (long int)drift_ppm / 256));
|
||||
"drift %ld", tsch_adaptive_timesync_get_drift_ppm()));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Either reset or update the neighbor's drift */
|
||||
|
@ -86,4 +86,6 @@ void tsch_timesync_update(struct tsch_neighbor *n, uint16_t time_delta_asn, int3
|
||||
|
||||
int32_t tsch_timesync_adaptive_compensate(rtimer_clock_t delta_ticks);
|
||||
|
||||
long int tsch_adaptive_timesync_get_drift_ppm(void);
|
||||
|
||||
#endif /* __TSCH_ADAPTIVE_TIMESYNC_H__ */
|
||||
|
@ -63,6 +63,7 @@ PROCESS_NAME(tsch_pending_events_process);
|
||||
static struct ringbufindex log_ringbuf;
|
||||
static struct tsch_log_t log_array[TSCH_LOG_QUEUE_LEN];
|
||||
static int log_dropped = 0;
|
||||
static int log_active = 0;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Process pending log messages */
|
||||
@ -73,16 +74,16 @@ tsch_log_process_pending(void)
|
||||
int16_t log_index;
|
||||
/* Loop on accessing (without removing) a pending input packet */
|
||||
if(log_dropped != last_log_dropped) {
|
||||
printf("TSCH:! logs dropped %u\n", log_dropped);
|
||||
printf("[WARN: TSCH-LOG ] logs dropped %u\n", log_dropped);
|
||||
last_log_dropped = log_dropped;
|
||||
}
|
||||
while((log_index = ringbufindex_peek_get(&log_ringbuf)) != -1) {
|
||||
struct tsch_log_t *log = &log_array[log_index];
|
||||
if(log->link == NULL) {
|
||||
printf("TSCH: {asn-%x.%lx link-NULL} ", log->asn.ms1b, log->asn.ls4b);
|
||||
printf("[INFO: TSCH-LOG ] {asn-%x.%lx link-NULL} ", log->asn.ms1b, log->asn.ls4b);
|
||||
} else {
|
||||
struct tsch_slotframe *sf = tsch_schedule_get_slotframe_by_handle(log->link->slotframe_handle);
|
||||
printf("TSCH: {asn-%x.%lx link-%u-%u-%u-%u ch-%u} ",
|
||||
printf("[INFO: TSCH-LOG ] {asn-%x.%lx link-%u-%u-%u-%u ch-%u} ",
|
||||
log->asn.ms1b, log->asn.ls4b,
|
||||
log->link->slotframe_handle, sf ? sf->size.val : 0, log->link->timeslot, log->link->channel_offset,
|
||||
tsch_calculate_channel(&log->asn, log->link->channel_offset));
|
||||
@ -144,15 +145,30 @@ tsch_log_prepare_add(void)
|
||||
void
|
||||
tsch_log_commit(void)
|
||||
{
|
||||
if(log_active == 1) {
|
||||
ringbufindex_put(&log_ringbuf);
|
||||
process_poll(&tsch_pending_events_process);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Initialize log module */
|
||||
void
|
||||
tsch_log_init(void)
|
||||
{
|
||||
if(log_active == 0) {
|
||||
ringbufindex_init(&log_ringbuf, TSCH_LOG_QUEUE_LEN);
|
||||
log_active = 1;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Stop log module */
|
||||
void
|
||||
tsch_log_stop(void)
|
||||
{
|
||||
if(log_active == 1) {
|
||||
tsch_log_process_pending();
|
||||
log_active = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* TSCH_LOG_PER_SLOT */
|
||||
|
@ -46,7 +46,7 @@
|
||||
#define TSCH_LOG_PER_SLOT TSCH_LOG_CONF_PER_SLOT
|
||||
#else /* TSCH_LOG_CONF_PER_SLOT */
|
||||
#include "sys/log.h"
|
||||
#define TSCH_LOG_PER_SLOT (MAC_LOG_LEVEL >= LOG_LEVEL_DBG)
|
||||
#define TSCH_LOG_PER_SLOT (LOG_LEVEL_MAC >= LOG_LEVEL_DBG)
|
||||
#endif /* TSCH_LOG_CONF_PER_SLOT */
|
||||
|
||||
/* The length of the log queue, i.e. maximum number postponed log messages */
|
||||
@ -112,6 +112,8 @@ void tsch_log_commit(void);
|
||||
void tsch_log_init(void);
|
||||
/* Process pending log messages */
|
||||
void tsch_log_process_pending(void);
|
||||
/* Stop logging module */
|
||||
void tsch_log_stop(void);
|
||||
|
||||
/************ Macros **********/
|
||||
|
||||
|
@ -54,7 +54,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "TSCH Pkt"
|
||||
#define LOG_LEVEL MAC_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_MAC
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Construct enhanced ACK packet and return ACK length */
|
||||
|
@ -58,7 +58,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "TSCH Queue"
|
||||
#define LOG_LEVEL MAC_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_MAC
|
||||
|
||||
/* Check if TSCH_QUEUE_NUM_PER_NEIGHBOR is power of two */
|
||||
#if (TSCH_QUEUE_NUM_PER_NEIGHBOR & (TSCH_QUEUE_NUM_PER_NEIGHBOR - 1)) != 0
|
||||
|
@ -54,7 +54,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "TSCH RPL"
|
||||
#define LOG_LEVEL MAC_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_MAC
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* To use, set #define TSCH_CALLBACK_KA_SENT tsch_rpl_callback_ka_sent */
|
||||
|
@ -58,7 +58,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "TSCH Sched"
|
||||
#define LOG_LEVEL MAC_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_MAC
|
||||
|
||||
/* Pre-allocated space for links */
|
||||
MEMB(link_memb, struct tsch_link, TSCH_SCHEDULE_MAX_LINKS);
|
||||
@ -418,6 +418,18 @@ tsch_schedule_create_minimal(void)
|
||||
0, 0);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
struct tsch_slotframe *
|
||||
tsch_schedule_slotframe_head(void)
|
||||
{
|
||||
return list_head(slotframe_list);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
struct tsch_slotframe *
|
||||
tsch_schedule_slotframe_next(struct tsch_slotframe *sf)
|
||||
{
|
||||
return list_item_next(sf);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Prints out the current schedule (all slotframes and links) */
|
||||
void
|
||||
tsch_schedule_print(void)
|
||||
|
@ -160,5 +160,8 @@ int tsch_schedule_remove_link_by_timeslot(struct tsch_slotframe *slotframe, uint
|
||||
/* Returns the next active link after a given ASN, and a backup link (for the same ASN, with Rx flag) */
|
||||
struct tsch_link * tsch_schedule_get_next_active_link(struct tsch_asn_t *asn, uint16_t *time_offset,
|
||||
struct tsch_link **backup_link);
|
||||
/* Access to slotframe list */
|
||||
struct tsch_slotframe *tsch_schedule_slotframe_head(void);
|
||||
struct tsch_slotframe *tsch_schedule_slotframe_next(struct tsch_slotframe *sf);
|
||||
|
||||
#endif /* __TSCH_SCHEDULE_H__ */
|
||||
|
@ -134,6 +134,7 @@ struct input_packet input_array[TSCH_MAX_INCOMING_PACKETS];
|
||||
|
||||
/* Last time we received Sync-IE (ACK or data packet from a time source) */
|
||||
static struct tsch_asn_t last_sync_asn;
|
||||
clock_time_t last_sync_time; /* Same info, in clock_time_t units */
|
||||
|
||||
/* A global lock for manipulating data structures safely from outside of interrupt */
|
||||
static volatile int tsch_locked = 0;
|
||||
@ -614,6 +615,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
|
||||
tsch_timesync_update(current_neighbor, since_last_timesync, drift_correction);
|
||||
/* Keep track of sync time */
|
||||
last_sync_asn = tsch_current_asn;
|
||||
last_sync_time = clock_time();
|
||||
tsch_schedule_keepalive();
|
||||
}
|
||||
mac_tx_status = MAC_TX_OK;
|
||||
@ -851,6 +853,7 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t))
|
||||
int32_t since_last_timesync = TSCH_ASN_DIFF(tsch_current_asn, last_sync_asn);
|
||||
/* Keep track of last sync time */
|
||||
last_sync_asn = tsch_current_asn;
|
||||
last_sync_time = clock_time();
|
||||
/* Save estimated drift */
|
||||
drift_correction = -estimated_drift;
|
||||
is_drift_correction_used = 1;
|
||||
@ -1053,6 +1056,7 @@ tsch_slot_operation_sync(rtimer_clock_t next_slot_start,
|
||||
current_slot_start = next_slot_start;
|
||||
tsch_current_asn = *next_slot_asn;
|
||||
last_sync_asn = tsch_current_asn;
|
||||
last_sync_time = clock_time();
|
||||
current_link = NULL;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -103,6 +103,8 @@ extern struct tsch_packet *dequeued_array[TSCH_DEQUEUED_ARRAY_SIZE];
|
||||
* Will be processed layer by tsch_rx_process_pending */
|
||||
extern struct ringbufindex input_ringbuf;
|
||||
extern struct input_packet input_array[TSCH_MAX_INCOMING_PACKETS];
|
||||
/* Last clock_time_t where synchronization happened */
|
||||
extern clock_time_t last_sync_time;
|
||||
|
||||
/********** Functions *********/
|
||||
|
||||
|
@ -69,7 +69,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "TSCH"
|
||||
#define LOG_LEVEL MAC_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_MAC
|
||||
|
||||
/* Use to collect link statistics even on Keep-Alive, even though they were
|
||||
* not sent from an upper layer and don't have a valid packet_sent callback */
|
||||
|
@ -107,7 +107,7 @@
|
||||
#ifdef TSCH_CONF_JOIN_MY_PANID_ONLY
|
||||
#define TSCH_JOIN_MY_PANID_ONLY TSCH_CONF_JOIN_MY_PANID_ONLY
|
||||
#else
|
||||
#define TSCH_JOIN_MY_PANID_ONLY 0
|
||||
#define TSCH_JOIN_MY_PANID_ONLY 1
|
||||
#endif
|
||||
|
||||
/* The radio polling frequency (in Hz) during association process */
|
||||
|
@ -38,7 +38,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "RPL"
|
||||
#define LOG_LEVEL RPL_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_RPL
|
||||
|
||||
#define RPL_DAG_GRACE_PERIOD (CLOCK_SECOND * 20 * 1)
|
||||
|
||||
|
@ -51,7 +51,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "RPL"
|
||||
#define LOG_LEVEL RPL_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_RPL
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
extern rpl_of_t rpl_of0, rpl_mrhof;
|
||||
@ -88,14 +88,17 @@ rpl_dag_leave(void)
|
||||
LOG_INFO_(", instance %u\n", curr_instance.instance_id);
|
||||
|
||||
/* Issue a no-path DAO */
|
||||
if(!rpl_dag_root_is_root()) {
|
||||
RPL_LOLLIPOP_INCREMENT(curr_instance.dag.dao_curr_seqno);
|
||||
rpl_icmp6_dao_output(0);
|
||||
}
|
||||
|
||||
/* Forget past link statistics */
|
||||
link_stats_reset();
|
||||
|
||||
/* Remove all neighbors */
|
||||
/* Remove all neighbors and lnks */
|
||||
rpl_neighbor_remove_all();
|
||||
rpl_ns_free_all();
|
||||
|
||||
/* Stop all timers */
|
||||
rpl_timers_stop_dag_timers();
|
||||
@ -110,6 +113,13 @@ rpl_dag_leave(void)
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rpl_dag_poison_and_leave(void)
|
||||
{
|
||||
curr_instance.dag.state = DAG_POISONING;
|
||||
rpl_timers_schedule_state_update();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rpl_dag_periodic(unsigned seconds)
|
||||
{
|
||||
if(curr_instance.used) {
|
||||
@ -197,8 +207,10 @@ rpl_local_repair(const char *str)
|
||||
{
|
||||
if(curr_instance.used) { /* Check needed because this is a public function */
|
||||
LOG_WARN("local repair (%s)\n", str);
|
||||
curr_instance.of->reset(); /* Reset OF */
|
||||
if(!rpl_dag_root_is_root()) {
|
||||
curr_instance.dag.state = DAG_INITIALIZED; /* Reset DAG state */
|
||||
}
|
||||
curr_instance.of->reset(); /* Reset OF */
|
||||
link_stats_reset(); /* Forget past link statistics */
|
||||
rpl_neighbor_remove_all(); /* Remove all neighbors */
|
||||
rpl_timers_dio_reset("Local repair"); /* Reset Trickle timer */
|
||||
@ -220,11 +232,13 @@ rpl_dag_ready_to_advertise(void)
|
||||
void
|
||||
rpl_dag_update_state(void)
|
||||
{
|
||||
if(curr_instance.used) {
|
||||
if(!rpl_dag_root_is_root()) {
|
||||
rpl_nbr_t *old_parent = curr_instance.dag.preferred_parent;
|
||||
rpl_rank_t old_rank = curr_instance.dag.rank;
|
||||
rpl_rank_t old_rank;
|
||||
|
||||
if(!curr_instance.used) {
|
||||
return;
|
||||
}
|
||||
|
||||
old_rank = curr_instance.dag.rank;
|
||||
/* Any scheduled state update is no longer needed */
|
||||
rpl_timers_unschedule_state_update();
|
||||
|
||||
@ -237,7 +251,8 @@ rpl_dag_update_state(void)
|
||||
rpl_timers_dio_reset("Poison routes");
|
||||
rpl_timers_schedule_leaving();
|
||||
}
|
||||
} else {
|
||||
} else if(!rpl_dag_root_is_root()) {
|
||||
rpl_nbr_t *old_parent = curr_instance.dag.preferred_parent;
|
||||
rpl_nbr_t *nbr;
|
||||
|
||||
/* Select and set preferred parent */
|
||||
@ -306,12 +321,10 @@ rpl_dag_update_state(void)
|
||||
#endif /* LOG_INFO_ENABLED */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally, update metric container */
|
||||
curr_instance.of->update_metric_container();
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static rpl_nbr_t *
|
||||
update_nbr_from_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||
@ -516,8 +529,6 @@ process_dio_init_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||
#endif /* RPL_WITH_PROBING */
|
||||
/* Leave the network after RPL_DELAY_BEFORE_LEAVING in case we do not
|
||||
find a parent */
|
||||
rpl_timers_schedule_leaving();
|
||||
|
||||
LOG_INFO("initialized DAG with instance ID %u, DAG ID ",
|
||||
curr_instance.instance_id);
|
||||
LOG_INFO_6ADDR(&curr_instance.dag.dag_id);
|
||||
@ -525,6 +536,9 @@ process_dio_init_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||
|
||||
LOG_ANNOTATE("#A init=%u\n", curr_instance.dag.dag_id.u8[sizeof(curr_instance.dag.dag_id) - 1]);
|
||||
|
||||
LOG_WARN_("just joined, no parent yet, setting timer for leaving\n");
|
||||
rpl_timers_schedule_leaving();
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -57,6 +57,11 @@
|
||||
* \return The description string
|
||||
*/
|
||||
const char *rpl_dag_state_to_str(enum rpl_dag_state state);
|
||||
/**
|
||||
* Start poisoning and leave the DAG after a delay
|
||||
*
|
||||
*/
|
||||
void rpl_dag_poison_and_leave(void);
|
||||
/**
|
||||
* Leaves the current DAG
|
||||
*
|
||||
|
@ -51,7 +51,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "RPL"
|
||||
#define LOG_LEVEL RPL_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_RPL
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
@ -365,14 +365,14 @@ rpl_ext_header_hbh_update(int uip_ext_opt_offset)
|
||||
uint16_t sender_rank;
|
||||
uint8_t sender_closer;
|
||||
rpl_nbr_t *sender;
|
||||
uint8_t opt_type = UIP_EXT_HDR_OPT_RPL_BUF->opt_type;
|
||||
uint8_t opt_len = UIP_EXT_HDR_OPT_RPL_BUF->opt_len;
|
||||
|
||||
if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)
|
||||
|| UIP_EXT_HDR_OPT_RPL_BUF->opt_type != UIP_EXT_HDR_OPT_RPL
|
||||
|| UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
|
||||
|
||||
|| opt_type != UIP_EXT_HDR_OPT_RPL
|
||||
|| opt_len != RPL_HDR_OPT_LEN) {
|
||||
LOG_ERR("hop-by-hop extension header has wrong size or type (%u %u %u)\n",
|
||||
UIP_HBHO_BUF->len, UIP_EXT_HDR_OPT_RPL_BUF->opt_type,
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->opt_len);
|
||||
UIP_HBHO_BUF->len, opt_type, opt_len);
|
||||
return 0; /* Drop */
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "RPL"
|
||||
#define LOG_LEVEL RPL_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_RPL
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define RPL_DIO_GROUNDED 0x80
|
||||
@ -557,10 +557,19 @@ rpl_icmp6_dao_output(uint8_t lifetime)
|
||||
/* Make sure we're up-to-date before sending data out */
|
||||
rpl_dag_update_state();
|
||||
|
||||
if(!curr_instance.used || curr_instance.dag.preferred_parent == NULL
|
||||
|| prefix == NULL || parent_ipaddr == NULL || curr_instance.mop == RPL_MOP_NO_DOWNWARD_ROUTES) {
|
||||
LOG_WARN("rpl_icmp6_dao_output: node not ready to send a DAO (used %u, pref parent %u, prefix %u, mop %u)\n",
|
||||
curr_instance.used, curr_instance.dag.preferred_parent != NULL && parent_ipaddr != NULL, prefix != NULL, curr_instance.mop);
|
||||
if(!curr_instance.used) {
|
||||
LOG_WARN("rpl_icmp6_dao_output: not in an instance, skip sending DAO\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(curr_instance.dag.preferred_parent == NULL) {
|
||||
LOG_WARN("rpl_icmp6_dao_output: no preferred parent, skip sending DAO\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(prefix == NULL || parent_ipaddr == NULL || curr_instance.mop == RPL_MOP_NO_DOWNWARD_ROUTES) {
|
||||
LOG_WARN("rpl_icmp6_dao_output: node not ready to send a DAO (prefix %p, parent addr %p, mop %u)\n",
|
||||
prefix, parent_ipaddr, curr_instance.mop);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "RPL"
|
||||
#define LOG_LEVEL RPL_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_RPL
|
||||
|
||||
/* RFC6551 and RFC6719 do not mandate the use of a specific formula to
|
||||
* compute the ETX value. This MRHOF implementation relies on the value
|
||||
|
@ -50,7 +50,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "RPL"
|
||||
#define LOG_LEVEL RPL_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_RPL
|
||||
|
||||
/*
|
||||
* Policy for neighbor addition
|
||||
|
@ -51,7 +51,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "RPL"
|
||||
#define LOG_LEVEL RPL_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_RPL
|
||||
|
||||
/* A configurable function called after every RPL parent switch */
|
||||
#ifdef RPL_CALLBACK_PARENT_SWITCH
|
||||
|
@ -44,7 +44,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "RPL"
|
||||
#define LOG_LEVEL RPL_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_RPL
|
||||
|
||||
/* Total number of nodes */
|
||||
static int num_nodes;
|
||||
@ -203,6 +203,7 @@ void
|
||||
rpl_ns_periodic(unsigned seconds)
|
||||
{
|
||||
rpl_ns_node_t *l;
|
||||
rpl_ns_node_t *next;
|
||||
/* First pass, decrement lifetime for all nodes with non-infinite lifetime */
|
||||
for(l = list_head(nodelist); l != NULL; l = list_item_next(l)) {
|
||||
/* Don't touch infinite lifetime nodes */
|
||||
@ -211,7 +212,8 @@ rpl_ns_periodic(unsigned seconds)
|
||||
}
|
||||
}
|
||||
/* Second pass, for all expired nodes, deallocate them iff no child points to them */
|
||||
for(l = list_head(nodelist); l != NULL; l = list_item_next(l)) {
|
||||
for(l = list_head(nodelist); l != NULL; l = next) {
|
||||
next = list_item_next(l);
|
||||
if(l->lifetime == 0) {
|
||||
rpl_ns_node_t *l2;
|
||||
for(l2 = list_head(nodelist); l2 != NULL; l2 = list_item_next(l2)) {
|
||||
@ -233,3 +235,16 @@ rpl_ns_periodic(unsigned seconds)
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rpl_ns_free_all(void)
|
||||
{
|
||||
rpl_ns_node_t *l;
|
||||
rpl_ns_node_t *next;
|
||||
for(l = list_head(nodelist); l != NULL; l = next) {
|
||||
next = list_item_next(l);
|
||||
list_remove(nodelist, l);
|
||||
memb_free(&nodememb, l);
|
||||
num_nodes--;
|
||||
}
|
||||
}
|
||||
|
@ -144,6 +144,11 @@ void rpl_ns_periodic(unsigned seconds);
|
||||
*/
|
||||
void rpl_ns_init(void);
|
||||
|
||||
/**
|
||||
* Deallocate all neighbors
|
||||
*/
|
||||
void rpl_ns_free_all(void);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* RPL_NS_H */
|
||||
|
@ -50,7 +50,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "RPL"
|
||||
#define LOG_LEVEL RPL_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_RPL
|
||||
|
||||
/* Constants from RFC6552. We use the default values. */
|
||||
#define RANK_STRETCH 0 /* Must be in the range [0;5] */
|
||||
|
@ -51,7 +51,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "RPL"
|
||||
#define LOG_LEVEL RPL_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_RPL
|
||||
|
||||
/* A configurable function called after update of the RPL DIO interval */
|
||||
#ifdef RPL_CALLBACK_NEW_DIO_INTERVAL
|
||||
@ -483,7 +483,7 @@ rpl_timers_schedule_leaving(void)
|
||||
{
|
||||
if(curr_instance.used) {
|
||||
if(ctimer_expired(&curr_instance.dag.leave)) {
|
||||
ctimer_set(&curr_instance.dag.leave, PERIODIC_DELAY, handle_leaving_timer, NULL);
|
||||
ctimer_set(&curr_instance.dag.leave, RPL_DELAY_BEFORE_LEAVING, handle_leaving_timer, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "RPL"
|
||||
#define LOG_LEVEL RPL_LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_LEVEL_RPL
|
||||
|
||||
uip_ipaddr_t rpl_multicast_addr;
|
||||
|
||||
|
@ -78,29 +78,29 @@
|
||||
/********************* A list of currently supported modules ******************/
|
||||
/******************************************************************************/
|
||||
|
||||
#ifndef RPL_LOG_LEVEL
|
||||
#define RPL_LOG_LEVEL LOG_LEVEL_NONE /* Only for rpl-lite */
|
||||
#endif /* RPL_LOG_LEVEL */
|
||||
#ifndef LOG_CONF_LEVEL_RPL
|
||||
#define LOG_CONF_LEVEL_RPL LOG_LEVEL_NONE /* Only for rpl-lite */
|
||||
#endif /* LOG_CONF_LEVEL_RPL */
|
||||
|
||||
#ifndef TCPIP_LOG_LEVEL
|
||||
#define TCPIP_LOG_LEVEL LOG_LEVEL_NONE
|
||||
#endif /* TCPIP_LOG_LEVEL */
|
||||
#ifndef LOG_CONF_LEVEL_TCPIP
|
||||
#define LOG_CONF_LEVEL_TCPIP LOG_LEVEL_NONE
|
||||
#endif /* LOG_CONF_LEVEL_TCPIP */
|
||||
|
||||
#ifndef IPV6_LOG_LEVEL
|
||||
#define IPV6_LOG_LEVEL LOG_LEVEL_NONE
|
||||
#endif /* IPV6_LOG_LEVEL */
|
||||
#ifndef LOG_CONF_LEVEL_IPV6
|
||||
#define LOG_CONF_LEVEL_IPV6 LOG_LEVEL_NONE
|
||||
#endif /* LOG_CONF_LEVEL_IPV6 */
|
||||
|
||||
#ifndef SICSLOWPAN_LOG_LEVEL
|
||||
#define SICSLOWPAN_LOG_LEVEL LOG_LEVEL_NONE
|
||||
#endif /* SICSLOWPAN_LOG_LEVEL */
|
||||
#ifndef LOG_CONF_LEVEL_6LOWPAN
|
||||
#define LOG_CONF_LEVEL_6LOWPAN LOG_LEVEL_NONE
|
||||
#endif /* LOG_CONF_LEVEL_6LOWPAN */
|
||||
|
||||
#ifndef MAC_LOG_LEVEL
|
||||
#define MAC_LOG_LEVEL LOG_LEVEL_NONE
|
||||
#endif /* MAC_LOG_LEVELL */
|
||||
#ifndef LOG_CONF_LEVEL_MAC
|
||||
#define LOG_CONF_LEVEL_MAC LOG_LEVEL_NONE
|
||||
#endif /* LOG_CONF_LEVEL_MAC */
|
||||
|
||||
#ifndef FRAMER_LOG_LEVEL
|
||||
#define FRAMER_LOG_LEVEL LOG_LEVEL_NONE
|
||||
#endif /* FRAMER_LOG_LEVEL */
|
||||
#ifndef LOG_CONF_LEVEL_FRAMER
|
||||
#define LOG_CONF_LEVEL_FRAMER LOG_LEVEL_NONE
|
||||
#endif /* LOG_CONF_LEVEL_FRAMER */
|
||||
|
||||
#endif /* __LOG_CONF_H__ */
|
||||
|
||||
|
@ -53,6 +53,24 @@
|
||||
#include "sys/log.h"
|
||||
#include "net/ip/ip64-addr.h"
|
||||
|
||||
|
||||
int curr_log_level_rpl = LOG_CONF_LEVEL_RPL;
|
||||
int curr_log_level_tcpip = LOG_CONF_LEVEL_TCPIP;
|
||||
int curr_log_level_ipv6 = LOG_CONF_LEVEL_IPV6;
|
||||
int curr_log_level_6lowpan = LOG_CONF_LEVEL_6LOWPAN;
|
||||
int curr_log_level_mac = LOG_CONF_LEVEL_MAC;
|
||||
int curr_log_level_framer = LOG_CONF_LEVEL_FRAMER;
|
||||
|
||||
struct log_module all_modules[] = {
|
||||
{"rpl", &curr_log_level_rpl, LOG_CONF_LEVEL_RPL},
|
||||
{"tcpip", &curr_log_level_tcpip, LOG_CONF_LEVEL_TCPIP},
|
||||
{"ipv6", &curr_log_level_ipv6, LOG_CONF_LEVEL_IPV6},
|
||||
{"6lowpan", &curr_log_level_6lowpan, LOG_CONF_LEVEL_6LOWPAN},
|
||||
{"mac", &curr_log_level_mac, LOG_CONF_LEVEL_MAC},
|
||||
{"framer", &curr_log_level_framer, LOG_CONF_LEVEL_FRAMER},
|
||||
{NULL, NULL, 0},
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
log_6addr(const uip_ipaddr_t *ipaddr)
|
||||
@ -131,6 +149,52 @@ log_lladdr_compact(const linkaddr_t *lladdr)
|
||||
LOG_OUTPUT("LL-%04x", UIP_HTONS(lladdr->u16[LINKADDR_SIZE/2-1]));
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
log_set_level(const char *module, int level)
|
||||
{
|
||||
if(level >= LOG_LEVEL_NONE && level <= LOG_LEVEL_DBG) {
|
||||
int i = 0;
|
||||
int module_all = !strcmp("all", module);
|
||||
while(all_modules[i].name != NULL) {
|
||||
if(module_all || !strcmp(module, all_modules[i].name)) {
|
||||
*all_modules[i].curr_log_level = MIN(level, all_modules[i].max_log_level);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
log_get_level(const char *module)
|
||||
{
|
||||
int i = 0;
|
||||
while(all_modules[i].name != NULL) {
|
||||
if(!strcmp(module, all_modules[i].name)) {
|
||||
return *all_modules[i].curr_log_level;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const char *
|
||||
log_level_to_str(int level)
|
||||
{
|
||||
switch(level) {
|
||||
case LOG_LEVEL_NONE:
|
||||
return "None";
|
||||
case LOG_LEVEL_ERR:
|
||||
return "Errors";
|
||||
case LOG_LEVEL_WARN:
|
||||
return "Warnings";
|
||||
case LOG_LEVEL_INFO:
|
||||
return "Info";
|
||||
case LOG_LEVEL_DBG:
|
||||
return "Debug";
|
||||
default:
|
||||
return "N/A";
|
||||
}
|
||||
}
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
@ -65,10 +65,34 @@
|
||||
#define LOG_LEVEL_INFO 3 /* Basic info */
|
||||
#define LOG_LEVEL_DBG 4 /* Detailled debug */
|
||||
|
||||
/* Per-module log level */
|
||||
|
||||
struct log_module {
|
||||
const char *name;
|
||||
int *curr_log_level;
|
||||
int max_log_level;
|
||||
};
|
||||
|
||||
extern int curr_log_level_rpl;
|
||||
extern int curr_log_level_tcpip;
|
||||
extern int curr_log_level_ipv6;
|
||||
extern int curr_log_level_6lowpan;
|
||||
extern int curr_log_level_mac;
|
||||
extern int curr_log_level_framer;
|
||||
|
||||
extern struct log_module all_modules[];
|
||||
|
||||
#define LOG_LEVEL_RPL MIN((LOG_CONF_LEVEL_RPL), curr_log_level_rpl)
|
||||
#define LOG_LEVEL_TCPIP MIN((LOG_CONF_LEVEL_TCPIP), curr_log_level_tcpip)
|
||||
#define LOG_LEVEL_IPV6 MIN((LOG_CONF_LEVEL_IPV6), curr_log_level_ipv6)
|
||||
#define LOG_LEVEL_6LOWPAN MIN((LOG_CONF_LEVEL_6LOWPAN), curr_log_level_6lowpan)
|
||||
#define LOG_LEVEL_MAC MIN((LOG_CONF_LEVEL_MAC), curr_log_level_mac)
|
||||
#define LOG_LEVEL_FRAMER MIN((LOG_CONF_LEVEL_FRAMER), curr_log_level_framer)
|
||||
|
||||
/* Main log function */
|
||||
|
||||
#define LOG(newline, level, levelstr, ...) do { \
|
||||
if(level <= LOG_LEVEL) { \
|
||||
if(level <= (LOG_LEVEL)) { \
|
||||
if(newline) { \
|
||||
LOG_OUTPUT("[%-4s: %-10s] ", levelstr, LOG_MODULE); \
|
||||
if(LOG_WITH_LOC) { \
|
||||
@ -88,7 +112,7 @@
|
||||
|
||||
/* Link-layer address */
|
||||
#define LOG_LLADDR(level, lladdr) do { \
|
||||
if(level <= LOG_LEVEL) { \
|
||||
if(level <= (LOG_LEVEL)) { \
|
||||
if(LOG_WITH_COMPACT_ADDR) { \
|
||||
log_lladdr_compact(lladdr); \
|
||||
} else { \
|
||||
@ -99,7 +123,7 @@
|
||||
|
||||
/* IPv6 address */
|
||||
#define LOG_6ADDR(level, ipaddr) do { \
|
||||
if(level <= LOG_LEVEL) { \
|
||||
if(level <= (LOG_LEVEL)) { \
|
||||
if(LOG_WITH_COMPACT_ADDR) { \
|
||||
log_6addr_compact(ipaddr); \
|
||||
} else { \
|
||||
@ -130,11 +154,10 @@
|
||||
#define LOG_DBG_6ADDR(...) LOG_6ADDR(LOG_LEVEL_DBG, __VA_ARGS__)
|
||||
|
||||
/* For testing log level */
|
||||
#define LOG_ERR_ENABLED (LOG_LEVEL >= LOG_LEVEL_ERR)
|
||||
#define LOG_WARN_ENABLED (LOG_LEVEL >= LOG_LEVEL_WARN)
|
||||
#define LOG_INFO_ENABLED (LOG_LEVEL >= LOG_LEVEL_INFO)
|
||||
#define LOG_DBG_ENABLED (LOG_LEVEL >= LOG_LEVEL_DBG)
|
||||
#define LOG_ANNOTATE_ENABLED (LOG_LEVEL >= LOG_LEVEL_ANNOTATE)
|
||||
#define LOG_ERR_ENABLED (MIN(LOG_LEVEL, curr_log_level) >= LOG_LEVEL_ERR)
|
||||
#define LOG_WARN_ENABLED (MIN(LOG_LEVEL, curr_log_level) >= LOG_LEVEL_WARN)
|
||||
#define LOG_INFO_ENABLED (MIN(LOG_LEVEL, curr_log_level) >= LOG_LEVEL_INFO)
|
||||
#define LOG_DBG_ENABLED (MIN(LOG_LEVEL, curr_log_level) >= LOG_LEVEL_DBG)
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
|
||||
@ -164,6 +187,29 @@ void log_lladdr(const linkaddr_t *lladdr);
|
||||
*/
|
||||
void log_lladdr_compact(const linkaddr_t *lladdr);
|
||||
|
||||
/**
|
||||
* Sets a log level at run-time. Logs are included in the firmware via
|
||||
* the compile-time flags in log-conf.h, but this allows to force lower log
|
||||
* levels, system-wide.
|
||||
* \param module The target module string descriptor
|
||||
* \param level The log level
|
||||
*/
|
||||
void log_set_level(const char *module, int level);
|
||||
|
||||
/**
|
||||
* Returns the current log level.
|
||||
* \param module The target module string descriptor
|
||||
* \return The current log level
|
||||
*/
|
||||
int log_get_level(const char *module);
|
||||
|
||||
/**
|
||||
* Returns a textual description of a log level
|
||||
* \param level log level
|
||||
* \return The textual description
|
||||
*/
|
||||
const char *log_level_to_str(int level);
|
||||
|
||||
#endif /* __LOG_H__ */
|
||||
|
||||
/** @} */
|
||||
|
@ -7,8 +7,9 @@ CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\"
|
||||
CONTIKI_WITH_IPV6 = 1
|
||||
MAKE_WITH_ORCHESTRA ?= 0 # force Orchestra from command line
|
||||
MAKE_WITH_SECURITY ?= 0 # force Security from command line
|
||||
MAKE_WITH_PERIODIC_ROUTES_PRINT ?= 0 # print #routes periodically, used for regression tests
|
||||
|
||||
APPS += orchestra
|
||||
APPS += orchestra shell
|
||||
MODULES += core/net/mac/tsch
|
||||
|
||||
ifeq ($(MAKE_WITH_ORCHESTRA),1)
|
||||
@ -19,4 +20,8 @@ ifeq ($(MAKE_WITH_SECURITY),1)
|
||||
CFLAGS += -DWITH_SECURITY=1
|
||||
endif
|
||||
|
||||
ifeq ($(MAKE_WITH_PERIODIC_ROUTES_PRINT),1)
|
||||
CFLAGS += -DWITH_PERIODIC_ROUTES_PRINT=1
|
||||
endif
|
||||
|
||||
include $(CONTIKI)/Makefile.include
|
||||
|
@ -40,205 +40,73 @@
|
||||
#include "node-id.h"
|
||||
#include "rpl.h"
|
||||
#include "rpl-dag-root.h"
|
||||
#include "sys/log.h"
|
||||
#include "net/ipv6/uip-ds6-route.h"
|
||||
#include "net/mac/tsch/tsch.h"
|
||||
#include "net/mac/tsch/tsch-log.h"
|
||||
#if UIP_CONF_IPV6_RPL_LITE == 0
|
||||
#include "rpl-private.h"
|
||||
#endif /* UIP_CONF_IPV6_RPL_LITE == 0 */
|
||||
#if WITH_ORCHESTRA
|
||||
#include "orchestra.h"
|
||||
#endif /* WITH_ORCHESTRA */
|
||||
#if WITH_SHELL
|
||||
#include "serial-shell.h"
|
||||
#endif /* WITH_SHELL */
|
||||
|
||||
#define DEBUG DEBUG_PRINT
|
||||
#include "net/ip/uip-debug.h"
|
||||
|
||||
#define CONFIG_VIA_BUTTON PLATFORM_HAS_BUTTON
|
||||
#if CONFIG_VIA_BUTTON
|
||||
#include "button-sensor.h"
|
||||
#endif /* CONFIG_VIA_BUTTON */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS(node_process, "RPL Node");
|
||||
#if CONFIG_VIA_BUTTON
|
||||
AUTOSTART_PROCESSES(&node_process, &sensors_process);
|
||||
#else /* CONFIG_VIA_BUTTON */
|
||||
AUTOSTART_PROCESSES(&node_process);
|
||||
#endif /* CONFIG_VIA_BUTTON */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
print_network_status(void)
|
||||
{
|
||||
int i;
|
||||
uint8_t state;
|
||||
uip_ds6_defrt_t *default_route;
|
||||
#if RPL_WITH_STORING
|
||||
uip_ds6_route_t *route;
|
||||
#endif /* RPL_WITH_STORING */
|
||||
#if RPL_WITH_NON_STORING
|
||||
rpl_ns_node_t *link;
|
||||
#endif /* RPL_WITH_NON_STORING */
|
||||
|
||||
PRINTF("--- Network status ---\n");
|
||||
|
||||
/* Our IPv6 addresses */
|
||||
PRINTF("- Server IPv6 addresses:\n");
|
||||
for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
|
||||
state = uip_ds6_if.addr_list[i].state;
|
||||
if(uip_ds6_if.addr_list[i].isused &&
|
||||
(state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) {
|
||||
PRINTF("-- ");
|
||||
PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr);
|
||||
PRINTF("\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Our default route */
|
||||
PRINTF("- Default route:\n");
|
||||
default_route = uip_ds6_defrt_lookup(uip_ds6_defrt_choose());
|
||||
if(default_route != NULL) {
|
||||
PRINTF("-- ");
|
||||
PRINT6ADDR(&default_route->ipaddr);
|
||||
PRINTF(" (lifetime: %lu seconds)\n", (unsigned long)default_route->lifetime.interval);
|
||||
} else {
|
||||
PRINTF("-- None\n");
|
||||
}
|
||||
|
||||
#if RPL_WITH_STORING
|
||||
/* Our routing entries */
|
||||
PRINTF("- Routing entries (%u in total):\n", uip_ds6_route_num_routes());
|
||||
route = uip_ds6_route_head();
|
||||
while(route != NULL) {
|
||||
PRINTF("-- ");
|
||||
PRINT6ADDR(&route->ipaddr);
|
||||
PRINTF(" via ");
|
||||
PRINT6ADDR(uip_ds6_route_nexthop(route));
|
||||
PRINTF(" (lifetime: %lu seconds)\n", (unsigned long)route->state.lifetime);
|
||||
route = uip_ds6_route_next(route);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RPL_WITH_NON_STORING
|
||||
/* Our routing links */
|
||||
PRINTF("- Routing links (%u in total):\n", rpl_ns_num_nodes());
|
||||
link = rpl_ns_node_head();
|
||||
while(link != 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);
|
||||
PRINTF("-- ");
|
||||
PRINT6ADDR(&child_ipaddr);
|
||||
if(link->parent == NULL) {
|
||||
memset(&parent_ipaddr, 0, sizeof(parent_ipaddr));
|
||||
PRINTF(" --- DODAG root ");
|
||||
} else {
|
||||
PRINTF(" to ");
|
||||
PRINT6ADDR(&parent_ipaddr);
|
||||
}
|
||||
PRINTF(" (lifetime: %lu seconds)\n", (unsigned long)link->lifetime);
|
||||
link = rpl_ns_node_next(link);
|
||||
}
|
||||
#endif
|
||||
|
||||
PRINTF("----------------------\n");
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
net_init(uip_ipaddr_t *br_prefix)
|
||||
{
|
||||
if(br_prefix) { /* We are RPL root. Will be set automatically
|
||||
as TSCH pan coordinator via the tsch-rpl module */
|
||||
rpl_dag_root_init(br_prefix, NULL);
|
||||
rpl_dag_root_init_dag_immediately();
|
||||
} else {
|
||||
rpl_dag_root_init(NULL, NULL);
|
||||
}
|
||||
|
||||
NETSTACK_MAC.on();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(node_process, ev, data)
|
||||
{
|
||||
static struct etimer et;
|
||||
int is_coordinator;
|
||||
|
||||
PROCESS_BEGIN();
|
||||
|
||||
/* 3 possible roles:
|
||||
* - role_6ln: simple node, will join any network, secured or not
|
||||
* - role_6dr: DAG root, will advertise (unsecured) beacons
|
||||
* - role_6dr_sec: DAG root, will advertise secured beacons
|
||||
* */
|
||||
static int is_coordinator = 0;
|
||||
static enum { role_6ln, role_6dr, role_6dr_sec } node_role;
|
||||
node_role = role_6ln;
|
||||
is_coordinator = 0;
|
||||
|
||||
int coordinator_candidate = 0;
|
||||
#if WITH_SHELL
|
||||
serial_shell_init();
|
||||
log_set_level("all", LOG_LEVEL_WARN);
|
||||
tsch_log_stop();
|
||||
#endif /* WITH_SHELL */
|
||||
|
||||
#if CONTIKI_TARGET_COOJA
|
||||
coordinator_candidate = (node_id == 1);
|
||||
is_coordinator = (node_id == 1);
|
||||
#endif
|
||||
|
||||
if(coordinator_candidate) {
|
||||
if(LLSEC802154_ENABLED) {
|
||||
node_role = role_6dr_sec;
|
||||
} else {
|
||||
node_role = role_6dr;
|
||||
}
|
||||
} else {
|
||||
node_role = role_6ln;
|
||||
}
|
||||
|
||||
#if CONFIG_VIA_BUTTON
|
||||
{
|
||||
#define CONFIG_WAIT_TIME 5
|
||||
|
||||
SENSORS_ACTIVATE(button_sensor);
|
||||
etimer_set(&et, CLOCK_SECOND * CONFIG_WAIT_TIME);
|
||||
|
||||
while(!etimer_expired(&et)) {
|
||||
printf("Init: current role: %s. Will start in %u seconds. Press user button to toggle mode.\n",
|
||||
node_role == role_6ln ? "6ln" : (node_role == role_6dr) ? "6dr" : "6dr-sec",
|
||||
CONFIG_WAIT_TIME);
|
||||
PROCESS_WAIT_EVENT_UNTIL(((ev == sensors_event) &&
|
||||
(data == &button_sensor) && button_sensor.value(0) > 0)
|
||||
|| etimer_expired(&et));
|
||||
if(ev == sensors_event && data == &button_sensor && button_sensor.value(0) > 0) {
|
||||
node_role = (node_role + 1) % 3;
|
||||
if(LLSEC802154_ENABLED == 0 && node_role == role_6dr_sec) {
|
||||
node_role = (node_role + 1) % 3;
|
||||
}
|
||||
etimer_restart(&et);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_VIA_BUTTON */
|
||||
|
||||
printf("Init: node starting with role %s\n",
|
||||
node_role == role_6ln ? "6ln" : (node_role == role_6dr) ? "6dr" : "6dr-sec");
|
||||
|
||||
tsch_set_pan_secured(LLSEC802154_ENABLED && (node_role == role_6dr_sec));
|
||||
is_coordinator = node_role > role_6ln;
|
||||
|
||||
if(is_coordinator) {
|
||||
uip_ipaddr_t prefix;
|
||||
uip_ip6addr(&prefix, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0);
|
||||
net_init(&prefix);
|
||||
} else {
|
||||
net_init(NULL);
|
||||
rpl_dag_root_init_dag_immediately();
|
||||
}
|
||||
NETSTACK_MAC.on();
|
||||
|
||||
#if WITH_ORCHESTRA
|
||||
orchestra_init();
|
||||
#endif /* WITH_ORCHESTRA */
|
||||
|
||||
#if WITH_PERIODIC_ROUTES_PRINT
|
||||
{
|
||||
static struct etimer et;
|
||||
/* Print out routing tables every minute */
|
||||
etimer_set(&et, CLOCK_SECOND * 60);
|
||||
while(1) {
|
||||
print_network_status();
|
||||
/* Used for non-regression testing */
|
||||
#if RPL_WITH_STORING
|
||||
PRINTF("Routing entries: %u\n", uip_ds6_route_num_routes());
|
||||
#endif
|
||||
#if RPL_WITH_NON_STORING
|
||||
PRINTF("Routing links: %u\n", rpl_ns_num_nodes());
|
||||
#endif
|
||||
PROCESS_YIELD_UNTIL(etimer_expired(&et));
|
||||
etimer_reset(&et);
|
||||
}
|
||||
}
|
||||
#endif /* WITH_PERIODIC_ROUTES_PRINT */
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
|
@ -35,6 +35,9 @@
|
||||
#ifndef __PROJECT_CONF_H__
|
||||
#define __PROJECT_CONF_H__
|
||||
|
||||
/* Set to use the Contiki shell */
|
||||
#define WITH_SHELL 1
|
||||
|
||||
/* Set to run orchestra */
|
||||
#ifndef WITH_ORCHESTRA
|
||||
#define WITH_ORCHESTRA 0
|
||||
@ -75,6 +78,18 @@
|
||||
#undef SYS_CTRL_CONF_OSC32K_USE_XTAL
|
||||
#define SYS_CTRL_CONF_OSC32K_USE_XTAL 1
|
||||
|
||||
#if WITH_SHELL
|
||||
/* Needed for CC2538 platforms, for serial */
|
||||
#define USB_SERIAL_CONF_ENABLE 1
|
||||
|
||||
/* USB serial takes space, free more space elsewhere */
|
||||
#undef SICSLOWPAN_CONF_FRAG
|
||||
#define SICSLOWPAN_CONF_FRAG 0
|
||||
#undef UIP_CONF_BUFFER_SIZE
|
||||
#define UIP_CONF_BUFFER_SIZE 160
|
||||
|
||||
#endif /* WITH_SHELL */
|
||||
|
||||
/* Needed for cc2420 platforms only */
|
||||
/* Disable DCO calibration (uses timerB) */
|
||||
#undef DCOSYNCH_CONF_ENABLED
|
||||
@ -87,13 +102,9 @@
|
||||
/******************* Configure TSCH ********************/
|
||||
/*******************************************************/
|
||||
|
||||
/* TSCH per-slot logging */
|
||||
#undef TSCH_LOG_CONF_PER_SLOT
|
||||
#define TSCH_LOG_CONF_PER_SLOT 1
|
||||
|
||||
/* IEEE802.15.4 PANID */
|
||||
#undef IEEE802154_CONF_PANID
|
||||
#define IEEE802154_CONF_PANID 0xabcd
|
||||
#define IEEE802154_CONF_PANID 0x81a5
|
||||
|
||||
/* Do not start TSCH at init, wait for NETSTACK_MAC.on() */
|
||||
#undef TSCH_CONF_AUTOSTART
|
||||
@ -145,4 +156,13 @@
|
||||
#define TSCH_CONF_MAX_EB_PERIOD (4 * CLOCK_SECOND)
|
||||
#endif /* CONTIKI_TARGET_COOJA */
|
||||
|
||||
/* Logging */
|
||||
#define LOG_CONF_LEVEL_RPL LOG_LEVEL_INFO
|
||||
#define LOG_CONF_LEVEL_TCPIP LOG_LEVEL_WARN
|
||||
#define LOG_CONF_LEVEL_IPV6 LOG_LEVEL_WARN
|
||||
#define LOG_CONF_LEVEL_6LOWPAN LOG_LEVEL_WARN
|
||||
#define LOG_CONF_LEVEL_MAC LOG_LEVEL_INFO
|
||||
#define LOG_CONF_LEVEL_FRAMER LOG_LEVEL_DBG
|
||||
#define TSCH_LOG_CONF_PER_SLOT 1
|
||||
|
||||
#endif /* __PROJECT_CONF_H__ */
|
||||
|
@ -39,11 +39,12 @@
|
||||
* LOG_LEVEL_INFO Basic info
|
||||
* LOG_LEVEL_DBG Detailled debug
|
||||
*/
|
||||
#define IPV6_LOG_LEVEL LOG_LEVEL_DBG
|
||||
#define SICSLOWPAN_LOG_LEVEL LOG_LEVEL_DBG
|
||||
#define TCPIP_LOG_LEVEL LOG_LEVEL_DBG
|
||||
#define MAC_LOG_LEVEL LOG_LEVEL_DBG
|
||||
#define FRAMER_LOG_LEVEL LOG_LEVEL_DBG
|
||||
#define LOG_CONF_LEVEL_IPV6 LOG_LEVEL_DBG
|
||||
#define LOG_CONF_LEVEL_RPL LOG_LEVEL_DBG
|
||||
#define LOG_CONF_LEVEL_6LOWPAN LOG_LEVEL_DBG
|
||||
#define LOG_CONF_LEVEL_TCPIP LOG_LEVEL_DBG
|
||||
#define LOG_CONF_LEVEL_MAC LOG_LEVEL_DBG
|
||||
#define LOG_CONF_LEVEL_FRAMER LOG_LEVEL_DBG
|
||||
|
||||
/* Enable cooja annotations */
|
||||
#define LOG_CONF_WITH_ANNOTATE 1
|
||||
|
@ -26,7 +26,7 @@
|
||||
<description>Cooja Mote Type #mtype1</description>
|
||||
<source EXPORT="discard">[CONTIKI_DIR]/examples/ipv6/rpl-tsch/node.c</source>
|
||||
<commands EXPORT="discard">make TARGET=cooja clean
|
||||
make node.cooja TARGET=cooja MAKE_WITH_ORCHESTRA=0 MAKE_WITH_SECURITY=0</commands>
|
||||
make node.cooja TARGET=cooja MAKE_WITH_ORCHESTRA=0 MAKE_WITH_SECURITY=0 MAKE_WITH_PERIODIC_ROUTES_PRINT=1</commands>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
|
||||
@ -278,7 +278,7 @@ log.log("Waiting for routing links to fill\n");
|
||||
while(true) {;
|
||||
WAIT_UNTIL(id == 1 && msg.contains("Routing links"));
|
||||
log.log(msg + "\n");
|
||||
if(msg.contains("Routing links (9 in total):")) {
|
||||
if(msg.contains("Routing links: 9")) {
|
||||
log.testOK(); /* Report test success and quit */
|
||||
}
|
||||
YIELD();
|
||||
|
@ -26,7 +26,7 @@
|
||||
<description>Cooja Mote Type #mtype11</description>
|
||||
<source EXPORT="discard">[CONTIKI_DIR]/examples/ipv6/rpl-tsch/node.c</source>
|
||||
<commands EXPORT="discard">make TARGET=cooja clean
|
||||
make node.cooja TARGET=cooja MAKE_WITH_ORCHESTRA=1 MAKE_WITH_SECURITY=0</commands>
|
||||
make node.cooja TARGET=cooja MAKE_WITH_ORCHESTRA=1 MAKE_WITH_SECURITY=0 MAKE_WITH_PERIODIC_ROUTES_PRINT=1</commands>
|
||||
<firmware
|
||||
EXPORT="copy">[CONTIKI_DIR]/examples/ipv6/rpl-tsch/node.mtype1</firmware>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||
@ -280,7 +280,7 @@ log.log("Waiting for routing links to fill\n");
|
||||
while(true) {;
|
||||
WAIT_UNTIL(id == 1 && msg.contains("Routing links"));
|
||||
log.log(msg + "\n");
|
||||
if(msg.contains("Routing links (9 in total):")) {
|
||||
if(msg.contains("Routing links: 9")) {
|
||||
log.testOK(); /* Report test success and quit */
|
||||
}
|
||||
YIELD();
|
||||
|
@ -26,7 +26,7 @@
|
||||
<description>Cooja Mote Type #mtype11</description>
|
||||
<source EXPORT="discard">[CONTIKI_DIR]/examples/ipv6/rpl-tsch/node.c</source>
|
||||
<commands EXPORT="discard">make TARGET=cooja clean
|
||||
make node.cooja TARGET=cooja MAKE_WITH_ORCHESTRA=0 MAKE_WITH_SECURITY=1</commands>
|
||||
make node.cooja TARGET=cooja MAKE_WITH_ORCHESTRA=0 MAKE_WITH_SECURITY=1 MAKE_WITH_PERIODIC_ROUTES_PRINT=1</commands>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
|
||||
@ -278,7 +278,7 @@ log.log("Waiting for routing links to fill\n");
|
||||
while(true) {;
|
||||
WAIT_UNTIL(id == 1 && msg.contains("Routing links"));
|
||||
log.log(msg + "\n");
|
||||
if(msg.contains("Routing links (9 in total):")) {
|
||||
if(msg.contains("Routing links: 9")) {
|
||||
log.testOK(); /* Report test success and quit */
|
||||
}
|
||||
YIELD();
|
||||
|
BIN
tools/jn516x/serialdump-linux
Normal file
BIN
tools/jn516x/serialdump-linux
Normal file
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user