Shell: added a number of RPL and TSCH mngt functions
This commit is contained in:
parent
f7d4d5a0ec
commit
0ea63514e3
@ -50,7 +50,11 @@
|
|||||||
#include "net/ip/uiplib.h"
|
#include "net/ip/uiplib.h"
|
||||||
#include "net/ipv6/uip-icmp6.h"
|
#include "net/ipv6/uip-icmp6.h"
|
||||||
#include "net/ipv6/uip-ds6.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-log.h"
|
||||||
|
#include "net/mac/tsch/tsch-private.h"
|
||||||
#if UIP_CONF_IPV6_RPL_LITE == 1
|
#if UIP_CONF_IPV6_RPL_LITE == 1
|
||||||
#include "net/rpl-lite/rpl.h"
|
#include "net/rpl-lite/rpl.h"
|
||||||
#else /* UIP_CONF_IPV6_RPL_LITE == 1 */
|
#else /* UIP_CONF_IPV6_RPL_LITE == 1 */
|
||||||
@ -68,6 +72,53 @@ static struct process *curr_ping_process;
|
|||||||
static uint8_t curr_ping_ttl;
|
static uint8_t curr_ping_ttl;
|
||||||
static uint16_t curr_ping_datalen;
|
static uint16_t curr_ping_datalen;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
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
|
static void
|
||||||
echo_reply_handler(uip_ipaddr_t *source, uint8_t ttl, uint8_t *data, uint16_t datalen)
|
echo_reply_handler(uip_ipaddr_t *source, uint8_t ttl, uint8_t *data, uint16_t datalen)
|
||||||
@ -238,7 +289,29 @@ PT_THREAD(cmd_help(struct pt *pt, shell_output_func output, char *args))
|
|||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static
|
static
|
||||||
PT_THREAD(ipaddr(struct pt *pt, shell_output_func output, char *args))
|
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;
|
int i;
|
||||||
uint8_t state;
|
uint8_t state;
|
||||||
@ -257,10 +330,83 @@ PT_THREAD(ipaddr(struct pt *pt, shell_output_func output, char *args))
|
|||||||
}
|
}
|
||||||
|
|
||||||
PT_END(pt);
|
PT_END(pt);
|
||||||
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static
|
static
|
||||||
PT_THREAD(routes(struct pt *pt, shell_output_func output, char *args))
|
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;
|
uip_ds6_defrt_t *default_route;
|
||||||
#if RPL_WITH_NON_STORING
|
#if RPL_WITH_NON_STORING
|
||||||
@ -353,11 +499,15 @@ shell_commands_init(void)
|
|||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
struct shell_command_t shell_commands[] = {
|
struct shell_command_t shell_commands[] = {
|
||||||
{ "help", cmd_help, "'> help': Shows this help" },
|
{ "help", cmd_help, "'> help': Shows this help" },
|
||||||
{ "ipaddr", ipaddr, "'> ipaddr': Shows all IPv6 addresses" },
|
{ "ipaddr", cmd_ipaddr, "'> ipaddr': Shows all IPv6 addresses" },
|
||||||
|
{ "log", cmd_log, "'> log level': Sets log level (0--4). Level 4 also enables TSCH per-slot logging." },
|
||||||
{ "ping", cmd_ping, "'> ping addr': Pings the IPv6 address 'addr'" },
|
{ "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-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." },
|
||||||
{ "routes", routes, "'> routes': Shows the route entries" },
|
{ "rpl-status", cmd_rpl_status, "'> rpl-status': Shows a summary of the current RPL state" },
|
||||||
{ "log", cmd_log, "'> log level': Sets log level (0--4). Level 4 also enables TSCH per-slot logging." },
|
{ "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-status", cmd_tsch_status, "'> tsch-status': Shows a summary of the current TSCH state" },
|
||||||
{ NULL, NULL, NULL },
|
{ NULL, NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -59,6 +59,12 @@ static uint32_t asn_since_last_learning;
|
|||||||
/* Units in which drift is stored: ppm * 256 */
|
/* Units in which drift is stored: ppm * 256 */
|
||||||
#define TSCH_DRIFT_UNIT (1000L * 1000 * 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 */
|
/* Add a value to a moving average estimator */
|
||||||
static int32_t
|
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,
|
TSCH_LOG_ADD(tsch_log_message,
|
||||||
snprintf(log->message, sizeof(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 */
|
/* 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);
|
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__ */
|
#endif /* __TSCH_ADAPTIVE_TIMESYNC_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) */
|
/* Last time we received Sync-IE (ACK or data packet from a time source) */
|
||||||
static struct tsch_asn_t last_sync_asn;
|
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 */
|
/* A global lock for manipulating data structures safely from outside of interrupt */
|
||||||
static volatile int tsch_locked = 0;
|
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);
|
tsch_timesync_update(current_neighbor, since_last_timesync, drift_correction);
|
||||||
/* Keep track of sync time */
|
/* Keep track of sync time */
|
||||||
last_sync_asn = tsch_current_asn;
|
last_sync_asn = tsch_current_asn;
|
||||||
|
last_sync_time = clock_time();
|
||||||
tsch_schedule_keepalive();
|
tsch_schedule_keepalive();
|
||||||
}
|
}
|
||||||
mac_tx_status = MAC_TX_OK;
|
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);
|
int32_t since_last_timesync = TSCH_ASN_DIFF(tsch_current_asn, last_sync_asn);
|
||||||
/* Keep track of last sync time */
|
/* Keep track of last sync time */
|
||||||
last_sync_asn = tsch_current_asn;
|
last_sync_asn = tsch_current_asn;
|
||||||
|
last_sync_time = clock_time();
|
||||||
/* Save estimated drift */
|
/* Save estimated drift */
|
||||||
drift_correction = -estimated_drift;
|
drift_correction = -estimated_drift;
|
||||||
is_drift_correction_used = 1;
|
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;
|
current_slot_start = next_slot_start;
|
||||||
tsch_current_asn = *next_slot_asn;
|
tsch_current_asn = *next_slot_asn;
|
||||||
last_sync_asn = tsch_current_asn;
|
last_sync_asn = tsch_current_asn;
|
||||||
|
last_sync_time = clock_time();
|
||||||
current_link = NULL;
|
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 */
|
* Will be processed layer by tsch_rx_process_pending */
|
||||||
extern struct ringbufindex input_ringbuf;
|
extern struct ringbufindex input_ringbuf;
|
||||||
extern struct input_packet input_array[TSCH_MAX_INCOMING_PACKETS];
|
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 *********/
|
/********** Functions *********/
|
||||||
|
|
||||||
|
@ -198,8 +198,10 @@ rpl_local_repair(const char *str)
|
|||||||
{
|
{
|
||||||
if(curr_instance.used) { /* Check needed because this is a public function */
|
if(curr_instance.used) { /* Check needed because this is a public function */
|
||||||
LOG_WARN("local repair (%s)\n", str);
|
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.dag.state = DAG_INITIALIZED; /* Reset DAG state */
|
||||||
|
}
|
||||||
|
curr_instance.of->reset(); /* Reset OF */
|
||||||
link_stats_reset(); /* Forget past link statistics */
|
link_stats_reset(); /* Forget past link statistics */
|
||||||
rpl_neighbor_remove_all(); /* Remove all neighbors */
|
rpl_neighbor_remove_all(); /* Remove all neighbors */
|
||||||
rpl_timers_dio_reset("Local repair"); /* Reset Trickle timer */
|
rpl_timers_dio_reset("Local repair"); /* Reset Trickle timer */
|
||||||
|
Loading…
Reference in New Issue
Block a user