diff --git a/coap-service/coap_service_api.h b/coap-service/coap_service_api.h index 4fa61cb58f10..7f0cef5363d2 100644 --- a/coap-service/coap_service_api.h +++ b/coap-service/coap_service_api.h @@ -69,9 +69,9 @@ extern const uint8_t COAP_MULTICAST_ADDR_SITE_LOCAL[16]; //!> ff05::fd, COAP sit * * Function that handles CoAP service message receiving and parsing * - * \param msg_id Id number of the current message. + * \param service_id Service handle. * \param source_address IPv6 source address. - * \param source_port Source port + * \param source_port Source port. * \param response_ptr Pointer to CoAP header structure. * * \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 * * \param service_id Id number of the current service. * \param source_address IPv6 source address. - * \param source_port Source port + * \param source_port Source port. * \param request_ptr Pointer to CoAP header structure. * * \return Status @@ -98,8 +98,10 @@ typedef int coap_service_request_recv_cb(int8_t service_id, uint8_t source_addre * Starts security service handling and fetches device password. * * \param service_id Id number of the current service. - * \param address Address of sender - * \param port Port of the device + * \param address Address of sender. + * \param port Port of the device. + * \param pw Pointer where to write the ecjpake password. + * \param pw_len Pointer where to write length of the ecjpake password. * * \return 0 for success / -1 for failure */ @@ -111,8 +113,8 @@ typedef int coap_service_security_start_cb(int8_t service_id, uint8_t address[st * CoAP service security done callback function. * * \param service_id Id number of the current service. - * \param address Address of sender - * \param keyblock Security key (40 bits) + * \param address Address of sender. + * \param keyblock Security key (40 bits). * * \return 0 for success / -1 for failure */ @@ -147,23 +149,12 @@ extern void coap_service_delete( int8_t service_id ); * * Closes secure connection (if present), but leaves socket open. * - * \param service_id Id number of the current service. + * \param service_id Id number of the current service. + * \param destimation_addr_ptr Connection destination address. + * \param port Connection destination port. */ extern void coap_service_close_secure_connection(int8_t service_id, uint8_t destination_addr_ptr[static 16], uint16_t port); -/** - * \brief Sets password for device - * - * \param service_id Service id - * \param address Device address - * \param port Device port - * \param pw_ptr Pointer to password. - * \param pw_len Lenght of password. - * - * \return 0 for success / -1 for failure - */ -//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); - /** * \brief Virtual socket sent callback. * @@ -213,7 +204,6 @@ extern int16_t coap_service_virtual_socket_set_cb(int8_t service_id, coap_servic * * \param service_id Id number of the current service. * \param *uri Uri address. - * \param port port that Application wants to use for communicate with coap server. * \param allowed_method Informs method that is allowed to use (used defines described above). * \param *request_recv_cb CoAP service request receive callback function pointer. * @@ -240,7 +230,7 @@ extern int8_t coap_service_unregister_uri(int8_t service_id, const char *uri); * * \param service_id Id number of the current service. * \param options Options defined above. - * \param destination_addr IPv6 address. + * \param destination_addr IPv6 address. * \param destination_port Destination port * \param msg_type Message type can be found from sn_coap_header. * \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 * Build and sends CoAP service response message. * * \param service_id Id number of the current service. - * \param msg_id Message ID number. * \param options Options defined above. - * \param response_ptr Pointer to CoAP header structure. + * \param request_ptr Pointer to CoAP request message header structure. + * \param message_code Message code can be found from sn_coap_header. + * \param content_type Content type can be found from sn_coap_header. + * \param payload_ptr Pointer to message content. + * \param payload_len Lenght of the message. * * \return -1 For failure *- 0 For success */ 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); +/** + * \brief Sends CoAP service response + * + * Build and sends CoAP service response message based on CoAP request message id. + * + * \param service_id Id number of the current service. + * \param options Options defined above. + * \param msg_id Request messages ID. + * \param msg_type Message type can be found from sn_coap_header. + * \param message_code Message code can be found from sn_coap_header. + * \param content_type Content type can be found from sn_coap_header. + * \param payload_ptr Pointer to message content. + * \param payload_len Lenght of the message. + * + * \return -1 For failure + *- 0 For success + */ +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); + + + /** * \brief Delete CoAP request transaction * @@ -316,7 +330,7 @@ extern int8_t coap_service_handshake_limits_set(uint8_t handshakes_max, uint8_t * Configures the CoAP duplication message buffer size. * * \param service_id Id number of the current service. - * \param size Buffer size (messages) + * \param size Buffer size (messages). * * \return -1 For failure *- 0 For success @@ -329,10 +343,10 @@ extern int8_t coap_service_set_duplicate_message_buffer(int8_t service_id, uint8 * Set DTLS certificates. * * \param service_id Id number of the current service. - * \param cert Pointer to certificate chain - * \param cert_len Certificate length - * \param priv_key pointer to private key - * \param priv_key_len length of private key + * \param cert Pointer to certificate chain. + * \param cert_len Certificate length. + * \param priv_key pointer to private key. + * \param priv_key_len length of private key. * * \return -1 For failure *- 0 For success diff --git a/source/coap_message_handler.c b/source/coap_message_handler.c index 2bd05770d4e7..933995dd42b1 100644 --- a/source/coap_message_handler.c +++ b/source/coap_message_handler.c @@ -256,15 +256,18 @@ int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t transaction_ptr->service_id = coap_service_id_find_by_socket(socket_id); transaction_ptr->msg_id = coap_message->msg_id; transaction_ptr->client_request = false;// this is server transaction + transaction_ptr->req_msg_type = coap_message->msg_type; memcpy(transaction_ptr->local_address, *(dst_addr_ptr) == 0xFF ? ns_in6addr_any : dst_addr_ptr, 16); memcpy(transaction_ptr->remote_address, source_addr_ptr, 16); + if (coap_message->token_len) { + memcpy(transaction_ptr->token, coap_message->token_ptr, coap_message->token_len); + } transaction_ptr->remote_port = port; int ret = cb(socket_id, coap_message, transaction_ptr); if (ret != 0) { tr_debug("Service %d, no response expected", transaction_ptr->service_id); sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_message); - transaction_delete(transaction_ptr); return -1; } } else { @@ -358,13 +361,37 @@ uint16_t coap_message_handler_request_send(coap_msg_handler_t *handle, int8_t se return transaction_ptr->msg_id; } -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) +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) { - coap_transaction_t *transaction_ptr; - sn_coap_hdr_s *response; sn_nsdl_addr_s dst_addr; uint16_t data_len; uint8_t *data_ptr; + + + dst_addr.addr_ptr = transaction_ptr->remote_address; + dst_addr.addr_len = 16; + dst_addr.type = SN_NSDL_ADDRESS_TYPE_IPV6; + dst_addr.port = transaction_ptr->remote_port; + + data_len = sn_coap_builder_calc_needed_packet_data_size(coap_msg_ptr); + data_ptr = own_alloc(data_len); + if (data_len > 0 && !data_ptr) { + return -1; + } + sn_coap_protocol_build(handle->coap, &dst_addr, data_ptr, coap_msg_ptr, transaction_ptr); + + handle->sn_coap_tx_callback(data_ptr, data_len, &dst_addr, transaction_ptr); + own_free(data_ptr); + + return 0; + +} + +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) +{ + sn_coap_hdr_s *response; + coap_transaction_t *transaction_ptr; + int8_t ret_val = 0; (void) options; (void)service_id; @@ -380,10 +407,6 @@ int8_t coap_message_handler_response_send(coap_msg_handler_t *handle, int8_t ser tr_error("response transaction not found"); return -2; } - dst_addr.addr_ptr = transaction_ptr->remote_address; - dst_addr.addr_len = 16; - dst_addr.type = SN_NSDL_ADDRESS_TYPE_IPV6; - dst_addr.port = transaction_ptr->remote_port; response = sn_coap_build_response(handle->coap, request_ptr, message_code); if( !response ){ @@ -393,18 +416,46 @@ int8_t coap_message_handler_response_send(coap_msg_handler_t *handle, int8_t ser response->payload_ptr = (uint8_t *) payload_ptr; // Cast away const and trust that nsdl doesn't modify... response->content_format = content_type; - data_len = sn_coap_builder_calc_needed_packet_data_size(response); - data_ptr = own_alloc(data_len); - if (data_len > 0 && !data_ptr) { - sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, response); + + ret_val = coap_message_handler_resp_build_and_send(handle, response, transaction_ptr); + sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, response); + if (ret_val == 0) { + sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, request_ptr); + } + + return ret_val; +} + +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) +{ + sn_coap_hdr_s response; + coap_transaction_t *transaction_ptr; + (void) options; + (void)service_id; + + transaction_ptr = transaction_find_server(msg_id); + if (!transaction_ptr || !handle) { return -1; } - sn_coap_protocol_build(handle->coap, &dst_addr, data_ptr, response, transaction_ptr); - sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, response); - handle->sn_coap_tx_callback(data_ptr, data_len, &dst_addr, transaction_ptr); - sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, request_ptr); - own_free(data_ptr); - return 0; + + tr_debug("Service %d, send CoAP response", service_id); + + memset(&response, 0, sizeof(sn_coap_hdr_s)); + + response.payload_len = payload_len; + response.payload_ptr = (uint8_t *) payload_ptr; // Cast away const and trust that nsdl doesn't modify... + response.content_format = content_type; + response.token_len = 4; + response.token_ptr = transaction_ptr->token; + response.msg_code = message_code; + if (transaction_ptr->req_msg_type == COAP_MSG_TYPE_CONFIRMABLE) { + response.msg_type = COAP_MSG_TYPE_ACKNOWLEDGEMENT; + response.msg_id = msg_id; + } else { + response.msg_type = COAP_MSG_TYPE_NON_CONFIRMABLE; + } + + return coap_message_handler_resp_build_and_send(handle, &response, transaction_ptr); } int8_t coap_message_handler_request_delete(coap_msg_handler_t *handle, int8_t service_id, uint16_t msg_id) diff --git a/source/coap_service_api.c b/source/coap_service_api.c index 09d2098cdcc8..f5ef123ca7fe 100644 --- a/source/coap_service_api.c +++ b/source/coap_service_api.c @@ -516,6 +516,10 @@ int8_t coap_service_response_send(int8_t service_id, uint8_t options, sn_coap_hd return coap_message_handler_response_send(coap_service_handle, service_id, options, request_ptr, message_code, content_type, payload_ptr, payload_len); } +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) { + 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); +} + int8_t coap_service_request_delete(int8_t service_id, uint16_t msg_id) { return coap_message_handler_request_delete(coap_service_handle, service_id, msg_id); diff --git a/source/include/coap_message_handler.h b/source/include/coap_message_handler.h index 9cfa6a4e3e81..707d42cad413 100644 --- a/source/include/coap_message_handler.h +++ b/source/include/coap_message_handler.h @@ -59,6 +59,7 @@ typedef struct coap_transaction { int8_t service_id; uint8_t options; uint8_t *data_ptr; + sn_coap_msg_type_e req_msg_type; bool client_request: 1; coap_message_handler_response_recv *resp_cb; @@ -93,4 +94,7 @@ extern void transaction_delete(coap_transaction_t *this); extern void transactions_delete_all(uint8_t *address_ptr, uint16_t port); +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, + sn_coap_content_format_e content_type, const uint8_t *payload_ptr,uint16_t payload_len); + #endif diff --git a/test/coap-service/unittest/stub/coap_message_handler_stub.c b/test/coap-service/unittest/stub/coap_message_handler_stub.c index 54d4759a6028..dc9236371966 100644 --- a/test/coap-service/unittest/stub/coap_message_handler_stub.c +++ b/test/coap-service/unittest/stub/coap_message_handler_stub.c @@ -70,3 +70,8 @@ int8_t coap_message_handler_exec(coap_msg_handler_t *handle, uint32_t current_ti return coap_message_handler_stub.int8_value; } +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) +{ + return coap_message_handler_stub.int8_value; +}