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