Jim Carver / Mbed OS mbed-cloud-workshop-connect-HTS221

Dependencies:   HTS221

Committer:
JimCarver
Date:
Fri Oct 19 02:01:38 2018 +0000
Revision:
1:521604503e81
Parent:
0:6b753f761943
bug fix

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JimCarver 0:6b753f761943 1 /*
JimCarver 0:6b753f761943 2 * Copyright (c) 2011-2015 ARM Limited. All rights reserved.
JimCarver 0:6b753f761943 3 * SPDX-License-Identifier: Apache-2.0
JimCarver 0:6b753f761943 4 * Licensed under the Apache License, Version 2.0 (the License); you may
JimCarver 0:6b753f761943 5 * not use this file except in compliance with the License.
JimCarver 0:6b753f761943 6 * You may obtain a copy of the License at
JimCarver 0:6b753f761943 7 *
JimCarver 0:6b753f761943 8 * http://www.apache.org/licenses/LICENSE-2.0
JimCarver 0:6b753f761943 9 *
JimCarver 0:6b753f761943 10 * Unless required by applicable law or agreed to in writing, software
JimCarver 0:6b753f761943 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
JimCarver 0:6b753f761943 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
JimCarver 0:6b753f761943 13 * See the License for the specific language governing permissions and
JimCarver 0:6b753f761943 14 * limitations under the License.
JimCarver 0:6b753f761943 15 */
JimCarver 0:6b753f761943 16
JimCarver 0:6b753f761943 17 /**
JimCarver 0:6b753f761943 18 * \file sn_coap_builder.c
JimCarver 0:6b753f761943 19 *
JimCarver 0:6b753f761943 20 * \brief CoAP Message builder
JimCarver 0:6b753f761943 21 *
JimCarver 0:6b753f761943 22 * Functionality: Builds CoAP message
JimCarver 0:6b753f761943 23 *
JimCarver 0:6b753f761943 24 */
JimCarver 0:6b753f761943 25
JimCarver 0:6b753f761943 26 /* * * * * * * * * * * * * * */
JimCarver 0:6b753f761943 27 /* * * * INCLUDE FILES * * * */
JimCarver 0:6b753f761943 28 /* * * * * * * * * * * * * * */
JimCarver 0:6b753f761943 29
JimCarver 0:6b753f761943 30 #include <string.h> /* For memset() and memcpy() */
JimCarver 0:6b753f761943 31
JimCarver 0:6b753f761943 32 #include "ns_types.h"
JimCarver 0:6b753f761943 33 #include "mbed-coap/sn_coap_header.h"
JimCarver 0:6b753f761943 34 #include "sn_coap_header_internal.h"
JimCarver 0:6b753f761943 35 #include "sn_coap_protocol_internal.h"
JimCarver 0:6b753f761943 36 #include "mbed-trace/mbed_trace.h"
JimCarver 0:6b753f761943 37
JimCarver 0:6b753f761943 38 #define TRACE_GROUP "coap"
JimCarver 0:6b753f761943 39 /* * * * LOCAL FUNCTION PROTOTYPES * * * */
JimCarver 0:6b753f761943 40 static int8_t sn_coap_builder_header_build(uint8_t **dst_packet_data_pptr, sn_coap_hdr_s *src_coap_msg_ptr);
JimCarver 0:6b753f761943 41 static int8_t sn_coap_builder_options_build(uint8_t **dst_packet_data_pptr, sn_coap_hdr_s *src_coap_msg_ptr);
JimCarver 0:6b753f761943 42 static uint16_t sn_coap_builder_options_calc_option_size(uint16_t query_len, uint8_t *query_ptr, sn_coap_option_numbers_e option);
JimCarver 0:6b753f761943 43 static int16_t sn_coap_builder_options_build_add_one_option(uint8_t **dst_packet_data_pptr, uint16_t option_len, uint8_t *option_ptr, sn_coap_option_numbers_e option_number, uint16_t *previous_option_number);
JimCarver 0:6b753f761943 44 static int16_t sn_coap_builder_options_build_add_multiple_option(uint8_t **dst_packet_data_pptr, uint8_t **src_pptr, uint16_t *src_len_ptr, sn_coap_option_numbers_e option, uint16_t *previous_option_number);
JimCarver 0:6b753f761943 45 static uint8_t sn_coap_builder_options_build_add_uint_option(uint8_t **dst_packet_data_pptr, uint32_t value, sn_coap_option_numbers_e option_number, uint16_t *previous_option_number);
JimCarver 0:6b753f761943 46 static uint8_t sn_coap_builder_options_get_option_part_count(uint16_t query_len, uint8_t *query_ptr, sn_coap_option_numbers_e option);
JimCarver 0:6b753f761943 47 static uint16_t sn_coap_builder_options_get_option_part_length_from_whole_option_string(uint16_t query_len, uint8_t *query_ptr, uint8_t query_index, sn_coap_option_numbers_e option);
JimCarver 0:6b753f761943 48 static int16_t sn_coap_builder_options_get_option_part_position(uint16_t query_len, uint8_t *query_ptr, uint8_t query_index, sn_coap_option_numbers_e option);
JimCarver 0:6b753f761943 49 static void sn_coap_builder_payload_build(uint8_t **dst_packet_data_pptr, sn_coap_hdr_s *src_coap_msg_ptr);
JimCarver 0:6b753f761943 50 static uint8_t sn_coap_builder_options_calculate_jump_need(sn_coap_hdr_s *src_coap_msg_ptr/*, uint8_t block_option*/);
JimCarver 0:6b753f761943 51
JimCarver 0:6b753f761943 52 sn_coap_hdr_s *sn_coap_build_response(struct coap_s *handle, sn_coap_hdr_s *coap_packet_ptr, uint8_t msg_code)
JimCarver 0:6b753f761943 53 {
JimCarver 0:6b753f761943 54 sn_coap_hdr_s *coap_res_ptr;
JimCarver 0:6b753f761943 55
JimCarver 0:6b753f761943 56 if (!coap_packet_ptr || !handle) {
JimCarver 0:6b753f761943 57 return NULL;
JimCarver 0:6b753f761943 58 }
JimCarver 0:6b753f761943 59
JimCarver 0:6b753f761943 60 coap_res_ptr = sn_coap_parser_alloc_message(handle);
JimCarver 0:6b753f761943 61 if (!coap_res_ptr) {
JimCarver 0:6b753f761943 62 tr_error("sn_coap_build_response - failed to allocate message!");
JimCarver 0:6b753f761943 63 return NULL;
JimCarver 0:6b753f761943 64 }
JimCarver 0:6b753f761943 65
JimCarver 0:6b753f761943 66 if (msg_code == COAP_MSG_CODE_REQUEST_GET) {
JimCarver 0:6b753f761943 67 // Blockwise message response is new GET
JimCarver 0:6b753f761943 68 coap_res_ptr->msg_type = COAP_MSG_TYPE_CONFIRMABLE;
JimCarver 0:6b753f761943 69 coap_res_ptr->msg_code = (sn_coap_msg_code_e)msg_code;
JimCarver 0:6b753f761943 70 /* msg_id needs to be set by the caller in this case */
JimCarver 0:6b753f761943 71 }
JimCarver 0:6b753f761943 72 else if (coap_packet_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE) {
JimCarver 0:6b753f761943 73 coap_res_ptr->msg_type = COAP_MSG_TYPE_ACKNOWLEDGEMENT;
JimCarver 0:6b753f761943 74 coap_res_ptr->msg_code = (sn_coap_msg_code_e)msg_code;
JimCarver 0:6b753f761943 75 coap_res_ptr->msg_id = coap_packet_ptr->msg_id;
JimCarver 0:6b753f761943 76 }
JimCarver 0:6b753f761943 77 else if (coap_packet_ptr->msg_type == COAP_MSG_TYPE_NON_CONFIRMABLE) {
JimCarver 0:6b753f761943 78 coap_res_ptr->msg_type = COAP_MSG_TYPE_NON_CONFIRMABLE;
JimCarver 0:6b753f761943 79 coap_res_ptr->msg_code = (sn_coap_msg_code_e)msg_code;
JimCarver 0:6b753f761943 80 /* msg_id needs to be set by the caller in this case */
JimCarver 0:6b753f761943 81 }
JimCarver 0:6b753f761943 82 else {
JimCarver 0:6b753f761943 83 handle->sn_coap_protocol_free( coap_res_ptr );
JimCarver 0:6b753f761943 84 return NULL;
JimCarver 0:6b753f761943 85 }
JimCarver 0:6b753f761943 86
JimCarver 0:6b753f761943 87 if (coap_packet_ptr->token_ptr) {
JimCarver 0:6b753f761943 88 coap_res_ptr->token_len = coap_packet_ptr->token_len;
JimCarver 0:6b753f761943 89 coap_res_ptr->token_ptr = handle->sn_coap_protocol_malloc(coap_res_ptr->token_len);
JimCarver 0:6b753f761943 90 if (!coap_res_ptr->token_ptr) {
JimCarver 0:6b753f761943 91 tr_error("sn_coap_build_response - failed to allocate token!");
JimCarver 0:6b753f761943 92 handle->sn_coap_protocol_free(coap_res_ptr);
JimCarver 0:6b753f761943 93 return NULL;
JimCarver 0:6b753f761943 94 }
JimCarver 0:6b753f761943 95 memcpy(coap_res_ptr->token_ptr, coap_packet_ptr->token_ptr, coap_res_ptr->token_len);
JimCarver 0:6b753f761943 96 }
JimCarver 0:6b753f761943 97 return coap_res_ptr;
JimCarver 0:6b753f761943 98 }
JimCarver 0:6b753f761943 99
JimCarver 0:6b753f761943 100 int16_t sn_coap_builder(uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_msg_ptr)
JimCarver 0:6b753f761943 101 {
JimCarver 0:6b753f761943 102 return sn_coap_builder_2(dst_packet_data_ptr, src_coap_msg_ptr, SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE);
JimCarver 0:6b753f761943 103 }
JimCarver 0:6b753f761943 104
JimCarver 0:6b753f761943 105 int16_t sn_coap_builder_2(uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_msg_ptr, uint16_t blockwise_payload_size)
JimCarver 0:6b753f761943 106 {
JimCarver 0:6b753f761943 107 uint8_t *base_packet_data_ptr = NULL;
JimCarver 0:6b753f761943 108
JimCarver 0:6b753f761943 109 /* * * * Check given pointers * * * */
JimCarver 0:6b753f761943 110 if (dst_packet_data_ptr == NULL || src_coap_msg_ptr == NULL) {
JimCarver 0:6b753f761943 111 return -2;
JimCarver 0:6b753f761943 112 }
JimCarver 0:6b753f761943 113
JimCarver 0:6b753f761943 114 /* Initialize given Packet data memory area with zero values */
JimCarver 0:6b753f761943 115 uint16_t dst_byte_count_to_be_built = sn_coap_builder_calc_needed_packet_data_size_2(src_coap_msg_ptr, blockwise_payload_size);
JimCarver 0:6b753f761943 116 if (!dst_byte_count_to_be_built) {
JimCarver 0:6b753f761943 117 tr_error("sn_coap_builder_2 - failed to allocate message!");
JimCarver 0:6b753f761943 118 return -1;
JimCarver 0:6b753f761943 119 }
JimCarver 0:6b753f761943 120
JimCarver 0:6b753f761943 121 memset(dst_packet_data_ptr, 0, dst_byte_count_to_be_built);
JimCarver 0:6b753f761943 122
JimCarver 0:6b753f761943 123 /* * * * Store base (= original) destination Packet data pointer for later usage * * * */
JimCarver 0:6b753f761943 124 base_packet_data_ptr = dst_packet_data_ptr;
JimCarver 0:6b753f761943 125
JimCarver 0:6b753f761943 126 /* * * * * * * * * * * * * * * * * * */
JimCarver 0:6b753f761943 127 /* * * * Header part building * * * */
JimCarver 0:6b753f761943 128 /* * * * * * * * * * * * * * * * * * */
JimCarver 0:6b753f761943 129 if (sn_coap_builder_header_build(&dst_packet_data_ptr, src_coap_msg_ptr) != 0) {
JimCarver 0:6b753f761943 130 /* Header building failed */
JimCarver 0:6b753f761943 131 tr_error("sn_coap_builder_2 - header building failed!");
JimCarver 0:6b753f761943 132 return -1;
JimCarver 0:6b753f761943 133 }
JimCarver 0:6b753f761943 134
JimCarver 0:6b753f761943 135 /* If else than Reset message because Reset message must be empty */
JimCarver 0:6b753f761943 136 if (src_coap_msg_ptr->msg_type != COAP_MSG_TYPE_RESET) {
JimCarver 0:6b753f761943 137 /* * * * * * * * * * * * * * * * * * */
JimCarver 0:6b753f761943 138 /* * * * Options part building * * * */
JimCarver 0:6b753f761943 139 /* * * * * * * * * * * * * * * * * * */
JimCarver 0:6b753f761943 140 sn_coap_builder_options_build(&dst_packet_data_ptr, src_coap_msg_ptr);
JimCarver 0:6b753f761943 141
JimCarver 0:6b753f761943 142 /* * * * * * * * * * * * * * * * * * */
JimCarver 0:6b753f761943 143 /* * * * Payload part building * * * */
JimCarver 0:6b753f761943 144 /* * * * * * * * * * * * * * * * * * */
JimCarver 0:6b753f761943 145 sn_coap_builder_payload_build(&dst_packet_data_ptr, src_coap_msg_ptr);
JimCarver 0:6b753f761943 146 }
JimCarver 0:6b753f761943 147 /* * * * Return built Packet data length * * * */
JimCarver 0:6b753f761943 148 return (dst_packet_data_ptr - base_packet_data_ptr);
JimCarver 0:6b753f761943 149 }
JimCarver 0:6b753f761943 150 uint16_t sn_coap_builder_calc_needed_packet_data_size(sn_coap_hdr_s *src_coap_msg_ptr)
JimCarver 0:6b753f761943 151 {
JimCarver 0:6b753f761943 152 return sn_coap_builder_calc_needed_packet_data_size_2(src_coap_msg_ptr, SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE);
JimCarver 0:6b753f761943 153 }
JimCarver 0:6b753f761943 154
JimCarver 0:6b753f761943 155 uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_msg_ptr, uint16_t blockwise_payload_size)
JimCarver 0:6b753f761943 156 {
JimCarver 0:6b753f761943 157 (void)blockwise_payload_size;
JimCarver 0:6b753f761943 158 uint16_t returned_byte_count = 0;
JimCarver 0:6b753f761943 159
JimCarver 0:6b753f761943 160 if (!src_coap_msg_ptr) {
JimCarver 0:6b753f761943 161 return 0;
JimCarver 0:6b753f761943 162 }
JimCarver 0:6b753f761943 163 /* * * * * HEADER * * * * */
JimCarver 0:6b753f761943 164
JimCarver 0:6b753f761943 165 /* Header size is fixed */
JimCarver 0:6b753f761943 166 returned_byte_count = COAP_HEADER_LENGTH;
JimCarver 0:6b753f761943 167
JimCarver 0:6b753f761943 168 /* * * * * OPTIONS * * * * */
JimCarver 0:6b753f761943 169
JimCarver 0:6b753f761943 170 /* If else than Reset message because Reset message must be empty */
JimCarver 0:6b753f761943 171 if (src_coap_msg_ptr->msg_type != COAP_MSG_TYPE_RESET) {
JimCarver 0:6b753f761943 172 uint16_t repeatable_option_size = 0;
JimCarver 0:6b753f761943 173 /* TOKEN - Length is 1-8 bytes */
JimCarver 0:6b753f761943 174 if (src_coap_msg_ptr->token_ptr != NULL) {
JimCarver 0:6b753f761943 175 if (src_coap_msg_ptr->token_len > 8 || src_coap_msg_ptr->token_len < 1) { /* Check that option is not longer than defined */
JimCarver 0:6b753f761943 176 tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - token too large!");
JimCarver 0:6b753f761943 177 return 0;
JimCarver 0:6b753f761943 178 }
JimCarver 0:6b753f761943 179
JimCarver 0:6b753f761943 180 returned_byte_count += src_coap_msg_ptr->token_len;
JimCarver 0:6b753f761943 181 }
JimCarver 0:6b753f761943 182 /* URI PATH - Repeatable option. Length of one option is 0-255 */
JimCarver 0:6b753f761943 183 if (src_coap_msg_ptr->uri_path_ptr != NULL) {
JimCarver 0:6b753f761943 184 repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->uri_path_len,
JimCarver 0:6b753f761943 185 src_coap_msg_ptr->uri_path_ptr, COAP_OPTION_URI_PATH);
JimCarver 0:6b753f761943 186 if (repeatable_option_size) {
JimCarver 0:6b753f761943 187 returned_byte_count += repeatable_option_size;
JimCarver 0:6b753f761943 188 } else {
JimCarver 0:6b753f761943 189 tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - uri path size failed!");
JimCarver 0:6b753f761943 190 return 0;
JimCarver 0:6b753f761943 191 }
JimCarver 0:6b753f761943 192 }
JimCarver 0:6b753f761943 193
JimCarver 0:6b753f761943 194 uint16_t tempInt = 0;
JimCarver 0:6b753f761943 195 /* CONTENT FORMAT - An integer option, up to 2 bytes */
JimCarver 0:6b753f761943 196 if (src_coap_msg_ptr->content_format != COAP_CT_NONE) {
JimCarver 0:6b753f761943 197 if ((uint32_t) src_coap_msg_ptr->content_format > 0xffff) {
JimCarver 0:6b753f761943 198 tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - content format too large!");
JimCarver 0:6b753f761943 199 return 0;
JimCarver 0:6b753f761943 200 }
JimCarver 0:6b753f761943 201
JimCarver 0:6b753f761943 202 returned_byte_count += sn_coap_builder_options_build_add_uint_option(NULL, src_coap_msg_ptr->content_format, COAP_OPTION_CONTENT_FORMAT, &tempInt);
JimCarver 0:6b753f761943 203 }
JimCarver 0:6b753f761943 204 /* If options list pointer exists */
JimCarver 0:6b753f761943 205 if (src_coap_msg_ptr->options_list_ptr != NULL) {
JimCarver 0:6b753f761943 206 /* ACCEPT - An integer option, up to 2 bytes */
JimCarver 0:6b753f761943 207 if (src_coap_msg_ptr->options_list_ptr->accept != COAP_CT_NONE) {
JimCarver 0:6b753f761943 208 if ((uint32_t) src_coap_msg_ptr->options_list_ptr->accept > 0xffff) {
JimCarver 0:6b753f761943 209 tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - accept too large!");
JimCarver 0:6b753f761943 210 return 0;
JimCarver 0:6b753f761943 211 }
JimCarver 0:6b753f761943 212
JimCarver 0:6b753f761943 213 returned_byte_count += sn_coap_builder_options_build_add_uint_option(NULL, src_coap_msg_ptr->options_list_ptr->accept, COAP_OPTION_ACCEPT, &tempInt);
JimCarver 0:6b753f761943 214 }
JimCarver 0:6b753f761943 215 /* MAX AGE - An integer option, omitted for default. Up to 4 bytes */
JimCarver 0:6b753f761943 216 if (src_coap_msg_ptr->options_list_ptr->max_age != COAP_OPTION_MAX_AGE_DEFAULT) {
JimCarver 0:6b753f761943 217 returned_byte_count += sn_coap_builder_options_build_add_uint_option(NULL, src_coap_msg_ptr->options_list_ptr->max_age, COAP_OPTION_MAX_AGE, &tempInt);
JimCarver 0:6b753f761943 218 }
JimCarver 0:6b753f761943 219 /* PROXY URI - Length of this option is 1-1034 bytes */
JimCarver 0:6b753f761943 220 if (src_coap_msg_ptr->options_list_ptr->proxy_uri_ptr != NULL) {
JimCarver 0:6b753f761943 221 if (src_coap_msg_ptr->options_list_ptr->proxy_uri_len >= 1 && src_coap_msg_ptr->options_list_ptr->proxy_uri_len <= 12) { /* Add option header byte(s) - depending of option length */
JimCarver 0:6b753f761943 222 returned_byte_count++;
JimCarver 0:6b753f761943 223 }
JimCarver 0:6b753f761943 224
JimCarver 0:6b753f761943 225 else if (src_coap_msg_ptr->options_list_ptr->proxy_uri_len >= 13 && src_coap_msg_ptr->options_list_ptr->proxy_uri_len <= 269) {
JimCarver 0:6b753f761943 226 returned_byte_count += 2;
JimCarver 0:6b753f761943 227 }
JimCarver 0:6b753f761943 228
JimCarver 0:6b753f761943 229 else if (src_coap_msg_ptr->options_list_ptr->proxy_uri_len >= 270 && src_coap_msg_ptr->options_list_ptr->proxy_uri_len <= 1034) {
JimCarver 0:6b753f761943 230 returned_byte_count += 3;
JimCarver 0:6b753f761943 231 }
JimCarver 0:6b753f761943 232
JimCarver 0:6b753f761943 233 else {
JimCarver 0:6b753f761943 234 tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - proxy uri too large!");
JimCarver 0:6b753f761943 235 return 0;
JimCarver 0:6b753f761943 236 }
JimCarver 0:6b753f761943 237
JimCarver 0:6b753f761943 238 /* Add needed memory for Option value */
JimCarver 0:6b753f761943 239 returned_byte_count += src_coap_msg_ptr->options_list_ptr->proxy_uri_len;
JimCarver 0:6b753f761943 240 }
JimCarver 0:6b753f761943 241 /* ETAG - Repeatable option. Length of this option is 1-8 bytes*/
JimCarver 0:6b753f761943 242 if (src_coap_msg_ptr->options_list_ptr->etag_ptr != NULL) {
JimCarver 0:6b753f761943 243 repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->options_list_ptr->etag_len,
JimCarver 0:6b753f761943 244 src_coap_msg_ptr->options_list_ptr->etag_ptr, COAP_OPTION_ETAG);
JimCarver 0:6b753f761943 245 if (repeatable_option_size) {
JimCarver 0:6b753f761943 246 returned_byte_count += repeatable_option_size;
JimCarver 0:6b753f761943 247 } else {
JimCarver 0:6b753f761943 248 tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - etag too large!");
JimCarver 0:6b753f761943 249 return 0;
JimCarver 0:6b753f761943 250 }
JimCarver 0:6b753f761943 251 }
JimCarver 0:6b753f761943 252 /* URI HOST - Length of this option is 1-255 bytes */
JimCarver 0:6b753f761943 253 if (src_coap_msg_ptr->options_list_ptr->uri_host_ptr != NULL) {
JimCarver 0:6b753f761943 254 if (src_coap_msg_ptr->options_list_ptr->uri_host_len > 0 && src_coap_msg_ptr->options_list_ptr->uri_host_len <= 12) {
JimCarver 0:6b753f761943 255 returned_byte_count++;
JimCarver 0:6b753f761943 256 }
JimCarver 0:6b753f761943 257
JimCarver 0:6b753f761943 258 else if (src_coap_msg_ptr->options_list_ptr->uri_host_len >= 13 && src_coap_msg_ptr->options_list_ptr->uri_host_len <= 255) {
JimCarver 0:6b753f761943 259 returned_byte_count += 2;
JimCarver 0:6b753f761943 260 }
JimCarver 0:6b753f761943 261
JimCarver 0:6b753f761943 262 else {
JimCarver 0:6b753f761943 263 tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - uri host too large!");
JimCarver 0:6b753f761943 264 return 0;
JimCarver 0:6b753f761943 265 }
JimCarver 0:6b753f761943 266
JimCarver 0:6b753f761943 267 returned_byte_count += src_coap_msg_ptr->options_list_ptr->uri_host_len;
JimCarver 0:6b753f761943 268 }
JimCarver 0:6b753f761943 269 /* LOCATION PATH - Repeatable option. Length of this option is 0-255 bytes*/
JimCarver 0:6b753f761943 270 if (src_coap_msg_ptr->options_list_ptr->location_path_ptr != NULL) {
JimCarver 0:6b753f761943 271 repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->options_list_ptr->location_path_len,
JimCarver 0:6b753f761943 272 src_coap_msg_ptr->options_list_ptr->location_path_ptr, COAP_OPTION_LOCATION_PATH);
JimCarver 0:6b753f761943 273 if (repeatable_option_size) {
JimCarver 0:6b753f761943 274 returned_byte_count += repeatable_option_size;
JimCarver 0:6b753f761943 275 } else {
JimCarver 0:6b753f761943 276 tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - location path too large!");
JimCarver 0:6b753f761943 277 return 0;
JimCarver 0:6b753f761943 278 }
JimCarver 0:6b753f761943 279 }
JimCarver 0:6b753f761943 280 /* URI PORT - An integer option, up to 2 bytes */
JimCarver 0:6b753f761943 281 if (src_coap_msg_ptr->options_list_ptr->uri_port != COAP_OPTION_URI_PORT_NONE) {
JimCarver 0:6b753f761943 282 if ((uint32_t) src_coap_msg_ptr->options_list_ptr->uri_port > 0xffff) {
JimCarver 0:6b753f761943 283 tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - uri port too large!");
JimCarver 0:6b753f761943 284 return 0;
JimCarver 0:6b753f761943 285 }
JimCarver 0:6b753f761943 286 returned_byte_count += sn_coap_builder_options_build_add_uint_option(NULL, src_coap_msg_ptr->options_list_ptr->uri_port, COAP_OPTION_URI_PORT, &tempInt);
JimCarver 0:6b753f761943 287 }
JimCarver 0:6b753f761943 288 /* lOCATION QUERY - Repeatable option. Length of this option is 0-255 bytes */
JimCarver 0:6b753f761943 289 if (src_coap_msg_ptr->options_list_ptr->location_query_ptr != NULL) {
JimCarver 0:6b753f761943 290 repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->options_list_ptr->location_query_len,
JimCarver 0:6b753f761943 291 src_coap_msg_ptr->options_list_ptr->location_query_ptr, COAP_OPTION_LOCATION_QUERY);
JimCarver 0:6b753f761943 292 if (repeatable_option_size) {
JimCarver 0:6b753f761943 293 returned_byte_count += repeatable_option_size;
JimCarver 0:6b753f761943 294 } else {
JimCarver 0:6b753f761943 295 tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - location query too large!");
JimCarver 0:6b753f761943 296 return 0;
JimCarver 0:6b753f761943 297 }
JimCarver 0:6b753f761943 298 }
JimCarver 0:6b753f761943 299 /* OBSERVE - An integer option, up to 3 bytes */
JimCarver 0:6b753f761943 300 if (src_coap_msg_ptr->options_list_ptr->observe != COAP_OBSERVE_NONE) {
JimCarver 0:6b753f761943 301 if ((uint32_t) src_coap_msg_ptr->options_list_ptr->observe > 0xffffff) {
JimCarver 0:6b753f761943 302 return 0;
JimCarver 0:6b753f761943 303 }
JimCarver 0:6b753f761943 304 returned_byte_count += sn_coap_builder_options_build_add_uint_option(NULL, src_coap_msg_ptr->options_list_ptr->observe, COAP_OPTION_OBSERVE, &tempInt);
JimCarver 0:6b753f761943 305 }
JimCarver 0:6b753f761943 306 /* URI QUERY - Repeatable option. Length of this option is 1-255 */
JimCarver 0:6b753f761943 307 if (src_coap_msg_ptr->options_list_ptr->uri_query_ptr != NULL) {
JimCarver 0:6b753f761943 308 repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->options_list_ptr->uri_query_len,
JimCarver 0:6b753f761943 309 src_coap_msg_ptr->options_list_ptr->uri_query_ptr, COAP_OPTION_URI_QUERY);
JimCarver 0:6b753f761943 310 if (repeatable_option_size) {
JimCarver 0:6b753f761943 311 returned_byte_count += repeatable_option_size;
JimCarver 0:6b753f761943 312 } else {
JimCarver 0:6b753f761943 313 tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - observe too large!");
JimCarver 0:6b753f761943 314 return 0;
JimCarver 0:6b753f761943 315 }
JimCarver 0:6b753f761943 316 }
JimCarver 0:6b753f761943 317
JimCarver 0:6b753f761943 318 /* BLOCK 1 - An integer option, up to 3 bytes */
JimCarver 0:6b753f761943 319 if (src_coap_msg_ptr->options_list_ptr->block1 != COAP_OPTION_BLOCK_NONE) {
JimCarver 0:6b753f761943 320 if ((uint32_t) src_coap_msg_ptr->options_list_ptr->block1 > 0xffffff) {
JimCarver 0:6b753f761943 321 tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - block1 too large!");
JimCarver 0:6b753f761943 322 return 0;
JimCarver 0:6b753f761943 323 }
JimCarver 0:6b753f761943 324 returned_byte_count += sn_coap_builder_options_build_add_uint_option(NULL, src_coap_msg_ptr->options_list_ptr->block1, COAP_OPTION_BLOCK1, &tempInt);
JimCarver 0:6b753f761943 325 }
JimCarver 0:6b753f761943 326 /* SIZE1 - Length of this option is 0-4 bytes */
JimCarver 0:6b753f761943 327 if (src_coap_msg_ptr->options_list_ptr->use_size1) {
JimCarver 0:6b753f761943 328 returned_byte_count += sn_coap_builder_options_build_add_uint_option(NULL, src_coap_msg_ptr->options_list_ptr->size1, COAP_OPTION_SIZE1, &tempInt);
JimCarver 0:6b753f761943 329 }
JimCarver 0:6b753f761943 330 /* BLOCK 2 - An integer option, up to 3 bytes */
JimCarver 0:6b753f761943 331 if (src_coap_msg_ptr->options_list_ptr->block2 != COAP_OPTION_BLOCK_NONE) {
JimCarver 0:6b753f761943 332 if ((uint32_t) src_coap_msg_ptr->options_list_ptr->block2 > 0xffffff) {
JimCarver 0:6b753f761943 333 tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - block2 too large!");
JimCarver 0:6b753f761943 334 return 0;
JimCarver 0:6b753f761943 335 }
JimCarver 0:6b753f761943 336 returned_byte_count += sn_coap_builder_options_build_add_uint_option(NULL, src_coap_msg_ptr->options_list_ptr->block2, COAP_OPTION_BLOCK2, &tempInt);
JimCarver 0:6b753f761943 337 }
JimCarver 0:6b753f761943 338 /* SIZE2 - Length of this option is 0-4 bytes */
JimCarver 0:6b753f761943 339 if (src_coap_msg_ptr->options_list_ptr->use_size2) {
JimCarver 0:6b753f761943 340 returned_byte_count += sn_coap_builder_options_build_add_uint_option(NULL, src_coap_msg_ptr->options_list_ptr->size2, COAP_OPTION_SIZE2, &tempInt);
JimCarver 0:6b753f761943 341 }
JimCarver 0:6b753f761943 342 }
JimCarver 0:6b753f761943 343 #if SN_COAP_BLOCKWISE_ENABLED || SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
JimCarver 0:6b753f761943 344 if ((src_coap_msg_ptr->payload_len > SN_COAP_MAX_NONBLOCKWISE_PAYLOAD_SIZE) &&
JimCarver 0:6b753f761943 345 (src_coap_msg_ptr->payload_len > blockwise_payload_size) &&
JimCarver 0:6b753f761943 346 (blockwise_payload_size > 0)) {
JimCarver 0:6b753f761943 347 returned_byte_count += blockwise_payload_size;
JimCarver 0:6b753f761943 348 } else {
JimCarver 0:6b753f761943 349 returned_byte_count += src_coap_msg_ptr->payload_len;
JimCarver 0:6b753f761943 350 }
JimCarver 0:6b753f761943 351 #else
JimCarver 0:6b753f761943 352 returned_byte_count += src_coap_msg_ptr->payload_len;
JimCarver 0:6b753f761943 353 #endif
JimCarver 0:6b753f761943 354 if (src_coap_msg_ptr->payload_len) {
JimCarver 0:6b753f761943 355 returned_byte_count ++; /* For payload marker */
JimCarver 0:6b753f761943 356 }
JimCarver 0:6b753f761943 357 returned_byte_count += sn_coap_builder_options_calculate_jump_need(src_coap_msg_ptr/*, 0*/);
JimCarver 0:6b753f761943 358 }
JimCarver 0:6b753f761943 359 return returned_byte_count;
JimCarver 0:6b753f761943 360 }
JimCarver 0:6b753f761943 361 /**
JimCarver 0:6b753f761943 362 * \fn static uint8_t sn_coap_builder_options_calculate_jump_need(sn_coap_hdr_s *src_coap_msg_ptr, uint8_t block_option)
JimCarver 0:6b753f761943 363 *
JimCarver 0:6b753f761943 364 * \brief Checks if there is need for option jump
JimCarver 0:6b753f761943 365 *
JimCarver 0:6b753f761943 366 * \param *src_coap_msg_ptr is source of checked CoAP message
JimCarver 0:6b753f761943 367 *
JimCarver 0:6b753f761943 368 * \param block option marks if block option is to be added to message later. 0 = no block option, 1 = block1 and 2 = block2
JimCarver 0:6b753f761943 369 *
JimCarver 0:6b753f761943 370 * \return Returns bytes needed for jumping
JimCarver 0:6b753f761943 371 */
JimCarver 0:6b753f761943 372
JimCarver 0:6b753f761943 373 static uint8_t sn_coap_builder_options_calculate_jump_need(sn_coap_hdr_s *src_coap_msg_ptr/*, uint8_t block_option*/)
JimCarver 0:6b753f761943 374 {
JimCarver 0:6b753f761943 375 uint8_t previous_option_number = 0;
JimCarver 0:6b753f761943 376 uint8_t needed_space = 0;
JimCarver 0:6b753f761943 377
JimCarver 0:6b753f761943 378 if (src_coap_msg_ptr->options_list_ptr != NULL) {
JimCarver 0:6b753f761943 379 /* If option numbers greater than 12 is not used, then jumping is not needed */
JimCarver 0:6b753f761943 380 //TODO: Check if this is really needed! Does it enhance perf? If not -> remove
JimCarver 0:6b753f761943 381 if (!src_coap_msg_ptr->options_list_ptr->uri_query_ptr &&
JimCarver 0:6b753f761943 382 src_coap_msg_ptr->options_list_ptr->accept == COAP_CT_NONE &&
JimCarver 0:6b753f761943 383 !src_coap_msg_ptr->options_list_ptr->location_query_ptr &&
JimCarver 0:6b753f761943 384 src_coap_msg_ptr->options_list_ptr->block2 == COAP_OPTION_BLOCK_NONE &&
JimCarver 0:6b753f761943 385 src_coap_msg_ptr->options_list_ptr->block1 == COAP_OPTION_BLOCK_NONE &&
JimCarver 0:6b753f761943 386 !src_coap_msg_ptr->options_list_ptr->proxy_uri_ptr &&
JimCarver 0:6b753f761943 387 src_coap_msg_ptr->options_list_ptr->max_age == COAP_OPTION_MAX_AGE_DEFAULT &&
JimCarver 0:6b753f761943 388 !src_coap_msg_ptr->options_list_ptr->use_size1 &&
JimCarver 0:6b753f761943 389 !src_coap_msg_ptr->options_list_ptr->use_size2) {
JimCarver 0:6b753f761943 390 return 0;
JimCarver 0:6b753f761943 391 }
JimCarver 0:6b753f761943 392
JimCarver 0:6b753f761943 393 if (src_coap_msg_ptr->options_list_ptr->uri_host_ptr != NULL) {
JimCarver 0:6b753f761943 394 previous_option_number = (COAP_OPTION_URI_HOST);
JimCarver 0:6b753f761943 395 }
JimCarver 0:6b753f761943 396
JimCarver 0:6b753f761943 397 if (src_coap_msg_ptr->options_list_ptr->etag_ptr != NULL) {
JimCarver 0:6b753f761943 398 previous_option_number = (COAP_OPTION_ETAG);
JimCarver 0:6b753f761943 399 }
JimCarver 0:6b753f761943 400
JimCarver 0:6b753f761943 401 if (src_coap_msg_ptr->options_list_ptr->observe != COAP_OBSERVE_NONE) {
JimCarver 0:6b753f761943 402 previous_option_number = (COAP_OPTION_OBSERVE);
JimCarver 0:6b753f761943 403 }
JimCarver 0:6b753f761943 404
JimCarver 0:6b753f761943 405 if (src_coap_msg_ptr->options_list_ptr->uri_port != COAP_OPTION_URI_PORT_NONE) {
JimCarver 0:6b753f761943 406 previous_option_number = (COAP_OPTION_URI_PORT);
JimCarver 0:6b753f761943 407 }
JimCarver 0:6b753f761943 408
JimCarver 0:6b753f761943 409 if (src_coap_msg_ptr->options_list_ptr->location_path_ptr != NULL) {
JimCarver 0:6b753f761943 410 previous_option_number = (COAP_OPTION_LOCATION_PATH);
JimCarver 0:6b753f761943 411 }
JimCarver 0:6b753f761943 412
JimCarver 0:6b753f761943 413 if (src_coap_msg_ptr->uri_path_ptr != NULL) {
JimCarver 0:6b753f761943 414 previous_option_number = (COAP_OPTION_URI_PATH);
JimCarver 0:6b753f761943 415 }
JimCarver 0:6b753f761943 416 if (src_coap_msg_ptr->content_format != COAP_CT_NONE) {
JimCarver 0:6b753f761943 417 previous_option_number = (COAP_OPTION_CONTENT_FORMAT);
JimCarver 0:6b753f761943 418 }
JimCarver 0:6b753f761943 419 if (src_coap_msg_ptr->options_list_ptr->max_age != COAP_OPTION_MAX_AGE_DEFAULT) {
JimCarver 0:6b753f761943 420 if ((COAP_OPTION_MAX_AGE - previous_option_number) > 12) {
JimCarver 0:6b753f761943 421 needed_space += 1;
JimCarver 0:6b753f761943 422 }
JimCarver 0:6b753f761943 423 previous_option_number = (COAP_OPTION_MAX_AGE);
JimCarver 0:6b753f761943 424 }
JimCarver 0:6b753f761943 425
JimCarver 0:6b753f761943 426 if (src_coap_msg_ptr->options_list_ptr->uri_query_ptr != NULL) {
JimCarver 0:6b753f761943 427 if ((COAP_OPTION_URI_QUERY - previous_option_number) > 12) {
JimCarver 0:6b753f761943 428 needed_space += 1;
JimCarver 0:6b753f761943 429 }
JimCarver 0:6b753f761943 430 previous_option_number = (COAP_OPTION_URI_QUERY);
JimCarver 0:6b753f761943 431 }
JimCarver 0:6b753f761943 432 if (src_coap_msg_ptr->options_list_ptr->accept != COAP_CT_NONE) {
JimCarver 0:6b753f761943 433 if ((COAP_OPTION_ACCEPT - previous_option_number) > 12) {
JimCarver 0:6b753f761943 434 needed_space += 1;
JimCarver 0:6b753f761943 435 }
JimCarver 0:6b753f761943 436 previous_option_number = (COAP_OPTION_ACCEPT);
JimCarver 0:6b753f761943 437 }
JimCarver 0:6b753f761943 438 if (src_coap_msg_ptr->options_list_ptr->location_query_ptr != NULL) {
JimCarver 0:6b753f761943 439 if ((COAP_OPTION_LOCATION_QUERY - previous_option_number) > 12) {
JimCarver 0:6b753f761943 440 needed_space += 1;
JimCarver 0:6b753f761943 441 }
JimCarver 0:6b753f761943 442 previous_option_number = (COAP_OPTION_LOCATION_QUERY);
JimCarver 0:6b753f761943 443 }
JimCarver 0:6b753f761943 444 if (src_coap_msg_ptr->options_list_ptr->block2 != COAP_OPTION_BLOCK_NONE) {
JimCarver 0:6b753f761943 445 if ((COAP_OPTION_BLOCK2 - previous_option_number) > 12 ){
JimCarver 0:6b753f761943 446 needed_space += 1;
JimCarver 0:6b753f761943 447 }
JimCarver 0:6b753f761943 448 previous_option_number = (COAP_OPTION_BLOCK2);
JimCarver 0:6b753f761943 449 }
JimCarver 0:6b753f761943 450 if (src_coap_msg_ptr->options_list_ptr->block1 != COAP_OPTION_BLOCK_NONE) {
JimCarver 0:6b753f761943 451 if ((COAP_OPTION_BLOCK1 - previous_option_number) > 12 ){
JimCarver 0:6b753f761943 452 needed_space += 1;
JimCarver 0:6b753f761943 453 }
JimCarver 0:6b753f761943 454 previous_option_number = (COAP_OPTION_BLOCK1);
JimCarver 0:6b753f761943 455 }
JimCarver 0:6b753f761943 456 if (src_coap_msg_ptr->options_list_ptr->use_size2) {
JimCarver 0:6b753f761943 457 if ((COAP_OPTION_SIZE2 - previous_option_number) > 12) {
JimCarver 0:6b753f761943 458 needed_space += 1;
JimCarver 0:6b753f761943 459 }
JimCarver 0:6b753f761943 460 previous_option_number = (COAP_OPTION_SIZE2);
JimCarver 0:6b753f761943 461 }
JimCarver 0:6b753f761943 462 if (src_coap_msg_ptr->options_list_ptr->proxy_uri_ptr != NULL) {
JimCarver 0:6b753f761943 463 if ((COAP_OPTION_PROXY_URI - previous_option_number) > 12) {
JimCarver 0:6b753f761943 464 needed_space += 1;
JimCarver 0:6b753f761943 465 }
JimCarver 0:6b753f761943 466 if ((COAP_OPTION_PROXY_URI - previous_option_number) > 269) { //Can not happen
JimCarver 0:6b753f761943 467 needed_space += 1;
JimCarver 0:6b753f761943 468 }
JimCarver 0:6b753f761943 469 previous_option_number = (COAP_OPTION_PROXY_URI);
JimCarver 0:6b753f761943 470 }
JimCarver 0:6b753f761943 471 if (src_coap_msg_ptr->options_list_ptr->use_size1 ) {
JimCarver 0:6b753f761943 472 if ((COAP_OPTION_SIZE1 - previous_option_number) > 12) {
JimCarver 0:6b753f761943 473 needed_space += 1;
JimCarver 0:6b753f761943 474 }
JimCarver 0:6b753f761943 475 previous_option_number = (COAP_OPTION_SIZE1);
JimCarver 0:6b753f761943 476 }
JimCarver 0:6b753f761943 477 }
JimCarver 0:6b753f761943 478
JimCarver 0:6b753f761943 479 else {
JimCarver 0:6b753f761943 480 if (src_coap_msg_ptr->uri_path_ptr != 0) {
JimCarver 0:6b753f761943 481 previous_option_number = (COAP_OPTION_URI_PATH);
JimCarver 0:6b753f761943 482 }
JimCarver 0:6b753f761943 483
JimCarver 0:6b753f761943 484 if (src_coap_msg_ptr->content_format != COAP_CT_NONE) {
JimCarver 0:6b753f761943 485 previous_option_number = (COAP_OPTION_CONTENT_FORMAT);
JimCarver 0:6b753f761943 486 }
JimCarver 0:6b753f761943 487 }
JimCarver 0:6b753f761943 488 return needed_space;
JimCarver 0:6b753f761943 489 }
JimCarver 0:6b753f761943 490
JimCarver 0:6b753f761943 491 /**
JimCarver 0:6b753f761943 492 * \fn static int8_t sn_coap_builder_header_build(uint8_t **dst_packet_data_pptr, sn_coap_hdr_s *src_coap_msg_ptr)
JimCarver 0:6b753f761943 493 *
JimCarver 0:6b753f761943 494 * \brief Builds Header part of Packet data
JimCarver 0:6b753f761943 495 *
JimCarver 0:6b753f761943 496 * \param **dst_packet_data_pptr is destination for built Packet data
JimCarver 0:6b753f761943 497 *
JimCarver 0:6b753f761943 498 * \param *src_coap_msg_ptr is source for building Packet data
JimCarver 0:6b753f761943 499 *
JimCarver 0:6b753f761943 500 * \return Return value is 0 in ok case and -1 in failure case
JimCarver 0:6b753f761943 501 **************************************************************************** */
JimCarver 0:6b753f761943 502 static int8_t sn_coap_builder_header_build(uint8_t **dst_packet_data_pptr, sn_coap_hdr_s *src_coap_msg_ptr)
JimCarver 0:6b753f761943 503 {
JimCarver 0:6b753f761943 504 /* * * * Check validity of Header values * * * */
JimCarver 0:6b753f761943 505 if (sn_coap_header_validity_check(src_coap_msg_ptr, COAP_VERSION) != 0) {
JimCarver 0:6b753f761943 506 tr_error("sn_coap_builder_header_build - header build failed!");
JimCarver 0:6b753f761943 507 return -1;
JimCarver 0:6b753f761943 508 }
JimCarver 0:6b753f761943 509
JimCarver 0:6b753f761943 510 /* * * Add CoAP Version * * */
JimCarver 0:6b753f761943 511 **dst_packet_data_pptr += COAP_VERSION;
JimCarver 0:6b753f761943 512
JimCarver 0:6b753f761943 513 /* * * Add Message type * * */
JimCarver 0:6b753f761943 514 **dst_packet_data_pptr += src_coap_msg_ptr->msg_type;
JimCarver 0:6b753f761943 515
JimCarver 0:6b753f761943 516 /* * * Add Token length * * */
JimCarver 0:6b753f761943 517 **dst_packet_data_pptr += (src_coap_msg_ptr->token_len);
JimCarver 0:6b753f761943 518
JimCarver 0:6b753f761943 519 (*dst_packet_data_pptr) ++;
JimCarver 0:6b753f761943 520 /* * * Add Message code * * */
JimCarver 0:6b753f761943 521 **dst_packet_data_pptr = src_coap_msg_ptr->msg_code;
JimCarver 0:6b753f761943 522 (*dst_packet_data_pptr) ++;
JimCarver 0:6b753f761943 523
JimCarver 0:6b753f761943 524 /* * * Add Message ID * * */
JimCarver 0:6b753f761943 525 **dst_packet_data_pptr = (uint8_t)(src_coap_msg_ptr->msg_id >> COAP_HEADER_MSG_ID_MSB_SHIFT); /* MSB part */
JimCarver 0:6b753f761943 526 (*dst_packet_data_pptr) ++;
JimCarver 0:6b753f761943 527 **dst_packet_data_pptr = (uint8_t)src_coap_msg_ptr->msg_id; /* LSB part */
JimCarver 0:6b753f761943 528 (*dst_packet_data_pptr) ++;
JimCarver 0:6b753f761943 529
JimCarver 0:6b753f761943 530 /* Success */
JimCarver 0:6b753f761943 531 return 0;
JimCarver 0:6b753f761943 532 }
JimCarver 0:6b753f761943 533
JimCarver 0:6b753f761943 534 /**
JimCarver 0:6b753f761943 535 * \fn static int8_t sn_coap_builder_options_build(uint8_t **dst_packet_data_pptr, sn_coap_hdr_s *src_coap_msg_ptr)
JimCarver 0:6b753f761943 536 *
JimCarver 0:6b753f761943 537 * \brief Builds Options part of Packet data
JimCarver 0:6b753f761943 538 *
JimCarver 0:6b753f761943 539 * \param **dst_packet_data_pptr is destination for built Packet data
JimCarver 0:6b753f761943 540 *
JimCarver 0:6b753f761943 541 * \param *src_coap_msg_ptr is source for building Packet data
JimCarver 0:6b753f761943 542 *
JimCarver 0:6b753f761943 543 * \return Return value is 0 in every case
JimCarver 0:6b753f761943 544 */
JimCarver 0:6b753f761943 545 static int8_t sn_coap_builder_options_build(uint8_t **dst_packet_data_pptr, sn_coap_hdr_s *src_coap_msg_ptr)
JimCarver 0:6b753f761943 546 {
JimCarver 0:6b753f761943 547 /* * * * Check if Options are used at all * * * */
JimCarver 0:6b753f761943 548 if (src_coap_msg_ptr->uri_path_ptr == NULL && src_coap_msg_ptr->token_ptr == NULL &&
JimCarver 0:6b753f761943 549 src_coap_msg_ptr->content_format == COAP_CT_NONE && src_coap_msg_ptr->options_list_ptr == NULL) {
JimCarver 0:6b753f761943 550 tr_error("sn_coap_builder_options_build - options not used!");
JimCarver 0:6b753f761943 551 return 0;
JimCarver 0:6b753f761943 552 }
JimCarver 0:6b753f761943 553
JimCarver 0:6b753f761943 554 /* * * * First add Token option * * * */
JimCarver 0:6b753f761943 555 if (src_coap_msg_ptr->token_len && src_coap_msg_ptr->token_ptr) {
JimCarver 0:6b753f761943 556 memcpy(*dst_packet_data_pptr, src_coap_msg_ptr->token_ptr, src_coap_msg_ptr->token_len);
JimCarver 0:6b753f761943 557 }
JimCarver 0:6b753f761943 558 (*dst_packet_data_pptr) += src_coap_msg_ptr->token_len;
JimCarver 0:6b753f761943 559
JimCarver 0:6b753f761943 560 /* Then build rest of the options */
JimCarver 0:6b753f761943 561
JimCarver 0:6b753f761943 562 /* * * * Initialize previous Option number for new built message * * * */
JimCarver 0:6b753f761943 563 uint16_t previous_option_number = 0;
JimCarver 0:6b753f761943 564
JimCarver 0:6b753f761943 565 //missing: COAP_OPTION_IF_MATCH, COAP_OPTION_IF_NONE_MATCH, COAP_OPTION_SIZE
JimCarver 0:6b753f761943 566
JimCarver 0:6b753f761943 567 /* Check if less used options are used at all */
JimCarver 0:6b753f761943 568 if (src_coap_msg_ptr->options_list_ptr != NULL) {
JimCarver 0:6b753f761943 569 /* * * * Build Uri-Host option * * * */
JimCarver 0:6b753f761943 570 sn_coap_builder_options_build_add_one_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->uri_host_len,
JimCarver 0:6b753f761943 571 src_coap_msg_ptr->options_list_ptr->uri_host_ptr, COAP_OPTION_URI_HOST, &previous_option_number);
JimCarver 0:6b753f761943 572
JimCarver 0:6b753f761943 573 /* * * * Build ETag option * * * */
JimCarver 0:6b753f761943 574 sn_coap_builder_options_build_add_multiple_option(dst_packet_data_pptr, &src_coap_msg_ptr->options_list_ptr->etag_ptr,
JimCarver 0:6b753f761943 575 (uint16_t *)&src_coap_msg_ptr->options_list_ptr->etag_len, COAP_OPTION_ETAG, &previous_option_number);
JimCarver 0:6b753f761943 576
JimCarver 0:6b753f761943 577 /* * * * Build Observe option * * * * */
JimCarver 0:6b753f761943 578 if (src_coap_msg_ptr->options_list_ptr->observe != COAP_OBSERVE_NONE) {
JimCarver 0:6b753f761943 579 sn_coap_builder_options_build_add_uint_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->observe,
JimCarver 0:6b753f761943 580 COAP_OPTION_OBSERVE, &previous_option_number);
JimCarver 0:6b753f761943 581 }
JimCarver 0:6b753f761943 582
JimCarver 0:6b753f761943 583 /* * * * Build Uri-Port option * * * */
JimCarver 0:6b753f761943 584 if (src_coap_msg_ptr->options_list_ptr->uri_port != COAP_OPTION_URI_PORT_NONE) {
JimCarver 0:6b753f761943 585 sn_coap_builder_options_build_add_uint_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->uri_port,
JimCarver 0:6b753f761943 586 COAP_OPTION_URI_PORT, &previous_option_number);
JimCarver 0:6b753f761943 587 }
JimCarver 0:6b753f761943 588
JimCarver 0:6b753f761943 589 /* * * * Build Location-Path option * * * */
JimCarver 0:6b753f761943 590 sn_coap_builder_options_build_add_multiple_option(dst_packet_data_pptr, &src_coap_msg_ptr->options_list_ptr->location_path_ptr,
JimCarver 0:6b753f761943 591 &src_coap_msg_ptr->options_list_ptr->location_path_len, COAP_OPTION_LOCATION_PATH, &previous_option_number);
JimCarver 0:6b753f761943 592 }
JimCarver 0:6b753f761943 593 /* * * * Build Uri-Path option * * * */
JimCarver 0:6b753f761943 594 sn_coap_builder_options_build_add_multiple_option(dst_packet_data_pptr, &src_coap_msg_ptr->uri_path_ptr,
JimCarver 0:6b753f761943 595 &src_coap_msg_ptr->uri_path_len, COAP_OPTION_URI_PATH, &previous_option_number);
JimCarver 0:6b753f761943 596
JimCarver 0:6b753f761943 597 /* * * * Build Content-Type option * * * */
JimCarver 0:6b753f761943 598 if (src_coap_msg_ptr->content_format != COAP_CT_NONE) {
JimCarver 0:6b753f761943 599 sn_coap_builder_options_build_add_uint_option(dst_packet_data_pptr, src_coap_msg_ptr->content_format,
JimCarver 0:6b753f761943 600 COAP_OPTION_CONTENT_FORMAT, &previous_option_number);
JimCarver 0:6b753f761943 601 }
JimCarver 0:6b753f761943 602
JimCarver 0:6b753f761943 603 if (src_coap_msg_ptr->options_list_ptr != NULL) {
JimCarver 0:6b753f761943 604 /* * * * Build Max-Age option * * * */
JimCarver 0:6b753f761943 605 if (src_coap_msg_ptr->options_list_ptr->max_age != COAP_OPTION_MAX_AGE_DEFAULT) {
JimCarver 0:6b753f761943 606 sn_coap_builder_options_build_add_uint_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->max_age,
JimCarver 0:6b753f761943 607 COAP_OPTION_MAX_AGE, &previous_option_number);
JimCarver 0:6b753f761943 608 }
JimCarver 0:6b753f761943 609
JimCarver 0:6b753f761943 610 /* * * * Build Uri-Query option * * * * */
JimCarver 0:6b753f761943 611 sn_coap_builder_options_build_add_multiple_option(dst_packet_data_pptr, &src_coap_msg_ptr->options_list_ptr->uri_query_ptr,
JimCarver 0:6b753f761943 612 &src_coap_msg_ptr->options_list_ptr->uri_query_len, COAP_OPTION_URI_QUERY, &previous_option_number);
JimCarver 0:6b753f761943 613
JimCarver 0:6b753f761943 614 /* * * * Build Accept option * * * * */
JimCarver 0:6b753f761943 615 if (src_coap_msg_ptr->options_list_ptr->accept != COAP_CT_NONE) {
JimCarver 0:6b753f761943 616 sn_coap_builder_options_build_add_uint_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->accept,
JimCarver 0:6b753f761943 617 COAP_OPTION_ACCEPT, &previous_option_number);
JimCarver 0:6b753f761943 618 }
JimCarver 0:6b753f761943 619 }
JimCarver 0:6b753f761943 620
JimCarver 0:6b753f761943 621 if (src_coap_msg_ptr->options_list_ptr != NULL) {
JimCarver 0:6b753f761943 622 /* * * * Build Location-Query option * * * */
JimCarver 0:6b753f761943 623 sn_coap_builder_options_build_add_multiple_option(dst_packet_data_pptr, &src_coap_msg_ptr->options_list_ptr->location_query_ptr,
JimCarver 0:6b753f761943 624 &src_coap_msg_ptr->options_list_ptr->location_query_len, COAP_OPTION_LOCATION_QUERY, &previous_option_number);
JimCarver 0:6b753f761943 625
JimCarver 0:6b753f761943 626 /* * * * Build Block2 option * * * * */
JimCarver 0:6b753f761943 627 if (src_coap_msg_ptr->options_list_ptr->block2 != COAP_OPTION_BLOCK_NONE) {
JimCarver 0:6b753f761943 628 sn_coap_builder_options_build_add_uint_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->block2,
JimCarver 0:6b753f761943 629 COAP_OPTION_BLOCK2, &previous_option_number);
JimCarver 0:6b753f761943 630 }
JimCarver 0:6b753f761943 631
JimCarver 0:6b753f761943 632 /* * * * Build Block1 option * * * * */
JimCarver 0:6b753f761943 633 if (src_coap_msg_ptr->options_list_ptr->block1 != COAP_OPTION_BLOCK_NONE) {
JimCarver 0:6b753f761943 634 sn_coap_builder_options_build_add_uint_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->block1,
JimCarver 0:6b753f761943 635 COAP_OPTION_BLOCK1, &previous_option_number);
JimCarver 0:6b753f761943 636 }
JimCarver 0:6b753f761943 637
JimCarver 0:6b753f761943 638 /* * * * Build Size2 option * * * */
JimCarver 0:6b753f761943 639 if (src_coap_msg_ptr->options_list_ptr->use_size2) {
JimCarver 0:6b753f761943 640 sn_coap_builder_options_build_add_uint_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->size2,
JimCarver 0:6b753f761943 641 COAP_OPTION_SIZE2, &previous_option_number);
JimCarver 0:6b753f761943 642 }
JimCarver 0:6b753f761943 643
JimCarver 0:6b753f761943 644 /* * * * Build Proxy-Uri option * * * */
JimCarver 0:6b753f761943 645 sn_coap_builder_options_build_add_one_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->proxy_uri_len,
JimCarver 0:6b753f761943 646 src_coap_msg_ptr->options_list_ptr->proxy_uri_ptr, COAP_OPTION_PROXY_URI, &previous_option_number);
JimCarver 0:6b753f761943 647
JimCarver 0:6b753f761943 648
JimCarver 0:6b753f761943 649 /* * * * Build Size1 option * * * */
JimCarver 0:6b753f761943 650 if (src_coap_msg_ptr->options_list_ptr->use_size1) {
JimCarver 0:6b753f761943 651 sn_coap_builder_options_build_add_uint_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->size1,
JimCarver 0:6b753f761943 652 COAP_OPTION_SIZE1, &previous_option_number);
JimCarver 0:6b753f761943 653 }
JimCarver 0:6b753f761943 654 }
JimCarver 0:6b753f761943 655
JimCarver 0:6b753f761943 656 /* Success */
JimCarver 0:6b753f761943 657 return 0;
JimCarver 0:6b753f761943 658 }
JimCarver 0:6b753f761943 659
JimCarver 0:6b753f761943 660 /**
JimCarver 0:6b753f761943 661 * \fn static int16_t sn_coap_builder_options_build_add_one_option(uint8_t **dst_packet_data_pptr, uint16_t option_value_len, uint8_t *option_value_ptr, sn_coap_option_numbers_e option_number)
JimCarver 0:6b753f761943 662 *
JimCarver 0:6b753f761943 663 * \brief Adds Options part of Packet data
JimCarver 0:6b753f761943 664 *
JimCarver 0:6b753f761943 665 * \param **dst_packet_data_pptr is destination for built Packet data
JimCarver 0:6b753f761943 666 *
JimCarver 0:6b753f761943 667 * \param option_value_len is Option value length to be added
JimCarver 0:6b753f761943 668 *
JimCarver 0:6b753f761943 669 * \param *option_value_ptr is pointer to Option value data to be added
JimCarver 0:6b753f761943 670 *
JimCarver 0:6b753f761943 671 * \param option_number is Option number to be added
JimCarver 0:6b753f761943 672 *
JimCarver 0:6b753f761943 673 * \return Return value is 0 if option was not added, 1 if added
JimCarver 0:6b753f761943 674 */
JimCarver 0:6b753f761943 675 static int16_t sn_coap_builder_options_build_add_one_option(uint8_t **dst_packet_data_pptr, uint16_t option_len,
JimCarver 0:6b753f761943 676 uint8_t *option_ptr, sn_coap_option_numbers_e option_number, uint16_t *previous_option_number)
JimCarver 0:6b753f761943 677 {
JimCarver 0:6b753f761943 678 /* Check if there is option at all */
JimCarver 0:6b753f761943 679 if (option_ptr != NULL) {
JimCarver 0:6b753f761943 680 uint16_t option_delta;
JimCarver 0:6b753f761943 681
JimCarver 0:6b753f761943 682 option_delta = (option_number - *previous_option_number);
JimCarver 0:6b753f761943 683
JimCarver 0:6b753f761943 684 /* * * Build option header * * */
JimCarver 0:6b753f761943 685
JimCarver 0:6b753f761943 686 /* First option length without extended part */
JimCarver 0:6b753f761943 687 if (option_len <= 12) {
JimCarver 0:6b753f761943 688 **dst_packet_data_pptr = option_len;
JimCarver 0:6b753f761943 689 }
JimCarver 0:6b753f761943 690
JimCarver 0:6b753f761943 691 else if (option_len > 12 && option_len < 269) {
JimCarver 0:6b753f761943 692 **dst_packet_data_pptr = 0x0D;
JimCarver 0:6b753f761943 693 }
JimCarver 0:6b753f761943 694
JimCarver 0:6b753f761943 695 else if (option_len >= 269) {
JimCarver 0:6b753f761943 696 **dst_packet_data_pptr = 0x0E;
JimCarver 0:6b753f761943 697 }
JimCarver 0:6b753f761943 698
JimCarver 0:6b753f761943 699 /* Then option delta with extensions, and move pointer */
JimCarver 0:6b753f761943 700 if (option_delta <= 12) {
JimCarver 0:6b753f761943 701 **dst_packet_data_pptr += (option_delta << 4);
JimCarver 0:6b753f761943 702 *dst_packet_data_pptr += 1;
JimCarver 0:6b753f761943 703 }
JimCarver 0:6b753f761943 704
JimCarver 0:6b753f761943 705 else if (option_delta > 12 && option_delta < 269) {
JimCarver 0:6b753f761943 706 **dst_packet_data_pptr += 0xD0;
JimCarver 0:6b753f761943 707 option_delta -= 13;
JimCarver 0:6b753f761943 708
JimCarver 0:6b753f761943 709 *(*dst_packet_data_pptr + 1) = (uint8_t)option_delta;
JimCarver 0:6b753f761943 710 *dst_packet_data_pptr += 2;
JimCarver 0:6b753f761943 711 }
JimCarver 0:6b753f761943 712 //This is currently dead code (but possibly needed in future)
JimCarver 0:6b753f761943 713 else if (option_delta >= 269) {
JimCarver 0:6b753f761943 714 **dst_packet_data_pptr += 0xE0;
JimCarver 0:6b753f761943 715 option_delta -= 269;
JimCarver 0:6b753f761943 716
JimCarver 0:6b753f761943 717 *(*dst_packet_data_pptr + 2) = (uint8_t)option_delta;
JimCarver 0:6b753f761943 718 *(*dst_packet_data_pptr + 1) = (option_delta >> 8);
JimCarver 0:6b753f761943 719 *dst_packet_data_pptr += 3;
JimCarver 0:6b753f761943 720 }
JimCarver 0:6b753f761943 721
JimCarver 0:6b753f761943 722 /* Now option length extensions, if needed */
JimCarver 0:6b753f761943 723 if (option_len > 12 && option_len < 269) {
JimCarver 0:6b753f761943 724 **dst_packet_data_pptr = (uint8_t)(option_len - 13);
JimCarver 0:6b753f761943 725 *dst_packet_data_pptr += 1;
JimCarver 0:6b753f761943 726 }
JimCarver 0:6b753f761943 727
JimCarver 0:6b753f761943 728 else if (option_len >= 269) {
JimCarver 0:6b753f761943 729 *(*dst_packet_data_pptr + 1) = (uint8_t)(option_len - 269);
JimCarver 0:6b753f761943 730 **dst_packet_data_pptr = ((option_len - 269) >> 8);
JimCarver 0:6b753f761943 731 *dst_packet_data_pptr += 2;
JimCarver 0:6b753f761943 732 }
JimCarver 0:6b753f761943 733
JimCarver 0:6b753f761943 734 *previous_option_number = option_number;
JimCarver 0:6b753f761943 735
JimCarver 0:6b753f761943 736 /* Write Option value */
JimCarver 0:6b753f761943 737 memcpy(*dst_packet_data_pptr, option_ptr, option_len);
JimCarver 0:6b753f761943 738
JimCarver 0:6b753f761943 739 /* Increase destination Packet data pointer */
JimCarver 0:6b753f761943 740 (*dst_packet_data_pptr) += option_len;
JimCarver 0:6b753f761943 741
JimCarver 0:6b753f761943 742 return 1;
JimCarver 0:6b753f761943 743 }
JimCarver 0:6b753f761943 744
JimCarver 0:6b753f761943 745 /* Success */
JimCarver 0:6b753f761943 746 return 0;
JimCarver 0:6b753f761943 747 }
JimCarver 0:6b753f761943 748
JimCarver 0:6b753f761943 749 /**
JimCarver 0:6b753f761943 750 * \brief Constructs a uint Options part of Packet data
JimCarver 0:6b753f761943 751 *
JimCarver 0:6b753f761943 752 * \param **dst_packet_data_pptr is destination for built Packet data; NULL
JimCarver 0:6b753f761943 753 * to compute size only.
JimCarver 0:6b753f761943 754 *
JimCarver 0:6b753f761943 755 * \param option_value is Option value to be added
JimCarver 0:6b753f761943 756 *
JimCarver 0:6b753f761943 757 * \param option_number is Option number to be added
JimCarver 0:6b753f761943 758 *
JimCarver 0:6b753f761943 759 * \return Return value is total option size, or -1 in write failure case
JimCarver 0:6b753f761943 760 */
JimCarver 0:6b753f761943 761 static uint8_t sn_coap_builder_options_build_add_uint_option(uint8_t **dst_packet_data_pptr, uint32_t option_value, sn_coap_option_numbers_e option_number, uint16_t *previous_option_number)
JimCarver 0:6b753f761943 762 {
JimCarver 0:6b753f761943 763 uint8_t payload[4];
JimCarver 0:6b753f761943 764 uint8_t len = 0;
JimCarver 0:6b753f761943 765 /* Construct the variable-length payload representing the value */
JimCarver 0:6b753f761943 766 for (uint8_t i = 0; i < 4; i++) {
JimCarver 0:6b753f761943 767 if (len > 0 || (option_value & 0xff000000)) {
JimCarver 0:6b753f761943 768 payload[len++] = option_value >> 24;
JimCarver 0:6b753f761943 769 }
JimCarver 0:6b753f761943 770 option_value <<= 8;
JimCarver 0:6b753f761943 771 }
JimCarver 0:6b753f761943 772
JimCarver 0:6b753f761943 773 /* If output pointer isn't NULL, write it out */
JimCarver 0:6b753f761943 774 if (dst_packet_data_pptr) {
JimCarver 0:6b753f761943 775 int16_t ret = sn_coap_builder_options_build_add_one_option(dst_packet_data_pptr, len, payload, option_number, previous_option_number);
JimCarver 0:6b753f761943 776 /* Allow for failure returns when writing (why even permit failure returns?) */
JimCarver 0:6b753f761943 777 if (ret < 0) {
JimCarver 0:6b753f761943 778 return ret;
JimCarver 0:6b753f761943 779 }
JimCarver 0:6b753f761943 780 }
JimCarver 0:6b753f761943 781
JimCarver 0:6b753f761943 782 /* Return the total option size */
JimCarver 0:6b753f761943 783 return 1 + len;
JimCarver 0:6b753f761943 784 }
JimCarver 0:6b753f761943 785
JimCarver 0:6b753f761943 786 /**
JimCarver 0:6b753f761943 787 * \fn static int16_t sn_coap_builder_options_build_add_multiple_option(uint8_t **dst_packet_data_pptr, uint8_t **src_pptr, uint16_t *src_len_ptr, sn_coap_option_numbers_e option)
JimCarver 0:6b753f761943 788 *
JimCarver 0:6b753f761943 789 * \brief Builds Option Uri-Query from given CoAP Header structure to Packet data
JimCarver 0:6b753f761943 790 *
JimCarver 0:6b753f761943 791 * \param **dst_packet_data_pptr is destination for built Packet data
JimCarver 0:6b753f761943 792 *
JimCarver 0:6b753f761943 793 * \param uint8_t **src_pptr
JimCarver 0:6b753f761943 794 *
JimCarver 0:6b753f761943 795 * \param uint16_t *src_len_ptr
JimCarver 0:6b753f761943 796 *
JimCarver 0:6b753f761943 797 * \paramsn_coap_option_numbers_e option option to be added
JimCarver 0:6b753f761943 798 *
JimCarver 0:6b753f761943 799 * \return Return value is 0 always
JimCarver 0:6b753f761943 800 */
JimCarver 0:6b753f761943 801 static int16_t sn_coap_builder_options_build_add_multiple_option(uint8_t **dst_packet_data_pptr, uint8_t **src_pptr, uint16_t *src_len_ptr, sn_coap_option_numbers_e option, uint16_t *previous_option_number)
JimCarver 0:6b753f761943 802 {
JimCarver 0:6b753f761943 803 /* Check if there is option at all */
JimCarver 0:6b753f761943 804 if (*src_pptr != NULL) {
JimCarver 0:6b753f761943 805 uint8_t *query_ptr = *src_pptr;
JimCarver 0:6b753f761943 806 uint8_t query_part_count = 0;
JimCarver 0:6b753f761943 807 uint16_t query_len = *src_len_ptr;
JimCarver 0:6b753f761943 808 uint8_t i = 0;
JimCarver 0:6b753f761943 809 uint16_t query_part_offset = 0;
JimCarver 0:6b753f761943 810
JimCarver 0:6b753f761943 811 /* Get query part count */
JimCarver 0:6b753f761943 812 query_part_count = sn_coap_builder_options_get_option_part_count(query_len, query_ptr, option);
JimCarver 0:6b753f761943 813
JimCarver 0:6b753f761943 814 /* * * * Options by adding all parts to option * * * */
JimCarver 0:6b753f761943 815 for (i = 0; i < query_part_count; i++) {
JimCarver 0:6b753f761943 816 /* Get length of query part */
JimCarver 0:6b753f761943 817 uint16_t one_query_part_len = sn_coap_builder_options_get_option_part_length_from_whole_option_string(query_len, query_ptr, i, option);
JimCarver 0:6b753f761943 818
JimCarver 0:6b753f761943 819 /* Get position of query part */
JimCarver 0:6b753f761943 820 query_part_offset = sn_coap_builder_options_get_option_part_position(query_len, query_ptr, i, option);
JimCarver 0:6b753f761943 821
JimCarver 0:6b753f761943 822 /* Add Uri-query's one part to Options */
JimCarver 0:6b753f761943 823 sn_coap_builder_options_build_add_one_option(dst_packet_data_pptr, one_query_part_len, *src_pptr + query_part_offset, option, previous_option_number);
JimCarver 0:6b753f761943 824 }
JimCarver 0:6b753f761943 825 }
JimCarver 0:6b753f761943 826 /* Success */
JimCarver 0:6b753f761943 827 return 0;
JimCarver 0:6b753f761943 828 }
JimCarver 0:6b753f761943 829
JimCarver 0:6b753f761943 830
JimCarver 0:6b753f761943 831 /**
JimCarver 0:6b753f761943 832 * \fn static uint16_t sn_coap_builder_options_calc_option_size(uint16_t query_len, uint8_t *query_ptr, sn_coap_option_numbers_e option)
JimCarver 0:6b753f761943 833 *
JimCarver 0:6b753f761943 834 * \brief Calculates needed Packet data memory size for option
JimCarver 0:6b753f761943 835 *
JimCarver 0:6b753f761943 836 * \param path_len is length of calculated strting(s)
JimCarver 0:6b753f761943 837 *
JimCarver 0:6b753f761943 838 * \param *path_ptr is pointer to calculated options
JimCarver 0:6b753f761943 839 *
JimCarver 0:6b753f761943 840 * \return Return value is count of needed memory as bytes for Uri-query option
JimCarver 0:6b753f761943 841 */
JimCarver 0:6b753f761943 842 static uint16_t sn_coap_builder_options_calc_option_size(uint16_t query_len, uint8_t *query_ptr, sn_coap_option_numbers_e option)
JimCarver 0:6b753f761943 843 {
JimCarver 0:6b753f761943 844 uint8_t query_part_count = sn_coap_builder_options_get_option_part_count(query_len, query_ptr, option);
JimCarver 0:6b753f761943 845 uint8_t i = 0;
JimCarver 0:6b753f761943 846 uint16_t ret_value = 0;
JimCarver 0:6b753f761943 847
JimCarver 0:6b753f761943 848 /* * * * * * * * * * * * * * * * * * * * * * * * */
JimCarver 0:6b753f761943 849 /* * * * Calculate Uri-query options length * * */
JimCarver 0:6b753f761943 850 /* * * * * * * * * * * * * * * * * * * * * * * * */
JimCarver 0:6b753f761943 851 for (i = 0; i < query_part_count; i++) {
JimCarver 0:6b753f761943 852 /* * * Length of Option number and Option value length * * */
JimCarver 0:6b753f761943 853
JimCarver 0:6b753f761943 854 /* Get length of Query part */
JimCarver 0:6b753f761943 855 uint16_t one_query_part_len = sn_coap_builder_options_get_option_part_length_from_whole_option_string(query_len, query_ptr, i, option);
JimCarver 0:6b753f761943 856
JimCarver 0:6b753f761943 857 /* Check option length */
JimCarver 0:6b753f761943 858 switch (option) {
JimCarver 0:6b753f761943 859 case (COAP_OPTION_ETAG): /* Length 1-8 */
JimCarver 0:6b753f761943 860 if (one_query_part_len < 1 || one_query_part_len > 8) {
JimCarver 0:6b753f761943 861 return 0;
JimCarver 0:6b753f761943 862 }
JimCarver 0:6b753f761943 863 break;
JimCarver 0:6b753f761943 864 case (COAP_OPTION_LOCATION_PATH): /* Length 0-255 */
JimCarver 0:6b753f761943 865 case (COAP_OPTION_URI_PATH): /* Length 0-255 */
JimCarver 0:6b753f761943 866 case (COAP_OPTION_LOCATION_QUERY): /* Length 0-255 */
JimCarver 0:6b753f761943 867 if (one_query_part_len > 255) {
JimCarver 0:6b753f761943 868 return 0;
JimCarver 0:6b753f761943 869 }
JimCarver 0:6b753f761943 870 break;
JimCarver 0:6b753f761943 871 case (COAP_OPTION_URI_QUERY): /* Length 1-255 */
JimCarver 0:6b753f761943 872 if (one_query_part_len < 1 || one_query_part_len > 255) {
JimCarver 0:6b753f761943 873 return 0;
JimCarver 0:6b753f761943 874 }
JimCarver 0:6b753f761943 875 break;
JimCarver 0:6b753f761943 876 // case (COAP_OPTION_ACCEPT): /* Length 0-2 */
JimCarver 0:6b753f761943 877 // if (one_query_part_len > 2) {
JimCarver 0:6b753f761943 878 // return 0;
JimCarver 0:6b753f761943 879 // }
JimCarver 0:6b753f761943 880 // break;
JimCarver 0:6b753f761943 881 default:
JimCarver 0:6b753f761943 882 break; //impossible scenario currently
JimCarver 0:6b753f761943 883 }
JimCarver 0:6b753f761943 884
JimCarver 0:6b753f761943 885 /* Check if 4 bits are enough for writing Option value length */
JimCarver 0:6b753f761943 886 if (one_query_part_len <= 12) {
JimCarver 0:6b753f761943 887 /* 4 bits are enough for Option value length */
JimCarver 0:6b753f761943 888 ret_value++;
JimCarver 0:6b753f761943 889 } else if (one_query_part_len >= 13 && one_query_part_len < 269) {
JimCarver 0:6b753f761943 890 /* Extra byte for Option value length is needed */
JimCarver 0:6b753f761943 891 ret_value += 2;
JimCarver 0:6b753f761943 892 }
JimCarver 0:6b753f761943 893 //This can only happen if we are in default case above, currently is not happening
JimCarver 0:6b753f761943 894 else if (one_query_part_len >= 270 && one_query_part_len < 1034) {
JimCarver 0:6b753f761943 895 /* Extra bytes for Option value length is needed */
JimCarver 0:6b753f761943 896 ret_value += 3;
JimCarver 0:6b753f761943 897 }
JimCarver 0:6b753f761943 898
JimCarver 0:6b753f761943 899
JimCarver 0:6b753f761943 900 /* * * Length of Option value * * */
JimCarver 0:6b753f761943 901
JimCarver 0:6b753f761943 902 /* Increase options length */
JimCarver 0:6b753f761943 903 ret_value += one_query_part_len;
JimCarver 0:6b753f761943 904 }
JimCarver 0:6b753f761943 905
JimCarver 0:6b753f761943 906 /* Success */
JimCarver 0:6b753f761943 907 return ret_value;
JimCarver 0:6b753f761943 908 }
JimCarver 0:6b753f761943 909
JimCarver 0:6b753f761943 910
JimCarver 0:6b753f761943 911
JimCarver 0:6b753f761943 912 /**
JimCarver 0:6b753f761943 913 * \fn static uint8_t sn_coap_builder_options_get_option_part_count(uint16_t query_len, uint8_t *query_ptr, sn_coap_option_numbers_e option)
JimCarver 0:6b753f761943 914 *
JimCarver 0:6b753f761943 915 * \brief Gets query part count from whole option string
JimCarver 0:6b753f761943 916 *
JimCarver 0:6b753f761943 917 * \param query_len is length of whole Path
JimCarver 0:6b753f761943 918 *
JimCarver 0:6b753f761943 919 * \param *query_ptr is pointer to the start of whole Path
JimCarver 0:6b753f761943 920 *
JimCarver 0:6b753f761943 921 * \return Return value is count of query parts
JimCarver 0:6b753f761943 922 */
JimCarver 0:6b753f761943 923 static uint8_t sn_coap_builder_options_get_option_part_count(uint16_t query_len, uint8_t *query_ptr, sn_coap_option_numbers_e option)
JimCarver 0:6b753f761943 924 {
JimCarver 0:6b753f761943 925 uint8_t returned_query_count = 0;
JimCarver 0:6b753f761943 926 uint16_t query_len_index = 0;
JimCarver 0:6b753f761943 927 uint8_t char_to_search = '&';
JimCarver 0:6b753f761943 928
JimCarver 0:6b753f761943 929 if (option == COAP_OPTION_URI_PATH || option == COAP_OPTION_LOCATION_PATH) {
JimCarver 0:6b753f761943 930 char_to_search = '/';
JimCarver 0:6b753f761943 931 }
JimCarver 0:6b753f761943 932
JimCarver 0:6b753f761943 933 /* Loop whole query and search '\0' characters (not first and last char) */
JimCarver 0:6b753f761943 934 for (query_len_index = 1; query_len_index < query_len - 1; query_len_index++) {
JimCarver 0:6b753f761943 935 /* If new query part starts */
JimCarver 0:6b753f761943 936 if (*(query_ptr + query_len_index) == char_to_search) { /* If match */
JimCarver 0:6b753f761943 937 returned_query_count++;
JimCarver 0:6b753f761943 938 }
JimCarver 0:6b753f761943 939 }
JimCarver 0:6b753f761943 940
JimCarver 0:6b753f761943 941 returned_query_count++;
JimCarver 0:6b753f761943 942
JimCarver 0:6b753f761943 943 return returned_query_count;
JimCarver 0:6b753f761943 944 }
JimCarver 0:6b753f761943 945
JimCarver 0:6b753f761943 946 /**
JimCarver 0:6b753f761943 947 * \fn static uint16_t sn_coap_builder_options_get_option_part_length_from_whole_option_string(uint16_t query_len,
JimCarver 0:6b753f761943 948 uint8_t *query_ptr,
JimCarver 0:6b753f761943 949 uint8_t query_index, sn_coap_option_numbers_e option)
JimCarver 0:6b753f761943 950 *
JimCarver 0:6b753f761943 951 * \brief Gets one's query part length from whole query string
JimCarver 0:6b753f761943 952 *
JimCarver 0:6b753f761943 953 * \param query_len is length of whole string
JimCarver 0:6b753f761943 954 *
JimCarver 0:6b753f761943 955 * \param *query_ptr is pointer to the start of whole string
JimCarver 0:6b753f761943 956 *
JimCarver 0:6b753f761943 957 * \param query_index is query part index to be found
JimCarver 0:6b753f761943 958 *
JimCarver 0:6b753f761943 959 * \param sn_coap_option_numbers_e option is option number of the option
JimCarver 0:6b753f761943 960 *
JimCarver 0:6b753f761943 961 * \return Return value is length of query part
JimCarver 0:6b753f761943 962 */
JimCarver 0:6b753f761943 963 static uint16_t sn_coap_builder_options_get_option_part_length_from_whole_option_string(uint16_t query_len, uint8_t *query_ptr,
JimCarver 0:6b753f761943 964 uint8_t query_index, sn_coap_option_numbers_e option)
JimCarver 0:6b753f761943 965 {
JimCarver 0:6b753f761943 966 uint16_t returned_query_part_len = 0;
JimCarver 0:6b753f761943 967 uint8_t temp_query_index = 0;
JimCarver 0:6b753f761943 968 uint16_t query_len_index = 0;
JimCarver 0:6b753f761943 969 uint8_t char_to_search = '&';
JimCarver 0:6b753f761943 970
JimCarver 0:6b753f761943 971 if (option == COAP_OPTION_URI_PATH || option == COAP_OPTION_LOCATION_PATH) {
JimCarver 0:6b753f761943 972 char_to_search = '/';
JimCarver 0:6b753f761943 973 }
JimCarver 0:6b753f761943 974
JimCarver 0:6b753f761943 975 /* Loop whole query and search '\0' characters */
JimCarver 0:6b753f761943 976 for (query_len_index = 0; query_len_index < query_len; query_len_index++) {
JimCarver 0:6b753f761943 977 /* Store character to temp_char for helping debugging */
JimCarver 0:6b753f761943 978 uint8_t temp_char = *query_ptr;
JimCarver 0:6b753f761943 979
JimCarver 0:6b753f761943 980 /* If new query part starts */
JimCarver 0:6b753f761943 981 if (temp_char == char_to_search && returned_query_part_len > 0) { /* returned_query_part_len > 0 is for querys which start with "\0" */
JimCarver 0:6b753f761943 982 /* If query part index is wanted */
JimCarver 0:6b753f761943 983 if (temp_query_index == query_index) {
JimCarver 0:6b753f761943 984 /* Return length of query part */
JimCarver 0:6b753f761943 985 return returned_query_part_len;
JimCarver 0:6b753f761943 986 } else {
JimCarver 0:6b753f761943 987 /* Reset length of query part because wanted query part finding continues*/
JimCarver 0:6b753f761943 988 returned_query_part_len = 0;
JimCarver 0:6b753f761943 989 }
JimCarver 0:6b753f761943 990
JimCarver 0:6b753f761943 991 /* Next query part is looped */
JimCarver 0:6b753f761943 992 temp_query_index++;
JimCarver 0:6b753f761943 993 } else if (temp_char != char_to_search) { /* Else if query part continues */
JimCarver 0:6b753f761943 994 /* Increase query part length */
JimCarver 0:6b753f761943 995 returned_query_part_len++;
JimCarver 0:6b753f761943 996 }
JimCarver 0:6b753f761943 997
JimCarver 0:6b753f761943 998 query_ptr++;
JimCarver 0:6b753f761943 999 }
JimCarver 0:6b753f761943 1000
JimCarver 0:6b753f761943 1001 /* Return length of query part in cases that query part does not finish to '\0' character (last query part can be like that) */
JimCarver 0:6b753f761943 1002 return returned_query_part_len;
JimCarver 0:6b753f761943 1003 }
JimCarver 0:6b753f761943 1004
JimCarver 0:6b753f761943 1005 /**
JimCarver 0:6b753f761943 1006 * \fn static uint16_t sn_coap_builder_options_get_option_part_position(uint16_t query_len,
JimCarver 0:6b753f761943 1007 uint8_t *query_ptr,
JimCarver 0:6b753f761943 1008 uint8_t query_index, sn_coap_option_numbers_e option)
JimCarver 0:6b753f761943 1009 *
JimCarver 0:6b753f761943 1010 * \brief Gets query part position in whole query
JimCarver 0:6b753f761943 1011 *
JimCarver 0:6b753f761943 1012 * \param query_len is length of whole query
JimCarver 0:6b753f761943 1013 *
JimCarver 0:6b753f761943 1014 * \param *query_ptr is pointer to the start of whole query
JimCarver 0:6b753f761943 1015 *
JimCarver 0:6b753f761943 1016 * \param query_index is query part index to be found
JimCarver 0:6b753f761943 1017 *
JimCarver 0:6b753f761943 1018 * \return Return value is position (= offset) of query part in whole query. In
JimCarver 0:6b753f761943 1019 * fail cases -1 is returned.
JimCarver 0:6b753f761943 1020 */
JimCarver 0:6b753f761943 1021 static int16_t sn_coap_builder_options_get_option_part_position(uint16_t query_len, uint8_t *query_ptr,
JimCarver 0:6b753f761943 1022 uint8_t query_index, sn_coap_option_numbers_e option)
JimCarver 0:6b753f761943 1023 {
JimCarver 0:6b753f761943 1024 uint16_t returned_query_part_offset = 0;
JimCarver 0:6b753f761943 1025 uint8_t temp_query_index = 0;
JimCarver 0:6b753f761943 1026 uint16_t query_len_index = 0;
JimCarver 0:6b753f761943 1027 uint8_t char_to_search = '&';
JimCarver 0:6b753f761943 1028
JimCarver 0:6b753f761943 1029 if (option == COAP_OPTION_URI_PATH || option == COAP_OPTION_LOCATION_PATH) {
JimCarver 0:6b753f761943 1030 char_to_search = '/';
JimCarver 0:6b753f761943 1031 }
JimCarver 0:6b753f761943 1032
JimCarver 0:6b753f761943 1033 if (query_index == 0) {
JimCarver 0:6b753f761943 1034 if (*query_ptr == 0 || *query_ptr == char_to_search) {
JimCarver 0:6b753f761943 1035 return 1;
JimCarver 0:6b753f761943 1036 } else {
JimCarver 0:6b753f761943 1037 return 0;
JimCarver 0:6b753f761943 1038 }
JimCarver 0:6b753f761943 1039 }
JimCarver 0:6b753f761943 1040
JimCarver 0:6b753f761943 1041 /* Loop whole query and search separator characters */
JimCarver 0:6b753f761943 1042 for (query_len_index = 0; query_len_index < query_len; query_len_index++) {
JimCarver 0:6b753f761943 1043 /* Store character to temp_char for helping debugging */
JimCarver 0:6b753f761943 1044 uint8_t temp_char = *query_ptr;
JimCarver 0:6b753f761943 1045
JimCarver 0:6b753f761943 1046 /* If new query part starts */
JimCarver 0:6b753f761943 1047 if (temp_char == char_to_search && returned_query_part_offset > 0) { /* returned_query_part_offset > 0 is for querys which start with searched char */
JimCarver 0:6b753f761943 1048 /* If query part index is wanted */
JimCarver 0:6b753f761943 1049 if (temp_query_index == (query_index - 1)) {
JimCarver 0:6b753f761943 1050 /* Return offset of query part */
JimCarver 0:6b753f761943 1051 return (returned_query_part_offset + 1); /* Plus one is for passing separator */
JimCarver 0:6b753f761943 1052 }
JimCarver 0:6b753f761943 1053
JimCarver 0:6b753f761943 1054 /* Next query part is looped */
JimCarver 0:6b753f761943 1055 temp_query_index++;
JimCarver 0:6b753f761943 1056 }
JimCarver 0:6b753f761943 1057
JimCarver 0:6b753f761943 1058 returned_query_part_offset++;
JimCarver 0:6b753f761943 1059
JimCarver 0:6b753f761943 1060 query_ptr++;
JimCarver 0:6b753f761943 1061 }
JimCarver 0:6b753f761943 1062
JimCarver 0:6b753f761943 1063 return -1; //Dead code?
JimCarver 0:6b753f761943 1064 }
JimCarver 0:6b753f761943 1065
JimCarver 0:6b753f761943 1066
JimCarver 0:6b753f761943 1067 /**
JimCarver 0:6b753f761943 1068 * \fn static void sn_coap_builder_payload_build(uint8_t **dst_packet_data_pptr, sn_coap_hdr_s *src_coap_msg_ptr)
JimCarver 0:6b753f761943 1069 *
JimCarver 0:6b753f761943 1070 * \brief Builds Options part of Packet data
JimCarver 0:6b753f761943 1071 *
JimCarver 0:6b753f761943 1072 * \param **dst_packet_data_pptr is destination for built Packet data
JimCarver 0:6b753f761943 1073 *
JimCarver 0:6b753f761943 1074 * \param *src_coap_msg_ptr is source for building Packet data
JimCarver 0:6b753f761943 1075 */
JimCarver 0:6b753f761943 1076 static void sn_coap_builder_payload_build(uint8_t **dst_packet_data_pptr, sn_coap_hdr_s *src_coap_msg_ptr)
JimCarver 0:6b753f761943 1077 {
JimCarver 0:6b753f761943 1078 /* Check if Payload is used at all */
JimCarver 0:6b753f761943 1079 if (src_coap_msg_ptr->payload_len && src_coap_msg_ptr->payload_ptr != NULL) {
JimCarver 0:6b753f761943 1080 /* Write Payload marker */
JimCarver 0:6b753f761943 1081
JimCarver 0:6b753f761943 1082 **dst_packet_data_pptr = 0xff;
JimCarver 0:6b753f761943 1083 (*dst_packet_data_pptr)++;
JimCarver 0:6b753f761943 1084
JimCarver 0:6b753f761943 1085 /* Write Payload */
JimCarver 0:6b753f761943 1086 memcpy(*dst_packet_data_pptr, src_coap_msg_ptr->payload_ptr, src_coap_msg_ptr->payload_len);
JimCarver 0:6b753f761943 1087
JimCarver 0:6b753f761943 1088 /* Increase destination Packet data pointer */
JimCarver 0:6b753f761943 1089 (*dst_packet_data_pptr) += src_coap_msg_ptr->payload_len;
JimCarver 0:6b753f761943 1090 }
JimCarver 0:6b753f761943 1091 }