sandbox / mbed-client-c

Fork of mbed-client-c by Christopher Haster

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