Toyomasa Watarai
/
Mbed-example-WS-W27
Mbed Cloud example program for workshop in W27 2018.
Embed:
(wiki syntax)
Show/hide line numbers
sn_grs.c
Go to the documentation of this file.
00001 /* 00002 * Copyright (c) 2011-2015 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 /** 00018 * 00019 * \file sn_grs.c 00020 * 00021 * \brief General resource server. 00022 * 00023 */ 00024 #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_grs_resource_list_s *sn_grs_list_resource(struct grs_s *handle, const char *path) 00143 { 00144 (void) (path); 00145 sn_grs_resource_list_s *grs_resource_list_ptr = NULL; 00146 00147 if(handle == NULL){ 00148 return NULL; 00149 } 00150 00151 /* Allocate memory for the resource list to be filled */ 00152 grs_resource_list_ptr = handle->sn_grs_alloc(sizeof(sn_grs_resource_list_s)); 00153 if (!grs_resource_list_ptr) { 00154 goto fail; 00155 } 00156 00157 /* Count resources to the resource list struct */ 00158 grs_resource_list_ptr->res_count = handle->resource_root_count; 00159 grs_resource_list_ptr->res = NULL; 00160 00161 /**************************************/ 00162 /* Fill resource structs to the table */ 00163 /**************************************/ 00164 00165 /* If resources in list */ 00166 if (grs_resource_list_ptr->res_count) { 00167 int i; 00168 00169 /* Allocate memory for resources */ 00170 grs_resource_list_ptr->res = handle->sn_grs_alloc(grs_resource_list_ptr->res_count * sizeof(sn_grs_resource_s)); 00171 if (!grs_resource_list_ptr->res) { 00172 goto fail; 00173 } 00174 00175 /* Initialise the pointers to NULL to permit easy cleanup */ 00176 for (i = 0; i < grs_resource_list_ptr->res_count; i++) { 00177 grs_resource_list_ptr->res[i].path = NULL; 00178 } 00179 00180 i = 0; 00181 size_t len = 0; 00182 ns_list_foreach(sn_nsdl_dynamic_resource_parameters_s, grs_resource_ptr, &handle->resource_root_list) { 00183 /* Copy pathlen to resource list */ 00184 len = strlen(grs_resource_ptr->static_resource_parameters->path); 00185 00186 /* Allocate memory for path string */ 00187 grs_resource_list_ptr->res[i].path = handle->sn_grs_alloc(len); 00188 if (!grs_resource_list_ptr->res[i].path) { 00189 goto fail; 00190 } 00191 00192 /* Copy pathstring to resource list */ 00193 memcpy(grs_resource_list_ptr->res[i].path, 00194 grs_resource_ptr->static_resource_parameters->path, 00195 len); 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 sn_nsdl_dynamic_resource_parameters_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 sn_nsdl_dynamic_resource_parameters_s *sn_grs_get_next_resource(struct grs_s *handle, 00236 const sn_nsdl_dynamic_resource_parameters_s *sn_grs_current_resource) 00237 { 00238 if( !handle || !sn_grs_current_resource ){ 00239 return NULL; 00240 } 00241 return ns_list_get_next(&handle->resource_root_list, sn_grs_current_resource); 00242 } 00243 00244 extern int8_t sn_grs_delete_resource(struct grs_s *handle, const char *path) 00245 { 00246 /* Local variables */ 00247 sn_nsdl_dynamic_resource_parameters_s *resource_temp = NULL; 00248 00249 /* Search if resource found */ 00250 resource_temp = sn_grs_search_resource(handle, path, SN_GRS_SEARCH_METHOD); 00251 00252 /* If not found */ 00253 if (resource_temp == NULL) { 00254 return SN_NSDL_FAILURE; 00255 } 00256 00257 /* If found, delete it and delete also subresources, if there is any */ 00258 do { 00259 /* Remove from list */ 00260 ns_list_remove(&handle->resource_root_list, resource_temp); 00261 --handle->resource_root_count; 00262 00263 /* Free */ 00264 sn_grs_resource_info_free(handle, resource_temp); 00265 00266 /* Search for subresources */ 00267 resource_temp = sn_grs_search_resource(handle, path, SN_GRS_DELETE_METHOD); 00268 } while (resource_temp != NULL); 00269 00270 return SN_NSDL_SUCCESS; 00271 } 00272 00273 int8_t sn_grs_put_resource(struct grs_s *handle, sn_nsdl_dynamic_resource_parameters_s *res) 00274 { 00275 if (!res || !handle) { 00276 return SN_NSDL_FAILURE; 00277 } 00278 00279 /* Check path validity */ 00280 if (!res->static_resource_parameters->path || res->static_resource_parameters->path[0] == '\0') { 00281 return SN_GRS_INVALID_PATH; 00282 } 00283 00284 /* Check if resource already exists */ 00285 if (sn_grs_search_resource(handle, 00286 res->static_resource_parameters->path, SN_GRS_SEARCH_METHOD) != (sn_nsdl_dynamic_resource_parameters_s *)NULL) { 00287 return SN_GRS_RESOURCE_ALREADY_EXISTS; 00288 } 00289 00290 res->registered = SN_NDSL_RESOURCE_NOT_REGISTERED; 00291 00292 ns_list_add_to_start(&handle->resource_root_list, res); 00293 ++handle->resource_root_count; 00294 00295 return SN_NSDL_SUCCESS; 00296 } 00297 00298 int8_t sn_grs_pop_resource(struct grs_s *handle, sn_nsdl_dynamic_resource_parameters_s *res) 00299 { 00300 if (!res || !handle) { 00301 return SN_NSDL_FAILURE; 00302 } 00303 00304 /* Check path validity */ 00305 if (!res->static_resource_parameters->path || res->static_resource_parameters->path[0] == '\0') { 00306 return SN_GRS_INVALID_PATH; 00307 } 00308 00309 /* Check if resource exists on list. */ 00310 if (sn_grs_search_resource(handle, 00311 res->static_resource_parameters->path, SN_GRS_SEARCH_METHOD) == (sn_nsdl_dynamic_resource_parameters_s *)NULL) { 00312 return SN_NSDL_FAILURE; 00313 } 00314 00315 ns_list_remove(&handle->resource_root_list, res); 00316 --handle->resource_root_count; 00317 00318 return SN_NSDL_SUCCESS; 00319 } 00320 00321 /** 00322 * \fn extern int8_t sn_grs_process_coap(uint8_t *packet, uint16_t *packet_len, sn_nsdl_addr_s *src) 00323 * 00324 * \brief To push CoAP packet to GRS library 00325 * 00326 * Used to push an CoAP packet to GRS library for processing. 00327 * 00328 * \param *packet Pointer to a uint8_t array containing the packet (including the CoAP headers). 00329 * After successful execution this array may contain the response packet. 00330 * 00331 * \param *packet_len Pointer to length of the packet. After successful execution this array may contain the length 00332 * of the response packet. 00333 * 00334 * \param *src Pointer to packet source address information. After successful execution this array may contain 00335 * the destination address of the response packet. 00336 * 00337 * \return 0 = success, -1 = failure 00338 */ 00339 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) 00340 { 00341 if( !coap_packet_ptr || !nsdl_handle){ 00342 return SN_NSDL_FAILURE; 00343 } 00344 00345 sn_nsdl_dynamic_resource_parameters_s *resource_temp_ptr = NULL; 00346 sn_coap_msg_code_e status = COAP_MSG_CODE_EMPTY; 00347 sn_coap_hdr_s *response_message_hdr_ptr = NULL; 00348 struct grs_s *handle = nsdl_handle->grs; 00349 bool static_get_request = false; 00350 00351 if (coap_packet_ptr->msg_code <= COAP_MSG_CODE_REQUEST_DELETE) { 00352 /* Check if .well-known/core */ 00353 if (coap_packet_ptr->uri_path_len == WELLKNOWN_PATH_LEN && memcmp(coap_packet_ptr->uri_path_ptr, WELLKNOWN_PATH, WELLKNOWN_PATH_LEN) == 0) { 00354 return sn_grs_core_request(nsdl_handle, src_addr_ptr, coap_packet_ptr); 00355 } 00356 00357 /* Get resource */ 00358 char* path = nsdl_handle->grs->sn_grs_alloc(coap_packet_ptr->uri_path_len + 1); 00359 if (!path) { 00360 return SN_NSDL_FAILURE; 00361 } 00362 00363 memcpy(path, 00364 coap_packet_ptr->uri_path_ptr, 00365 coap_packet_ptr->uri_path_len); 00366 path[coap_packet_ptr->uri_path_len] = '\0'; 00367 00368 resource_temp_ptr = sn_grs_search_resource(handle, path, SN_GRS_SEARCH_METHOD); 00369 nsdl_handle->grs->sn_grs_free(path); 00370 00371 /* * * * * * * * * * * */ 00372 /* If resource exists */ 00373 /* * * * * * * * * * * */ 00374 if (resource_temp_ptr) { 00375 /* If dynamic resource, go to callback */ 00376 if (resource_temp_ptr->static_resource_parameters->mode == SN_GRS_DYNAMIC) { 00377 /* Check accesses */ 00378 if (((coap_packet_ptr->msg_code == COAP_MSG_CODE_REQUEST_GET) && !(resource_temp_ptr->access & SN_GRS_GET_ALLOWED)) || 00379 ((coap_packet_ptr->msg_code == COAP_MSG_CODE_REQUEST_POST) && !(resource_temp_ptr->access & SN_GRS_POST_ALLOWED)) || 00380 ((coap_packet_ptr->msg_code == COAP_MSG_CODE_REQUEST_PUT) && !(resource_temp_ptr->access & SN_GRS_PUT_ALLOWED)) || 00381 ((coap_packet_ptr->msg_code == COAP_MSG_CODE_REQUEST_DELETE) && !(resource_temp_ptr->access & SN_GRS_DELETE_ALLOWED))) { 00382 status = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00383 } else { 00384 /* Do not call null pointer.. */ 00385 if (resource_temp_ptr->sn_grs_dyn_res_callback != NULL) { 00386 resource_temp_ptr->sn_grs_dyn_res_callback(nsdl_handle, coap_packet_ptr, src_addr_ptr, SN_NSDL_PROTOCOL_COAP); 00387 } 00388 00389 if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) { 00390 handle->sn_grs_free(coap_packet_ptr->payload_ptr); 00391 coap_packet_ptr->payload_ptr = 0; 00392 } 00393 sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_packet_ptr); 00394 return SN_NSDL_SUCCESS; 00395 } 00396 } else { 00397 /* Static resource handling */ 00398 switch (coap_packet_ptr->msg_code) { 00399 case COAP_MSG_CODE_REQUEST_GET: 00400 if (resource_temp_ptr->access & SN_GRS_GET_ALLOWED) { 00401 status = COAP_MSG_CODE_RESPONSE_CONTENT; 00402 static_get_request = true; 00403 } else { 00404 status = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00405 } 00406 break; 00407 00408 case COAP_MSG_CODE_REQUEST_POST: 00409 case COAP_MSG_CODE_REQUEST_PUT: 00410 case COAP_MSG_CODE_REQUEST_DELETE: 00411 status = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; 00412 break; 00413 00414 default: 00415 status = COAP_MSG_CODE_RESPONSE_FORBIDDEN; 00416 break; 00417 } 00418 } 00419 } 00420 00421 /* * * * * * * * * * * * * * */ 00422 /* If resource was not found */ 00423 /* * * * * * * * * * * * * * */ 00424 00425 else { 00426 if (coap_packet_ptr->msg_code == COAP_MSG_CODE_REQUEST_POST) { 00427 handle->sn_grs_rx_callback(nsdl_handle, coap_packet_ptr, src_addr_ptr); 00428 00429 if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) { 00430 handle->sn_grs_free(coap_packet_ptr->payload_ptr); 00431 coap_packet_ptr->payload_ptr = 0; 00432 } 00433 00434 sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_packet_ptr); 00435 return SN_NSDL_SUCCESS; 00436 } else { 00437 status = COAP_MSG_CODE_RESPONSE_NOT_FOUND; 00438 } 00439 } 00440 } 00441 00442 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 00443 /* If received packed was other than reset, create response */ 00444 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 00445 if (coap_packet_ptr->msg_type != COAP_MSG_TYPE_RESET && coap_packet_ptr->msg_type != COAP_MSG_TYPE_ACKNOWLEDGEMENT) { 00446 00447 /* Allocate resopnse message */ 00448 response_message_hdr_ptr = sn_coap_parser_alloc_message(handle->coap); 00449 if (!response_message_hdr_ptr) { 00450 if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) { 00451 handle->sn_grs_free(coap_packet_ptr->payload_ptr); 00452 coap_packet_ptr->payload_ptr = 0; 00453 } 00454 sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_packet_ptr); 00455 return SN_NSDL_FAILURE; 00456 } 00457 00458 /* If status has not been defined, response internal server error */ 00459 if (status == COAP_MSG_CODE_EMPTY) { 00460 status = COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR; 00461 } 00462 00463 /* Fill header */ 00464 response_message_hdr_ptr->msg_code = status; 00465 00466 if (coap_packet_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE) { 00467 response_message_hdr_ptr->msg_type = COAP_MSG_TYPE_ACKNOWLEDGEMENT; 00468 } else { 00469 response_message_hdr_ptr->msg_type = COAP_MSG_TYPE_NON_CONFIRMABLE; 00470 } 00471 00472 response_message_hdr_ptr->msg_id = coap_packet_ptr->msg_id; 00473 00474 if (coap_packet_ptr->token_ptr) { 00475 response_message_hdr_ptr->token_len = coap_packet_ptr->token_len; 00476 response_message_hdr_ptr->token_ptr = handle->sn_grs_alloc(response_message_hdr_ptr->token_len); 00477 if (!response_message_hdr_ptr->token_ptr) { 00478 sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, response_message_hdr_ptr); 00479 00480 if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) { 00481 handle->sn_grs_free(coap_packet_ptr->payload_ptr); 00482 coap_packet_ptr->payload_ptr = 0; 00483 } 00484 00485 sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_packet_ptr); 00486 return SN_NSDL_FAILURE; 00487 } 00488 memcpy(response_message_hdr_ptr->token_ptr, coap_packet_ptr->token_ptr, response_message_hdr_ptr->token_len); 00489 } 00490 00491 if (status == COAP_MSG_CODE_RESPONSE_CONTENT) { 00492 /* Add content type if other than default */ 00493 if (resource_temp_ptr->static_resource_parameters) { 00494 response_message_hdr_ptr->content_format = 00495 (sn_coap_content_format_e) resource_temp_ptr->coap_content_type; 00496 } 00497 00498 /* Add payload */ 00499 if (resource_temp_ptr->resourcelen != 0) { 00500 response_message_hdr_ptr->payload_len = resource_temp_ptr->resourcelen; 00501 response_message_hdr_ptr->payload_ptr = handle->sn_grs_alloc(response_message_hdr_ptr->payload_len); 00502 00503 if (!response_message_hdr_ptr->payload_ptr) { 00504 sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, response_message_hdr_ptr); 00505 00506 if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) { 00507 handle->sn_grs_free(coap_packet_ptr->payload_ptr); 00508 coap_packet_ptr->payload_ptr = 0; 00509 } 00510 00511 sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_packet_ptr); 00512 return SN_NSDL_FAILURE; 00513 } 00514 00515 memcpy(response_message_hdr_ptr->payload_ptr, 00516 resource_temp_ptr->resource, 00517 response_message_hdr_ptr->payload_len); 00518 } 00519 // Add max-age attribute for static resources. 00520 // Not a mandatory parameter, no need to return in case of memory allocation fails. 00521 if (static_get_request) { 00522 if (sn_coap_parser_alloc_options(handle->coap, response_message_hdr_ptr)) { 00523 response_message_hdr_ptr->options_list_ptr->max_age = 0; 00524 } 00525 } 00526 } 00527 sn_grs_send_coap_message(nsdl_handle, src_addr_ptr, response_message_hdr_ptr); 00528 00529 if (response_message_hdr_ptr->payload_ptr) { 00530 handle->sn_grs_free(response_message_hdr_ptr->payload_ptr); 00531 response_message_hdr_ptr->payload_ptr = 0; 00532 } 00533 sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, response_message_hdr_ptr); 00534 } 00535 00536 /* Free parsed CoAP message */ 00537 if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) { 00538 handle->sn_grs_free(coap_packet_ptr->payload_ptr); 00539 coap_packet_ptr->payload_ptr = 0; 00540 } 00541 sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_packet_ptr); 00542 00543 return SN_NSDL_SUCCESS; 00544 } 00545 00546 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) 00547 { 00548 uint8_t *message_ptr = NULL; 00549 uint16_t message_len = 0; 00550 int16_t ret_val = 0; 00551 00552 if( !handle ){ 00553 return SN_NSDL_FAILURE; 00554 } 00555 00556 #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwising is not used at all, this part of code will not be compiled */ 00557 ret_val = prepare_blockwise_message(handle->grs->coap, coap_hdr_ptr); 00558 if( 0 != ret_val ) { 00559 return SN_NSDL_FAILURE; 00560 } 00561 #endif 00562 00563 /* Calculate message length */ 00564 message_len = sn_coap_builder_calc_needed_packet_data_size_2(coap_hdr_ptr, handle->grs->coap->sn_coap_block_data_size); 00565 00566 /* Allocate memory for message and check was allocating successfully */ 00567 message_ptr = handle->grs->sn_grs_alloc(message_len); 00568 if (message_ptr == NULL) { 00569 return SN_NSDL_FAILURE; 00570 } 00571 00572 /* Build CoAP message */ 00573 ret_val = sn_coap_protocol_build(handle->grs->coap, address_ptr, message_ptr, coap_hdr_ptr, (void *)handle); 00574 if (ret_val < 0) { 00575 handle->grs->sn_grs_free(message_ptr); 00576 message_ptr = 0; 00577 if (ret_val == -4) { 00578 return SN_NSDL_RESEND_QUEUE_FULL; 00579 } else { 00580 return SN_NSDL_FAILURE; 00581 } 00582 } 00583 00584 /* Call tx callback function to send message */ 00585 ret_val = handle->grs->sn_grs_tx_callback(handle, SN_NSDL_PROTOCOL_COAP, message_ptr, message_len, address_ptr); 00586 00587 /* Free allocated memory */ 00588 handle->grs->sn_grs_free(message_ptr); 00589 message_ptr = 0; 00590 00591 if (ret_val == 0) { 00592 return SN_NSDL_FAILURE; 00593 } else { 00594 return SN_NSDL_SUCCESS; 00595 } 00596 } 00597 00598 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) 00599 { 00600 sn_coap_hdr_s *response_message_hdr_ptr = NULL; 00601 sn_coap_content_format_e wellknown_content_format = COAP_CT_LINK_FORMAT; 00602 00603 /* Allocate response message */ 00604 response_message_hdr_ptr = sn_coap_parser_alloc_message(handle->grs->coap); 00605 if (response_message_hdr_ptr == NULL) { 00606 if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) { 00607 handle->grs->sn_grs_free(coap_packet_ptr->payload_ptr); 00608 coap_packet_ptr->payload_ptr = 0; 00609 } 00610 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr); 00611 return SN_NSDL_FAILURE; 00612 } 00613 00614 /* Build response */ 00615 response_message_hdr_ptr->msg_code = COAP_MSG_CODE_RESPONSE_CONTENT; 00616 response_message_hdr_ptr->msg_type = COAP_MSG_TYPE_ACKNOWLEDGEMENT; 00617 response_message_hdr_ptr->msg_id = coap_packet_ptr->msg_id; 00618 response_message_hdr_ptr->content_format = wellknown_content_format; 00619 00620 sn_nsdl_build_registration_body(handle, response_message_hdr_ptr, 0); 00621 00622 /* Send and free */ 00623 sn_grs_send_coap_message(handle, src_addr_ptr, response_message_hdr_ptr); 00624 00625 if (response_message_hdr_ptr->payload_ptr) { 00626 handle->grs->sn_grs_free(response_message_hdr_ptr->payload_ptr); 00627 response_message_hdr_ptr->payload_ptr = 0; 00628 } 00629 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, response_message_hdr_ptr); 00630 00631 /* Free parsed CoAP message */ 00632 if (coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED && coap_packet_ptr->payload_ptr) { 00633 handle->grs->sn_grs_free(coap_packet_ptr->payload_ptr); 00634 coap_packet_ptr->payload_ptr = 0; 00635 } 00636 sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr); 00637 00638 return SN_NSDL_SUCCESS; 00639 } 00640 00641 /** 00642 * \fn static sn_grs_resource_info_s *sn_grs_search_resource(struct grs_s *handle, const char *path, uint8_t search_method) 00643 * 00644 * \brief Searches given resource from linked list 00645 * 00646 * Search either precise path, or subresources, eg. dr/x -> returns dr/x/1, dr/x/2 etc... 00647 * 00648 * \param pathlen Length of the path to be search 00649 * 00650 * \param *path Pointer to the path string to be search 00651 * 00652 * \param search_method Search method, SEARCH or DELETE 00653 * 00654 * \return Pointer to the resource. If resource not found, return value is NULL 00655 * 00656 */ 00657 00658 sn_nsdl_dynamic_resource_parameters_s *sn_grs_search_resource(struct grs_s *handle, const char *path, uint8_t search_method) 00659 { 00660 /* Local variables */ 00661 char *path_temp_ptr = NULL; 00662 /* Check parameters */ 00663 if (!handle || !path) { 00664 return NULL; 00665 } 00666 uint16_t pathlen = strlen(path); 00667 /* Remove '/' - marks from the end and beginning */ 00668 path_temp_ptr = sn_grs_convert_uri(&pathlen, path); 00669 00670 /* Searchs exact path */ 00671 if (search_method == SN_GRS_SEARCH_METHOD) { 00672 /* Scan all nodes on list */ 00673 ns_list_foreach(sn_nsdl_dynamic_resource_parameters_s, resource_search_temp, &handle->resource_root_list) { 00674 /* If length equals.. */ 00675 size_t len = 0; 00676 if(resource_search_temp && 00677 resource_search_temp->static_resource_parameters && 00678 resource_search_temp->static_resource_parameters->path) { 00679 len = strlen(resource_search_temp->static_resource_parameters->path); 00680 } 00681 00682 if (len == pathlen) { 00683 /* Compare paths, If same return node pointer*/ 00684 if (0 == memcmp(resource_search_temp->static_resource_parameters->path, 00685 path_temp_ptr, 00686 pathlen)) { 00687 return resource_search_temp; 00688 } 00689 } 00690 } 00691 } 00692 /* Search also subresources, eg. dr/x -> returns dr/x/1, dr/x/2 etc... */ 00693 else if (search_method == SN_GRS_DELETE_METHOD) { 00694 /* Scan all nodes on list */ 00695 ns_list_foreach(sn_nsdl_dynamic_resource_parameters_s, resource_search_temp, &handle->resource_root_list) { 00696 char *temp_path = resource_search_temp->static_resource_parameters->path; 00697 if (strlen(resource_search_temp->static_resource_parameters->path) > pathlen && 00698 (*(temp_path + (uint8_t)pathlen) == '/') && 00699 0 == memcmp(resource_search_temp->static_resource_parameters->path, 00700 path_temp_ptr, 00701 pathlen)) { 00702 return resource_search_temp; 00703 } 00704 } 00705 } 00706 00707 /* If there was not nodes we wanted, return NULL */ 00708 return NULL; 00709 } 00710 00711 /** 00712 * \fn static uint8_t *sn_grs_convert_uri(uint16_t *uri_len, uint8_t *uri_ptr) 00713 * 00714 * \brief Removes '/' from the beginning and from the end of uri string 00715 * 00716 * \param *uri_len Pointer to the length of the path string 00717 * 00718 * \param *uri_ptr Pointer to the path string 00719 * 00720 * \return start pointer of the uri 00721 * 00722 */ 00723 00724 static char *sn_grs_convert_uri(uint16_t *uri_len, const char *uri_ptr) 00725 { 00726 /* Local variables */ 00727 char *uri_start_ptr = (char *) uri_ptr; 00728 00729 /* If '/' in the beginning, update uri start pointer and uri len */ 00730 if (*uri_ptr == '/') { 00731 uri_start_ptr = (char *) uri_ptr + 1; 00732 *uri_len = *uri_len - 1; 00733 } 00734 00735 /* If '/' at the end, update uri len */ 00736 if (*(uri_start_ptr + *uri_len - 1) == '/') { 00737 *uri_len = *uri_len - 1; 00738 } 00739 00740 /* Return start pointer */ 00741 return uri_start_ptr; 00742 } 00743 00744 /** 00745 * \fn static int8_t sn_grs_resource_info_free(sn_grs_resource_info_s *resource_ptr) 00746 * 00747 * \brief Frees resource info structure 00748 * 00749 * \param *resource_ptr Pointer to the resource 00750 * 00751 * \return 0 if success, -1 if failed 00752 * 00753 */ 00754 static int8_t sn_grs_resource_info_free(struct grs_s *handle, sn_nsdl_dynamic_resource_parameters_s *resource_ptr) 00755 { 00756 if (resource_ptr) { 00757 #ifdef MEMORY_OPTIMIZED_API 00758 if (resource_ptr->free_on_delete) { 00759 handle->sn_grs_free(resource_ptr); 00760 } 00761 return SN_NSDL_FAILURE; 00762 #else 00763 if (resource_ptr->static_resource_parameters && 00764 resource_ptr->static_resource_parameters->free_on_delete) { 00765 #ifndef RESOURCE_ATTRIBUTES_LIST 00766 #ifndef DISABLE_INTERFACE_DESCRIPTION 00767 if (resource_ptr->static_resource_parameters->interface_description_ptr) { 00768 handle->sn_grs_free(resource_ptr->static_resource_parameters->interface_description_ptr); 00769 resource_ptr->static_resource_parameters->interface_description_ptr = 0; 00770 } 00771 #endif 00772 #ifndef DISABLE_RESOURCE_TYPE 00773 if (resource_ptr->static_resource_parameters->resource_type_ptr) { 00774 handle->sn_grs_free(resource_ptr->static_resource_parameters->resource_type_ptr); 00775 resource_ptr->static_resource_parameters->resource_type_ptr = 0; 00776 } 00777 #endif 00778 #else 00779 sn_nsdl_free_resource_attributes_list(resource_ptr->static_resource_parameters); 00780 #endif 00781 if (resource_ptr->static_resource_parameters->path) { 00782 handle->sn_grs_free(resource_ptr->static_resource_parameters->path); 00783 resource_ptr->static_resource_parameters->path = 0; 00784 } 00785 00786 if (resource_ptr->resource) { 00787 handle->sn_grs_free(resource_ptr->resource); 00788 resource_ptr->resource = 0; 00789 } 00790 00791 handle->sn_grs_free(resource_ptr->static_resource_parameters); 00792 resource_ptr->static_resource_parameters = 0; 00793 } 00794 if (resource_ptr->free_on_delete) { 00795 handle->sn_grs_free(resource_ptr); 00796 } 00797 return SN_NSDL_SUCCESS; 00798 #endif 00799 } 00800 return SN_NSDL_FAILURE; //Dead code? 00801 } 00802 00803 void sn_grs_mark_resources_as_registered(struct nsdl_s *handle) 00804 { 00805 if( !handle ){ 00806 return; 00807 } 00808 00809 sn_nsdl_dynamic_resource_parameters_s *temp_resource; 00810 00811 temp_resource = sn_grs_get_first_resource(handle->grs); 00812 00813 while (temp_resource) { 00814 if (temp_resource->registered == SN_NDSL_RESOURCE_REGISTERING) { 00815 temp_resource->registered = SN_NDSL_RESOURCE_REGISTERED; 00816 } 00817 temp_resource = sn_grs_get_next_resource(handle->grs, temp_resource); 00818 } 00819 }
Generated on Tue Jul 12 2022 16:22:11 by 1.7.2