ON Semiconductor / mbed-os

Dependents:   mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510

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