mbed client lightswitch demo

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Fork of mbed-client-classic-example-lwip by Austin Blackstone

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