Skip to content

Commit adc04c4

Browse files
author
Tero Heinonen
authored
Add API to send response to request based on Message ID (ARMmbed#78)
API to send response to request, using request's message ID as a identifier.
1 parent 58f0ed5 commit adc04c4

File tree

5 files changed

+126
-48
lines changed

5 files changed

+126
-48
lines changed

coap-service/coap_service_api.h

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ extern const uint8_t COAP_MULTICAST_ADDR_SITE_LOCAL[16]; //!> ff05::fd, COAP sit
6969
*
7070
* Function that handles CoAP service message receiving and parsing
7171
*
72-
* \param msg_id Id number of the current message.
72+
* \param service_id Service handle.
7373
* \param source_address IPv6 source address.
74-
* \param source_port Source port
74+
* \param source_port Source port.
7575
* \param response_ptr Pointer to CoAP header structure.
7676
*
7777
* \return 0 for success / -1 for failure
@@ -85,7 +85,7 @@ typedef int coap_service_response_recv(int8_t service_id, uint8_t source_address
8585
*
8686
* \param service_id Id number of the current service.
8787
* \param source_address IPv6 source address.
88-
* \param source_port Source port
88+
* \param source_port Source port.
8989
* \param request_ptr Pointer to CoAP header structure.
9090
*
9191
* \return Status
@@ -98,8 +98,10 @@ typedef int coap_service_request_recv_cb(int8_t service_id, uint8_t source_addre
9898
* Starts security service handling and fetches device password.
9999
*
100100
* \param service_id Id number of the current service.
101-
* \param address Address of sender
102-
* \param port Port of the device
101+
* \param address Address of sender.
102+
* \param port Port of the device.
103+
* \param pw Pointer where to write the ecjpake password.
104+
* \param pw_len Pointer where to write length of the ecjpake password.
103105
*
104106
* \return 0 for success / -1 for failure
105107
*/
@@ -111,8 +113,8 @@ typedef int coap_service_security_start_cb(int8_t service_id, uint8_t address[st
111113
* CoAP service security done callback function.
112114
*
113115
* \param service_id Id number of the current service.
114-
* \param address Address of sender
115-
* \param keyblock Security key (40 bits)
116+
* \param address Address of sender.
117+
* \param keyblock Security key (40 bits).
116118
*
117119
* \return 0 for success / -1 for failure
118120
*/
@@ -147,23 +149,12 @@ extern void coap_service_delete( int8_t service_id );
147149
*
148150
* Closes secure connection (if present), but leaves socket open.
149151
*
150-
* \param service_id Id number of the current service.
152+
* \param service_id Id number of the current service.
153+
* \param destimation_addr_ptr Connection destination address.
154+
* \param port Connection destination port.
151155
*/
152156
extern void coap_service_close_secure_connection(int8_t service_id, uint8_t destination_addr_ptr[static 16], uint16_t port);
153157

154-
/**
155-
* \brief Sets password for device
156-
*
157-
* \param service_id Service id
158-
* \param address Device address
159-
* \param port Device port
160-
* \param pw_ptr Pointer to password.
161-
* \param pw_len Lenght of password.
162-
*
163-
* \return 0 for success / -1 for failure
164-
*/
165-
//int coap_service_security_key_set(int8_t service_id, uint8_t address[static 16], uint16_t port, uint8_t *pw_ptr, uint8_t pw_len);
166-
167158
/**
168159
* \brief Virtual socket sent callback.
169160
*
@@ -213,7 +204,6 @@ extern int16_t coap_service_virtual_socket_set_cb(int8_t service_id, coap_servic
213204
*
214205
* \param service_id Id number of the current service.
215206
* \param *uri Uri address.
216-
* \param port port that Application wants to use for communicate with coap server.
217207
* \param allowed_method Informs method that is allowed to use (used defines described above).
218208
* \param *request_recv_cb CoAP service request receive callback function pointer.
219209
*
@@ -240,7 +230,7 @@ extern int8_t coap_service_unregister_uri(int8_t service_id, const char *uri);
240230
*
241231
* \param service_id Id number of the current service.
242232
* \param options Options defined above.
243-
* \param destination_addr IPv6 address.
233+
* \param destination_addr IPv6 address.
244234
* \param destination_port Destination port
245235
* \param msg_type Message type can be found from sn_coap_header.
246236
* \param msg_code Message code can be found from sn_coap_header.
@@ -261,15 +251,39 @@ extern uint16_t coap_service_request_send(int8_t service_id, uint8_t options, co
261251
* Build and sends CoAP service response message.
262252
*
263253
* \param service_id Id number of the current service.
264-
* \param msg_id Message ID number.
265254
* \param options Options defined above.
266-
* \param response_ptr Pointer to CoAP header structure.
255+
* \param request_ptr Pointer to CoAP request message header structure.
256+
* \param message_code Message code can be found from sn_coap_header.
257+
* \param content_type Content type can be found from sn_coap_header.
258+
* \param payload_ptr Pointer to message content.
259+
* \param payload_len Lenght of the message.
267260
*
268261
* \return -1 For failure
269262
*- 0 For success
270263
*/
271264
extern int8_t coap_service_response_send(int8_t service_id, uint8_t options, sn_coap_hdr_s *request_ptr, sn_coap_msg_code_e message_code, sn_coap_content_format_e content_type, const uint8_t *payload_ptr,uint16_t payload_len);
272265

266+
/**
267+
* \brief Sends CoAP service response
268+
*
269+
* Build and sends CoAP service response message based on CoAP request message id.
270+
*
271+
* \param service_id Id number of the current service.
272+
* \param options Options defined above.
273+
* \param msg_id Request messages ID.
274+
* \param msg_type Message type can be found from sn_coap_header.
275+
* \param message_code Message code can be found from sn_coap_header.
276+
* \param content_type Content type can be found from sn_coap_header.
277+
* \param payload_ptr Pointer to message content.
278+
* \param payload_len Lenght of the message.
279+
*
280+
* \return -1 For failure
281+
*- 0 For success
282+
*/
283+
extern int8_t coap_service_response_send_by_msg_id(int8_t service_id, uint8_t options, uint16_t msg_id, sn_coap_msg_code_e message_code, sn_coap_content_format_e content_type, const uint8_t *payload_ptr,uint16_t payload_len);
284+
285+
286+
273287
/**
274288
* \brief Delete CoAP request transaction
275289
*
@@ -316,7 +330,7 @@ extern int8_t coap_service_handshake_limits_set(uint8_t handshakes_max, uint8_t
316330
* Configures the CoAP duplication message buffer size.
317331
*
318332
* \param service_id Id number of the current service.
319-
* \param size Buffer size (messages)
333+
* \param size Buffer size (messages).
320334
*
321335
* \return -1 For failure
322336
*- 0 For success
@@ -329,10 +343,10 @@ extern int8_t coap_service_set_duplicate_message_buffer(int8_t service_id, uint8
329343
* Set DTLS certificates.
330344
*
331345
* \param service_id Id number of the current service.
332-
* \param cert Pointer to certificate chain
333-
* \param cert_len Certificate length
334-
* \param priv_key pointer to private key
335-
* \param priv_key_len length of private key
346+
* \param cert Pointer to certificate chain.
347+
* \param cert_len Certificate length.
348+
* \param priv_key pointer to private key.
349+
* \param priv_key_len length of private key.
336350
*
337351
* \return -1 For failure
338352
*- 0 For success

source/coap_message_handler.c

Lines changed: 69 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -256,15 +256,18 @@ int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t
256256
transaction_ptr->service_id = coap_service_id_find_by_socket(socket_id);
257257
transaction_ptr->msg_id = coap_message->msg_id;
258258
transaction_ptr->client_request = false;// this is server transaction
259+
transaction_ptr->req_msg_type = coap_message->msg_type;
259260
memcpy(transaction_ptr->local_address, *(dst_addr_ptr) == 0xFF ? ns_in6addr_any : dst_addr_ptr, 16);
260261
memcpy(transaction_ptr->remote_address, source_addr_ptr, 16);
262+
if (coap_message->token_len) {
263+
memcpy(transaction_ptr->token, coap_message->token_ptr, coap_message->token_len);
264+
}
261265
transaction_ptr->remote_port = port;
262266

263267
int ret = cb(socket_id, coap_message, transaction_ptr);
264268
if (ret != 0) {
265269
tr_debug("Service %d, no response expected", transaction_ptr->service_id);
266270
sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_message);
267-
transaction_delete(transaction_ptr);
268271
return -1;
269272
}
270273
} else {
@@ -358,13 +361,37 @@ uint16_t coap_message_handler_request_send(coap_msg_handler_t *handle, int8_t se
358361
return transaction_ptr->msg_id;
359362
}
360363

361-
int8_t coap_message_handler_response_send(coap_msg_handler_t *handle, int8_t service_id, uint8_t options, sn_coap_hdr_s *request_ptr, sn_coap_msg_code_e message_code, sn_coap_content_format_e content_type, const uint8_t *payload_ptr, uint16_t payload_len)
364+
static int8_t coap_message_handler_resp_build_and_send(coap_msg_handler_t *handle, sn_coap_hdr_s *coap_msg_ptr, coap_transaction_t *transaction_ptr)
362365
{
363-
coap_transaction_t *transaction_ptr;
364-
sn_coap_hdr_s *response;
365366
sn_nsdl_addr_s dst_addr;
366367
uint16_t data_len;
367368
uint8_t *data_ptr;
369+
370+
371+
dst_addr.addr_ptr = transaction_ptr->remote_address;
372+
dst_addr.addr_len = 16;
373+
dst_addr.type = SN_NSDL_ADDRESS_TYPE_IPV6;
374+
dst_addr.port = transaction_ptr->remote_port;
375+
376+
data_len = sn_coap_builder_calc_needed_packet_data_size(coap_msg_ptr);
377+
data_ptr = own_alloc(data_len);
378+
if (data_len > 0 && !data_ptr) {
379+
return -1;
380+
}
381+
sn_coap_protocol_build(handle->coap, &dst_addr, data_ptr, coap_msg_ptr, transaction_ptr);
382+
383+
handle->sn_coap_tx_callback(data_ptr, data_len, &dst_addr, transaction_ptr);
384+
own_free(data_ptr);
385+
386+
return 0;
387+
388+
}
389+
390+
int8_t coap_message_handler_response_send(coap_msg_handler_t *handle, int8_t service_id, uint8_t options, sn_coap_hdr_s *request_ptr, sn_coap_msg_code_e message_code, sn_coap_content_format_e content_type, const uint8_t *payload_ptr, uint16_t payload_len)
391+
{
392+
sn_coap_hdr_s *response;
393+
coap_transaction_t *transaction_ptr;
394+
int8_t ret_val = 0;
368395
(void) options;
369396
(void)service_id;
370397

@@ -380,10 +407,6 @@ int8_t coap_message_handler_response_send(coap_msg_handler_t *handle, int8_t ser
380407
tr_error("response transaction not found");
381408
return -2;
382409
}
383-
dst_addr.addr_ptr = transaction_ptr->remote_address;
384-
dst_addr.addr_len = 16;
385-
dst_addr.type = SN_NSDL_ADDRESS_TYPE_IPV6;
386-
dst_addr.port = transaction_ptr->remote_port;
387410

388411
response = sn_coap_build_response(handle->coap, request_ptr, message_code);
389412
if( !response ){
@@ -393,18 +416,46 @@ int8_t coap_message_handler_response_send(coap_msg_handler_t *handle, int8_t ser
393416
response->payload_ptr = (uint8_t *) payload_ptr; // Cast away const and trust that nsdl doesn't modify...
394417
response->content_format = content_type;
395418

396-
data_len = sn_coap_builder_calc_needed_packet_data_size(response);
397-
data_ptr = own_alloc(data_len);
398-
if (data_len > 0 && !data_ptr) {
399-
sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, response);
419+
420+
ret_val = coap_message_handler_resp_build_and_send(handle, response, transaction_ptr);
421+
sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, response);
422+
if (ret_val == 0) {
423+
sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, request_ptr);
424+
}
425+
426+
return ret_val;
427+
}
428+
429+
int8_t coap_message_handler_response_send_by_msg_id(coap_msg_handler_t *handle, int8_t service_id, uint8_t options, uint16_t msg_id, sn_coap_msg_code_e message_code, sn_coap_content_format_e content_type, const uint8_t *payload_ptr,uint16_t payload_len)
430+
{
431+
sn_coap_hdr_s response;
432+
coap_transaction_t *transaction_ptr;
433+
(void) options;
434+
(void)service_id;
435+
436+
transaction_ptr = transaction_find_server(msg_id);
437+
if (!transaction_ptr || !handle) {
400438
return -1;
401439
}
402-
sn_coap_protocol_build(handle->coap, &dst_addr, data_ptr, response, transaction_ptr);
403-
sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, response);
404-
handle->sn_coap_tx_callback(data_ptr, data_len, &dst_addr, transaction_ptr);
405-
sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, request_ptr);
406-
own_free(data_ptr);
407-
return 0;
440+
441+
tr_debug("Service %d, send CoAP response", service_id);
442+
443+
memset(&response, 0, sizeof(sn_coap_hdr_s));
444+
445+
response.payload_len = payload_len;
446+
response.payload_ptr = (uint8_t *) payload_ptr; // Cast away const and trust that nsdl doesn't modify...
447+
response.content_format = content_type;
448+
response.token_len = 4;
449+
response.token_ptr = transaction_ptr->token;
450+
response.msg_code = message_code;
451+
if (transaction_ptr->req_msg_type == COAP_MSG_TYPE_CONFIRMABLE) {
452+
response.msg_type = COAP_MSG_TYPE_ACKNOWLEDGEMENT;
453+
response.msg_id = msg_id;
454+
} else {
455+
response.msg_type = COAP_MSG_TYPE_NON_CONFIRMABLE;
456+
}
457+
458+
return coap_message_handler_resp_build_and_send(handle, &response, transaction_ptr);
408459
}
409460

410461
int8_t coap_message_handler_request_delete(coap_msg_handler_t *handle, int8_t service_id, uint16_t msg_id)

source/coap_service_api.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,10 @@ int8_t coap_service_response_send(int8_t service_id, uint8_t options, sn_coap_hd
516516
return coap_message_handler_response_send(coap_service_handle, service_id, options, request_ptr, message_code, content_type, payload_ptr, payload_len);
517517
}
518518

519+
int8_t coap_service_response_send_by_msg_id(int8_t service_id, uint8_t options, uint16_t msg_id, sn_coap_msg_code_e message_code, sn_coap_content_format_e content_type, const uint8_t *payload_ptr,uint16_t payload_len) {
520+
return coap_message_handler_response_send_by_msg_id(coap_service_handle, service_id, options, msg_id, message_code, content_type, payload_ptr, payload_len);
521+
}
522+
519523
int8_t coap_service_request_delete(int8_t service_id, uint16_t msg_id)
520524
{
521525
return coap_message_handler_request_delete(coap_service_handle, service_id, msg_id);

source/include/coap_message_handler.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ typedef struct coap_transaction {
5959
int8_t service_id;
6060
uint8_t options;
6161
uint8_t *data_ptr;
62+
sn_coap_msg_type_e req_msg_type;
6263
bool client_request: 1;
6364

6465
coap_message_handler_response_recv *resp_cb;
@@ -93,4 +94,7 @@ extern void transaction_delete(coap_transaction_t *this);
9394

9495
extern void transactions_delete_all(uint8_t *address_ptr, uint16_t port);
9596

97+
extern int8_t coap_message_handler_response_send_by_msg_id(coap_msg_handler_t *handle, int8_t service_id, uint8_t options, uint16_t msg_id, sn_coap_msg_code_e message_code,
98+
sn_coap_content_format_e content_type, const uint8_t *payload_ptr,uint16_t payload_len);
99+
96100
#endif

test/coap-service/unittest/stub/coap_message_handler_stub.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,8 @@ int8_t coap_message_handler_exec(coap_msg_handler_t *handle, uint32_t current_ti
7070
return coap_message_handler_stub.int8_value;
7171
}
7272

73+
int8_t coap_message_handler_response_send_by_msg_id(coap_msg_handler_t *handle, int8_t service_id, uint8_t options, uint16_t msg_id, sn_coap_msg_code_e message_code,
74+
sn_coap_content_format_e content_type, const uint8_t *payload_ptr,uint16_t payload_len)
75+
{
76+
return coap_message_handler_stub.int8_value;
77+
}

0 commit comments

Comments
 (0)