version of nsdl to work with lwm2m, updated RD parameters and location option handling

Dependents:   ArchPro_LWM2M_LED_Client Weather_Station_LWM2M mbedEndpointNetwork

Fork of nanoservice_client_1_12 by Zach Shelby

Committer:
michaeljkoster
Date:
Mon Apr 13 22:13:40 2015 +0000
Revision:
10:b5ecd6660d71
Parent:
0:aafd54b05111
Add error return from sn_nsdl_register_endpoint() in sn_nsdl.c

Who changed what in which revision?

UserRevisionLine numberNew contents of line
zdshelby 0:aafd54b05111 1 /**
zdshelby 0:aafd54b05111 2 * \file sn_coap_protocol.c
zdshelby 0:aafd54b05111 3 *
zdshelby 0:aafd54b05111 4 * \brief CoAP Protocol implementation
zdshelby 0:aafd54b05111 5 *
zdshelby 0:aafd54b05111 6 * Functionality: CoAP Protocol
zdshelby 0:aafd54b05111 7 *
zdshelby 0:aafd54b05111 8 * Created on: Jul 19, 2011
zdshelby 0:aafd54b05111 9 * Author: tero
zdshelby 0:aafd54b05111 10 *
zdshelby 0:aafd54b05111 11 * \note Supports draft-ietf-core-coap-18
zdshelby 0:aafd54b05111 12 */
zdshelby 0:aafd54b05111 13
zdshelby 0:aafd54b05111 14
zdshelby 0:aafd54b05111 15 /* * * * * * * * * * * * * * */
zdshelby 0:aafd54b05111 16 /* * * * INCLUDE FILES * * * */
zdshelby 0:aafd54b05111 17 /* * * * * * * * * * * * * * */
zdshelby 0:aafd54b05111 18
zdshelby 0:aafd54b05111 19 #include <stdio.h>
zdshelby 0:aafd54b05111 20 #include <stdint.h>
zdshelby 0:aafd54b05111 21 #include <stdlib.h> /* For libary malloc() */
zdshelby 0:aafd54b05111 22 #include <string.h> /* For memset() and memcpy() */
zdshelby 0:aafd54b05111 23 #ifndef REAL_EMBEDDED
zdshelby 0:aafd54b05111 24 #include <time.h>
zdshelby 0:aafd54b05111 25 #endif
zdshelby 0:aafd54b05111 26
zdshelby 0:aafd54b05111 27 #include "nsdl_types.h"
zdshelby 0:aafd54b05111 28 #include "sn_nsdl.h"
zdshelby 0:aafd54b05111 29 #include "sn_coap_header.h"
zdshelby 0:aafd54b05111 30 #include "sn_coap_protocol.h"
zdshelby 0:aafd54b05111 31 #include "sn_coap_header_internal.h"
zdshelby 0:aafd54b05111 32 #include "sn_coap_protocol_internal.h"
zdshelby 0:aafd54b05111 33 #include "sn_linked_list.h"
zdshelby 0:aafd54b05111 34
zdshelby 0:aafd54b05111 35 /* * * * * * * * * * * * * * * * * * * * */
zdshelby 0:aafd54b05111 36 /* * * * LOCAL FUNCTION PROTOTYPES * * * */
zdshelby 0:aafd54b05111 37 /* * * * * * * * * * * * * * * * * * * * */
zdshelby 0:aafd54b05111 38
zdshelby 0:aafd54b05111 39
zdshelby 0:aafd54b05111 40 static void sn_coap_protocol_linked_list_ack_info_store(uint16_t msg_id, uint8_t token_len, uint8_t *token_ptr, sn_nsdl_addr_s *addr_ptr);
zdshelby 0:aafd54b05111 41 static int32_t sn_coap_protocol_linked_list_ack_info_search(uint16_t msg_id, uint8_t token_len, uint8_t *token_ptr, sn_nsdl_addr_s *addr_ptr);
zdshelby 0:aafd54b05111 42 static void sn_coap_protocol_linked_list_ack_info_remove(uint16_t msg_id, sn_nsdl_addr_s *addr_ptr);
zdshelby 0:aafd54b05111 43 static void sn_coap_protocol_linked_list_ack_info_remove_old_ones(void);
zdshelby 0:aafd54b05111 44 static void sn_coap_protocol_send_rst(uint16_t msg_id, sn_nsdl_addr_s *addr_ptr);
zdshelby 0:aafd54b05111 45 #if SN_COAP_DUPLICATION_MAX_MSGS_COUNT /* If Message duplication detection is not used at all, this part of code will not be compiled */
zdshelby 0:aafd54b05111 46 static void sn_coap_protocol_linked_list_duplication_info_store(sn_nsdl_addr_s *src_addr_ptr, uint16_t msg_id);
zdshelby 0:aafd54b05111 47 static int8_t sn_coap_protocol_linked_list_duplication_info_search(sn_nsdl_addr_s *scr_addr_ptr, uint16_t msg_id);
zdshelby 0:aafd54b05111 48 static void sn_coap_protocol_linked_list_duplication_info_remove(uint8_t *scr_addr_ptr, uint16_t port, uint16_t msg_id);
zdshelby 0:aafd54b05111 49 static void sn_coap_protocol_linked_list_duplication_info_remove_old_ones(void);
zdshelby 0:aafd54b05111 50 #endif
zdshelby 0:aafd54b05111 51 #if SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE /* If Message blockwising is not used at all, this part of code will not be compiled */
zdshelby 0:aafd54b05111 52 static void sn_coap_protocol_linked_list_blockwise_msg_remove_current();
zdshelby 0:aafd54b05111 53 static void sn_coap_protocol_linked_list_blockwise_payload_store(sn_nsdl_addr_s *addr_ptr, uint16_t stored_payload_len, uint8_t *stored_payload_ptr);
zdshelby 0:aafd54b05111 54 static uint8_t *sn_coap_protocol_linked_list_blockwise_payload_search(sn_nsdl_addr_s *src_addr_ptr, uint16_t *payload_length);
zdshelby 0:aafd54b05111 55 static void sn_coap_protocol_linked_list_blockwise_payload_remove_oldest();
zdshelby 0:aafd54b05111 56 static uint16_t sn_coap_protocol_linked_list_blockwise_payloads_get_len(sn_nsdl_addr_s *src_addr_ptr);
zdshelby 0:aafd54b05111 57 static void sn_coap_protocol_linked_list_blockwise_remove_old_data(void);
zdshelby 0:aafd54b05111 58 static sn_coap_hdr_s *sn_coap_handle_blockwise_message(sn_nsdl_addr_s *src_addr_ptr, sn_coap_hdr_s *received_coap_msg_ptr);
zdshelby 0:aafd54b05111 59 static int8_t sn_coap_convert_block_size(uint16_t block_size);
zdshelby 0:aafd54b05111 60 static sn_coap_hdr_s *sn_coap_protocol_copy_header(sn_coap_hdr_s *source_header_ptr);
zdshelby 0:aafd54b05111 61 #endif
zdshelby 0:aafd54b05111 62 #if ENABLE_RESENDINGS
zdshelby 0:aafd54b05111 63 static sn_nsdl_transmit_s *sn_coap_protocol_build_msg(void *src_msg_ptr);
zdshelby 0:aafd54b05111 64 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);
zdshelby 0:aafd54b05111 65 static sn_nsdl_transmit_s *sn_coap_protocol_linked_list_send_msg_search(sn_nsdl_addr_s *src_addr_ptr, uint16_t msg_id);
zdshelby 0:aafd54b05111 66 static void sn_coap_protocol_linked_list_send_msg_remove(sn_nsdl_addr_s *src_addr_ptr, uint16_t msg_id);
zdshelby 0:aafd54b05111 67 static coap_send_msg_s *sn_coap_protocol_allocate_mem_for_msg(sn_nsdl_addr_s *dst_addr_ptr, uint16_t packet_data_len);
zdshelby 0:aafd54b05111 68 static void sn_coap_protocol_release_allocated_send_msg_mem(coap_send_msg_s *freed_send_msg_ptr);
zdshelby 0:aafd54b05111 69 static uint16_t sn_coap_count_linked_list_size(sn_linked_list_t *linked_list_ptr);
zdshelby 0:aafd54b05111 70 #endif
zdshelby 0:aafd54b05111 71 static void coap_protocol_free_lists(void);
zdshelby 0:aafd54b05111 72
zdshelby 0:aafd54b05111 73 /* * * * * * * * * * * * * * * * * */
zdshelby 0:aafd54b05111 74 /* * * * GLOBAL DECLARATIONS * * * */
zdshelby 0:aafd54b05111 75 /* * * * * * * * * * * * * * * * * */
zdshelby 0:aafd54b05111 76
zdshelby 0:aafd54b05111 77 #if ENABLE_RESENDINGS /* If Message resending is not used at all, this part of code will not be compiled */
zdshelby 0:aafd54b05111 78 static sn_linked_list_t *global_linked_list_resent_msgs_ptr = NULL; /* Active resending messages are stored to this Linked list */
zdshelby 0:aafd54b05111 79 #endif
zdshelby 0:aafd54b05111 80 static sn_linked_list_t *global_linked_list_ack_info_ptr = NULL; /* Message Acknowledgement info is stored to this Linked list */
zdshelby 0:aafd54b05111 81 #if SN_COAP_DUPLICATION_MAX_MSGS_COUNT /* If Message duplication detection is not used at all, this part of code will not be compiled */
zdshelby 0:aafd54b05111 82 static sn_linked_list_t *global_linked_list_duplication_msgs_ptr = NULL; /* Messages for duplicated messages detection is stored to this Linked list */
zdshelby 0:aafd54b05111 83 #endif
zdshelby 0:aafd54b05111 84 #if SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE /* If Message blockwise is not used at all, this part of code will not be compiled */
zdshelby 0:aafd54b05111 85 static sn_linked_list_t *global_linked_list_blockwise_sent_msgs_ptr = NULL; /* Blockwise message to to be sent is stored to this Linked list */
zdshelby 0:aafd54b05111 86 static sn_linked_list_t *global_linked_list_blockwise_received_payloads_ptr = NULL; /* Blockwise payload to to be received is stored to this Linked list */
zdshelby 0:aafd54b05111 87 #endif
zdshelby 0:aafd54b05111 88
zdshelby 0:aafd54b05111 89 static uint16_t global_message_id = 100; /* Increasing Message ID which is written to CoAP message header in building */
zdshelby 0:aafd54b05111 90 static uint32_t global_system_time = 0; /* System time seconds */
zdshelby 0:aafd54b05111 91
zdshelby 0:aafd54b05111 92
zdshelby 0:aafd54b05111 93 uint16_t sn_coap_block_data_size = 0;
zdshelby 0:aafd54b05111 94
zdshelby 0:aafd54b05111 95 uint8_t sn_coap_resending_queue_msgs = 0;
zdshelby 0:aafd54b05111 96 uint8_t sn_coap_resending_queue_bytes = 0;
zdshelby 0:aafd54b05111 97 uint8_t sn_coap_resending_count = 0;
zdshelby 0:aafd54b05111 98 uint8_t sn_coap_resending_intervall = 0;
zdshelby 0:aafd54b05111 99
zdshelby 0:aafd54b05111 100 uint8_t sn_coap_duplication_buffer_size = 0;
zdshelby 0:aafd54b05111 101
zdshelby 0:aafd54b05111 102
zdshelby 0:aafd54b05111 103 static void *(*sn_coap_protocol_malloc)(uint16_t) = NULL; /* Function pointer for used malloc() function */
zdshelby 0:aafd54b05111 104 static void (*sn_coap_protocol_free)(void*) = NULL; /* Function pointer for used free() function */
zdshelby 0:aafd54b05111 105 static uint8_t (*sn_coap_tx_callback)(sn_nsdl_capab_e , uint8_t *, uint16_t, sn_nsdl_addr_s *) = NULL;
zdshelby 0:aafd54b05111 106
zdshelby 0:aafd54b05111 107
zdshelby 0:aafd54b05111 108 static uint8_t resource_path_ptr[] = {'r','d'};
zdshelby 0:aafd54b05111 109 static uint8_t ep_name_parameter_string[] = {'h','='};
zdshelby 0:aafd54b05111 110 static uint8_t resource_type_parameter[] = {'r','t','='};
zdshelby 0:aafd54b05111 111
zdshelby 0:aafd54b05111 112 /**
zdshelby 0:aafd54b05111 113 * \fn int8_t sn_coap_register(sn_coap_hdr_s *coap_hdr_ptr, registration_info_t *endpoint_info_ptr)
zdshelby 0:aafd54b05111 114 *
zdshelby 0:aafd54b05111 115 * \brief Builds RD registrtion request packet
zdshelby 0:aafd54b05111 116 *
zdshelby 0:aafd54b05111 117 * \param *coap_hdr_ptr is destination for built Packet data
zdshelby 0:aafd54b05111 118 * \param *endpoint_info_ptr pointer to struct that contains endpoint info parameters
zdshelby 0:aafd54b05111 119 *
zdshelby 0:aafd54b05111 120 * \return Return value 0 given on success. In failure cases:\n
zdshelby 0:aafd54b05111 121 * -1 = Failure
zdshelby 0:aafd54b05111 122 */
zdshelby 0:aafd54b05111 123
zdshelby 0:aafd54b05111 124 int8_t sn_coap_register(sn_coap_hdr_s *coap_hdr_ptr, registration_info_t *endpoint_info_ptr)
zdshelby 0:aafd54b05111 125 {
zdshelby 0:aafd54b05111 126 uint8_t *temp_ptr;
zdshelby 0:aafd54b05111 127
zdshelby 0:aafd54b05111 128 coap_hdr_ptr->msg_code = COAP_MSG_CODE_REQUEST_POST;
zdshelby 0:aafd54b05111 129 coap_hdr_ptr->msg_type = COAP_MSG_TYPE_CONFIRMABLE;
zdshelby 0:aafd54b05111 130 coap_hdr_ptr->msg_id = global_message_id++;
zdshelby 0:aafd54b05111 131
zdshelby 0:aafd54b05111 132 coap_hdr_ptr->uri_path_len = sizeof(resource_path_ptr);
zdshelby 0:aafd54b05111 133 coap_hdr_ptr->uri_path_ptr = resource_path_ptr;
zdshelby 0:aafd54b05111 134
zdshelby 0:aafd54b05111 135 /* Payload copy */
zdshelby 0:aafd54b05111 136 coap_hdr_ptr->payload_len = endpoint_info_ptr->links_len;
zdshelby 0:aafd54b05111 137 coap_hdr_ptr->payload_ptr = sn_coap_protocol_malloc(coap_hdr_ptr->payload_len);
zdshelby 0:aafd54b05111 138 if(!coap_hdr_ptr->payload_ptr)
zdshelby 0:aafd54b05111 139 return -1;
zdshelby 0:aafd54b05111 140 memcpy(coap_hdr_ptr->payload_ptr, endpoint_info_ptr->links_ptr, coap_hdr_ptr->payload_len);
zdshelby 0:aafd54b05111 141
zdshelby 0:aafd54b05111 142 /* Options allocation */
zdshelby 0:aafd54b05111 143 if(!coap_hdr_ptr->options_list_ptr)
zdshelby 0:aafd54b05111 144 {
zdshelby 0:aafd54b05111 145 coap_hdr_ptr->options_list_ptr = sn_coap_protocol_malloc(sizeof(sn_coap_options_list_s));
zdshelby 0:aafd54b05111 146 if(!coap_hdr_ptr->options_list_ptr)
zdshelby 0:aafd54b05111 147 {
zdshelby 0:aafd54b05111 148 sn_coap_protocol_free(coap_hdr_ptr->payload_ptr);
zdshelby 0:aafd54b05111 149 return -1;
zdshelby 0:aafd54b05111 150 }
zdshelby 0:aafd54b05111 151 }
zdshelby 0:aafd54b05111 152 memset(coap_hdr_ptr->options_list_ptr, 0, sizeof(sn_coap_options_list_s));
zdshelby 0:aafd54b05111 153
zdshelby 0:aafd54b05111 154 /* Uri query filling */
zdshelby 0:aafd54b05111 155 coap_hdr_ptr->options_list_ptr->uri_query_len = sizeof(ep_name_parameter_string) + endpoint_info_ptr->endpoint_len +
zdshelby 0:aafd54b05111 156 sizeof(resource_type_parameter) + endpoint_info_ptr->endpoint_type_len + 1; // + 1 for '&'
zdshelby 0:aafd54b05111 157
zdshelby 0:aafd54b05111 158 coap_hdr_ptr->options_list_ptr->uri_query_ptr = sn_coap_protocol_malloc(coap_hdr_ptr->options_list_ptr->uri_query_len);
zdshelby 0:aafd54b05111 159 if(!coap_hdr_ptr->options_list_ptr->uri_query_ptr)
zdshelby 0:aafd54b05111 160 {
zdshelby 0:aafd54b05111 161 sn_coap_protocol_free(coap_hdr_ptr->options_list_ptr);
zdshelby 0:aafd54b05111 162 sn_coap_protocol_free(coap_hdr_ptr->payload_ptr);
zdshelby 0:aafd54b05111 163 return -1;
zdshelby 0:aafd54b05111 164 }
zdshelby 0:aafd54b05111 165
zdshelby 0:aafd54b05111 166 temp_ptr = coap_hdr_ptr->options_list_ptr->uri_query_ptr;
zdshelby 0:aafd54b05111 167
zdshelby 0:aafd54b05111 168 memcpy(temp_ptr, ep_name_parameter_string, sizeof(ep_name_parameter_string));
zdshelby 0:aafd54b05111 169 temp_ptr += sizeof(ep_name_parameter_string);
zdshelby 0:aafd54b05111 170
zdshelby 0:aafd54b05111 171 memcpy(temp_ptr, endpoint_info_ptr->endpoint_ptr, endpoint_info_ptr->endpoint_len);
zdshelby 0:aafd54b05111 172 temp_ptr += endpoint_info_ptr->endpoint_len;
zdshelby 0:aafd54b05111 173
zdshelby 0:aafd54b05111 174 *temp_ptr++ = '&';
zdshelby 0:aafd54b05111 175
zdshelby 0:aafd54b05111 176 memcpy(temp_ptr, resource_type_parameter, sizeof(resource_type_parameter));
zdshelby 0:aafd54b05111 177 temp_ptr += sizeof(resource_type_parameter);
zdshelby 0:aafd54b05111 178
zdshelby 0:aafd54b05111 179 memcpy(temp_ptr, endpoint_info_ptr->endpoint_type_ptr, endpoint_info_ptr->endpoint_type_len);
zdshelby 0:aafd54b05111 180 temp_ptr += endpoint_info_ptr->endpoint_type_len;
zdshelby 0:aafd54b05111 181
zdshelby 0:aafd54b05111 182 return 0;
zdshelby 0:aafd54b05111 183 }
zdshelby 0:aafd54b05111 184
zdshelby 0:aafd54b05111 185 /**
zdshelby 0:aafd54b05111 186 * \fn int8_t sn_coap_register_update(sn_coap_hdr_s *coap_hdr_ptr, uint8_t *location, uint8_t length)
zdshelby 0:aafd54b05111 187 *
zdshelby 0:aafd54b05111 188 * \brief Builds RD update request packet
zdshelby 0:aafd54b05111 189 *
zdshelby 0:aafd54b05111 190 * \param *coap_hdr_ptr is destination for built Packet data
zdshelby 0:aafd54b05111 191 * \param *location The location returned when registering with the RD
zdshelby 0:aafd54b05111 192 * \param length length of the location
zdshelby 0:aafd54b05111 193 *
zdshelby 0:aafd54b05111 194 * \return Return value 0 given on success. In failure cases:\n
zdshelby 0:aafd54b05111 195 * -1 = Failure
zdshelby 0:aafd54b05111 196 */
zdshelby 0:aafd54b05111 197
zdshelby 0:aafd54b05111 198 int8_t sn_coap_register_update(sn_coap_hdr_s *coap_hdr_ptr, uint8_t *location, uint8_t length)
zdshelby 0:aafd54b05111 199 {
zdshelby 0:aafd54b05111 200 coap_hdr_ptr->msg_code = COAP_MSG_CODE_REQUEST_PUT;
zdshelby 0:aafd54b05111 201 coap_hdr_ptr->msg_type = COAP_MSG_TYPE_CONFIRMABLE;
zdshelby 0:aafd54b05111 202 coap_hdr_ptr->msg_id = global_message_id++;
zdshelby 0:aafd54b05111 203 coap_hdr_ptr->uri_path_len = length;
zdshelby 0:aafd54b05111 204 coap_hdr_ptr->uri_path_ptr = location;
zdshelby 0:aafd54b05111 205
zdshelby 0:aafd54b05111 206 return 0;
zdshelby 0:aafd54b05111 207 }
zdshelby 0:aafd54b05111 208
zdshelby 0:aafd54b05111 209 /**
zdshelby 0:aafd54b05111 210 * \fn int8_t sn_coap_deregister(sn_coap_hdr_s *coap_hdr_ptr, uint8_t *location, uint8_t length)
zdshelby 0:aafd54b05111 211 *
zdshelby 0:aafd54b05111 212 * \brief Builds RD de-registrtion request packet
zdshelby 0:aafd54b05111 213 *
zdshelby 0:aafd54b05111 214 * \param *coap_hdr_ptr is destination for built Packet data
zdshelby 0:aafd54b05111 215 * \param *location The location returned when registering with the RD
zdshelby 0:aafd54b05111 216 * \param length length of the location
zdshelby 0:aafd54b05111 217 *
zdshelby 0:aafd54b05111 218 * \return Return value 0 given on success. In failure cases:\n
zdshelby 0:aafd54b05111 219 * -1 = Failure
zdshelby 0:aafd54b05111 220 */
zdshelby 0:aafd54b05111 221
zdshelby 0:aafd54b05111 222 int8_t sn_coap_deregister(sn_coap_hdr_s *coap_hdr_ptr, uint8_t *location, uint8_t length)
zdshelby 0:aafd54b05111 223 {
zdshelby 0:aafd54b05111 224 coap_hdr_ptr->msg_code = COAP_MSG_CODE_REQUEST_DELETE;
zdshelby 0:aafd54b05111 225 coap_hdr_ptr->msg_type = COAP_MSG_TYPE_CONFIRMABLE;
zdshelby 0:aafd54b05111 226 coap_hdr_ptr->msg_id = global_message_id++;
zdshelby 0:aafd54b05111 227 coap_hdr_ptr->uri_path_len = length;
zdshelby 0:aafd54b05111 228 coap_hdr_ptr->uri_path_ptr = location;
zdshelby 0:aafd54b05111 229
zdshelby 0:aafd54b05111 230 return 0;
zdshelby 0:aafd54b05111 231 }
zdshelby 0:aafd54b05111 232
zdshelby 0:aafd54b05111 233 /**
zdshelby 0:aafd54b05111 234 * \fn int8_t sn_coap_protocol_destroy(void)
zdshelby 0:aafd54b05111 235 *
zdshelby 0:aafd54b05111 236 * \brief Frees all memory from CoAP protocol part
zdshelby 0:aafd54b05111 237 *
zdshelby 0:aafd54b05111 238 * \return Return value is always 0
zdshelby 0:aafd54b05111 239 */
zdshelby 0:aafd54b05111 240
zdshelby 0:aafd54b05111 241 int8_t sn_coap_protocol_destroy(void)
zdshelby 0:aafd54b05111 242 {
zdshelby 0:aafd54b05111 243 #if ENABLE_RESENDINGS /* If Message resending is not used at all, this part of code will not be compiled */
zdshelby 0:aafd54b05111 244 if(global_linked_list_resent_msgs_ptr)
zdshelby 0:aafd54b05111 245 {
zdshelby 0:aafd54b05111 246 uint16_t size = sn_linked_list_count_nodes(global_linked_list_resent_msgs_ptr);
zdshelby 0:aafd54b05111 247 uint16_t i = 0;
zdshelby 0:aafd54b05111 248 coap_send_msg_s*tmp;
zdshelby 0:aafd54b05111 249 for(i=0;i<size;i++)
zdshelby 0:aafd54b05111 250 {
zdshelby 0:aafd54b05111 251 tmp = sn_linked_list_get_first_node(global_linked_list_resent_msgs_ptr);
zdshelby 0:aafd54b05111 252
zdshelby 0:aafd54b05111 253 if(tmp)
zdshelby 0:aafd54b05111 254 {
zdshelby 0:aafd54b05111 255 if(tmp->send_msg_ptr)
zdshelby 0:aafd54b05111 256 {
zdshelby 0:aafd54b05111 257 if(tmp->send_msg_ptr->dst_addr_ptr)
zdshelby 0:aafd54b05111 258 {
zdshelby 0:aafd54b05111 259 if(tmp->send_msg_ptr->dst_addr_ptr->addr_ptr)
zdshelby 0:aafd54b05111 260 {
zdshelby 0:aafd54b05111 261 sn_coap_protocol_free(tmp->send_msg_ptr->dst_addr_ptr->addr_ptr);
zdshelby 0:aafd54b05111 262 tmp->send_msg_ptr->dst_addr_ptr->addr_ptr = 0;
zdshelby 0:aafd54b05111 263 }
zdshelby 0:aafd54b05111 264 if(tmp->send_msg_ptr->dst_addr_ptr->socket_information)
zdshelby 0:aafd54b05111 265 {
zdshelby 0:aafd54b05111 266 sn_coap_protocol_free(tmp->send_msg_ptr->dst_addr_ptr->socket_information);
zdshelby 0:aafd54b05111 267 tmp->send_msg_ptr->dst_addr_ptr->socket_information = 0;
zdshelby 0:aafd54b05111 268 }
zdshelby 0:aafd54b05111 269 sn_coap_protocol_free(tmp->send_msg_ptr->dst_addr_ptr);
zdshelby 0:aafd54b05111 270 tmp->send_msg_ptr->dst_addr_ptr = 0;
zdshelby 0:aafd54b05111 271 }
zdshelby 0:aafd54b05111 272 if(tmp->send_msg_ptr->packet_ptr)
zdshelby 0:aafd54b05111 273 {
zdshelby 0:aafd54b05111 274 sn_coap_protocol_free(tmp->send_msg_ptr->packet_ptr);
zdshelby 0:aafd54b05111 275 tmp->send_msg_ptr->packet_ptr = 0;
zdshelby 0:aafd54b05111 276 }
zdshelby 0:aafd54b05111 277 sn_coap_protocol_free(tmp->send_msg_ptr);
zdshelby 0:aafd54b05111 278 tmp->send_msg_ptr = 0;
zdshelby 0:aafd54b05111 279 }
zdshelby 0:aafd54b05111 280 sn_linked_list_remove_current_node(global_linked_list_resent_msgs_ptr);
zdshelby 0:aafd54b05111 281 sn_coap_protocol_free(tmp);
zdshelby 0:aafd54b05111 282 tmp = 0;
zdshelby 0:aafd54b05111 283 }
zdshelby 0:aafd54b05111 284 }
zdshelby 0:aafd54b05111 285
zdshelby 0:aafd54b05111 286 if(!sn_linked_list_count_nodes(global_linked_list_resent_msgs_ptr))
zdshelby 0:aafd54b05111 287 {
zdshelby 0:aafd54b05111 288 sn_coap_protocol_free(global_linked_list_resent_msgs_ptr);
zdshelby 0:aafd54b05111 289 global_linked_list_resent_msgs_ptr = 0;
zdshelby 0:aafd54b05111 290 }
zdshelby 0:aafd54b05111 291 }
zdshelby 0:aafd54b05111 292 #endif
zdshelby 0:aafd54b05111 293
zdshelby 0:aafd54b05111 294 if(global_linked_list_ack_info_ptr)
zdshelby 0:aafd54b05111 295 {
zdshelby 0:aafd54b05111 296 uint16_t size = sn_linked_list_count_nodes(global_linked_list_ack_info_ptr);
zdshelby 0:aafd54b05111 297 uint16_t i = 0;
zdshelby 0:aafd54b05111 298 coap_ack_info_s*tmp;
zdshelby 0:aafd54b05111 299
zdshelby 0:aafd54b05111 300 for(i=0;i<size;i++)
zdshelby 0:aafd54b05111 301 {
zdshelby 0:aafd54b05111 302 tmp = sn_linked_list_get_first_node(global_linked_list_ack_info_ptr);
zdshelby 0:aafd54b05111 303
zdshelby 0:aafd54b05111 304 if(tmp)
zdshelby 0:aafd54b05111 305 {
zdshelby 0:aafd54b05111 306 if(tmp->token_ptr)
zdshelby 0:aafd54b05111 307 {
zdshelby 0:aafd54b05111 308 sn_coap_protocol_free(tmp->token_ptr);
zdshelby 0:aafd54b05111 309 tmp->token_ptr = 0;
zdshelby 0:aafd54b05111 310 }
zdshelby 0:aafd54b05111 311 if(tmp->addr_ptr)
zdshelby 0:aafd54b05111 312 {
zdshelby 0:aafd54b05111 313 sn_coap_protocol_free(tmp->addr_ptr);
zdshelby 0:aafd54b05111 314 tmp->addr_ptr = 0;
zdshelby 0:aafd54b05111 315 }
zdshelby 0:aafd54b05111 316 sn_linked_list_remove_current_node(global_linked_list_ack_info_ptr);
zdshelby 0:aafd54b05111 317 sn_coap_protocol_free(tmp);
zdshelby 0:aafd54b05111 318 tmp = 0;
zdshelby 0:aafd54b05111 319 }
zdshelby 0:aafd54b05111 320 }
zdshelby 0:aafd54b05111 321
zdshelby 0:aafd54b05111 322 if(!sn_linked_list_count_nodes(global_linked_list_ack_info_ptr))
zdshelby 0:aafd54b05111 323 {
zdshelby 0:aafd54b05111 324 sn_coap_protocol_free(global_linked_list_ack_info_ptr);
zdshelby 0:aafd54b05111 325 global_linked_list_ack_info_ptr = 0;
zdshelby 0:aafd54b05111 326 }
zdshelby 0:aafd54b05111 327 }
zdshelby 0:aafd54b05111 328
zdshelby 0:aafd54b05111 329 #if SN_COAP_DUPLICATION_MAX_MSGS_COUNT /* If Message duplication detection is not used at all, this part of code will not be compiled */
zdshelby 0:aafd54b05111 330 if(global_linked_list_duplication_msgs_ptr)
zdshelby 0:aafd54b05111 331 {
zdshelby 0:aafd54b05111 332
zdshelby 0:aafd54b05111 333 }
zdshelby 0:aafd54b05111 334 #endif
zdshelby 0:aafd54b05111 335
zdshelby 0:aafd54b05111 336 #if SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE /* If Message blockwise is not used at all, this part of code will not be compiled */
zdshelby 0:aafd54b05111 337 if(global_linked_list_blockwise_sent_msgs_ptr)
zdshelby 0:aafd54b05111 338 {
zdshelby 0:aafd54b05111 339
zdshelby 0:aafd54b05111 340 }
zdshelby 0:aafd54b05111 341 if(global_linked_list_blockwise_received_payloads_ptr)
zdshelby 0:aafd54b05111 342 {
zdshelby 0:aafd54b05111 343
zdshelby 0:aafd54b05111 344 }
zdshelby 0:aafd54b05111 345 #endif
zdshelby 0:aafd54b05111 346 return 0;
zdshelby 0:aafd54b05111 347 }
zdshelby 0:aafd54b05111 348
zdshelby 0:aafd54b05111 349
zdshelby 0:aafd54b05111 350
zdshelby 0:aafd54b05111 351 void coap_protocol_free_lists(void)
zdshelby 0:aafd54b05111 352 {
zdshelby 0:aafd54b05111 353 #if ENABLE_RESENDINGS
zdshelby 0:aafd54b05111 354 if(NULL != global_linked_list_resent_msgs_ptr)
zdshelby 0:aafd54b05111 355 {
zdshelby 0:aafd54b05111 356 sn_linked_list_free(global_linked_list_resent_msgs_ptr);
zdshelby 0:aafd54b05111 357 global_linked_list_resent_msgs_ptr = NULL;
zdshelby 0:aafd54b05111 358 }
zdshelby 0:aafd54b05111 359 #endif
zdshelby 0:aafd54b05111 360 if(NULL != global_linked_list_ack_info_ptr)
zdshelby 0:aafd54b05111 361 {
zdshelby 0:aafd54b05111 362 sn_linked_list_free(global_linked_list_ack_info_ptr);
zdshelby 0:aafd54b05111 363 global_linked_list_ack_info_ptr = NULL;
zdshelby 0:aafd54b05111 364 }
zdshelby 0:aafd54b05111 365 #if SN_COAP_DUPLICATION_MAX_MSGS_COUNT
zdshelby 0:aafd54b05111 366 if(NULL != global_linked_list_duplication_msgs_ptr)
zdshelby 0:aafd54b05111 367 {
zdshelby 0:aafd54b05111 368 sn_linked_list_free(global_linked_list_duplication_msgs_ptr);
zdshelby 0:aafd54b05111 369 global_linked_list_duplication_msgs_ptr = NULL;
zdshelby 0:aafd54b05111 370 }
zdshelby 0:aafd54b05111 371 #endif
zdshelby 0:aafd54b05111 372 #if SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE
zdshelby 0:aafd54b05111 373 if(NULL != global_linked_list_blockwise_sent_msgs_ptr)
zdshelby 0:aafd54b05111 374 {
zdshelby 0:aafd54b05111 375 sn_linked_list_free(global_linked_list_blockwise_sent_msgs_ptr);
zdshelby 0:aafd54b05111 376 global_linked_list_blockwise_sent_msgs_ptr = NULL;
zdshelby 0:aafd54b05111 377 }
zdshelby 0:aafd54b05111 378 if(NULL != global_linked_list_blockwise_received_payloads_ptr)
zdshelby 0:aafd54b05111 379 {
zdshelby 0:aafd54b05111 380 sn_linked_list_free(global_linked_list_blockwise_received_payloads_ptr);
zdshelby 0:aafd54b05111 381 global_linked_list_blockwise_received_payloads_ptr = NULL;
zdshelby 0:aafd54b05111 382 }
zdshelby 0:aafd54b05111 383 #endif
zdshelby 0:aafd54b05111 384
zdshelby 0:aafd54b05111 385 }
zdshelby 0:aafd54b05111 386
zdshelby 0:aafd54b05111 387 /**************************************************************************//**
zdshelby 0:aafd54b05111 388 * \fn int8_t sn_coap_protocol_init(void* (*used_malloc_func_ptr)(uint16_t), void (*used_free_func_ptr)(void*),
zdshelby 0:aafd54b05111 389 uint8_t (*used_tx_callback_ptr)(sn_nsdl_capab_e , uint8_t *, uint16_t, sn_nsdl_addr_s *))
zdshelby 0:aafd54b05111 390 *
zdshelby 0:aafd54b05111 391 * \brief Initializes CoAP Protocol part
zdshelby 0:aafd54b05111 392 *
zdshelby 0:aafd54b05111 393 * \param *used_malloc_func_ptr is function pointer for used malloc() function.
zdshelby 0:aafd54b05111 394 * If set to NULL, CoAP Protocol part uses standard C-library malloc() function.
zdshelby 0:aafd54b05111 395 *
zdshelby 0:aafd54b05111 396 * \param *used_free_func_ptr is function pointer for used free() function.
zdshelby 0:aafd54b05111 397 * If set to NULL, CoAP Protocol part uses standard C-library free() function.
zdshelby 0:aafd54b05111 398 *
zdshelby 0:aafd54b05111 399 * \param *used_tx_callback_ptr function callback pointer to tx function for sending coap messages
zdshelby 0:aafd54b05111 400 *****************************************************************************/
zdshelby 0:aafd54b05111 401
zdshelby 0:aafd54b05111 402 int8_t sn_coap_protocol_init(void* (*used_malloc_func_ptr)(uint16_t), void (*used_free_func_ptr)(void*),
zdshelby 0:aafd54b05111 403 uint8_t (*used_tx_callback_ptr)(sn_nsdl_capab_e , uint8_t *, uint16_t, sn_nsdl_addr_s *))
zdshelby 0:aafd54b05111 404 {
zdshelby 0:aafd54b05111 405 /* * * Handling malloc() * * */
zdshelby 0:aafd54b05111 406 if (used_malloc_func_ptr != NULL)
zdshelby 0:aafd54b05111 407 sn_coap_protocol_malloc = used_malloc_func_ptr;
zdshelby 0:aafd54b05111 408 else
zdshelby 0:aafd54b05111 409 return -1;
zdshelby 0:aafd54b05111 410
zdshelby 0:aafd54b05111 411 /* * * Handling free() * * */
zdshelby 0:aafd54b05111 412 if (used_free_func_ptr != NULL)
zdshelby 0:aafd54b05111 413 sn_coap_protocol_free = used_free_func_ptr;
zdshelby 0:aafd54b05111 414 else
zdshelby 0:aafd54b05111 415 return -1;
zdshelby 0:aafd54b05111 416
zdshelby 0:aafd54b05111 417 /* * * Handle tx callback * * */
zdshelby 0:aafd54b05111 418 if(used_tx_callback_ptr != NULL)
zdshelby 0:aafd54b05111 419 sn_coap_tx_callback = used_tx_callback_ptr;
zdshelby 0:aafd54b05111 420 else
zdshelby 0:aafd54b05111 421 return -1;
zdshelby 0:aafd54b05111 422
zdshelby 0:aafd54b05111 423 sn_linked_list_init(sn_coap_protocol_malloc, sn_coap_protocol_free);
zdshelby 0:aafd54b05111 424
zdshelby 0:aafd54b05111 425 #if ENABLE_RESENDINGS /* If Message resending is not used at all, this part of code will not be compiled */
zdshelby 0:aafd54b05111 426
zdshelby 0:aafd54b05111 427 /* * * * Create Linked list for storing active resending messages * * * */
zdshelby 0:aafd54b05111 428 sn_coap_resending_queue_msgs = SN_COAP_RESENDING_QUEUE_SIZE_MSGS;
zdshelby 0:aafd54b05111 429 sn_coap_resending_queue_bytes = SN_COAP_RESENDING_QUEUE_SIZE_BYTES;
zdshelby 0:aafd54b05111 430 sn_coap_resending_intervall = DEFAULT_RESPONSE_TIMEOUT;
zdshelby 0:aafd54b05111 431 sn_coap_resending_count = SN_COAP_RESENDING_MAX_COUNT;
zdshelby 0:aafd54b05111 432
zdshelby 0:aafd54b05111 433 /* Check that Linked list is not already created */
zdshelby 0:aafd54b05111 434 if (global_linked_list_resent_msgs_ptr == NULL)
zdshelby 0:aafd54b05111 435 {
zdshelby 0:aafd54b05111 436 global_linked_list_resent_msgs_ptr = sn_linked_list_create();
zdshelby 0:aafd54b05111 437
zdshelby 0:aafd54b05111 438 if(global_linked_list_resent_msgs_ptr == NULL)
zdshelby 0:aafd54b05111 439 {
zdshelby 0:aafd54b05111 440 coap_protocol_free_lists();
zdshelby 0:aafd54b05111 441 return (-1);
zdshelby 0:aafd54b05111 442 }
zdshelby 0:aafd54b05111 443
zdshelby 0:aafd54b05111 444 }
zdshelby 0:aafd54b05111 445
zdshelby 0:aafd54b05111 446 #endif /* ENABLE_RESENDINGS */
zdshelby 0:aafd54b05111 447
zdshelby 0:aafd54b05111 448 /* * * * Create Linked list for storing Acknowledgement info, if not already created * * * */
zdshelby 0:aafd54b05111 449 if (global_linked_list_ack_info_ptr == NULL)
zdshelby 0:aafd54b05111 450 {
zdshelby 0:aafd54b05111 451 global_linked_list_ack_info_ptr = sn_linked_list_create();
zdshelby 0:aafd54b05111 452
zdshelby 0:aafd54b05111 453 if(global_linked_list_ack_info_ptr == NULL)
zdshelby 0:aafd54b05111 454 {
zdshelby 0:aafd54b05111 455 coap_protocol_free_lists();
zdshelby 0:aafd54b05111 456 return (-1);
zdshelby 0:aafd54b05111 457 }
zdshelby 0:aafd54b05111 458
zdshelby 0:aafd54b05111 459 }
zdshelby 0:aafd54b05111 460
zdshelby 0:aafd54b05111 461 #if SN_COAP_DUPLICATION_MAX_MSGS_COUNT /* If Message duplication detection is not used at all, this part of code will not be compiled */
zdshelby 0:aafd54b05111 462 /* * * * Create Linked list for storing Duplication info * * * */
zdshelby 0:aafd54b05111 463 sn_coap_duplication_buffer_size = SN_COAP_DUPLICATION_MAX_MSGS_COUNT;
zdshelby 0:aafd54b05111 464
zdshelby 0:aafd54b05111 465 /* Check that Linked list is not already created */
zdshelby 0:aafd54b05111 466 if (global_linked_list_duplication_msgs_ptr == NULL)
zdshelby 0:aafd54b05111 467 {
zdshelby 0:aafd54b05111 468 global_linked_list_duplication_msgs_ptr = sn_linked_list_create();
zdshelby 0:aafd54b05111 469
zdshelby 0:aafd54b05111 470 if(global_linked_list_duplication_msgs_ptr == NULL)
zdshelby 0:aafd54b05111 471 {
zdshelby 0:aafd54b05111 472 coap_protocol_free_lists();
zdshelby 0:aafd54b05111 473 return (-1);
zdshelby 0:aafd54b05111 474 }
zdshelby 0:aafd54b05111 475 }
zdshelby 0:aafd54b05111 476 #endif
zdshelby 0:aafd54b05111 477
zdshelby 0:aafd54b05111 478 #if SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE /* If Message blockwising is not used at all, this part of code will not be compiled */
zdshelby 0:aafd54b05111 479
zdshelby 0:aafd54b05111 480 sn_coap_block_data_size = SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE;
zdshelby 0:aafd54b05111 481
zdshelby 0:aafd54b05111 482 /* * * * Create Linked list for storing sent blockwise messages, if not already created * * * */
zdshelby 0:aafd54b05111 483 if (global_linked_list_blockwise_sent_msgs_ptr == NULL)
zdshelby 0:aafd54b05111 484 {
zdshelby 0:aafd54b05111 485 global_linked_list_blockwise_sent_msgs_ptr = sn_linked_list_create();
zdshelby 0:aafd54b05111 486
zdshelby 0:aafd54b05111 487 if(global_linked_list_blockwise_sent_msgs_ptr == NULL)
zdshelby 0:aafd54b05111 488 {
zdshelby 0:aafd54b05111 489 coap_protocol_free_lists();
zdshelby 0:aafd54b05111 490 return (-1);
zdshelby 0:aafd54b05111 491 }
zdshelby 0:aafd54b05111 492
zdshelby 0:aafd54b05111 493 }
zdshelby 0:aafd54b05111 494
zdshelby 0:aafd54b05111 495 /* * * * Create Linked list for storing received blockwise payload, if not already created * * * */
zdshelby 0:aafd54b05111 496 if (global_linked_list_blockwise_received_payloads_ptr == NULL)
zdshelby 0:aafd54b05111 497 {
zdshelby 0:aafd54b05111 498 global_linked_list_blockwise_received_payloads_ptr = sn_linked_list_create();
zdshelby 0:aafd54b05111 499
zdshelby 0:aafd54b05111 500 if(global_linked_list_blockwise_received_payloads_ptr == NULL)
zdshelby 0:aafd54b05111 501 {
zdshelby 0:aafd54b05111 502 coap_protocol_free_lists();
zdshelby 0:aafd54b05111 503 return (-1);
zdshelby 0:aafd54b05111 504 }
zdshelby 0:aafd54b05111 505 }
zdshelby 0:aafd54b05111 506 #endif /* ENABLE_RESENDINGS */
zdshelby 0:aafd54b05111 507
zdshelby 0:aafd54b05111 508 /* Randomize global message ID */
zdshelby 0:aafd54b05111 509 #ifndef REAL_EMBEDDED
zdshelby 0:aafd54b05111 510 srand(time(NULL));
zdshelby 0:aafd54b05111 511 #endif
zdshelby 0:aafd54b05111 512 {
zdshelby 0:aafd54b05111 513 uint8_t random_number = rand();
zdshelby 0:aafd54b05111 514 global_message_id = 100 + random_number;
zdshelby 0:aafd54b05111 515 }
zdshelby 0:aafd54b05111 516
zdshelby 0:aafd54b05111 517 return 0;
zdshelby 0:aafd54b05111 518 }
zdshelby 0:aafd54b05111 519
zdshelby 0:aafd54b05111 520 /**************************************************************************//**
zdshelby 0:aafd54b05111 521 * \fn int8_t sn_coap_protocol_set_block_size(uint16_t block_size)
zdshelby 0:aafd54b05111 522 *
zdshelby 0:aafd54b05111 523 * \brief Sets block size
zdshelby 0:aafd54b05111 524 *
zdshelby 0:aafd54b05111 525 * \param uint16_t block_size maximum size of CoAP payload. Valid sizes are 16, 32, 64, 128, 256, 512 and 1024 bytes
zdshelby 0:aafd54b05111 526 * \return 0 = success
zdshelby 0:aafd54b05111 527 * -1 = failure
zdshelby 0:aafd54b05111 528 */
zdshelby 0:aafd54b05111 529
zdshelby 0:aafd54b05111 530 int8_t sn_coap_protocol_set_block_size(uint16_t block_size)
zdshelby 0:aafd54b05111 531 {
zdshelby 0:aafd54b05111 532 #if SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE
zdshelby 0:aafd54b05111 533 switch(block_size)
zdshelby 0:aafd54b05111 534 {
zdshelby 0:aafd54b05111 535 case 0:
zdshelby 0:aafd54b05111 536 case 16:
zdshelby 0:aafd54b05111 537 case 32:
zdshelby 0:aafd54b05111 538 case 64:
zdshelby 0:aafd54b05111 539 case 128:
zdshelby 0:aafd54b05111 540 case 256:
zdshelby 0:aafd54b05111 541 case 512:
zdshelby 0:aafd54b05111 542 case 1024:
zdshelby 0:aafd54b05111 543 sn_coap_block_data_size = block_size;
zdshelby 0:aafd54b05111 544 return 0;
zdshelby 0:aafd54b05111 545 default:
zdshelby 0:aafd54b05111 546 break;
zdshelby 0:aafd54b05111 547 }
zdshelby 0:aafd54b05111 548 #endif
zdshelby 0:aafd54b05111 549 return -1;
zdshelby 0:aafd54b05111 550
zdshelby 0:aafd54b05111 551 }
zdshelby 0:aafd54b05111 552
zdshelby 0:aafd54b05111 553 /**************************************************************************//**
zdshelby 0:aafd54b05111 554 * \fn int8_t sn_coap_protocol_set_duplicate_buffer_size(uint8_t message_count)
zdshelby 0:aafd54b05111 555 *
zdshelby 0:aafd54b05111 556 * \brief Sets max number of messages saved for message duplication checks
zdshelby 0:aafd54b05111 557 *
zdshelby 0:aafd54b05111 558 * \param uint8_t message_count max number of messages saved for duplicate control
zdshelby 0:aafd54b05111 559 * \return 0 = success
zdshelby 0:aafd54b05111 560 * -1 = failure
zdshelby 0:aafd54b05111 561 */
zdshelby 0:aafd54b05111 562
zdshelby 0:aafd54b05111 563 int8_t sn_coap_protocol_set_duplicate_buffer_size(uint8_t message_count)
zdshelby 0:aafd54b05111 564 {
zdshelby 0:aafd54b05111 565 #if SN_COAP_DUPLICATION_MAX_MSGS_COUNT
zdshelby 0:aafd54b05111 566 if(message_count <= SN_COAP_MAX_ALLOWED_DUPLICATION_MESSAGE_COUNT)
zdshelby 0:aafd54b05111 567 {
zdshelby 0:aafd54b05111 568 sn_coap_duplication_buffer_size = message_count;
zdshelby 0:aafd54b05111 569 return 0;
zdshelby 0:aafd54b05111 570 }
zdshelby 0:aafd54b05111 571 #endif
zdshelby 0:aafd54b05111 572 return -1;
zdshelby 0:aafd54b05111 573 }
zdshelby 0:aafd54b05111 574
zdshelby 0:aafd54b05111 575 /**************************************************************************//**
zdshelby 0:aafd54b05111 576 * \fn int8_t sn_coap_protocol_set_retransmission_parameters(uint8_t resending_count, uint8_t resending_intervall)
zdshelby 0:aafd54b05111 577 *
zdshelby 0:aafd54b05111 578 * \brief Sets message retransmission parameters
zdshelby 0:aafd54b05111 579 *
zdshelby 0:aafd54b05111 580 * \param uint8_t resending_count max number of resendings for message
zdshelby 0:aafd54b05111 581 * \param uint8_t resending_intervall message resending inervall in seconds
zdshelby 0:aafd54b05111 582 * \return 0 = success
zdshelby 0:aafd54b05111 583 * -1 = failure
zdshelby 0:aafd54b05111 584 */
zdshelby 0:aafd54b05111 585
zdshelby 0:aafd54b05111 586 int8_t sn_coap_protocol_set_retransmission_parameters(uint8_t resending_count, uint8_t resending_intervall)
zdshelby 0:aafd54b05111 587 {
zdshelby 0:aafd54b05111 588 #if ENABLE_RESENDINGS
zdshelby 0:aafd54b05111 589 if(resending_count <= SN_COAP_MAX_ALLOWED_RESENDING_COUNT &&
zdshelby 0:aafd54b05111 590 resending_intervall <= SN_COAP_MAX_ALLOWED_RESPONSE_TIMEOUT && resending_intervall > 0)
zdshelby 0:aafd54b05111 591 {
zdshelby 0:aafd54b05111 592 sn_coap_resending_count = resending_count;
zdshelby 0:aafd54b05111 593 sn_coap_resending_intervall = resending_intervall;
zdshelby 0:aafd54b05111 594 return 0;
zdshelby 0:aafd54b05111 595 }
zdshelby 0:aafd54b05111 596 #endif
zdshelby 0:aafd54b05111 597 return -1;
zdshelby 0:aafd54b05111 598 }
zdshelby 0:aafd54b05111 599
zdshelby 0:aafd54b05111 600 /**************************************************************************//**
zdshelby 0:aafd54b05111 601 * \fn int8_t sn_coap_protocol_set_retransmission_buffer(uint8_t buffer_size_messages, uint16_t buffer_size_bytes)
zdshelby 0:aafd54b05111 602 *
zdshelby 0:aafd54b05111 603 * \brief Sets message retransmission queue. Set size to '0' to disable feature. If both are set to '0', then re-sendings are disabled.
zdshelby 0:aafd54b05111 604 *
zdshelby 0:aafd54b05111 605 * \param uint8_t buffer_size_messages queue size - maximum number of messages to be saved to queue
zdshelby 0:aafd54b05111 606 * \param uint8_t buffer_size_bytes queue size - maximum size of messages saved to queue
zdshelby 0:aafd54b05111 607 * \return 0 = success
zdshelby 0:aafd54b05111 608 * -1 = failure
zdshelby 0:aafd54b05111 609 */
zdshelby 0:aafd54b05111 610
zdshelby 0:aafd54b05111 611 int8_t sn_coap_protocol_set_retransmission_buffer(uint8_t buffer_size_messages, uint16_t buffer_size_bytes)
zdshelby 0:aafd54b05111 612 {
zdshelby 0:aafd54b05111 613 #if ENABLE_RESENDINGS
zdshelby 0:aafd54b05111 614 if(buffer_size_bytes <= SN_COAP_MAX_ALLOWED_RESENDING_BUFF_SIZE_BYTES)
zdshelby 0:aafd54b05111 615 sn_coap_resending_queue_bytes = buffer_size_bytes;
zdshelby 0:aafd54b05111 616 if(buffer_size_bytes <= SN_COAP_MAX_ALLOWED_RESENDING_BUFF_SIZE_MSGS)
zdshelby 0:aafd54b05111 617 sn_coap_resending_queue_msgs = buffer_size_messages;
zdshelby 0:aafd54b05111 618
zdshelby 0:aafd54b05111 619 #endif
zdshelby 0:aafd54b05111 620 return -1;
zdshelby 0:aafd54b05111 621
zdshelby 0:aafd54b05111 622 }
zdshelby 0:aafd54b05111 623
zdshelby 0:aafd54b05111 624 /**************************************************************************//**
zdshelby 0:aafd54b05111 625 * \fn int16_t sn_coap_protocol_build(sn_nsdl_addr_s *dst_addr_ptr, uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_msg_ptr)
zdshelby 0:aafd54b05111 626 *
zdshelby 0:aafd54b05111 627 * \brief Builds Packet data from given CoAP header structure to be sent
zdshelby 0:aafd54b05111 628 *
zdshelby 0:aafd54b05111 629 * \param *dst_addr_ptr is pointer to destination address where CoAP message
zdshelby 0:aafd54b05111 630 * will be sent (CoAP builder needs that information for message resending purposes)
zdshelby 0:aafd54b05111 631 *
zdshelby 0:aafd54b05111 632 * \param *dst_packet_data_ptr is pointer to destination of built Packet data
zdshelby 0:aafd54b05111 633 *
zdshelby 0:aafd54b05111 634 * \param *src_coap_msg_ptr is pointer to source of built Packet data
zdshelby 0:aafd54b05111 635 *
zdshelby 0:aafd54b05111 636 * \return Return value is byte count of built Packet data.\n
zdshelby 0:aafd54b05111 637 * Note: If message is blockwised, all payload is not sent at the same time\n
zdshelby 0:aafd54b05111 638 * In failure cases:\n
zdshelby 0:aafd54b05111 639 * -1 = Failure in CoAP header structure\n
zdshelby 0:aafd54b05111 640 * -2 = Failure in given pointer (= NULL)\n
zdshelby 0:aafd54b05111 641 * -3 = Failure in Reset message\ŋ
zdshelby 0:aafd54b05111 642 * If there is not enough memory (or User given limit exceeded) for storing
zdshelby 0:aafd54b05111 643 * resending messages, situation is ignored.
zdshelby 0:aafd54b05111 644 *****************************************************************************/
zdshelby 0:aafd54b05111 645
zdshelby 0:aafd54b05111 646 int16_t sn_coap_protocol_build(sn_nsdl_addr_s *dst_addr_ptr,
zdshelby 0:aafd54b05111 647 uint8_t *dst_packet_data_ptr,
zdshelby 0:aafd54b05111 648 sn_coap_hdr_s *src_coap_msg_ptr)
zdshelby 0:aafd54b05111 649 {
zdshelby 0:aafd54b05111 650 int32_t message_id = -3;
zdshelby 0:aafd54b05111 651 int16_t byte_count_built = 0;
zdshelby 0:aafd54b05111 652 #if SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE /* If Message blockwising is not used at all, this part of code will not be compiled */
zdshelby 0:aafd54b05111 653 uint16_t original_payload_len = 0;
zdshelby 0:aafd54b05111 654 #endif
zdshelby 0:aafd54b05111 655
zdshelby 0:aafd54b05111 656 /* * * * Check given pointers * * * */
zdshelby 0:aafd54b05111 657 if ((dst_addr_ptr == NULL) || (dst_packet_data_ptr == NULL) || (src_coap_msg_ptr == NULL))
zdshelby 0:aafd54b05111 658 return -2;
zdshelby 0:aafd54b05111 659
zdshelby 0:aafd54b05111 660 if(dst_addr_ptr->addr_ptr == NULL)
zdshelby 0:aafd54b05111 661 return -2;
zdshelby 0:aafd54b05111 662
zdshelby 0:aafd54b05111 663 /* Check if built Message type is Reset message or Message code is some of response messages or empty */
zdshelby 0:aafd54b05111 664 /* (for these messages CoAP writes same Message ID which was stored earlier from request message) */
zdshelby 0:aafd54b05111 665 if (src_coap_msg_ptr->msg_type == COAP_MSG_TYPE_RESET ||
zdshelby 0:aafd54b05111 666 (src_coap_msg_ptr->msg_code >= COAP_MSG_CODE_RESPONSE_CREATED || src_coap_msg_ptr->msg_code == COAP_MSG_CODE_EMPTY))
zdshelby 0:aafd54b05111 667 {
zdshelby 0:aafd54b05111 668 /* Check if there is Token option in built CoAP message */
zdshelby 0:aafd54b05111 669 /* (only these messages can be acknowledged because Token option is used as key for stored messages) */
zdshelby 0:aafd54b05111 670 if (src_coap_msg_ptr->token_ptr != NULL)
zdshelby 0:aafd54b05111 671 {
zdshelby 0:aafd54b05111 672 /* Search Message ID from Linked list with Token option and Address as key */
zdshelby 0:aafd54b05111 673 message_id = sn_coap_protocol_linked_list_ack_info_search(src_coap_msg_ptr->msg_id, src_coap_msg_ptr->token_len,
zdshelby 0:aafd54b05111 674 src_coap_msg_ptr->token_ptr, dst_addr_ptr);
zdshelby 0:aafd54b05111 675 }
zdshelby 0:aafd54b05111 676 else
zdshelby 0:aafd54b05111 677 {
zdshelby 0:aafd54b05111 678 message_id = sn_coap_protocol_linked_list_ack_info_search(src_coap_msg_ptr->msg_id, 0, NULL, dst_addr_ptr);
zdshelby 0:aafd54b05111 679 }
zdshelby 0:aafd54b05111 680
zdshelby 0:aafd54b05111 681 /* If Message ID found */
zdshelby 0:aafd54b05111 682 if (message_id >= 0)
zdshelby 0:aafd54b05111 683 {
zdshelby 0:aafd54b05111 684 /* * * * Manage received CoAP message acknowledgement * * * */
zdshelby 0:aafd54b05111 685 /* Piggy-backed response message found */
zdshelby 0:aafd54b05111 686
zdshelby 0:aafd54b05111 687 /* Client Server */
zdshelby 0:aafd54b05111 688
zdshelby 0:aafd54b05111 689 /* ------------------> Confirmable request message (CoAP stores Acknowledgement info to Linked list) */
zdshelby 0:aafd54b05111 690
zdshelby 0:aafd54b05111 691 /* <------------------ THIS IS DONE HERE: Piggy-backed acknowledgement response message (CoAP writes same
zdshelby 0:aafd54b05111 692 Message ID than was in Request message).
zdshelby 0:aafd54b05111 693 User has written correct Token option to the response message. */
zdshelby 0:aafd54b05111 694
zdshelby 0:aafd54b05111 695 if (src_coap_msg_ptr->msg_type != COAP_MSG_TYPE_RESET)
zdshelby 0:aafd54b05111 696 {
zdshelby 0:aafd54b05111 697 /* Now is built Piggy-backed Acknowledgement response message */
zdshelby 0:aafd54b05111 698 src_coap_msg_ptr->msg_type = COAP_MSG_TYPE_ACKNOWLEDGEMENT;
zdshelby 0:aafd54b05111 699 }
zdshelby 0:aafd54b05111 700
zdshelby 0:aafd54b05111 701 /* Remove Acknowledgement info from Linked list */
zdshelby 0:aafd54b05111 702 sn_coap_protocol_linked_list_ack_info_remove(src_coap_msg_ptr->msg_id, dst_addr_ptr);
zdshelby 0:aafd54b05111 703 }
zdshelby 0:aafd54b05111 704 else if (src_coap_msg_ptr->msg_type == COAP_MSG_TYPE_RESET)
zdshelby 0:aafd54b05111 705 {
zdshelby 0:aafd54b05111 706 /* There was not found Message ID for Reset message */
zdshelby 0:aafd54b05111 707 return -3;
zdshelby 0:aafd54b05111 708 }
zdshelby 0:aafd54b05111 709 }
zdshelby 0:aafd54b05111 710
zdshelby 0:aafd54b05111 711 /* Check if built Message type is else than Acknowledgement or Reset i.e. message type is Confirmable or Non-confirmable */
zdshelby 0:aafd54b05111 712 /* (for Acknowledgement and Reset messages is written same Message ID than was in the Request message) */
zdshelby 0:aafd54b05111 713 if (src_coap_msg_ptr->msg_type != COAP_MSG_TYPE_ACKNOWLEDGEMENT &&
zdshelby 0:aafd54b05111 714 src_coap_msg_ptr->msg_type != COAP_MSG_TYPE_RESET &&
zdshelby 0:aafd54b05111 715 src_coap_msg_ptr->msg_id == 0)
zdshelby 0:aafd54b05111 716 {
zdshelby 0:aafd54b05111 717 /* * * * Generate new Message ID and increase it by one * * * */
zdshelby 0:aafd54b05111 718 if(0 > message_id)
zdshelby 0:aafd54b05111 719 {
zdshelby 0:aafd54b05111 720 src_coap_msg_ptr->msg_id = global_message_id;
zdshelby 0:aafd54b05111 721 global_message_id++;
zdshelby 0:aafd54b05111 722 }
zdshelby 0:aafd54b05111 723 }
zdshelby 0:aafd54b05111 724
zdshelby 0:aafd54b05111 725 #if SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE /* If Message blockwising is not used at all, this part of code will not be compiled */
zdshelby 0:aafd54b05111 726
zdshelby 0:aafd54b05111 727 /* If blockwising needed */
zdshelby 0:aafd54b05111 728 if ((src_coap_msg_ptr->payload_len > sn_coap_block_data_size) && (sn_coap_block_data_size > 0))
zdshelby 0:aafd54b05111 729 {
zdshelby 0:aafd54b05111 730 /* * * * Add Blockwise option to send CoAP message * * */
zdshelby 0:aafd54b05111 731
zdshelby 0:aafd54b05111 732 if (src_coap_msg_ptr->options_list_ptr == NULL)
zdshelby 0:aafd54b05111 733 {
zdshelby 0:aafd54b05111 734 /* Allocate memory for less used options */
zdshelby 0:aafd54b05111 735 src_coap_msg_ptr->options_list_ptr = sn_coap_protocol_malloc(sizeof(sn_coap_options_list_s));
zdshelby 0:aafd54b05111 736
zdshelby 0:aafd54b05111 737 if (src_coap_msg_ptr->options_list_ptr == NULL)
zdshelby 0:aafd54b05111 738 {
zdshelby 0:aafd54b05111 739 return -2;
zdshelby 0:aafd54b05111 740 }
zdshelby 0:aafd54b05111 741 memset(src_coap_msg_ptr->options_list_ptr, 0, sizeof(sn_coap_options_list_s));
zdshelby 0:aafd54b05111 742 }
zdshelby 0:aafd54b05111 743
zdshelby 0:aafd54b05111 744
zdshelby 0:aafd54b05111 745 /* Check if Request message */
zdshelby 0:aafd54b05111 746 if (src_coap_msg_ptr->msg_code < COAP_MSG_CODE_RESPONSE_CREATED )
zdshelby 0:aafd54b05111 747 {
zdshelby 0:aafd54b05111 748 /* Add Blockwise option, use Block1 because Request payload */
zdshelby 0:aafd54b05111 749 src_coap_msg_ptr->options_list_ptr->block1_len = 1;
zdshelby 0:aafd54b05111 750 src_coap_msg_ptr->options_list_ptr->block1_ptr = sn_coap_protocol_malloc(1);
zdshelby 0:aafd54b05111 751
zdshelby 0:aafd54b05111 752 if (src_coap_msg_ptr->options_list_ptr->block1_ptr == NULL)
zdshelby 0:aafd54b05111 753 {
zdshelby 0:aafd54b05111 754 sn_coap_protocol_free(src_coap_msg_ptr->options_list_ptr);
zdshelby 0:aafd54b05111 755
zdshelby 0:aafd54b05111 756 return -2;
zdshelby 0:aafd54b05111 757 }
zdshelby 0:aafd54b05111 758
zdshelby 0:aafd54b05111 759 *(src_coap_msg_ptr->options_list_ptr->block1_ptr) = 0x08; /* First block (BLOCK NUMBER, 4 MSB bits) + More to come (MORE, 1 bit) */
zdshelby 0:aafd54b05111 760 *(src_coap_msg_ptr->options_list_ptr->block1_ptr) |= sn_coap_convert_block_size(sn_coap_block_data_size);
zdshelby 0:aafd54b05111 761
zdshelby 0:aafd54b05111 762 }
zdshelby 0:aafd54b05111 763 else /* Response message */
zdshelby 0:aafd54b05111 764 {
zdshelby 0:aafd54b05111 765 /* Add Blockwise option, use Block2 because Response payload */
zdshelby 0:aafd54b05111 766 src_coap_msg_ptr->options_list_ptr->block2_len = 1;
zdshelby 0:aafd54b05111 767 src_coap_msg_ptr->options_list_ptr->block2_ptr = sn_coap_protocol_malloc(1);
zdshelby 0:aafd54b05111 768
zdshelby 0:aafd54b05111 769 if (src_coap_msg_ptr->options_list_ptr->block2_ptr == NULL)
zdshelby 0:aafd54b05111 770 {
zdshelby 0:aafd54b05111 771 sn_coap_protocol_free(src_coap_msg_ptr->options_list_ptr);
zdshelby 0:aafd54b05111 772 return -2;
zdshelby 0:aafd54b05111 773 }
zdshelby 0:aafd54b05111 774
zdshelby 0:aafd54b05111 775 *(src_coap_msg_ptr->options_list_ptr->block2_ptr) = 0x08; /* First block (BLOCK NUMBER, 4 MSB bits) + More to come (MORE, 1 bit) */
zdshelby 0:aafd54b05111 776 *(src_coap_msg_ptr->options_list_ptr->block2_ptr) |= sn_coap_convert_block_size(sn_coap_block_data_size);
zdshelby 0:aafd54b05111 777 }
zdshelby 0:aafd54b05111 778
zdshelby 0:aafd54b05111 779 /* Store original Payload length */
zdshelby 0:aafd54b05111 780 original_payload_len = src_coap_msg_ptr->payload_len;
zdshelby 0:aafd54b05111 781
zdshelby 0:aafd54b05111 782 /* Change Payload length of send message because Payload is blockwised */
zdshelby 0:aafd54b05111 783 src_coap_msg_ptr->payload_len = sn_coap_block_data_size;
zdshelby 0:aafd54b05111 784 }
zdshelby 0:aafd54b05111 785
zdshelby 0:aafd54b05111 786 #endif
zdshelby 0:aafd54b05111 787 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
zdshelby 0:aafd54b05111 788 /* * * * Build Packet data from CoAP message by using CoAP Header builder * * * */
zdshelby 0:aafd54b05111 789 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
zdshelby 0:aafd54b05111 790
zdshelby 0:aafd54b05111 791 byte_count_built = sn_coap_builder(dst_packet_data_ptr, src_coap_msg_ptr);
zdshelby 0:aafd54b05111 792
zdshelby 0:aafd54b05111 793 if (byte_count_built < 0)
zdshelby 0:aafd54b05111 794 {
zdshelby 0:aafd54b05111 795 return byte_count_built;
zdshelby 0:aafd54b05111 796 }
zdshelby 0:aafd54b05111 797
zdshelby 0:aafd54b05111 798 #if ENABLE_RESENDINGS /* If Message resending is not used at all, this part of code will not be compiled */
zdshelby 0:aafd54b05111 799
zdshelby 0:aafd54b05111 800 /* Check if built Message type was confirmable, only these messages are resent */
zdshelby 0:aafd54b05111 801 if (src_coap_msg_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE)
zdshelby 0:aafd54b05111 802 {
zdshelby 0:aafd54b05111 803 /* Store message to Linked list for resending purposes */
zdshelby 0:aafd54b05111 804 sn_coap_protocol_linked_list_send_msg_store(dst_addr_ptr, byte_count_built, dst_packet_data_ptr,
zdshelby 0:aafd54b05111 805 global_system_time + (uint32_t)(sn_coap_resending_intervall * RESPONSE_RANDOM_FACTOR));
zdshelby 0:aafd54b05111 806 }
zdshelby 0:aafd54b05111 807
zdshelby 0:aafd54b05111 808 #endif /* ENABLE_RESENDINGS */
zdshelby 0:aafd54b05111 809
zdshelby 0:aafd54b05111 810 #if SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE /* If Message blockwising is not used at all, this part of code will not be compiled */
zdshelby 0:aafd54b05111 811
zdshelby 0:aafd54b05111 812 /* If blockwising needed */
zdshelby 0:aafd54b05111 813 if ((original_payload_len > sn_coap_block_data_size) && (sn_coap_block_data_size > 0))
zdshelby 0:aafd54b05111 814 {
zdshelby 0:aafd54b05111 815
zdshelby 0:aafd54b05111 816 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
zdshelby 0:aafd54b05111 817 /* * * * Manage rest blockwise messages sending by storing them to Linked list * * * */
zdshelby 0:aafd54b05111 818 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
zdshelby 0:aafd54b05111 819
zdshelby 0:aafd54b05111 820 coap_blockwise_msg_s *stored_blockwise_msg_ptr;
zdshelby 0:aafd54b05111 821
zdshelby 0:aafd54b05111 822 stored_blockwise_msg_ptr = sn_coap_protocol_malloc(sizeof(coap_blockwise_msg_s));
zdshelby 0:aafd54b05111 823 if(!stored_blockwise_msg_ptr)
zdshelby 0:aafd54b05111 824 {
zdshelby 0:aafd54b05111 825 //block paylaod save failed, only first block can be build. Perhaps we should return error.
zdshelby 0:aafd54b05111 826 return byte_count_built;
zdshelby 0:aafd54b05111 827 }
zdshelby 0:aafd54b05111 828 memset(stored_blockwise_msg_ptr, 0, sizeof(coap_blockwise_msg_s));
zdshelby 0:aafd54b05111 829
zdshelby 0:aafd54b05111 830 /* Fill struct */
zdshelby 0:aafd54b05111 831 stored_blockwise_msg_ptr->timestamp = global_system_time;
zdshelby 0:aafd54b05111 832
zdshelby 0:aafd54b05111 833 stored_blockwise_msg_ptr->coap_msg_ptr = sn_coap_protocol_copy_header(src_coap_msg_ptr);
zdshelby 0:aafd54b05111 834
zdshelby 0:aafd54b05111 835 stored_blockwise_msg_ptr->coap_msg_ptr->payload_len = original_payload_len;
zdshelby 0:aafd54b05111 836 stored_blockwise_msg_ptr->coap_msg_ptr->payload_ptr = sn_coap_protocol_malloc(stored_blockwise_msg_ptr->coap_msg_ptr->payload_len);
zdshelby 0:aafd54b05111 837 if(!stored_blockwise_msg_ptr->coap_msg_ptr->payload_ptr)
zdshelby 0:aafd54b05111 838 {
zdshelby 0:aafd54b05111 839 //block paylaod save failed, only first block can be build. Perhaps we should return error.
zdshelby 0:aafd54b05111 840 sn_coap_protocol_free(stored_blockwise_msg_ptr);
zdshelby 0:aafd54b05111 841 return byte_count_built;
zdshelby 0:aafd54b05111 842 }
zdshelby 0:aafd54b05111 843 memcpy(stored_blockwise_msg_ptr->coap_msg_ptr->payload_ptr, src_coap_msg_ptr->payload_ptr, stored_blockwise_msg_ptr->coap_msg_ptr->payload_len);
zdshelby 0:aafd54b05111 844
zdshelby 0:aafd54b05111 845 sn_linked_list_add_node(global_linked_list_blockwise_sent_msgs_ptr, stored_blockwise_msg_ptr);
zdshelby 0:aafd54b05111 846 }
zdshelby 0:aafd54b05111 847
zdshelby 0:aafd54b05111 848 else if(src_coap_msg_ptr->msg_code == COAP_MSG_CODE_REQUEST_GET)
zdshelby 0:aafd54b05111 849 {
zdshelby 0:aafd54b05111 850 /* Add message to linked list - response can be in blocks and we need header to build response.. */
zdshelby 0:aafd54b05111 851 coap_blockwise_msg_s *stored_blockwise_msg_ptr;
zdshelby 0:aafd54b05111 852
zdshelby 0:aafd54b05111 853 stored_blockwise_msg_ptr = sn_coap_protocol_malloc(sizeof(coap_blockwise_msg_s));
zdshelby 0:aafd54b05111 854 if(!stored_blockwise_msg_ptr)
zdshelby 0:aafd54b05111 855 {
zdshelby 0:aafd54b05111 856 return byte_count_built;
zdshelby 0:aafd54b05111 857 }
zdshelby 0:aafd54b05111 858 memset(stored_blockwise_msg_ptr, 0, sizeof(coap_blockwise_msg_s));
zdshelby 0:aafd54b05111 859
zdshelby 0:aafd54b05111 860 /* Fill struct */
zdshelby 0:aafd54b05111 861 stored_blockwise_msg_ptr->timestamp = global_system_time;
zdshelby 0:aafd54b05111 862
zdshelby 0:aafd54b05111 863 stored_blockwise_msg_ptr->coap_msg_ptr = sn_coap_protocol_copy_header(src_coap_msg_ptr);
zdshelby 0:aafd54b05111 864
zdshelby 0:aafd54b05111 865 sn_linked_list_add_node(global_linked_list_blockwise_sent_msgs_ptr, stored_blockwise_msg_ptr);
zdshelby 0:aafd54b05111 866 }
zdshelby 0:aafd54b05111 867
zdshelby 0:aafd54b05111 868 #endif /* SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE */
zdshelby 0:aafd54b05111 869
zdshelby 0:aafd54b05111 870 /* * * * Return built CoAP message Packet data length * * * */
zdshelby 0:aafd54b05111 871 return byte_count_built;
zdshelby 0:aafd54b05111 872 }
zdshelby 0:aafd54b05111 873
zdshelby 0:aafd54b05111 874 /**************************************************************************//**
zdshelby 0:aafd54b05111 875 * \fn sn_coap_hdr_s *sn_coap_protocol_parse(sn_nsdl_addr_s *src_addr_ptr, uint16_t packet_data_len, uint8_t *packet_data_ptr)
zdshelby 0:aafd54b05111 876 *
zdshelby 0:aafd54b05111 877 * \brief Parses received CoAP message from given Packet data
zdshelby 0:aafd54b05111 878 *
zdshelby 0:aafd54b05111 879 * \param *src_addr_ptr is pointer to source address of received CoAP message
zdshelby 0:aafd54b05111 880 * (CoAP parser needs that information for Message acknowledgement)
zdshelby 0:aafd54b05111 881 *
zdshelby 0:aafd54b05111 882 * \param packet_data_len is length of given Packet data to be parsed to CoAP message
zdshelby 0:aafd54b05111 883 *
zdshelby 0:aafd54b05111 884 * \param *packet_data_ptr is pointer to source of Packet data to be parsed to CoAP message
zdshelby 0:aafd54b05111 885 *
zdshelby 0:aafd54b05111 886 * \return Return value is pointer to parsed CoAP message structure. This structure includes also coap_status field.\n
zdshelby 0:aafd54b05111 887 * In following failure cases NULL is returned:\n
zdshelby 0:aafd54b05111 888 * -Given NULL pointer\n
zdshelby 0:aafd54b05111 889 * -Failure in parsed header of non-confirmable message\ŋ
zdshelby 0:aafd54b05111 890 * -Out of memory (malloc() returns NULL)
zdshelby 0:aafd54b05111 891 *****************************************************************************/
zdshelby 0:aafd54b05111 892
zdshelby 0:aafd54b05111 893 sn_coap_hdr_s *sn_coap_protocol_parse(sn_nsdl_addr_s *src_addr_ptr, uint16_t packet_data_len, uint8_t *packet_data_ptr)
zdshelby 0:aafd54b05111 894 {
zdshelby 0:aafd54b05111 895 sn_coap_hdr_s *returned_dst_coap_msg_ptr = NULL;
zdshelby 0:aafd54b05111 896 coap_version_e coap_version = COAP_VERSION_UNKNOWN;
zdshelby 0:aafd54b05111 897
zdshelby 0:aafd54b05111 898 /* * * * Check given pointer * * * */
zdshelby 0:aafd54b05111 899 if (src_addr_ptr == NULL || src_addr_ptr->addr_ptr == NULL ||
zdshelby 0:aafd54b05111 900 packet_data_ptr == NULL)
zdshelby 0:aafd54b05111 901 {
zdshelby 0:aafd54b05111 902 return NULL;
zdshelby 0:aafd54b05111 903 }
zdshelby 0:aafd54b05111 904
zdshelby 0:aafd54b05111 905 /* * * * Parse Packet data to CoAP message by using CoAP Header parser * * * */
zdshelby 0:aafd54b05111 906 returned_dst_coap_msg_ptr = sn_coap_parser(packet_data_len, packet_data_ptr, &coap_version);
zdshelby 0:aafd54b05111 907
zdshelby 0:aafd54b05111 908 /* Check status of returned pointer */
zdshelby 0:aafd54b05111 909 if (returned_dst_coap_msg_ptr == NULL)
zdshelby 0:aafd54b05111 910 {
zdshelby 0:aafd54b05111 911 /* Memory allocation error in parser */
zdshelby 0:aafd54b05111 912 return NULL;
zdshelby 0:aafd54b05111 913 }
zdshelby 0:aafd54b05111 914
zdshelby 0:aafd54b05111 915 /* * * * Check validity of parsed Header values * * * */
zdshelby 0:aafd54b05111 916 if (sn_coap_header_validity_check(returned_dst_coap_msg_ptr, coap_version) != 0)
zdshelby 0:aafd54b05111 917 {
zdshelby 0:aafd54b05111 918 /* If message code is in a reserved class (1, 6 or 7), send reset. Message code class is 3 MSB of the message code byte */
zdshelby 0:aafd54b05111 919 if(((returned_dst_coap_msg_ptr->msg_code >> 5) == 1) || // if class == 1
zdshelby 0:aafd54b05111 920 ((returned_dst_coap_msg_ptr->msg_code >> 5) == 6) || // if class == 6
zdshelby 0:aafd54b05111 921 ((returned_dst_coap_msg_ptr->msg_code >> 5) == 7)) // if class == 7
zdshelby 0:aafd54b05111 922 {
zdshelby 0:aafd54b05111 923 sn_coap_protocol_send_rst(returned_dst_coap_msg_ptr->msg_id, src_addr_ptr);
zdshelby 0:aafd54b05111 924 }
zdshelby 0:aafd54b05111 925
zdshelby 0:aafd54b05111 926 /* Release memory of CoAP message */
zdshelby 0:aafd54b05111 927 sn_coap_parser_release_allocated_coap_msg_mem(returned_dst_coap_msg_ptr);
zdshelby 0:aafd54b05111 928
zdshelby 0:aafd54b05111 929 /* Return NULL because Header validity check failed */
zdshelby 0:aafd54b05111 930 return NULL;
zdshelby 0:aafd54b05111 931 }
zdshelby 0:aafd54b05111 932
zdshelby 0:aafd54b05111 933 /* Check if we need to send reset message */
zdshelby 0:aafd54b05111 934 /* A recipient MUST acknowledge a Confirmable message with an Acknowledgement
zdshelby 0:aafd54b05111 935 message or, if it lacks context to process the message properly
zdshelby 0:aafd54b05111 936 (including the case where the message is Empty, uses a code with a
zdshelby 0:aafd54b05111 937 reserved class (1, 6 or 7), or has a message format error), MUST
zdshelby 0:aafd54b05111 938 reject it; rejecting a Confirmable message is effected by sending a
zdshelby 0:aafd54b05111 939 matching Reset message and otherwise ignoring it. */
zdshelby 0:aafd54b05111 940 if(returned_dst_coap_msg_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE)
zdshelby 0:aafd54b05111 941 {
zdshelby 0:aafd54b05111 942 /* CoAP ping */
zdshelby 0:aafd54b05111 943 if(returned_dst_coap_msg_ptr->msg_code == COAP_MSG_CODE_EMPTY)
zdshelby 0:aafd54b05111 944 {
zdshelby 0:aafd54b05111 945 sn_coap_protocol_send_rst(returned_dst_coap_msg_ptr->msg_id, src_addr_ptr);
zdshelby 0:aafd54b05111 946
zdshelby 0:aafd54b05111 947 /* Release memory of CoAP message */
zdshelby 0:aafd54b05111 948 sn_coap_parser_release_allocated_coap_msg_mem(returned_dst_coap_msg_ptr);
zdshelby 0:aafd54b05111 949
zdshelby 0:aafd54b05111 950 /* Return NULL because Header validity check failed */
zdshelby 0:aafd54b05111 951 return NULL;
zdshelby 0:aafd54b05111 952 }
zdshelby 0:aafd54b05111 953 }
zdshelby 0:aafd54b05111 954
zdshelby 0:aafd54b05111 955 #if !SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE /* If Message blockwising is used, this part of code will not be compiled */
zdshelby 0:aafd54b05111 956 /* If blockwising used in received message */
zdshelby 0:aafd54b05111 957 if (returned_dst_coap_msg_ptr->options_list_ptr != NULL &&
zdshelby 0:aafd54b05111 958 (returned_dst_coap_msg_ptr->options_list_ptr->block1_ptr != NULL ||
zdshelby 0:aafd54b05111 959 returned_dst_coap_msg_ptr->options_list_ptr->block2_ptr != NULL))
zdshelby 0:aafd54b05111 960 {
zdshelby 0:aafd54b05111 961 /* Set returned status to User */
zdshelby 0:aafd54b05111 962 returned_dst_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_BLOCKWISE_MSG_REJECTED;
zdshelby 0:aafd54b05111 963 //todo: send response -> not implemented
zdshelby 0:aafd54b05111 964 return returned_dst_coap_msg_ptr;
zdshelby 0:aafd54b05111 965 }
zdshelby 0:aafd54b05111 966 #endif /* !SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE */
zdshelby 0:aafd54b05111 967
zdshelby 0:aafd54b05111 968 #if SN_COAP_DUPLICATION_MAX_MSGS_COUNT /* If Message duplication is used, this part of code will not be compiled */
zdshelby 0:aafd54b05111 969
zdshelby 0:aafd54b05111 970 /* * * * Manage received CoAP message duplicate detection * * * */
zdshelby 0:aafd54b05111 971
zdshelby 0:aafd54b05111 972 /* Check if duplication message detected */
zdshelby 0:aafd54b05111 973 ret_status = sn_coap_protocol_linked_list_duplication_info_search(src_addr_ptr, msg_id);
zdshelby 0:aafd54b05111 974
zdshelby 0:aafd54b05111 975 /* If no message duplication detected */
zdshelby 0:aafd54b05111 976 if (ret_status == -1)
zdshelby 0:aafd54b05111 977 {
zdshelby 0:aafd54b05111 978 /* * * No Message duplication: Store received message for detecting later duplication * * */
zdshelby 0:aafd54b05111 979
zdshelby 0:aafd54b05111 980 /* Get count of stored duplication messages */
zdshelby 0:aafd54b05111 981 uint16_t stored_duplication_msgs_count = sn_linked_list_count_nodes(global_linked_list_duplication_msgs_ptr);
zdshelby 0:aafd54b05111 982
zdshelby 0:aafd54b05111 983 /* Check if there is no room to store message for duplication detection purposes */
zdshelby 0:aafd54b05111 984 if (stored_duplication_msgs_count >= sn_coap_duplication_buffer_size)
zdshelby 0:aafd54b05111 985 {
zdshelby 0:aafd54b05111 986 /* Get oldest stored duplication message */
zdshelby 0:aafd54b05111 987 coap_duplication_info_s *stored_duplication_info_ptr = sn_linked_list_get_last_node(global_linked_list_duplication_msgs_ptr);
zdshelby 0:aafd54b05111 988
zdshelby 0:aafd54b05111 989 /* Remove oldest stored duplication message for getting room for new duplication message */
zdshelby 0:aafd54b05111 990 sn_coap_protocol_linked_list_duplication_info_remove(stored_duplication_info_ptr->addr_ptr, stored_duplication_info_ptr->port, stored_duplication_info_ptr->msg_id);
zdshelby 0:aafd54b05111 991 }
zdshelby 0:aafd54b05111 992
zdshelby 0:aafd54b05111 993 /* Store Duplication info to Linked list */
zdshelby 0:aafd54b05111 994 sn_coap_protocol_linked_list_duplication_info_store(src_addr_ptr, msg_id);
zdshelby 0:aafd54b05111 995 }
zdshelby 0:aafd54b05111 996 else /* * * Message duplication detected * * */
zdshelby 0:aafd54b05111 997 {
zdshelby 0:aafd54b05111 998 /* Set returned status to User */
zdshelby 0:aafd54b05111 999 returned_dst_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_DUPLICATED_MSG;
zdshelby 0:aafd54b05111 1000
zdshelby 0:aafd54b05111 1001 /* Because duplicate message, return with coap_status set */
zdshelby 0:aafd54b05111 1002 return returned_dst_coap_msg_ptr;
zdshelby 0:aafd54b05111 1003 }
zdshelby 0:aafd54b05111 1004 #endif
zdshelby 0:aafd54b05111 1005
zdshelby 0:aafd54b05111 1006
zdshelby 0:aafd54b05111 1007 /*** And here we check if message was block message ***/
zdshelby 0:aafd54b05111 1008 /*** If so, we call own block handling function and ***/
zdshelby 0:aafd54b05111 1009 /*** return to caller. ***/
zdshelby 0:aafd54b05111 1010 #if SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE
zdshelby 0:aafd54b05111 1011
zdshelby 0:aafd54b05111 1012 coap_blockwise_msg_s *stored_blockwise_msg_temp_ptr;
zdshelby 0:aafd54b05111 1013
zdshelby 0:aafd54b05111 1014 if (returned_dst_coap_msg_ptr->options_list_ptr != NULL &&
zdshelby 0:aafd54b05111 1015 (returned_dst_coap_msg_ptr->options_list_ptr->block1_ptr != NULL ||
zdshelby 0:aafd54b05111 1016 returned_dst_coap_msg_ptr->options_list_ptr->block2_ptr != NULL))
zdshelby 0:aafd54b05111 1017 {
zdshelby 0:aafd54b05111 1018 returned_dst_coap_msg_ptr = sn_coap_handle_blockwise_message(src_addr_ptr, returned_dst_coap_msg_ptr);
zdshelby 0:aafd54b05111 1019 }
zdshelby 0:aafd54b05111 1020 else
zdshelby 0:aafd54b05111 1021 {
zdshelby 0:aafd54b05111 1022 stored_blockwise_msg_temp_ptr = sn_linked_list_get_last_node(global_linked_list_blockwise_sent_msgs_ptr);
zdshelby 0:aafd54b05111 1023
zdshelby 0:aafd54b05111 1024 /* Get ... */
zdshelby 0:aafd54b05111 1025 while(stored_blockwise_msg_temp_ptr && (returned_dst_coap_msg_ptr->msg_id != stored_blockwise_msg_temp_ptr->coap_msg_ptr->msg_id))
zdshelby 0:aafd54b05111 1026 {
zdshelby 0:aafd54b05111 1027 stored_blockwise_msg_temp_ptr = sn_linked_list_get_previous_node(global_linked_list_blockwise_sent_msgs_ptr);
zdshelby 0:aafd54b05111 1028 }
zdshelby 0:aafd54b05111 1029
zdshelby 0:aafd54b05111 1030 if(stored_blockwise_msg_temp_ptr)
zdshelby 0:aafd54b05111 1031 {
zdshelby 0:aafd54b05111 1032 sn_linked_list_remove_current_node(global_linked_list_blockwise_sent_msgs_ptr);
zdshelby 0:aafd54b05111 1033
zdshelby 0:aafd54b05111 1034 if(stored_blockwise_msg_temp_ptr->coap_msg_ptr)
zdshelby 0:aafd54b05111 1035 sn_coap_parser_release_allocated_coap_msg_mem(stored_blockwise_msg_temp_ptr->coap_msg_ptr);
zdshelby 0:aafd54b05111 1036
zdshelby 0:aafd54b05111 1037 sn_coap_protocol_free(stored_blockwise_msg_temp_ptr);
zdshelby 0:aafd54b05111 1038 }
zdshelby 0:aafd54b05111 1039 }
zdshelby 0:aafd54b05111 1040
zdshelby 0:aafd54b05111 1041 if(!returned_dst_coap_msg_ptr)
zdshelby 0:aafd54b05111 1042 return NULL;
zdshelby 0:aafd54b05111 1043
zdshelby 0:aafd54b05111 1044 #endif
zdshelby 0:aafd54b05111 1045
zdshelby 0:aafd54b05111 1046 /* Check if received Message type was confirmable */
zdshelby 0:aafd54b05111 1047 if (returned_dst_coap_msg_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE)
zdshelby 0:aafd54b05111 1048 {
zdshelby 0:aafd54b05111 1049 if (returned_dst_coap_msg_ptr->token_ptr != NULL)
zdshelby 0:aafd54b05111 1050 {
zdshelby 0:aafd54b05111 1051 /* * * * Manage received CoAP message acknowledgement * * */
zdshelby 0:aafd54b05111 1052
zdshelby 0:aafd54b05111 1053 /* Client Server */
zdshelby 0:aafd54b05111 1054
zdshelby 0:aafd54b05111 1055 /* ------------------> THIS IS DONE HERE: Confirmable request (CoAP stores Acknowledgement info to Linked list) */
zdshelby 0:aafd54b05111 1056
zdshelby 0:aafd54b05111 1057 /* <------------------ Piggy-backed acknowledgement response message (CoAP writes same Message ID
zdshelby 0:aafd54b05111 1058 than was in Request message).
zdshelby 0:aafd54b05111 1059 User has written correct Token option to the response message. */
zdshelby 0:aafd54b05111 1060
zdshelby 0:aafd54b05111 1061 /* Store message's Acknowledgement info to Linked list */
zdshelby 0:aafd54b05111 1062 sn_coap_protocol_linked_list_ack_info_store(returned_dst_coap_msg_ptr->msg_id, returned_dst_coap_msg_ptr->token_len, returned_dst_coap_msg_ptr->token_ptr, src_addr_ptr);
zdshelby 0:aafd54b05111 1063 }
zdshelby 0:aafd54b05111 1064 else
zdshelby 0:aafd54b05111 1065 {
zdshelby 0:aafd54b05111 1066 sn_coap_protocol_linked_list_ack_info_store(returned_dst_coap_msg_ptr->msg_id, 0, NULL, src_addr_ptr);
zdshelby 0:aafd54b05111 1067 }
zdshelby 0:aafd54b05111 1068 }
zdshelby 0:aafd54b05111 1069
zdshelby 0:aafd54b05111 1070
zdshelby 0:aafd54b05111 1071 #if ENABLE_RESENDINGS /* If Message resending is not used at all, this part of code will not be compiled */
zdshelby 0:aafd54b05111 1072
zdshelby 0:aafd54b05111 1073 /* Check if received Message type was acknowledgement */
zdshelby 0:aafd54b05111 1074 if ((returned_dst_coap_msg_ptr->msg_type == COAP_MSG_TYPE_ACKNOWLEDGEMENT) || (returned_dst_coap_msg_ptr->msg_type == COAP_MSG_TYPE_RESET))
zdshelby 0:aafd54b05111 1075 {
zdshelby 0:aafd54b05111 1076 /* * * * Manage CoAP message resending by removing active resending message from Linked list * * */
zdshelby 0:aafd54b05111 1077
zdshelby 0:aafd54b05111 1078 /* Get node count i.e. count of active resending messages */
zdshelby 0:aafd54b05111 1079 uint16_t stored_resending_msgs_count = sn_linked_list_count_nodes(global_linked_list_resent_msgs_ptr);
zdshelby 0:aafd54b05111 1080
zdshelby 0:aafd54b05111 1081 /* Check if there is ongoing active message resendings */
zdshelby 0:aafd54b05111 1082 if (stored_resending_msgs_count > 0)
zdshelby 0:aafd54b05111 1083 {
zdshelby 0:aafd54b05111 1084 sn_nsdl_transmit_s *removed_msg_ptr = NULL;
zdshelby 0:aafd54b05111 1085
zdshelby 0:aafd54b05111 1086 /* Check if received message was confirmation for some active resending message */
zdshelby 0:aafd54b05111 1087
zdshelby 0:aafd54b05111 1088 removed_msg_ptr = sn_coap_protocol_linked_list_send_msg_search(src_addr_ptr, returned_dst_coap_msg_ptr->msg_id);
zdshelby 0:aafd54b05111 1089
zdshelby 0:aafd54b05111 1090 if (removed_msg_ptr != NULL)
zdshelby 0:aafd54b05111 1091 {
zdshelby 0:aafd54b05111 1092 /* Remove resending message from active message resending Linked list */
zdshelby 0:aafd54b05111 1093 sn_coap_protocol_linked_list_send_msg_remove(src_addr_ptr, returned_dst_coap_msg_ptr->msg_id);
zdshelby 0:aafd54b05111 1094 }
zdshelby 0:aafd54b05111 1095 }
zdshelby 0:aafd54b05111 1096 }
zdshelby 0:aafd54b05111 1097 #endif /* ENABLE_RESENDINGS */
zdshelby 0:aafd54b05111 1098
zdshelby 0:aafd54b05111 1099 /* * * * Return parsed CoAP message * * * */
zdshelby 0:aafd54b05111 1100 return (returned_dst_coap_msg_ptr);
zdshelby 0:aafd54b05111 1101 }
zdshelby 0:aafd54b05111 1102
zdshelby 0:aafd54b05111 1103 /**************************************************************************//**
zdshelby 0:aafd54b05111 1104 * \fn int8_t sn_coap_protocol_exec(uint32_t current_time)
zdshelby 0:aafd54b05111 1105 *
zdshelby 0:aafd54b05111 1106 * \brief Sends CoAP messages from re-sending queue, if there is any.
zdshelby 0:aafd54b05111 1107 * Cleans also old messages from the duplication list and from block receiving list
zdshelby 0:aafd54b05111 1108 *
zdshelby 0:aafd54b05111 1109 * This function can be called e.g. once in a second but also more frequently.
zdshelby 0:aafd54b05111 1110 *
zdshelby 0:aafd54b05111 1111 * \param current_time is System time in seconds. This time is
zdshelby 0:aafd54b05111 1112 * used for message re-sending timing and to identify old saved data.
zdshelby 0:aafd54b05111 1113 *
zdshelby 0:aafd54b05111 1114 * \return 0 if success
zdshelby 0:aafd54b05111 1115 * -1 if failed
zdshelby 0:aafd54b05111 1116 *****************************************************************************/
zdshelby 0:aafd54b05111 1117
zdshelby 0:aafd54b05111 1118 int8_t sn_coap_protocol_exec(uint32_t current_time)
zdshelby 0:aafd54b05111 1119 {
zdshelby 0:aafd54b05111 1120 #if ENABLE_RESENDINGS
zdshelby 0:aafd54b05111 1121 uint8_t stored_resending_msgs_count;
zdshelby 0:aafd54b05111 1122 #endif
zdshelby 0:aafd54b05111 1123
zdshelby 0:aafd54b05111 1124 #if SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE
zdshelby 0:aafd54b05111 1125 /* * * * Remove old blocwise data * * * */
zdshelby 0:aafd54b05111 1126 sn_coap_protocol_linked_list_blockwise_remove_old_data();
zdshelby 0:aafd54b05111 1127 #endif
zdshelby 0:aafd54b05111 1128
zdshelby 0:aafd54b05111 1129 /* * * * Store current System time * * * */
zdshelby 0:aafd54b05111 1130 global_system_time = current_time;
zdshelby 0:aafd54b05111 1131
zdshelby 0:aafd54b05111 1132 #if SN_COAP_DUPLICATION_MAX_MSGS_COUNT
zdshelby 0:aafd54b05111 1133 /* * * * Remove old duplication messages * * * */
zdshelby 0:aafd54b05111 1134 sn_coap_protocol_linked_list_duplication_info_remove_old_ones();
zdshelby 0:aafd54b05111 1135 #endif
zdshelby 0:aafd54b05111 1136
zdshelby 0:aafd54b05111 1137 /* Remove old Acknowledgement infos */
zdshelby 0:aafd54b05111 1138 sn_coap_protocol_linked_list_ack_info_remove_old_ones();
zdshelby 0:aafd54b05111 1139
zdshelby 0:aafd54b05111 1140 #if ENABLE_RESENDINGS
zdshelby 0:aafd54b05111 1141 /* Check if there is ongoing active message sendings */
zdshelby 0:aafd54b05111 1142 stored_resending_msgs_count = sn_linked_list_count_nodes(global_linked_list_resent_msgs_ptr);
zdshelby 0:aafd54b05111 1143
zdshelby 0:aafd54b05111 1144 if (stored_resending_msgs_count > 0)
zdshelby 0:aafd54b05111 1145 {
zdshelby 0:aafd54b05111 1146 coap_send_msg_s *stored_msg_ptr = sn_linked_list_get_last_node(global_linked_list_resent_msgs_ptr);
zdshelby 0:aafd54b05111 1147 uint8_t i = 0;
zdshelby 0:aafd54b05111 1148
zdshelby 0:aafd54b05111 1149 for (i = 0; i < stored_resending_msgs_count; i++)
zdshelby 0:aafd54b05111 1150 {
zdshelby 0:aafd54b05111 1151 sn_nsdl_transmit_s *returned_msg_ptr = NULL;
zdshelby 0:aafd54b05111 1152
zdshelby 0:aafd54b05111 1153 /* Check if it is time to send this message */
zdshelby 0:aafd54b05111 1154 if (current_time >= stored_msg_ptr->resending_time)
zdshelby 0:aafd54b05111 1155 {
zdshelby 0:aafd54b05111 1156 /* * * Increase Resending counter * * */
zdshelby 0:aafd54b05111 1157 stored_msg_ptr->resending_counter++;
zdshelby 0:aafd54b05111 1158
zdshelby 0:aafd54b05111 1159 /* * * * Allocate and build returned message from stored data * * * */
zdshelby 0:aafd54b05111 1160 returned_msg_ptr = sn_coap_protocol_build_msg(stored_msg_ptr);
zdshelby 0:aafd54b05111 1161
zdshelby 0:aafd54b05111 1162 if (returned_msg_ptr == NULL)
zdshelby 0:aafd54b05111 1163 {
zdshelby 0:aafd54b05111 1164 return -1;
zdshelby 0:aafd54b05111 1165 }
zdshelby 0:aafd54b05111 1166
zdshelby 0:aafd54b05111 1167 /* Check if it was last sending of this message */
zdshelby 0:aafd54b05111 1168 if (stored_msg_ptr->resending_counter >= sn_coap_resending_count)
zdshelby 0:aafd54b05111 1169 {
zdshelby 0:aafd54b05111 1170 /* Get message ID from stored sending message */
zdshelby 0:aafd54b05111 1171 uint16_t temp_msg_id = (stored_msg_ptr->send_msg_ptr->packet_ptr[2] << 8);
zdshelby 0:aafd54b05111 1172 temp_msg_id += (uint16_t)stored_msg_ptr->send_msg_ptr->packet_ptr[3];
zdshelby 0:aafd54b05111 1173
zdshelby 0:aafd54b05111 1174 /* Remove message from Linked list */
zdshelby 0:aafd54b05111 1175 sn_coap_protocol_linked_list_send_msg_remove(stored_msg_ptr->send_msg_ptr->dst_addr_ptr, temp_msg_id);
zdshelby 0:aafd54b05111 1176 }
zdshelby 0:aafd54b05111 1177 else
zdshelby 0:aafd54b05111 1178 {
zdshelby 0:aafd54b05111 1179 /* * * Count new Resending time * * */
zdshelby 0:aafd54b05111 1180 stored_msg_ptr->resending_time = current_time + (((uint32_t)(sn_coap_resending_intervall * RESPONSE_RANDOM_FACTOR)) <<
zdshelby 0:aafd54b05111 1181 stored_msg_ptr->resending_counter);
zdshelby 0:aafd54b05111 1182 }
zdshelby 0:aafd54b05111 1183
zdshelby 0:aafd54b05111 1184 /* Send message */
zdshelby 0:aafd54b05111 1185 sn_coap_tx_callback(returned_msg_ptr->protocol, returned_msg_ptr->packet_ptr,
zdshelby 0:aafd54b05111 1186 returned_msg_ptr->packet_len, returned_msg_ptr->dst_addr_ptr);
zdshelby 0:aafd54b05111 1187
zdshelby 0:aafd54b05111 1188 /* Free sent packet */
zdshelby 0:aafd54b05111 1189 sn_coap_builder_release_allocated_send_msg_mem(returned_msg_ptr);
zdshelby 0:aafd54b05111 1190 return 0;
zdshelby 0:aafd54b05111 1191 }
zdshelby 0:aafd54b05111 1192
zdshelby 0:aafd54b05111 1193 /* Get next stored sending message from Linked list */
zdshelby 0:aafd54b05111 1194 stored_msg_ptr = sn_linked_list_get_previous_node(global_linked_list_resent_msgs_ptr);
zdshelby 0:aafd54b05111 1195 }
zdshelby 0:aafd54b05111 1196 }
zdshelby 0:aafd54b05111 1197
zdshelby 0:aafd54b05111 1198 #endif /* ENABLE_RESENDINGS */
zdshelby 0:aafd54b05111 1199
zdshelby 0:aafd54b05111 1200 return 0;
zdshelby 0:aafd54b05111 1201 }
zdshelby 0:aafd54b05111 1202
zdshelby 0:aafd54b05111 1203 #if ENABLE_RESENDINGS /* If Message resending is not used at all, this part of code will not be compiled */
zdshelby 0:aafd54b05111 1204
zdshelby 0:aafd54b05111 1205 /**************************************************************************//**
zdshelby 0:aafd54b05111 1206 * \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)
zdshelby 0:aafd54b05111 1207 *
zdshelby 0:aafd54b05111 1208 * \brief Stores message to Linked list for sending purposes.
zdshelby 0:aafd54b05111 1209
zdshelby 0:aafd54b05111 1210 * \param *dst_addr_ptr is pointer to destination address where CoAP message will be sent
zdshelby 0:aafd54b05111 1211 *
zdshelby 0:aafd54b05111 1212 * \param send_packet_data_len is length of Packet data to be stored
zdshelby 0:aafd54b05111 1213 *
zdshelby 0:aafd54b05111 1214 * \param *send_packet_data_ptr is Packet data to be stored
zdshelby 0:aafd54b05111 1215 *
zdshelby 0:aafd54b05111 1216 * \param sending_time is stored sending time
zdshelby 0:aafd54b05111 1217 *****************************************************************************/
zdshelby 0:aafd54b05111 1218
zdshelby 0:aafd54b05111 1219 static void sn_coap_protocol_linked_list_send_msg_store(sn_nsdl_addr_s *dst_addr_ptr, uint16_t send_packet_data_len,
zdshelby 0:aafd54b05111 1220 uint8_t *send_packet_data_ptr, uint32_t sending_time)
zdshelby 0:aafd54b05111 1221 {
zdshelby 0:aafd54b05111 1222
zdshelby 0:aafd54b05111 1223 coap_send_msg_s *stored_msg_ptr = NULL;
zdshelby 0:aafd54b05111 1224
zdshelby 0:aafd54b05111 1225 /* Blocking also needs this - to be removed... */
zdshelby 0:aafd54b05111 1226 if(sn_coap_block_data_size == 0)
zdshelby 0:aafd54b05111 1227 {
zdshelby 0:aafd54b05111 1228 /* If both parameters are "0", then resending is disabled */
zdshelby 0:aafd54b05111 1229 if((sn_coap_resending_queue_msgs == 0) && (sn_coap_resending_queue_bytes == 0))
zdshelby 0:aafd54b05111 1230 return;
zdshelby 0:aafd54b05111 1231
zdshelby 0:aafd54b05111 1232 if (sn_coap_resending_queue_msgs > 0)
zdshelby 0:aafd54b05111 1233 {
zdshelby 0:aafd54b05111 1234 if(sn_linked_list_count_nodes(global_linked_list_resent_msgs_ptr) >= sn_coap_resending_queue_msgs)
zdshelby 0:aafd54b05111 1235 return;
zdshelby 0:aafd54b05111 1236 }
zdshelby 0:aafd54b05111 1237
zdshelby 0:aafd54b05111 1238 /* Count resending queue size, if buffer size is defined */
zdshelby 0:aafd54b05111 1239 if(sn_coap_resending_queue_bytes > 0)
zdshelby 0:aafd54b05111 1240 {
zdshelby 0:aafd54b05111 1241 if((sn_coap_count_linked_list_size(global_linked_list_resent_msgs_ptr) + send_packet_data_len) > sn_coap_resending_queue_bytes)
zdshelby 0:aafd54b05111 1242 return;
zdshelby 0:aafd54b05111 1243 }
zdshelby 0:aafd54b05111 1244 }
zdshelby 0:aafd54b05111 1245
zdshelby 0:aafd54b05111 1246 /* Allocating memory for stored message */
zdshelby 0:aafd54b05111 1247 stored_msg_ptr = sn_coap_protocol_allocate_mem_for_msg(dst_addr_ptr, send_packet_data_len);
zdshelby 0:aafd54b05111 1248
zdshelby 0:aafd54b05111 1249 if(stored_msg_ptr == 0)
zdshelby 0:aafd54b05111 1250 return;
zdshelby 0:aafd54b05111 1251
zdshelby 0:aafd54b05111 1252 /* Filling of coap_send_msg_s with initialization values */
zdshelby 0:aafd54b05111 1253 stored_msg_ptr->resending_counter = 0;
zdshelby 0:aafd54b05111 1254 stored_msg_ptr->resending_time = sending_time;
zdshelby 0:aafd54b05111 1255
zdshelby 0:aafd54b05111 1256 /* Filling of sn_nsdl_transmit_s */
zdshelby 0:aafd54b05111 1257 stored_msg_ptr->send_msg_ptr->protocol = SN_NSDL_PROTOCOL_COAP;
zdshelby 0:aafd54b05111 1258 stored_msg_ptr->send_msg_ptr->packet_len = send_packet_data_len;
zdshelby 0:aafd54b05111 1259 memcpy(stored_msg_ptr->send_msg_ptr->packet_ptr, send_packet_data_ptr, send_packet_data_len);
zdshelby 0:aafd54b05111 1260
zdshelby 0:aafd54b05111 1261 /* Filling of sn_nsdl_addr_s */
zdshelby 0:aafd54b05111 1262 stored_msg_ptr->send_msg_ptr->dst_addr_ptr->type = dst_addr_ptr->type;
zdshelby 0:aafd54b05111 1263 stored_msg_ptr->send_msg_ptr->dst_addr_ptr->addr_len = dst_addr_ptr->addr_len;
zdshelby 0:aafd54b05111 1264 memcpy(stored_msg_ptr->send_msg_ptr->dst_addr_ptr->addr_ptr, dst_addr_ptr->addr_ptr, dst_addr_ptr->addr_len);
zdshelby 0:aafd54b05111 1265 stored_msg_ptr->send_msg_ptr->dst_addr_ptr->port = dst_addr_ptr->port;
zdshelby 0:aafd54b05111 1266
zdshelby 0:aafd54b05111 1267 /* Storing Resending message to Linked list */
zdshelby 0:aafd54b05111 1268 if(sn_linked_list_add_node(global_linked_list_resent_msgs_ptr, stored_msg_ptr) != 0)
zdshelby 0:aafd54b05111 1269 sn_coap_protocol_release_allocated_send_msg_mem(stored_msg_ptr);
zdshelby 0:aafd54b05111 1270
zdshelby 0:aafd54b05111 1271 }
zdshelby 0:aafd54b05111 1272
zdshelby 0:aafd54b05111 1273 /**************************************************************************//**
zdshelby 0:aafd54b05111 1274 * \fn static sn_nsdl_transmit_s *sn_coap_protocol_linked_list_send_msg_search(sn_nsdl_addr_s *src_addr_ptr, uint16_t msg_id)
zdshelby 0:aafd54b05111 1275 *
zdshelby 0:aafd54b05111 1276 * \brief Searches stored resending message from Linked list
zdshelby 0:aafd54b05111 1277 *
zdshelby 0:aafd54b05111 1278 * \param *src_addr_ptr is searching key for searched message
zdshelby 0:aafd54b05111 1279 *
zdshelby 0:aafd54b05111 1280 * \param msg_id is searching key for searched message
zdshelby 0:aafd54b05111 1281 *
zdshelby 0:aafd54b05111 1282 * \return Return value is pointer to found stored resending message in Linked
zdshelby 0:aafd54b05111 1283 * list or NULL if message not found
zdshelby 0:aafd54b05111 1284 *****************************************************************************/
zdshelby 0:aafd54b05111 1285
zdshelby 0:aafd54b05111 1286 static sn_nsdl_transmit_s *sn_coap_protocol_linked_list_send_msg_search(sn_nsdl_addr_s *src_addr_ptr, uint16_t msg_id)
zdshelby 0:aafd54b05111 1287 {
zdshelby 0:aafd54b05111 1288 coap_send_msg_s *stored_msg_ptr = sn_linked_list_get_last_node(global_linked_list_resent_msgs_ptr);
zdshelby 0:aafd54b05111 1289 uint16_t stored_resending_msgs_count = sn_linked_list_count_nodes(global_linked_list_resent_msgs_ptr);
zdshelby 0:aafd54b05111 1290 uint8_t i = 0;
zdshelby 0:aafd54b05111 1291
zdshelby 0:aafd54b05111 1292 /* Loop all stored resending messages Linked list */
zdshelby 0:aafd54b05111 1293 for (i = 0; i < stored_resending_msgs_count; i++)
zdshelby 0:aafd54b05111 1294 {
zdshelby 0:aafd54b05111 1295 /* Get message ID from stored resending message */
zdshelby 0:aafd54b05111 1296 uint16_t temp_msg_id = (stored_msg_ptr->send_msg_ptr->packet_ptr[2] << 8);
zdshelby 0:aafd54b05111 1297 temp_msg_id += (uint16_t)stored_msg_ptr->send_msg_ptr->packet_ptr[3];
zdshelby 0:aafd54b05111 1298
zdshelby 0:aafd54b05111 1299 /* If message's Message ID is same than is searched */
zdshelby 0:aafd54b05111 1300 if (temp_msg_id == msg_id)
zdshelby 0:aafd54b05111 1301 {
zdshelby 0:aafd54b05111 1302 int8_t mem_cmp_result = memcmp(src_addr_ptr->addr_ptr, stored_msg_ptr->send_msg_ptr->dst_addr_ptr->addr_ptr, src_addr_ptr->addr_len);
zdshelby 0:aafd54b05111 1303
zdshelby 0:aafd54b05111 1304 /* If message's Source address is same than is searched */
zdshelby 0:aafd54b05111 1305 if (mem_cmp_result == 0)
zdshelby 0:aafd54b05111 1306 {
zdshelby 0:aafd54b05111 1307 /* If message's Source address port is same than is searched */
zdshelby 0:aafd54b05111 1308 if (stored_msg_ptr->send_msg_ptr->dst_addr_ptr->port == src_addr_ptr->port)
zdshelby 0:aafd54b05111 1309 {
zdshelby 0:aafd54b05111 1310 /* * * Message found, return pointer to that stored resending message * * * */
zdshelby 0:aafd54b05111 1311 return stored_msg_ptr->send_msg_ptr;
zdshelby 0:aafd54b05111 1312 }
zdshelby 0:aafd54b05111 1313 }
zdshelby 0:aafd54b05111 1314 }
zdshelby 0:aafd54b05111 1315
zdshelby 0:aafd54b05111 1316 /* Get next stored message to be searched */
zdshelby 0:aafd54b05111 1317 stored_msg_ptr = sn_linked_list_get_previous_node(global_linked_list_resent_msgs_ptr);
zdshelby 0:aafd54b05111 1318 }
zdshelby 0:aafd54b05111 1319
zdshelby 0:aafd54b05111 1320 /* Message not found */
zdshelby 0:aafd54b05111 1321 return NULL;
zdshelby 0:aafd54b05111 1322 }
zdshelby 0:aafd54b05111 1323 /**************************************************************************//**
zdshelby 0:aafd54b05111 1324 * \fn static void sn_coap_protocol_linked_list_send_msg_remove(sn_nsdl_addr_s *src_addr_ptr, uint16_t msg_id)
zdshelby 0:aafd54b05111 1325 *
zdshelby 0:aafd54b05111 1326 * \brief Removes stored resending message from Linked list
zdshelby 0:aafd54b05111 1327 *
zdshelby 0:aafd54b05111 1328 * \param *src_addr_ptr is searching key for searched message
zdshelby 0:aafd54b05111 1329 * \param msg_id is searching key for removed message
zdshelby 0:aafd54b05111 1330 *****************************************************************************/
zdshelby 0:aafd54b05111 1331
zdshelby 0:aafd54b05111 1332 static void sn_coap_protocol_linked_list_send_msg_remove(sn_nsdl_addr_s *src_addr_ptr, uint16_t msg_id)
zdshelby 0:aafd54b05111 1333 {
zdshelby 0:aafd54b05111 1334 coap_send_msg_s *stored_msg_ptr = sn_linked_list_get_last_node(global_linked_list_resent_msgs_ptr);
zdshelby 0:aafd54b05111 1335 uint16_t stored_resending_msgs_count = sn_linked_list_count_nodes(global_linked_list_resent_msgs_ptr);
zdshelby 0:aafd54b05111 1336 uint8_t i = 0;
zdshelby 0:aafd54b05111 1337
zdshelby 0:aafd54b05111 1338 /* Loop all stored resending messages in Linked list */
zdshelby 0:aafd54b05111 1339 for (i = 0; i < stored_resending_msgs_count; i++)
zdshelby 0:aafd54b05111 1340 {
zdshelby 0:aafd54b05111 1341 /* Get message ID from stored resending message */
zdshelby 0:aafd54b05111 1342 uint16_t temp_msg_id = (stored_msg_ptr->send_msg_ptr->packet_ptr[2] << 8);
zdshelby 0:aafd54b05111 1343 temp_msg_id += (uint16_t)stored_msg_ptr->send_msg_ptr->packet_ptr[3];
zdshelby 0:aafd54b05111 1344
zdshelby 0:aafd54b05111 1345 /* If message's Message ID is same than is searched */
zdshelby 0:aafd54b05111 1346 if (temp_msg_id == msg_id)
zdshelby 0:aafd54b05111 1347 {
zdshelby 0:aafd54b05111 1348 int8_t mem_cmp_result = memcmp(src_addr_ptr->addr_ptr, stored_msg_ptr->send_msg_ptr->dst_addr_ptr->addr_ptr, src_addr_ptr->addr_len);
zdshelby 0:aafd54b05111 1349
zdshelby 0:aafd54b05111 1350 /* If message's Source address is same than is searched */
zdshelby 0:aafd54b05111 1351 if (mem_cmp_result == 0)
zdshelby 0:aafd54b05111 1352 {
zdshelby 0:aafd54b05111 1353 /* If message's Source address port is same than is searched */
zdshelby 0:aafd54b05111 1354 if (stored_msg_ptr->send_msg_ptr->dst_addr_ptr->port == src_addr_ptr->port)
zdshelby 0:aafd54b05111 1355 {
zdshelby 0:aafd54b05111 1356 /* * * Message found * * */
zdshelby 0:aafd54b05111 1357
zdshelby 0:aafd54b05111 1358 /* Free memory of stored message */
zdshelby 0:aafd54b05111 1359 sn_coap_protocol_release_allocated_send_msg_mem(stored_msg_ptr);
zdshelby 0:aafd54b05111 1360
zdshelby 0:aafd54b05111 1361 /* Remove message from Linked list */
zdshelby 0:aafd54b05111 1362 stored_msg_ptr = sn_linked_list_remove_current_node(global_linked_list_resent_msgs_ptr);
zdshelby 0:aafd54b05111 1363
zdshelby 0:aafd54b05111 1364 return;
zdshelby 0:aafd54b05111 1365 }
zdshelby 0:aafd54b05111 1366 }
zdshelby 0:aafd54b05111 1367 }
zdshelby 0:aafd54b05111 1368
zdshelby 0:aafd54b05111 1369 /* Get next stored message to be searched */
zdshelby 0:aafd54b05111 1370 stored_msg_ptr = sn_linked_list_get_previous_node(global_linked_list_resent_msgs_ptr);
zdshelby 0:aafd54b05111 1371 }
zdshelby 0:aafd54b05111 1372 }
zdshelby 0:aafd54b05111 1373 #endif /* ENABLE_RESENDINGS */
zdshelby 0:aafd54b05111 1374
zdshelby 0:aafd54b05111 1375 /**************************************************************************//**
zdshelby 0:aafd54b05111 1376 * \fn static void sn_coap_protocol_linked_list_ack_info_store(uint16_t msg_id, uint8_t token_len, uint8_t *token_ptr, sn_nsdl_addr_s *addr_ptr)
zdshelby 0:aafd54b05111 1377 *
zdshelby 0:aafd54b05111 1378 * \brief Stores Acknowledgement info to Linked list
zdshelby 0:aafd54b05111 1379 *
zdshelby 0:aafd54b05111 1380 * \param msg_id is Message ID to be stored
zdshelby 0:aafd54b05111 1381 *
zdshelby 0:aafd54b05111 1382 * \param token_len is length of Token to be stored
zdshelby 0:aafd54b05111 1383 *
zdshelby 0:aafd54b05111 1384 * \param *token_ptr is pointer to Token data to be stored
zdshelby 0:aafd54b05111 1385 *
zdshelby 0:aafd54b05111 1386 * \param *addr_ptr is pointer to Address information to be stored
zdshelby 0:aafd54b05111 1387 *****************************************************************************/
zdshelby 0:aafd54b05111 1388
zdshelby 0:aafd54b05111 1389 static void sn_coap_protocol_linked_list_ack_info_store(uint16_t msg_id, uint8_t token_len, uint8_t *token_ptr, sn_nsdl_addr_s *addr_ptr)
zdshelby 0:aafd54b05111 1390 {
zdshelby 0:aafd54b05111 1391 coap_ack_info_s *stored_ack_info_ptr = NULL;
zdshelby 0:aafd54b05111 1392
zdshelby 0:aafd54b05111 1393 /* Remove oldest ack infos from linked list */
zdshelby 0:aafd54b05111 1394 if(sn_linked_list_count_nodes(global_linked_list_ack_info_ptr) >= SN_COAP_ACK_INFO_MAX_COUNT_MESSAGES_SAVED)
zdshelby 0:aafd54b05111 1395 {
zdshelby 0:aafd54b05111 1396 stored_ack_info_ptr = sn_linked_list_get_last_node(global_linked_list_ack_info_ptr);
zdshelby 0:aafd54b05111 1397
zdshelby 0:aafd54b05111 1398 if(stored_ack_info_ptr)
zdshelby 0:aafd54b05111 1399 {
zdshelby 0:aafd54b05111 1400 sn_linked_list_remove_current_node(global_linked_list_ack_info_ptr);
zdshelby 0:aafd54b05111 1401
zdshelby 0:aafd54b05111 1402 if(stored_ack_info_ptr->addr_ptr)
zdshelby 0:aafd54b05111 1403 sn_coap_protocol_free(stored_ack_info_ptr->addr_ptr);
zdshelby 0:aafd54b05111 1404
zdshelby 0:aafd54b05111 1405 if(stored_ack_info_ptr->token_ptr)
zdshelby 0:aafd54b05111 1406 sn_coap_protocol_free(stored_ack_info_ptr->token_ptr);
zdshelby 0:aafd54b05111 1407
zdshelby 0:aafd54b05111 1408 sn_coap_protocol_free(stored_ack_info_ptr);
zdshelby 0:aafd54b05111 1409
zdshelby 0:aafd54b05111 1410 stored_ack_info_ptr = NULL;
zdshelby 0:aafd54b05111 1411 }
zdshelby 0:aafd54b05111 1412 }
zdshelby 0:aafd54b05111 1413
zdshelby 0:aafd54b05111 1414 /* * * * Allocating memory for stored Acknowledgement info * * * */
zdshelby 0:aafd54b05111 1415
zdshelby 0:aafd54b05111 1416 /* Allocate memory for stored Acknowledgement info's structure */
zdshelby 0:aafd54b05111 1417 stored_ack_info_ptr = sn_coap_protocol_malloc(sizeof(coap_ack_info_s));
zdshelby 0:aafd54b05111 1418
zdshelby 0:aafd54b05111 1419 if (stored_ack_info_ptr == NULL)
zdshelby 0:aafd54b05111 1420 {
zdshelby 0:aafd54b05111 1421 return;
zdshelby 0:aafd54b05111 1422 }
zdshelby 0:aafd54b05111 1423
zdshelby 0:aafd54b05111 1424 if(token_ptr)
zdshelby 0:aafd54b05111 1425 {
zdshelby 0:aafd54b05111 1426
zdshelby 0:aafd54b05111 1427 /* Allocate memory for stored Acknowledgement info's token */
zdshelby 0:aafd54b05111 1428 stored_ack_info_ptr->token_ptr = sn_coap_protocol_malloc(token_len);
zdshelby 0:aafd54b05111 1429
zdshelby 0:aafd54b05111 1430 if (stored_ack_info_ptr->token_ptr == NULL)
zdshelby 0:aafd54b05111 1431 {
zdshelby 0:aafd54b05111 1432 sn_coap_protocol_free(stored_ack_info_ptr);
zdshelby 0:aafd54b05111 1433
zdshelby 0:aafd54b05111 1434 return;
zdshelby 0:aafd54b05111 1435 }
zdshelby 0:aafd54b05111 1436
zdshelby 0:aafd54b05111 1437 }
zdshelby 0:aafd54b05111 1438
zdshelby 0:aafd54b05111 1439 /* Allocate memory for stored Acknowledgement info's address */
zdshelby 0:aafd54b05111 1440 stored_ack_info_ptr->addr_ptr = sn_coap_protocol_malloc(addr_ptr->addr_len);
zdshelby 0:aafd54b05111 1441
zdshelby 0:aafd54b05111 1442 if (stored_ack_info_ptr->addr_ptr == NULL)
zdshelby 0:aafd54b05111 1443 {
zdshelby 0:aafd54b05111 1444 sn_coap_protocol_free(stored_ack_info_ptr->token_ptr);
zdshelby 0:aafd54b05111 1445 sn_coap_protocol_free(stored_ack_info_ptr);
zdshelby 0:aafd54b05111 1446 return;
zdshelby 0:aafd54b05111 1447 }
zdshelby 0:aafd54b05111 1448
zdshelby 0:aafd54b05111 1449 /* * * * Filling fields of stored Acknowledgement info * * * */
zdshelby 0:aafd54b05111 1450
zdshelby 0:aafd54b05111 1451 stored_ack_info_ptr->timestamp = global_system_time;
zdshelby 0:aafd54b05111 1452 stored_ack_info_ptr->msg_id = msg_id;
zdshelby 0:aafd54b05111 1453 stored_ack_info_ptr->token_len = token_len;
zdshelby 0:aafd54b05111 1454 if(token_ptr)
zdshelby 0:aafd54b05111 1455 {
zdshelby 0:aafd54b05111 1456 memcpy(stored_ack_info_ptr->token_ptr, token_ptr, token_len);
zdshelby 0:aafd54b05111 1457 }
zdshelby 0:aafd54b05111 1458 else
zdshelby 0:aafd54b05111 1459 {
zdshelby 0:aafd54b05111 1460 stored_ack_info_ptr->token_ptr = NULL;
zdshelby 0:aafd54b05111 1461 }
zdshelby 0:aafd54b05111 1462 memcpy(stored_ack_info_ptr->addr_ptr, addr_ptr->addr_ptr, addr_ptr->addr_len);
zdshelby 0:aafd54b05111 1463 stored_ack_info_ptr->port = addr_ptr->port;
zdshelby 0:aafd54b05111 1464
zdshelby 0:aafd54b05111 1465 /* * * * Storing Acknowledgement info to Linked list * * * */
zdshelby 0:aafd54b05111 1466
zdshelby 0:aafd54b05111 1467 if(sn_linked_list_add_node(global_linked_list_ack_info_ptr, stored_ack_info_ptr) != 0)
zdshelby 0:aafd54b05111 1468 {
zdshelby 0:aafd54b05111 1469 sn_coap_protocol_free(stored_ack_info_ptr->addr_ptr);
zdshelby 0:aafd54b05111 1470 sn_coap_protocol_free(stored_ack_info_ptr->token_ptr);
zdshelby 0:aafd54b05111 1471 sn_coap_protocol_free(stored_ack_info_ptr);
zdshelby 0:aafd54b05111 1472 return;
zdshelby 0:aafd54b05111 1473 }
zdshelby 0:aafd54b05111 1474 }
zdshelby 0:aafd54b05111 1475
zdshelby 0:aafd54b05111 1476 /**************************************************************************//**
zdshelby 0:aafd54b05111 1477 * \fn static int32_t sn_coap_protocol_linked_list_ack_info_search(uint8_t token_len, uint8_t *token_ptr, sn_nsdl_addr_s *addr_ptr)
zdshelby 0:aafd54b05111 1478 *
zdshelby 0:aafd54b05111 1479 * \brief Searches stored Message ID from Linked list
zdshelby 0:aafd54b05111 1480 *
zdshelby 0:aafd54b05111 1481 * \param token_len is length of Token key to be searched
zdshelby 0:aafd54b05111 1482 *
zdshelby 0:aafd54b05111 1483 * \param *token_ptr is pointer to Token key to be searched
zdshelby 0:aafd54b05111 1484 *
zdshelby 0:aafd54b05111 1485 * \param *addr_ptr is pointer to Address key to be searched
zdshelby 0:aafd54b05111 1486 *
zdshelby 0:aafd54b05111 1487 * \return Return value is found Message ID. If Message ID not found, -1 is returned.
zdshelby 0:aafd54b05111 1488 *****************************************************************************/
zdshelby 0:aafd54b05111 1489
zdshelby 0:aafd54b05111 1490 static int32_t sn_coap_protocol_linked_list_ack_info_search(uint16_t msg_id, uint8_t token_len, uint8_t *token_ptr, sn_nsdl_addr_s *addr_ptr)
zdshelby 0:aafd54b05111 1491 {
zdshelby 0:aafd54b05111 1492 coap_ack_info_s *stored_ack_info_ptr = sn_linked_list_get_last_node(global_linked_list_ack_info_ptr);
zdshelby 0:aafd54b05111 1493 uint16_t stored_ack_info_count = sn_linked_list_count_nodes(global_linked_list_ack_info_ptr);
zdshelby 0:aafd54b05111 1494 uint8_t i = 0;
zdshelby 0:aafd54b05111 1495 uint8_t mem_cmp_result = 0;
zdshelby 0:aafd54b05111 1496
zdshelby 0:aafd54b05111 1497 if(!addr_ptr)
zdshelby 0:aafd54b05111 1498 return -1;
zdshelby 0:aafd54b05111 1499
zdshelby 0:aafd54b05111 1500 if(!addr_ptr->addr_ptr)
zdshelby 0:aafd54b05111 1501 return -1;
zdshelby 0:aafd54b05111 1502
zdshelby 0:aafd54b05111 1503 /* Loop all nodes in Linked list for searching Message ID */
zdshelby 0:aafd54b05111 1504 for (i = 0; i < stored_ack_info_count; i++)
zdshelby 0:aafd54b05111 1505 {
zdshelby 0:aafd54b05111 1506 if(!stored_ack_info_ptr)
zdshelby 0:aafd54b05111 1507 return -1;
zdshelby 0:aafd54b05111 1508
zdshelby 0:aafd54b05111 1509 /* If message's Token option is same than is searched */
zdshelby 0:aafd54b05111 1510 if(msg_id == stored_ack_info_ptr->msg_id)
zdshelby 0:aafd54b05111 1511 {
zdshelby 0:aafd54b05111 1512 if(stored_ack_info_ptr->addr_ptr)
zdshelby 0:aafd54b05111 1513 {
zdshelby 0:aafd54b05111 1514 mem_cmp_result = memcmp(addr_ptr->addr_ptr, stored_ack_info_ptr->addr_ptr, addr_ptr->addr_len);
zdshelby 0:aafd54b05111 1515
zdshelby 0:aafd54b05111 1516 /* If message's Source address is same than is searched */
zdshelby 0:aafd54b05111 1517 if (mem_cmp_result == 0)
zdshelby 0:aafd54b05111 1518 {
zdshelby 0:aafd54b05111 1519 /* If message's Source address port is same than is searched */
zdshelby 0:aafd54b05111 1520 if (stored_ack_info_ptr->port == addr_ptr->port)
zdshelby 0:aafd54b05111 1521 {
zdshelby 0:aafd54b05111 1522 if(stored_ack_info_ptr->token_ptr && token_ptr)
zdshelby 0:aafd54b05111 1523 {
zdshelby 0:aafd54b05111 1524 if(stored_ack_info_ptr->token_len == token_len)
zdshelby 0:aafd54b05111 1525 {
zdshelby 0:aafd54b05111 1526 mem_cmp_result = memcmp(token_ptr, stored_ack_info_ptr->token_ptr, token_len);
zdshelby 0:aafd54b05111 1527
zdshelby 0:aafd54b05111 1528 if (mem_cmp_result == 0)
zdshelby 0:aafd54b05111 1529 {
zdshelby 0:aafd54b05111 1530 /* ACK found and token match */
zdshelby 0:aafd54b05111 1531 return stored_ack_info_ptr->msg_id;
zdshelby 0:aafd54b05111 1532 }
zdshelby 0:aafd54b05111 1533
zdshelby 0:aafd54b05111 1534 }
zdshelby 0:aafd54b05111 1535 return (-2); /* Token does not match */
zdshelby 0:aafd54b05111 1536 }
zdshelby 0:aafd54b05111 1537 else
zdshelby 0:aafd54b05111 1538 {
zdshelby 0:aafd54b05111 1539 /* * * Correct Acknowledgement info found * * * */
zdshelby 0:aafd54b05111 1540 return stored_ack_info_ptr->msg_id;
zdshelby 0:aafd54b05111 1541 }
zdshelby 0:aafd54b05111 1542 }
zdshelby 0:aafd54b05111 1543 }
zdshelby 0:aafd54b05111 1544 }
zdshelby 0:aafd54b05111 1545 }
zdshelby 0:aafd54b05111 1546 /* Get next stored Acknowledgement info to be searched */
zdshelby 0:aafd54b05111 1547 stored_ack_info_ptr = sn_linked_list_get_previous_node(global_linked_list_ack_info_ptr);
zdshelby 0:aafd54b05111 1548 }
zdshelby 0:aafd54b05111 1549
zdshelby 0:aafd54b05111 1550 return -1;
zdshelby 0:aafd54b05111 1551 }
zdshelby 0:aafd54b05111 1552
zdshelby 0:aafd54b05111 1553 /**************************************************************************//**
zdshelby 0:aafd54b05111 1554 * \fn static void sn_coap_protocol_linked_list_ack_info_remove(uint8_t token_len, uint8_t *token_ptr, sn_nsdl_addr_s *addr_ptr)
zdshelby 0:aafd54b05111 1555 *
zdshelby 0:aafd54b05111 1556 * \brief Removes stored Acknowledgement info from Linked list
zdshelby 0:aafd54b05111 1557 *
zdshelby 0:aafd54b05111 1558 * \param token_len is length of Token key to be removed
zdshelby 0:aafd54b05111 1559 *
zdshelby 0:aafd54b05111 1560 * \param *token_ptr is pointer to Token key to be removed
zdshelby 0:aafd54b05111 1561 *
zdshelby 0:aafd54b05111 1562 * \param *addr_ptr is pointer to Address key to be removed
zdshelby 0:aafd54b05111 1563 *****************************************************************************/
zdshelby 0:aafd54b05111 1564
zdshelby 0:aafd54b05111 1565 static void sn_coap_protocol_linked_list_ack_info_remove(uint16_t msg_id, sn_nsdl_addr_s *addr_ptr)
zdshelby 0:aafd54b05111 1566 {
zdshelby 0:aafd54b05111 1567 uint16_t stored_ack_info_count = sn_linked_list_count_nodes(global_linked_list_ack_info_ptr);
zdshelby 0:aafd54b05111 1568 coap_ack_info_s *stored_ack_info_ptr = sn_linked_list_get_last_node(global_linked_list_ack_info_ptr);
zdshelby 0:aafd54b05111 1569 uint8_t i = 0;
zdshelby 0:aafd54b05111 1570
zdshelby 0:aafd54b05111 1571 if(!addr_ptr)
zdshelby 0:aafd54b05111 1572 return;
zdshelby 0:aafd54b05111 1573
zdshelby 0:aafd54b05111 1574 if(!addr_ptr->addr_ptr)
zdshelby 0:aafd54b05111 1575 return;
zdshelby 0:aafd54b05111 1576
zdshelby 0:aafd54b05111 1577 /* Loop all stored Acknowledgement infos in Linked list */
zdshelby 0:aafd54b05111 1578 for (i = 0; i < stored_ack_info_count; i++)
zdshelby 0:aafd54b05111 1579 {
zdshelby 0:aafd54b05111 1580 if(!stored_ack_info_ptr)
zdshelby 0:aafd54b05111 1581 return;
zdshelby 0:aafd54b05111 1582
zdshelby 0:aafd54b05111 1583 /* If message's Token option is same than is searched */
zdshelby 0:aafd54b05111 1584 if (msg_id == stored_ack_info_ptr->msg_id)
zdshelby 0:aafd54b05111 1585 {
zdshelby 0:aafd54b05111 1586
zdshelby 0:aafd54b05111 1587 if (stored_ack_info_ptr->port == addr_ptr->port)
zdshelby 0:aafd54b05111 1588 {
zdshelby 0:aafd54b05111 1589 if(stored_ack_info_ptr->addr_ptr)
zdshelby 0:aafd54b05111 1590 {
zdshelby 0:aafd54b05111 1591 /* If message's Address is same than is searched */
zdshelby 0:aafd54b05111 1592 if (!memcmp(addr_ptr->addr_ptr, stored_ack_info_ptr->addr_ptr, addr_ptr->addr_len))
zdshelby 0:aafd54b05111 1593 {
zdshelby 0:aafd54b05111 1594 /* * * * Correct Acknowledgement info found, remove it from Linked list * * * */
zdshelby 0:aafd54b05111 1595 stored_ack_info_ptr = sn_linked_list_remove_current_node(global_linked_list_ack_info_ptr);
zdshelby 0:aafd54b05111 1596
zdshelby 0:aafd54b05111 1597 /* Free memory of stored Acknowledgement info */
zdshelby 0:aafd54b05111 1598 if(stored_ack_info_ptr->token_ptr)
zdshelby 0:aafd54b05111 1599 sn_coap_protocol_free(stored_ack_info_ptr->token_ptr);
zdshelby 0:aafd54b05111 1600
zdshelby 0:aafd54b05111 1601 sn_coap_protocol_free(stored_ack_info_ptr->addr_ptr);
zdshelby 0:aafd54b05111 1602 sn_coap_protocol_free(stored_ack_info_ptr);
zdshelby 0:aafd54b05111 1603
zdshelby 0:aafd54b05111 1604 return;
zdshelby 0:aafd54b05111 1605 }
zdshelby 0:aafd54b05111 1606 }
zdshelby 0:aafd54b05111 1607 }
zdshelby 0:aafd54b05111 1608
zdshelby 0:aafd54b05111 1609 }
zdshelby 0:aafd54b05111 1610
zdshelby 0:aafd54b05111 1611 /* Get next stored message to be searched */
zdshelby 0:aafd54b05111 1612 stored_ack_info_ptr = sn_linked_list_get_previous_node(global_linked_list_ack_info_ptr);
zdshelby 0:aafd54b05111 1613 }
zdshelby 0:aafd54b05111 1614 }
zdshelby 0:aafd54b05111 1615
zdshelby 0:aafd54b05111 1616 /**************************************************************************//**
zdshelby 0:aafd54b05111 1617 * \fn static void sn_coap_protocol_linked_list_ack_info_remove_old_ones(void)
zdshelby 0:aafd54b05111 1618 *
zdshelby 0:aafd54b05111 1619 * \brief Removes old stored Acknowledgement infos from Linked list
zdshelby 0:aafd54b05111 1620 *****************************************************************************/
zdshelby 0:aafd54b05111 1621
zdshelby 0:aafd54b05111 1622 static void sn_coap_protocol_linked_list_ack_info_remove_old_ones(void)
zdshelby 0:aafd54b05111 1623 {
zdshelby 0:aafd54b05111 1624 coap_ack_info_s *removed_ack_info_ptr = sn_linked_list_get_first_node(global_linked_list_ack_info_ptr);
zdshelby 0:aafd54b05111 1625
zdshelby 0:aafd54b05111 1626 /* Loop all stored Acknowledgement infos in Linked list */
zdshelby 0:aafd54b05111 1627 while(removed_ack_info_ptr)
zdshelby 0:aafd54b05111 1628 {
zdshelby 0:aafd54b05111 1629 if ((global_system_time - removed_ack_info_ptr->timestamp) > SN_COAP_ACK_INFO_MAX_TIME_MSGS_STORED)
zdshelby 0:aafd54b05111 1630 {
zdshelby 0:aafd54b05111 1631 /* * * * Old Acknowledgement info found, remove it from Linked list * * * */
zdshelby 0:aafd54b05111 1632 removed_ack_info_ptr = sn_linked_list_remove_current_node(global_linked_list_ack_info_ptr);
zdshelby 0:aafd54b05111 1633
zdshelby 0:aafd54b05111 1634 /* Free memory of stored Acknowledgement info */
zdshelby 0:aafd54b05111 1635 if(removed_ack_info_ptr->token_ptr)
zdshelby 0:aafd54b05111 1636 {
zdshelby 0:aafd54b05111 1637 sn_coap_protocol_free(removed_ack_info_ptr->token_ptr);
zdshelby 0:aafd54b05111 1638 }
zdshelby 0:aafd54b05111 1639
zdshelby 0:aafd54b05111 1640 if(removed_ack_info_ptr->addr_ptr)
zdshelby 0:aafd54b05111 1641 {
zdshelby 0:aafd54b05111 1642 sn_coap_protocol_free(removed_ack_info_ptr->addr_ptr);
zdshelby 0:aafd54b05111 1643 }
zdshelby 0:aafd54b05111 1644
zdshelby 0:aafd54b05111 1645 sn_coap_protocol_free(removed_ack_info_ptr);
zdshelby 0:aafd54b05111 1646
zdshelby 0:aafd54b05111 1647 /* Remove current node moved list automatically to next node. That is why we can fetch it now by calling get current node. */
zdshelby 0:aafd54b05111 1648 removed_ack_info_ptr = sn_linked_list_get_current_node(global_linked_list_ack_info_ptr);
zdshelby 0:aafd54b05111 1649 }
zdshelby 0:aafd54b05111 1650 else
zdshelby 0:aafd54b05111 1651 {
zdshelby 0:aafd54b05111 1652 /* Get next stored message to be searched */
zdshelby 0:aafd54b05111 1653 removed_ack_info_ptr = sn_linked_list_get_next_node(global_linked_list_ack_info_ptr);
zdshelby 0:aafd54b05111 1654 }
zdshelby 0:aafd54b05111 1655 }
zdshelby 0:aafd54b05111 1656 }
zdshelby 0:aafd54b05111 1657
zdshelby 0:aafd54b05111 1658 static void sn_coap_protocol_send_rst(uint16_t msg_id, sn_nsdl_addr_s *addr_ptr)
zdshelby 0:aafd54b05111 1659 {
zdshelby 0:aafd54b05111 1660 uint8_t packet_ptr[4];
zdshelby 0:aafd54b05111 1661
zdshelby 0:aafd54b05111 1662 /* Add CoAP version and message type */
zdshelby 0:aafd54b05111 1663 packet_ptr[0] = COAP_VERSION_1;
zdshelby 0:aafd54b05111 1664 packet_ptr[0] |= COAP_MSG_TYPE_RESET;
zdshelby 0:aafd54b05111 1665
zdshelby 0:aafd54b05111 1666 /* Add message code */
zdshelby 0:aafd54b05111 1667 packet_ptr[1] = COAP_MSG_CODE_EMPTY;
zdshelby 0:aafd54b05111 1668
zdshelby 0:aafd54b05111 1669 /* Add message ID */
zdshelby 0:aafd54b05111 1670 packet_ptr[2] = msg_id >> 8;
zdshelby 0:aafd54b05111 1671 packet_ptr[3] = (uint8_t)msg_id;
zdshelby 0:aafd54b05111 1672
zdshelby 0:aafd54b05111 1673 /* Send RST */
zdshelby 0:aafd54b05111 1674 sn_coap_tx_callback(SN_NSDL_PROTOCOL_COAP, packet_ptr, 4, addr_ptr);
zdshelby 0:aafd54b05111 1675
zdshelby 0:aafd54b05111 1676 }
zdshelby 0:aafd54b05111 1677 #if SN_COAP_DUPLICATION_MAX_MSGS_COUNT /* If Message duplication detection is not used at all, this part of code will not be compiled */
zdshelby 0:aafd54b05111 1678
zdshelby 0:aafd54b05111 1679 /**************************************************************************//**
zdshelby 0:aafd54b05111 1680 * \fn static void sn_coap_protocol_linked_list_duplication_info_store(sn_nsdl_addr_s *addr_ptr, uint16_t msg_id)
zdshelby 0:aafd54b05111 1681 *
zdshelby 0:aafd54b05111 1682 * \brief Stores Duplication info to Linked list
zdshelby 0:aafd54b05111 1683 *
zdshelby 0:aafd54b05111 1684 * \param msg_id is Message ID to be stored
zdshelby 0:aafd54b05111 1685 * \param *addr_ptr is pointer to Address information to be stored
zdshelby 0:aafd54b05111 1686 *****************************************************************************/
zdshelby 0:aafd54b05111 1687
zdshelby 0:aafd54b05111 1688 static void sn_coap_protocol_linked_list_duplication_info_store(sn_nsdl_addr_s *addr_ptr,
zdshelby 0:aafd54b05111 1689 uint16_t msg_id)
zdshelby 0:aafd54b05111 1690 {
zdshelby 0:aafd54b05111 1691 coap_duplication_info_s *stored_duplication_info_ptr = NULL;
zdshelby 0:aafd54b05111 1692
zdshelby 0:aafd54b05111 1693 /* * * * Allocating memory for stored Duplication info * * * */
zdshelby 0:aafd54b05111 1694
zdshelby 0:aafd54b05111 1695 /* Allocate memory for stored Duplication info's structure */
zdshelby 0:aafd54b05111 1696 stored_duplication_info_ptr = sn_coap_protocol_malloc(sizeof(coap_duplication_info_s));
zdshelby 0:aafd54b05111 1697
zdshelby 0:aafd54b05111 1698 if (stored_duplication_info_ptr == NULL)
zdshelby 0:aafd54b05111 1699 {
zdshelby 0:aafd54b05111 1700 return;
zdshelby 0:aafd54b05111 1701 }
zdshelby 0:aafd54b05111 1702
zdshelby 0:aafd54b05111 1703 /* Allocate memory for stored Duplication info's address */
zdshelby 0:aafd54b05111 1704 stored_duplication_info_ptr->addr_ptr = sn_coap_protocol_malloc(addr_ptr->addr_len);
zdshelby 0:aafd54b05111 1705
zdshelby 0:aafd54b05111 1706 if (stored_duplication_info_ptr->addr_ptr == NULL)
zdshelby 0:aafd54b05111 1707 {
zdshelby 0:aafd54b05111 1708 sn_coap_protocol_free(stored_duplication_info_ptr);
zdshelby 0:aafd54b05111 1709
zdshelby 0:aafd54b05111 1710 return;
zdshelby 0:aafd54b05111 1711 }
zdshelby 0:aafd54b05111 1712
zdshelby 0:aafd54b05111 1713 /* * * * Filling fields of stored Duplication info * * * */
zdshelby 0:aafd54b05111 1714
zdshelby 0:aafd54b05111 1715 stored_duplication_info_ptr->timestamp = global_system_time;
zdshelby 0:aafd54b05111 1716 stored_duplication_info_ptr->addr_len = addr_ptr->addr_len;
zdshelby 0:aafd54b05111 1717 memcpy(stored_duplication_info_ptr->addr_ptr, addr_ptr->addr_ptr, addr_ptr->addr_len);
zdshelby 0:aafd54b05111 1718 stored_duplication_info_ptr->port = addr_ptr->port;
zdshelby 0:aafd54b05111 1719 stored_duplication_info_ptr->msg_id = msg_id;
zdshelby 0:aafd54b05111 1720
zdshelby 0:aafd54b05111 1721 /* * * * Storing Duplication info to Linked list * * * */
zdshelby 0:aafd54b05111 1722
zdshelby 0:aafd54b05111 1723 sn_linked_list_add_node(global_linked_list_duplication_msgs_ptr, stored_duplication_info_ptr);
zdshelby 0:aafd54b05111 1724 }
zdshelby 0:aafd54b05111 1725
zdshelby 0:aafd54b05111 1726 /**************************************************************************//**
zdshelby 0:aafd54b05111 1727 * \fn static int8_t sn_coap_protocol_linked_list_duplication_info_search(sn_nsdl_addr_s *addr_ptr, uint16_t msg_id)
zdshelby 0:aafd54b05111 1728 *
zdshelby 0:aafd54b05111 1729 * \brief Searches stored message from Linked list (Address and Message ID as key)
zdshelby 0:aafd54b05111 1730 *
zdshelby 0:aafd54b05111 1731 * \param *addr_ptr is pointer to Address key to be searched
zdshelby 0:aafd54b05111 1732 * \param msg_id is Message ID key to be searched
zdshelby 0:aafd54b05111 1733 *
zdshelby 0:aafd54b05111 1734 * \return Return value is 0 when message found and -1 if not found
zdshelby 0:aafd54b05111 1735 *****************************************************************************/
zdshelby 0:aafd54b05111 1736
zdshelby 0:aafd54b05111 1737 static int8_t sn_coap_protocol_linked_list_duplication_info_search(sn_nsdl_addr_s *addr_ptr,
zdshelby 0:aafd54b05111 1738 uint16_t msg_id)
zdshelby 0:aafd54b05111 1739 {
zdshelby 0:aafd54b05111 1740 coap_duplication_info_s *stored_duplication_info_ptr = sn_linked_list_get_last_node(global_linked_list_duplication_msgs_ptr);
zdshelby 0:aafd54b05111 1741 uint16_t stored_duplication_msgs_count = sn_linked_list_count_nodes(global_linked_list_duplication_msgs_ptr);
zdshelby 0:aafd54b05111 1742 uint8_t i = 0;
zdshelby 0:aafd54b05111 1743
zdshelby 0:aafd54b05111 1744 /* Loop all nodes in Linked list for searching Message ID */
zdshelby 0:aafd54b05111 1745 for (i = 0; i < stored_duplication_msgs_count; i++)
zdshelby 0:aafd54b05111 1746 {
zdshelby 0:aafd54b05111 1747 /* If message's Message ID is same than is searched */
zdshelby 0:aafd54b05111 1748 if (stored_duplication_info_ptr->msg_id == msg_id)
zdshelby 0:aafd54b05111 1749 {
zdshelby 0:aafd54b05111 1750 int8_t mem_cmp_result = memcmp(addr_ptr->addr_ptr, stored_duplication_info_ptr->addr_ptr, addr_ptr->addr_len);
zdshelby 0:aafd54b05111 1751
zdshelby 0:aafd54b05111 1752 /* If message's Source address is same than is searched */
zdshelby 0:aafd54b05111 1753 if (mem_cmp_result == 0)
zdshelby 0:aafd54b05111 1754 {
zdshelby 0:aafd54b05111 1755 /* If message's Source address port is same than is searched */
zdshelby 0:aafd54b05111 1756 if (stored_duplication_info_ptr->port == addr_ptr->port)
zdshelby 0:aafd54b05111 1757 {
zdshelby 0:aafd54b05111 1758 /* * * Correct Duplication info found * * * */
zdshelby 0:aafd54b05111 1759 return 0;
zdshelby 0:aafd54b05111 1760 }
zdshelby 0:aafd54b05111 1761 }
zdshelby 0:aafd54b05111 1762 }
zdshelby 0:aafd54b05111 1763 /* Get next stored Duplication info to be searched */
zdshelby 0:aafd54b05111 1764 stored_duplication_info_ptr = sn_linked_list_get_previous_node(global_linked_list_duplication_msgs_ptr);
zdshelby 0:aafd54b05111 1765 }
zdshelby 0:aafd54b05111 1766
zdshelby 0:aafd54b05111 1767 return -1;
zdshelby 0:aafd54b05111 1768 }
zdshelby 0:aafd54b05111 1769
zdshelby 0:aafd54b05111 1770 /**************************************************************************//**
zdshelby 0:aafd54b05111 1771 * \fn static void sn_coap_protocol_linked_list_duplication_info_remove(uint8_t *addr_ptr, uint16_t port, uint16_t msg_id)
zdshelby 0:aafd54b05111 1772 *
zdshelby 0:aafd54b05111 1773 * \brief Removes stored Duplication info from Linked list
zdshelby 0:aafd54b05111 1774 *
zdshelby 0:aafd54b05111 1775 * \param *addr_ptr is pointer to Address key to be removed
zdshelby 0:aafd54b05111 1776 *
zdshelby 0:aafd54b05111 1777 * \param port is Port key to be removed
zdshelby 0:aafd54b05111 1778 *
zdshelby 0:aafd54b05111 1779 * \param msg_id is Message ID key to be removed
zdshelby 0:aafd54b05111 1780 *****************************************************************************/
zdshelby 0:aafd54b05111 1781
zdshelby 0:aafd54b05111 1782 static void sn_coap_protocol_linked_list_duplication_info_remove(uint8_t *addr_ptr, uint16_t port, uint16_t msg_id)
zdshelby 0:aafd54b05111 1783 {
zdshelby 0:aafd54b05111 1784 coap_duplication_info_s *removed_duplication_info_ptr = sn_linked_list_get_last_node(global_linked_list_duplication_msgs_ptr);
zdshelby 0:aafd54b05111 1785 uint16_t stored_duplication_msgs_count = sn_linked_list_count_nodes(global_linked_list_duplication_msgs_ptr);
zdshelby 0:aafd54b05111 1786 uint8_t i = 0;
zdshelby 0:aafd54b05111 1787
zdshelby 0:aafd54b05111 1788 /* Loop all stored duplication messages in Linked list */
zdshelby 0:aafd54b05111 1789 for (i = 0; i < stored_duplication_msgs_count; i++)
zdshelby 0:aafd54b05111 1790 {
zdshelby 0:aafd54b05111 1791 int8_t mem_cmp_result = memcmp(addr_ptr, removed_duplication_info_ptr->addr_ptr, removed_duplication_info_ptr->addr_len);
zdshelby 0:aafd54b05111 1792
zdshelby 0:aafd54b05111 1793 /* If message's Address is same than is searched */
zdshelby 0:aafd54b05111 1794 if (mem_cmp_result == 0)
zdshelby 0:aafd54b05111 1795 {
zdshelby 0:aafd54b05111 1796 /* If message's Address prt is same than is searched */
zdshelby 0:aafd54b05111 1797 if (removed_duplication_info_ptr->port == port)
zdshelby 0:aafd54b05111 1798 {
zdshelby 0:aafd54b05111 1799 /* If Message ID is same than is searched */
zdshelby 0:aafd54b05111 1800 if (removed_duplication_info_ptr->msg_id == msg_id)
zdshelby 0:aafd54b05111 1801 {
zdshelby 0:aafd54b05111 1802 /* * * * Correct Duplication info found, remove it from Linked list * * * */
zdshelby 0:aafd54b05111 1803 removed_duplication_info_ptr = sn_linked_list_remove_current_node(global_linked_list_duplication_msgs_ptr);
zdshelby 0:aafd54b05111 1804
zdshelby 0:aafd54b05111 1805 /* Free memory of stored Duplication info */
zdshelby 0:aafd54b05111 1806 sn_coap_protocol_free(removed_duplication_info_ptr->addr_ptr);
zdshelby 0:aafd54b05111 1807 sn_coap_protocol_free(removed_duplication_info_ptr);
zdshelby 0:aafd54b05111 1808
zdshelby 0:aafd54b05111 1809 return;
zdshelby 0:aafd54b05111 1810 }
zdshelby 0:aafd54b05111 1811 }
zdshelby 0:aafd54b05111 1812 }
zdshelby 0:aafd54b05111 1813
zdshelby 0:aafd54b05111 1814 /* Get next stored message to be searched */
zdshelby 0:aafd54b05111 1815 removed_duplication_info_ptr = sn_linked_list_get_previous_node(global_linked_list_duplication_msgs_ptr);
zdshelby 0:aafd54b05111 1816 }
zdshelby 0:aafd54b05111 1817 }
zdshelby 0:aafd54b05111 1818
zdshelby 0:aafd54b05111 1819 /**************************************************************************//**
zdshelby 0:aafd54b05111 1820 * \fn static void sn_coap_protocol_linked_list_duplication_info_remove_old_ones(void)
zdshelby 0:aafd54b05111 1821 *
zdshelby 0:aafd54b05111 1822 * \brief Removes old stored Duplication detection infos from Linked list
zdshelby 0:aafd54b05111 1823 *****************************************************************************/
zdshelby 0:aafd54b05111 1824
zdshelby 0:aafd54b05111 1825 static void sn_coap_protocol_linked_list_duplication_info_remove_old_ones(void)
zdshelby 0:aafd54b05111 1826 {
zdshelby 0:aafd54b05111 1827 coap_duplication_info_s *removed_duplication_info_ptr = sn_linked_list_get_first_node(global_linked_list_duplication_msgs_ptr);
zdshelby 0:aafd54b05111 1828
zdshelby 0:aafd54b05111 1829 /* Loop all stored duplication messages in Linked list */
zdshelby 0:aafd54b05111 1830 while(removed_duplication_info_ptr)
zdshelby 0:aafd54b05111 1831 {
zdshelby 0:aafd54b05111 1832 if ((global_system_time - removed_duplication_info_ptr->timestamp) > SN_COAP_DUPLICATION_MAX_TIME_MSGS_STORED)
zdshelby 0:aafd54b05111 1833 {
zdshelby 0:aafd54b05111 1834 /* * * * Old Duplication info found, remove it from Linked list * * * */
zdshelby 0:aafd54b05111 1835 removed_duplication_info_ptr = sn_linked_list_remove_current_node(global_linked_list_duplication_msgs_ptr);
zdshelby 0:aafd54b05111 1836
zdshelby 0:aafd54b05111 1837 /* Free memory of stored Duplication info */
zdshelby 0:aafd54b05111 1838 sn_coap_protocol_free(removed_duplication_info_ptr->addr_ptr);
zdshelby 0:aafd54b05111 1839 sn_coap_protocol_free(removed_duplication_info_ptr);
zdshelby 0:aafd54b05111 1840
zdshelby 0:aafd54b05111 1841 removed_duplication_info_ptr = sn_linked_list_get_current_node(global_linked_list_duplication_msgs_ptr);
zdshelby 0:aafd54b05111 1842 }
zdshelby 0:aafd54b05111 1843 else
zdshelby 0:aafd54b05111 1844 {
zdshelby 0:aafd54b05111 1845 /* Get next stored message to be searched */
zdshelby 0:aafd54b05111 1846 removed_duplication_info_ptr = sn_linked_list_get_next_node(global_linked_list_duplication_msgs_ptr);
zdshelby 0:aafd54b05111 1847 }
zdshelby 0:aafd54b05111 1848 }
zdshelby 0:aafd54b05111 1849 }
zdshelby 0:aafd54b05111 1850
zdshelby 0:aafd54b05111 1851 #endif /* SN_COAP_DUPLICATION_MAX_MSGS_COUNT */
zdshelby 0:aafd54b05111 1852
zdshelby 0:aafd54b05111 1853 #if SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE
zdshelby 0:aafd54b05111 1854 /**************************************************************************//**
zdshelby 0:aafd54b05111 1855 * \fn static void sn_coap_protocol_linked_list_blockwise_msg_remove_current()
zdshelby 0:aafd54b05111 1856 *
zdshelby 0:aafd54b05111 1857 * \brief Removes current stored blockwise message from Linked list
zdshelby 0:aafd54b05111 1858 *****************************************************************************/
zdshelby 0:aafd54b05111 1859
zdshelby 0:aafd54b05111 1860 static void sn_coap_protocol_linked_list_blockwise_msg_remove_current()
zdshelby 0:aafd54b05111 1861 {
zdshelby 0:aafd54b05111 1862 coap_blockwise_msg_s *removed_msg_ptr = sn_linked_list_remove_current_node(global_linked_list_blockwise_sent_msgs_ptr);
zdshelby 0:aafd54b05111 1863
zdshelby 0:aafd54b05111 1864 if (removed_msg_ptr != NULL)
zdshelby 0:aafd54b05111 1865 {
zdshelby 0:aafd54b05111 1866 if(removed_msg_ptr->coap_msg_ptr->payload_ptr)
zdshelby 0:aafd54b05111 1867 sn_coap_protocol_free(removed_msg_ptr->coap_msg_ptr->payload_ptr);
zdshelby 0:aafd54b05111 1868
zdshelby 0:aafd54b05111 1869 sn_coap_parser_release_allocated_coap_msg_mem(removed_msg_ptr->coap_msg_ptr);
zdshelby 0:aafd54b05111 1870
zdshelby 0:aafd54b05111 1871 sn_coap_protocol_free(removed_msg_ptr);
zdshelby 0:aafd54b05111 1872 }
zdshelby 0:aafd54b05111 1873 }
zdshelby 0:aafd54b05111 1874
zdshelby 0:aafd54b05111 1875 /**************************************************************************//**
zdshelby 0:aafd54b05111 1876 * \fn static void sn_coap_protocol_linked_list_blockwise_payload_store(sn_nsdl_addr_s *addr_ptr, uint16_t stored_payload_len, uint8_t *stored_payload_ptr)
zdshelby 0:aafd54b05111 1877 *
zdshelby 0:aafd54b05111 1878 * \brief Stores blockwise payload to Linked list
zdshelby 0:aafd54b05111 1879 *
zdshelby 0:aafd54b05111 1880 * \param *addr_ptr is pointer to Address information to be stored
zdshelby 0:aafd54b05111 1881 * \param stored_payload_len is length of stored Payload
zdshelby 0:aafd54b05111 1882 * \param *stored_payload_ptr is pointer to stored Payload
zdshelby 0:aafd54b05111 1883 *****************************************************************************/
zdshelby 0:aafd54b05111 1884
zdshelby 0:aafd54b05111 1885 static void sn_coap_protocol_linked_list_blockwise_payload_store(sn_nsdl_addr_s *addr_ptr,//TODO: addr + header parametreiksi, blokin offset talteen.
zdshelby 0:aafd54b05111 1886 uint16_t stored_payload_len,
zdshelby 0:aafd54b05111 1887 uint8_t *stored_payload_ptr)
zdshelby 0:aafd54b05111 1888 {
zdshelby 0:aafd54b05111 1889 if(!addr_ptr || !stored_payload_len || !stored_payload_ptr)
zdshelby 0:aafd54b05111 1890 return;
zdshelby 0:aafd54b05111 1891
zdshelby 0:aafd54b05111 1892 coap_blockwise_payload_s *stored_blockwise_payload_ptr = NULL;
zdshelby 0:aafd54b05111 1893
zdshelby 0:aafd54b05111 1894 /* * * * Allocating memory for stored Payload * * * */
zdshelby 0:aafd54b05111 1895
zdshelby 0:aafd54b05111 1896 /* Allocate memory for stored Payload's structure */
zdshelby 0:aafd54b05111 1897 stored_blockwise_payload_ptr = sn_coap_protocol_malloc(sizeof(coap_blockwise_payload_s));
zdshelby 0:aafd54b05111 1898
zdshelby 0:aafd54b05111 1899 if (stored_blockwise_payload_ptr == NULL)
zdshelby 0:aafd54b05111 1900 {
zdshelby 0:aafd54b05111 1901 return;
zdshelby 0:aafd54b05111 1902 }
zdshelby 0:aafd54b05111 1903
zdshelby 0:aafd54b05111 1904 /* Allocate memory for stored Payload's data */
zdshelby 0:aafd54b05111 1905 stored_blockwise_payload_ptr->payload_ptr = sn_coap_protocol_malloc(stored_payload_len);
zdshelby 0:aafd54b05111 1906
zdshelby 0:aafd54b05111 1907 if (stored_blockwise_payload_ptr->payload_ptr == NULL)
zdshelby 0:aafd54b05111 1908 {
zdshelby 0:aafd54b05111 1909 sn_coap_protocol_free(stored_blockwise_payload_ptr);
zdshelby 0:aafd54b05111 1910
zdshelby 0:aafd54b05111 1911 return;
zdshelby 0:aafd54b05111 1912 }
zdshelby 0:aafd54b05111 1913
zdshelby 0:aafd54b05111 1914 /* Allocate memory for stored Payload's address */
zdshelby 0:aafd54b05111 1915 stored_blockwise_payload_ptr->addr_ptr = sn_coap_protocol_malloc(addr_ptr->addr_len);
zdshelby 0:aafd54b05111 1916
zdshelby 0:aafd54b05111 1917 if (stored_blockwise_payload_ptr->addr_ptr == NULL)
zdshelby 0:aafd54b05111 1918 {
zdshelby 0:aafd54b05111 1919 sn_coap_protocol_free(stored_blockwise_payload_ptr);
zdshelby 0:aafd54b05111 1920 sn_coap_protocol_free(stored_blockwise_payload_ptr->payload_ptr);
zdshelby 0:aafd54b05111 1921
zdshelby 0:aafd54b05111 1922 return;
zdshelby 0:aafd54b05111 1923 }
zdshelby 0:aafd54b05111 1924
zdshelby 0:aafd54b05111 1925 /* * * * Filling fields of stored Payload * * * */
zdshelby 0:aafd54b05111 1926
zdshelby 0:aafd54b05111 1927 stored_blockwise_payload_ptr->timestamp = global_system_time;
zdshelby 0:aafd54b05111 1928
zdshelby 0:aafd54b05111 1929 memcpy(stored_blockwise_payload_ptr->addr_ptr, addr_ptr->addr_ptr, addr_ptr->addr_len);
zdshelby 0:aafd54b05111 1930 stored_blockwise_payload_ptr->port = addr_ptr->port;
zdshelby 0:aafd54b05111 1931 memcpy(stored_blockwise_payload_ptr->payload_ptr, stored_payload_ptr, stored_payload_len);
zdshelby 0:aafd54b05111 1932 stored_blockwise_payload_ptr->payload_len = stored_payload_len;
zdshelby 0:aafd54b05111 1933
zdshelby 0:aafd54b05111 1934 /* * * * Storing Payload to Linked list * * * */
zdshelby 0:aafd54b05111 1935
zdshelby 0:aafd54b05111 1936 sn_linked_list_add_node(global_linked_list_blockwise_received_payloads_ptr, stored_blockwise_payload_ptr);//TODO: hukkAS
zdshelby 0:aafd54b05111 1937 }
zdshelby 0:aafd54b05111 1938
zdshelby 0:aafd54b05111 1939 /**************************************************************************//**
zdshelby 0:aafd54b05111 1940 * \fn static uint8_t *sn_coap_protocol_linked_list_blockwise_payload_search(sn_nsdl_addr_s *src_addr_ptr, uint16_t *payload_length)
zdshelby 0:aafd54b05111 1941 *
zdshelby 0:aafd54b05111 1942 * \brief Searches stored blockwise payload from Linked list (Address as key)
zdshelby 0:aafd54b05111 1943 *
zdshelby 0:aafd54b05111 1944 * \param *addr_ptr is pointer to Address key to be searched
zdshelby 0:aafd54b05111 1945 * \param *payload_length is pointer to returned Payload length
zdshelby 0:aafd54b05111 1946 *
zdshelby 0:aafd54b05111 1947 * \return Return value is pointer to found stored blockwise payload in Linked
zdshelby 0:aafd54b05111 1948 * list or NULL if payload not found
zdshelby 0:aafd54b05111 1949 *****************************************************************************/
zdshelby 0:aafd54b05111 1950
zdshelby 0:aafd54b05111 1951 static uint8_t *sn_coap_protocol_linked_list_blockwise_payload_search(sn_nsdl_addr_s *src_addr_ptr, uint16_t *payload_length)
zdshelby 0:aafd54b05111 1952 {
zdshelby 0:aafd54b05111 1953 coap_blockwise_payload_s *stored_payload_info_ptr = sn_linked_list_get_last_node(global_linked_list_blockwise_received_payloads_ptr);
zdshelby 0:aafd54b05111 1954 uint16_t stored_blockwise_payloads_count = sn_linked_list_count_nodes(global_linked_list_blockwise_received_payloads_ptr);
zdshelby 0:aafd54b05111 1955 uint8_t i = 0;
zdshelby 0:aafd54b05111 1956
zdshelby 0:aafd54b05111 1957 /* Loop all stored blockwise payloads in Linked list */
zdshelby 0:aafd54b05111 1958 for (i = 0; i < stored_blockwise_payloads_count; i++)
zdshelby 0:aafd54b05111 1959 {
zdshelby 0:aafd54b05111 1960 int8_t mem_cmp_result = memcmp(src_addr_ptr->addr_ptr, stored_payload_info_ptr->addr_ptr, src_addr_ptr->addr_len);
zdshelby 0:aafd54b05111 1961
zdshelby 0:aafd54b05111 1962 /* If payload's Source address is same than is searched */
zdshelby 0:aafd54b05111 1963 if (mem_cmp_result == 0)
zdshelby 0:aafd54b05111 1964 {
zdshelby 0:aafd54b05111 1965 /* If payload's Source address port is same than is searched */
zdshelby 0:aafd54b05111 1966 if (stored_payload_info_ptr->port == src_addr_ptr->port)
zdshelby 0:aafd54b05111 1967 {
zdshelby 0:aafd54b05111 1968 /* * * Correct Payload found * * * */
zdshelby 0:aafd54b05111 1969 *payload_length = stored_payload_info_ptr->payload_len;
zdshelby 0:aafd54b05111 1970
zdshelby 0:aafd54b05111 1971 return stored_payload_info_ptr->payload_ptr;
zdshelby 0:aafd54b05111 1972 }
zdshelby 0:aafd54b05111 1973 }
zdshelby 0:aafd54b05111 1974
zdshelby 0:aafd54b05111 1975 /* Get next stored payload to be searched */
zdshelby 0:aafd54b05111 1976 stored_payload_info_ptr = sn_linked_list_get_previous_node(global_linked_list_blockwise_received_payloads_ptr);
zdshelby 0:aafd54b05111 1977 }
zdshelby 0:aafd54b05111 1978
zdshelby 0:aafd54b05111 1979 return NULL;
zdshelby 0:aafd54b05111 1980 }
zdshelby 0:aafd54b05111 1981
zdshelby 0:aafd54b05111 1982 /**************************************************************************//**
zdshelby 0:aafd54b05111 1983 * \fn static void sn_coap_protocol_linked_list_blockwise_payload_remove_oldest()
zdshelby 0:aafd54b05111 1984 *
zdshelby 0:aafd54b05111 1985 * \brief Removes current stored blockwise paylod from Linked list
zdshelby 0:aafd54b05111 1986 *****************************************************************************/
zdshelby 0:aafd54b05111 1987
zdshelby 0:aafd54b05111 1988 static void sn_coap_protocol_linked_list_blockwise_payload_remove_oldest()
zdshelby 0:aafd54b05111 1989 {
zdshelby 0:aafd54b05111 1990 coap_blockwise_payload_s *removed_payload_ptr = NULL;
zdshelby 0:aafd54b05111 1991
zdshelby 0:aafd54b05111 1992 /* Set Linked list to point oldest node */
zdshelby 0:aafd54b05111 1993 sn_linked_list_get_last_node(global_linked_list_blockwise_received_payloads_ptr);
zdshelby 0:aafd54b05111 1994
zdshelby 0:aafd54b05111 1995 /* Remove oldest node in Linked list*/
zdshelby 0:aafd54b05111 1996 removed_payload_ptr = sn_linked_list_remove_current_node(global_linked_list_blockwise_received_payloads_ptr);
zdshelby 0:aafd54b05111 1997
zdshelby 0:aafd54b05111 1998 /* Free memory of stored payload */
zdshelby 0:aafd54b05111 1999 if (removed_payload_ptr != NULL)
zdshelby 0:aafd54b05111 2000 {
zdshelby 0:aafd54b05111 2001 if (removed_payload_ptr->addr_ptr != NULL)
zdshelby 0:aafd54b05111 2002 {
zdshelby 0:aafd54b05111 2003 sn_coap_protocol_free(removed_payload_ptr->addr_ptr);
zdshelby 0:aafd54b05111 2004 }
zdshelby 0:aafd54b05111 2005
zdshelby 0:aafd54b05111 2006 if (removed_payload_ptr->payload_ptr != NULL)
zdshelby 0:aafd54b05111 2007 {
zdshelby 0:aafd54b05111 2008 sn_coap_protocol_free(removed_payload_ptr->payload_ptr);
zdshelby 0:aafd54b05111 2009 }
zdshelby 0:aafd54b05111 2010
zdshelby 0:aafd54b05111 2011 sn_coap_protocol_free(removed_payload_ptr);
zdshelby 0:aafd54b05111 2012 }
zdshelby 0:aafd54b05111 2013 }
zdshelby 0:aafd54b05111 2014
zdshelby 0:aafd54b05111 2015 /**************************************************************************//**
zdshelby 0:aafd54b05111 2016 * \fn static void sn_coap_protocol_linked_list_blockwise_payload_remove_current()
zdshelby 0:aafd54b05111 2017 *
zdshelby 0:aafd54b05111 2018 * \brief Removes current stored blockwise paylod from Linked list
zdshelby 0:aafd54b05111 2019 *****************************************************************************/
zdshelby 0:aafd54b05111 2020
zdshelby 0:aafd54b05111 2021 static void sn_coap_protocol_linked_list_blockwise_payload_remove_current()
zdshelby 0:aafd54b05111 2022 {
zdshelby 0:aafd54b05111 2023 coap_blockwise_payload_s *removed_payload_ptr = NULL;
zdshelby 0:aafd54b05111 2024
zdshelby 0:aafd54b05111 2025 /* Remove oldest node in Linked list*/
zdshelby 0:aafd54b05111 2026 removed_payload_ptr = sn_linked_list_remove_current_node(global_linked_list_blockwise_received_payloads_ptr);
zdshelby 0:aafd54b05111 2027
zdshelby 0:aafd54b05111 2028 /* Free memory of stored payload */
zdshelby 0:aafd54b05111 2029 if (removed_payload_ptr != NULL)
zdshelby 0:aafd54b05111 2030 {
zdshelby 0:aafd54b05111 2031 if (removed_payload_ptr->addr_ptr != NULL)
zdshelby 0:aafd54b05111 2032 {
zdshelby 0:aafd54b05111 2033 sn_coap_protocol_free(removed_payload_ptr->addr_ptr);
zdshelby 0:aafd54b05111 2034 }
zdshelby 0:aafd54b05111 2035
zdshelby 0:aafd54b05111 2036 if (removed_payload_ptr->payload_ptr != NULL)
zdshelby 0:aafd54b05111 2037 {
zdshelby 0:aafd54b05111 2038 sn_coap_protocol_free(removed_payload_ptr->payload_ptr);
zdshelby 0:aafd54b05111 2039 }
zdshelby 0:aafd54b05111 2040
zdshelby 0:aafd54b05111 2041 sn_coap_protocol_free(removed_payload_ptr);
zdshelby 0:aafd54b05111 2042 }
zdshelby 0:aafd54b05111 2043 }
zdshelby 0:aafd54b05111 2044
zdshelby 0:aafd54b05111 2045 /**************************************************************************//**
zdshelby 0:aafd54b05111 2046 * \fn static uint16_t sn_coap_protocol_linked_list_blockwise_payloads_get_len(sn_nsdl_addr_s *src_addr_ptr)
zdshelby 0:aafd54b05111 2047 *
zdshelby 0:aafd54b05111 2048 * \brief Counts length of Payloads in Linked list (Address as key)
zdshelby 0:aafd54b05111 2049 *
zdshelby 0:aafd54b05111 2050 * \param *addr_ptr is pointer to Address key
zdshelby 0:aafd54b05111 2051 *
zdshelby 0:aafd54b05111 2052 * \return Return value is length of Payloads as bytes
zdshelby 0:aafd54b05111 2053 *****************************************************************************/
zdshelby 0:aafd54b05111 2054
zdshelby 0:aafd54b05111 2055 static uint16_t sn_coap_protocol_linked_list_blockwise_payloads_get_len(sn_nsdl_addr_s *src_addr_ptr)
zdshelby 0:aafd54b05111 2056 {
zdshelby 0:aafd54b05111 2057 coap_blockwise_payload_s *searched_payload_info_ptr = sn_linked_list_get_last_node(global_linked_list_blockwise_received_payloads_ptr);
zdshelby 0:aafd54b05111 2058 uint16_t stored_blockwise_payloads_count = sn_linked_list_count_nodes(global_linked_list_blockwise_received_payloads_ptr);
zdshelby 0:aafd54b05111 2059 uint8_t i = 0;
zdshelby 0:aafd54b05111 2060 uint16_t ret_whole_payload_len = 0;
zdshelby 0:aafd54b05111 2061
zdshelby 0:aafd54b05111 2062 /* Loop all stored blockwise payloads in Linked list */
zdshelby 0:aafd54b05111 2063 for (i = 0; i < stored_blockwise_payloads_count; i++)
zdshelby 0:aafd54b05111 2064 {
zdshelby 0:aafd54b05111 2065 int8_t mem_cmp_result = memcmp(src_addr_ptr->addr_ptr, searched_payload_info_ptr->addr_ptr, src_addr_ptr->addr_len);
zdshelby 0:aafd54b05111 2066
zdshelby 0:aafd54b05111 2067 /* If payload's Source address is same than is searched */
zdshelby 0:aafd54b05111 2068 if (mem_cmp_result == 0)
zdshelby 0:aafd54b05111 2069 {
zdshelby 0:aafd54b05111 2070 /* If payload's Source address port is same than is searched */
zdshelby 0:aafd54b05111 2071 if (searched_payload_info_ptr->port == src_addr_ptr->port)
zdshelby 0:aafd54b05111 2072 {
zdshelby 0:aafd54b05111 2073 /* * * Correct Payload found * * * */
zdshelby 0:aafd54b05111 2074 ret_whole_payload_len += searched_payload_info_ptr->payload_len;
zdshelby 0:aafd54b05111 2075 }
zdshelby 0:aafd54b05111 2076 }
zdshelby 0:aafd54b05111 2077
zdshelby 0:aafd54b05111 2078 /* Get next stored payload to be searched */
zdshelby 0:aafd54b05111 2079 searched_payload_info_ptr = sn_linked_list_get_previous_node(global_linked_list_blockwise_received_payloads_ptr);
zdshelby 0:aafd54b05111 2080 }
zdshelby 0:aafd54b05111 2081
zdshelby 0:aafd54b05111 2082 return ret_whole_payload_len;
zdshelby 0:aafd54b05111 2083 }
zdshelby 0:aafd54b05111 2084
zdshelby 0:aafd54b05111 2085 /**************************************************************************//**
zdshelby 0:aafd54b05111 2086 * \fn static void sn_coap_protocol_linked_list_blockwise_remove_old_data(void)
zdshelby 0:aafd54b05111 2087 *
zdshelby 0:aafd54b05111 2088 * \brief Removes old stored Blockwise messages and payloads from Linked list
zdshelby 0:aafd54b05111 2089 *****************************************************************************/
zdshelby 0:aafd54b05111 2090
zdshelby 0:aafd54b05111 2091 static void sn_coap_protocol_linked_list_blockwise_remove_old_data(void)
zdshelby 0:aafd54b05111 2092 {
zdshelby 0:aafd54b05111 2093 coap_blockwise_msg_s *removed_blocwise_msg_ptr = sn_linked_list_get_first_node(global_linked_list_blockwise_sent_msgs_ptr);
zdshelby 0:aafd54b05111 2094 coap_blockwise_payload_s *removed_blocwise_payload_ptr = sn_linked_list_get_first_node(global_linked_list_blockwise_received_payloads_ptr);
zdshelby 0:aafd54b05111 2095
zdshelby 0:aafd54b05111 2096 /* Loop all stored Blockwise messages in Linked list */
zdshelby 0:aafd54b05111 2097 while(removed_blocwise_msg_ptr)
zdshelby 0:aafd54b05111 2098 {
zdshelby 0:aafd54b05111 2099 if ((global_system_time - removed_blocwise_msg_ptr->timestamp) > SN_COAP_BLOCKWISE_MAX_TIME_DATA_STORED)
zdshelby 0:aafd54b05111 2100 {
zdshelby 0:aafd54b05111 2101 /* * * * Old Blockise message found, remove it from Linked list * * * */
zdshelby 0:aafd54b05111 2102 sn_coap_protocol_linked_list_blockwise_msg_remove_current();
zdshelby 0:aafd54b05111 2103 removed_blocwise_msg_ptr = sn_linked_list_get_current_node(global_linked_list_blockwise_sent_msgs_ptr);
zdshelby 0:aafd54b05111 2104 }
zdshelby 0:aafd54b05111 2105 else
zdshelby 0:aafd54b05111 2106 {
zdshelby 0:aafd54b05111 2107 /* Get next stored message to be searched */
zdshelby 0:aafd54b05111 2108 removed_blocwise_msg_ptr = sn_linked_list_get_next_node(global_linked_list_blockwise_sent_msgs_ptr);
zdshelby 0:aafd54b05111 2109 }
zdshelby 0:aafd54b05111 2110 }
zdshelby 0:aafd54b05111 2111
zdshelby 0:aafd54b05111 2112 /* Loop all stored Blockwise payloads in Linked list */
zdshelby 0:aafd54b05111 2113 while(removed_blocwise_payload_ptr)
zdshelby 0:aafd54b05111 2114 {
zdshelby 0:aafd54b05111 2115 if ((global_system_time - removed_blocwise_payload_ptr->timestamp) > SN_COAP_BLOCKWISE_MAX_TIME_DATA_STORED)
zdshelby 0:aafd54b05111 2116 {
zdshelby 0:aafd54b05111 2117 /* * * * Old Blockise payload found, remove it from Linked list * * * */
zdshelby 0:aafd54b05111 2118 sn_coap_protocol_linked_list_blockwise_payload_remove_current();
zdshelby 0:aafd54b05111 2119 removed_blocwise_payload_ptr = sn_linked_list_get_current_node(global_linked_list_blockwise_received_payloads_ptr);
zdshelby 0:aafd54b05111 2120
zdshelby 0:aafd54b05111 2121 }
zdshelby 0:aafd54b05111 2122 else
zdshelby 0:aafd54b05111 2123 {
zdshelby 0:aafd54b05111 2124 /* Get next stored payload to be searched */
zdshelby 0:aafd54b05111 2125 removed_blocwise_payload_ptr = sn_linked_list_get_next_node(global_linked_list_blockwise_received_payloads_ptr);
zdshelby 0:aafd54b05111 2126 }
zdshelby 0:aafd54b05111 2127 }
zdshelby 0:aafd54b05111 2128 }
zdshelby 0:aafd54b05111 2129
zdshelby 0:aafd54b05111 2130 #endif /* SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE */
zdshelby 0:aafd54b05111 2131
zdshelby 0:aafd54b05111 2132 #if ENABLE_RESENDINGS
zdshelby 0:aafd54b05111 2133 /**************************************************************************//**
zdshelby 0:aafd54b05111 2134 * \fn sn_nsdl_transmit_s *sn_coap_protocol_build_msg(void *src_msg_ptr)
zdshelby 0:aafd54b05111 2135 *
zdshelby 0:aafd54b05111 2136 * \brief Builds message (sn_nsdl_transmit_s) from given data
zdshelby 0:aafd54b05111 2137 *
zdshelby 0:aafd54b05111 2138 * \param *src_msg_ptr is pointer to source of built message
zdshelby 0:aafd54b05111 2139 *
zdshelby 0:aafd54b05111 2140 * \return Return value is pointer to built message
zdshelby 0:aafd54b05111 2141 *****************************************************************************/
zdshelby 0:aafd54b05111 2142
zdshelby 0:aafd54b05111 2143 sn_nsdl_transmit_s *sn_coap_protocol_build_msg(void *src_msg_ptr)
zdshelby 0:aafd54b05111 2144 {
zdshelby 0:aafd54b05111 2145 /* Allocate memory for structures behind sending messages list pointers */
zdshelby 0:aafd54b05111 2146
zdshelby 0:aafd54b05111 2147 sn_nsdl_transmit_s *returned_msg_ptr = sn_coap_protocol_malloc(sizeof(sn_nsdl_transmit_s));
zdshelby 0:aafd54b05111 2148
zdshelby 0:aafd54b05111 2149 if (returned_msg_ptr == NULL)
zdshelby 0:aafd54b05111 2150 return NULL;
zdshelby 0:aafd54b05111 2151
zdshelby 0:aafd54b05111 2152 returned_msg_ptr->dst_addr_ptr = sn_coap_protocol_malloc(sizeof(sn_nsdl_addr_s));
zdshelby 0:aafd54b05111 2153
zdshelby 0:aafd54b05111 2154 if (returned_msg_ptr->dst_addr_ptr == NULL)
zdshelby 0:aafd54b05111 2155 {
zdshelby 0:aafd54b05111 2156 sn_coap_builder_release_allocated_send_msg_mem(returned_msg_ptr);
zdshelby 0:aafd54b05111 2157 return NULL;
zdshelby 0:aafd54b05111 2158 }
zdshelby 0:aafd54b05111 2159
zdshelby 0:aafd54b05111 2160 returned_msg_ptr->packet_ptr = sn_coap_protocol_malloc(((coap_send_msg_s*)src_msg_ptr)->send_msg_ptr->packet_len);
zdshelby 0:aafd54b05111 2161
zdshelby 0:aafd54b05111 2162 if (returned_msg_ptr->packet_ptr == NULL)
zdshelby 0:aafd54b05111 2163 {
zdshelby 0:aafd54b05111 2164 sn_coap_builder_release_allocated_send_msg_mem(returned_msg_ptr);
zdshelby 0:aafd54b05111 2165 return NULL;
zdshelby 0:aafd54b05111 2166 }
zdshelby 0:aafd54b05111 2167
zdshelby 0:aafd54b05111 2168 returned_msg_ptr->dst_addr_ptr->addr_ptr = sn_coap_protocol_malloc(((coap_send_msg_s*)src_msg_ptr)->send_msg_ptr->dst_addr_ptr->addr_len);
zdshelby 0:aafd54b05111 2169
zdshelby 0:aafd54b05111 2170 if (returned_msg_ptr->dst_addr_ptr->addr_ptr == NULL)
zdshelby 0:aafd54b05111 2171 {
zdshelby 0:aafd54b05111 2172 sn_coap_builder_release_allocated_send_msg_mem(returned_msg_ptr);
zdshelby 0:aafd54b05111 2173 return NULL;
zdshelby 0:aafd54b05111 2174 }
zdshelby 0:aafd54b05111 2175
zdshelby 0:aafd54b05111 2176 /* Filling of sn_nsdl_transmit_s */
zdshelby 0:aafd54b05111 2177 returned_msg_ptr->protocol = ((coap_send_msg_s*)src_msg_ptr)->send_msg_ptr->protocol;
zdshelby 0:aafd54b05111 2178 returned_msg_ptr->packet_len = ((coap_send_msg_s*)src_msg_ptr)->send_msg_ptr->packet_len;
zdshelby 0:aafd54b05111 2179 memcpy(returned_msg_ptr->packet_ptr, ((coap_send_msg_s*)src_msg_ptr)->send_msg_ptr->packet_ptr, ((coap_send_msg_s*)src_msg_ptr)->send_msg_ptr->packet_len);
zdshelby 0:aafd54b05111 2180
zdshelby 0:aafd54b05111 2181 /* Filling of sn_nsdl_addr_s */
zdshelby 0:aafd54b05111 2182 returned_msg_ptr->dst_addr_ptr->type = ((coap_send_msg_s*)src_msg_ptr)->send_msg_ptr->dst_addr_ptr->type;
zdshelby 0:aafd54b05111 2183 returned_msg_ptr->dst_addr_ptr->addr_len = ((coap_send_msg_s*)src_msg_ptr)->send_msg_ptr->dst_addr_ptr->addr_len;
zdshelby 0:aafd54b05111 2184 memcpy(returned_msg_ptr->dst_addr_ptr->addr_ptr, ((coap_send_msg_s*)src_msg_ptr)->send_msg_ptr->dst_addr_ptr->addr_ptr, ((coap_send_msg_s*)src_msg_ptr)->send_msg_ptr->dst_addr_ptr->addr_len);
zdshelby 0:aafd54b05111 2185 returned_msg_ptr->dst_addr_ptr->port = ((coap_send_msg_s*)src_msg_ptr)->send_msg_ptr->dst_addr_ptr->port;
zdshelby 0:aafd54b05111 2186
zdshelby 0:aafd54b05111 2187 return returned_msg_ptr;
zdshelby 0:aafd54b05111 2188 }
zdshelby 0:aafd54b05111 2189 #endif /* ENABLE_RESENDINGS */
zdshelby 0:aafd54b05111 2190
zdshelby 0:aafd54b05111 2191
zdshelby 0:aafd54b05111 2192 #if ENABLE_RESENDINGS /* If Message resending is not used at all, this part of code will not be compiled */
zdshelby 0:aafd54b05111 2193 /***************************************************************************//**
zdshelby 0:aafd54b05111 2194 * \fn int8_t sn_coap_protocol_allocate_mem_for_msg(sn_nsdl_addr_s *dst_addr_ptr, uint16_t packet_data_len, coap_send_msg_s *msg_ptr)
zdshelby 0:aafd54b05111 2195 *
zdshelby 0:aafd54b05111 2196 * \brief Allocates memory for given message (send or blockwise message)
zdshelby 0:aafd54b05111 2197 *
zdshelby 0:aafd54b05111 2198 * \param *dst_addr_ptr is pointer to destination address where message will be sent
zdshelby 0:aafd54b05111 2199 * \param packet_data_len is length of allocated Packet data
zdshelby 0:aafd54b05111 2200 *
zdshelby 0:aafd54b05111 2201 * \return pointer to allocated struct
zdshelby 0:aafd54b05111 2202 *****************************************************************************/
zdshelby 0:aafd54b05111 2203
zdshelby 0:aafd54b05111 2204 coap_send_msg_s *sn_coap_protocol_allocate_mem_for_msg(sn_nsdl_addr_s *dst_addr_ptr, uint16_t packet_data_len)
zdshelby 0:aafd54b05111 2205 {
zdshelby 0:aafd54b05111 2206
zdshelby 0:aafd54b05111 2207 coap_send_msg_s *msg_ptr = sn_coap_protocol_malloc(sizeof(coap_send_msg_s));
zdshelby 0:aafd54b05111 2208
zdshelby 0:aafd54b05111 2209 if (msg_ptr == NULL)
zdshelby 0:aafd54b05111 2210 return 0;
zdshelby 0:aafd54b05111 2211
zdshelby 0:aafd54b05111 2212 memset(msg_ptr, 0, sizeof(coap_send_msg_s));
zdshelby 0:aafd54b05111 2213
zdshelby 0:aafd54b05111 2214 msg_ptr->send_msg_ptr = sn_coap_protocol_malloc(sizeof(sn_nsdl_transmit_s));
zdshelby 0:aafd54b05111 2215
zdshelby 0:aafd54b05111 2216 if (msg_ptr->send_msg_ptr == NULL)
zdshelby 0:aafd54b05111 2217 {
zdshelby 0:aafd54b05111 2218 sn_coap_protocol_release_allocated_send_msg_mem(msg_ptr);
zdshelby 0:aafd54b05111 2219 return 0;
zdshelby 0:aafd54b05111 2220 }
zdshelby 0:aafd54b05111 2221
zdshelby 0:aafd54b05111 2222 memset(msg_ptr->send_msg_ptr, 0 ,sizeof(sn_nsdl_transmit_s));
zdshelby 0:aafd54b05111 2223
zdshelby 0:aafd54b05111 2224 msg_ptr->send_msg_ptr->dst_addr_ptr = sn_coap_protocol_malloc(sizeof(sn_nsdl_addr_s));
zdshelby 0:aafd54b05111 2225
zdshelby 0:aafd54b05111 2226 if (msg_ptr->send_msg_ptr->dst_addr_ptr == NULL)
zdshelby 0:aafd54b05111 2227 {
zdshelby 0:aafd54b05111 2228 sn_coap_protocol_release_allocated_send_msg_mem(msg_ptr);
zdshelby 0:aafd54b05111 2229 return 0;
zdshelby 0:aafd54b05111 2230 }
zdshelby 0:aafd54b05111 2231
zdshelby 0:aafd54b05111 2232 memset(msg_ptr->send_msg_ptr->dst_addr_ptr, 0, sizeof(sn_nsdl_addr_s));
zdshelby 0:aafd54b05111 2233
zdshelby 0:aafd54b05111 2234 msg_ptr->send_msg_ptr->packet_ptr = sn_coap_protocol_malloc(packet_data_len);
zdshelby 0:aafd54b05111 2235
zdshelby 0:aafd54b05111 2236 if (msg_ptr->send_msg_ptr->packet_ptr == NULL)
zdshelby 0:aafd54b05111 2237 {
zdshelby 0:aafd54b05111 2238 sn_coap_protocol_release_allocated_send_msg_mem(msg_ptr);
zdshelby 0:aafd54b05111 2239 return 0;
zdshelby 0:aafd54b05111 2240 }
zdshelby 0:aafd54b05111 2241
zdshelby 0:aafd54b05111 2242 msg_ptr->send_msg_ptr->dst_addr_ptr->addr_ptr = sn_coap_protocol_malloc(dst_addr_ptr->addr_len);
zdshelby 0:aafd54b05111 2243
zdshelby 0:aafd54b05111 2244 if (msg_ptr->send_msg_ptr->dst_addr_ptr->addr_ptr == NULL)
zdshelby 0:aafd54b05111 2245 {
zdshelby 0:aafd54b05111 2246 sn_coap_protocol_release_allocated_send_msg_mem(msg_ptr);
zdshelby 0:aafd54b05111 2247 return 0;
zdshelby 0:aafd54b05111 2248 }
zdshelby 0:aafd54b05111 2249
zdshelby 0:aafd54b05111 2250 memset(msg_ptr->send_msg_ptr->dst_addr_ptr->addr_ptr, 0, dst_addr_ptr->addr_len);
zdshelby 0:aafd54b05111 2251
zdshelby 0:aafd54b05111 2252 return msg_ptr;
zdshelby 0:aafd54b05111 2253 }
zdshelby 0:aafd54b05111 2254
zdshelby 0:aafd54b05111 2255
zdshelby 0:aafd54b05111 2256 /**************************************************************************//**
zdshelby 0:aafd54b05111 2257 * \fn static void sn_coap_protocol_release_allocated_send_msg_mem(coap_send_msg_s *freed_send_msg_ptr)
zdshelby 0:aafd54b05111 2258 *
zdshelby 0:aafd54b05111 2259 * \brief Releases memory of given Sending message (coap_send_msg_s)
zdshelby 0:aafd54b05111 2260 *
zdshelby 0:aafd54b05111 2261 * \param *freed_send_msg_ptr is pointer to released Sending message
zdshelby 0:aafd54b05111 2262 *****************************************************************************/
zdshelby 0:aafd54b05111 2263
zdshelby 0:aafd54b05111 2264 static void sn_coap_protocol_release_allocated_send_msg_mem(coap_send_msg_s *freed_send_msg_ptr)
zdshelby 0:aafd54b05111 2265 {
zdshelby 0:aafd54b05111 2266 if (freed_send_msg_ptr != NULL)
zdshelby 0:aafd54b05111 2267 {
zdshelby 0:aafd54b05111 2268 sn_coap_builder_release_allocated_send_msg_mem(freed_send_msg_ptr->send_msg_ptr);
zdshelby 0:aafd54b05111 2269 sn_coap_protocol_free(freed_send_msg_ptr);
zdshelby 0:aafd54b05111 2270 }
zdshelby 0:aafd54b05111 2271 }
zdshelby 0:aafd54b05111 2272
zdshelby 0:aafd54b05111 2273 /**************************************************************************//**
zdshelby 0:aafd54b05111 2274 * \fn static uint16_t sn_coap_count_linked_list_size(sn_linked_list_t *linked_list_ptr)
zdshelby 0:aafd54b05111 2275 *
zdshelby 0:aafd54b05111 2276 * \brief Counts total message size of all messages in linked list
zdshelby 0:aafd54b05111 2277 *
zdshelby 0:aafd54b05111 2278 * \param sn_linked_list_t *linked_list_ptr pointer to linked list
zdshelby 0:aafd54b05111 2279 *****************************************************************************/
zdshelby 0:aafd54b05111 2280 static uint16_t sn_coap_count_linked_list_size(sn_linked_list_t *linked_list_ptr)
zdshelby 0:aafd54b05111 2281 {
zdshelby 0:aafd54b05111 2282 uint16_t total_size = 0;
zdshelby 0:aafd54b05111 2283 uint16_t message_count = sn_linked_list_count_nodes(linked_list_ptr);
zdshelby 0:aafd54b05111 2284 coap_send_msg_s *stored_msg_ptr = sn_linked_list_get_first_node(linked_list_ptr);
zdshelby 0:aafd54b05111 2285
zdshelby 0:aafd54b05111 2286 while(message_count--)
zdshelby 0:aafd54b05111 2287 {
zdshelby 0:aafd54b05111 2288 if(stored_msg_ptr)
zdshelby 0:aafd54b05111 2289 {
zdshelby 0:aafd54b05111 2290 if(stored_msg_ptr->send_msg_ptr)
zdshelby 0:aafd54b05111 2291 total_size += stored_msg_ptr->send_msg_ptr->packet_len;
zdshelby 0:aafd54b05111 2292 }
zdshelby 0:aafd54b05111 2293 stored_msg_ptr = sn_linked_list_get_next_node(linked_list_ptr);
zdshelby 0:aafd54b05111 2294 }
zdshelby 0:aafd54b05111 2295
zdshelby 0:aafd54b05111 2296 return total_size;
zdshelby 0:aafd54b05111 2297 }
zdshelby 0:aafd54b05111 2298
zdshelby 0:aafd54b05111 2299 #endif
zdshelby 0:aafd54b05111 2300 #if SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE /* If Message blockwising is not used at all, this part of code will not be compiled */
zdshelby 0:aafd54b05111 2301
zdshelby 0:aafd54b05111 2302 /**************************************************************************//**
zdshelby 0:aafd54b05111 2303 * \fn static int8_t sn_coap_handle_blockwise_message(void)
zdshelby 0:aafd54b05111 2304 *
zdshelby 0:aafd54b05111 2305 * \brief Handles all received blockwise messages
zdshelby 0:aafd54b05111 2306 *
zdshelby 0:aafd54b05111 2307 * \param *src_addr_ptr pointer to source address information struct
zdshelby 0:aafd54b05111 2308 * \param *received_coap_msg_ptr pointer to parsed CoAP message structure
zdshelby 0:aafd54b05111 2309 *****************************************************************************/
zdshelby 0:aafd54b05111 2310
zdshelby 0:aafd54b05111 2311 static sn_coap_hdr_s *sn_coap_handle_blockwise_message(sn_nsdl_addr_s *src_addr_ptr, sn_coap_hdr_s *received_coap_msg_ptr)
zdshelby 0:aafd54b05111 2312 {
zdshelby 0:aafd54b05111 2313 sn_coap_hdr_s *src_coap_blockwise_ack_msg_ptr = NULL;
zdshelby 0:aafd54b05111 2314 uint16_t dst_packed_data_needed_mem = 0;
zdshelby 0:aafd54b05111 2315 uint8_t *dst_ack_packet_data_ptr = NULL;
zdshelby 0:aafd54b05111 2316 uint8_t block_temp = 0;
zdshelby 0:aafd54b05111 2317
zdshelby 0:aafd54b05111 2318 uint16_t original_payload_len = 0;
zdshelby 0:aafd54b05111 2319 uint8_t *original_payload_ptr = NULL;
zdshelby 0:aafd54b05111 2320
zdshelby 0:aafd54b05111 2321 /* Block1 Option in a request (e.g., PUT or POST) */
zdshelby 0:aafd54b05111 2322 // Blocked request sending, received ACK, sending next block..
zdshelby 0:aafd54b05111 2323 if(received_coap_msg_ptr->options_list_ptr->block1_ptr)
zdshelby 0:aafd54b05111 2324 {
zdshelby 0:aafd54b05111 2325 if(received_coap_msg_ptr->msg_code > COAP_MSG_CODE_REQUEST_DELETE)
zdshelby 0:aafd54b05111 2326 {
zdshelby 0:aafd54b05111 2327 if(*(received_coap_msg_ptr->options_list_ptr->block1_ptr + (received_coap_msg_ptr->options_list_ptr->block1_len - 1)) & 0x08)
zdshelby 0:aafd54b05111 2328 {
zdshelby 0:aafd54b05111 2329 coap_blockwise_msg_s *stored_blockwise_msg_temp_ptr = sn_linked_list_get_last_node(global_linked_list_blockwise_sent_msgs_ptr);
zdshelby 0:aafd54b05111 2330
zdshelby 0:aafd54b05111 2331 /* Get */
zdshelby 0:aafd54b05111 2332 while(stored_blockwise_msg_temp_ptr && (received_coap_msg_ptr->msg_id != stored_blockwise_msg_temp_ptr->coap_msg_ptr->msg_id))
zdshelby 0:aafd54b05111 2333 {
zdshelby 0:aafd54b05111 2334 stored_blockwise_msg_temp_ptr = sn_linked_list_get_previous_node(global_linked_list_blockwise_sent_msgs_ptr);
zdshelby 0:aafd54b05111 2335 }
zdshelby 0:aafd54b05111 2336
zdshelby 0:aafd54b05111 2337 if(stored_blockwise_msg_temp_ptr)
zdshelby 0:aafd54b05111 2338 {
zdshelby 0:aafd54b05111 2339 /* Build response message */
zdshelby 0:aafd54b05111 2340
zdshelby 0:aafd54b05111 2341 uint16_t block_size = 1;
zdshelby 0:aafd54b05111 2342 uint32_t block_number = 0;
zdshelby 0:aafd54b05111 2343
zdshelby 0:aafd54b05111 2344 /* Get block option parameters from received message */
zdshelby 0:aafd54b05111 2345 if(received_coap_msg_ptr->options_list_ptr->block1_len == 3)
zdshelby 0:aafd54b05111 2346 {
zdshelby 0:aafd54b05111 2347 block_number = *(received_coap_msg_ptr->options_list_ptr->block1_ptr) << 12;
zdshelby 0:aafd54b05111 2348 block_number |= *(received_coap_msg_ptr->options_list_ptr->block1_ptr + 1) << 4;
zdshelby 0:aafd54b05111 2349 block_number |= (*(received_coap_msg_ptr->options_list_ptr->block1_ptr + 2)) >> 4;
zdshelby 0:aafd54b05111 2350 }
zdshelby 0:aafd54b05111 2351
zdshelby 0:aafd54b05111 2352 else if(received_coap_msg_ptr->options_list_ptr->block1_len == 2)
zdshelby 0:aafd54b05111 2353 {
zdshelby 0:aafd54b05111 2354 block_number = *(received_coap_msg_ptr->options_list_ptr->block1_ptr) << 4;
zdshelby 0:aafd54b05111 2355 block_number |= (*(received_coap_msg_ptr->options_list_ptr->block1_ptr + 1)) >> 4;
zdshelby 0:aafd54b05111 2356 }
zdshelby 0:aafd54b05111 2357 else if(received_coap_msg_ptr->options_list_ptr->block1_len == 1)
zdshelby 0:aafd54b05111 2358 {
zdshelby 0:aafd54b05111 2359 block_number = (*received_coap_msg_ptr->options_list_ptr->block1_ptr) >> 4;
zdshelby 0:aafd54b05111 2360 }
zdshelby 0:aafd54b05111 2361
zdshelby 0:aafd54b05111 2362
zdshelby 0:aafd54b05111 2363 block_temp = *(received_coap_msg_ptr->options_list_ptr->block1_ptr + (received_coap_msg_ptr->options_list_ptr->block1_len - 1)) & 0x07;
zdshelby 0:aafd54b05111 2364 block_size = block_size << (block_temp + 4);
zdshelby 0:aafd54b05111 2365
zdshelby 0:aafd54b05111 2366
zdshelby 0:aafd54b05111 2367 /* Build next block message */
zdshelby 0:aafd54b05111 2368 src_coap_blockwise_ack_msg_ptr = stored_blockwise_msg_temp_ptr->coap_msg_ptr;
zdshelby 0:aafd54b05111 2369
zdshelby 0:aafd54b05111 2370 if(src_coap_blockwise_ack_msg_ptr->options_list_ptr)
zdshelby 0:aafd54b05111 2371 {
zdshelby 0:aafd54b05111 2372 if(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr)
zdshelby 0:aafd54b05111 2373 {
zdshelby 0:aafd54b05111 2374 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr);
zdshelby 0:aafd54b05111 2375 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr = 0;
zdshelby 0:aafd54b05111 2376
zdshelby 0:aafd54b05111 2377 }
zdshelby 0:aafd54b05111 2378 if(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_ptr)
zdshelby 0:aafd54b05111 2379 {
zdshelby 0:aafd54b05111 2380 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_ptr);
zdshelby 0:aafd54b05111 2381 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_ptr = 0;
zdshelby 0:aafd54b05111 2382 }
zdshelby 0:aafd54b05111 2383 }
zdshelby 0:aafd54b05111 2384 else
zdshelby 0:aafd54b05111 2385 {
zdshelby 0:aafd54b05111 2386 src_coap_blockwise_ack_msg_ptr->options_list_ptr = sn_coap_protocol_malloc(sizeof(sn_coap_options_list_s));
zdshelby 0:aafd54b05111 2387 if(!src_coap_blockwise_ack_msg_ptr->options_list_ptr)
zdshelby 0:aafd54b05111 2388 {
zdshelby 0:aafd54b05111 2389 sn_coap_parser_release_allocated_coap_msg_mem(received_coap_msg_ptr);
zdshelby 0:aafd54b05111 2390 return 0;
zdshelby 0:aafd54b05111 2391 }
zdshelby 0:aafd54b05111 2392 memset(src_coap_blockwise_ack_msg_ptr->options_list_ptr, 0, (sizeof(sn_coap_options_list_s)));
zdshelby 0:aafd54b05111 2393 }
zdshelby 0:aafd54b05111 2394
zdshelby 0:aafd54b05111 2395 block_number++;
zdshelby 0:aafd54b05111 2396
zdshelby 0:aafd54b05111 2397 if(block_number <= 0x0f)
zdshelby 0:aafd54b05111 2398 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_len = 1;
zdshelby 0:aafd54b05111 2399 else if(block_number <= 0x0fff)
zdshelby 0:aafd54b05111 2400 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_len = 2;
zdshelby 0:aafd54b05111 2401 else if(block_number <= 0x0fffff)
zdshelby 0:aafd54b05111 2402 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_len = 3;
zdshelby 0:aafd54b05111 2403
zdshelby 0:aafd54b05111 2404 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr = sn_coap_protocol_malloc(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_len);
zdshelby 0:aafd54b05111 2405
zdshelby 0:aafd54b05111 2406 if(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr == 0)
zdshelby 0:aafd54b05111 2407 {
zdshelby 0:aafd54b05111 2408 sn_coap_parser_release_allocated_coap_msg_mem(received_coap_msg_ptr);
zdshelby 0:aafd54b05111 2409 return 0;
zdshelby 0:aafd54b05111 2410 }
zdshelby 0:aafd54b05111 2411
zdshelby 0:aafd54b05111 2412 *(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr + (src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_len - 1)) = block_temp;
zdshelby 0:aafd54b05111 2413 *src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr |= block_number << 4;
zdshelby 0:aafd54b05111 2414
zdshelby 0:aafd54b05111 2415
zdshelby 0:aafd54b05111 2416 if(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_len == 3)
zdshelby 0:aafd54b05111 2417 {
zdshelby 0:aafd54b05111 2418 *(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr + 2) = block_number << 4;
zdshelby 0:aafd54b05111 2419 *(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr + 1) |= block_number >> 4;
zdshelby 0:aafd54b05111 2420 *src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr |= block_number >> 12;
zdshelby 0:aafd54b05111 2421 }
zdshelby 0:aafd54b05111 2422 else if(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_len == 2)
zdshelby 0:aafd54b05111 2423 {
zdshelby 0:aafd54b05111 2424 *(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr + 1) |= block_number << 4;
zdshelby 0:aafd54b05111 2425 *src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr |= block_number >> 4;
zdshelby 0:aafd54b05111 2426 }
zdshelby 0:aafd54b05111 2427 else
zdshelby 0:aafd54b05111 2428 *src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr |= block_number << 4;
zdshelby 0:aafd54b05111 2429
zdshelby 0:aafd54b05111 2430 original_payload_len = stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len;
zdshelby 0:aafd54b05111 2431 original_payload_ptr = stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_ptr;
zdshelby 0:aafd54b05111 2432
zdshelby 0:aafd54b05111 2433 if((block_size * (block_number+1)) > stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len)
zdshelby 0:aafd54b05111 2434 {
zdshelby 0:aafd54b05111 2435 src_coap_blockwise_ack_msg_ptr->payload_len = stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len - (block_size * (block_number));
zdshelby 0:aafd54b05111 2436 src_coap_blockwise_ack_msg_ptr->payload_ptr = src_coap_blockwise_ack_msg_ptr->payload_ptr + (block_size * block_number);
zdshelby 0:aafd54b05111 2437 }
zdshelby 0:aafd54b05111 2438
zdshelby 0:aafd54b05111 2439 /* Not last block */
zdshelby 0:aafd54b05111 2440 else
zdshelby 0:aafd54b05111 2441 {
zdshelby 0:aafd54b05111 2442 /* set more - bit */
zdshelby 0:aafd54b05111 2443 *(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr + (src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_len-1)) |= 0x08;
zdshelby 0:aafd54b05111 2444 src_coap_blockwise_ack_msg_ptr->payload_len = block_size;
zdshelby 0:aafd54b05111 2445 src_coap_blockwise_ack_msg_ptr->payload_ptr = src_coap_blockwise_ack_msg_ptr->payload_ptr + (block_size * block_number);
zdshelby 0:aafd54b05111 2446 }
zdshelby 0:aafd54b05111 2447
zdshelby 0:aafd54b05111 2448 /* Build and send block message */
zdshelby 0:aafd54b05111 2449 dst_packed_data_needed_mem = sn_coap_builder_calc_needed_packet_data_size(src_coap_blockwise_ack_msg_ptr);
zdshelby 0:aafd54b05111 2450
zdshelby 0:aafd54b05111 2451 dst_ack_packet_data_ptr = sn_coap_protocol_malloc(dst_packed_data_needed_mem);
zdshelby 0:aafd54b05111 2452 if(!dst_ack_packet_data_ptr)
zdshelby 0:aafd54b05111 2453 {
zdshelby 0:aafd54b05111 2454 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr);
zdshelby 0:aafd54b05111 2455 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->options_list_ptr);
zdshelby 0:aafd54b05111 2456 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr);
zdshelby 0:aafd54b05111 2457 sn_coap_parser_release_allocated_coap_msg_mem(received_coap_msg_ptr);
zdshelby 0:aafd54b05111 2458 return NULL;
zdshelby 0:aafd54b05111 2459 }
zdshelby 0:aafd54b05111 2460 src_coap_blockwise_ack_msg_ptr->msg_id = global_message_id++;
zdshelby 0:aafd54b05111 2461
zdshelby 0:aafd54b05111 2462 sn_coap_builder(dst_ack_packet_data_ptr, src_coap_blockwise_ack_msg_ptr);
zdshelby 0:aafd54b05111 2463
zdshelby 0:aafd54b05111 2464 sn_coap_tx_callback(SN_NSDL_PROTOCOL_COAP, dst_ack_packet_data_ptr, dst_packed_data_needed_mem, src_addr_ptr);
zdshelby 0:aafd54b05111 2465
zdshelby 0:aafd54b05111 2466 sn_coap_protocol_free(dst_ack_packet_data_ptr);
zdshelby 0:aafd54b05111 2467
zdshelby 0:aafd54b05111 2468 stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len = original_payload_len;
zdshelby 0:aafd54b05111 2469 stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_ptr = original_payload_ptr;
zdshelby 0:aafd54b05111 2470
zdshelby 0:aafd54b05111 2471 received_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_BLOCKWISE_ACK;
zdshelby 0:aafd54b05111 2472 }
zdshelby 0:aafd54b05111 2473 }
zdshelby 0:aafd54b05111 2474 else
zdshelby 0:aafd54b05111 2475 {
zdshelby 0:aafd54b05111 2476 sn_coap_protocol_linked_list_blockwise_msg_remove_current();
zdshelby 0:aafd54b05111 2477 received_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_BLOCKWISE_ACK;
zdshelby 0:aafd54b05111 2478 }
zdshelby 0:aafd54b05111 2479 }
zdshelby 0:aafd54b05111 2480
zdshelby 0:aafd54b05111 2481 // Blocked request receiving
zdshelby 0:aafd54b05111 2482 else
zdshelby 0:aafd54b05111 2483 {
zdshelby 0:aafd54b05111 2484 if(received_coap_msg_ptr->payload_len > sn_coap_block_data_size)
zdshelby 0:aafd54b05111 2485 received_coap_msg_ptr->payload_len = sn_coap_block_data_size;
zdshelby 0:aafd54b05111 2486
zdshelby 0:aafd54b05111 2487 sn_coap_protocol_linked_list_blockwise_payload_store(src_addr_ptr, received_coap_msg_ptr->payload_len, received_coap_msg_ptr->payload_ptr);
zdshelby 0:aafd54b05111 2488 /* If not last block (more value is set) */
zdshelby 0:aafd54b05111 2489 /* 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. */
zdshelby 0:aafd54b05111 2490 if(*(received_coap_msg_ptr->options_list_ptr->block1_ptr + (received_coap_msg_ptr->options_list_ptr->block1_len - 1)) & 0x08)
zdshelby 0:aafd54b05111 2491 {
zdshelby 0:aafd54b05111 2492 //send ack
zdshelby 0:aafd54b05111 2493 src_coap_blockwise_ack_msg_ptr = sn_coap_protocol_malloc(sizeof(sn_coap_hdr_s));
zdshelby 0:aafd54b05111 2494
zdshelby 0:aafd54b05111 2495 if (src_coap_blockwise_ack_msg_ptr == NULL)
zdshelby 0:aafd54b05111 2496 {
zdshelby 0:aafd54b05111 2497 sn_coap_parser_release_allocated_coap_msg_mem(received_coap_msg_ptr);
zdshelby 0:aafd54b05111 2498 return NULL;
zdshelby 0:aafd54b05111 2499 }
zdshelby 0:aafd54b05111 2500
zdshelby 0:aafd54b05111 2501 memset(src_coap_blockwise_ack_msg_ptr, 0, sizeof(sn_coap_hdr_s));
zdshelby 0:aafd54b05111 2502
zdshelby 0:aafd54b05111 2503 src_coap_blockwise_ack_msg_ptr->options_list_ptr = sn_coap_protocol_malloc(sizeof(sn_coap_options_list_s));
zdshelby 0:aafd54b05111 2504
zdshelby 0:aafd54b05111 2505 if (src_coap_blockwise_ack_msg_ptr->options_list_ptr == NULL)
zdshelby 0:aafd54b05111 2506 {
zdshelby 0:aafd54b05111 2507 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr);
zdshelby 0:aafd54b05111 2508 sn_coap_parser_release_allocated_coap_msg_mem(received_coap_msg_ptr);
zdshelby 0:aafd54b05111 2509 return NULL;
zdshelby 0:aafd54b05111 2510 }
zdshelby 0:aafd54b05111 2511
zdshelby 0:aafd54b05111 2512 memset(src_coap_blockwise_ack_msg_ptr->options_list_ptr, 0, sizeof(sn_coap_options_list_s));
zdshelby 0:aafd54b05111 2513
zdshelby 0:aafd54b05111 2514 if(received_coap_msg_ptr->msg_code == COAP_MSG_CODE_REQUEST_GET)
zdshelby 0:aafd54b05111 2515 src_coap_blockwise_ack_msg_ptr->msg_code = COAP_MSG_CODE_RESPONSE_CONTENT;
zdshelby 0:aafd54b05111 2516 else if(received_coap_msg_ptr->msg_code == COAP_MSG_CODE_REQUEST_POST)
zdshelby 0:aafd54b05111 2517 src_coap_blockwise_ack_msg_ptr->msg_code = COAP_MSG_CODE_RESPONSE_CREATED;
zdshelby 0:aafd54b05111 2518 else if(received_coap_msg_ptr->msg_code == COAP_MSG_CODE_REQUEST_PUT)
zdshelby 0:aafd54b05111 2519 src_coap_blockwise_ack_msg_ptr->msg_code = COAP_MSG_CODE_RESPONSE_CHANGED;
zdshelby 0:aafd54b05111 2520 else if(received_coap_msg_ptr->msg_code == COAP_MSG_CODE_REQUEST_DELETE)
zdshelby 0:aafd54b05111 2521 src_coap_blockwise_ack_msg_ptr->msg_code = COAP_MSG_CODE_RESPONSE_DELETED;
zdshelby 0:aafd54b05111 2522
zdshelby 0:aafd54b05111 2523 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_len = received_coap_msg_ptr->options_list_ptr->block1_len;
zdshelby 0:aafd54b05111 2524 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr = sn_coap_protocol_malloc(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_len);
zdshelby 0:aafd54b05111 2525 if(!src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr)
zdshelby 0:aafd54b05111 2526 {
zdshelby 0:aafd54b05111 2527 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->options_list_ptr);
zdshelby 0:aafd54b05111 2528 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr);
zdshelby 0:aafd54b05111 2529 return NULL;
zdshelby 0:aafd54b05111 2530 }
zdshelby 0:aafd54b05111 2531
zdshelby 0:aafd54b05111 2532 src_coap_blockwise_ack_msg_ptr->msg_type = COAP_MSG_TYPE_ACKNOWLEDGEMENT;
zdshelby 0:aafd54b05111 2533
zdshelby 0:aafd54b05111 2534 memcpy(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr, received_coap_msg_ptr->options_list_ptr->block1_ptr, received_coap_msg_ptr->options_list_ptr->block1_len);
zdshelby 0:aafd54b05111 2535
zdshelby 0:aafd54b05111 2536 /* Check block size */
zdshelby 0:aafd54b05111 2537 block_temp = (*(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr + (src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_len - 1)) & 0x07);
zdshelby 0:aafd54b05111 2538 if(block_temp > sn_coap_convert_block_size(sn_coap_block_data_size))
zdshelby 0:aafd54b05111 2539 {
zdshelby 0:aafd54b05111 2540 *(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr + (src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_len - 1)) &= 0xF8;
zdshelby 0:aafd54b05111 2541 *(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr + (src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_len - 1)) |= sn_coap_convert_block_size(sn_coap_block_data_size);
zdshelby 0:aafd54b05111 2542 }
zdshelby 0:aafd54b05111 2543
zdshelby 0:aafd54b05111 2544 src_coap_blockwise_ack_msg_ptr->msg_id = received_coap_msg_ptr->msg_id;
zdshelby 0:aafd54b05111 2545
zdshelby 0:aafd54b05111 2546 dst_packed_data_needed_mem = sn_coap_builder_calc_needed_packet_data_size(src_coap_blockwise_ack_msg_ptr);
zdshelby 0:aafd54b05111 2547
zdshelby 0:aafd54b05111 2548 dst_ack_packet_data_ptr = sn_coap_protocol_malloc(dst_packed_data_needed_mem);
zdshelby 0:aafd54b05111 2549 if(!dst_ack_packet_data_ptr)
zdshelby 0:aafd54b05111 2550 {
zdshelby 0:aafd54b05111 2551 sn_coap_parser_release_allocated_coap_msg_mem(received_coap_msg_ptr);
zdshelby 0:aafd54b05111 2552 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr);
zdshelby 0:aafd54b05111 2553 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->options_list_ptr);
zdshelby 0:aafd54b05111 2554 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr);
zdshelby 0:aafd54b05111 2555 return NULL;
zdshelby 0:aafd54b05111 2556 }
zdshelby 0:aafd54b05111 2557
zdshelby 0:aafd54b05111 2558 sn_coap_builder(dst_ack_packet_data_ptr, src_coap_blockwise_ack_msg_ptr);
zdshelby 0:aafd54b05111 2559
zdshelby 0:aafd54b05111 2560 sn_coap_tx_callback(SN_NSDL_PROTOCOL_COAP, dst_ack_packet_data_ptr, dst_packed_data_needed_mem, src_addr_ptr);
zdshelby 0:aafd54b05111 2561
zdshelby 0:aafd54b05111 2562 sn_coap_parser_release_allocated_coap_msg_mem(src_coap_blockwise_ack_msg_ptr);
zdshelby 0:aafd54b05111 2563 sn_coap_protocol_free(dst_ack_packet_data_ptr);
zdshelby 0:aafd54b05111 2564
zdshelby 0:aafd54b05111 2565 received_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVING;
zdshelby 0:aafd54b05111 2566
zdshelby 0:aafd54b05111 2567 }
zdshelby 0:aafd54b05111 2568 else
zdshelby 0:aafd54b05111 2569 {
zdshelby 0:aafd54b05111 2570 /* * * This is the last block when whole Blockwise payload from received * * */
zdshelby 0:aafd54b05111 2571 /* * * blockwise messages is gathered and returned to User * * */
zdshelby 0:aafd54b05111 2572
zdshelby 0:aafd54b05111 2573 /* Store last Blockwise payload to Linked list */
zdshelby 0:aafd54b05111 2574 uint16_t payload_len = 0;
zdshelby 0:aafd54b05111 2575 uint8_t *payload_ptr = sn_coap_protocol_linked_list_blockwise_payload_search(src_addr_ptr, &payload_len);
zdshelby 0:aafd54b05111 2576 uint16_t whole_payload_len = sn_coap_protocol_linked_list_blockwise_payloads_get_len(src_addr_ptr);
zdshelby 0:aafd54b05111 2577 uint8_t *temp_whole_payload_ptr = NULL;
zdshelby 0:aafd54b05111 2578
zdshelby 0:aafd54b05111 2579 temp_whole_payload_ptr = sn_coap_protocol_malloc(whole_payload_len);
zdshelby 0:aafd54b05111 2580 if(!temp_whole_payload_ptr)
zdshelby 0:aafd54b05111 2581 {
zdshelby 0:aafd54b05111 2582 sn_coap_parser_release_allocated_coap_msg_mem(received_coap_msg_ptr);
zdshelby 0:aafd54b05111 2583 return 0;
zdshelby 0:aafd54b05111 2584 }
zdshelby 0:aafd54b05111 2585
zdshelby 0:aafd54b05111 2586 received_coap_msg_ptr->payload_ptr = temp_whole_payload_ptr;
zdshelby 0:aafd54b05111 2587 received_coap_msg_ptr->payload_len = whole_payload_len;
zdshelby 0:aafd54b05111 2588
zdshelby 0:aafd54b05111 2589 /* Copy stored Blockwise payloads to returned whole Blockwise payload pointer */
zdshelby 0:aafd54b05111 2590 while (payload_ptr != NULL)
zdshelby 0:aafd54b05111 2591 {
zdshelby 0:aafd54b05111 2592 memcpy(temp_whole_payload_ptr, payload_ptr, payload_len);
zdshelby 0:aafd54b05111 2593
zdshelby 0:aafd54b05111 2594 temp_whole_payload_ptr += payload_len;
zdshelby 0:aafd54b05111 2595
zdshelby 0:aafd54b05111 2596 sn_coap_protocol_linked_list_blockwise_payload_remove_oldest();
zdshelby 0:aafd54b05111 2597 payload_ptr = sn_coap_protocol_linked_list_blockwise_payload_search(src_addr_ptr, &payload_len);
zdshelby 0:aafd54b05111 2598 }
zdshelby 0:aafd54b05111 2599 received_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED;
zdshelby 0:aafd54b05111 2600 }
zdshelby 0:aafd54b05111 2601 }
zdshelby 0:aafd54b05111 2602 }
zdshelby 0:aafd54b05111 2603
zdshelby 0:aafd54b05111 2604
zdshelby 0:aafd54b05111 2605 /* Block2 Option in a response (e.g., a 2.05 response for GET) */
zdshelby 0:aafd54b05111 2606 /* Message ID must be same than in received message */
zdshelby 0:aafd54b05111 2607 else
zdshelby 0:aafd54b05111 2608 {
zdshelby 0:aafd54b05111 2609 //This is response to request we made
zdshelby 0:aafd54b05111 2610 if(received_coap_msg_ptr->msg_code > COAP_MSG_CODE_REQUEST_DELETE)
zdshelby 0:aafd54b05111 2611 {
zdshelby 0:aafd54b05111 2612 uint32_t block_number = 0;
zdshelby 0:aafd54b05111 2613 coap_blockwise_msg_s *previous_blockwise_msg_ptr = 0;
zdshelby 0:aafd54b05111 2614
zdshelby 0:aafd54b05111 2615 /* Store blockwise payload to Linked list */
zdshelby 0:aafd54b05111 2616 //todo: add block number to stored values - just to make sure all packets are in order
zdshelby 0:aafd54b05111 2617 sn_coap_protocol_linked_list_blockwise_payload_store(src_addr_ptr, received_coap_msg_ptr->payload_len, received_coap_msg_ptr->payload_ptr);
zdshelby 0:aafd54b05111 2618
zdshelby 0:aafd54b05111 2619 /* If not last block (more value is set) */
zdshelby 0:aafd54b05111 2620 if(*(received_coap_msg_ptr->options_list_ptr->block2_ptr + (received_coap_msg_ptr->options_list_ptr->block2_len - 1)) & 0x08)
zdshelby 0:aafd54b05111 2621 {
zdshelby 0:aafd54b05111 2622 //build and send ack
zdshelby 0:aafd54b05111 2623 received_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVING;
zdshelby 0:aafd54b05111 2624
zdshelby 0:aafd54b05111 2625 previous_blockwise_msg_ptr = sn_linked_list_get_first_node(global_linked_list_blockwise_sent_msgs_ptr);
zdshelby 0:aafd54b05111 2626
zdshelby 0:aafd54b05111 2627 while(previous_blockwise_msg_ptr && (received_coap_msg_ptr->msg_id != previous_blockwise_msg_ptr->coap_msg_ptr->msg_id))
zdshelby 0:aafd54b05111 2628 {
zdshelby 0:aafd54b05111 2629 previous_blockwise_msg_ptr = sn_linked_list_get_next_node(global_linked_list_blockwise_sent_msgs_ptr);
zdshelby 0:aafd54b05111 2630 }
zdshelby 0:aafd54b05111 2631
zdshelby 0:aafd54b05111 2632 if(!previous_blockwise_msg_ptr || !previous_blockwise_msg_ptr->coap_msg_ptr)
zdshelby 0:aafd54b05111 2633 {
zdshelby 0:aafd54b05111 2634 sn_coap_parser_release_allocated_coap_msg_mem(received_coap_msg_ptr);
zdshelby 0:aafd54b05111 2635 return 0;
zdshelby 0:aafd54b05111 2636 }
zdshelby 0:aafd54b05111 2637
zdshelby 0:aafd54b05111 2638 src_coap_blockwise_ack_msg_ptr = previous_blockwise_msg_ptr->coap_msg_ptr;
zdshelby 0:aafd54b05111 2639
zdshelby 0:aafd54b05111 2640 sn_linked_list_remove_current_node(global_linked_list_blockwise_sent_msgs_ptr);
zdshelby 0:aafd54b05111 2641 sn_coap_protocol_free(previous_blockwise_msg_ptr);
zdshelby 0:aafd54b05111 2642
zdshelby 0:aafd54b05111 2643 if(src_coap_blockwise_ack_msg_ptr->payload_ptr)
zdshelby 0:aafd54b05111 2644 {
zdshelby 0:aafd54b05111 2645 src_coap_blockwise_ack_msg_ptr->payload_ptr = 0;
zdshelby 0:aafd54b05111 2646 src_coap_blockwise_ack_msg_ptr->payload_len = 0;
zdshelby 0:aafd54b05111 2647 }
zdshelby 0:aafd54b05111 2648
zdshelby 0:aafd54b05111 2649 /* * * Then build CoAP Acknowledgement message * * */
zdshelby 0:aafd54b05111 2650 if(!src_coap_blockwise_ack_msg_ptr->options_list_ptr)
zdshelby 0:aafd54b05111 2651 {
zdshelby 0:aafd54b05111 2652 src_coap_blockwise_ack_msg_ptr->options_list_ptr = sn_coap_protocol_malloc(sizeof(sn_coap_options_list_s));
zdshelby 0:aafd54b05111 2653 if(!src_coap_blockwise_ack_msg_ptr->options_list_ptr)
zdshelby 0:aafd54b05111 2654 {
zdshelby 0:aafd54b05111 2655 sn_coap_parser_release_allocated_coap_msg_mem(received_coap_msg_ptr);
zdshelby 0:aafd54b05111 2656 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr);
zdshelby 0:aafd54b05111 2657 return 0;
zdshelby 0:aafd54b05111 2658 }
zdshelby 0:aafd54b05111 2659 memset(src_coap_blockwise_ack_msg_ptr->options_list_ptr, 0, sizeof(sn_coap_options_list_s));
zdshelby 0:aafd54b05111 2660 }
zdshelby 0:aafd54b05111 2661
zdshelby 0:aafd54b05111 2662 src_coap_blockwise_ack_msg_ptr->msg_id = global_message_id++;
zdshelby 0:aafd54b05111 2663
zdshelby 0:aafd54b05111 2664 if(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_ptr)
zdshelby 0:aafd54b05111 2665 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_ptr);
zdshelby 0:aafd54b05111 2666
zdshelby 0:aafd54b05111 2667 /* Update block option */
zdshelby 0:aafd54b05111 2668 block_temp = *(received_coap_msg_ptr->options_list_ptr->block2_ptr + ( received_coap_msg_ptr->options_list_ptr->block2_len - 1)) & 0x07;
zdshelby 0:aafd54b05111 2669
zdshelby 0:aafd54b05111 2670 if(received_coap_msg_ptr->options_list_ptr->block2_len == 3)
zdshelby 0:aafd54b05111 2671 {
zdshelby 0:aafd54b05111 2672 block_number = *(received_coap_msg_ptr->options_list_ptr->block2_ptr) << 12;
zdshelby 0:aafd54b05111 2673 block_number |= *(received_coap_msg_ptr->options_list_ptr->block2_ptr + 1) << 4;
zdshelby 0:aafd54b05111 2674 block_number |= (*(received_coap_msg_ptr->options_list_ptr->block2_ptr + 2)) >> 4;
zdshelby 0:aafd54b05111 2675 }
zdshelby 0:aafd54b05111 2676
zdshelby 0:aafd54b05111 2677 else if(received_coap_msg_ptr->options_list_ptr->block2_len == 2)
zdshelby 0:aafd54b05111 2678 {
zdshelby 0:aafd54b05111 2679 block_number = *(received_coap_msg_ptr->options_list_ptr->block2_ptr) << 4;
zdshelby 0:aafd54b05111 2680 block_number |= (*(received_coap_msg_ptr->options_list_ptr->block2_ptr + 1)) >> 4;
zdshelby 0:aafd54b05111 2681 }
zdshelby 0:aafd54b05111 2682 else if(received_coap_msg_ptr->options_list_ptr->block2_len == 1)
zdshelby 0:aafd54b05111 2683 {
zdshelby 0:aafd54b05111 2684 block_number = (*received_coap_msg_ptr->options_list_ptr->block2_ptr) >> 4;
zdshelby 0:aafd54b05111 2685 }
zdshelby 0:aafd54b05111 2686
zdshelby 0:aafd54b05111 2687 block_number ++;
zdshelby 0:aafd54b05111 2688
zdshelby 0:aafd54b05111 2689 if(block_number <= 0x0f)
zdshelby 0:aafd54b05111 2690 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_len = 1;
zdshelby 0:aafd54b05111 2691 else if(block_number <= 0x0fff)
zdshelby 0:aafd54b05111 2692 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_len = 2;
zdshelby 0:aafd54b05111 2693 else if(block_number <= 0x0fffff)
zdshelby 0:aafd54b05111 2694 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_len = 3;
zdshelby 0:aafd54b05111 2695
zdshelby 0:aafd54b05111 2696 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_ptr = sn_coap_protocol_malloc(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_len);
zdshelby 0:aafd54b05111 2697
zdshelby 0:aafd54b05111 2698 if(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_ptr == 0)
zdshelby 0:aafd54b05111 2699 {
zdshelby 0:aafd54b05111 2700 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->options_list_ptr);
zdshelby 0:aafd54b05111 2701 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr);
zdshelby 0:aafd54b05111 2702 sn_coap_parser_release_allocated_coap_msg_mem(received_coap_msg_ptr);
zdshelby 0:aafd54b05111 2703 return 0;
zdshelby 0:aafd54b05111 2704 }
zdshelby 0:aafd54b05111 2705
zdshelby 0:aafd54b05111 2706 *(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_ptr + (src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_len - 1)) = block_temp;
zdshelby 0:aafd54b05111 2707
zdshelby 0:aafd54b05111 2708 if(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_len == 3)
zdshelby 0:aafd54b05111 2709 {
zdshelby 0:aafd54b05111 2710 *(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_ptr + 2) = block_number << 4;
zdshelby 0:aafd54b05111 2711 *(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_ptr + 1) |= block_number >> 4;
zdshelby 0:aafd54b05111 2712 *src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_ptr |= block_number >> 12;
zdshelby 0:aafd54b05111 2713 }
zdshelby 0:aafd54b05111 2714 else if(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_len == 2)
zdshelby 0:aafd54b05111 2715 {
zdshelby 0:aafd54b05111 2716 *(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_ptr + 1) = block_number << 4;
zdshelby 0:aafd54b05111 2717 *src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_ptr |= block_number >> 4;
zdshelby 0:aafd54b05111 2718 }
zdshelby 0:aafd54b05111 2719 else
zdshelby 0:aafd54b05111 2720 *src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_ptr |= block_number << 4;
zdshelby 0:aafd54b05111 2721
zdshelby 0:aafd54b05111 2722 /* Then get needed memory count for Packet data */
zdshelby 0:aafd54b05111 2723 dst_packed_data_needed_mem = sn_coap_builder_calc_needed_packet_data_size(src_coap_blockwise_ack_msg_ptr);
zdshelby 0:aafd54b05111 2724
zdshelby 0:aafd54b05111 2725 /* Then allocate memory for Packet data */
zdshelby 0:aafd54b05111 2726 dst_ack_packet_data_ptr = sn_coap_protocol_malloc(dst_packed_data_needed_mem);
zdshelby 0:aafd54b05111 2727 memset(dst_ack_packet_data_ptr, 0, dst_packed_data_needed_mem);
zdshelby 0:aafd54b05111 2728
zdshelby 0:aafd54b05111 2729 if (dst_ack_packet_data_ptr == NULL)
zdshelby 0:aafd54b05111 2730 {
zdshelby 0:aafd54b05111 2731 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr);
zdshelby 0:aafd54b05111 2732 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->options_list_ptr);
zdshelby 0:aafd54b05111 2733 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_ptr);
zdshelby 0:aafd54b05111 2734 sn_coap_parser_release_allocated_coap_msg_mem(received_coap_msg_ptr);
zdshelby 0:aafd54b05111 2735 return NULL;
zdshelby 0:aafd54b05111 2736 }
zdshelby 0:aafd54b05111 2737
zdshelby 0:aafd54b05111 2738 /* * * Then build Acknowledgement message to Packed data * * */
zdshelby 0:aafd54b05111 2739 if ((sn_coap_builder(dst_ack_packet_data_ptr, src_coap_blockwise_ack_msg_ptr)) < 0)
zdshelby 0:aafd54b05111 2740 {
zdshelby 0:aafd54b05111 2741 sn_coap_protocol_free(dst_ack_packet_data_ptr);
zdshelby 0:aafd54b05111 2742 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr);
zdshelby 0:aafd54b05111 2743 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->options_list_ptr);
zdshelby 0:aafd54b05111 2744 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_ptr);
zdshelby 0:aafd54b05111 2745 sn_coap_parser_release_allocated_coap_msg_mem(received_coap_msg_ptr);
zdshelby 0:aafd54b05111 2746 return NULL;
zdshelby 0:aafd54b05111 2747 }
zdshelby 0:aafd54b05111 2748
zdshelby 0:aafd54b05111 2749 /* * * Save to linked list * * */
zdshelby 0:aafd54b05111 2750 coap_blockwise_msg_s *stored_blockwise_msg_ptr;
zdshelby 0:aafd54b05111 2751
zdshelby 0:aafd54b05111 2752 stored_blockwise_msg_ptr = sn_coap_protocol_malloc(sizeof(coap_blockwise_msg_s));
zdshelby 0:aafd54b05111 2753 if(!stored_blockwise_msg_ptr)
zdshelby 0:aafd54b05111 2754 {
zdshelby 0:aafd54b05111 2755 sn_coap_parser_release_allocated_coap_msg_mem(received_coap_msg_ptr);
zdshelby 0:aafd54b05111 2756 return 0;
zdshelby 0:aafd54b05111 2757 }
zdshelby 0:aafd54b05111 2758 memset(stored_blockwise_msg_ptr, 0, sizeof(coap_blockwise_msg_s));
zdshelby 0:aafd54b05111 2759
zdshelby 0:aafd54b05111 2760 stored_blockwise_msg_ptr->timestamp = global_system_time;
zdshelby 0:aafd54b05111 2761
zdshelby 0:aafd54b05111 2762 stored_blockwise_msg_ptr->coap_msg_ptr = src_coap_blockwise_ack_msg_ptr;
zdshelby 0:aafd54b05111 2763
zdshelby 0:aafd54b05111 2764 sn_linked_list_add_node(global_linked_list_blockwise_sent_msgs_ptr, stored_blockwise_msg_ptr); // todo check return value
zdshelby 0:aafd54b05111 2765
zdshelby 0:aafd54b05111 2766
zdshelby 0:aafd54b05111 2767 /* * * Then release memory of CoAP Acknowledgement message * * */
zdshelby 0:aafd54b05111 2768 sn_coap_tx_callback(SN_NSDL_PROTOCOL_COAP, dst_ack_packet_data_ptr,
zdshelby 0:aafd54b05111 2769 dst_packed_data_needed_mem, src_addr_ptr);
zdshelby 0:aafd54b05111 2770
zdshelby 0:aafd54b05111 2771 #if ENABLE_RESENDINGS
zdshelby 0:aafd54b05111 2772 sn_coap_protocol_linked_list_send_msg_store(src_addr_ptr,
zdshelby 0:aafd54b05111 2773 dst_packed_data_needed_mem,
zdshelby 0:aafd54b05111 2774 dst_ack_packet_data_ptr,
zdshelby 0:aafd54b05111 2775 global_system_time + (uint32_t)(sn_coap_resending_intervall * RESPONSE_RANDOM_FACTOR));
zdshelby 0:aafd54b05111 2776 #endif
zdshelby 0:aafd54b05111 2777 sn_coap_protocol_free(dst_ack_packet_data_ptr);
zdshelby 0:aafd54b05111 2778 }
zdshelby 0:aafd54b05111 2779
zdshelby 0:aafd54b05111 2780 //Last block received
zdshelby 0:aafd54b05111 2781 else
zdshelby 0:aafd54b05111 2782 {
zdshelby 0:aafd54b05111 2783 /* * * This is the last block when whole Blockwise payload from received * * */
zdshelby 0:aafd54b05111 2784 /* * * blockwise messages is gathered and returned to User * * */
zdshelby 0:aafd54b05111 2785
zdshelby 0:aafd54b05111 2786 /* Store last Blockwise payload to Linked list */
zdshelby 0:aafd54b05111 2787 uint16_t payload_len = 0;
zdshelby 0:aafd54b05111 2788 uint8_t *payload_ptr = sn_coap_protocol_linked_list_blockwise_payload_search(src_addr_ptr, &payload_len);
zdshelby 0:aafd54b05111 2789 uint16_t whole_payload_len = sn_coap_protocol_linked_list_blockwise_payloads_get_len(src_addr_ptr);
zdshelby 0:aafd54b05111 2790 uint8_t *temp_whole_payload_ptr = NULL;
zdshelby 0:aafd54b05111 2791
zdshelby 0:aafd54b05111 2792 temp_whole_payload_ptr = sn_coap_protocol_malloc(whole_payload_len);
zdshelby 0:aafd54b05111 2793 if(!temp_whole_payload_ptr)
zdshelby 0:aafd54b05111 2794 return 0;
zdshelby 0:aafd54b05111 2795
zdshelby 0:aafd54b05111 2796 received_coap_msg_ptr->payload_ptr = temp_whole_payload_ptr;
zdshelby 0:aafd54b05111 2797 received_coap_msg_ptr->payload_len = whole_payload_len;
zdshelby 0:aafd54b05111 2798
zdshelby 0:aafd54b05111 2799 /* Copy stored Blockwise payloads to returned whole Blockwise payload pointer */
zdshelby 0:aafd54b05111 2800 while (payload_ptr != NULL)
zdshelby 0:aafd54b05111 2801 {
zdshelby 0:aafd54b05111 2802 memcpy(temp_whole_payload_ptr, payload_ptr, payload_len);
zdshelby 0:aafd54b05111 2803
zdshelby 0:aafd54b05111 2804 temp_whole_payload_ptr += payload_len;
zdshelby 0:aafd54b05111 2805
zdshelby 0:aafd54b05111 2806 sn_coap_protocol_linked_list_blockwise_payload_remove_oldest();
zdshelby 0:aafd54b05111 2807 payload_ptr = sn_coap_protocol_linked_list_blockwise_payload_search(src_addr_ptr, &payload_len);
zdshelby 0:aafd54b05111 2808 }
zdshelby 0:aafd54b05111 2809 received_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED;
zdshelby 0:aafd54b05111 2810
zdshelby 0:aafd54b05111 2811 //todo: remove previous msg from list
zdshelby 0:aafd54b05111 2812 }
zdshelby 0:aafd54b05111 2813
zdshelby 0:aafd54b05111 2814 }
zdshelby 0:aafd54b05111 2815
zdshelby 0:aafd54b05111 2816 //Now we send data to request
zdshelby 0:aafd54b05111 2817 else
zdshelby 0:aafd54b05111 2818 {
zdshelby 0:aafd54b05111 2819 //Get message by using block number
zdshelby 0:aafd54b05111 2820 coap_blockwise_msg_s *stored_blockwise_msg_temp_ptr = sn_linked_list_get_last_node(global_linked_list_blockwise_sent_msgs_ptr);
zdshelby 0:aafd54b05111 2821 if(stored_blockwise_msg_temp_ptr)
zdshelby 0:aafd54b05111 2822 {
zdshelby 0:aafd54b05111 2823 uint16_t block_size = 1;
zdshelby 0:aafd54b05111 2824 uint32_t block_number = 0;
zdshelby 0:aafd54b05111 2825
zdshelby 0:aafd54b05111 2826 /* Resolve block parameters */
zdshelby 0:aafd54b05111 2827 if(received_coap_msg_ptr->options_list_ptr->block2_len == 3)
zdshelby 0:aafd54b05111 2828 {
zdshelby 0:aafd54b05111 2829 block_number = *(received_coap_msg_ptr->options_list_ptr->block2_ptr) << 12;
zdshelby 0:aafd54b05111 2830 block_number |= *(received_coap_msg_ptr->options_list_ptr->block2_ptr + 1) << 4;
zdshelby 0:aafd54b05111 2831 block_number |= (*(received_coap_msg_ptr->options_list_ptr->block2_ptr + 2)) >> 4;
zdshelby 0:aafd54b05111 2832 }
zdshelby 0:aafd54b05111 2833
zdshelby 0:aafd54b05111 2834 else if(received_coap_msg_ptr->options_list_ptr->block2_len == 2)
zdshelby 0:aafd54b05111 2835 {
zdshelby 0:aafd54b05111 2836 block_number = *(received_coap_msg_ptr->options_list_ptr->block2_ptr) << 4;
zdshelby 0:aafd54b05111 2837 block_number |= (*(received_coap_msg_ptr->options_list_ptr->block2_ptr + 1)) >> 4;
zdshelby 0:aafd54b05111 2838 }
zdshelby 0:aafd54b05111 2839 else if(received_coap_msg_ptr->options_list_ptr->block2_len == 1)
zdshelby 0:aafd54b05111 2840 {
zdshelby 0:aafd54b05111 2841 block_number = (*received_coap_msg_ptr->options_list_ptr->block2_ptr) >> 4;
zdshelby 0:aafd54b05111 2842 }
zdshelby 0:aafd54b05111 2843
zdshelby 0:aafd54b05111 2844 block_temp = *(received_coap_msg_ptr->options_list_ptr->block2_ptr + (received_coap_msg_ptr->options_list_ptr->block2_len - 1)) & 0x07;
zdshelby 0:aafd54b05111 2845 block_size = block_size << (block_temp + 4);
zdshelby 0:aafd54b05111 2846
zdshelby 0:aafd54b05111 2847 /* Build response message */
zdshelby 0:aafd54b05111 2848 src_coap_blockwise_ack_msg_ptr = stored_blockwise_msg_temp_ptr->coap_msg_ptr;
zdshelby 0:aafd54b05111 2849
zdshelby 0:aafd54b05111 2850 if(src_coap_blockwise_ack_msg_ptr->options_list_ptr)
zdshelby 0:aafd54b05111 2851 {
zdshelby 0:aafd54b05111 2852 if(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr)
zdshelby 0:aafd54b05111 2853 {
zdshelby 0:aafd54b05111 2854 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr);
zdshelby 0:aafd54b05111 2855 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1_ptr = 0;
zdshelby 0:aafd54b05111 2856
zdshelby 0:aafd54b05111 2857 }
zdshelby 0:aafd54b05111 2858 if(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_ptr)
zdshelby 0:aafd54b05111 2859 {
zdshelby 0:aafd54b05111 2860 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_ptr);
zdshelby 0:aafd54b05111 2861 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_ptr = 0;
zdshelby 0:aafd54b05111 2862 }
zdshelby 0:aafd54b05111 2863 }
zdshelby 0:aafd54b05111 2864 else
zdshelby 0:aafd54b05111 2865 {
zdshelby 0:aafd54b05111 2866 src_coap_blockwise_ack_msg_ptr->options_list_ptr = sn_coap_protocol_malloc(sizeof(sn_coap_options_list_s));
zdshelby 0:aafd54b05111 2867 if(!src_coap_blockwise_ack_msg_ptr->options_list_ptr)
zdshelby 0:aafd54b05111 2868 {
zdshelby 0:aafd54b05111 2869 return 0;
zdshelby 0:aafd54b05111 2870 }
zdshelby 0:aafd54b05111 2871 memset(src_coap_blockwise_ack_msg_ptr->options_list_ptr, 0, (sizeof(sn_coap_options_list_s)));
zdshelby 0:aafd54b05111 2872 }
zdshelby 0:aafd54b05111 2873
zdshelby 0:aafd54b05111 2874
zdshelby 0:aafd54b05111 2875 src_coap_blockwise_ack_msg_ptr->msg_id = received_coap_msg_ptr->msg_id;
zdshelby 0:aafd54b05111 2876
zdshelby 0:aafd54b05111 2877 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_len = received_coap_msg_ptr->options_list_ptr->block2_len;
zdshelby 0:aafd54b05111 2878 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_ptr = sn_coap_protocol_malloc(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_len);
zdshelby 0:aafd54b05111 2879
zdshelby 0:aafd54b05111 2880 if(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_ptr == NULL)
zdshelby 0:aafd54b05111 2881 {
zdshelby 0:aafd54b05111 2882 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->options_list_ptr);
zdshelby 0:aafd54b05111 2883 sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr);
zdshelby 0:aafd54b05111 2884 return NULL;
zdshelby 0:aafd54b05111 2885 }
zdshelby 0:aafd54b05111 2886 memcpy(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_ptr, received_coap_msg_ptr->options_list_ptr->block2_ptr, src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_len);
zdshelby 0:aafd54b05111 2887
zdshelby 0:aafd54b05111 2888 /* * Payload part * */
zdshelby 0:aafd54b05111 2889
zdshelby 0:aafd54b05111 2890 /* Check if last block */
zdshelby 0:aafd54b05111 2891
zdshelby 0:aafd54b05111 2892 original_payload_len = stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len;
zdshelby 0:aafd54b05111 2893 original_payload_ptr = stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_ptr;
zdshelby 0:aafd54b05111 2894
zdshelby 0:aafd54b05111 2895 if((block_size * (block_number + 1)) > stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len)
zdshelby 0:aafd54b05111 2896 {
zdshelby 0:aafd54b05111 2897 src_coap_blockwise_ack_msg_ptr->payload_len = stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len - (block_size * block_number);
zdshelby 0:aafd54b05111 2898 src_coap_blockwise_ack_msg_ptr->payload_ptr = stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_ptr + (block_size * block_number);
zdshelby 0:aafd54b05111 2899 }
zdshelby 0:aafd54b05111 2900 /* Not last block */
zdshelby 0:aafd54b05111 2901 else
zdshelby 0:aafd54b05111 2902 {
zdshelby 0:aafd54b05111 2903 /* set more - bit */
zdshelby 0:aafd54b05111 2904 *(src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_ptr + (src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2_len-1)) |= 0x08;
zdshelby 0:aafd54b05111 2905 src_coap_blockwise_ack_msg_ptr->payload_len = block_size;
zdshelby 0:aafd54b05111 2906 src_coap_blockwise_ack_msg_ptr->payload_ptr = stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_ptr + (block_size * block_number);
zdshelby 0:aafd54b05111 2907 }
zdshelby 0:aafd54b05111 2908
zdshelby 0:aafd54b05111 2909 /* Build and send block message */
zdshelby 0:aafd54b05111 2910 dst_packed_data_needed_mem = sn_coap_builder_calc_needed_packet_data_size(src_coap_blockwise_ack_msg_ptr);
zdshelby 0:aafd54b05111 2911
zdshelby 0:aafd54b05111 2912 dst_ack_packet_data_ptr = sn_coap_protocol_malloc(dst_packed_data_needed_mem);
zdshelby 0:aafd54b05111 2913 if(!dst_ack_packet_data_ptr)
zdshelby 0:aafd54b05111 2914 {
zdshelby 0:aafd54b05111 2915 return NULL;
zdshelby 0:aafd54b05111 2916 }
zdshelby 0:aafd54b05111 2917
zdshelby 0:aafd54b05111 2918 sn_coap_builder(dst_ack_packet_data_ptr, src_coap_blockwise_ack_msg_ptr);
zdshelby 0:aafd54b05111 2919
zdshelby 0:aafd54b05111 2920 sn_coap_tx_callback(SN_NSDL_PROTOCOL_COAP, dst_ack_packet_data_ptr, dst_packed_data_needed_mem, src_addr_ptr);
zdshelby 0:aafd54b05111 2921
zdshelby 0:aafd54b05111 2922 sn_coap_protocol_free(dst_ack_packet_data_ptr);
zdshelby 0:aafd54b05111 2923
zdshelby 0:aafd54b05111 2924 stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len = original_payload_len;
zdshelby 0:aafd54b05111 2925 stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_ptr = original_payload_ptr;
zdshelby 0:aafd54b05111 2926
zdshelby 0:aafd54b05111 2927 if((block_size * (block_number + 1)) > stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len)
zdshelby 0:aafd54b05111 2928 sn_coap_protocol_linked_list_blockwise_msg_remove_current();
zdshelby 0:aafd54b05111 2929
zdshelby 0:aafd54b05111 2930 received_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_BLOCKWISE_ACK;
zdshelby 0:aafd54b05111 2931 }
zdshelby 0:aafd54b05111 2932 }
zdshelby 0:aafd54b05111 2933 }
zdshelby 0:aafd54b05111 2934 return received_coap_msg_ptr;
zdshelby 0:aafd54b05111 2935 }
zdshelby 0:aafd54b05111 2936
zdshelby 0:aafd54b05111 2937 static int8_t sn_coap_convert_block_size(uint16_t block_size)
zdshelby 0:aafd54b05111 2938 {
zdshelby 0:aafd54b05111 2939 if(block_size == 16)
zdshelby 0:aafd54b05111 2940 return 0;
zdshelby 0:aafd54b05111 2941 else if(block_size == 32)
zdshelby 0:aafd54b05111 2942 return 1;
zdshelby 0:aafd54b05111 2943 else if(block_size == 64)
zdshelby 0:aafd54b05111 2944 return 2;
zdshelby 0:aafd54b05111 2945 else if(block_size == 128)
zdshelby 0:aafd54b05111 2946 return 3;
zdshelby 0:aafd54b05111 2947 else if(block_size == 256)
zdshelby 0:aafd54b05111 2948 return 4;
zdshelby 0:aafd54b05111 2949 else if(block_size == 512)
zdshelby 0:aafd54b05111 2950 return 5;
zdshelby 0:aafd54b05111 2951 else if(block_size == 1024)
zdshelby 0:aafd54b05111 2952 return 6;
zdshelby 0:aafd54b05111 2953
zdshelby 0:aafd54b05111 2954 return 0;
zdshelby 0:aafd54b05111 2955 }
zdshelby 0:aafd54b05111 2956
zdshelby 0:aafd54b05111 2957 static sn_coap_hdr_s *sn_coap_protocol_copy_header(sn_coap_hdr_s *source_header_ptr)
zdshelby 0:aafd54b05111 2958 {
zdshelby 0:aafd54b05111 2959 sn_coap_hdr_s *destination_header_ptr;
zdshelby 0:aafd54b05111 2960
zdshelby 0:aafd54b05111 2961 destination_header_ptr = sn_coap_protocol_malloc(sizeof(sn_coap_hdr_s));
zdshelby 0:aafd54b05111 2962 if(!destination_header_ptr)
zdshelby 0:aafd54b05111 2963 return 0;
zdshelby 0:aafd54b05111 2964 memset(destination_header_ptr, 0, sizeof(sn_coap_hdr_s));
zdshelby 0:aafd54b05111 2965
zdshelby 0:aafd54b05111 2966 destination_header_ptr->coap_status = source_header_ptr->coap_status;
zdshelby 0:aafd54b05111 2967 destination_header_ptr->msg_type = source_header_ptr->msg_type;
zdshelby 0:aafd54b05111 2968 destination_header_ptr->msg_code = source_header_ptr->msg_code;
zdshelby 0:aafd54b05111 2969 destination_header_ptr->msg_id = source_header_ptr->msg_id;
zdshelby 0:aafd54b05111 2970
zdshelby 0:aafd54b05111 2971 if(source_header_ptr->uri_path_ptr)
zdshelby 0:aafd54b05111 2972 {
zdshelby 0:aafd54b05111 2973 destination_header_ptr->uri_path_len = source_header_ptr->uri_path_len;
zdshelby 0:aafd54b05111 2974 destination_header_ptr->uri_path_ptr = sn_coap_protocol_malloc(source_header_ptr->uri_path_len);
zdshelby 0:aafd54b05111 2975 if(!destination_header_ptr->uri_path_ptr)
zdshelby 0:aafd54b05111 2976 {
zdshelby 0:aafd54b05111 2977 sn_coap_parser_release_allocated_coap_msg_mem(destination_header_ptr);
zdshelby 0:aafd54b05111 2978 return 0;
zdshelby 0:aafd54b05111 2979 }
zdshelby 0:aafd54b05111 2980 memcpy(destination_header_ptr->uri_path_ptr, source_header_ptr->uri_path_ptr, source_header_ptr->uri_path_len);
zdshelby 0:aafd54b05111 2981 }
zdshelby 0:aafd54b05111 2982
zdshelby 0:aafd54b05111 2983 if(source_header_ptr->token_ptr)
zdshelby 0:aafd54b05111 2984 {
zdshelby 0:aafd54b05111 2985 destination_header_ptr->token_len = source_header_ptr->token_len;
zdshelby 0:aafd54b05111 2986 destination_header_ptr->token_ptr = sn_coap_protocol_malloc(source_header_ptr->token_len);
zdshelby 0:aafd54b05111 2987 if(!destination_header_ptr->token_ptr)
zdshelby 0:aafd54b05111 2988 {
zdshelby 0:aafd54b05111 2989 sn_coap_parser_release_allocated_coap_msg_mem(destination_header_ptr);
zdshelby 0:aafd54b05111 2990 return 0;
zdshelby 0:aafd54b05111 2991 }
zdshelby 0:aafd54b05111 2992 memcpy(destination_header_ptr->token_ptr, source_header_ptr->token_ptr, source_header_ptr->token_len);
zdshelby 0:aafd54b05111 2993 }
zdshelby 0:aafd54b05111 2994
zdshelby 0:aafd54b05111 2995 if(source_header_ptr->content_type_ptr)
zdshelby 0:aafd54b05111 2996 {
zdshelby 0:aafd54b05111 2997 destination_header_ptr->content_type_len = source_header_ptr->content_type_len;
zdshelby 0:aafd54b05111 2998 destination_header_ptr->content_type_ptr = sn_coap_protocol_malloc(source_header_ptr->content_type_len);
zdshelby 0:aafd54b05111 2999 if(!destination_header_ptr->content_type_ptr)
zdshelby 0:aafd54b05111 3000 {
zdshelby 0:aafd54b05111 3001 sn_coap_parser_release_allocated_coap_msg_mem(destination_header_ptr);
zdshelby 0:aafd54b05111 3002 return 0;
zdshelby 0:aafd54b05111 3003 }
zdshelby 0:aafd54b05111 3004 memcpy(destination_header_ptr->content_type_ptr, source_header_ptr->content_type_ptr, source_header_ptr->content_type_len);
zdshelby 0:aafd54b05111 3005 }
zdshelby 0:aafd54b05111 3006
zdshelby 0:aafd54b05111 3007 /* Options list */
zdshelby 0:aafd54b05111 3008 if(source_header_ptr->options_list_ptr)
zdshelby 0:aafd54b05111 3009 {
zdshelby 0:aafd54b05111 3010 destination_header_ptr->options_list_ptr = sn_coap_protocol_malloc(sizeof(sn_coap_options_list_s));
zdshelby 0:aafd54b05111 3011 if(!destination_header_ptr->options_list_ptr)
zdshelby 0:aafd54b05111 3012 {
zdshelby 0:aafd54b05111 3013 sn_coap_parser_release_allocated_coap_msg_mem(destination_header_ptr);
zdshelby 0:aafd54b05111 3014 return 0;
zdshelby 0:aafd54b05111 3015 }
zdshelby 0:aafd54b05111 3016 memset(destination_header_ptr->options_list_ptr, 0, sizeof(sn_coap_options_list_s));
zdshelby 0:aafd54b05111 3017
zdshelby 0:aafd54b05111 3018
zdshelby 0:aafd54b05111 3019 if(source_header_ptr->options_list_ptr->max_age_ptr)
zdshelby 0:aafd54b05111 3020 {
zdshelby 0:aafd54b05111 3021 destination_header_ptr->options_list_ptr->max_age_len = source_header_ptr->options_list_ptr->max_age_len;
zdshelby 0:aafd54b05111 3022 destination_header_ptr->options_list_ptr->max_age_ptr = sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->max_age_len);
zdshelby 0:aafd54b05111 3023 if(!destination_header_ptr->options_list_ptr->max_age_ptr)
zdshelby 0:aafd54b05111 3024 {
zdshelby 0:aafd54b05111 3025 sn_coap_parser_release_allocated_coap_msg_mem(destination_header_ptr);
zdshelby 0:aafd54b05111 3026 return 0;
zdshelby 0:aafd54b05111 3027 }
zdshelby 0:aafd54b05111 3028 memcpy(destination_header_ptr->options_list_ptr->max_age_ptr, source_header_ptr->options_list_ptr->max_age_ptr, source_header_ptr->options_list_ptr->max_age_len);
zdshelby 0:aafd54b05111 3029 }
zdshelby 0:aafd54b05111 3030
zdshelby 0:aafd54b05111 3031 if(source_header_ptr->options_list_ptr->proxy_uri_ptr)
zdshelby 0:aafd54b05111 3032 {
zdshelby 0:aafd54b05111 3033 destination_header_ptr->options_list_ptr->proxy_uri_len = source_header_ptr->options_list_ptr->proxy_uri_len;
zdshelby 0:aafd54b05111 3034 destination_header_ptr->options_list_ptr->proxy_uri_ptr = sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->proxy_uri_len);
zdshelby 0:aafd54b05111 3035 if(!destination_header_ptr->options_list_ptr->proxy_uri_ptr)
zdshelby 0:aafd54b05111 3036 {
zdshelby 0:aafd54b05111 3037 sn_coap_parser_release_allocated_coap_msg_mem(destination_header_ptr);
zdshelby 0:aafd54b05111 3038 return 0;
zdshelby 0:aafd54b05111 3039 }
zdshelby 0:aafd54b05111 3040 memcpy(destination_header_ptr->options_list_ptr->proxy_uri_ptr, source_header_ptr->options_list_ptr->proxy_uri_ptr, source_header_ptr->options_list_ptr->proxy_uri_len);
zdshelby 0:aafd54b05111 3041 }
zdshelby 0:aafd54b05111 3042
zdshelby 0:aafd54b05111 3043 if(source_header_ptr->options_list_ptr->etag_ptr)
zdshelby 0:aafd54b05111 3044 {
zdshelby 0:aafd54b05111 3045 destination_header_ptr->options_list_ptr->etag_len = source_header_ptr->options_list_ptr->etag_len;
zdshelby 0:aafd54b05111 3046 destination_header_ptr->options_list_ptr->etag_ptr = sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->etag_len);
zdshelby 0:aafd54b05111 3047 if(!destination_header_ptr->options_list_ptr->etag_ptr)
zdshelby 0:aafd54b05111 3048 {
zdshelby 0:aafd54b05111 3049 sn_coap_parser_release_allocated_coap_msg_mem(destination_header_ptr);
zdshelby 0:aafd54b05111 3050 return 0;
zdshelby 0:aafd54b05111 3051 }
zdshelby 0:aafd54b05111 3052 memcpy(destination_header_ptr->options_list_ptr->etag_ptr, source_header_ptr->options_list_ptr->etag_ptr, source_header_ptr->options_list_ptr->etag_len);
zdshelby 0:aafd54b05111 3053 }
zdshelby 0:aafd54b05111 3054
zdshelby 0:aafd54b05111 3055 if(source_header_ptr->options_list_ptr->uri_host_ptr)
zdshelby 0:aafd54b05111 3056 {
zdshelby 0:aafd54b05111 3057 destination_header_ptr->options_list_ptr->uri_host_len = source_header_ptr->options_list_ptr->uri_host_len;
zdshelby 0:aafd54b05111 3058 destination_header_ptr->options_list_ptr->uri_host_ptr = sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->uri_host_len);
zdshelby 0:aafd54b05111 3059 if(!destination_header_ptr->options_list_ptr->uri_host_ptr)
zdshelby 0:aafd54b05111 3060 {
zdshelby 0:aafd54b05111 3061 sn_coap_parser_release_allocated_coap_msg_mem(destination_header_ptr);
zdshelby 0:aafd54b05111 3062 return 0;
zdshelby 0:aafd54b05111 3063 }
zdshelby 0:aafd54b05111 3064 memcpy(destination_header_ptr->options_list_ptr->uri_host_ptr, source_header_ptr->options_list_ptr->uri_host_ptr, source_header_ptr->options_list_ptr->uri_host_len);
zdshelby 0:aafd54b05111 3065 }
zdshelby 0:aafd54b05111 3066
zdshelby 0:aafd54b05111 3067 if(source_header_ptr->options_list_ptr->location_path_ptr)
zdshelby 0:aafd54b05111 3068 {
zdshelby 0:aafd54b05111 3069 destination_header_ptr->options_list_ptr->location_path_len = source_header_ptr->options_list_ptr->location_path_len;
zdshelby 0:aafd54b05111 3070 destination_header_ptr->options_list_ptr->location_path_ptr = sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->location_path_len);
zdshelby 0:aafd54b05111 3071 if(!destination_header_ptr->options_list_ptr->location_path_ptr)
zdshelby 0:aafd54b05111 3072 {
zdshelby 0:aafd54b05111 3073 sn_coap_parser_release_allocated_coap_msg_mem(destination_header_ptr);
zdshelby 0:aafd54b05111 3074 return 0;
zdshelby 0:aafd54b05111 3075 }
zdshelby 0:aafd54b05111 3076 memcpy(destination_header_ptr->options_list_ptr->location_path_ptr, source_header_ptr->options_list_ptr->location_path_ptr, source_header_ptr->options_list_ptr->location_path_len);
zdshelby 0:aafd54b05111 3077 }
zdshelby 0:aafd54b05111 3078
zdshelby 0:aafd54b05111 3079 if(source_header_ptr->options_list_ptr->uri_port_ptr)
zdshelby 0:aafd54b05111 3080 {
zdshelby 0:aafd54b05111 3081 destination_header_ptr->options_list_ptr->uri_port_len = source_header_ptr->options_list_ptr->uri_port_len;
zdshelby 0:aafd54b05111 3082 destination_header_ptr->options_list_ptr->uri_port_ptr = sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->uri_port_len);
zdshelby 0:aafd54b05111 3083 if(!destination_header_ptr->options_list_ptr->uri_port_ptr)
zdshelby 0:aafd54b05111 3084 {
zdshelby 0:aafd54b05111 3085 sn_coap_parser_release_allocated_coap_msg_mem(destination_header_ptr);
zdshelby 0:aafd54b05111 3086 return 0;
zdshelby 0:aafd54b05111 3087 }
zdshelby 0:aafd54b05111 3088 memcpy(destination_header_ptr->options_list_ptr->uri_port_ptr, source_header_ptr->options_list_ptr->uri_port_ptr, source_header_ptr->options_list_ptr->uri_port_len);
zdshelby 0:aafd54b05111 3089 }
zdshelby 0:aafd54b05111 3090
zdshelby 0:aafd54b05111 3091 if(source_header_ptr->options_list_ptr->location_query_ptr)
zdshelby 0:aafd54b05111 3092 {
zdshelby 0:aafd54b05111 3093 destination_header_ptr->options_list_ptr->location_query_len = source_header_ptr->options_list_ptr->location_query_len;
zdshelby 0:aafd54b05111 3094 destination_header_ptr->options_list_ptr->location_query_ptr = sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->location_query_len);
zdshelby 0:aafd54b05111 3095 if(!destination_header_ptr->options_list_ptr->location_query_ptr)
zdshelby 0:aafd54b05111 3096 {
zdshelby 0:aafd54b05111 3097 sn_coap_parser_release_allocated_coap_msg_mem(destination_header_ptr);
zdshelby 0:aafd54b05111 3098 return 0;
zdshelby 0:aafd54b05111 3099 }
zdshelby 0:aafd54b05111 3100 memcpy(destination_header_ptr->options_list_ptr->location_query_ptr, source_header_ptr->options_list_ptr->location_query_ptr, source_header_ptr->options_list_ptr->location_query_len);
zdshelby 0:aafd54b05111 3101 }
zdshelby 0:aafd54b05111 3102
zdshelby 0:aafd54b05111 3103 if(source_header_ptr->options_list_ptr->observe_ptr)
zdshelby 0:aafd54b05111 3104 {
zdshelby 0:aafd54b05111 3105 destination_header_ptr->options_list_ptr->observe_len = source_header_ptr->options_list_ptr->observe_len;
zdshelby 0:aafd54b05111 3106 destination_header_ptr->options_list_ptr->observe_ptr = sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->observe_len);
zdshelby 0:aafd54b05111 3107 if(!destination_header_ptr->options_list_ptr->observe_ptr)
zdshelby 0:aafd54b05111 3108 {
zdshelby 0:aafd54b05111 3109 sn_coap_parser_release_allocated_coap_msg_mem(destination_header_ptr);
zdshelby 0:aafd54b05111 3110 return 0;
zdshelby 0:aafd54b05111 3111 }
zdshelby 0:aafd54b05111 3112 memcpy(destination_header_ptr->options_list_ptr->observe_ptr, source_header_ptr->options_list_ptr->observe_ptr, source_header_ptr->options_list_ptr->observe_len);
zdshelby 0:aafd54b05111 3113 }
zdshelby 0:aafd54b05111 3114
zdshelby 0:aafd54b05111 3115 if(source_header_ptr->options_list_ptr->accept_ptr)
zdshelby 0:aafd54b05111 3116 {
zdshelby 0:aafd54b05111 3117 destination_header_ptr->options_list_ptr->accept_len = source_header_ptr->options_list_ptr->accept_len;
zdshelby 0:aafd54b05111 3118 destination_header_ptr->options_list_ptr->accept_ptr = sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->accept_len);
zdshelby 0:aafd54b05111 3119 if(!destination_header_ptr->options_list_ptr->accept_ptr)
zdshelby 0:aafd54b05111 3120 {
zdshelby 0:aafd54b05111 3121 sn_coap_parser_release_allocated_coap_msg_mem(destination_header_ptr);
zdshelby 0:aafd54b05111 3122 return 0;
zdshelby 0:aafd54b05111 3123 }
zdshelby 0:aafd54b05111 3124 memcpy(destination_header_ptr->options_list_ptr->accept_ptr, source_header_ptr->options_list_ptr->accept_ptr, source_header_ptr->options_list_ptr->accept_len);
zdshelby 0:aafd54b05111 3125 }
zdshelby 0:aafd54b05111 3126
zdshelby 0:aafd54b05111 3127 if(source_header_ptr->options_list_ptr->uri_query_ptr)
zdshelby 0:aafd54b05111 3128 {
zdshelby 0:aafd54b05111 3129 destination_header_ptr->options_list_ptr->uri_query_len = source_header_ptr->options_list_ptr->uri_query_len;
zdshelby 0:aafd54b05111 3130 destination_header_ptr->options_list_ptr->uri_query_ptr = sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->uri_query_len);
zdshelby 0:aafd54b05111 3131 if(!destination_header_ptr->options_list_ptr->uri_query_ptr)
zdshelby 0:aafd54b05111 3132 {
zdshelby 0:aafd54b05111 3133 sn_coap_parser_release_allocated_coap_msg_mem(destination_header_ptr);
zdshelby 0:aafd54b05111 3134 return 0;
zdshelby 0:aafd54b05111 3135 }
zdshelby 0:aafd54b05111 3136 memcpy(destination_header_ptr->options_list_ptr->uri_query_ptr, source_header_ptr->options_list_ptr->uri_query_ptr, source_header_ptr->options_list_ptr->uri_query_len);
zdshelby 0:aafd54b05111 3137 }
zdshelby 0:aafd54b05111 3138
zdshelby 0:aafd54b05111 3139 if(source_header_ptr->options_list_ptr->block1_ptr)
zdshelby 0:aafd54b05111 3140 {
zdshelby 0:aafd54b05111 3141 destination_header_ptr->options_list_ptr->block1_len = source_header_ptr->options_list_ptr->block1_len;
zdshelby 0:aafd54b05111 3142 destination_header_ptr->options_list_ptr->block1_ptr = sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->block1_len);
zdshelby 0:aafd54b05111 3143 if(!destination_header_ptr->options_list_ptr->block1_ptr)
zdshelby 0:aafd54b05111 3144 {
zdshelby 0:aafd54b05111 3145 sn_coap_parser_release_allocated_coap_msg_mem(destination_header_ptr);
zdshelby 0:aafd54b05111 3146 return 0;
zdshelby 0:aafd54b05111 3147 }
zdshelby 0:aafd54b05111 3148 memcpy(destination_header_ptr->options_list_ptr->block1_ptr, source_header_ptr->options_list_ptr->block1_ptr, source_header_ptr->options_list_ptr->block1_len);
zdshelby 0:aafd54b05111 3149 }
zdshelby 0:aafd54b05111 3150
zdshelby 0:aafd54b05111 3151 if(source_header_ptr->options_list_ptr->block2_ptr)
zdshelby 0:aafd54b05111 3152 {
zdshelby 0:aafd54b05111 3153 destination_header_ptr->options_list_ptr->block2_len = source_header_ptr->options_list_ptr->block2_len;
zdshelby 0:aafd54b05111 3154 destination_header_ptr->options_list_ptr->block2_ptr = sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->block2_len);
zdshelby 0:aafd54b05111 3155 if(!destination_header_ptr->options_list_ptr->block2_ptr)
zdshelby 0:aafd54b05111 3156 {
zdshelby 0:aafd54b05111 3157 sn_coap_parser_release_allocated_coap_msg_mem(destination_header_ptr);
zdshelby 0:aafd54b05111 3158 return 0;
zdshelby 0:aafd54b05111 3159 }
zdshelby 0:aafd54b05111 3160 memcpy(destination_header_ptr->options_list_ptr->block2_ptr, source_header_ptr->options_list_ptr->block2_ptr, source_header_ptr->options_list_ptr->block2_len);
zdshelby 0:aafd54b05111 3161 }
zdshelby 0:aafd54b05111 3162 }
zdshelby 0:aafd54b05111 3163
zdshelby 0:aafd54b05111 3164 return destination_header_ptr;
zdshelby 0:aafd54b05111 3165 }
zdshelby 0:aafd54b05111 3166 #endif
zdshelby 0:aafd54b05111 3167