Unified coap_request_state and added status for extra information
This commit is contained in:
parent
8a863a7a76
commit
2db8fa80e2
|
@ -60,37 +60,36 @@
|
||||||
void
|
void
|
||||||
coap_blocking_request_callback(void *callback_data, coap_message_t *response)
|
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;
|
blocking_state->state.response = response;
|
||||||
process_poll(state->process);
|
process_poll(blocking_state->process);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
PT_THREAD(coap_blocking_request
|
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_endpoint_t *remote_ep,
|
||||||
coap_message_t *request,
|
coap_message_t *request,
|
||||||
coap_blocking_response_handler_t request_callback))
|
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;
|
PT_BEGIN(&blocking_state->pt);
|
||||||
static uint8_t more;
|
|
||||||
static uint8_t block_error;
|
|
||||||
|
|
||||||
state->block_num = 0;
|
state->block_num = 0;
|
||||||
state->response = NULL;
|
state->response = NULL;
|
||||||
state->process = PROCESS_CURRENT();
|
blocking_state->process = PROCESS_CURRENT();
|
||||||
|
|
||||||
more = 0;
|
state->more = 0;
|
||||||
res_block = 0;
|
state->res_block = 0;
|
||||||
block_error = 0;
|
state->block_error = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
request->mid = coap_get_mid();
|
request->mid = coap_get_mid();
|
||||||
if((state->transaction = coap_new_transaction(request->mid, remote_ep))) {
|
if((state->transaction = coap_new_transaction(request->mid, remote_ep))) {
|
||||||
state->transaction->callback = coap_blocking_request_callback;
|
state->transaction->callback = coap_blocking_request_callback;
|
||||||
state->transaction->callback_data = state;
|
state->transaction->callback_data = blocking_state;
|
||||||
|
|
||||||
if(state->block_num > 0) {
|
if(state->block_num > 0) {
|
||||||
coap_set_header_block2(request, 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);
|
coap_send_transaction(state->transaction);
|
||||||
LOG_DBG("Requested #%"PRIu32" (MID %u)\n", state->block_num, request->mid);
|
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) {
|
if(!state->response) {
|
||||||
LOG_WARN("Server not responding\n");
|
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);
|
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);
|
request_callback(state->response);
|
||||||
++(state->block_num);
|
++(state->block_num);
|
||||||
} else {
|
} else {
|
||||||
LOG_WARN("WRONG BLOCK %"PRIu32"/%"PRIu32"\n",
|
LOG_WARN("WRONG BLOCK %"PRIu32"/%"PRIu32"\n",
|
||||||
res_block, state->block_num);
|
state->res_block, state->block_num);
|
||||||
++block_error;
|
++(state->block_error);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG_WARN("Could not allocate transaction buffer");
|
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);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -39,31 +39,30 @@
|
||||||
|
|
||||||
#include "sys/pt.h"
|
#include "sys/pt.h"
|
||||||
#include "coap-transactions.h"
|
#include "coap-transactions.h"
|
||||||
|
#include "coap-request-state.h"
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/*- Client Part -------------------------------------------------------------*/
|
/*- Client Part -------------------------------------------------------------*/
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
typedef struct coap_request_state {
|
typedef struct coap_blocking_request_state {
|
||||||
|
coap_request_state_t state;
|
||||||
struct pt pt;
|
struct pt pt;
|
||||||
struct process *process;
|
struct process *process;
|
||||||
coap_transaction_t *transaction;
|
} coap_blocking_request_state_t;
|
||||||
coap_message_t *response;
|
|
||||||
uint32_t block_num;
|
|
||||||
} coap_request_state_t;
|
|
||||||
|
|
||||||
typedef void (* coap_blocking_response_handler_t)(coap_message_t *response);
|
typedef void (* coap_blocking_response_handler_t)(coap_message_t *response);
|
||||||
|
|
||||||
PT_THREAD(coap_blocking_request
|
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_endpoint_t *remote,
|
||||||
coap_message_t *request,
|
coap_message_t *request,
|
||||||
coap_blocking_response_handler_t request_callback));
|
coap_blocking_response_handler_t request_callback));
|
||||||
|
|
||||||
#define COAP_BLOCKING_REQUEST(server_endpoint, request, chunk_handler) \
|
#define COAP_BLOCKING_REQUEST(server_endpoint, request, chunk_handler) \
|
||||||
{ \
|
{ \
|
||||||
static coap_request_state_t request_state; \
|
static coap_blocking_request_state_t blocking_state; \
|
||||||
PT_SPAWN(process_pt, &request_state.pt, \
|
PT_SPAWN(process_pt, &blocking_state.pt, \
|
||||||
coap_blocking_request(&request_state, ev, \
|
coap_blocking_request(&blocking_state, ev, \
|
||||||
server_endpoint, \
|
server_endpoint, \
|
||||||
request, chunk_handler) \
|
request, chunk_handler) \
|
||||||
); \
|
); \
|
||||||
|
|
|
@ -54,19 +54,13 @@
|
||||||
#define LOG_MODULE "coap"
|
#define LOG_MODULE "coap"
|
||||||
#define LOG_LEVEL LOG_LEVEL_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 void coap_request_callback(void *callback_data, coap_message_t *response);
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
static int
|
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;
|
coap_message_t *request = state->request;
|
||||||
request->mid = coap_get_mid();
|
request->mid = coap_get_mid();
|
||||||
if((state->transaction =
|
if((state->transaction =
|
||||||
|
@ -93,7 +87,9 @@ progress_request(coap_request_state_t *state) {
|
||||||
static void
|
static void
|
||||||
coap_request_callback(void *callback_data, coap_message_t *response)
|
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;
|
uint32_t res_block1;
|
||||||
|
|
||||||
state->response = response;
|
state->response = response;
|
||||||
|
@ -102,58 +98,70 @@ coap_request_callback(void *callback_data, coap_message_t *response)
|
||||||
|
|
||||||
if(!state->response) {
|
if(!state->response) {
|
||||||
LOG_WARN("Server not responding giving up...\n");
|
LOG_WARN("Server not responding giving up...\n");
|
||||||
state->callback(state);
|
state->status = COAP_REQUEST_STATUS_TIMEOUT;
|
||||||
|
callback_state->callback(callback_state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Got a response */
|
/* 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);
|
coap_get_header_block1(state->response, &res_block1, NULL, NULL, NULL);
|
||||||
|
|
||||||
LOG_DBG("Received #%lu%s B1:%lu (%u bytes)\n",
|
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,
|
(unsigned long)res_block1,
|
||||||
state->response->payload_len);
|
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 */
|
/* 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.*/
|
/* this is only for counting BLOCK2 blocks.*/
|
||||||
++(state->block_num);
|
++(state->block_num);
|
||||||
} else {
|
} else {
|
||||||
LOG_WARN("WRONG BLOCK %"PRIu32"/%"PRIu32"\n", res_block, state->block_num);
|
LOG_WARN("WRONG BLOCK %"PRIu32"/%"PRIu32"\n", state->res_block, state->block_num);
|
||||||
++block_error;
|
++(state->block_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(more && block_error < COAP_MAX_ATTEMPTS) {
|
if(state->more) {
|
||||||
progress_request(state);
|
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 {
|
} 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->response = NULL;
|
||||||
state->callback(state);
|
callback_state->callback(callback_state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
int
|
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,
|
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? */
|
coap_request_state_t *state = &callback_state->state;
|
||||||
/* ripped from blocking request */
|
|
||||||
more = 0;
|
|
||||||
res_block = 0;
|
|
||||||
block_error = 0;
|
|
||||||
|
|
||||||
|
state->more = 0;
|
||||||
|
state->res_block = 0;
|
||||||
|
state->block_error = 0;
|
||||||
state->block_num = 0;
|
state->block_num = 0;
|
||||||
state->response = NULL;
|
state->response = NULL;
|
||||||
state->request = request;
|
state->request = request;
|
||||||
state->remote_endpoint = endpoint;
|
state->remote_endpoint = endpoint;
|
||||||
state->callback = callback;
|
callback_state->callback = callback;
|
||||||
|
|
||||||
return progress_request(state);
|
return progress_request(callback_state);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -47,35 +47,30 @@
|
||||||
|
|
||||||
#include "coap-engine.h"
|
#include "coap-engine.h"
|
||||||
#include "coap-transactions.h"
|
#include "coap-transactions.h"
|
||||||
|
#include "coap-request-state.h"
|
||||||
#include "sys/cc.h"
|
#include "sys/cc.h"
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/*- Client Part -------------------------------------------------------------*/
|
/*- 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 {
|
struct coap_callback_request_state {
|
||||||
coap_transaction_t *transaction;
|
coap_request_state_t state;
|
||||||
coap_message_t *response;
|
void (*callback)(coap_callback_request_state_t *state);
|
||||||
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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Send a CoAP request to a remote endpoint
|
* \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 endpoint The destination endpoint
|
||||||
* \param request The request to be sent
|
* \param request The request to be sent
|
||||||
* \param callback callback to execute when the response arrives or the timeout expires
|
* \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
|
* \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,
|
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_ */
|
#endif /* COAP_CALLBACK_API_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 <carlosgp143@gmail.com>
|
||||||
|
*/
|
||||||
|
#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_ */
|
||||||
|
/** @} */
|
|
@ -84,7 +84,7 @@
|
||||||
#define STATE_MACHINE_UPDATE_INTERVAL 500
|
#define STATE_MACHINE_UPDATE_INTERVAL 500
|
||||||
|
|
||||||
static struct lwm2m_session_info session_info;
|
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. */
|
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 uint8_t rd_flags = FLAG_RD_DATA_UPDATE_ON_DIRTY;
|
||||||
static uint64_t wait_until_network_check = 0;
|
static uint64_t wait_until_network_check = 0;
|
||||||
static uint64_t last_update;
|
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 char query_data[64]; /* allocate some data for queries and updates */
|
||||||
static uint8_t rd_data[128]; /* allocate some data for the RD */
|
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 uint32_t rd_block1;
|
||||||
static uint8_t rd_more;
|
static uint8_t rd_more;
|
||||||
static coap_timer_t rd_timer;
|
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;
|
static coap_timer_t block1_timer;
|
||||||
|
|
||||||
|
@ -143,7 +142,7 @@ static void queue_mode_awake_timer_callback(coap_timer_t *timer);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void check_periodic_observations();
|
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
|
static int
|
||||||
set_rd_data(coap_message_t *request)
|
set_rd_data(coap_message_t *request)
|
||||||
|
@ -370,10 +369,11 @@ update_bootstrap_server(void)
|
||||||
* TODO
|
* TODO
|
||||||
*/
|
*/
|
||||||
static void
|
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);
|
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) {
|
if(CHANGED_2_04 == state->response->code) {
|
||||||
LOG_DBG_("Considered done!\n");
|
LOG_DBG_("Considered done!\n");
|
||||||
rd_state = BOOTSTRAP_DONE;
|
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);
|
LOG_DBG_("Failed with code %d. Retrying\n", state->response->code);
|
||||||
/* TODO Application callback? */
|
/* TODO Application callback? */
|
||||||
rd_state = INIT;
|
rd_state = INIT;
|
||||||
} else if(BOOTSTRAP_SENT == rd_state) { /* this can handle double invocations */
|
} else if(state->status == COAP_REQUEST_STATUS_TIMEOUT) {
|
||||||
/* Failure! */
|
LOG_DBG_("Server not responding! Retry?");
|
||||||
LOG_DBG("Bootstrap failed! Retry?");
|
|
||||||
rd_state = DO_BOOTSTRAP;
|
rd_state = DO_BOOTSTRAP;
|
||||||
|
} else if(state->status == COAP_REQUEST_STATUS_FINISHED) {
|
||||||
|
LOG_DBG_("Request finished. Ignore\n");
|
||||||
} else {
|
} 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.
|
* Page 65-66 in 07 April 2016 spec.
|
||||||
*/
|
*/
|
||||||
static void
|
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);
|
coap_request_state_t *state = &callback_state->state;
|
||||||
if(state->response) {
|
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 */
|
/* check state and possibly set registration to done */
|
||||||
/* If we get a continue - we need to call the rd generator one more time */
|
/* If we get a continue - we need to call the rd generator one more time */
|
||||||
if(CONTINUE_2_31 == state->response->code) {
|
if(CONTINUE_2_31 == state->response->code) {
|
||||||
|
@ -472,10 +475,14 @@ registration_callback(coap_request_state_t *state)
|
||||||
}
|
}
|
||||||
/* TODO Application callback? */
|
/* TODO Application callback? */
|
||||||
rd_state = INIT;
|
rd_state = INIT;
|
||||||
/* remember last progress time */
|
} else if(state->status == COAP_REQUEST_STATUS_TIMEOUT) {
|
||||||
last_rd_progress = coap_timer_uptime();
|
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 {
|
} 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.
|
* Page 65-66 in 07 April 2016 spec.
|
||||||
*/
|
*/
|
||||||
static void
|
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 we get a continue - we need to call the rd generator one more time */
|
||||||
if(CONTINUE_2_31 == state->response->code) {
|
if(CONTINUE_2_31 == state->response->code) {
|
||||||
/* We assume that size never change?! */
|
/* We assume that size never change?! */
|
||||||
|
@ -522,20 +530,26 @@ update_callback(coap_request_state_t *state)
|
||||||
state->response->code);
|
state->response->code);
|
||||||
rd_state = DO_REGISTRATION;
|
rd_state = DO_REGISTRATION;
|
||||||
}
|
}
|
||||||
/* remember last progress */
|
} else if(state->status == COAP_REQUEST_STATUS_TIMEOUT) {
|
||||||
last_rd_progress = coap_timer_uptime();
|
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 {
|
} else {
|
||||||
LOG_DBG("Ignore\n");
|
LOG_DBG_("Unexpected error, trying to reconnect\n");
|
||||||
|
rd_state = INIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
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);
|
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");
|
LOG_DBG("Deregistration success\n");
|
||||||
rd_state = DEREGISTERED;
|
rd_state = DEREGISTERED;
|
||||||
perform_session_callback(LWM2M_RD_CLIENT_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 */
|
/* CoAP timer callback */
|
||||||
static void
|
static void
|
||||||
periodic_process(coap_timer_t *timer)
|
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_COAP_EP(&session_info.bs_server_ep);
|
||||||
LOG_INFO_("] as '%s'\n", query_data);
|
LOG_INFO_("] as '%s'\n", query_data);
|
||||||
|
|
||||||
coap_send_request(&rd_request_state, &session_info.bs_server_ep,
|
if(coap_send_request(&rd_request_state, &session_info.bs_server_ep,
|
||||||
request, bootstrap_callback);
|
request, bootstrap_callback)) {
|
||||||
|
rd_state = BOOTSTRAP_SENT;
|
||||||
rd_state = BOOTSTRAP_SENT;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -710,18 +717,14 @@ periodic_process(coap_timer_t *timer)
|
||||||
}
|
}
|
||||||
LOG_INFO_("' More:%d\n", rd_more);
|
LOG_INFO_("' More:%d\n", rd_more);
|
||||||
|
|
||||||
coap_send_request(&rd_request_state, &session_info.server_ep,
|
if(coap_send_request(&rd_request_state, &session_info.server_ep,
|
||||||
request, registration_callback);
|
request, registration_callback)){
|
||||||
last_rd_progress = coap_timer_uptime();
|
rd_state = REGISTRATION_SENT;
|
||||||
rd_state = REGISTRATION_SENT;
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case REGISTRATION_SENT:
|
case REGISTRATION_SENT:
|
||||||
/* just wait until the callback kicks us to the next state... */
|
/* 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;
|
break;
|
||||||
case REGISTRATION_DONE:
|
case REGISTRATION_DONE:
|
||||||
/* All is done! */
|
/* All is done! */
|
||||||
|
@ -733,10 +736,10 @@ periodic_process(coap_timer_t *timer)
|
||||||
((uint32_t)session_info.lifetime * 500) <= now - last_update) {
|
((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 */
|
/* 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);
|
prepare_update(request, rd_flags & FLAG_RD_DATA_UPDATE_TRIGGERED);
|
||||||
coap_send_request(&rd_request_state, &session_info.server_ep, request,
|
if(coap_send_request(&rd_request_state, &session_info.server_ep, request,
|
||||||
update_callback);
|
update_callback)) {
|
||||||
last_rd_progress = coap_timer_uptime();
|
rd_state = UPDATE_SENT;
|
||||||
rd_state = UPDATE_SENT;
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#if LWM2M_QUEUE_MODE_ENABLED
|
#if LWM2M_QUEUE_MODE_ENABLED
|
||||||
|
@ -754,27 +757,24 @@ periodic_process(coap_timer_t *timer)
|
||||||
LWM2M_QUEUE_MODE_WAKE_UP();
|
LWM2M_QUEUE_MODE_WAKE_UP();
|
||||||
#endif /* LWM2M_QUEUE_MODE_WAKE_UP */
|
#endif /* LWM2M_QUEUE_MODE_WAKE_UP */
|
||||||
prepare_update(request, rd_flags & FLAG_RD_DATA_UPDATE_TRIGGERED);
|
prepare_update(request, rd_flags & FLAG_RD_DATA_UPDATE_TRIGGERED);
|
||||||
coap_send_request(&rd_request_state, &session_info.server_ep, request,
|
if(coap_send_request(&rd_request_state, &session_info.server_ep, request,
|
||||||
update_callback);
|
update_callback)) {
|
||||||
last_rd_progress = coap_timer_uptime();
|
rd_state = UPDATE_SENT;
|
||||||
rd_state = UPDATE_SENT;
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* LWM2M_QUEUE_MODE_ENABLED */
|
#endif /* LWM2M_QUEUE_MODE_ENABLED */
|
||||||
|
|
||||||
case UPDATE_SENT:
|
case UPDATE_SENT:
|
||||||
/* just wait until the callback kicks us to the next state... */
|
/* 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;
|
break;
|
||||||
case DEREGISTER:
|
case DEREGISTER:
|
||||||
LOG_INFO("DEREGISTER %s\n", session_info.assigned_ep);
|
LOG_INFO("DEREGISTER %s\n", session_info.assigned_ep);
|
||||||
coap_init_message(request, COAP_TYPE_CON, COAP_DELETE, 0);
|
coap_init_message(request, COAP_TYPE_CON, COAP_DELETE, 0);
|
||||||
coap_set_header_uri_path(request, session_info.assigned_ep);
|
coap_set_header_uri_path(request, session_info.assigned_ep);
|
||||||
coap_send_request(&rd_request_state, &session_info.server_ep, request,
|
if(coap_send_request(&rd_request_state, &session_info.server_ep, request,
|
||||||
deregister_callback);
|
deregister_callback)) {
|
||||||
rd_state = DEREGISTER_SENT;
|
rd_state = DEREGISTER_SENT;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case DEREGISTER_SENT:
|
case DEREGISTER_SENT:
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue