Timothy Beight / Mbed 2 deprecated 6_songs-from-the-cloud

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Fork of 6_songs-from-the-cloud by MakingMusicWorkshop

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