diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c old mode 100755 new mode 100644 index 2ec8cab0a..f8587dbf8 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -99,6 +99,21 @@ MEMB(parent_memb, struct rpl_parent, rpl_instance_t instance_table[RPL_MAX_INSTANCES]; rpl_instance_t *default_instance; +/************************************************************************/ +/* lollipop greater than function. */ +/************************************************************************/ +int rpl_lollipop_greater_than(int a, int b) { + /* Check if we are comparing an initial value with an old value */ + if(a > RPL_LOLLIPOP_CIRCULAR_REGION && b <= RPL_LOLLIPOP_CIRCULAR_REGION) { + return (RPL_LOLLIPOP_MAX_VALUE + 1 + b - a) > RPL_LOLLIPOP_SEQUENCE_WINDOWS; + } + /* Otherwise check if a > b and comparable => ok, or + if they have wrapped and are still comparable */ + return (a > b && (a - b) < RPL_LOLLIPOP_SEQUENCE_WINDOWS) || + (a < b && (b - a) > (RPL_LOLLIPOP_CIRCULAR_REGION + 1- + RPL_LOLLIPOP_SEQUENCE_WINDOWS)); +} + /************************************************************************/ /* Remove DAG parents with a rank that is at least the same as minimum_rank. */ static void @@ -161,10 +176,9 @@ should_send_dao(rpl_instance_t *instance, rpl_dio_t *dio, rpl_parent_t *p) if(instance->mop == RPL_MOP_NO_DOWNWARD_ROUTES) { return 0; } + /* check if the new DTSN is more recent */ return p == instance->current_dag->preferred_parent && - (RPL_LOLLIPOP_GREATER_THAN(dio->dtsn, p->dtsn) || - ((RPL_LOLLIPOP_GREATER_THAN(p->dtsn, dio->dtsn)) && - RPL_LOLLIPOP_IS_INIT(dio->dtsn))); + (rpl_lollipop_greater_than(dio->dtsn, p->dtsn)); } /************************************************************************/ static int @@ -1127,18 +1141,18 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) return; } - if(RPL_LOLLIPOP_GREATER_THAN(dio->version, dag->version)) { + if(rpl_lollipop_greater_than(dio->version, dag->version)) { if(dag->rank == ROOT_RANK(instance)) { PRINTF("RPL: Root received inconsistent DIO version number\n"); - dag->version = dio->version; - RPL_LOLLIPOP_INCREMENT(dag->version); - rpl_reset_dio_timer(instance); + dag->version = dio->version; + RPL_LOLLIPOP_INCREMENT(dag->version); + rpl_reset_dio_timer(instance); } else { global_repair(from, dag, dio); } return; } else { - if(RPL_LOLLIPOP_GREATER_THAN(dag->version, dio->version)) { + if(rpl_lollipop_greater_than(dag->version, dio->version)) { /* The DIO sender is on an older version of the DAG. */ PRINTF("RPL: old version received => inconsistency detected\n"); if(dag->joined) { diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h index 66660e29f..e039cf98d 100644 --- a/core/net/rpl/rpl.h +++ b/core/net/rpl/rpl.h @@ -131,19 +131,12 @@ typedef uint16_t rpl_ocp_t; #define RPL_LOLLIPOP_CIRCULAR_REGION 127 #define RPL_LOLLIPOP_SEQUENCE_WINDOWS 16 #define RPL_LOLLIPOP_INIT RPL_LOLLIPOP_MAX_VALUE - RPL_LOLLIPOP_SEQUENCE_WINDOWS + 1 -#define RPL_LOLLIPOP_INCREMENT(counter) (counter > RPL_LOLLIPOP_CIRCULAR_REGION ?\ - (counter == RPL_LOLLIPOP_MAX_VALUE ? counter=0 : ++counter):\ - (counter == RPL_LOLLIPOP_CIRCULAR_REGION ? counter=0 : ++counter)) +#define RPL_LOLLIPOP_INCREMENT(ctr) (ctr > RPL_LOLLIPOP_CIRCULAR_REGION ? \ + ++ctr & RPL_LOLLIPOP_MAX_VALUE : \ + ++ctr & RPL_LOLLIPOP_CIRCULAR_REGION) + #define RPL_LOLLIPOP_IS_INIT(counter) (counter > RPL_LOLLIPOP_CIRCULAR_REGION) -#define RPL_LOLLIPOP_GREATER_THAN_LOCAL(A,B) (((A < B) && (RPL_LOLLIPOP_CIRCULAR_REGION + 1 - B + A < RPL_LOLLIPOP_SEQUENCE_WINDOWS)) || \ - ((A > B) && (A - B < RPL_LOLLIPOP_SEQUENCE_WINDOWS))) -#define RPL_LOLLIPOP_GREATER_THAN(A,B) ((A > RPL_LOLLIPOP_CIRCULAR_REGION )?\ - ((B > RPL_LOLLIPOP_CIRCULAR_REGION )?\ - RPL_LOLLIPOP_GREATER_THAN_LOCAL(A,B):\ - 0):\ - ((B > RPL_LOLLIPOP_CIRCULAR_REGION )?\ - 1:\ - RPL_LOLLIPOP_GREATER_THAN_LOCAL(A,B))) + /*---------------------------------------------------------------------------*/ /* DAG Metric Container Object Types, to be confirmed by IANA. */ #define RPL_DAG_MC_NONE 0 /* Local identifier for empty MC */