ON Semiconductor / mbed-os

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

Embed: (wiki syntax)

« Back to documentation index

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