void bootstrap_step(lwm2m_context_t * contextP, uint32_t currentTime, time_t* timeoutP) { lwm2m_server_t * targetP; targetP = contextP->bootstrapServerList; while (targetP != NULL) { switch (targetP->status) { case STATE_DEREGISTERED: targetP->registration = currentTime + targetP->lifetime; targetP->status = STATE_BS_HOLD_OFF; if (*timeoutP > targetP->lifetime) { *timeoutP = targetP->lifetime; } break; case STATE_BS_HOLD_OFF: if (targetP->registration <= currentTime) { bootstrap_initiating_request(contextP, targetP); } else if (*timeoutP > targetP->registration - currentTime) { *timeoutP = targetP->registration - currentTime; } break; case STATE_BS_INITIATED: case STATE_BS_PENDING: // waiting break; case STATE_BS_FINISHED: // do nothing break; case STATE_BS_FAILED: // do nothing break; default: break; } targetP = targetP->next; } }
void update_bootstrap_state(lwm2m_context_t * context, uint32_t currentTime, time_t* timeoutP) { if (context->bsState == BOOTSTRAP_REQUESTED) { context->bsState = BOOTSTRAP_CLIENT_HOLD_OFF; context->bsStart = currentTime; LOG("[BOOTSTRAP] Bootstrap requested at: %lu, now waiting during ClientHoldOffTime...\r\n", (unsigned long)context->bsStart); } if (context->bsState == BOOTSTRAP_CLIENT_HOLD_OFF) { lwm2m_server_t * bootstrapServer = context->bootstrapServerList; if (bootstrapServer != NULL) { // get ClientHoldOffTime from bootstrapServer->lifetime // (see objects.c => object_getServers()) int32_t timeToBootstrap = (context->bsStart + bootstrapServer->lifetime) - currentTime; LOG("[BOOTSTRAP] ClientHoldOffTime %ld\r\n", (long)timeToBootstrap); if (0 >= timeToBootstrap) { bootstrap_initiating_request(context); } else if (timeToBootstrap < *timeoutP) { *timeoutP = timeToBootstrap; } } else { bootstrap_failed(context); } } if (context->bsState == BOOTSTRAP_PENDING) { // Use COAP_DEFAULT_MAX_AGE according proposal in // https://github.com/OpenMobileAlliance/OMA-LwM2M-Public-Review/issues/35 int32_t timeToBootstrap = (context->bsStart + COAP_DEFAULT_MAX_AGE) - currentTime; LOG("[BOOTSTRAP] Pending %ld\r\n", (long)timeToBootstrap); if (0 >= timeToBootstrap) { // Time out and no error => bootstrap OK // TODO: add smarter condition for bootstrap success: // 1) security object contains at least one bootstrap server // 2) there are coherent configurations for provisioned DM servers // if these conditions are not met, then bootstrap has failed and previous security // and server object configurations might be restored by client LOG("\r\n[BOOTSTRAP] Bootstrap finished at: %lu (difftime: %lu s)\r\n", (unsigned long)currentTime, (unsigned long)(currentTime - context->bsStart)); context->bsState = BOOTSTRAP_FINISHED; context->bsStart = currentTime; *timeoutP = 1; } else if (timeToBootstrap < *timeoutP) { *timeoutP = timeToBootstrap; } } else if (context->bsState == BOOTSTRAP_FINISHED) { context->bsStart = currentTime; if (0 <= lwm2m_start(context)) { context->bsState = BOOTSTRAPPED; } else { bootstrap_failed(context); } // during next step, lwm2m_update_registrations will connect the client to DM server } if (BOOTSTRAP_FAILED == context->bsState) { lwm2m_server_t * bootstrapServer = context->bootstrapServerList; if (bootstrapServer != NULL) { // get ClientHoldOffTime from bootstrapServer->lifetime // (see objects.c => object_getServers()) int32_t timeToBootstrap = (context->bsStart + bootstrapServer->lifetime) - currentTime; LOG("[BOOTSTRAP] Bootstrap failed: %lu, now waiting during ClientHoldOffTime %ld ...\r\n", (unsigned long)context->bsStart, (long)timeToBootstrap); if (0 >= timeToBootstrap) { context->bsState = NOT_BOOTSTRAPPED; context->bsStart = currentTime; LOG("[BOOTSTRAP] Bootstrap failed: retry ...\r\n"); *timeoutP = 1; } else if (timeToBootstrap < *timeoutP) { *timeoutP = timeToBootstrap; } } } }