Merge pull request #454 from adamdunkels/push/dao-updates-rebased
RPL feather mode
This commit is contained in:
commit
7283e48f09
|
@ -78,10 +78,16 @@ NBR_TABLE(rpl_parent_t, rpl_parents);
|
||||||
rpl_instance_t instance_table[RPL_MAX_INSTANCES];
|
rpl_instance_t instance_table[RPL_MAX_INSTANCES];
|
||||||
rpl_instance_t *default_instance;
|
rpl_instance_t *default_instance;
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
nbr_callback(void *ptr)
|
||||||
|
{
|
||||||
|
rpl_remove_parent(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rpl_dag_init(void)
|
rpl_dag_init(void)
|
||||||
{
|
{
|
||||||
nbr_table_register(rpl_parents, (nbr_table_callback *)rpl_remove_parent);
|
nbr_table_register(rpl_parents, (nbr_table_callback *)nbr_callback);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
rpl_rank_t
|
rpl_rank_t
|
||||||
|
@ -178,7 +184,7 @@ nullify_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank)
|
||||||
{
|
{
|
||||||
rpl_parent_t *p;
|
rpl_parent_t *p;
|
||||||
|
|
||||||
PRINTF("RPL: Removing parents (minimum rank %u)\n",
|
PRINTF("RPL: Nullifying parents (minimum rank %u)\n",
|
||||||
minimum_rank);
|
minimum_rank);
|
||||||
|
|
||||||
p = nbr_table_head(rpl_parents);
|
p = nbr_table_head(rpl_parents);
|
||||||
|
@ -541,17 +547,23 @@ rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr)
|
||||||
* Typically, the parent is added upon receiving a DIO. */
|
* Typically, the parent is added upon receiving a DIO. */
|
||||||
const uip_lladdr_t *lladdr = uip_ds6_nbr_lladdr_from_ipaddr(addr);
|
const uip_lladdr_t *lladdr = uip_ds6_nbr_lladdr_from_ipaddr(addr);
|
||||||
|
|
||||||
PRINTF("RPL: rpl_add_parent lladdr %p\n", lladdr);
|
PRINTF("RPL: rpl_add_parent lladdr %p ", lladdr);
|
||||||
|
PRINT6ADDR(addr);
|
||||||
|
PRINTF("\n");
|
||||||
if(lladdr != NULL) {
|
if(lladdr != NULL) {
|
||||||
/* Add parent in rpl_parents */
|
/* Add parent in rpl_parents */
|
||||||
p = nbr_table_add_lladdr(rpl_parents, (rimeaddr_t *)lladdr);
|
p = nbr_table_add_lladdr(rpl_parents, (rimeaddr_t *)lladdr);
|
||||||
p->dag = dag;
|
if(p == NULL) {
|
||||||
p->rank = dio->rank;
|
PRINTF("RPL: rpl_add_parent p NULL\n");
|
||||||
p->dtsn = dio->dtsn;
|
} else {
|
||||||
p->link_metric = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR;
|
p->dag = dag;
|
||||||
|
p->rank = dio->rank;
|
||||||
|
p->dtsn = dio->dtsn;
|
||||||
|
p->link_metric = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR;
|
||||||
#if RPL_DAG_MC != RPL_DAG_MC_NONE
|
#if RPL_DAG_MC != RPL_DAG_MC_NONE
|
||||||
memcpy(&p->mc, &dio->mc, sizeof(p->mc));
|
memcpy(&p->mc, &dio->mc, sizeof(p->mc));
|
||||||
#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */
|
#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
|
@ -689,8 +701,8 @@ rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p)
|
||||||
return best_dag;
|
return best_dag;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
rpl_parent_t *
|
static rpl_parent_t *
|
||||||
rpl_select_parent(rpl_dag_t *dag)
|
best_parent(rpl_dag_t *dag)
|
||||||
{
|
{
|
||||||
rpl_parent_t *p, *best;
|
rpl_parent_t *p, *best;
|
||||||
|
|
||||||
|
@ -708,6 +720,14 @@ rpl_select_parent(rpl_dag_t *dag)
|
||||||
p = nbr_table_next(rpl_parents, p);
|
p = nbr_table_next(rpl_parents, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return best;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
rpl_parent_t *
|
||||||
|
rpl_select_parent(rpl_dag_t *dag)
|
||||||
|
{
|
||||||
|
rpl_parent_t *best = best_parent(dag);
|
||||||
|
|
||||||
if(best != NULL) {
|
if(best != NULL) {
|
||||||
rpl_set_preferred_parent(dag, best);
|
rpl_set_preferred_parent(dag, best);
|
||||||
}
|
}
|
||||||
|
@ -776,9 +796,7 @@ rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent)
|
||||||
PRINT6ADDR(rpl_get_parent_ipaddr(parent));
|
PRINT6ADDR(rpl_get_parent_ipaddr(parent));
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
|
|
||||||
list_remove(dag_src->parents, parent);
|
|
||||||
parent->dag = dag_dst;
|
parent->dag = dag_dst;
|
||||||
list_add(dag_dst->parents, parent);
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
rpl_dag_t *
|
rpl_dag_t *
|
||||||
|
@ -1192,7 +1210,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||||
} else if(dio->rank == INFINITE_RANK && dag->joined) {
|
} else if(dio->rank == INFINITE_RANK && dag->joined) {
|
||||||
rpl_reset_dio_timer(instance);
|
rpl_reset_dio_timer(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prefix Information Option treated to add new prefix */
|
/* Prefix Information Option treated to add new prefix */
|
||||||
if(dio->prefix_info.length != 0) {
|
if(dio->prefix_info.length != 0) {
|
||||||
if(dio->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS) {
|
if(dio->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS) {
|
||||||
|
@ -1277,4 +1295,10 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||||
p->dtsn = dio->dtsn;
|
p->dtsn = dio->dtsn;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
rpl_lock_parent(rpl_parent_t *p)
|
||||||
|
{
|
||||||
|
nbr_table_lock(rpl_parents, p);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
#endif /* UIP_CONF_IPV6 */
|
#endif /* UIP_CONF_IPV6 */
|
||||||
|
|
|
@ -69,6 +69,7 @@ rpl_verify_header(int uip_ext_opt_offset)
|
||||||
rpl_instance_t *instance;
|
rpl_instance_t *instance;
|
||||||
int down;
|
int down;
|
||||||
uint8_t sender_closer;
|
uint8_t sender_closer;
|
||||||
|
uip_ds6_route_t *route;
|
||||||
|
|
||||||
if(UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
|
if(UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
|
||||||
PRINTF("RPL: Bad header option! (wrong length)\n");
|
PRINTF("RPL: Bad header option! (wrong length)\n");
|
||||||
|
@ -83,11 +84,11 @@ rpl_verify_header(int uip_ext_opt_offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_FWD_ERR) {
|
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_FWD_ERR) {
|
||||||
|
PRINTF("RPL: Forward error!\n");
|
||||||
/* We should try to repair it by removing the neighbor that caused
|
/* We should try to repair it by removing the neighbor that caused
|
||||||
the packet to be forwareded in the first place. We drop any
|
the packet to be forwareded in the first place. We drop any
|
||||||
routes that go through the neighbor that sent the packet to
|
routes that go through the neighbor that sent the packet to
|
||||||
us. */
|
us. */
|
||||||
uip_ds6_route_t *route;
|
|
||||||
route = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr);
|
route = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr);
|
||||||
if(route != NULL) {
|
if(route != NULL) {
|
||||||
uip_ds6_route_rm(route);
|
uip_ds6_route_rm(route);
|
||||||
|
|
|
@ -146,7 +146,8 @@ dis_input(void)
|
||||||
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
|
|
||||||
for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) {
|
for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES;
|
||||||
|
instance < end; ++instance) {
|
||||||
if(instance->used == 1) {
|
if(instance->used == 1) {
|
||||||
#if RPL_LEAF_ONLY
|
#if RPL_LEAF_ONLY
|
||||||
if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
|
if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
|
||||||
|
@ -578,6 +579,7 @@ dao_input(void)
|
||||||
int i;
|
int i;
|
||||||
int learned_from;
|
int learned_from;
|
||||||
rpl_parent_t *p;
|
rpl_parent_t *p;
|
||||||
|
uip_ds6_nbr_t *nbr;
|
||||||
|
|
||||||
prefixlen = 0;
|
prefixlen = 0;
|
||||||
|
|
||||||
|
@ -667,6 +669,20 @@ dao_input(void)
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
rep->state.nopath_received = 1;
|
rep->state.nopath_received = 1;
|
||||||
rep->state.lifetime = DAO_EXPIRATION_TIMEOUT;
|
rep->state.lifetime = DAO_EXPIRATION_TIMEOUT;
|
||||||
|
|
||||||
|
/* We forward the incoming no-path DAO to our parent, if we have
|
||||||
|
one. */
|
||||||
|
if(dag->preferred_parent != NULL &&
|
||||||
|
rpl_get_parent_ipaddr(dag->preferred_parent) != NULL) {
|
||||||
|
PRINTF("RPL: Forwarding no-path DAO to parent ");
|
||||||
|
PRINT6ADDR(rpl_get_parent_ipaddr(dag->preferred_parent));
|
||||||
|
PRINTF("\n");
|
||||||
|
uip_icmp6_send(rpl_get_parent_ipaddr(dag->preferred_parent),
|
||||||
|
ICMP6_RPL, RPL_CODE_DAO, buffer_length);
|
||||||
|
}
|
||||||
|
if(flags & RPL_DAO_K_FLAG) {
|
||||||
|
dao_ack_output(instance, &dao_sender_addr, sequence);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -700,6 +716,32 @@ dao_input(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
PRINTF("RPL: adding DAO route\n");
|
PRINTF("RPL: adding DAO route\n");
|
||||||
|
|
||||||
|
if((nbr = uip_ds6_nbr_lookup(&dao_sender_addr)) == NULL) {
|
||||||
|
if((nbr = uip_ds6_nbr_add(&dao_sender_addr,
|
||||||
|
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER),
|
||||||
|
0, NBR_REACHABLE)) != NULL) {
|
||||||
|
/* set reachable timer */
|
||||||
|
stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
|
||||||
|
PRINTF("RPL: Neighbor added to neighbor cache ");
|
||||||
|
PRINT6ADDR(&dao_sender_addr);
|
||||||
|
PRINTF(", ");
|
||||||
|
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||||
|
PRINTF("\n");
|
||||||
|
} else {
|
||||||
|
PRINTF("RPL: Out of Memory, dropping DAO from ");
|
||||||
|
PRINT6ADDR(&dao_sender_addr);
|
||||||
|
PRINTF(", ");
|
||||||
|
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||||
|
PRINTF("\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PRINTF("RPL: Neighbor already in neighbor cache\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl_lock_parent(p);
|
||||||
|
|
||||||
rep = rpl_add_route(dag, &prefix, prefixlen, &dao_sender_addr);
|
rep = rpl_add_route(dag, &prefix, prefixlen, &dao_sender_addr);
|
||||||
if(rep == NULL) {
|
if(rep == NULL) {
|
||||||
RPL_STAT(rpl_stats.mem_overflows++);
|
RPL_STAT(rpl_stats.mem_overflows++);
|
||||||
|
@ -751,6 +793,11 @@ dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime)
|
||||||
|
|
||||||
/* Destination Advertisement Object */
|
/* Destination Advertisement Object */
|
||||||
|
|
||||||
|
/* If we are in feather mode, we should not send any DAOs */
|
||||||
|
if(rpl_get_mode() == RPL_MODE_FEATHER) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(parent == NULL) {
|
if(parent == NULL) {
|
||||||
PRINTF("RPL dao_output_target error parent NULL\n");
|
PRINTF("RPL dao_output_target error parent NULL\n");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -304,11 +304,17 @@ uip_ds6_route_t *rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix,
|
||||||
int prefix_len, uip_ipaddr_t *next_hop);
|
int prefix_len, uip_ipaddr_t *next_hop);
|
||||||
void rpl_purge_routes(void);
|
void rpl_purge_routes(void);
|
||||||
|
|
||||||
|
/* Lock a parent in the neighbor cache. */
|
||||||
|
void rpl_lock_parent(rpl_parent_t *p);
|
||||||
|
|
||||||
/* Objective function. */
|
/* Objective function. */
|
||||||
rpl_of_t *rpl_find_of(rpl_ocp_t);
|
rpl_of_t *rpl_find_of(rpl_ocp_t);
|
||||||
|
|
||||||
/* Timer functions. */
|
/* Timer functions. */
|
||||||
void rpl_schedule_dao(rpl_instance_t *);
|
void rpl_schedule_dao(rpl_instance_t *);
|
||||||
|
void rpl_schedule_dao_immediately(rpl_instance_t *);
|
||||||
|
void rpl_cancel_dao(rpl_instance_t *instance);
|
||||||
|
|
||||||
void rpl_reset_dio_timer(rpl_instance_t *);
|
void rpl_reset_dio_timer(rpl_instance_t *);
|
||||||
void rpl_reset_periodic_timer(void);
|
void rpl_reset_periodic_timer(void);
|
||||||
|
|
||||||
|
|
|
@ -194,6 +194,28 @@ rpl_reset_dio_timer(rpl_instance_t *instance)
|
||||||
#endif /* RPL_LEAF_ONLY */
|
#endif /* RPL_LEAF_ONLY */
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void handle_dao_timer(void *ptr);
|
||||||
|
static void
|
||||||
|
set_dao_lifetime_timer(rpl_instance_t *instance)
|
||||||
|
{
|
||||||
|
if(rpl_get_mode() == RPL_MODE_FEATHER) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set up another DAO within half the expiration time, if such a
|
||||||
|
time has been configured */
|
||||||
|
if(instance->lifetime_unit != 0xffff && instance->default_lifetime != 0xff) {
|
||||||
|
clock_time_t expiration_time;
|
||||||
|
expiration_time = (clock_time_t)instance->default_lifetime *
|
||||||
|
(clock_time_t)instance->lifetime_unit *
|
||||||
|
CLOCK_SECOND / 2;
|
||||||
|
PRINTF("RPL: Scheduling DAO lifetime timer %u ticks in the future\n",
|
||||||
|
(unsigned)expiration_time);
|
||||||
|
ctimer_set(&instance->dao_lifetime_timer, expiration_time,
|
||||||
|
handle_dao_timer, instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
handle_dao_timer(void *ptr)
|
handle_dao_timer(void *ptr)
|
||||||
{
|
{
|
||||||
|
@ -215,26 +237,60 @@ handle_dao_timer(void *ptr)
|
||||||
} else {
|
} else {
|
||||||
PRINTF("RPL: No suitable DAO parent\n");
|
PRINTF("RPL: No suitable DAO parent\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
ctimer_stop(&instance->dao_timer);
|
ctimer_stop(&instance->dao_timer);
|
||||||
|
|
||||||
|
if(etimer_expired(&instance->dao_lifetime_timer.etimer)) {
|
||||||
|
set_dao_lifetime_timer(instance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
static void
|
||||||
rpl_schedule_dao(rpl_instance_t *instance)
|
schedule_dao(rpl_instance_t *instance, clock_time_t latency)
|
||||||
{
|
{
|
||||||
clock_time_t expiration_time;
|
clock_time_t expiration_time;
|
||||||
|
|
||||||
|
if(rpl_get_mode() == RPL_MODE_FEATHER) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
expiration_time = etimer_expiration_time(&instance->dao_timer.etimer);
|
expiration_time = etimer_expiration_time(&instance->dao_timer.etimer);
|
||||||
|
|
||||||
if(!etimer_expired(&instance->dao_timer.etimer)) {
|
if(!etimer_expired(&instance->dao_timer.etimer)) {
|
||||||
PRINTF("RPL: DAO timer already scheduled\n");
|
PRINTF("RPL: DAO timer already scheduled\n");
|
||||||
} else {
|
} else {
|
||||||
expiration_time = RPL_DAO_LATENCY / 2 +
|
if(latency != 0) {
|
||||||
(random_rand() % (RPL_DAO_LATENCY));
|
expiration_time = latency / 2 +
|
||||||
|
(random_rand() % (latency));
|
||||||
|
} else {
|
||||||
|
expiration_time = 0;
|
||||||
|
}
|
||||||
PRINTF("RPL: Scheduling DAO timer %u ticks in the future\n",
|
PRINTF("RPL: Scheduling DAO timer %u ticks in the future\n",
|
||||||
(unsigned)expiration_time);
|
(unsigned)expiration_time);
|
||||||
ctimer_set(&instance->dao_timer, expiration_time,
|
ctimer_set(&instance->dao_timer, expiration_time,
|
||||||
handle_dao_timer, instance);
|
handle_dao_timer, instance);
|
||||||
|
|
||||||
|
set_dao_lifetime_timer(instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
rpl_schedule_dao(rpl_instance_t *instance)
|
||||||
|
{
|
||||||
|
schedule_dao(instance, RPL_DAO_LATENCY);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
rpl_schedule_dao_immediately(rpl_instance_t *instance)
|
||||||
|
{
|
||||||
|
schedule_dao(instance, 0);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
rpl_cancel_dao(rpl_instance_t *instance)
|
||||||
|
{
|
||||||
|
ctimer_stop(&instance->dao_timer);
|
||||||
|
ctimer_stop(&instance->dao_lifetime_timer);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
#endif /* UIP_CONF_IPV6 */
|
#endif /* UIP_CONF_IPV6 */
|
||||||
|
|
|
@ -57,6 +57,47 @@
|
||||||
rpl_stats_t rpl_stats;
|
rpl_stats_t rpl_stats;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static enum rpl_mode mode = RPL_MODE_MESH;
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
enum rpl_mode
|
||||||
|
rpl_get_mode(void)
|
||||||
|
{
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
enum rpl_mode
|
||||||
|
rpl_set_mode(enum rpl_mode m)
|
||||||
|
{
|
||||||
|
enum rpl_mode oldmode = mode;
|
||||||
|
|
||||||
|
/* We need to do different things depending on what mode we are
|
||||||
|
switching to. */
|
||||||
|
if(m == RPL_MODE_MESH) {
|
||||||
|
|
||||||
|
/* If we switcht to mesh mode, we should send out a DAO message to
|
||||||
|
inform our parent that we now are reachable. Before we do this,
|
||||||
|
we must set the mode variable, since DAOs will not be send if
|
||||||
|
we are in feather mode. */
|
||||||
|
PRINTF("RPL: switching to mesh mode\n");
|
||||||
|
mode = m;
|
||||||
|
|
||||||
|
if(default_instance != NULL) {
|
||||||
|
rpl_schedule_dao_immediately(default_instance);
|
||||||
|
}
|
||||||
|
} else if(m == RPL_MODE_FEATHER) {
|
||||||
|
|
||||||
|
PRINTF("RPL: switching to feather mode\n");
|
||||||
|
mode = m;
|
||||||
|
if(default_instance != NULL) {
|
||||||
|
rpl_cancel_dao(default_instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
mode = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
return oldmode;
|
||||||
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rpl_purge_routes(void)
|
rpl_purge_routes(void)
|
||||||
|
|
|
@ -45,9 +45,6 @@
|
||||||
#include "net/uip-ds6.h"
|
#include "net/uip-ds6.h"
|
||||||
#include "sys/ctimer.h"
|
#include "sys/ctimer.h"
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
/* The amount of parents that this node has in a particular DAG. */
|
|
||||||
#define RPL_PARENT_COUNT(dag) list_length((dag)->parents)
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
typedef uint16_t rpl_rank_t;
|
typedef uint16_t rpl_rank_t;
|
||||||
typedef uint16_t rpl_ocp_t;
|
typedef uint16_t rpl_ocp_t;
|
||||||
|
@ -142,7 +139,6 @@ struct rpl_dag {
|
||||||
rpl_parent_t *preferred_parent;
|
rpl_parent_t *preferred_parent;
|
||||||
rpl_rank_t rank;
|
rpl_rank_t rank;
|
||||||
struct rpl_instance *instance;
|
struct rpl_instance *instance;
|
||||||
LIST_STRUCT(parents);
|
|
||||||
rpl_prefix_t prefix_info;
|
rpl_prefix_t prefix_info;
|
||||||
};
|
};
|
||||||
typedef struct rpl_dag rpl_dag_t;
|
typedef struct rpl_dag rpl_dag_t;
|
||||||
|
@ -225,6 +221,7 @@ struct rpl_instance {
|
||||||
clock_time_t dio_next_delay; /* delay for completion of dio interval */
|
clock_time_t dio_next_delay; /* delay for completion of dio interval */
|
||||||
struct ctimer dio_timer;
|
struct ctimer dio_timer;
|
||||||
struct ctimer dao_timer;
|
struct ctimer dao_timer;
|
||||||
|
struct ctimer dao_lifetime_timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -247,5 +244,38 @@ uip_ipaddr_t *rpl_get_parent_ipaddr(rpl_parent_t *nbr);
|
||||||
rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr);
|
rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr);
|
||||||
uint16_t rpl_get_parent_link_metric(const uip_lladdr_t *addr);
|
uint16_t rpl_get_parent_link_metric(const uip_lladdr_t *addr);
|
||||||
void rpl_dag_init(void);
|
void rpl_dag_init(void);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RPL modes
|
||||||
|
*
|
||||||
|
* The RPL module can be in either of three modes: mesh mode
|
||||||
|
* (RPL_MODE_MESH), feater mode (RPL_MODE_FEATHER), and leaf mode
|
||||||
|
* (RPL_MODE_LEAF). In mesh mode, nodes forward data for other nodes,
|
||||||
|
* and are reachable by others. In feather mode, nodes can forward
|
||||||
|
* data for other nodes, but are not reachable themselves. In leaf
|
||||||
|
* mode, nodes do not forward data for others, but are reachable by
|
||||||
|
* others. */
|
||||||
|
enum rpl_mode {
|
||||||
|
RPL_MODE_MESH = 0,
|
||||||
|
RPL_MODE_FEATHER = 1,
|
||||||
|
RPL_MODE_LEAF = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the RPL mode
|
||||||
|
*
|
||||||
|
* \param mode The new RPL mode
|
||||||
|
* \retval The previous RPL mode
|
||||||
|
*/
|
||||||
|
enum rpl_mode rpl_set_mode(enum rpl_mode mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the RPL mode
|
||||||
|
*
|
||||||
|
* \retval The RPL mode
|
||||||
|
*/
|
||||||
|
enum rpl_mode rpl_get_mode(void);
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#endif /* RPL_H */
|
#endif /* RPL_H */
|
||||||
|
|
|
@ -142,7 +142,7 @@ collect_common_send(void)
|
||||||
}
|
}
|
||||||
rtmetric = dag->rank;
|
rtmetric = dag->rank;
|
||||||
beacon_interval = (uint16_t) ((2L << dag->instance->dio_intcurrent) / 1000);
|
beacon_interval = (uint16_t) ((2L << dag->instance->dio_intcurrent) / 1000);
|
||||||
num_neighbors = RPL_PARENT_COUNT(dag);
|
num_neighbors = uip_ds6_nbr_num();
|
||||||
} else {
|
} else {
|
||||||
rtmetric = 0;
|
rtmetric = 0;
|
||||||
beacon_interval = 0;
|
beacon_interval = 0;
|
||||||
|
|
Loading…
Reference in a new issue