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