sandbox / mbed-client-c

Fork of mbed-client-c by Christopher Haster

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