Bugfix for separate NON requests and updated separate resonse API.\nEnabled multiple BLOCKING_REQUESTs in the same scope.

This commit is contained in:
Matthias Kovatsch 2012-02-05 06:21:35 +01:00
parent 2eee14a1d8
commit 2ef46ac47a
6 changed files with 44 additions and 37 deletions

View file

@ -202,8 +202,8 @@ handle_incoming_data(void)
} }
else else
{ {
coap_error_code = INTERNAL_SERVER_ERROR_5_00; coap_error_code = NOT_IMPLEMENTED_5_01;
coap_error_message = "Service callback undefined"; coap_error_message = "NoServiceCallbck"; // no a to fit 16 bytes
} /* if (service callback) */ } /* if (service callback) */
} else { } else {

View file

@ -81,12 +81,14 @@ PT_THREAD(coap_blocking_request(struct request_state_t *state, process_event_t e
blocking_response_handler request_callback)); blocking_response_handler request_callback));
#define COAP_BLOCKING_REQUEST(server_addr, server_port, request, chunk_handler) \ #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, \ static struct request_state_t request_state; \
PT_SPAWN(process_pt, &request_state.pt, \
coap_blocking_request(&request_state, ev, \ coap_blocking_request(&request_state, ev, \
server_addr, server_port, \ server_addr, server_port, \
request, chunk_handler) \ request, chunk_handler) \
); ); \
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
#endif /* COAP_SERVER_H_ */ #endif /* COAP_SERVER_H_ */

View file

@ -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); 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. */ /* 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)); 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. */ /* 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 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_packet_t *const coap_req = (coap_packet_t *) request;
coap_transaction_t *const t = coap_get_transaction_by_mid(coap_res->mid); coap_transaction_t *const t = coap_get_transaction_by_mid(coap_req->mid);
if (t) if (t)
{ {
uip_ipaddr_copy(&separate_store->addr, &t->addr); uip_ipaddr_copy(&separate_store->addr, &t->addr);
separate_store->port = t->port; separate_store->port = t->port;
separate_store->mid = coap_res->mid; separate_store->type = coap_req->type==COAP_TYPE_CON ? COAP_TYPE_CON : COAP_TYPE_NON;
separate_store->type = coap_res->type; 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); memcpy(separate_store->token, coap_req->token, coap_req->token_len);
separate_store->token_len = coap_res->token_len; separate_store->token_len = coap_req->token_len;
separate_store->block2_num = coap_res->block2_num; separate_store->block2_num = coap_req->block2_num;
separate_store->block2_more = coap_res->block2_more; separate_store->block2_more = coap_req->block2_more;
separate_store->block2_size = coap_res->block2_size; separate_store->block2_size = coap_req->block2_size;
separate_store->block2_offset = coap_res->block2_offset; separate_store->block2_offset = coap_req->block2_offset;
/* Signal the engine to skip automatic response and clear transaction by engine. */ /* Signal the engine to skip automatic response and clear transaction by engine. */
coap_error_code = MANUAL_RESPONSE; coap_error_code = MANUAL_RESPONSE;

View file

@ -52,14 +52,12 @@ typedef struct coap_separate {
uint8_t token_len; uint8_t token_len;
uint8_t token[COAP_TOKEN_LEN]; uint8_t token[COAP_TOKEN_LEN];
/* separate + blockwise is untested! */
uint32_t block2_num; uint32_t block2_num;
uint8_t block2_more; uint8_t block2_more;
uint16_t block2_size; uint16_t block2_size;
uint32_t block2_offset; uint32_t block2_offset;
/* Add fields for addition information to be saved here, e.g.: */
char buffer[17];
} coap_separate_t; } coap_separate_t;
int coap_separate_handler(resource_t *resource, void *request, void *response); int coap_separate_handler(resource_t *resource, void *request, void *response);

View file

@ -17,10 +17,14 @@ UIP_CONF_IPV6=1
# configure CoAP implementation (3|7) # configure CoAP implementation (3|7)
WITH_COAP=7 WITH_COAP=7
# must be CFLAGS not variables # new variable since slip-radio
# minimal-net does not support RPL, avoid redefine warnings
ifneq ($(TARGET), minimal-net) 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 endif
# linker optimizations # linker optimizations

View file

@ -355,12 +355,22 @@ chunks_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre
#include "er-coap-07-transactions.h" #include "er-coap-07-transactions.h"
/* /*
* CoAP-specific example for separate responses. * 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\""); 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 uint8_t separate_active = 0;
static coap_separate_t separate_store[1]; static application_separate_store_t separate_store[1];
void void
separate_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) 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; separate_active = 1;
/* Take over and skip response by engine. */ /* 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). * 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) if (separate_active)
{ {
coap_transaction_t *transaction = NULL; 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_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)); coap_set_payload(response, separate_store->buffer, strlen(separate_store->buffer));