diff --git a/features/FEATURE_COMMON_PAL/mbed-coap/CHANGELOG.md b/features/FEATURE_COMMON_PAL/mbed-coap/CHANGELOG.md index b2e282fe54..9b2c59ed47 100644 --- a/features/FEATURE_COMMON_PAL/mbed-coap/CHANGELOG.md +++ b/features/FEATURE_COMMON_PAL/mbed-coap/CHANGELOG.md @@ -1,5 +1,17 @@ # Change Log +## [v4.0.3](https://github.com/ARMmbed/mbed-coap/releases/tag/v4.0.3) + +-[Full Changelog](https://github.com/ARMmbed/mbed-coap/compare/v4.0.2...v4.0.3) + + **New feature** + + - CoAP Protocol Confirmable resend fix and minor memory optimization (IOTMAC-328) + + **Closed issues:** + + - IOTCLT-1439 - stuck in while loop + ## [v4.0.0](https://github.com/ARMmbed/mbed-coap/releases/tag/v4.0.2) **New feature** diff --git a/features/FEATURE_COMMON_PAL/mbed-coap/mbed-coap/sn_coap_protocol.h b/features/FEATURE_COMMON_PAL/mbed-coap/mbed-coap/sn_coap_protocol.h index 2fee18e1c8..b9fbdc63ac 100644 --- a/features/FEATURE_COMMON_PAL/mbed-coap/mbed-coap/sn_coap_protocol.h +++ b/features/FEATURE_COMMON_PAL/mbed-coap/mbed-coap/sn_coap_protocol.h @@ -83,7 +83,8 @@ extern int8_t sn_coap_protocol_destroy(struct coap_s *handle); * In failure cases:\n * -1 = Failure in CoAP header structure\n * -2 = Failure in given pointer (= NULL)\n - * -3 = Failure in Reset message\ŋ + * -3 = Failure in Reset message\n + * -4 = Failure in Resending message store\n * If there is not enough memory (or User given limit exceeded) for storing * resending messages, situation is ignored. */ diff --git a/features/FEATURE_COMMON_PAL/mbed-coap/module.json b/features/FEATURE_COMMON_PAL/mbed-coap/module.json index c03d51e4cf..b581d6bac6 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.2", + "version": "4.0.3", "description": "COAP library", "keywords": [ "coap", diff --git a/features/FEATURE_COMMON_PAL/mbed-coap/source/include/sn_coap_header_internal.h b/features/FEATURE_COMMON_PAL/mbed-coap/source/include/sn_coap_header_internal.h index 0a6d5936cb..f00dd7d7cd 100644 --- a/features/FEATURE_COMMON_PAL/mbed-coap/source/include/sn_coap_header_internal.h +++ b/features/FEATURE_COMMON_PAL/mbed-coap/source/include/sn_coap_header_internal.h @@ -64,8 +64,6 @@ typedef struct sn_nsdl_transmit_ { uint16_t packet_len; uint8_t *packet_ptr; - uint8_t *uri_path_ptr; - uint8_t uri_path_len; } sn_nsdl_transmit_s; /* * * * * * * * * * * * * * * * * * * * * * */ diff --git a/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_builder.c b/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_builder.c index 5a530122a4..0901fd0086 100644 --- a/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_builder.c +++ b/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_builder.c @@ -174,21 +174,16 @@ uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_ returned_byte_count += src_coap_msg_ptr->token_len; } /* URI PATH - Repeatable option. Length of one option is 0-255 */ - /* Do not add uri-path for notification message. - * Uri-path is needed for cancelling observation with RESET message */ - if (!src_coap_msg_ptr->options_list_ptr || - (src_coap_msg_ptr->options_list_ptr && - COAP_OBSERVE_NONE == src_coap_msg_ptr->options_list_ptr->observe)) { - if (src_coap_msg_ptr->uri_path_ptr != NULL) { - repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->uri_path_len, - src_coap_msg_ptr->uri_path_ptr, COAP_OPTION_URI_PATH); - if (repeatable_option_size) { - returned_byte_count += repeatable_option_size; - } else { - return 0; - } + if (src_coap_msg_ptr->uri_path_ptr != NULL) { + repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->uri_path_len, + src_coap_msg_ptr->uri_path_ptr, COAP_OPTION_URI_PATH); + if (repeatable_option_size) { + returned_byte_count += repeatable_option_size; + } else { + return 0; } } + uint16_t tempInt = 0; /* CONTENT FORMAT - An integer option, up to 2 bytes */ if (src_coap_msg_ptr->content_format != COAP_CT_NONE) { @@ -574,13 +569,8 @@ static int8_t sn_coap_builder_options_build(uint8_t **dst_packet_data_pptr, sn_c &src_coap_msg_ptr->options_list_ptr->location_path_len, COAP_OPTION_LOCATION_PATH, &previous_option_number); } /* * * * Build Uri-Path option * * * */ - /* Do not add uri-path for notification message. - * Uri-path is needed for cancelling observation with RESET message */ - if (!src_coap_msg_ptr->options_list_ptr || - (src_coap_msg_ptr->options_list_ptr && - COAP_OBSERVE_NONE == src_coap_msg_ptr->options_list_ptr->observe)) - sn_coap_builder_options_build_add_multiple_option(dst_packet_data_pptr, &src_coap_msg_ptr->uri_path_ptr, - &src_coap_msg_ptr->uri_path_len, COAP_OPTION_URI_PATH, &previous_option_number); + sn_coap_builder_options_build_add_multiple_option(dst_packet_data_pptr, &src_coap_msg_ptr->uri_path_ptr, + &src_coap_msg_ptr->uri_path_len, COAP_OPTION_URI_PATH, &previous_option_number); /* * * * Build Content-Type option * * * */ if (src_coap_msg_ptr->content_format != COAP_CT_NONE) { diff --git a/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_parser.c b/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_parser.c index 6ec7c68de4..8f63f736d7 100644 --- a/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_parser.c +++ b/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_parser.c @@ -35,7 +35,6 @@ #include "mbed-coap/sn_coap_protocol.h" #include "sn_coap_header_internal.h" #include "sn_coap_protocol_internal.h" - /* * * * * * * * * * * * * * * * * * * * */ /* * * * LOCAL FUNCTION PROTOTYPES * * * */ /* * * * * * * * * * * * * * * * * * * * */ @@ -315,6 +314,7 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack (*packet_data_pptr) += 2; } + message_left = packet_len - (*packet_data_pptr - packet_data_start_ptr); /* * * Parse option itself * * */ /* Some options are handled independently in own functions */ @@ -655,7 +655,7 @@ static int16_t sn_coap_parser_options_count_needed_memory_multiple_option(uint8_ uint16_t i = 1; /* Loop all Uri-Query options */ - while (i < packet_left_len) { + while (i <= packet_left_len) { if (option == COAP_OPTION_LOCATION_PATH && option_number_len > 255) { return -1; } @@ -677,14 +677,13 @@ static int16_t sn_coap_parser_options_count_needed_memory_multiple_option(uint8_ i += option_number_len; ret_value += option_number_len + 1; /* + 1 is for separator */ - if(ret_value >= packet_left_len) - break; - if(ret_value >= packet_left_len) - break; - - if( i == packet_left_len ) + if( i == packet_left_len ) { break; + } + else if( i > packet_left_len ) { + return -1; + } if ((*(packet_data_ptr + i) >> COAP_OPTIONS_OPTION_NUMBER_SHIFT) != 0) { return (ret_value - 1); /* -1 because last Part path does not include separator */ @@ -693,9 +692,19 @@ static int16_t sn_coap_parser_options_count_needed_memory_multiple_option(uint8_ option_number_len = (*(packet_data_ptr + i) & 0x0F); if (option_number_len == 13) { + + if(i + 1 >= packet_left_len) { + return -1; + } + i++; option_number_len = *(packet_data_ptr + i) + 13; } else if (option_number_len == 14) { + + if(i + 2 >= packet_left_len) { + return -1; + } + option_number_len = *(packet_data_ptr + i + 2); option_number_len += (*(packet_data_ptr + i + 1) << 8) + 269; i += 2; @@ -750,3 +759,4 @@ static int8_t sn_coap_parser_payload_parse(uint16_t packet_data_len, uint8_t *pa } return 0; } + 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 0612d16b25..2df34e3dd3 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 @@ -67,7 +67,7 @@ static int8_t sn_coap_convert_block_size(uint16_t block_size); static sn_coap_hdr_s *sn_coap_protocol_copy_header(struct coap_s *handle, sn_coap_hdr_s *source_header_ptr); #endif #if ENABLE_RESENDINGS -static void sn_coap_protocol_linked_list_send_msg_store(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_ptr, uint16_t send_packet_data_len, uint8_t *send_packet_data_ptr, uint32_t sending_time, void *param, uint8_t *uri_path_ptr, uint8_t uri_path_len); +static uint8_t sn_coap_protocol_linked_list_send_msg_store(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_ptr, uint16_t send_packet_data_len, uint8_t *send_packet_data_ptr, uint32_t sending_time, void *param); static sn_nsdl_transmit_s *sn_coap_protocol_linked_list_send_msg_search(struct coap_s *handle,sn_nsdl_addr_s *src_addr_ptr, uint16_t msg_id); static void sn_coap_protocol_linked_list_send_msg_remove(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr, uint16_t msg_id); static coap_send_msg_s *sn_coap_protocol_allocate_mem_for_msg(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_ptr, uint16_t packet_data_len); @@ -300,30 +300,9 @@ void sn_coap_protocol_clear_retransmission_buffer(struct coap_s *handle) return; } ns_list_foreach_safe(coap_send_msg_s, tmp, &handle->linked_list_resent_msgs) { - if (tmp->send_msg_ptr) { - if (tmp->send_msg_ptr->dst_addr_ptr) { - if (tmp->send_msg_ptr->dst_addr_ptr->addr_ptr) { - handle->sn_coap_protocol_free(tmp->send_msg_ptr->dst_addr_ptr->addr_ptr); - tmp->send_msg_ptr->dst_addr_ptr->addr_ptr = 0; - } - handle->sn_coap_protocol_free(tmp->send_msg_ptr->dst_addr_ptr); - tmp->send_msg_ptr->dst_addr_ptr = 0; - } - if (tmp->send_msg_ptr->packet_ptr) { - handle->sn_coap_protocol_free(tmp->send_msg_ptr->packet_ptr); - tmp->send_msg_ptr->packet_ptr = 0; - } - if (tmp->send_msg_ptr->uri_path_ptr) { - handle->sn_coap_protocol_free(tmp->send_msg_ptr->uri_path_ptr); - tmp->send_msg_ptr->uri_path_ptr = 0; - } - handle->sn_coap_protocol_free(tmp->send_msg_ptr); - tmp->send_msg_ptr = 0; - } ns_list_remove(&handle->linked_list_resent_msgs, tmp); + sn_coap_protocol_release_allocated_send_msg_mem(handle, tmp); --handle->count_resent_msgs; - handle->sn_coap_protocol_free(tmp); - tmp = 0; } #endif } @@ -445,9 +424,11 @@ int16_t sn_coap_protocol_build(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_p /* Check if built Message type was confirmable, only these messages are resent */ if (src_coap_msg_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE) { /* Store message to Linked list for resending purposes */ - sn_coap_protocol_linked_list_send_msg_store(handle, dst_addr_ptr, byte_count_built, dst_packet_data_ptr, + if (sn_coap_protocol_linked_list_send_msg_store(handle, dst_addr_ptr, byte_count_built, dst_packet_data_ptr, handle->system_time + (uint32_t)(handle->sn_coap_resending_intervall * RESPONSE_RANDOM_FACTOR), - param, src_coap_msg_ptr->uri_path_ptr, src_coap_msg_ptr->uri_path_len); + param) == 0) { + return -4; + } } #endif /* ENABLE_RESENDINGS */ @@ -702,15 +683,6 @@ sn_coap_hdr_s *sn_coap_protocol_parse(struct coap_s *handle, sn_nsdl_addr_s *src removed_msg_ptr = sn_coap_protocol_linked_list_send_msg_search(handle, src_addr_ptr, returned_dst_coap_msg_ptr->msg_id); if (removed_msg_ptr != NULL) { - if (returned_dst_coap_msg_ptr->msg_type == COAP_MSG_TYPE_RESET) { - if(removed_msg_ptr->uri_path_len) { - returned_dst_coap_msg_ptr->uri_path_ptr = handle->sn_coap_protocol_malloc(removed_msg_ptr->uri_path_len); - if (returned_dst_coap_msg_ptr->uri_path_ptr != NULL) { - memcpy(returned_dst_coap_msg_ptr->uri_path_ptr, removed_msg_ptr->uri_path_ptr, removed_msg_ptr->uri_path_len); - returned_dst_coap_msg_ptr->uri_path_len = removed_msg_ptr->uri_path_len; - } - } - } /* Remove resending message from active message resending Linked list */ sn_coap_protocol_linked_list_send_msg_remove(handle, src_addr_ptr, returned_dst_coap_msg_ptr->msg_id); } @@ -799,7 +771,7 @@ int8_t sn_coap_protocol_exec(struct coap_s *handle, uint32_t current_time) #if ENABLE_RESENDINGS /* If Message resending is not used at all, this part of code will not be compiled */ /**************************************************************************//** - * \fn static void sn_coap_protocol_linked_list_send_msg_store(sn_nsdl_addr_s *dst_addr_ptr, uint16_t send_packet_data_len, uint8_t *send_packet_data_ptr, uint32_t sending_time) + * \fn static uint8_t sn_coap_protocol_linked_list_send_msg_store(sn_nsdl_addr_s *dst_addr_ptr, uint16_t send_packet_data_len, uint8_t *send_packet_data_ptr, uint32_t sending_time) * * \brief Stores message to Linked list for sending purposes. @@ -810,29 +782,33 @@ int8_t sn_coap_protocol_exec(struct coap_s *handle, uint32_t current_time) * \param *send_packet_data_ptr is Packet data to be stored * * \param sending_time is stored sending time + * + * \return 0 Allocation or buffer limit reached + * + * \return 1 Msg stored properly *****************************************************************************/ -static void sn_coap_protocol_linked_list_send_msg_store(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_ptr, uint16_t send_packet_data_len, - uint8_t *send_packet_data_ptr, uint32_t sending_time, void *param, uint8_t *uri_path_ptr, uint8_t uri_path_len) +static uint8_t sn_coap_protocol_linked_list_send_msg_store(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_ptr, uint16_t send_packet_data_len, + uint8_t *send_packet_data_ptr, uint32_t sending_time, void *param) { coap_send_msg_s *stored_msg_ptr = NULL; /* If both queue parameters are "0" or resending count is "0", then re-sending is disabled */ if (((handle->sn_coap_resending_queue_msgs == 0) && (handle->sn_coap_resending_queue_bytes == 0)) || (handle->sn_coap_resending_count == 0)) { - return; + return 1; } if (handle->sn_coap_resending_queue_msgs > 0) { if (handle->count_resent_msgs >= handle->sn_coap_resending_queue_msgs) { - return; + return 0; } } /* Count resending queue size, if buffer size is defined */ if (handle->sn_coap_resending_queue_bytes > 0) { if ((sn_coap_count_linked_list_size(&handle->linked_list_resent_msgs) + send_packet_data_len) > handle->sn_coap_resending_queue_bytes) { - return; + return 0; } } @@ -840,7 +816,7 @@ static void sn_coap_protocol_linked_list_send_msg_store(struct coap_s *handle, s stored_msg_ptr = sn_coap_protocol_allocate_mem_for_msg(handle, dst_addr_ptr, send_packet_data_len); if (stored_msg_ptr == 0) { - return; + return 0; } /* Filling of coap_send_msg_s with initialization values */ @@ -861,19 +837,10 @@ static void sn_coap_protocol_linked_list_send_msg_store(struct coap_s *handle, s stored_msg_ptr->coap = handle; stored_msg_ptr->param = param; - if (uri_path_len) { - stored_msg_ptr->send_msg_ptr->uri_path_ptr = handle->sn_coap_protocol_malloc(uri_path_len); - if (stored_msg_ptr->send_msg_ptr->uri_path_ptr == NULL){ - return; - } - stored_msg_ptr->send_msg_ptr->uri_path_len = uri_path_len; - memcpy(stored_msg_ptr->send_msg_ptr->uri_path_ptr, uri_path_ptr, uri_path_len); - } - - /* Storing Resending message to Linked list */ ns_list_add_to_end(&handle->linked_list_resent_msgs, stored_msg_ptr); ++handle->count_resent_msgs; + return 1; } /**************************************************************************//** @@ -1367,6 +1334,7 @@ static void sn_coap_protocol_linked_list_blockwise_remove_old_data(struct coap_s * * \param *dst_addr_ptr is pointer to destination address where message will be sent * \param packet_data_len is length of allocated Packet data + * \param uri_path_len is length of messages path url * * \return pointer to allocated struct *****************************************************************************/ @@ -1377,45 +1345,35 @@ coap_send_msg_s *sn_coap_protocol_allocate_mem_for_msg(struct coap_s *handle, sn coap_send_msg_s *msg_ptr = handle->sn_coap_protocol_malloc(sizeof(coap_send_msg_s)); if (msg_ptr == NULL) { - return 0; + return NULL; } + //Locall structure for 1 malloc for send msg + struct + { + sn_nsdl_transmit_s transmit; + sn_nsdl_addr_s addr; + uint8_t trail_data[]; + } *m; + int trail_size = dst_addr_ptr->addr_len + packet_data_len; + + m = handle->sn_coap_protocol_malloc(sizeof *m + trail_size); + if (!m) { + handle->sn_coap_protocol_free(msg_ptr); + return NULL; + } + //Init data + memset(m, 0, sizeof(*m) + trail_size); memset(msg_ptr, 0, sizeof(coap_send_msg_s)); - msg_ptr->send_msg_ptr = handle->sn_coap_protocol_malloc(sizeof(sn_nsdl_transmit_s)); + msg_ptr->send_msg_ptr = &m->transmit; + msg_ptr->send_msg_ptr->dst_addr_ptr = &m->addr; - if (msg_ptr->send_msg_ptr == NULL) { - sn_coap_protocol_release_allocated_send_msg_mem(handle, msg_ptr); - return 0; + msg_ptr->send_msg_ptr->dst_addr_ptr->addr_ptr = m->trail_data; + if (packet_data_len) { + msg_ptr->send_msg_ptr->packet_ptr = m->trail_data + dst_addr_ptr->addr_len; } - memset(msg_ptr->send_msg_ptr, 0 , sizeof(sn_nsdl_transmit_s)); - - msg_ptr->send_msg_ptr->dst_addr_ptr = handle->sn_coap_protocol_malloc(sizeof(sn_nsdl_addr_s)); - - if (msg_ptr->send_msg_ptr->dst_addr_ptr == NULL) { - sn_coap_protocol_release_allocated_send_msg_mem(handle, msg_ptr); - return 0; - } - - memset(msg_ptr->send_msg_ptr->dst_addr_ptr, 0, sizeof(sn_nsdl_addr_s)); - - msg_ptr->send_msg_ptr->packet_ptr = handle->sn_coap_protocol_malloc(packet_data_len); - - if (msg_ptr->send_msg_ptr->packet_ptr == NULL) { - sn_coap_protocol_release_allocated_send_msg_mem(handle, msg_ptr); - return 0; - } - - msg_ptr->send_msg_ptr->dst_addr_ptr->addr_ptr = handle->sn_coap_protocol_malloc(dst_addr_ptr->addr_len); - - if (msg_ptr->send_msg_ptr->dst_addr_ptr->addr_ptr == NULL) { - sn_coap_protocol_release_allocated_send_msg_mem(handle, msg_ptr); - return 0; - } - - memset(msg_ptr->send_msg_ptr->dst_addr_ptr->addr_ptr, 0, dst_addr_ptr->addr_len); - return msg_ptr; } @@ -1431,33 +1389,10 @@ coap_send_msg_s *sn_coap_protocol_allocate_mem_for_msg(struct coap_s *handle, sn static void sn_coap_protocol_release_allocated_send_msg_mem(struct coap_s *handle, coap_send_msg_s *freed_send_msg_ptr) { if (freed_send_msg_ptr != NULL) { - if (freed_send_msg_ptr->send_msg_ptr != NULL) { - if (freed_send_msg_ptr->send_msg_ptr->dst_addr_ptr != NULL) { - if (freed_send_msg_ptr->send_msg_ptr->dst_addr_ptr->addr_ptr != NULL) { - handle->sn_coap_protocol_free(freed_send_msg_ptr->send_msg_ptr->dst_addr_ptr->addr_ptr); - freed_send_msg_ptr->send_msg_ptr->dst_addr_ptr->addr_ptr = 0; - } - - handle->sn_coap_protocol_free(freed_send_msg_ptr->send_msg_ptr->dst_addr_ptr); - freed_send_msg_ptr->send_msg_ptr->dst_addr_ptr = 0; - } - - if (freed_send_msg_ptr->send_msg_ptr->packet_ptr != NULL) { - handle->sn_coap_protocol_free(freed_send_msg_ptr->send_msg_ptr->packet_ptr); - freed_send_msg_ptr->send_msg_ptr->packet_ptr = 0; - } - - if (freed_send_msg_ptr->send_msg_ptr->uri_path_ptr != NULL) { - handle->sn_coap_protocol_free(freed_send_msg_ptr->send_msg_ptr->uri_path_ptr); - freed_send_msg_ptr->send_msg_ptr->uri_path_ptr = 0; - } - - handle->sn_coap_protocol_free(freed_send_msg_ptr->send_msg_ptr); - freed_send_msg_ptr->send_msg_ptr = 0; - } - + handle->sn_coap_protocol_free(freed_send_msg_ptr->send_msg_ptr); + freed_send_msg_ptr->send_msg_ptr = NULL; handle->sn_coap_protocol_free(freed_send_msg_ptr); - freed_send_msg_ptr = 0; + freed_send_msg_ptr = NULL; } } @@ -1877,7 +1812,7 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn sn_coap_protocol_linked_list_send_msg_store(handle, src_addr_ptr, dst_packed_data_needed_mem, dst_ack_packet_data_ptr, - handle->system_time + (uint32_t)(handle->sn_coap_resending_intervall * RESPONSE_RANDOM_FACTOR), param, NULL, 0); + handle->system_time + (uint32_t)(handle->sn_coap_resending_intervall * RESPONSE_RANDOM_FACTOR), param); #endif handle->sn_coap_protocol_free(dst_ack_packet_data_ptr); dst_ack_packet_data_ptr = 0;