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