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: FXAS21002 FXOS8700Q
sn_nsdl.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 * \file sn_nsdl.c 00018 * 00019 * \brief Nano service device library 00020 * 00021 */ 00022 00023 // Needed for PRIu64 on FreeRTOS 00024 #include <stdio.h> 00025 // Note: this macro is needed on armcc to get the the limit macros like UINT16_MAX 00026 #ifndef __STDC_LIMIT_MACROS 00027 #define __STDC_LIMIT_MACROS 00028 #endif 00029 00030 // Note: this macro is needed on armcc to get the the PRI*32 macros 00031 // from inttypes.h in a C++ code. 00032 #ifndef __STDC_FORMAT_MACROS 00033 #define __STDC_FORMAT_MACROS 00034 #endif 00035 00036 #include <string.h> 00037 #include <assert.h> 00038 00039 #include "ns_types.h" 00040 #include "sn_nsdl.h" 00041 #include "sn_coap_header.h" 00042 #include "sn_coap_protocol.h" 00043 #include "source/include/sn_coap_protocol_internal.h" 00044 #include "sn_nsdl_lib.h" 00045 #include "sn_grs.h" 00046 #include "mbed-trace/mbed_trace.h" 00047 #include "mbedtls/base64.h" 00048 #include "common_functions.h" 00049 #include "randLIB.h" 00050 00051 #include <stdlib.h> 00052 00053 /* Defines */ 00054 #define TRACE_GROUP "mClt" 00055 #define RESOURCE_DIR_LEN 2 00056 #define EP_NAME_PARAMETERS_LEN 3 00057 #define ET_PARAMETER_LEN 3 00058 #define LT_PARAMETER_LEN 3 00059 #define DOMAIN_PARAMETER_LEN 2 00060 #define RT_PARAMETER_LEN 3 00061 #define IF_PARAMETER_LEN 3 00062 #define NAME_PARAMETER_LEN 5 00063 #define OBS_PARAMETER_LEN 3 00064 #define AOBS_PARAMETER_LEN 5 00065 #define COAP_CON_PARAMETER_LEN 3 00066 #define BS_EP_PARAMETER_LEN 3 00067 #define BS_QUEUE_MODE_PARAMETER_LEN 2 00068 #define RESOURCE_VALUE_PARAMETER_LEN 2 00069 #define FIRMWARE_DOWNLOAD_LEN 2 00070 #define GENERIC_DOWNLOAD_LEN 8 00071 00072 #define SN_NSDL_EP_REGISTER_MESSAGE 1 00073 #define SN_NSDL_EP_UPDATE_MESSAGE 2 00074 00075 #if defined MBED_CONF_MBED_CLIENT_COAP_DISABLE_OBS_FEATURE 00076 #define COAP_DISABLE_OBS_FEATURE MBED_CONF_MBED_CLIENT_COAP_DISABLE_OBS_FEATURE 00077 #endif 00078 00079 #if defined MBED_CONF_MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00080 #define MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE MBED_CONF_MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00081 #endif 00082 00083 /* Constants */ 00084 static uint8_t ep_name_parameter_string[] = {'e', 'p', '='}; /* Endpoint name. A unique name for the registering node in a domain. */ 00085 static uint8_t resource_path_ptr[] = {'r', 'd'}; /* For resource directory */ 00086 static uint8_t resource_type_parameter[] = {'r', 't', '='}; /* Resource type. Only once for registration */ 00087 #ifndef COAP_DISABLE_OBS_FEATURE 00088 static uint8_t obs_parameter[] = {'o', 'b', 's'}; /* Observable */ 00089 static uint8_t aobs_parameter[] = {'a', 'o', 'b', 's', '='}; /* Auto observable */ 00090 #endif 00091 static uint8_t if_description_parameter[] = {'i', 'f', '='}; /* Interface description. Only once */ 00092 static uint8_t ep_lifetime_parameter[] = {'l', 't', '='}; /* Lifetime. Number of seconds that this registration will be valid for. Must be updated within this time, or will be removed. */ 00093 static uint8_t ep_domain_parameter[] = {'d', '='}; /* Domain name. If this parameter is missing, a default domain is assumed. */ 00094 static uint8_t coap_con_type_parameter[] = {'c', 't', '='}; /* CoAP content type */ 00095 static uint8_t resource_value[] = {'v', '='}; /* Resource value */ 00096 #ifdef RESOURCE_ATTRIBUTES_LIST 00097 static uint8_t name_parameter[] = {'n', 'a', 'm', 'e', '='}; 00098 #endif 00099 00100 static uint8_t firmware_download_uri[] = {'f', 'w'}; /* Path for firmware update. */ 00101 static uint8_t generic_download_uri[] = {'d', 'o', 'w', 'n', 'l', 'o', 'a', 'd'}; /* Path for generic download. */ 00102 00103 /* * OMA BS parameters * */ 00104 static uint8_t bs_uri[] = {'b', 's'}; 00105 static uint8_t bs_ep_name[] = {'e', 'p', '='}; 00106 static uint8_t et_parameter[] = {'e', 't', '='}; /* Endpoint type */ 00107 static uint8_t bs_queue_mode[] = {'b', '='}; 00108 00109 /* Function prototypes */ 00110 static int32_t sn_nsdl_internal_coap_send(struct nsdl_s *handle, sn_coap_hdr_s *coap_header_ptr, sn_nsdl_addr_s *dst_addr_ptr); 00111 static void sn_nsdl_resolve_nsp_address(struct nsdl_s *handle); 00112 int8_t sn_nsdl_build_registration_body(struct nsdl_s *handle, sn_coap_hdr_s *message_ptr, uint8_t updating_registeration); 00113 static uint16_t sn_nsdl_calculate_registration_body_size(struct nsdl_s *handle, uint8_t updating_registeration, int8_t *error); 00114 static uint8_t sn_nsdl_calculate_uri_query_option_len(sn_nsdl_ep_parameters_s *endpoint_info_ptr, uint8_t msg_type, const char *uri_query); 00115 static int8_t sn_nsdl_fill_uri_query_options(struct nsdl_s *handle, sn_nsdl_ep_parameters_s *parameter_ptr, sn_coap_hdr_s *source_msg_ptr, uint8_t msg_type, const char *uri_query); 00116 static int8_t sn_nsdl_local_rx_function(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr, sn_nsdl_addr_s *address_ptr); 00117 static int8_t sn_nsdl_resolve_ep_information(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr); 00118 static uint8_t sn_nsdl_itoa_len(uint32_t value); 00119 static uint8_t *sn_nsdl_itoa(uint8_t *ptr, uint32_t value); 00120 static int8_t set_endpoint_info(struct nsdl_s *handle, sn_nsdl_ep_parameters_s *endpoint_info_ptr); 00121 static bool validateParameters(sn_nsdl_ep_parameters_s *parameter_ptr); 00122 static bool validate(uint8_t* ptr, uint32_t len, char illegalChar); 00123 static bool sn_nsdl_check_uint_overflow(uint16_t resource_size, uint16_t param_a, uint16_t param_b); 00124 static void remove_previous_block_data(struct nsdl_s *handle, sn_nsdl_addr_s *src_ptr, const uint32_t block_number); 00125 static bool update_last_block_data(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr, bool block1); 00126 #if MBED_CONF_MBED_TRACE_ENABLE 00127 static const char* sn_nsdl_coap_status_description(sn_coap_status_e status); 00128 static const char* sn_nsdl_coap_message_code_desc(int msg_code); 00129 static const char* sn_nsdl_coap_message_type_desc(int msg_type); 00130 #endif 00131 00132 static void sn_nsdl_add_token(struct nsdl_s *handle, uint32_t *token, sn_coap_hdr_s *message_ptr); 00133 00134 int8_t sn_nsdl_destroy(struct nsdl_s *handle) 00135 { 00136 if (handle == NULL) { 00137 return SN_NSDL_FAILURE; 00138 } 00139 00140 if (handle->ep_information_ptr) { 00141 handle->sn_nsdl_free(handle->ep_information_ptr->endpoint_name_ptr); 00142 handle->sn_nsdl_free(handle->ep_information_ptr->domain_name_ptr); 00143 handle->sn_nsdl_free(handle->ep_information_ptr->location_ptr); 00144 handle->sn_nsdl_free(handle->ep_information_ptr->type_ptr); 00145 handle->sn_nsdl_free(handle->ep_information_ptr->lifetime_ptr); 00146 handle->sn_nsdl_free(handle->ep_information_ptr); 00147 } 00148 00149 if (handle->server_address.addr_ptr) { 00150 handle->sn_nsdl_free(handle->server_address.addr_ptr); 00151 handle->server_address.addr_ptr = NULL; 00152 handle->server_address.type = SN_NSDL_ADDRESS_TYPE_NONE; 00153 } 00154 00155 /* Destroy also libCoap and grs part of libNsdl */ 00156 sn_coap_protocol_destroy(handle->grs->coap); 00157 sn_grs_destroy(handle->grs); 00158 handle->sn_nsdl_free(handle); 00159 00160 return SN_NSDL_SUCCESS; 00161 } 00162 00163 struct nsdl_s *sn_nsdl_init(uint8_t (*sn_nsdl_tx_cb)(struct nsdl_s *, sn_nsdl_capab_e , uint8_t *, uint16_t, sn_nsdl_addr_s *), 00164 uint8_t (*sn_nsdl_rx_cb)(struct nsdl_s *, sn_coap_hdr_s *, sn_nsdl_addr_s *), 00165 void *(*sn_nsdl_alloc)(uint16_t), void (*sn_nsdl_free)(void *), 00166 uint8_t (*sn_nsdl_auto_obs_token_cb)(struct nsdl_s *, const char *, uint8_t *)) 00167 { 00168 /* Check pointers and define function pointers */ 00169 if (!sn_nsdl_alloc || !sn_nsdl_free || !sn_nsdl_tx_cb || !sn_nsdl_rx_cb) { 00170 return NULL; 00171 } 00172 00173 struct nsdl_s *handle = NULL; 00174 00175 handle = sn_nsdl_alloc(sizeof(struct nsdl_s)); 00176 00177 if (handle == NULL) { 00178 return NULL; 00179 } 00180 00181 memset(handle, 0, sizeof(struct nsdl_s)); 00182 00183 /* Define function pointers */ 00184 handle->sn_nsdl_alloc = sn_nsdl_alloc; 00185 handle->sn_nsdl_free = sn_nsdl_free; 00186 00187 handle->sn_nsdl_tx_callback = sn_nsdl_tx_cb; 00188 handle->sn_nsdl_rx_callback = sn_nsdl_rx_cb; 00189 handle->sn_nsdl_auto_obs_token_callback = sn_nsdl_auto_obs_token_cb; 00190 00191 /* Initialize ep parameters struct */ 00192 if (!handle->ep_information_ptr) { 00193 handle->ep_information_ptr = handle->sn_nsdl_alloc(sizeof(sn_nsdl_ep_parameters_s)); 00194 if (!handle->ep_information_ptr) { 00195 sn_nsdl_free(handle); 00196 return NULL; 00197 } 00198 memset(handle->ep_information_ptr, 0, sizeof(sn_nsdl_ep_parameters_s)); 00199 } 00200 00201 handle->grs = sn_grs_init(sn_nsdl_tx_cb, &sn_nsdl_local_rx_function, sn_nsdl_alloc, sn_nsdl_free); 00202 00203 /* Initialize GRS */ 00204 if (handle->grs == NULL) { 00205 handle->sn_nsdl_free(handle->ep_information_ptr); 00206 handle->ep_information_ptr = 0; 00207 sn_nsdl_free(handle); 00208 return NULL; 00209 } 00210 00211 sn_nsdl_resolve_nsp_address(handle); 00212 00213 handle->sn_nsdl_endpoint_registered = SN_NSDL_ENDPOINT_NOT_REGISTERED; 00214 handle->context = NULL; 00215 00216 randLIB_get_n_bytes_random(&handle->token_seed, sizeof(handle->token_seed)); 00217 if (handle->token_seed == 0) { 00218 handle->token_seed++; 00219 } 00220 return handle; 00221 } 00222 00223 uint16_t sn_nsdl_register_endpoint(struct nsdl_s *handle, 00224 sn_nsdl_ep_parameters_s *endpoint_info_ptr, 00225 const char *uri_query_parameters) 00226 { 00227 /* Local variables */ 00228 sn_coap_hdr_s *register_message_ptr; 00229 uint16_t message_id = 0; 00230 00231 if (endpoint_info_ptr == NULL || handle == NULL) { 00232 return 0; 00233 } 00234 00235 // Clear any leftovers from previous registration or bootstrap 00236 sn_nsdl_clear_coap_sent_blockwise_messages(handle); 00237 sn_nsdl_clear_coap_received_blockwise_messages(handle); 00238 sn_nsdl_clear_coap_resending_queue(handle); 00239 00240 /*** Build endpoint register message ***/ 00241 00242 handle->is_bs_server = false; 00243 00244 /* Allocate memory for header struct */ 00245 register_message_ptr = sn_coap_parser_alloc_message(handle->grs->coap); 00246 if (register_message_ptr == NULL) { 00247 return 0; 00248 } 00249 00250 /* Fill message fields -> confirmable post to specified NSP path */ 00251 register_message_ptr->msg_type = COAP_MSG_TYPE_CONFIRMABLE; 00252 register_message_ptr->msg_code = COAP_MSG_CODE_REQUEST_POST; 00253 00254 /* Allocate memory for the extended options list */ 00255 if (sn_coap_parser_alloc_options(handle->grs->coap, register_message_ptr) == NULL) { 00256 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr); 00257 register_message_ptr = 0; 00258 return 0; 00259 } 00260 00261 register_message_ptr->uri_path_len = sizeof(resource_path_ptr); 00262 register_message_ptr->uri_path_ptr = resource_path_ptr; 00263 00264 /* Fill Uri-query options */ 00265 if( SN_NSDL_FAILURE == sn_nsdl_fill_uri_query_options(handle, endpoint_info_ptr, 00266 register_message_ptr, SN_NSDL_EP_REGISTER_MESSAGE, 00267 uri_query_parameters) ){ 00268 register_message_ptr->uri_path_ptr = NULL; 00269 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr); 00270 return 0; 00271 } 00272 00273 if (endpoint_info_ptr->ds_register_mode == REGISTER_WITH_RESOURCES) { 00274 /* Built body for message */ 00275 if (sn_nsdl_build_registration_body(handle, register_message_ptr, 0) == SN_NSDL_FAILURE) { 00276 register_message_ptr->uri_path_ptr = NULL; 00277 register_message_ptr->options_list_ptr->uri_host_ptr = NULL; 00278 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr); 00279 return 0; 00280 } 00281 } 00282 tr_info("REGISTER MESSAGE %.*s", register_message_ptr->payload_len, register_message_ptr->payload_ptr); 00283 00284 /* Clean (possible) existing and save new endpoint info to handle */ 00285 if (set_endpoint_info(handle, endpoint_info_ptr) == -1) { 00286 00287 handle->sn_nsdl_free(register_message_ptr->payload_ptr); 00288 register_message_ptr->payload_ptr = NULL; 00289 00290 register_message_ptr->uri_path_ptr = NULL; 00291 register_message_ptr->options_list_ptr->uri_host_ptr = NULL; 00292 00293 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr); 00294 00295 return 0; 00296 } 00297 00298 sn_nsdl_add_token(handle, &handle->register_token, register_message_ptr); 00299 00300 /* Build and send coap message to NSP */ 00301 message_id = sn_nsdl_internal_coap_send(handle, register_message_ptr, &handle->server_address); 00302 00303 handle->sn_nsdl_free(register_message_ptr->payload_ptr); 00304 register_message_ptr->payload_ptr = NULL; 00305 00306 register_message_ptr->uri_path_ptr = NULL; 00307 register_message_ptr->options_list_ptr->uri_host_ptr = NULL; 00308 00309 register_message_ptr->token_ptr = NULL; 00310 register_message_ptr->token_len = 0; 00311 00312 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr); 00313 00314 return message_id; 00315 } 00316 00317 int32_t sn_nsdl_unregister_endpoint(struct nsdl_s *handle) 00318 { 00319 /* Local variables */ 00320 sn_coap_hdr_s *unregister_message_ptr; 00321 uint8_t *temp_ptr = 0; 00322 int32_t message_id = 0; 00323 00324 /* Check parameters */ 00325 if (handle == NULL) { 00326 return 0; 00327 } 00328 00329 /* Check that EP have been registered */ 00330 if (sn_nsdl_is_ep_registered(handle)) { 00331 00332 /* Memory allocation for unregister message */ 00333 unregister_message_ptr = sn_coap_parser_alloc_message(handle->grs->coap); 00334 if (!unregister_message_ptr) { 00335 return 0; 00336 } 00337 00338 /* Fill unregister message */ 00339 unregister_message_ptr->msg_type = COAP_MSG_TYPE_CONFIRMABLE; 00340 unregister_message_ptr->msg_code = COAP_MSG_CODE_REQUEST_DELETE; 00341 00342 if(handle->ep_information_ptr->location_ptr) { 00343 unregister_message_ptr->uri_path_len = handle->ep_information_ptr->location_len; 00344 unregister_message_ptr->uri_path_ptr = handle->sn_nsdl_alloc(unregister_message_ptr->uri_path_len); 00345 if (!unregister_message_ptr->uri_path_ptr) { 00346 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, unregister_message_ptr); 00347 return 0; 00348 } 00349 00350 temp_ptr = unregister_message_ptr->uri_path_ptr; 00351 00352 memcpy(temp_ptr , handle->ep_information_ptr->location_ptr, handle->ep_information_ptr->location_len); 00353 } else { 00354 unregister_message_ptr->uri_path_len = (RESOURCE_DIR_LEN + 1 + handle->ep_information_ptr->domain_name_len + 1 + handle->ep_information_ptr->endpoint_name_len); 00355 unregister_message_ptr->uri_path_ptr = handle->sn_nsdl_alloc(unregister_message_ptr->uri_path_len); 00356 if (!unregister_message_ptr->uri_path_ptr) { 00357 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, unregister_message_ptr); 00358 return 0; 00359 } 00360 00361 temp_ptr = unregister_message_ptr->uri_path_ptr; 00362 00363 memcpy(temp_ptr, resource_path_ptr, RESOURCE_DIR_LEN); 00364 temp_ptr += RESOURCE_DIR_LEN; 00365 00366 *temp_ptr++ = '/'; 00367 00368 memcpy(temp_ptr , handle->ep_information_ptr->domain_name_ptr, handle->ep_information_ptr->domain_name_len); 00369 temp_ptr += handle->ep_information_ptr->domain_name_len; 00370 00371 *temp_ptr++ = '/'; 00372 00373 memcpy(temp_ptr , handle->ep_information_ptr->endpoint_name_ptr, handle->ep_information_ptr->endpoint_name_len); 00374 } 00375 00376 sn_nsdl_add_token(handle, &handle->unregister_token, unregister_message_ptr); 00377 00378 /* Send message */ 00379 message_id = sn_nsdl_internal_coap_send(handle, unregister_message_ptr, &handle->server_address); 00380 00381 unregister_message_ptr->token_ptr = NULL; 00382 unregister_message_ptr->token_len = 0; 00383 00384 /* Free memory */ 00385 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, unregister_message_ptr); 00386 00387 } 00388 00389 return message_id; 00390 } 00391 00392 int32_t sn_nsdl_update_registration(struct nsdl_s *handle, uint8_t *lt_ptr, uint8_t lt_len) 00393 { 00394 /* Local variables */ 00395 sn_coap_hdr_s *register_message_ptr; 00396 uint8_t *temp_ptr; 00397 sn_nsdl_ep_parameters_s temp_parameters; 00398 int32_t message_id = 0; 00399 00400 /* Check parameters */ 00401 if (handle == NULL) { 00402 return -1; 00403 } 00404 00405 if (!sn_nsdl_is_ep_registered(handle)){ 00406 return -1; 00407 } 00408 00409 memset(&temp_parameters, 0, sizeof(sn_nsdl_ep_parameters_s)); 00410 00411 temp_parameters.lifetime_len = lt_len; 00412 temp_parameters.lifetime_ptr = lt_ptr; 00413 00414 if (handle->ep_information_ptr) { 00415 temp_parameters.type_len = handle->ep_information_ptr->type_len; 00416 temp_parameters.type_ptr = handle->ep_information_ptr->type_ptr; 00417 } 00418 00419 /*** Build endpoint register update message ***/ 00420 00421 /* Allocate memory for header struct */ 00422 register_message_ptr = sn_coap_parser_alloc_message(handle->grs->coap); 00423 if (register_message_ptr == NULL) { 00424 return -2; 00425 } 00426 00427 /* Fill message fields -> confirmable post to specified NSP path */ 00428 register_message_ptr->msg_type = COAP_MSG_TYPE_CONFIRMABLE; 00429 register_message_ptr->msg_code = COAP_MSG_CODE_REQUEST_POST; 00430 00431 if(handle->ep_information_ptr->location_ptr) { 00432 register_message_ptr->uri_path_len = handle->ep_information_ptr->location_len; /* = Only location set by Device Server*/ 00433 00434 register_message_ptr->uri_path_ptr = handle->sn_nsdl_alloc(register_message_ptr->uri_path_len); 00435 if (!register_message_ptr->uri_path_ptr) { 00436 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr); 00437 return -2; 00438 } 00439 00440 temp_ptr = register_message_ptr->uri_path_ptr; 00441 00442 /* location */ 00443 memcpy(temp_ptr, handle->ep_information_ptr->location_ptr, handle->ep_information_ptr->location_len); 00444 } else { 00445 register_message_ptr->uri_path_len = sizeof(resource_path_ptr) + handle->ep_information_ptr->domain_name_len + handle->ep_information_ptr->endpoint_name_len + 2; /* = rd/domain/endpoint */ 00446 00447 register_message_ptr->uri_path_ptr = handle->sn_nsdl_alloc(register_message_ptr->uri_path_len); 00448 if (!register_message_ptr->uri_path_ptr) { 00449 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr); 00450 return -2; 00451 } 00452 00453 temp_ptr = register_message_ptr->uri_path_ptr; 00454 00455 /* rd/ */ 00456 memcpy(temp_ptr, resource_path_ptr, sizeof(resource_path_ptr)); 00457 temp_ptr += sizeof(resource_path_ptr); 00458 *temp_ptr++ = '/'; 00459 00460 /* rd/DOMAIN/ */ 00461 memcpy(temp_ptr, handle->ep_information_ptr->domain_name_ptr, handle->ep_information_ptr->domain_name_len); 00462 temp_ptr += handle->ep_information_ptr->domain_name_len; 00463 *temp_ptr++ = '/'; 00464 00465 /* rd/domain/ENDPOINT */ 00466 memcpy(temp_ptr, handle->ep_information_ptr->endpoint_name_ptr, handle->ep_information_ptr->endpoint_name_len); 00467 } 00468 00469 /* Allocate memory for the extended options list */ 00470 if (sn_coap_parser_alloc_options(handle->grs->coap, register_message_ptr) == NULL) { 00471 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr); 00472 return -2; 00473 } 00474 00475 /* Fill Uri-query options */ 00476 sn_nsdl_fill_uri_query_options(handle, &temp_parameters, register_message_ptr, SN_NSDL_EP_UPDATE_MESSAGE, NULL); 00477 00478 /* Build payload */ 00479 if (handle->ep_information_ptr->ds_register_mode == REGISTER_WITH_RESOURCES) { 00480 if (sn_nsdl_build_registration_body(handle, register_message_ptr, 1) == SN_NSDL_FAILURE) { 00481 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr); 00482 return -2; 00483 } 00484 } 00485 00486 // Remove previous update reg message from the queue if exists 00487 00488 sn_nsdl_remove_msg_from_retransmission(handle, 00489 (uint8_t*)&handle->update_register_token, 00490 sizeof(handle->update_register_token)); 00491 00492 sn_nsdl_add_token(handle, &handle->update_register_token, register_message_ptr); 00493 00494 /* Build and send coap message to NSP */ 00495 message_id = sn_nsdl_internal_coap_send(handle, register_message_ptr, &handle->server_address); 00496 00497 register_message_ptr->token_ptr = NULL; 00498 register_message_ptr->token_len = 0; 00499 00500 handle->sn_nsdl_free(register_message_ptr->payload_ptr); 00501 00502 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr); 00503 00504 if (message_id == 0) { 00505 // Failure when sending 00506 return -2; 00507 } 00508 00509 return message_id; 00510 } 00511 00512 int8_t sn_nsdl_set_endpoint_location(struct nsdl_s *handle, uint8_t *location_ptr, uint8_t location_len) 00513 { 00514 if(!handle || !location_ptr || (location_len == 0)) { 00515 return -1; 00516 } 00517 00518 handle->sn_nsdl_free(handle->ep_information_ptr->location_ptr); 00519 handle->ep_information_ptr->location_ptr = handle->sn_nsdl_alloc(location_len); 00520 memcpy(handle->ep_information_ptr->location_ptr, location_ptr, location_len); 00521 handle->ep_information_ptr->location_len = location_len; 00522 00523 return 0; 00524 } 00525 00526 void sn_nsdl_nsp_lost(struct nsdl_s *handle) 00527 { 00528 /* Check parameters */ 00529 if (handle == NULL) { 00530 return; 00531 } 00532 00533 handle->sn_nsdl_endpoint_registered = SN_NSDL_ENDPOINT_NOT_REGISTERED; 00534 } 00535 00536 int8_t sn_nsdl_is_ep_registered(struct nsdl_s *handle) 00537 { 00538 /* Check parameters */ 00539 if (handle == NULL) { 00540 return SN_NSDL_FAILURE; 00541 } 00542 00543 return handle->sn_nsdl_endpoint_registered; 00544 } 00545 00546 int32_t sn_nsdl_send_observation_notification(struct nsdl_s *handle, uint8_t *token_ptr, uint8_t token_len, 00547 uint8_t *payload_ptr, uint16_t payload_len, sn_coap_observe_e observe, sn_coap_msg_type_e message_type, 00548 sn_coap_content_format_e content_format, 00549 const int32_t message_id) 00550 { 00551 sn_coap_hdr_s *notification_message_ptr; 00552 int32_t return_msg_id = 0; 00553 00554 /* Check parameters */ 00555 if (handle == NULL || handle->grs == NULL || token_len == 0) { 00556 return 0; 00557 } 00558 00559 /* Allocate and initialize memory for header struct */ 00560 notification_message_ptr = sn_coap_parser_alloc_message(handle->grs->coap); 00561 if (notification_message_ptr == NULL) { 00562 return 0; 00563 } 00564 00565 if (sn_coap_parser_alloc_options(handle->grs->coap, notification_message_ptr) == NULL) { 00566 handle->sn_nsdl_free(notification_message_ptr); 00567 return 0; 00568 } 00569 00570 /* Fill header */ 00571 notification_message_ptr->msg_type = message_type; 00572 notification_message_ptr->msg_code = COAP_MSG_CODE_RESPONSE_CONTENT; 00573 00574 /* Fill token */ 00575 notification_message_ptr->token_len = token_len; 00576 notification_message_ptr->token_ptr = token_ptr; 00577 00578 /* Fill payload */ 00579 notification_message_ptr->payload_len = payload_len; 00580 notification_message_ptr->payload_ptr = payload_ptr; 00581 00582 /* Fill observe */ 00583 notification_message_ptr->options_list_ptr->observe = observe; 00584 00585 /* Fill content format */ 00586 notification_message_ptr->content_format = content_format; 00587 00588 if (message_id != -1) { 00589 notification_message_ptr->msg_id = message_id; 00590 } 00591 00592 /* Send message */ 00593 return_msg_id = sn_nsdl_send_coap_message(handle, &handle->server_address, notification_message_ptr); 00594 if (return_msg_id >= SN_NSDL_SUCCESS) { 00595 return_msg_id = notification_message_ptr->msg_id; 00596 } 00597 00598 /* Free memory */ 00599 notification_message_ptr->payload_ptr = NULL; 00600 notification_message_ptr->token_ptr = NULL; 00601 00602 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, notification_message_ptr); 00603 00604 return return_msg_id; 00605 } 00606 00607 /* * * * * * * * * * */ 00608 /* ~ OMA functions ~ */ 00609 /* * * * * * * * * * */ 00610 00611 uint16_t sn_nsdl_oma_bootstrap(struct nsdl_s *handle, 00612 sn_nsdl_addr_s *bootstrap_address_ptr, 00613 sn_nsdl_ep_parameters_s *endpoint_info_ptr, 00614 const char *uri_query_parameters) 00615 { 00616 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00617 /* Local variables */ 00618 sn_coap_hdr_s bootstrap_coap_header; 00619 uint8_t *uri_query_tmp_ptr; 00620 uint16_t message_id = 0; 00621 00622 /* Check parameters */ 00623 if (!bootstrap_address_ptr || !endpoint_info_ptr || !handle) { 00624 return 0; 00625 } 00626 00627 if (set_NSP_address(handle, 00628 bootstrap_address_ptr->addr_ptr, 00629 bootstrap_address_ptr->addr_len, 00630 bootstrap_address_ptr->port, 00631 bootstrap_address_ptr->type) == SN_NSDL_FAILURE) { 00632 return 0; 00633 } 00634 00635 handle->is_bs_server = true; 00636 00637 /* XXX FIX -- Init CoAP header struct */ 00638 sn_coap_parser_init_message(&bootstrap_coap_header); 00639 00640 if (!sn_coap_parser_alloc_options(handle->grs->coap, &bootstrap_coap_header)) { 00641 return 0; 00642 } 00643 00644 /* Build bootstrap start message */ 00645 bootstrap_coap_header.msg_code = COAP_MSG_CODE_REQUEST_POST; 00646 bootstrap_coap_header.msg_type = COAP_MSG_TYPE_CONFIRMABLE; 00647 00648 bootstrap_coap_header.uri_path_ptr = bs_uri; 00649 bootstrap_coap_header.uri_path_len = sizeof(bs_uri); 00650 00651 size_t query_len = endpoint_info_ptr->endpoint_name_len + BS_EP_PARAMETER_LEN; 00652 size_t optional_params_len = 0; 00653 if (uri_query_parameters) { 00654 optional_params_len = strlen(uri_query_parameters); 00655 } 00656 00657 query_len += optional_params_len; 00658 00659 if (query_len > MAX_URI_QUERY_LEN) { 00660 handle->sn_nsdl_free(bootstrap_coap_header.options_list_ptr); 00661 tr_error("sn_nsdl_oma_bootstrap - max param length reached (%lu)", (unsigned long)query_len); 00662 return 0; 00663 } 00664 00665 uri_query_tmp_ptr = handle->sn_nsdl_alloc(query_len); 00666 if (!uri_query_tmp_ptr) { 00667 handle->sn_nsdl_free(bootstrap_coap_header.options_list_ptr); 00668 return 0; 00669 } 00670 00671 memcpy(uri_query_tmp_ptr, bs_ep_name, BS_EP_PARAMETER_LEN); 00672 memcpy((uri_query_tmp_ptr + BS_EP_PARAMETER_LEN), 00673 endpoint_info_ptr->endpoint_name_ptr, 00674 endpoint_info_ptr->endpoint_name_len); 00675 00676 if (optional_params_len > 0) { 00677 memcpy(uri_query_tmp_ptr + endpoint_info_ptr->endpoint_name_len + BS_EP_PARAMETER_LEN, 00678 uri_query_parameters, 00679 optional_params_len); 00680 } 00681 00682 bootstrap_coap_header.options_list_ptr->uri_query_len = query_len; 00683 bootstrap_coap_header.options_list_ptr->uri_query_ptr = uri_query_tmp_ptr; 00684 00685 /* Save bootstrap server address */ 00686 sn_nsdl_add_token(handle, &handle->bootstrap_token, &bootstrap_coap_header); 00687 00688 /* Send message */ 00689 message_id = sn_nsdl_internal_coap_send(handle, &bootstrap_coap_header, bootstrap_address_ptr); 00690 00691 /* Free allocated memory */ 00692 handle->sn_nsdl_free(uri_query_tmp_ptr); 00693 handle->sn_nsdl_free(bootstrap_coap_header.options_list_ptr); 00694 00695 return message_id; 00696 #else 00697 return 0; 00698 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00699 00700 } 00701 00702 char *sn_nsdl_get_version(void) 00703 { 00704 #if defined(YOTTA_MBED_CLIENT_C_VERSION_STRING) 00705 return YOTTA_MBED_CLIENT_C_VERSION_STRING; 00706 #elif defined(VERSION) 00707 return VERSION; 00708 #else 00709 return "0.0.0"; 00710 #endif 00711 } 00712 00713 int8_t sn_nsdl_process_coap(struct nsdl_s *handle, uint8_t *packet_ptr, uint16_t packet_len, sn_nsdl_addr_s *src_ptr) 00714 { 00715 sn_coap_hdr_s *coap_packet_ptr = NULL; 00716 sn_coap_hdr_s *coap_response_ptr = NULL; 00717 sn_nsdl_dynamic_resource_parameters_s *resource = NULL; 00718 /* Check parameters */ 00719 if (handle == NULL) { 00720 return SN_NSDL_FAILURE; 00721 } 00722 00723 /* Parse CoAP packet */ 00724 coap_packet_ptr = sn_coap_protocol_parse(handle->grs->coap, src_ptr, packet_len, packet_ptr, (void *)handle); 00725 00726 /* Check if parsing was successfull */ 00727 if (coap_packet_ptr == (sn_coap_hdr_s *)NULL) { 00728 return SN_NSDL_FAILURE; 00729 } 00730 sn_nsdl_print_coap_data(coap_packet_ptr, false); 00731 00732 #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE 00733 // Pass block to application if external_memory_block is set 00734 if((coap_packet_ptr->options_list_ptr && 00735 coap_packet_ptr->options_list_ptr->block1 != -1) && 00736 (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVING || 00737 coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED)) { 00738 // Block 1 handling 00739 /* Get resource */ 00740 char* path = handle->sn_nsdl_alloc(coap_packet_ptr->uri_path_len + 1); 00741 if (!path) { 00742 return SN_NSDL_FAILURE; 00743 } 00744 00745 memcpy(path, 00746 coap_packet_ptr->uri_path_ptr, 00747 coap_packet_ptr->uri_path_len); 00748 path[coap_packet_ptr->uri_path_len] = '\0'; 00749 00750 00751 resource = sn_nsdl_get_resource(handle, path); 00752 handle->sn_nsdl_free(path); 00753 00754 if (coap_packet_ptr->options_list_ptr) { 00755 if(resource && 00756 resource->static_resource_parameters->external_memory_block && 00757 coap_packet_ptr->options_list_ptr->block1) { 00758 00759 uint32_t block_number = coap_packet_ptr->options_list_ptr->block1 >> 4; 00760 if (block_number) { 00761 remove_previous_block_data(handle, src_ptr, block_number); 00762 } 00763 00764 // Whole message received --> pass only the last block data to application 00765 if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED) { 00766 // Get the block size 00767 uint8_t temp = (coap_packet_ptr->options_list_ptr->block1 & 0x07); 00768 uint16_t block_size = 1u << (temp + 4); 00769 00770 uint32_t new_payload_len = coap_packet_ptr->payload_len - block_size; 00771 uint8_t *temp_ptr = handle->grs->coap->sn_coap_protocol_malloc(new_payload_len); 00772 if (temp_ptr) { 00773 // Skip the second last block data since it's still stored in mbed-coap list! 00774 memcpy(temp_ptr, coap_packet_ptr->payload_ptr + block_size, new_payload_len); 00775 handle->grs->coap->sn_coap_protocol_free(coap_packet_ptr->payload_ptr); 00776 coap_packet_ptr->payload_ptr = NULL; 00777 00778 coap_packet_ptr->payload_ptr = handle->grs->coap->sn_coap_protocol_malloc(new_payload_len); 00779 if (coap_packet_ptr->payload_ptr) { 00780 memcpy(coap_packet_ptr->payload_ptr, temp_ptr, new_payload_len); 00781 coap_packet_ptr->payload_len = new_payload_len; 00782 } 00783 00784 handle->grs->coap->sn_coap_protocol_free(temp_ptr); 00785 } 00786 } 00787 } else { 00788 resource = NULL; 00789 } 00790 } else { 00791 resource = NULL; 00792 } 00793 } 00794 #endif 00795 00796 // Handling of GET responses 00797 if (coap_packet_ptr->msg_code == COAP_MSG_CODE_RESPONSE_CONTENT) { 00798 bool data_updated = false; 00799 if (coap_packet_ptr->options_list_ptr && coap_packet_ptr->options_list_ptr->block2 != -1) { 00800 uint32_t block_number = coap_packet_ptr->options_list_ptr->block2 >> 4; 00801 if (block_number) { 00802 remove_previous_block_data(handle, src_ptr, block_number); 00803 } 00804 00805 // Modify payload to have only last received block data 00806 data_updated = update_last_block_data(handle, coap_packet_ptr, false); 00807 } 00808 00809 handle->sn_nsdl_rx_callback(handle, coap_packet_ptr, src_ptr); 00810 if (data_updated) { 00811 handle->grs->coap->sn_coap_protocol_free(coap_packet_ptr->payload_ptr); 00812 } 00813 00814 #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE 00815 // Remove sent blockwise message(GET request) from the linked list. 00816 sn_coap_protocol_remove_sent_blockwise_message(handle->grs->coap, coap_packet_ptr->msg_id); 00817 #endif 00818 00819 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr); 00820 return SN_NSDL_SUCCESS; 00821 } 00822 00823 /* Check, if coap itself sends response, or block receiving is ongoing... */ 00824 if (coap_packet_ptr->coap_status != COAP_STATUS_OK && 00825 coap_packet_ptr->coap_status != COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && 00826 coap_packet_ptr && 00827 !resource) { 00828 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr); 00829 return SN_NSDL_SUCCESS; 00830 } 00831 00832 /* If proxy options added, return not supported */ 00833 if (coap_packet_ptr->options_list_ptr) { 00834 if (coap_packet_ptr->options_list_ptr->proxy_uri_len) { 00835 coap_response_ptr = sn_coap_build_response(handle->grs->coap, coap_packet_ptr, COAP_MSG_CODE_RESPONSE_PROXYING_NOT_SUPPORTED); 00836 if (coap_response_ptr) { 00837 sn_nsdl_send_coap_message(handle, src_ptr, coap_response_ptr); 00838 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_response_ptr); 00839 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr); 00840 return SN_NSDL_SUCCESS; 00841 } else { 00842 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr); 00843 return SN_NSDL_FAILURE; 00844 } 00845 } 00846 } 00847 00848 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 00849 /* If message is response message, call RX callback */ 00850 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 00851 00852 if (((coap_packet_ptr->msg_code > COAP_MSG_CODE_REQUEST_DELETE) || 00853 (coap_packet_ptr->msg_type >= COAP_MSG_TYPE_ACKNOWLEDGEMENT))) { 00854 int8_t retval = sn_nsdl_local_rx_function(handle, coap_packet_ptr, src_ptr); 00855 if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && 00856 coap_packet_ptr->payload_ptr) { 00857 handle->sn_nsdl_free(coap_packet_ptr->payload_ptr); 00858 coap_packet_ptr->payload_ptr = 0; 00859 } 00860 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr); 00861 return retval; 00862 } 00863 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00864 /* * If OMA bootstrap message... * */ 00865 bool bootstrap_msg = handle->is_bs_server; 00866 00867 // Pass bootstrap data to application 00868 if (bootstrap_msg) { 00869 // If retval is 2 skip the freeing, it will be done in MBED_CLIENT_NSDLINTERFACE_BS_PUT_EVENT event 00870 if (handle->sn_nsdl_rx_callback(handle, coap_packet_ptr,src_ptr) != 2) { 00871 if (coap_packet_ptr && 00872 coap_packet_ptr->options_list_ptr && 00873 coap_packet_ptr->coap_status != COAP_STATUS_BUILDER_MESSAGE_SENDING_FAILED && 00874 coap_packet_ptr->options_list_ptr->block1 != -1) { 00875 handle->sn_nsdl_free(coap_packet_ptr->payload_ptr); 00876 coap_packet_ptr->payload_ptr = NULL; 00877 } 00878 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr); 00879 } 00880 00881 return SN_NSDL_SUCCESS; 00882 } 00883 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00884 00885 /* * * * * * * * * * * * * * * */ 00886 /* Other messages are for GRS */ 00887 /* * * * * * * * * * * * * * * */ 00888 return sn_grs_process_coap(handle, coap_packet_ptr, src_ptr); 00889 } 00890 00891 int8_t sn_nsdl_exec(struct nsdl_s *handle, uint32_t time) 00892 { 00893 if(!handle || !handle->grs){ 00894 return SN_NSDL_FAILURE; 00895 } 00896 /* Call CoAP execution function */ 00897 return sn_coap_protocol_exec(handle->grs->coap, time); 00898 } 00899 00900 sn_nsdl_dynamic_resource_parameters_s *sn_nsdl_get_resource(struct nsdl_s *handle, const char *path_ptr) 00901 { 00902 /* Check parameters */ 00903 if (handle == NULL) { 00904 return NULL; 00905 } 00906 00907 return sn_grs_search_resource(handle->grs, path_ptr, SN_GRS_SEARCH_METHOD); 00908 } 00909 00910 00911 /** 00912 * \fn static int32_t sn_nsdl_internal_coap_send(struct nsdl_s *handle, sn_coap_hdr_s *coap_header_ptr, sn_nsdl_addr_s *dst_addr_ptr) 00913 * 00914 * 00915 * \brief To send NSDL messages. Stores message id?s and message description to catch response from NSP server 00916 * \param *handle Pointer to nsdl-library handle 00917 * \param *coap_header_ptr Pointer to the CoAP message header to be sent 00918 * \param *dst_addr_ptr Pointer to the address structure that contains destination address information 00919 * \param message_description Message description to be stored to list for waiting response 00920 * 00921 * \return message id, <=0 if failed 00922 */ 00923 static int32_t sn_nsdl_internal_coap_send(struct nsdl_s *handle, sn_coap_hdr_s *coap_header_ptr, sn_nsdl_addr_s *dst_addr_ptr) 00924 { 00925 00926 tr_debug("sn_nsdl_internal_coap_send"); 00927 uint8_t *coap_message_ptr = NULL; 00928 int32_t coap_message_len = 0; 00929 00930 #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwising is not used at all, this part of code will not be compiled */ 00931 int8_t ret_val = prepare_blockwise_message(handle->grs->coap, coap_header_ptr); 00932 if( 0 != ret_val ) { 00933 return 0; 00934 } 00935 #endif 00936 00937 coap_message_len = sn_coap_builder_calc_needed_packet_data_size_2(coap_header_ptr, handle->grs->coap->sn_coap_block_data_size); 00938 tr_debug("sn_nsdl_internal_coap_send - msg len after calc: %" PRId32 "", coap_message_len); 00939 if (coap_message_len == 0) { 00940 return 0; 00941 } 00942 00943 coap_message_ptr = handle->sn_nsdl_alloc(coap_message_len); 00944 if (!coap_message_ptr) { 00945 return 0; 00946 } 00947 00948 /* Build message */ 00949 int16_t ret = sn_coap_protocol_build(handle->grs->coap, dst_addr_ptr, coap_message_ptr, coap_header_ptr, (void *)handle); 00950 if (ret < 0) { 00951 handle->sn_nsdl_free(coap_message_ptr); 00952 return ret; 00953 } 00954 00955 handle->sn_nsdl_tx_callback(handle, SN_NSDL_PROTOCOL_COAP, coap_message_ptr, coap_message_len, dst_addr_ptr); 00956 handle->sn_nsdl_free(coap_message_ptr); 00957 00958 return coap_header_ptr->msg_id; 00959 } 00960 00961 /** 00962 * \fn static void sn_nsdl_resolve_nsp_address(struct nsdl_s *handle) 00963 * 00964 * \brief Resolves NSP server address. 00965 * 00966 * \param *handle Pointer to nsdl-library handle 00967 * \note Application must set NSP address with set_nsp_address 00968 */ 00969 static void sn_nsdl_resolve_nsp_address(struct nsdl_s *handle) 00970 { 00971 memset(&handle->server_address, 0, sizeof(sn_nsdl_addr_s)); 00972 handle->server_address.type = SN_NSDL_ADDRESS_TYPE_NONE; 00973 } 00974 00975 #ifdef RESOURCE_ATTRIBUTES_LIST 00976 static char *sn_nsdl_build_resource_attribute_str(char *dst, const sn_nsdl_attribute_item_s *attribute, const char *name, const size_t name_len) 00977 { 00978 if (attribute != NULL && name != NULL && name_len > 0 && attribute->value) { 00979 size_t attribute_len = strlen(attribute->value); 00980 *dst++ = ';'; 00981 memcpy(dst, name, name_len); 00982 dst += name_len; 00983 *dst++ = '"'; 00984 memcpy(dst, 00985 attribute->value, 00986 attribute_len); 00987 dst += attribute_len; 00988 *dst++ = '"'; 00989 } 00990 return dst; 00991 } 00992 #endif 00993 00994 /** 00995 * \fn int8_t sn_nsdl_build_registration_body(struct nsdl_s *handle, sn_coap_hdr_s *message_ptr, uint8_t updating_registeration) 00996 * 00997 * \brief To build GRS resources to registration message payload 00998 * \param *handle Pointer to nsdl-library handle 00999 * \param *message_ptr Pointer to CoAP message header 01000 * 01001 * \return SN_NSDL_SUCCESS = 0, Failed = -1 01002 */ 01003 int8_t sn_nsdl_build_registration_body(struct nsdl_s *handle, sn_coap_hdr_s *message_ptr, uint8_t updating_registeration) 01004 { 01005 tr_debug("sn_nsdl_build_registration_body"); 01006 /* Local variables */ 01007 uint8_t *temp_ptr; 01008 sn_nsdl_dynamic_resource_parameters_s *resource_temp_ptr; 01009 01010 /* Calculate needed memory and allocate */ 01011 int8_t error = 0; 01012 uint16_t msg_len = sn_nsdl_calculate_registration_body_size(handle, updating_registeration, &error); 01013 if (SN_NSDL_FAILURE == error) { 01014 return error; 01015 } 01016 01017 if (!msg_len) { 01018 return SN_NSDL_SUCCESS; 01019 } else { 01020 message_ptr->payload_len = msg_len; 01021 } 01022 tr_debug("sn_nsdl_build_registration_body - body size: [%d]", message_ptr->payload_len); 01023 message_ptr->payload_ptr = handle->sn_nsdl_alloc(message_ptr->payload_len); 01024 if (!message_ptr->payload_ptr) { 01025 return SN_NSDL_FAILURE; 01026 } 01027 01028 /* Build message */ 01029 temp_ptr = message_ptr->payload_ptr; 01030 01031 resource_temp_ptr = sn_grs_get_first_resource(handle->grs); 01032 01033 /* Loop trough all resources */ 01034 while (resource_temp_ptr) { 01035 /* if resource needs to be registered */ 01036 if (resource_temp_ptr->publish_uri) { 01037 if (!resource_temp_ptr->always_publish && updating_registeration && resource_temp_ptr->registered == SN_NDSL_RESOURCE_REGISTERED) { 01038 resource_temp_ptr = sn_grs_get_next_resource(handle->grs, resource_temp_ptr); 01039 continue; 01040 } else if (resource_temp_ptr->registered != SN_NDSL_RESOURCE_DELETE) { 01041 resource_temp_ptr->registered = SN_NDSL_RESOURCE_REGISTERED; 01042 } 01043 01044 /* If not first resource, add '.' to separator */ 01045 if (temp_ptr != message_ptr->payload_ptr) { 01046 *temp_ptr++ = ','; 01047 } 01048 01049 *temp_ptr++ = '<'; 01050 *temp_ptr++ = '/'; 01051 size_t path_len = 0; 01052 if (resource_temp_ptr->static_resource_parameters->path) { 01053 path_len = strlen(resource_temp_ptr->static_resource_parameters->path); 01054 } 01055 memcpy(temp_ptr, 01056 resource_temp_ptr->static_resource_parameters->path, 01057 path_len); 01058 temp_ptr += path_len; 01059 *temp_ptr++ = '>'; 01060 01061 /* Resource attributes */ 01062 if (resource_temp_ptr->registered == SN_NDSL_RESOURCE_DELETE) { 01063 *temp_ptr++ = ';'; 01064 *temp_ptr++ = 'd'; 01065 } 01066 #ifndef RESOURCE_ATTRIBUTES_LIST 01067 #ifndef DISABLE_RESOURCE_TYPE 01068 size_t resource_type_len = 0; 01069 if (resource_temp_ptr->static_resource_parameters->resource_type_ptr) { 01070 resource_type_len = strlen(resource_temp_ptr->static_resource_parameters->resource_type_ptr); 01071 } 01072 if (resource_type_len) { 01073 *temp_ptr++ = ';'; 01074 memcpy(temp_ptr, resource_type_parameter, RT_PARAMETER_LEN); 01075 temp_ptr += RT_PARAMETER_LEN; 01076 *temp_ptr++ = '"'; 01077 memcpy(temp_ptr, 01078 resource_temp_ptr->static_resource_parameters->resource_type_ptr, 01079 resource_type_len); 01080 temp_ptr += resource_type_len; 01081 *temp_ptr++ = '"'; 01082 } 01083 #endif 01084 #ifndef DISABLE_INTERFACE_DESCRIPTION 01085 size_t interface_description_len = 0; 01086 if (resource_temp_ptr->static_resource_parameters->interface_description_ptr) { 01087 interface_description_len = strlen(resource_temp_ptr->static_resource_parameters->interface_description_ptr); 01088 } 01089 01090 if (interface_description_len) { 01091 *temp_ptr++ = ';'; 01092 memcpy(temp_ptr, if_description_parameter, IF_PARAMETER_LEN); 01093 temp_ptr += IF_PARAMETER_LEN; 01094 *temp_ptr++ = '"'; 01095 memcpy(temp_ptr, 01096 resource_temp_ptr->static_resource_parameters->interface_description_ptr, 01097 interface_description_len); 01098 temp_ptr += interface_description_len; 01099 *temp_ptr++ = '"'; 01100 } 01101 #endif 01102 #else 01103 size_t attribute_len = 0; 01104 if (resource_temp_ptr->static_resource_parameters->attributes_ptr) { 01105 sn_nsdl_attribute_item_s *attribute = resource_temp_ptr->static_resource_parameters->attributes_ptr; 01106 while (attribute->attribute_name != ATTR_END) { 01107 switch (attribute->attribute_name) { 01108 case ATTR_RESOURCE_TYPE: 01109 temp_ptr = sn_nsdl_build_resource_attribute_str(temp_ptr, attribute, resource_type_parameter, RT_PARAMETER_LEN); 01110 break; 01111 case ATTR_INTERFACE_DESCRIPTION: 01112 temp_ptr = sn_nsdl_build_resource_attribute_str(temp_ptr, attribute, if_description_parameter, IF_PARAMETER_LEN); 01113 break; 01114 case ATTR_ENDPOINT_NAME: 01115 temp_ptr = sn_nsdl_build_resource_attribute_str(temp_ptr, attribute, name_parameter, NAME_PARAMETER_LEN); 01116 break; 01117 default: 01118 break; 01119 } 01120 attribute++; 01121 } 01122 } 01123 #endif 01124 if (resource_temp_ptr->coap_content_type != 0) { 01125 *temp_ptr++ = ';'; 01126 memcpy(temp_ptr, coap_con_type_parameter, COAP_CON_PARAMETER_LEN); 01127 temp_ptr += COAP_CON_PARAMETER_LEN; 01128 *temp_ptr++ = '"'; 01129 temp_ptr = sn_nsdl_itoa(temp_ptr, 01130 resource_temp_ptr->coap_content_type); 01131 *temp_ptr++ = '"'; 01132 } 01133 01134 /* ;v */ 01135 if ((resource_temp_ptr->publish_value > 0) && resource_temp_ptr->resource) { 01136 // If the resource is Opaque then do Base64 encoding of data 01137 if (resource_temp_ptr->publish_value == 2) { 01138 size_t dst_size = (((resource_temp_ptr->resource_len + 2) / 3) << 2) + 1; 01139 unsigned char *dst = (unsigned char*)handle->sn_nsdl_alloc(dst_size); 01140 size_t olen = 0; 01141 if (dst) { 01142 if (mbedtls_base64_encode(dst, dst_size, &olen, 01143 resource_temp_ptr->resource, resource_temp_ptr->resource_len) == 0) { 01144 *temp_ptr++ = ';'; 01145 memcpy(temp_ptr, resource_value, RESOURCE_VALUE_PARAMETER_LEN); 01146 temp_ptr += RESOURCE_VALUE_PARAMETER_LEN; 01147 *temp_ptr++ = '"'; 01148 memcpy(temp_ptr, dst, olen); 01149 temp_ptr += olen; 01150 *temp_ptr++ = '"'; 01151 01152 } 01153 handle->sn_nsdl_free(dst); 01154 } 01155 01156 } else { // For resources which does not require Base64 encoding of data 01157 *temp_ptr++ = ';'; 01158 memcpy(temp_ptr, resource_value, RESOURCE_VALUE_PARAMETER_LEN); 01159 temp_ptr += RESOURCE_VALUE_PARAMETER_LEN; 01160 *temp_ptr++ = '"'; 01161 memcpy(temp_ptr, resource_temp_ptr->resource, resource_temp_ptr->resource_len); 01162 temp_ptr += resource_temp_ptr->resource_len; 01163 *temp_ptr++ = '"'; 01164 } 01165 } 01166 01167 /* ;aobs / ;obs */ 01168 // This needs to be re-visited and may be need an API for maganging obs value for different server implementation 01169 #ifndef COAP_DISABLE_OBS_FEATURE 01170 if (resource_temp_ptr->auto_observable) { 01171 uint8_t token[MAX_TOKEN_SIZE] = {0}; 01172 uint8_t len = handle->sn_nsdl_auto_obs_token_callback(handle, 01173 resource_temp_ptr->static_resource_parameters->path, 01174 (uint8_t*)token); 01175 if (len > 0) { 01176 *temp_ptr++ = ';'; 01177 memcpy(temp_ptr, aobs_parameter, AOBS_PARAMETER_LEN); 01178 temp_ptr += AOBS_PARAMETER_LEN; 01179 *temp_ptr++ = '"'; 01180 uint16_t temp = common_read_16_bit((uint8_t*)token); 01181 temp_ptr = sn_nsdl_itoa(temp_ptr, temp); 01182 *temp_ptr++ = '"'; 01183 } 01184 } 01185 else if (resource_temp_ptr->observable) { 01186 *temp_ptr++ = ';'; 01187 memcpy(temp_ptr, obs_parameter, OBS_PARAMETER_LEN); 01188 temp_ptr += OBS_PARAMETER_LEN; 01189 } 01190 #endif 01191 } 01192 resource_temp_ptr = sn_grs_get_next_resource(handle->grs, resource_temp_ptr); 01193 01194 } 01195 return SN_NSDL_SUCCESS; 01196 } 01197 01198 /** 01199 * \fn static uint16_t sn_nsdl_calculate_registration_body_size(struct nsdl_s *handle, uint8_t updating_registeration, int8_t *error) 01200 * 01201 * 01202 * \brief Calculates registration message payload size 01203 * \param *handle Pointer to nsdl-library handle 01204 * \param *updating_registeration Pointer to list of GRS resources 01205 * \param *error Error code, SN_NSDL_SUCCESS or SN_NSDL_FAILURE 01206 * 01207 * \return Needed payload size 01208 */ 01209 static uint16_t sn_nsdl_calculate_registration_body_size(struct nsdl_s *handle, uint8_t updating_registeration, int8_t *error) 01210 { 01211 tr_debug("sn_nsdl_calculate_registration_body_size"); 01212 /* Local variables */ 01213 uint16_t return_value = 0; 01214 *error = SN_NSDL_SUCCESS; 01215 const sn_nsdl_dynamic_resource_parameters_s *resource_temp_ptr; 01216 01217 /* check pointer */ 01218 resource_temp_ptr = sn_grs_get_first_resource(handle->grs); 01219 01220 while (resource_temp_ptr) { 01221 if (resource_temp_ptr->publish_uri) { 01222 if (!resource_temp_ptr->always_publish && updating_registeration && resource_temp_ptr->registered == SN_NDSL_RESOURCE_REGISTERED) { 01223 resource_temp_ptr = sn_grs_get_next_resource(handle->grs, resource_temp_ptr); 01224 continue; 01225 } 01226 /* If not first resource, then '.' will be added */ 01227 if (return_value) { 01228 if (sn_nsdl_check_uint_overflow(return_value, 1, 0)) { 01229 return_value++; 01230 } else { 01231 *error = SN_NSDL_FAILURE; 01232 break; 01233 } 01234 } 01235 01236 /* Count length for the resource path </path> */ 01237 size_t path_len = 0; 01238 if (resource_temp_ptr->static_resource_parameters->path) { 01239 path_len = strlen(resource_temp_ptr->static_resource_parameters->path); 01240 } 01241 01242 if (sn_nsdl_check_uint_overflow(return_value, 3, path_len)) { 01243 return_value += (3 + path_len); 01244 } else { 01245 *error = SN_NSDL_FAILURE; 01246 break; 01247 } 01248 01249 /* Count lengths of the attributes */ 01250 if (resource_temp_ptr->registered == SN_NDSL_RESOURCE_DELETE) { 01251 return_value += 2; 01252 } 01253 #ifndef RESOURCE_ATTRIBUTES_LIST 01254 #ifndef DISABLE_RESOURCE_TYPE 01255 /* Resource type parameter */ 01256 size_t resource_type_len = 0; 01257 if (resource_temp_ptr->static_resource_parameters->resource_type_ptr) { 01258 resource_type_len = strlen(resource_temp_ptr->static_resource_parameters->resource_type_ptr); 01259 } 01260 01261 if (resource_type_len) { 01262 /* ;rt="restype" */ 01263 if (sn_nsdl_check_uint_overflow(return_value, 01264 6, 01265 resource_type_len)) { 01266 return_value += (6 + resource_type_len); 01267 } else { 01268 *error = SN_NSDL_FAILURE; 01269 break; 01270 } 01271 } 01272 #endif 01273 01274 #ifndef DISABLE_INTERFACE_DESCRIPTION 01275 /* Interface description parameter */ 01276 size_t interface_description_len = 0; 01277 if (resource_temp_ptr->static_resource_parameters->interface_description_ptr) { 01278 interface_description_len = strlen(resource_temp_ptr->static_resource_parameters->interface_description_ptr); 01279 } 01280 if (interface_description_len) { 01281 /* ;if="iftype" */ 01282 if (sn_nsdl_check_uint_overflow(return_value, 01283 6, 01284 interface_description_len)) { 01285 return_value += (6 + interface_description_len); 01286 } else { 01287 *error = SN_NSDL_FAILURE; 01288 break; 01289 } 01290 } 01291 #endif 01292 #else 01293 /* All attributes */ 01294 if (resource_temp_ptr->static_resource_parameters->attributes_ptr) { 01295 size_t attribute_len = 0; 01296 size_t attribute_desc_len = 0; 01297 uint8_t success = 1; 01298 sn_nsdl_attribute_item_s *item = resource_temp_ptr->static_resource_parameters->attributes_ptr; 01299 while (item->attribute_name != ATTR_END) { 01300 switch(item->attribute_name) { 01301 case ATTR_RESOURCE_TYPE: 01302 /* ;rt="restype" */ 01303 attribute_desc_len = 6; 01304 attribute_len = strlen(item->value); 01305 break; 01306 case ATTR_INTERFACE_DESCRIPTION: 01307 /* ;if="iftype" */ 01308 attribute_desc_len = 6; 01309 attribute_len = strlen(item->value); 01310 break; 01311 case ATTR_ENDPOINT_NAME: 01312 /* ;name="name" */ 01313 attribute_desc_len = 8; 01314 attribute_len = strlen(item->value); 01315 break; 01316 default: 01317 break; 01318 } 01319 if (sn_nsdl_check_uint_overflow(return_value, 01320 attribute_desc_len, 01321 attribute_len)) { 01322 return_value += (attribute_desc_len + attribute_len); 01323 } else { 01324 success = 0; 01325 break; 01326 } 01327 item++; 01328 } 01329 if (!success) { 01330 *error = SN_NSDL_FAILURE; 01331 break; 01332 } 01333 } 01334 #endif 01335 if (resource_temp_ptr->coap_content_type != 0) { 01336 /* ;if="content" */ 01337 uint8_t len = sn_nsdl_itoa_len(resource_temp_ptr->coap_content_type); 01338 if (sn_nsdl_check_uint_overflow(return_value, 6, len)) { 01339 return_value += (6 + len); 01340 } else { 01341 *error = SN_NSDL_FAILURE; 01342 break; 01343 } 01344 } 01345 01346 if ((resource_temp_ptr->publish_value > 0) && resource_temp_ptr->resource) { 01347 /* ;v="" */ 01348 uint16_t len = resource_temp_ptr->resource_len; 01349 if (resource_temp_ptr->publish_value == 2) { 01350 len = (((resource_temp_ptr->resource_len + 2) / 3) << 2); 01351 } 01352 if (sn_nsdl_check_uint_overflow(return_value, 5, len)) { 01353 return_value += 5 + len; 01354 } else { 01355 *error = SN_NSDL_FAILURE; 01356 break; 01357 } 01358 /* ;v="" */ 01359 } 01360 01361 #ifndef COAP_DISABLE_OBS_FEATURE 01362 // Auto obs will take higher priority 01363 // This needs to be re-visited and may be need an API for maganging obs value for different server implementation 01364 if (resource_temp_ptr->auto_observable) { 01365 /* ;aobs="" */ 01366 uint8_t token[MAX_TOKEN_SIZE] = {0}; 01367 uint8_t len = handle->sn_nsdl_auto_obs_token_callback(handle, 01368 resource_temp_ptr->static_resource_parameters->path, 01369 (uint8_t*)token); 01370 01371 if (len > 0) { 01372 uint16_t temp = common_read_16_bit((uint8_t*)token); 01373 uint8_t token_len = sn_nsdl_itoa_len(temp); 01374 if (sn_nsdl_check_uint_overflow(return_value, 8, token_len)) { 01375 return_value += (8 + token_len); 01376 } else { 01377 *error = SN_NSDL_FAILURE; 01378 break; 01379 } 01380 } else { 01381 *error = SN_NSDL_FAILURE; 01382 break; 01383 } 01384 } 01385 else if (resource_temp_ptr->observable) { 01386 if (sn_nsdl_check_uint_overflow(return_value, 4, 0)) { 01387 return_value += 4; 01388 } else { 01389 *error = SN_NSDL_FAILURE; 01390 break; 01391 } 01392 } 01393 #endif 01394 } 01395 resource_temp_ptr = sn_grs_get_next_resource(handle->grs, resource_temp_ptr); 01396 } 01397 return return_value; 01398 } 01399 01400 /** 01401 * \fn static uint8_t sn_nsdl_calculate_uri_query_option_len(sn_nsdl_ep_parameters_s *endpoint_info_ptr, uint8_t msg_type) 01402 * 01403 * 01404 * \brief Calculates needed uri query option length 01405 * 01406 * \param *endpoint_info_ptr Pointer to endpoint info structure 01407 * \param msg_type Message type 01408 * 01409 * \return number of parameters in uri query 01410 */ 01411 static uint8_t sn_nsdl_calculate_uri_query_option_len(sn_nsdl_ep_parameters_s *endpoint_info_ptr, 01412 uint8_t msg_type, 01413 const char *uri_query) 01414 { 01415 uint16_t return_value = 0; 01416 uint8_t number_of_parameters = 0; 01417 01418 01419 if ((endpoint_info_ptr->endpoint_name_len != 0) && (msg_type == SN_NSDL_EP_REGISTER_MESSAGE) && endpoint_info_ptr->endpoint_name_ptr != 0) { 01420 return_value += endpoint_info_ptr->endpoint_name_len; 01421 return_value += EP_NAME_PARAMETERS_LEN; //ep= 01422 number_of_parameters++; 01423 } 01424 01425 if ((endpoint_info_ptr->type_len != 0) && 01426 (msg_type == SN_NSDL_EP_REGISTER_MESSAGE || msg_type == SN_NSDL_EP_UPDATE_MESSAGE) && 01427 (endpoint_info_ptr->type_ptr != 0)) { 01428 return_value += endpoint_info_ptr->type_len; 01429 return_value += ET_PARAMETER_LEN; //et= 01430 number_of_parameters++; 01431 } 01432 01433 if ((endpoint_info_ptr->lifetime_len != 0) && (endpoint_info_ptr->lifetime_ptr != 0)) { 01434 return_value += endpoint_info_ptr->lifetime_len; 01435 return_value += LT_PARAMETER_LEN; //lt= 01436 number_of_parameters++; 01437 } 01438 01439 if ((endpoint_info_ptr->domain_name_len != 0) && (msg_type == SN_NSDL_EP_REGISTER_MESSAGE) && (endpoint_info_ptr->domain_name_ptr != 0)) { 01440 return_value += endpoint_info_ptr->domain_name_len; 01441 return_value += DOMAIN_PARAMETER_LEN; //d= 01442 number_of_parameters++; 01443 } 01444 01445 if (((endpoint_info_ptr->binding_and_mode & 0x04) || (endpoint_info_ptr->binding_and_mode & 0x01)) && (msg_type == SN_NSDL_EP_REGISTER_MESSAGE)) { 01446 return_value += BS_QUEUE_MODE_PARAMETER_LEN; 01447 01448 if (endpoint_info_ptr->binding_and_mode & 0x01) { 01449 return_value++; 01450 } 01451 if (endpoint_info_ptr->binding_and_mode & 0x04) { 01452 return_value++; 01453 } 01454 if ((endpoint_info_ptr->binding_and_mode & 0x02) && ((endpoint_info_ptr->binding_and_mode & 0x04) || (endpoint_info_ptr->binding_and_mode & 0x01))) { 01455 return_value++; 01456 } 01457 01458 number_of_parameters++; 01459 } 01460 01461 if (number_of_parameters != 0) { 01462 return_value += (number_of_parameters - 1); 01463 } 01464 01465 if (uri_query) { 01466 return_value += strlen(uri_query); 01467 } 01468 01469 if (return_value > MAX_URI_QUERY_LEN) { 01470 tr_error("sn_nsdl_calculate_uri_query_option_len - max param length reached (%d)", return_value); 01471 return_value = 0; 01472 } 01473 01474 return return_value; 01475 } 01476 01477 /** 01478 * \fn static int8_t sn_nsdl_fill_uri_query_options(struct nsdl_s *handle, sn_nsdl_ep_parameters_s *parameter_ptr, sn_coap_hdr_s *source_msg_ptr, uint8_t msg_type) 01479 * 01480 * 01481 * \brief Fills uri-query options to message header struct 01482 * \param *handle Pointer to nsdl-library handle 01483 * \param *parameter_ptr Pointer to endpoint parameters struct 01484 * \param *source_msg_ptr Pointer to CoAP header struct 01485 * \param msg_type Message type 01486 * 01487 * \return SN_NSDL_SUCCESS = 0, Failed = -1 01488 */ 01489 static int8_t sn_nsdl_fill_uri_query_options(struct nsdl_s *handle, 01490 sn_nsdl_ep_parameters_s *parameter_ptr, 01491 sn_coap_hdr_s *source_msg_ptr, 01492 uint8_t msg_type, 01493 const char *uri_query) 01494 { 01495 uint8_t *temp_ptr = NULL; 01496 if( !validateParameters(parameter_ptr) ){ 01497 return SN_NSDL_FAILURE; 01498 } 01499 01500 size_t query_len = sn_nsdl_calculate_uri_query_option_len(parameter_ptr, msg_type, uri_query); 01501 if (query_len == 0) { 01502 return 0; 01503 } 01504 01505 source_msg_ptr->options_list_ptr->uri_query_len = query_len; 01506 source_msg_ptr->options_list_ptr->uri_query_ptr = handle->sn_nsdl_alloc(query_len); 01507 01508 if (source_msg_ptr->options_list_ptr->uri_query_ptr == NULL) { 01509 return SN_NSDL_FAILURE; 01510 } 01511 memset(source_msg_ptr->options_list_ptr->uri_query_ptr, 0, source_msg_ptr->options_list_ptr->uri_query_len); 01512 01513 temp_ptr = source_msg_ptr->options_list_ptr->uri_query_ptr; 01514 01515 /******************************************************/ 01516 /* If endpoint name is configured, fill needed fields */ 01517 /******************************************************/ 01518 01519 if ((parameter_ptr->endpoint_name_len != 0) && 01520 (parameter_ptr->endpoint_name_ptr != 0) && 01521 (msg_type == SN_NSDL_EP_REGISTER_MESSAGE)) { 01522 /* fill endpoint name, first ?ep=, then endpoint name */ 01523 memcpy(temp_ptr, ep_name_parameter_string, sizeof(ep_name_parameter_string)); 01524 temp_ptr += EP_NAME_PARAMETERS_LEN; 01525 memcpy(temp_ptr, parameter_ptr->endpoint_name_ptr, parameter_ptr->endpoint_name_len); 01526 temp_ptr += parameter_ptr->endpoint_name_len; 01527 } 01528 01529 /******************************************************/ 01530 /* If endpoint type is configured, fill needed fields */ 01531 /******************************************************/ 01532 01533 if ((parameter_ptr->type_len != 0) && 01534 (parameter_ptr->type_ptr != 0) && 01535 (msg_type == SN_NSDL_EP_REGISTER_MESSAGE || msg_type == SN_NSDL_EP_UPDATE_MESSAGE)) { 01536 if (temp_ptr != source_msg_ptr->options_list_ptr->uri_query_ptr) { 01537 *temp_ptr++ = '&'; 01538 } 01539 01540 memcpy(temp_ptr, et_parameter, sizeof(et_parameter)); 01541 temp_ptr += ET_PARAMETER_LEN; 01542 memcpy(temp_ptr, parameter_ptr->type_ptr, parameter_ptr->type_len); 01543 temp_ptr += parameter_ptr->type_len; 01544 } 01545 01546 01547 /******************************************************/ 01548 /* If lifetime is configured, fill needed fields */ 01549 /******************************************************/ 01550 01551 if ((parameter_ptr->lifetime_len != 0) && (parameter_ptr->lifetime_ptr != 0)) { 01552 if (temp_ptr != source_msg_ptr->options_list_ptr->uri_query_ptr) { 01553 *temp_ptr++ = '&'; 01554 } 01555 01556 memcpy(temp_ptr, ep_lifetime_parameter, sizeof(ep_lifetime_parameter)); 01557 temp_ptr += LT_PARAMETER_LEN; 01558 memcpy(temp_ptr, parameter_ptr->lifetime_ptr, parameter_ptr->lifetime_len); 01559 temp_ptr += parameter_ptr->lifetime_len; 01560 } 01561 01562 /******************************************************/ 01563 /* If domain is configured, fill needed fields */ 01564 /******************************************************/ 01565 01566 if ((parameter_ptr->domain_name_len != 0) && 01567 (parameter_ptr->domain_name_ptr != 0) && 01568 (msg_type == SN_NSDL_EP_REGISTER_MESSAGE)) { 01569 if (temp_ptr != source_msg_ptr->options_list_ptr->uri_query_ptr) { 01570 *temp_ptr++ = '&'; 01571 } 01572 01573 memcpy(temp_ptr, ep_domain_parameter, sizeof(ep_domain_parameter)); 01574 temp_ptr += DOMAIN_PARAMETER_LEN; 01575 memcpy(temp_ptr, parameter_ptr->domain_name_ptr, parameter_ptr->domain_name_len); 01576 temp_ptr += parameter_ptr->domain_name_len; 01577 } 01578 01579 /******************************************************/ 01580 /* If queue-mode is configured, fill needed fields */ 01581 /******************************************************/ 01582 01583 if (((parameter_ptr->binding_and_mode & 0x01) || 01584 (parameter_ptr->binding_and_mode & 0x04)) && 01585 (msg_type == SN_NSDL_EP_REGISTER_MESSAGE)) { 01586 if (temp_ptr != source_msg_ptr->options_list_ptr->uri_query_ptr) { 01587 *temp_ptr++ = '&'; 01588 } 01589 01590 memcpy(temp_ptr, bs_queue_mode, sizeof(bs_queue_mode)); 01591 temp_ptr += BS_QUEUE_MODE_PARAMETER_LEN; 01592 01593 if (parameter_ptr->binding_and_mode & 0x01) { 01594 *temp_ptr++ = 'U'; 01595 if (parameter_ptr->binding_and_mode & 0x02) { 01596 *temp_ptr++ = 'Q'; 01597 } 01598 } 01599 01600 if (parameter_ptr->binding_and_mode & 0x04) { 01601 *temp_ptr++ = 'S'; 01602 if ((parameter_ptr->binding_and_mode & 0x02) && !(parameter_ptr->binding_and_mode & 0x01)) { 01603 *temp_ptr++ = 'Q'; 01604 } 01605 } 01606 } 01607 01608 if (uri_query) { 01609 memcpy(temp_ptr, uri_query, strlen(uri_query)); 01610 } 01611 01612 return SN_NSDL_SUCCESS; 01613 } 01614 01615 static bool validateParameters(sn_nsdl_ep_parameters_s *parameter_ptr) 01616 { 01617 if( !validate( parameter_ptr->domain_name_ptr, parameter_ptr->domain_name_len, '&' ) ){ 01618 return false; 01619 } 01620 01621 if( !validate( parameter_ptr->endpoint_name_ptr, parameter_ptr->endpoint_name_len, '&' ) ){ 01622 return false; 01623 } 01624 01625 if( !validate( parameter_ptr->lifetime_ptr, parameter_ptr->lifetime_len, '&' ) ){ 01626 return false; 01627 } 01628 01629 if( !validate( parameter_ptr->type_ptr, parameter_ptr->type_len, '&' ) ){ 01630 return false; 01631 } 01632 return true; 01633 } 01634 01635 static bool validate(uint8_t* ptr, uint32_t len, char illegalChar) 01636 { 01637 if( ptr ){ 01638 for( uint32_t i=0; i < len; i++ ){ 01639 if( ptr[i] == illegalChar ){ 01640 return false; 01641 } 01642 } 01643 } 01644 return true; 01645 } 01646 01647 /** 01648 * \fn static int8_t sn_nsdl_local_rx_function(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr, sn_nsdl_addr_s *address_ptr) 01649 * 01650 * \brief If received message is reply for the message that NSDL has been sent, it is processed here. Else, packet will be sent to application. 01651 * \param *handle Pointer to nsdl-library handle 01652 * \param *coap_packet_ptr Pointer to received CoAP packet 01653 * \param *address_ptr Pointer to source address struct 01654 * 01655 * \return SN_NSDL_SUCCESS = 0, Failed = -1 01656 */ 01657 static int8_t sn_nsdl_local_rx_function(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr, sn_nsdl_addr_s *address_ptr) 01658 { 01659 if ((coap_packet_ptr == 0) || (address_ptr == 0)) { 01660 return -1; 01661 } 01662 01663 bool is_reg_msg = false; 01664 bool is_update_reg_msg = false; 01665 bool is_unreg_msg = false; 01666 bool is_bs_msg = false; 01667 01668 if (coap_packet_ptr->msg_code == COAP_MSG_CODE_RESPONSE_CREATED && 01669 coap_packet_ptr->token_len == sizeof(handle->register_token) && 01670 memcmp(coap_packet_ptr->token_ptr, &handle->register_token, coap_packet_ptr->token_len) == 0) { 01671 handle->sn_nsdl_endpoint_registered = SN_NSDL_ENDPOINT_IS_REGISTERED; 01672 sn_grs_mark_resources_as_registered(handle); 01673 is_reg_msg = true; 01674 if (sn_nsdl_resolve_ep_information(handle, coap_packet_ptr) != SN_NSDL_SUCCESS) { 01675 return SN_NSDL_FAILURE; 01676 } 01677 } 01678 01679 else if (coap_packet_ptr->msg_code == COAP_MSG_CODE_RESPONSE_CHANGED && 01680 coap_packet_ptr->token_len == sizeof(handle->update_register_token) && 01681 memcmp(coap_packet_ptr->token_ptr, 01682 &handle->update_register_token, 01683 coap_packet_ptr->token_len) == 0) { 01684 is_update_reg_msg = true; 01685 } 01686 01687 else if (coap_packet_ptr->msg_code == COAP_MSG_CODE_RESPONSE_DELETED && 01688 coap_packet_ptr->token_len == sizeof(handle->unregister_token) && 01689 memcmp(coap_packet_ptr->token_ptr, &handle->unregister_token, coap_packet_ptr->token_len) == 0) { 01690 is_unreg_msg = true; 01691 handle->sn_nsdl_free(handle->ep_information_ptr->endpoint_name_ptr); 01692 handle->ep_information_ptr->endpoint_name_ptr = 0; 01693 handle->ep_information_ptr->endpoint_name_len = 0; 01694 01695 handle->sn_nsdl_free(handle->ep_information_ptr->domain_name_ptr); 01696 handle->ep_information_ptr->domain_name_ptr = 0; 01697 handle->ep_information_ptr->domain_name_len = 0; 01698 } 01699 else if (coap_packet_ptr->token_len == sizeof(handle->bootstrap_token) && 01700 memcmp(coap_packet_ptr->token_ptr, &handle->bootstrap_token, coap_packet_ptr->token_len) == 0) { 01701 is_bs_msg = true; 01702 } 01703 01704 /* Store the current message token so that we can identify if same operation was initiated from callback */ 01705 uint32_t temp_token = 0; 01706 if (is_reg_msg) { 01707 temp_token = handle->register_token; 01708 } 01709 else if (is_unreg_msg) { 01710 temp_token = handle->unregister_token; 01711 } 01712 else if (is_update_reg_msg) { 01713 temp_token = handle->update_register_token; 01714 } 01715 else if (is_bs_msg) { 01716 temp_token = handle->bootstrap_token; 01717 } 01718 01719 /* No messages to wait for, or message was not response to our request */ 01720 int ret = handle->sn_nsdl_rx_callback(handle, coap_packet_ptr, address_ptr); 01721 01722 /* If callback initiated same operation then token is updated in handle and temp_token won't match. 01723 This means we don't clear the handle token here because we will wait for response to new request. */ 01724 if (is_reg_msg && temp_token == handle->register_token) { 01725 handle->register_token = 0; 01726 } 01727 else if (is_unreg_msg && temp_token == handle->unregister_token) { 01728 handle->unregister_token = 0; 01729 } 01730 else if (is_update_reg_msg && temp_token == handle->update_register_token) { 01731 handle->update_register_token = 0; 01732 } 01733 else if (is_bs_msg && temp_token == handle->bootstrap_token) { 01734 handle->bootstrap_token = 0; 01735 } 01736 return ret; 01737 } 01738 01739 /** 01740 * \fn static int8_t sn_nsdl_resolve_ep_information(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr) 01741 * 01742 * 01743 * \brief Resolves endpoint information from received CoAP message 01744 * \param *handle Pointer to nsdl-library handle 01745 * \param *coap_packet_ptr Pointer to received CoAP message 01746 * 01747 * \return SN_NSDL_SUCCESS = 0, Failed = -1 01748 */ 01749 static int8_t sn_nsdl_resolve_ep_information(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr) 01750 { 01751 uint8_t *temp_ptr; 01752 uint8_t parameter_count = 0; 01753 uint16_t parameter_len = 0; 01754 01755 if (!coap_packet_ptr || !coap_packet_ptr->options_list_ptr || 01756 !coap_packet_ptr->options_list_ptr->location_path_ptr) { 01757 return SN_NSDL_FAILURE; 01758 } 01759 01760 temp_ptr = coap_packet_ptr->options_list_ptr->location_path_ptr; 01761 01762 while (temp_ptr <= (coap_packet_ptr->options_list_ptr->location_path_ptr + coap_packet_ptr->options_list_ptr->location_path_len)) { 01763 01764 if ((temp_ptr == (coap_packet_ptr->options_list_ptr->location_path_ptr + coap_packet_ptr->options_list_ptr->location_path_len)) || (*temp_ptr == '/')) { 01765 01766 parameter_count++; 01767 if (parameter_count == 2) { 01768 if (!handle->ep_information_ptr->domain_name_ptr) { 01769 handle->ep_information_ptr->domain_name_len = parameter_len - 1; 01770 handle->ep_information_ptr->domain_name_ptr = handle->sn_nsdl_alloc(handle->ep_information_ptr->domain_name_len); 01771 if (!handle->ep_information_ptr->domain_name_ptr) { 01772 return SN_NSDL_FAILURE; 01773 } 01774 memcpy(handle->ep_information_ptr->domain_name_ptr, temp_ptr - handle->ep_information_ptr->domain_name_len, handle->ep_information_ptr->domain_name_len); 01775 } 01776 01777 } 01778 if (parameter_count == 3) { 01779 if (!handle->ep_information_ptr->endpoint_name_ptr) { 01780 handle->ep_information_ptr->endpoint_name_len = parameter_len - 1; 01781 handle->ep_information_ptr->endpoint_name_ptr = handle->sn_nsdl_alloc(handle->ep_information_ptr->endpoint_name_len); 01782 if (!handle->ep_information_ptr->endpoint_name_ptr) { 01783 if (handle->ep_information_ptr->domain_name_ptr) { 01784 handle->sn_nsdl_free(handle->ep_information_ptr->domain_name_ptr); 01785 handle->ep_information_ptr->domain_name_ptr = NULL; 01786 handle->ep_information_ptr->domain_name_len = 0; 01787 } 01788 01789 return SN_NSDL_FAILURE; 01790 01791 } 01792 memcpy(handle->ep_information_ptr->endpoint_name_ptr, temp_ptr - handle->ep_information_ptr->endpoint_name_len, handle->ep_information_ptr->endpoint_name_len); 01793 } 01794 } 01795 parameter_len = 0; 01796 } 01797 parameter_len++; 01798 temp_ptr++; 01799 } 01800 01801 01802 return SN_NSDL_SUCCESS; 01803 } 01804 01805 extern int8_t set_NSP_address(struct nsdl_s *handle, uint8_t *NSP_address, uint8_t address_length, uint16_t port, sn_nsdl_addr_type_e address_type) 01806 { 01807 /* Check parameters and source pointers */ 01808 if (!handle || !NSP_address) { 01809 return SN_NSDL_FAILURE; 01810 } 01811 01812 handle->server_address.type = address_type; 01813 01814 handle->sn_nsdl_free(handle->server_address.addr_ptr); 01815 01816 handle->server_address.addr_len = address_length; 01817 01818 handle->server_address.addr_ptr = handle->sn_nsdl_alloc(handle->server_address.addr_len); 01819 if (!handle->server_address.addr_ptr) { 01820 return SN_NSDL_FAILURE; 01821 } 01822 01823 memcpy(handle->server_address.addr_ptr, NSP_address, handle->server_address.addr_len); 01824 handle->server_address.port = port; 01825 01826 return SN_NSDL_SUCCESS; 01827 } 01828 01829 01830 static uint8_t sn_nsdl_itoa_len(uint32_t value) 01831 { 01832 uint8_t i = 0; 01833 01834 do { 01835 i++; 01836 } while ((value /= 10) > 0); 01837 01838 return i; 01839 } 01840 01841 static uint8_t *sn_nsdl_itoa(uint8_t *ptr, uint32_t value) 01842 { 01843 01844 uint8_t start = 0; 01845 uint8_t end = 0; 01846 uint8_t i; 01847 01848 i = 0; 01849 01850 /* ITOA */ 01851 do { 01852 ptr[i++] = (value % 10) + '0'; 01853 } while ((value /= 10) > 0); 01854 01855 end = i - 1; 01856 01857 /* reverse (part of ITOA) */ 01858 while (start < end) { 01859 uint8_t chr; 01860 01861 chr = ptr[start]; 01862 ptr[start] = ptr[end]; 01863 ptr[end] = chr; 01864 01865 start++; 01866 end--; 01867 01868 } 01869 return (ptr + i); 01870 } 01871 01872 static int8_t set_endpoint_info(struct nsdl_s *handle, sn_nsdl_ep_parameters_s *endpoint_info_ptr) 01873 { 01874 handle->sn_nsdl_free(handle->ep_information_ptr->domain_name_ptr); 01875 handle->ep_information_ptr->domain_name_ptr = 0; 01876 handle->ep_information_ptr->domain_name_len = 0; 01877 01878 handle->sn_nsdl_free(handle->ep_information_ptr->endpoint_name_ptr); 01879 handle->ep_information_ptr->endpoint_name_ptr = 0; 01880 handle->ep_information_ptr->endpoint_name_len = 0; 01881 01882 handle->sn_nsdl_free(handle->ep_information_ptr->type_ptr); 01883 handle->ep_information_ptr->type_ptr = 0; 01884 handle->ep_information_ptr->type_len = 0; 01885 01886 if (endpoint_info_ptr->domain_name_ptr && endpoint_info_ptr->domain_name_len) { 01887 handle->ep_information_ptr->domain_name_ptr = handle->sn_nsdl_alloc(endpoint_info_ptr->domain_name_len); 01888 01889 if (!handle->ep_information_ptr->domain_name_ptr) { 01890 return -1; 01891 } 01892 01893 memcpy(handle->ep_information_ptr->domain_name_ptr, endpoint_info_ptr->domain_name_ptr, endpoint_info_ptr->domain_name_len); 01894 handle->ep_information_ptr->domain_name_len = endpoint_info_ptr->domain_name_len; 01895 } 01896 01897 if (endpoint_info_ptr->endpoint_name_ptr && endpoint_info_ptr->endpoint_name_len) { 01898 handle->ep_information_ptr->endpoint_name_ptr = handle->sn_nsdl_alloc(endpoint_info_ptr->endpoint_name_len); 01899 01900 if (!handle->ep_information_ptr->endpoint_name_ptr) { 01901 handle->sn_nsdl_free(handle->ep_information_ptr->domain_name_ptr); 01902 handle->ep_information_ptr->domain_name_ptr = 0; 01903 handle->ep_information_ptr->domain_name_len = 0; 01904 return -1; 01905 } 01906 01907 memcpy(handle->ep_information_ptr->endpoint_name_ptr, endpoint_info_ptr->endpoint_name_ptr, endpoint_info_ptr->endpoint_name_len); 01908 handle->ep_information_ptr->endpoint_name_len = endpoint_info_ptr->endpoint_name_len; 01909 } 01910 01911 if (endpoint_info_ptr->type_ptr && endpoint_info_ptr->type_len) { 01912 handle->ep_information_ptr->type_ptr = handle->sn_nsdl_alloc(endpoint_info_ptr->type_len); 01913 if (handle->ep_information_ptr->type_ptr) { 01914 memcpy(handle->ep_information_ptr->type_ptr, endpoint_info_ptr->type_ptr, endpoint_info_ptr->type_len); 01915 handle->ep_information_ptr->type_len = endpoint_info_ptr->type_len; 01916 } 01917 } 01918 01919 handle->ep_information_ptr->binding_and_mode = endpoint_info_ptr->binding_and_mode; 01920 handle->ep_information_ptr->ds_register_mode = endpoint_info_ptr->ds_register_mode; 01921 01922 return 0; 01923 } 01924 01925 extern int8_t sn_nsdl_send_coap_message(struct nsdl_s *handle, sn_nsdl_addr_s *address_ptr, sn_coap_hdr_s *coap_hdr_ptr) 01926 { 01927 /* Check parameters */ 01928 if (handle == NULL) { 01929 return SN_NSDL_FAILURE; 01930 } 01931 01932 int8_t ret = sn_grs_send_coap_message(handle, address_ptr, coap_hdr_ptr); 01933 01934 return ret; 01935 } 01936 01937 extern int8_t sn_nsdl_handle_block2_response_internally(struct nsdl_s *handle, uint8_t build_response) 01938 { 01939 /* Check parameters */ 01940 if (handle == NULL) { 01941 return SN_NSDL_FAILURE; 01942 } 01943 01944 return sn_coap_protocol_handle_block2_response_internally(handle->grs->coap, build_response); 01945 } 01946 01947 extern int8_t sn_nsdl_clear_coap_sent_blockwise_messages(struct nsdl_s *handle) 01948 { 01949 /* Check parameters */ 01950 if (handle == NULL) { 01951 return SN_NSDL_FAILURE; 01952 } 01953 01954 // Enable function once new CoAP API is released to mbed-os 01955 sn_coap_protocol_clear_sent_blockwise_messages(handle->grs->coap); 01956 01957 return SN_NSDL_SUCCESS; 01958 } 01959 01960 extern int8_t sn_nsdl_clear_coap_received_blockwise_messages(struct nsdl_s *handle) 01961 { 01962 /* Check parameters */ 01963 if (handle == NULL) { 01964 return SN_NSDL_FAILURE; 01965 } 01966 01967 // Enable function once new CoAP API is released to mbed-os 01968 // sn_coap_protocol_clear_received_blockwise_messages(handle->grs->coap); 01969 01970 /* Loop all stored Blockwise messages in Linked list */ 01971 ns_list_foreach_safe(coap_blockwise_payload_s, removed_payload_ptr, &handle->grs->coap->linked_list_blockwise_received_payloads) { 01972 ns_list_remove(&handle->grs->coap->linked_list_blockwise_received_payloads, removed_payload_ptr); 01973 /* Free memory of stored payload */ 01974 handle->grs->coap->sn_coap_protocol_free(removed_payload_ptr->addr_ptr); 01975 handle->grs->coap->sn_coap_protocol_free(removed_payload_ptr->payload_ptr); 01976 handle->grs->coap->sn_coap_protocol_free(removed_payload_ptr->token_ptr); 01977 handle->grs->coap->sn_coap_protocol_free(removed_payload_ptr); 01978 } 01979 01980 return SN_NSDL_SUCCESS; 01981 } 01982 01983 extern int32_t sn_nsdl_send_request(struct nsdl_s *handle, 01984 const sn_coap_msg_code_e msg_code, 01985 const char *uri_path, 01986 const uint32_t token, 01987 const size_t offset, 01988 const uint16_t payload_len, 01989 uint8_t* payload_ptr, 01990 DownloadType type) 01991 { 01992 sn_coap_hdr_s req_message; 01993 int32_t message_id; 01994 01995 if (handle == NULL || uri_path == NULL) { 01996 return 0; 01997 } 01998 01999 memset(&req_message, 0, sizeof(sn_coap_hdr_s)); 02000 02001 // Fill message fields 02002 req_message.msg_type = COAP_MSG_TYPE_CONFIRMABLE; 02003 req_message.msg_code = msg_code; 02004 02005 // In GET we use hardcoded uri path('fw' or 'download') since the actual binary path will be part of 02006 // proxy uri option 02007 if (req_message.msg_code == COAP_MSG_CODE_REQUEST_GET) { 02008 if (type == FIRMWARE_DOWNLOAD) { 02009 req_message.uri_path_len = FIRMWARE_DOWNLOAD_LEN; 02010 req_message.uri_path_ptr = firmware_download_uri; 02011 } else { 02012 req_message.uri_path_len = GENERIC_DOWNLOAD_LEN; 02013 req_message.uri_path_ptr = generic_download_uri; 02014 } 02015 } else { 02016 req_message.uri_path_len = (uint16_t)strlen(uri_path); 02017 req_message.uri_path_ptr = (uint8_t*)uri_path; 02018 } 02019 req_message.token_ptr = (uint8_t*)&token; 02020 req_message.token_len = sizeof(token); 02021 if (msg_code == COAP_MSG_CODE_REQUEST_POST || msg_code == COAP_MSG_CODE_REQUEST_PUT) { 02022 // Use payload only if POST or PUT request 02023 req_message.payload_ptr = payload_ptr; 02024 req_message.payload_len = payload_len; 02025 } 02026 02027 if (sn_coap_parser_alloc_options(handle->grs->coap, &req_message) == NULL) { 02028 handle->grs->coap->sn_coap_protocol_free(req_message.options_list_ptr); 02029 return 0; 02030 } 02031 02032 if (msg_code == COAP_MSG_CODE_REQUEST_GET) { 02033 req_message.options_list_ptr->proxy_uri_len = (uint16_t)strlen(uri_path); 02034 req_message.options_list_ptr->proxy_uri_ptr = (uint8_t*)uri_path; 02035 } 02036 02037 // Skip block options if feature is not enabled 02038 #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE 02039 // Add block number 02040 req_message.options_list_ptr->block2 = 0; 02041 if (offset > 0) { 02042 req_message.options_list_ptr->block2 = ((offset / handle->grs->coap->sn_coap_block_data_size) << 4); 02043 } 02044 // Add block size 02045 req_message.options_list_ptr->block2 |= sn_coap_convert_block_size(handle->grs->coap->sn_coap_block_data_size); 02046 #else 02047 (void)offset; 02048 #endif 02049 02050 // Build and send coap message 02051 message_id = sn_nsdl_internal_coap_send(handle, &req_message, &handle->server_address); 02052 handle->grs->coap->sn_coap_protocol_free(req_message.options_list_ptr); 02053 02054 return message_id; 02055 } 02056 02057 extern int8_t sn_nsdl_put_resource(struct nsdl_s *handle, sn_nsdl_dynamic_resource_parameters_s *res) 02058 { 02059 if (!handle) { 02060 return SN_NSDL_FAILURE; 02061 } 02062 02063 return sn_grs_put_resource(handle->grs, res); 02064 } 02065 02066 extern int8_t sn_nsdl_pop_resource(struct nsdl_s *handle, sn_nsdl_dynamic_resource_parameters_s *res) 02067 { 02068 if (!handle) { 02069 return SN_NSDL_FAILURE; 02070 } 02071 02072 return sn_grs_pop_resource(handle->grs, res); 02073 } 02074 02075 extern int8_t sn_nsdl_delete_resource(struct nsdl_s *handle, const char *path) 02076 { 02077 /* Check parameters */ 02078 if (handle == NULL) { 02079 return SN_NSDL_FAILURE; 02080 } 02081 02082 return sn_grs_delete_resource(handle->grs, path); 02083 } 02084 extern const sn_nsdl_dynamic_resource_parameters_s *sn_nsdl_get_first_resource(struct nsdl_s *handle) 02085 { 02086 /* Check parameters */ 02087 if (handle == NULL) { 02088 return NULL; 02089 } 02090 02091 return sn_grs_get_first_resource(handle->grs); 02092 } 02093 extern const sn_nsdl_dynamic_resource_parameters_s *sn_nsdl_get_next_resource(struct nsdl_s *handle, const sn_nsdl_dynamic_resource_parameters_s *resource) 02094 { 02095 /* Check parameters */ 02096 if (handle == NULL) { 02097 return NULL; 02098 } 02099 02100 return sn_grs_get_next_resource(handle->grs, resource); 02101 } 02102 02103 extern sn_coap_hdr_s *sn_nsdl_build_response(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr, uint8_t msg_code) 02104 { 02105 if (handle == NULL) { 02106 return NULL; 02107 } 02108 02109 return sn_coap_build_response(handle->grs->coap, coap_packet_ptr, msg_code); 02110 } 02111 02112 extern sn_coap_options_list_s *sn_nsdl_alloc_options_list(struct nsdl_s *handle, sn_coap_hdr_s *coap_msg_ptr) 02113 { 02114 if (handle == NULL || coap_msg_ptr == NULL) { 02115 return NULL; 02116 } 02117 return sn_coap_parser_alloc_options(handle->grs->coap, coap_msg_ptr); 02118 } 02119 02120 extern void sn_nsdl_release_allocated_coap_msg_mem(struct nsdl_s *handle, sn_coap_hdr_s *freed_coap_msg_ptr) 02121 { 02122 if (handle == NULL) { 02123 return; 02124 } 02125 02126 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, freed_coap_msg_ptr); 02127 } 02128 02129 extern int8_t sn_nsdl_set_retransmission_parameters(struct nsdl_s *handle, 02130 uint8_t resending_count, uint8_t resending_interval) 02131 { 02132 if (handle == NULL) { 02133 return SN_NSDL_FAILURE; 02134 } 02135 return sn_coap_protocol_set_retransmission_parameters(handle->grs->coap, 02136 resending_count,resending_interval); 02137 } 02138 02139 extern int8_t sn_nsdl_set_retransmission_buffer(struct nsdl_s *handle, 02140 uint8_t buffer_size_messages, uint16_t buffer_size_bytes) 02141 { 02142 if (handle == NULL) { 02143 return SN_NSDL_FAILURE; 02144 } 02145 return sn_coap_protocol_set_retransmission_buffer(handle->grs->coap, 02146 buffer_size_messages, buffer_size_bytes); 02147 } 02148 02149 extern int8_t sn_nsdl_set_block_size(struct nsdl_s *handle, uint16_t block_size) 02150 { 02151 if (handle == NULL) { 02152 return SN_NSDL_FAILURE; 02153 } 02154 return sn_coap_protocol_set_block_size(handle->grs->coap, block_size); 02155 } 02156 02157 extern int8_t sn_nsdl_set_duplicate_buffer_size(struct nsdl_s *handle, uint8_t message_count) 02158 { 02159 if (handle == NULL) { 02160 return SN_NSDL_FAILURE; 02161 } 02162 return sn_coap_protocol_set_duplicate_buffer_size(handle->grs->coap, message_count); 02163 } 02164 02165 bool sn_nsdl_check_uint_overflow(uint16_t resource_size, uint16_t param_a, uint16_t param_b) 02166 { 02167 uint16_t first_check = param_a + param_b; 02168 if (first_check < param_b) { 02169 return false; 02170 } else { 02171 uint16_t total = resource_size + first_check; 02172 if (total < first_check) { 02173 return false; 02174 } else { 02175 return true; 02176 } 02177 } 02178 } 02179 02180 extern int8_t sn_nsdl_set_context(struct nsdl_s * const handle, void * const context) 02181 { 02182 if (handle == NULL) { 02183 return SN_NSDL_FAILURE; 02184 } 02185 handle->context = context; 02186 return SN_NSDL_SUCCESS; 02187 } 02188 02189 extern void *sn_nsdl_get_context(const struct nsdl_s * const handle) 02190 { 02191 if (handle == NULL) { 02192 return NULL; 02193 } 02194 return handle->context; 02195 } 02196 02197 02198 int8_t sn_nsdl_clear_coap_resending_queue(struct nsdl_s *handle) 02199 { 02200 if (handle == NULL || handle->grs == NULL) { 02201 tr_err("sn_nsdl_clear_coap_resending_queue failed."); 02202 return SN_NSDL_FAILURE; 02203 } 02204 sn_coap_protocol_clear_retransmission_buffer(handle->grs->coap); 02205 return SN_NSDL_SUCCESS; 02206 } 02207 02208 int8_t sn_nsdl_remove_msg_from_retransmission(struct nsdl_s *handle, uint8_t *token, uint8_t token_len) 02209 { 02210 if (handle == NULL || handle->grs == NULL || handle->grs->coap == NULL || token == NULL || token_len == 0) { 02211 tr_err("sn_nsdl_remove_msg_from_retransmission failed."); 02212 return SN_NSDL_FAILURE; 02213 } 02214 02215 #if ENABLE_RESENDINGS 02216 // Workaround until new "sn_coap_protocol_delete_retransmission_by_token" API is released 02217 // return sn_coap_protocol_delete_retransmission_by_token(handle->grs->coap, token, token_len); 02218 ns_list_foreach(coap_send_msg_s, stored_msg, &handle->grs->coap->linked_list_resent_msgs) { 02219 uint8_t stored_token_len = (stored_msg->send_msg_ptr->packet_ptr[0] & 0x0F); 02220 if (stored_token_len == token_len) { 02221 uint8_t stored_token[8]; 02222 memcpy(stored_token, &stored_msg->send_msg_ptr->packet_ptr[4], stored_token_len); 02223 if (memcmp(stored_token, token, stored_token_len) == 0) { 02224 uint16_t temp_msg_id = (stored_msg->send_msg_ptr->packet_ptr[2] << 8); 02225 temp_msg_id += (uint16_t)stored_msg->send_msg_ptr->packet_ptr[3]; 02226 tr_debug("sn_nsdl_remove_msg_from_retransmission - removed msg_id: %d", temp_msg_id); 02227 ns_list_remove(&handle->grs->coap->linked_list_resent_msgs, stored_msg); 02228 --handle->grs->coap->count_resent_msgs; 02229 02230 handle->grs->coap->sn_coap_protocol_free(stored_msg->send_msg_ptr); 02231 handle->grs->coap->sn_coap_protocol_free(stored_msg); 02232 02233 return 0; 02234 } 02235 } 02236 } 02237 #endif 02238 02239 return SN_NSDL_FAILURE; 02240 } 02241 02242 #ifdef RESOURCE_ATTRIBUTES_LIST 02243 static void sn_nsdl_free_attribute_value(sn_nsdl_attribute_item_s *attribute) 02244 { 02245 switch (attribute->attribute_name) { 02246 case ATTR_RESOURCE_TYPE: 02247 case ATTR_INTERFACE_DESCRIPTION: 02248 case ATTR_ENDPOINT_NAME: 02249 free(attribute->value); 02250 attribute->value = NULL; 02251 break; 02252 case ATTR_NOP: 02253 case ATTR_END: 02254 default: 02255 break; 02256 } 02257 } 02258 02259 void sn_nsdl_free_resource_attributes_list(sn_nsdl_static_resource_parameters_s *params) 02260 { 02261 if (params == NULL || params->free_on_delete == false) { 02262 return; 02263 } 02264 sn_nsdl_attribute_item_s *item = params->attributes_ptr; 02265 if (item) { 02266 while (item->attribute_name != ATTR_END) { 02267 sn_nsdl_free_attribute_value(item); 02268 item++; 02269 } 02270 free(params->attributes_ptr); 02271 params->attributes_ptr = NULL; 02272 } 02273 } 02274 02275 bool sn_nsdl_set_resource_attribute(sn_nsdl_static_resource_parameters_s *params, const sn_nsdl_attribute_item_s *attribute) 02276 { 02277 if (params == NULL || params->free_on_delete == false) { 02278 return false; 02279 } 02280 unsigned int item_count = 0; 02281 sn_nsdl_attribute_item_s *item = params->attributes_ptr; 02282 // Count the number of attributes for reallocation, update in place though 02283 // if the attribute already existed 02284 while (item != NULL) { 02285 item_count++; 02286 if (item->attribute_name == ATTR_END) { 02287 break; 02288 } 02289 // Check if attribute already exists or if there is NOP we can overwrite 02290 if (item->attribute_name == attribute->attribute_name || item->attribute_name == ATTR_NOP) { 02291 // Found attribute or NOP, overwrite it 02292 sn_nsdl_free_attribute_value(item); 02293 item->attribute_name = attribute->attribute_name; 02294 item->value = attribute->value; 02295 return true; 02296 } 02297 item++; 02298 } 02299 // Attribute did not yet exist (ptr was null or ATTR_END was first one) 02300 if (item_count > 0) { 02301 // List already had some attributes, so reallocate 02302 size_t new_size = (item_count + 1) * sizeof(sn_nsdl_attribute_item_s); 02303 item = params->attributes_ptr; 02304 params->attributes_ptr = realloc(item, new_size); 02305 if (params->attributes_ptr == NULL) { 02306 // realloc failed, put back original pointer and return false 02307 params->attributes_ptr = item; 02308 return false; 02309 } 02310 // And move item ptr to ATTR_END to update that and last attribute 02311 item = &(params->attributes_ptr[item_count - 1]); 02312 } 02313 else { 02314 // No attributes, so allocate first time (1 struct for attribute and 1 struct for ATTR_END) 02315 params->attributes_ptr = (char*)malloc(2 * sizeof(sn_nsdl_attribute_item_s)); 02316 if (params->attributes_ptr == NULL) { 02317 return false; 02318 } 02319 item = params->attributes_ptr; 02320 } 02321 item->attribute_name = attribute->attribute_name; 02322 item->value = attribute->value; 02323 item++; 02324 item->attribute_name = ATTR_END; 02325 item->value = NULL; 02326 return true; 02327 } 02328 02329 const char *sn_nsdl_get_resource_attribute(const sn_nsdl_static_resource_parameters_s *params, sn_nsdl_resource_attribute_t attribute_name) 02330 { 02331 char *value = NULL; 02332 if (params != NULL) { 02333 sn_nsdl_attribute_item_s *item = params->attributes_ptr; 02334 while (item != NULL && item->attribute_name != ATTR_END) { 02335 if (item->attribute_name == attribute_name) { 02336 value = item->value; 02337 break; 02338 } 02339 item++; 02340 } 02341 } 02342 return value; 02343 } 02344 02345 bool sn_nsdl_remove_resource_attribute(sn_nsdl_static_resource_parameters_s *params, sn_nsdl_resource_attribute_t attribute_name) 02346 { 02347 if (params == NULL || params->free_on_delete == false) { 02348 return false; 02349 } 02350 02351 bool found = false; 02352 sn_nsdl_attribute_item_s *item = params->attributes_ptr; 02353 while (item != NULL) { 02354 if (item->attribute_name == ATTR_END) { 02355 break; 02356 } 02357 // Remove if attribute name matches 02358 if (item->attribute_name == attribute_name) { 02359 // Currently only pointer values, need to free and set as NOP 02360 sn_nsdl_free_attribute_value(item); 02361 item->attribute_name = ATTR_NOP; 02362 found = true; 02363 break; 02364 } 02365 item++; 02366 } 02367 02368 return found; 02369 02370 } 02371 02372 #endif 02373 02374 02375 void sn_nsdl_print_coap_data(sn_coap_hdr_s *coap_header_ptr, bool outgoing) 02376 { 02377 #if MBED_CONF_MBED_TRACE_ENABLE 02378 if (!coap_header_ptr) { 02379 return; 02380 } 02381 02382 if (outgoing) { 02383 tr_info("======== Outgoing CoAP package ========"); 02384 } else { 02385 tr_info("======== Incoming CoAP package ========"); 02386 } 02387 02388 if (coap_header_ptr->uri_path_len > 0 && coap_header_ptr->uri_path_ptr) { 02389 tr_info("Uri-Path:\t\t%.*s", coap_header_ptr->uri_path_len, coap_header_ptr->uri_path_ptr); 02390 } 02391 tr_info("Status:\t\t%s", sn_nsdl_coap_status_description(coap_header_ptr->coap_status)); 02392 tr_info("Code:\t\t%s", sn_nsdl_coap_message_code_desc(coap_header_ptr->msg_code)); 02393 tr_info("Type:\t\t%s", sn_nsdl_coap_message_type_desc(coap_header_ptr->msg_type)); 02394 tr_info("Id:\t\t%d", coap_header_ptr->msg_id); 02395 if (coap_header_ptr->token_ptr && coap_header_ptr->token_len > 0) { 02396 tr_info("Token:\t\t%s", tr_array(coap_header_ptr->token_ptr, coap_header_ptr->token_len)); 02397 } 02398 if (coap_header_ptr->content_format != -1) { 02399 tr_info("Content-type:\t%d", coap_header_ptr->content_format); 02400 } 02401 tr_info("Payload len:\t%d", coap_header_ptr->payload_len); 02402 #ifdef MBED_CLIENT_PRINT_COAP_PAYLOAD 02403 if (coap_header_ptr->payload_ptr && coap_header_ptr->payload_len > 0) { 02404 int i = 0; 02405 int row_len = 40; 02406 int max_length = 2048; 02407 while (i < coap_header_ptr->payload_len && i < max_length) { 02408 if (i + row_len > coap_header_ptr->payload_len) { 02409 row_len = coap_header_ptr->payload_len - i; 02410 } 02411 tr_info("Payload:\t\t%s", tr_array( coap_header_ptr->payload_ptr + i, row_len)); 02412 i += row_len; 02413 } 02414 if (i >= max_length) 02415 tr_info("Payload:\t\t....."); 02416 } 02417 #endif 02418 02419 if (coap_header_ptr->options_list_ptr) { 02420 if (coap_header_ptr->options_list_ptr->etag_ptr && coap_header_ptr->options_list_ptr->etag_len > 0) { 02421 tr_info("E-tag:\t%s", tr_array(coap_header_ptr->options_list_ptr->etag_ptr, coap_header_ptr->options_list_ptr->etag_len)); 02422 } 02423 if (coap_header_ptr->options_list_ptr->proxy_uri_ptr && coap_header_ptr->options_list_ptr->proxy_uri_len > 0) { 02424 tr_info("Proxy uri:\t%.*s", coap_header_ptr->options_list_ptr->proxy_uri_len, coap_header_ptr->options_list_ptr->proxy_uri_ptr); 02425 } 02426 02427 if (coap_header_ptr->options_list_ptr->uri_host_ptr && coap_header_ptr->options_list_ptr->uri_host_len > 0) { 02428 tr_info("Uri host:\t%.*s", coap_header_ptr->options_list_ptr->uri_host_len, coap_header_ptr->options_list_ptr->uri_host_ptr); 02429 } 02430 02431 if (coap_header_ptr->options_list_ptr->location_path_ptr && coap_header_ptr->options_list_ptr->location_path_len > 0) { 02432 tr_info("Location path:\t%.*s", coap_header_ptr->options_list_ptr->location_path_len, coap_header_ptr->options_list_ptr->location_path_ptr); 02433 } 02434 02435 if (coap_header_ptr->options_list_ptr->location_query_ptr && coap_header_ptr->options_list_ptr->location_query_len > 0) { 02436 tr_info("Location query:\t%.*s", coap_header_ptr->options_list_ptr->location_query_len, coap_header_ptr->options_list_ptr->location_query_ptr); 02437 } 02438 02439 if (coap_header_ptr->options_list_ptr->uri_query_ptr && coap_header_ptr->options_list_ptr->uri_query_len > 0) { 02440 tr_info("Uri query:\t%.*s", coap_header_ptr->options_list_ptr->uri_query_len, coap_header_ptr->options_list_ptr->uri_query_ptr); 02441 } 02442 02443 tr_info("Max-age:\t\t%" PRIu32"", coap_header_ptr->options_list_ptr->max_age); 02444 if (coap_header_ptr->options_list_ptr->use_size1) { 02445 tr_info("Size 1:\t\t%" PRIu32"", coap_header_ptr->options_list_ptr->size1); 02446 } 02447 if (coap_header_ptr->options_list_ptr->use_size2) { 02448 tr_info("Size 2:\t\t%" PRIu32"", coap_header_ptr->options_list_ptr->size2); 02449 } 02450 if (coap_header_ptr->options_list_ptr->accept != -1) { 02451 tr_info("Accept:\t\t%d", coap_header_ptr->options_list_ptr->accept); 02452 } 02453 if (coap_header_ptr->options_list_ptr->uri_port != -1) { 02454 tr_info("Uri port:\t%" PRId32"", coap_header_ptr->options_list_ptr->uri_port); 02455 } 02456 if (coap_header_ptr->options_list_ptr->observe != -1) { 02457 tr_info("Observe:\t\t%" PRId32"", coap_header_ptr->options_list_ptr->observe); 02458 } 02459 if (coap_header_ptr->options_list_ptr->block1 != -1) { 02460 tr_info("Block1 number:\t%" PRId32"", coap_header_ptr->options_list_ptr->block1 >> 4); 02461 uint8_t temp = (coap_header_ptr->options_list_ptr->block1 & 0x07); 02462 uint16_t block_size = 1u << (temp + 4); 02463 tr_info("Block1 size:\t%d", block_size); 02464 tr_info("Block1 more:\t%d", (coap_header_ptr->options_list_ptr->block1) & 0x08 ? true : false); 02465 } 02466 if (coap_header_ptr->options_list_ptr->block2 != -1) { 02467 tr_info("Block2 number:\t%" PRId32"", coap_header_ptr->options_list_ptr->block2 >> 4); 02468 uint8_t temp = (coap_header_ptr->options_list_ptr->block2 & 0x07); 02469 uint16_t block_size = 1u << (temp + 4); 02470 tr_info("Block2 size:\t%d", block_size); 02471 tr_info("Block2 more:\t%d", (coap_header_ptr->options_list_ptr->block2) & 0x08 ? true : false); 02472 } 02473 } 02474 tr_info("======== End of CoAP package ========"); 02475 #else 02476 (void) coap_header_ptr; 02477 (void) outgoing; 02478 #endif 02479 } 02480 02481 #if MBED_CONF_MBED_TRACE_ENABLE 02482 const char *sn_nsdl_coap_status_description(sn_coap_status_e status) 02483 { 02484 switch(status) { 02485 case COAP_STATUS_OK: 02486 return "COAP_STATUS_OK"; 02487 case COAP_STATUS_PARSER_ERROR_IN_HEADER: 02488 return "COAP_STATUS_PARSER_ERROR_IN_HEADER"; 02489 case COAP_STATUS_PARSER_DUPLICATED_MSG: 02490 return "COAP_STATUS_PARSER_DUPLICATED_MSG"; 02491 case COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVING: 02492 return "COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVING"; 02493 case COAP_STATUS_PARSER_BLOCKWISE_ACK: 02494 return "COAP_STATUS_PARSER_BLOCKWISE_ACK"; 02495 case COAP_STATUS_PARSER_BLOCKWISE_MSG_REJECTED: 02496 return "COAP_STATUS_PARSER_BLOCKWISE_MSG_REJECTED"; 02497 case COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED: 02498 return "COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED"; 02499 case COAP_STATUS_BUILDER_MESSAGE_SENDING_FAILED: 02500 return "COAP_STATUS_BUILDER_MESSAGE_SENDING_FAILED"; 02501 default: 02502 return ""; 02503 } 02504 } 02505 02506 const char *sn_nsdl_coap_message_code_desc(int msg_code) 02507 { 02508 switch(msg_code) { 02509 case COAP_MSG_CODE_EMPTY: 02510 return "COAP_MSG_CODE_EMPTY"; 02511 case COAP_MSG_CODE_REQUEST_GET: 02512 return "COAP_MSG_CODE_REQUEST_GET"; 02513 case COAP_MSG_CODE_REQUEST_POST: 02514 return "COAP_MSG_CODE_REQUEST_POST"; 02515 case COAP_MSG_CODE_REQUEST_PUT: 02516 return "COAP_MSG_CODE_REQUEST_PUT"; 02517 case COAP_MSG_CODE_REQUEST_DELETE: 02518 return "COAP_MSG_CODE_REQUEST_DELETE"; 02519 case COAP_MSG_CODE_RESPONSE_CREATED: 02520 return "COAP_MSG_CODE_RESPONSE_CREATED"; 02521 case COAP_MSG_CODE_RESPONSE_DELETED: 02522 return "COAP_MSG_CODE_RESPONSE_DELETED"; 02523 case COAP_MSG_CODE_RESPONSE_VALID: 02524 return "COAP_MSG_CODE_RESPONSE_VALID"; 02525 case COAP_MSG_CODE_RESPONSE_CHANGED: 02526 return "COAP_MSG_CODE_RESPONSE_CHANGED"; 02527 case COAP_MSG_CODE_RESPONSE_CONTENT: 02528 return "COAP_MSG_CODE_RESPONSE_CONTENT"; 02529 case COAP_MSG_CODE_RESPONSE_CONTINUE: 02530 return "COAP_MSG_CODE_RESPONSE_CONTINUE"; 02531 case COAP_MSG_CODE_RESPONSE_BAD_REQUEST: 02532 return "COAP_MSG_CODE_RESPONSE_BAD_REQUEST"; 02533 case COAP_MSG_CODE_RESPONSE_UNAUTHORIZED: 02534 return "COAP_MSG_CODE_RESPONSE_UNAUTHORIZED"; 02535 case COAP_MSG_CODE_RESPONSE_BAD_OPTION: 02536 return "COAP_MSG_CODE_RESPONSE_BAD_OPTION"; 02537 case COAP_MSG_CODE_RESPONSE_FORBIDDEN: 02538 return "COAP_MSG_CODE_RESPONSE_FORBIDDEN"; 02539 case COAP_MSG_CODE_RESPONSE_NOT_FOUND: 02540 return "COAP_MSG_CODE_RESPONSE_NOT_FOUND"; 02541 case COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED: 02542 return "COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED"; 02543 case COAP_MSG_CODE_RESPONSE_NOT_ACCEPTABLE: 02544 return "COAP_MSG_CODE_RESPONSE_NOT_ACCEPTABLE"; 02545 case COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_INCOMPLETE: 02546 return "COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_INCOMPLETE"; 02547 case COAP_MSG_CODE_RESPONSE_PRECONDITION_FAILED: 02548 return "COAP_MSG_CODE_RESPONSE_PRECONDITION_FAILED"; 02549 case COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE: 02550 return "COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE"; 02551 case COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT: 02552 return "COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT"; 02553 case COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR: 02554 return "COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR"; 02555 case COAP_MSG_CODE_RESPONSE_NOT_IMPLEMENTED: 02556 return "COAP_MSG_CODE_RESPONSE_NOT_IMPLEMENTED"; 02557 case COAP_MSG_CODE_RESPONSE_BAD_GATEWAY: 02558 return "COAP_MSG_CODE_RESPONSE_BAD_GATEWAY"; 02559 case COAP_MSG_CODE_RESPONSE_SERVICE_UNAVAILABLE: 02560 return "COAP_MSG_CODE_RESPONSE_SERVICE_UNAVAILABLE"; 02561 case COAP_MSG_CODE_RESPONSE_GATEWAY_TIMEOUT: 02562 return "COAP_MSG_CODE_RESPONSE_GATEWAY_TIMEOUT"; 02563 case COAP_MSG_CODE_RESPONSE_PROXYING_NOT_SUPPORTED: 02564 return "COAP_MSG_CODE_RESPONSE_PROXYING_NOT_SUPPORTED"; 02565 default: 02566 return ""; 02567 } 02568 } 02569 02570 const char *sn_nsdl_coap_message_type_desc(int msg_type) 02571 { 02572 switch(msg_type) { 02573 case COAP_MSG_TYPE_CONFIRMABLE: 02574 return "COAP_MSG_TYPE_CONFIRMABLE"; 02575 case COAP_MSG_TYPE_NON_CONFIRMABLE: 02576 return "COAP_MSG_TYPE_NON_CONFIRMABLE"; 02577 case COAP_MSG_TYPE_ACKNOWLEDGEMENT: 02578 return "COAP_MSG_TYPE_ACKNOWLEDGEMENT"; 02579 case COAP_MSG_TYPE_RESET: 02580 return "COAP_MSG_TYPE_RESET"; 02581 default: 02582 return ""; 02583 } 02584 } 02585 #endif 02586 02587 void remove_previous_block_data(struct nsdl_s *handle, sn_nsdl_addr_s *src_ptr, const uint32_t block_number) 02588 { 02589 #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE 02590 ns_list_foreach(coap_blockwise_payload_s, stored_payload_info_ptr, &handle->grs->coap->linked_list_blockwise_received_payloads) { 02591 uint32_t stored_number = stored_payload_info_ptr->block_number; 02592 // Remove the previous block data 02593 if (block_number - 1 == stored_number) { 02594 sn_coap_protocol_block_remove(handle->grs->coap, 02595 src_ptr, 02596 stored_payload_info_ptr->payload_len, 02597 stored_payload_info_ptr->payload_ptr); 02598 break; 02599 } 02600 } 02601 #endif 02602 } 02603 02604 bool update_last_block_data(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr, bool block1) 02605 { 02606 bool data_updated = false; 02607 // Whole message received --> pass only the last block data to application 02608 if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED) { 02609 // Get the block size 02610 uint8_t temp = 0; 02611 if (block1) { 02612 temp = (coap_packet_ptr->options_list_ptr->block1 & 0x07); 02613 } else { 02614 temp = (coap_packet_ptr->options_list_ptr->block2 & 0x07); 02615 } 02616 uint16_t block_size = 1u << (temp + 4); 02617 02618 uint32_t new_payload_len = coap_packet_ptr->payload_len - block_size; 02619 uint8_t *temp_ptr = handle->grs->coap->sn_coap_protocol_malloc(new_payload_len); 02620 if (temp_ptr) { 02621 // Skip the second last block data since it's still stored in mbed-coap list! 02622 memcpy(temp_ptr, coap_packet_ptr->payload_ptr + block_size, new_payload_len); 02623 handle->grs->coap->sn_coap_protocol_free(coap_packet_ptr->payload_ptr); 02624 coap_packet_ptr->payload_ptr = temp_ptr; 02625 coap_packet_ptr->payload_len = new_payload_len; 02626 data_updated = true; 02627 } 02628 } 02629 02630 return data_updated; 02631 } 02632 02633 static void sn_nsdl_add_token(struct nsdl_s *handle, uint32_t *token, sn_coap_hdr_s *message_ptr) 02634 { 02635 handle->token_seed++; 02636 if (handle->token_seed == 0) { 02637 handle->token_seed++; 02638 } 02639 02640 *token = handle->token_seed; 02641 02642 message_ptr->token_ptr = (uint8_t*)token; 02643 message_ptr->token_len = sizeof(*token); 02644 } 02645 02646 uint16_t sn_nsdl_get_block_size(const struct nsdl_s *handle) 02647 { 02648 if (handle == NULL) { 02649 return 0; 02650 } 02651 02652 return handle->grs->coap->sn_coap_block_data_size; 02653 } 02654 02655 extern uint8_t sn_nsdl_get_retransmission_count(struct nsdl_s *handle) 02656 { 02657 #if ENABLE_RESENDINGS 02658 if (handle == NULL) { 02659 return 0; 02660 } 02661 02662 return handle->grs->coap->sn_coap_resending_count; 02663 #else 02664 (void) handle; 02665 return 0; 02666 #endif 02667 } 02668 02669 int32_t sn_nsdl_send_coap_ping(struct nsdl_s *handle) 02670 { 02671 assert(handle); 02672 assert(handle->grs); 02673 02674 sn_coap_hdr_s coap_ping = {0}; 02675 int32_t return_msg_id = 0; 02676 02677 /* Fill header */ 02678 coap_ping.msg_type = COAP_MSG_TYPE_CONFIRMABLE; 02679 coap_ping.msg_code = COAP_MSG_CODE_EMPTY; 02680 coap_ping.content_format = COAP_CT_NONE; 02681 02682 /* Send message */ 02683 return_msg_id = sn_nsdl_send_coap_message(handle, &handle->server_address, &coap_ping); 02684 if (return_msg_id >= SN_NSDL_SUCCESS) { 02685 return_msg_id = coap_ping.msg_id; 02686 } 02687 02688 return return_msg_id; 02689 }
Generated on Tue Jul 12 2022 20:21:03 by
