void sec_prot_timer_timeout_handle(sec_prot_t *prot, sec_prot_common_t *data, const trickle_params_t *trickle_params, uint16_t ticks) { if (data->trickle_running) { bool running = trickle_running(&data->trickle_timer, trickle_params); // Checks for trickle timer expiration */ if (trickle_timer(&data->trickle_timer, trickle_params, ticks)) { sec_prot_result_set(data, SEC_RESULT_TIMEOUT); prot->state_machine(prot); } // Checks if maximum number of trickle timer expirations has happened if (running && !trickle_running(&data->trickle_timer, trickle_params)) { sec_prot_result_set(data, SEC_RESULT_TIMEOUT); sec_prot_state_set(prot, data, SEC_STATE_FINISH); } } if (data->ticks > ticks) { data->ticks -= ticks; } else { tr_debug("prot timeout"); data->ticks = 0; sec_prot_result_set(data, SEC_RESULT_TIMEOUT); sec_prot_state_set(prot, data, SEC_STATE_FINISH); } }
/* Returns true if you should transmit now */ bool trickle_timer(trickle_t *t, const trickle_params_t *params, uint16_t ticks) { if (!trickle_running(t, params)) { return false; } bool transmit = false; trickle_time_t new_time = t->now + ticks; /* Catch overflow */ if (new_time < t->now) { new_time = TRICKLE_TIME_MAX; } /* RFC 6206 Rule 4 */ if (t->now < t->t && new_time >= t->t) { /* Treat k == 0 as "infinity", as per RFC 6206 6.5 */ if (t->c < params->k || params->k == 0) { transmit = true; } } /* RFC 6206 Rule 5 */ t->now = new_time; if (new_time >= t->I) { if (t->I <= TRICKLE_TIME_MAX / 2) { t->I *= 2; } else { t->I = TRICKLE_TIME_MAX; } if (t->I > params->Imax) { t->I = params->Imax; } if (t->e < UINT8_MAX) { t->e++; } trickle_begin_interval(t); } return transmit; }
/* RFC 6206 Rule 6 */ void trickle_inconsistent_heard(trickle_t *t, const trickle_params_t *params) { if (t->I != params->Imin || !trickle_running(t, params)) { trickle_reset_timer(t, params); } }