leo hendrickson / Mbed OS example-Ethernet-mbed-Cloud-connect
Committer:
leothedragon
Date:
Tue May 04 08:55:12 2021 +0000
Revision:
0:8f0bb79ddd48
nmn

Who changed what in which revision?

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