Merge pull request #4455 from anttiylitokola/master

mbed-coap fixes
pull/4466/head
Anna Bridge 2017-06-06 15:53:38 +01:00 committed by GitHub
commit 8d6bc1d47d
4 changed files with 127 additions and 56 deletions

View File

@ -1,6 +1,6 @@
{
"name": "mbed-coap",
"version": "4.0.3",
"version": "4.0.6",
"description": "COAP library",
"keywords": [
"coap",

View File

@ -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;

View File

@ -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);

View File

@ -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;