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