Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed Socket lwip-eth lwip-sys lwip
Fork of 6_songs-from-the-cloud by
sn_coap_builder.c
00001 /* 00002 * Copyright (c) 2011-2015 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 /** 00018 * \file sn_coap_builder.c 00019 * 00020 * \brief CoAP Message builder 00021 * 00022 * Functionality: Builds CoAP message 00023 * 00024 */ 00025 00026 /* * * * * * * * * * * * * * */ 00027 /* * * * INCLUDE FILES * * * */ 00028 /* * * * * * * * * * * * * * */ 00029 00030 #include <string.h> /* For memset() and memcpy() */ 00031 00032 #include "ns_types.h" 00033 #include "sn_nsdl.h" 00034 #include "sn_coap_header.h" 00035 #include "sn_coap_header_internal.h" 00036 #include "sn_coap_protocol_internal.h" 00037 00038 /* * * * LOCAL FUNCTION PROTOTYPES * * * */ 00039 static int8_t sn_coap_builder_header_build(uint8_t **dst_packet_data_pptr, sn_coap_hdr_s *src_coap_msg_ptr); 00040 static int8_t sn_coap_builder_options_build(uint8_t **dst_packet_data_pptr, sn_coap_hdr_s *src_coap_msg_ptr); 00041 static uint16_t sn_coap_builder_options_calc_option_size(uint16_t query_len, uint8_t *query_ptr, sn_coap_option_numbers_e option); 00042 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); 00043 static int16_t sn_coap_builder_options_build_add_zero_length_option(uint8_t **dst_packet_data_pptr, uint8_t option_length, uint8_t option_exist, sn_coap_option_numbers_e option_number); 00044 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); 00045 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); 00046 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); 00047 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); 00048 static void sn_coap_builder_payload_build(uint8_t **dst_packet_data_pptr, sn_coap_hdr_s *src_coap_msg_ptr); 00049 static uint8_t sn_coap_builder_options_calculate_jump_need(sn_coap_hdr_s *src_coap_msg_ptr, uint8_t block_option); 00050 00051 /* * * * GLOBAL DECLARATIONS * * * */ 00052 static uint16_t global_previous_option_number = 0; /* Previous Option number in CoAP message */ 00053 00054 /* * * * EXTERN VARIABLES * * * */ 00055 #if SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE 00056 extern uint16_t sn_coap_block_data_size; /* From sn_coap_protocol_ieft_draft_12.c */ 00057 #endif 00058 00059 sn_coap_hdr_s *sn_coap_build_response(struct coap_s *handle, sn_coap_hdr_s *coap_packet_ptr, uint8_t msg_code) 00060 { 00061 sn_coap_hdr_s *coap_res_ptr; 00062 00063 if (!coap_packet_ptr || !handle) { 00064 return NULL; 00065 } 00066 00067 coap_res_ptr = handle->sn_coap_protocol_malloc(sizeof(sn_coap_hdr_s)); 00068 if (!coap_res_ptr) { 00069 return NULL; 00070 } 00071 00072 memset(coap_res_ptr, 0x00, sizeof(sn_coap_hdr_s)); 00073 00074 if (coap_packet_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE) { 00075 coap_res_ptr->msg_type = COAP_MSG_TYPE_ACKNOWLEDGEMENT; 00076 coap_res_ptr->msg_code = (sn_coap_msg_code_e)msg_code; 00077 coap_res_ptr->msg_id = coap_packet_ptr->msg_id; 00078 } 00079 00080 else if (coap_packet_ptr->msg_type == COAP_MSG_TYPE_NON_CONFIRMABLE) { 00081 coap_res_ptr->msg_type = COAP_MSG_TYPE_NON_CONFIRMABLE; 00082 coap_res_ptr->msg_code = (sn_coap_msg_code_e)msg_code; 00083 /* msg_id needs to be set by the caller in this case */ 00084 } 00085 00086 else { 00087 handle->sn_coap_protocol_free( coap_res_ptr ); 00088 return NULL; 00089 } 00090 00091 if (coap_packet_ptr->token_ptr) { 00092 coap_res_ptr->token_len = coap_packet_ptr->token_len; 00093 coap_res_ptr->token_ptr = handle->sn_coap_protocol_malloc(coap_res_ptr->token_len); 00094 if (!coap_res_ptr->token_ptr) { 00095 handle->sn_coap_protocol_free(coap_res_ptr); 00096 return NULL; 00097 } 00098 memcpy(coap_res_ptr->token_ptr, coap_packet_ptr->token_ptr, coap_res_ptr->token_len); 00099 } 00100 return coap_res_ptr; 00101 } 00102 00103 int16_t sn_coap_builder(uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_msg_ptr) 00104 { 00105 uint8_t *base_packet_data_ptr = NULL; 00106 00107 /* * * * Check given pointers * * * */ 00108 if (dst_packet_data_ptr == NULL || src_coap_msg_ptr == NULL) { 00109 return -2; 00110 } 00111 00112 /* Initialize given Packet data memory area with zero values */ 00113 uint16_t dst_byte_count_to_be_built = sn_coap_builder_calc_needed_packet_data_size(src_coap_msg_ptr); 00114 00115 if (!dst_byte_count_to_be_built) { 00116 return -1; 00117 } 00118 00119 memset(dst_packet_data_ptr, 0, dst_byte_count_to_be_built); 00120 00121 /* * * * Store base (= original) destination Packet data pointer for later usage * * * */ 00122 base_packet_data_ptr = dst_packet_data_ptr; 00123 00124 /* * * * * * * * * * * * * * * * * * */ 00125 /* * * * Header part building * * * */ 00126 /* * * * * * * * * * * * * * * * * * */ 00127 if (sn_coap_builder_header_build(&dst_packet_data_ptr, src_coap_msg_ptr) != 0) { 00128 /* Header building failed */ 00129 return -1; 00130 } 00131 00132 /* If else than Reset message because Reset message must be empty */ 00133 if (src_coap_msg_ptr->msg_type != COAP_MSG_TYPE_RESET) { 00134 /* * * * * * * * * * * * * * * * * * */ 00135 /* * * * Options part building * * * */ 00136 /* * * * * * * * * * * * * * * * * * */ 00137 sn_coap_builder_options_build(&dst_packet_data_ptr, src_coap_msg_ptr); 00138 00139 /* * * * * * * * * * * * * * * * * * */ 00140 /* * * * Payload part building * * * */ 00141 /* * * * * * * * * * * * * * * * * * */ 00142 sn_coap_builder_payload_build(&dst_packet_data_ptr, src_coap_msg_ptr); 00143 } 00144 00145 /* * * * Return built Packet data length * * * */ 00146 return (dst_packet_data_ptr - base_packet_data_ptr); 00147 } 00148 00149 uint16_t sn_coap_builder_calc_needed_packet_data_size(sn_coap_hdr_s *src_coap_msg_ptr) 00150 { 00151 uint16_t returned_byte_count = 0; 00152 00153 if (!src_coap_msg_ptr) { 00154 return 0; 00155 } 00156 00157 /* * * * * HEADER * * * * */ 00158 00159 /* Header size is fixed */ 00160 returned_byte_count = COAP_HEADER_LENGTH; 00161 00162 /* * * * * OPTIONS * * * * */ 00163 00164 /* If else than Reset message because Reset message must be empty */ 00165 if (src_coap_msg_ptr->msg_type != COAP_MSG_TYPE_RESET) { 00166 uint16_t repeatable_option_size = 0; 00167 00168 /* TOKEN - Length is 1-8 bytes */ 00169 if (src_coap_msg_ptr->token_ptr != NULL) { 00170 if (src_coap_msg_ptr->token_len > 8 || src_coap_msg_ptr->token_len < 1) { /* Check that option is not longer than defined */ 00171 return 0; 00172 } 00173 00174 returned_byte_count += src_coap_msg_ptr->token_len; 00175 } 00176 00177 /* URI PATH - Repeatable option. Length of one option is 0-255 */ 00178 if (src_coap_msg_ptr->uri_path_ptr != NULL) { 00179 repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->uri_path_len, 00180 src_coap_msg_ptr->uri_path_ptr, COAP_OPTION_URI_PATH); 00181 if (repeatable_option_size) { 00182 returned_byte_count += repeatable_option_size; 00183 } else { 00184 return 0; 00185 } 00186 } 00187 00188 /* CONTENT TYPE - Length of this option is 0-2 bytes */ 00189 if (src_coap_msg_ptr->content_type_ptr != NULL) { 00190 returned_byte_count++; 00191 if (src_coap_msg_ptr->content_type_len > 2) { 00192 return 0; 00193 } 00194 00195 returned_byte_count += src_coap_msg_ptr->content_type_len; 00196 } 00197 00198 /* If options list pointer exists */ 00199 if (src_coap_msg_ptr->options_list_ptr != NULL) { 00200 /* ACCEPT - Repeatable option. Length of this option is 0-2 bytes */ 00201 if (src_coap_msg_ptr->options_list_ptr->accept_ptr != NULL) { 00202 repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->options_list_ptr->accept_len, 00203 src_coap_msg_ptr->options_list_ptr->accept_ptr, COAP_OPTION_ACCEPT); 00204 if (repeatable_option_size) { 00205 returned_byte_count += repeatable_option_size; 00206 } else { 00207 return 0; 00208 } 00209 } 00210 00211 /* MAX AGE - Length of this option is 0-4 bytes */ 00212 if (src_coap_msg_ptr->options_list_ptr->max_age_ptr != NULL) { 00213 returned_byte_count++; 00214 if (src_coap_msg_ptr->options_list_ptr->max_age_len > 4) { 00215 return 0; 00216 } 00217 00218 returned_byte_count += src_coap_msg_ptr->options_list_ptr->max_age_len; 00219 } 00220 00221 /* PROXY URI - Length of this option is 1-1034 bytes */ 00222 if (src_coap_msg_ptr->options_list_ptr->proxy_uri_ptr != NULL) { 00223 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 */ 00224 returned_byte_count++; 00225 } 00226 00227 else if (src_coap_msg_ptr->options_list_ptr->proxy_uri_len >= 13 && src_coap_msg_ptr->options_list_ptr->proxy_uri_len <= 269) { 00228 returned_byte_count += 2; 00229 } 00230 00231 else if (src_coap_msg_ptr->options_list_ptr->proxy_uri_len >= 270 && src_coap_msg_ptr->options_list_ptr->proxy_uri_len <= 1034) { 00232 returned_byte_count += 3; 00233 } 00234 00235 else { 00236 return 0; 00237 } 00238 00239 /* Add needed memory for Option value */ 00240 returned_byte_count += src_coap_msg_ptr->options_list_ptr->proxy_uri_len; 00241 } 00242 00243 /* ETAG - Repeatable option. Length of this option is 1-8 bytes*/ 00244 if (src_coap_msg_ptr->options_list_ptr->etag_ptr != NULL) { 00245 repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->options_list_ptr->etag_len, 00246 src_coap_msg_ptr->options_list_ptr->etag_ptr, COAP_OPTION_ETAG); 00247 if (repeatable_option_size) { 00248 returned_byte_count += repeatable_option_size; 00249 } else { 00250 return 0; 00251 } 00252 } 00253 00254 /* URI HOST - Length of this option is 1-255 bytes */ 00255 if (src_coap_msg_ptr->options_list_ptr->uri_host_ptr != NULL) { 00256 if (src_coap_msg_ptr->options_list_ptr->uri_host_len > 0 && src_coap_msg_ptr->options_list_ptr->uri_host_len <= 12) { 00257 returned_byte_count++; 00258 } 00259 00260 else if (src_coap_msg_ptr->options_list_ptr->uri_host_len >= 13 && src_coap_msg_ptr->options_list_ptr->uri_host_len <= 255) { 00261 returned_byte_count += 2; 00262 } 00263 00264 else { 00265 return 0; 00266 } 00267 00268 returned_byte_count += src_coap_msg_ptr->options_list_ptr->uri_host_len; 00269 } 00270 00271 /* LOCATION PATH - Repeatable option. Length of this option is 0-255 bytes*/ 00272 if (src_coap_msg_ptr->options_list_ptr->location_path_ptr != NULL) { 00273 repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->options_list_ptr->location_path_len, 00274 src_coap_msg_ptr->options_list_ptr->location_path_ptr, COAP_OPTION_LOCATION_PATH); 00275 if (repeatable_option_size) { 00276 returned_byte_count += repeatable_option_size; 00277 } else { 00278 return 0; 00279 } 00280 } 00281 00282 /* URI PORT - Length of this option is 0-2 bytes */ 00283 if (src_coap_msg_ptr->options_list_ptr->uri_port_ptr != NULL) { 00284 returned_byte_count++; 00285 if (src_coap_msg_ptr->options_list_ptr->uri_port_len > 2) { 00286 return 0; 00287 } 00288 00289 returned_byte_count += src_coap_msg_ptr->options_list_ptr->uri_port_len; 00290 } 00291 00292 /* lOCATION QUERY - Repeatable option. Length of this option is 0-255 bytes */ 00293 if (src_coap_msg_ptr->options_list_ptr->location_query_ptr != NULL) { 00294 repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->options_list_ptr->location_query_len, 00295 src_coap_msg_ptr->options_list_ptr->location_query_ptr, COAP_OPTION_LOCATION_QUERY); 00296 if (repeatable_option_size) { 00297 returned_byte_count += repeatable_option_size; 00298 } else { 00299 return 0; 00300 } 00301 } 00302 00303 /* OBSERVE - Length of this option is 0-3 bytes */ 00304 if (src_coap_msg_ptr->options_list_ptr->observe_ptr != NULL) { 00305 returned_byte_count++; 00306 if (src_coap_msg_ptr->options_list_ptr->observe_len > 3) { 00307 return 0; 00308 } 00309 00310 returned_byte_count += src_coap_msg_ptr->options_list_ptr->observe_len; 00311 } else if (src_coap_msg_ptr->options_list_ptr->observe) { 00312 returned_byte_count++; 00313 } 00314 00315 /* URI QUERY - Repeatable option. Length of this option is 1-255 */ 00316 if (src_coap_msg_ptr->options_list_ptr->uri_query_ptr != NULL) { 00317 repeatable_option_size = sn_coap_builder_options_calc_option_size(src_coap_msg_ptr->options_list_ptr->uri_query_len, 00318 src_coap_msg_ptr->options_list_ptr->uri_query_ptr, COAP_OPTION_URI_QUERY); 00319 if (repeatable_option_size) { 00320 returned_byte_count += repeatable_option_size; 00321 } else { 00322 return 0; 00323 } 00324 } 00325 00326 /* BLOCK 1 - Length of this option is 1-3 bytes*/ 00327 if (src_coap_msg_ptr->options_list_ptr->block2_ptr != NULL) { 00328 returned_byte_count++; 00329 if (src_coap_msg_ptr->options_list_ptr->block2_len > 3 || src_coap_msg_ptr->options_list_ptr->block2_len < 1) { 00330 return 0; 00331 } 00332 00333 returned_byte_count += src_coap_msg_ptr->options_list_ptr->block2_len; 00334 } 00335 00336 /* BLOCK 2 - Length of this option is 1-3 bytes*/ 00337 if (src_coap_msg_ptr->options_list_ptr->block1_ptr != NULL) { 00338 returned_byte_count++; 00339 00340 if (src_coap_msg_ptr->options_list_ptr->block1_len > 3 || src_coap_msg_ptr->options_list_ptr->block1_len < 1) { 00341 return 0; 00342 } 00343 00344 returned_byte_count += src_coap_msg_ptr->options_list_ptr->block1_len; 00345 } 00346 } 00347 00348 /* * * * * PAYLOAD * * * * */ 00349 #if SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE /* If Message blockwising is not used at all, this part of code will not be compiled */ 00350 if ((src_coap_msg_ptr->payload_len > sn_coap_block_data_size) && (sn_coap_block_data_size > 0)) { 00351 /* Two bytes for Block option */ 00352 returned_byte_count += 2; 00353 00354 if (src_coap_msg_ptr->msg_code < COAP_MSG_CODE_RESPONSE_CREATED) { 00355 returned_byte_count += sn_coap_builder_options_calculate_jump_need(src_coap_msg_ptr, 1); 00356 } else { /* Response message */ 00357 returned_byte_count += sn_coap_builder_options_calculate_jump_need(src_coap_msg_ptr, 2); 00358 } 00359 /* Add maximum payload at one Blockwise message */ 00360 returned_byte_count += sn_coap_block_data_size; 00361 returned_byte_count ++; /* For payload marker */ 00362 } else { 00363 returned_byte_count += sn_coap_builder_options_calculate_jump_need(src_coap_msg_ptr, 0); 00364 /* Add wanted payload */ 00365 00366 returned_byte_count += src_coap_msg_ptr->payload_len; 00367 00368 if (src_coap_msg_ptr->payload_len) { 00369 returned_byte_count ++; /* For payload marker */ 00370 } 00371 00372 } 00373 #else 00374 returned_byte_count += src_coap_msg_ptr->payload_len; 00375 if (src_coap_msg_ptr->payload_len) { 00376 returned_byte_count ++; /* For payload marker */ 00377 } 00378 returned_byte_count += sn_coap_builder_options_calculate_jump_need(src_coap_msg_ptr, 0); 00379 #endif 00380 } 00381 00382 return returned_byte_count; 00383 } 00384 00385 /** 00386 * \fn static uint8_t sn_coap_builder_options_calculate_jump_need(sn_coap_hdr_s *src_coap_msg_ptr, uint8_t block_option) 00387 * 00388 * \brief Checks if there is need for option jump 00389 * 00390 * \param *src_coap_msg_ptr is source of checked CoAP message 00391 * 00392 * \param block option marks if block option is to be added to message later. 0 = no block option, 1 = block1 and 2 = block2 00393 * 00394 * \return Returns bytes needed for jumping 00395 */ 00396 00397 static uint8_t sn_coap_builder_options_calculate_jump_need(sn_coap_hdr_s *src_coap_msg_ptr, uint8_t block_option) 00398 { 00399 uint8_t previous_option_number = 0; 00400 uint8_t needed_space = 0; 00401 00402 if (src_coap_msg_ptr->options_list_ptr != NULL) { 00403 /* If option numbers greater than 12 is not used, then jumping is not needed */ 00404 if (!src_coap_msg_ptr->options_list_ptr->uri_query_ptr && 00405 !src_coap_msg_ptr->options_list_ptr->accept_ptr && 00406 !src_coap_msg_ptr->options_list_ptr->location_query_ptr && 00407 !src_coap_msg_ptr->options_list_ptr->block2_ptr && 00408 !src_coap_msg_ptr->options_list_ptr->block1_ptr && 00409 !src_coap_msg_ptr->options_list_ptr->proxy_uri_ptr && 00410 !block_option && 00411 !src_coap_msg_ptr->options_list_ptr->max_age_ptr) { 00412 return 0; 00413 } 00414 00415 if (src_coap_msg_ptr->options_list_ptr->uri_host_ptr != NULL) { 00416 previous_option_number = (COAP_OPTION_URI_HOST); 00417 } 00418 00419 if (src_coap_msg_ptr->options_list_ptr->etag_ptr != NULL) { 00420 previous_option_number = (COAP_OPTION_ETAG); 00421 } 00422 00423 if ((src_coap_msg_ptr->options_list_ptr->observe_ptr != NULL) || (src_coap_msg_ptr->options_list_ptr->observe)) { 00424 previous_option_number = (COAP_OPTION_OBSERVE); 00425 } 00426 00427 if (src_coap_msg_ptr->options_list_ptr->uri_port_ptr != NULL) { 00428 previous_option_number = (COAP_OPTION_URI_PORT); 00429 } 00430 00431 if (src_coap_msg_ptr->options_list_ptr->location_path_ptr != NULL) { 00432 previous_option_number = (COAP_OPTION_LOCATION_PATH); 00433 } 00434 00435 if (src_coap_msg_ptr->uri_path_ptr != NULL) { 00436 previous_option_number = (COAP_OPTION_URI_PATH); 00437 } 00438 if (src_coap_msg_ptr->content_type_ptr != NULL) { 00439 previous_option_number = (COAP_OPTION_CONTENT_FORMAT); 00440 } 00441 if (src_coap_msg_ptr->options_list_ptr->max_age_ptr != NULL) { 00442 if ((COAP_OPTION_MAX_AGE - previous_option_number) > 12) { 00443 needed_space += 1; 00444 } 00445 previous_option_number = (COAP_OPTION_MAX_AGE); 00446 } 00447 00448 if (src_coap_msg_ptr->options_list_ptr->uri_query_ptr != NULL) { 00449 if ((COAP_OPTION_URI_QUERY - previous_option_number) > 12) { 00450 needed_space += 1; 00451 } 00452 previous_option_number = (COAP_OPTION_URI_QUERY); 00453 } 00454 if (src_coap_msg_ptr->options_list_ptr->accept_ptr != NULL) { 00455 if ((COAP_OPTION_ACCEPT - previous_option_number) > 12) { 00456 needed_space += 1; 00457 } 00458 previous_option_number = (COAP_OPTION_ACCEPT); 00459 } 00460 if (src_coap_msg_ptr->options_list_ptr->location_query_ptr != NULL) { 00461 if ((COAP_OPTION_LOCATION_QUERY - previous_option_number) > 12) { 00462 needed_space += 1; 00463 } 00464 previous_option_number = (COAP_OPTION_LOCATION_QUERY); 00465 } 00466 if (src_coap_msg_ptr->options_list_ptr->block2_ptr != NULL) { 00467 if ((COAP_OPTION_BLOCK2 - previous_option_number) > 12 || (block_option == 2 && (COAP_OPTION_BLOCK2 - previous_option_number) > 12)) { 00468 needed_space += 1; 00469 } 00470 previous_option_number = (COAP_OPTION_BLOCK2); 00471 } 00472 if (src_coap_msg_ptr->options_list_ptr->block1_ptr != NULL) { 00473 if ((COAP_OPTION_BLOCK1 - previous_option_number) > 12 || (block_option == 1 && (COAP_OPTION_BLOCK1 - previous_option_number) > 12)) { 00474 needed_space += 1; 00475 } 00476 previous_option_number = (COAP_OPTION_BLOCK1); 00477 } 00478 if (src_coap_msg_ptr->options_list_ptr->proxy_uri_ptr != NULL) { 00479 if ((COAP_OPTION_PROXY_URI - previous_option_number) > 12) { 00480 needed_space += 1; 00481 } 00482 if ((COAP_OPTION_PROXY_URI - previous_option_number) > 269) { //Can not happen 00483 needed_space += 1; 00484 } 00485 previous_option_number = (COAP_OPTION_PROXY_URI); 00486 } 00487 } 00488 00489 else { 00490 if (src_coap_msg_ptr->uri_path_ptr != 0) { 00491 previous_option_number = (COAP_OPTION_URI_PATH); 00492 } 00493 00494 if (src_coap_msg_ptr->content_type_ptr != 0) { 00495 previous_option_number = (COAP_OPTION_CONTENT_FORMAT); 00496 } 00497 00498 #if SN_COAP_BLOCKWISE_MAX_PAYLOAD_SIZE //block_option 1 & 2 only used if this maro is defined 00499 if (block_option == 2) { 00500 if ((COAP_OPTION_BLOCK2 - previous_option_number) > 12) { 00501 needed_space += 1; 00502 } 00503 previous_option_number = (COAP_OPTION_BLOCK2); 00504 } 00505 if (block_option == 1) { 00506 if ((COAP_OPTION_BLOCK1 - previous_option_number) > 12) { 00507 needed_space += 1; 00508 } 00509 previous_option_number = (COAP_OPTION_BLOCK1); 00510 } 00511 #endif 00512 } 00513 return needed_space; 00514 } 00515 00516 /** 00517 * \fn static int8_t sn_coap_builder_header_build(uint8_t **dst_packet_data_pptr, sn_coap_hdr_s *src_coap_msg_ptr) 00518 * 00519 * \brief Builds Header part of Packet data 00520 * 00521 * \param **dst_packet_data_pptr is destination for built Packet data 00522 * 00523 * \param *src_coap_msg_ptr is source for building Packet data 00524 * 00525 * \return Return value is 0 in ok case and -1 in failure case 00526 **************************************************************************** */ 00527 static int8_t sn_coap_builder_header_build(uint8_t **dst_packet_data_pptr, sn_coap_hdr_s *src_coap_msg_ptr) 00528 { 00529 /* * * * Check validity of Header values * * * */ 00530 if (sn_coap_header_validity_check(src_coap_msg_ptr, COAP_VERSION) != 0) { 00531 return -1; 00532 } 00533 00534 /* * * Add CoAP Version * * */ 00535 **dst_packet_data_pptr += COAP_VERSION; 00536 00537 /* * * Add Message type * * */ 00538 **dst_packet_data_pptr += src_coap_msg_ptr->msg_type; 00539 00540 /* * * Add Token length * * */ 00541 **dst_packet_data_pptr += (src_coap_msg_ptr->token_len); 00542 00543 (*dst_packet_data_pptr) ++; 00544 /* * * Add Message code * * */ 00545 **dst_packet_data_pptr = src_coap_msg_ptr->msg_code; 00546 (*dst_packet_data_pptr) ++; 00547 00548 /* * * Add Message ID * * */ 00549 **dst_packet_data_pptr = (uint8_t)(src_coap_msg_ptr->msg_id >> COAP_HEADER_MSG_ID_MSB_SHIFT); /* MSB part */ 00550 (*dst_packet_data_pptr) ++; 00551 **dst_packet_data_pptr = (uint8_t)src_coap_msg_ptr->msg_id; /* LSB part */ 00552 (*dst_packet_data_pptr) ++; 00553 00554 /* Success */ 00555 return 0; 00556 } 00557 00558 /** 00559 * \fn static int8_t sn_coap_builder_options_build(uint8_t **dst_packet_data_pptr, sn_coap_hdr_s *src_coap_msg_ptr) 00560 * 00561 * \brief Builds Options part of Packet data 00562 * 00563 * \param **dst_packet_data_pptr is destination for built Packet data 00564 * 00565 * \param *src_coap_msg_ptr is source for building Packet data 00566 * 00567 * \return Return value is 0 in every case 00568 */ 00569 static int8_t sn_coap_builder_options_build(uint8_t **dst_packet_data_pptr, sn_coap_hdr_s *src_coap_msg_ptr) 00570 { 00571 int16_t ret_status = 0; 00572 00573 /* * * * Check if Options are used at all * * * */ 00574 if (src_coap_msg_ptr->uri_path_ptr == NULL && src_coap_msg_ptr->token_ptr == NULL && 00575 src_coap_msg_ptr->content_type_ptr == NULL && src_coap_msg_ptr->options_list_ptr == NULL) { 00576 return 0; 00577 } 00578 00579 /* * * * First add Token option * * * */ 00580 if (src_coap_msg_ptr->token_len && src_coap_msg_ptr->token_ptr) { 00581 memcpy(*dst_packet_data_pptr, src_coap_msg_ptr->token_ptr, src_coap_msg_ptr->token_len); 00582 } 00583 (*dst_packet_data_pptr) += src_coap_msg_ptr->token_len; 00584 00585 /* Then build rest of the options */ 00586 00587 /* * * * Initialize previous Option number for new built message * * * */ 00588 global_previous_option_number = 0; 00589 00590 //missing: COAP_OPTION_IF_MATCH, COAP_OPTION_IF_NONE_MATCH, COAP_OPTION_SIZE 00591 00592 /* Check if less used options are used at all */ 00593 if (src_coap_msg_ptr->options_list_ptr != NULL) { 00594 /* * * * Build Uri-Host option * * * */ 00595 sn_coap_builder_options_build_add_one_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->uri_host_len, 00596 src_coap_msg_ptr->options_list_ptr->uri_host_ptr, COAP_OPTION_URI_HOST); 00597 00598 /* * * * Build ETag option * * * */ 00599 sn_coap_builder_options_build_add_multiple_option(dst_packet_data_pptr, &src_coap_msg_ptr->options_list_ptr->etag_ptr, 00600 (uint16_t *)&src_coap_msg_ptr->options_list_ptr->etag_len, COAP_OPTION_ETAG); 00601 00602 /* * * * Build Observe option * * * * */ 00603 ret_status = sn_coap_builder_options_build_add_one_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->observe_len, 00604 src_coap_msg_ptr->options_list_ptr->observe_ptr, COAP_OPTION_OBSERVE); 00605 if (ret_status == 0) { 00606 sn_coap_builder_options_build_add_zero_length_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->observe_len, src_coap_msg_ptr->options_list_ptr->observe, COAP_OPTION_OBSERVE); 00607 } 00608 00609 /* * * * Build Uri-Port option * * * */ 00610 sn_coap_builder_options_build_add_one_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->uri_port_len, 00611 src_coap_msg_ptr->options_list_ptr->uri_port_ptr, COAP_OPTION_URI_PORT); 00612 00613 /* * * * Build Location-Path option * * * */ 00614 sn_coap_builder_options_build_add_multiple_option(dst_packet_data_pptr, &src_coap_msg_ptr->options_list_ptr->location_path_ptr, 00615 &src_coap_msg_ptr->options_list_ptr->location_path_len, COAP_OPTION_LOCATION_PATH); 00616 } 00617 /* * * * Build Uri-Path option * * * */ 00618 sn_coap_builder_options_build_add_multiple_option(dst_packet_data_pptr, &src_coap_msg_ptr->uri_path_ptr, 00619 &src_coap_msg_ptr->uri_path_len, COAP_OPTION_URI_PATH); 00620 00621 /* * * * Build Content-Type option * * * */ 00622 sn_coap_builder_options_build_add_one_option(dst_packet_data_pptr, src_coap_msg_ptr->content_type_len, 00623 src_coap_msg_ptr->content_type_ptr, COAP_OPTION_CONTENT_FORMAT); 00624 00625 if (src_coap_msg_ptr->options_list_ptr != NULL) { 00626 /* * * * Build Max-Age option * * * */ 00627 sn_coap_builder_options_build_add_one_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->max_age_len, 00628 src_coap_msg_ptr->options_list_ptr->max_age_ptr, COAP_OPTION_MAX_AGE); 00629 00630 /* * * * Build Uri-Query option * * * * */ 00631 sn_coap_builder_options_build_add_multiple_option(dst_packet_data_pptr, &src_coap_msg_ptr->options_list_ptr->uri_query_ptr, 00632 &src_coap_msg_ptr->options_list_ptr->uri_query_len, COAP_OPTION_URI_QUERY); 00633 00634 /* * * * Build Accept option * * * * */ 00635 sn_coap_builder_options_build_add_multiple_option(dst_packet_data_pptr, &src_coap_msg_ptr->options_list_ptr->accept_ptr, 00636 (uint16_t *)&src_coap_msg_ptr->options_list_ptr->accept_len, COAP_OPTION_ACCEPT); 00637 } 00638 00639 if (src_coap_msg_ptr->options_list_ptr != NULL) { 00640 /* * * * Build Location-Query option * * * */ 00641 sn_coap_builder_options_build_add_multiple_option(dst_packet_data_pptr, &src_coap_msg_ptr->options_list_ptr->location_query_ptr, 00642 &src_coap_msg_ptr->options_list_ptr->location_query_len, COAP_OPTION_LOCATION_QUERY); 00643 00644 /* * * * Build Block2 option * * * * */ 00645 sn_coap_builder_options_build_add_one_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->block2_len, 00646 src_coap_msg_ptr->options_list_ptr->block2_ptr, COAP_OPTION_BLOCK2); 00647 00648 /* * * * Build Block1 option * * * * */ 00649 sn_coap_builder_options_build_add_one_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->block1_len, 00650 src_coap_msg_ptr->options_list_ptr->block1_ptr, COAP_OPTION_BLOCK1); 00651 00652 /* * * * Build Proxy-Uri option * * * */ 00653 sn_coap_builder_options_build_add_one_option(dst_packet_data_pptr, src_coap_msg_ptr->options_list_ptr->proxy_uri_len, 00654 src_coap_msg_ptr->options_list_ptr->proxy_uri_ptr, COAP_OPTION_PROXY_URI); 00655 } 00656 00657 /* Success */ 00658 return 0; 00659 } 00660 00661 /** 00662 * \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) 00663 * 00664 * \brief Adds Options part of Packet data 00665 * 00666 * \param **dst_packet_data_pptr is destination for built Packet data 00667 * 00668 * \param option_value_len is Option value length to be added 00669 * 00670 * \param *option_value_ptr is pointer to Option value data to be added 00671 * 00672 * \param option_number is Option number to be added 00673 * 00674 * \return Return value is 0 if option was not added, 1 if added 00675 */ 00676 static int16_t sn_coap_builder_options_build_add_one_option(uint8_t **dst_packet_data_pptr, uint16_t option_len, 00677 uint8_t *option_ptr, sn_coap_option_numbers_e option_number) 00678 { 00679 /* Check if there is option at all */ 00680 if (option_ptr != NULL) { 00681 uint16_t option_delta; 00682 00683 option_delta = (option_number - global_previous_option_number); 00684 00685 /* * * Build option header * * */ 00686 00687 /* First option length without extended part */ 00688 if (option_len <= 12) { 00689 **dst_packet_data_pptr = option_len; 00690 } 00691 00692 else if (option_len > 12 && option_len < 269) { 00693 **dst_packet_data_pptr = 0x0D; 00694 } 00695 00696 else if (option_len >= 269) { 00697 **dst_packet_data_pptr = 0x0E; 00698 } 00699 00700 /* Then option delta with extensions, and move pointer */ 00701 if (option_delta <= 12) { 00702 **dst_packet_data_pptr += (option_delta << 4); 00703 *dst_packet_data_pptr += 1; 00704 } 00705 00706 else if (option_delta > 12 && option_delta < 269) { 00707 **dst_packet_data_pptr += 0xD0; 00708 option_delta -= 13; 00709 00710 *(*dst_packet_data_pptr + 1) = (uint8_t)option_delta; 00711 *dst_packet_data_pptr += 2; 00712 } 00713 //This is currently dead code (but possibly needed in future) 00714 else if (option_delta >= 269) { 00715 **dst_packet_data_pptr += 0xE0; 00716 option_delta -= 269; 00717 00718 *(*dst_packet_data_pptr + 2) = (uint8_t)option_delta; 00719 *(*dst_packet_data_pptr + 1) = (option_delta >> 8); 00720 *dst_packet_data_pptr += 3; 00721 } 00722 00723 /* Now option length extensions, if needed */ 00724 if (option_len > 12 && option_len < 269) { 00725 **dst_packet_data_pptr = (uint8_t)(option_len - 13); 00726 *dst_packet_data_pptr += 1; 00727 } 00728 00729 else if (option_len >= 269) { 00730 *(*dst_packet_data_pptr + 1) = (uint8_t)(option_len - 269); 00731 **dst_packet_data_pptr = ((option_len - 269) >> 8); 00732 *dst_packet_data_pptr += 2; 00733 } 00734 00735 global_previous_option_number = option_number; 00736 00737 /* Write Option value */ 00738 memcpy(*dst_packet_data_pptr, option_ptr, option_len); 00739 00740 /* Increase destination Packet data pointer */ 00741 (*dst_packet_data_pptr) += option_len; 00742 00743 return 1; 00744 } 00745 00746 /* Success */ 00747 return 0; 00748 } 00749 00750 /* 00751 * @return 1 if was added 0 otherwise 00752 */ 00753 int16_t sn_coap_builder_options_build_add_zero_length_option(uint8_t **dst_packet_data_pptr, uint8_t option_length, uint8_t option_exist, sn_coap_option_numbers_e option_number) 00754 { 00755 if ((option_exist != 0) && (option_length == 0)) { 00756 uint16_t option_delta; 00757 00758 option_delta = (option_number - global_previous_option_number); 00759 00760 /* * * Build option header * * */ 00761 00762 /* First option length without extended part */ 00763 **dst_packet_data_pptr = 0; 00764 00765 /* Then option delta with extensions, and move pointer */ 00766 if (option_delta <= 12) { 00767 **dst_packet_data_pptr += (option_delta << 4); 00768 *dst_packet_data_pptr += 1; 00769 } 00770 //Cannot happen currently --> 00771 else if (option_delta > 12 && option_delta < 269) { 00772 **dst_packet_data_pptr += 0xD0; 00773 option_delta -= 13; 00774 00775 *(*dst_packet_data_pptr + 1) = (uint8_t)option_delta; 00776 *dst_packet_data_pptr += 2; 00777 } 00778 00779 else if (option_delta >= 269) { 00780 **dst_packet_data_pptr += 0xE0; 00781 option_delta -= 269; 00782 00783 *(*dst_packet_data_pptr + 2) = (uint8_t)option_delta; 00784 *(*dst_packet_data_pptr + 1) = (option_delta >> 8); 00785 *dst_packet_data_pptr += 3; 00786 } 00787 //<-- Cannot happen currently 00788 00789 global_previous_option_number = option_number; 00790 00791 return 1; 00792 } 00793 return 0; 00794 } 00795 00796 /** 00797 * \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) 00798 * 00799 * \brief Builds Option Uri-Query from given CoAP Header structure to Packet data 00800 * 00801 * \param **dst_packet_data_pptr is destination for built Packet data 00802 * 00803 * \param uint8_t **src_pptr 00804 * 00805 * \param uint16_t *src_len_ptr 00806 * 00807 * \paramsn_coap_option_numbers_e option option to be added 00808 * 00809 * \return Return value is 0 always 00810 */ 00811 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) 00812 { 00813 /* Check if there is option at all */ 00814 if (*src_pptr != NULL) { 00815 uint8_t *query_ptr = *src_pptr; 00816 uint8_t query_part_count = 0; 00817 uint16_t query_len = *src_len_ptr; 00818 uint8_t i = 0; 00819 uint16_t query_part_offset = 0; 00820 00821 /* Get query part count */ 00822 query_part_count = sn_coap_builder_options_get_option_part_count(query_len, query_ptr, option); 00823 00824 /* * * * Options by adding all parts to option * * * */ 00825 for (i = 0; i < query_part_count; i++) { 00826 /* Get length of query part */ 00827 uint16_t one_query_part_len = sn_coap_builder_options_get_option_part_length_from_whole_option_string(query_len, query_ptr, i, option); 00828 00829 /* Get position of query part */ 00830 query_part_offset = sn_coap_builder_options_get_option_part_position(query_len, query_ptr, i, option); 00831 00832 /* Add Uri-query's one part to Options */ 00833 sn_coap_builder_options_build_add_one_option(dst_packet_data_pptr, one_query_part_len, *src_pptr + query_part_offset, option); 00834 } 00835 } 00836 /* Success */ 00837 return 0; 00838 } 00839 00840 00841 /** 00842 * \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) 00843 * 00844 * \brief Calculates needed Packet data memory size for option 00845 * 00846 * \param path_len is length of calculated strting(s) 00847 * 00848 * \param *path_ptr is pointer to calculated options 00849 * 00850 * \return Return value is count of needed memory as bytes for Uri-query option 00851 */ 00852 static uint16_t sn_coap_builder_options_calc_option_size(uint16_t query_len, uint8_t *query_ptr, sn_coap_option_numbers_e option) 00853 { 00854 uint8_t query_part_count = sn_coap_builder_options_get_option_part_count(query_len, query_ptr, option); 00855 uint8_t i = 0; 00856 uint16_t ret_value = 0; 00857 00858 /* * * * * * * * * * * * * * * * * * * * * * * * */ 00859 /* * * * Calculate Uri-query options length * * */ 00860 /* * * * * * * * * * * * * * * * * * * * * * * * */ 00861 for (i = 0; i < query_part_count; i++) { 00862 /* * * Length of Option number and Option value length * * */ 00863 00864 /* Get length of Query part */ 00865 uint16_t one_query_part_len = sn_coap_builder_options_get_option_part_length_from_whole_option_string(query_len, query_ptr, i, option); 00866 00867 /* Check option length */ 00868 switch (option) { 00869 case (COAP_OPTION_ETAG): /* Length 1-8 */ 00870 if (one_query_part_len < 1 || one_query_part_len > 8) { 00871 return 0; 00872 } 00873 break; 00874 case (COAP_OPTION_LOCATION_PATH): /* Length 0-255 */ 00875 case (COAP_OPTION_URI_PATH): /* Length 0-255 */ 00876 case (COAP_OPTION_LOCATION_QUERY): /* Length 0-255 */ 00877 if (one_query_part_len > 255) { 00878 return 0; 00879 } 00880 break; 00881 case (COAP_OPTION_URI_QUERY): /* Length 1-255 */ 00882 if (one_query_part_len < 1 || one_query_part_len > 255) { 00883 return 0; 00884 } 00885 break; 00886 case (COAP_OPTION_ACCEPT): /* Length 0-2 */ 00887 if (one_query_part_len > 2) { 00888 return 0; 00889 } 00890 break; 00891 default: 00892 break; //impossible scenario currently 00893 } 00894 00895 /* Check if 4 bits are enough for writing Option value length */ 00896 if (one_query_part_len <= 12) { 00897 /* 4 bits are enough for Option value length */ 00898 ret_value++; 00899 } else if (one_query_part_len >= 13 && one_query_part_len < 269) { 00900 /* Extra byte for Option value length is needed */ 00901 ret_value += 2; 00902 } 00903 //This can only happen if we are in default case above, currently is not happening 00904 else if (one_query_part_len >= 270 && one_query_part_len < 1034) { 00905 /* Extra bytes for Option value length is needed */ 00906 ret_value += 3; 00907 } 00908 00909 00910 /* * * Length of Option value * * */ 00911 00912 /* Increase options length */ 00913 ret_value += one_query_part_len; 00914 } 00915 00916 /* Success */ 00917 return ret_value; 00918 } 00919 00920 00921 00922 /** 00923 * \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) 00924 * 00925 * \brief Gets query part count from whole option string 00926 * 00927 * \param query_len is length of whole Path 00928 * 00929 * \param *query_ptr is pointer to the start of whole Path 00930 * 00931 * \return Return value is count of query parts 00932 */ 00933 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) 00934 { 00935 uint8_t returned_query_count = 0; 00936 uint16_t query_len_index = 0; 00937 uint8_t char_to_search = '&'; 00938 00939 if (option == COAP_OPTION_URI_PATH || option == COAP_OPTION_LOCATION_PATH) { 00940 char_to_search = '/'; 00941 } 00942 00943 /* Loop whole query and search '\0' characters (not first and last char) */ 00944 for (query_len_index = 1; query_len_index < query_len - 1; query_len_index++) { 00945 /* If new query part starts */ 00946 if (*(query_ptr + query_len_index) == char_to_search) { /* If match */ 00947 returned_query_count++; 00948 } 00949 } 00950 00951 returned_query_count++; 00952 00953 return returned_query_count; 00954 } 00955 00956 /** 00957 * \fn static uint16_t sn_coap_builder_options_get_option_part_length_from_whole_option_string(uint16_t query_len, 00958 uint8_t *query_ptr, 00959 uint8_t query_index, sn_coap_option_numbers_e option) 00960 * 00961 * \brief Gets one's query part length from whole query string 00962 * 00963 * \param query_len is length of whole string 00964 * 00965 * \param *query_ptr is pointer to the start of whole string 00966 * 00967 * \param query_index is query part index to be found 00968 * 00969 * \param sn_coap_option_numbers_e option is option number of the option 00970 * 00971 * \return Return value is length of query part 00972 */ 00973 static uint16_t sn_coap_builder_options_get_option_part_length_from_whole_option_string(uint16_t query_len, uint8_t *query_ptr, 00974 uint8_t query_index, sn_coap_option_numbers_e option) 00975 { 00976 uint16_t returned_query_part_len = 0; 00977 uint8_t temp_query_index = 0; 00978 uint16_t query_len_index = 0; 00979 uint8_t char_to_search = '&'; 00980 00981 if (option == COAP_OPTION_URI_PATH || option == COAP_OPTION_LOCATION_PATH) { 00982 char_to_search = '/'; 00983 } 00984 00985 /* Loop whole query and search '\0' characters */ 00986 for (query_len_index = 0; query_len_index < query_len; query_len_index++) { 00987 /* Store character to temp_char for helping debugging */ 00988 uint8_t temp_char = *query_ptr; 00989 00990 /* If new query part starts */ 00991 if (temp_char == char_to_search && returned_query_part_len > 0) { /* returned_query_part_len > 0 is for querys which start with "\0" */ 00992 /* If query part index is wanted */ 00993 if (temp_query_index == query_index) { 00994 /* Return length of query part */ 00995 return returned_query_part_len; 00996 } else { 00997 /* Reset length of query part because wanted query part finding continues*/ 00998 returned_query_part_len = 0; 00999 } 01000 01001 /* Next query part is looped */ 01002 temp_query_index++; 01003 } else if (temp_char != char_to_search) { /* Else if query part continues */ 01004 /* Increase query part length */ 01005 returned_query_part_len++; 01006 } 01007 01008 query_ptr++; 01009 } 01010 01011 /* Return length of query part in cases that query part does not finish to '\0' character (last query part can be like that) */ 01012 return returned_query_part_len; 01013 } 01014 01015 /** 01016 * \fn static uint16_t sn_coap_builder_options_get_option_part_position(uint16_t query_len, 01017 uint8_t *query_ptr, 01018 uint8_t query_index, sn_coap_option_numbers_e option) 01019 * 01020 * \brief Gets query part position in whole query 01021 * 01022 * \param query_len is length of whole query 01023 * 01024 * \param *query_ptr is pointer to the start of whole query 01025 * 01026 * \param query_index is query part index to be found 01027 * 01028 * \return Return value is position (= offset) of query part in whole query. In 01029 * fail cases -1 is returned. 01030 */ 01031 static int16_t sn_coap_builder_options_get_option_part_position(uint16_t query_len, uint8_t *query_ptr, 01032 uint8_t query_index, sn_coap_option_numbers_e option) 01033 { 01034 uint16_t returned_query_part_offset = 0; 01035 uint8_t temp_query_index = 0; 01036 uint16_t query_len_index = 0; 01037 uint8_t char_to_search = '&'; 01038 01039 if (option == COAP_OPTION_URI_PATH || option == COAP_OPTION_LOCATION_PATH) { 01040 char_to_search = '/'; 01041 } 01042 01043 if (query_index == 0) { 01044 if (*query_ptr == 0 || *query_ptr == char_to_search) { 01045 return 1; 01046 } else { 01047 return 0; 01048 } 01049 } 01050 01051 /* Loop whole query and search separator characters */ 01052 for (query_len_index = 0; query_len_index < query_len; query_len_index++) { 01053 /* Store character to temp_char for helping debugging */ 01054 uint8_t temp_char = *query_ptr; 01055 01056 /* If new query part starts */ 01057 if (temp_char == char_to_search && returned_query_part_offset > 0) { /* returned_query_part_offset > 0 is for querys which start with searched char */ 01058 /* If query part index is wanted */ 01059 if (temp_query_index == (query_index - 1)) { 01060 /* Return offset of query part */ 01061 return (returned_query_part_offset + 1); /* Plus one is for passing separator */ 01062 } 01063 01064 /* Next query part is looped */ 01065 temp_query_index++; 01066 } 01067 01068 returned_query_part_offset++; 01069 01070 query_ptr++; 01071 } 01072 01073 return -1; //Dead code? 01074 } 01075 01076 01077 /** 01078 * \fn static void sn_coap_builder_payload_build(uint8_t **dst_packet_data_pptr, sn_coap_hdr_s *src_coap_msg_ptr) 01079 * 01080 * \brief Builds Options part of Packet data 01081 * 01082 * \param **dst_packet_data_pptr is destination for built Packet data 01083 * 01084 * \param *src_coap_msg_ptr is source for building Packet data 01085 */ 01086 static void sn_coap_builder_payload_build(uint8_t **dst_packet_data_pptr, sn_coap_hdr_s *src_coap_msg_ptr) 01087 { 01088 /* Check if Payload is used at all */ 01089 if (src_coap_msg_ptr->payload_ptr != NULL) { 01090 /* Write Payload marker */ 01091 01092 **dst_packet_data_pptr = 0xff; 01093 (*dst_packet_data_pptr)++; 01094 01095 /* Write Payload */ 01096 memcpy(*dst_packet_data_pptr, src_coap_msg_ptr->payload_ptr, src_coap_msg_ptr->payload_len); 01097 01098 /* Increase destination Packet data pointer */ 01099 (*dst_packet_data_pptr) += src_coap_msg_ptr->payload_len; 01100 } 01101 } 01102
Generated on Tue Jul 12 2022 12:47:49 by
