Removed the force flag from rpl_reset_dio_timer. Removed an unnecessary DIO timer reset when changing rank but keeping the same preferred parent.

This commit is contained in:
Nicolas Tsiftes 2012-01-04 11:22:11 +01:00
parent 3f31fb9514
commit f112fa99d5
4 changed files with 66 additions and 63 deletions

View file

@ -91,7 +91,8 @@ static rpl_of_t * const objective_functions[] = {&RPL_OF};
/************************************************************************/ /************************************************************************/
/* Allocate parents from the same static MEMB chunk to reduce memory waste. */ /* Allocate parents from the same static MEMB chunk to reduce memory waste. */
MEMB(parent_memb, struct rpl_parent, RPL_MAX_PARENTS_PER_DODAG*RPL_MAX_INSTANCES*RPL_MAX_DODAG_PER_INSTANCE); MEMB(parent_memb, struct rpl_parent,
RPL_MAX_PARENTS_PER_DODAG * RPL_MAX_INSTANCES * RPL_MAX_DODAG_PER_INSTANCE);
/************************************************************************/ /************************************************************************/
/* Allocate instance table. */ /* Allocate instance table. */
@ -147,8 +148,7 @@ remove_worst_parent(rpl_dag_t *dag, rpl_rank_t min_worst_rank)
worst = p; worst = p;
} }
} }
/* Remove the neighbor if its rank is worse than the minimum worst /* Remove the neighbor if its rank is worse than the minimum worst rank. */
rank. */
if(worst != NULL && worst->rank > min_worst_rank) { if(worst != NULL && worst->rank > min_worst_rank) {
rpl_remove_parent(dag, worst); rpl_remove_parent(dag, worst);
} }
@ -213,6 +213,10 @@ rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id)
instance->dio_intdoubl = DEFAULT_DIO_INTERVAL_DOUBLINGS; instance->dio_intdoubl = DEFAULT_DIO_INTERVAL_DOUBLINGS;
instance->dio_intmin = DEFAULT_DIO_INTERVAL_MIN; instance->dio_intmin = DEFAULT_DIO_INTERVAL_MIN;
/* The current interval must differ from the minimum interval in order to
trigger a DIO timer reset. */
instance->dio_intcurrent = DEFAULT_DIO_INTERVAL_MIN +
DEFAULT_DIO_INTERVAL_DOUBLINGS;
instance->dio_redundancy = DEFAULT_DIO_REDUNDANCY; instance->dio_redundancy = DEFAULT_DIO_REDUNDANCY;
instance->max_rankinc = DEFAULT_MAX_RANKINC; instance->max_rankinc = DEFAULT_MAX_RANKINC;
instance->min_hoprankinc = DEFAULT_MIN_HOPRANKINC; instance->min_hoprankinc = DEFAULT_MIN_HOPRANKINC;
@ -239,7 +243,7 @@ rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id)
ANNOTATE("#A root=%u\n", dag->dag_id.u8[sizeof(dag->dag_id) - 1]); ANNOTATE("#A root=%u\n", dag->dag_id.u8[sizeof(dag->dag_id) - 1]);
rpl_reset_dio_timer(instance, 1); rpl_reset_dio_timer(instance);
return dag; return dag;
} }
@ -247,20 +251,18 @@ rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id)
int int
rpl_repair_root(uint8_t instance_id) rpl_repair_root(uint8_t instance_id)
{ {
rpl_instance_t * instance; rpl_instance_t *instance;
instance = rpl_get_instance(instance_id); instance = rpl_get_instance(instance_id);
if(instance == NULL) { if(instance == NULL ||
instance->current_dag->rank != ROOT_RANK(instance)) {
return 0; return 0;
} }
if(instance->current_dag->rank == ROOT_RANK(instance)) { RPL_LOLLIPOP_INCREMENT(instance->current_dag->version);
RPL_LOLLIPOP_INCREMENT(instance->current_dag->version); RPL_LOLLIPOP_INCREMENT(instance->dtsn_out);
RPL_LOLLIPOP_INCREMENT(instance->dtsn_out); rpl_reset_dio_timer(instance);
rpl_reset_dio_timer(instance, 1); return 1;
return 1;
}
return 0;
} }
/************************************************************************/ /************************************************************************/
static void static void
@ -497,8 +499,8 @@ rpl_find_parent(rpl_dag_t *dag, uip_ipaddr_t *addr)
} }
/************************************************************************/ /************************************************************************/
rpl_dag_t * static rpl_dag_t *
rpl_find_parent_dag(rpl_instance_t *instance, uip_ipaddr_t *addr) find_parent_dag(rpl_instance_t *instance, uip_ipaddr_t *addr)
{ {
rpl_parent_t *p; rpl_parent_t *p;
rpl_dag_t *dag, *end; rpl_dag_t *dag, *end;
@ -616,12 +618,10 @@ rpl_select_dodag(rpl_instance_t *instance, rpl_parent_t *p)
RPL_LOLLIPOP_INCREMENT(instance->dtsn_out); RPL_LOLLIPOP_INCREMENT(instance->dtsn_out);
rpl_schedule_dao(instance); rpl_schedule_dao(instance);
} }
rpl_reset_dio_timer(instance, 1); rpl_reset_dio_timer(instance);
} else if(best_dag->rank != old_rank) { } else if(best_dag->rank != old_rank) {
PRINTF("RPL: Preferred parent update, rank changed from %u to %u\n", PRINTF("RPL: Preferred parent update, rank changed from %u to %u\n",
(unsigned)old_rank, best_dag->rank); (unsigned)old_rank, best_dag->rank);
RPL_STAT(rpl_stats.parent_switch++);
rpl_reset_dio_timer(instance, 1);
} }
return best_dag; return best_dag;
} }
@ -839,6 +839,7 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
instance->min_hoprankinc = dio->dag_min_hoprankinc; instance->min_hoprankinc = dio->dag_min_hoprankinc;
instance->dio_intdoubl = dio->dag_intdoubl; instance->dio_intdoubl = dio->dag_intdoubl;
instance->dio_intmin = dio->dag_intmin; instance->dio_intmin = dio->dag_intmin;
instance->dio_intcurrent = instance->dio_intmin + instance->dio_intdoubl;
instance->dio_redundancy = dio->dag_redund; instance->dio_redundancy = dio->dag_redund;
instance->default_lifetime = dio->default_lifetime; instance->default_lifetime = dio->default_lifetime;
instance->lifetime_unit = dio->lifetime_unit; instance->lifetime_unit = dio->lifetime_unit;
@ -864,7 +865,7 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
ANNOTATE("#A join=%u\n", dag->dag_id.u8[sizeof(dag->dag_id) - 1]); ANNOTATE("#A join=%u\n", dag->dag_id.u8[sizeof(dag->dag_id) - 1]);
rpl_reset_dio_timer(instance, 1); rpl_reset_dio_timer(instance);
rpl_set_default_route(instance, from); rpl_set_default_route(instance, from);
if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES) { if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES) {
@ -891,7 +892,7 @@ rpl_add_dodag(uip_ipaddr_t *from, rpl_dio_t *dio)
instance = dag->instance; instance = dag->instance;
previous_dag = rpl_find_parent_dag(instance, from); previous_dag = find_parent_dag(instance, from);
if(previous_dag == NULL) { if(previous_dag == NULL) {
PRINTF("RPL: Adding "); PRINTF("RPL: Adding ");
PRINT6ADDR(from); PRINT6ADDR(from);
@ -995,7 +996,7 @@ rpl_local_repair(rpl_instance_t *instance)
} }
} }
rpl_reset_dio_timer(instance, 0); rpl_reset_dio_timer(instance);
RPL_STAT(rpl_stats.local_repairs++); RPL_STAT(rpl_stats.local_repairs++);
} }
@ -1131,7 +1132,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
PRINTF("RPL: Root received inconsistent DIO version number\n"); PRINTF("RPL: Root received inconsistent DIO version number\n");
dag->version = dio->version; dag->version = dio->version;
RPL_LOLLIPOP_INCREMENT(dag->version); RPL_LOLLIPOP_INCREMENT(dag->version);
rpl_reset_dio_timer(instance, 0); rpl_reset_dio_timer(instance);
} else { } else {
global_repair(from, dag, dio); global_repair(from, dag, dio);
} }
@ -1141,7 +1142,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
/* The DIO sender is on an older version of the DAG. */ /* The DIO sender is on an older version of the DAG. */
PRINTF("RPL: old version received => inconsistency detected\n"); PRINTF("RPL: old version received => inconsistency detected\n");
if(dag->joined) { if(dag->joined) {
rpl_reset_dio_timer(instance, 0); rpl_reset_dio_timer(instance);
return; return;
} }
} }
@ -1149,7 +1150,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
if(dio->rank == INFINITE_RANK) { if(dio->rank == INFINITE_RANK) {
if(dag->joined) { if(dag->joined) {
rpl_reset_dio_timer(instance, 0); rpl_reset_dio_timer(instance);
} }
} else if(dio->rank < ROOT_RANK(instance)) { } else if(dio->rank < ROOT_RANK(instance)) {
PRINTF("RPL: Ignoring DIO with too low rank: %u\n", PRINTF("RPL: Ignoring DIO with too low rank: %u\n",
@ -1173,7 +1174,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
p = rpl_find_parent(dag, from); p = rpl_find_parent(dag, from);
if(p == NULL) { if(p == NULL) {
previous_dag = rpl_find_parent_dag(instance, from); previous_dag = find_parent_dag(instance, from);
if(previous_dag == NULL) { if(previous_dag == NULL) {
if(RPL_PARENT_COUNT(dag) == RPL_MAX_PARENTS_PER_DODAG) { if(RPL_PARENT_COUNT(dag) == RPL_MAX_PARENTS_PER_DODAG) {
/* Make room for a new parent. */ /* Make room for a new parent. */
@ -1205,11 +1206,11 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
} }
} }
PRINTF("RPL current state: Prefered DODAG: "); PRINTF("RPL: preferred DODAG ");
PRINT6ADDR(&instance->current_dag->dag_id); PRINT6ADDR(&instance->current_dag->dag_id);
PRINTF(", rank: %u, min_rank: %u, ", PRINTF(", rank %u, min_rank %u, ",
instance->current_dag->rank, instance->current_dag->min_rank); instance->current_dag->rank, instance->current_dag->min_rank);
PRINTF("parent rank: %u, parent etx: %u, link metric: %u, instance etx %u\n", PRINTF("parent rank %u, parent etx %u, link metric %u, instance etx %u\n",
p->rank, p->mc.obj.etx, p->link_metric, instance->mc.obj.etx); p->rank, p->mc.obj.etx, p->link_metric, instance->mc.obj.etx);
/* We have allocated a candidate parent; process the DIO further. */ /* We have allocated a candidate parent; process the DIO further. */

View file

@ -159,7 +159,7 @@ dis_input(void)
#else /* !RPL_LEAF_ONLY */ #else /* !RPL_LEAF_ONLY */
if(uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) { if(uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
PRINTF("RPL: Multicast DIS => reset DIO timer\n"); PRINTF("RPL: Multicast DIS => reset DIO timer\n");
rpl_reset_dio_timer(instance, 0); rpl_reset_dio_timer(instance);
} else { } else {
#endif /* !RPL_LEAF_ONLY */ #endif /* !RPL_LEAF_ONLY */
PRINTF("RPL: Unicast DIS, reply to sender\n"); PRINTF("RPL: Unicast DIS, reply to sender\n");

View file

@ -53,21 +53,24 @@
#include "net/uip-ds6.h" #include "net/uip-ds6.h"
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/** \brief Is IPv6 address a the link local all rpl nodes multicast address */ /** \brief Is IPv6 address addr the link-local, all-RPL-nodes
#define uip_is_addr_linklocal_rplnodes_mcast(a) \ multicast address? */
((((a)->u8[0]) == 0xff) && \ #define uip_is_addr_linklocal_rplnodes_mcast(a) \
(((a)->u8[1]) == 0x02) && \ ((addr)->u8[0] == 0xff) && \
(((a)->u16[1]) == 0) && \ ((addr)->u8[1] == 0x02) && \
(((a)->u16[2]) == 0) && \ ((addr)->u16[1] == 0) && \
(((a)->u16[3]) == 0) && \ ((addr)->u16[2] == 0) && \
(((a)->u16[4]) == 0) && \ ((addr)->u16[3] == 0) && \
(((a)->u16[5]) == 0) && \ ((addr)->u16[4] == 0) && \
(((a)->u16[6]) == 0) && \ ((addr)->u16[5] == 0) && \
(((a)->u8[14]) == 0) && \ ((addr)->u16[6] == 0) && \
(((a)->u8[15]) == 0x1a)) ((addr)->u8[14] == 0) && \
((addr)->u8[15] == 0x1a))
/** \brief set IP address a to the link local all-rpl nodes multicast address */ /** \brief Set IP address addr to the link-local, all-rpl-nodes
#define uip_create_linklocal_rplnodes_mcast(a) uip_ip6addr(a, 0xff02, 0, 0, 0, 0, 0, 0, 0x001a) multicast address. */
#define uip_create_linklocal_rplnodes_mcast(addr) \
uip_ip6addr((addr), 0xff02, 0, 0, 0, 0, 0, 0, 0x001a)
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* RPL message types */ /* RPL message types */
#define RPL_CODE_DIS 0x00 /* DAG Information Solicitation */ #define RPL_CODE_DIS 0x00 /* DAG Information Solicitation */
@ -80,16 +83,16 @@
#define RPL_CODE_SEC_DAO_ACK 0x83 /* Secure DAO ACK */ #define RPL_CODE_SEC_DAO_ACK 0x83 /* Secure DAO ACK */
/* RPL control message options. */ /* RPL control message options. */
#define RPL_OPTION_PAD1 0 #define RPL_OPTION_PAD1 0
#define RPL_OPTION_PADN 1 #define RPL_OPTION_PADN 1
#define RPL_OPTION_DAG_METRIC_CONTAINER 2 #define RPL_OPTION_DAG_METRIC_CONTAINER 2
#define RPL_OPTION_ROUTE_INFO 3 #define RPL_OPTION_ROUTE_INFO 3
#define RPL_OPTION_DAG_CONF 4 #define RPL_OPTION_DAG_CONF 4
#define RPL_OPTION_TARGET 5 #define RPL_OPTION_TARGET 5
#define RPL_OPTION_TRANSIT 6 #define RPL_OPTION_TRANSIT 6
#define RPL_OPTION_SOLICITED_INFO 7 #define RPL_OPTION_SOLICITED_INFO 7
#define RPL_OPTION_PREFIX_INFO 8 #define RPL_OPTION_PREFIX_INFO 8
#define RPL_OPTION_TARGET_DESC 9 #define RPL_OPTION_TARGET_DESC 9
#define RPL_DAO_K_FLAG 0x80 /* DAO ACK requested */ #define RPL_DAO_K_FLAG 0x80 /* DAO ACK requested */
#define RPL_DAO_D_FLAG 0x40 /* DODAG ID present */ #define RPL_DAO_D_FLAG 0x40 /* DODAG ID present */
@ -116,15 +119,15 @@
#define RPL_DEFAULT_LIFETIME_UNIT 0xffff #define RPL_DEFAULT_LIFETIME_UNIT 0xffff
/* Default route lifetime as a multiple of the lifetime unit. */ /* Default route lifetime as a multiple of the lifetime unit. */
#define RPL_DEFAULT_LIFETIME 0xff #define RPL_DEFAULT_LIFETIME 0xff
#define RPL_LIFETIME(instance, lifetime) \ #define RPL_LIFETIME(instance, lifetime) \
(((unsigned long)(instance)->lifetime_unit) * lifetime) ((unsigned long)(instance)->lifetime_unit * (lifetime))
#ifndef RPL_CONF_MIN_HOPRANKINC #ifndef RPL_CONF_MIN_HOPRANKINC
#define DEFAULT_MIN_HOPRANKINC 256 #define DEFAULT_MIN_HOPRANKINC 256
#else #else
#define DEFAULT_MIN_HOPRANKINC RPL_CONF_MIN_HOPRANKINC #define DEFAULT_MIN_HOPRANKINC RPL_CONF_MIN_HOPRANKINC
#endif #endif
#define DEFAULT_MAX_RANKINC (3 * DEFAULT_MIN_HOPRANKINC) #define DEFAULT_MAX_RANKINC (3 * DEFAULT_MIN_HOPRANKINC)
@ -134,7 +137,7 @@
#define BASE_RANK 0 #define BASE_RANK 0
/* Rank of a root node. */ /* Rank of a root node. */
#define ROOT_RANK(instance) (instance)->min_hoprankinc #define ROOT_RANK(instance) (instance)->min_hoprankinc
#define INFINITE_RANK 0xffff #define INFINITE_RANK 0xffff
@ -277,8 +280,7 @@ void rpl_free_instance(rpl_instance_t *);
/* DAG parent management function. */ /* DAG parent management function. */
rpl_parent_t *rpl_add_parent(rpl_dag_t *, rpl_dio_t *dio, uip_ipaddr_t *); rpl_parent_t *rpl_add_parent(rpl_dag_t *, rpl_dio_t *dio, uip_ipaddr_t *);
rpl_parent_t *rpl_find_parent(rpl_dag_t *, uip_ipaddr_t *); rpl_parent_t *rpl_find_parent(rpl_dag_t *, uip_ipaddr_t *);
rpl_parent_t * rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr); rpl_parent_t *rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr);
rpl_dag_t * rpl_find_parent_dag(rpl_instance_t *instance, uip_ipaddr_t *addr);
void rpl_nullify_parent(rpl_dag_t *, rpl_parent_t *); void rpl_nullify_parent(rpl_dag_t *, rpl_parent_t *);
void rpl_remove_parent(rpl_dag_t *, rpl_parent_t *); void rpl_remove_parent(rpl_dag_t *, rpl_parent_t *);
void rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent); void rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent);
@ -298,7 +300,7 @@ 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_reset_dio_timer(rpl_instance_t *, uint8_t); void rpl_reset_dio_timer(rpl_instance_t *);
void rpl_reset_periodic_timer(void); void rpl_reset_periodic_timer(void);
/* Route poisoning. */ /* Route poisoning. */

View file

@ -153,7 +153,7 @@ handle_dio_timer(void *ptr)
instance->dio_counter, instance->dio_redundancy); instance->dio_counter, instance->dio_redundancy);
} }
instance->dio_send = 0; instance->dio_send = 0;
PRINTF("RPL: Scheduling DIO timer %"PRIu32" ticks in future (sent)\n", PRINTF("RPL: Scheduling DIO timer %lu ticks in future (sent)\n",
instance->dio_next_delay); instance->dio_next_delay);
ctimer_set(&instance->dio_timer, instance->dio_next_delay, handle_dio_timer, instance); ctimer_set(&instance->dio_timer, instance->dio_next_delay, handle_dio_timer, instance);
} else { } else {
@ -175,12 +175,12 @@ rpl_reset_periodic_timer(void)
/************************************************************************/ /************************************************************************/
/* Resets the DIO timer in the instance to its minimal interval. */ /* Resets the DIO timer in the instance to its minimal interval. */
void void
rpl_reset_dio_timer(rpl_instance_t *instance, uint8_t force) rpl_reset_dio_timer(rpl_instance_t *instance)
{ {
#if !RPL_LEAF_ONLY #if !RPL_LEAF_ONLY
/* Do not reset if we are already on the minimum interval, /* Do not reset if we are already on the minimum interval,
unless forced to do so. */ unless forced to do so. */
if(force || instance->dio_intcurrent > instance->dio_intmin) { if(instance->dio_intcurrent > instance->dio_intmin) {
instance->dio_counter = 0; instance->dio_counter = 0;
instance->dio_intcurrent = instance->dio_intmin; instance->dio_intcurrent = instance->dio_intmin;
new_dio_interval(instance); new_dio_interval(instance);