Nathan Yonkee / Mbed 2 deprecated Nucleo_sinewave_output_copy

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers coap_service_api.c Source File

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 interface_id, sn_coap_hdr_s *coap_message, coap_transaction_t *transaction_ptr);
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 static uri_registration_t *uri_registration_find(coap_service_t *this, const void *uri_ptr, uint16_t uri_len)
00074 {
00075     ns_list_foreach(uri_registration_t, cur_ptr, &this->uri_list) {
00076         if (cur_ptr->uri_len == uri_len && memcmp(cur_ptr->uri_ptr, uri_ptr, uri_len) == 0) {
00077             return cur_ptr;
00078         }
00079     }
00080     return NULL;
00081 }
00082 static coap_service_t *service_find(int8_t service_id)
00083 {
00084     coap_service_t *this = NULL;
00085     ns_list_foreach(coap_service_t, cur_ptr, &instance_list) {
00086         if (cur_ptr->service_id == service_id) {
00087             this = cur_ptr;
00088             break;
00089         }
00090     }
00091     return this;
00092 }
00093 
00094 static coap_service_t *service_find_by_socket(int8_t socket_id)
00095 {
00096     coap_service_t *this = NULL;
00097     ns_list_foreach(coap_service_t, cur_ptr, &instance_list) {
00098         if( coap_connection_handler_socket_belongs_to(cur_ptr->conn_handler, socket_id) ){
00099             this = cur_ptr;
00100             break;
00101         }
00102     }
00103     return this;
00104 }
00105 
00106 static coap_service_t *service_find_by_uri(uint8_t socket_id, uint8_t *uri_ptr, uint16_t uri_len)
00107 {
00108     ns_list_foreach(coap_service_t, cur_ptr, &instance_list) {
00109         if (coap_connection_handler_socket_belongs_to(cur_ptr->conn_handler, socket_id) && uri_registration_find(cur_ptr, uri_ptr, uri_len)) {
00110             return cur_ptr;
00111         }
00112     }
00113     return NULL;
00114 }
00115 
00116 static bool coap_service_can_leave_multicast_group(coap_conn_handler_t *conn_handler)
00117 {
00118     int mc_count = 0;
00119     bool current_handler_joined_to_mc_group = false;
00120 
00121     ns_list_foreach(coap_service_t, cur_ptr, &instance_list) {
00122         if (cur_ptr->conn_handler && cur_ptr->conn_handler->registered_to_multicast) {
00123             if (conn_handler == cur_ptr->conn_handler) {
00124                 current_handler_joined_to_mc_group = true;
00125             }
00126             mc_count ++;
00127         }
00128     }
00129 
00130     if (mc_count == 1 && current_handler_joined_to_mc_group) {
00131         // current handler is the only one joined to multicast group
00132         return true;
00133     }
00134 
00135     return false;
00136 }
00137 
00138 /**
00139  *  Coap handling functions
00140  */
00141 static void *own_alloc(uint16_t size)
00142 {
00143     if (size) {
00144         return ns_dyn_mem_temporary_alloc(size);
00145     } else {
00146         return 0;
00147     }
00148 }
00149 
00150 static void own_free(void *ptr)
00151 {
00152     if (ptr) {
00153         ns_dyn_mem_free(ptr);
00154     }
00155 }
00156 
00157 static uint8_t coap_tx_function(uint8_t *data_ptr, uint16_t data_len, sn_nsdl_addr_s *address_ptr, void *param)
00158 {
00159     coap_service_t *this;
00160     coap_transaction_t *transaction_ptr = coap_message_handler_transaction_valid(param);
00161     ns_address_t dest_addr;
00162     int ret_val;
00163 
00164     if (!transaction_ptr || !data_ptr) {
00165         return 0;
00166     }
00167 
00168     tr_debug("Service %d, CoAP TX Function - mid: %d", transaction_ptr->service_id, common_read_16_bit(data_ptr + 2));
00169 
00170     this = service_find(transaction_ptr->service_id);
00171     if (!this) {
00172         return 0;
00173     }
00174 
00175     memcpy(&(dest_addr.address), address_ptr->addr_ptr, 16);
00176     dest_addr.identifier = address_ptr->port;
00177     dest_addr.type = ADDRESS_IPV6;
00178 
00179     ret_val = coap_connection_handler_send_data(this->conn_handler, &dest_addr, transaction_ptr->local_address,
00180             data_ptr, data_len, (this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS) == COAP_SERVICE_OPTIONS_SECURE_BYPASS);
00181     if (ret_val == 0) {
00182         if (!transaction_ptr->data_ptr) {
00183             transaction_ptr->data_ptr = ns_dyn_mem_alloc(data_len);
00184             if (!transaction_ptr->data_ptr) {
00185                 tr_debug("coap tx out of memory");
00186                 return 0;
00187             }
00188             memcpy(transaction_ptr->data_ptr, data_ptr, data_len);
00189             transaction_ptr->data_len = data_len;
00190         }
00191     } else if ((ret_val == -1) || (!transaction_ptr->resp_cb && transaction_ptr->req_msg_type == COAP_MSG_TYPE_NON_CONFIRMABLE)) {
00192         transaction_delete(transaction_ptr);
00193     }
00194 
00195     return 0;
00196 }
00197 
00198 static void service_event_handler(arm_event_s *event)
00199 {
00200     if (event->event_type == ARM_LIB_TASKLET_INIT_EVENT) {
00201         tr_debug("service tasklet initialised");
00202         /*initialize coap service and listen socket*/
00203     }
00204     if (event->event_type == ARM_LIB_SYSTEM_TIMER_EVENT && event->event_id == COAP_TICK_TIMER) {
00205         coap_message_handler_exec(coap_service_handle, coap_ticks++);
00206         if(coap_ticks && !coap_ticks % SECURE_SESSION_CLEAN_INTERVAL){
00207             coap_connection_handler_exec(coap_ticks);
00208         }
00209     }
00210     eventOS_event_timer_request((uint8_t)COAP_TICK_TIMER, ARM_LIB_SYSTEM_TIMER_EVENT, tasklet_id, 1000);
00211 }
00212 
00213 static int16_t coap_msg_process_callback(int8_t socket_id, int8_t interface_id, sn_coap_hdr_s *coap_message, coap_transaction_t *transaction_ptr)
00214 {
00215     coap_service_t *this;
00216     if (!coap_message || !transaction_ptr) {
00217         return -1;
00218     }
00219 
00220     // Message is request, find correct handle
00221     this = service_find_by_uri(socket_id, coap_message->uri_path_ptr, coap_message->uri_path_len);
00222     if (!this) {
00223         tr_debug("not registered uri %.*s", coap_message->uri_path_len, coap_message->uri_path_ptr);
00224         if (coap_message->msg_type == COAP_MSG_TYPE_CONFIRMABLE) {
00225             coap_message_handler_response_send(coap_service_handle, transaction_ptr->service_id, COAP_SERVICE_OPTIONS_NONE, coap_message,
00226                 COAP_MSG_CODE_RESPONSE_NOT_FOUND, COAP_CT_NONE, NULL, 0);
00227             return 0;
00228         }
00229         return -1;
00230     }
00231 
00232     if ((interface_id != -1) && (this->interface_id != interface_id)) {
00233         tr_debug("uri %.*s not registered to interface %d", coap_message->uri_path_len, coap_message->uri_path_ptr, interface_id);
00234         return 0;
00235     }
00236 
00237     uri_registration_t *uri_reg_ptr = uri_registration_find(this, coap_message->uri_path_ptr, coap_message->uri_path_len);
00238     if (uri_reg_ptr && uri_reg_ptr->request_recv_cb) {
00239         tr_debug("Service %d, call request recv cb uri %.*s", this->service_id, coap_message->uri_path_len, coap_message->uri_path_ptr);
00240 
00241         if ((this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS) == COAP_SERVICE_OPTIONS_SECURE_BYPASS ) {//TODO Add secure bypass option
00242             // Service has secure bypass active TODO this is not defined in interface
00243             // this check can be removed I think
00244             transaction_ptr->options = COAP_REQUEST_OPTIONS_SECURE_BYPASS;
00245         }
00246         transaction_ptr->service_id = this->service_id;
00247         return uri_reg_ptr->request_recv_cb(this->service_id, transaction_ptr->remote_address, transaction_ptr->remote_port, coap_message);
00248     }
00249     return -1;
00250 }
00251 
00252 static int recv_cb(int8_t socket_id, int8_t interface_id, uint8_t src_address[static 16], uint16_t port, const uint8_t dst_address[static 16], unsigned char *data, int len)
00253 {
00254     uint8_t *data_ptr = NULL;
00255     uint16_t data_len = 0;
00256 
00257     if (!data || !len) {
00258         return -1;
00259     }
00260 
00261     data_ptr = own_alloc(len);
00262 
00263     if (!data_ptr) {
00264         return -1;
00265     }
00266     memcpy(data_ptr, data, len);
00267     data_len = len;
00268     tr_debug("service recv socket data len %d ", data_len);
00269 
00270     //parse coap message what CoAP to use
00271     int ret = coap_message_handler_coap_msg_process(coap_service_handle, socket_id, interface_id, src_address, port, dst_address, data_ptr, data_len, &coap_msg_process_callback);
00272     own_free(data_ptr);
00273     return ret;
00274 }
00275 
00276 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)
00277 {
00278     coap_service_t *this = service_find_by_socket(socket_id);
00279     if (this && this->virtual_socket_send_cb) {
00280         tr_debug("send to virtual socket, service: %d", this->service_id);
00281         return this->virtual_socket_send_cb(this->service_id, (uint8_t*)address, port, data_ptr, data_len);
00282     }
00283     return -1;
00284 }
00285 
00286 static void sec_done_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, uint8_t keyblock[static 40])
00287 {
00288     //TODO: this is not enough if shared socket. Inform all!
00289     coap_service_t *this = service_find_by_socket(socket_id);
00290     if (this && this->coap_security_done_cb) { // secure done callback
00291         this->coap_security_done_cb(this->service_id, address, keyblock);
00292     }
00293 
00294     //TODO: send all unsend transactions if more than 1
00295     coap_transaction_t *transaction_ptr = coap_message_handler_find_transaction(address, port);
00296     if (transaction_ptr && transaction_ptr->data_ptr) {
00297         tr_debug("send delayed packet");
00298         ns_address_t dest_addr;
00299         memcpy(dest_addr.address, address, 16);
00300         dest_addr.identifier = port;
00301         dest_addr.type = ADDRESS_IPV6;
00302 
00303         coap_connection_handler_send_data(this->conn_handler, &dest_addr, transaction_ptr->local_address,
00304                 transaction_ptr->data_ptr, transaction_ptr->data_len, (this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS) == COAP_SERVICE_OPTIONS_SECURE_BYPASS);
00305         ns_dyn_mem_free(transaction_ptr->data_ptr);
00306         transaction_ptr->data_ptr = NULL;
00307         transaction_ptr->data_len = 0;
00308         if (!transaction_ptr->resp_cb && transaction_ptr->req_msg_type == COAP_MSG_TYPE_NON_CONFIRMABLE) {
00309             transaction_delete(transaction_ptr);
00310         }
00311     }
00312 }
00313 
00314 static int get_passwd_cb(int8_t socket_id, uint8_t address[static 16], uint16_t port, coap_security_keys_t *security_ptr)
00315 {
00316     uint8_t *pw_ptr = NULL;
00317     uint8_t pw_len = 0;
00318     coap_service_t *this = service_find_by_socket(socket_id);
00319 
00320     if (!this || !security_ptr) {
00321         return -1;
00322     }
00323 
00324     /* Certificates set */
00325     if (this->conn_handler->security_keys) {
00326         *security_ptr = *this->conn_handler->security_keys;
00327         return 0;
00328     }
00329 
00330     pw_ptr = ns_dyn_mem_alloc(64);
00331     if (!pw_ptr) {
00332         return -1;
00333     }
00334 
00335     if (this->security_start_cb && !this->security_start_cb(this->service_id, address, port, pw_ptr, &pw_len)) {
00336         security_ptr->mode = ECJPAKE;
00337         security_ptr->_key = pw_ptr;
00338         security_ptr->_key_len = pw_len;
00339         return 0;
00340     }
00341 
00342     return -1;
00343 }
00344 
00345 int8_t coap_service_initialize(int8_t interface_id, uint16_t listen_port, uint8_t service_options,
00346                                  coap_service_security_start_cb *start_ptr, coap_service_security_done_cb *coap_security_done_cb)
00347 {
00348     coap_service_t *this = ns_dyn_mem_alloc(sizeof(coap_service_t));
00349 
00350     if (!this) {
00351         return -1;
00352     }
00353     memset(this, 0, sizeof(coap_service_t));
00354     tr_debug("service init interface %d, port %d, options %d", interface_id, listen_port, service_options);
00355 
00356     int8_t id = 1;// get unique id
00357     while (service_find(id) && id < 127) {
00358         id++;
00359     }
00360     this->interface_id = interface_id;
00361     this->service_id = id;
00362     this->service_options = service_options;
00363 
00364     this->security_start_cb = start_ptr;
00365     this->coap_security_done_cb = coap_security_done_cb;
00366 
00367     if (tasklet_id == -1) {
00368         tr_debug("service tasklet init");
00369         tasklet_id = eventOS_event_handler_create(&service_event_handler, ARM_LIB_TASKLET_INIT_EVENT);
00370     }
00371 
00372     this->conn_handler = connection_handler_create(recv_cb, virtual_send_cb, get_passwd_cb, sec_done_cb);
00373     if(!this->conn_handler){
00374         ns_dyn_mem_free(this);
00375         return -1;
00376     }
00377 
00378     this->conn_handler->socket_interface_selection = 0; // zero is illegal interface ID
00379     if (this->service_options & COAP_SERVICE_OPTIONS_SELECT_SOCKET_IF) {
00380         this->conn_handler->socket_interface_selection = this->interface_id;
00381     }
00382 
00383     this->conn_handler->registered_to_multicast = this->service_options & COAP_SERVICE_OPTIONS_MULTICAST_JOIN;
00384 
00385     if (0 > coap_connection_handler_open_connection(this->conn_handler, listen_port,
00386             (this->service_options & COAP_SERVICE_OPTIONS_EPHEMERAL_PORT),
00387             (this->service_options & COAP_SERVICE_OPTIONS_SECURE),
00388             !(this->service_options & COAP_SERVICE_OPTIONS_VIRTUAL_SOCKET),
00389             (this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS))) {
00390         ns_dyn_mem_free(this->conn_handler);
00391         ns_dyn_mem_free(this);
00392         return -1;
00393     }
00394 
00395     if (!coap_service_handle) {
00396         coap_service_handle = coap_message_handler_init(&own_alloc, &own_free, &coap_tx_function);
00397     }
00398     if (!coap_service_handle) {
00399         tr_error("coap service alloc failed");
00400         //TODO proper handling
00401     }
00402 
00403     ns_list_add_to_start(&instance_list, this);
00404 
00405     return id;
00406 }
00407 
00408 void coap_service_delete(int8_t service_id)
00409 {
00410     coap_service_t *this = service_find(service_id);
00411     if (!this) {
00412         return;
00413     }
00414 
00415     if (this->conn_handler){
00416         bool leave_multicast_group = false;
00417         if (coap_service_can_leave_multicast_group(this->conn_handler)) {
00418             // This is the last handler joined to multicast group
00419             leave_multicast_group = true;
00420         }
00421         connection_handler_destroy(this->conn_handler, leave_multicast_group);
00422     }
00423 
00424     //TODO clear all transactions
00425     ns_list_foreach_safe(uri_registration_t, cur_ptr, &this->uri_list) {
00426         ns_dyn_mem_free(cur_ptr->uri_ptr);
00427         ns_list_remove(&this->uri_list, cur_ptr);
00428         ns_dyn_mem_free(cur_ptr);
00429     }
00430 
00431     ns_list_remove(&instance_list, this);
00432     ns_dyn_mem_free(this);
00433     return;
00434 }
00435 
00436 extern void coap_service_close_secure_connection(int8_t service_id, uint8_t destination_addr_ptr[static 16], uint16_t port)
00437 {
00438     coap_service_t *this = service_find(service_id);
00439     if (!this || !destination_addr_ptr) {
00440         return;
00441     }
00442     if (this->conn_handler){
00443         connection_handler_close_secure_connection(this->conn_handler, destination_addr_ptr, port);
00444     }
00445 }
00446 
00447 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)
00448 {
00449     coap_service_t *this = service_find(service_id);
00450     tr_debug("Service %d, virtual socket received", service_id);
00451     if (!this) {
00452         return -1;
00453     }
00454     return coap_connection_handler_virtual_recv(this->conn_handler, source_addr_ptr, port, data_ptr, data_len);
00455 }
00456 
00457 int16_t coap_service_virtual_socket_set_cb(int8_t service_id, coap_service_virtual_socket_send_cb *send_method_ptr)
00458 {
00459     coap_service_t *this = service_find(service_id);
00460     tr_debug("register virtual socket cb to service %d", service_id);
00461     if (!this) {
00462         return -1;
00463     }
00464     this->virtual_socket_send_cb = send_method_ptr;
00465     return 0;
00466 }
00467 
00468 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)
00469 {
00470     coap_service_t *this = service_find(service_id);
00471     uri_registration_t *uri_reg_ptr;
00472     char *uri_ptr = NULL;
00473     uint16_t uri_len;
00474     tr_debug("Service %d, Uri registration uri: %s", service_id, uri);
00475     if (!this || !uri) {
00476         return -1;
00477     }
00478     uri_len = strlen(uri);
00479 
00480     uri_reg_ptr = uri_registration_find(this, uri, uri_len);
00481     if (!uri_reg_ptr) {
00482         uri_reg_ptr = ns_dyn_mem_alloc(sizeof(uri_registration_t));
00483         if( !uri_reg_ptr ){
00484             tr_error("Uri registration failed, OOM");
00485             return -2;
00486         }
00487         uri_reg_ptr->uri_ptr = NULL;
00488     } else {
00489         ns_dyn_mem_free(uri_reg_ptr->uri_ptr);
00490         ns_list_remove(&this->uri_list, uri_reg_ptr);
00491     }
00492 
00493     uri_ptr = ns_dyn_mem_alloc(uri_len);
00494     if (!uri_ptr) {
00495         ns_dyn_mem_free(uri_reg_ptr);
00496         tr_error("Uri registration failed, OOM");
00497         return -2;
00498     }
00499 
00500     uri_reg_ptr->uri_ptr = memcpy(uri_ptr, uri, uri_len);
00501     uri_reg_ptr->uri_len = uri_len;
00502     uri_reg_ptr->request_recv_cb = request_recv_cb;
00503     uri_reg_ptr->allowed_method = allowed_method;
00504     ns_list_add_to_start(&this->uri_list, uri_reg_ptr);
00505     return 0;
00506 }
00507 
00508 int8_t coap_service_unregister_uri(int8_t service_id, const char *uri)
00509 {
00510     coap_service_t *this = service_find(service_id);
00511     uri_registration_t *uri_reg_ptr;
00512     tr_debug("Service %d, Uri unregistration uri: %s", service_id, uri);
00513     if (!this || !uri) {
00514         return -1;
00515     }
00516 
00517     uri_reg_ptr = uri_registration_find(this, uri, strlen(uri));
00518     if (!uri_reg_ptr) {
00519         return -2;
00520     }
00521 
00522     ns_dyn_mem_free(uri_reg_ptr->uri_ptr);
00523     ns_list_remove(&this->uri_list, uri_reg_ptr);
00524     ns_dyn_mem_free(uri_reg_ptr);
00525 
00526     return 0;
00527 }
00528 
00529 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,
00530         sn_coap_content_format_e cont_type, const uint8_t *payload_ptr, uint16_t payload_len, coap_service_response_recv *request_response_cb){
00531     //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!
00532     //Callback would be still needed, but where to store callback?
00533     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);
00534 }
00535 
00536 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){
00537     return coap_message_handler_response_send(coap_service_handle, service_id, options, request_ptr, message_code, content_type, payload_ptr, payload_len);
00538 }
00539 
00540 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) {
00541     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);
00542 }
00543 
00544 int8_t coap_service_request_delete(int8_t service_id, uint16_t msg_id)
00545 {
00546     return coap_message_handler_request_delete(coap_service_handle, service_id, msg_id);
00547 }
00548 
00549 int8_t coap_service_set_handshake_timeout(int8_t service_id, uint32_t min, uint32_t max)
00550 {
00551     coap_service_t *this = service_find(service_id);
00552     if(!this){
00553         return -1;
00554     }
00555 
00556     return coap_connection_handler_set_timeout(this->conn_handler, min, max);
00557 }
00558 
00559 int8_t coap_service_handshake_limits_set(uint8_t handshakes_max, uint8_t connections_max)
00560 {
00561     return coap_connection_handler_handshake_limits_set(handshakes_max, connections_max);
00562 }
00563 
00564 int8_t coap_service_set_duplicate_message_buffer(int8_t service_id, uint8_t size)
00565 {
00566     (void) service_id;
00567 
00568     if (!coap_service_handle) {
00569         return -1;
00570     }
00571 
00572     return sn_coap_protocol_set_duplicate_buffer_size(coap_service_handle->coap, size);
00573 }
00574 
00575 uint32_t coap_service_get_internal_timer_ticks(void)
00576 {
00577     return coap_ticks;
00578 }
00579 
00580 uint16_t coap_service_id_find_by_socket(int8_t socket_id)
00581 {
00582     coap_service_t *this = service_find_by_socket(socket_id);
00583 
00584     return this ? this->service_id:0;
00585 }
00586 
00587 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)
00588 {
00589     coap_service_t *this = service_find(service_id);
00590     if (!this) {
00591         return -1;
00592     }
00593 
00594     if (!this->conn_handler->security_keys) {
00595         this->conn_handler->security_keys = ns_dyn_mem_alloc(sizeof(coap_security_keys_t));
00596 
00597         if (!this->conn_handler->security_keys) {
00598             return -1;
00599         }
00600     }
00601 
00602     memset(this->conn_handler->security_keys, 0, sizeof(coap_security_keys_t));
00603 
00604     this->conn_handler->security_keys->_cert = cert;
00605     this->conn_handler->security_keys->_cert_len = cert_len;
00606 
00607     this->conn_handler->security_keys->_priv_key = priv_key;
00608     this->conn_handler->security_keys->_priv_key_len = priv_key_len;
00609 
00610     this->conn_handler->security_keys->mode = CERTIFICATE;
00611 
00612     return 0;
00613 }