This program collects raw time series data from the ADC using the NXP board that will later be post processed by PFP Cyber-security cloud base machine learning engine to determine the state of the device.

Dependencies:   FXAS21002 FXOS8700Q

Committer:
vithyat
Date:
Fri Mar 20 20:15:18 2020 +0000
Revision:
2:990c985a69ae
Parent:
0:977e87915078
Update to work with P2Scan runtime

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vithyat 0:977e87915078 1 /*
vithyat 0:977e87915078 2 * Copyright (c) 2011-2015 ARM Limited. All rights reserved.
vithyat 0:977e87915078 3 * SPDX-License-Identifier: Apache-2.0
vithyat 0:977e87915078 4 * Licensed under the Apache License, Version 2.0 (the License); you may
vithyat 0:977e87915078 5 * not use this file except in compliance with the License.
vithyat 0:977e87915078 6 * You may obtain a copy of the License at
vithyat 0:977e87915078 7 *
vithyat 0:977e87915078 8 * http://www.apache.org/licenses/LICENSE-2.0
vithyat 0:977e87915078 9 *
vithyat 0:977e87915078 10 * Unless required by applicable law or agreed to in writing, software
vithyat 0:977e87915078 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
vithyat 0:977e87915078 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
vithyat 0:977e87915078 13 * See the License for the specific language governing permissions and
vithyat 0:977e87915078 14 * limitations under the License.
vithyat 0:977e87915078 15 */
vithyat 0:977e87915078 16
vithyat 0:977e87915078 17 /**
vithyat 0:977e87915078 18 * \file sn_coap_protocol.c
vithyat 0:977e87915078 19 *
vithyat 0:977e87915078 20 * \brief CoAP Protocol implementation
vithyat 0:977e87915078 21 *
vithyat 0:977e87915078 22 * Functionality: CoAP Protocol
vithyat 0:977e87915078 23 *
vithyat 0:977e87915078 24 */
vithyat 0:977e87915078 25
vithyat 0:977e87915078 26
vithyat 0:977e87915078 27 /* * * * * * * * * * * * * * */
vithyat 0:977e87915078 28 /* * * * INCLUDE FILES * * * */
vithyat 0:977e87915078 29 /* * * * * * * * * * * * * * */
vithyat 0:977e87915078 30
vithyat 0:977e87915078 31 #include <stdio.h>
vithyat 0:977e87915078 32 #include <stdlib.h> /* For libary malloc() */
vithyat 0:977e87915078 33 #include <string.h> /* For memset() and memcpy() */
vithyat 0:977e87915078 34 #if defined __linux__ || defined TARGET_LIKE_MBED
vithyat 0:977e87915078 35 #include <time.h>
vithyat 0:977e87915078 36 #endif
vithyat 0:977e87915078 37
vithyat 0:977e87915078 38 #include "ns_types.h"
vithyat 0:977e87915078 39 #include "mbed-coap/sn_coap_protocol.h"
vithyat 0:977e87915078 40 #include "sn_coap_header_internal.h"
vithyat 0:977e87915078 41 #include "sn_coap_protocol_internal.h"
vithyat 0:977e87915078 42 #include "randLIB.h"
vithyat 0:977e87915078 43 #include "mbed-trace/mbed_trace.h"
vithyat 0:977e87915078 44
vithyat 0:977e87915078 45 #define TRACE_GROUP "coap"
vithyat 0:977e87915078 46 /* * * * * * * * * * * * * * * * * * * * */
vithyat 0:977e87915078 47 /* * * * LOCAL FUNCTION PROTOTYPES * * * */
vithyat 0:977e87915078 48 /* * * * * * * * * * * * * * * * * * * * */
vithyat 0:977e87915078 49
vithyat 0:977e87915078 50 #if SN_COAP_DUPLICATION_MAX_MSGS_COUNT/* If Message duplication detection is not used at all, this part of code will not be compiled */
vithyat 0:977e87915078 51 static void sn_coap_protocol_linked_list_duplication_info_store(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr, uint16_t msg_id, void *param);
vithyat 0:977e87915078 52 static coap_duplication_info_s *sn_coap_protocol_linked_list_duplication_info_search(const struct coap_s *handle, const sn_nsdl_addr_s *scr_addr_ptr, const uint16_t msg_id);
vithyat 0:977e87915078 53 static void sn_coap_protocol_linked_list_duplication_info_remove(struct coap_s *handle, uint8_t *scr_addr_ptr, uint16_t port, uint16_t msg_id);
vithyat 0:977e87915078 54 static void sn_coap_protocol_linked_list_duplication_info_remove_old_ones(struct coap_s *handle);
vithyat 0:977e87915078 55 static bool sn_coap_protocol_update_duplicate_package_data(const struct coap_s *handle, const sn_nsdl_addr_s *dst_addr_ptr, const sn_coap_hdr_s *coap_msg_ptr, const int16_t data_size, const uint8_t *dst_packet_data_ptr);
vithyat 0:977e87915078 56 #endif
vithyat 0:977e87915078 57
vithyat 0:977e87915078 58 #if SN_COAP_BLOCKWISE_ENABLED || SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwising is not enabled, this part of code will not be compiled */
vithyat 0:977e87915078 59 static void sn_coap_protocol_linked_list_blockwise_msg_remove(struct coap_s *handle, coap_blockwise_msg_s *removed_msg_ptr);
vithyat 0:977e87915078 60 static void sn_coap_protocol_linked_list_blockwise_payload_store(struct coap_s *handle, sn_nsdl_addr_s *addr_ptr, uint16_t stored_payload_len, uint8_t *stored_payload_ptr, uint8_t *token_ptr, uint8_t token_len, uint32_t block_number);
vithyat 0:977e87915078 61 static uint8_t *sn_coap_protocol_linked_list_blockwise_payload_search(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr, uint16_t *payload_length, uint8_t *token_ptr, uint8_t token_len);
vithyat 0:977e87915078 62 static bool sn_coap_protocol_linked_list_blockwise_payload_compare_block_number(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr, uint8_t *token_ptr, uint8_t token_len, uint32_t block_number);
vithyat 0:977e87915078 63 static void sn_coap_protocol_linked_list_blockwise_payload_remove(struct coap_s *handle, coap_blockwise_payload_s *removed_payload_ptr);
vithyat 0:977e87915078 64 static void sn_coap_protocol_linked_list_blockwise_payload_remove_oldest(struct coap_s *handle, uint8_t *token_ptr, uint8_t token_len);
vithyat 0:977e87915078 65 static uint32_t sn_coap_protocol_linked_list_blockwise_payloads_get_len(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr, uint8_t *token_ptr, uint8_t token_len);
vithyat 0:977e87915078 66 static void sn_coap_protocol_handle_blockwise_timout(struct coap_s *handle);
vithyat 0:977e87915078 67 static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr, sn_coap_hdr_s *received_coap_msg_ptr, void *param);
vithyat 0:977e87915078 68 static sn_coap_hdr_s *sn_coap_protocol_copy_header(struct coap_s *handle, sn_coap_hdr_s *source_header_ptr);
vithyat 0:977e87915078 69 #endif
vithyat 0:977e87915078 70
vithyat 0:977e87915078 71 #if ENABLE_RESENDINGS
vithyat 0:977e87915078 72 static uint8_t sn_coap_protocol_linked_list_send_msg_store(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_ptr, uint16_t send_packet_data_len, uint8_t *send_packet_data_ptr, uint32_t sending_time, void *param);
vithyat 0:977e87915078 73 static sn_nsdl_transmit_s *sn_coap_protocol_linked_list_send_msg_search(struct coap_s *handle,sn_nsdl_addr_s *src_addr_ptr, uint16_t msg_id);
vithyat 0:977e87915078 74 static void sn_coap_protocol_linked_list_send_msg_remove(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr, uint16_t msg_id);
vithyat 0:977e87915078 75 static coap_send_msg_s *sn_coap_protocol_allocate_mem_for_msg(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_ptr, uint16_t packet_data_len);
vithyat 0:977e87915078 76 static void sn_coap_protocol_release_allocated_send_msg_mem(struct coap_s *handle, coap_send_msg_s *freed_send_msg_ptr);
vithyat 0:977e87915078 77 static uint16_t sn_coap_count_linked_list_size(const coap_send_msg_list_t *linked_list_ptr);
vithyat 0:977e87915078 78 static uint32_t sn_coap_calculate_new_resend_time(const uint32_t current_time, const uint8_t interval, const uint8_t counter);
vithyat 0:977e87915078 79 #endif
vithyat 0:977e87915078 80
vithyat 0:977e87915078 81 /* * * * * * * * * * * * * * * * * */
vithyat 0:977e87915078 82 /* * * * GLOBAL DECLARATIONS * * * */
vithyat 0:977e87915078 83 /* * * * * * * * * * * * * * * * * */
vithyat 0:977e87915078 84 static uint16_t message_id;
vithyat 0:977e87915078 85
vithyat 0:977e87915078 86 int8_t sn_coap_protocol_destroy(struct coap_s *handle)
vithyat 0:977e87915078 87 {
vithyat 0:977e87915078 88 if (handle == NULL) {
vithyat 0:977e87915078 89 return -1;
vithyat 0:977e87915078 90 }
vithyat 0:977e87915078 91 #if ENABLE_RESENDINGS /* If Message resending is not used at all, this part of code will not be compiled */
vithyat 0:977e87915078 92
vithyat 0:977e87915078 93 sn_coap_protocol_clear_retransmission_buffer(handle);
vithyat 0:977e87915078 94
vithyat 0:977e87915078 95 #endif
vithyat 0:977e87915078 96
vithyat 0:977e87915078 97 #if SN_COAP_DUPLICATION_MAX_MSGS_COUNT /* If Message duplication detection is not used at all, this part of code will not be compiled */
vithyat 0:977e87915078 98 ns_list_foreach_safe(coap_duplication_info_s, tmp, &handle->linked_list_duplication_msgs) {
vithyat 0:977e87915078 99 if (tmp->coap == handle) {
vithyat 0:977e87915078 100 if (tmp->address) {
vithyat 0:977e87915078 101 if (tmp->address->addr_ptr) {
vithyat 0:977e87915078 102 handle->sn_coap_protocol_free(tmp->address->addr_ptr);
vithyat 0:977e87915078 103 tmp->address->addr_ptr = 0;
vithyat 0:977e87915078 104 }
vithyat 0:977e87915078 105 handle->sn_coap_protocol_free(tmp->address);
vithyat 0:977e87915078 106 tmp->address = 0;
vithyat 0:977e87915078 107 }
vithyat 0:977e87915078 108 if (tmp->packet_ptr) {
vithyat 0:977e87915078 109 handle->sn_coap_protocol_free(tmp->packet_ptr);
vithyat 0:977e87915078 110 tmp->packet_ptr = 0;
vithyat 0:977e87915078 111 }
vithyat 0:977e87915078 112 ns_list_remove(&handle->linked_list_duplication_msgs, tmp);
vithyat 0:977e87915078 113 handle->count_duplication_msgs--;
vithyat 0:977e87915078 114 handle->sn_coap_protocol_free(tmp);
vithyat 0:977e87915078 115 tmp = 0;
vithyat 0:977e87915078 116 }
vithyat 0:977e87915078 117 }
vithyat 0:977e87915078 118
vithyat 0:977e87915078 119 #endif
vithyat 0:977e87915078 120
vithyat 0:977e87915078 121
vithyat 0:977e87915078 122 #if SN_COAP_BLOCKWISE_ENABLED || SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwise is not enabled, this part of code will not be compiled */
vithyat 0:977e87915078 123 ns_list_foreach_safe(coap_blockwise_msg_s, tmp, &handle->linked_list_blockwise_sent_msgs) {
vithyat 0:977e87915078 124 if (tmp->coap == handle) {
vithyat 0:977e87915078 125 if (tmp->coap_msg_ptr) {
vithyat 0:977e87915078 126 handle->sn_coap_protocol_free(tmp->coap_msg_ptr->payload_ptr);
vithyat 0:977e87915078 127 sn_coap_parser_release_allocated_coap_msg_mem(tmp->coap, tmp->coap_msg_ptr);
vithyat 0:977e87915078 128 }
vithyat 0:977e87915078 129 ns_list_remove(&handle->linked_list_blockwise_sent_msgs, tmp);
vithyat 0:977e87915078 130 handle->sn_coap_protocol_free(tmp);
vithyat 0:977e87915078 131 }
vithyat 0:977e87915078 132 }
vithyat 0:977e87915078 133
vithyat 0:977e87915078 134 ns_list_foreach_safe(coap_blockwise_payload_s, tmp, &handle->linked_list_blockwise_received_payloads) {
vithyat 0:977e87915078 135 if (tmp->coap == handle) {
vithyat 0:977e87915078 136 sn_coap_protocol_linked_list_blockwise_payload_remove(handle, tmp);
vithyat 0:977e87915078 137 }
vithyat 0:977e87915078 138 }
vithyat 0:977e87915078 139 #endif
vithyat 0:977e87915078 140
vithyat 0:977e87915078 141 handle->sn_coap_protocol_free(handle);
vithyat 0:977e87915078 142 handle = 0;
vithyat 0:977e87915078 143 return 0;
vithyat 0:977e87915078 144 }
vithyat 0:977e87915078 145
vithyat 0:977e87915078 146 struct coap_s *sn_coap_protocol_init(void *(*used_malloc_func_ptr)(uint16_t), void (*used_free_func_ptr)(void *),
vithyat 0:977e87915078 147 uint8_t (*used_tx_callback_ptr)(uint8_t *, uint16_t, sn_nsdl_addr_s *, void *),
vithyat 0:977e87915078 148 int8_t (*used_rx_callback_ptr)(sn_coap_hdr_s *, sn_nsdl_addr_s *, void *param))
vithyat 0:977e87915078 149 {
vithyat 0:977e87915078 150 /* Check paramters */
vithyat 0:977e87915078 151 if ((used_malloc_func_ptr == NULL) || (used_free_func_ptr == NULL) || (used_tx_callback_ptr == NULL)) {
vithyat 0:977e87915078 152 return NULL;
vithyat 0:977e87915078 153 }
vithyat 0:977e87915078 154
vithyat 0:977e87915078 155 struct coap_s *handle;
vithyat 0:977e87915078 156 handle = used_malloc_func_ptr(sizeof(struct coap_s));
vithyat 0:977e87915078 157 if (handle == NULL) {
vithyat 0:977e87915078 158 return NULL;
vithyat 0:977e87915078 159 }
vithyat 0:977e87915078 160
vithyat 0:977e87915078 161 memset(handle, 0, sizeof(struct coap_s));
vithyat 0:977e87915078 162
vithyat 0:977e87915078 163 /* * * Handle tx callback * * */
vithyat 0:977e87915078 164 handle->sn_coap_tx_callback = used_tx_callback_ptr;
vithyat 0:977e87915078 165
vithyat 0:977e87915078 166 handle->sn_coap_protocol_free = used_free_func_ptr;
vithyat 0:977e87915078 167 handle->sn_coap_protocol_malloc = used_malloc_func_ptr;
vithyat 0:977e87915078 168
vithyat 0:977e87915078 169 /* * * Handle rx callback * * */
vithyat 0:977e87915078 170 /* If pointer = 0, then re-sending does not return error when failed */
vithyat 0:977e87915078 171 handle->sn_coap_rx_callback = used_rx_callback_ptr;
vithyat 0:977e87915078 172
vithyat 0:977e87915078 173 // Handles internally all GET req responses
vithyat 0:977e87915078 174 handle->sn_coap_internal_block2_resp_handling = true;
vithyat 0:977e87915078 175
vithyat 0:977e87915078 176 #if ENABLE_RESENDINGS /* If Message resending is not used at all, this part of code will not be compiled */
vithyat 0:977e87915078 177 /* * * * Create Linked list for storing active resending messages * * * */
vithyat 0:977e87915078 178 ns_list_init(&handle->linked_list_resent_msgs);
vithyat 0:977e87915078 179 handle->sn_coap_resending_queue_msgs = SN_COAP_RESENDING_QUEUE_SIZE_MSGS;
vithyat 0:977e87915078 180 handle->sn_coap_resending_queue_bytes = SN_COAP_RESENDING_QUEUE_SIZE_BYTES;
vithyat 0:977e87915078 181 handle->sn_coap_resending_intervall = DEFAULT_RESPONSE_TIMEOUT;
vithyat 0:977e87915078 182 handle->sn_coap_resending_count = SN_COAP_RESENDING_MAX_COUNT;
vithyat 0:977e87915078 183
vithyat 0:977e87915078 184
vithyat 0:977e87915078 185 #endif /* ENABLE_RESENDINGS */
vithyat 0:977e87915078 186
vithyat 0:977e87915078 187 #if SN_COAP_DUPLICATION_MAX_MSGS_COUNT /* If Message duplication detection is not used at all, this part of code will not be compiled */
vithyat 0:977e87915078 188 /* * * * Create Linked list for storing Duplication info * * * */
vithyat 0:977e87915078 189 ns_list_init(&handle->linked_list_duplication_msgs);
vithyat 0:977e87915078 190 handle->sn_coap_duplication_buffer_size = SN_COAP_DUPLICATION_MAX_MSGS_COUNT;
vithyat 0:977e87915078 191 #endif
vithyat 0:977e87915078 192
vithyat 0:977e87915078 193 #if SN_COAP_BLOCKWISE_ENABLED || SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwising is not enabled, this part of code will not be compiled */
vithyat 0:977e87915078 194
vithyat 0:977e87915078 195 ns_list_init(&handle->linked_list_blockwise_sent_msgs);
vithyat 0:977e87915078 196 ns_list_init(&handle->linked_list_blockwise_received_payloads);
vithyat 0:977e87915078 197 handle->sn_coap_block_data_size = SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE;
vithyat 0:977e87915078 198
vithyat 0:977e87915078 199 #endif /* ENABLE_RESENDINGS */
vithyat 0:977e87915078 200
vithyat 0:977e87915078 201 /* Randomize global message ID */
vithyat 0:977e87915078 202 randLIB_seed_random();
vithyat 0:977e87915078 203 message_id = randLIB_get_16bit();
vithyat 0:977e87915078 204 if (message_id == 0) {
vithyat 0:977e87915078 205 message_id = 1;
vithyat 0:977e87915078 206 }
vithyat 0:977e87915078 207
vithyat 0:977e87915078 208 return handle;
vithyat 0:977e87915078 209 }
vithyat 0:977e87915078 210
vithyat 0:977e87915078 211 int8_t sn_coap_protocol_handle_block2_response_internally(struct coap_s *handle, uint8_t build_response)
vithyat 0:977e87915078 212 {
vithyat 0:977e87915078 213 if (handle == NULL) {
vithyat 0:977e87915078 214 return -1;
vithyat 0:977e87915078 215 }
vithyat 0:977e87915078 216
vithyat 0:977e87915078 217 handle->sn_coap_internal_block2_resp_handling = build_response;
vithyat 0:977e87915078 218 return 0;
vithyat 0:977e87915078 219 }
vithyat 0:977e87915078 220
vithyat 0:977e87915078 221 int8_t sn_coap_protocol_set_block_size(struct coap_s *handle, uint16_t block_size)
vithyat 0:977e87915078 222 {
vithyat 0:977e87915078 223 (void) handle;
vithyat 0:977e87915078 224 (void) block_size;
vithyat 0:977e87915078 225 #if SN_COAP_BLOCKWISE_ENABLED || SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
vithyat 0:977e87915078 226 if (handle == NULL) {
vithyat 0:977e87915078 227 return -1;
vithyat 0:977e87915078 228 }
vithyat 0:977e87915078 229 switch (block_size) {
vithyat 0:977e87915078 230 case 0:
vithyat 0:977e87915078 231 case 16:
vithyat 0:977e87915078 232 case 32:
vithyat 0:977e87915078 233 case 64:
vithyat 0:977e87915078 234 case 128:
vithyat 0:977e87915078 235 case 256:
vithyat 0:977e87915078 236 case 512:
vithyat 0:977e87915078 237 case 1024:
vithyat 0:977e87915078 238 handle->sn_coap_block_data_size = block_size;
vithyat 0:977e87915078 239 return 0;
vithyat 0:977e87915078 240 default:
vithyat 0:977e87915078 241 break;
vithyat 0:977e87915078 242 }
vithyat 0:977e87915078 243 #endif
vithyat 0:977e87915078 244 return -1;
vithyat 0:977e87915078 245
vithyat 0:977e87915078 246 }
vithyat 0:977e87915078 247
vithyat 0:977e87915078 248 void sn_coap_protocol_clear_sent_blockwise_messages(struct coap_s *handle)
vithyat 0:977e87915078 249 {
vithyat 0:977e87915078 250 (void) handle;
vithyat 0:977e87915078 251 #if SN_COAP_BLOCKWISE_ENABLED || SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
vithyat 0:977e87915078 252 if (handle == NULL) {
vithyat 0:977e87915078 253 return;
vithyat 0:977e87915078 254 }
vithyat 0:977e87915078 255
vithyat 0:977e87915078 256 /* Loop all stored Blockwise messages in Linked list */
vithyat 0:977e87915078 257 ns_list_foreach_safe(coap_blockwise_msg_s, removed_blocwise_msg_ptr, &handle->linked_list_blockwise_sent_msgs) {
vithyat 0:977e87915078 258 sn_coap_protocol_linked_list_blockwise_msg_remove(handle, removed_blocwise_msg_ptr);
vithyat 0:977e87915078 259 }
vithyat 0:977e87915078 260 #endif
vithyat 0:977e87915078 261 }
vithyat 0:977e87915078 262
vithyat 0:977e87915078 263 void sn_coap_protocol_clear_received_blockwise_messages(struct coap_s *handle)
vithyat 0:977e87915078 264 {
vithyat 0:977e87915078 265 (void) handle;
vithyat 0:977e87915078 266 #if SN_COAP_BLOCKWISE_ENABLED || SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
vithyat 0:977e87915078 267 if (handle == NULL) {
vithyat 0:977e87915078 268 return;
vithyat 0:977e87915078 269 }
vithyat 0:977e87915078 270
vithyat 0:977e87915078 271 /* Loop all stored Blockwise messages in Linked list */
vithyat 0:977e87915078 272 ns_list_foreach_safe(coap_blockwise_payload_s, removed_blockwise_payload_ptr, &handle->linked_list_blockwise_received_payloads) {
vithyat 0:977e87915078 273 sn_coap_protocol_linked_list_blockwise_payload_remove(handle, removed_blockwise_payload_ptr);
vithyat 0:977e87915078 274 }
vithyat 0:977e87915078 275 #endif
vithyat 0:977e87915078 276 }
vithyat 0:977e87915078 277
vithyat 0:977e87915078 278 int8_t sn_coap_protocol_set_duplicate_buffer_size(struct coap_s *handle, uint8_t message_count)
vithyat 0:977e87915078 279 {
vithyat 0:977e87915078 280 (void) handle;
vithyat 0:977e87915078 281 (void) message_count;
vithyat 0:977e87915078 282 #if SN_COAP_DUPLICATION_MAX_MSGS_COUNT
vithyat 0:977e87915078 283 if (handle == NULL) {
vithyat 0:977e87915078 284 return -1;
vithyat 0:977e87915078 285 }
vithyat 0:977e87915078 286 if (message_count <= SN_COAP_MAX_ALLOWED_DUPLICATION_MESSAGE_COUNT) {
vithyat 0:977e87915078 287 handle->sn_coap_duplication_buffer_size = message_count;
vithyat 0:977e87915078 288 return 0;
vithyat 0:977e87915078 289 }
vithyat 0:977e87915078 290 #endif
vithyat 0:977e87915078 291 return -1;
vithyat 0:977e87915078 292 }
vithyat 0:977e87915078 293
vithyat 0:977e87915078 294 int8_t sn_coap_protocol_set_retransmission_parameters(struct coap_s *handle,
vithyat 0:977e87915078 295 uint8_t resending_count, uint8_t resending_intervall)
vithyat 0:977e87915078 296 {
vithyat 0:977e87915078 297 #if ENABLE_RESENDINGS
vithyat 0:977e87915078 298 if (handle == NULL) {
vithyat 0:977e87915078 299 return -1;
vithyat 0:977e87915078 300 }
vithyat 0:977e87915078 301 if (resending_count <= SN_COAP_MAX_ALLOWED_RESENDING_COUNT &&
vithyat 0:977e87915078 302 resending_intervall <= SN_COAP_MAX_ALLOWED_RESPONSE_TIMEOUT) {
vithyat 0:977e87915078 303 handle->sn_coap_resending_count = resending_count;
vithyat 0:977e87915078 304
vithyat 0:977e87915078 305 if (resending_intervall == 0) {
vithyat 0:977e87915078 306 handle->sn_coap_resending_intervall = 1;
vithyat 0:977e87915078 307 } else {
vithyat 0:977e87915078 308 handle->sn_coap_resending_intervall = resending_intervall;
vithyat 0:977e87915078 309 }
vithyat 0:977e87915078 310 return 0;
vithyat 0:977e87915078 311 }
vithyat 0:977e87915078 312 #endif
vithyat 0:977e87915078 313 return -1;
vithyat 0:977e87915078 314 }
vithyat 0:977e87915078 315
vithyat 0:977e87915078 316 int8_t sn_coap_protocol_set_retransmission_buffer(struct coap_s *handle,
vithyat 0:977e87915078 317 uint8_t buffer_size_messages, uint16_t buffer_size_bytes)
vithyat 0:977e87915078 318 {
vithyat 0:977e87915078 319 #if ENABLE_RESENDINGS
vithyat 0:977e87915078 320 if (handle == NULL) {
vithyat 0:977e87915078 321 return -1;
vithyat 0:977e87915078 322 }
vithyat 0:977e87915078 323 if (buffer_size_bytes <= SN_COAP_MAX_ALLOWED_RESENDING_BUFF_SIZE_BYTES &&
vithyat 0:977e87915078 324 buffer_size_messages <= SN_COAP_MAX_ALLOWED_RESENDING_BUFF_SIZE_MSGS ) {
vithyat 0:977e87915078 325 handle->sn_coap_resending_queue_bytes = buffer_size_bytes;
vithyat 0:977e87915078 326 handle->sn_coap_resending_queue_msgs = buffer_size_messages;
vithyat 0:977e87915078 327 return 0;
vithyat 0:977e87915078 328 }
vithyat 0:977e87915078 329
vithyat 0:977e87915078 330 #endif
vithyat 0:977e87915078 331 return -1;
vithyat 0:977e87915078 332
vithyat 0:977e87915078 333 }
vithyat 0:977e87915078 334
vithyat 0:977e87915078 335 void sn_coap_protocol_clear_retransmission_buffer(struct coap_s *handle)
vithyat 0:977e87915078 336 {
vithyat 0:977e87915078 337 #if ENABLE_RESENDINGS /* If Message resending is not used at all, this part of code will not be compiled */
vithyat 0:977e87915078 338 if (handle == NULL) {
vithyat 0:977e87915078 339 return;
vithyat 0:977e87915078 340 }
vithyat 0:977e87915078 341 ns_list_foreach_safe(coap_send_msg_s, tmp, &handle->linked_list_resent_msgs) {
vithyat 0:977e87915078 342 ns_list_remove(&handle->linked_list_resent_msgs, tmp);
vithyat 0:977e87915078 343 sn_coap_protocol_release_allocated_send_msg_mem(handle, tmp);
vithyat 0:977e87915078 344 --handle->count_resent_msgs;
vithyat 0:977e87915078 345 }
vithyat 0:977e87915078 346 #endif
vithyat 0:977e87915078 347 }
vithyat 0:977e87915078 348
vithyat 0:977e87915078 349 int8_t sn_coap_protocol_delete_retransmission(struct coap_s *handle, uint16_t msg_id)
vithyat 0:977e87915078 350 {
vithyat 0:977e87915078 351 #if ENABLE_RESENDINGS /* If Message resending is not used at all, this part of code will not be compiled */
vithyat 0:977e87915078 352 if (handle == NULL) {
vithyat 0:977e87915078 353 return -1;
vithyat 0:977e87915078 354 }
vithyat 0:977e87915078 355 ns_list_foreach_safe(coap_send_msg_s, tmp, &handle->linked_list_resent_msgs) {
vithyat 0:977e87915078 356 if (tmp->send_msg_ptr && tmp->send_msg_ptr->packet_ptr ) {
vithyat 0:977e87915078 357 uint16_t temp_msg_id = (tmp->send_msg_ptr->packet_ptr[2] << 8);
vithyat 0:977e87915078 358 temp_msg_id += (uint16_t)tmp->send_msg_ptr->packet_ptr[3];
vithyat 0:977e87915078 359 if(temp_msg_id == msg_id){
vithyat 0:977e87915078 360 ns_list_remove(&handle->linked_list_resent_msgs, tmp);
vithyat 0:977e87915078 361 --handle->count_resent_msgs;
vithyat 0:977e87915078 362 sn_coap_protocol_release_allocated_send_msg_mem(handle, tmp);
vithyat 0:977e87915078 363 return 0;
vithyat 0:977e87915078 364 }
vithyat 0:977e87915078 365 }
vithyat 0:977e87915078 366 }
vithyat 0:977e87915078 367 #endif
vithyat 0:977e87915078 368 return -2;
vithyat 0:977e87915078 369 }
vithyat 0:977e87915078 370
vithyat 0:977e87915078 371 int8_t sn_coap_protocol_delete_retransmission_by_token(struct coap_s *handle, uint8_t *token, uint8_t token_len)
vithyat 0:977e87915078 372 {
vithyat 0:977e87915078 373 #if ENABLE_RESENDINGS /* If Message resending is not used at all, this part of code will not be compiled */
vithyat 0:977e87915078 374 if (handle == NULL || token == NULL || token_len == 0) {
vithyat 0:977e87915078 375 tr_error("sn_coap_protocol_delete_retransmission_by_token NULL");
vithyat 0:977e87915078 376 return -1;
vithyat 0:977e87915078 377 }
vithyat 0:977e87915078 378
vithyat 0:977e87915078 379 ns_list_foreach(coap_send_msg_s, stored_msg, &handle->linked_list_resent_msgs) {
vithyat 0:977e87915078 380 uint8_t stored_token_len = (stored_msg->send_msg_ptr->packet_ptr[0] & 0x0F);
vithyat 0:977e87915078 381 if (stored_token_len == token_len) {
vithyat 0:977e87915078 382 uint8_t stored_token[8];
vithyat 0:977e87915078 383 memcpy(stored_token, &stored_msg->send_msg_ptr->packet_ptr[4], stored_token_len);
vithyat 0:977e87915078 384 if (memcmp(stored_token, token, stored_token_len) == 0) {
vithyat 0:977e87915078 385 uint16_t temp_msg_id = (stored_msg->send_msg_ptr->packet_ptr[2] << 8);
vithyat 0:977e87915078 386 temp_msg_id += (uint16_t)stored_msg->send_msg_ptr->packet_ptr[3];
vithyat 0:977e87915078 387 tr_debug("sn_coap_protocol_delete_retransmission_by_token - removed msg_id: %d", temp_msg_id);
vithyat 0:977e87915078 388 ns_list_remove(&handle->linked_list_resent_msgs, stored_msg);
vithyat 0:977e87915078 389 --handle->count_resent_msgs;
vithyat 0:977e87915078 390
vithyat 0:977e87915078 391 /* Free memory of stored message */
vithyat 0:977e87915078 392 sn_coap_protocol_release_allocated_send_msg_mem(handle, stored_msg);
vithyat 0:977e87915078 393 return 0;
vithyat 0:977e87915078 394 }
vithyat 0:977e87915078 395 }
vithyat 0:977e87915078 396 }
vithyat 0:977e87915078 397 #endif
vithyat 0:977e87915078 398 return -2;
vithyat 0:977e87915078 399 }
vithyat 0:977e87915078 400
vithyat 0:977e87915078 401
vithyat 0:977e87915078 402 int8_t prepare_blockwise_message(struct coap_s *handle, sn_coap_hdr_s *src_coap_msg_ptr)
vithyat 0:977e87915078 403 {
vithyat 0:977e87915078 404 (void) handle;
vithyat 0:977e87915078 405 (void) src_coap_msg_ptr;
vithyat 0:977e87915078 406
vithyat 0:977e87915078 407 #if SN_COAP_BLOCKWISE_ENABLED || SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwising is not enabled, this part of code will not be compiled */
vithyat 0:977e87915078 408 if ((src_coap_msg_ptr->payload_len > SN_COAP_MAX_NONBLOCKWISE_PAYLOAD_SIZE) &&
vithyat 0:977e87915078 409 (src_coap_msg_ptr->payload_len > handle->sn_coap_block_data_size) &&
vithyat 0:977e87915078 410 (handle->sn_coap_block_data_size > 0)) {
vithyat 0:977e87915078 411 /* * * * Add Blockwise option to send CoAP message * * */
vithyat 0:977e87915078 412
vithyat 0:977e87915078 413 /* Allocate memory for less used options */
vithyat 0:977e87915078 414 if (sn_coap_parser_alloc_options(handle, src_coap_msg_ptr) == NULL) {
vithyat 0:977e87915078 415 tr_error("prepare_blockwise_message - failed to allocate options!");
vithyat 0:977e87915078 416 return -2;
vithyat 0:977e87915078 417 }
vithyat 0:977e87915078 418
vithyat 0:977e87915078 419 /* Check if Request message */
vithyat 0:977e87915078 420 if (src_coap_msg_ptr->msg_code < COAP_MSG_CODE_RESPONSE_CREATED) {
vithyat 0:977e87915078 421 /* Add Blockwise option, use Block1 because Request payload */
vithyat 0:977e87915078 422 src_coap_msg_ptr->options_list_ptr->block1 = 0x08; /* First block (BLOCK NUMBER, 4 MSB bits) + More to come (MORE, 1 bit) */
vithyat 0:977e87915078 423 src_coap_msg_ptr->options_list_ptr->block1 |= sn_coap_convert_block_size(handle->sn_coap_block_data_size);
vithyat 0:977e87915078 424
vithyat 0:977e87915078 425 /* Add size1 parameter */
vithyat 0:977e87915078 426
vithyat 0:977e87915078 427 src_coap_msg_ptr->options_list_ptr->use_size1 = true;
vithyat 0:977e87915078 428 src_coap_msg_ptr->options_list_ptr->use_size2 = false;
vithyat 0:977e87915078 429 src_coap_msg_ptr->options_list_ptr->size1 = src_coap_msg_ptr->payload_len;
vithyat 0:977e87915078 430 } else { /* Response message */
vithyat 0:977e87915078 431 /* Add Blockwise option, use Block2 because Response payload */
vithyat 0:977e87915078 432 src_coap_msg_ptr->options_list_ptr->block2 = 0x08; /* First block (BLOCK NUMBER, 4 MSB bits) + More to come (MORE, 1 bit) */
vithyat 0:977e87915078 433 src_coap_msg_ptr->options_list_ptr->block2 |= sn_coap_convert_block_size(handle->sn_coap_block_data_size);
vithyat 0:977e87915078 434
vithyat 0:977e87915078 435 src_coap_msg_ptr->options_list_ptr->use_size1 = false;
vithyat 0:977e87915078 436 src_coap_msg_ptr->options_list_ptr->use_size2 = true;
vithyat 0:977e87915078 437 src_coap_msg_ptr->options_list_ptr->size2 = src_coap_msg_ptr->payload_len;
vithyat 0:977e87915078 438 }
vithyat 0:977e87915078 439 }
vithyat 0:977e87915078 440 #endif
vithyat 0:977e87915078 441 return 0;
vithyat 0:977e87915078 442 }
vithyat 0:977e87915078 443
vithyat 0:977e87915078 444
vithyat 0:977e87915078 445 int16_t sn_coap_protocol_build(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_ptr,
vithyat 0:977e87915078 446 uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_msg_ptr, void *param)
vithyat 0:977e87915078 447 {
vithyat 0:977e87915078 448 int16_t byte_count_built = 0;
vithyat 0:977e87915078 449 #if SN_COAP_BLOCKWISE_ENABLED || SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwising is not enabled, this part of code will not be compiled */
vithyat 0:977e87915078 450 uint16_t original_payload_len = 0;
vithyat 0:977e87915078 451 #endif
vithyat 0:977e87915078 452 /* * * * Check given pointers * * * */
vithyat 0:977e87915078 453 if ((dst_addr_ptr == NULL) || (dst_packet_data_ptr == NULL) || (src_coap_msg_ptr == NULL) || handle == NULL) {
vithyat 0:977e87915078 454 return -2;
vithyat 0:977e87915078 455 }
vithyat 0:977e87915078 456
vithyat 0:977e87915078 457 if (dst_addr_ptr->addr_ptr == NULL) {
vithyat 0:977e87915078 458 return -2;
vithyat 0:977e87915078 459 }
vithyat 0:977e87915078 460
vithyat 0:977e87915078 461 /* Check if built Message type is else than Acknowledgement or Reset i.e. message type is Confirmable or Non-confirmable */
vithyat 0:977e87915078 462 /* (for Acknowledgement and Reset messages is written same Message ID than was in the Request message) */
vithyat 0:977e87915078 463 if (src_coap_msg_ptr->msg_type != COAP_MSG_TYPE_ACKNOWLEDGEMENT &&
vithyat 0:977e87915078 464 src_coap_msg_ptr->msg_type != COAP_MSG_TYPE_RESET &&
vithyat 0:977e87915078 465 src_coap_msg_ptr->msg_id == 0) {
vithyat 0:977e87915078 466 /* * * * Generate new Message ID and increase it by one * * * */
vithyat 0:977e87915078 467 src_coap_msg_ptr->msg_id = message_id;
vithyat 0:977e87915078 468 message_id++;
vithyat 0:977e87915078 469 if (message_id == 0) {
vithyat 0:977e87915078 470 message_id = 1;
vithyat 0:977e87915078 471 }
vithyat 0:977e87915078 472 }
vithyat 0:977e87915078 473
vithyat 0:977e87915078 474 #if SN_COAP_BLOCKWISE_ENABLED || SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwising is not enabled, this part of code will not be compiled */
vithyat 0:977e87915078 475 /* If blockwising needed */
vithyat 0:977e87915078 476 if ((src_coap_msg_ptr->payload_len > SN_COAP_MAX_NONBLOCKWISE_PAYLOAD_SIZE) &&
vithyat 0:977e87915078 477 (src_coap_msg_ptr->payload_len > handle->sn_coap_block_data_size) &&
vithyat 0:977e87915078 478 (handle->sn_coap_block_data_size > 0)) {
vithyat 0:977e87915078 479 /* Store original Payload length */
vithyat 0:977e87915078 480 original_payload_len = src_coap_msg_ptr->payload_len;
vithyat 0:977e87915078 481 /* Change Payload length of send message because Payload is blockwised */
vithyat 0:977e87915078 482 src_coap_msg_ptr->payload_len = handle->sn_coap_block_data_size;
vithyat 0:977e87915078 483 }
vithyat 0:977e87915078 484 #endif
vithyat 0:977e87915078 485 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
vithyat 0:977e87915078 486 /* * * * Build Packet data from CoAP message by using CoAP Header builder * * * */
vithyat 0:977e87915078 487 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
vithyat 0:977e87915078 488
vithyat 0:977e87915078 489 byte_count_built = sn_coap_builder_2(dst_packet_data_ptr, src_coap_msg_ptr, handle->sn_coap_block_data_size);
vithyat 0:977e87915078 490
vithyat 0:977e87915078 491 if (byte_count_built < 0) {
vithyat 0:977e87915078 492 tr_error("sn_coap_protocol_build - failed to build message!");
vithyat 0:977e87915078 493 return byte_count_built;
vithyat 0:977e87915078 494 }
vithyat 0:977e87915078 495
vithyat 0:977e87915078 496 #if ENABLE_RESENDINGS /* If Message resending is not used at all, this part of code will not be compiled */
vithyat 0:977e87915078 497
vithyat 0:977e87915078 498 /* Check if built Message type was confirmable, only these messages are resent */
vithyat 0:977e87915078 499 if (src_coap_msg_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE) {
vithyat 0:977e87915078 500 /* Store message to Linked list for resending purposes */
vithyat 0:977e87915078 501 uint32_t resend_time = sn_coap_calculate_new_resend_time(handle->system_time, handle->sn_coap_resending_intervall, 0);
vithyat 0:977e87915078 502 if (sn_coap_protocol_linked_list_send_msg_store(handle, dst_addr_ptr, byte_count_built, dst_packet_data_ptr,
vithyat 0:977e87915078 503 resend_time,
vithyat 0:977e87915078 504 param) == 0) {
vithyat 0:977e87915078 505 return -4;
vithyat 0:977e87915078 506 }
vithyat 0:977e87915078 507 }
vithyat 0:977e87915078 508
vithyat 0:977e87915078 509 #endif /* ENABLE_RESENDINGS */
vithyat 0:977e87915078 510
vithyat 0:977e87915078 511 #if SN_COAP_DUPLICATION_MAX_MSGS_COUNT
vithyat 0:977e87915078 512
vithyat 0:977e87915078 513 // copy coap data buffer to duplicate list for resending purposes
vithyat 0:977e87915078 514 if (!sn_coap_protocol_update_duplicate_package_data(handle, dst_addr_ptr, src_coap_msg_ptr, byte_count_built, dst_packet_data_ptr)) {
vithyat 0:977e87915078 515 return -4;
vithyat 0:977e87915078 516 }
vithyat 0:977e87915078 517
vithyat 0:977e87915078 518 #endif
vithyat 0:977e87915078 519
vithyat 0:977e87915078 520 #if SN_COAP_BLOCKWISE_ENABLED || SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwising is not enabled, this part of code will not be compiled */
vithyat 0:977e87915078 521
vithyat 0:977e87915078 522 /* If blockwising needed */
vithyat 0:977e87915078 523 if ((original_payload_len > handle->sn_coap_block_data_size) && (handle->sn_coap_block_data_size > 0)) {
vithyat 0:977e87915078 524
vithyat 0:977e87915078 525 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
vithyat 0:977e87915078 526 /* * * * Manage rest blockwise messages sending by storing them to Linked list * * * */
vithyat 0:977e87915078 527 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
vithyat 0:977e87915078 528
vithyat 0:977e87915078 529 coap_blockwise_msg_s *stored_blockwise_msg_ptr;
vithyat 0:977e87915078 530
vithyat 0:977e87915078 531 stored_blockwise_msg_ptr = handle->sn_coap_protocol_malloc(sizeof(coap_blockwise_msg_s));
vithyat 0:977e87915078 532 if (!stored_blockwise_msg_ptr) {
vithyat 0:977e87915078 533 //block paylaod save failed, only first block can be build. Perhaps we should return error.
vithyat 0:977e87915078 534 tr_error("sn_coap_protocol_build - blockwise message allocation failed!");
vithyat 0:977e87915078 535 return byte_count_built;
vithyat 0:977e87915078 536 }
vithyat 0:977e87915078 537 memset(stored_blockwise_msg_ptr, 0, sizeof(coap_blockwise_msg_s));
vithyat 0:977e87915078 538
vithyat 0:977e87915078 539 /* Fill struct */
vithyat 0:977e87915078 540 stored_blockwise_msg_ptr->timestamp = handle->system_time;
vithyat 0:977e87915078 541
vithyat 0:977e87915078 542 stored_blockwise_msg_ptr->coap_msg_ptr = sn_coap_protocol_copy_header(handle, src_coap_msg_ptr);
vithyat 0:977e87915078 543 if( stored_blockwise_msg_ptr->coap_msg_ptr == NULL ){
vithyat 0:977e87915078 544 handle->sn_coap_protocol_free(stored_blockwise_msg_ptr);
vithyat 0:977e87915078 545 stored_blockwise_msg_ptr = 0;
vithyat 0:977e87915078 546 tr_error("sn_coap_protocol_build - block header copy failed!");
vithyat 0:977e87915078 547 return -2;
vithyat 0:977e87915078 548 }
vithyat 0:977e87915078 549
vithyat 0:977e87915078 550 stored_blockwise_msg_ptr->coap_msg_ptr->payload_len = original_payload_len;
vithyat 0:977e87915078 551 stored_blockwise_msg_ptr->coap_msg_ptr->payload_ptr = handle->sn_coap_protocol_malloc(stored_blockwise_msg_ptr->coap_msg_ptr->payload_len);
vithyat 0:977e87915078 552
vithyat 0:977e87915078 553 if (!stored_blockwise_msg_ptr->coap_msg_ptr->payload_ptr) {
vithyat 0:977e87915078 554 //block payload save failed, only first block can be build. Perhaps we should return error.
vithyat 0:977e87915078 555 sn_coap_parser_release_allocated_coap_msg_mem(handle, stored_blockwise_msg_ptr->coap_msg_ptr);
vithyat 0:977e87915078 556 handle->sn_coap_protocol_free(stored_blockwise_msg_ptr);
vithyat 0:977e87915078 557 stored_blockwise_msg_ptr = 0;
vithyat 0:977e87915078 558 tr_error("sn_coap_protocol_build - block payload allocation failed!");
vithyat 0:977e87915078 559 return byte_count_built;
vithyat 0:977e87915078 560 }
vithyat 0:977e87915078 561 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);
vithyat 0:977e87915078 562
vithyat 0:977e87915078 563 stored_blockwise_msg_ptr->coap = handle;
vithyat 0:977e87915078 564 stored_blockwise_msg_ptr->param = param;
vithyat 0:977e87915078 565 stored_blockwise_msg_ptr->msg_id = stored_blockwise_msg_ptr->coap_msg_ptr->msg_id;
vithyat 0:977e87915078 566 ns_list_add_to_end(&handle->linked_list_blockwise_sent_msgs, stored_blockwise_msg_ptr);
vithyat 0:977e87915078 567 } else if (src_coap_msg_ptr->msg_code <= COAP_MSG_CODE_REQUEST_DELETE &&
vithyat 0:977e87915078 568 src_coap_msg_ptr->msg_code != COAP_MSG_CODE_EMPTY) {
vithyat 0:977e87915078 569 /* Add message to linked list - response can be in blocks and we need header to build response.. */
vithyat 0:977e87915078 570 coap_blockwise_msg_s *stored_blockwise_msg_ptr;
vithyat 0:977e87915078 571
vithyat 0:977e87915078 572 stored_blockwise_msg_ptr = handle->sn_coap_protocol_malloc(sizeof(coap_blockwise_msg_s));
vithyat 0:977e87915078 573 if (!stored_blockwise_msg_ptr) {
vithyat 0:977e87915078 574 tr_error("sn_coap_protocol_build - blockwise (GET) allocation failed!");
vithyat 0:977e87915078 575 return byte_count_built;
vithyat 0:977e87915078 576 }
vithyat 0:977e87915078 577 memset(stored_blockwise_msg_ptr, 0, sizeof(coap_blockwise_msg_s));
vithyat 0:977e87915078 578
vithyat 0:977e87915078 579 /* Fill struct */
vithyat 0:977e87915078 580 stored_blockwise_msg_ptr->timestamp = handle->system_time;
vithyat 0:977e87915078 581
vithyat 0:977e87915078 582 stored_blockwise_msg_ptr->coap_msg_ptr = sn_coap_protocol_copy_header(handle, src_coap_msg_ptr);
vithyat 0:977e87915078 583 if( stored_blockwise_msg_ptr->coap_msg_ptr == NULL ){
vithyat 0:977e87915078 584 handle->sn_coap_protocol_free(stored_blockwise_msg_ptr);
vithyat 0:977e87915078 585 stored_blockwise_msg_ptr = 0;
vithyat 0:977e87915078 586 tr_error("sn_coap_protocol_build - blockwise (GET) copy header failed!");
vithyat 0:977e87915078 587 return -2;
vithyat 0:977e87915078 588 }
vithyat 0:977e87915078 589
vithyat 0:977e87915078 590 stored_blockwise_msg_ptr->coap = handle;
vithyat 0:977e87915078 591 stored_blockwise_msg_ptr->param = param;
vithyat 0:977e87915078 592 stored_blockwise_msg_ptr->msg_id = stored_blockwise_msg_ptr->coap_msg_ptr->msg_id;
vithyat 0:977e87915078 593 ns_list_add_to_end(&handle->linked_list_blockwise_sent_msgs, stored_blockwise_msg_ptr);
vithyat 0:977e87915078 594 }
vithyat 0:977e87915078 595
vithyat 0:977e87915078 596 #endif /* SN_COAP_BLOCKWISE_ENABLED || SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE */
vithyat 0:977e87915078 597
vithyat 0:977e87915078 598 /* * * * Return built CoAP message Packet data length * * * */
vithyat 0:977e87915078 599 return byte_count_built;
vithyat 0:977e87915078 600 }
vithyat 0:977e87915078 601
vithyat 0:977e87915078 602 sn_coap_hdr_s *sn_coap_protocol_parse(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr, uint16_t packet_data_len, uint8_t *packet_data_ptr, void *param)
vithyat 0:977e87915078 603 {
vithyat 0:977e87915078 604 sn_coap_hdr_s *returned_dst_coap_msg_ptr = NULL;
vithyat 0:977e87915078 605 coap_version_e coap_version = COAP_VERSION_UNKNOWN;
vithyat 0:977e87915078 606
vithyat 0:977e87915078 607 /* * * * Check given pointer * * * */
vithyat 0:977e87915078 608 if (src_addr_ptr == NULL || src_addr_ptr->addr_ptr == NULL ||
vithyat 0:977e87915078 609 packet_data_ptr == NULL || handle == NULL) {
vithyat 0:977e87915078 610 return NULL;
vithyat 0:977e87915078 611 }
vithyat 0:977e87915078 612
vithyat 0:977e87915078 613 /* * * * Parse Packet data to CoAP message by using CoAP Header parser * * * */
vithyat 0:977e87915078 614 returned_dst_coap_msg_ptr = sn_coap_parser(handle, packet_data_len, packet_data_ptr, &coap_version);
vithyat 0:977e87915078 615
vithyat 0:977e87915078 616 /* Check status of returned pointer */
vithyat 0:977e87915078 617 if (returned_dst_coap_msg_ptr == NULL) {
vithyat 0:977e87915078 618 /* Memory allocation error in parser */
vithyat 0:977e87915078 619 tr_error("sn_coap_protocol_parse - allocation fail in parser!");
vithyat 0:977e87915078 620 return NULL;
vithyat 0:977e87915078 621 }
vithyat 0:977e87915078 622 /* * * * Send bad request response if parsing fails * * * */
vithyat 0:977e87915078 623 if (returned_dst_coap_msg_ptr->coap_status == COAP_STATUS_PARSER_ERROR_IN_HEADER) {
vithyat 0:977e87915078 624 sn_coap_protocol_send_rst(handle, returned_dst_coap_msg_ptr->msg_id, src_addr_ptr, param);
vithyat 0:977e87915078 625 sn_coap_parser_release_allocated_coap_msg_mem(handle, returned_dst_coap_msg_ptr);
vithyat 0:977e87915078 626 tr_error("sn_coap_protocol_parse - COAP_STATUS_PARSER_ERROR_IN_HEADER");
vithyat 0:977e87915078 627 return NULL;
vithyat 0:977e87915078 628 }
vithyat 0:977e87915078 629
vithyat 0:977e87915078 630 /* * * * Check validity of parsed Header values * * * */
vithyat 0:977e87915078 631 if (sn_coap_header_validity_check(returned_dst_coap_msg_ptr, coap_version) != 0) {
vithyat 0:977e87915078 632 /* 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 */
vithyat 0:977e87915078 633 if (((returned_dst_coap_msg_ptr->msg_code >> 5) == 1) || // if class == 1
vithyat 0:977e87915078 634 ((returned_dst_coap_msg_ptr->msg_code >> 5) == 6) || // if class == 6
vithyat 0:977e87915078 635 ((returned_dst_coap_msg_ptr->msg_code >> 5) == 7)) { // if class == 7
vithyat 0:977e87915078 636 tr_error("sn_coap_protocol_parse - message code not valid!");
vithyat 0:977e87915078 637 sn_coap_protocol_send_rst(handle, returned_dst_coap_msg_ptr->msg_id, src_addr_ptr, param);
vithyat 0:977e87915078 638 }
vithyat 0:977e87915078 639
vithyat 0:977e87915078 640 /* Release memory of CoAP message */
vithyat 0:977e87915078 641 sn_coap_parser_release_allocated_coap_msg_mem(handle, returned_dst_coap_msg_ptr);
vithyat 0:977e87915078 642
vithyat 0:977e87915078 643 /* Return NULL because Header validity check failed */
vithyat 0:977e87915078 644 return NULL;
vithyat 0:977e87915078 645 }
vithyat 0:977e87915078 646
vithyat 0:977e87915078 647 /* Check if we need to send reset message */
vithyat 0:977e87915078 648 /* A recipient MUST acknowledge a Confirmable message with an Acknowledgement
vithyat 0:977e87915078 649 message or, if it lacks context to process the message properly
vithyat 0:977e87915078 650 (including the case where the message is Empty, uses a code with a
vithyat 0:977e87915078 651 reserved class (1, 6 or 7), or has a message format error), MUST
vithyat 0:977e87915078 652 reject it; rejecting a Confirmable message is effected by sending a
vithyat 0:977e87915078 653 matching Reset message and otherwise ignoring it. */
vithyat 0:977e87915078 654 if (returned_dst_coap_msg_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE) {
vithyat 0:977e87915078 655 /* CoAP ping */
vithyat 0:977e87915078 656 if (returned_dst_coap_msg_ptr->msg_code == COAP_MSG_CODE_EMPTY) {
vithyat 0:977e87915078 657 sn_coap_protocol_send_rst(handle, returned_dst_coap_msg_ptr->msg_id, src_addr_ptr, param);
vithyat 0:977e87915078 658
vithyat 0:977e87915078 659 /* Release memory of CoAP message */
vithyat 0:977e87915078 660 sn_coap_parser_release_allocated_coap_msg_mem(handle, returned_dst_coap_msg_ptr);
vithyat 0:977e87915078 661
vithyat 0:977e87915078 662 /* Return NULL because Header validity check failed */
vithyat 0:977e87915078 663 return NULL;
vithyat 0:977e87915078 664 }
vithyat 0:977e87915078 665 }
vithyat 0:977e87915078 666
vithyat 0:977e87915078 667
vithyat 0:977e87915078 668 #if !SN_COAP_BLOCKWISE_ENABLED && !SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwising is enabled, this part of code will not be compiled */
vithyat 0:977e87915078 669 /* If blockwising used in received message */
vithyat 0:977e87915078 670 if (returned_dst_coap_msg_ptr->options_list_ptr != NULL &&
vithyat 0:977e87915078 671 (returned_dst_coap_msg_ptr->options_list_ptr->block1 != COAP_OPTION_BLOCK_NONE ||
vithyat 0:977e87915078 672 returned_dst_coap_msg_ptr->options_list_ptr->block2 != COAP_OPTION_BLOCK_NONE)) {
vithyat 0:977e87915078 673 /* Set returned status to User */
vithyat 0:977e87915078 674 returned_dst_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_BLOCKWISE_MSG_REJECTED;
vithyat 0:977e87915078 675 tr_error("sn_coap_protocol_parse - COAP_STATUS_PARSER_BLOCKWISE_MSG_REJECTED!");
vithyat 0:977e87915078 676 //todo: send response -> not implemented
vithyat 0:977e87915078 677 return returned_dst_coap_msg_ptr;
vithyat 0:977e87915078 678 }
vithyat 0:977e87915078 679 #endif /* !SN_COAP_BLOCKWISE_ENABLED && !SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE */
vithyat 0:977e87915078 680
vithyat 0:977e87915078 681 #if SN_COAP_DUPLICATION_MAX_MSGS_COUNT/* If Message duplication is used, this part of code will not be compiled */
vithyat 0:977e87915078 682
vithyat 0:977e87915078 683 /* * * * Manage received CoAP message duplicate detection * * * */
vithyat 0:977e87915078 684
vithyat 0:977e87915078 685 /* If no message duplication detected */
vithyat 0:977e87915078 686 if ((returned_dst_coap_msg_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE ||
vithyat 0:977e87915078 687 returned_dst_coap_msg_ptr->msg_type == COAP_MSG_TYPE_NON_CONFIRMABLE) &&
vithyat 0:977e87915078 688 handle->sn_coap_duplication_buffer_size != 0) {
vithyat 0:977e87915078 689 if (sn_coap_protocol_linked_list_duplication_info_search(handle, src_addr_ptr, returned_dst_coap_msg_ptr->msg_id) == NULL) {
vithyat 0:977e87915078 690 /* * * No Message duplication: Store received message for detecting later duplication * * */
vithyat 0:977e87915078 691
vithyat 0:977e87915078 692 /* Get count of stored duplication messages */
vithyat 0:977e87915078 693 uint16_t stored_duplication_msgs_count = handle->count_duplication_msgs;
vithyat 0:977e87915078 694
vithyat 0:977e87915078 695 /* Check if there is no room to store message for duplication detection purposes */
vithyat 0:977e87915078 696 if (stored_duplication_msgs_count >= handle->sn_coap_duplication_buffer_size) {
vithyat 0:977e87915078 697 tr_debug("sn_coap_protocol_parse - duplicate list full, dropping oldest");
vithyat 0:977e87915078 698
vithyat 0:977e87915078 699 /* Get oldest stored duplication message */
vithyat 0:977e87915078 700 coap_duplication_info_s *stored_duplication_info_ptr = ns_list_get_first(&handle->linked_list_duplication_msgs);
vithyat 0:977e87915078 701
vithyat 0:977e87915078 702 /* Remove oldest stored duplication message for getting room for new duplication message */
vithyat 0:977e87915078 703 sn_coap_protocol_linked_list_duplication_info_remove(handle,
vithyat 0:977e87915078 704 stored_duplication_info_ptr->address->addr_ptr,
vithyat 0:977e87915078 705 stored_duplication_info_ptr->address->port,
vithyat 0:977e87915078 706 stored_duplication_info_ptr->msg_id);
vithyat 0:977e87915078 707 }
vithyat 0:977e87915078 708
vithyat 0:977e87915078 709 /* Store Duplication info to Linked list */
vithyat 0:977e87915078 710 sn_coap_protocol_linked_list_duplication_info_store(handle, src_addr_ptr, returned_dst_coap_msg_ptr->msg_id, param);
vithyat 0:977e87915078 711 } else { /* * * Message duplication detected * * */
vithyat 0:977e87915078 712 /* Set returned status to User */
vithyat 0:977e87915078 713 returned_dst_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_DUPLICATED_MSG;
vithyat 0:977e87915078 714 coap_duplication_info_s* response = sn_coap_protocol_linked_list_duplication_info_search(handle,
vithyat 0:977e87915078 715 src_addr_ptr,
vithyat 0:977e87915078 716 returned_dst_coap_msg_ptr->msg_id);
vithyat 0:977e87915078 717 /* Send ACK response */
vithyat 0:977e87915078 718 if (response) {
vithyat 0:977e87915078 719 /* Check that response has been created */
vithyat 0:977e87915078 720 if (response->packet_ptr) {
vithyat 0:977e87915078 721 tr_debug("sn_coap_protocol_parse - send ack for duplicate message");
vithyat 0:977e87915078 722 response->coap->sn_coap_tx_callback(response->packet_ptr,
vithyat 0:977e87915078 723 response->packet_len, response->address, response->param);
vithyat 0:977e87915078 724 }
vithyat 0:977e87915078 725 }
vithyat 0:977e87915078 726
vithyat 0:977e87915078 727 return returned_dst_coap_msg_ptr;
vithyat 0:977e87915078 728 }
vithyat 0:977e87915078 729 }
vithyat 0:977e87915078 730 #endif
vithyat 0:977e87915078 731
vithyat 0:977e87915078 732 /*** And here we check if message was block message ***/
vithyat 0:977e87915078 733 /*** If so, we call own block handling function and ***/
vithyat 0:977e87915078 734 /*** return to caller. ***/
vithyat 0:977e87915078 735 #if SN_COAP_BLOCKWISE_ENABLED || SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
vithyat 0:977e87915078 736
vithyat 0:977e87915078 737 if (returned_dst_coap_msg_ptr->options_list_ptr != NULL &&
vithyat 0:977e87915078 738 (returned_dst_coap_msg_ptr->options_list_ptr->block1 != COAP_OPTION_BLOCK_NONE ||
vithyat 0:977e87915078 739 returned_dst_coap_msg_ptr->options_list_ptr->block2 != COAP_OPTION_BLOCK_NONE)) {
vithyat 0:977e87915078 740 returned_dst_coap_msg_ptr = sn_coap_handle_blockwise_message(handle, src_addr_ptr, returned_dst_coap_msg_ptr, param);
vithyat 0:977e87915078 741 } else if (returned_dst_coap_msg_ptr->msg_code != COAP_MSG_CODE_EMPTY) {
vithyat 0:977e87915078 742 // Do not clean stored blockwise message when empty ack is received.
vithyat 0:977e87915078 743 // Stored message is mandatory when building a next (GET) blockwise message.
vithyat 0:977e87915078 744 // This will happen when non piggybacked response mode is selected.
vithyat 0:977e87915078 745 /* Get ... */
vithyat 0:977e87915078 746 coap_blockwise_msg_s *stored_blockwise_msg_temp_ptr = NULL;
vithyat 0:977e87915078 747
vithyat 0:977e87915078 748 ns_list_foreach(coap_blockwise_msg_s, msg, &handle->linked_list_blockwise_sent_msgs) {
vithyat 0:977e87915078 749 if (returned_dst_coap_msg_ptr->msg_id == msg->coap_msg_ptr->msg_id) {
vithyat 0:977e87915078 750 stored_blockwise_msg_temp_ptr = msg;
vithyat 0:977e87915078 751 break;
vithyat 0:977e87915078 752 }
vithyat 0:977e87915078 753 }
vithyat 0:977e87915078 754 /* Remove from the list if not an notification message.
vithyat 0:977e87915078 755 * Initial notification message is needed for sending rest of the blocks (GET request).
vithyat 0:977e87915078 756 */
vithyat 0:977e87915078 757 bool remove_from_the_list = false;
vithyat 0:977e87915078 758 if (stored_blockwise_msg_temp_ptr) {
vithyat 0:977e87915078 759 if (stored_blockwise_msg_temp_ptr->coap_msg_ptr &&
vithyat 0:977e87915078 760 stored_blockwise_msg_temp_ptr->coap_msg_ptr->options_list_ptr &&
vithyat 0:977e87915078 761 stored_blockwise_msg_temp_ptr->coap_msg_ptr->options_list_ptr->observe != COAP_OBSERVE_NONE) {
vithyat 0:977e87915078 762 remove_from_the_list = false;
vithyat 0:977e87915078 763 } else {
vithyat 0:977e87915078 764 remove_from_the_list = true;
vithyat 0:977e87915078 765 }
vithyat 0:977e87915078 766 }
vithyat 0:977e87915078 767 if (remove_from_the_list) {
vithyat 0:977e87915078 768 ns_list_remove(&handle->linked_list_blockwise_sent_msgs, stored_blockwise_msg_temp_ptr);
vithyat 0:977e87915078 769 if (stored_blockwise_msg_temp_ptr->coap_msg_ptr) {
vithyat 0:977e87915078 770 if(stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_ptr){
vithyat 0:977e87915078 771 handle->sn_coap_protocol_free(stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_ptr);
vithyat 0:977e87915078 772 stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_ptr = 0;
vithyat 0:977e87915078 773 }
vithyat 0:977e87915078 774 sn_coap_parser_release_allocated_coap_msg_mem(stored_blockwise_msg_temp_ptr->coap, stored_blockwise_msg_temp_ptr->coap_msg_ptr);
vithyat 0:977e87915078 775 }
vithyat 0:977e87915078 776
vithyat 0:977e87915078 777 handle->sn_coap_protocol_free(stored_blockwise_msg_temp_ptr);
vithyat 0:977e87915078 778 stored_blockwise_msg_temp_ptr = 0;
vithyat 0:977e87915078 779 }
vithyat 0:977e87915078 780 }
vithyat 0:977e87915078 781
vithyat 0:977e87915078 782 if (!returned_dst_coap_msg_ptr) {
vithyat 0:977e87915078 783 tr_error("sn_coap_protocol_parse - returned_dst_coap_msg_ptr null!");
vithyat 0:977e87915078 784 return NULL;
vithyat 0:977e87915078 785 }
vithyat 0:977e87915078 786
vithyat 0:977e87915078 787 #endif
vithyat 0:977e87915078 788
vithyat 0:977e87915078 789
vithyat 0:977e87915078 790 #if ENABLE_RESENDINGS /* If Message resending is not used at all, this part of code will not be compiled */
vithyat 0:977e87915078 791
vithyat 0:977e87915078 792 /* Check if received Message type was acknowledgement */
vithyat 0:977e87915078 793 if ((returned_dst_coap_msg_ptr->msg_type == COAP_MSG_TYPE_ACKNOWLEDGEMENT) || (returned_dst_coap_msg_ptr->msg_type == COAP_MSG_TYPE_RESET)) {
vithyat 0:977e87915078 794 /* * * * Manage CoAP message resending by removing active resending message from Linked list * * */
vithyat 0:977e87915078 795
vithyat 0:977e87915078 796 /* Get node count i.e. count of active resending messages */
vithyat 0:977e87915078 797 uint16_t stored_resending_msgs_count = handle->count_resent_msgs;
vithyat 0:977e87915078 798
vithyat 0:977e87915078 799 /* Check if there is ongoing active message resendings */
vithyat 0:977e87915078 800 if (stored_resending_msgs_count > 0) {
vithyat 0:977e87915078 801 sn_nsdl_transmit_s *removed_msg_ptr = NULL;
vithyat 0:977e87915078 802
vithyat 0:977e87915078 803 /* Check if received message was confirmation for some active resending message */
vithyat 0:977e87915078 804 removed_msg_ptr = sn_coap_protocol_linked_list_send_msg_search(handle, src_addr_ptr, returned_dst_coap_msg_ptr->msg_id);
vithyat 0:977e87915078 805
vithyat 0:977e87915078 806 if (removed_msg_ptr != NULL) {
vithyat 0:977e87915078 807 /* Remove resending message from active message resending Linked list */
vithyat 0:977e87915078 808 sn_coap_protocol_linked_list_send_msg_remove(handle, src_addr_ptr, returned_dst_coap_msg_ptr->msg_id);
vithyat 0:977e87915078 809 }
vithyat 0:977e87915078 810 }
vithyat 0:977e87915078 811 }
vithyat 0:977e87915078 812 #endif /* ENABLE_RESENDINGS */
vithyat 0:977e87915078 813
vithyat 0:977e87915078 814 /* * * * Return parsed CoAP message * * * */
vithyat 0:977e87915078 815 return returned_dst_coap_msg_ptr;
vithyat 0:977e87915078 816 }
vithyat 0:977e87915078 817
vithyat 0:977e87915078 818
vithyat 0:977e87915078 819 int8_t sn_coap_protocol_exec(struct coap_s *handle, uint32_t current_time)
vithyat 0:977e87915078 820 {
vithyat 0:977e87915078 821 if( !handle ){
vithyat 0:977e87915078 822 return -1;
vithyat 0:977e87915078 823 }
vithyat 0:977e87915078 824
vithyat 0:977e87915078 825 /* * * * Store current System time * * * */
vithyat 0:977e87915078 826 handle->system_time = current_time;
vithyat 0:977e87915078 827
vithyat 0:977e87915078 828 #if SN_COAP_BLOCKWISE_ENABLED || SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
vithyat 0:977e87915078 829 /* * * * Handle block transfer timed outs * * * */
vithyat 0:977e87915078 830 sn_coap_protocol_handle_blockwise_timout(handle);
vithyat 0:977e87915078 831 #endif
vithyat 0:977e87915078 832
vithyat 0:977e87915078 833 #if SN_COAP_DUPLICATION_MAX_MSGS_COUNT
vithyat 0:977e87915078 834 /* * * * Remove old duplication messages * * * */
vithyat 0:977e87915078 835 sn_coap_protocol_linked_list_duplication_info_remove_old_ones(handle);
vithyat 0:977e87915078 836 #endif
vithyat 0:977e87915078 837
vithyat 0:977e87915078 838 #if ENABLE_RESENDINGS
vithyat 0:977e87915078 839 /* Check if there is ongoing active message sendings */
vithyat 0:977e87915078 840 /* foreach_safe isn't sufficient because callback routine could cancel messages. */
vithyat 0:977e87915078 841 rescan:
vithyat 0:977e87915078 842 ns_list_foreach(coap_send_msg_s, stored_msg_ptr, &handle->linked_list_resent_msgs) {
vithyat 0:977e87915078 843 // First check that msg belongs to handle
vithyat 0:977e87915078 844 if( stored_msg_ptr->coap == handle ){
vithyat 0:977e87915078 845 /* Check if it is time to send this message */
vithyat 0:977e87915078 846 if (current_time >= stored_msg_ptr->resending_time) {
vithyat 0:977e87915078 847 /* * * Increase Resending counter * * */
vithyat 0:977e87915078 848 stored_msg_ptr->resending_counter++;
vithyat 0:977e87915078 849
vithyat 0:977e87915078 850 /* Check if all re-sendings have been done */
vithyat 0:977e87915078 851 if (stored_msg_ptr->resending_counter > handle->sn_coap_resending_count) {
vithyat 0:977e87915078 852 coap_version_e coap_version = COAP_VERSION_UNKNOWN;
vithyat 0:977e87915078 853
vithyat 0:977e87915078 854 /* Get message ID from stored sending message */
vithyat 0:977e87915078 855 uint16_t temp_msg_id = (stored_msg_ptr->send_msg_ptr->packet_ptr[2] << 8);
vithyat 0:977e87915078 856 temp_msg_id += (uint16_t)stored_msg_ptr->send_msg_ptr->packet_ptr[3];
vithyat 0:977e87915078 857
vithyat 0:977e87915078 858 /* Remove message from Linked list */
vithyat 0:977e87915078 859 ns_list_remove(&handle->linked_list_resent_msgs, stored_msg_ptr);
vithyat 0:977e87915078 860 --handle->count_resent_msgs;
vithyat 0:977e87915078 861
vithyat 0:977e87915078 862 /* If RX callback have been defined.. */
vithyat 0:977e87915078 863 if (stored_msg_ptr->coap->sn_coap_rx_callback != 0) {
vithyat 0:977e87915078 864 sn_coap_hdr_s *tmp_coap_hdr_ptr;
vithyat 0:977e87915078 865 /* Parse CoAP message, set status and call RX callback */
vithyat 0:977e87915078 866 tmp_coap_hdr_ptr = sn_coap_parser(stored_msg_ptr->coap, stored_msg_ptr->send_msg_ptr->packet_len, stored_msg_ptr->send_msg_ptr->packet_ptr, &coap_version);
vithyat 0:977e87915078 867
vithyat 0:977e87915078 868 if (tmp_coap_hdr_ptr != 0) {
vithyat 0:977e87915078 869 tmp_coap_hdr_ptr->coap_status = COAP_STATUS_BUILDER_MESSAGE_SENDING_FAILED;
vithyat 0:977e87915078 870 stored_msg_ptr->coap->sn_coap_rx_callback(tmp_coap_hdr_ptr, stored_msg_ptr->send_msg_ptr->dst_addr_ptr, stored_msg_ptr->param);
vithyat 0:977e87915078 871
vithyat 0:977e87915078 872 sn_coap_parser_release_allocated_coap_msg_mem(stored_msg_ptr->coap, tmp_coap_hdr_ptr);
vithyat 0:977e87915078 873 }
vithyat 0:977e87915078 874 }
vithyat 0:977e87915078 875
vithyat 0:977e87915078 876 /* Free memory of stored message */
vithyat 0:977e87915078 877 sn_coap_protocol_release_allocated_send_msg_mem(handle, stored_msg_ptr);
vithyat 0:977e87915078 878 } else {
vithyat 0:977e87915078 879 /* Send message */
vithyat 0:977e87915078 880 stored_msg_ptr->coap->sn_coap_tx_callback(stored_msg_ptr->send_msg_ptr->packet_ptr,
vithyat 0:977e87915078 881 stored_msg_ptr->send_msg_ptr->packet_len, stored_msg_ptr->send_msg_ptr->dst_addr_ptr, stored_msg_ptr->param);
vithyat 0:977e87915078 882
vithyat 0:977e87915078 883 /* * * Count new Resending time * * */
vithyat 0:977e87915078 884 stored_msg_ptr->resending_time = sn_coap_calculate_new_resend_time(current_time,
vithyat 0:977e87915078 885 handle->sn_coap_resending_intervall,
vithyat 0:977e87915078 886 stored_msg_ptr->resending_counter);
vithyat 0:977e87915078 887 }
vithyat 0:977e87915078 888 /* Callback routine could have wiped the list (eg as a response to sending failed) */
vithyat 0:977e87915078 889 /* Be super cautious and rescan from the start */
vithyat 0:977e87915078 890 goto rescan;
vithyat 0:977e87915078 891 }
vithyat 0:977e87915078 892 }
vithyat 0:977e87915078 893 }
vithyat 0:977e87915078 894
vithyat 0:977e87915078 895 #endif /* ENABLE_RESENDINGS */
vithyat 0:977e87915078 896
vithyat 0:977e87915078 897 return 0;
vithyat 0:977e87915078 898 }
vithyat 0:977e87915078 899
vithyat 0:977e87915078 900 #if ENABLE_RESENDINGS /* If Message resending is not used at all, this part of code will not be compiled */
vithyat 0:977e87915078 901
vithyat 0:977e87915078 902 /**************************************************************************//**
vithyat 0:977e87915078 903 * \fn static uint8_t sn_coap_protocol_linked_list_send_msg_store(sn_nsdl_addr_s *dst_addr_ptr, uint16_t send_packet_data_len, uint8_t *send_packet_data_ptr, uint32_t sending_time)
vithyat 0:977e87915078 904 *
vithyat 0:977e87915078 905 * \brief Stores message to Linked list for sending purposes.
vithyat 0:977e87915078 906
vithyat 0:977e87915078 907 * \param *dst_addr_ptr is pointer to destination address where CoAP message will be sent
vithyat 0:977e87915078 908 *
vithyat 0:977e87915078 909 * \param send_packet_data_len is length of Packet data to be stored
vithyat 0:977e87915078 910 *
vithyat 0:977e87915078 911 * \param *send_packet_data_ptr is Packet data to be stored
vithyat 0:977e87915078 912 *
vithyat 0:977e87915078 913 * \param sending_time is stored sending time
vithyat 0:977e87915078 914 *
vithyat 0:977e87915078 915 * \return 0 Allocation or buffer limit reached
vithyat 0:977e87915078 916 *
vithyat 0:977e87915078 917 * \return 1 Msg stored properly
vithyat 0:977e87915078 918 *****************************************************************************/
vithyat 0:977e87915078 919
vithyat 0:977e87915078 920 static uint8_t sn_coap_protocol_linked_list_send_msg_store(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_ptr, uint16_t send_packet_data_len,
vithyat 0:977e87915078 921 uint8_t *send_packet_data_ptr, uint32_t sending_time, void *param)
vithyat 0:977e87915078 922 {
vithyat 0:977e87915078 923
vithyat 0:977e87915078 924 coap_send_msg_s *stored_msg_ptr = NULL;
vithyat 0:977e87915078 925
vithyat 0:977e87915078 926 /* If both queue parameters are "0" or resending count is "0", then re-sending is disabled */
vithyat 0:977e87915078 927 if (((handle->sn_coap_resending_queue_msgs == 0) && (handle->sn_coap_resending_queue_bytes == 0)) || (handle->sn_coap_resending_count == 0)) {
vithyat 0:977e87915078 928 return 1;
vithyat 0:977e87915078 929 }
vithyat 0:977e87915078 930
vithyat 0:977e87915078 931 if (handle->sn_coap_resending_queue_msgs > 0) {
vithyat 0:977e87915078 932 if (handle->count_resent_msgs >= handle->sn_coap_resending_queue_msgs) {
vithyat 0:977e87915078 933 tr_error("sn_coap_protocol_linked_list_send_msg_store - resend queue full!");
vithyat 0:977e87915078 934 return 0;
vithyat 0:977e87915078 935 }
vithyat 0:977e87915078 936 }
vithyat 0:977e87915078 937
vithyat 0:977e87915078 938 /* Count resending queue size, if buffer size is defined */
vithyat 0:977e87915078 939 if (handle->sn_coap_resending_queue_bytes > 0) {
vithyat 0:977e87915078 940 if ((sn_coap_count_linked_list_size(&handle->linked_list_resent_msgs) + send_packet_data_len) > handle->sn_coap_resending_queue_bytes) {
vithyat 0:977e87915078 941 tr_error("sn_coap_protocol_linked_list_send_msg_store - resend buffer size reached!");
vithyat 0:977e87915078 942 return 0;
vithyat 0:977e87915078 943 }
vithyat 0:977e87915078 944 }
vithyat 0:977e87915078 945
vithyat 0:977e87915078 946 /* Allocating memory for stored message */
vithyat 0:977e87915078 947 stored_msg_ptr = sn_coap_protocol_allocate_mem_for_msg(handle, dst_addr_ptr, send_packet_data_len);
vithyat 0:977e87915078 948
vithyat 0:977e87915078 949 if (stored_msg_ptr == 0) {
vithyat 0:977e87915078 950 tr_error("sn_coap_protocol_linked_list_send_msg_store - failed to allocate message!");
vithyat 0:977e87915078 951 return 0;
vithyat 0:977e87915078 952 }
vithyat 0:977e87915078 953
vithyat 0:977e87915078 954 /* Filling of coap_send_msg_s with initialization values */
vithyat 0:977e87915078 955 stored_msg_ptr->resending_counter = 0;
vithyat 0:977e87915078 956 stored_msg_ptr->resending_time = sending_time;
vithyat 0:977e87915078 957
vithyat 0:977e87915078 958 /* Filling of sn_nsdl_transmit_s */
vithyat 0:977e87915078 959 stored_msg_ptr->send_msg_ptr->protocol = SN_NSDL_PROTOCOL_COAP;
vithyat 0:977e87915078 960 stored_msg_ptr->send_msg_ptr->packet_len = send_packet_data_len;
vithyat 0:977e87915078 961 memcpy(stored_msg_ptr->send_msg_ptr->packet_ptr, send_packet_data_ptr, send_packet_data_len);
vithyat 0:977e87915078 962
vithyat 0:977e87915078 963 /* Filling of sn_nsdl_addr_s */
vithyat 0:977e87915078 964 stored_msg_ptr->send_msg_ptr->dst_addr_ptr->type = dst_addr_ptr->type;
vithyat 0:977e87915078 965 stored_msg_ptr->send_msg_ptr->dst_addr_ptr->addr_len = dst_addr_ptr->addr_len;
vithyat 0:977e87915078 966 memcpy(stored_msg_ptr->send_msg_ptr->dst_addr_ptr->addr_ptr, dst_addr_ptr->addr_ptr, dst_addr_ptr->addr_len);
vithyat 0:977e87915078 967 stored_msg_ptr->send_msg_ptr->dst_addr_ptr->port = dst_addr_ptr->port;
vithyat 0:977e87915078 968
vithyat 0:977e87915078 969 stored_msg_ptr->coap = handle;
vithyat 0:977e87915078 970 stored_msg_ptr->param = param;
vithyat 0:977e87915078 971
vithyat 0:977e87915078 972 /* Storing Resending message to Linked list */
vithyat 0:977e87915078 973 ns_list_add_to_end(&handle->linked_list_resent_msgs, stored_msg_ptr);
vithyat 0:977e87915078 974 ++handle->count_resent_msgs;
vithyat 0:977e87915078 975 return 1;
vithyat 0:977e87915078 976 }
vithyat 0:977e87915078 977
vithyat 0:977e87915078 978 /**************************************************************************//**
vithyat 0:977e87915078 979 * \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)
vithyat 0:977e87915078 980 *
vithyat 0:977e87915078 981 * \brief Searches stored resending message from Linked list
vithyat 0:977e87915078 982 *
vithyat 0:977e87915078 983 * \param *src_addr_ptr is searching key for searched message
vithyat 0:977e87915078 984 *
vithyat 0:977e87915078 985 * \param msg_id is searching key for searched message
vithyat 0:977e87915078 986 *
vithyat 0:977e87915078 987 * \return Return value is pointer to found stored resending message in Linked
vithyat 0:977e87915078 988 * list or NULL if message not found
vithyat 0:977e87915078 989 *****************************************************************************/
vithyat 0:977e87915078 990
vithyat 0:977e87915078 991 static sn_nsdl_transmit_s *sn_coap_protocol_linked_list_send_msg_search(struct coap_s *handle,
vithyat 0:977e87915078 992 sn_nsdl_addr_s *src_addr_ptr, uint16_t msg_id)
vithyat 0:977e87915078 993 {
vithyat 0:977e87915078 994 /* Loop all stored resending messages Linked list */
vithyat 0:977e87915078 995 ns_list_foreach(coap_send_msg_s, stored_msg_ptr, &handle->linked_list_resent_msgs) {
vithyat 0:977e87915078 996 /* Get message ID from stored resending message */
vithyat 0:977e87915078 997 uint16_t temp_msg_id = (stored_msg_ptr->send_msg_ptr->packet_ptr[2] << 8);
vithyat 0:977e87915078 998 temp_msg_id += (uint16_t)stored_msg_ptr->send_msg_ptr->packet_ptr[3];
vithyat 0:977e87915078 999
vithyat 0:977e87915078 1000 /* If message's Message ID is same than is searched */
vithyat 0:977e87915078 1001 if (temp_msg_id == msg_id) {
vithyat 0:977e87915078 1002 /* If message's Source address is same than is searched */
vithyat 0:977e87915078 1003 if (0 == memcmp(src_addr_ptr->addr_ptr, stored_msg_ptr->send_msg_ptr->dst_addr_ptr->addr_ptr, src_addr_ptr->addr_len)) {
vithyat 0:977e87915078 1004 /* If message's Source address port is same than is searched */
vithyat 0:977e87915078 1005 if (stored_msg_ptr->send_msg_ptr->dst_addr_ptr->port == src_addr_ptr->port) {
vithyat 0:977e87915078 1006 /* * * Message found, return pointer to that stored resending message * * * */
vithyat 0:977e87915078 1007 return stored_msg_ptr->send_msg_ptr;
vithyat 0:977e87915078 1008 }
vithyat 0:977e87915078 1009 }
vithyat 0:977e87915078 1010 }
vithyat 0:977e87915078 1011 }
vithyat 0:977e87915078 1012
vithyat 0:977e87915078 1013 /* Message not found */
vithyat 0:977e87915078 1014 return NULL;
vithyat 0:977e87915078 1015 }
vithyat 0:977e87915078 1016 /**************************************************************************//**
vithyat 0:977e87915078 1017 * \fn static void sn_coap_protocol_linked_list_send_msg_remove(sn_nsdl_addr_s *src_addr_ptr, uint16_t msg_id)
vithyat 0:977e87915078 1018 *
vithyat 0:977e87915078 1019 * \brief Removes stored resending message from Linked list
vithyat 0:977e87915078 1020 *
vithyat 0:977e87915078 1021 * \param *src_addr_ptr is searching key for searched message
vithyat 0:977e87915078 1022 * \param msg_id is searching key for removed message
vithyat 0:977e87915078 1023 *****************************************************************************/
vithyat 0:977e87915078 1024
vithyat 0:977e87915078 1025 static void sn_coap_protocol_linked_list_send_msg_remove(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr, uint16_t msg_id)
vithyat 0:977e87915078 1026 {
vithyat 0:977e87915078 1027 /* Loop all stored resending messages in Linked list */
vithyat 0:977e87915078 1028 ns_list_foreach(coap_send_msg_s, stored_msg_ptr, &handle->linked_list_resent_msgs) {
vithyat 0:977e87915078 1029 /* Get message ID from stored resending message */
vithyat 0:977e87915078 1030 uint16_t temp_msg_id = (stored_msg_ptr->send_msg_ptr->packet_ptr[2] << 8);
vithyat 0:977e87915078 1031 temp_msg_id += (uint16_t)stored_msg_ptr->send_msg_ptr->packet_ptr[3];
vithyat 0:977e87915078 1032
vithyat 0:977e87915078 1033 /* If message's Message ID is same than is searched */
vithyat 0:977e87915078 1034 if (temp_msg_id == msg_id) {
vithyat 0:977e87915078 1035 /* If message's Source address is same than is searched */
vithyat 0:977e87915078 1036 if (0 == memcmp(src_addr_ptr->addr_ptr, stored_msg_ptr->send_msg_ptr->dst_addr_ptr->addr_ptr, src_addr_ptr->addr_len)) {
vithyat 0:977e87915078 1037 /* If message's Source address port is same than is searched */
vithyat 0:977e87915078 1038 if (stored_msg_ptr->send_msg_ptr->dst_addr_ptr->port == src_addr_ptr->port) {
vithyat 0:977e87915078 1039 /* * * Message found * * */
vithyat 0:977e87915078 1040
vithyat 0:977e87915078 1041 /* Remove message from Linked list */
vithyat 0:977e87915078 1042 ns_list_remove(&handle->linked_list_resent_msgs, stored_msg_ptr);
vithyat 0:977e87915078 1043 --handle->count_resent_msgs;
vithyat 0:977e87915078 1044
vithyat 0:977e87915078 1045 /* Free memory of stored message */
vithyat 0:977e87915078 1046 sn_coap_protocol_release_allocated_send_msg_mem(handle, stored_msg_ptr);
vithyat 0:977e87915078 1047
vithyat 0:977e87915078 1048 return;
vithyat 0:977e87915078 1049 }
vithyat 0:977e87915078 1050 }
vithyat 0:977e87915078 1051 }
vithyat 0:977e87915078 1052 }
vithyat 0:977e87915078 1053 }
vithyat 0:977e87915078 1054
vithyat 0:977e87915078 1055 uint32_t sn_coap_calculate_new_resend_time(const uint32_t current_time, const uint8_t interval, const uint8_t counter)
vithyat 0:977e87915078 1056 {
vithyat 0:977e87915078 1057 uint32_t resend_time = interval << counter;
vithyat 0:977e87915078 1058 uint16_t random_factor = randLIB_get_random_in_range(100, RESPONSE_RANDOM_FACTOR * 100);
vithyat 0:977e87915078 1059 return current_time + ((resend_time * random_factor) / 100);
vithyat 0:977e87915078 1060 }
vithyat 0:977e87915078 1061
vithyat 0:977e87915078 1062 #endif /* ENABLE_RESENDINGS */
vithyat 0:977e87915078 1063
vithyat 0:977e87915078 1064 void sn_coap_protocol_send_rst(struct coap_s *handle, uint16_t msg_id, sn_nsdl_addr_s *addr_ptr, void *param)
vithyat 0:977e87915078 1065 {
vithyat 0:977e87915078 1066 uint8_t packet_ptr[4];
vithyat 0:977e87915078 1067
vithyat 0:977e87915078 1068 /* Add CoAP version and message type */
vithyat 0:977e87915078 1069 packet_ptr[0] = COAP_VERSION_1;
vithyat 0:977e87915078 1070 packet_ptr[0] |= COAP_MSG_TYPE_RESET;
vithyat 0:977e87915078 1071
vithyat 0:977e87915078 1072 /* Add message code */
vithyat 0:977e87915078 1073 packet_ptr[1] = COAP_MSG_CODE_EMPTY;
vithyat 0:977e87915078 1074
vithyat 0:977e87915078 1075 /* Add message ID */
vithyat 0:977e87915078 1076 packet_ptr[2] = msg_id >> 8;
vithyat 0:977e87915078 1077 packet_ptr[3] = (uint8_t)msg_id;
vithyat 0:977e87915078 1078
vithyat 0:977e87915078 1079 /* Send RST */
vithyat 0:977e87915078 1080 handle->sn_coap_tx_callback(packet_ptr, 4, addr_ptr, param);
vithyat 0:977e87915078 1081
vithyat 0:977e87915078 1082 }
vithyat 0:977e87915078 1083
vithyat 0:977e87915078 1084 uint16_t sn_coap_protocol_get_configured_blockwise_size(struct coap_s *handle)
vithyat 0:977e87915078 1085 {
vithyat 0:977e87915078 1086 return handle->sn_coap_block_data_size;
vithyat 0:977e87915078 1087 }
vithyat 0:977e87915078 1088
vithyat 0:977e87915078 1089 #if SN_COAP_DUPLICATION_MAX_MSGS_COUNT /* If Message duplication detection is not used at all, this part of code will not be compiled */
vithyat 0:977e87915078 1090
vithyat 0:977e87915078 1091 /**************************************************************************//**
vithyat 0:977e87915078 1092 * \fn static void sn_coap_protocol_linked_list_duplication_info_store(sn_nsdl_addr_s *addr_ptr, uint16_t msg_id)
vithyat 0:977e87915078 1093 *
vithyat 0:977e87915078 1094 * \brief Stores Duplication info to Linked list
vithyat 0:977e87915078 1095 *
vithyat 0:977e87915078 1096 * \param msg_id is Message ID to be stored
vithyat 0:977e87915078 1097 * \param *addr_ptr is pointer to Address information to be stored
vithyat 0:977e87915078 1098 *****************************************************************************/
vithyat 0:977e87915078 1099
vithyat 0:977e87915078 1100 static void sn_coap_protocol_linked_list_duplication_info_store(struct coap_s *handle, sn_nsdl_addr_s *addr_ptr,
vithyat 0:977e87915078 1101 uint16_t msg_id, void *param)
vithyat 0:977e87915078 1102 {
vithyat 0:977e87915078 1103 coap_duplication_info_s *stored_duplication_info_ptr = NULL;
vithyat 0:977e87915078 1104
vithyat 0:977e87915078 1105 /* * * * Allocating memory for stored Duplication info * * * */
vithyat 0:977e87915078 1106
vithyat 0:977e87915078 1107 /* Allocate memory for stored Duplication info's structure */
vithyat 0:977e87915078 1108 stored_duplication_info_ptr = handle->sn_coap_protocol_malloc(sizeof(coap_duplication_info_s));
vithyat 0:977e87915078 1109
vithyat 0:977e87915078 1110 if (stored_duplication_info_ptr == NULL) {
vithyat 0:977e87915078 1111 tr_error("sn_coap_protocol_linked_list_duplication_info_store - failed to allocate duplication info!");
vithyat 0:977e87915078 1112 return;
vithyat 0:977e87915078 1113 }
vithyat 0:977e87915078 1114 memset(stored_duplication_info_ptr, 0, sizeof(coap_duplication_info_s));
vithyat 0:977e87915078 1115
vithyat 0:977e87915078 1116 /* Allocate memory for stored Duplication info's address */
vithyat 0:977e87915078 1117 stored_duplication_info_ptr->address = handle->sn_coap_protocol_malloc(sizeof(sn_nsdl_addr_s));
vithyat 0:977e87915078 1118 if (stored_duplication_info_ptr->address == NULL) {
vithyat 0:977e87915078 1119 tr_error("sn_coap_protocol_linked_list_duplication_info_store - failed to allocate address!");
vithyat 0:977e87915078 1120 handle->sn_coap_protocol_free(stored_duplication_info_ptr);
vithyat 0:977e87915078 1121 stored_duplication_info_ptr = 0;
vithyat 0:977e87915078 1122 return;
vithyat 0:977e87915078 1123 }
vithyat 0:977e87915078 1124 memset(stored_duplication_info_ptr->address, 0, sizeof(sn_nsdl_addr_s));
vithyat 0:977e87915078 1125
vithyat 0:977e87915078 1126 stored_duplication_info_ptr->address->addr_ptr = handle->sn_coap_protocol_malloc(addr_ptr->addr_len);
vithyat 0:977e87915078 1127
vithyat 0:977e87915078 1128 if (stored_duplication_info_ptr->address->addr_ptr == NULL) {
vithyat 0:977e87915078 1129 tr_error("sn_coap_protocol_linked_list_duplication_info_store - failed to allocate address pointer!");
vithyat 0:977e87915078 1130 handle->sn_coap_protocol_free(stored_duplication_info_ptr->address);
vithyat 0:977e87915078 1131 stored_duplication_info_ptr->address = 0;
vithyat 0:977e87915078 1132 handle->sn_coap_protocol_free(stored_duplication_info_ptr);
vithyat 0:977e87915078 1133 stored_duplication_info_ptr = 0;
vithyat 0:977e87915078 1134 return;
vithyat 0:977e87915078 1135 }
vithyat 0:977e87915078 1136
vithyat 0:977e87915078 1137 /* * * * Filling fields of stored Duplication info * * * */
vithyat 0:977e87915078 1138 stored_duplication_info_ptr->timestamp = handle->system_time;
vithyat 0:977e87915078 1139 stored_duplication_info_ptr->address->addr_len = addr_ptr->addr_len;
vithyat 0:977e87915078 1140 memcpy(stored_duplication_info_ptr->address->addr_ptr, addr_ptr->addr_ptr, addr_ptr->addr_len);
vithyat 0:977e87915078 1141 stored_duplication_info_ptr->address->port = addr_ptr->port;
vithyat 0:977e87915078 1142 stored_duplication_info_ptr->msg_id = msg_id;
vithyat 0:977e87915078 1143
vithyat 0:977e87915078 1144 stored_duplication_info_ptr->coap = handle;
vithyat 0:977e87915078 1145
vithyat 0:977e87915078 1146 stored_duplication_info_ptr->param = param;
vithyat 0:977e87915078 1147 /* * * * Storing Duplication info to Linked list * * * */
vithyat 0:977e87915078 1148
vithyat 0:977e87915078 1149 ns_list_add_to_end(&handle->linked_list_duplication_msgs, stored_duplication_info_ptr);
vithyat 0:977e87915078 1150 ++handle->count_duplication_msgs;
vithyat 0:977e87915078 1151 }
vithyat 0:977e87915078 1152
vithyat 0:977e87915078 1153 /**************************************************************************//**
vithyat 0:977e87915078 1154 * \fn static coap_duplication_info_s *sn_coap_protocol_linked_list_duplication_info_search(const struct coap_s *handle, const sn_nsdl_addr_s *scr_addr_ptr, const uint16_t msg_id)
vithyat 0:977e87915078 1155 *
vithyat 0:977e87915078 1156 * \brief Searches stored message from Linked list (Address and Message ID as key)
vithyat 0:977e87915078 1157 *
vithyat 0:977e87915078 1158 * \param *addr_ptr is pointer to Address key to be searched
vithyat 0:977e87915078 1159 * \param msg_id is Message ID key to be searched
vithyat 0:977e87915078 1160 *
vithyat 0:977e87915078 1161 * \return Return value is 0 when message found and -1 if not found
vithyat 0:977e87915078 1162 *****************************************************************************/
vithyat 0:977e87915078 1163
vithyat 0:977e87915078 1164 static coap_duplication_info_s* sn_coap_protocol_linked_list_duplication_info_search(const struct coap_s *handle,
vithyat 0:977e87915078 1165 const sn_nsdl_addr_s *addr_ptr, const uint16_t msg_id)
vithyat 0:977e87915078 1166 {
vithyat 0:977e87915078 1167 /* Loop all nodes in Linked list for searching Message ID */
vithyat 0:977e87915078 1168 ns_list_foreach(coap_duplication_info_s, stored_duplication_info_ptr, &handle->linked_list_duplication_msgs) {
vithyat 0:977e87915078 1169 /* If message's Message ID is same than is searched */
vithyat 0:977e87915078 1170 if (stored_duplication_info_ptr->msg_id == msg_id) {
vithyat 0:977e87915078 1171 /* If message's Source address is same than is searched */
vithyat 0:977e87915078 1172 if (0 == memcmp(addr_ptr->addr_ptr, stored_duplication_info_ptr->address->addr_ptr, addr_ptr->addr_len)) {
vithyat 0:977e87915078 1173 /* If message's Source address port is same than is searched */
vithyat 0:977e87915078 1174 if (stored_duplication_info_ptr->address->port == addr_ptr->port) {
vithyat 0:977e87915078 1175 /* * * Correct Duplication info found * * * */
vithyat 0:977e87915078 1176 return stored_duplication_info_ptr;
vithyat 0:977e87915078 1177 }
vithyat 0:977e87915078 1178 }
vithyat 0:977e87915078 1179 }
vithyat 0:977e87915078 1180 }
vithyat 0:977e87915078 1181 return NULL;
vithyat 0:977e87915078 1182 }
vithyat 0:977e87915078 1183
vithyat 0:977e87915078 1184 /**************************************************************************//**
vithyat 0:977e87915078 1185 * \fn static void sn_coap_protocol_linked_list_duplication_info_remove(struct coap_s *handle, uint8_t *addr_ptr, uint16_t port, uint16_t msg_id)
vithyat 0:977e87915078 1186 *
vithyat 0:977e87915078 1187 * \brief Removes stored Duplication info from Linked list
vithyat 0:977e87915078 1188 *
vithyat 0:977e87915078 1189 * \param *addr_ptr is pointer to Address key to be removed
vithyat 0:977e87915078 1190 *
vithyat 0:977e87915078 1191 * \param port is Port key to be removed
vithyat 0:977e87915078 1192 *
vithyat 0:977e87915078 1193 * \param msg_id is Message ID key to be removed
vithyat 0:977e87915078 1194 *****************************************************************************/
vithyat 0:977e87915078 1195
vithyat 0:977e87915078 1196 static void sn_coap_protocol_linked_list_duplication_info_remove(struct coap_s *handle, uint8_t *addr_ptr, uint16_t port, uint16_t msg_id)
vithyat 0:977e87915078 1197 {
vithyat 0:977e87915078 1198 /* Loop all stored duplication messages in Linked list */
vithyat 0:977e87915078 1199 ns_list_foreach(coap_duplication_info_s, removed_duplication_info_ptr, &handle->linked_list_duplication_msgs) {
vithyat 0:977e87915078 1200 /* If message's Address is same than is searched */
vithyat 0:977e87915078 1201 if (handle == removed_duplication_info_ptr->coap && 0 == memcmp(addr_ptr,
vithyat 0:977e87915078 1202 removed_duplication_info_ptr->address->addr_ptr,
vithyat 0:977e87915078 1203 removed_duplication_info_ptr->address->addr_len)) {
vithyat 0:977e87915078 1204 /* If message's Address prt is same than is searched */
vithyat 0:977e87915078 1205 if (removed_duplication_info_ptr->address->port == port) {
vithyat 0:977e87915078 1206 /* If Message ID is same than is searched */
vithyat 0:977e87915078 1207 if (removed_duplication_info_ptr->msg_id == msg_id) {
vithyat 0:977e87915078 1208 /* * * * Correct Duplication info found, remove it from Linked list * * * */
vithyat 0:977e87915078 1209 ns_list_remove(&handle->linked_list_duplication_msgs, removed_duplication_info_ptr);
vithyat 0:977e87915078 1210 --handle->count_duplication_msgs;
vithyat 0:977e87915078 1211
vithyat 0:977e87915078 1212 /* Free memory of stored Duplication info */
vithyat 0:977e87915078 1213 handle->sn_coap_protocol_free(removed_duplication_info_ptr->address->addr_ptr);
vithyat 0:977e87915078 1214 removed_duplication_info_ptr->address->addr_ptr = 0;
vithyat 0:977e87915078 1215 handle->sn_coap_protocol_free(removed_duplication_info_ptr->address);
vithyat 0:977e87915078 1216 removed_duplication_info_ptr->address = 0;
vithyat 0:977e87915078 1217 handle->sn_coap_protocol_free(removed_duplication_info_ptr->packet_ptr);
vithyat 0:977e87915078 1218 removed_duplication_info_ptr->packet_ptr = 0;
vithyat 0:977e87915078 1219 handle->sn_coap_protocol_free(removed_duplication_info_ptr);
vithyat 0:977e87915078 1220 removed_duplication_info_ptr = 0;
vithyat 0:977e87915078 1221 return;
vithyat 0:977e87915078 1222 }
vithyat 0:977e87915078 1223 }
vithyat 0:977e87915078 1224 }
vithyat 0:977e87915078 1225 }
vithyat 0:977e87915078 1226 }
vithyat 0:977e87915078 1227
vithyat 0:977e87915078 1228 /**************************************************************************//**
vithyat 0:977e87915078 1229 * \fn static void sn_coap_protocol_linked_list_duplication_info_remove_old_ones(struct coap_s *handle)
vithyat 0:977e87915078 1230 *
vithyat 0:977e87915078 1231 * \brief Removes old stored Duplication detection infos from Linked list
vithyat 0:977e87915078 1232 *****************************************************************************/
vithyat 0:977e87915078 1233
vithyat 0:977e87915078 1234 static void sn_coap_protocol_linked_list_duplication_info_remove_old_ones(struct coap_s *handle)
vithyat 0:977e87915078 1235 {
vithyat 0:977e87915078 1236 /* Loop all stored duplication messages in Linked list */
vithyat 0:977e87915078 1237 ns_list_foreach_safe(coap_duplication_info_s, removed_duplication_info_ptr, &handle->linked_list_duplication_msgs) {
vithyat 0:977e87915078 1238 if ((handle->system_time - removed_duplication_info_ptr->timestamp) > SN_COAP_DUPLICATION_MAX_TIME_MSGS_STORED) {
vithyat 0:977e87915078 1239 /* * * * Old Duplication info found, remove it from Linked list * * * */
vithyat 0:977e87915078 1240 ns_list_remove(&handle->linked_list_duplication_msgs, removed_duplication_info_ptr);
vithyat 0:977e87915078 1241 --handle->count_duplication_msgs;
vithyat 0:977e87915078 1242
vithyat 0:977e87915078 1243 /* Free memory of stored Duplication info */
vithyat 0:977e87915078 1244 handle->sn_coap_protocol_free(removed_duplication_info_ptr->address->addr_ptr);
vithyat 0:977e87915078 1245 removed_duplication_info_ptr->address->addr_ptr = 0;
vithyat 0:977e87915078 1246 handle->sn_coap_protocol_free(removed_duplication_info_ptr->address);
vithyat 0:977e87915078 1247 removed_duplication_info_ptr->address = 0;
vithyat 0:977e87915078 1248 handle->sn_coap_protocol_free(removed_duplication_info_ptr->packet_ptr);
vithyat 0:977e87915078 1249 removed_duplication_info_ptr->packet_ptr = 0;
vithyat 0:977e87915078 1250 handle->sn_coap_protocol_free(removed_duplication_info_ptr);
vithyat 0:977e87915078 1251 removed_duplication_info_ptr = 0;
vithyat 0:977e87915078 1252 }
vithyat 0:977e87915078 1253 }
vithyat 0:977e87915078 1254 }
vithyat 0:977e87915078 1255
vithyat 0:977e87915078 1256 #endif /* SN_COAP_DUPLICATION_MAX_MSGS_COUNT */
vithyat 0:977e87915078 1257
vithyat 0:977e87915078 1258 #if SN_COAP_BLOCKWISE_ENABLED || SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
vithyat 0:977e87915078 1259 /**************************************************************************//**
vithyat 0:977e87915078 1260 * \fn static void sn_coap_protocol_linked_list_blockwise_msg_remove(struct coap_s *handle, coap_blockwise_msg_s *removed_msg_ptr)
vithyat 0:977e87915078 1261 *
vithyat 0:977e87915078 1262 * \brief Removes stored blockwise message from Linked list
vithyat 0:977e87915078 1263 *
vithyat 0:977e87915078 1264 * \param removed_msg_ptr is message to be removed
vithyat 0:977e87915078 1265 *****************************************************************************/
vithyat 0:977e87915078 1266
vithyat 0:977e87915078 1267 static void sn_coap_protocol_linked_list_blockwise_msg_remove(struct coap_s *handle, coap_blockwise_msg_s *removed_msg_ptr)
vithyat 0:977e87915078 1268 {
vithyat 0:977e87915078 1269 if( removed_msg_ptr->coap == handle ){
vithyat 0:977e87915078 1270 ns_list_remove(&handle->linked_list_blockwise_sent_msgs, removed_msg_ptr);
vithyat 0:977e87915078 1271
vithyat 0:977e87915078 1272 if( removed_msg_ptr->coap_msg_ptr ){
vithyat 0:977e87915078 1273 if (removed_msg_ptr->coap_msg_ptr->payload_ptr) {
vithyat 0:977e87915078 1274 handle->sn_coap_protocol_free(removed_msg_ptr->coap_msg_ptr->payload_ptr);
vithyat 0:977e87915078 1275 removed_msg_ptr->coap_msg_ptr->payload_ptr = 0;
vithyat 0:977e87915078 1276 }
vithyat 0:977e87915078 1277
vithyat 0:977e87915078 1278 sn_coap_parser_release_allocated_coap_msg_mem(handle, removed_msg_ptr->coap_msg_ptr);
vithyat 0:977e87915078 1279 }
vithyat 0:977e87915078 1280
vithyat 0:977e87915078 1281 handle->sn_coap_protocol_free(removed_msg_ptr);
vithyat 0:977e87915078 1282 removed_msg_ptr = 0;
vithyat 0:977e87915078 1283 }
vithyat 0:977e87915078 1284 }
vithyat 0:977e87915078 1285
vithyat 0:977e87915078 1286 /**************************************************************************//**
vithyat 0:977e87915078 1287 * \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)
vithyat 0:977e87915078 1288 *
vithyat 0:977e87915078 1289 * \brief Stores blockwise payload to Linked list
vithyat 0:977e87915078 1290 *
vithyat 0:977e87915078 1291 * \param *addr_ptr is pointer to Address information to be stored
vithyat 0:977e87915078 1292 * \param stored_payload_len is length of stored Payload
vithyat 0:977e87915078 1293 * \param *stored_payload_ptr is pointer to stored Payload
vithyat 0:977e87915078 1294 *****************************************************************************/
vithyat 0:977e87915078 1295
vithyat 0:977e87915078 1296 static void sn_coap_protocol_linked_list_blockwise_payload_store(struct coap_s *handle, sn_nsdl_addr_s *addr_ptr,
vithyat 0:977e87915078 1297 uint16_t stored_payload_len,
vithyat 0:977e87915078 1298 uint8_t *stored_payload_ptr,
vithyat 0:977e87915078 1299 uint8_t *token_ptr,
vithyat 0:977e87915078 1300 uint8_t token_len,
vithyat 0:977e87915078 1301 uint32_t block_number)
vithyat 0:977e87915078 1302 {
vithyat 0:977e87915078 1303 if (!addr_ptr || !stored_payload_len || !stored_payload_ptr) {
vithyat 0:977e87915078 1304 return;
vithyat 0:977e87915078 1305 }
vithyat 0:977e87915078 1306
vithyat 0:977e87915078 1307 // Do not add duplicates to list, this could happen if server needs to retransmit block message again
vithyat 0:977e87915078 1308 ns_list_foreach(coap_blockwise_payload_s, payload_info_ptr, &handle->linked_list_blockwise_received_payloads) {
vithyat 0:977e87915078 1309 if ((0 == memcmp(addr_ptr->addr_ptr, payload_info_ptr->addr_ptr, addr_ptr->addr_len)) && (payload_info_ptr->port == addr_ptr->port)) {
vithyat 0:977e87915078 1310 if (token_ptr) {
vithyat 0:977e87915078 1311 if (!payload_info_ptr->token_ptr || (payload_info_ptr->token_len != token_len) || (memcmp(payload_info_ptr->token_ptr, token_ptr, token_len))) {
vithyat 0:977e87915078 1312 continue;
vithyat 0:977e87915078 1313 }
vithyat 0:977e87915078 1314 } else if (payload_info_ptr->token_ptr) {
vithyat 0:977e87915078 1315 continue;
vithyat 0:977e87915078 1316 }
vithyat 0:977e87915078 1317 if (payload_info_ptr->block_number == block_number) {
vithyat 0:977e87915078 1318 return;
vithyat 0:977e87915078 1319 }
vithyat 0:977e87915078 1320 }
vithyat 0:977e87915078 1321 }
vithyat 0:977e87915078 1322
vithyat 0:977e87915078 1323 coap_blockwise_payload_s *stored_blockwise_payload_ptr = NULL;
vithyat 0:977e87915078 1324
vithyat 0:977e87915078 1325 /* * * * Allocating memory for stored Payload * * * */
vithyat 0:977e87915078 1326
vithyat 0:977e87915078 1327 /* Allocate memory for stored Payload's structure */
vithyat 0:977e87915078 1328 stored_blockwise_payload_ptr = handle->sn_coap_protocol_malloc(sizeof(coap_blockwise_payload_s));
vithyat 0:977e87915078 1329
vithyat 0:977e87915078 1330 if (stored_blockwise_payload_ptr == NULL) {
vithyat 0:977e87915078 1331 tr_error("sn_coap_protocol_linked_list_blockwise_payload_store - failed to allocate blockwise!");
vithyat 0:977e87915078 1332 return;
vithyat 0:977e87915078 1333 }
vithyat 0:977e87915078 1334
vithyat 0:977e87915078 1335
vithyat 0:977e87915078 1336 /* Allocate memory for stored Payload's data */
vithyat 0:977e87915078 1337 stored_blockwise_payload_ptr->payload_ptr = handle->sn_coap_protocol_malloc(stored_payload_len);
vithyat 0:977e87915078 1338
vithyat 0:977e87915078 1339 if (stored_blockwise_payload_ptr->payload_ptr == NULL) {
vithyat 0:977e87915078 1340 tr_error("sn_coap_protocol_linked_list_blockwise_payload_store - failed to allocate payload!");
vithyat 0:977e87915078 1341 handle->sn_coap_protocol_free(stored_blockwise_payload_ptr);
vithyat 0:977e87915078 1342 stored_blockwise_payload_ptr = 0;
vithyat 0:977e87915078 1343 return;
vithyat 0:977e87915078 1344 }
vithyat 0:977e87915078 1345
vithyat 0:977e87915078 1346 /* Allocate memory for stored Payload's address */
vithyat 0:977e87915078 1347 stored_blockwise_payload_ptr->addr_ptr = handle->sn_coap_protocol_malloc(addr_ptr->addr_len);
vithyat 0:977e87915078 1348
vithyat 0:977e87915078 1349 if (stored_blockwise_payload_ptr->addr_ptr == NULL) {
vithyat 0:977e87915078 1350 tr_error("sn_coap_protocol_linked_list_blockwise_payload_store - failed to allocate address pointer!");
vithyat 0:977e87915078 1351 handle->sn_coap_protocol_free(stored_blockwise_payload_ptr->payload_ptr);
vithyat 0:977e87915078 1352 stored_blockwise_payload_ptr->payload_ptr = 0;
vithyat 0:977e87915078 1353 handle->sn_coap_protocol_free(stored_blockwise_payload_ptr);
vithyat 0:977e87915078 1354 stored_blockwise_payload_ptr = 0;
vithyat 0:977e87915078 1355
vithyat 0:977e87915078 1356 return;
vithyat 0:977e87915078 1357 }
vithyat 0:977e87915078 1358
vithyat 0:977e87915078 1359 /* Allocate & copy token number */
vithyat 0:977e87915078 1360 if (token_ptr && token_len) {
vithyat 0:977e87915078 1361 stored_blockwise_payload_ptr->token_ptr = handle->sn_coap_protocol_malloc(token_len);
vithyat 0:977e87915078 1362
vithyat 0:977e87915078 1363 if(!stored_blockwise_payload_ptr->token_ptr) {
vithyat 0:977e87915078 1364 tr_error("sn_coap_protocol_linked_list_blockwise_payload_store - failed to allocate token pointer!");
vithyat 0:977e87915078 1365 handle->sn_coap_protocol_free(stored_blockwise_payload_ptr->addr_ptr);
vithyat 0:977e87915078 1366 handle->sn_coap_protocol_free(stored_blockwise_payload_ptr->payload_ptr);
vithyat 0:977e87915078 1367 handle->sn_coap_protocol_free(stored_blockwise_payload_ptr);
vithyat 0:977e87915078 1368 return;
vithyat 0:977e87915078 1369 }
vithyat 0:977e87915078 1370
vithyat 0:977e87915078 1371 memcpy(stored_blockwise_payload_ptr->token_ptr, token_ptr, token_len);
vithyat 0:977e87915078 1372 stored_blockwise_payload_ptr->token_len = token_len;
vithyat 0:977e87915078 1373 } else {
vithyat 0:977e87915078 1374 stored_blockwise_payload_ptr->token_ptr = NULL;
vithyat 0:977e87915078 1375 stored_blockwise_payload_ptr->token_len = 0;
vithyat 0:977e87915078 1376 }
vithyat 0:977e87915078 1377
vithyat 0:977e87915078 1378 /* * * * Filling fields of stored Payload * * * */
vithyat 0:977e87915078 1379
vithyat 0:977e87915078 1380 stored_blockwise_payload_ptr->timestamp = handle->system_time;
vithyat 0:977e87915078 1381
vithyat 0:977e87915078 1382 memcpy(stored_blockwise_payload_ptr->addr_ptr, addr_ptr->addr_ptr, addr_ptr->addr_len);
vithyat 0:977e87915078 1383 stored_blockwise_payload_ptr->port = addr_ptr->port;
vithyat 0:977e87915078 1384 memcpy(stored_blockwise_payload_ptr->payload_ptr, stored_payload_ptr, stored_payload_len);
vithyat 0:977e87915078 1385 stored_blockwise_payload_ptr->payload_len = stored_payload_len;
vithyat 0:977e87915078 1386
vithyat 0:977e87915078 1387 stored_blockwise_payload_ptr->coap = handle;
vithyat 0:977e87915078 1388
vithyat 0:977e87915078 1389 stored_blockwise_payload_ptr->block_number = block_number;
vithyat 0:977e87915078 1390
vithyat 0:977e87915078 1391 /* * * * Storing Payload to Linked list * * * */
vithyat 0:977e87915078 1392 ns_list_add_to_end(&handle->linked_list_blockwise_received_payloads, stored_blockwise_payload_ptr);
vithyat 0:977e87915078 1393 }
vithyat 0:977e87915078 1394
vithyat 0:977e87915078 1395 /**************************************************************************//**
vithyat 0:977e87915078 1396 * \fn static uint8_t *sn_coap_protocol_linked_list_blockwise_payload_search(sn_nsdl_addr_s *src_addr_ptr, uint16_t *payload_length)
vithyat 0:977e87915078 1397 *
vithyat 0:977e87915078 1398 * \brief Searches stored blockwise payload from Linked list (Address as key)
vithyat 0:977e87915078 1399 *
vithyat 0:977e87915078 1400 * \param *addr_ptr is pointer to Address key to be searched
vithyat 0:977e87915078 1401 * \param *payload_length is pointer to returned Payload length
vithyat 0:977e87915078 1402 *
vithyat 0:977e87915078 1403 * \return Return value is pointer to found stored blockwise payload in Linked
vithyat 0:977e87915078 1404 * list or NULL if payload not found
vithyat 0:977e87915078 1405 *****************************************************************************/
vithyat 0:977e87915078 1406
vithyat 0:977e87915078 1407 static uint8_t *sn_coap_protocol_linked_list_blockwise_payload_search(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr, uint16_t *payload_length, uint8_t *token_ptr, uint8_t token_len)
vithyat 0:977e87915078 1408 {
vithyat 0:977e87915078 1409 /* Loop all stored blockwise payloads in Linked list */
vithyat 0:977e87915078 1410 ns_list_foreach(coap_blockwise_payload_s, stored_payload_info_ptr, &handle->linked_list_blockwise_received_payloads) {
vithyat 0:977e87915078 1411 /* If payload's Source address and port is same than is searched */
vithyat 0:977e87915078 1412 if ((0 == memcmp(src_addr_ptr->addr_ptr, stored_payload_info_ptr->addr_ptr, src_addr_ptr->addr_len)) && (stored_payload_info_ptr->port == src_addr_ptr->port)) {
vithyat 0:977e87915078 1413 /* Check token */
vithyat 0:977e87915078 1414 if (token_ptr) {
vithyat 0:977e87915078 1415 if (!stored_payload_info_ptr->token_ptr || (token_len != stored_payload_info_ptr->token_len) || (memcmp(stored_payload_info_ptr->token_ptr, token_ptr, token_len))) {
vithyat 0:977e87915078 1416 continue;
vithyat 0:977e87915078 1417 }
vithyat 0:977e87915078 1418 } else if (stored_payload_info_ptr->token_ptr) {
vithyat 0:977e87915078 1419 continue;
vithyat 0:977e87915078 1420 }
vithyat 0:977e87915078 1421 /* * * Correct Payload found * * * */
vithyat 0:977e87915078 1422 *payload_length = stored_payload_info_ptr->payload_len;
vithyat 0:977e87915078 1423 return stored_payload_info_ptr->payload_ptr;
vithyat 0:977e87915078 1424 }
vithyat 0:977e87915078 1425 }
vithyat 0:977e87915078 1426
vithyat 0:977e87915078 1427 return NULL;
vithyat 0:977e87915078 1428 }
vithyat 0:977e87915078 1429
vithyat 0:977e87915078 1430 static bool sn_coap_protocol_linked_list_blockwise_payload_compare_block_number(struct coap_s *handle,
vithyat 0:977e87915078 1431 sn_nsdl_addr_s *src_addr_ptr,
vithyat 0:977e87915078 1432 uint8_t *token_ptr,
vithyat 0:977e87915078 1433 uint8_t token_len,
vithyat 0:977e87915078 1434 uint32_t block_number)
vithyat 0:977e87915078 1435 {
vithyat 0:977e87915078 1436 /* Loop all stored blockwise payloads in Linked list */
vithyat 0:977e87915078 1437 ns_list_foreach(coap_blockwise_payload_s, stored_payload_info_ptr, &handle->linked_list_blockwise_received_payloads) {
vithyat 0:977e87915078 1438 /* If payload's Source address and port is same than is searched */
vithyat 0:977e87915078 1439 if ((0 == memcmp(src_addr_ptr->addr_ptr, stored_payload_info_ptr->addr_ptr, src_addr_ptr->addr_len)) && (stored_payload_info_ptr->port == src_addr_ptr->port)) {
vithyat 0:977e87915078 1440 /* Check token number */
vithyat 0:977e87915078 1441 if (token_ptr) {
vithyat 0:977e87915078 1442 if (!stored_payload_info_ptr->token_ptr || (token_len != stored_payload_info_ptr->token_len) || (memcmp(stored_payload_info_ptr->token_ptr, token_ptr, token_len))) {
vithyat 0:977e87915078 1443 continue;
vithyat 0:977e87915078 1444 }
vithyat 0:977e87915078 1445 } else if (stored_payload_info_ptr->token_ptr) {
vithyat 0:977e87915078 1446 continue;
vithyat 0:977e87915078 1447 }
vithyat 0:977e87915078 1448 // Check that incoming block number matches to last received one
vithyat 0:977e87915078 1449 if (block_number - 1 == stored_payload_info_ptr->block_number) {
vithyat 0:977e87915078 1450 return true;
vithyat 0:977e87915078 1451 }
vithyat 0:977e87915078 1452 }
vithyat 0:977e87915078 1453 }
vithyat 0:977e87915078 1454
vithyat 0:977e87915078 1455 return false;
vithyat 0:977e87915078 1456 }
vithyat 0:977e87915078 1457
vithyat 0:977e87915078 1458 /**************************************************************************//**
vithyat 0:977e87915078 1459 * \fn static void sn_coap_protocol_linked_list_blockwise_payload_remove_oldest(struct coap_s *handle)
vithyat 0:977e87915078 1460 *
vithyat 0:977e87915078 1461 * \brief Removes current stored blockwise paylod from Linked list
vithyat 0:977e87915078 1462 *****************************************************************************/
vithyat 0:977e87915078 1463
vithyat 0:977e87915078 1464 static void sn_coap_protocol_linked_list_blockwise_payload_remove_oldest(struct coap_s *handle, uint8_t *token_ptr, uint8_t token_len)
vithyat 0:977e87915078 1465 {
vithyat 0:977e87915078 1466 /* Remove oldest node in Linked list*/
vithyat 0:977e87915078 1467 if (token_ptr) {
vithyat 0:977e87915078 1468 ns_list_foreach(coap_blockwise_payload_s, removed_payload_ptr, &handle->linked_list_blockwise_received_payloads) {
vithyat 0:977e87915078 1469 if ((token_len == removed_payload_ptr->token_len) && !memcmp(removed_payload_ptr->token_ptr, token_ptr, token_len)) {
vithyat 0:977e87915078 1470 sn_coap_protocol_linked_list_blockwise_payload_remove(handle, removed_payload_ptr);
vithyat 0:977e87915078 1471 return;
vithyat 0:977e87915078 1472 }
vithyat 0:977e87915078 1473 }
vithyat 0:977e87915078 1474 } else {
vithyat 0:977e87915078 1475 ns_list_foreach(coap_blockwise_payload_s, removed_payload_ptr, &handle->linked_list_blockwise_received_payloads) {
vithyat 0:977e87915078 1476 if (!removed_payload_ptr->token_ptr) {
vithyat 0:977e87915078 1477 sn_coap_protocol_linked_list_blockwise_payload_remove(handle, removed_payload_ptr);
vithyat 0:977e87915078 1478 return;
vithyat 0:977e87915078 1479 }
vithyat 0:977e87915078 1480 }
vithyat 0:977e87915078 1481 }
vithyat 0:977e87915078 1482 }
vithyat 0:977e87915078 1483
vithyat 0:977e87915078 1484 /**************************************************************************//**
vithyat 0:977e87915078 1485 * \fn static void sn_coap_protocol_linked_list_blockwise_payload_remove(struct coap_s *handle,
vithyat 0:977e87915078 1486 * coap_blockwise_msg_s *removed_msg_ptr)
vithyat 0:977e87915078 1487 *
vithyat 0:977e87915078 1488 * \brief Removes stored blockwise payload from Linked list
vithyat 0:977e87915078 1489 *
vithyat 0:977e87915078 1490 * \param removed_payload_ptr is payload to be removed
vithyat 0:977e87915078 1491 *****************************************************************************/
vithyat 0:977e87915078 1492
vithyat 0:977e87915078 1493 static void sn_coap_protocol_linked_list_blockwise_payload_remove(struct coap_s *handle,
vithyat 0:977e87915078 1494 coap_blockwise_payload_s *removed_payload_ptr)
vithyat 0:977e87915078 1495 {
vithyat 0:977e87915078 1496 ns_list_remove(&handle->linked_list_blockwise_received_payloads, removed_payload_ptr);
vithyat 0:977e87915078 1497 /* Free memory of stored payload */
vithyat 0:977e87915078 1498 if (removed_payload_ptr->addr_ptr != NULL) {
vithyat 0:977e87915078 1499 handle->sn_coap_protocol_free(removed_payload_ptr->addr_ptr);
vithyat 0:977e87915078 1500 removed_payload_ptr->addr_ptr = 0;
vithyat 0:977e87915078 1501 }
vithyat 0:977e87915078 1502
vithyat 0:977e87915078 1503 if (removed_payload_ptr->payload_ptr != NULL) {
vithyat 0:977e87915078 1504 handle->sn_coap_protocol_free(removed_payload_ptr->payload_ptr);
vithyat 0:977e87915078 1505 removed_payload_ptr->payload_ptr = 0;
vithyat 0:977e87915078 1506 }
vithyat 0:977e87915078 1507
vithyat 0:977e87915078 1508 if (removed_payload_ptr->token_ptr != NULL) {
vithyat 0:977e87915078 1509 handle->sn_coap_protocol_free(removed_payload_ptr->token_ptr);
vithyat 0:977e87915078 1510 removed_payload_ptr->token_ptr = 0;
vithyat 0:977e87915078 1511 }
vithyat 0:977e87915078 1512
vithyat 0:977e87915078 1513 handle->sn_coap_protocol_free(removed_payload_ptr);
vithyat 0:977e87915078 1514 removed_payload_ptr = 0;
vithyat 0:977e87915078 1515 }
vithyat 0:977e87915078 1516
vithyat 0:977e87915078 1517 /**************************************************************************//**
vithyat 0:977e87915078 1518 * \fn static uint32_t sn_coap_protocol_linked_list_blockwise_payloads_get_len(sn_nsdl_addr_s *src_addr_ptr)
vithyat 0:977e87915078 1519 *
vithyat 0:977e87915078 1520 * \brief Counts length of Payloads in Linked list (Address as key)
vithyat 0:977e87915078 1521 *
vithyat 0:977e87915078 1522 * \param *addr_ptr is pointer to Address key
vithyat 0:977e87915078 1523 *
vithyat 0:977e87915078 1524 * \return Return value is length of Payloads as bytes
vithyat 0:977e87915078 1525 *****************************************************************************/
vithyat 0:977e87915078 1526
vithyat 0:977e87915078 1527 static uint32_t sn_coap_protocol_linked_list_blockwise_payloads_get_len(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr, uint8_t *token_ptr, uint8_t token_len)
vithyat 0:977e87915078 1528 {
vithyat 0:977e87915078 1529 uint32_t ret_whole_payload_len = 0;
vithyat 0:977e87915078 1530 /* Loop all stored blockwise payloads in Linked list */
vithyat 0:977e87915078 1531 ns_list_foreach(coap_blockwise_payload_s, searched_payload_info_ptr, &handle->linked_list_blockwise_received_payloads) {
vithyat 0:977e87915078 1532 /* If payload's Source address and port is same than is searched */
vithyat 0:977e87915078 1533 if ((0 == memcmp(src_addr_ptr->addr_ptr, searched_payload_info_ptr->addr_ptr, src_addr_ptr->addr_len)) && (searched_payload_info_ptr->port == src_addr_ptr->port)) {
vithyat 0:977e87915078 1534 /* Check token */
vithyat 0:977e87915078 1535 if (token_ptr) {
vithyat 0:977e87915078 1536 if(!searched_payload_info_ptr->token_ptr || (token_len != searched_payload_info_ptr->token_len) || (memcmp(searched_payload_info_ptr->token_ptr, token_ptr, token_len))) {
vithyat 0:977e87915078 1537 continue;
vithyat 0:977e87915078 1538 }
vithyat 0:977e87915078 1539 } else if (searched_payload_info_ptr->token_ptr) {
vithyat 0:977e87915078 1540 continue;
vithyat 0:977e87915078 1541 }
vithyat 0:977e87915078 1542 /* * * Correct Payload found * * * */
vithyat 0:977e87915078 1543 ret_whole_payload_len += searched_payload_info_ptr->payload_len;
vithyat 0:977e87915078 1544 }
vithyat 0:977e87915078 1545 }
vithyat 0:977e87915078 1546
vithyat 0:977e87915078 1547 return ret_whole_payload_len;
vithyat 0:977e87915078 1548 }
vithyat 0:977e87915078 1549
vithyat 0:977e87915078 1550 /**************************************************************************//**
vithyat 0:977e87915078 1551 * \fn static void sn_coap_protocol_handle_blockwise_timout(struct coap_s *handle)
vithyat 0:977e87915078 1552 *
vithyat 0:977e87915078 1553 * \brief Check incoming and outgoing blockwise messages for time out.
vithyat 0:977e87915078 1554 * Remove timed out messages from lists. Notify application if
vithyat 0:977e87915078 1555 * outgoing message times out.
vithyat 0:977e87915078 1556 *****************************************************************************/
vithyat 0:977e87915078 1557
vithyat 0:977e87915078 1558 static void sn_coap_protocol_handle_blockwise_timout(struct coap_s *handle)
vithyat 0:977e87915078 1559 {
vithyat 0:977e87915078 1560 /* Loop all outgoing blockwise messages */
vithyat 0:977e87915078 1561 /* foreach_safe isn't sufficient because callback routine could remove messages. */
vithyat 0:977e87915078 1562 rescan:
vithyat 0:977e87915078 1563 ns_list_foreach_safe(coap_blockwise_msg_s, removed_blocwise_msg_ptr, &handle->linked_list_blockwise_sent_msgs) {
vithyat 0:977e87915078 1564 if ((handle->system_time - removed_blocwise_msg_ptr->timestamp) > SN_COAP_BLOCKWISE_MAX_TIME_DATA_STORED) {
vithyat 0:977e87915078 1565 bool callback_called = false;
vithyat 0:977e87915078 1566 // Item must be removed from the list before calling the rx_callback function.
vithyat 0:977e87915078 1567 // Callback could actually clear the list and free the item and cause a use after free when callback returns.
vithyat 0:977e87915078 1568 ns_list_remove(&handle->linked_list_blockwise_sent_msgs, removed_blocwise_msg_ptr);
vithyat 0:977e87915078 1569
vithyat 0:977e87915078 1570 /* * * * This messages has timed out, remove it from Linked list * * * */
vithyat 0:977e87915078 1571 if( removed_blocwise_msg_ptr->coap_msg_ptr ){
vithyat 0:977e87915078 1572 if (handle->sn_coap_rx_callback) {
vithyat 0:977e87915078 1573 /* Notify the application about the time out */
vithyat 0:977e87915078 1574 removed_blocwise_msg_ptr->coap_msg_ptr->coap_status = COAP_STATUS_BUILDER_BLOCK_SENDING_FAILED;
vithyat 0:977e87915078 1575 removed_blocwise_msg_ptr->coap_msg_ptr->msg_id = removed_blocwise_msg_ptr->msg_id;
vithyat 0:977e87915078 1576 sn_coap_protocol_delete_retransmission(handle, removed_blocwise_msg_ptr->msg_id);
vithyat 0:977e87915078 1577 handle->sn_coap_rx_callback(removed_blocwise_msg_ptr->coap_msg_ptr, NULL, removed_blocwise_msg_ptr->param);
vithyat 0:977e87915078 1578 callback_called = true;
vithyat 0:977e87915078 1579 }
vithyat 0:977e87915078 1580
vithyat 0:977e87915078 1581 handle->sn_coap_protocol_free(removed_blocwise_msg_ptr->coap_msg_ptr->payload_ptr);
vithyat 0:977e87915078 1582 sn_coap_parser_release_allocated_coap_msg_mem(handle, removed_blocwise_msg_ptr->coap_msg_ptr);
vithyat 0:977e87915078 1583 }
vithyat 0:977e87915078 1584
vithyat 0:977e87915078 1585 handle->sn_coap_protocol_free(removed_blocwise_msg_ptr);
vithyat 0:977e87915078 1586
vithyat 0:977e87915078 1587 if (callback_called) {
vithyat 0:977e87915078 1588 /* Callback routine could have wiped the list already */
vithyat 0:977e87915078 1589 /* Be super cautious and rescan from the start */
vithyat 0:977e87915078 1590 goto rescan;
vithyat 0:977e87915078 1591 }
vithyat 0:977e87915078 1592 }
vithyat 0:977e87915078 1593 }
vithyat 0:977e87915078 1594
vithyat 0:977e87915078 1595
vithyat 0:977e87915078 1596 /* Loop all incoming Blockwise messages */
vithyat 0:977e87915078 1597 ns_list_foreach_safe(coap_blockwise_payload_s, removed_blocwise_payload_ptr, &handle->linked_list_blockwise_received_payloads) {
vithyat 0:977e87915078 1598 if ((handle->system_time - removed_blocwise_payload_ptr->timestamp) > SN_COAP_BLOCKWISE_MAX_TIME_DATA_STORED) {
vithyat 0:977e87915078 1599 /* * * * This messages has timed out, remove it from Linked list * * * */
vithyat 0:977e87915078 1600 sn_coap_protocol_linked_list_blockwise_payload_remove(handle, removed_blocwise_payload_ptr);
vithyat 0:977e87915078 1601 }
vithyat 0:977e87915078 1602 }
vithyat 0:977e87915078 1603 }
vithyat 0:977e87915078 1604
vithyat 0:977e87915078 1605 #endif /* SN_COAP_BLOCKWISE_ENABLED || SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE */
vithyat 0:977e87915078 1606
vithyat 0:977e87915078 1607
vithyat 0:977e87915078 1608 #if ENABLE_RESENDINGS /* If Message resending is not used at all, this part of code will not be compiled */
vithyat 0:977e87915078 1609 /***************************************************************************//**
vithyat 0:977e87915078 1610 * \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)
vithyat 0:977e87915078 1611 *
vithyat 0:977e87915078 1612 * \brief Allocates memory for given message (send or blockwise message)
vithyat 0:977e87915078 1613 *
vithyat 0:977e87915078 1614 * \param *dst_addr_ptr is pointer to destination address where message will be sent
vithyat 0:977e87915078 1615 * \param packet_data_len is length of allocated Packet data
vithyat 0:977e87915078 1616 * \param uri_path_len is length of messages path url
vithyat 0:977e87915078 1617 *
vithyat 0:977e87915078 1618 * \return pointer to allocated struct
vithyat 0:977e87915078 1619 *****************************************************************************/
vithyat 0:977e87915078 1620
vithyat 0:977e87915078 1621 coap_send_msg_s *sn_coap_protocol_allocate_mem_for_msg(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_ptr, uint16_t packet_data_len)
vithyat 0:977e87915078 1622 {
vithyat 0:977e87915078 1623
vithyat 0:977e87915078 1624 coap_send_msg_s *msg_ptr = handle->sn_coap_protocol_malloc(sizeof(coap_send_msg_s));
vithyat 0:977e87915078 1625
vithyat 0:977e87915078 1626 if (msg_ptr == NULL) {
vithyat 0:977e87915078 1627 return NULL;
vithyat 0:977e87915078 1628 }
vithyat 0:977e87915078 1629
vithyat 0:977e87915078 1630 //Locall structure for 1 malloc for send msg
vithyat 0:977e87915078 1631 struct
vithyat 0:977e87915078 1632 {
vithyat 0:977e87915078 1633 sn_nsdl_transmit_s transmit;
vithyat 0:977e87915078 1634 sn_nsdl_addr_s addr;
vithyat 0:977e87915078 1635 uint8_t trail_data[];
vithyat 0:977e87915078 1636 } *m;
vithyat 0:977e87915078 1637 int trail_size = dst_addr_ptr->addr_len + packet_data_len;
vithyat 0:977e87915078 1638
vithyat 0:977e87915078 1639 m = handle->sn_coap_protocol_malloc(sizeof *m + trail_size);
vithyat 0:977e87915078 1640 if (!m) {
vithyat 0:977e87915078 1641 handle->sn_coap_protocol_free(msg_ptr);
vithyat 0:977e87915078 1642 return NULL;
vithyat 0:977e87915078 1643 }
vithyat 0:977e87915078 1644 //Init data
vithyat 0:977e87915078 1645 memset(m, 0, sizeof(*m) + trail_size);
vithyat 0:977e87915078 1646 memset(msg_ptr, 0, sizeof(coap_send_msg_s));
vithyat 0:977e87915078 1647
vithyat 0:977e87915078 1648 msg_ptr->send_msg_ptr = &m->transmit;
vithyat 0:977e87915078 1649 msg_ptr->send_msg_ptr->dst_addr_ptr = &m->addr;
vithyat 0:977e87915078 1650
vithyat 0:977e87915078 1651 msg_ptr->send_msg_ptr->dst_addr_ptr->addr_ptr = m->trail_data;
vithyat 0:977e87915078 1652 if (packet_data_len) {
vithyat 0:977e87915078 1653 msg_ptr->send_msg_ptr->packet_ptr = m->trail_data + dst_addr_ptr->addr_len;
vithyat 0:977e87915078 1654 }
vithyat 0:977e87915078 1655
vithyat 0:977e87915078 1656 return msg_ptr;
vithyat 0:977e87915078 1657 }
vithyat 0:977e87915078 1658
vithyat 0:977e87915078 1659
vithyat 0:977e87915078 1660 /**************************************************************************//**
vithyat 0:977e87915078 1661 * \fn static void sn_coap_protocol_release_allocated_send_msg_mem(struct coap_s *handle, coap_send_msg_s *freed_send_msg_ptr)
vithyat 0:977e87915078 1662 *
vithyat 0:977e87915078 1663 * \brief Releases memory of given Sending message (coap_send_msg_s)
vithyat 0:977e87915078 1664 *
vithyat 0:977e87915078 1665 * \param *freed_send_msg_ptr is pointer to released Sending message
vithyat 0:977e87915078 1666 *****************************************************************************/
vithyat 0:977e87915078 1667
vithyat 0:977e87915078 1668 static void sn_coap_protocol_release_allocated_send_msg_mem(struct coap_s *handle, coap_send_msg_s *freed_send_msg_ptr)
vithyat 0:977e87915078 1669 {
vithyat 0:977e87915078 1670 if (freed_send_msg_ptr != NULL) {
vithyat 0:977e87915078 1671 handle->sn_coap_protocol_free(freed_send_msg_ptr->send_msg_ptr);
vithyat 0:977e87915078 1672 freed_send_msg_ptr->send_msg_ptr = NULL;
vithyat 0:977e87915078 1673 handle->sn_coap_protocol_free(freed_send_msg_ptr);
vithyat 0:977e87915078 1674 freed_send_msg_ptr = NULL;
vithyat 0:977e87915078 1675 }
vithyat 0:977e87915078 1676 }
vithyat 0:977e87915078 1677
vithyat 0:977e87915078 1678 /**************************************************************************//**
vithyat 0:977e87915078 1679 * \fn static uint16_t sn_coap_count_linked_list_size(const coap_send_msg_list_t *linked_list_ptr)
vithyat 0:977e87915078 1680 *
vithyat 0:977e87915078 1681 * \brief Counts total message size of all messages in linked list
vithyat 0:977e87915078 1682 *
vithyat 0:977e87915078 1683 * \param const coap_send_msg_list_t *linked_list_ptr pointer to linked list
vithyat 0:977e87915078 1684 *****************************************************************************/
vithyat 0:977e87915078 1685 static uint16_t sn_coap_count_linked_list_size(const coap_send_msg_list_t *linked_list_ptr)
vithyat 0:977e87915078 1686 {
vithyat 0:977e87915078 1687 uint16_t total_size = 0;
vithyat 0:977e87915078 1688
vithyat 0:977e87915078 1689 ns_list_foreach(coap_send_msg_s, stored_msg_ptr, linked_list_ptr) {
vithyat 0:977e87915078 1690 if (stored_msg_ptr->send_msg_ptr) {
vithyat 0:977e87915078 1691 total_size += stored_msg_ptr->send_msg_ptr->packet_len;
vithyat 0:977e87915078 1692 }
vithyat 0:977e87915078 1693 }
vithyat 0:977e87915078 1694
vithyat 0:977e87915078 1695 return total_size;
vithyat 0:977e87915078 1696 }
vithyat 0:977e87915078 1697
vithyat 0:977e87915078 1698 #endif
vithyat 0:977e87915078 1699
vithyat 0:977e87915078 1700 #if SN_COAP_BLOCKWISE_ENABLED || SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
vithyat 0:977e87915078 1701 void sn_coap_protocol_remove_sent_blockwise_message(struct coap_s *handle, uint16_t msg_id)
vithyat 0:977e87915078 1702 {
vithyat 0:977e87915078 1703 if (!handle) {
vithyat 0:977e87915078 1704 return;
vithyat 0:977e87915078 1705 }
vithyat 0:977e87915078 1706
vithyat 0:977e87915078 1707 ns_list_foreach_safe(coap_blockwise_msg_s, tmp, &handle->linked_list_blockwise_sent_msgs) {
vithyat 0:977e87915078 1708 if (tmp->coap == handle && tmp->coap_msg_ptr && tmp->coap_msg_ptr->msg_id == msg_id) {
vithyat 0:977e87915078 1709 handle->sn_coap_protocol_free(tmp->coap_msg_ptr->payload_ptr);
vithyat 0:977e87915078 1710 sn_coap_parser_release_allocated_coap_msg_mem(tmp->coap, tmp->coap_msg_ptr);
vithyat 0:977e87915078 1711 ns_list_remove(&handle->linked_list_blockwise_sent_msgs, tmp);
vithyat 0:977e87915078 1712 handle->sn_coap_protocol_free(tmp);
vithyat 0:977e87915078 1713 break;
vithyat 0:977e87915078 1714 }
vithyat 0:977e87915078 1715 }
vithyat 0:977e87915078 1716 }
vithyat 0:977e87915078 1717
vithyat 0:977e87915078 1718 void sn_coap_protocol_block_remove(struct coap_s *handle, sn_nsdl_addr_s *source_address, uint16_t payload_length, void *payload)
vithyat 0:977e87915078 1719 {
vithyat 0:977e87915078 1720 if (!handle || !source_address || !payload) {
vithyat 0:977e87915078 1721 return;
vithyat 0:977e87915078 1722 }
vithyat 0:977e87915078 1723
vithyat 0:977e87915078 1724 /* Loop all stored blockwise payloads in Linked list */
vithyat 0:977e87915078 1725 ns_list_foreach(coap_blockwise_payload_s, stored_payload_info_ptr, &handle->linked_list_blockwise_received_payloads) {
vithyat 0:977e87915078 1726 /* If payload's Source address is not the same than is searched */
vithyat 0:977e87915078 1727 if (memcmp(source_address->addr_ptr, stored_payload_info_ptr->addr_ptr, source_address->addr_len)) {
vithyat 0:977e87915078 1728 continue;
vithyat 0:977e87915078 1729 }
vithyat 0:977e87915078 1730
vithyat 0:977e87915078 1731 /* If payload's Source address port is not the same than is searched */
vithyat 0:977e87915078 1732 if (stored_payload_info_ptr->port != source_address->port) {
vithyat 0:977e87915078 1733 continue;
vithyat 0:977e87915078 1734 }
vithyat 0:977e87915078 1735
vithyat 0:977e87915078 1736 /* Check the payload */
vithyat 0:977e87915078 1737 if(payload_length != stored_payload_info_ptr->payload_len){
vithyat 0:977e87915078 1738 continue;
vithyat 0:977e87915078 1739 }
vithyat 0:977e87915078 1740
vithyat 0:977e87915078 1741 if(!memcmp(stored_payload_info_ptr->payload_ptr, payload, stored_payload_info_ptr->payload_len))
vithyat 0:977e87915078 1742 {
vithyat 0:977e87915078 1743 /* Everything matches, remove and return. */
vithyat 0:977e87915078 1744 sn_coap_protocol_linked_list_blockwise_payload_remove(handle, stored_payload_info_ptr);
vithyat 0:977e87915078 1745 return;
vithyat 0:977e87915078 1746 }
vithyat 0:977e87915078 1747 }
vithyat 0:977e87915078 1748 }
vithyat 0:977e87915078 1749
vithyat 0:977e87915078 1750 /****************************************************************************
vithyat 0:977e87915078 1751 * \fn coap_blockwise_msg_s *sn_coap_stored_blockwise_msg_get(struct coap_s *handle, sn_coap_hdr_s *received_coap_msg_ptr)
vithyat 0:977e87915078 1752 *
vithyat 0:977e87915078 1753 * \brief Get blockwise message from list
vithyat 0:977e87915078 1754 *
vithyat 0:977e87915078 1755 * \param *handle Pointer to the coap handle structure
vithyat 0:977e87915078 1756 * \param *received_coap_msg_ptr Pointer to parsed CoAP message structure
vithyat 0:977e87915078 1757 *****************************************************************************/
vithyat 0:977e87915078 1758 static coap_blockwise_msg_s *sn_coap_stored_blockwise_msg_get(struct coap_s *handle, sn_coap_hdr_s *received_coap_msg_ptr)
vithyat 0:977e87915078 1759 {
vithyat 0:977e87915078 1760 ns_list_foreach(coap_blockwise_msg_s, msg, &handle->linked_list_blockwise_sent_msgs) {
vithyat 0:977e87915078 1761 if (!received_coap_msg_ptr->token_ptr && !msg->coap_msg_ptr->token_ptr) {
vithyat 0:977e87915078 1762 return msg;
vithyat 0:977e87915078 1763 } else if ((received_coap_msg_ptr->token_len == msg->coap_msg_ptr->token_len) && (!memcmp(received_coap_msg_ptr->token_ptr, msg->coap_msg_ptr->token_ptr, received_coap_msg_ptr->token_len))) {
vithyat 0:977e87915078 1764 return msg;
vithyat 0:977e87915078 1765 }
vithyat 0:977e87915078 1766 }
vithyat 0:977e87915078 1767
vithyat 0:977e87915078 1768 return ns_list_get_first(&handle->linked_list_blockwise_sent_msgs);
vithyat 0:977e87915078 1769 }
vithyat 0:977e87915078 1770
vithyat 0:977e87915078 1771 /**************************************************************************//**
vithyat 0:977e87915078 1772 * \fn static int8_t sn_coap_handle_blockwise_message(void)
vithyat 0:977e87915078 1773 *
vithyat 0:977e87915078 1774 * \brief Handles all received blockwise messages
vithyat 0:977e87915078 1775 *
vithyat 0:977e87915078 1776 * \param *src_addr_ptr pointer to source address information struct
vithyat 0:977e87915078 1777 * \param *received_coap_msg_ptr pointer to parsed CoAP message structure
vithyat 0:977e87915078 1778 *****************************************************************************/
vithyat 0:977e87915078 1779
vithyat 0:977e87915078 1780 static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr, sn_coap_hdr_s *received_coap_msg_ptr, void *param)
vithyat 0:977e87915078 1781 {
vithyat 0:977e87915078 1782 sn_coap_hdr_s *src_coap_blockwise_ack_msg_ptr = NULL;
vithyat 0:977e87915078 1783 uint16_t dst_packed_data_needed_mem = 0;
vithyat 0:977e87915078 1784 uint8_t *dst_ack_packet_data_ptr = NULL;
vithyat 0:977e87915078 1785 uint8_t block_temp = 0;
vithyat 0:977e87915078 1786
vithyat 0:977e87915078 1787 uint16_t original_payload_len = 0;
vithyat 0:977e87915078 1788 uint8_t *original_payload_ptr = NULL;
vithyat 0:977e87915078 1789
vithyat 0:977e87915078 1790 /* Block1 Option in a request (e.g., PUT or POST) */
vithyat 0:977e87915078 1791 // Blocked request sending, received ACK, sending next block..
vithyat 0:977e87915078 1792 if (received_coap_msg_ptr->options_list_ptr->block1 != COAP_OPTION_BLOCK_NONE) {
vithyat 0:977e87915078 1793 if (received_coap_msg_ptr->msg_code > COAP_MSG_CODE_REQUEST_DELETE) {
vithyat 0:977e87915078 1794 if (received_coap_msg_ptr->options_list_ptr->block1 & 0x08) {
vithyat 0:977e87915078 1795 coap_blockwise_msg_s *stored_blockwise_msg_temp_ptr = NULL;
vithyat 0:977e87915078 1796
vithyat 0:977e87915078 1797 /* Get */
vithyat 0:977e87915078 1798 ns_list_foreach(coap_blockwise_msg_s, msg, &handle->linked_list_blockwise_sent_msgs) {
vithyat 0:977e87915078 1799 if (msg->coap_msg_ptr && received_coap_msg_ptr->msg_id == msg->coap_msg_ptr->msg_id) {
vithyat 0:977e87915078 1800 stored_blockwise_msg_temp_ptr = msg;
vithyat 0:977e87915078 1801 break;
vithyat 0:977e87915078 1802 }
vithyat 0:977e87915078 1803 }
vithyat 0:977e87915078 1804
vithyat 0:977e87915078 1805 if (stored_blockwise_msg_temp_ptr) {
vithyat 0:977e87915078 1806 /* Build response message */
vithyat 0:977e87915078 1807
vithyat 0:977e87915078 1808 uint16_t block_size;
vithyat 0:977e87915078 1809 uint32_t block_number;
vithyat 0:977e87915078 1810
vithyat 0:977e87915078 1811 /* Get block option parameters from received message */
vithyat 0:977e87915078 1812 block_number = received_coap_msg_ptr->options_list_ptr->block1 >> 4;
vithyat 0:977e87915078 1813 block_temp = received_coap_msg_ptr->options_list_ptr->block1 & 0x07;
vithyat 0:977e87915078 1814 block_size = 1u << (block_temp + 4);
vithyat 0:977e87915078 1815
vithyat 0:977e87915078 1816 /* Build next block message */
vithyat 0:977e87915078 1817 src_coap_blockwise_ack_msg_ptr = stored_blockwise_msg_temp_ptr->coap_msg_ptr;
vithyat 0:977e87915078 1818
vithyat 0:977e87915078 1819 if (src_coap_blockwise_ack_msg_ptr->options_list_ptr) {
vithyat 0:977e87915078 1820 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1 = COAP_OPTION_BLOCK_NONE;
vithyat 0:977e87915078 1821 // Do not clear block2 as it might have been set in the original request to request
vithyat 0:977e87915078 1822 // specific size blocks
vithyat 0:977e87915078 1823 } else {
vithyat 0:977e87915078 1824 if (!sn_coap_parser_alloc_options(handle, src_coap_blockwise_ack_msg_ptr)) {
vithyat 0:977e87915078 1825 tr_error("sn_coap_handle_blockwise_message - (send block1) failed to allocate ack message!");
vithyat 0:977e87915078 1826 sn_coap_parser_release_allocated_coap_msg_mem(handle, received_coap_msg_ptr);
vithyat 0:977e87915078 1827 return 0;
vithyat 0:977e87915078 1828 }
vithyat 0:977e87915078 1829 }
vithyat 0:977e87915078 1830
vithyat 0:977e87915078 1831 block_number++;
vithyat 0:977e87915078 1832 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1 = (block_number << 4) | block_temp;
vithyat 0:977e87915078 1833
vithyat 0:977e87915078 1834 original_payload_len = stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len;
vithyat 0:977e87915078 1835 original_payload_ptr = stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_ptr;
vithyat 0:977e87915078 1836
vithyat 0:977e87915078 1837 if ((block_size * (block_number + 1)) > stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len) {
vithyat 0:977e87915078 1838 src_coap_blockwise_ack_msg_ptr->payload_len = stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len - (block_size * (block_number));
vithyat 0:977e87915078 1839 src_coap_blockwise_ack_msg_ptr->payload_ptr = src_coap_blockwise_ack_msg_ptr->payload_ptr + (block_size * block_number);
vithyat 0:977e87915078 1840 }
vithyat 0:977e87915078 1841
vithyat 0:977e87915078 1842 /* Not last block */
vithyat 0:977e87915078 1843 else {
vithyat 0:977e87915078 1844 /* set more - bit */
vithyat 0:977e87915078 1845 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1 |= 0x08;
vithyat 0:977e87915078 1846 src_coap_blockwise_ack_msg_ptr->payload_len = block_size;
vithyat 0:977e87915078 1847 src_coap_blockwise_ack_msg_ptr->payload_ptr = src_coap_blockwise_ack_msg_ptr->payload_ptr + (block_size * block_number);
vithyat 0:977e87915078 1848 }
vithyat 0:977e87915078 1849
vithyat 0:977e87915078 1850 /* Build and send block message */
vithyat 0:977e87915078 1851 dst_packed_data_needed_mem = sn_coap_builder_calc_needed_packet_data_size_2(src_coap_blockwise_ack_msg_ptr, handle->sn_coap_block_data_size);
vithyat 0:977e87915078 1852
vithyat 0:977e87915078 1853 dst_ack_packet_data_ptr = handle->sn_coap_protocol_malloc(dst_packed_data_needed_mem);
vithyat 0:977e87915078 1854 if (!dst_ack_packet_data_ptr) {
vithyat 0:977e87915078 1855 tr_error("sn_coap_handle_blockwise_message - (send block1) failed to allocate ack message!");
vithyat 0:977e87915078 1856 handle->sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->options_list_ptr);
vithyat 0:977e87915078 1857 src_coap_blockwise_ack_msg_ptr->options_list_ptr = 0;
vithyat 0:977e87915078 1858 handle->sn_coap_protocol_free(original_payload_ptr);
vithyat 0:977e87915078 1859 original_payload_ptr = 0;
vithyat 0:977e87915078 1860 handle->sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr);
vithyat 0:977e87915078 1861 src_coap_blockwise_ack_msg_ptr = 0;
vithyat 0:977e87915078 1862 stored_blockwise_msg_temp_ptr->coap_msg_ptr = NULL;
vithyat 0:977e87915078 1863 sn_coap_parser_release_allocated_coap_msg_mem(handle, received_coap_msg_ptr);
vithyat 0:977e87915078 1864 return NULL;
vithyat 0:977e87915078 1865 }
vithyat 0:977e87915078 1866 src_coap_blockwise_ack_msg_ptr->msg_id = message_id++;
vithyat 0:977e87915078 1867 if (message_id == 0) {
vithyat 0:977e87915078 1868 message_id = 1;
vithyat 0:977e87915078 1869 }
vithyat 0:977e87915078 1870
vithyat 0:977e87915078 1871 sn_coap_builder_2(dst_ack_packet_data_ptr, src_coap_blockwise_ack_msg_ptr, handle->sn_coap_block_data_size);
vithyat 0:977e87915078 1872
vithyat 0:977e87915078 1873 handle->sn_coap_tx_callback(dst_ack_packet_data_ptr, dst_packed_data_needed_mem, src_addr_ptr, param);
vithyat 0:977e87915078 1874
vithyat 0:977e87915078 1875 #if ENABLE_RESENDINGS
vithyat 0:977e87915078 1876 uint32_t resend_time = sn_coap_calculate_new_resend_time(handle->system_time, handle->sn_coap_resending_intervall, 0);
vithyat 0:977e87915078 1877 if (src_coap_blockwise_ack_msg_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE) {
vithyat 0:977e87915078 1878 sn_coap_protocol_linked_list_send_msg_store(handle, src_addr_ptr,
vithyat 0:977e87915078 1879 dst_packed_data_needed_mem,
vithyat 0:977e87915078 1880 dst_ack_packet_data_ptr,
vithyat 0:977e87915078 1881 resend_time, param);
vithyat 0:977e87915078 1882 }
vithyat 0:977e87915078 1883 #endif
vithyat 0:977e87915078 1884
vithyat 0:977e87915078 1885 handle->sn_coap_protocol_free(dst_ack_packet_data_ptr);
vithyat 0:977e87915078 1886 dst_ack_packet_data_ptr = 0;
vithyat 0:977e87915078 1887
vithyat 0:977e87915078 1888 stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len = original_payload_len;
vithyat 0:977e87915078 1889 stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_ptr = original_payload_ptr;
vithyat 0:977e87915078 1890
vithyat 0:977e87915078 1891 received_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_BLOCKWISE_ACK;
vithyat 0:977e87915078 1892
vithyat 0:977e87915078 1893 // Remove original message from the list when last block has been sent.
vithyat 0:977e87915078 1894 if (!((src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1) & 0x08)) {
vithyat 0:977e87915078 1895 sn_coap_protocol_remove_sent_blockwise_message(handle, stored_blockwise_msg_temp_ptr->coap_msg_ptr->msg_id);
vithyat 0:977e87915078 1896 }
vithyat 0:977e87915078 1897 }
vithyat 0:977e87915078 1898 } else {
vithyat 0:977e87915078 1899 // XXX what was this trying to free?
vithyat 0:977e87915078 1900 received_coap_msg_ptr->coap_status = COAP_STATUS_OK;
vithyat 0:977e87915078 1901
vithyat 0:977e87915078 1902 }
vithyat 0:977e87915078 1903 }
vithyat 0:977e87915078 1904
vithyat 0:977e87915078 1905 // Blocked request receiving
vithyat 0:977e87915078 1906 else {
vithyat 0:977e87915078 1907 if (received_coap_msg_ptr->payload_len > handle->sn_coap_block_data_size) {
vithyat 0:977e87915078 1908 received_coap_msg_ptr->payload_len = handle->sn_coap_block_data_size;
vithyat 0:977e87915078 1909 }
vithyat 0:977e87915078 1910
vithyat 0:977e87915078 1911 // Check that incoming block number is in order.
vithyat 0:977e87915078 1912 uint32_t block_number = received_coap_msg_ptr->options_list_ptr->block1 >> 4;
vithyat 0:977e87915078 1913 bool blocks_in_order = true;
vithyat 0:977e87915078 1914
vithyat 0:977e87915078 1915 if (block_number > 0 &&
vithyat 0:977e87915078 1916 !sn_coap_protocol_linked_list_blockwise_payload_compare_block_number(handle,
vithyat 0:977e87915078 1917 src_addr_ptr,
vithyat 0:977e87915078 1918 received_coap_msg_ptr->token_ptr,
vithyat 0:977e87915078 1919 received_coap_msg_ptr->token_len,
vithyat 0:977e87915078 1920 block_number)) {
vithyat 0:977e87915078 1921 blocks_in_order = false;
vithyat 0:977e87915078 1922 }
vithyat 0:977e87915078 1923
vithyat 0:977e87915078 1924 sn_coap_protocol_linked_list_blockwise_payload_store(handle,
vithyat 0:977e87915078 1925 src_addr_ptr,
vithyat 0:977e87915078 1926 received_coap_msg_ptr->payload_len,
vithyat 0:977e87915078 1927 received_coap_msg_ptr->payload_ptr,
vithyat 0:977e87915078 1928 received_coap_msg_ptr->token_ptr,
vithyat 0:977e87915078 1929 received_coap_msg_ptr->token_len,
vithyat 0:977e87915078 1930 block_number);
vithyat 0:977e87915078 1931
vithyat 0:977e87915078 1932 /* If not last block (more value is set) */
vithyat 0:977e87915078 1933 /* 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. */
vithyat 0:977e87915078 1934 if (received_coap_msg_ptr->options_list_ptr->block1 & 0x08) {
vithyat 0:977e87915078 1935 src_coap_blockwise_ack_msg_ptr = sn_coap_parser_alloc_message(handle);
vithyat 0:977e87915078 1936 if (src_coap_blockwise_ack_msg_ptr == NULL) {
vithyat 0:977e87915078 1937 tr_error("sn_coap_handle_blockwise_message - (recv block1) failed to allocate ack message!");
vithyat 0:977e87915078 1938 sn_coap_parser_release_allocated_coap_msg_mem(handle, received_coap_msg_ptr);
vithyat 0:977e87915078 1939 return NULL;
vithyat 0:977e87915078 1940 }
vithyat 0:977e87915078 1941
vithyat 0:977e87915078 1942 if (sn_coap_parser_alloc_options(handle, src_coap_blockwise_ack_msg_ptr) == NULL) {
vithyat 0:977e87915078 1943 tr_error("sn_coap_handle_blockwise_message - (recv block1) failed to allocate options!");
vithyat 0:977e87915078 1944 handle->sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr);
vithyat 0:977e87915078 1945 src_coap_blockwise_ack_msg_ptr = 0;
vithyat 0:977e87915078 1946 sn_coap_parser_release_allocated_coap_msg_mem(handle, received_coap_msg_ptr);
vithyat 0:977e87915078 1947 return NULL;
vithyat 0:977e87915078 1948 }
vithyat 0:977e87915078 1949
vithyat 0:977e87915078 1950 if (!blocks_in_order) {
vithyat 0:977e87915078 1951 tr_error("sn_coap_handle_blockwise_message - (recv block1) COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_INCOMPLETE!");
vithyat 0:977e87915078 1952 src_coap_blockwise_ack_msg_ptr->msg_code = COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_INCOMPLETE;
vithyat 0:977e87915078 1953 } else if (received_coap_msg_ptr->msg_code == COAP_MSG_CODE_REQUEST_GET) {
vithyat 0:977e87915078 1954 src_coap_blockwise_ack_msg_ptr->msg_code = COAP_MSG_CODE_RESPONSE_CONTENT;
vithyat 0:977e87915078 1955 } else if (received_coap_msg_ptr->msg_code == COAP_MSG_CODE_REQUEST_POST) {
vithyat 0:977e87915078 1956 src_coap_blockwise_ack_msg_ptr->msg_code = COAP_MSG_CODE_RESPONSE_CONTINUE;
vithyat 0:977e87915078 1957 } else if (received_coap_msg_ptr->msg_code == COAP_MSG_CODE_REQUEST_PUT) {
vithyat 0:977e87915078 1958 src_coap_blockwise_ack_msg_ptr->msg_code = COAP_MSG_CODE_RESPONSE_CONTINUE;
vithyat 0:977e87915078 1959 } else if (received_coap_msg_ptr->msg_code == COAP_MSG_CODE_REQUEST_DELETE) {
vithyat 0:977e87915078 1960 src_coap_blockwise_ack_msg_ptr->msg_code = COAP_MSG_CODE_RESPONSE_DELETED;
vithyat 0:977e87915078 1961 }
vithyat 0:977e87915078 1962
vithyat 0:977e87915078 1963 // Response with COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE if the payload size is more than we can handle
vithyat 0:977e87915078 1964 if (received_coap_msg_ptr->options_list_ptr->size1 > SN_COAP_MAX_INCOMING_BLOCK_MESSAGE_SIZE) {
vithyat 0:977e87915078 1965 // Include maximum size that stack can handle into response
vithyat 0:977e87915078 1966 tr_error("sn_coap_handle_blockwise_message - (recv block1) COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE!");
vithyat 0:977e87915078 1967 src_coap_blockwise_ack_msg_ptr->msg_code = COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE;
vithyat 0:977e87915078 1968 }
vithyat 0:977e87915078 1969 else {
vithyat 0:977e87915078 1970 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1 = received_coap_msg_ptr->options_list_ptr->block1;
vithyat 0:977e87915078 1971 src_coap_blockwise_ack_msg_ptr->msg_type = COAP_MSG_TYPE_ACKNOWLEDGEMENT;
vithyat 0:977e87915078 1972
vithyat 0:977e87915078 1973 /* Check block size */
vithyat 0:977e87915078 1974 block_temp = (src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1 & 0x07);
vithyat 0:977e87915078 1975 uint16_t block_size = 1u << (block_temp + 4);
vithyat 0:977e87915078 1976 if (block_size > handle->sn_coap_block_data_size) {
vithyat 0:977e87915078 1977 // Include maximum size that stack can handle into response
vithyat 0:977e87915078 1978 tr_error("sn_coap_handle_blockwise_message - (recv block1) COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE!");
vithyat 0:977e87915078 1979 src_coap_blockwise_ack_msg_ptr->msg_code = COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE;
vithyat 0:977e87915078 1980 src_coap_blockwise_ack_msg_ptr->options_list_ptr->size1 = handle->sn_coap_block_data_size;
vithyat 0:977e87915078 1981 sn_coap_protocol_linked_list_blockwise_payload_remove_oldest(handle, received_coap_msg_ptr->token_ptr, received_coap_msg_ptr->token_len);
vithyat 0:977e87915078 1982 }
vithyat 0:977e87915078 1983
vithyat 0:977e87915078 1984 if (block_temp > sn_coap_convert_block_size(handle->sn_coap_block_data_size)) {
vithyat 0:977e87915078 1985 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1 &= 0xFFFFF8;
vithyat 0:977e87915078 1986 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1 |= sn_coap_convert_block_size(handle->sn_coap_block_data_size);
vithyat 0:977e87915078 1987 }
vithyat 0:977e87915078 1988 }
vithyat 0:977e87915078 1989
vithyat 0:977e87915078 1990 src_coap_blockwise_ack_msg_ptr->msg_id = received_coap_msg_ptr->msg_id;
vithyat 0:977e87915078 1991
vithyat 0:977e87915078 1992 // Copy token to response
vithyat 0:977e87915078 1993 src_coap_blockwise_ack_msg_ptr->token_ptr = handle->sn_coap_protocol_malloc(received_coap_msg_ptr->token_len);
vithyat 0:977e87915078 1994 if (src_coap_blockwise_ack_msg_ptr->token_ptr) {
vithyat 0:977e87915078 1995 memcpy(src_coap_blockwise_ack_msg_ptr->token_ptr, received_coap_msg_ptr->token_ptr, received_coap_msg_ptr->token_len);
vithyat 0:977e87915078 1996 src_coap_blockwise_ack_msg_ptr->token_len = received_coap_msg_ptr->token_len;
vithyat 0:977e87915078 1997 }
vithyat 0:977e87915078 1998
vithyat 0:977e87915078 1999 dst_packed_data_needed_mem = sn_coap_builder_calc_needed_packet_data_size_2(src_coap_blockwise_ack_msg_ptr, handle->sn_coap_block_data_size);
vithyat 0:977e87915078 2000
vithyat 0:977e87915078 2001 dst_ack_packet_data_ptr = handle->sn_coap_protocol_malloc(dst_packed_data_needed_mem);
vithyat 0:977e87915078 2002 if (!dst_ack_packet_data_ptr) {
vithyat 0:977e87915078 2003 tr_error("sn_coap_handle_blockwise_message - (recv block1) message allocation failed!");
vithyat 0:977e87915078 2004 sn_coap_parser_release_allocated_coap_msg_mem(handle, received_coap_msg_ptr);
vithyat 0:977e87915078 2005 handle->sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->options_list_ptr);
vithyat 0:977e87915078 2006 src_coap_blockwise_ack_msg_ptr->options_list_ptr = 0;
vithyat 0:977e87915078 2007 handle->sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr);
vithyat 0:977e87915078 2008 src_coap_blockwise_ack_msg_ptr = 0;
vithyat 0:977e87915078 2009 return NULL;
vithyat 0:977e87915078 2010 }
vithyat 0:977e87915078 2011
vithyat 0:977e87915078 2012 sn_coap_builder_2(dst_ack_packet_data_ptr, src_coap_blockwise_ack_msg_ptr, handle->sn_coap_block_data_size);
vithyat 0:977e87915078 2013
vithyat 0:977e87915078 2014 #if SN_COAP_DUPLICATION_MAX_MSGS_COUNT
vithyat 0:977e87915078 2015 // copy coap data buffer to duplicate list for resending purposes
vithyat 0:977e87915078 2016 if (!sn_coap_protocol_update_duplicate_package_data(handle,
vithyat 0:977e87915078 2017 src_addr_ptr,
vithyat 0:977e87915078 2018 src_coap_blockwise_ack_msg_ptr,
vithyat 0:977e87915078 2019 dst_packed_data_needed_mem,
vithyat 0:977e87915078 2020 dst_ack_packet_data_ptr)) {
vithyat 0:977e87915078 2021 sn_coap_parser_release_allocated_coap_msg_mem(handle, src_coap_blockwise_ack_msg_ptr);
vithyat 0:977e87915078 2022 handle->sn_coap_protocol_free(dst_ack_packet_data_ptr);
vithyat 0:977e87915078 2023 return NULL;
vithyat 0:977e87915078 2024 }
vithyat 0:977e87915078 2025 #endif
vithyat 0:977e87915078 2026 handle->sn_coap_tx_callback(dst_ack_packet_data_ptr, dst_packed_data_needed_mem, src_addr_ptr, param);
vithyat 0:977e87915078 2027
vithyat 0:977e87915078 2028 sn_coap_parser_release_allocated_coap_msg_mem(handle, src_coap_blockwise_ack_msg_ptr);
vithyat 0:977e87915078 2029 handle->sn_coap_protocol_free(dst_ack_packet_data_ptr);
vithyat 0:977e87915078 2030 dst_ack_packet_data_ptr = 0;
vithyat 0:977e87915078 2031
vithyat 0:977e87915078 2032 received_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVING;
vithyat 0:977e87915078 2033
vithyat 0:977e87915078 2034 } else {
vithyat 0:977e87915078 2035 /* * * This is the last block when whole Blockwise payload from received * * */
vithyat 0:977e87915078 2036 /* * * blockwise messages is gathered and returned to User * * */
vithyat 0:977e87915078 2037
vithyat 0:977e87915078 2038 /* Store last Blockwise payload to Linked list */
vithyat 0:977e87915078 2039 uint16_t payload_len = 0;
vithyat 0:977e87915078 2040 uint8_t *payload_ptr = sn_coap_protocol_linked_list_blockwise_payload_search(handle, src_addr_ptr, &payload_len, received_coap_msg_ptr->token_ptr, received_coap_msg_ptr->token_len);
vithyat 0:977e87915078 2041 uint32_t whole_payload_len = sn_coap_protocol_linked_list_blockwise_payloads_get_len(handle, src_addr_ptr, received_coap_msg_ptr->token_ptr, received_coap_msg_ptr->token_len);
vithyat 0:977e87915078 2042 uint8_t *temp_whole_payload_ptr = NULL;
vithyat 0:977e87915078 2043
vithyat 0:977e87915078 2044 temp_whole_payload_ptr = handle->sn_coap_protocol_malloc(whole_payload_len);
vithyat 0:977e87915078 2045 if (temp_whole_payload_ptr == NULL || whole_payload_len > UINT16_MAX) {
vithyat 0:977e87915078 2046 tr_error("sn_coap_handle_blockwise_message - (recv block1) failed to allocate all blocks!");
vithyat 0:977e87915078 2047 sn_coap_parser_release_allocated_coap_msg_mem(handle, received_coap_msg_ptr);
vithyat 0:977e87915078 2048 handle->sn_coap_protocol_free(temp_whole_payload_ptr);
vithyat 0:977e87915078 2049 return 0;
vithyat 0:977e87915078 2050 }
vithyat 0:977e87915078 2051
vithyat 0:977e87915078 2052 // In block message case, payload_ptr freeing must be done in application level
vithyat 0:977e87915078 2053 received_coap_msg_ptr->payload_ptr = temp_whole_payload_ptr;
vithyat 0:977e87915078 2054 received_coap_msg_ptr->payload_len = whole_payload_len;
vithyat 0:977e87915078 2055
vithyat 0:977e87915078 2056 /* Copy stored Blockwise payloads to returned whole Blockwise payload pointer */
vithyat 0:977e87915078 2057 while (payload_ptr != NULL) {
vithyat 0:977e87915078 2058 memcpy(temp_whole_payload_ptr, payload_ptr, payload_len);
vithyat 0:977e87915078 2059 temp_whole_payload_ptr += payload_len;
vithyat 0:977e87915078 2060 sn_coap_protocol_linked_list_blockwise_payload_remove_oldest(handle, received_coap_msg_ptr->token_ptr, received_coap_msg_ptr->token_len);
vithyat 0:977e87915078 2061 payload_ptr = sn_coap_protocol_linked_list_blockwise_payload_search(handle, src_addr_ptr, &payload_len, received_coap_msg_ptr->token_ptr, received_coap_msg_ptr->token_len);
vithyat 0:977e87915078 2062 }
vithyat 0:977e87915078 2063 received_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED;
vithyat 0:977e87915078 2064 }
vithyat 0:977e87915078 2065 }
vithyat 0:977e87915078 2066 }
vithyat 0:977e87915078 2067
vithyat 0:977e87915078 2068
vithyat 0:977e87915078 2069 /* Block2 Option in a response (e.g., a 2.05 response for GET) */
vithyat 0:977e87915078 2070 /* Message ID must be same than in received message */
vithyat 0:977e87915078 2071 else {
vithyat 0:977e87915078 2072 //This is response to request we made
vithyat 0:977e87915078 2073 if (received_coap_msg_ptr->msg_code > COAP_MSG_CODE_REQUEST_DELETE) {
vithyat 0:977e87915078 2074 if (handle->sn_coap_internal_block2_resp_handling) {
vithyat 0:977e87915078 2075 uint32_t block_number = 0;
vithyat 0:977e87915078 2076
vithyat 0:977e87915078 2077 /* Store blockwise payload to Linked list */
vithyat 0:977e87915078 2078 //todo: add block number to stored values - just to make sure all packets are in order
vithyat 0:977e87915078 2079 sn_coap_protocol_linked_list_blockwise_payload_store(handle,
vithyat 0:977e87915078 2080 src_addr_ptr,
vithyat 0:977e87915078 2081 received_coap_msg_ptr->payload_len,
vithyat 0:977e87915078 2082 received_coap_msg_ptr->payload_ptr,
vithyat 0:977e87915078 2083 received_coap_msg_ptr->token_ptr,
vithyat 0:977e87915078 2084 received_coap_msg_ptr->token_len,
vithyat 0:977e87915078 2085 received_coap_msg_ptr->options_list_ptr->block2 >> 4);
vithyat 0:977e87915078 2086 /* If not last block (more value is set) */
vithyat 0:977e87915078 2087 if (received_coap_msg_ptr->options_list_ptr->block2 & 0x08) {
vithyat 0:977e87915078 2088 coap_blockwise_msg_s *previous_blockwise_msg_ptr = NULL;
vithyat 0:977e87915078 2089 //build and send ack
vithyat 0:977e87915078 2090 received_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVING;
vithyat 0:977e87915078 2091
vithyat 0:977e87915078 2092 ns_list_foreach(coap_blockwise_msg_s, msg, &handle->linked_list_blockwise_sent_msgs) {
vithyat 0:977e87915078 2093 if (received_coap_msg_ptr->msg_id == msg->coap_msg_ptr->msg_id) {
vithyat 0:977e87915078 2094 previous_blockwise_msg_ptr = msg;
vithyat 0:977e87915078 2095 break;
vithyat 0:977e87915078 2096 }
vithyat 0:977e87915078 2097 }
vithyat 0:977e87915078 2098
vithyat 0:977e87915078 2099 if (!previous_blockwise_msg_ptr || !previous_blockwise_msg_ptr->coap_msg_ptr) {
vithyat 0:977e87915078 2100 tr_error("sn_coap_handle_blockwise_message - (send block2) previous message null!");
vithyat 0:977e87915078 2101 sn_coap_parser_release_allocated_coap_msg_mem(handle, received_coap_msg_ptr);
vithyat 0:977e87915078 2102 return 0;
vithyat 0:977e87915078 2103 }
vithyat 0:977e87915078 2104
vithyat 0:977e87915078 2105 src_coap_blockwise_ack_msg_ptr = sn_coap_parser_alloc_message(handle);
vithyat 0:977e87915078 2106 if (src_coap_blockwise_ack_msg_ptr == NULL) {
vithyat 0:977e87915078 2107 tr_error("sn_coap_handle_blockwise_message - (send block2) failed to allocate message!");
vithyat 0:977e87915078 2108 return 0;
vithyat 0:977e87915078 2109 }
vithyat 0:977e87915078 2110
vithyat 0:977e87915078 2111 /* * * Then build CoAP Acknowledgement message * * */
vithyat 0:977e87915078 2112
vithyat 0:977e87915078 2113 if (sn_coap_parser_alloc_options(handle, src_coap_blockwise_ack_msg_ptr) == NULL) {
vithyat 0:977e87915078 2114 tr_error("sn_coap_handle_blockwise_message - (send block2) failed to allocate options!");
vithyat 0:977e87915078 2115 handle->sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr);
vithyat 0:977e87915078 2116 src_coap_blockwise_ack_msg_ptr = 0;
vithyat 0:977e87915078 2117 sn_coap_parser_release_allocated_coap_msg_mem(handle, received_coap_msg_ptr);
vithyat 0:977e87915078 2118 return NULL;
vithyat 0:977e87915078 2119 }
vithyat 0:977e87915078 2120
vithyat 0:977e87915078 2121 src_coap_blockwise_ack_msg_ptr->msg_id = message_id++;
vithyat 0:977e87915078 2122 if (message_id == 0) {
vithyat 0:977e87915078 2123 message_id = 1;
vithyat 0:977e87915078 2124 }
vithyat 0:977e87915078 2125
vithyat 0:977e87915078 2126 /* Update block option */
vithyat 0:977e87915078 2127 block_temp = received_coap_msg_ptr->options_list_ptr->block2 & 0x07;
vithyat 0:977e87915078 2128
vithyat 0:977e87915078 2129 block_number = received_coap_msg_ptr->options_list_ptr->block2 >> 4;
vithyat 0:977e87915078 2130 block_number ++;
vithyat 0:977e87915078 2131
vithyat 0:977e87915078 2132 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2 = (block_number << 4) | block_temp;
vithyat 0:977e87915078 2133
vithyat 0:977e87915078 2134
vithyat 0:977e87915078 2135 /* Set BLOCK2 (subsequent) GET msg code and copy uri path from previous msg*/
vithyat 0:977e87915078 2136 src_coap_blockwise_ack_msg_ptr->msg_code = previous_blockwise_msg_ptr->coap_msg_ptr->msg_code;
vithyat 0:977e87915078 2137 if (previous_blockwise_msg_ptr->coap_msg_ptr->uri_path_ptr) {
vithyat 0:977e87915078 2138 src_coap_blockwise_ack_msg_ptr->uri_path_len = previous_blockwise_msg_ptr->coap_msg_ptr->uri_path_len;
vithyat 0:977e87915078 2139 src_coap_blockwise_ack_msg_ptr->uri_path_ptr = handle->sn_coap_protocol_malloc(previous_blockwise_msg_ptr->coap_msg_ptr->uri_path_len);
vithyat 0:977e87915078 2140 if (!src_coap_blockwise_ack_msg_ptr->uri_path_ptr) {
vithyat 0:977e87915078 2141 sn_coap_parser_release_allocated_coap_msg_mem(handle, src_coap_blockwise_ack_msg_ptr);
vithyat 0:977e87915078 2142 tr_error("sn_coap_handle_blockwise_message - failed to allocate for uri path ptr!");
vithyat 0:977e87915078 2143 return NULL;
vithyat 0:977e87915078 2144 }
vithyat 0:977e87915078 2145 memcpy(src_coap_blockwise_ack_msg_ptr->uri_path_ptr, previous_blockwise_msg_ptr->coap_msg_ptr->uri_path_ptr, previous_blockwise_msg_ptr->coap_msg_ptr->uri_path_len);
vithyat 0:977e87915078 2146 }
vithyat 0:977e87915078 2147 if (previous_blockwise_msg_ptr->coap_msg_ptr->token_ptr) {
vithyat 0:977e87915078 2148 src_coap_blockwise_ack_msg_ptr->token_len = previous_blockwise_msg_ptr->coap_msg_ptr->token_len;
vithyat 0:977e87915078 2149 src_coap_blockwise_ack_msg_ptr->token_ptr = handle->sn_coap_protocol_malloc(previous_blockwise_msg_ptr->coap_msg_ptr->token_len);
vithyat 0:977e87915078 2150 if (!src_coap_blockwise_ack_msg_ptr->token_ptr) {
vithyat 0:977e87915078 2151 sn_coap_parser_release_allocated_coap_msg_mem(handle, src_coap_blockwise_ack_msg_ptr);
vithyat 0:977e87915078 2152 tr_error("sn_coap_handle_blockwise_message - failed to allocate for token ptr!");
vithyat 0:977e87915078 2153 return NULL;
vithyat 0:977e87915078 2154 }
vithyat 0:977e87915078 2155 memcpy(src_coap_blockwise_ack_msg_ptr->token_ptr, previous_blockwise_msg_ptr->coap_msg_ptr->token_ptr, previous_blockwise_msg_ptr->coap_msg_ptr->token_len);
vithyat 0:977e87915078 2156 }
vithyat 0:977e87915078 2157
vithyat 0:977e87915078 2158 ns_list_remove(&handle->linked_list_blockwise_sent_msgs, previous_blockwise_msg_ptr);
vithyat 0:977e87915078 2159 if (previous_blockwise_msg_ptr->coap_msg_ptr) {
vithyat 0:977e87915078 2160 if (previous_blockwise_msg_ptr->coap_msg_ptr->payload_ptr) {
vithyat 0:977e87915078 2161 handle->sn_coap_protocol_free(previous_blockwise_msg_ptr->coap_msg_ptr->payload_ptr);
vithyat 0:977e87915078 2162 previous_blockwise_msg_ptr->coap_msg_ptr->payload_ptr = 0;
vithyat 0:977e87915078 2163 }
vithyat 0:977e87915078 2164 sn_coap_parser_release_allocated_coap_msg_mem(handle, previous_blockwise_msg_ptr->coap_msg_ptr);
vithyat 0:977e87915078 2165 previous_blockwise_msg_ptr->coap_msg_ptr = 0;
vithyat 0:977e87915078 2166 }
vithyat 0:977e87915078 2167 handle->sn_coap_protocol_free(previous_blockwise_msg_ptr);
vithyat 0:977e87915078 2168 previous_blockwise_msg_ptr = 0;
vithyat 0:977e87915078 2169
vithyat 0:977e87915078 2170 /* Then get needed memory count for Packet data */
vithyat 0:977e87915078 2171 dst_packed_data_needed_mem = sn_coap_builder_calc_needed_packet_data_size_2(src_coap_blockwise_ack_msg_ptr ,handle->sn_coap_block_data_size);
vithyat 0:977e87915078 2172
vithyat 0:977e87915078 2173 /* Then allocate memory for Packet data */
vithyat 0:977e87915078 2174 dst_ack_packet_data_ptr = handle->sn_coap_protocol_malloc(dst_packed_data_needed_mem);
vithyat 0:977e87915078 2175
vithyat 0:977e87915078 2176 if (dst_ack_packet_data_ptr == NULL) {
vithyat 0:977e87915078 2177 tr_error("sn_coap_handle_blockwise_message - (send block2) failed to allocate packet!");
vithyat 0:977e87915078 2178 sn_coap_parser_release_allocated_coap_msg_mem(handle, src_coap_blockwise_ack_msg_ptr);
vithyat 0:977e87915078 2179 sn_coap_parser_release_allocated_coap_msg_mem(handle, received_coap_msg_ptr);
vithyat 0:977e87915078 2180 return NULL;
vithyat 0:977e87915078 2181 }
vithyat 0:977e87915078 2182 memset(dst_ack_packet_data_ptr, 0, dst_packed_data_needed_mem);
vithyat 0:977e87915078 2183
vithyat 0:977e87915078 2184 /* * * Then build Acknowledgement message to Packed data * * */
vithyat 0:977e87915078 2185 if ((sn_coap_builder_2(dst_ack_packet_data_ptr, src_coap_blockwise_ack_msg_ptr, handle->sn_coap_block_data_size)) < 0) {
vithyat 0:977e87915078 2186 tr_error("sn_coap_handle_blockwise_message - (send block2) builder failed!");
vithyat 0:977e87915078 2187 handle->sn_coap_protocol_free(dst_ack_packet_data_ptr);
vithyat 0:977e87915078 2188 dst_ack_packet_data_ptr = 0;
vithyat 0:977e87915078 2189 sn_coap_parser_release_allocated_coap_msg_mem(handle, src_coap_blockwise_ack_msg_ptr);
vithyat 0:977e87915078 2190 sn_coap_parser_release_allocated_coap_msg_mem(handle, received_coap_msg_ptr);
vithyat 0:977e87915078 2191 return NULL;
vithyat 0:977e87915078 2192 }
vithyat 0:977e87915078 2193
vithyat 0:977e87915078 2194 /* * * Save to linked list * * */
vithyat 0:977e87915078 2195 coap_blockwise_msg_s *stored_blockwise_msg_ptr;
vithyat 0:977e87915078 2196
vithyat 0:977e87915078 2197 stored_blockwise_msg_ptr = handle->sn_coap_protocol_malloc(sizeof(coap_blockwise_msg_s));
vithyat 0:977e87915078 2198 if (!stored_blockwise_msg_ptr) {
vithyat 0:977e87915078 2199 tr_error("sn_coap_handle_blockwise_message - (send block2) failed to allocate blockwise message!");
vithyat 0:977e87915078 2200 handle->sn_coap_protocol_free(dst_ack_packet_data_ptr);
vithyat 0:977e87915078 2201 dst_ack_packet_data_ptr = 0;
vithyat 0:977e87915078 2202 sn_coap_parser_release_allocated_coap_msg_mem(handle, src_coap_blockwise_ack_msg_ptr);
vithyat 0:977e87915078 2203 sn_coap_parser_release_allocated_coap_msg_mem(handle, received_coap_msg_ptr);
vithyat 0:977e87915078 2204 return 0;
vithyat 0:977e87915078 2205 }
vithyat 0:977e87915078 2206 memset(stored_blockwise_msg_ptr, 0, sizeof(coap_blockwise_msg_s));
vithyat 0:977e87915078 2207
vithyat 0:977e87915078 2208 stored_blockwise_msg_ptr->timestamp = handle->system_time;
vithyat 0:977e87915078 2209
vithyat 0:977e87915078 2210 stored_blockwise_msg_ptr->coap_msg_ptr = src_coap_blockwise_ack_msg_ptr;
vithyat 0:977e87915078 2211 stored_blockwise_msg_ptr->coap = handle;
vithyat 0:977e87915078 2212 stored_blockwise_msg_ptr->param = param;
vithyat 0:977e87915078 2213 stored_blockwise_msg_ptr->msg_id = stored_blockwise_msg_ptr->coap_msg_ptr->msg_id;
vithyat 0:977e87915078 2214 ns_list_add_to_end(&handle->linked_list_blockwise_sent_msgs, stored_blockwise_msg_ptr);
vithyat 0:977e87915078 2215
vithyat 0:977e87915078 2216 /* * * Then release memory of CoAP Acknowledgement message * * */
vithyat 0:977e87915078 2217 handle->sn_coap_tx_callback(dst_ack_packet_data_ptr,
vithyat 0:977e87915078 2218 dst_packed_data_needed_mem, src_addr_ptr, param);
vithyat 0:977e87915078 2219
vithyat 0:977e87915078 2220 #if ENABLE_RESENDINGS
vithyat 0:977e87915078 2221 uint32_t resend_time = sn_coap_calculate_new_resend_time(handle->system_time, handle->sn_coap_resending_intervall, 0);
vithyat 0:977e87915078 2222 sn_coap_protocol_linked_list_send_msg_store(handle, src_addr_ptr,
vithyat 0:977e87915078 2223 dst_packed_data_needed_mem,
vithyat 0:977e87915078 2224 dst_ack_packet_data_ptr,
vithyat 0:977e87915078 2225 resend_time, param);
vithyat 0:977e87915078 2226 #endif
vithyat 0:977e87915078 2227 handle->sn_coap_protocol_free(dst_ack_packet_data_ptr);
vithyat 0:977e87915078 2228 dst_ack_packet_data_ptr = 0;
vithyat 0:977e87915078 2229 }
vithyat 0:977e87915078 2230
vithyat 0:977e87915078 2231 //Last block received
vithyat 0:977e87915078 2232 else {
vithyat 0:977e87915078 2233 /* * * This is the last block when whole Blockwise payload from received * * */
vithyat 0:977e87915078 2234 /* * * blockwise messages is gathered and returned to User * * */
vithyat 0:977e87915078 2235
vithyat 0:977e87915078 2236 /* Store last Blockwise payload to Linked list */
vithyat 0:977e87915078 2237 uint16_t payload_len = 0;
vithyat 0:977e87915078 2238 uint8_t *payload_ptr = sn_coap_protocol_linked_list_blockwise_payload_search(handle, src_addr_ptr, &payload_len, received_coap_msg_ptr->token_ptr, received_coap_msg_ptr->token_len);
vithyat 0:977e87915078 2239 uint16_t whole_payload_len = sn_coap_protocol_linked_list_blockwise_payloads_get_len(handle, src_addr_ptr, received_coap_msg_ptr->token_ptr, received_coap_msg_ptr->token_len);
vithyat 0:977e87915078 2240 uint8_t *temp_whole_payload_ptr = NULL;
vithyat 0:977e87915078 2241
vithyat 0:977e87915078 2242 temp_whole_payload_ptr = handle->sn_coap_protocol_malloc(whole_payload_len);
vithyat 0:977e87915078 2243 if (!temp_whole_payload_ptr) {
vithyat 0:977e87915078 2244 tr_error("sn_coap_handle_blockwise_message - (send block2) failed to allocate whole payload!");
vithyat 0:977e87915078 2245 return 0;
vithyat 0:977e87915078 2246 }
vithyat 0:977e87915078 2247
vithyat 0:977e87915078 2248 received_coap_msg_ptr->payload_ptr = temp_whole_payload_ptr;
vithyat 0:977e87915078 2249 received_coap_msg_ptr->payload_len = whole_payload_len;
vithyat 0:977e87915078 2250
vithyat 0:977e87915078 2251 /* Copy stored Blockwise payloads to returned whole Blockwise payload pointer */
vithyat 0:977e87915078 2252 while (payload_ptr != NULL) {
vithyat 0:977e87915078 2253 memcpy(temp_whole_payload_ptr, payload_ptr, payload_len);
vithyat 0:977e87915078 2254
vithyat 0:977e87915078 2255 temp_whole_payload_ptr += payload_len;
vithyat 0:977e87915078 2256
vithyat 0:977e87915078 2257 sn_coap_protocol_linked_list_blockwise_payload_remove_oldest(handle, received_coap_msg_ptr->token_ptr, received_coap_msg_ptr->token_len);
vithyat 0:977e87915078 2258 payload_ptr = sn_coap_protocol_linked_list_blockwise_payload_search(handle, src_addr_ptr, &payload_len, received_coap_msg_ptr->token_ptr, received_coap_msg_ptr->token_len);
vithyat 0:977e87915078 2259 }
vithyat 0:977e87915078 2260 received_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED;
vithyat 0:977e87915078 2261
vithyat 0:977e87915078 2262 //todo: remove previous msg from list
vithyat 0:977e87915078 2263 }
vithyat 0:977e87915078 2264 }
vithyat 0:977e87915078 2265 }
vithyat 0:977e87915078 2266
vithyat 0:977e87915078 2267 //Now we send data to request
vithyat 0:977e87915078 2268 else {
vithyat 0:977e87915078 2269 //Get message by using block number
vithyat 0:977e87915078 2270 //NOTE: Getting the first from list might not be correct one
vithyat 0:977e87915078 2271 coap_blockwise_msg_s *stored_blockwise_msg_temp_ptr = sn_coap_stored_blockwise_msg_get(handle, received_coap_msg_ptr);
vithyat 0:977e87915078 2272 if (stored_blockwise_msg_temp_ptr) {
vithyat 0:977e87915078 2273 uint16_t block_size;
vithyat 0:977e87915078 2274 uint32_t block_number;
vithyat 0:977e87915078 2275
vithyat 0:977e87915078 2276 /* Resolve block parameters */
vithyat 0:977e87915078 2277 block_number = received_coap_msg_ptr->options_list_ptr->block2 >> 4;
vithyat 0:977e87915078 2278 block_temp = received_coap_msg_ptr->options_list_ptr->block2 & 0x07;
vithyat 0:977e87915078 2279 block_size = 1u << (block_temp + 4);
vithyat 0:977e87915078 2280 /* Build response message */
vithyat 0:977e87915078 2281 src_coap_blockwise_ack_msg_ptr = stored_blockwise_msg_temp_ptr->coap_msg_ptr;
vithyat 0:977e87915078 2282
vithyat 0:977e87915078 2283 if (src_coap_blockwise_ack_msg_ptr->options_list_ptr) {
vithyat 0:977e87915078 2284 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block1 = COAP_OPTION_BLOCK_NONE;
vithyat 0:977e87915078 2285 // Do not clear block2 as it might have been set in the original request to request
vithyat 0:977e87915078 2286 // specific size blocks
vithyat 0:977e87915078 2287 } else {
vithyat 0:977e87915078 2288 if (sn_coap_parser_alloc_options(handle, src_coap_blockwise_ack_msg_ptr) == NULL) {
vithyat 0:977e87915078 2289 tr_error("sn_coap_handle_blockwise_message - (recv block2) failed to allocate options!");
vithyat 0:977e87915078 2290 return 0;
vithyat 0:977e87915078 2291 }
vithyat 0:977e87915078 2292 }
vithyat 0:977e87915078 2293
vithyat 0:977e87915078 2294 src_coap_blockwise_ack_msg_ptr->msg_id = received_coap_msg_ptr->msg_id;
vithyat 0:977e87915078 2295
vithyat 0:977e87915078 2296 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2 = received_coap_msg_ptr->options_list_ptr->block2;
vithyat 0:977e87915078 2297
vithyat 0:977e87915078 2298 /* * Payload part * */
vithyat 0:977e87915078 2299
vithyat 0:977e87915078 2300 /* Check if last block */
vithyat 0:977e87915078 2301
vithyat 0:977e87915078 2302 original_payload_len = stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len;
vithyat 0:977e87915078 2303 original_payload_ptr = stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_ptr;
vithyat 0:977e87915078 2304
vithyat 0:977e87915078 2305 if ((block_size * (block_number + 1)) >= stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len) {
vithyat 0:977e87915078 2306 src_coap_blockwise_ack_msg_ptr->payload_len = stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len - (block_size * block_number);
vithyat 0:977e87915078 2307 src_coap_blockwise_ack_msg_ptr->payload_ptr = stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_ptr + (block_size * block_number);
vithyat 0:977e87915078 2308 }
vithyat 0:977e87915078 2309 /* Not last block */
vithyat 0:977e87915078 2310 else {
vithyat 0:977e87915078 2311 /* set more - bit */
vithyat 0:977e87915078 2312 src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2 |= 0x08;
vithyat 0:977e87915078 2313 src_coap_blockwise_ack_msg_ptr->payload_len = block_size;
vithyat 0:977e87915078 2314 src_coap_blockwise_ack_msg_ptr->payload_ptr = stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_ptr + (block_size * block_number);
vithyat 0:977e87915078 2315 }
vithyat 0:977e87915078 2316
vithyat 0:977e87915078 2317 /* Update token to match one which is in GET request.
vithyat 0:977e87915078 2318 * This is needed only in case of notification message.
vithyat 0:977e87915078 2319 */
vithyat 0:977e87915078 2320 if (src_coap_blockwise_ack_msg_ptr->options_list_ptr &&
vithyat 0:977e87915078 2321 src_coap_blockwise_ack_msg_ptr->options_list_ptr->observe != COAP_OBSERVE_NONE) {
vithyat 0:977e87915078 2322 if (received_coap_msg_ptr->token_len && src_coap_blockwise_ack_msg_ptr->token_ptr) {
vithyat 0:977e87915078 2323 handle->sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->token_ptr);
vithyat 0:977e87915078 2324 src_coap_blockwise_ack_msg_ptr->token_ptr = handle->sn_coap_protocol_malloc(received_coap_msg_ptr->token_len);
vithyat 0:977e87915078 2325 if (src_coap_blockwise_ack_msg_ptr->token_ptr) {
vithyat 0:977e87915078 2326 memcpy(src_coap_blockwise_ack_msg_ptr->token_ptr, received_coap_msg_ptr->token_ptr, received_coap_msg_ptr->token_len);
vithyat 0:977e87915078 2327 src_coap_blockwise_ack_msg_ptr->token_len = received_coap_msg_ptr->token_len;
vithyat 0:977e87915078 2328 }
vithyat 0:977e87915078 2329 }
vithyat 0:977e87915078 2330 }
vithyat 0:977e87915078 2331
vithyat 0:977e87915078 2332 /* Build and send block message */
vithyat 0:977e87915078 2333 dst_packed_data_needed_mem = sn_coap_builder_calc_needed_packet_data_size_2(src_coap_blockwise_ack_msg_ptr, handle->sn_coap_block_data_size);
vithyat 0:977e87915078 2334
vithyat 0:977e87915078 2335 dst_ack_packet_data_ptr = handle->sn_coap_protocol_malloc(dst_packed_data_needed_mem);
vithyat 0:977e87915078 2336 if (!dst_ack_packet_data_ptr) {
vithyat 0:977e87915078 2337 tr_error("sn_coap_handle_blockwise_message - (recv block2) failed to allocate packet!");
vithyat 0:977e87915078 2338 if(original_payload_ptr){
vithyat 0:977e87915078 2339 handle->sn_coap_protocol_free(original_payload_ptr);
vithyat 0:977e87915078 2340 original_payload_ptr = NULL;
vithyat 0:977e87915078 2341 }
vithyat 0:977e87915078 2342 sn_coap_parser_release_allocated_coap_msg_mem(handle, src_coap_blockwise_ack_msg_ptr);
vithyat 0:977e87915078 2343 stored_blockwise_msg_temp_ptr->coap_msg_ptr = NULL;
vithyat 0:977e87915078 2344 return NULL;
vithyat 0:977e87915078 2345 }
vithyat 0:977e87915078 2346
vithyat 0:977e87915078 2347 sn_coap_builder_2(dst_ack_packet_data_ptr, src_coap_blockwise_ack_msg_ptr, handle->sn_coap_block_data_size);
vithyat 0:977e87915078 2348 handle->sn_coap_tx_callback(dst_ack_packet_data_ptr, dst_packed_data_needed_mem, src_addr_ptr, param);
vithyat 0:977e87915078 2349
vithyat 0:977e87915078 2350 handle->sn_coap_protocol_free(dst_ack_packet_data_ptr);
vithyat 0:977e87915078 2351 dst_ack_packet_data_ptr = 0;
vithyat 0:977e87915078 2352
vithyat 0:977e87915078 2353 stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len = original_payload_len;
vithyat 0:977e87915078 2354 stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_ptr = original_payload_ptr;
vithyat 0:977e87915078 2355
vithyat 0:977e87915078 2356 if ((block_size * (block_number + 1)) >= stored_blockwise_msg_temp_ptr->coap_msg_ptr->payload_len) {
vithyat 0:977e87915078 2357
vithyat 0:977e87915078 2358 if (handle->sn_coap_rx_callback) {
vithyat 0:977e87915078 2359 stored_blockwise_msg_temp_ptr->coap_msg_ptr->coap_status = COAP_STATUS_BUILDER_BLOCK_SENDING_DONE;
vithyat 0:977e87915078 2360 stored_blockwise_msg_temp_ptr->coap_msg_ptr->msg_id = stored_blockwise_msg_temp_ptr->msg_id;
vithyat 0:977e87915078 2361 handle->sn_coap_rx_callback(stored_blockwise_msg_temp_ptr->coap_msg_ptr, NULL, stored_blockwise_msg_temp_ptr->param);
vithyat 0:977e87915078 2362 }
vithyat 0:977e87915078 2363
vithyat 0:977e87915078 2364 sn_coap_protocol_linked_list_blockwise_msg_remove(handle, stored_blockwise_msg_temp_ptr);
vithyat 0:977e87915078 2365 }
vithyat 0:977e87915078 2366
vithyat 0:977e87915078 2367 received_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_BLOCKWISE_ACK;
vithyat 0:977e87915078 2368 }
vithyat 0:977e87915078 2369 }
vithyat 0:977e87915078 2370 }
vithyat 0:977e87915078 2371 return received_coap_msg_ptr;
vithyat 0:977e87915078 2372 }
vithyat 0:977e87915078 2373
vithyat 0:977e87915078 2374 int8_t sn_coap_convert_block_size(uint16_t block_size)
vithyat 0:977e87915078 2375 {
vithyat 0:977e87915078 2376 if (block_size == 16) {
vithyat 0:977e87915078 2377 return 0;
vithyat 0:977e87915078 2378 } else if (block_size == 32) {
vithyat 0:977e87915078 2379 return 1;
vithyat 0:977e87915078 2380 } else if (block_size == 64) {
vithyat 0:977e87915078 2381 return 2;
vithyat 0:977e87915078 2382 } else if (block_size == 128) {
vithyat 0:977e87915078 2383 return 3;
vithyat 0:977e87915078 2384 } else if (block_size == 256) {
vithyat 0:977e87915078 2385 return 4;
vithyat 0:977e87915078 2386 } else if (block_size == 512) {
vithyat 0:977e87915078 2387 return 5;
vithyat 0:977e87915078 2388 } else if (block_size == 1024) {
vithyat 0:977e87915078 2389 return 6;
vithyat 0:977e87915078 2390 }
vithyat 0:977e87915078 2391
vithyat 0:977e87915078 2392 return 0;
vithyat 0:977e87915078 2393 }
vithyat 0:977e87915078 2394
vithyat 0:977e87915078 2395 static sn_coap_hdr_s *sn_coap_protocol_copy_header(struct coap_s *handle, sn_coap_hdr_s *source_header_ptr)
vithyat 0:977e87915078 2396 {
vithyat 0:977e87915078 2397 sn_coap_hdr_s *destination_header_ptr;
vithyat 0:977e87915078 2398
vithyat 0:977e87915078 2399 destination_header_ptr = sn_coap_parser_alloc_message(handle);
vithyat 0:977e87915078 2400 if (!destination_header_ptr) {
vithyat 0:977e87915078 2401 tr_error("sn_coap_protocol_copy_header - failed to allocate message!");
vithyat 0:977e87915078 2402 return 0;
vithyat 0:977e87915078 2403 }
vithyat 0:977e87915078 2404
vithyat 0:977e87915078 2405 destination_header_ptr->coap_status = source_header_ptr->coap_status;
vithyat 0:977e87915078 2406 destination_header_ptr->msg_type = source_header_ptr->msg_type;
vithyat 0:977e87915078 2407 destination_header_ptr->msg_code = source_header_ptr->msg_code;
vithyat 0:977e87915078 2408 destination_header_ptr->msg_id = source_header_ptr->msg_id;
vithyat 0:977e87915078 2409
vithyat 0:977e87915078 2410 if (source_header_ptr->uri_path_ptr) {
vithyat 0:977e87915078 2411 destination_header_ptr->uri_path_len = source_header_ptr->uri_path_len;
vithyat 0:977e87915078 2412 destination_header_ptr->uri_path_ptr = handle->sn_coap_protocol_malloc(source_header_ptr->uri_path_len);
vithyat 0:977e87915078 2413 if (!destination_header_ptr->uri_path_ptr) {
vithyat 0:977e87915078 2414 tr_error("sn_coap_protocol_copy_header - failed to allocate uri path!");
vithyat 0:977e87915078 2415 sn_coap_parser_release_allocated_coap_msg_mem(handle, destination_header_ptr);
vithyat 0:977e87915078 2416 return 0;
vithyat 0:977e87915078 2417 }
vithyat 0:977e87915078 2418 memcpy(destination_header_ptr->uri_path_ptr, source_header_ptr->uri_path_ptr, source_header_ptr->uri_path_len);
vithyat 0:977e87915078 2419 }
vithyat 0:977e87915078 2420
vithyat 0:977e87915078 2421 if (source_header_ptr->token_ptr) {
vithyat 0:977e87915078 2422 destination_header_ptr->token_len = source_header_ptr->token_len;
vithyat 0:977e87915078 2423 destination_header_ptr->token_ptr = handle->sn_coap_protocol_malloc(source_header_ptr->token_len);
vithyat 0:977e87915078 2424 if (!destination_header_ptr->token_ptr) {
vithyat 0:977e87915078 2425 sn_coap_parser_release_allocated_coap_msg_mem(handle, destination_header_ptr);
vithyat 0:977e87915078 2426 tr_error("sn_coap_protocol_copy_header - failed to allocate token!");
vithyat 0:977e87915078 2427 return 0;
vithyat 0:977e87915078 2428 }
vithyat 0:977e87915078 2429 memcpy(destination_header_ptr->token_ptr, source_header_ptr->token_ptr, source_header_ptr->token_len);
vithyat 0:977e87915078 2430 }
vithyat 0:977e87915078 2431
vithyat 0:977e87915078 2432 destination_header_ptr->content_format = source_header_ptr->content_format;
vithyat 0:977e87915078 2433
vithyat 0:977e87915078 2434 /* Options list */
vithyat 0:977e87915078 2435 if (source_header_ptr->options_list_ptr) {
vithyat 0:977e87915078 2436 if (sn_coap_parser_alloc_options(handle, destination_header_ptr) == NULL) {
vithyat 0:977e87915078 2437 sn_coap_parser_release_allocated_coap_msg_mem(handle, destination_header_ptr);
vithyat 0:977e87915078 2438 tr_error("sn_coap_protocol_copy_header - failed to allocate options!");
vithyat 0:977e87915078 2439 return 0;
vithyat 0:977e87915078 2440 }
vithyat 0:977e87915078 2441
vithyat 0:977e87915078 2442 destination_header_ptr->options_list_ptr->max_age = source_header_ptr->options_list_ptr->max_age;
vithyat 0:977e87915078 2443
vithyat 0:977e87915078 2444 if (source_header_ptr->options_list_ptr->proxy_uri_ptr) {
vithyat 0:977e87915078 2445 destination_header_ptr->options_list_ptr->proxy_uri_len = source_header_ptr->options_list_ptr->proxy_uri_len;
vithyat 0:977e87915078 2446 destination_header_ptr->options_list_ptr->proxy_uri_ptr = handle->sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->proxy_uri_len);
vithyat 0:977e87915078 2447 if (!destination_header_ptr->options_list_ptr->proxy_uri_ptr) {
vithyat 0:977e87915078 2448 sn_coap_parser_release_allocated_coap_msg_mem(handle, destination_header_ptr);
vithyat 0:977e87915078 2449 tr_error("sn_coap_protocol_copy_header - failed to allocate proxy uri!");
vithyat 0:977e87915078 2450 return 0;
vithyat 0:977e87915078 2451 }
vithyat 0:977e87915078 2452 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);
vithyat 0:977e87915078 2453 }
vithyat 0:977e87915078 2454
vithyat 0:977e87915078 2455 if (source_header_ptr->options_list_ptr->etag_ptr) {
vithyat 0:977e87915078 2456 destination_header_ptr->options_list_ptr->etag_len = source_header_ptr->options_list_ptr->etag_len;
vithyat 0:977e87915078 2457 destination_header_ptr->options_list_ptr->etag_ptr = handle->sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->etag_len);
vithyat 0:977e87915078 2458 if (!destination_header_ptr->options_list_ptr->etag_ptr) {
vithyat 0:977e87915078 2459 sn_coap_parser_release_allocated_coap_msg_mem(handle, destination_header_ptr);
vithyat 0:977e87915078 2460 tr_error("sn_coap_protocol_copy_header - failed to allocate etag!");
vithyat 0:977e87915078 2461 return 0;
vithyat 0:977e87915078 2462 }
vithyat 0:977e87915078 2463 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);
vithyat 0:977e87915078 2464 }
vithyat 0:977e87915078 2465
vithyat 0:977e87915078 2466 if (source_header_ptr->options_list_ptr->uri_host_ptr) {
vithyat 0:977e87915078 2467 destination_header_ptr->options_list_ptr->uri_host_len = source_header_ptr->options_list_ptr->uri_host_len;
vithyat 0:977e87915078 2468 destination_header_ptr->options_list_ptr->uri_host_ptr = handle->sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->uri_host_len);
vithyat 0:977e87915078 2469 if (!destination_header_ptr->options_list_ptr->uri_host_ptr) {
vithyat 0:977e87915078 2470 sn_coap_parser_release_allocated_coap_msg_mem(handle, destination_header_ptr);
vithyat 0:977e87915078 2471 tr_error("sn_coap_protocol_copy_header - failed to allocate uri host!");
vithyat 0:977e87915078 2472 return 0;
vithyat 0:977e87915078 2473 }
vithyat 0:977e87915078 2474 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);
vithyat 0:977e87915078 2475 }
vithyat 0:977e87915078 2476
vithyat 0:977e87915078 2477 if (source_header_ptr->options_list_ptr->location_path_ptr) {
vithyat 0:977e87915078 2478 destination_header_ptr->options_list_ptr->location_path_len = source_header_ptr->options_list_ptr->location_path_len;
vithyat 0:977e87915078 2479 destination_header_ptr->options_list_ptr->location_path_ptr = handle->sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->location_path_len);
vithyat 0:977e87915078 2480 if (!destination_header_ptr->options_list_ptr->location_path_ptr) {
vithyat 0:977e87915078 2481 tr_error("sn_coap_protocol_copy_header - failed to allocate location path!");
vithyat 0:977e87915078 2482 sn_coap_parser_release_allocated_coap_msg_mem(handle, destination_header_ptr);
vithyat 0:977e87915078 2483 return 0;
vithyat 0:977e87915078 2484 }
vithyat 0:977e87915078 2485 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);
vithyat 0:977e87915078 2486 }
vithyat 0:977e87915078 2487
vithyat 0:977e87915078 2488 destination_header_ptr->options_list_ptr->uri_port = source_header_ptr->options_list_ptr->uri_port;
vithyat 0:977e87915078 2489
vithyat 0:977e87915078 2490 if (source_header_ptr->options_list_ptr->location_query_ptr) {
vithyat 0:977e87915078 2491 destination_header_ptr->options_list_ptr->location_query_len = source_header_ptr->options_list_ptr->location_query_len;
vithyat 0:977e87915078 2492 destination_header_ptr->options_list_ptr->location_query_ptr = handle->sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->location_query_len);
vithyat 0:977e87915078 2493 if (!destination_header_ptr->options_list_ptr->location_query_ptr) {
vithyat 0:977e87915078 2494 sn_coap_parser_release_allocated_coap_msg_mem(handle, destination_header_ptr);
vithyat 0:977e87915078 2495 tr_error("sn_coap_protocol_copy_header - failed to allocate location query!");
vithyat 0:977e87915078 2496 return 0;
vithyat 0:977e87915078 2497 }
vithyat 0:977e87915078 2498 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);
vithyat 0:977e87915078 2499 }
vithyat 0:977e87915078 2500
vithyat 0:977e87915078 2501 destination_header_ptr->options_list_ptr->observe = source_header_ptr->options_list_ptr->observe;
vithyat 0:977e87915078 2502 destination_header_ptr->options_list_ptr->accept = source_header_ptr->options_list_ptr->accept;
vithyat 0:977e87915078 2503
vithyat 0:977e87915078 2504 if (source_header_ptr->options_list_ptr->uri_query_ptr) {
vithyat 0:977e87915078 2505 destination_header_ptr->options_list_ptr->uri_query_len = source_header_ptr->options_list_ptr->uri_query_len;
vithyat 0:977e87915078 2506 destination_header_ptr->options_list_ptr->uri_query_ptr = handle->sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->uri_query_len);
vithyat 0:977e87915078 2507 if (!destination_header_ptr->options_list_ptr->uri_query_ptr) {
vithyat 0:977e87915078 2508 sn_coap_parser_release_allocated_coap_msg_mem(handle, destination_header_ptr);
vithyat 0:977e87915078 2509 tr_error("sn_coap_protocol_copy_header - failed to allocate uri query!");
vithyat 0:977e87915078 2510 return 0;
vithyat 0:977e87915078 2511 }
vithyat 0:977e87915078 2512 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);
vithyat 0:977e87915078 2513 }
vithyat 0:977e87915078 2514
vithyat 0:977e87915078 2515 destination_header_ptr->options_list_ptr->block1 = source_header_ptr->options_list_ptr->block1;
vithyat 0:977e87915078 2516 destination_header_ptr->options_list_ptr->block2 = source_header_ptr->options_list_ptr->block2;
vithyat 0:977e87915078 2517 }
vithyat 0:977e87915078 2518
vithyat 0:977e87915078 2519 return destination_header_ptr;
vithyat 0:977e87915078 2520 }
vithyat 0:977e87915078 2521 #endif
vithyat 0:977e87915078 2522
vithyat 0:977e87915078 2523 #if SN_COAP_DUPLICATION_MAX_MSGS_COUNT
vithyat 0:977e87915078 2524 static bool sn_coap_protocol_update_duplicate_package_data(const struct coap_s *handle,
vithyat 0:977e87915078 2525 const sn_nsdl_addr_s *dst_addr_ptr,
vithyat 0:977e87915078 2526 const sn_coap_hdr_s *coap_msg_ptr,
vithyat 0:977e87915078 2527 const int16_t data_size,
vithyat 0:977e87915078 2528 const uint8_t *dst_packet_data_ptr)
vithyat 0:977e87915078 2529 {
vithyat 0:977e87915078 2530 if (coap_msg_ptr->msg_type == COAP_MSG_TYPE_ACKNOWLEDGEMENT &&
vithyat 0:977e87915078 2531 handle->sn_coap_duplication_buffer_size != 0) {
vithyat 0:977e87915078 2532 coap_duplication_info_s* info = sn_coap_protocol_linked_list_duplication_info_search(handle,
vithyat 0:977e87915078 2533 dst_addr_ptr,
vithyat 0:977e87915078 2534 coap_msg_ptr->msg_id);
vithyat 0:977e87915078 2535
vithyat 0:977e87915078 2536 /* Update package data to duplication info struct if it's not there yet */
vithyat 0:977e87915078 2537 if (info && info->packet_ptr == NULL) {
vithyat 0:977e87915078 2538 info->packet_ptr = handle->sn_coap_protocol_malloc(data_size);
vithyat 0:977e87915078 2539 if (info->packet_ptr) {
vithyat 0:977e87915078 2540 memcpy(info->packet_ptr, dst_packet_data_ptr, data_size);
vithyat 0:977e87915078 2541 info->packet_len = data_size;
vithyat 0:977e87915078 2542 } else {
vithyat 0:977e87915078 2543 tr_error("sn_coap_protocol_update_duplication_package_data - failed to allocate duplication info!");
vithyat 0:977e87915078 2544 return false;
vithyat 0:977e87915078 2545 }
vithyat 0:977e87915078 2546 }
vithyat 0:977e87915078 2547 }
vithyat 0:977e87915078 2548 return true;
vithyat 0:977e87915078 2549 }
vithyat 0:977e87915078 2550 #endif