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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
coap_message_handler.c
00001 /* 00002 * Copyright (c) 2015-2019, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #include <string.h> 00019 #include "nsdynmemLIB.h" 00020 #include "coap_service_api_internal.h" 00021 #include "coap_message_handler.h" 00022 #include "mbed-coap/sn_coap_protocol.h" 00023 #include "source/include/sn_coap_protocol_internal.h" 00024 #include "socket_api.h" 00025 #include "ns_types.h" 00026 #include "ns_list.h" 00027 #include "ns_trace.h" 00028 #include "randLIB.h" 00029 00030 #define TRACE_GROUP "CoSA" 00031 00032 static void *own_alloc(uint16_t size) 00033 { 00034 if (size) { 00035 return ns_dyn_mem_temporary_alloc(size); 00036 } else { 00037 return 0; 00038 } 00039 } 00040 00041 static void own_free(void *ptr) 00042 { 00043 if (ptr) { 00044 ns_dyn_mem_free(ptr); 00045 } 00046 } 00047 00048 static NS_LIST_DEFINE(request_list, coap_transaction_t, link); 00049 00050 static coap_transaction_t *transaction_find_client_by_token(uint8_t *token, uint8_t token_len, const uint8_t address[static 16], uint16_t port) 00051 { 00052 (void) address; 00053 (void) port; 00054 coap_transaction_t *this = NULL; 00055 00056 ns_list_foreach(coap_transaction_t, cur_ptr, &request_list) { 00057 if ((cur_ptr->token_len == token_len) && (memcmp(cur_ptr->token, token, token_len) == 0) && cur_ptr->client_request) { 00058 this = cur_ptr; 00059 break; 00060 } 00061 } 00062 return this; 00063 } 00064 00065 static coap_transaction_t *transaction_find_server(uint16_t msg_id) 00066 { 00067 coap_transaction_t *this = NULL; 00068 ns_list_foreach(coap_transaction_t, cur_ptr, &request_list) { 00069 if (cur_ptr->msg_id == msg_id && !cur_ptr->client_request) { 00070 this = cur_ptr; 00071 break; 00072 } 00073 } 00074 return this; 00075 } 00076 00077 static coap_transaction_t *transaction_find_client(uint16_t msg_id) 00078 { 00079 coap_transaction_t *this = NULL; 00080 ns_list_foreach(coap_transaction_t, cur_ptr, &request_list) { 00081 if (cur_ptr->msg_id == msg_id && cur_ptr->client_request) { 00082 this = cur_ptr; 00083 break; 00084 } 00085 } 00086 return this; 00087 } 00088 00089 static coap_transaction_t *transaction_find_by_address(uint8_t *address_ptr, uint16_t port) 00090 { 00091 coap_transaction_t *this = NULL; 00092 ns_list_foreach(coap_transaction_t, cur_ptr, &request_list) { 00093 if (cur_ptr->remote_port == port && memcmp(cur_ptr->remote_address, address_ptr, 16) == 0) { 00094 this = cur_ptr; 00095 break; 00096 } 00097 } 00098 return this; 00099 } 00100 00101 static coap_transaction_t *transaction_find_by_service_id(int8_t service_id) 00102 { 00103 coap_transaction_t *this = NULL; 00104 ns_list_foreach(coap_transaction_t, cur_ptr, &request_list) { 00105 if (cur_ptr->service_id == service_id) { 00106 this = cur_ptr; 00107 break; 00108 } 00109 } 00110 return this; 00111 } 00112 00113 /* retransmission valid time is calculated to be max. time that CoAP message sending can take: */ 00114 /* Number of retransmisisons, each retransmission is 2 * previous retransmisison time */ 00115 /* + random factor (max. 1.5) */ 00116 static uint32_t transaction_valid_time_calculate(void) 00117 { 00118 int i; 00119 uint32_t time_valid = 0; 00120 00121 for (i = 0; i <= COAP_RESENDING_COUNT; i++) { 00122 time_valid += (COAP_RESENDING_INTERVAL << i) * 1.5; 00123 } 00124 00125 return time_valid + coap_service_get_internal_timer_ticks(); 00126 } 00127 00128 static coap_transaction_t *transaction_create(void) 00129 { 00130 coap_transaction_t *this = ns_dyn_mem_alloc(sizeof(coap_transaction_t)); 00131 if (this) { 00132 memset(this, 0, sizeof(coap_transaction_t)); 00133 this->client_request = true;// default to client initiated method 00134 this->valid_until = transaction_valid_time_calculate(); 00135 ns_list_add_to_start(&request_list, this); 00136 } 00137 00138 return this; 00139 } 00140 00141 static void transaction_free(coap_transaction_t *this) 00142 { 00143 if (this->data_ptr) { 00144 ns_dyn_mem_free(this->data_ptr); 00145 } 00146 ns_dyn_mem_free(this); 00147 } 00148 00149 void transaction_delete(coap_transaction_t *this) 00150 { 00151 if (!coap_message_handler_transaction_valid(this)) { 00152 return; 00153 } 00154 ns_list_remove(&request_list, this); 00155 transaction_free(this); 00156 00157 return; 00158 } 00159 00160 void transactions_delete_all(uint8_t *address_ptr, uint16_t port) 00161 { 00162 coap_transaction_t *transaction = transaction_find_by_address(address_ptr, port); 00163 00164 while (transaction) { 00165 ns_list_remove(&request_list, transaction); 00166 if (transaction->resp_cb) { 00167 transaction->resp_cb(transaction->service_id, address_ptr, port, NULL); 00168 } 00169 sn_coap_protocol_delete_retransmission(coap_service_handle->coap, transaction->msg_id); 00170 transaction_free(transaction); 00171 transaction = transaction_find_by_address(address_ptr, port); 00172 } 00173 } 00174 00175 static void transactions_delete_all_by_service_id(int8_t service_id) 00176 { 00177 coap_transaction_t *transaction = transaction_find_by_service_id(service_id); 00178 00179 while (transaction) { 00180 ns_list_remove(&request_list, transaction); 00181 if (transaction->resp_cb) { 00182 transaction->resp_cb(transaction->service_id, transaction->remote_address, transaction->remote_port, NULL); 00183 } 00184 sn_coap_protocol_delete_retransmission(coap_service_handle->coap, transaction->msg_id); 00185 transaction_free(transaction); 00186 transaction = transaction_find_by_service_id(service_id); 00187 } 00188 } 00189 00190 static int8_t coap_rx_function(sn_coap_hdr_s *resp_ptr, sn_nsdl_addr_s *address_ptr, void *param) 00191 { 00192 coap_transaction_t *this = NULL; 00193 (void)param; 00194 00195 if (!resp_ptr || !address_ptr) { 00196 return -1; 00197 } 00198 00199 tr_warn("transaction was not handled %d", resp_ptr->msg_id); 00200 00201 if (resp_ptr->coap_status == COAP_STATUS_BUILDER_BLOCK_SENDING_DONE) { 00202 return 0; 00203 } 00204 00205 if (resp_ptr->token_ptr) { 00206 this = transaction_find_client_by_token(resp_ptr->token_ptr, resp_ptr->token_len, address_ptr->addr_ptr, address_ptr->port); 00207 } 00208 if (!this) { 00209 return 0; 00210 } 00211 00212 ns_list_remove(&request_list, this); 00213 if (this->resp_cb) { 00214 this->resp_cb(this->service_id, address_ptr->addr_ptr, address_ptr->port, NULL); 00215 } 00216 transaction_free(this); 00217 return 0; 00218 } 00219 00220 coap_msg_handler_t *coap_message_handler_init(void *(*used_malloc_func_ptr)(uint16_t), void (*used_free_func_ptr)(void *), 00221 uint8_t (*used_tx_callback_ptr)(uint8_t *, uint16_t, sn_nsdl_addr_s *, void *)) 00222 { 00223 00224 if ((used_malloc_func_ptr == NULL) || (used_free_func_ptr == NULL) || (used_tx_callback_ptr == NULL)) { 00225 return NULL; 00226 } 00227 00228 coap_msg_handler_t *handle; 00229 handle = ns_dyn_mem_alloc(sizeof(coap_msg_handler_t)); 00230 if (handle == NULL) { 00231 return NULL; 00232 } 00233 00234 memset(handle, 0, sizeof(coap_msg_handler_t)); 00235 00236 handle->sn_coap_tx_callback = used_tx_callback_ptr; 00237 00238 handle->sn_coap_service_free = used_free_func_ptr; 00239 handle->sn_coap_service_malloc = used_malloc_func_ptr; 00240 00241 handle->coap = sn_coap_protocol_init(used_malloc_func_ptr, used_free_func_ptr, used_tx_callback_ptr, &coap_rx_function); 00242 if (!handle->coap) { 00243 ns_dyn_mem_free(handle); 00244 return NULL; 00245 } 00246 00247 /* Set default buffer size for CoAP duplicate message detection */ 00248 sn_coap_protocol_set_duplicate_buffer_size(handle->coap, DUPLICATE_MESSAGE_BUFFER_SIZE); 00249 00250 /* Set default blockwise message size. */ 00251 sn_coap_protocol_set_block_size(handle->coap, DEFAULT_BLOCKWISE_DATA_SIZE); 00252 00253 /* Set default CoAP retransmission paramters */ 00254 sn_coap_protocol_set_retransmission_parameters(handle->coap, COAP_RESENDING_COUNT, COAP_RESENDING_INTERVAL); 00255 00256 return handle; 00257 } 00258 00259 int8_t coap_message_handler_destroy(coap_msg_handler_t *handle) 00260 { 00261 if (!handle) { 00262 return -1; 00263 } 00264 00265 if (handle->coap) { 00266 sn_coap_protocol_destroy(handle->coap); 00267 } 00268 00269 //Destroy transactions 00270 ns_list_foreach_safe(coap_transaction_t, cur_ptr, &request_list) { 00271 ns_list_remove(&request_list, cur_ptr); 00272 ns_dyn_mem_free(cur_ptr); 00273 cur_ptr = NULL; 00274 } 00275 00276 handle->sn_coap_service_free(handle); 00277 return 0; 00278 } 00279 00280 coap_transaction_t *coap_message_handler_transaction_valid(coap_transaction_t *tr_ptr) 00281 { 00282 ns_list_foreach(coap_transaction_t, cur_ptr, &request_list) { 00283 if (cur_ptr == tr_ptr) { 00284 return tr_ptr; 00285 } 00286 } 00287 return NULL; 00288 } 00289 00290 coap_transaction_t *coap_message_handler_find_transaction(uint8_t *address_ptr, uint16_t port) 00291 { 00292 if (!address_ptr) { 00293 return NULL; 00294 } 00295 return transaction_find_by_address(address_ptr, port); 00296 } 00297 00298 int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t socket_id, int8_t recv_if_id, const uint8_t source_addr_ptr[static 16], uint16_t port, const uint8_t dst_addr_ptr[static 16], 00299 uint8_t *data_ptr, uint16_t data_len, coap_msg_process_cb *msg_process_callback) 00300 { 00301 sn_nsdl_addr_s src_addr; 00302 sn_coap_hdr_s *coap_message; 00303 int16_t ret_val = 0; 00304 coap_transaction_t *this = NULL; 00305 00306 if (!msg_process_callback || !handle) { 00307 return -1; 00308 } 00309 00310 src_addr.addr_ptr = (uint8_t *)source_addr_ptr; 00311 src_addr.addr_len = 16; 00312 src_addr.type = SN_NSDL_ADDRESS_TYPE_IPV6; 00313 src_addr.port = port; 00314 00315 coap_transaction_t *transaction_ptr = transaction_create(); 00316 if (!transaction_ptr) { 00317 return -1; 00318 } 00319 transaction_ptr->service_id = coap_service_id_find_by_socket(socket_id); 00320 transaction_ptr->client_request = false;// this is server transaction 00321 memcpy(transaction_ptr->local_address, *(dst_addr_ptr) == 0xFF ? ns_in6addr_any : dst_addr_ptr, 16); 00322 memcpy(transaction_ptr->remote_address, source_addr_ptr, 16); 00323 transaction_ptr->remote_port = port; 00324 00325 coap_message = sn_coap_protocol_parse(handle->coap, &src_addr, data_len, data_ptr, transaction_ptr); 00326 if (coap_message == NULL) { 00327 transaction_delete(transaction_ptr); 00328 tr_err("CoAP Parsing failed"); 00329 return -1; 00330 } 00331 00332 tr_debug("CoAP status:%d, type:%d, code:%d, id:%d", coap_message->coap_status, coap_message->msg_type, coap_message->msg_code, coap_message->msg_id); 00333 00334 /* Check, if coap itself sends response, or block receiving is ongoing... */ 00335 if (coap_message->coap_status != COAP_STATUS_OK && coap_message->coap_status != COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED) { 00336 tr_debug("CoAP library responds"); 00337 transaction_delete(transaction_ptr); 00338 ret_val = -1; 00339 goto exit; 00340 } 00341 00342 if (coap_message->msg_code > 0 && coap_message->msg_code < 32) { 00343 /* Request received */ 00344 transaction_ptr->msg_id = coap_message->msg_id; 00345 transaction_ptr->req_msg_type = coap_message->msg_type; 00346 if (coap_message->token_len) { 00347 memcpy(transaction_ptr->token, coap_message->token_ptr, coap_message->token_len); 00348 transaction_ptr->token_len = coap_message->token_len; 00349 } 00350 if (msg_process_callback(socket_id, recv_if_id, coap_message, transaction_ptr, dst_addr_ptr) < 0) { 00351 // negative return value = message ignored -> delete transaction 00352 transaction_delete(transaction_ptr); 00353 } 00354 goto exit; 00355 } else { 00356 /* Response received */ 00357 transaction_delete(transaction_ptr); // transaction_ptr not needed in response 00358 if (coap_message->token_ptr) { 00359 this = transaction_find_client_by_token(coap_message->token_ptr, coap_message->token_len, source_addr_ptr, port); 00360 } 00361 if (!this) { 00362 tr_error("client transaction not found"); 00363 ret_val = -1; 00364 goto exit; 00365 } 00366 tr_debug("Service %d, response received", this->service_id); 00367 ns_list_remove(&request_list, this); 00368 if (this->resp_cb) { 00369 this->resp_cb(this->service_id, (uint8_t *)source_addr_ptr, port, coap_message); 00370 } 00371 transaction_free(this); 00372 } 00373 00374 exit: 00375 if (coap_message->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED) { 00376 handle->sn_coap_service_free(coap_message->payload_ptr); 00377 } 00378 00379 sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_message); 00380 00381 return ret_val; 00382 } 00383 00384 uint16_t coap_message_handler_request_send(coap_msg_handler_t *handle, int8_t service_id, uint8_t options, const uint8_t destination_addr[static 16], 00385 uint16_t destination_port, sn_coap_msg_type_e msg_type, sn_coap_msg_code_e msg_code, const char *uri, 00386 sn_coap_content_format_e cont_type, const uint8_t *payload_ptr, uint16_t payload_len, coap_message_handler_response_recv *request_response_cb) 00387 { 00388 coap_transaction_t *transaction_ptr; 00389 sn_coap_hdr_s request; 00390 sn_nsdl_addr_s dst_addr; 00391 uint8_t token[4]; 00392 uint16_t data_len; 00393 uint8_t *data_ptr; 00394 00395 tr_debug("Service %d, send CoAP request payload_len %d", service_id, payload_len); 00396 transaction_ptr = transaction_create(); 00397 00398 if (!uri || !transaction_ptr || !handle) { 00399 return 0; 00400 } 00401 00402 transaction_ptr->service_id = service_id; 00403 transaction_ptr->client_request = true; 00404 transaction_ptr->resp_cb = request_response_cb; 00405 transaction_ptr->options = options; 00406 memcpy(transaction_ptr->remote_address, destination_addr, 16); 00407 transaction_ptr->remote_port = destination_port; 00408 transaction_ptr->req_msg_type = msg_type; 00409 memset(&request, 0, sizeof(request)); 00410 dst_addr.addr_ptr = (uint8_t *) destination_addr; // Cast away const and trust that nsdl doesn't modify... 00411 dst_addr.addr_len = 16; 00412 dst_addr.type = SN_NSDL_ADDRESS_TYPE_IPV6; 00413 dst_addr.port = destination_port; 00414 00415 request.msg_type = msg_type; 00416 request.msg_code = msg_code; 00417 request.uri_path_ptr = (uint8_t *)uri; 00418 request.uri_path_len = strlen(uri); 00419 request.content_format = cont_type; 00420 00421 do { 00422 randLIB_get_n_bytes_random(token, 4); 00423 } while (transaction_find_client_by_token(token, 4, destination_addr, destination_port)); 00424 memcpy(transaction_ptr->token, token, 4); 00425 transaction_ptr->token_len = 4; 00426 request.token_ptr = transaction_ptr->token; 00427 request.token_len = 4; 00428 00429 request.payload_len = payload_len; 00430 request.payload_ptr = (uint8_t *) payload_ptr; // Cast away const and trust that nsdl doesn't modify... 00431 00432 prepare_blockwise_message(handle->coap, &request); 00433 00434 data_len = sn_coap_builder_calc_needed_packet_data_size_2(&request, sn_coap_protocol_get_configured_blockwise_size(handle->coap)); 00435 data_ptr = own_alloc(data_len); 00436 if (data_len > 0 && !data_ptr) { 00437 transaction_delete(transaction_ptr); 00438 return 0; 00439 } 00440 int16_t sn_coap_ret = sn_coap_protocol_build(handle->coap, &dst_addr, data_ptr, &request, transaction_ptr); 00441 if (sn_coap_ret == -4) { 00442 /* 00443 * Not able to add message to resend queue, adjust message lifetime to one resending 00444 */ 00445 transaction_ptr->valid_until = coap_service_get_internal_timer_ticks() + COAP_RESENDING_INTERVAL; 00446 } else if (sn_coap_ret < 0) { 00447 /* 00448 * Failed to build message, set transaction validity time to minimum to get this transaction cleared 00449 * immediately and callback called. 00450 */ 00451 transaction_ptr->valid_until = coap_service_get_internal_timer_ticks(); 00452 } 00453 00454 transaction_ptr->msg_id = request.msg_id; 00455 handle->sn_coap_tx_callback(data_ptr, data_len, &dst_addr, transaction_ptr); 00456 00457 // Free allocated data 00458 own_free(data_ptr); 00459 if (request.options_list_ptr) { 00460 own_free(request.options_list_ptr); 00461 } 00462 00463 if (request_response_cb == NULL) { 00464 //No response expected 00465 return 0; 00466 } 00467 return request.msg_id; 00468 } 00469 00470 static int8_t coap_message_handler_resp_build_and_send(coap_msg_handler_t *handle, sn_coap_hdr_s *coap_msg_ptr, coap_transaction_t *transaction_ptr) 00471 { 00472 sn_nsdl_addr_s dst_addr; 00473 uint16_t data_len; 00474 uint8_t *data_ptr; 00475 00476 00477 dst_addr.addr_ptr = transaction_ptr->remote_address; 00478 dst_addr.addr_len = 16; 00479 dst_addr.type = SN_NSDL_ADDRESS_TYPE_IPV6; 00480 dst_addr.port = transaction_ptr->remote_port; 00481 #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE 00482 prepare_blockwise_message(handle->coap, coap_msg_ptr); 00483 #endif 00484 data_len = sn_coap_builder_calc_needed_packet_data_size_2(coap_msg_ptr, sn_coap_protocol_get_configured_blockwise_size(handle->coap)); 00485 data_ptr = own_alloc(data_len); 00486 if (data_len > 0 && !data_ptr) { 00487 return -1; 00488 } 00489 sn_coap_protocol_build(handle->coap, &dst_addr, data_ptr, coap_msg_ptr, transaction_ptr); 00490 00491 handle->sn_coap_tx_callback(data_ptr, data_len, &dst_addr, transaction_ptr); 00492 own_free(data_ptr); 00493 00494 return 0; 00495 00496 } 00497 00498 int8_t coap_message_handler_response_send(coap_msg_handler_t *handle, int8_t service_id, uint8_t options, sn_coap_hdr_s *request_ptr, sn_coap_msg_code_e message_code, sn_coap_content_format_e content_type, const uint8_t *payload_ptr, uint16_t payload_len) 00499 { 00500 sn_coap_hdr_s *response; 00501 coap_transaction_t *transaction_ptr; 00502 int8_t ret_val = 0; 00503 (void) options; 00504 (void)service_id; 00505 00506 tr_debug("Service %d, send CoAP response", service_id); 00507 if (!request_ptr || !handle) { 00508 tr_error("invalid params"); 00509 return -1; 00510 } 00511 00512 transaction_ptr = transaction_find_server(request_ptr->msg_id); 00513 00514 if (!transaction_ptr) { 00515 tr_error("response transaction not found"); 00516 return -2; 00517 } 00518 00519 response = sn_coap_build_response(handle->coap, request_ptr, message_code); 00520 if (!response) { 00521 return -1; 00522 } 00523 response->payload_len = payload_len; 00524 response->payload_ptr = (uint8_t *) payload_ptr; // Cast away const and trust that nsdl doesn't modify... 00525 response->content_format = content_type; 00526 00527 00528 ret_val = coap_message_handler_resp_build_and_send(handle, response, transaction_ptr); 00529 sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, response); 00530 if (ret_val == 0) { 00531 transaction_delete(transaction_ptr); 00532 } 00533 00534 return ret_val; 00535 } 00536 00537 int8_t coap_message_handler_response_send_by_msg_id(coap_msg_handler_t *handle, int8_t service_id, uint8_t options, uint16_t msg_id, sn_coap_msg_code_e message_code, sn_coap_content_format_e content_type, const uint8_t *payload_ptr, uint16_t payload_len) 00538 { 00539 sn_coap_hdr_s response; 00540 coap_transaction_t *transaction_ptr; 00541 int8_t ret_val; 00542 00543 (void) options; 00544 (void)service_id; 00545 00546 transaction_ptr = transaction_find_server(msg_id); 00547 if (!transaction_ptr || !handle) { 00548 return -1; 00549 } 00550 00551 tr_debug("Service %d, send CoAP response", service_id); 00552 00553 memset(&response, 0, sizeof(sn_coap_hdr_s)); 00554 00555 response.payload_len = payload_len; 00556 response.payload_ptr = (uint8_t *) payload_ptr; // Cast away const and trust that nsdl doesn't modify... 00557 response.content_format = content_type; 00558 response.token_len = transaction_ptr->token_len; 00559 response.token_ptr = transaction_ptr->token; 00560 response.msg_code = message_code; 00561 if (transaction_ptr->req_msg_type == COAP_MSG_TYPE_CONFIRMABLE) { 00562 response.msg_type = COAP_MSG_TYPE_ACKNOWLEDGEMENT; 00563 response.msg_id = msg_id; 00564 } else { 00565 response.msg_type = COAP_MSG_TYPE_NON_CONFIRMABLE; 00566 } 00567 00568 ret_val = coap_message_handler_resp_build_and_send(handle, &response, transaction_ptr); 00569 if (ret_val == 0) { 00570 transaction_delete(transaction_ptr); 00571 } 00572 00573 return ret_val; 00574 } 00575 00576 int8_t coap_message_handler_request_delete(coap_msg_handler_t *handle, int8_t service_id, uint16_t msg_id) 00577 { 00578 coap_transaction_t *transaction_ptr; 00579 (void)service_id; 00580 00581 00582 tr_debug("Service %d, delete CoAP request %d", service_id, msg_id); 00583 if (!handle) { 00584 tr_error("invalid params"); 00585 return -1; 00586 } 00587 00588 sn_coap_protocol_delete_retransmission(handle->coap, msg_id); 00589 00590 transaction_ptr = transaction_find_client(msg_id); 00591 if (!transaction_ptr) { 00592 tr_error("response transaction not found"); 00593 return -2; 00594 } 00595 00596 if (transaction_ptr->resp_cb) { 00597 transaction_ptr->resp_cb(transaction_ptr->service_id, transaction_ptr->remote_address, transaction_ptr->remote_port, NULL); 00598 } 00599 transaction_delete(transaction_ptr); 00600 return 0; 00601 } 00602 00603 int8_t coap_message_handler_request_delete_by_service_id(coap_msg_handler_t *handle, int8_t service_id) 00604 { 00605 tr_debug("Service %d, delete all CoAP requests", service_id); 00606 00607 if (!handle) { 00608 tr_error("invalid params"); 00609 return -1; 00610 } 00611 00612 transactions_delete_all_by_service_id(service_id); 00613 00614 return 0; 00615 } 00616 00617 int8_t coap_message_handler_exec(coap_msg_handler_t *handle, uint32_t current_time) 00618 { 00619 00620 if (!handle) { 00621 return -1; 00622 } 00623 00624 // Remove outdated transactions from queue 00625 ns_list_foreach_safe(coap_transaction_t, transaction, &request_list) { 00626 if (transaction->valid_until < current_time) { 00627 tr_debug("transaction %d timed out", transaction->msg_id); 00628 ns_list_remove(&request_list, transaction); 00629 if (transaction->resp_cb) { 00630 transaction->resp_cb(transaction->service_id, transaction->remote_address, transaction->remote_port, NULL); 00631 } 00632 transaction_free(transaction); 00633 } 00634 } 00635 00636 return sn_coap_protocol_exec(handle->coap, current_time); 00637 }
Generated on Tue Jul 12 2022 13:54:12 by
