42 #include "contiki-conf.h"
43 #include "net/rpl/rpl-private.h"
44 #include "lib/random.h"
47 #define DEBUG DEBUG_NONE
51 static struct ctimer periodic_timer;
53 static void handle_periodic_timer(
void *ptr);
54 static void new_dio_interval(rpl_dag_t *dag);
55 static void handle_dio_timer(
void *ptr);
57 static uint16_t next_dis;
60 static uint8_t dio_send_ok;
64 handle_periodic_timer(
void *ptr)
67 rpl_recalculate_ranks();
72 if(rpl_get_dag(RPL_ANY_INSTANCE) ==
NULL && next_dis >= RPL_DIS_INTERVAL) {
81 new_dio_interval(rpl_dag_t *dag)
86 time = 1UL << dag->dio_intcurrent;
91 dag->dio_next_delay = time;
95 time += (time * random_rand()) / RANDOM_RAND_MAX;
102 dag->dio_next_delay -= time;
108 dag->dio_totrecv += dag->dio_counter;
109 ANNOTATE(
"#A rank=%u.%u(%u),stats=%d %d %d %d,color=%s\n",
110 DAG_RANK(dag->rank, dag),
111 (10 * (dag->rank % dag->min_hoprankinc)) / dag->min_hoprankinc,
113 dag->dio_totint, dag->dio_totsend,
114 dag->dio_totrecv,dag->dio_intcurrent,
115 dag->rank == ROOT_RANK(dag) ?
"BLUE" :
"ORANGE");
119 dag->dio_counter = 0;
122 PRINTF(
"RPL: Scheduling DIO timer %lu ticks in future (Interval)\n", time);
123 ctimer_set(&dag->dio_timer, time, &handle_dio_timer, dag);
127 handle_dio_timer(
void *ptr)
131 dag = (rpl_dag_t *)ptr;
133 PRINTF(
"RPL: DIO Timer triggered\n");
135 if(uip_ds6_get_link_local(ADDR_PREFERRED) !=
NULL) {
138 PRINTF(
"RPL: Postponing DIO transmission since link local address is not ok\n");
146 if(dag->dio_counter < dag->dio_redundancy) {
150 dio_output(dag,
NULL);
152 PRINTF(
"RPL: Supressing DIO transmission (%d >= %d)\n",
153 dag->dio_counter, dag->dio_redundancy);
156 PRINTF(
"RPL: Scheduling DIO timer %u ticks in future (sent)\n",
157 dag->dio_next_delay);
158 ctimer_set(&dag->dio_timer, dag->dio_next_delay, handle_dio_timer, dag);
161 if(dag->dio_intcurrent < dag->dio_intmin + dag->dio_intdoubl) {
162 dag->dio_intcurrent++;
163 PRINTF(
"RPL: DIO Timer interval doubled %d\n", dag->dio_intcurrent);
165 new_dio_interval(dag);
170 rpl_reset_periodic_timer(
void)
172 next_dis = RPL_DIS_INTERVAL - RPL_DIS_START_DELAY;
178 rpl_reset_dio_timer(rpl_dag_t *dag, uint8_t force)
181 if(force || dag->dio_intcurrent > dag->dio_intmin) {
182 dag->dio_counter = 0;
183 dag->dio_intcurrent = dag->dio_intmin;
184 new_dio_interval(dag);
192 handle_dao_timer(
void *ptr)
196 dag = (rpl_dag_t *)ptr;
198 if (!dio_send_ok && uip_ds6_get_link_local(ADDR_PREFERRED) ==
NULL) {
199 PRINTF(
"RPL: Postpone DAO transmission... \n");
205 if(dag->preferred_parent !=
NULL) {
206 PRINTF(
"RPL: handle_dao_timer - sending DAO\n");
208 dao_output(dag->preferred_parent, dag->default_lifetime);
210 PRINTF(
"RPL: No suitable DAO parent\n");
216 rpl_schedule_dao(rpl_dag_t *dag)
218 clock_time_t expiration_time;
223 PRINTF(
"RPL: DAO timer already scheduled\n");
225 expiration_time = DEFAULT_DAO_LATENCY / 2 +
226 (random_rand() % (DEFAULT_DAO_LATENCY));
227 PRINTF(
"RPL: Scheduling DAO timer %u ticks in the future\n",
228 (
unsigned)expiration_time);
230 handle_dao_timer, dag);