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