Simulated product dispenser
Fork of mbed-cloud-workshop-connect-HTS221 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 #include "ns_list.h" 00027 #include "ns_types.h" 00028 #include "sn_nsdl.h" 00029 #include "sn_coap_header.h" 00030 #include "sn_coap_protocol.h" 00031 #include "source/include/sn_coap_protocol_internal.h" 00032 #include "sn_nsdl_lib.h" 00033 #include "sn_grs.h" 00034 00035 /* Defines */ 00036 #define WELLKNOWN_PATH_LEN 16 00037 #define WELLKNOWN_PATH (".well-known/core") 00038 00039 /* Local static function prototypes */ 00040 static int8_t sn_grs_resource_info_free(struct grs_s *handle, sn_nsdl_dynamic_resource_parameters_s *resource_ptr); 00041 static char *sn_grs_convert_uri(uint16_t *uri_len, const char *uri_ptr); 00042 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); 00043 static uint8_t coap_tx_callback(uint8_t *, uint16_t, sn_nsdl_addr_s *, void *); 00044 static int8_t coap_rx_callback(sn_coap_hdr_s *coap_ptr, sn_nsdl_addr_s *address_ptr, void *param); 00045 00046 /* Extern function prototypes */ 00047 extern int8_t sn_nsdl_build_registration_body(struct nsdl_s *handle, sn_coap_hdr_s *message_ptr, uint8_t updating_registeration); 00048 00049 /** 00050 * \fn int8_t sn_grs_destroy(void) 00051 * \brief This function may be used to flush GRS related stuff when a program exits. 00052 * @return always 0. 00053 */ 00054 extern int8_t sn_grs_destroy(struct grs_s *handle) 00055 { 00056 if( handle == NULL ){ 00057 return 0; 00058 } 00059 ns_list_foreach_safe(sn_nsdl_dynamic_resource_parameters_s, tmp, &handle->resource_root_list) { 00060 ns_list_remove(&handle->resource_root_list, tmp); 00061 --handle->resource_root_count; 00062 sn_grs_resource_info_free(handle, tmp); 00063 } 00064 handle->sn_grs_free(handle); 00065 00066 return 0; 00067 } 00068 00069 static uint8_t coap_tx_callback(uint8_t *data_ptr, uint16_t data_len, sn_nsdl_addr_s *address_ptr, void *param) 00070 { 00071 struct nsdl_s *handle = (struct nsdl_s *)param; 00072 00073 if (handle == NULL) { 00074 return 0; 00075 } 00076 00077 return handle->grs->sn_grs_tx_callback(handle, SN_NSDL_PROTOCOL_COAP, data_ptr, data_len, address_ptr); 00078 } 00079 00080 static int8_t coap_rx_callback(sn_coap_hdr_s *coap_ptr, sn_nsdl_addr_s *address_ptr, void *param) 00081 { 00082 struct nsdl_s *handle = (struct nsdl_s *)param; 00083 00084 if (handle == NULL) { 00085 return 0; 00086 } 00087 00088 return handle->sn_nsdl_rx_callback(handle, coap_ptr, address_ptr); 00089 } 00090 00091 /** 00092 * \fn int8_t sn_grs_init (uint8_t (*sn_grs_tx_callback_ptr)(sn_nsdl_capab_e , uint8_t *, uint16_t, 00093 * 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) 00094 * 00095 * \brief GRS library initialize function. 00096 * 00097 * This function initializes GRS and CoAP libraries. 00098 * 00099 * \param sn_grs_tx_callback A function pointer to a transmit callback function. 00100 * \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 00101 * upper level (NSDL) to be proceed. 00102 * \param sn_memory A pointer to a structure containing the platform specific functions for memory allocation and free. 00103 * 00104 * \return success = 0, failure = -1 00105 * 00106 */ 00107 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, 00108 sn_nsdl_addr_s *), int8_t (*sn_grs_rx_callback_ptr)(struct nsdl_s *, sn_coap_hdr_s *, sn_nsdl_addr_s *), 00109 void *(*sn_grs_alloc)(uint16_t), void (*sn_grs_free)(void *)) 00110 { 00111 00112 struct grs_s *handle_ptr = NULL; 00113 00114 /* Check parameters */ 00115 if (sn_grs_alloc == NULL || sn_grs_free == NULL || 00116 sn_grs_tx_callback_ptr == NULL || sn_grs_rx_callback_ptr == NULL) { 00117 return NULL; 00118 } 00119 00120 handle_ptr = sn_grs_alloc(sizeof(struct grs_s)); 00121 00122 if (handle_ptr == NULL) { 00123 return NULL; 00124 } 00125 00126 memset(handle_ptr, 0, sizeof(struct grs_s)); 00127 00128 /* Allocation and free - function pointers */ 00129 handle_ptr->sn_grs_alloc = sn_grs_alloc; 00130 handle_ptr->sn_grs_free = sn_grs_free; 00131 00132 /* TX callback function pointer */ 00133 handle_ptr->sn_grs_tx_callback = sn_grs_tx_callback_ptr; 00134 handle_ptr->sn_grs_rx_callback = sn_grs_rx_callback_ptr; 00135 00136 /* Initialize CoAP protocol library */ 00137 handle_ptr->coap = sn_coap_protocol_init(sn_grs_alloc, sn_grs_free, coap_tx_callback, coap_rx_callback); 00138 00139 return handle_ptr; 00140 } 00141 00142 extern sn_nsdl_dynamic_resource_parameters_s *sn_grs_get_first_resource(struct grs_s *handle) 00143 { 00144 if( !handle ){ 00145 return NULL; 00146 } 00147 return ns_list_get_first(&handle->resource_root_list); 00148 } 00149 00150 extern sn_nsdl_dynamic_resource_parameters_s *sn_grs_get_next_resource(struct grs_s *handle, 00151 const sn_nsdl_dynamic_resource_parameters_s *sn_grs_current_resource) 00152 { 00153 if( !handle || !sn_grs_current_resource ){ 00154 return NULL; 00155 } 00156 return ns_list_get_next(&handle->resource_root_list, sn_grs_current_resource); 00157 } 00158 00159 extern int8_t sn_grs_delete_resource(struct grs_s *handle, const char *path) 00160 { 00161 /* Local variables */ 00162 sn_nsdl_dynamic_resource_parameters_s *resource_temp = NULL; 00163 00164 /* Search if resource found */ 00165 resource_temp = sn_grs_search_resource(handle, path, SN_GRS_SEARCH_METHOD); 00166 00167 /* If not found */ 00168 if (resource_temp == NULL) { 00169 return SN_NSDL_FAILURE; 00170 } 00171 00172 /* If found, delete it and delete also subresources, if there is any */ 00173 do { 00174 /* Remove from list */ 00175 ns_list_remove(&handle->resource_root_list, resource_temp); 00176 --handle->resource_root_count; 00177 00178 /* Free */ 00179 sn_grs_resource_info_free(handle, resource_temp); 00180 00181 /* Search for subresources */ 00182 resource_temp = sn_grs_search_resource(handle, path, SN_GRS_DELETE_METHOD); 00183 } while (resource_temp != NULL); 00184 00185 return SN_NSDL_SUCCESS; 00186 } 00187 00188 int8_t sn_grs_put_resource(struct grs_s *handle, sn_nsdl_dynamic_resource_parameters_s *res) 00189 { 00190 if (!res || !handle) { 00191 return SN_NSDL_FAILURE; 00192 } 00193 00194 /* Check path validity */ 00195 if (!res->static_resource_parameters->path || res->static_resource_parameters->path[0] == '\0') { 00196 return SN_GRS_INVALID_PATH; 00197 } 00198 00199 /* Check if resource already exists */ 00200 if (sn_grs_search_resource(handle, 00201 res->static_resource_parameters->path, SN_GRS_SEARCH_METHOD) != (sn_nsdl_dynamic_resource_parameters_s *)NULL) { 00202 return SN_GRS_RESOURCE_ALREADY_EXISTS; 00203 } 00204 00205 res->registered = SN_NDSL_RESOURCE_NOT_REGISTERED; 00206 00207 ns_list_add_to_start(&handle->resource_root_list, res); 00208 ++handle->resource_root_count; 00209 00210 return SN_NSDL_SUCCESS; 00211 } 00212 00213 int8_t sn_grs_pop_resource(struct grs_s *handle, sn_nsdl_dynamic_resource_parameters_s *res) 00214 { 00215 if (!res || !handle) { 00216 return SN_NSDL_FAILURE; 00217 } 00218 00219 /* Check path validity */ 00220 if (!res->static_resource_parameters->path || res->static_resource_parameters->path[0] == '\0') { 00221 return SN_GRS_INVALID_PATH; 00222 } 00223 00224 /* Check if resource exists on list. */ 00225 if (sn_grs_search_resource(handle, 00226 res->static_resource_parameters->path, SN_GRS_SEARCH_METHOD) == (sn_nsdl_dynamic_resource_parameters_s *)NULL) { 00227 return SN_NSDL_FAILURE; 00228 } 00229 00230 ns_list_remove(&handle->resource_root_list, res); 00231 --handle->resource_root_count; 00232 00233 return SN_NSDL_SUCCESS; 00234 } 00235 00236 /** 00237 * \fn extern int8_t sn_grs_process_coap(uint8_t *packet, uint16_t *packet_len, sn_nsdl_addr_s *src) 00238 * 00239 * \brief To push CoAP packet to GRS library 00240 * 00241 * Used to push an CoAP packet to GRS library for processing. 00242 * 00243 * \param *packet Pointer to a uint8_t array containing the packet (including the CoAP headers). 00244 * After successful execution this array may contain the response packet. 00245 * 00246 * \param *packet_len Pointer to length of the packet. After successful execution this array may contain the length 00247 * of the response packet. 00248 * 00249 * \param *src Pointer to packet source address information. After successful execution this array may contain 00250 * the destination address of the response packet. 00251 * 00252 * \return 0 = success, -1 = failure 00253 */ 00254 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) 00255 { 00256 if( !coap_packet_ptr || !nsdl_handle){ 00257 return SN_NSDL_FAILURE; 00258 } 00259 00260 sn_nsdl_dynamic_resource_parameters_s *resource_temp_ptr = NULL; 00261 sn_coap_msg_code_e status = COAP_MSG_CODE_EMPTY; 00262 sn_coap_hdr_s *response_message_hdr_ptr = NULL; 00263 struct grs_s *handle = nsdl_handle->grs; 00264 bool static_get_request = false; 00265 00266 if (coap_packet_ptr->msg_code <= COAP_MSG_CODE_REQUEST_DELETE) { 00267 /* Check if .well-known/core */ 00268 if (coap_packet_ptr->uri_path_len == WELLKNOWN_PATH_LEN && memcmp(coap_packet_ptr->uri_path_ptr, WELLKNOWN_PATH, WELLKNOWN_PATH_LEN) == 0) { 00269 return sn_grs_core_request(nsdl_handle, src_addr_ptr, coap_packet_ptr); 00270 } 00271 00272 /* Get resource */ 00273 char* path = nsdl_handle->grs->sn_grs_alloc(coap_packet_ptr->uri_path_len + 1); 00274 if (!path) { 00275 return SN_NSDL_FAILURE; 00276 } 00277 00278 memcpy(path, 00279 coap_packet_ptr->uri_path_ptr, 00280 coap_packet_ptr->uri_path_len); 00281 path[coap_packet_ptr->uri_path_len] = '\0'; 00282 00283 resource_temp_ptr = sn_grs_search_resource(handle, path, SN_GRS_SEARCH_METHOD); 00284 nsdl_handle->grs->sn_grs_free(path); 00285 00286 /* * * * * * * * * * * */ 00287 /* If resource exists */ 00288 /* * * * * * * * * * * */ 00289 if (resource_temp_ptr) { 00290 /* If dynamic resource, go to callback */ 00291 if (resource_temp_ptr->static_resource_parameters->mode == SN_GRS_DYNAMIC) { 00292 /* Check accesses */ 00293 if (((coap_packet_ptr->msg_code == COAP_MSG_CODE_REQUEST_GET) && !(resource_temp_ptr->access & SN_GRS_GET_ALLOWED)) || 00294 ((coap_packet_ptr->msg_code == COAP_MSG_CODE_REQUEST_POST) && !(resource_temp_ptr->access & SN_GRS_POST_ALLOWED)) || 00295 ((coap_packet_ptr->msg_code == COAP_MSG_CODE_REQUEST_PUT) && !(resource_temp_ptr->access & SN_GRS_PUT_ALLOWED)) || 00296 ((coap_packet_ptr->msg_code == COAP_MSG_CODE_REQUEST_DELETE) && !(resource_temp_ptr->access & SN_GRS_DELETE_ALLOWED))) { 00297 status = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00298 } else { 00299 /* Do not call null pointer.. */ 00300 if (resource_temp_ptr->sn_grs_dyn_res_callback != NULL) { 00301 resource_temp_ptr->sn_grs_dyn_res_callback(nsdl_handle, coap_packet_ptr, src_addr_ptr, SN_NSDL_PROTOCOL_COAP); 00302 } else { 00303 if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) { 00304 handle->sn_grs_free(coap_packet_ptr->payload_ptr); 00305 coap_packet_ptr->payload_ptr = 0; 00306 } 00307 sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_packet_ptr); 00308 } 00309 00310 return SN_NSDL_SUCCESS; 00311 } 00312 } else { 00313 /* Static resource handling */ 00314 switch (coap_packet_ptr->msg_code) { 00315 case COAP_MSG_CODE_REQUEST_GET: 00316 if (resource_temp_ptr->access & SN_GRS_GET_ALLOWED) { 00317 status = COAP_MSG_CODE_RESPONSE_CONTENT; 00318 static_get_request = true; 00319 } else { 00320 status = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00321 } 00322 break; 00323 00324 case COAP_MSG_CODE_REQUEST_POST: 00325 case COAP_MSG_CODE_REQUEST_PUT: 00326 case COAP_MSG_CODE_REQUEST_DELETE: 00327 status = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00328 break; 00329 00330 default: 00331 status = COAP_MSG_CODE_RESPONSE_FORBIDDEN; 00332 break; 00333 } 00334 } 00335 } 00336 00337 /* * * * * * * * * * * * * * */ 00338 /* If resource was not found */ 00339 /* * * * * * * * * * * * * * */ 00340 00341 else { 00342 if (coap_packet_ptr->msg_code == COAP_MSG_CODE_REQUEST_POST) { 00343 handle->sn_grs_rx_callback(nsdl_handle, coap_packet_ptr, src_addr_ptr); 00344 00345 if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) { 00346 handle->sn_grs_free(coap_packet_ptr->payload_ptr); 00347 coap_packet_ptr->payload_ptr = 0; 00348 } 00349 00350 sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_packet_ptr); 00351 return SN_NSDL_SUCCESS; 00352 } else { 00353 status = COAP_MSG_CODE_RESPONSE_NOT_FOUND; 00354 } 00355 } 00356 } 00357 00358 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 00359 /* If received packed was other than reset, create response */ 00360 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 00361 if (coap_packet_ptr->msg_type != COAP_MSG_TYPE_RESET && coap_packet_ptr->msg_type != COAP_MSG_TYPE_ACKNOWLEDGEMENT) { 00362 00363 /* Allocate resopnse message */ 00364 response_message_hdr_ptr = sn_coap_parser_alloc_message(handle->coap); 00365 if (!response_message_hdr_ptr) { 00366 if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) { 00367 handle->sn_grs_free(coap_packet_ptr->payload_ptr); 00368 coap_packet_ptr->payload_ptr = 0; 00369 } 00370 sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_packet_ptr); 00371 return SN_NSDL_FAILURE; 00372 } 00373 00374 /* If status has not been defined, response internal server error */ 00375 if (status == COAP_MSG_CODE_EMPTY) { 00376 status = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR; 00377 } 00378 00379 /* Fill header */ 00380 response_message_hdr_ptr->msg_code = status; 00381 00382 if (coap_packet_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE) { 00383 response_message_hdr_ptr->msg_type = COAP_MSG_TYPE_ACKNOWLEDGEMENT; 00384 } else { 00385 response_message_hdr_ptr->msg_type = COAP_MSG_TYPE_NON_CONFIRMABLE; 00386 } 00387 00388 response_message_hdr_ptr->msg_id = coap_packet_ptr->msg_id; 00389 00390 if (coap_packet_ptr->token_ptr) { 00391 response_message_hdr_ptr->token_len = coap_packet_ptr->token_len; 00392 response_message_hdr_ptr->token_ptr = handle->sn_grs_alloc(response_message_hdr_ptr->token_len); 00393 if (!response_message_hdr_ptr->token_ptr) { 00394 sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, response_message_hdr_ptr); 00395 00396 if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) { 00397 handle->sn_grs_free(coap_packet_ptr->payload_ptr); 00398 coap_packet_ptr->payload_ptr = 0; 00399 } 00400 00401 sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_packet_ptr); 00402 return SN_NSDL_FAILURE; 00403 } 00404 memcpy(response_message_hdr_ptr->token_ptr, coap_packet_ptr->token_ptr, response_message_hdr_ptr->token_len); 00405 } 00406 00407 if (status == COAP_MSG_CODE_RESPONSE_CONTENT) { 00408 /* Add content type if other than default */ 00409 if (resource_temp_ptr->static_resource_parameters) { 00410 response_message_hdr_ptr->content_format = 00411 (sn_coap_content_format_e) resource_temp_ptr->coap_content_type; 00412 } 00413 00414 /* Add payload */ 00415 if (resource_temp_ptr->resource_len != 0) { 00416 response_message_hdr_ptr->payload_len = resource_temp_ptr->resource_len; 00417 response_message_hdr_ptr->payload_ptr = handle->sn_grs_alloc(response_message_hdr_ptr->payload_len); 00418 00419 if (!response_message_hdr_ptr->payload_ptr) { 00420 sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, response_message_hdr_ptr); 00421 00422 if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) { 00423 handle->sn_grs_free(coap_packet_ptr->payload_ptr); 00424 coap_packet_ptr->payload_ptr = 0; 00425 } 00426 00427 sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_packet_ptr); 00428 return SN_NSDL_FAILURE; 00429 } 00430 00431 memcpy(response_message_hdr_ptr->payload_ptr, 00432 resource_temp_ptr->resource, 00433 response_message_hdr_ptr->payload_len); 00434 } 00435 // Add max-age attribute for static resources. 00436 // Not a mandatory parameter, no need to return in case of memory allocation fails. 00437 if (static_get_request) { 00438 if (sn_coap_parser_alloc_options(handle->coap, response_message_hdr_ptr)) { 00439 response_message_hdr_ptr->options_list_ptr->max_age = 0; 00440 } 00441 } 00442 } 00443 sn_grs_send_coap_message(nsdl_handle, src_addr_ptr, response_message_hdr_ptr); 00444 00445 if (response_message_hdr_ptr->payload_ptr) { 00446 handle->sn_grs_free(response_message_hdr_ptr->payload_ptr); 00447 response_message_hdr_ptr->payload_ptr = 0; 00448 } 00449 sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, response_message_hdr_ptr); 00450 } 00451 00452 /* Free parsed CoAP message */ 00453 if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) { 00454 handle->sn_grs_free(coap_packet_ptr->payload_ptr); 00455 coap_packet_ptr->payload_ptr = 0; 00456 } 00457 sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_packet_ptr); 00458 00459 return SN_NSDL_SUCCESS; 00460 } 00461 00462 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) 00463 { 00464 uint8_t *message_ptr = NULL; 00465 uint16_t message_len = 0; 00466 int16_t ret_val = 0; 00467 00468 if( !handle ){ 00469 return SN_NSDL_FAILURE; 00470 } 00471 00472 #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwising is not used at all, this part of code will not be compiled */ 00473 ret_val = prepare_blockwise_message(handle->grs->coap, coap_hdr_ptr); 00474 if( 0 != ret_val ) { 00475 return SN_NSDL_FAILURE; 00476 } 00477 #endif 00478 00479 /* Calculate message length */ 00480 message_len = sn_coap_builder_calc_needed_packet_data_size_2(coap_hdr_ptr, handle->grs->coap->sn_coap_block_data_size); 00481 00482 /* Allocate memory for message and check was allocating successfully */ 00483 message_ptr = handle->grs->sn_grs_alloc(message_len); 00484 if (message_ptr == NULL) { 00485 return SN_NSDL_FAILURE; 00486 } 00487 00488 /* Build CoAP message */ 00489 ret_val = sn_coap_protocol_build(handle->grs->coap, address_ptr, message_ptr, coap_hdr_ptr, (void *)handle); 00490 if (ret_val < 0) { 00491 handle->grs->sn_grs_free(message_ptr); 00492 message_ptr = 0; 00493 if (ret_val == -4) { 00494 return SN_NSDL_RESEND_QUEUE_FULL; 00495 } else { 00496 return SN_NSDL_FAILURE; 00497 } 00498 } 00499 00500 /* Call tx callback function to send message */ 00501 ret_val = handle->grs->sn_grs_tx_callback(handle, SN_NSDL_PROTOCOL_COAP, message_ptr, message_len, address_ptr); 00502 00503 /* Free allocated memory */ 00504 handle->grs->sn_grs_free(message_ptr); 00505 message_ptr = 0; 00506 00507 if (ret_val == 0) { 00508 return SN_NSDL_FAILURE; 00509 } else { 00510 return SN_NSDL_SUCCESS; 00511 } 00512 } 00513 00514 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) 00515 { 00516 sn_coap_hdr_s *response_message_hdr_ptr = NULL; 00517 sn_coap_content_format_e wellknown_content_format = COAP_CT_LINK_FORMAT; 00518 00519 /* Allocate response message */ 00520 response_message_hdr_ptr = sn_coap_parser_alloc_message(handle->grs->coap); 00521 if (response_message_hdr_ptr == NULL) { 00522 if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) { 00523 handle->grs->sn_grs_free(coap_packet_ptr->payload_ptr); 00524 coap_packet_ptr->payload_ptr = 0; 00525 } 00526 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr); 00527 return SN_NSDL_FAILURE; 00528 } 00529 00530 /* Build response */ 00531 response_message_hdr_ptr->msg_code = COAP_MSG_CODE_RESPONSE_CONTENT; 00532 response_message_hdr_ptr->msg_type = COAP_MSG_TYPE_ACKNOWLEDGEMENT; 00533 response_message_hdr_ptr->msg_id = coap_packet_ptr->msg_id; 00534 response_message_hdr_ptr->content_format = wellknown_content_format; 00535 00536 sn_nsdl_build_registration_body(handle, response_message_hdr_ptr, 0); 00537 00538 /* Send and free */ 00539 sn_grs_send_coap_message(handle, src_addr_ptr, response_message_hdr_ptr); 00540 00541 if (response_message_hdr_ptr->payload_ptr) { 00542 handle->grs->sn_grs_free(response_message_hdr_ptr->payload_ptr); 00543 response_message_hdr_ptr->payload_ptr = 0; 00544 } 00545 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, response_message_hdr_ptr); 00546 00547 /* Free parsed CoAP message */ 00548 if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) { 00549 handle->grs->sn_grs_free(coap_packet_ptr->payload_ptr); 00550 coap_packet_ptr->payload_ptr = 0; 00551 } 00552 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr); 00553 00554 return SN_NSDL_SUCCESS; 00555 } 00556 00557 /** 00558 * \fn static sn_grs_resource_info_s *sn_grs_search_resource(struct grs_s *handle, const char *path, uint8_t search_method) 00559 * 00560 * \brief Searches given resource from linked list 00561 * 00562 * Search either precise path, or subresources, eg. dr/x -> returns dr/x/1, dr/x/2 etc... 00563 * 00564 * \param pathlen Length of the path to be search 00565 * 00566 * \param *path Pointer to the path string to be search 00567 * 00568 * \param search_method Search method, SEARCH or DELETE 00569 * 00570 * \return Pointer to the resource. If resource not found, return value is NULL 00571 * 00572 */ 00573 00574 sn_nsdl_dynamic_resource_parameters_s *sn_grs_search_resource(struct grs_s *handle, const char *path, uint8_t search_method) 00575 { 00576 /* Local variables */ 00577 char *path_temp_ptr = NULL; 00578 /* Check parameters */ 00579 if (!handle || !path) { 00580 return NULL; 00581 } 00582 uint16_t pathlen = strlen(path); 00583 /* Remove '/' - marks from the end and beginning */ 00584 path_temp_ptr = sn_grs_convert_uri(&pathlen, path); 00585 00586 /* Searchs exact path */ 00587 if (search_method == SN_GRS_SEARCH_METHOD) { 00588 /* Scan all nodes on list */ 00589 ns_list_foreach(sn_nsdl_dynamic_resource_parameters_s, resource_search_temp, &handle->resource_root_list) { 00590 /* If length equals.. */ 00591 size_t len = 0; 00592 if(resource_search_temp && 00593 resource_search_temp->static_resource_parameters && 00594 resource_search_temp->static_resource_parameters->path) { 00595 len = strlen(resource_search_temp->static_resource_parameters->path); 00596 } 00597 00598 if (len == pathlen) { 00599 /* Compare paths, If same return node pointer*/ 00600 if (0 == memcmp(resource_search_temp->static_resource_parameters->path, 00601 path_temp_ptr, 00602 pathlen)) { 00603 return resource_search_temp; 00604 } 00605 } 00606 } 00607 } 00608 /* Search also subresources, eg. dr/x -> returns dr/x/1, dr/x/2 etc... */ 00609 else if (search_method == SN_GRS_DELETE_METHOD) { 00610 /* Scan all nodes on list */ 00611 ns_list_foreach(sn_nsdl_dynamic_resource_parameters_s, resource_search_temp, &handle->resource_root_list) { 00612 char *temp_path = resource_search_temp->static_resource_parameters->path; 00613 if (strlen(resource_search_temp->static_resource_parameters->path) > pathlen && 00614 (*(temp_path + (uint8_t)pathlen) == '/') && 00615 0 == memcmp(resource_search_temp->static_resource_parameters->path, 00616 path_temp_ptr, 00617 pathlen)) { 00618 return resource_search_temp; 00619 } 00620 } 00621 } 00622 00623 /* If there was not nodes we wanted, return NULL */ 00624 return NULL; 00625 } 00626 00627 /** 00628 * \fn static uint8_t *sn_grs_convert_uri(uint16_t *uri_len, uint8_t *uri_ptr) 00629 * 00630 * \brief Removes '/' from the beginning and from the end of uri string 00631 * 00632 * \param *uri_len Pointer to the length of the path string 00633 * 00634 * \param *uri_ptr Pointer to the path string 00635 * 00636 * \return start pointer of the uri 00637 * 00638 */ 00639 00640 static char *sn_grs_convert_uri(uint16_t *uri_len, const char *uri_ptr) 00641 { 00642 /* Local variables */ 00643 char *uri_start_ptr = (char *) uri_ptr; 00644 00645 /* If '/' in the beginning, update uri start pointer and uri len */ 00646 if (*uri_ptr == '/') { 00647 uri_start_ptr = (char *) uri_ptr + 1; 00648 *uri_len = *uri_len - 1; 00649 } 00650 00651 /* If '/' at the end, update uri len */ 00652 if (*(uri_start_ptr + *uri_len - 1) == '/') { 00653 *uri_len = *uri_len - 1; 00654 } 00655 00656 /* Return start pointer */ 00657 return uri_start_ptr; 00658 } 00659 00660 /** 00661 * \fn static int8_t sn_grs_resource_info_free(sn_grs_resource_info_s *resource_ptr) 00662 * 00663 * \brief Frees resource info structure 00664 * 00665 * \param *resource_ptr Pointer to the resource 00666 * 00667 * \return 0 if success, -1 if failed 00668 * 00669 */ 00670 static int8_t sn_grs_resource_info_free(struct grs_s *handle, sn_nsdl_dynamic_resource_parameters_s *resource_ptr) 00671 { 00672 if (resource_ptr) { 00673 #ifdef MEMORY_OPTIMIZED_API 00674 if (resource_ptr->free_on_delete) { 00675 handle->sn_grs_free(resource_ptr); 00676 } 00677 return SN_NSDL_FAILURE; 00678 #else 00679 if (resource_ptr->static_resource_parameters && 00680 resource_ptr->static_resource_parameters->free_on_delete) { 00681 #ifndef RESOURCE_ATTRIBUTES_LIST 00682 #ifndef DISABLE_INTERFACE_DESCRIPTION 00683 if (resource_ptr->static_resource_parameters->interface_description_ptr) { 00684 handle->sn_grs_free(resource_ptr->static_resource_parameters->interface_description_ptr); 00685 resource_ptr->static_resource_parameters->interface_description_ptr = 0; 00686 } 00687 #endif 00688 #ifndef DISABLE_RESOURCE_TYPE 00689 if (resource_ptr->static_resource_parameters->resource_type_ptr) { 00690 handle->sn_grs_free(resource_ptr->static_resource_parameters->resource_type_ptr); 00691 resource_ptr->static_resource_parameters->resource_type_ptr = 0; 00692 } 00693 #endif 00694 #else 00695 sn_nsdl_free_resource_attributes_list(resource_ptr->static_resource_parameters); 00696 #endif 00697 if (resource_ptr->static_resource_parameters->path) { 00698 handle->sn_grs_free(resource_ptr->static_resource_parameters->path); 00699 resource_ptr->static_resource_parameters->path = 0; 00700 } 00701 00702 if (resource_ptr->resource) { 00703 handle->sn_grs_free(resource_ptr->resource); 00704 resource_ptr->resource = 0; 00705 } 00706 00707 handle->sn_grs_free(resource_ptr->static_resource_parameters); 00708 resource_ptr->static_resource_parameters = 0; 00709 } 00710 if (resource_ptr->free_on_delete) { 00711 handle->sn_grs_free(resource_ptr); 00712 } 00713 return SN_NSDL_SUCCESS; 00714 #endif 00715 } 00716 return SN_NSDL_FAILURE; //Dead code? 00717 } 00718 00719 void sn_grs_mark_resources_as_registered(struct nsdl_s *handle) 00720 { 00721 if( !handle ){ 00722 return; 00723 } 00724 00725 sn_nsdl_dynamic_resource_parameters_s *temp_resource; 00726 00727 temp_resource = sn_grs_get_first_resource(handle->grs); 00728 00729 while (temp_resource) { 00730 if (temp_resource->registered == SN_NDSL_RESOURCE_REGISTERING) { 00731 temp_resource->registered = SN_NDSL_RESOURCE_REGISTERED; 00732 } 00733 temp_resource = sn_grs_get_next_resource(handle->grs, temp_resource); 00734 } 00735 }
Generated on Tue Jul 12 2022 19:12:15 by 1.7.2