From 02ec6530f44caa56e947864608adcd6e9eaa4d7c Mon Sep 17 00:00:00 2001 From: Yogesh Pande Date: Mon, 31 Jul 2017 06:07:58 -0700 Subject: [PATCH] Updating mbed-coap to version 4.0.8 Fixes errors reported in Github - #4798 - Fixed Lwm2m blockwise data transfer (using Block1 option) with Leshan - ARMmbed/mbed-client#512 - Fixed an ongoing blocktransfer (Block 1 option) interruption by out of order Block to return error 4.08 Request Entity Incomplete as specified in the coap specification. - ARMmbed/mbed-client#511 - Fixed detected duplicate message duplications will not stop mbed-client --- .../FEATURE_COMMON_PAL/mbed-coap/CHANGELOG.md | 9 +++ .../FEATURE_COMMON_PAL/mbed-coap/module.json | 2 +- .../include/sn_coap_protocol_internal.h | 1 + .../mbed-coap/source/sn_coap_protocol.c | 76 ++++++++++++++++--- 4 files changed, 76 insertions(+), 12 deletions(-) diff --git a/features/FEATURE_COMMON_PAL/mbed-coap/CHANGELOG.md b/features/FEATURE_COMMON_PAL/mbed-coap/CHANGELOG.md index f4f7ad8162..7995a1d87a 100644 --- a/features/FEATURE_COMMON_PAL/mbed-coap/CHANGELOG.md +++ b/features/FEATURE_COMMON_PAL/mbed-coap/CHANGELOG.md @@ -1,5 +1,14 @@ # Change Log +## [v4.0.8](https://github.com/ARMmbed/mbed-coap/releases/tag/v4.0.8) + +-[Full Changelog](https://github.com/ARMmbed/mbed-coap/compare/v4.0.4...v4.0.8) + + **Closed issues:** + - IOTCLT-1880 Lwm2m blockwise data transfer (using Block1 option) with Leshan not working + - IOTCLT-1885 Return 4.08 Request Entity Incomplete on Block transfer errors + - IOTCLT-1883 Detected message duplications stop mbed-client + ## [v4.0.4](https://github.com/ARMmbed/mbed-coap/releases/tag/v4.0.4) -[Full Changelog](https://github.com/ARMmbed/mbed-coap/compare/v4.0.3...v4.0.4) diff --git a/features/FEATURE_COMMON_PAL/mbed-coap/module.json b/features/FEATURE_COMMON_PAL/mbed-coap/module.json index 28d37c9f41..df17fbba50 100644 --- a/features/FEATURE_COMMON_PAL/mbed-coap/module.json +++ b/features/FEATURE_COMMON_PAL/mbed-coap/module.json @@ -1,6 +1,6 @@ { "name": "mbed-coap", - "version": "4.0.6", + "version": "4.0.8", "description": "COAP library", "keywords": [ "coap", diff --git a/features/FEATURE_COMMON_PAL/mbed-coap/source/include/sn_coap_protocol_internal.h b/features/FEATURE_COMMON_PAL/mbed-coap/source/include/sn_coap_protocol_internal.h index d3cc664503..3a603d3dfa 100644 --- a/features/FEATURE_COMMON_PAL/mbed-coap/source/include/sn_coap_protocol_internal.h +++ b/features/FEATURE_COMMON_PAL/mbed-coap/source/include/sn_coap_protocol_internal.h @@ -189,6 +189,7 @@ typedef struct coap_blockwise_payload_ { uint8_t addr_len; uint8_t *addr_ptr; uint16_t port; + uint32_t block_number; uint16_t payload_len; uint8_t *payload_ptr; diff --git a/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_protocol.c b/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_protocol.c index fc643e329a..aed99fb242 100644 --- a/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_protocol.c +++ b/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_protocol.c @@ -56,8 +56,9 @@ static void sn_coap_protocol_linked_list_duplication_info_remov #endif #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwising is not used at all, this part of code will not be compiled */ static void sn_coap_protocol_linked_list_blockwise_msg_remove(struct coap_s *handle, coap_blockwise_msg_s *removed_msg_ptr); -static void sn_coap_protocol_linked_list_blockwise_payload_store(struct coap_s *handle, sn_nsdl_addr_s *addr_ptr, uint16_t stored_payload_len, uint8_t *stored_payload_ptr); +static void sn_coap_protocol_linked_list_blockwise_payload_store(struct coap_s *handle, sn_nsdl_addr_s *addr_ptr, uint16_t stored_payload_len, uint8_t *stored_payload_ptr, uint32_t block_number); static uint8_t *sn_coap_protocol_linked_list_blockwise_payload_search(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr, uint16_t *payload_length); +static bool sn_coap_protocol_linked_list_blockwise_payload_compare_block_number(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr, uint32_t block_number); static void sn_coap_protocol_linked_list_blockwise_payload_remove(struct coap_s *handle, coap_blockwise_payload_s *removed_payload_ptr); static void sn_coap_protocol_linked_list_blockwise_payload_remove_oldest(struct coap_s *handle); static uint32_t sn_coap_protocol_linked_list_blockwise_payloads_get_len(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr); @@ -653,9 +654,11 @@ sn_coap_hdr_s *sn_coap_protocol_parse(struct coap_s *handle, sn_nsdl_addr_s *src returned_dst_coap_msg_ptr->msg_id); /* Send ACK response */ if (response) { - response->coap->sn_coap_tx_callback(response->packet_ptr, - response->packet_len, response->address, response->param); - + /* Check that response has been created */ + if (response->packet_ptr) { + response->coap->sn_coap_tx_callback(response->packet_ptr, + response->packet_len, response->address, response->param); + } } return returned_dst_coap_msg_ptr; @@ -795,7 +798,6 @@ int8_t sn_coap_protocol_exec(struct coap_s *handle, uint32_t current_time) if (tmp_coap_hdr_ptr != 0) { tmp_coap_hdr_ptr->coap_status = COAP_STATUS_BUILDER_MESSAGE_SENDING_FAILED; - stored_msg_ptr->coap->sn_coap_rx_callback(tmp_coap_hdr_ptr, stored_msg_ptr->send_msg_ptr->dst_addr_ptr, stored_msg_ptr->param); sn_coap_parser_release_allocated_coap_msg_mem(stored_msg_ptr->coap, tmp_coap_hdr_ptr); @@ -1210,7 +1212,8 @@ static void sn_coap_protocol_linked_list_blockwise_msg_remove(struct coap_s *han static void sn_coap_protocol_linked_list_blockwise_payload_store(struct coap_s *handle, sn_nsdl_addr_s *addr_ptr, uint16_t stored_payload_len, - uint8_t *stored_payload_ptr) + uint8_t *stored_payload_ptr, + uint32_t block_number) { if (!addr_ptr || !stored_payload_len || !stored_payload_ptr) { return; @@ -1227,6 +1230,7 @@ static void sn_coap_protocol_linked_list_blockwise_payload_store(struct coap_s * return; } + /* Allocate memory for stored Payload's data */ stored_blockwise_payload_ptr->payload_ptr = handle->sn_coap_protocol_malloc(stored_payload_len); @@ -1259,6 +1263,8 @@ static void sn_coap_protocol_linked_list_blockwise_payload_store(struct coap_s * stored_blockwise_payload_ptr->coap = handle; + stored_blockwise_payload_ptr->block_number = block_number; + /* * * * Storing Payload to Linked list * * * */ ns_list_add_to_end(&handle->linked_list_blockwise_received_payloads, stored_blockwise_payload_ptr); @@ -1295,6 +1301,27 @@ static uint8_t *sn_coap_protocol_linked_list_blockwise_payload_search(struct coa return NULL; } +static bool sn_coap_protocol_linked_list_blockwise_payload_compare_block_number(struct coap_s *handle, + sn_nsdl_addr_s *src_addr_ptr, + uint32_t block_number) +{ + /* Loop all stored blockwise payloads in Linked list */ + ns_list_foreach(coap_blockwise_payload_s, stored_payload_info_ptr, &handle->linked_list_blockwise_received_payloads) { + /* If payload's Source address is same than is searched */ + if (0 == memcmp(src_addr_ptr->addr_ptr, stored_payload_info_ptr->addr_ptr, src_addr_ptr->addr_len)) { + /* If payload's Source address port is same than is searched */ + if (stored_payload_info_ptr->port == src_addr_ptr->port) { + // Check that incoming block number matches to last received one + if (block_number - 1 == stored_payload_info_ptr->block_number) { + tr_debug("sn_coap_protocol_linked_list_blockwise_payload_search_block_number - found %d", stored_payload_info_ptr->block_number); + return true; + } + } + } + } + return false; +} + /**************************************************************************//** * \fn static void sn_coap_protocol_linked_list_blockwise_payload_remove_oldest(struct coap_s *handle) * @@ -1326,7 +1353,6 @@ static void sn_coap_protocol_linked_list_blockwise_payload_remove(struct coap_s coap_blockwise_payload_s *removed_payload_ptr) { ns_list_remove(&handle->linked_list_blockwise_received_payloads, removed_payload_ptr); - /* Free memory of stored payload */ if (removed_payload_ptr->addr_ptr != NULL) { handle->sn_coap_protocol_free(removed_payload_ptr->addr_ptr); @@ -1658,7 +1684,22 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn received_coap_msg_ptr->payload_len = handle->sn_coap_block_data_size; } - sn_coap_protocol_linked_list_blockwise_payload_store(handle, src_addr_ptr, received_coap_msg_ptr->payload_len, received_coap_msg_ptr->payload_ptr); + // Check that incoming block number is in order. + uint32_t block_number = received_coap_msg_ptr->options_list_ptr->block1 >> 4; + bool blocks_in_order = true; + if (block_number > 0 && + !sn_coap_protocol_linked_list_blockwise_payload_compare_block_number(handle, + src_addr_ptr, + block_number)) { + blocks_in_order = false; + } + + sn_coap_protocol_linked_list_blockwise_payload_store(handle, + src_addr_ptr, + received_coap_msg_ptr->payload_len, + received_coap_msg_ptr->payload_ptr, + block_number); + /* If not last block (more value is set) */ /* Block option length can be 1-3 bytes. First 4-20 bits are for block number. Last 4 bits are ALWAYS more bit + block size. */ if (received_coap_msg_ptr->options_list_ptr->block1 & 0x08) { @@ -1678,12 +1719,14 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn // Response with COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE if the payload size is more than we can handle tr_debug("sn_coap_handle_blockwise_message - block1 received - incoming size: [%d]", received_coap_msg_ptr->options_list_ptr->size1); + uint32_t max_size = SN_COAP_MAX_INCOMING_BLOCK_MESSAGE_SIZE; - if (received_coap_msg_ptr->options_list_ptr->size1 > max_size) { + if (!blocks_in_order) { + src_coap_blockwise_ack_msg_ptr->msg_code = COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_INCOMPLETE; + } else if (received_coap_msg_ptr->options_list_ptr->size1 > max_size) { // Include maximum size that stack can handle into response src_coap_blockwise_ack_msg_ptr->msg_code = COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE; src_coap_blockwise_ack_msg_ptr->options_list_ptr->size1 = max_size; - } else if (received_coap_msg_ptr->msg_code == COAP_MSG_CODE_REQUEST_GET) { src_coap_blockwise_ack_msg_ptr->msg_code = COAP_MSG_CODE_RESPONSE_CONTENT; } else if (received_coap_msg_ptr->msg_code == COAP_MSG_CODE_REQUEST_POST) { @@ -1706,6 +1749,13 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn src_coap_blockwise_ack_msg_ptr->msg_id = received_coap_msg_ptr->msg_id; + // Copy token to response + src_coap_blockwise_ack_msg_ptr->token_ptr = handle->sn_coap_protocol_malloc(received_coap_msg_ptr->token_len); + if (src_coap_blockwise_ack_msg_ptr->token_ptr) { + memcpy(src_coap_blockwise_ack_msg_ptr->token_ptr, received_coap_msg_ptr->token_ptr, received_coap_msg_ptr->token_len); + src_coap_blockwise_ack_msg_ptr->token_len = received_coap_msg_ptr->token_len; + } + dst_packed_data_needed_mem = sn_coap_builder_calc_needed_packet_data_size_2(src_coap_blockwise_ack_msg_ptr, handle->sn_coap_block_data_size); dst_ack_packet_data_ptr = handle->sn_coap_protocol_malloc(dst_packed_data_needed_mem); @@ -1776,7 +1826,11 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn /* Store blockwise payload to Linked list */ //todo: add block number to stored values - just to make sure all packets are in order - sn_coap_protocol_linked_list_blockwise_payload_store(handle, src_addr_ptr, received_coap_msg_ptr->payload_len, received_coap_msg_ptr->payload_ptr); + sn_coap_protocol_linked_list_blockwise_payload_store(handle, + src_addr_ptr, + received_coap_msg_ptr->payload_len, + received_coap_msg_ptr->payload_ptr, + received_coap_msg_ptr->options_list_ptr->block1 >> 4); /* If not last block (more value is set) */ if (received_coap_msg_ptr->options_list_ptr->block2 & 0x08) {