erkin yucel / mbed-os

Dependents:   BLE_file_test BLE_Blink ExternalEncoder

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sn_nsdl.c Source File

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