joey shelton / LED_Demo

Dependencies:   MAX44000 PWM_Tone_Library nexpaq_mdk

Fork of LED_Demo by Maxim nexpaq

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sn_nsdl.c Source File

sn_nsdl.c

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