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_service_api.c
00001 /* 00002 * Copyright (c) 2015-2017, 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 00019 00020 #include <string.h> 00021 00022 #include "ns_types.h" 00023 #include "ns_list.h" 00024 #include "ns_trace.h" 00025 #include "nsdynmemLIB.h" 00026 #include "mbed-coap/sn_coap_header.h" 00027 #include "coap_service_api.h" 00028 #include "coap_message_handler.h" 00029 #include "eventOS_event.h" 00030 #include "eventOS_scheduler.h" 00031 #include "eventOS_event_timer.h" 00032 #include "common_functions.h" 00033 #include "coap_connection_handler.h" 00034 #include "net_interface.h" 00035 #include "coap_service_api_internal.h" 00036 #include "coap_message_handler.h" 00037 #include "mbed-coap/sn_coap_protocol.h" 00038 00039 static int16_t coap_msg_process_callback(int8_t socket_id, int8_t recv_if_id, sn_coap_hdr_s *coap_message, coap_transaction_t *transaction_ptr, const uint8_t *local_addr); 00040 00041 typedef struct uri_registration { 00042 char *uri_ptr; 00043 uint16_t uri_len; 00044 uint8_t allowed_method; 00045 coap_service_request_recv_cb *request_recv_cb; 00046 ns_list_link_t link; 00047 } uri_registration_t; 00048 00049 typedef NS_LIST_HEAD (uri_registration_t, link) uri_registration_list_t; 00050 00051 typedef struct coap_service { 00052 coap_service_security_done_cb *coap_security_done_cb; 00053 coap_service_security_start_cb *security_start_cb; 00054 coap_service_virtual_socket_send_cb *virtual_socket_send_cb; 00055 uri_registration_list_t uri_list; 00056 coap_conn_handler_t *conn_handler; 00057 int8_t interface_id; 00058 int8_t service_id; 00059 int8_t listen_socket; 00060 uint8_t service_options; 00061 ns_list_link_t link; 00062 } coap_service_t; 00063 00064 #define TRACE_GROUP "ThSA" 00065 00066 static NS_LIST_DEFINE(instance_list, coap_service_t, link); 00067 static int8_t tasklet_id = -1; 00068 coap_msg_handler_t *coap_service_handle = NULL; 00069 static uint32_t coap_ticks = 1; 00070 00071 #define COAP_TICK_TIMER 0xf1 00072 00073 //#define TRACE_DEEP 00074 #ifdef TRACE_DEEP 00075 #define tr_deep tr_debug 00076 #else 00077 #define tr_deep(...) 00078 #endif 00079 00080 static uri_registration_t *uri_registration_find(coap_service_t *this, const void *uri_ptr, uint16_t uri_len) 00081 { 00082 ns_list_foreach(uri_registration_t, cur_ptr, &this->uri_list) { 00083 if (cur_ptr->uri_len == uri_len && memcmp(cur_ptr->uri_ptr, uri_ptr, uri_len) == 0) { 00084 return cur_ptr; 00085 } 00086 } 00087 return NULL; 00088 } 00089 static coap_service_t *service_find(int8_t service_id) 00090 { 00091 coap_service_t *this = NULL; 00092 ns_list_foreach(coap_service_t, cur_ptr, &instance_list) { 00093 if (cur_ptr->service_id == service_id) { 00094 this = cur_ptr; 00095 break; 00096 } 00097 } 00098 return this; 00099 } 00100 00101 static coap_service_t *service_find_by_socket(int8_t socket_id) 00102 { 00103 coap_service_t *this = NULL; 00104 ns_list_foreach(coap_service_t, cur_ptr, &instance_list) { 00105 if (coap_connection_handler_socket_belongs_to(cur_ptr->conn_handler, socket_id)) { 00106 this = cur_ptr; 00107 break; 00108 } 00109 } 00110 return this; 00111 } 00112 00113 static coap_service_t *service_find_by_uri(uint8_t socket_id, uint8_t *uri_ptr, uint16_t uri_len) 00114 { 00115 ns_list_foreach(coap_service_t, cur_ptr, &instance_list) { 00116 if (coap_connection_handler_socket_belongs_to(cur_ptr->conn_handler, socket_id) && uri_registration_find(cur_ptr, uri_ptr, uri_len)) { 00117 return cur_ptr; 00118 } 00119 } 00120 return NULL; 00121 } 00122 00123 static bool coap_service_can_leave_multicast_group(coap_conn_handler_t *conn_handler) 00124 { 00125 int mc_count = 0; 00126 bool current_handler_joined_to_mc_group = false; 00127 00128 ns_list_foreach(coap_service_t, cur_ptr, &instance_list) { 00129 if (cur_ptr->conn_handler && cur_ptr->conn_handler->registered_to_multicast) { 00130 if (conn_handler == cur_ptr->conn_handler) { 00131 current_handler_joined_to_mc_group = true; 00132 } 00133 mc_count ++; 00134 } 00135 } 00136 00137 if (mc_count == 1 && current_handler_joined_to_mc_group) { 00138 // current handler is the only one joined to multicast group 00139 return true; 00140 } 00141 00142 return false; 00143 } 00144 00145 /** 00146 * Coap handling functions 00147 */ 00148 static void *own_alloc(uint16_t size) 00149 { 00150 if (size) { 00151 return ns_dyn_mem_temporary_alloc(size); 00152 } else { 00153 return 0; 00154 } 00155 } 00156 00157 static void own_free(void *ptr) 00158 { 00159 if (ptr) { 00160 ns_dyn_mem_free(ptr); 00161 } 00162 } 00163 00164 static uint8_t coap_tx_function(uint8_t *data_ptr, uint16_t data_len, sn_nsdl_addr_s *address_ptr, void *param) 00165 { 00166 coap_service_t *this; 00167 coap_transaction_t *transaction_ptr = coap_message_handler_transaction_valid(param); 00168 ns_address_t dest_addr; 00169 int ret_val; 00170 00171 if (!transaction_ptr || !data_ptr) { 00172 return 0; 00173 } 00174 00175 tr_debug("Service %d, CoAP TX - mid: %d", transaction_ptr->service_id, common_read_16_bit(data_ptr + 2)); 00176 00177 this = service_find(transaction_ptr->service_id); 00178 if (!this) { 00179 return 0; 00180 } 00181 00182 memcpy(&(dest_addr.address), address_ptr->addr_ptr, 16); 00183 dest_addr.identifier = address_ptr->port; 00184 dest_addr.type = ADDRESS_IPV6; 00185 00186 ret_val = coap_connection_handler_send_data(this->conn_handler, &dest_addr, transaction_ptr->local_address, 00187 data_ptr, data_len, (this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS) == COAP_SERVICE_OPTIONS_SECURE_BYPASS); 00188 if (ret_val == 0) { 00189 if (!transaction_ptr->data_ptr) { 00190 transaction_ptr->data_ptr = ns_dyn_mem_alloc(data_len); 00191 if (!transaction_ptr->data_ptr) { 00192 tr_debug("coap tx out of memory"); 00193 return 0; 00194 } 00195 memcpy(transaction_ptr->data_ptr, data_ptr, data_len); 00196 transaction_ptr->data_len = data_len; 00197 } 00198 } else if ((ret_val == -1) || (!transaction_ptr->resp_cb && transaction_ptr->req_msg_type == COAP_MSG_TYPE_NON_CONFIRMABLE)) { 00199 transaction_delete(transaction_ptr); 00200 } 00201 00202 return 0; 00203 } 00204 00205 static void service_event_handler(arm_event_s *event) 00206 { 00207 if (event->event_type == ARM_LIB_TASKLET_INIT_EVENT) { 00208 tr_debug("service tasklet initialised"); 00209 /*initialize coap service and listen socket*/ 00210 } 00211 00212 if (event->event_type == ARM_LIB_SYSTEM_TIMER_EVENT && event->event_id == COAP_TICK_TIMER) { 00213 coap_message_handler_exec(coap_service_handle, coap_ticks++); 00214 if (coap_ticks && !(coap_ticks % SECURE_SESSION_CLEAN_INTERVAL)) { 00215 coap_connection_handler_exec(coap_ticks); 00216 } 00217 } 00218 eventOS_event_timer_request((uint8_t)COAP_TICK_TIMER, ARM_LIB_SYSTEM_TIMER_EVENT, tasklet_id, 1000); 00219 } 00220 00221 static int16_t coap_msg_process_callback(int8_t socket_id, int8_t recv_if_id, sn_coap_hdr_s *coap_message, coap_transaction_t *transaction_ptr, const uint8_t *local_addr) 00222 { 00223 coap_service_t *this; 00224 coap_service_msg_prevalidate_cb *msg_prevalidate_callback; 00225 uint16_t listen_socket_port; 00226 00227 if (!coap_message || !transaction_ptr) { 00228 return -1; 00229 } 00230 00231 // Message is request, find correct handle based on URI 00232 this = service_find_by_uri(socket_id, coap_message->uri_path_ptr, coap_message->uri_path_len); 00233 if (!this) { 00234 tr_deep("URI %.*s not registered", coap_message->uri_path_len, coap_message->uri_path_ptr); 00235 // URI is not available, find any service that holds the same shared socket so that we can get msg_prevalidate_callback to validate addresses 00236 this = service_find_by_socket(socket_id); 00237 if (!this) { 00238 return -1; 00239 } 00240 } 00241 00242 msg_prevalidate_callback = (coap_service_msg_prevalidate_cb *)coap_connection_handler_msg_prevalidate_callback_get(this->conn_handler, &listen_socket_port); 00243 if (msg_prevalidate_callback) { 00244 // message prevalidation activated for the port 00245 char request_uri[coap_message->uri_path_len + 1]; 00246 memcpy(request_uri, coap_message->uri_path_ptr, coap_message->uri_path_len); 00247 request_uri[coap_message->uri_path_len] = 0; 00248 00249 int msg_prevalidate_status = msg_prevalidate_callback(this->interface_id, (uint8_t *)local_addr, listen_socket_port, recv_if_id, transaction_ptr->remote_address, transaction_ptr->remote_port, request_uri); 00250 if (msg_prevalidate_status >= 1) { 00251 tr_deep("Drop CoAP msg %s from %s to %s", request_uri, trace_ipv6(transaction_ptr->remote_address), trace_ipv6(local_addr)); 00252 return -1; 00253 } 00254 } 00255 00256 uri_registration_t *uri_reg_ptr = uri_registration_find(this, coap_message->uri_path_ptr, coap_message->uri_path_len); 00257 if (!uri_reg_ptr) { 00258 /* URI is not available, stop further processing */ 00259 if (coap_message->msg_type == COAP_MSG_TYPE_CONFIRMABLE) { 00260 coap_message_handler_response_send(coap_service_handle, transaction_ptr->service_id, COAP_SERVICE_OPTIONS_NONE, coap_message, 00261 COAP_MSG_CODE_RESPONSE_NOT_FOUND, COAP_CT_NONE, NULL, 0); 00262 return 0; 00263 } 00264 return -1; 00265 } 00266 00267 if (uri_reg_ptr->request_recv_cb) { 00268 if ((this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS) == COAP_SERVICE_OPTIONS_SECURE_BYPASS) { //TODO Add secure bypass option 00269 // Service has secure bypass active TODO this is not defined in interface 00270 // this check can be removed I think 00271 transaction_ptr->options = COAP_REQUEST_OPTIONS_SECURE_BYPASS; 00272 } 00273 00274 transaction_ptr->service_id = this->service_id; 00275 tr_debug("Service %d, recv msg: %.*s", this->service_id, coap_message->uri_path_len, coap_message->uri_path_ptr); 00276 return uri_reg_ptr->request_recv_cb(this->service_id, transaction_ptr->remote_address, transaction_ptr->remote_port, coap_message); 00277 } 00278 00279 return -1; 00280 } 00281 00282 static int recv_cb(int8_t socket_id, int8_t recv_if_id, uint8_t src_address[static 16], uint16_t port, const uint8_t dst_address[static 16], unsigned char *data, int len) 00283 { 00284 uint8_t *data_ptr = NULL; 00285 uint16_t data_len = 0; 00286 00287 if (!data || !len) { 00288 return -1; 00289 } 00290 00291 data_ptr = own_alloc(len); 00292 00293 if (!data_ptr) { 00294 return -1; 00295 } 00296 memcpy(data_ptr, data, len); 00297 data_len = len; 00298 00299 //parse coap message what CoAP to use 00300 int ret = coap_message_handler_coap_msg_process(coap_service_handle, socket_id, recv_if_id, src_address, port, dst_address, data_ptr, data_len, &coap_msg_process_callback); 00301 own_free(data_ptr); 00302 return ret; 00303 } 00304 00305 static int virtual_send_cb(int8_t socket_id, const uint8_t address[static 16], uint16_t port, const void *data_ptr, int data_len) 00306 { 00307 coap_service_t *this = service_find_by_socket(socket_id); 00308 if (this && this->virtual_socket_send_cb) { 00309 tr_debug("send to virtual socket, service: %d", this->service_id); 00310 return this->virtual_socket_send_cb(this->service_id, (uint8_t *)address, port, data_ptr, data_len); 00311 } 00312 return -1; 00313 } 00314 00315 static void sec_done_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t keyblock[static 40]) 00316 { 00317 //TODO: this is not enough if shared socket. Inform all! 00318 coap_service_t *this = service_find_by_socket(socket_id); 00319 if (this && this->coap_security_done_cb) { // secure done callback 00320 this->coap_security_done_cb(this->service_id, address, keyblock); 00321 } 00322 00323 //TODO: send all unsend transactions if more than 1 00324 coap_transaction_t *transaction_ptr = coap_message_handler_find_transaction(address, port); 00325 if (transaction_ptr && transaction_ptr->data_ptr) { 00326 tr_debug("send delayed packet"); 00327 ns_address_t dest_addr; 00328 memcpy(dest_addr.address, address, 16); 00329 dest_addr.identifier = port; 00330 dest_addr.type = ADDRESS_IPV6; 00331 00332 coap_connection_handler_send_data(this->conn_handler, &dest_addr, transaction_ptr->local_address, 00333 transaction_ptr->data_ptr, transaction_ptr->data_len, (this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS) == COAP_SERVICE_OPTIONS_SECURE_BYPASS); 00334 ns_dyn_mem_free(transaction_ptr->data_ptr); 00335 transaction_ptr->data_ptr = NULL; 00336 transaction_ptr->data_len = 0; 00337 if (!transaction_ptr->resp_cb && transaction_ptr->req_msg_type == COAP_MSG_TYPE_NON_CONFIRMABLE) { 00338 transaction_delete(transaction_ptr); 00339 } 00340 } 00341 } 00342 00343 static int get_passwd_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, coap_security_keys_t *security_ptr) 00344 { 00345 uint8_t *pw_ptr = NULL; 00346 uint8_t pw_len = 0; 00347 coap_service_t *this = service_find_by_socket(socket_id); 00348 00349 if (!this || !security_ptr) { 00350 return -1; 00351 } 00352 00353 /* Certificates set */ 00354 if (this->conn_handler->security_keys) { 00355 *security_ptr = *this->conn_handler->security_keys; 00356 return 0; 00357 } 00358 00359 pw_ptr = ns_dyn_mem_alloc(64); 00360 if (!pw_ptr) { 00361 return -1; 00362 } 00363 00364 if (this->security_start_cb && !this->security_start_cb(this->service_id, address, port, pw_ptr, &pw_len)) { 00365 security_ptr->mode = ECJPAKE; 00366 security_ptr->_key = pw_ptr; 00367 security_ptr->_key_len = pw_len; 00368 return 0; 00369 } 00370 00371 return -1; 00372 } 00373 00374 int8_t coap_service_initialize(int8_t interface_id, uint16_t listen_port, uint8_t service_options, 00375 coap_service_security_start_cb *start_ptr, coap_service_security_done_cb *coap_security_done_cb) 00376 { 00377 coap_service_t *this = ns_dyn_mem_alloc(sizeof(coap_service_t)); 00378 00379 if (!this) { 00380 return -1; 00381 } 00382 memset(this, 0, sizeof(coap_service_t)); 00383 tr_debug("service init interface %d, port %d, options %d", interface_id, listen_port, service_options); 00384 00385 int8_t id = 1;// get unique id 00386 while (service_find(id) && id < 127) { 00387 id++; 00388 } 00389 this->interface_id = interface_id; 00390 this->service_id = id; 00391 this->service_options = service_options; 00392 00393 this->security_start_cb = start_ptr; 00394 this->coap_security_done_cb = coap_security_done_cb; 00395 00396 if (tasklet_id == -1) { 00397 tr_debug("service tasklet init"); 00398 tasklet_id = eventOS_event_handler_create(&service_event_handler, ARM_LIB_TASKLET_INIT_EVENT); 00399 } 00400 00401 this->conn_handler = connection_handler_create(recv_cb, virtual_send_cb, get_passwd_cb, sec_done_cb); 00402 if (!this->conn_handler) { 00403 ns_dyn_mem_free(this); 00404 return -1; 00405 } 00406 00407 this->conn_handler->socket_interface_selection = 0; // zero is illegal interface ID 00408 if (this->service_options & COAP_SERVICE_OPTIONS_SELECT_SOCKET_IF) { 00409 this->conn_handler->socket_interface_selection = this->interface_id; 00410 } 00411 00412 this->conn_handler->registered_to_multicast = this->service_options & COAP_SERVICE_OPTIONS_MULTICAST_JOIN; 00413 00414 if (0 > coap_connection_handler_open_connection(this->conn_handler, listen_port, 00415 (this->service_options & COAP_SERVICE_OPTIONS_EPHEMERAL_PORT), 00416 (this->service_options & COAP_SERVICE_OPTIONS_SECURE), 00417 !(this->service_options & COAP_SERVICE_OPTIONS_VIRTUAL_SOCKET), 00418 (this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS))) { 00419 ns_dyn_mem_free(this->conn_handler); 00420 ns_dyn_mem_free(this); 00421 return -1; 00422 } 00423 00424 if (!coap_service_handle) { 00425 coap_service_handle = coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function); 00426 } 00427 if (!coap_service_handle) { 00428 tr_error("coap service alloc failed"); 00429 //TODO proper handling 00430 } 00431 00432 ns_list_add_to_start(&instance_list, this); 00433 00434 return id; 00435 } 00436 00437 void coap_service_delete(int8_t service_id) 00438 { 00439 coap_service_t *this = service_find(service_id); 00440 if (!this) { 00441 return; 00442 } 00443 00444 if (this->conn_handler) { 00445 bool leave_multicast_group = false; 00446 if (coap_service_can_leave_multicast_group(this->conn_handler)) { 00447 // This is the last handler joined to multicast group 00448 leave_multicast_group = true; 00449 } 00450 connection_handler_destroy(this->conn_handler, leave_multicast_group); 00451 } 00452 00453 //TODO clear all transactions 00454 ns_list_foreach_safe(uri_registration_t, cur_ptr, &this->uri_list) { 00455 ns_dyn_mem_free(cur_ptr->uri_ptr); 00456 ns_list_remove(&this->uri_list, cur_ptr); 00457 ns_dyn_mem_free(cur_ptr); 00458 } 00459 00460 ns_list_remove(&instance_list, this); 00461 ns_dyn_mem_free(this); 00462 return; 00463 } 00464 00465 extern void coap_service_close_secure_connection(int8_t service_id, uint8_t destination_addr_ptr[static 16], uint16_t port) 00466 { 00467 coap_service_t *this = service_find(service_id); 00468 if (!this || !destination_addr_ptr) { 00469 return; 00470 } 00471 if (this->conn_handler) { 00472 connection_handler_close_secure_connection(this->conn_handler, destination_addr_ptr, port); 00473 } 00474 } 00475 00476 int16_t coap_service_virtual_socket_recv(int8_t service_id, uint8_t source_addr_ptr[static 16], uint16_t port, uint8_t *data_ptr, uint16_t data_len) 00477 { 00478 coap_service_t *this = service_find(service_id); 00479 tr_debug("Service %d, virtual socket received", service_id); 00480 if (!this) { 00481 return -1; 00482 } 00483 return coap_connection_handler_virtual_recv(this->conn_handler, source_addr_ptr, port, data_ptr, data_len); 00484 } 00485 00486 int16_t coap_service_virtual_socket_set_cb(int8_t service_id, coap_service_virtual_socket_send_cb *send_method_ptr) 00487 { 00488 coap_service_t *this = service_find(service_id); 00489 tr_debug("register virtual socket cb to service %d", service_id); 00490 if (!this) { 00491 return -1; 00492 } 00493 this->virtual_socket_send_cb = send_method_ptr; 00494 return 0; 00495 } 00496 00497 int8_t coap_service_register_uri(int8_t service_id, const char *uri, uint8_t allowed_method, coap_service_request_recv_cb *request_recv_cb) 00498 { 00499 coap_service_t *this = service_find(service_id); 00500 uri_registration_t *uri_reg_ptr; 00501 char *uri_ptr = NULL; 00502 uint16_t uri_len; 00503 tr_debug("Service %d, Uri registration uri: %s", service_id, uri); 00504 if (!this || !uri) { 00505 return -1; 00506 } 00507 uri_len = strlen(uri); 00508 00509 uri_reg_ptr = uri_registration_find(this, uri, uri_len); 00510 if (!uri_reg_ptr) { 00511 uri_reg_ptr = ns_dyn_mem_alloc(sizeof(uri_registration_t)); 00512 if (!uri_reg_ptr) { 00513 tr_error("Uri registration failed, OOM"); 00514 return -2; 00515 } 00516 uri_reg_ptr->uri_ptr = NULL; 00517 } else { 00518 ns_dyn_mem_free(uri_reg_ptr->uri_ptr); 00519 ns_list_remove(&this->uri_list, uri_reg_ptr); 00520 } 00521 00522 uri_ptr = ns_dyn_mem_alloc(uri_len); 00523 if (!uri_ptr) { 00524 ns_dyn_mem_free(uri_reg_ptr); 00525 tr_error("Uri registration failed, OOM"); 00526 return -2; 00527 } 00528 00529 uri_reg_ptr->uri_ptr = memcpy(uri_ptr, uri, uri_len); 00530 uri_reg_ptr->uri_len = uri_len; 00531 uri_reg_ptr->request_recv_cb = request_recv_cb; 00532 uri_reg_ptr->allowed_method = allowed_method; 00533 ns_list_add_to_start(&this->uri_list, uri_reg_ptr); 00534 return 0; 00535 } 00536 00537 int8_t coap_service_unregister_uri(int8_t service_id, const char *uri) 00538 { 00539 coap_service_t *this = service_find(service_id); 00540 uri_registration_t *uri_reg_ptr; 00541 tr_debug("Service %d, Uri unregistration uri: %s", service_id, uri); 00542 if (!this || !uri) { 00543 return -1; 00544 } 00545 00546 uri_reg_ptr = uri_registration_find(this, uri, strlen(uri)); 00547 if (!uri_reg_ptr) { 00548 return -2; 00549 } 00550 00551 ns_dyn_mem_free(uri_reg_ptr->uri_ptr); 00552 ns_list_remove(&this->uri_list, uri_reg_ptr); 00553 ns_dyn_mem_free(uri_reg_ptr); 00554 00555 return 0; 00556 } 00557 00558 uint16_t coap_service_request_send(int8_t service_id, uint8_t options, const uint8_t destination_addr[static 16], uint16_t destination_port, sn_coap_msg_type_e msg_type, sn_coap_msg_code_e msg_code, const char *uri, 00559 sn_coap_content_format_e cont_type, const uint8_t *payload_ptr, uint16_t payload_len, coap_service_response_recv *request_response_cb) 00560 { 00561 //TODO: coap_service_response_recv is an ugly cast, this should be refactored away + sn_coap_hdr_s MUST NOT be exposed to users of coap-service! 00562 //Callback would be still needed, but where to store callback? 00563 return coap_message_handler_request_send(coap_service_handle, service_id, options, destination_addr, destination_port, msg_type, msg_code, uri, cont_type, payload_ptr, payload_len, request_response_cb); 00564 } 00565 00566 int8_t coap_service_response_send(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) 00567 { 00568 return coap_message_handler_response_send(coap_service_handle, service_id, options, request_ptr, message_code, content_type, payload_ptr, payload_len); 00569 } 00570 00571 int8_t coap_service_response_send_by_msg_id(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) 00572 { 00573 return coap_message_handler_response_send_by_msg_id(coap_service_handle, service_id, options, msg_id, message_code, content_type, payload_ptr, payload_len); 00574 } 00575 00576 int8_t coap_service_request_delete(int8_t service_id, uint16_t msg_id) 00577 { 00578 return coap_message_handler_request_delete(coap_service_handle, service_id, msg_id); 00579 } 00580 00581 void coap_service_request_delete_by_service_id(int8_t service_id) 00582 { 00583 coap_message_handler_request_delete_by_service_id(coap_service_handle, service_id); 00584 } 00585 00586 int8_t coap_service_set_handshake_timeout(int8_t service_id, uint32_t min, uint32_t max) 00587 { 00588 coap_service_t *this = service_find(service_id); 00589 if (!this) { 00590 return -1; 00591 } 00592 00593 return coap_connection_handler_set_timeout(this->conn_handler, min, max); 00594 } 00595 00596 int8_t coap_service_handshake_limits_set(uint8_t handshakes_max, uint8_t connections_max) 00597 { 00598 return coap_connection_handler_handshake_limits_set(handshakes_max, connections_max); 00599 } 00600 00601 int8_t coap_service_set_duplicate_message_buffer(int8_t service_id, uint8_t size) 00602 { 00603 (void) service_id; 00604 00605 if (!coap_service_handle) { 00606 return -1; 00607 } 00608 00609 return sn_coap_protocol_set_duplicate_buffer_size(coap_service_handle->coap, size); 00610 } 00611 00612 uint32_t coap_service_get_internal_timer_ticks(void) 00613 { 00614 return coap_ticks; 00615 } 00616 00617 uint16_t coap_service_id_find_by_socket(int8_t socket_id) 00618 { 00619 coap_service_t *this = service_find_by_socket(socket_id); 00620 00621 return this ? this->service_id : 0; 00622 } 00623 00624 int8_t coap_service_certificate_set(int8_t service_id, const unsigned char *cert, uint16_t cert_len, const unsigned char *priv_key, uint8_t priv_key_len) 00625 { 00626 coap_service_t *this = service_find(service_id); 00627 if (!this) { 00628 return -1; 00629 } 00630 00631 if (!this->conn_handler->security_keys) { 00632 this->conn_handler->security_keys = ns_dyn_mem_alloc(sizeof(coap_security_keys_t)); 00633 00634 if (!this->conn_handler->security_keys) { 00635 return -1; 00636 } 00637 } 00638 00639 memset(this->conn_handler->security_keys, 0, sizeof(coap_security_keys_t)); 00640 00641 this->conn_handler->security_keys->_cert = cert; 00642 this->conn_handler->security_keys->_cert_len = cert_len; 00643 00644 this->conn_handler->security_keys->_priv_key = priv_key; 00645 this->conn_handler->security_keys->_priv_key_len = priv_key_len; 00646 00647 this->conn_handler->security_keys->mode = CERTIFICATE; 00648 00649 return 0; 00650 } 00651 00652 int8_t coap_service_blockwise_size_set(int8_t service_id, uint16_t size) 00653 { 00654 (void) service_id; 00655 00656 if (!coap_service_handle) { 00657 return -1; 00658 } 00659 00660 return sn_coap_protocol_set_block_size(coap_service_handle->coap, size); 00661 } 00662 00663 int8_t coap_service_msg_prevalidate_callback_set(uint16_t listen_socket, coap_service_msg_prevalidate_cb *msg_prevalidate_cb) 00664 { 00665 coap_conn_handler_t *conn_handler = coap_connection_handler_find_by_socket_port(listen_socket); 00666 if (conn_handler) { 00667 return (int8_t)coap_connection_handler_msg_prevalidate_callback_set(conn_handler, (cch_func_cb *)msg_prevalidate_cb); 00668 } 00669 return -1; 00670 }
Generated on Tue Jul 12 2022 13:54:12 by
1.7.2