diff --git a/os/net/app-layer/coap/coap-blocking-api.c b/os/net/app-layer/coap/coap-blocking-api.c index 1be7cbe7c..9fd691d74 100644 --- a/os/net/app-layer/coap/coap-blocking-api.c +++ b/os/net/app-layer/coap/coap-blocking-api.c @@ -60,37 +60,36 @@ void coap_blocking_request_callback(void *callback_data, coap_message_t *response) { - coap_request_state_t *state = (coap_request_state_t *)callback_data; + coap_blocking_request_state_t *blocking_state = (coap_blocking_request_state_t *)callback_data; - state->response = response; - process_poll(state->process); + blocking_state->state.response = response; + process_poll(blocking_state->process); } /*---------------------------------------------------------------------------*/ PT_THREAD(coap_blocking_request - (coap_request_state_t *state, process_event_t ev, + (coap_blocking_request_state_t *blocking_state, process_event_t ev, coap_endpoint_t *remote_ep, coap_message_t *request, coap_blocking_response_handler_t request_callback)) { - PT_BEGIN(&state->pt); + /* Before PT_BEGIN in order to not be a local variable in the PT_Thread and maintain it */ + coap_request_state_t *state = &blocking_state->state; - static uint32_t res_block; - static uint8_t more; - static uint8_t block_error; + PT_BEGIN(&blocking_state->pt); state->block_num = 0; state->response = NULL; - state->process = PROCESS_CURRENT(); + blocking_state->process = PROCESS_CURRENT(); - more = 0; - res_block = 0; - block_error = 0; + state->more = 0; + state->res_block = 0; + state->block_error = 0; do { request->mid = coap_get_mid(); if((state->transaction = coap_new_transaction(request->mid, remote_ep))) { state->transaction->callback = coap_blocking_request_callback; - state->transaction->callback_data = state; + state->transaction->callback_data = blocking_state; if(state->block_num > 0) { coap_set_header_block2(request, state->block_num, 0, @@ -104,33 +103,46 @@ PT_THREAD(coap_blocking_request coap_send_transaction(state->transaction); LOG_DBG("Requested #%"PRIu32" (MID %u)\n", state->block_num, request->mid); - PT_YIELD_UNTIL(&state->pt, ev == PROCESS_EVENT_POLL); + PT_YIELD_UNTIL(&blocking_state->pt, ev == PROCESS_EVENT_POLL); if(!state->response) { LOG_WARN("Server not responding\n"); - PT_EXIT(&state->pt); + state->status = COAP_REQUEST_STATUS_TIMEOUT; + PT_EXIT(&blocking_state->pt); } - coap_get_header_block2(state->response, &res_block, &more, NULL, NULL); + coap_get_header_block2(state->response, &state->res_block, &state->more, NULL, NULL); - LOG_DBG("Received #%"PRIu32"%s (%u bytes)\n", res_block, more ? "+" : "", + LOG_DBG("Received #%"PRIu32"%s (%u bytes)\n", state->res_block, state->more ? "+" : "", state->response->payload_len); + if(state->more) { + state->status = COAP_REQUEST_STATUS_MORE; + } else { + state->status = COAP_REQUEST_STATUS_RESPONSE; + } - if(res_block == state->block_num) { + if(state->res_block == state->block_num) { request_callback(state->response); ++(state->block_num); } else { LOG_WARN("WRONG BLOCK %"PRIu32"/%"PRIu32"\n", - res_block, state->block_num); - ++block_error; + state->res_block, state->block_num); + ++(state->block_error); } } else { LOG_WARN("Could not allocate transaction buffer"); - PT_EXIT(&state->pt); + PT_EXIT(&blocking_state->pt); } - } while(more && block_error < COAP_MAX_ATTEMPTS); + } while(state->more && (state->block_error) < COAP_MAX_ATTEMPTS); - PT_END(&state->pt); + if((state->block_error) >= COAP_MAX_ATTEMPTS) { + /* failure - now we give up */ + state->status = COAP_REQUEST_STATUS_BLOCK_ERROR; + } else { + /* No more blocks, request finished */ + state->status = COAP_REQUEST_STATUS_FINISHED; + } + PT_END(&blocking_state->pt); } /*---------------------------------------------------------------------------*/ /** @} */ diff --git a/os/net/app-layer/coap/coap-blocking-api.h b/os/net/app-layer/coap/coap-blocking-api.h index d9a916c04..716a261b5 100644 --- a/os/net/app-layer/coap/coap-blocking-api.h +++ b/os/net/app-layer/coap/coap-blocking-api.h @@ -39,31 +39,30 @@ #include "sys/pt.h" #include "coap-transactions.h" +#include "coap-request-state.h" /*---------------------------------------------------------------------------*/ /*- Client Part -------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -typedef struct coap_request_state { +typedef struct coap_blocking_request_state { + coap_request_state_t state; struct pt pt; struct process *process; - coap_transaction_t *transaction; - coap_message_t *response; - uint32_t block_num; -} coap_request_state_t; +} coap_blocking_request_state_t; typedef void (* coap_blocking_response_handler_t)(coap_message_t *response); PT_THREAD(coap_blocking_request - (coap_request_state_t *state, process_event_t ev, + (coap_blocking_request_state_t *blocking_state, process_event_t ev, coap_endpoint_t *remote, coap_message_t *request, coap_blocking_response_handler_t request_callback)); #define COAP_BLOCKING_REQUEST(server_endpoint, request, chunk_handler) \ { \ - static coap_request_state_t request_state; \ - PT_SPAWN(process_pt, &request_state.pt, \ - coap_blocking_request(&request_state, ev, \ + static coap_blocking_request_state_t blocking_state; \ + PT_SPAWN(process_pt, &blocking_state.pt, \ + coap_blocking_request(&blocking_state, ev, \ server_endpoint, \ request, chunk_handler) \ ); \ diff --git a/os/net/app-layer/coap/coap-callback-api.c b/os/net/app-layer/coap/coap-callback-api.c index 0f0ab2c99..41a2ef846 100644 --- a/os/net/app-layer/coap/coap-callback-api.c +++ b/os/net/app-layer/coap/coap-callback-api.c @@ -54,19 +54,13 @@ #define LOG_MODULE "coap" #define LOG_LEVEL LOG_LEVEL_COAP -/* These should go into the state struct so that we can have multiple - requests */ - -static uint32_t res_block; -static uint8_t more; -static uint8_t block_error; - static void coap_request_callback(void *callback_data, coap_message_t *response); /*---------------------------------------------------------------------------*/ static int -progress_request(coap_request_state_t *state) { +progress_request(coap_callback_request_state_t *callback_state) { + coap_request_state_t *state = &callback_state->state; coap_message_t *request = state->request; request->mid = coap_get_mid(); if((state->transaction = @@ -93,7 +87,9 @@ progress_request(coap_request_state_t *state) { static void coap_request_callback(void *callback_data, coap_message_t *response) { - coap_request_state_t *state = (coap_request_state_t *)callback_data; + coap_callback_request_state_t *callback_state = (coap_callback_request_state_t*)callback_data; + coap_request_state_t *state = &callback_state->state; + uint32_t res_block1; state->response = response; @@ -102,58 +98,70 @@ coap_request_callback(void *callback_data, coap_message_t *response) if(!state->response) { LOG_WARN("Server not responding giving up...\n"); - state->callback(state); + state->status = COAP_REQUEST_STATUS_TIMEOUT; + callback_state->callback(callback_state); return; } /* Got a response */ - coap_get_header_block2(state->response, &res_block, &more, NULL, NULL); + coap_get_header_block2(state->response, &state->res_block, &state->more, NULL, NULL); coap_get_header_block1(state->response, &res_block1, NULL, NULL, NULL); LOG_DBG("Received #%lu%s B1:%lu (%u bytes)\n", - (unsigned long)res_block, (unsigned)more ? "+" : "", + (unsigned long)state->res_block, (unsigned)state->more ? "+" : "", (unsigned long)res_block1, state->response->payload_len); - if(res_block == state->block_num) { + if(state->res_block == state->block_num) { /* Call the callback function as we have more data */ - state->callback(state); + if(state->more) { + state->status = COAP_REQUEST_STATUS_MORE; + } else { + state->status = COAP_REQUEST_STATUS_RESPONSE; + } + callback_state->callback(callback_state); /* this is only for counting BLOCK2 blocks.*/ ++(state->block_num); } else { - LOG_WARN("WRONG BLOCK %"PRIu32"/%"PRIu32"\n", res_block, state->block_num); - ++block_error; + LOG_WARN("WRONG BLOCK %"PRIu32"/%"PRIu32"\n", state->res_block, state->block_num); + ++(state->block_error); } - if(more && block_error < COAP_MAX_ATTEMPTS) { - progress_request(state); + if(state->more) { + if((state->block_error) < COAP_MAX_ATTEMPTS) { + progress_request(callback_state); + } else { + /* failure - now we give up and notify the callback */ + state->status = COAP_REQUEST_STATUS_BLOCK_ERROR; + callback_state->callback(callback_state); + } } else { - /* failure - now we give up and notify the callback */ + /* No more blocks, finish and notify the callback */ + state->status = COAP_REQUEST_STATUS_FINISHED; state->response = NULL; - state->callback(state); + callback_state->callback(callback_state); } } /*---------------------------------------------------------------------------*/ int -coap_send_request(coap_request_state_t *state, coap_endpoint_t *endpoint, +coap_send_request(coap_callback_request_state_t *callback_state, coap_endpoint_t *endpoint, coap_message_t *request, - void (*callback)(coap_request_state_t *state)) + void (*callback)(coap_callback_request_state_t *callback_state)) { - /* can we have these variables shared between multiple requests? */ - /* ripped from blocking request */ - more = 0; - res_block = 0; - block_error = 0; + coap_request_state_t *state = &callback_state->state; + state->more = 0; + state->res_block = 0; + state->block_error = 0; state->block_num = 0; state->response = NULL; state->request = request; state->remote_endpoint = endpoint; - state->callback = callback; + callback_state->callback = callback; - return progress_request(state); + return progress_request(callback_state); } /*---------------------------------------------------------------------------*/ /** @} */ diff --git a/os/net/app-layer/coap/coap-callback-api.h b/os/net/app-layer/coap/coap-callback-api.h index 69ceea4f5..a9019aeb8 100644 --- a/os/net/app-layer/coap/coap-callback-api.h +++ b/os/net/app-layer/coap/coap-callback-api.h @@ -47,35 +47,30 @@ #include "coap-engine.h" #include "coap-transactions.h" +#include "coap-request-state.h" #include "sys/cc.h" /*---------------------------------------------------------------------------*/ /*- Client Part -------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -typedef struct coap_request_state coap_request_state_t; +typedef struct coap_callback_request_state coap_callback_request_state_t; -struct coap_request_state { - coap_transaction_t *transaction; - coap_message_t *response; - coap_message_t *request; - coap_endpoint_t *remote_endpoint; - uint32_t block_num; - void *user_data; - coap_timer_t coap_timer; - void (*callback)(coap_request_state_t *state); +struct coap_callback_request_state { + coap_request_state_t state; + void (*callback)(coap_callback_request_state_t *state); }; /** * \brief Send a CoAP request to a remote endpoint - * \param state The state to handle the CoAP request + * \param callback_state The callback state to handle the CoAP request * \param endpoint The destination endpoint * \param request The request to be sent * \param callback callback to execute when the response arrives or the timeout expires * \return 1 if there is a transaction available to send, 0 otherwise */ -int coap_send_request(coap_request_state_t *state, coap_endpoint_t *endpoint, +int coap_send_request(coap_callback_request_state_t *callback_state, coap_endpoint_t *endpoint, coap_message_t *request, - void (*callback)(coap_request_state_t *state)); + void (*callback)(coap_callback_request_state_t *callback_state)); #endif /* COAP_CALLBACK_API_H_ */ /** @} */ diff --git a/os/net/app-layer/coap/coap-request-state.h b/os/net/app-layer/coap/coap-request-state.h new file mode 100644 index 000000000..4c5881bb6 --- /dev/null +++ b/os/net/app-layer/coap/coap-request-state.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018, RISE SICS AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * \addtogroup coap + * @{ + */ + +/** + * \file + * Common request state for all the APIs + * \author + * Carlos Gonzalo Peces + */ +#ifndef COAP_REQUEST_STATE_H_ +#define COAP_REQUEST_STATE_H_ + +typedef enum { + COAP_REQUEST_STATUS_RESPONSE, /* Response received and no more blocks */ + COAP_REQUEST_STATUS_MORE, /* Response received and there are more blocks */ + COAP_REQUEST_STATUS_FINISHED, /* Request finished */ + COAP_REQUEST_STATUS_TIMEOUT, /* Request Timeout after all retransmissions */ + COAP_REQUEST_STATUS_BLOCK_ERROR /* Blocks in wrong order */ +} coap_request_status_t; + + +typedef struct coap_request_state { + coap_transaction_t *transaction; + coap_message_t *response; + coap_message_t *request; + coap_endpoint_t *remote_endpoint; + uint32_t block_num; + uint32_t res_block; + uint8_t more; + uint8_t block_error; + void *user_data; + coap_request_status_t status; +} coap_request_state_t; + + +#endif /* COAP_REQUEST_STATE_H_ */ +/** @} */ diff --git a/os/services/lwm2m/lwm2m-rd-client.c b/os/services/lwm2m/lwm2m-rd-client.c index 63c9443e1..4b4b11528 100644 --- a/os/services/lwm2m/lwm2m-rd-client.c +++ b/os/services/lwm2m/lwm2m-rd-client.c @@ -84,7 +84,7 @@ #define STATE_MACHINE_UPDATE_INTERVAL 500 static struct lwm2m_session_info session_info; -static coap_request_state_t rd_request_state; +static coap_callback_request_state_t rd_request_state; static coap_message_t request[1]; /* This way the message can be treated as pointer as usual. */ @@ -118,7 +118,6 @@ static uint8_t rd_state = 0; static uint8_t rd_flags = FLAG_RD_DATA_UPDATE_ON_DIRTY; static uint64_t wait_until_network_check = 0; static uint64_t last_update; -static uint64_t last_rd_progress = 0; static char query_data[64]; /* allocate some data for queries and updates */ static uint8_t rd_data[128]; /* allocate some data for the RD */ @@ -126,7 +125,7 @@ static uint8_t rd_data[128]; /* allocate some data for the RD */ static uint32_t rd_block1; static uint8_t rd_more; static coap_timer_t rd_timer; -static void (*rd_callback)(coap_request_state_t *state); +static void (*rd_callback)(coap_callback_request_state_t *callback_state); static coap_timer_t block1_timer; @@ -143,7 +142,7 @@ static void queue_mode_awake_timer_callback(coap_timer_t *timer); #endif static void check_periodic_observations(); -static void update_callback(coap_request_state_t *state); +static void update_callback(coap_callback_request_state_t *callback_state); static int set_rd_data(coap_message_t *request) @@ -370,10 +369,11 @@ update_bootstrap_server(void) * TODO */ static void -bootstrap_callback(coap_request_state_t *state) +bootstrap_callback(coap_callback_request_state_t *callback_state) { + coap_request_state_t *state = &callback_state->state; LOG_DBG("Bootstrap callback Response: %d, ", state->response != NULL); - if(state->response) { + if(state->status == COAP_REQUEST_STATUS_RESPONSE) { if(CHANGED_2_04 == state->response->code) { LOG_DBG_("Considered done!\n"); rd_state = BOOTSTRAP_DONE; @@ -383,12 +383,14 @@ bootstrap_callback(coap_request_state_t *state) LOG_DBG_("Failed with code %d. Retrying\n", state->response->code); /* TODO Application callback? */ rd_state = INIT; - } else if(BOOTSTRAP_SENT == rd_state) { /* this can handle double invocations */ - /* Failure! */ - LOG_DBG("Bootstrap failed! Retry?"); + } else if(state->status == COAP_REQUEST_STATUS_TIMEOUT) { + LOG_DBG_("Server not responding! Retry?"); rd_state = DO_BOOTSTRAP; + } else if(state->status == COAP_REQUEST_STATUS_FINISHED) { + LOG_DBG_("Request finished. Ignore\n"); } else { - LOG_DBG("Ignore\n"); + LOG_DBG_("Unexpected error! Retry?"); + rd_state = DO_BOOTSTRAP; } } /*---------------------------------------------------------------------------*/ @@ -427,10 +429,11 @@ block1_rd_callback(coap_timer_t *timer) * Page 65-66 in 07 April 2016 spec. */ static void -registration_callback(coap_request_state_t *state) +registration_callback(coap_callback_request_state_t *callback_state) { - LOG_DBG("Registration callback. Response: %d, ", state->response != NULL); - if(state->response) { + coap_request_state_t *state = &callback_state->state; + LOG_DBG("Registration callback. Status: %d. Response: %d, ", state->status, state->response != NULL); + if(state->status == COAP_REQUEST_STATUS_RESPONSE) { /* check state and possibly set registration to done */ /* If we get a continue - we need to call the rd generator one more time */ if(CONTINUE_2_31 == state->response->code) { @@ -472,10 +475,14 @@ registration_callback(coap_request_state_t *state) } /* TODO Application callback? */ rd_state = INIT; - /* remember last progress time */ - last_rd_progress = coap_timer_uptime(); + } else if(state->status == COAP_REQUEST_STATUS_TIMEOUT) { + LOG_DBG_("Server not responding, trying to reconnect\n"); + rd_state = INIT; + } else if(state->status == COAP_REQUEST_STATUS_FINISHED){ + LOG_DBG_("Request finished. Ignore\n"); } else { - LOG_DBG_("Ignore\n"); + LOG_DBG_("Unexpected error, trying to reconnect\n"); + rd_state = INIT; } } /*---------------------------------------------------------------------------*/ @@ -483,11 +490,12 @@ registration_callback(coap_request_state_t *state) * Page 65-66 in 07 April 2016 spec. */ static void -update_callback(coap_request_state_t *state) +update_callback(coap_callback_request_state_t *callback_state) { - LOG_DBG("Update callback. Response: %d, ", state->response != NULL); + coap_request_state_t *state = &callback_state->state; + LOG_DBG("Update callback. Status: %d. Response: %d, ", state->status, state->response != NULL); - if(state->response) { + if(state->status == COAP_REQUEST_STATUS_RESPONSE) { /* If we get a continue - we need to call the rd generator one more time */ if(CONTINUE_2_31 == state->response->code) { /* We assume that size never change?! */ @@ -522,20 +530,26 @@ update_callback(coap_request_state_t *state) state->response->code); rd_state = DO_REGISTRATION; } - /* remember last progress */ - last_rd_progress = coap_timer_uptime(); + } else if(state->status == COAP_REQUEST_STATUS_TIMEOUT) { + LOG_DBG_("Server not responding, trying to reconnect\n"); + rd_state = INIT; + } else if(state->status == COAP_REQUEST_STATUS_FINISHED){ + LOG_DBG_("Request finished. Ignore\n"); } else { - LOG_DBG("Ignore\n"); + LOG_DBG_("Unexpected error, trying to reconnect\n"); + rd_state = INIT; } } /*---------------------------------------------------------------------------*/ static void -deregister_callback(coap_request_state_t *state) +deregister_callback(coap_callback_request_state_t *callback_state) { - LOG_DBG("Deregister callback. Response Code: %d\n", + coap_request_state_t *state = &callback_state->state; + LOG_DBG("Deregister callback. Status: %d. Response Code: %d\n", + state->status, state->response != NULL ? state->response->code : 0); - if(state->response && (DELETED_2_02 == state->response->code)) { + if(state->status == COAP_REQUEST_STATUS_RESPONSE && (DELETED_2_02 == state->response->code)) { LOG_DBG("Deregistration success\n"); rd_state = DEREGISTERED; perform_session_callback(LWM2M_RD_CLIENT_DEREGISTERED); @@ -548,13 +562,6 @@ deregister_callback(coap_request_state_t *state) } } /*---------------------------------------------------------------------------*/ -static void -recover_from_rd_delay(void) -{ - /* This can be improved in the future... */ - rd_state = INIT; -} -/*---------------------------------------------------------------------------*/ /* CoAP timer callback */ static void periodic_process(coap_timer_t *timer) @@ -611,10 +618,10 @@ periodic_process(coap_timer_t *timer) LOG_INFO_COAP_EP(&session_info.bs_server_ep); LOG_INFO_("] as '%s'\n", query_data); - coap_send_request(&rd_request_state, &session_info.bs_server_ep, - request, bootstrap_callback); - - rd_state = BOOTSTRAP_SENT; + if(coap_send_request(&rd_request_state, &session_info.bs_server_ep, + request, bootstrap_callback)) { + rd_state = BOOTSTRAP_SENT; + } } } break; @@ -710,18 +717,14 @@ periodic_process(coap_timer_t *timer) } LOG_INFO_("' More:%d\n", rd_more); - coap_send_request(&rd_request_state, &session_info.server_ep, - request, registration_callback); - last_rd_progress = coap_timer_uptime(); - rd_state = REGISTRATION_SENT; + if(coap_send_request(&rd_request_state, &session_info.server_ep, + request, registration_callback)){ + rd_state = REGISTRATION_SENT; + } } break; case REGISTRATION_SENT: /* just wait until the callback kicks us to the next state... */ - if(last_rd_progress + MAX_RD_UPDATE_WAIT < coap_timer_uptime()) { - /* Timeout on the update - something is wrong? */ - recover_from_rd_delay(); - } break; case REGISTRATION_DONE: /* All is done! */ @@ -733,10 +736,10 @@ periodic_process(coap_timer_t *timer) ((uint32_t)session_info.lifetime * 500) <= now - last_update) { /* triggered or time to send an update to the server, at half-time! sec vs ms */ prepare_update(request, rd_flags & FLAG_RD_DATA_UPDATE_TRIGGERED); - coap_send_request(&rd_request_state, &session_info.server_ep, request, - update_callback); - last_rd_progress = coap_timer_uptime(); - rd_state = UPDATE_SENT; + if(coap_send_request(&rd_request_state, &session_info.server_ep, request, + update_callback)) { + rd_state = UPDATE_SENT; + } } break; #if LWM2M_QUEUE_MODE_ENABLED @@ -754,27 +757,24 @@ periodic_process(coap_timer_t *timer) LWM2M_QUEUE_MODE_WAKE_UP(); #endif /* LWM2M_QUEUE_MODE_WAKE_UP */ prepare_update(request, rd_flags & FLAG_RD_DATA_UPDATE_TRIGGERED); - coap_send_request(&rd_request_state, &session_info.server_ep, request, - update_callback); - last_rd_progress = coap_timer_uptime(); - rd_state = UPDATE_SENT; + if(coap_send_request(&rd_request_state, &session_info.server_ep, request, + update_callback)) { + rd_state = UPDATE_SENT; + } break; #endif /* LWM2M_QUEUE_MODE_ENABLED */ case UPDATE_SENT: /* just wait until the callback kicks us to the next state... */ - if(last_rd_progress + MAX_RD_UPDATE_WAIT < coap_timer_uptime()) { - /* Timeout on the update - something is wrong? */ - recover_from_rd_delay(); - } break; case DEREGISTER: LOG_INFO("DEREGISTER %s\n", session_info.assigned_ep); coap_init_message(request, COAP_TYPE_CON, COAP_DELETE, 0); coap_set_header_uri_path(request, session_info.assigned_ep); - coap_send_request(&rd_request_state, &session_info.server_ep, request, - deregister_callback); - rd_state = DEREGISTER_SENT; + if(coap_send_request(&rd_request_state, &session_info.server_ep, request, + deregister_callback)) { + rd_state = DEREGISTER_SENT; + } break; case DEREGISTER_SENT: break;