ON Semiconductor / mbed-os

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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sn_nsdl2.c Source File

sn_nsdl2.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_nsdl2.c
00018  *
00019  * \brief Nano service device library
00020  *
00021  */
00022 #ifdef MBED_CLIENT_C_NEW_API
00023 
00024 #include <string.h>
00025 
00026 #include "ns_types.h"
00027 #include "sn_nsdl.h"
00028 #include "sn_coap_header.h"
00029 #include "sn_coap_protocol.h"
00030 #include "sn_coap_protocol_internal.h"
00031 #include "sn_nsdl_lib.h"
00032 #include "sn_grs.h"
00033 #include "sn_config.h"
00034 #include "mbed-trace/mbed_trace.h"
00035 
00036 #define TRACE_GROUP "coap"
00037 /* Defines */
00038 #define TRACE_GROUP "coap"
00039 #define RESOURCE_DIR_LEN                2
00040 #define EP_NAME_PARAMETERS_LEN          3
00041 #define ET_PARAMETER_LEN                3
00042 #define LT_PARAMETER_LEN                3
00043 #define DOMAIN_PARAMETER_LEN            2
00044 #define RT_PARAMETER_LEN                3
00045 #define IF_PARAMETER_LEN                3
00046 #define OBS_PARAMETER_LEN               3
00047 #define AOBS_PARAMETER_LEN              8
00048 #define COAP_CON_PARAMETER_LEN          3
00049 #define BS_EP_PARAMETER_LEN             3
00050 #define BS_QUEUE_MODE_PARAMATER_LEN     2
00051 
00052 #define SN_NSDL_EP_REGISTER_MESSAGE     1
00053 #define SN_NSDL_EP_UPDATE_MESSAGE       2
00054 
00055 #define SN_NSDL_MSG_UNDEFINED           0
00056 #define SN_NSDL_MSG_REGISTER            1
00057 #define SN_NSDL_MSG_UNREGISTER          2
00058 #define SN_NSDL_MSG_UPDATE              3
00059 #define SN_NSDL_MSG_BOOTSTRAP           4
00060 
00061 #ifdef YOTTA_CFG_DISABLE_OBS_FEATURE
00062 #define COAP_DISABLE_OBS_FEATURE YOTTA_CFG_DISABLE_OBS_FEATURE
00063 #elif defined MBED_CONF_MBED_CLIENT_COAP_DISABLE_OBS_FEATURE
00064 #define COAP_DISABLE_OBS_FEATURE MBED_CONF_MBED_CLIENT_COAP_DISABLE_OBS_FEATURE
00065 #endif
00066 
00067 #ifdef YOTTA_CFG_DISABLE_BOOTSTRAP_FEATURE
00068 #define MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE YOTTA_CFG_DISABLE_BOOTSTRAP_FEATURE
00069 #elif defined MBED_CONF_MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
00070 #define MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE MBED_CONF_MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
00071 #endif
00072 
00073 
00074 /* Constants */
00075 static uint8_t      ep_name_parameter_string[]  = {'e', 'p', '='};      /* Endpoint name. A unique name for the registering node in a domain.  */
00076 static uint8_t      resource_path_ptr[]         = {'r', 'd'};           /* For resource directory */
00077 static uint8_t      resource_type_parameter[]   = {'r', 't', '='};      /* Resource type. Only once for registration */
00078 #ifndef COAP_DISABLE_OBS_FEATURE
00079 static uint8_t      obs_parameter[]             = {'o', 'b', 's'};      /* Observable */
00080 #endif
00081 static uint8_t      if_description_parameter[]  = {'i', 'f', '='};      /* Interface description. Only once */
00082 static uint8_t      ep_lifetime_parameter[]     = {'l', 't', '='};      /* Lifetime. Number of seconds that this registration will be valid for. Must be updated within this time, or will be removed. */
00083 static uint8_t      ep_domain_parameter[]       = {'d', '='};           /* Domain name. If this parameter is missing, a default domain is assumed. */
00084 static uint8_t      coap_con_type_parameter[]   = {'c', 't', '='};      /* CoAP content type */
00085 /* * OMA BS parameters * */
00086 static uint8_t bs_uri[]                         = {'b', 's'};
00087 static uint8_t bs_ep_name[]                     = {'e', 'p', '='};
00088 static uint8_t et_parameter[]                   = {'e', 't', '='};      /* Endpoint type */
00089 static uint8_t bs_queue_mode[]                  = {'b', '='};
00090 
00091 /* Function prototypes */
00092 static uint16_t         sn_nsdl_internal_coap_send(struct nsdl_s *handle, sn_coap_hdr_s *coap_header_ptr, sn_nsdl_addr_s *dst_addr_ptr, uint8_t message_description);
00093 static void             sn_nsdl_resolve_nsp_address(struct nsdl_s *handle);
00094 int8_t                  sn_nsdl_build_registration_body(struct nsdl_s *handle, sn_coap_hdr_s *message_ptr, uint8_t updating_registeration);
00095 static uint16_t         sn_nsdl_calculate_registration_body_size(struct nsdl_s *handle, uint8_t updating_registeration, int8_t *error);
00096 static uint8_t          sn_nsdl_calculate_uri_query_option_len(sn_nsdl_ep_parameters_s *endpoint_info_ptr, uint8_t msg_type);
00097 static int8_t           sn_nsdl_fill_uri_query_options(struct nsdl_s *handle, sn_nsdl_ep_parameters_s *parameter_ptr, sn_coap_hdr_s *source_msg_ptr, uint8_t msg_type);
00098 static int8_t           sn_nsdl_local_rx_function(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr, sn_nsdl_addr_s *address_ptr);
00099 static int8_t           sn_nsdl_resolve_ep_information(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr);
00100 static uint8_t          sn_nsdl_itoa_len(uint8_t value);
00101 static uint8_t          *sn_nsdl_itoa(uint8_t *ptr, uint8_t value);
00102 static int8_t           set_endpoint_info(struct nsdl_s *handle, sn_nsdl_ep_parameters_s *endpoint_info_ptr);
00103 static bool             validateParameters(sn_nsdl_ep_parameters_s *parameter_ptr);
00104 static bool             validate(uint8_t* ptr, uint32_t len, char illegalChar);
00105 static bool             sn_nsdl_check_uint_overflow(uint16_t resource_size, uint16_t param_a, uint16_t param_b);
00106 
00107 int8_t sn_nsdl_destroy(struct nsdl_s *handle)
00108 {
00109     if (handle == NULL) {
00110         return SN_NSDL_FAILURE;
00111     }
00112 
00113     if (handle->ep_information_ptr) {
00114         if (handle->ep_information_ptr->endpoint_name_ptr) {
00115             handle->sn_nsdl_free(handle->ep_information_ptr->endpoint_name_ptr);
00116             handle->ep_information_ptr->endpoint_name_ptr = 0;
00117         }
00118         if (handle->ep_information_ptr->domain_name_ptr) {
00119             handle->sn_nsdl_free(handle->ep_information_ptr->domain_name_ptr);
00120             handle->ep_information_ptr->domain_name_ptr = 0;
00121             handle->ep_information_ptr->domain_name_len = 0;
00122         }
00123         if (handle->ep_information_ptr->location_ptr) {
00124             handle->sn_nsdl_free(handle->ep_information_ptr->location_ptr);
00125             handle->ep_information_ptr->location_ptr = 0;
00126             handle->ep_information_ptr->location_len = 0;
00127         }
00128         if (handle->ep_information_ptr->type_ptr) {
00129             handle->sn_nsdl_free(handle->ep_information_ptr->type_ptr);
00130             handle->ep_information_ptr->type_ptr = 0;
00131         }
00132 
00133         if (handle->ep_information_ptr->lifetime_ptr)
00134 
00135         {
00136             handle->sn_nsdl_free(handle->ep_information_ptr->lifetime_ptr);
00137             handle->ep_information_ptr->lifetime_ptr = 0;
00138         }
00139 
00140         handle->sn_nsdl_free(handle->ep_information_ptr);
00141         handle->ep_information_ptr = 0;
00142     }
00143 
00144     if (handle->nsp_address_ptr) {
00145         if (handle->nsp_address_ptr->omalw_address_ptr) {
00146             if (handle->nsp_address_ptr->omalw_address_ptr->addr_ptr) {
00147                 handle->sn_nsdl_free(handle->nsp_address_ptr->omalw_address_ptr->addr_ptr);
00148                 handle->nsp_address_ptr->omalw_address_ptr->addr_ptr = 0;
00149             }
00150             handle->sn_nsdl_free(handle->nsp_address_ptr->omalw_address_ptr);
00151         }
00152 
00153         handle->sn_nsdl_free(handle->nsp_address_ptr);
00154         handle->nsp_address_ptr = 0;
00155     }
00156 
00157     if (handle->oma_bs_address_ptr) {
00158         handle->sn_nsdl_free(handle->oma_bs_address_ptr);
00159     }
00160 
00161     /* Destroy also libCoap and grs part of libNsdl */
00162     sn_coap_protocol_destroy(handle->grs->coap);
00163     sn_grs_destroy(handle->grs);
00164     handle->sn_nsdl_free(handle);
00165 
00166     return SN_NSDL_SUCCESS;
00167 }
00168 
00169 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 *),
00170                             uint8_t (*sn_nsdl_rx_cb)(struct nsdl_s *, sn_coap_hdr_s *, sn_nsdl_addr_s *),
00171                             void *(*sn_nsdl_alloc)(uint16_t), void (*sn_nsdl_free)(void *))
00172 {
00173     /* Check pointers and define function pointers */
00174     if (!sn_nsdl_alloc || !sn_nsdl_free || !sn_nsdl_tx_cb || !sn_nsdl_rx_cb) {
00175         return NULL;
00176     }
00177 
00178     struct nsdl_s *handle = NULL;
00179 
00180     handle = sn_nsdl_alloc(sizeof(struct nsdl_s));
00181 
00182     if (handle == NULL) {
00183         return NULL;
00184     }
00185 
00186     memset(handle, 0, sizeof(struct nsdl_s));
00187 
00188     /* Define function pointers */
00189     handle->sn_nsdl_alloc = sn_nsdl_alloc;
00190     handle->sn_nsdl_free = sn_nsdl_free;
00191 
00192     handle->sn_nsdl_tx_callback = sn_nsdl_tx_cb;
00193     handle->sn_nsdl_rx_callback = sn_nsdl_rx_cb;
00194 
00195     /* Initialize ep parameters struct */
00196     if (!handle->ep_information_ptr) {
00197         handle->ep_information_ptr = handle->sn_nsdl_alloc(sizeof(sn_nsdl_ep_parameters_s));
00198         if (!handle->ep_information_ptr) {
00199             sn_nsdl_free(handle);
00200             return NULL;
00201         }
00202         memset(handle->ep_information_ptr, 0, sizeof(sn_nsdl_ep_parameters_s));
00203     }
00204 
00205     handle->grs = sn_grs_init(sn_nsdl_tx_cb, &sn_nsdl_local_rx_function, sn_nsdl_alloc, sn_nsdl_free);
00206 
00207     /* Initialize GRS */
00208     if (handle->grs == NULL) {
00209         handle->sn_nsdl_free(handle->ep_information_ptr);
00210         handle->ep_information_ptr = 0;
00211         sn_nsdl_free(handle);
00212         return NULL;
00213     }
00214 
00215     sn_nsdl_resolve_nsp_address(handle);
00216 
00217     handle->sn_nsdl_endpoint_registered = SN_NSDL_ENDPOINT_NOT_REGISTERED;
00218     handle->context = NULL;
00219 
00220     return handle;
00221 }
00222 
00223 uint16_t sn_nsdl_register_endpoint(struct nsdl_s *handle, sn_nsdl_ep_parameters_s *endpoint_info_ptr)
00224 {
00225     /* Local variables */
00226     sn_coap_hdr_s   *register_message_ptr;
00227     uint16_t        message_id  = 0;
00228 
00229     if (endpoint_info_ptr == NULL || handle == NULL) {
00230         return 0;
00231     }
00232 
00233     /*** Build endpoint register message ***/
00234 
00235     /* Allocate memory for header struct */
00236     register_message_ptr = sn_coap_parser_alloc_message(handle->grs->coap);
00237     if (register_message_ptr == NULL) {
00238         return 0;
00239     }
00240 
00241     /* Fill message fields -> confirmable post to specified NSP path */
00242     register_message_ptr->msg_type = COAP_MSG_TYPE_CONFIRMABLE;
00243     register_message_ptr->msg_code = COAP_MSG_CODE_REQUEST_POST;
00244 
00245     /* Allocate memory for the extended options list */
00246     if (sn_coap_parser_alloc_options(handle->grs->coap, register_message_ptr) == NULL) {
00247         sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr);
00248         register_message_ptr = 0;
00249         return 0;
00250     }
00251 
00252     register_message_ptr->uri_path_len = sizeof(resource_path_ptr);
00253     register_message_ptr->uri_path_ptr = resource_path_ptr;
00254 
00255     /* Fill Uri-query options */
00256     if( SN_NSDL_FAILURE == sn_nsdl_fill_uri_query_options(handle, endpoint_info_ptr,
00257                                                           register_message_ptr, SN_NSDL_EP_REGISTER_MESSAGE) ){
00258         register_message_ptr->uri_path_ptr = NULL;
00259         sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr);
00260         return 0;
00261     }
00262 
00263     if (endpoint_info_ptr->ds_register_mode == REGISTER_WITH_RESOURCES) {
00264         /* Built body for message */
00265         if (sn_nsdl_build_registration_body(handle, register_message_ptr, 0) == SN_NSDL_FAILURE) {
00266             register_message_ptr->uri_path_ptr = NULL;
00267             register_message_ptr->options_list_ptr->uri_host_ptr = NULL;
00268             sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr);
00269             return 0;
00270         }
00271     }
00272 
00273     /* Clean (possible) existing and save new endpoint info to handle */
00274     if (set_endpoint_info(handle, endpoint_info_ptr) == -1) {
00275         if (register_message_ptr->payload_ptr) {
00276             handle->sn_nsdl_free(register_message_ptr->payload_ptr);
00277             register_message_ptr->payload_ptr = NULL;
00278         }
00279 
00280         register_message_ptr->uri_path_ptr = NULL;
00281         register_message_ptr->options_list_ptr->uri_host_ptr = NULL;
00282 
00283         sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr);
00284 
00285         return 0;
00286     }
00287 
00288     /* Build and send coap message to NSP */
00289     message_id = sn_nsdl_internal_coap_send(handle, register_message_ptr, handle->nsp_address_ptr->omalw_address_ptr, SN_NSDL_MSG_REGISTER);
00290 
00291     if (register_message_ptr->payload_ptr) {
00292         handle->sn_nsdl_free(register_message_ptr->payload_ptr);
00293         register_message_ptr->payload_ptr = NULL;
00294     }
00295 
00296     register_message_ptr->uri_path_ptr = NULL;
00297     register_message_ptr->options_list_ptr->uri_host_ptr = NULL;
00298 
00299     sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr);
00300 
00301     return message_id;
00302 }
00303 
00304 uint16_t sn_nsdl_unregister_endpoint(struct nsdl_s *handle)
00305 {
00306     /* Local variables */
00307     sn_coap_hdr_s   *unregister_message_ptr;
00308     uint8_t         *temp_ptr = 0;
00309     uint16_t        message_id = 0;
00310 
00311     /* Check parameters */
00312     if (handle == NULL) {
00313         return 0;
00314     }
00315 
00316     /* Check that EP have been registered */
00317     if (sn_nsdl_is_ep_registered(handle)) {
00318 
00319         /* Memory allocation for unregister message */
00320         unregister_message_ptr = sn_coap_parser_alloc_message(handle->grs->coap);
00321         if (!unregister_message_ptr) {
00322             return 0;
00323         }
00324 
00325         /* Fill unregister message */
00326         unregister_message_ptr->msg_type = COAP_MSG_TYPE_CONFIRMABLE;
00327         unregister_message_ptr->msg_code = COAP_MSG_CODE_REQUEST_DELETE;
00328 
00329         if(handle->ep_information_ptr->location_ptr) {
00330             unregister_message_ptr->uri_path_len = handle->ep_information_ptr->location_len;
00331             unregister_message_ptr->uri_path_ptr = handle->sn_nsdl_alloc(unregister_message_ptr->uri_path_len);
00332             if (!unregister_message_ptr->uri_path_ptr) {
00333                 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, unregister_message_ptr);
00334                 return 0;
00335             }
00336 
00337             temp_ptr = unregister_message_ptr->uri_path_ptr;
00338 
00339             memcpy(temp_ptr , handle->ep_information_ptr->location_ptr, handle->ep_information_ptr->location_len);
00340         } else {
00341             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);
00342             unregister_message_ptr->uri_path_ptr = handle->sn_nsdl_alloc(unregister_message_ptr->uri_path_len);
00343             if (!unregister_message_ptr->uri_path_ptr) {
00344                 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, unregister_message_ptr);
00345                 return 0;
00346             }
00347 
00348             temp_ptr = unregister_message_ptr->uri_path_ptr;
00349 
00350             memcpy(temp_ptr, resource_path_ptr, RESOURCE_DIR_LEN);
00351             temp_ptr += RESOURCE_DIR_LEN;
00352 
00353             *temp_ptr++ = '/';
00354 
00355             memcpy(temp_ptr , handle->ep_information_ptr->domain_name_ptr, handle->ep_information_ptr->domain_name_len);
00356             temp_ptr += handle->ep_information_ptr->domain_name_len;
00357 
00358             *temp_ptr++ = '/';
00359 
00360             memcpy(temp_ptr , handle->ep_information_ptr->endpoint_name_ptr, handle->ep_information_ptr->endpoint_name_len);
00361         }
00362 
00363         /* Send message */
00364         message_id = sn_nsdl_internal_coap_send(handle, unregister_message_ptr, handle->nsp_address_ptr->omalw_address_ptr, SN_NSDL_MSG_UNREGISTER);
00365 
00366         /* Free memory */
00367         sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, unregister_message_ptr);
00368 
00369     }
00370 
00371     return message_id;
00372 }
00373 
00374 uint16_t sn_nsdl_update_registration(struct nsdl_s *handle, uint8_t *lt_ptr, uint8_t lt_len)
00375 {
00376     /* Local variables */
00377     sn_coap_hdr_s   *register_message_ptr;
00378     uint8_t         *temp_ptr;
00379     sn_nsdl_ep_parameters_s temp_parameters;
00380     uint16_t        message_id = 0;
00381 
00382     /* Check parameters */
00383     if (handle == NULL) {
00384         return 0;
00385     }
00386 
00387     if (!sn_nsdl_is_ep_registered(handle)){
00388         return 0;
00389     }
00390 
00391     memset(&temp_parameters, 0, sizeof(sn_nsdl_ep_parameters_s));
00392 
00393     temp_parameters.lifetime_len = lt_len;
00394     temp_parameters.lifetime_ptr = lt_ptr;
00395 
00396     /*** Build endpoint register update message ***/
00397 
00398     /* Allocate memory for header struct */
00399     register_message_ptr = sn_coap_parser_alloc_message(handle->grs->coap);
00400     if (register_message_ptr == NULL) {
00401         return 0;
00402     }
00403 
00404     /* Fill message fields -> confirmable post to specified NSP path */
00405     register_message_ptr->msg_type  =   COAP_MSG_TYPE_CONFIRMABLE;
00406     register_message_ptr->msg_code  =   COAP_MSG_CODE_REQUEST_POST;
00407 
00408     if(handle->ep_information_ptr->location_ptr) {
00409         register_message_ptr->uri_path_len  =   handle->ep_information_ptr->location_len;    /* = Only location set by Device Server*/
00410 
00411         register_message_ptr->uri_path_ptr  =   handle->sn_nsdl_alloc(register_message_ptr->uri_path_len);
00412         if (!register_message_ptr->uri_path_ptr) {
00413             sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr);
00414             return 0;
00415         }
00416 
00417         temp_ptr = register_message_ptr->uri_path_ptr;
00418 
00419         /* location */
00420         memcpy(temp_ptr, handle->ep_information_ptr->location_ptr, handle->ep_information_ptr->location_len);
00421     } else {
00422         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 */
00423 
00424         register_message_ptr->uri_path_ptr  =   handle->sn_nsdl_alloc(register_message_ptr->uri_path_len);
00425         if (!register_message_ptr->uri_path_ptr) {
00426             sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr);
00427             return 0;
00428         }
00429 
00430         temp_ptr = register_message_ptr->uri_path_ptr;
00431 
00432         /* rd/ */
00433         memcpy(temp_ptr, resource_path_ptr, sizeof(resource_path_ptr));
00434         temp_ptr += sizeof(resource_path_ptr);
00435         *temp_ptr++ = '/';
00436 
00437         /* rd/DOMAIN/ */
00438         memcpy(temp_ptr, handle->ep_information_ptr->domain_name_ptr, handle->ep_information_ptr->domain_name_len);
00439         temp_ptr += handle->ep_information_ptr->domain_name_len;
00440         *temp_ptr++ = '/';
00441 
00442         /* rd/domain/ENDPOINT */
00443         memcpy(temp_ptr, handle->ep_information_ptr->endpoint_name_ptr, handle->ep_information_ptr->endpoint_name_len);
00444     }
00445 
00446     /* Allocate memory for the extended options list */
00447     if (sn_coap_parser_alloc_options(handle->grs->coap, register_message_ptr) == NULL) {
00448         sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr);
00449         return 0;
00450     }
00451 
00452     /* Fill Uri-query options */
00453     sn_nsdl_fill_uri_query_options(handle, &temp_parameters, register_message_ptr, SN_NSDL_EP_UPDATE_MESSAGE);
00454 
00455     /* Build payload */
00456     if (handle->ep_information_ptr->ds_register_mode == REGISTER_WITH_RESOURCES) {
00457 
00458         if (sn_nsdl_build_registration_body(handle, register_message_ptr, 1) == SN_NSDL_FAILURE) {
00459             sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr);
00460             return 0;
00461         }
00462     }
00463 
00464     /* Build and send coap message to NSP */
00465     message_id = sn_nsdl_internal_coap_send(handle, register_message_ptr, handle->nsp_address_ptr->omalw_address_ptr, SN_NSDL_MSG_UPDATE);
00466 
00467     if (register_message_ptr->payload_ptr) {
00468         handle->sn_nsdl_free(register_message_ptr->payload_ptr);
00469     }
00470     sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, register_message_ptr);
00471 
00472     return message_id;
00473 }
00474 
00475 int8_t sn_nsdl_set_endpoint_location(struct nsdl_s *handle, uint8_t *location_ptr, uint8_t location_len)
00476 {
00477     if(!handle || !location_ptr || (location_len == 0)) {
00478         return -1;
00479     }
00480 
00481     handle->sn_nsdl_free(handle->ep_information_ptr->location_ptr);
00482     handle->ep_information_ptr->location_ptr = handle->sn_nsdl_alloc(location_len);
00483     memcpy(handle->ep_information_ptr->location_ptr, location_ptr, location_len);
00484     handle->ep_information_ptr->location_len = location_len;
00485 
00486     return 0;
00487 }
00488 
00489 void sn_nsdl_nsp_lost(struct nsdl_s *handle)
00490 {
00491     /* Check parameters */
00492     if (handle == NULL) {
00493         return;
00494     }
00495 
00496     handle->sn_nsdl_endpoint_registered = SN_NSDL_ENDPOINT_NOT_REGISTERED;
00497 }
00498 
00499 int8_t sn_nsdl_is_ep_registered(struct nsdl_s *handle)
00500 {
00501     /* Check parameters */
00502     if (handle == NULL) {
00503         return SN_NSDL_FAILURE;
00504     }
00505 
00506     return handle->sn_nsdl_endpoint_registered;
00507 }
00508 
00509 uint16_t sn_nsdl_send_observation_notification(struct nsdl_s *handle, uint8_t *token_ptr, uint8_t token_len,
00510    uint8_t *payload_ptr, uint16_t payload_len, sn_coap_observe_e observe, sn_coap_msg_type_e message_type,
00511    sn_coap_content_format_e content_format)
00512 {
00513     sn_coap_hdr_s   *notification_message_ptr;
00514     uint16_t        return_msg_id = 0;
00515 
00516     /* Check parameters */
00517     if (handle == NULL || handle->grs == NULL) {
00518         return 0;
00519     }
00520 
00521     /* Allocate and initialize memory for header struct */
00522     notification_message_ptr = sn_coap_parser_alloc_message(handle->grs->coap);
00523     if (notification_message_ptr == NULL) {
00524         return 0;
00525     }
00526 
00527     if (sn_coap_parser_alloc_options(handle->grs->coap, notification_message_ptr) == NULL) {
00528         handle->sn_nsdl_free(notification_message_ptr);
00529         return 0;
00530     }
00531 
00532     /* Fill header */
00533     notification_message_ptr->msg_type = message_type;
00534     notification_message_ptr->msg_code = COAP_MSG_CODE_RESPONSE_CONTENT;
00535 
00536     /* Fill token */
00537     notification_message_ptr->token_len = token_len;
00538     notification_message_ptr->token_ptr = token_ptr;
00539 
00540     /* Fill payload */
00541     notification_message_ptr->payload_len = payload_len;
00542     notification_message_ptr->payload_ptr = payload_ptr;
00543 
00544     /* Fill observe */
00545     notification_message_ptr->options_list_ptr->observe = observe;
00546 
00547     /* Fill content format */
00548     notification_message_ptr->content_format = content_format;
00549 
00550     /* Send message */
00551     if (sn_nsdl_send_coap_message(handle, handle->nsp_address_ptr->omalw_address_ptr, notification_message_ptr) == SN_NSDL_FAILURE) {
00552         return_msg_id = 0;
00553     } else {
00554         return_msg_id = notification_message_ptr->msg_id;
00555     }
00556 
00557     /* Free memory */
00558     notification_message_ptr->payload_ptr = NULL;
00559     notification_message_ptr->token_ptr = NULL;
00560 
00561     sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, notification_message_ptr);
00562 
00563     return return_msg_id;
00564 }
00565 
00566 
00567 /* * * * * * * * * * */
00568 /* ~ OMA functions ~ */
00569 /* * * * * * * * * * */
00570 
00571 uint16_t sn_nsdl_oma_bootstrap(struct nsdl_s *handle, sn_nsdl_addr_s *bootstrap_address_ptr,
00572                                sn_nsdl_ep_parameters_s *endpoint_info_ptr,
00573                                sn_nsdl_bs_ep_info_t *bootstrap_endpoint_info_ptr)
00574 {
00575 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
00576     /* Local variables */
00577     sn_coap_hdr_s bootstrap_coap_header;
00578     uint8_t *uri_query_tmp_ptr;
00579     uint16_t message_id = 0;
00580 
00581     /* Check parameters */
00582     if (!bootstrap_address_ptr || !bootstrap_endpoint_info_ptr || !endpoint_info_ptr || !handle) {
00583         return 0;
00584     }
00585 
00586     handle->sn_nsdl_oma_bs_done_cb = bootstrap_endpoint_info_ptr->oma_bs_status_cb;
00587     handle->sn_nsdl_oma_bs_done_cb_handle = bootstrap_endpoint_info_ptr->oma_bs_status_cb_handle;
00588 
00589     /* XXX FIX -- Init CoAP header struct */
00590     sn_coap_parser_init_message(&bootstrap_coap_header);
00591 
00592     if (!sn_coap_parser_alloc_options(handle->grs->coap, &bootstrap_coap_header)) {
00593         return 0;
00594     }
00595 
00596     /* Build bootstrap start message */
00597     bootstrap_coap_header.msg_code = COAP_MSG_CODE_REQUEST_POST;
00598     bootstrap_coap_header.msg_type = COAP_MSG_TYPE_CONFIRMABLE;
00599 
00600     bootstrap_coap_header.uri_path_ptr = bs_uri;
00601     bootstrap_coap_header.uri_path_len = sizeof(bs_uri);
00602 
00603     uri_query_tmp_ptr = handle->sn_nsdl_alloc(endpoint_info_ptr->endpoint_name_len + BS_EP_PARAMETER_LEN);
00604     if (!uri_query_tmp_ptr) {
00605         handle->sn_nsdl_free(bootstrap_coap_header.options_list_ptr);
00606         return 0;
00607     }
00608 
00609     memcpy(uri_query_tmp_ptr, bs_ep_name, BS_EP_PARAMETER_LEN);
00610     memcpy((uri_query_tmp_ptr + BS_EP_PARAMETER_LEN), endpoint_info_ptr->endpoint_name_ptr, endpoint_info_ptr->endpoint_name_len);
00611 
00612     bootstrap_coap_header.options_list_ptr->uri_query_len = endpoint_info_ptr->endpoint_name_len + BS_EP_PARAMETER_LEN;
00613     bootstrap_coap_header.options_list_ptr->uri_query_ptr = uri_query_tmp_ptr;
00614 
00615     /* Save bootstrap server address */
00616     handle->oma_bs_address_len = bootstrap_address_ptr->addr_len;       /* Length.. */
00617     handle->oma_bs_address_ptr = handle->sn_nsdl_alloc(handle->oma_bs_address_len);     /* Address.. */
00618     if (!handle->oma_bs_address_ptr) {
00619         handle->sn_nsdl_free(bootstrap_coap_header.options_list_ptr);
00620         handle->sn_nsdl_free(uri_query_tmp_ptr);
00621         return 0;
00622     }
00623     memcpy(handle->oma_bs_address_ptr, bootstrap_address_ptr->addr_ptr, handle->oma_bs_address_len);
00624     handle->oma_bs_port = bootstrap_address_ptr->port;                  /* And port */
00625 
00626     /* Send message */
00627     message_id = sn_nsdl_internal_coap_send(handle, &bootstrap_coap_header, bootstrap_address_ptr, SN_NSDL_MSG_BOOTSTRAP);
00628 
00629     /* Free allocated memory */
00630     handle->sn_nsdl_free(uri_query_tmp_ptr);
00631     handle->sn_nsdl_free(bootstrap_coap_header.options_list_ptr);
00632 
00633     return message_id;
00634 #else
00635     return 0;
00636 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
00637 
00638 }
00639 
00640 char *sn_nsdl_get_version(void)
00641 {
00642 #if defined(YOTTA_MBED_CLIENT_C_VERSION_STRING)
00643     return YOTTA_MBED_CLIENT_C_VERSION_STRING;
00644 #elif defined(VERSION)
00645     return VERSION;
00646 #else
00647     return "0.0.0";
00648 #endif
00649 }
00650 
00651 int8_t sn_nsdl_process_coap(struct nsdl_s *handle, uint8_t *packet_ptr, uint16_t packet_len, sn_nsdl_addr_s *src_ptr)
00652 {
00653     sn_coap_hdr_s           *coap_packet_ptr    = NULL;
00654     sn_coap_hdr_s           *coap_response_ptr  = NULL;
00655     sn_nsdl_dynamic_resource_parameters_s *resource = NULL;
00656     /* Check parameters */
00657     if (handle == NULL) {
00658         return SN_NSDL_FAILURE;
00659     }
00660 
00661     /* Parse CoAP packet */
00662     coap_packet_ptr = sn_coap_protocol_parse(handle->grs->coap, src_ptr, packet_len, packet_ptr, (void *)handle);
00663 
00664     /* Check if parsing was successfull */
00665     if (coap_packet_ptr == (sn_coap_hdr_s *)NULL) {
00666         return SN_NSDL_FAILURE;
00667     }
00668 #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
00669     // Pass block to application if external_memory_block is set
00670     if(coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVING) {
00671         resource = sn_nsdl_get_resource(handle, coap_packet_ptr->uri_path_len, coap_packet_ptr->uri_path_ptr);
00672         if(resource && resource->static_resource_parameters->external_memory_block) {
00673             sn_coap_protocol_block_remove(handle->grs->coap,
00674                                           src_ptr,
00675                                           coap_packet_ptr->payload_len,
00676                                           coap_packet_ptr->payload_ptr);
00677         } else {
00678             resource = NULL;
00679         }
00680     }
00681 #endif
00682     /* Check, if coap itself sends response, or block receiving is ongoing... */
00683     if (coap_packet_ptr->coap_status != COAP_STATUS_OK &&
00684             coap_packet_ptr->coap_status != COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED &&coap_packet_ptr &&
00685             !resource) {
00686         sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr);
00687         return SN_NSDL_SUCCESS;
00688     }
00689 
00690     /* If proxy options added, return not supported */
00691     if (coap_packet_ptr->options_list_ptr) {
00692         if (coap_packet_ptr->options_list_ptr->proxy_uri_len) {
00693             coap_response_ptr = sn_coap_build_response(handle->grs->coap, coap_packet_ptr, COAP_MSG_CODE_RESPONSE_PROXYING_NOT_SUPPORTED);
00694             if (coap_response_ptr) {
00695                 sn_nsdl_send_coap_message(handle, src_ptr, coap_response_ptr);
00696                 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_response_ptr);
00697                 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr);
00698                 return SN_NSDL_SUCCESS;
00699             } else {
00700                 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr);
00701                 return SN_NSDL_FAILURE;
00702             }
00703         }
00704     }
00705 
00706     /* * * * * * * * * * * * * * * * * * * * * * * * * * */
00707     /* If message is response message, call RX callback  */
00708     /* * * * * * * * * * * * * * * * * * * * * * * * * * */
00709 
00710     if ((coap_packet_ptr->msg_code > COAP_MSG_CODE_REQUEST_DELETE) ||
00711             (coap_packet_ptr->msg_type >= COAP_MSG_TYPE_ACKNOWLEDGEMENT)) {
00712         int8_t retval = sn_nsdl_local_rx_function(handle, coap_packet_ptr, src_ptr);
00713         if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED &&
00714                 coap_packet_ptr->payload_ptr) {
00715             handle->sn_nsdl_free(coap_packet_ptr->payload_ptr);
00716             coap_packet_ptr->payload_ptr = 0;
00717         }
00718         sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr);
00719         return retval;
00720     }
00721 #ifndef MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
00722     /* * If OMA bootstrap message... * */
00723     bool bootstrap_msg = src_ptr && (handle->oma_bs_address_len == src_ptr->addr_len) &&
00724             (handle->oma_bs_port == src_ptr->port) &&
00725             !memcmp(handle->oma_bs_address_ptr, src_ptr->addr_ptr, handle->oma_bs_address_len);
00726 
00727     // Pass bootstrap data to application
00728     if (bootstrap_msg) {
00729         handle->sn_nsdl_rx_callback(handle, coap_packet_ptr,src_ptr);
00730         sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr);
00731         return SN_NSDL_SUCCESS;
00732     }
00733 #endif //MBED_CLIENT_DISABLE_BOOTSTRAP_FEATURE
00734 
00735     /* * * * * * * * * * * * * * * */
00736     /* Other messages are for GRS  */
00737     /* * * * * * * * * * * * * * * */
00738     return sn_grs_process_coap(handle, coap_packet_ptr, src_ptr);
00739 }
00740 
00741 int8_t sn_nsdl_exec(struct nsdl_s *handle, uint32_t time)
00742 {
00743     if(!handle || !handle->grs){
00744         return SN_NSDL_FAILURE;
00745     }
00746     /* Call CoAP execution function */
00747     return sn_coap_protocol_exec(handle->grs->coap, time);
00748 }
00749 
00750 sn_nsdl_dynamic_resource_parameters_s *sn_nsdl_get_resource(struct nsdl_s *handle, uint16_t pathlen, uint8_t *path_ptr)
00751 {
00752     /* Check parameters */
00753     if (handle == NULL) {
00754         return NULL;
00755     }
00756 
00757     return sn_grs_search_resource(handle->grs, pathlen, path_ptr, SN_GRS_SEARCH_METHOD);
00758 }
00759 
00760 
00761 /**
00762  * \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)
00763  *
00764  *
00765  * \brief To send NSDL messages. Stores message id?s and message description to catch response from NSP server
00766  * \param   *handle             Pointer to nsdl-library handle
00767  * \param   *coap_header_ptr    Pointer to the CoAP message header to be sent
00768  * \param   *dst_addr_ptr       Pointer to the address structure that contains destination address information
00769  * \param   message_description Message description to be stored to list for waiting response
00770  *
00771  * \return  message id, 0 if failed
00772  */
00773 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)
00774 {
00775 
00776     tr_debug("sn_nsdl_internal_coap_send");
00777     uint8_t     *coap_message_ptr   = NULL;
00778     int32_t     coap_message_len    = 0;
00779     uint16_t    coap_header_len     = 0;
00780 
00781 #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwising is not used at all, this part of code will not be compiled */
00782     int8_t ret_val = prepare_blockwise_message(handle->grs->coap, coap_header_ptr);
00783     if( 0 != ret_val ) {
00784         return 0;
00785     }
00786 #endif
00787 
00788     coap_message_len = sn_coap_builder_calc_needed_packet_data_size_2(coap_header_ptr, handle->grs->coap->sn_coap_block_data_size);
00789     tr_debug("sn_nsdl_internal_coap_send - msg len after calc: [%d]", coap_message_len);
00790     if (coap_message_len == 0) {
00791         return 0;
00792     }
00793 
00794     coap_message_ptr = handle->sn_nsdl_alloc(coap_message_len);
00795     if (!coap_message_ptr) {
00796         return 0;
00797     }
00798 
00799     coap_header_len = coap_header_ptr->payload_len;
00800     /* Build message */
00801     if (sn_coap_protocol_build(handle->grs->coap, dst_addr_ptr, coap_message_ptr, coap_header_ptr, (void *)handle) < 0) {
00802         handle->sn_nsdl_free(coap_message_ptr);
00803         return 0;
00804     }
00805 
00806     /* If mesage type is confirmable, save it to list to wait for reply */
00807     if (coap_header_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE) {
00808         if (message_description == SN_NSDL_MSG_REGISTER) {
00809             handle->register_msg_id = coap_header_ptr->msg_id;
00810             handle->register_msg_len = coap_header_len;
00811         }
00812         else if (message_description == SN_NSDL_MSG_UNREGISTER) {
00813             handle->unregister_msg_id = coap_header_ptr->msg_id;
00814         }
00815         else if (message_description == SN_NSDL_MSG_UPDATE) {
00816             handle->update_register_msg_id = coap_header_ptr->msg_id;
00817             handle->update_register_msg_len = coap_header_len;
00818         }
00819         else if (message_description == SN_NSDL_MSG_BOOTSTRAP) {
00820             handle->bootstrap_msg_id = coap_header_ptr->msg_id;
00821         }
00822     }
00823 
00824     handle->sn_nsdl_tx_callback(handle, SN_NSDL_PROTOCOL_COAP, coap_message_ptr, coap_message_len, dst_addr_ptr);
00825     handle->sn_nsdl_free(coap_message_ptr);
00826 
00827     return coap_header_ptr->msg_id;
00828 }
00829 
00830 /**
00831  * \fn static void sn_nsdl_resolve_nsp_address(struct nsdl_s *handle)
00832  *
00833  * \brief Resolves NSP server address.
00834  *
00835  * \param *handle Pointer to nsdl-library handle
00836  * \note Application must set NSP address with set_nsp_address
00837  */
00838 static void sn_nsdl_resolve_nsp_address(struct nsdl_s *handle)
00839 {
00840     /* Local variables */
00841     if (!handle->nsp_address_ptr) {
00842         //allocate only if previously not allocated
00843         handle->nsp_address_ptr = handle->sn_nsdl_alloc(sizeof(sn_nsdl_oma_server_info_t));
00844     }
00845 
00846     if (handle->nsp_address_ptr) {
00847         handle->nsp_address_ptr->omalw_server_security = SEC_NOT_SET;
00848         handle->nsp_address_ptr->omalw_address_ptr = handle->sn_nsdl_alloc(sizeof(sn_nsdl_addr_s));
00849         if (handle->nsp_address_ptr->omalw_address_ptr) {
00850             memset(handle->nsp_address_ptr->omalw_address_ptr, 0, sizeof(sn_nsdl_addr_s));
00851             handle->nsp_address_ptr->omalw_address_ptr->type = SN_NSDL_ADDRESS_TYPE_NONE;
00852         }
00853     }
00854 }
00855 
00856 /**
00857  * \fn int8_t sn_nsdl_build_registration_body(struct nsdl_s *handle, sn_coap_hdr_s *message_ptr, uint8_t updating_registeration)
00858  *
00859  * \brief   To build GRS resources to registration message payload
00860  * \param *handle Pointer to nsdl-library handle
00861  * \param   *message_ptr Pointer to CoAP message header
00862  *
00863  * \return  SN_NSDL_SUCCESS = 0, Failed = -1
00864  */
00865 int8_t sn_nsdl_build_registration_body(struct nsdl_s *handle, sn_coap_hdr_s *message_ptr, uint8_t updating_registeration)
00866 {
00867     tr_debug("sn_nsdl_build_registration_body");
00868     /* Local variables */
00869     uint8_t                 *temp_ptr;
00870     sn_nsdl_dynamic_resource_parameters_s   *resource_temp_ptr;
00871 
00872     /* Calculate needed memory and allocate */
00873     int8_t error = 0;
00874     uint16_t msg_len = sn_nsdl_calculate_registration_body_size(handle, updating_registeration, &error);
00875     if (SN_NSDL_FAILURE == error) {
00876         return error;
00877     }
00878 
00879     if (!msg_len) {
00880         return SN_NSDL_SUCCESS;
00881     } else {
00882         message_ptr->payload_len = msg_len;
00883     }
00884     tr_debug("sn_nsdl_build_registration_body - body size: [%d]", message_ptr->payload_len);
00885     message_ptr->payload_ptr = handle->sn_nsdl_alloc(message_ptr->payload_len);
00886     if (!message_ptr->payload_ptr) {
00887         return SN_NSDL_FAILURE;
00888     }
00889 
00890     /* Build message */
00891     temp_ptr = message_ptr->payload_ptr;
00892 
00893     resource_temp_ptr = sn_grs_get_first_resource(handle->grs);
00894 
00895     /* Loop trough all resources */
00896     while (resource_temp_ptr) {
00897         /* if resource needs to be registered */
00898         if (resource_temp_ptr->publish_uri) {
00899             if (updating_registeration && resource_temp_ptr->registered == SN_NDSL_RESOURCE_REGISTERED) {
00900                 resource_temp_ptr = sn_grs_get_next_resource(handle->grs, resource_temp_ptr);
00901                 continue;
00902             } else {
00903                 resource_temp_ptr->registered = SN_NDSL_RESOURCE_REGISTERED;
00904             }
00905 
00906             /* If not first resource, add '.' to separator */
00907             if (temp_ptr != message_ptr->payload_ptr) {
00908                 *temp_ptr++ = ',';
00909             }
00910 
00911             *temp_ptr++ = '<';
00912             *temp_ptr++ = '/';
00913             memcpy(temp_ptr,
00914                    resource_temp_ptr->static_resource_parameters->path,
00915                    resource_temp_ptr->static_resource_parameters->pathlen);
00916             temp_ptr += resource_temp_ptr->static_resource_parameters->pathlen;
00917             *temp_ptr++ = '>';
00918 
00919             /* Resource attributes */
00920             size_t resource_type_len = 0;
00921             if (resource_temp_ptr->static_resource_parameters->resource_type_ptr) {
00922                 resource_type_len = strlen(resource_temp_ptr->static_resource_parameters->resource_type_ptr);
00923             }
00924             if (resource_type_len) {
00925                 *temp_ptr++ = ';';
00926                 memcpy(temp_ptr, resource_type_parameter, RT_PARAMETER_LEN);
00927                 temp_ptr += RT_PARAMETER_LEN;
00928                 *temp_ptr++ = '"';
00929                 memcpy(temp_ptr,
00930                        resource_temp_ptr->static_resource_parameters->resource_type_ptr,
00931                        resource_type_len);
00932                 temp_ptr += resource_type_len;
00933                 *temp_ptr++ = '"';
00934             }
00935 
00936             size_t interface_description_len = 0;
00937             if (resource_temp_ptr->static_resource_parameters->interface_description_ptr) {
00938                 interface_description_len = strlen(resource_temp_ptr->static_resource_parameters->interface_description_ptr);
00939             }
00940 
00941             if (interface_description_len) {
00942                 *temp_ptr++ = ';';
00943                 memcpy(temp_ptr, if_description_parameter, IF_PARAMETER_LEN);
00944                 temp_ptr += IF_PARAMETER_LEN;
00945                 *temp_ptr++ = '"';
00946                 memcpy(temp_ptr,
00947                        resource_temp_ptr->static_resource_parameters->interface_description_ptr,
00948                        interface_description_len);
00949                 temp_ptr += interface_description_len;
00950                 *temp_ptr++ = '"';
00951             }
00952 
00953             if (resource_temp_ptr->coap_content_type != 0) {
00954                 *temp_ptr++ = ';';
00955                 memcpy(temp_ptr, coap_con_type_parameter, COAP_CON_PARAMETER_LEN);
00956                 temp_ptr += COAP_CON_PARAMETER_LEN;
00957                 *temp_ptr++ = '"';
00958                 temp_ptr = sn_nsdl_itoa(temp_ptr,
00959                                         resource_temp_ptr->coap_content_type);
00960                 *temp_ptr++ = '"';
00961             }
00962 
00963             /* ;obs */
00964              // This needs to be re-visited and may be need an API for maganging obs value for different server implementation
00965 #ifndef COAP_DISABLE_OBS_FEATURE
00966             if (resource_temp_ptr->observable) {
00967                 *temp_ptr++ = ';';
00968                 memcpy(temp_ptr, obs_parameter, OBS_PARAMETER_LEN);
00969                 temp_ptr += OBS_PARAMETER_LEN;
00970             }
00971 #endif
00972         }
00973         resource_temp_ptr = sn_grs_get_next_resource(handle->grs, resource_temp_ptr);
00974     }
00975     return SN_NSDL_SUCCESS;
00976 }
00977 
00978 /**
00979  * \fn static uint16_t sn_nsdl_calculate_registration_body_size(struct nsdl_s *handle, uint8_t updating_registeration, int8_t *error)
00980  *
00981  *
00982  * \brief   Calculates registration message payload size
00983  * \param   *handle                 Pointer to nsdl-library handle
00984  * \param   *updating_registeration Pointer to list of GRS resources
00985  * \param   *error                  Error code, SN_NSDL_SUCCESS or SN_NSDL_FAILURE
00986  *
00987  * \return  Needed payload size
00988  */
00989 static uint16_t sn_nsdl_calculate_registration_body_size(struct nsdl_s *handle, uint8_t updating_registeration, int8_t *error)
00990 {
00991     tr_debug("sn_nsdl_calculate_registration_body_size");
00992     /* Local variables */
00993     uint16_t return_value = 0;
00994     *error = SN_NSDL_SUCCESS;
00995     const sn_nsdl_dynamic_resource_parameters_s *resource_temp_ptr;
00996 
00997     /* check pointer */
00998     resource_temp_ptr = sn_grs_get_first_resource(handle->grs);
00999 
01000     while (resource_temp_ptr) {
01001         if (resource_temp_ptr->publish_uri) {
01002             if (updating_registeration && resource_temp_ptr->registered == SN_NDSL_RESOURCE_REGISTERED) {
01003                 resource_temp_ptr = sn_grs_get_next_resource(handle->grs, resource_temp_ptr);
01004                 continue;
01005             }
01006             /* If not first resource, then '.' will be added */
01007             if (return_value) {
01008                 if (sn_nsdl_check_uint_overflow(return_value, 1, 0)) {
01009                     return_value++;
01010                 } else {
01011                     *error = SN_NSDL_FAILURE;
01012                     break;
01013                 }
01014             }
01015 
01016             /* Count length for the resource path </path> */
01017             if (sn_nsdl_check_uint_overflow(return_value,
01018                                             3,
01019                                             resource_temp_ptr->static_resource_parameters->pathlen)) {
01020                 return_value += (3 + resource_temp_ptr->static_resource_parameters->pathlen);
01021             } else {
01022                 *error = SN_NSDL_FAILURE;
01023                 break;
01024             }
01025 
01026             /* Count lengths of the attributes */
01027 
01028             /* Resource type parameter */
01029             size_t resource_type_len = 0;
01030             if (resource_temp_ptr->static_resource_parameters->resource_type_ptr) {
01031                 resource_type_len = strlen(resource_temp_ptr->static_resource_parameters->resource_type_ptr);
01032             }
01033 
01034             if (resource_type_len) {
01035                 /* ;rt="restype" */
01036                 if (sn_nsdl_check_uint_overflow(return_value,
01037                                                 6,
01038                                                 resource_type_len)) {
01039                     return_value += (6 + resource_type_len);
01040                 } else {
01041                     *error = SN_NSDL_FAILURE;
01042                     break;
01043                 }
01044             }
01045 
01046             /* Interface description parameter */
01047             size_t interface_description_len = 0;
01048             if (resource_temp_ptr->static_resource_parameters->interface_description_ptr) {
01049                 interface_description_len = strlen(resource_temp_ptr->static_resource_parameters->interface_description_ptr);
01050             }
01051             if (interface_description_len) {
01052                 /* ;if="iftype" */
01053                 if (sn_nsdl_check_uint_overflow(return_value,
01054                                                 6,
01055                                                 interface_description_len)) {
01056                     return_value += (6 + interface_description_len);
01057                 } else {
01058                     *error = SN_NSDL_FAILURE;
01059                     break;
01060                 }
01061             }
01062 
01063             if (resource_temp_ptr->coap_content_type != 0) {
01064                 /* ;if="content" */
01065                 uint8_t len = sn_nsdl_itoa_len(resource_temp_ptr->coap_content_type);
01066                 if (sn_nsdl_check_uint_overflow(return_value, 6, len)) {
01067                     return_value += (6 + len);
01068                 } else {
01069                     *error = SN_NSDL_FAILURE;
01070                     break;
01071                 }
01072             }
01073 #ifndef COAP_DISABLE_OBS_FEATURE
01074             // This needs to be re-visited and may be need an API for maganging obs value for different server implementation
01075             if (resource_temp_ptr->observable) {
01076                 if (sn_nsdl_check_uint_overflow(return_value, 4, 0)) {
01077                     return_value += 4;
01078                 } else {
01079                     *error = SN_NSDL_FAILURE;
01080                     break;
01081                 }
01082             }
01083 #endif
01084         }
01085         resource_temp_ptr = sn_grs_get_next_resource(handle->grs, resource_temp_ptr);
01086     }
01087     return return_value;
01088 }
01089 
01090 /**
01091  * \fn static uint8_t sn_nsdl_calculate_uri_query_option_len(sn_nsdl_ep_parameters_s *endpoint_info_ptr, uint8_t msg_type)
01092  *
01093  *
01094  * \brief Calculates needed uri query option length
01095  *
01096  * \param *endpoint_info_ptr    Pointer to endpoint info structure
01097  * \param msg_type              Message type
01098  *
01099  * \return  number of parameters in uri query
01100  */
01101 static uint8_t sn_nsdl_calculate_uri_query_option_len(sn_nsdl_ep_parameters_s *endpoint_info_ptr, uint8_t msg_type)
01102 {
01103     uint8_t return_value = 0;
01104     uint8_t number_of_parameters = 0;
01105 
01106 
01107     if ((endpoint_info_ptr->endpoint_name_len != 0) && (msg_type == SN_NSDL_EP_REGISTER_MESSAGE) && endpoint_info_ptr->endpoint_name_ptr != 0) {
01108         return_value += endpoint_info_ptr->endpoint_name_len;
01109         return_value += EP_NAME_PARAMETERS_LEN; //ep=
01110         number_of_parameters++;
01111     }
01112 
01113     if ((endpoint_info_ptr->type_len != 0) && (msg_type == SN_NSDL_EP_REGISTER_MESSAGE) && (endpoint_info_ptr->type_ptr != 0)) {
01114         return_value += endpoint_info_ptr->type_len;
01115         return_value += ET_PARAMETER_LEN;       //et=
01116         number_of_parameters++;
01117     }
01118 
01119     if ((endpoint_info_ptr->lifetime_len != 0) && (endpoint_info_ptr->lifetime_ptr != 0)) {
01120         return_value += endpoint_info_ptr->lifetime_len;
01121         return_value += LT_PARAMETER_LEN;       //lt=
01122         number_of_parameters++;
01123     }
01124 
01125     if ((endpoint_info_ptr->domain_name_len != 0) && (msg_type == SN_NSDL_EP_REGISTER_MESSAGE) && (endpoint_info_ptr->domain_name_ptr != 0)) {
01126         return_value += endpoint_info_ptr->domain_name_len;
01127         return_value += DOMAIN_PARAMETER_LEN;       //d=
01128         number_of_parameters++;
01129     }
01130 
01131     if (((endpoint_info_ptr->binding_and_mode & 0x04) || (endpoint_info_ptr->binding_and_mode & 0x01)) && (msg_type == SN_NSDL_EP_REGISTER_MESSAGE)) {
01132         return_value += BS_QUEUE_MODE_PARAMATER_LEN;
01133 
01134         if (endpoint_info_ptr->binding_and_mode & 0x01) {
01135             return_value++;
01136         }
01137         if (endpoint_info_ptr->binding_and_mode & 0x04) {
01138             return_value++;
01139         }
01140         if ((endpoint_info_ptr->binding_and_mode & 0x02) && ((endpoint_info_ptr->binding_and_mode & 0x04) || (endpoint_info_ptr->binding_and_mode & 0x01))) {
01141             return_value++;
01142         }
01143 
01144         number_of_parameters++;
01145     }
01146 
01147     if (number_of_parameters != 0) {
01148         return_value += (number_of_parameters - 1);
01149     }
01150 
01151     return return_value;
01152 }
01153 
01154 /**
01155  * \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)
01156  *
01157  *
01158  * \brief Fills uri-query options to message header struct
01159  * \param *handle           Pointer to nsdl-library handle
01160  * \param *parameter_ptr    Pointer to endpoint parameters struct
01161  * \param *source_msg_ptr   Pointer to CoAP header struct
01162  * \param msg_type          Message type
01163  *
01164  * \return  SN_NSDL_SUCCESS = 0, Failed = -1
01165  */
01166 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)
01167 {
01168     uint8_t *temp_ptr = NULL;
01169     if( !validateParameters(parameter_ptr) ){
01170         return SN_NSDL_FAILURE;
01171     }
01172     source_msg_ptr->options_list_ptr->uri_query_len  = sn_nsdl_calculate_uri_query_option_len(parameter_ptr, msg_type);
01173     if (source_msg_ptr->options_list_ptr->uri_query_len == 0) {
01174         return 0;
01175     }
01176 
01177     source_msg_ptr->options_list_ptr->uri_query_ptr     =   handle->sn_nsdl_alloc(source_msg_ptr->options_list_ptr->uri_query_len);
01178 
01179     if (source_msg_ptr->options_list_ptr->uri_query_ptr == NULL) {
01180         return SN_NSDL_FAILURE;
01181     }
01182     memset(source_msg_ptr->options_list_ptr->uri_query_ptr,0,source_msg_ptr->options_list_ptr->uri_query_len);
01183 
01184     temp_ptr = source_msg_ptr->options_list_ptr->uri_query_ptr;
01185 
01186     /******************************************************/
01187     /* If endpoint name is configured, fill needed fields */
01188     /******************************************************/
01189 
01190     if ((parameter_ptr->endpoint_name_len != 0) && (parameter_ptr->endpoint_name_ptr != 0) && (msg_type == SN_NSDL_EP_REGISTER_MESSAGE)) {
01191         /* fill endpoint name, first ?ep=, then endpoint name */
01192         memcpy(temp_ptr, ep_name_parameter_string, sizeof(ep_name_parameter_string));
01193         temp_ptr += EP_NAME_PARAMETERS_LEN;
01194         memcpy(temp_ptr, parameter_ptr->endpoint_name_ptr, parameter_ptr->endpoint_name_len);
01195         temp_ptr += parameter_ptr->endpoint_name_len;
01196     }
01197 
01198     /******************************************************/
01199     /* If endpoint type is configured, fill needed fields */
01200     /******************************************************/
01201 
01202     if ((parameter_ptr->type_len != 0) && (parameter_ptr->type_ptr != 0) && (msg_type == SN_NSDL_EP_REGISTER_MESSAGE)) {
01203         if (temp_ptr != source_msg_ptr->options_list_ptr->uri_query_ptr) {
01204             *temp_ptr++ = '&';
01205         }
01206 
01207         memcpy(temp_ptr, et_parameter, sizeof(et_parameter));
01208         temp_ptr += ET_PARAMETER_LEN;
01209         memcpy(temp_ptr, parameter_ptr->type_ptr, parameter_ptr->type_len);
01210         temp_ptr += parameter_ptr->type_len;
01211     }
01212 
01213 
01214     /******************************************************/
01215     /* If lifetime is configured, fill needed fields */
01216     /******************************************************/
01217 
01218     if ((parameter_ptr->lifetime_len != 0) && (parameter_ptr->lifetime_ptr != 0)) {
01219         if (temp_ptr != source_msg_ptr->options_list_ptr->uri_query_ptr) {
01220             *temp_ptr++ = '&';
01221         }
01222 
01223         memcpy(temp_ptr, ep_lifetime_parameter, sizeof(ep_lifetime_parameter));
01224         temp_ptr += LT_PARAMETER_LEN;
01225         memcpy(temp_ptr, parameter_ptr->lifetime_ptr, parameter_ptr->lifetime_len);
01226         temp_ptr += parameter_ptr->lifetime_len;
01227     }
01228 
01229     /******************************************************/
01230     /* If domain is configured, fill needed fields */
01231     /******************************************************/
01232 
01233     if ((parameter_ptr->domain_name_len != 0) && (parameter_ptr->domain_name_ptr != 0) && (msg_type == SN_NSDL_EP_REGISTER_MESSAGE)) {
01234         if (temp_ptr != source_msg_ptr->options_list_ptr->uri_query_ptr) {
01235             *temp_ptr++ = '&';
01236         }
01237 
01238         memcpy(temp_ptr, ep_domain_parameter, sizeof(ep_domain_parameter));
01239         temp_ptr += DOMAIN_PARAMETER_LEN;
01240         memcpy(temp_ptr, parameter_ptr->domain_name_ptr, parameter_ptr->domain_name_len);
01241         temp_ptr += parameter_ptr->domain_name_len;
01242     }
01243 
01244     /******************************************************/
01245     /* If queue-mode is configured, fill needed fields    */
01246     /******************************************************/
01247 
01248     if (((parameter_ptr->binding_and_mode & 0x01) || (parameter_ptr->binding_and_mode & 0x04)) && (msg_type == SN_NSDL_EP_REGISTER_MESSAGE)) {
01249         if (temp_ptr != source_msg_ptr->options_list_ptr->uri_query_ptr) {
01250             *temp_ptr++ = '&';
01251         }
01252 
01253         memcpy(temp_ptr, bs_queue_mode, sizeof(bs_queue_mode));
01254         temp_ptr += BS_QUEUE_MODE_PARAMATER_LEN;
01255 
01256         if (parameter_ptr->binding_and_mode & 0x01) {
01257             *temp_ptr++ = 'U';
01258             if (parameter_ptr->binding_and_mode & 0x02) {
01259                 *temp_ptr++ = 'Q';
01260             }
01261         }
01262 
01263         if (parameter_ptr->binding_and_mode & 0x04) {
01264             *temp_ptr++ = 'S';
01265             if ((parameter_ptr->binding_and_mode & 0x02) && !(parameter_ptr->binding_and_mode & 0x01)) {
01266                 *temp_ptr++ = 'Q';
01267             }
01268         }
01269     }
01270 
01271     return SN_NSDL_SUCCESS;
01272 }
01273 
01274 static bool validateParameters(sn_nsdl_ep_parameters_s *parameter_ptr)
01275 {
01276     if( !validate( parameter_ptr->domain_name_ptr, parameter_ptr->domain_name_len, '&' ) ){
01277         return false;
01278     }
01279 
01280     if( !validate( parameter_ptr->endpoint_name_ptr, parameter_ptr->endpoint_name_len, '&' ) ){
01281         return false;
01282     }
01283 
01284     if( !validate( parameter_ptr->lifetime_ptr, parameter_ptr->lifetime_len, '&' ) ){
01285         return false;
01286     }
01287 
01288     if( !validate( parameter_ptr->type_ptr, parameter_ptr->type_len, '&' ) ){
01289         return false;
01290     }
01291     return true;
01292 }
01293 
01294 static bool validate(uint8_t* ptr, uint32_t len, char illegalChar)
01295 {
01296     if( ptr ){
01297         for( uint32_t i=0; i < len; i++ ){
01298             if( ptr[i] == illegalChar ){
01299                 return false;
01300             }
01301         }
01302     }
01303     return true;
01304 }
01305 
01306 /**
01307  * \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)
01308  *
01309  * \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.
01310  * \param *handle           Pointer to nsdl-library handle
01311  * \param *coap_packet_ptr  Pointer to received CoAP packet
01312  * \param *address_ptr      Pointer to source address struct
01313  *
01314  * \return      SN_NSDL_SUCCESS = 0, Failed = -1
01315  */
01316 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)
01317 {
01318     if ((coap_packet_ptr == 0) || (address_ptr == 0)) {
01319         return -1;
01320     }
01321 
01322     bool is_reg_msg = false;
01323     bool is_update_reg_msg = false;
01324     bool is_unreg_msg = false;
01325     if (coap_packet_ptr->msg_code == COAP_MSG_CODE_RESPONSE_CREATED) {
01326         if (handle->grs->coap->sn_coap_block_data_size > 0) {
01327             handle->register_msg_id += handle->register_msg_len / handle->grs->coap->sn_coap_block_data_size;
01328         }
01329         if (coap_packet_ptr->msg_id == handle->register_msg_id) {
01330             handle->sn_nsdl_endpoint_registered = SN_NSDL_ENDPOINT_IS_REGISTERED;
01331             is_reg_msg = true;
01332             sn_grs_mark_resources_as_registered(handle);
01333             if (sn_nsdl_resolve_ep_information(handle, coap_packet_ptr) != SN_NSDL_SUCCESS) {
01334                 return SN_NSDL_FAILURE;
01335             }
01336         }
01337     }
01338 
01339     else if (coap_packet_ptr->msg_code == COAP_MSG_CODE_RESPONSE_CHANGED) {
01340         if (handle->grs->coap->sn_coap_block_data_size > 0) {
01341             handle->update_register_msg_id += handle->update_register_msg_len / handle->grs->coap->sn_coap_block_data_size;
01342         }
01343         if (coap_packet_ptr->msg_id == handle->update_register_msg_id) {
01344             is_update_reg_msg = true;
01345         }
01346     }
01347 
01348     if (coap_packet_ptr->msg_id == handle->unregister_msg_id) {
01349         is_unreg_msg = true;
01350         if (coap_packet_ptr->msg_code == COAP_MSG_CODE_RESPONSE_DELETED) {
01351             if (handle->ep_information_ptr->endpoint_name_ptr) {
01352                 handle->sn_nsdl_free(handle->ep_information_ptr->endpoint_name_ptr);
01353                 handle->ep_information_ptr->endpoint_name_ptr = 0;
01354                 handle->ep_information_ptr->endpoint_name_len = 0;
01355             }
01356             if (handle->ep_information_ptr->domain_name_ptr) {
01357                 handle->sn_nsdl_free(handle->ep_information_ptr->domain_name_ptr);
01358                 handle->ep_information_ptr->domain_name_ptr = 0;
01359                 handle->ep_information_ptr->domain_name_len = 0;
01360             }
01361         }
01362     }
01363 
01364     /* No messages to wait for, or message was not response to our request */
01365     int ret = handle->sn_nsdl_rx_callback(handle, coap_packet_ptr, address_ptr);
01366     if (is_reg_msg) {
01367         handle->register_msg_id = 0;
01368         handle->register_msg_len = 0;
01369     }
01370     else if (is_unreg_msg) {
01371         handle->unregister_msg_id = 0;
01372     }
01373     else if (is_update_reg_msg) {
01374         handle->update_register_msg_id = 0;
01375         handle->update_register_msg_len = 0;
01376     }
01377     return ret;
01378 }
01379 
01380 /**
01381  * \fn static int8_t sn_nsdl_resolve_ep_information(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr)
01382  *
01383  *
01384  * \brief Resolves endpoint information from received CoAP message
01385  * \param *handle           Pointer to nsdl-library handle
01386  * \param *coap_packet_ptr  Pointer to received CoAP message
01387  *
01388  * \return  SN_NSDL_SUCCESS = 0, Failed = -1
01389  */
01390 static int8_t sn_nsdl_resolve_ep_information(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr)
01391 {
01392     uint8_t     *temp_ptr;
01393     uint8_t     parameter_count     = 0;
01394     uint16_t    parameter_len       = 0;
01395 
01396     if (!coap_packet_ptr || !coap_packet_ptr->options_list_ptr ||
01397         !coap_packet_ptr->options_list_ptr->location_path_ptr) {
01398         return SN_NSDL_FAILURE;
01399     }
01400 
01401     temp_ptr = coap_packet_ptr->options_list_ptr->location_path_ptr;
01402 
01403     while (temp_ptr <= (coap_packet_ptr->options_list_ptr->location_path_ptr + coap_packet_ptr->options_list_ptr->location_path_len)) {
01404 
01405         if ((temp_ptr == (coap_packet_ptr->options_list_ptr->location_path_ptr + coap_packet_ptr->options_list_ptr->location_path_len)) || (*temp_ptr == '/')) {
01406 
01407             parameter_count++;
01408             if (parameter_count == 2) {
01409                 if (!handle->ep_information_ptr->domain_name_ptr) {
01410                     handle->ep_information_ptr->domain_name_len = parameter_len - 1;
01411                     handle->ep_information_ptr->domain_name_ptr = handle->sn_nsdl_alloc(handle->ep_information_ptr->domain_name_len);
01412                     if (!handle->ep_information_ptr->domain_name_ptr) {
01413                         return SN_NSDL_FAILURE;
01414                     }
01415                     memcpy(handle->ep_information_ptr->domain_name_ptr, temp_ptr - handle->ep_information_ptr->domain_name_len, handle->ep_information_ptr->domain_name_len);
01416                 }
01417 
01418             }
01419             if (parameter_count == 3) {
01420                 if (!handle->ep_information_ptr->endpoint_name_ptr) {
01421                     handle->ep_information_ptr->endpoint_name_len = parameter_len - 1;
01422                     handle->ep_information_ptr->endpoint_name_ptr = handle->sn_nsdl_alloc(handle->ep_information_ptr->endpoint_name_len);
01423                     if (!handle->ep_information_ptr->endpoint_name_ptr) {
01424                         if (handle->ep_information_ptr->domain_name_ptr) {
01425                             handle->sn_nsdl_free(handle->ep_information_ptr->domain_name_ptr);
01426                             handle->ep_information_ptr->domain_name_ptr = NULL;
01427                             handle->ep_information_ptr->domain_name_len = 0;
01428                         }
01429 
01430                         return SN_NSDL_FAILURE;
01431 
01432                     }
01433                     memcpy(handle->ep_information_ptr->endpoint_name_ptr, temp_ptr - handle->ep_information_ptr->endpoint_name_len, handle->ep_information_ptr->endpoint_name_len);
01434                 }
01435             }
01436             parameter_len = 0;
01437         }
01438         parameter_len++;
01439         temp_ptr++;
01440     }
01441 
01442 
01443     return SN_NSDL_SUCCESS;
01444 }
01445 
01446 extern int8_t set_NSP_address(struct nsdl_s *handle, uint8_t *NSP_address, uint8_t address_length, uint16_t port, sn_nsdl_addr_type_e address_type)
01447 {
01448     /* Check parameters and source pointers */
01449     if (!handle || !handle->nsp_address_ptr || !handle->nsp_address_ptr->omalw_address_ptr || !NSP_address) {
01450         return SN_NSDL_FAILURE;
01451     }
01452 
01453     handle->nsp_address_ptr->omalw_address_ptr->type = address_type;
01454     handle->nsp_address_ptr->omalw_server_security = SEC_NOT_SET;
01455 
01456     if (handle->nsp_address_ptr->omalw_address_ptr->addr_ptr) {
01457         handle->sn_nsdl_free(handle->nsp_address_ptr->omalw_address_ptr->addr_ptr);
01458     }
01459 
01460     handle->nsp_address_ptr->omalw_address_ptr->addr_len = address_length;
01461 
01462     handle->nsp_address_ptr->omalw_address_ptr->addr_ptr = handle->sn_nsdl_alloc(handle->nsp_address_ptr->omalw_address_ptr->addr_len);
01463     if (!handle->nsp_address_ptr->omalw_address_ptr->addr_ptr) {
01464         return SN_NSDL_FAILURE;
01465     }
01466 
01467     memcpy(handle->nsp_address_ptr->omalw_address_ptr->addr_ptr, NSP_address, handle->nsp_address_ptr->omalw_address_ptr->addr_len);
01468     handle->nsp_address_ptr->omalw_address_ptr->port = port;
01469 
01470     return SN_NSDL_SUCCESS;
01471 }
01472 
01473 
01474 static uint8_t sn_nsdl_itoa_len(uint8_t value)
01475 {
01476     uint8_t i = 0;
01477 
01478     do {
01479         i++;
01480     } while ((value /= 10) > 0);
01481 
01482     return i;
01483 }
01484 
01485 static uint8_t *sn_nsdl_itoa(uint8_t *ptr, uint8_t value)
01486 {
01487 
01488     uint8_t start = 0;
01489     uint8_t end = 0;
01490     uint8_t i;
01491 
01492     i = 0;
01493 
01494     /* ITOA */
01495     do {
01496         ptr[i++] = (value % 10) + '0';
01497     } while ((value /= 10) > 0);
01498 
01499     end = i - 1;
01500 
01501     /* reverse (part of ITOA) */
01502     while (start < end) {
01503         uint8_t chr;
01504 
01505         chr = ptr[start];
01506         ptr[start] = ptr[end];
01507         ptr[end] = chr;
01508 
01509         start++;
01510         end--;
01511 
01512     }
01513     return (ptr + i);
01514 }
01515 
01516 static int8_t set_endpoint_info(struct nsdl_s *handle, sn_nsdl_ep_parameters_s *endpoint_info_ptr)
01517 {
01518     if (handle->ep_information_ptr->domain_name_ptr) {
01519         handle->sn_nsdl_free(handle->ep_information_ptr->domain_name_ptr);
01520         handle->ep_information_ptr->domain_name_ptr = 0;
01521         handle->ep_information_ptr->domain_name_len = 0;
01522     }
01523 
01524     if (handle->ep_information_ptr->endpoint_name_ptr) {
01525         handle->sn_nsdl_free(handle->ep_information_ptr->endpoint_name_ptr);
01526         handle->ep_information_ptr->endpoint_name_ptr = 0;
01527         handle->ep_information_ptr->endpoint_name_len = 0;
01528     }
01529 
01530     if (endpoint_info_ptr->domain_name_ptr && endpoint_info_ptr->domain_name_len) {
01531         handle->ep_information_ptr->domain_name_ptr = handle->sn_nsdl_alloc(endpoint_info_ptr->domain_name_len);
01532 
01533         if (!handle->ep_information_ptr->domain_name_ptr) {
01534             return -1;
01535         }
01536 
01537         memcpy(handle->ep_information_ptr->domain_name_ptr, endpoint_info_ptr->domain_name_ptr, endpoint_info_ptr->domain_name_len);
01538         handle->ep_information_ptr->domain_name_len = endpoint_info_ptr->domain_name_len;
01539     }
01540 
01541     if (endpoint_info_ptr->endpoint_name_ptr && endpoint_info_ptr->endpoint_name_len) {
01542         handle->ep_information_ptr->endpoint_name_ptr = handle->sn_nsdl_alloc(endpoint_info_ptr->endpoint_name_len);
01543 
01544         if (!handle->ep_information_ptr->endpoint_name_ptr) {
01545             if (handle->ep_information_ptr->domain_name_ptr) {
01546                 handle->sn_nsdl_free(handle->ep_information_ptr->domain_name_ptr);
01547                 handle->ep_information_ptr->domain_name_ptr = 0;
01548                 handle->ep_information_ptr->domain_name_len = 0;
01549             }
01550             return -1;
01551         }
01552 
01553         memcpy(handle->ep_information_ptr->endpoint_name_ptr, endpoint_info_ptr->endpoint_name_ptr, endpoint_info_ptr->endpoint_name_len);
01554         handle->ep_information_ptr->endpoint_name_len = endpoint_info_ptr->endpoint_name_len;
01555     }
01556 
01557     handle->ep_information_ptr->binding_and_mode = endpoint_info_ptr->binding_and_mode;
01558     handle->ep_information_ptr->ds_register_mode = endpoint_info_ptr->ds_register_mode;
01559 
01560     handle->ep_information_ptr->location_ptr = 0;
01561     handle->ep_information_ptr->location_len = 0;
01562 
01563     return 0;
01564 }
01565 
01566 /* Wrapper */
01567 sn_grs_resource_list_s *sn_nsdl_list_resource(struct nsdl_s *handle, uint16_t pathlen, uint8_t *path)
01568 {
01569     /* Check parameters */
01570     if (handle == NULL) {
01571         return NULL;
01572     }
01573 
01574     return sn_grs_list_resource(handle->grs, pathlen, path);
01575 }
01576 
01577 void sn_nsdl_free_resource_list(struct nsdl_s *handle, sn_grs_resource_list_s *list)
01578 {
01579     /* Check parameters */
01580     if (handle == NULL) {
01581         return;
01582     }
01583 
01584     sn_grs_free_resource_list(handle->grs, list);
01585 }
01586 
01587 #ifndef MEMORY_OPTIMIZED_API
01588 extern int8_t sn_nsdl_update_resource(struct nsdl_s *handle, sn_nsdl_dynamic_resource_parameters_s *res)
01589 {
01590     /* Check parameters */
01591     if (handle == NULL) {
01592         return SN_NSDL_FAILURE;
01593     }
01594 
01595     return sn_grs_update_resource(handle->grs, res);
01596 }
01597 
01598 extern int8_t sn_nsdl_create_resource(struct nsdl_s *handle, sn_nsdl_dynamic_resource_parameters_s *res)
01599 {
01600     /* Check parameters */
01601     if (handle == NULL) {
01602         return SN_NSDL_FAILURE;
01603     }
01604 
01605     return sn_grs_create_resource(handle->grs, res);
01606 }
01607 #endif
01608 
01609 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)
01610 {
01611     /* Check parameters */
01612     if (handle == NULL) {
01613         return SN_NSDL_FAILURE;
01614     }
01615 
01616     return sn_grs_send_coap_message(handle, address_ptr, coap_hdr_ptr);
01617 }
01618 
01619 extern int8_t sn_nsdl_put_resource(struct nsdl_s *handle, sn_nsdl_dynamic_resource_parameters_s *res)
01620 {
01621     if (!handle) {
01622         return SN_NSDL_FAILURE;
01623     }
01624 
01625     return sn_grs_put_resource(handle->grs, res);
01626 }
01627 
01628 extern int8_t sn_nsdl_pop_resource(struct nsdl_s *handle, sn_nsdl_dynamic_resource_parameters_s *res)
01629 {
01630     if (!handle) {
01631         return SN_NSDL_FAILURE;
01632     }
01633 
01634     return sn_grs_pop_resource(handle->grs, res);
01635 }
01636 
01637 extern int8_t sn_nsdl_delete_resource(struct nsdl_s *handle, uint16_t pathlen, uint8_t *path)
01638 {
01639     /* Check parameters */
01640     if (handle == NULL) {
01641         return SN_NSDL_FAILURE;
01642     }
01643 
01644     return sn_grs_delete_resource(handle->grs, pathlen, path);
01645 }
01646 extern const sn_nsdl_dynamic_resource_parameters_s *sn_nsdl_get_first_resource(struct nsdl_s *handle)
01647 {
01648     /* Check parameters */
01649     if (handle == NULL) {
01650         return NULL;
01651     }
01652 
01653     return sn_grs_get_first_resource(handle->grs);
01654 }
01655 extern const sn_nsdl_dynamic_resource_parameters_s *sn_nsdl_get_next_resource(struct nsdl_s *handle, const sn_nsdl_dynamic_resource_parameters_s *resource)
01656 {
01657     /* Check parameters */
01658     if (handle == NULL) {
01659         return NULL;
01660     }
01661 
01662     return sn_grs_get_next_resource(handle->grs, resource);
01663 }
01664 
01665 extern sn_coap_hdr_s *sn_nsdl_build_response(struct nsdl_s *handle, sn_coap_hdr_s *coap_packet_ptr, uint8_t msg_code)
01666 {
01667     if (handle == NULL) {
01668         return NULL;
01669     }
01670 
01671     return sn_coap_build_response(handle->grs->coap, coap_packet_ptr, msg_code);
01672 }
01673 
01674 extern sn_coap_options_list_s *sn_nsdl_alloc_options_list(struct nsdl_s *handle, sn_coap_hdr_s *coap_msg_ptr)
01675 {
01676     if (handle == NULL || coap_msg_ptr == NULL) {
01677         return NULL;
01678     }
01679     return sn_coap_parser_alloc_options(handle->grs->coap, coap_msg_ptr);
01680 }
01681 
01682 extern void sn_nsdl_release_allocated_coap_msg_mem(struct nsdl_s *handle, sn_coap_hdr_s *freed_coap_msg_ptr)
01683 {
01684     if (handle == NULL) {
01685         return;
01686     }
01687 
01688     sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, freed_coap_msg_ptr);
01689 }
01690 
01691 extern int8_t sn_nsdl_set_retransmission_parameters(struct nsdl_s *handle,
01692     uint8_t resending_count, uint8_t resending_interval)
01693 {
01694     if (handle == NULL) {
01695         return SN_NSDL_FAILURE;
01696     }
01697     return sn_coap_protocol_set_retransmission_parameters(handle->grs->coap,
01698                                                           resending_count,resending_interval);
01699 }
01700 
01701 extern int8_t sn_nsdl_set_retransmission_buffer(struct nsdl_s *handle,
01702         uint8_t buffer_size_messages, uint16_t buffer_size_bytes)
01703 {
01704     if (handle == NULL) {
01705         return SN_NSDL_FAILURE;
01706     }
01707     return sn_coap_protocol_set_retransmission_buffer(handle->grs->coap,
01708                                                       buffer_size_messages, buffer_size_bytes);
01709 }
01710 
01711 extern int8_t sn_nsdl_set_block_size(struct nsdl_s *handle, uint16_t block_size)
01712 {
01713     if (handle == NULL) {
01714         return SN_NSDL_FAILURE;
01715     }
01716     return sn_coap_protocol_set_block_size(handle->grs->coap, block_size);
01717 }
01718 
01719 extern int8_t sn_nsdl_set_duplicate_buffer_size(struct nsdl_s *handle, uint8_t message_count)
01720 {
01721     if (handle == NULL) {
01722         return SN_NSDL_FAILURE;
01723     }
01724     return sn_coap_protocol_set_duplicate_buffer_size(handle->grs->coap, message_count);
01725 }
01726 
01727 bool sn_nsdl_check_uint_overflow(uint16_t resource_size, uint16_t param_a, uint16_t param_b)
01728 {
01729     uint16_t first_check = param_a + param_b;
01730     if (first_check < param_b) {
01731         return false;
01732     } else {
01733         uint16_t total = resource_size + first_check;
01734         if (total < first_check) {
01735             return false;
01736         } else {
01737             return true;
01738         }
01739     }
01740 }
01741 
01742 extern int8_t sn_nsdl_set_context(struct nsdl_s * const handle, void * const context)
01743 {
01744     if (handle == NULL) {
01745         return SN_NSDL_FAILURE;
01746     }
01747     handle->context = context;
01748     return SN_NSDL_SUCCESS;
01749 }
01750 
01751 extern void *sn_nsdl_get_context(const struct nsdl_s * const handle)
01752 {
01753     if (handle == NULL) {
01754         return NULL;
01755     }
01756     return handle->context;
01757 }
01758 
01759 #endif
01760