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