Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510
sn_nsdl2.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_nsdl2.c 00018 * 00019 * \brief Nano service device library 00020 * 00021 */ 00022 #ifdef MBED_CLIENT_C_NEW_API 00023 00024 #include <string.h> 00025 00026 #include "ns_types.h" 00027 #include "sn_nsdl.h" 00028 #include "sn_coap_header.h" 00029 #include "sn_coap_protocol.h" 00030 #include "sn_coap_protocol_internal.h" 00031 #include "sn_nsdl_lib.h" 00032 #include "sn_grs.h" 00033 #include "sn_config.h" 00034 #include "mbed-trace/mbed_trace.h" 00035 00036 #define TRACE_GROUP "coap" 00037 /* Defines */ 00038 #define TRACE_GROUP "coap" 00039 #define RESOURCE_DIR_LEN 2 00040 #define EP_NAME_PARAMETERS_LEN 3 00041 #define ET_PARAMETER_LEN 3 00042 #define LT_PARAMETER_LEN 3 00043 #define DOMAIN_PARAMETER_LEN 2 00044 #define RT_PARAMETER_LEN 3 00045 #define IF_PARAMETER_LEN 3 00046 #define OBS_PARAMETER_LEN 3 00047 #define AOBS_PARAMETER_LEN 8 00048 #define COAP_CON_PARAMETER_LEN 3 00049 #define BS_EP_PARAMETER_LEN 3 00050 #define BS_QUEUE_MODE_PARAMATER_LEN 2 00051 00052 #define SN_NSDL_EP_REGISTER_MESSAGE 1 00053 #define SN_NSDL_EP_UPDATE_MESSAGE 2 00054 00055 #define SN_NSDL_MSG_UNDEFINED 0 00056 #define SN_NSDL_MSG_REGISTER 1 00057 #define SN_NSDL_MSG_UNREGISTER 2 00058 #define SN_NSDL_MSG_UPDATE 3 00059 #define SN_NSDL_MSG_BOOTSTRAP 4 00060 00061 #ifdef YOTTA_CFG_DISABLE_OBS_FEATURE 00062 #define COAP_DISABLE_OBS_FEATURE YOTTA_CFG_DISABLE_OBS_FEATURE 00063 #elif defined MBED_CONF_MBED_CLIENT_COAP_DISABLE_OBS_FEATURE 00064 #define COAP_DISABLE_OBS_FEATURE MBED_CONF_MBED_CLIENT_COAP_DISABLE_OBS_FEATURE 00065 #endif 00066 00067 #ifdef YOTTA_CFG_DISABLE_BOOTSTRAP_FEATURE 00068 #define MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE YOTTA_CFG_DISABLE_BOOTSTRAP_FEATURE 00069 #elif defined MBED_CONF_MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00070 #define MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE MBED_CONF_MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00071 #endif 00072 00073 00074 /* Constants */ 00075 static uint8_t ep_name_parameter_string[] = {'e', 'p', '='}; /* Endpoint name. A unique name for the registering node in a domain. */ 00076 static uint8_t resource_path_ptr[] = {'r', 'd'}; /* For resource directory */ 00077 static uint8_t resource_type_parameter[] = {'r', 't', '='}; /* Resource type. Only once for registration */ 00078 #ifndef COAP_DISABLE_OBS_FEATURE 00079 static uint8_t obs_parameter[] = {'o', 'b', 's'}; /* Observable */ 00080 #endif 00081 static uint8_t if_description_parameter[] = {'i', 'f', '='}; /* Interface description. Only once */ 00082 static uint8_t ep_lifetime_parameter[] = {'l', 't', '='}; /* Lifetime. Number of seconds that this registration will be valid for. Must be updated within this time, or will be removed. */ 00083 static uint8_t ep_domain_parameter[] = {'d', '='}; /* Domain name. If this parameter is missing, a default domain is assumed. */ 00084 static uint8_t coap_con_type_parameter[] = {'c', 't', '='}; /* CoAP content type */ 00085 /* * OMA BS parameters * */ 00086 static uint8_t bs_uri[] = {'b', 's'}; 00087 static uint8_t bs_ep_name[] = {'e', 'p', '='}; 00088 static uint8_t et_parameter[] = {'e', 't', '='}; /* Endpoint type */ 00089 static uint8_t bs_queue_mode[] = {'b', '='}; 00090 00091 /* Function prototypes */ 00092 static uint16_t sn_nsdl_internal_coap_send(struct nsdl_s *handle, sn_coap_hdr_s *coap_header_ptr, sn_nsdl_addr_s *dst_addr_ptr, uint8_t message_description); 00093 static void sn_nsdl_resolve_nsp_address(struct nsdl_s *handle); 00094 int8_t sn_nsdl_build_registration_body(struct nsdl_s *handle, sn_coap_hdr_s *message_ptr, uint8_t updating_registeration); 00095 static uint16_t sn_nsdl_calculate_registration_body_size(struct nsdl_s *handle, uint8_t updating_registeration, int8_t *error); 00096 static uint8_t sn_nsdl_calculate_uri_query_option_len(sn_nsdl_ep_parameters_s *endpoint_info_ptr, uint8_t msg_type); 00097 static int8_t sn_nsdl_fill_uri_query_options(struct nsdl_s *handle, sn_nsdl_ep_parameters_s *parameter_ptr, sn_coap_hdr_s *source_msg_ptr, uint8_t msg_type); 00098 static int8_t sn_nsdl_local_rx_function(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr, sn_nsdl_addr_s *address_ptr); 00099 static int8_t sn_nsdl_resolve_ep_information(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr); 00100 static uint8_t sn_nsdl_itoa_len(uint8_t value); 00101 static uint8_t *sn_nsdl_itoa(uint8_t *ptr, uint8_t value); 00102 static int8_t set_endpoint_info(struct nsdl_s *handle, sn_nsdl_ep_parameters_s *endpoint_info_ptr); 00103 static bool validateParameters(sn_nsdl_ep_parameters_s *parameter_ptr); 00104 static bool validate(uint8_t* ptr, uint32_t len, char illegalChar); 00105 static bool sn_nsdl_check_uint_overflow(uint16_t resource_size, uint16_t param_a, uint16_t param_b); 00106 00107 int8_t sn_nsdl_destroy(struct nsdl_s *handle) 00108 { 00109 if (handle == NULL) { 00110 return SN_NSDL_FAILURE; 00111 } 00112 00113 if (handle->ep_information_ptr) { 00114 if (handle->ep_information_ptr->endpoint_name_ptr) { 00115 handle->sn_nsdl_free(handle->ep_information_ptr->endpoint_name_ptr); 00116 handle->ep_information_ptr->endpoint_name_ptr = 0; 00117 } 00118 if (handle->ep_information_ptr->domain_name_ptr) { 00119 handle->sn_nsdl_free(handle->ep_information_ptr->domain_name_ptr); 00120 handle->ep_information_ptr->domain_name_ptr = 0; 00121 handle->ep_information_ptr->domain_name_len = 0; 00122 } 00123 if (handle->ep_information_ptr->location_ptr) { 00124 handle->sn_nsdl_free(handle->ep_information_ptr->location_ptr); 00125 handle->ep_information_ptr->location_ptr = 0; 00126 handle->ep_information_ptr->location_len = 0; 00127 } 00128 if (handle->ep_information_ptr->type_ptr) { 00129 handle->sn_nsdl_free(handle->ep_information_ptr->type_ptr); 00130 handle->ep_information_ptr->type_ptr = 0; 00131 } 00132 00133 if (handle->ep_information_ptr->lifetime_ptr) 00134 00135 { 00136 handle->sn_nsdl_free(handle->ep_information_ptr->lifetime_ptr); 00137 handle->ep_information_ptr->lifetime_ptr = 0; 00138 } 00139 00140 handle->sn_nsdl_free(handle->ep_information_ptr); 00141 handle->ep_information_ptr = 0; 00142 } 00143 00144 if (handle->nsp_address_ptr) { 00145 if (handle->nsp_address_ptr->omalw_address_ptr) { 00146 if (handle->nsp_address_ptr->omalw_address_ptr->addr_ptr) { 00147 handle->sn_nsdl_free(handle->nsp_address_ptr->omalw_address_ptr->addr_ptr); 00148 handle->nsp_address_ptr->omalw_address_ptr->addr_ptr = 0; 00149 } 00150 handle->sn_nsdl_free(handle->nsp_address_ptr->omalw_address_ptr); 00151 } 00152 00153 handle->sn_nsdl_free(handle->nsp_address_ptr); 00154 handle->nsp_address_ptr = 0; 00155 } 00156 00157 if (handle->oma_bs_address_ptr) { 00158 handle->sn_nsdl_free(handle->oma_bs_address_ptr); 00159 } 00160 00161 /* Destroy also libCoap and grs part of libNsdl */ 00162 sn_coap_protocol_destroy(handle->grs->coap); 00163 sn_grs_destroy(handle->grs); 00164 handle->sn_nsdl_free(handle); 00165 00166 return SN_NSDL_SUCCESS; 00167 } 00168 00169 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 *), 00170 uint8_t (*sn_nsdl_rx_cb)(struct nsdl_s *, sn_coap_hdr_s *, sn_nsdl_addr_s *), 00171 void *(*sn_nsdl_alloc)(uint16_t), void (*sn_nsdl_free)(void *)) 00172 { 00173 /* Check pointers and define function pointers */ 00174 if (!sn_nsdl_alloc || !sn_nsdl_free || !sn_nsdl_tx_cb || !sn_nsdl_rx_cb) { 00175 return NULL; 00176 } 00177 00178 struct nsdl_s *handle = NULL; 00179 00180 handle = sn_nsdl_alloc(sizeof(struct nsdl_s)); 00181 00182 if (handle == NULL) { 00183 return NULL; 00184 } 00185 00186 memset(handle, 0, sizeof(struct nsdl_s)); 00187 00188 /* Define function pointers */ 00189 handle->sn_nsdl_alloc = sn_nsdl_alloc; 00190 handle->sn_nsdl_free = sn_nsdl_free; 00191 00192 handle->sn_nsdl_tx_callback = sn_nsdl_tx_cb; 00193 handle->sn_nsdl_rx_callback = sn_nsdl_rx_cb; 00194 00195 /* Initialize ep parameters struct */ 00196 if (!handle->ep_information_ptr) { 00197 handle->ep_information_ptr = handle->sn_nsdl_alloc(sizeof(sn_nsdl_ep_parameters_s)); 00198 if (!handle->ep_information_ptr) { 00199 sn_nsdl_free(handle); 00200 return NULL; 00201 } 00202 memset(handle->ep_information_ptr, 0, sizeof(sn_nsdl_ep_parameters_s)); 00203 } 00204 00205 handle->grs = sn_grs_init(sn_nsdl_tx_cb, &sn_nsdl_local_rx_function, sn_nsdl_alloc, sn_nsdl_free); 00206 00207 /* Initialize GRS */ 00208 if (handle->grs == NULL) { 00209 handle->sn_nsdl_free(handle->ep_information_ptr); 00210 handle->ep_information_ptr = 0; 00211 sn_nsdl_free(handle); 00212 return NULL; 00213 } 00214 00215 sn_nsdl_resolve_nsp_address(handle); 00216 00217 handle->sn_nsdl_endpoint_registered = SN_NSDL_ENDPOINT_NOT_REGISTERED; 00218 handle->context = NULL; 00219 00220 return handle; 00221 } 00222 00223 uint16_t sn_nsdl_register_endpoint(struct nsdl_s *handle, sn_nsdl_ep_parameters_s *endpoint_info_ptr) 00224 { 00225 /* Local variables */ 00226 sn_coap_hdr_s *register_message_ptr; 00227 uint16_t message_id = 0; 00228 00229 if (endpoint_info_ptr == NULL || handle == NULL) { 00230 return 0; 00231 } 00232 00233 /*** Build endpoint register message ***/ 00234 00235 /* Allocate memory for header struct */ 00236 register_message_ptr = sn_coap_parser_alloc_message(handle->grs->coap); 00237 if (register_message_ptr == NULL) { 00238 return 0; 00239 } 00240 00241 /* Fill message fields -> confirmable post to specified NSP path */ 00242 register_message_ptr->msg_type = COAP_MSG_TYPE_CONFIRMABLE; 00243 register_message_ptr->msg_code = COAP_MSG_CODE_REQUEST_POST; 00244 00245 /* Allocate memory for the extended options list */ 00246 if (sn_coap_parser_alloc_options(handle->grs->coap, register_message_ptr) == NULL) { 00247 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr); 00248 register_message_ptr = 0; 00249 return 0; 00250 } 00251 00252 register_message_ptr->uri_path_len = sizeof(resource_path_ptr); 00253 register_message_ptr->uri_path_ptr = resource_path_ptr; 00254 00255 /* Fill Uri-query options */ 00256 if( SN_NSDL_FAILURE == sn_nsdl_fill_uri_query_options(handle, endpoint_info_ptr, 00257 register_message_ptr, SN_NSDL_EP_REGISTER_MESSAGE) ){ 00258 register_message_ptr->uri_path_ptr = NULL; 00259 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr); 00260 return 0; 00261 } 00262 00263 if (endpoint_info_ptr->ds_register_mode == REGISTER_WITH_RESOURCES) { 00264 /* Built body for message */ 00265 if (sn_nsdl_build_registration_body(handle, register_message_ptr, 0) == SN_NSDL_FAILURE) { 00266 register_message_ptr->uri_path_ptr = NULL; 00267 register_message_ptr->options_list_ptr->uri_host_ptr = NULL; 00268 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr); 00269 return 0; 00270 } 00271 } 00272 00273 /* Clean (possible) existing and save new endpoint info to handle */ 00274 if (set_endpoint_info(handle, endpoint_info_ptr) == -1) { 00275 if (register_message_ptr->payload_ptr) { 00276 handle->sn_nsdl_free(register_message_ptr->payload_ptr); 00277 register_message_ptr->payload_ptr = NULL; 00278 } 00279 00280 register_message_ptr->uri_path_ptr = NULL; 00281 register_message_ptr->options_list_ptr->uri_host_ptr = NULL; 00282 00283 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr); 00284 00285 return 0; 00286 } 00287 00288 /* Build and send coap message to NSP */ 00289 message_id = sn_nsdl_internal_coap_send(handle, register_message_ptr, handle->nsp_address_ptr->omalw_address_ptr, SN_NSDL_MSG_REGISTER); 00290 00291 if (register_message_ptr->payload_ptr) { 00292 handle->sn_nsdl_free(register_message_ptr->payload_ptr); 00293 register_message_ptr->payload_ptr = NULL; 00294 } 00295 00296 register_message_ptr->uri_path_ptr = NULL; 00297 register_message_ptr->options_list_ptr->uri_host_ptr = NULL; 00298 00299 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr); 00300 00301 return message_id; 00302 } 00303 00304 uint16_t sn_nsdl_unregister_endpoint(struct nsdl_s *handle) 00305 { 00306 /* Local variables */ 00307 sn_coap_hdr_s *unregister_message_ptr; 00308 uint8_t *temp_ptr = 0; 00309 uint16_t message_id = 0; 00310 00311 /* Check parameters */ 00312 if (handle == NULL) { 00313 return 0; 00314 } 00315 00316 /* Check that EP have been registered */ 00317 if (sn_nsdl_is_ep_registered(handle)) { 00318 00319 /* Memory allocation for unregister message */ 00320 unregister_message_ptr = sn_coap_parser_alloc_message(handle->grs->coap); 00321 if (!unregister_message_ptr) { 00322 return 0; 00323 } 00324 00325 /* Fill unregister message */ 00326 unregister_message_ptr->msg_type = COAP_MSG_TYPE_CONFIRMABLE; 00327 unregister_message_ptr->msg_code = COAP_MSG_CODE_REQUEST_DELETE; 00328 00329 if(handle->ep_information_ptr->location_ptr) { 00330 unregister_message_ptr->uri_path_len = handle->ep_information_ptr->location_len; 00331 unregister_message_ptr->uri_path_ptr = handle->sn_nsdl_alloc(unregister_message_ptr->uri_path_len); 00332 if (!unregister_message_ptr->uri_path_ptr) { 00333 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, unregister_message_ptr); 00334 return 0; 00335 } 00336 00337 temp_ptr = unregister_message_ptr->uri_path_ptr; 00338 00339 memcpy(temp_ptr , handle->ep_information_ptr->location_ptr, handle->ep_information_ptr->location_len); 00340 } else { 00341 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); 00342 unregister_message_ptr->uri_path_ptr = handle->sn_nsdl_alloc(unregister_message_ptr->uri_path_len); 00343 if (!unregister_message_ptr->uri_path_ptr) { 00344 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, unregister_message_ptr); 00345 return 0; 00346 } 00347 00348 temp_ptr = unregister_message_ptr->uri_path_ptr; 00349 00350 memcpy(temp_ptr, resource_path_ptr, RESOURCE_DIR_LEN); 00351 temp_ptr += RESOURCE_DIR_LEN; 00352 00353 *temp_ptr++ = '/'; 00354 00355 memcpy(temp_ptr , handle->ep_information_ptr->domain_name_ptr, handle->ep_information_ptr->domain_name_len); 00356 temp_ptr += handle->ep_information_ptr->domain_name_len; 00357 00358 *temp_ptr++ = '/'; 00359 00360 memcpy(temp_ptr , handle->ep_information_ptr->endpoint_name_ptr, handle->ep_information_ptr->endpoint_name_len); 00361 } 00362 00363 /* Send message */ 00364 message_id = sn_nsdl_internal_coap_send(handle, unregister_message_ptr, handle->nsp_address_ptr->omalw_address_ptr, SN_NSDL_MSG_UNREGISTER); 00365 00366 /* Free memory */ 00367 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, unregister_message_ptr); 00368 00369 } 00370 00371 return message_id; 00372 } 00373 00374 uint16_t sn_nsdl_update_registration(struct nsdl_s *handle, uint8_t *lt_ptr, uint8_t lt_len) 00375 { 00376 /* Local variables */ 00377 sn_coap_hdr_s *register_message_ptr; 00378 uint8_t *temp_ptr; 00379 sn_nsdl_ep_parameters_s temp_parameters; 00380 uint16_t message_id = 0; 00381 00382 /* Check parameters */ 00383 if (handle == NULL) { 00384 return 0; 00385 } 00386 00387 if (!sn_nsdl_is_ep_registered(handle)){ 00388 return 0; 00389 } 00390 00391 memset(&temp_parameters, 0, sizeof(sn_nsdl_ep_parameters_s)); 00392 00393 temp_parameters.lifetime_len = lt_len; 00394 temp_parameters.lifetime_ptr = lt_ptr; 00395 00396 /*** Build endpoint register update message ***/ 00397 00398 /* Allocate memory for header struct */ 00399 register_message_ptr = sn_coap_parser_alloc_message(handle->grs->coap); 00400 if (register_message_ptr == NULL) { 00401 return 0; 00402 } 00403 00404 /* Fill message fields -> confirmable post to specified NSP path */ 00405 register_message_ptr->msg_type = COAP_MSG_TYPE_CONFIRMABLE; 00406 register_message_ptr->msg_code = COAP_MSG_CODE_REQUEST_POST; 00407 00408 if(handle->ep_information_ptr->location_ptr) { 00409 register_message_ptr->uri_path_len = handle->ep_information_ptr->location_len; /* = Only location set by Device Server*/ 00410 00411 register_message_ptr->uri_path_ptr = handle->sn_nsdl_alloc(register_message_ptr->uri_path_len); 00412 if (!register_message_ptr->uri_path_ptr) { 00413 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr); 00414 return 0; 00415 } 00416 00417 temp_ptr = register_message_ptr->uri_path_ptr; 00418 00419 /* location */ 00420 memcpy(temp_ptr, handle->ep_information_ptr->location_ptr, handle->ep_information_ptr->location_len); 00421 } else { 00422 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 */ 00423 00424 register_message_ptr->uri_path_ptr = handle->sn_nsdl_alloc(register_message_ptr->uri_path_len); 00425 if (!register_message_ptr->uri_path_ptr) { 00426 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr); 00427 return 0; 00428 } 00429 00430 temp_ptr = register_message_ptr->uri_path_ptr; 00431 00432 /* rd/ */ 00433 memcpy(temp_ptr, resource_path_ptr, sizeof(resource_path_ptr)); 00434 temp_ptr += sizeof(resource_path_ptr); 00435 *temp_ptr++ = '/'; 00436 00437 /* rd/DOMAIN/ */ 00438 memcpy(temp_ptr, handle->ep_information_ptr->domain_name_ptr, handle->ep_information_ptr->domain_name_len); 00439 temp_ptr += handle->ep_information_ptr->domain_name_len; 00440 *temp_ptr++ = '/'; 00441 00442 /* rd/domain/ENDPOINT */ 00443 memcpy(temp_ptr, handle->ep_information_ptr->endpoint_name_ptr, handle->ep_information_ptr->endpoint_name_len); 00444 } 00445 00446 /* Allocate memory for the extended options list */ 00447 if (sn_coap_parser_alloc_options(handle->grs->coap, register_message_ptr) == NULL) { 00448 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr); 00449 return 0; 00450 } 00451 00452 /* Fill Uri-query options */ 00453 sn_nsdl_fill_uri_query_options(handle, &temp_parameters, register_message_ptr, SN_NSDL_EP_UPDATE_MESSAGE); 00454 00455 /* Build payload */ 00456 if (handle->ep_information_ptr->ds_register_mode == REGISTER_WITH_RESOURCES) { 00457 00458 if (sn_nsdl_build_registration_body(handle, register_message_ptr, 1) == SN_NSDL_FAILURE) { 00459 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr); 00460 return 0; 00461 } 00462 } 00463 00464 /* Build and send coap message to NSP */ 00465 message_id = sn_nsdl_internal_coap_send(handle, register_message_ptr, handle->nsp_address_ptr->omalw_address_ptr, SN_NSDL_MSG_UPDATE); 00466 00467 if (register_message_ptr->payload_ptr) { 00468 handle->sn_nsdl_free(register_message_ptr->payload_ptr); 00469 } 00470 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr); 00471 00472 return message_id; 00473 } 00474 00475 int8_t sn_nsdl_set_endpoint_location(struct nsdl_s *handle, uint8_t *location_ptr, uint8_t location_len) 00476 { 00477 if(!handle || !location_ptr || (location_len == 0)) { 00478 return -1; 00479 } 00480 00481 handle->sn_nsdl_free(handle->ep_information_ptr->location_ptr); 00482 handle->ep_information_ptr->location_ptr = handle->sn_nsdl_alloc(location_len); 00483 memcpy(handle->ep_information_ptr->location_ptr, location_ptr, location_len); 00484 handle->ep_information_ptr->location_len = location_len; 00485 00486 return 0; 00487 } 00488 00489 void sn_nsdl_nsp_lost(struct nsdl_s *handle) 00490 { 00491 /* Check parameters */ 00492 if (handle == NULL) { 00493 return; 00494 } 00495 00496 handle->sn_nsdl_endpoint_registered = SN_NSDL_ENDPOINT_NOT_REGISTERED; 00497 } 00498 00499 int8_t sn_nsdl_is_ep_registered(struct nsdl_s *handle) 00500 { 00501 /* Check parameters */ 00502 if (handle == NULL) { 00503 return SN_NSDL_FAILURE; 00504 } 00505 00506 return handle->sn_nsdl_endpoint_registered; 00507 } 00508 00509 uint16_t sn_nsdl_send_observation_notification(struct nsdl_s *handle, uint8_t *token_ptr, uint8_t token_len, 00510 uint8_t *payload_ptr, uint16_t payload_len, sn_coap_observe_e observe, sn_coap_msg_type_e message_type, 00511 sn_coap_content_format_e content_format) 00512 { 00513 sn_coap_hdr_s *notification_message_ptr; 00514 uint16_t return_msg_id = 0; 00515 00516 /* Check parameters */ 00517 if (handle == NULL || handle->grs == NULL) { 00518 return 0; 00519 } 00520 00521 /* Allocate and initialize memory for header struct */ 00522 notification_message_ptr = sn_coap_parser_alloc_message(handle->grs->coap); 00523 if (notification_message_ptr == NULL) { 00524 return 0; 00525 } 00526 00527 if (sn_coap_parser_alloc_options(handle->grs->coap, notification_message_ptr) == NULL) { 00528 handle->sn_nsdl_free(notification_message_ptr); 00529 return 0; 00530 } 00531 00532 /* Fill header */ 00533 notification_message_ptr->msg_type = message_type; 00534 notification_message_ptr->msg_code = COAP_MSG_CODE_RESPONSE_CONTENT; 00535 00536 /* Fill token */ 00537 notification_message_ptr->token_len = token_len; 00538 notification_message_ptr->token_ptr = token_ptr; 00539 00540 /* Fill payload */ 00541 notification_message_ptr->payload_len = payload_len; 00542 notification_message_ptr->payload_ptr = payload_ptr; 00543 00544 /* Fill observe */ 00545 notification_message_ptr->options_list_ptr->observe = observe; 00546 00547 /* Fill content format */ 00548 notification_message_ptr->content_format = content_format; 00549 00550 /* Send message */ 00551 if (sn_nsdl_send_coap_message(handle, handle->nsp_address_ptr->omalw_address_ptr, notification_message_ptr) == SN_NSDL_FAILURE) { 00552 return_msg_id = 0; 00553 } else { 00554 return_msg_id = notification_message_ptr->msg_id; 00555 } 00556 00557 /* Free memory */ 00558 notification_message_ptr->payload_ptr = NULL; 00559 notification_message_ptr->token_ptr = NULL; 00560 00561 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, notification_message_ptr); 00562 00563 return return_msg_id; 00564 } 00565 00566 00567 /* * * * * * * * * * */ 00568 /* ~ OMA functions ~ */ 00569 /* * * * * * * * * * */ 00570 00571 uint16_t sn_nsdl_oma_bootstrap(struct nsdl_s *handle, sn_nsdl_addr_s *bootstrap_address_ptr, 00572 sn_nsdl_ep_parameters_s *endpoint_info_ptr, 00573 sn_nsdl_bs_ep_info_t *bootstrap_endpoint_info_ptr) 00574 { 00575 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00576 /* Local variables */ 00577 sn_coap_hdr_s bootstrap_coap_header; 00578 uint8_t *uri_query_tmp_ptr; 00579 uint16_t message_id = 0; 00580 00581 /* Check parameters */ 00582 if (!bootstrap_address_ptr || !bootstrap_endpoint_info_ptr || !endpoint_info_ptr || !handle) { 00583 return 0; 00584 } 00585 00586 handle->sn_nsdl_oma_bs_done_cb = bootstrap_endpoint_info_ptr->oma_bs_status_cb; 00587 handle->sn_nsdl_oma_bs_done_cb_handle = bootstrap_endpoint_info_ptr->oma_bs_status_cb_handle; 00588 00589 /* XXX FIX -- Init CoAP header struct */ 00590 sn_coap_parser_init_message(&bootstrap_coap_header); 00591 00592 if (!sn_coap_parser_alloc_options(handle->grs->coap, &bootstrap_coap_header)) { 00593 return 0; 00594 } 00595 00596 /* Build bootstrap start message */ 00597 bootstrap_coap_header.msg_code = COAP_MSG_CODE_REQUEST_POST; 00598 bootstrap_coap_header.msg_type = COAP_MSG_TYPE_CONFIRMABLE; 00599 00600 bootstrap_coap_header.uri_path_ptr = bs_uri; 00601 bootstrap_coap_header.uri_path_len = sizeof(bs_uri); 00602 00603 uri_query_tmp_ptr = handle->sn_nsdl_alloc(endpoint_info_ptr->endpoint_name_len + BS_EP_PARAMETER_LEN); 00604 if (!uri_query_tmp_ptr) { 00605 handle->sn_nsdl_free(bootstrap_coap_header.options_list_ptr); 00606 return 0; 00607 } 00608 00609 memcpy(uri_query_tmp_ptr, bs_ep_name, BS_EP_PARAMETER_LEN); 00610 memcpy((uri_query_tmp_ptr + BS_EP_PARAMETER_LEN), endpoint_info_ptr->endpoint_name_ptr, endpoint_info_ptr->endpoint_name_len); 00611 00612 bootstrap_coap_header.options_list_ptr->uri_query_len = endpoint_info_ptr->endpoint_name_len + BS_EP_PARAMETER_LEN; 00613 bootstrap_coap_header.options_list_ptr->uri_query_ptr = uri_query_tmp_ptr; 00614 00615 /* Save bootstrap server address */ 00616 handle->oma_bs_address_len = bootstrap_address_ptr->addr_len; /* Length.. */ 00617 handle->oma_bs_address_ptr = handle->sn_nsdl_alloc(handle->oma_bs_address_len); /* Address.. */ 00618 if (!handle->oma_bs_address_ptr) { 00619 handle->sn_nsdl_free(bootstrap_coap_header.options_list_ptr); 00620 handle->sn_nsdl_free(uri_query_tmp_ptr); 00621 return 0; 00622 } 00623 memcpy(handle->oma_bs_address_ptr, bootstrap_address_ptr->addr_ptr, handle->oma_bs_address_len); 00624 handle->oma_bs_port = bootstrap_address_ptr->port; /* And port */ 00625 00626 /* Send message */ 00627 message_id = sn_nsdl_internal_coap_send(handle, &bootstrap_coap_header, bootstrap_address_ptr, SN_NSDL_MSG_BOOTSTRAP); 00628 00629 /* Free allocated memory */ 00630 handle->sn_nsdl_free(uri_query_tmp_ptr); 00631 handle->sn_nsdl_free(bootstrap_coap_header.options_list_ptr); 00632 00633 return message_id; 00634 #else 00635 return 0; 00636 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00637 00638 } 00639 00640 char *sn_nsdl_get_version(void) 00641 { 00642 #if defined(YOTTA_MBED_CLIENT_C_VERSION_STRING) 00643 return YOTTA_MBED_CLIENT_C_VERSION_STRING; 00644 #elif defined(VERSION) 00645 return VERSION; 00646 #else 00647 return "0.0.0"; 00648 #endif 00649 } 00650 00651 int8_t sn_nsdl_process_coap(struct nsdl_s *handle, uint8_t *packet_ptr, uint16_t packet_len, sn_nsdl_addr_s *src_ptr) 00652 { 00653 sn_coap_hdr_s *coap_packet_ptr = NULL; 00654 sn_coap_hdr_s *coap_response_ptr = NULL; 00655 sn_nsdl_dynamic_resource_parameters_s *resource = NULL; 00656 /* Check parameters */ 00657 if (handle == NULL) { 00658 return SN_NSDL_FAILURE; 00659 } 00660 00661 /* Parse CoAP packet */ 00662 coap_packet_ptr = sn_coap_protocol_parse(handle->grs->coap, src_ptr, packet_len, packet_ptr, (void *)handle); 00663 00664 /* Check if parsing was successfull */ 00665 if (coap_packet_ptr == (sn_coap_hdr_s *)NULL) { 00666 return SN_NSDL_FAILURE; 00667 } 00668 #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE 00669 // Pass block to application if external_memory_block is set 00670 if(coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVING) { 00671 resource = sn_nsdl_get_resource(handle, coap_packet_ptr->uri_path_len, coap_packet_ptr->uri_path_ptr); 00672 if(resource && resource->static_resource_parameters->external_memory_block) { 00673 sn_coap_protocol_block_remove(handle->grs->coap, 00674 src_ptr, 00675 coap_packet_ptr->payload_len, 00676 coap_packet_ptr->payload_ptr); 00677 } else { 00678 resource = NULL; 00679 } 00680 } 00681 #endif 00682 /* Check, if coap itself sends response, or block receiving is ongoing... */ 00683 if (coap_packet_ptr->coap_status != COAP_STATUS_OK && 00684 coap_packet_ptr->coap_status != COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED &&coap_packet_ptr && 00685 !resource) { 00686 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr); 00687 return SN_NSDL_SUCCESS; 00688 } 00689 00690 /* If proxy options added, return not supported */ 00691 if (coap_packet_ptr->options_list_ptr) { 00692 if (coap_packet_ptr->options_list_ptr->proxy_uri_len) { 00693 coap_response_ptr = sn_coap_build_response(handle->grs->coap, coap_packet_ptr, COAP_MSG_CODE_RESPONSE_PROXYING_NOT_SUPPORTED); 00694 if (coap_response_ptr) { 00695 sn_nsdl_send_coap_message(handle, src_ptr, coap_response_ptr); 00696 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_response_ptr); 00697 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr); 00698 return SN_NSDL_SUCCESS; 00699 } else { 00700 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr); 00701 return SN_NSDL_FAILURE; 00702 } 00703 } 00704 } 00705 00706 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 00707 /* If message is response message, call RX callback */ 00708 /* * * * * * * * * * * * * * * * * * * * * * * * * * */ 00709 00710 if ((coap_packet_ptr->msg_code > COAP_MSG_CODE_REQUEST_DELETE) || 00711 (coap_packet_ptr->msg_type >= COAP_MSG_TYPE_ACKNOWLEDGEMENT)) { 00712 int8_t retval = sn_nsdl_local_rx_function(handle, coap_packet_ptr, src_ptr); 00713 if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && 00714 coap_packet_ptr->payload_ptr) { 00715 handle->sn_nsdl_free(coap_packet_ptr->payload_ptr); 00716 coap_packet_ptr->payload_ptr = 0; 00717 } 00718 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr); 00719 return retval; 00720 } 00721 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00722 /* * If OMA bootstrap message... * */ 00723 bool bootstrap_msg = src_ptr && (handle->oma_bs_address_len == src_ptr->addr_len) && 00724 (handle->oma_bs_port == src_ptr->port) && 00725 !memcmp(handle->oma_bs_address_ptr, src_ptr->addr_ptr, handle->oma_bs_address_len); 00726 00727 // Pass bootstrap data to application 00728 if (bootstrap_msg) { 00729 handle->sn_nsdl_rx_callback(handle, coap_packet_ptr,src_ptr); 00730 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr); 00731 return SN_NSDL_SUCCESS; 00732 } 00733 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE 00734 00735 /* * * * * * * * * * * * * * * */ 00736 /* Other messages are for GRS */ 00737 /* * * * * * * * * * * * * * * */ 00738 return sn_grs_process_coap(handle, coap_packet_ptr, src_ptr); 00739 } 00740 00741 int8_t sn_nsdl_exec(struct nsdl_s *handle, uint32_t time) 00742 { 00743 if(!handle || !handle->grs){ 00744 return SN_NSDL_FAILURE; 00745 } 00746 /* Call CoAP execution function */ 00747 return sn_coap_protocol_exec(handle->grs->coap, time); 00748 } 00749 00750 sn_nsdl_dynamic_resource_parameters_s *sn_nsdl_get_resource(struct nsdl_s *handle, uint16_t pathlen, uint8_t *path_ptr) 00751 { 00752 /* Check parameters */ 00753 if (handle == NULL) { 00754 return NULL; 00755 } 00756 00757 return sn_grs_search_resource(handle->grs, pathlen, path_ptr, SN_GRS_SEARCH_METHOD); 00758 } 00759 00760 00761 /** 00762 * \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) 00763 * 00764 * 00765 * \brief To send NSDL messages. Stores message id?s and message description to catch response from NSP server 00766 * \param *handle Pointer to nsdl-library handle 00767 * \param *coap_header_ptr Pointer to the CoAP message header to be sent 00768 * \param *dst_addr_ptr Pointer to the address structure that contains destination address information 00769 * \param message_description Message description to be stored to list for waiting response 00770 * 00771 * \return message id, 0 if failed 00772 */ 00773 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) 00774 { 00775 00776 tr_debug("sn_nsdl_internal_coap_send"); 00777 uint8_t *coap_message_ptr = NULL; 00778 int32_t coap_message_len = 0; 00779 uint16_t coap_header_len = 0; 00780 00781 #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwising is not used at all, this part of code will not be compiled */ 00782 int8_t ret_val = prepare_blockwise_message(handle->grs->coap, coap_header_ptr); 00783 if( 0 != ret_val ) { 00784 return 0; 00785 } 00786 #endif 00787 00788 coap_message_len = sn_coap_builder_calc_needed_packet_data_size_2(coap_header_ptr, handle->grs->coap->sn_coap_block_data_size); 00789 tr_debug("sn_nsdl_internal_coap_send - msg len after calc: [%d]", coap_message_len); 00790 if (coap_message_len == 0) { 00791 return 0; 00792 } 00793 00794 coap_message_ptr = handle->sn_nsdl_alloc(coap_message_len); 00795 if (!coap_message_ptr) { 00796 return 0; 00797 } 00798 00799 coap_header_len = coap_header_ptr->payload_len; 00800 /* Build message */ 00801 if (sn_coap_protocol_build(handle->grs->coap, dst_addr_ptr, coap_message_ptr, coap_header_ptr, (void *)handle) < 0) { 00802 handle->sn_nsdl_free(coap_message_ptr); 00803 return 0; 00804 } 00805 00806 /* If mesage type is confirmable, save it to list to wait for reply */ 00807 if (coap_header_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE) { 00808 if (message_description == SN_NSDL_MSG_REGISTER) { 00809 handle->register_msg_id = coap_header_ptr->msg_id; 00810 handle->register_msg_len = coap_header_len; 00811 } 00812 else if (message_description == SN_NSDL_MSG_UNREGISTER) { 00813 handle->unregister_msg_id = coap_header_ptr->msg_id; 00814 } 00815 else if (message_description == SN_NSDL_MSG_UPDATE) { 00816 handle->update_register_msg_id = coap_header_ptr->msg_id; 00817 handle->update_register_msg_len = coap_header_len; 00818 } 00819 else if (message_description == SN_NSDL_MSG_BOOTSTRAP) { 00820 handle->bootstrap_msg_id = coap_header_ptr->msg_id; 00821 } 00822 } 00823 00824 handle->sn_nsdl_tx_callback(handle, SN_NSDL_PROTOCOL_COAP, coap_message_ptr, coap_message_len, dst_addr_ptr); 00825 handle->sn_nsdl_free(coap_message_ptr); 00826 00827 return coap_header_ptr->msg_id; 00828 } 00829 00830 /** 00831 * \fn static void sn_nsdl_resolve_nsp_address(struct nsdl_s *handle) 00832 * 00833 * \brief Resolves NSP server address. 00834 * 00835 * \param *handle Pointer to nsdl-library handle 00836 * \note Application must set NSP address with set_nsp_address 00837 */ 00838 static void sn_nsdl_resolve_nsp_address(struct nsdl_s *handle) 00839 { 00840 /* Local variables */ 00841 if (!handle->nsp_address_ptr) { 00842 //allocate only if previously not allocated 00843 handle->nsp_address_ptr = handle->sn_nsdl_alloc(sizeof(sn_nsdl_oma_server_info_t)); 00844 } 00845 00846 if (handle->nsp_address_ptr) { 00847 handle->nsp_address_ptr->omalw_server_security = SEC_NOT_SET; 00848 handle->nsp_address_ptr->omalw_address_ptr = handle->sn_nsdl_alloc(sizeof(sn_nsdl_addr_s)); 00849 if (handle->nsp_address_ptr->omalw_address_ptr) { 00850 memset(handle->nsp_address_ptr->omalw_address_ptr, 0, sizeof(sn_nsdl_addr_s)); 00851 handle->nsp_address_ptr->omalw_address_ptr->type = SN_NSDL_ADDRESS_TYPE_NONE; 00852 } 00853 } 00854 } 00855 00856 /** 00857 * \fn int8_t sn_nsdl_build_registration_body(struct nsdl_s *handle, sn_coap_hdr_s *message_ptr, uint8_t updating_registeration) 00858 * 00859 * \brief To build GRS resources to registration message payload 00860 * \param *handle Pointer to nsdl-library handle 00861 * \param *message_ptr Pointer to CoAP message header 00862 * 00863 * \return SN_NSDL_SUCCESS = 0, Failed = -1 00864 */ 00865 int8_t sn_nsdl_build_registration_body(struct nsdl_s *handle, sn_coap_hdr_s *message_ptr, uint8_t updating_registeration) 00866 { 00867 tr_debug("sn_nsdl_build_registration_body"); 00868 /* Local variables */ 00869 uint8_t *temp_ptr; 00870 sn_nsdl_dynamic_resource_parameters_s *resource_temp_ptr; 00871 00872 /* Calculate needed memory and allocate */ 00873 int8_t error = 0; 00874 uint16_t msg_len = sn_nsdl_calculate_registration_body_size(handle, updating_registeration, &error); 00875 if (SN_NSDL_FAILURE == error) { 00876 return error; 00877 } 00878 00879 if (!msg_len) { 00880 return SN_NSDL_SUCCESS; 00881 } else { 00882 message_ptr->payload_len = msg_len; 00883 } 00884 tr_debug("sn_nsdl_build_registration_body - body size: [%d]", message_ptr->payload_len); 00885 message_ptr->payload_ptr = handle->sn_nsdl_alloc(message_ptr->payload_len); 00886 if (!message_ptr->payload_ptr) { 00887 return SN_NSDL_FAILURE; 00888 } 00889 00890 /* Build message */ 00891 temp_ptr = message_ptr->payload_ptr; 00892 00893 resource_temp_ptr = sn_grs_get_first_resource(handle->grs); 00894 00895 /* Loop trough all resources */ 00896 while (resource_temp_ptr) { 00897 /* if resource needs to be registered */ 00898 if (resource_temp_ptr->publish_uri) { 00899 if (updating_registeration && resource_temp_ptr->registered == SN_NDSL_RESOURCE_REGISTERED) { 00900 resource_temp_ptr = sn_grs_get_next_resource(handle->grs, resource_temp_ptr); 00901 continue; 00902 } else { 00903 resource_temp_ptr->registered = SN_NDSL_RESOURCE_REGISTERED; 00904 } 00905 00906 /* If not first resource, add '.' to separator */ 00907 if (temp_ptr != message_ptr->payload_ptr) { 00908 *temp_ptr++ = ','; 00909 } 00910 00911 *temp_ptr++ = '<'; 00912 *temp_ptr++ = '/'; 00913 memcpy(temp_ptr, 00914 resource_temp_ptr->static_resource_parameters->path, 00915 resource_temp_ptr->static_resource_parameters->pathlen); 00916 temp_ptr += resource_temp_ptr->static_resource_parameters->pathlen; 00917 *temp_ptr++ = '>'; 00918 00919 /* Resource attributes */ 00920 size_t resource_type_len = 0; 00921 if (resource_temp_ptr->static_resource_parameters->resource_type_ptr) { 00922 resource_type_len = strlen(resource_temp_ptr->static_resource_parameters->resource_type_ptr); 00923 } 00924 if (resource_type_len) { 00925 *temp_ptr++ = ';'; 00926 memcpy(temp_ptr, resource_type_parameter, RT_PARAMETER_LEN); 00927 temp_ptr += RT_PARAMETER_LEN; 00928 *temp_ptr++ = '"'; 00929 memcpy(temp_ptr, 00930 resource_temp_ptr->static_resource_parameters->resource_type_ptr, 00931 resource_type_len); 00932 temp_ptr += resource_type_len; 00933 *temp_ptr++ = '"'; 00934 } 00935 00936 size_t interface_description_len = 0; 00937 if (resource_temp_ptr->static_resource_parameters->interface_description_ptr) { 00938 interface_description_len = strlen(resource_temp_ptr->static_resource_parameters->interface_description_ptr); 00939 } 00940 00941 if (interface_description_len) { 00942 *temp_ptr++ = ';'; 00943 memcpy(temp_ptr, if_description_parameter, IF_PARAMETER_LEN); 00944 temp_ptr += IF_PARAMETER_LEN; 00945 *temp_ptr++ = '"'; 00946 memcpy(temp_ptr, 00947 resource_temp_ptr->static_resource_parameters->interface_description_ptr, 00948 interface_description_len); 00949 temp_ptr += interface_description_len; 00950 *temp_ptr++ = '"'; 00951 } 00952 00953 if (resource_temp_ptr->coap_content_type != 0) { 00954 *temp_ptr++ = ';'; 00955 memcpy(temp_ptr, coap_con_type_parameter, COAP_CON_PARAMETER_LEN); 00956 temp_ptr += COAP_CON_PARAMETER_LEN; 00957 *temp_ptr++ = '"'; 00958 temp_ptr = sn_nsdl_itoa(temp_ptr, 00959 resource_temp_ptr->coap_content_type); 00960 *temp_ptr++ = '"'; 00961 } 00962 00963 /* ;obs */ 00964 // This needs to be re-visited and may be need an API for maganging obs value for different server implementation 00965 #ifndef COAP_DISABLE_OBS_FEATURE 00966 if (resource_temp_ptr->observable) { 00967 *temp_ptr++ = ';'; 00968 memcpy(temp_ptr, obs_parameter, OBS_PARAMETER_LEN); 00969 temp_ptr += OBS_PARAMETER_LEN; 00970 } 00971 #endif 00972 } 00973 resource_temp_ptr = sn_grs_get_next_resource(handle->grs, resource_temp_ptr); 00974 } 00975 return SN_NSDL_SUCCESS; 00976 } 00977 00978 /** 00979 * \fn static uint16_t sn_nsdl_calculate_registration_body_size(struct nsdl_s *handle, uint8_t updating_registeration, int8_t *error) 00980 * 00981 * 00982 * \brief Calculates registration message payload size 00983 * \param *handle Pointer to nsdl-library handle 00984 * \param *updating_registeration Pointer to list of GRS resources 00985 * \param *error Error code, SN_NSDL_SUCCESS or SN_NSDL_FAILURE 00986 * 00987 * \return Needed payload size 00988 */ 00989 static uint16_t sn_nsdl_calculate_registration_body_size(struct nsdl_s *handle, uint8_t updating_registeration, int8_t *error) 00990 { 00991 tr_debug("sn_nsdl_calculate_registration_body_size"); 00992 /* Local variables */ 00993 uint16_t return_value = 0; 00994 *error = SN_NSDL_SUCCESS; 00995 const sn_nsdl_dynamic_resource_parameters_s *resource_temp_ptr; 00996 00997 /* check pointer */ 00998 resource_temp_ptr = sn_grs_get_first_resource(handle->grs); 00999 01000 while (resource_temp_ptr) { 01001 if (resource_temp_ptr->publish_uri) { 01002 if (updating_registeration && resource_temp_ptr->registered == SN_NDSL_RESOURCE_REGISTERED) { 01003 resource_temp_ptr = sn_grs_get_next_resource(handle->grs, resource_temp_ptr); 01004 continue; 01005 } 01006 /* If not first resource, then '.' will be added */ 01007 if (return_value) { 01008 if (sn_nsdl_check_uint_overflow(return_value, 1, 0)) { 01009 return_value++; 01010 } else { 01011 *error = SN_NSDL_FAILURE; 01012 break; 01013 } 01014 } 01015 01016 /* Count length for the resource path </path> */ 01017 if (sn_nsdl_check_uint_overflow(return_value, 01018 3, 01019 resource_temp_ptr->static_resource_parameters->pathlen)) { 01020 return_value += (3 + resource_temp_ptr->static_resource_parameters->pathlen); 01021 } else { 01022 *error = SN_NSDL_FAILURE; 01023 break; 01024 } 01025 01026 /* Count lengths of the attributes */ 01027 01028 /* Resource type parameter */ 01029 size_t resource_type_len = 0; 01030 if (resource_temp_ptr->static_resource_parameters->resource_type_ptr) { 01031 resource_type_len = strlen(resource_temp_ptr->static_resource_parameters->resource_type_ptr); 01032 } 01033 01034 if (resource_type_len) { 01035 /* ;rt="restype" */ 01036 if (sn_nsdl_check_uint_overflow(return_value, 01037 6, 01038 resource_type_len)) { 01039 return_value += (6 + resource_type_len); 01040 } else { 01041 *error = SN_NSDL_FAILURE; 01042 break; 01043 } 01044 } 01045 01046 /* Interface description parameter */ 01047 size_t interface_description_len = 0; 01048 if (resource_temp_ptr->static_resource_parameters->interface_description_ptr) { 01049 interface_description_len = strlen(resource_temp_ptr->static_resource_parameters->interface_description_ptr); 01050 } 01051 if (interface_description_len) { 01052 /* ;if="iftype" */ 01053 if (sn_nsdl_check_uint_overflow(return_value, 01054 6, 01055 interface_description_len)) { 01056 return_value += (6 + interface_description_len); 01057 } else { 01058 *error = SN_NSDL_FAILURE; 01059 break; 01060 } 01061 } 01062 01063 if (resource_temp_ptr->coap_content_type != 0) { 01064 /* ;if="content" */ 01065 uint8_t len = sn_nsdl_itoa_len(resource_temp_ptr->coap_content_type); 01066 if (sn_nsdl_check_uint_overflow(return_value, 6, len)) { 01067 return_value += (6 + len); 01068 } else { 01069 *error = SN_NSDL_FAILURE; 01070 break; 01071 } 01072 } 01073 #ifndef COAP_DISABLE_OBS_FEATURE 01074 // This needs to be re-visited and may be need an API for maganging obs value for different server implementation 01075 if (resource_temp_ptr->observable) { 01076 if (sn_nsdl_check_uint_overflow(return_value, 4, 0)) { 01077 return_value += 4; 01078 } else { 01079 *error = SN_NSDL_FAILURE; 01080 break; 01081 } 01082 } 01083 #endif 01084 } 01085 resource_temp_ptr = sn_grs_get_next_resource(handle->grs, resource_temp_ptr); 01086 } 01087 return return_value; 01088 } 01089 01090 /** 01091 * \fn static uint8_t sn_nsdl_calculate_uri_query_option_len(sn_nsdl_ep_parameters_s *endpoint_info_ptr, uint8_t msg_type) 01092 * 01093 * 01094 * \brief Calculates needed uri query option length 01095 * 01096 * \param *endpoint_info_ptr Pointer to endpoint info structure 01097 * \param msg_type Message type 01098 * 01099 * \return number of parameters in uri query 01100 */ 01101 static uint8_t sn_nsdl_calculate_uri_query_option_len(sn_nsdl_ep_parameters_s *endpoint_info_ptr, uint8_t msg_type) 01102 { 01103 uint8_t return_value = 0; 01104 uint8_t number_of_parameters = 0; 01105 01106 01107 if ((endpoint_info_ptr->endpoint_name_len != 0) && (msg_type == SN_NSDL_EP_REGISTER_MESSAGE) && endpoint_info_ptr->endpoint_name_ptr != 0) { 01108 return_value += endpoint_info_ptr->endpoint_name_len; 01109 return_value += EP_NAME_PARAMETERS_LEN; //ep= 01110 number_of_parameters++; 01111 } 01112 01113 if ((endpoint_info_ptr->type_len != 0) && (msg_type == SN_NSDL_EP_REGISTER_MESSAGE) && (endpoint_info_ptr->type_ptr != 0)) { 01114 return_value += endpoint_info_ptr->type_len; 01115 return_value += ET_PARAMETER_LEN; //et= 01116 number_of_parameters++; 01117 } 01118 01119 if ((endpoint_info_ptr->lifetime_len != 0) && (endpoint_info_ptr->lifetime_ptr != 0)) { 01120 return_value += endpoint_info_ptr->lifetime_len; 01121 return_value += LT_PARAMETER_LEN; //lt= 01122 number_of_parameters++; 01123 } 01124 01125 if ((endpoint_info_ptr->domain_name_len != 0) && (msg_type == SN_NSDL_EP_REGISTER_MESSAGE) && (endpoint_info_ptr->domain_name_ptr != 0)) { 01126 return_value += endpoint_info_ptr->domain_name_len; 01127 return_value += DOMAIN_PARAMETER_LEN; //d= 01128 number_of_parameters++; 01129 } 01130 01131 if (((endpoint_info_ptr->binding_and_mode & 0x04) || (endpoint_info_ptr->binding_and_mode & 0x01)) && (msg_type == SN_NSDL_EP_REGISTER_MESSAGE)) { 01132 return_value += BS_QUEUE_MODE_PARAMATER_LEN; 01133 01134 if (endpoint_info_ptr->binding_and_mode & 0x01) { 01135 return_value++; 01136 } 01137 if (endpoint_info_ptr->binding_and_mode & 0x04) { 01138 return_value++; 01139 } 01140 if ((endpoint_info_ptr->binding_and_mode & 0x02) && ((endpoint_info_ptr->binding_and_mode & 0x04) || (endpoint_info_ptr->binding_and_mode & 0x01))) { 01141 return_value++; 01142 } 01143 01144 number_of_parameters++; 01145 } 01146 01147 if (number_of_parameters != 0) { 01148 return_value += (number_of_parameters - 1); 01149 } 01150 01151 return return_value; 01152 } 01153 01154 /** 01155 * \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) 01156 * 01157 * 01158 * \brief Fills uri-query options to message header struct 01159 * \param *handle Pointer to nsdl-library handle 01160 * \param *parameter_ptr Pointer to endpoint parameters struct 01161 * \param *source_msg_ptr Pointer to CoAP header struct 01162 * \param msg_type Message type 01163 * 01164 * \return SN_NSDL_SUCCESS = 0, Failed = -1 01165 */ 01166 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) 01167 { 01168 uint8_t *temp_ptr = NULL; 01169 if( !validateParameters(parameter_ptr) ){ 01170 return SN_NSDL_FAILURE; 01171 } 01172 source_msg_ptr->options_list_ptr->uri_query_len = sn_nsdl_calculate_uri_query_option_len(parameter_ptr, msg_type); 01173 if (source_msg_ptr->options_list_ptr->uri_query_len == 0) { 01174 return 0; 01175 } 01176 01177 source_msg_ptr->options_list_ptr->uri_query_ptr = handle->sn_nsdl_alloc(source_msg_ptr->options_list_ptr->uri_query_len); 01178 01179 if (source_msg_ptr->options_list_ptr->uri_query_ptr == NULL) { 01180 return SN_NSDL_FAILURE; 01181 } 01182 memset(source_msg_ptr->options_list_ptr->uri_query_ptr,0,source_msg_ptr->options_list_ptr->uri_query_len); 01183 01184 temp_ptr = source_msg_ptr->options_list_ptr->uri_query_ptr; 01185 01186 /******************************************************/ 01187 /* If endpoint name is configured, fill needed fields */ 01188 /******************************************************/ 01189 01190 if ((parameter_ptr->endpoint_name_len != 0) && (parameter_ptr->endpoint_name_ptr != 0) && (msg_type == SN_NSDL_EP_REGISTER_MESSAGE)) { 01191 /* fill endpoint name, first ?ep=, then endpoint name */ 01192 memcpy(temp_ptr, ep_name_parameter_string, sizeof(ep_name_parameter_string)); 01193 temp_ptr += EP_NAME_PARAMETERS_LEN; 01194 memcpy(temp_ptr, parameter_ptr->endpoint_name_ptr, parameter_ptr->endpoint_name_len); 01195 temp_ptr += parameter_ptr->endpoint_name_len; 01196 } 01197 01198 /******************************************************/ 01199 /* If endpoint type is configured, fill needed fields */ 01200 /******************************************************/ 01201 01202 if ((parameter_ptr->type_len != 0) && (parameter_ptr->type_ptr != 0) && (msg_type == SN_NSDL_EP_REGISTER_MESSAGE)) { 01203 if (temp_ptr != source_msg_ptr->options_list_ptr->uri_query_ptr) { 01204 *temp_ptr++ = '&'; 01205 } 01206 01207 memcpy(temp_ptr, et_parameter, sizeof(et_parameter)); 01208 temp_ptr += ET_PARAMETER_LEN; 01209 memcpy(temp_ptr, parameter_ptr->type_ptr, parameter_ptr->type_len); 01210 temp_ptr += parameter_ptr->type_len; 01211 } 01212 01213 01214 /******************************************************/ 01215 /* If lifetime is configured, fill needed fields */ 01216 /******************************************************/ 01217 01218 if ((parameter_ptr->lifetime_len != 0) && (parameter_ptr->lifetime_ptr != 0)) { 01219 if (temp_ptr != source_msg_ptr->options_list_ptr->uri_query_ptr) { 01220 *temp_ptr++ = '&'; 01221 } 01222 01223 memcpy(temp_ptr, ep_lifetime_parameter, sizeof(ep_lifetime_parameter)); 01224 temp_ptr += LT_PARAMETER_LEN; 01225 memcpy(temp_ptr, parameter_ptr->lifetime_ptr, parameter_ptr->lifetime_len); 01226 temp_ptr += parameter_ptr->lifetime_len; 01227 } 01228 01229 /******************************************************/ 01230 /* If domain is configured, fill needed fields */ 01231 /******************************************************/ 01232 01233 if ((parameter_ptr->domain_name_len != 0) && (parameter_ptr->domain_name_ptr != 0) && (msg_type == SN_NSDL_EP_REGISTER_MESSAGE)) { 01234 if (temp_ptr != source_msg_ptr->options_list_ptr->uri_query_ptr) { 01235 *temp_ptr++ = '&'; 01236 } 01237 01238 memcpy(temp_ptr, ep_domain_parameter, sizeof(ep_domain_parameter)); 01239 temp_ptr += DOMAIN_PARAMETER_LEN; 01240 memcpy(temp_ptr, parameter_ptr->domain_name_ptr, parameter_ptr->domain_name_len); 01241 temp_ptr += parameter_ptr->domain_name_len; 01242 } 01243 01244 /******************************************************/ 01245 /* If queue-mode is configured, fill needed fields */ 01246 /******************************************************/ 01247 01248 if (((parameter_ptr->binding_and_mode & 0x01) || (parameter_ptr->binding_and_mode & 0x04)) && (msg_type == SN_NSDL_EP_REGISTER_MESSAGE)) { 01249 if (temp_ptr != source_msg_ptr->options_list_ptr->uri_query_ptr) { 01250 *temp_ptr++ = '&'; 01251 } 01252 01253 memcpy(temp_ptr, bs_queue_mode, sizeof(bs_queue_mode)); 01254 temp_ptr += BS_QUEUE_MODE_PARAMATER_LEN; 01255 01256 if (parameter_ptr->binding_and_mode & 0x01) { 01257 *temp_ptr++ = 'U'; 01258 if (parameter_ptr->binding_and_mode & 0x02) { 01259 *temp_ptr++ = 'Q'; 01260 } 01261 } 01262 01263 if (parameter_ptr->binding_and_mode & 0x04) { 01264 *temp_ptr++ = 'S'; 01265 if ((parameter_ptr->binding_and_mode & 0x02) && !(parameter_ptr->binding_and_mode & 0x01)) { 01266 *temp_ptr++ = 'Q'; 01267 } 01268 } 01269 } 01270 01271 return SN_NSDL_SUCCESS; 01272 } 01273 01274 static bool validateParameters(sn_nsdl_ep_parameters_s *parameter_ptr) 01275 { 01276 if( !validate( parameter_ptr->domain_name_ptr, parameter_ptr->domain_name_len, '&' ) ){ 01277 return false; 01278 } 01279 01280 if( !validate( parameter_ptr->endpoint_name_ptr, parameter_ptr->endpoint_name_len, '&' ) ){ 01281 return false; 01282 } 01283 01284 if( !validate( parameter_ptr->lifetime_ptr, parameter_ptr->lifetime_len, '&' ) ){ 01285 return false; 01286 } 01287 01288 if( !validate( parameter_ptr->type_ptr, parameter_ptr->type_len, '&' ) ){ 01289 return false; 01290 } 01291 return true; 01292 } 01293 01294 static bool validate(uint8_t* ptr, uint32_t len, char illegalChar) 01295 { 01296 if( ptr ){ 01297 for( uint32_t i=0; i < len; i++ ){ 01298 if( ptr[i] == illegalChar ){ 01299 return false; 01300 } 01301 } 01302 } 01303 return true; 01304 } 01305 01306 /** 01307 * \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) 01308 * 01309 * \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. 01310 * \param *handle Pointer to nsdl-library handle 01311 * \param *coap_packet_ptr Pointer to received CoAP packet 01312 * \param *address_ptr Pointer to source address struct 01313 * 01314 * \return SN_NSDL_SUCCESS = 0, Failed = -1 01315 */ 01316 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) 01317 { 01318 if ((coap_packet_ptr == 0) || (address_ptr == 0)) { 01319 return -1; 01320 } 01321 01322 bool is_reg_msg = false; 01323 bool is_update_reg_msg = false; 01324 bool is_unreg_msg = false; 01325 if (coap_packet_ptr->msg_code == COAP_MSG_CODE_RESPONSE_CREATED) { 01326 if (handle->grs->coap->sn_coap_block_data_size > 0) { 01327 handle->register_msg_id += handle->register_msg_len / handle->grs->coap->sn_coap_block_data_size; 01328 } 01329 if (coap_packet_ptr->msg_id == handle->register_msg_id) { 01330 handle->sn_nsdl_endpoint_registered = SN_NSDL_ENDPOINT_IS_REGISTERED; 01331 is_reg_msg = true; 01332 sn_grs_mark_resources_as_registered(handle); 01333 if (sn_nsdl_resolve_ep_information(handle, coap_packet_ptr) != SN_NSDL_SUCCESS) { 01334 return SN_NSDL_FAILURE; 01335 } 01336 } 01337 } 01338 01339 else if (coap_packet_ptr->msg_code == COAP_MSG_CODE_RESPONSE_CHANGED) { 01340 if (handle->grs->coap->sn_coap_block_data_size > 0) { 01341 handle->update_register_msg_id += handle->update_register_msg_len / handle->grs->coap->sn_coap_block_data_size; 01342 } 01343 if (coap_packet_ptr->msg_id == handle->update_register_msg_id) { 01344 is_update_reg_msg = true; 01345 } 01346 } 01347 01348 if (coap_packet_ptr->msg_id == handle->unregister_msg_id) { 01349 is_unreg_msg = true; 01350 if (coap_packet_ptr->msg_code == COAP_MSG_CODE_RESPONSE_DELETED) { 01351 if (handle->ep_information_ptr->endpoint_name_ptr) { 01352 handle->sn_nsdl_free(handle->ep_information_ptr->endpoint_name_ptr); 01353 handle->ep_information_ptr->endpoint_name_ptr = 0; 01354 handle->ep_information_ptr->endpoint_name_len = 0; 01355 } 01356 if (handle->ep_information_ptr->domain_name_ptr) { 01357 handle->sn_nsdl_free(handle->ep_information_ptr->domain_name_ptr); 01358 handle->ep_information_ptr->domain_name_ptr = 0; 01359 handle->ep_information_ptr->domain_name_len = 0; 01360 } 01361 } 01362 } 01363 01364 /* No messages to wait for, or message was not response to our request */ 01365 int ret = handle->sn_nsdl_rx_callback(handle, coap_packet_ptr, address_ptr); 01366 if (is_reg_msg) { 01367 handle->register_msg_id = 0; 01368 handle->register_msg_len = 0; 01369 } 01370 else if (is_unreg_msg) { 01371 handle->unregister_msg_id = 0; 01372 } 01373 else if (is_update_reg_msg) { 01374 handle->update_register_msg_id = 0; 01375 handle->update_register_msg_len = 0; 01376 } 01377 return ret; 01378 } 01379 01380 /** 01381 * \fn static int8_t sn_nsdl_resolve_ep_information(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr) 01382 * 01383 * 01384 * \brief Resolves endpoint information from received CoAP message 01385 * \param *handle Pointer to nsdl-library handle 01386 * \param *coap_packet_ptr Pointer to received CoAP message 01387 * 01388 * \return SN_NSDL_SUCCESS = 0, Failed = -1 01389 */ 01390 static int8_t sn_nsdl_resolve_ep_information(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr) 01391 { 01392 uint8_t *temp_ptr; 01393 uint8_t parameter_count = 0; 01394 uint16_t parameter_len = 0; 01395 01396 if (!coap_packet_ptr || !coap_packet_ptr->options_list_ptr || 01397 !coap_packet_ptr->options_list_ptr->location_path_ptr) { 01398 return SN_NSDL_FAILURE; 01399 } 01400 01401 temp_ptr = coap_packet_ptr->options_list_ptr->location_path_ptr; 01402 01403 while (temp_ptr <= (coap_packet_ptr->options_list_ptr->location_path_ptr + coap_packet_ptr->options_list_ptr->location_path_len)) { 01404 01405 if ((temp_ptr == (coap_packet_ptr->options_list_ptr->location_path_ptr + coap_packet_ptr->options_list_ptr->location_path_len)) || (*temp_ptr == '/')) { 01406 01407 parameter_count++; 01408 if (parameter_count == 2) { 01409 if (!handle->ep_information_ptr->domain_name_ptr) { 01410 handle->ep_information_ptr->domain_name_len = parameter_len - 1; 01411 handle->ep_information_ptr->domain_name_ptr = handle->sn_nsdl_alloc(handle->ep_information_ptr->domain_name_len); 01412 if (!handle->ep_information_ptr->domain_name_ptr) { 01413 return SN_NSDL_FAILURE; 01414 } 01415 memcpy(handle->ep_information_ptr->domain_name_ptr, temp_ptr - handle->ep_information_ptr->domain_name_len, handle->ep_information_ptr->domain_name_len); 01416 } 01417 01418 } 01419 if (parameter_count == 3) { 01420 if (!handle->ep_information_ptr->endpoint_name_ptr) { 01421 handle->ep_information_ptr->endpoint_name_len = parameter_len - 1; 01422 handle->ep_information_ptr->endpoint_name_ptr = handle->sn_nsdl_alloc(handle->ep_information_ptr->endpoint_name_len); 01423 if (!handle->ep_information_ptr->endpoint_name_ptr) { 01424 if (handle->ep_information_ptr->domain_name_ptr) { 01425 handle->sn_nsdl_free(handle->ep_information_ptr->domain_name_ptr); 01426 handle->ep_information_ptr->domain_name_ptr = NULL; 01427 handle->ep_information_ptr->domain_name_len = 0; 01428 } 01429 01430 return SN_NSDL_FAILURE; 01431 01432 } 01433 memcpy(handle->ep_information_ptr->endpoint_name_ptr, temp_ptr - handle->ep_information_ptr->endpoint_name_len, handle->ep_information_ptr->endpoint_name_len); 01434 } 01435 } 01436 parameter_len = 0; 01437 } 01438 parameter_len++; 01439 temp_ptr++; 01440 } 01441 01442 01443 return SN_NSDL_SUCCESS; 01444 } 01445 01446 extern int8_t set_NSP_address(struct nsdl_s *handle, uint8_t *NSP_address, uint8_t address_length, uint16_t port, sn_nsdl_addr_type_e address_type) 01447 { 01448 /* Check parameters and source pointers */ 01449 if (!handle || !handle->nsp_address_ptr || !handle->nsp_address_ptr->omalw_address_ptr || !NSP_address) { 01450 return SN_NSDL_FAILURE; 01451 } 01452 01453 handle->nsp_address_ptr->omalw_address_ptr->type = address_type; 01454 handle->nsp_address_ptr->omalw_server_security = SEC_NOT_SET; 01455 01456 if (handle->nsp_address_ptr->omalw_address_ptr->addr_ptr) { 01457 handle->sn_nsdl_free(handle->nsp_address_ptr->omalw_address_ptr->addr_ptr); 01458 } 01459 01460 handle->nsp_address_ptr->omalw_address_ptr->addr_len = address_length; 01461 01462 handle->nsp_address_ptr->omalw_address_ptr->addr_ptr = handle->sn_nsdl_alloc(handle->nsp_address_ptr->omalw_address_ptr->addr_len); 01463 if (!handle->nsp_address_ptr->omalw_address_ptr->addr_ptr) { 01464 return SN_NSDL_FAILURE; 01465 } 01466 01467 memcpy(handle->nsp_address_ptr->omalw_address_ptr->addr_ptr, NSP_address, handle->nsp_address_ptr->omalw_address_ptr->addr_len); 01468 handle->nsp_address_ptr->omalw_address_ptr->port = port; 01469 01470 return SN_NSDL_SUCCESS; 01471 } 01472 01473 01474 static uint8_t sn_nsdl_itoa_len(uint8_t value) 01475 { 01476 uint8_t i = 0; 01477 01478 do { 01479 i++; 01480 } while ((value /= 10) > 0); 01481 01482 return i; 01483 } 01484 01485 static uint8_t *sn_nsdl_itoa(uint8_t *ptr, uint8_t value) 01486 { 01487 01488 uint8_t start = 0; 01489 uint8_t end = 0; 01490 uint8_t i; 01491 01492 i = 0; 01493 01494 /* ITOA */ 01495 do { 01496 ptr[i++] = (value % 10) + '0'; 01497 } while ((value /= 10) > 0); 01498 01499 end = i - 1; 01500 01501 /* reverse (part of ITOA) */ 01502 while (start < end) { 01503 uint8_t chr; 01504 01505 chr = ptr[start]; 01506 ptr[start] = ptr[end]; 01507 ptr[end] = chr; 01508 01509 start++; 01510 end--; 01511 01512 } 01513 return (ptr + i); 01514 } 01515 01516 static int8_t set_endpoint_info(struct nsdl_s *handle, sn_nsdl_ep_parameters_s *endpoint_info_ptr) 01517 { 01518 if (handle->ep_information_ptr->domain_name_ptr) { 01519 handle->sn_nsdl_free(handle->ep_information_ptr->domain_name_ptr); 01520 handle->ep_information_ptr->domain_name_ptr = 0; 01521 handle->ep_information_ptr->domain_name_len = 0; 01522 } 01523 01524 if (handle->ep_information_ptr->endpoint_name_ptr) { 01525 handle->sn_nsdl_free(handle->ep_information_ptr->endpoint_name_ptr); 01526 handle->ep_information_ptr->endpoint_name_ptr = 0; 01527 handle->ep_information_ptr->endpoint_name_len = 0; 01528 } 01529 01530 if (endpoint_info_ptr->domain_name_ptr && endpoint_info_ptr->domain_name_len) { 01531 handle->ep_information_ptr->domain_name_ptr = handle->sn_nsdl_alloc(endpoint_info_ptr->domain_name_len); 01532 01533 if (!handle->ep_information_ptr->domain_name_ptr) { 01534 return -1; 01535 } 01536 01537 memcpy(handle->ep_information_ptr->domain_name_ptr, endpoint_info_ptr->domain_name_ptr, endpoint_info_ptr->domain_name_len); 01538 handle->ep_information_ptr->domain_name_len = endpoint_info_ptr->domain_name_len; 01539 } 01540 01541 if (endpoint_info_ptr->endpoint_name_ptr && endpoint_info_ptr->endpoint_name_len) { 01542 handle->ep_information_ptr->endpoint_name_ptr = handle->sn_nsdl_alloc(endpoint_info_ptr->endpoint_name_len); 01543 01544 if (!handle->ep_information_ptr->endpoint_name_ptr) { 01545 if (handle->ep_information_ptr->domain_name_ptr) { 01546 handle->sn_nsdl_free(handle->ep_information_ptr->domain_name_ptr); 01547 handle->ep_information_ptr->domain_name_ptr = 0; 01548 handle->ep_information_ptr->domain_name_len = 0; 01549 } 01550 return -1; 01551 } 01552 01553 memcpy(handle->ep_information_ptr->endpoint_name_ptr, endpoint_info_ptr->endpoint_name_ptr, endpoint_info_ptr->endpoint_name_len); 01554 handle->ep_information_ptr->endpoint_name_len = endpoint_info_ptr->endpoint_name_len; 01555 } 01556 01557 handle->ep_information_ptr->binding_and_mode = endpoint_info_ptr->binding_and_mode; 01558 handle->ep_information_ptr->ds_register_mode = endpoint_info_ptr->ds_register_mode; 01559 01560 handle->ep_information_ptr->location_ptr = 0; 01561 handle->ep_information_ptr->location_len = 0; 01562 01563 return 0; 01564 } 01565 01566 /* Wrapper */ 01567 sn_grs_resource_list_s *sn_nsdl_list_resource(struct nsdl_s *handle, uint16_t pathlen, uint8_t *path) 01568 { 01569 /* Check parameters */ 01570 if (handle == NULL) { 01571 return NULL; 01572 } 01573 01574 return sn_grs_list_resource(handle->grs, pathlen, path); 01575 } 01576 01577 void sn_nsdl_free_resource_list(struct nsdl_s *handle, sn_grs_resource_list_s *list) 01578 { 01579 /* Check parameters */ 01580 if (handle == NULL) { 01581 return; 01582 } 01583 01584 sn_grs_free_resource_list(handle->grs, list); 01585 } 01586 01587 #ifndef MEMORY_OPTIMIZED_API 01588 extern int8_t sn_nsdl_update_resource(struct nsdl_s *handle, sn_nsdl_dynamic_resource_parameters_s *res) 01589 { 01590 /* Check parameters */ 01591 if (handle == NULL) { 01592 return SN_NSDL_FAILURE; 01593 } 01594 01595 return sn_grs_update_resource(handle->grs, res); 01596 } 01597 01598 extern int8_t sn_nsdl_create_resource(struct nsdl_s *handle, sn_nsdl_dynamic_resource_parameters_s *res) 01599 { 01600 /* Check parameters */ 01601 if (handle == NULL) { 01602 return SN_NSDL_FAILURE; 01603 } 01604 01605 return sn_grs_create_resource(handle->grs, res); 01606 } 01607 #endif 01608 01609 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) 01610 { 01611 /* Check parameters */ 01612 if (handle == NULL) { 01613 return SN_NSDL_FAILURE; 01614 } 01615 01616 return sn_grs_send_coap_message(handle, address_ptr, coap_hdr_ptr); 01617 } 01618 01619 extern int8_t sn_nsdl_put_resource(struct nsdl_s *handle, sn_nsdl_dynamic_resource_parameters_s *res) 01620 { 01621 if (!handle) { 01622 return SN_NSDL_FAILURE; 01623 } 01624 01625 return sn_grs_put_resource(handle->grs, res); 01626 } 01627 01628 extern int8_t sn_nsdl_pop_resource(struct nsdl_s *handle, sn_nsdl_dynamic_resource_parameters_s *res) 01629 { 01630 if (!handle) { 01631 return SN_NSDL_FAILURE; 01632 } 01633 01634 return sn_grs_pop_resource(handle->grs, res); 01635 } 01636 01637 extern int8_t sn_nsdl_delete_resource(struct nsdl_s *handle, uint16_t pathlen, uint8_t *path) 01638 { 01639 /* Check parameters */ 01640 if (handle == NULL) { 01641 return SN_NSDL_FAILURE; 01642 } 01643 01644 return sn_grs_delete_resource(handle->grs, pathlen, path); 01645 } 01646 extern const sn_nsdl_dynamic_resource_parameters_s *sn_nsdl_get_first_resource(struct nsdl_s *handle) 01647 { 01648 /* Check parameters */ 01649 if (handle == NULL) { 01650 return NULL; 01651 } 01652 01653 return sn_grs_get_first_resource(handle->grs); 01654 } 01655 extern const sn_nsdl_dynamic_resource_parameters_s *sn_nsdl_get_next_resource(struct nsdl_s *handle, const sn_nsdl_dynamic_resource_parameters_s *resource) 01656 { 01657 /* Check parameters */ 01658 if (handle == NULL) { 01659 return NULL; 01660 } 01661 01662 return sn_grs_get_next_resource(handle->grs, resource); 01663 } 01664 01665 extern sn_coap_hdr_s *sn_nsdl_build_response(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr, uint8_t msg_code) 01666 { 01667 if (handle == NULL) { 01668 return NULL; 01669 } 01670 01671 return sn_coap_build_response(handle->grs->coap, coap_packet_ptr, msg_code); 01672 } 01673 01674 extern sn_coap_options_list_s *sn_nsdl_alloc_options_list(struct nsdl_s *handle, sn_coap_hdr_s *coap_msg_ptr) 01675 { 01676 if (handle == NULL || coap_msg_ptr == NULL) { 01677 return NULL; 01678 } 01679 return sn_coap_parser_alloc_options(handle->grs->coap, coap_msg_ptr); 01680 } 01681 01682 extern void sn_nsdl_release_allocated_coap_msg_mem(struct nsdl_s *handle, sn_coap_hdr_s *freed_coap_msg_ptr) 01683 { 01684 if (handle == NULL) { 01685 return; 01686 } 01687 01688 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, freed_coap_msg_ptr); 01689 } 01690 01691 extern int8_t sn_nsdl_set_retransmission_parameters(struct nsdl_s *handle, 01692 uint8_t resending_count, uint8_t resending_interval) 01693 { 01694 if (handle == NULL) { 01695 return SN_NSDL_FAILURE; 01696 } 01697 return sn_coap_protocol_set_retransmission_parameters(handle->grs->coap, 01698 resending_count,resending_interval); 01699 } 01700 01701 extern int8_t sn_nsdl_set_retransmission_buffer(struct nsdl_s *handle, 01702 uint8_t buffer_size_messages, uint16_t buffer_size_bytes) 01703 { 01704 if (handle == NULL) { 01705 return SN_NSDL_FAILURE; 01706 } 01707 return sn_coap_protocol_set_retransmission_buffer(handle->grs->coap, 01708 buffer_size_messages, buffer_size_bytes); 01709 } 01710 01711 extern int8_t sn_nsdl_set_block_size(struct nsdl_s *handle, uint16_t block_size) 01712 { 01713 if (handle == NULL) { 01714 return SN_NSDL_FAILURE; 01715 } 01716 return sn_coap_protocol_set_block_size(handle->grs->coap, block_size); 01717 } 01718 01719 extern int8_t sn_nsdl_set_duplicate_buffer_size(struct nsdl_s *handle, uint8_t message_count) 01720 { 01721 if (handle == NULL) { 01722 return SN_NSDL_FAILURE; 01723 } 01724 return sn_coap_protocol_set_duplicate_buffer_size(handle->grs->coap, message_count); 01725 } 01726 01727 bool sn_nsdl_check_uint_overflow(uint16_t resource_size, uint16_t param_a, uint16_t param_b) 01728 { 01729 uint16_t first_check = param_a + param_b; 01730 if (first_check < param_b) { 01731 return false; 01732 } else { 01733 uint16_t total = resource_size + first_check; 01734 if (total < first_check) { 01735 return false; 01736 } else { 01737 return true; 01738 } 01739 } 01740 } 01741 01742 extern int8_t sn_nsdl_set_context(struct nsdl_s * const handle, void * const context) 01743 { 01744 if (handle == NULL) { 01745 return SN_NSDL_FAILURE; 01746 } 01747 handle->context = context; 01748 return SN_NSDL_SUCCESS; 01749 } 01750 01751 extern void *sn_nsdl_get_context(const struct nsdl_s * const handle) 01752 { 01753 if (handle == NULL) { 01754 return NULL; 01755 } 01756 return handle->context; 01757 } 01758 01759 #endif 01760
Generated on Tue Jul 12 2022 11:02:51 by
