joey shelton / LED_Demo

Dependencies:   MAX44000 PWM_Tone_Library nexpaq_mdk

Fork of LED_Demo by Maxim nexpaq

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sn_grs.c Source File

sn_grs.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 /**
00018  *
00019  * \file sn_grs.c
00020  *
00021  * \brief General resource server.
00022  *
00023  */
00024 #include <string.h>
00025 #include <stdlib.h>
00026 
00027 #include "ns_list.h"
00028 #include "ns_types.h"
00029 #include "sn_nsdl.h"
00030 #include "sn_coap_header.h"
00031 #include "sn_coap_protocol.h"
00032 #include "sn_coap_protocol_internal.h"
00033 #include "sn_nsdl_lib.h"
00034 #include "sn_grs.h"
00035 #include "mbed-trace/mbed_trace.h"
00036 
00037 /* Defines */
00038 #define TRACE_GROUP "coap"
00039 #define WELLKNOWN_PATH_LEN              16
00040 #define WELLKNOWN_PATH                  (".well-known/core")
00041 
00042 /* Local static function prototypes */
00043 static int8_t                       sn_grs_resource_info_free(struct grs_s *handle, sn_nsdl_resource_info_s *resource_ptr);
00044 static uint8_t                     *sn_grs_convert_uri(uint16_t *uri_len, uint8_t *uri_ptr);
00045 static int8_t                       sn_grs_add_resource_to_list(struct grs_s *handle, sn_nsdl_resource_info_s *resource_ptr);
00046 static int8_t                       sn_grs_core_request(struct nsdl_s *handle, sn_nsdl_addr_s *src_addr_ptr, sn_coap_hdr_s *coap_packet_ptr);
00047 static uint8_t                      coap_tx_callback(uint8_t *, uint16_t, sn_nsdl_addr_s *, void *);
00048 static int8_t                       coap_rx_callback(sn_coap_hdr_s *coap_ptr, sn_nsdl_addr_s *address_ptr, void *param);
00049 
00050 /* Extern function prototypes */
00051 extern int8_t                       sn_nsdl_build_registration_body(struct nsdl_s *handle, sn_coap_hdr_s *message_ptr, uint8_t updating_registeration);
00052 
00053 /**
00054  * \fn int8_t sn_grs_destroy(void)
00055  * \brief This function may be used to flush GRS related stuff when a program exits.
00056  * @return always 0.
00057  */
00058 extern int8_t sn_grs_destroy(struct grs_s *handle)
00059 {
00060     if( handle == NULL ){
00061         return 0;
00062     }
00063     ns_list_foreach_safe(sn_nsdl_resource_info_s, tmp, &handle->resource_root_list) {
00064         ns_list_remove(&handle->resource_root_list, tmp);
00065         --handle->resource_root_count;
00066         sn_grs_resource_info_free(handle, tmp);
00067     }
00068     handle->sn_grs_free(handle);
00069 
00070     return 0;
00071 }
00072 
00073 static uint8_t coap_tx_callback(uint8_t *data_ptr, uint16_t data_len, sn_nsdl_addr_s *address_ptr, void *param)
00074 {
00075     struct nsdl_s *handle = (struct nsdl_s *)param;
00076 
00077     if (handle == NULL) {
00078         return 0;
00079     }
00080 
00081     return handle->grs->sn_grs_tx_callback(handle, SN_NSDL_PROTOCOL_COAP, data_ptr, data_len, address_ptr);
00082 }
00083 
00084 static int8_t coap_rx_callback(sn_coap_hdr_s *coap_ptr, sn_nsdl_addr_s *address_ptr, void *param)
00085 {
00086     struct nsdl_s *handle = (struct nsdl_s *)param;
00087 
00088     if (handle == NULL) {
00089         return 0;
00090     }
00091 
00092     return handle->sn_nsdl_rx_callback(handle, coap_ptr, address_ptr);
00093 }
00094 
00095 /**
00096  * \fn int8_t sn_grs_init   (uint8_t (*sn_grs_tx_callback_ptr)(sn_nsdl_capab_e , uint8_t *, uint16_t,
00097  *      sn_nsdl_addr_s *), int8_t (*sn_grs_rx_callback_ptr)(sn_coap_hdr_s *, sn_nsdl_addr_s *), sn_nsdl_mem_s *sn_memory)
00098  *
00099  * \brief GRS library initialize function.
00100  *
00101  * This function initializes GRS and CoAP libraries.
00102  *
00103  * \param   sn_grs_tx_callback      A function pointer to a transmit callback function.
00104  * \param  *sn_grs_rx_callback_ptr A function pointer to a receiving callback function. If received packet is not for GRS, it will be passed to
00105  *                                  upper level (NSDL) to be proceed.
00106  * \param   sn_memory               A pointer to a structure containing the platform specific functions for memory allocation and free.
00107  *
00108  * \return success = 0, failure = -1
00109  *
00110 */
00111 extern struct grs_s *sn_grs_init(uint8_t (*sn_grs_tx_callback_ptr)(struct nsdl_s *, sn_nsdl_capab_e , uint8_t *, uint16_t,
00112                                  sn_nsdl_addr_s *), int8_t (*sn_grs_rx_callback_ptr)(struct nsdl_s *, sn_coap_hdr_s *, sn_nsdl_addr_s *),
00113                                  void *(*sn_grs_alloc)(uint16_t), void (*sn_grs_free)(void *))
00114 {
00115 
00116     struct grs_s *handle_ptr = NULL;
00117 
00118     /* Check parameters */
00119     if (sn_grs_alloc == NULL || sn_grs_free == NULL ||
00120         sn_grs_tx_callback_ptr == NULL || sn_grs_rx_callback_ptr == NULL) {
00121         return NULL;
00122     }
00123 
00124     handle_ptr = sn_grs_alloc(sizeof(struct grs_s));
00125 
00126     if (handle_ptr == NULL) {
00127         return NULL;
00128     }
00129 
00130     memset(handle_ptr, 0, sizeof(struct grs_s));
00131 
00132     /* Allocation and free - function pointers  */
00133     handle_ptr->sn_grs_alloc = sn_grs_alloc;
00134     handle_ptr->sn_grs_free = sn_grs_free;
00135 
00136     /* TX callback function pointer */
00137     handle_ptr->sn_grs_tx_callback = sn_grs_tx_callback_ptr;
00138     handle_ptr->sn_grs_rx_callback = sn_grs_rx_callback_ptr;
00139 
00140     /* Initialize CoAP protocol library */
00141     handle_ptr->coap = sn_coap_protocol_init(sn_grs_alloc, sn_grs_free, coap_tx_callback, coap_rx_callback);
00142 
00143     return handle_ptr;
00144 }
00145 
00146 
00147 extern sn_grs_resource_list_s *sn_grs_list_resource(struct grs_s *handle, uint16_t pathlen, uint8_t *path)
00148 {
00149     (void) pathlen;
00150     sn_grs_resource_list_s *grs_resource_list_ptr = NULL;
00151 
00152     if( handle == NULL || path == NULL){
00153         return NULL;
00154     }
00155 
00156     /* Allocate memory for the resource list to be filled */
00157     grs_resource_list_ptr = handle->sn_grs_alloc(sizeof(sn_grs_resource_list_s));
00158     if (!grs_resource_list_ptr) {
00159         goto fail;
00160     }
00161 
00162     /* Count resources to the resource list struct */
00163     grs_resource_list_ptr->res_count = handle->resource_root_count;
00164     grs_resource_list_ptr->res = NULL;
00165 
00166     /**************************************/
00167     /* Fill resource structs to the table */
00168     /**************************************/
00169 
00170     /* If resources in list */
00171     if (grs_resource_list_ptr->res_count) {
00172         int i;
00173 
00174         /* Allocate memory for resources */
00175         grs_resource_list_ptr->res = handle->sn_grs_alloc(grs_resource_list_ptr->res_count * sizeof(sn_grs_resource_s));
00176         if (!grs_resource_list_ptr->res) {
00177             goto fail;
00178         }
00179 
00180         /* Initialise the pointers to NULL to permit easy cleanup */
00181         for (i = 0; i < grs_resource_list_ptr->res_count; i++) {
00182             grs_resource_list_ptr->res[i].path = NULL;
00183             grs_resource_list_ptr->res[i].pathlen = 0;
00184         }
00185 
00186         i = 0;
00187         ns_list_foreach(sn_nsdl_resource_info_s, grs_resource_ptr, &handle->resource_root_list) {
00188             /* Copy pathlen to resource list */
00189             grs_resource_list_ptr->res[i].pathlen = grs_resource_ptr->pathlen;
00190 
00191             /* Allocate memory for path string */
00192             grs_resource_list_ptr->res[i].path = handle->sn_grs_alloc(grs_resource_list_ptr->res[i].pathlen);
00193             if (!grs_resource_list_ptr->res[i].path) {
00194                 goto fail;
00195             }
00196 
00197             /* Copy pathstring to resource list */
00198             memcpy(grs_resource_list_ptr->res[i].path, grs_resource_ptr->path, grs_resource_ptr->pathlen);
00199 
00200             i++;
00201         }
00202     }
00203     return grs_resource_list_ptr;
00204 
00205 fail:
00206     sn_grs_free_resource_list(handle, grs_resource_list_ptr);
00207     return NULL;
00208 }
00209 
00210 extern void sn_grs_free_resource_list(struct grs_s *handle, sn_grs_resource_list_s *list)
00211 {
00212     if (!list || !handle) {
00213         return;
00214     }
00215 
00216     if (list->res) {
00217         for (int i = 0; i < list->res_count; i++) {
00218             if (list->res[i].path) {
00219                 handle->sn_grs_free(list->res[i].path);
00220                 list->res[i].path = NULL;
00221             }
00222         }
00223         handle->sn_grs_free(list->res);
00224         list->res = NULL;
00225     }
00226 
00227     handle->sn_grs_free(list);
00228 }
00229 
00230 extern const sn_nsdl_resource_info_s *sn_grs_get_first_resource(struct grs_s *handle)
00231 {
00232     if( !handle ){
00233         return NULL;
00234     }
00235     return ns_list_get_first(&handle->resource_root_list);
00236 }
00237 
00238 extern const sn_nsdl_resource_info_s *sn_grs_get_next_resource(struct grs_s *handle, const sn_nsdl_resource_info_s *sn_grs_current_resource)
00239 {
00240     if( !handle || !sn_grs_current_resource ){
00241         return NULL;
00242     }
00243     return ns_list_get_next(&handle->resource_root_list, sn_grs_current_resource);
00244 }
00245 
00246 extern int8_t sn_grs_delete_resource(struct grs_s *handle, uint16_t pathlen, uint8_t *path)
00247 {
00248     /* Local variables */
00249     sn_nsdl_resource_info_s     *resource_temp  = NULL;
00250 
00251     /* Search if resource found */
00252     resource_temp = sn_grs_search_resource(handle, pathlen, path, SN_GRS_SEARCH_METHOD);
00253 
00254     /* If not found */
00255     if (resource_temp == NULL) {
00256         return SN_NSDL_FAILURE;
00257     }
00258 
00259     /* If found, delete it and delete also subresources, if there is any */
00260     do {
00261         /* Remove from list */
00262         ns_list_remove(&handle->resource_root_list, resource_temp);
00263         --handle->resource_root_count;
00264 
00265         /* Free */
00266         sn_grs_resource_info_free(handle, resource_temp);
00267 
00268         /* Search for subresources */
00269         resource_temp = sn_grs_search_resource(handle, pathlen, path, SN_GRS_DELETE_METHOD);
00270     } while (resource_temp != NULL);
00271 
00272     return SN_NSDL_SUCCESS;
00273 }
00274 
00275 extern int8_t sn_grs_update_resource(struct grs_s *handle, sn_nsdl_resource_info_s *res)
00276 {
00277     /* Local variables */
00278     sn_nsdl_resource_info_s     *resource_temp  = NULL;
00279 
00280     if( !res || !handle ){
00281         return SN_NSDL_FAILURE;
00282     }
00283 
00284     /* Search resource */
00285     resource_temp = sn_grs_search_resource(handle, res->pathlen, res->path, SN_GRS_SEARCH_METHOD);
00286     if (!resource_temp) {
00287         return SN_NSDL_FAILURE;
00288     }
00289 
00290     /* If there is payload on resource, free it */
00291     if (resource_temp->resource != NULL) {
00292         handle->sn_grs_free(resource_temp->resource);
00293         resource_temp->resource = 0;
00294     }
00295     /* Update resource len */
00296     resource_temp->resourcelen = res->resourcelen;
00297 
00298     /* If resource len >0, allocate memory and copy payload */
00299     if (res->resourcelen) {
00300         resource_temp->resource = handle->sn_grs_alloc(res->resourcelen);
00301         if (resource_temp->resource == NULL) {
00302 
00303             resource_temp->resourcelen = 0;
00304             return SN_NSDL_FAILURE;
00305 
00306         }
00307 
00308         memcpy(resource_temp->resource, res->resource, resource_temp->resourcelen);
00309     }
00310 
00311     /* Update access rights and callback address */
00312     resource_temp->access = res->access;
00313     resource_temp->sn_grs_dyn_res_callback = res->sn_grs_dyn_res_callback;
00314 
00315     /* TODO: resource_parameters_ptr not copied */
00316 
00317     return SN_NSDL_SUCCESS;
00318 }
00319 
00320 extern int8_t sn_grs_create_resource(struct grs_s *handle, sn_nsdl_resource_info_s *res)
00321 {
00322     if (!res || !handle) {
00323         return SN_NSDL_FAILURE;
00324     }
00325 
00326     /* Check path validity */
00327     if (!res->pathlen || !res->path) {
00328         return SN_GRS_INVALID_PATH;
00329     }
00330 
00331     /* Check if resource already exists */
00332     if (sn_grs_search_resource(handle, res->pathlen, res->path, SN_GRS_SEARCH_METHOD) != (sn_nsdl_resource_info_s *)NULL) {
00333         return SN_GRS_RESOURCE_ALREADY_EXISTS;
00334     }
00335 
00336     if (res->resource_parameters_ptr) {
00337         res->resource_parameters_ptr->registered = SN_NDSL_RESOURCE_NOT_REGISTERED;
00338     }
00339 
00340     /* Create resource */
00341     if (sn_grs_add_resource_to_list(handle, res) == SN_NSDL_SUCCESS) {
00342         return SN_NSDL_SUCCESS;
00343     }
00344     return SN_GRS_LIST_ADDING_FAILURE;
00345 }
00346 
00347 
00348 
00349 /**
00350  * \fn  extern int8_t sn_grs_process_coap(uint8_t *packet, uint16_t *packet_len, sn_nsdl_addr_s *src)
00351  *
00352  * \brief To push CoAP packet to GRS library
00353  *
00354  *  Used to push an CoAP packet to GRS library for processing.
00355  *
00356  *  \param  *packet     Pointer to a uint8_t array containing the packet (including the CoAP headers).
00357  *                      After successful execution this array may contain the response packet.
00358  *
00359  *  \param  *packet_len Pointer to length of the packet. After successful execution this array may contain the length
00360  *                      of the response packet.
00361  *
00362  *  \param  *src        Pointer to packet source address information. After successful execution this array may contain
00363  *                      the destination address of the response packet.
00364  *
00365  *  \return             0 = success, -1 = failure
00366 */
00367 extern int8_t sn_grs_process_coap(struct nsdl_s *nsdl_handle, sn_coap_hdr_s *coap_packet_ptr, sn_nsdl_addr_s *src_addr_ptr)
00368 {
00369     if( !coap_packet_ptr || !nsdl_handle){
00370         return SN_NSDL_FAILURE;
00371     }
00372 
00373     sn_nsdl_resource_info_s *resource_temp_ptr  = NULL;
00374     sn_coap_msg_code_e      status              = COAP_MSG_CODE_EMPTY;
00375     sn_coap_hdr_s           *response_message_hdr_ptr = NULL;
00376     struct grs_s            *handle = nsdl_handle->grs;
00377     bool                    static_get_request = false;
00378 
00379     if (coap_packet_ptr->msg_code <= COAP_MSG_CODE_REQUEST_DELETE) {
00380         /* Check if .well-known/core */
00381         if (coap_packet_ptr->uri_path_len == WELLKNOWN_PATH_LEN && memcmp(coap_packet_ptr->uri_path_ptr, WELLKNOWN_PATH, WELLKNOWN_PATH_LEN) == 0) {
00382             return sn_grs_core_request(nsdl_handle, src_addr_ptr, coap_packet_ptr);
00383         }
00384 
00385         /* Get resource */
00386         resource_temp_ptr = sn_grs_search_resource(handle, coap_packet_ptr->uri_path_len, coap_packet_ptr->uri_path_ptr, SN_GRS_SEARCH_METHOD);
00387 
00388         /* * * * * * * * * * * */
00389         /* If resource exists  */
00390         /* * * * * * * * * * * */
00391         if (resource_temp_ptr) {
00392             /* If dynamic resource, go to callback */
00393             if (resource_temp_ptr->mode == SN_GRS_DYNAMIC) {
00394                 /* Check accesses */
00395                 if (((coap_packet_ptr->msg_code == COAP_MSG_CODE_REQUEST_GET) && !(resource_temp_ptr->access & SN_GRS_GET_ALLOWED))          ||
00396                         ((coap_packet_ptr->msg_code == COAP_MSG_CODE_REQUEST_POST) && !(resource_temp_ptr->access & SN_GRS_POST_ALLOWED))   ||
00397                         ((coap_packet_ptr->msg_code == COAP_MSG_CODE_REQUEST_PUT) && !(resource_temp_ptr->access & SN_GRS_PUT_ALLOWED))     ||
00398                         ((coap_packet_ptr->msg_code == COAP_MSG_CODE_REQUEST_DELETE) && !(resource_temp_ptr->access & SN_GRS_DELETE_ALLOWED))) {
00399 
00400                     status = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
00401                 } else {
00402                     /* Do not call null pointer.. */
00403                     if (resource_temp_ptr->sn_grs_dyn_res_callback != NULL) {
00404                         resource_temp_ptr->sn_grs_dyn_res_callback(nsdl_handle, coap_packet_ptr, src_addr_ptr, SN_NSDL_PROTOCOL_COAP);
00405                     }
00406 
00407                     if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) {
00408                         handle->sn_grs_free(coap_packet_ptr->payload_ptr);
00409                         coap_packet_ptr->payload_ptr = 0;
00410                     }
00411                     sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_packet_ptr);
00412                     return SN_NSDL_SUCCESS;
00413                 }
00414             } else {
00415                 /* Static resource handling */
00416                 switch (coap_packet_ptr->msg_code) {
00417                     case (COAP_MSG_CODE_REQUEST_GET):
00418                         if (resource_temp_ptr->access & SN_GRS_GET_ALLOWED) {
00419                             status = COAP_MSG_CODE_RESPONSE_CONTENT;
00420                             static_get_request = true;
00421                         } else {
00422                             status = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
00423                         }
00424                         break;
00425                     case (COAP_MSG_CODE_REQUEST_POST):
00426                         if (resource_temp_ptr->access & SN_GRS_POST_ALLOWED) {
00427                             resource_temp_ptr->resourcelen = coap_packet_ptr->payload_len;
00428                             handle->sn_grs_free(resource_temp_ptr->resource);
00429                             resource_temp_ptr->resource = 0;
00430                             if (resource_temp_ptr->resourcelen) {
00431                                 resource_temp_ptr->resource = handle->sn_grs_alloc(resource_temp_ptr->resourcelen);
00432                                 if (!resource_temp_ptr->resource) {
00433                                     status = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR;
00434                                     break;
00435                                 }
00436                                 memcpy(resource_temp_ptr->resource, coap_packet_ptr->payload_ptr, resource_temp_ptr->resourcelen);
00437                             }
00438                             if (coap_packet_ptr->content_type_ptr) {
00439                                 if (resource_temp_ptr->resource_parameters_ptr) {
00440                                     resource_temp_ptr->resource_parameters_ptr->coap_content_type = *coap_packet_ptr->content_type_ptr;
00441                                 }
00442                             }
00443                             status = COAP_MSG_CODE_RESPONSE_CHANGED;
00444                         } else {
00445                             status = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
00446                         }
00447                         break;
00448                     case (COAP_MSG_CODE_REQUEST_PUT):
00449                         if (resource_temp_ptr->access & SN_GRS_PUT_ALLOWED) {
00450                             resource_temp_ptr->resourcelen = coap_packet_ptr->payload_len;
00451                             handle->sn_grs_free(resource_temp_ptr->resource);
00452                             resource_temp_ptr->resource = 0;
00453                             if (resource_temp_ptr->resourcelen) {
00454                                 resource_temp_ptr->resource = handle->sn_grs_alloc(resource_temp_ptr->resourcelen);
00455                                 if (!resource_temp_ptr->resource) {
00456                                     status = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR;
00457                                     break;
00458                                 }
00459                                 memcpy(resource_temp_ptr->resource, coap_packet_ptr->payload_ptr, resource_temp_ptr->resourcelen);
00460                             }
00461                             if (coap_packet_ptr->content_type_ptr) {
00462                                 if (resource_temp_ptr->resource_parameters_ptr) {
00463                                     resource_temp_ptr->resource_parameters_ptr->coap_content_type = *coap_packet_ptr->content_type_ptr;
00464                                 }
00465                             }
00466                             status = COAP_MSG_CODE_RESPONSE_CHANGED;
00467                         } else {
00468                             status = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
00469                         }
00470                         break;
00471 
00472                     case (COAP_MSG_CODE_REQUEST_DELETE):
00473                         if (resource_temp_ptr->access & SN_GRS_DELETE_ALLOWED) {
00474                             if (sn_grs_delete_resource(handle, coap_packet_ptr->uri_path_len, coap_packet_ptr->uri_path_ptr) == SN_NSDL_SUCCESS) {
00475                                 status = COAP_MSG_CODE_RESPONSE_DELETED;
00476                             } else {
00477                                 //This is dead code (Currently only time delete fails is when resource is not found
00478                                 //and sn_grs_search_resource is used with same arguments above!)
00479                                 status = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR;
00480                             }
00481                         } else {
00482                             status = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED;
00483                         }
00484                         break;
00485 
00486                     default:
00487                         status = COAP_MSG_CODE_RESPONSE_FORBIDDEN;
00488                         break;
00489                 }
00490             }
00491         }
00492 
00493         /* * * * * * * * * * * * * * */
00494         /* If resource was not found */
00495         /* * * * * * * * * * * * * * */
00496 
00497         else {
00498             if (coap_packet_ptr->msg_code == COAP_MSG_CODE_REQUEST_POST) {
00499                 handle->sn_grs_rx_callback(nsdl_handle, coap_packet_ptr, src_addr_ptr);
00500 
00501                 if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) {
00502                     handle->sn_grs_free(coap_packet_ptr->payload_ptr);
00503                     coap_packet_ptr->payload_ptr = 0;
00504                 }
00505 
00506                 sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_packet_ptr);
00507                 return SN_NSDL_SUCCESS;
00508             } else {
00509                 status = COAP_MSG_CODE_RESPONSE_NOT_FOUND;
00510             }
00511         }
00512 
00513     }
00514 
00515 
00516     /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00517     /* If received packed was other than reset, create response  */
00518     /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00519     if (coap_packet_ptr->msg_type != COAP_MSG_TYPE_RESET && coap_packet_ptr->msg_type != COAP_MSG_TYPE_ACKNOWLEDGEMENT) {
00520 
00521         /* Allocate resopnse message  */
00522         response_message_hdr_ptr = sn_coap_parser_alloc_message(handle->coap);
00523         if (!response_message_hdr_ptr) {
00524             if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) {
00525                 handle->sn_grs_free(coap_packet_ptr->payload_ptr);
00526                 coap_packet_ptr->payload_ptr = 0;
00527             }
00528             sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_packet_ptr);
00529             return SN_NSDL_FAILURE;
00530         }
00531 
00532         /* If status has not been defined, response internal server error */
00533         if (status == COAP_MSG_CODE_EMPTY) {
00534             status = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR;
00535         }
00536 
00537         /* Fill header */
00538         response_message_hdr_ptr->msg_code = status;
00539 
00540         if (coap_packet_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE) {
00541             response_message_hdr_ptr->msg_type = COAP_MSG_TYPE_ACKNOWLEDGEMENT;
00542         } else {
00543             response_message_hdr_ptr->msg_type = COAP_MSG_TYPE_NON_CONFIRMABLE;
00544         }
00545 
00546         response_message_hdr_ptr->msg_id = coap_packet_ptr->msg_id;
00547 
00548         if (coap_packet_ptr->token_ptr) {
00549             response_message_hdr_ptr->token_len = coap_packet_ptr->token_len;
00550             response_message_hdr_ptr->token_ptr = handle->sn_grs_alloc(response_message_hdr_ptr->token_len);
00551             if (!response_message_hdr_ptr->token_ptr) {
00552                 sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, response_message_hdr_ptr);
00553 
00554                 if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) {
00555                     handle->sn_grs_free(coap_packet_ptr->payload_ptr);
00556                     coap_packet_ptr->payload_ptr = 0;
00557                 }
00558 
00559                 sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_packet_ptr);
00560                 return SN_NSDL_FAILURE;
00561             }
00562             memcpy(response_message_hdr_ptr->token_ptr, coap_packet_ptr->token_ptr, response_message_hdr_ptr->token_len);
00563         }
00564 
00565         if (status == COAP_MSG_CODE_RESPONSE_CONTENT) {
00566             /* Add content type if other than default */
00567             if (resource_temp_ptr->resource_parameters_ptr) {
00568                 if (resource_temp_ptr->resource_parameters_ptr->coap_content_type != 0) {
00569                     response_message_hdr_ptr->content_type_len = 1;
00570                     response_message_hdr_ptr->content_type_ptr = handle->sn_grs_alloc(response_message_hdr_ptr->content_type_len);
00571                     if (!response_message_hdr_ptr->content_type_ptr) {
00572                         sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, response_message_hdr_ptr);
00573 
00574                         if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) {
00575                             handle->sn_grs_free(coap_packet_ptr->payload_ptr);
00576                             coap_packet_ptr->payload_ptr = 0;
00577                         }
00578 
00579                         sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_packet_ptr);
00580                         return SN_NSDL_FAILURE;
00581                     }
00582                     memcpy(response_message_hdr_ptr->content_type_ptr, &resource_temp_ptr->resource_parameters_ptr->coap_content_type, response_message_hdr_ptr->content_type_len);
00583                 }
00584             }
00585 
00586             /* Add payload */
00587             if (resource_temp_ptr->resourcelen != 0) {
00588                 response_message_hdr_ptr->payload_len = resource_temp_ptr->resourcelen;
00589                 response_message_hdr_ptr->payload_ptr = handle->sn_grs_alloc(response_message_hdr_ptr->payload_len);
00590 
00591                 if (!response_message_hdr_ptr->payload_ptr) {
00592                     sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, response_message_hdr_ptr);
00593 
00594                     if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) {
00595                         handle->sn_grs_free(coap_packet_ptr->payload_ptr);
00596                         coap_packet_ptr->payload_ptr = 0;
00597                     }
00598 
00599                     sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_packet_ptr);
00600                     return SN_NSDL_FAILURE;
00601                 }
00602 
00603                 memcpy(response_message_hdr_ptr->payload_ptr, resource_temp_ptr->resource, response_message_hdr_ptr->payload_len);
00604             }
00605             // Add max-age attribute for static resources.
00606             // Not a mandatory parameter, no need to return in case of memory allocation fails.
00607             if (static_get_request) {
00608                 if (sn_coap_parser_alloc_options(handle->coap, response_message_hdr_ptr)) {
00609                     response_message_hdr_ptr->options_list_ptr->max_age_ptr = handle->sn_grs_alloc(1);
00610                     if (response_message_hdr_ptr->options_list_ptr->max_age_ptr) {
00611                         response_message_hdr_ptr->options_list_ptr->max_age_ptr[0] = 0;
00612                         response_message_hdr_ptr->options_list_ptr->max_age_len = 1;
00613                     }
00614                 }
00615             }
00616         }
00617         sn_grs_send_coap_message(nsdl_handle, src_addr_ptr, response_message_hdr_ptr);
00618 
00619         if (response_message_hdr_ptr->payload_ptr) {
00620             handle->sn_grs_free(response_message_hdr_ptr->payload_ptr);
00621             response_message_hdr_ptr->payload_ptr = 0;
00622         }
00623         sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, response_message_hdr_ptr);
00624     }
00625 
00626     /* Free parsed CoAP message */
00627     if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) {
00628         handle->sn_grs_free(coap_packet_ptr->payload_ptr);
00629         coap_packet_ptr->payload_ptr = 0;
00630     }
00631     sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_packet_ptr);
00632 
00633 
00634     return SN_NSDL_SUCCESS;
00635 }
00636 
00637 extern int8_t sn_grs_send_coap_message(struct nsdl_s *handle, sn_nsdl_addr_s *address_ptr, sn_coap_hdr_s *coap_hdr_ptr)
00638 {
00639     tr_debug("sn_grs_send_coap_message");
00640     uint8_t     *message_ptr = NULL;
00641     uint16_t    message_len = 0;
00642     uint8_t     ret_val = 0;
00643 
00644     if( !handle ){
00645         return SN_NSDL_FAILURE;
00646     }
00647 
00648     /* Calculate message length */
00649     message_len = sn_coap_builder_calc_needed_packet_data_size_2(coap_hdr_ptr, handle->grs->coap->sn_coap_block_data_size);
00650     tr_debug("sn_grs_send_coap_message - msg len after calc: [%d]", message_len);
00651     tr_debug("sn_grs_send_coap_message - msg id: [%d]", coap_hdr_ptr->msg_id);
00652 
00653     /* Allocate memory for message and check was allocating successfully */
00654     message_ptr = handle->grs->sn_grs_alloc(message_len);
00655     if (message_ptr == NULL) {
00656         return SN_NSDL_FAILURE;
00657     }
00658 
00659     /* Build CoAP message */
00660     if (sn_coap_protocol_build(handle->grs->coap, address_ptr, message_ptr, coap_hdr_ptr, (void *)handle) < 0) {
00661         handle->grs->sn_grs_free(message_ptr);
00662         message_ptr = 0;
00663         return SN_NSDL_FAILURE;
00664     }
00665 
00666     /* Call tx callback function to send message */
00667     ret_val = handle->grs->sn_grs_tx_callback(handle, SN_NSDL_PROTOCOL_COAP, message_ptr, message_len, address_ptr);
00668 
00669     /* Free allocated memory */
00670     handle->grs->sn_grs_free(message_ptr);
00671     message_ptr = 0;
00672 
00673     if (ret_val == 0) {
00674         return SN_NSDL_FAILURE;
00675     } else {
00676         return SN_NSDL_SUCCESS;
00677     }
00678 }
00679 
00680 static int8_t sn_grs_core_request(struct nsdl_s *handle, sn_nsdl_addr_s *src_addr_ptr, sn_coap_hdr_s *coap_packet_ptr)
00681 {
00682     sn_coap_hdr_s           *response_message_hdr_ptr = NULL;
00683     sn_coap_content_format_e wellknown_content_format = COAP_CT_LINK_FORMAT;
00684 
00685     /* Allocate response message  */
00686     response_message_hdr_ptr = sn_coap_parser_alloc_message(handle->grs->coap);
00687     if (response_message_hdr_ptr == NULL) {
00688         if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) {
00689             handle->grs->sn_grs_free(coap_packet_ptr->payload_ptr);
00690             coap_packet_ptr->payload_ptr = 0;
00691         }
00692         sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr);
00693         return SN_NSDL_FAILURE;
00694     }
00695 
00696     /* Build response */
00697     response_message_hdr_ptr->msg_code = COAP_MSG_CODE_RESPONSE_CONTENT;
00698     response_message_hdr_ptr->msg_type = COAP_MSG_TYPE_ACKNOWLEDGEMENT;
00699     response_message_hdr_ptr->msg_id = coap_packet_ptr->msg_id;
00700     response_message_hdr_ptr->content_type_len = 1;
00701     response_message_hdr_ptr->content_type_ptr = handle->grs->sn_grs_alloc(1);
00702     if (!response_message_hdr_ptr->content_type_ptr) {
00703         if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) {
00704             handle->grs->sn_grs_free(coap_packet_ptr->payload_ptr);
00705             coap_packet_ptr->payload_ptr = 0;
00706         }
00707         sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr);
00708         handle->grs->sn_grs_free(response_message_hdr_ptr);
00709         return SN_NSDL_FAILURE;
00710     }
00711 
00712     *response_message_hdr_ptr->content_type_ptr = wellknown_content_format;
00713 
00714     sn_nsdl_build_registration_body(handle, response_message_hdr_ptr, 0);
00715 
00716     /* Send and free */
00717     sn_grs_send_coap_message(handle, src_addr_ptr, response_message_hdr_ptr);
00718 
00719     if (response_message_hdr_ptr->payload_ptr) {
00720         handle->grs->sn_grs_free(response_message_hdr_ptr->payload_ptr);
00721         response_message_hdr_ptr->payload_ptr = 0;
00722     }
00723     sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, response_message_hdr_ptr);
00724 
00725     /* Free parsed CoAP message */
00726     if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) {
00727         handle->grs->sn_grs_free(coap_packet_ptr->payload_ptr);
00728         coap_packet_ptr->payload_ptr = 0;
00729     }
00730     sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr);
00731 
00732     return SN_NSDL_SUCCESS;
00733 }
00734 
00735 /**
00736  * \fn  static sn_grs_resource_info_s *sn_grs_search_resource(uint16_t pathlen, uint8_t *path, uint8_t search_method)
00737  *
00738  * \brief Searches given resource from linked list
00739  *
00740  *  Search either precise path, or subresources, eg. dr/x -> returns dr/x/1, dr/x/2 etc...
00741  *
00742  *  \param  pathlen         Length of the path to be search
00743  *
00744  *  \param  *path           Pointer to the path string to be search
00745  *
00746  *  \param  search_method   Search method, SEARCH or DELETE
00747  *
00748  *  \return                 Pointer to the resource. If resource not found, return value is NULL
00749  *
00750 */
00751 
00752 sn_nsdl_resource_info_s *sn_grs_search_resource(struct grs_s *handle, uint16_t pathlen, uint8_t *path, uint8_t search_method)
00753 {
00754 
00755     /* Local variables */
00756     uint8_t                     *path_temp_ptr          = NULL;
00757     /* Check parameters */
00758     if (!handle || !pathlen || !path) {
00759         return NULL;
00760     }
00761 
00762     /* Remove '/' - marks from the end and beginning */
00763     path_temp_ptr = sn_grs_convert_uri(&pathlen, path);
00764 
00765     /* Searchs exact path */
00766     if (search_method == SN_GRS_SEARCH_METHOD) {
00767         /* Scan all nodes on list */
00768         ns_list_foreach(sn_nsdl_resource_info_s, resource_search_temp, &handle->resource_root_list) {
00769             /* If length equals.. */
00770             if (resource_search_temp->pathlen == pathlen) {
00771                 /* Compare paths, If same return node pointer*/
00772                 if (0 == memcmp(resource_search_temp->path, path_temp_ptr, pathlen)) {
00773                     return resource_search_temp;
00774                 }
00775             }
00776         }
00777     }
00778     /* Search also subresources, eg. dr/x -> returns dr/x/1, dr/x/2 etc... */
00779     else if (search_method == SN_GRS_DELETE_METHOD) {
00780         /* Scan all nodes on list */
00781         ns_list_foreach(sn_nsdl_resource_info_s, resource_search_temp, &handle->resource_root_list) {
00782             uint8_t *temp_path = resource_search_temp->path;
00783             if (resource_search_temp->pathlen > pathlen &&
00784                     (*(temp_path + (uint8_t)pathlen) == '/') &&
00785                     0 == memcmp(resource_search_temp->path, path_temp_ptr, pathlen)) {
00786                 return resource_search_temp;
00787             }
00788         }
00789     }
00790 
00791     /* If there was not nodes we wanted, return NULL */
00792     return NULL;
00793 }
00794 
00795 
00796 /**
00797  * \fn  static int8_t sn_grs_add_resource_to_list(sn_grs_resource_info_s *resource_ptr)
00798  *
00799  * \brief Adds given resource to resource list
00800  *
00801  *  \param  *resource_ptr           Pointer to the path string to be search
00802  *
00803  *  \return 0 = SN_NSDL_SUCCESS, -1 = SN_NSDL_FAILURE
00804  *
00805 */
00806 static int8_t sn_grs_add_resource_to_list(struct grs_s *handle, sn_nsdl_resource_info_s *resource_ptr)
00807 {
00808     /* Local variables */
00809     uint8_t *path_start_ptr = NULL;
00810     uint16_t path_len = 0;
00811     sn_nsdl_resource_info_s *resource_copy_ptr = NULL;
00812 
00813     /* Allocate memory for the resource info copy */
00814     if (!resource_ptr->pathlen) { //Dead code
00815         return SN_NSDL_FAILURE;
00816     }
00817     resource_copy_ptr = handle->sn_grs_alloc(sizeof(sn_nsdl_resource_info_s));
00818     if (resource_copy_ptr == NULL) {
00819         return SN_NSDL_FAILURE;
00820     }
00821 
00822     /* Set everything to zero  */
00823     memset(resource_copy_ptr, 0, sizeof(sn_nsdl_resource_info_s));
00824 
00825     resource_copy_ptr->mode = resource_ptr->mode;
00826     resource_copy_ptr->resourcelen = resource_ptr->resourcelen;
00827     resource_copy_ptr->sn_grs_dyn_res_callback = resource_ptr->sn_grs_dyn_res_callback;
00828     resource_copy_ptr->access = resource_ptr->access;
00829     resource_copy_ptr->publish_uri = resource_ptr->publish_uri;
00830 
00831     /* Remove '/' - chars from the beginning and from the end */
00832 
00833     path_len = resource_ptr->pathlen;
00834     path_start_ptr = sn_grs_convert_uri(&path_len, resource_ptr->path);
00835 
00836     /* Allocate memory for the path */
00837     resource_copy_ptr->path = handle->sn_grs_alloc(path_len);
00838     if (!resource_copy_ptr->path) {
00839         sn_grs_resource_info_free(handle, resource_copy_ptr);
00840         return SN_NSDL_FAILURE;
00841     }
00842 
00843     /* Update pathlen */
00844     resource_copy_ptr->pathlen = path_len;
00845 
00846     /* Copy path string to the copy */
00847     memcpy(resource_copy_ptr->path, path_start_ptr, resource_copy_ptr->pathlen);
00848 
00849     /* Allocate memory for the resource, and copy it to copy */
00850     if (resource_ptr->resource) {
00851         resource_copy_ptr->resource = handle->sn_grs_alloc(resource_ptr->resourcelen);
00852         if (!resource_copy_ptr->resource) {
00853             sn_grs_resource_info_free(handle, resource_copy_ptr);
00854             return SN_NSDL_FAILURE;
00855         }
00856         memcpy(resource_copy_ptr->resource, resource_ptr->resource, resource_ptr->resourcelen);
00857     }
00858 
00859 
00860 
00861     /* If resource parameters exists, copy them */
00862     if (resource_ptr->resource_parameters_ptr) {
00863         resource_copy_ptr->resource_parameters_ptr = handle->sn_grs_alloc(sizeof(sn_nsdl_resource_parameters_s));
00864         if (!resource_copy_ptr->resource_parameters_ptr) {
00865             sn_grs_resource_info_free(handle, resource_copy_ptr);
00866             return SN_NSDL_FAILURE;
00867         }
00868 
00869         memset(resource_copy_ptr->resource_parameters_ptr, 0, sizeof(sn_nsdl_resource_parameters_s));
00870 
00871 
00872         resource_copy_ptr->resource_parameters_ptr->resource_type_len = resource_ptr->resource_parameters_ptr->resource_type_len;
00873 
00874         resource_copy_ptr->resource_parameters_ptr->interface_description_len = resource_ptr->resource_parameters_ptr->interface_description_len;
00875 
00876         resource_copy_ptr->resource_parameters_ptr->mime_content_type = resource_ptr->resource_parameters_ptr->mime_content_type;
00877 
00878         resource_copy_ptr->resource_parameters_ptr->observable = resource_ptr->resource_parameters_ptr->observable;
00879 
00880         if (resource_ptr->resource_parameters_ptr->resource_type_ptr) {
00881             resource_copy_ptr->resource_parameters_ptr->resource_type_ptr = handle->sn_grs_alloc(resource_ptr->resource_parameters_ptr->resource_type_len);
00882             if (!resource_copy_ptr->resource_parameters_ptr->resource_type_ptr) {
00883                 sn_grs_resource_info_free(handle, resource_copy_ptr);
00884                 return SN_NSDL_FAILURE;
00885             }
00886             memcpy(resource_copy_ptr->resource_parameters_ptr->resource_type_ptr, resource_ptr->resource_parameters_ptr->resource_type_ptr, resource_ptr->resource_parameters_ptr->resource_type_len);
00887         }
00888 
00889         if (resource_ptr->resource_parameters_ptr->interface_description_ptr) {
00890             resource_copy_ptr->resource_parameters_ptr->interface_description_ptr = handle->sn_grs_alloc(resource_ptr->resource_parameters_ptr->interface_description_len);
00891             if (!resource_copy_ptr->resource_parameters_ptr->interface_description_ptr) {
00892                 sn_grs_resource_info_free(handle, resource_copy_ptr);
00893                 return SN_NSDL_FAILURE;
00894             }
00895             memcpy(resource_copy_ptr->resource_parameters_ptr->interface_description_ptr, resource_ptr->resource_parameters_ptr->interface_description_ptr, resource_ptr->resource_parameters_ptr->interface_description_len);
00896         }
00897 
00898         /* Copy auto observation parameter */
00899         /* todo: aobs not supported ATM - needs fixing */
00900         /*      if(resource_ptr->resource_parameters_ptr->auto_obs_ptr && resource_ptr->resource_parameters_ptr->auto_obs_len)
00901                 {
00902                     resource_copy_ptr->resource_parameters_ptr->auto_obs_ptr = sn_grs_alloc(resource_ptr->resource_parameters_ptr->auto_obs_len);
00903                     if(!resource_copy_ptr->resource_parameters_ptr->auto_obs_ptr)
00904                     {
00905                         sn_grs_resource_info_free(resource_copy_ptr);
00906                         return SN_NSDL_FAILURE;
00907                     }
00908                     memcpy(resource_copy_ptr->resource_parameters_ptr->auto_obs_ptr, resource_ptr->resource_parameters_ptr->auto_obs_ptr, resource_ptr->resource_parameters_ptr->auto_obs_len);
00909                     resource_copy_ptr->resource_parameters_ptr->auto_obs_len = resource_ptr->resource_parameters_ptr->auto_obs_len;
00910                 }
00911 
00912                 resource_copy_ptr->resource_parameters_ptr->coap_content_type = resource_ptr->resource_parameters_ptr->coap_content_type;
00913                 */
00914     }
00915 
00916     /* Add copied resource to the linked list */
00917     ns_list_add_to_start(&handle->resource_root_list, resource_copy_ptr);
00918     ++handle->resource_root_count;
00919 
00920     return SN_NSDL_SUCCESS;
00921 }
00922 
00923 
00924 /**
00925  * \fn  static uint8_t *sn_grs_convert_uri(uint16_t *uri_len, uint8_t *uri_ptr)
00926  *
00927  * \brief Removes '/' from the beginning and from the end of uri string
00928  *
00929  *  \param  *uri_len            Pointer to the length of the path string
00930  *
00931  *  \param  *uri_ptr            Pointer to the path string
00932  *
00933  *  \return start pointer of the uri
00934  *
00935 */
00936 
00937 static uint8_t *sn_grs_convert_uri(uint16_t *uri_len, uint8_t *uri_ptr)
00938 {
00939     /* Local variables */
00940     uint8_t *uri_start_ptr = uri_ptr;
00941 
00942     /* If '/' in the beginning, update uri start pointer and uri len */
00943     if (*uri_ptr == '/') {
00944         uri_start_ptr = uri_ptr + 1;
00945         *uri_len = *uri_len - 1;
00946     }
00947 
00948     /* If '/' at the end, update uri len */
00949     if (*(uri_start_ptr + *uri_len - 1) == '/') {
00950         *uri_len = *uri_len - 1;
00951     }
00952 
00953     /* Return start pointer */
00954     return uri_start_ptr;
00955 }
00956 
00957 /**
00958  * \fn  static int8_t sn_grs_resource_info_free(sn_grs_resource_info_s *resource_ptr)
00959  *
00960  * \brief Frees resource info structure
00961  *
00962  *  \param *resource_ptr    Pointer to the resource
00963  *
00964  *  \return 0 if success, -1 if failed
00965  *
00966 */
00967 static int8_t sn_grs_resource_info_free(struct grs_s *handle, sn_nsdl_resource_info_s *resource_ptr)
00968 {
00969     if (resource_ptr) {
00970         if (resource_ptr->resource_parameters_ptr) {
00971             if (resource_ptr->resource_parameters_ptr->interface_description_ptr) {
00972                 handle->sn_grs_free(resource_ptr->resource_parameters_ptr->interface_description_ptr);
00973                 resource_ptr->resource_parameters_ptr->interface_description_ptr = 0;
00974             }
00975 
00976             if (resource_ptr->resource_parameters_ptr->resource_type_ptr) {
00977                 handle->sn_grs_free(resource_ptr->resource_parameters_ptr->resource_type_ptr);
00978                 resource_ptr->resource_parameters_ptr->resource_type_ptr = 0;
00979             }
00980 
00981             /* Todo: aobs not supported ATM - needs fixing */
00982             /*
00983             if(resource_ptr->resource_parameters_ptr->auto_obs_ptr)
00984             {
00985                 sn_grs_free(resource_ptr->resource_parameters_ptr->auto_obs_ptr);
00986                 resource_ptr->resource_parameters_ptr->auto_obs_ptr = 0;
00987             }
00988             */
00989 
00990             handle->sn_grs_free(resource_ptr->resource_parameters_ptr);
00991             resource_ptr->resource_parameters_ptr = 0;
00992         }
00993 
00994         if (resource_ptr->path) {
00995             handle->sn_grs_free(resource_ptr->path);
00996             resource_ptr->path = 0;
00997         }
00998         if (resource_ptr->resource) {
00999             handle->sn_grs_free(resource_ptr->resource);
01000             resource_ptr->resource = 0;
01001         }
01002         handle->sn_grs_free(resource_ptr);
01003 
01004         return SN_NSDL_SUCCESS;
01005     }
01006     return SN_NSDL_FAILURE; //Dead code?
01007 }
01008 
01009 void sn_grs_mark_resources_as_registered(struct nsdl_s *handle)
01010 {
01011     if( !handle ){
01012         return;
01013     }
01014 
01015     const sn_nsdl_resource_info_s *temp_resource;
01016 
01017     temp_resource = sn_grs_get_first_resource(handle->grs);
01018 
01019     while (temp_resource) {
01020         if (temp_resource->resource_parameters_ptr) {
01021             if (temp_resource->resource_parameters_ptr->registered == SN_NDSL_RESOURCE_REGISTERING) {
01022                 temp_resource->resource_parameters_ptr->registered = SN_NDSL_RESOURCE_REGISTERED;
01023             }
01024         }
01025         temp_resource = sn_grs_get_next_resource(handle->grs, temp_resource);
01026     }
01027 }