Bugfix for separate NON requests and updated separate resonse API.\nEnabled multiple BLOCKING_REQUESTs in the same scope.
This commit is contained in:
parent
2eee14a1d8
commit
2ef46ac47a
6 changed files with 44 additions and 37 deletions
|
@ -202,8 +202,8 @@ handle_incoming_data(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
coap_error_code = INTERNAL_SERVER_ERROR_5_00;
|
||||
coap_error_message = "Service callback undefined";
|
||||
coap_error_code = NOT_IMPLEMENTED_5_01;
|
||||
coap_error_message = "NoServiceCallbck"; // no a to fit 16 bytes
|
||||
} /* if (service callback) */
|
||||
|
||||
} else {
|
||||
|
|
|
@ -81,12 +81,14 @@ PT_THREAD(coap_blocking_request(struct request_state_t *state, process_event_t e
|
|||
blocking_response_handler request_callback));
|
||||
|
||||
#define COAP_BLOCKING_REQUEST(server_addr, server_port, request, chunk_handler) \
|
||||
static struct request_state_t request_state; \
|
||||
PT_SPAWN(process_pt, &request_state.pt, \
|
||||
coap_blocking_request(&request_state, ev, \
|
||||
server_addr, server_port, \
|
||||
request, chunk_handler) \
|
||||
);
|
||||
{ \
|
||||
static struct request_state_t request_state; \
|
||||
PT_SPAWN(process_pt, &request_state.pt, \
|
||||
coap_blocking_request(&request_state, ev, \
|
||||
server_addr, server_port, \
|
||||
request, chunk_handler) \
|
||||
); \
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
#endif /* COAP_SERVER_H_ */
|
||||
|
|
|
@ -72,13 +72,6 @@ int coap_separate_handler(resource_t *resource, void *request, void *response)
|
|||
coap_init_message(ack, COAP_TYPE_ACK, 0, coap_req->mid);
|
||||
/* Serializing into IPBUF: Only overwrites header parts that are already parsed into the request struct. */
|
||||
coap_send_message(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, (uip_appdata), coap_serialize_message(ack, uip_appdata));
|
||||
|
||||
/* Change response to separate response. */
|
||||
coap_res->type = COAP_TYPE_CON;
|
||||
coap_res->mid = coap_get_mid();
|
||||
|
||||
/* Update MID in transaction for identification. */
|
||||
t->mid = coap_res->mid;
|
||||
}
|
||||
|
||||
/* Pre-handlers could skip the handling by returning 0. */
|
||||
|
@ -86,26 +79,26 @@ int coap_separate_handler(resource_t *resource, void *request, void *response)
|
|||
}
|
||||
|
||||
int
|
||||
coap_separate_response(void *response, coap_separate_t *separate_store)
|
||||
coap_separate_response(void *request, coap_separate_t *separate_store)
|
||||
{
|
||||
coap_packet_t *const coap_res = (coap_packet_t *) response;
|
||||
coap_transaction_t *const t = coap_get_transaction_by_mid(coap_res->mid);
|
||||
coap_packet_t *const coap_req = (coap_packet_t *) request;
|
||||
coap_transaction_t *const t = coap_get_transaction_by_mid(coap_req->mid);
|
||||
|
||||
if (t)
|
||||
{
|
||||
uip_ipaddr_copy(&separate_store->addr, &t->addr);
|
||||
separate_store->port = t->port;
|
||||
|
||||
separate_store->mid = coap_res->mid;
|
||||
separate_store->type = coap_res->type;
|
||||
separate_store->type = coap_req->type==COAP_TYPE_CON ? COAP_TYPE_CON : COAP_TYPE_NON;
|
||||
separate_store->mid = coap_get_mid(); // if it was NON, we burned one MID in the engine...
|
||||
|
||||
memcpy(separate_store->token, coap_res->token, coap_res->token_len);
|
||||
separate_store->token_len = coap_res->token_len;
|
||||
memcpy(separate_store->token, coap_req->token, coap_req->token_len);
|
||||
separate_store->token_len = coap_req->token_len;
|
||||
|
||||
separate_store->block2_num = coap_res->block2_num;
|
||||
separate_store->block2_more = coap_res->block2_more;
|
||||
separate_store->block2_size = coap_res->block2_size;
|
||||
separate_store->block2_offset = coap_res->block2_offset;
|
||||
separate_store->block2_num = coap_req->block2_num;
|
||||
separate_store->block2_more = coap_req->block2_more;
|
||||
separate_store->block2_size = coap_req->block2_size;
|
||||
separate_store->block2_offset = coap_req->block2_offset;
|
||||
|
||||
/* Signal the engine to skip automatic response and clear transaction by engine. */
|
||||
coap_error_code = MANUAL_RESPONSE;
|
||||
|
|
|
@ -52,14 +52,12 @@ typedef struct coap_separate {
|
|||
uint8_t token_len;
|
||||
uint8_t token[COAP_TOKEN_LEN];
|
||||
|
||||
/* separate + blockwise is untested! */
|
||||
uint32_t block2_num;
|
||||
uint8_t block2_more;
|
||||
uint16_t block2_size;
|
||||
uint32_t block2_offset;
|
||||
|
||||
/* Add fields for addition information to be saved here, e.g.: */
|
||||
char buffer[17];
|
||||
|
||||
} coap_separate_t;
|
||||
|
||||
int coap_separate_handler(resource_t *resource, void *request, void *response);
|
||||
|
|
|
@ -17,10 +17,14 @@ UIP_CONF_IPV6=1
|
|||
# configure CoAP implementation (3|7)
|
||||
WITH_COAP=7
|
||||
|
||||
# must be CFLAGS not variables
|
||||
# minimal-net does not support RPL, avoid redefine warnings
|
||||
# new variable since slip-radio
|
||||
ifneq ($(TARGET), minimal-net)
|
||||
CFLAGS += -DUIP_CONF_IPV6_RPL=1
|
||||
UIP_CONF_RPL=1
|
||||
else
|
||||
# minimal-net does not support RPL under Linux and is mostly used to test CoAP only
|
||||
${info INFO: compiling without RPL}
|
||||
UIP_CONF_RPL=0
|
||||
CFLAGS += -DUIP_CONF_ND6_DEF_MAXDADNS=0
|
||||
endif
|
||||
|
||||
# linker optimizations
|
||||
|
|
|
@ -355,12 +355,22 @@ chunks_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre
|
|||
#include "er-coap-07-transactions.h"
|
||||
/*
|
||||
* CoAP-specific example for separate responses.
|
||||
* This resource is .
|
||||
* Note the call "rest_set_pre_handler(&resource_separate, coap_separate_handler);" in the main process.
|
||||
* The pre-handler takes care of the empty ACK and updates the MID and message type for CON requests.
|
||||
* The resource handler must store all information that required to finalize the response later.
|
||||
*/
|
||||
RESOURCE(separate, METHOD_GET, "debug/separate", "title=\"Separate demo\"");
|
||||
|
||||
/* A structure to store the required information */
|
||||
typedef struct application_separate_store {
|
||||
/* Provided by Erbium to store generic request information such as remote address and token. */
|
||||
coap_separate_t request_metadata;
|
||||
/* Add fields for addition information to be stored for finalizing, e.g.: */
|
||||
char buffer[16];
|
||||
} application_separate_store_t;
|
||||
|
||||
static uint8_t separate_active = 0;
|
||||
static coap_separate_t separate_store[1];
|
||||
static application_separate_store_t separate_store[1];
|
||||
|
||||
void
|
||||
separate_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
|
@ -380,7 +390,7 @@ separate_handler(void* request, void* response, uint8_t *buffer, uint16_t prefer
|
|||
separate_active = 1;
|
||||
|
||||
/* Take over and skip response by engine. */
|
||||
coap_separate_response(response, separate_store);
|
||||
coap_separate_response(request, &separate_store->request_metadata);
|
||||
|
||||
/*
|
||||
* At the moment, only the minimal information is stored in the store (client address, port, token, MID, type, and Block2).
|
||||
|
@ -397,10 +407,10 @@ separate_finalize_handler()
|
|||
if (separate_active)
|
||||
{
|
||||
coap_transaction_t *transaction = NULL;
|
||||
if ( (transaction = coap_new_transaction(separate_store->mid, &separate_store->addr, separate_store->port)) )
|
||||
if ( (transaction = coap_new_transaction(separate_store->request_metadata.mid, &separate_store->request_metadata.addr, separate_store->request_metadata.port)) )
|
||||
{
|
||||
coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */
|
||||
coap_init_message(response, separate_store->type, CONTENT_2_05, separate_store->mid);
|
||||
coap_init_message(response, separate_store->request_metadata.type, CONTENT_2_05, separate_store->request_metadata.mid);
|
||||
|
||||
coap_set_payload(response, separate_store->buffer, strlen(separate_store->buffer));
|
||||
|
||||
|
|
Loading…
Reference in a new issue