42 #include "contiki-conf.h"
43 #include "net/rpl/rpl-private.h"
45 #include "lib/random.h"
50 #define DEBUG DEBUG_NONE
54 static struct ctimer periodic_timer;
56 static void handle_periodic_timer(
void *ptr);
58 static void handle_dio_timer(
void *ptr);
60 static uint16_t next_dis;
63 static uint8_t dio_send_ok;
67 handle_periodic_timer(
void *ptr)
70 rpl_recalculate_ranks();
75 if(rpl_get_any_dag() ==
NULL && next_dis >= RPL_DIS_INTERVAL) {
90 time = 1UL << instance->dio_intcurrent;
94 instance->dio_next_delay = ticks;
97 ticks = ticks / 2 + (ticks / 2 * (uint32_t)
random_rand()) / RANDOM_RAND_MAX;
104 instance->dio_next_delay -= ticks;
105 instance->dio_send = 1;
109 instance->dio_totint++;
110 instance->dio_totrecv += instance->dio_counter;
111 ANNOTATE(
"#A rank=%u.%u(%u),stats=%d %d %d %d,color=%s\n",
112 DAG_RANK(instance->current_dag->rank, instance),
113 (10 * (instance->current_dag->rank % instance->min_hoprankinc)) / instance->min_hoprankinc,
114 instance->current_dag->version,
115 instance->dio_totint, instance->dio_totsend,
116 instance->dio_totrecv,instance->dio_intcurrent,
117 instance->current_dag->rank == ROOT_RANK(instance) ?
"BLUE" :
"ORANGE");
121 instance->dio_counter = 0;
124 PRINTF(
"RPL: Scheduling DIO timer %lu ticks in future (Interval)\n", ticks);
125 ctimer_set(&instance->dio_timer, ticks, &handle_dio_timer, instance);
129 handle_dio_timer(
void *ptr)
135 PRINTF(
"RPL: DIO Timer triggered\n");
137 if(uip_ds6_get_link_local(ADDR_PREFERRED) !=
NULL) {
140 PRINTF(
"RPL: Postponing DIO transmission since link local address is not ok\n");
146 if(instance->dio_send) {
148 if(instance->dio_counter < instance->dio_redundancy) {
150 instance->dio_totsend++;
152 dio_output(instance,
NULL);
154 PRINTF(
"RPL: Supressing DIO transmission (%d >= %d)\n",
155 instance->dio_counter, instance->dio_redundancy);
157 instance->dio_send = 0;
158 PRINTF(
"RPL: Scheduling DIO timer %lu ticks in future (sent)\n",
159 instance->dio_next_delay);
160 ctimer_set(&instance->dio_timer, instance->dio_next_delay, handle_dio_timer, instance);
163 if(instance->dio_intcurrent < instance->dio_intmin + instance->dio_intdoubl) {
164 instance->dio_intcurrent++;
165 PRINTF(
"RPL: DIO Timer interval doubled %d\n", instance->dio_intcurrent);
167 new_dio_interval(instance);
172 rpl_reset_periodic_timer(
void)
174 next_dis = RPL_DIS_INTERVAL / 2 +
175 ((uint32_t)RPL_DIS_INTERVAL * (uint32_t)
random_rand()) / RANDOM_RAND_MAX -
187 if(instance->dio_intcurrent > instance->dio_intmin) {
188 instance->dio_counter = 0;
189 instance->dio_intcurrent = instance->dio_intmin;
190 new_dio_interval(instance);
198 static void handle_dao_timer(
void *ptr);
208 if(instance->lifetime_unit != 0xffff && instance->default_lifetime != 0xff) {
209 clock_time_t expiration_time;
210 expiration_time = (clock_time_t)instance->default_lifetime *
211 (clock_time_t)instance->lifetime_unit *
213 PRINTF(
"RPL: Scheduling DAO lifetime timer %u ticks in the future\n",
214 (
unsigned)expiration_time);
215 ctimer_set(&instance->dao_lifetime_timer, expiration_time,
216 handle_dao_timer, instance);
221 handle_dao_timer(
void *ptr)
224 #if RPL_CONF_MULTICAST
231 if(!dio_send_ok && uip_ds6_get_link_local(ADDR_PREFERRED) ==
NULL) {
232 PRINTF(
"RPL: Postpone DAO transmission\n");
238 if(instance->current_dag->preferred_parent !=
NULL) {
239 PRINTF(
"RPL: handle_dao_timer - sending DAO\n");
241 dao_output(instance->current_dag->preferred_parent, instance->default_lifetime);
243 #if RPL_CONF_MULTICAST
245 if(instance->mop == RPL_MOP_STORING_MULTICAST) {
247 for(i = 0; i < UIP_DS6_MADDR_NB; i++) {
248 if(uip_ds6_if.maddr_list[i].isused
250 dao_output_target(instance->current_dag->preferred_parent,
251 &uip_ds6_if.maddr_list[i].ipaddr, RPL_MCAST_LIFETIME);
256 mcast_route = uip_mcast6_route_list_head();
257 while(mcast_route !=
NULL) {
259 if(uip_ds6_maddr_lookup(&mcast_route->group) ==
NULL) {
260 dao_output_target(instance->current_dag->preferred_parent,
261 &mcast_route->group, RPL_MCAST_LIFETIME);
268 PRINTF(
"RPL: No suitable DAO parent\n");
274 set_dao_lifetime_timer(instance);
281 clock_time_t expiration_time;
290 PRINTF(
"RPL: DAO timer already scheduled\n");
293 expiration_time = latency / 2 +
298 PRINTF(
"RPL: Scheduling DAO timer %u ticks in the future\n",
299 (
unsigned)expiration_time);
300 ctimer_set(&instance->dao_timer, expiration_time,
301 handle_dao_timer, instance);
303 set_dao_lifetime_timer(instance);
310 schedule_dao(instance, RPL_DAO_LATENCY);
316 schedule_dao(instance, 0);