diff --git a/features/FEATURE_COMMON_PAL/mbed-coap/module.json b/features/FEATURE_COMMON_PAL/mbed-coap/module.json index b581d6bac6..28d37c9f41 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.3", + "version": "4.0.6", "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 dbd161ab81..d3cc664503 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 @@ -71,7 +71,7 @@ struct sn_coap_hdr_; #define SN_COAP_MAX_ALLOWED_RESENDING_BUFF_SIZE_BYTES 512 /**< Maximum allowed size of re-sending buffer */ #define SN_COAP_MAX_ALLOWED_RESPONSE_TIMEOUT 40 /**< Maximum allowed re-sending timeout */ -#define RESPONSE_RANDOM_FACTOR 1 /**< Resending random factor, value is specified in IETF CoAP specification */ +#define RESPONSE_RANDOM_FACTOR 1.5 /**< Resending random factor, value is specified in IETF CoAP specification */ /* * For Message duplication detecting * */ @@ -113,9 +113,12 @@ struct sn_coap_hdr_; #define SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE 0 /**< Must be 2^x and x is at least 4. Suitable values: 0, 16, 32, 64, 128, 256, 512 and 1024 */ #endif +#ifdef MBED_CONF_MBED_CLIENT_SN_COAP_BLOCKWISE_MAX_TIME_DATA_STORED +#define SN_COAP_BLOCKWISE_MAX_TIME_DATA_STORED MBED_CONF_MBED_CLIENT_SN_COAP_BLOCKWISE_MAX_TIME_DATA_STORED +#endif #ifndef SN_COAP_BLOCKWISE_MAX_TIME_DATA_STORED -#define SN_COAP_BLOCKWISE_MAX_TIME_DATA_STORED 10 /**< Maximum time in seconds of data (messages and payload) to be stored for blockwising */ +#define SN_COAP_BLOCKWISE_MAX_TIME_DATA_STORED 60 /**< Maximum time in seconds of data (messages and payload) to be stored for blockwising */ #endif #ifdef YOTTA_CFG_COAP_MAX_INCOMING_BLOCK_MESSAGE_SIZE @@ -156,16 +159,13 @@ typedef NS_LIST_HEAD(coap_send_msg_s, link) coap_send_msg_list_t; /* Structure which is stored to Linked list for message duplication detection purposes */ typedef struct coap_duplication_info_ { uint32_t timestamp; /* Tells when duplication information is stored to Linked list */ - - uint8_t addr_len; - uint8_t *addr_ptr; - uint16_t port; - uint16_t msg_id; - + uint16_t packet_len; + uint8_t *packet_ptr; struct coap_s *coap; /* CoAP library handle */ - - ns_list_link_t link; + sn_nsdl_addr_s *address; + void *param; + ns_list_link_t link; } coap_duplication_info_s; typedef NS_LIST_HEAD(coap_duplication_info_s, link) coap_duplication_info_list_t; 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 8f63f736d7..52a0c59355 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 @@ -280,11 +280,6 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack /* Get option length WITHOUT extensions */ uint16_t option_len = (**packet_data_pptr & 0x0F); - /* Option number length 15 is reserved for the future use - ERROR */ - if (option_len == 15) { - return -1; - } - /* Resolve option delta */ uint16_t option_number = (**packet_data_pptr >> COAP_OPTIONS_OPTION_NUMBER_SHIFT); @@ -313,6 +308,10 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack option_len += (*(*packet_data_pptr + 1) << 8) + 269; (*packet_data_pptr) += 2; } + /* Option number length 15 is reserved for the future use - ERROR */ + else if (option_len == 15) { + return -1; + } message_left = packet_len - (*packet_data_pptr - packet_data_start_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 0cd14b1597..fc643e329a 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 @@ -49,8 +49,8 @@ static void sn_coap_protocol_send_rst(struct coap_s *handle, uint16_t msg_id, sn_nsdl_addr_s *addr_ptr, void *param); #if SN_COAP_DUPLICATION_MAX_MSGS_COUNT/* If Message duplication detection is not used at all, this part of code will not be compiled */ -static void sn_coap_protocol_linked_list_duplication_info_store(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr, uint16_t msg_id); -static int8_t sn_coap_protocol_linked_list_duplication_info_search(struct coap_s *handle, sn_nsdl_addr_s *scr_addr_ptr, uint16_t msg_id); +static void sn_coap_protocol_linked_list_duplication_info_store(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr, uint16_t msg_id, void *param); +static coap_duplication_info_s *sn_coap_protocol_linked_list_duplication_info_search(struct coap_s *handle, sn_nsdl_addr_s *scr_addr_ptr, uint16_t msg_id); static void sn_coap_protocol_linked_list_duplication_info_remove(struct coap_s *handle, uint8_t *scr_addr_ptr, uint16_t port, uint16_t msg_id); static void sn_coap_protocol_linked_list_duplication_info_remove_old_ones(struct coap_s *handle); #endif @@ -73,6 +73,7 @@ static void sn_coap_protocol_linked_list_send_msg_remove(struct 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); static void sn_coap_protocol_release_allocated_send_msg_mem(struct coap_s *handle, coap_send_msg_s *freed_send_msg_ptr); static uint16_t sn_coap_count_linked_list_size(const coap_send_msg_list_t *linked_list_ptr); +static uint32_t sn_coap_calculate_new_resend_time(const uint32_t current_time, const uint8_t interval, const uint8_t counter); #endif /* * * * * * * * * * * * * * * * * */ @@ -94,9 +95,17 @@ int8_t sn_coap_protocol_destroy(struct coap_s *handle) #if SN_COAP_DUPLICATION_MAX_MSGS_COUNT /* If Message duplication detection is not used at all, this part of code will not be compiled */ ns_list_foreach_safe(coap_duplication_info_s, tmp, &handle->linked_list_duplication_msgs) { if (tmp->coap == handle) { - if (tmp->addr_ptr) { - handle->sn_coap_protocol_free(tmp->addr_ptr); - tmp->addr_ptr = 0; + if (tmp->address) { + if (tmp->address->addr_ptr) { + handle->sn_coap_protocol_free(tmp->address->addr_ptr); + tmp->address->addr_ptr = 0; + } + handle->sn_coap_protocol_free(tmp->address); + tmp->address = 0; + } + if (tmp->packet_ptr) { + handle->sn_coap_protocol_free(tmp->packet_ptr); + tmp->packet_ptr = 0; } ns_list_remove(&handle->linked_list_duplication_msgs, tmp); handle->count_duplication_msgs--; @@ -104,8 +113,10 @@ int8_t sn_coap_protocol_destroy(struct coap_s *handle) tmp = 0; } } + #endif + #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwise is not used at all, this part of code will not be compiled */ ns_list_foreach_safe(coap_blockwise_msg_s, tmp, &handle->linked_list_blockwise_sent_msgs) { if (tmp->coap == handle) { @@ -205,6 +216,7 @@ struct coap_s *sn_coap_protocol_init(void *(*used_malloc_func_ptr)(uint16_t), vo message_id = 1; } tr_debug("Coap random msg ID: %d", message_id); + tr_debug("Coap BLOCKWISE_MAX_TIME_DATA_STORED: %d", SN_COAP_BLOCKWISE_MAX_TIME_DATA_STORED); return handle; } @@ -424,8 +436,9 @@ 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 */ + uint32_t resend_time = sn_coap_calculate_new_resend_time(handle->system_time, handle->sn_coap_resending_intervall, 0); 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), + resend_time, param) == 0) { return -4; } @@ -433,6 +446,25 @@ int16_t sn_coap_protocol_build(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_p #endif /* ENABLE_RESENDINGS */ +#if SN_COAP_DUPLICATION_MAX_MSGS_COUNT + if (src_coap_msg_ptr->msg_type == COAP_MSG_TYPE_ACKNOWLEDGEMENT && + handle->sn_coap_duplication_buffer_size != 0) { + coap_duplication_info_s* info = sn_coap_protocol_linked_list_duplication_info_search(handle, + dst_addr_ptr, + src_coap_msg_ptr->msg_id); + /* Update package data to duplication info struct if it's not there yet */ + if (info && info->packet_ptr == NULL) { + info->packet_ptr = handle->sn_coap_protocol_malloc(byte_count_built); + if (info->packet_ptr) { + memcpy(info->packet_ptr, dst_packet_data_ptr, byte_count_built); + info->packet_len = byte_count_built; + } else { + return -4; + } + } + } +#endif + #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwising is not used at all, this part of code will not be compiled */ /* If blockwising needed */ @@ -590,10 +622,10 @@ sn_coap_hdr_s *sn_coap_protocol_parse(struct coap_s *handle, sn_nsdl_addr_s *src /* * * * Manage received CoAP message duplicate detection * * * */ /* If no message duplication detected */ - if (returned_dst_coap_msg_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE || - returned_dst_coap_msg_ptr->msg_type == COAP_MSG_TYPE_NON_CONFIRMABLE) { - - if (sn_coap_protocol_linked_list_duplication_info_search(handle, src_addr_ptr, returned_dst_coap_msg_ptr->msg_id) == -1) { + if ((returned_dst_coap_msg_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE || + returned_dst_coap_msg_ptr->msg_type == COAP_MSG_TYPE_NON_CONFIRMABLE) && + handle->sn_coap_duplication_buffer_size != 0) { + if (sn_coap_protocol_linked_list_duplication_info_search(handle, src_addr_ptr, returned_dst_coap_msg_ptr->msg_id) == NULL) { /* * * No Message duplication: Store received message for detecting later duplication * * */ /* Get count of stored duplication messages */ @@ -605,16 +637,27 @@ sn_coap_hdr_s *sn_coap_protocol_parse(struct coap_s *handle, sn_nsdl_addr_s *src coap_duplication_info_s *stored_duplication_info_ptr = ns_list_get_first(&handle->linked_list_duplication_msgs); /* Remove oldest stored duplication message for getting room for new duplication message */ - sn_coap_protocol_linked_list_duplication_info_remove(handle, stored_duplication_info_ptr->addr_ptr, stored_duplication_info_ptr->port, stored_duplication_info_ptr->msg_id); + sn_coap_protocol_linked_list_duplication_info_remove(handle, + stored_duplication_info_ptr->address->addr_ptr, + stored_duplication_info_ptr->address->port, + stored_duplication_info_ptr->msg_id); } /* Store Duplication info to Linked list */ - sn_coap_protocol_linked_list_duplication_info_store(handle, src_addr_ptr, returned_dst_coap_msg_ptr->msg_id); + sn_coap_protocol_linked_list_duplication_info_store(handle, src_addr_ptr, returned_dst_coap_msg_ptr->msg_id, param); } else { /* * * Message duplication detected * * */ /* Set returned status to User */ returned_dst_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_DUPLICATED_MSG; - // todo: send ACK to confirmable messages - /* Because duplicate message, return with coap_status set */ + coap_duplication_info_s* response = sn_coap_protocol_linked_list_duplication_info_search(handle, + src_addr_ptr, + 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); + + } + return returned_dst_coap_msg_ptr; } } @@ -642,12 +685,14 @@ sn_coap_hdr_s *sn_coap_protocol_parse(struct coap_s *handle, sn_nsdl_addr_s *src /* Remove from the list if not an notification message. * Initial notification message is needed for sending rest of the blocks (GET request). */ - bool remove_from_the_list = true; + bool remove_from_the_list = false; if (stored_blockwise_msg_temp_ptr) { if (stored_blockwise_msg_temp_ptr->coap_msg_ptr && stored_blockwise_msg_temp_ptr->coap_msg_ptr->options_list_ptr && stored_blockwise_msg_temp_ptr->coap_msg_ptr->options_list_ptr->observe != COAP_OBSERVE_NONE) { remove_from_the_list = false; + } else { + remove_from_the_list = true; } } if (remove_from_the_list) { @@ -709,7 +754,6 @@ int8_t sn_coap_protocol_exec(struct coap_s *handle, uint32_t current_time) /* * * * Store current System time * * * */ handle->system_time = current_time; - #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* * * * Remove old blocwise data * * * */ sn_coap_protocol_linked_list_blockwise_remove_old_data(handle); @@ -766,8 +810,9 @@ int8_t sn_coap_protocol_exec(struct coap_s *handle, uint32_t current_time) stored_msg_ptr->send_msg_ptr->packet_len, stored_msg_ptr->send_msg_ptr->dst_addr_ptr, stored_msg_ptr->param); /* * * Count new Resending time * * */ - stored_msg_ptr->resending_time = current_time + (((uint32_t)(handle->sn_coap_resending_intervall * RESPONSE_RANDOM_FACTOR)) << - stored_msg_ptr->resending_counter); + stored_msg_ptr->resending_time = sn_coap_calculate_new_resend_time(current_time, + handle->sn_coap_resending_intervall, + stored_msg_ptr->resending_counter); } } @@ -930,8 +975,15 @@ static void sn_coap_protocol_linked_list_send_msg_remove(struct coap_s *handle, } } } -#endif /* ENABLE_RESENDINGS */ +uint32_t sn_coap_calculate_new_resend_time(const uint32_t current_time, const uint8_t interval, const uint8_t counter) +{ + uint32_t resend_time = interval << counter; + uint16_t random_factor = randLIB_get_random_in_range(100, RESPONSE_RANDOM_FACTOR * 100); + return current_time + ((resend_time * random_factor) / 100); +} + +#endif /* ENABLE_RESENDINGS */ static void sn_coap_protocol_send_rst(struct coap_s *handle, uint16_t msg_id, sn_nsdl_addr_s *addr_ptr, void *param) { @@ -964,7 +1016,7 @@ static void sn_coap_protocol_send_rst(struct coap_s *handle, uint16_t msg_id, sn *****************************************************************************/ static void sn_coap_protocol_linked_list_duplication_info_store(struct coap_s *handle, sn_nsdl_addr_s *addr_ptr, - uint16_t msg_id) + uint16_t msg_id, void *param) { coap_duplication_info_s *stored_duplication_info_ptr = NULL; @@ -976,26 +1028,37 @@ static void sn_coap_protocol_linked_list_duplication_info_store(struct coap_s *h if (stored_duplication_info_ptr == NULL) { return; } + memset(stored_duplication_info_ptr, 0, sizeof(coap_duplication_info_s)); /* Allocate memory for stored Duplication info's address */ - stored_duplication_info_ptr->addr_ptr = handle->sn_coap_protocol_malloc(addr_ptr->addr_len); + stored_duplication_info_ptr->address = handle->sn_coap_protocol_malloc(sizeof(sn_nsdl_addr_s)); + if (stored_duplication_info_ptr->address == NULL) { + handle->sn_coap_protocol_free(stored_duplication_info_ptr); + stored_duplication_info_ptr = 0; + return; + } + memset(stored_duplication_info_ptr->address, 0, sizeof(sn_nsdl_addr_s)); - if (stored_duplication_info_ptr->addr_ptr == NULL) { + stored_duplication_info_ptr->address->addr_ptr = handle->sn_coap_protocol_malloc(addr_ptr->addr_len); + + if (stored_duplication_info_ptr->address->addr_ptr == NULL) { + handle->sn_coap_protocol_free(stored_duplication_info_ptr->address); + stored_duplication_info_ptr->address = 0; handle->sn_coap_protocol_free(stored_duplication_info_ptr); stored_duplication_info_ptr = 0; return; } /* * * * Filling fields of stored Duplication info * * * */ - stored_duplication_info_ptr->timestamp = handle->system_time; - stored_duplication_info_ptr->addr_len = addr_ptr->addr_len; - memcpy(stored_duplication_info_ptr->addr_ptr, addr_ptr->addr_ptr, addr_ptr->addr_len); - stored_duplication_info_ptr->port = addr_ptr->port; + stored_duplication_info_ptr->address->addr_len = addr_ptr->addr_len; + memcpy(stored_duplication_info_ptr->address->addr_ptr, addr_ptr->addr_ptr, addr_ptr->addr_len); + stored_duplication_info_ptr->address->port = addr_ptr->port; stored_duplication_info_ptr->msg_id = msg_id; stored_duplication_info_ptr->coap = handle; + stored_duplication_info_ptr->param = param; /* * * * Storing Duplication info to Linked list * * * */ ns_list_add_to_end(&handle->linked_list_duplication_msgs, stored_duplication_info_ptr); @@ -1013,7 +1076,7 @@ static void sn_coap_protocol_linked_list_duplication_info_store(struct coap_s *h * \return Return value is 0 when message found and -1 if not found *****************************************************************************/ -static int8_t sn_coap_protocol_linked_list_duplication_info_search(struct coap_s *handle, +static coap_duplication_info_s* sn_coap_protocol_linked_list_duplication_info_search(struct coap_s *handle, sn_nsdl_addr_s *addr_ptr, uint16_t msg_id) { /* Loop all nodes in Linked list for searching Message ID */ @@ -1021,17 +1084,16 @@ static int8_t sn_coap_protocol_linked_list_duplication_info_search(struct coap_s /* If message's Message ID is same than is searched */ if (stored_duplication_info_ptr->msg_id == msg_id) { /* If message's Source address is same than is searched */ - if (0 == memcmp(addr_ptr->addr_ptr, stored_duplication_info_ptr->addr_ptr, addr_ptr->addr_len)) { + if (0 == memcmp(addr_ptr->addr_ptr, stored_duplication_info_ptr->address->addr_ptr, addr_ptr->addr_len)) { /* If message's Source address port is same than is searched */ - if (stored_duplication_info_ptr->port == addr_ptr->port) { + if (stored_duplication_info_ptr->address->port == addr_ptr->port) { /* * * Correct Duplication info found * * * */ - return 0; + return stored_duplication_info_ptr; } } } } - - return -1; + return NULL; } /**************************************************************************//** @@ -1051,9 +1113,11 @@ static void sn_coap_protocol_linked_list_duplication_info_remove(struct coap_s * /* Loop all stored duplication messages in Linked list */ ns_list_foreach(coap_duplication_info_s, removed_duplication_info_ptr, &handle->linked_list_duplication_msgs) { /* If message's Address is same than is searched */ - if (handle == removed_duplication_info_ptr->coap && 0 == memcmp(addr_ptr, removed_duplication_info_ptr->addr_ptr, removed_duplication_info_ptr->addr_len)) { + if (handle == removed_duplication_info_ptr->coap && 0 == memcmp(addr_ptr, + removed_duplication_info_ptr->address->addr_ptr, + removed_duplication_info_ptr->address->addr_len)) { /* If message's Address prt is same than is searched */ - if (removed_duplication_info_ptr->port == port) { + if (removed_duplication_info_ptr->address->port == port) { /* If Message ID is same than is searched */ if (removed_duplication_info_ptr->msg_id == msg_id) { /* * * * Correct Duplication info found, remove it from Linked list * * * */ @@ -1061,11 +1125,14 @@ static void sn_coap_protocol_linked_list_duplication_info_remove(struct coap_s * --handle->count_duplication_msgs; /* Free memory of stored Duplication info */ - handle->sn_coap_protocol_free(removed_duplication_info_ptr->addr_ptr); - removed_duplication_info_ptr->addr_ptr = 0; + handle->sn_coap_protocol_free(removed_duplication_info_ptr->address->addr_ptr); + removed_duplication_info_ptr->address->addr_ptr = 0; + handle->sn_coap_protocol_free(removed_duplication_info_ptr->address); + removed_duplication_info_ptr->address = 0; + handle->sn_coap_protocol_free(removed_duplication_info_ptr->packet_ptr); + removed_duplication_info_ptr->packet_ptr = 0; handle->sn_coap_protocol_free(removed_duplication_info_ptr); removed_duplication_info_ptr = 0; - return; } } @@ -1089,8 +1156,12 @@ static void sn_coap_protocol_linked_list_duplication_info_remove_old_ones(struct --handle->count_duplication_msgs; /* Free memory of stored Duplication info */ - handle->sn_coap_protocol_free(removed_duplication_info_ptr->addr_ptr); - removed_duplication_info_ptr->addr_ptr = 0; + handle->sn_coap_protocol_free(removed_duplication_info_ptr->address->addr_ptr); + removed_duplication_info_ptr->address->addr_ptr = 0; + handle->sn_coap_protocol_free(removed_duplication_info_ptr->address); + removed_duplication_info_ptr->address = 0; + handle->sn_coap_protocol_free(removed_duplication_info_ptr->packet_ptr); + removed_duplication_info_ptr->packet_ptr = 0; handle->sn_coap_protocol_free(removed_duplication_info_ptr); removed_duplication_info_ptr = 0; } @@ -1819,10 +1890,11 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn dst_packed_data_needed_mem, src_addr_ptr, param); #if ENABLE_RESENDINGS + uint32_t resend_time = sn_coap_calculate_new_resend_time(handle->system_time, handle->sn_coap_resending_intervall, 0); 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); + resend_time, param); #endif handle->sn_coap_protocol_free(dst_ack_packet_data_ptr); dst_ack_packet_data_ptr = 0;