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