Skip to content

Commit e046a96

Browse files
author
Arto Kinnunen
committed
Squashed 'features/nanostack/coap-service/' changes from c45afcd..227cc3d
227cc3d Merge pull request #120 from ARMmbed/sync_with_mbedos_2 88894d1 Follow Mbed OS coding style f3db9a1 (via Mbed OS) Add mbedtls platform setup and teardown to modules 5feb8dd Merge pull request #119 from ARMmbed/sync_with_MbedOS 10d5054 (via Mbed OS) Add missing mbed_lib.json for frameworks and nanostack a344676 Remove references to yotta (#118) 610afda Remove excess tracing (#117) 53382d6 Merge pull request #116 from ARMmbed/IOTTHD-1608 15889cb Use Mbed OS coding style d6eff5c Clarify function signature 587e8de Update message prevalidation API 46f86d4 Add API to set callback for CoAP msg prevalidation (#115) 0eb6630 Merge pull request #114 from ARMmbed/sync_with_mbed_os f75732b (split) Add unit tests for TLSSocket and TLSSocketWrapper git-subtree-dir: features/nanostack/coap-service git-subtree-split: 227cc3d
1 parent e6a851f commit e046a96

27 files changed

+408
-71
lines changed

.gitignore

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,5 @@
33
output
44
lcov
55
coverage
6-
.yotta.json
76
build/
8-
yotta_modules/
9-
yotta_targets/
107
upload.tar.gz

Makefile.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ test: $(TESTDIRS)
4040
@rm -f lcov/index.xml
4141
@find ./ -name '*.gcno' | xargs cp --backup=numbered -t ./coverage/
4242
@find ./ -name '*.gcda' | xargs cp --backup=numbered -t ./coverage/
43-
@gcovr --object-directory ./coverage --exclude-unreachable-branches -e '.*/builds/.*' -e '.*/test/.*' -e '.*/yotta_modules/.*' -e '.*/stub/.*' -x -o ./lcov/gcovr.xml
43+
@gcovr --object-directory ./coverage --exclude-unreachable-branches -e '.*/builds/.*' -e '.*/test/.*' -e '.*/stub/.*' -x -o ./lcov/gcovr.xml
4444
@lcov -d test/. -c -o $(COVERAGEFILE)
4545
@lcov -q -r $(COVERAGEFILE) "/usr*" -o $(COVERAGEFILE)
4646
@lcov -q -r $(COVERAGEFILE) "/test*" -o $(COVERAGEFILE)

coap-service/coap_service_api.h

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,26 @@ typedef int coap_service_security_start_cb(int8_t service_id, uint8_t address[st
120120
*/
121121
typedef int coap_service_security_done_cb(int8_t service_id, uint8_t address[static 16], uint8_t keyblock[static 40]);
122122

123+
/**
124+
* \brief Message prevalidation callback
125+
*
126+
* Message prevalidation callback function type used in method coap_service_msg_prevalidate_callback_set.
127+
*
128+
* \param local_interface_id Local interface ID, message arrived to this interface.
129+
* \param local_address Local address, message arrived to this address.
130+
* \param local_port Local port, message arrived to this port.
131+
* \param recv_interface_id Interface ID where message was received.
132+
* \param source_address Sender address.
133+
* \param source_port Sender port.
134+
* \param coap_uri CoAP URI, NUL terminated.
135+
*
136+
* \return <0 in case of errors,
137+
* 0 if message is valid to process further,
138+
* >0 if message should be dropped.
139+
*/
140+
141+
typedef int coap_service_msg_prevalidate_cb(int8_t local_interface_id, uint8_t local_address[static 16], uint16_t local_port, int8_t recv_interface_id, uint8_t source_address[static 16], uint16_t source_port, char *coap_uri);
142+
123143
/**
124144
* \brief Initialise server instance.
125145
*
@@ -131,7 +151,7 @@ typedef int coap_service_security_done_cb(int8_t service_id, uint8_t address[sta
131151
* \param *start_ptr Callback to inform security handling is started and to fetch device password.
132152
* \param *coap_security_done_cb Callback to inform security handling is done.
133153
*
134-
* \return service_id / -1 for failure
154+
* \return service_id / -1 for failure
135155
*/
136156
extern int8_t coap_service_initialize(int8_t interface_id, uint16_t listen_port, uint8_t service_options, coap_service_security_start_cb *start_ptr, coap_service_security_done_cb *coap_security_done_cb);
137157

@@ -373,6 +393,22 @@ extern int8_t coap_service_certificate_set(int8_t service_id, const unsigned cha
373393
*- 0 For success
374394
*/
375395
extern int8_t coap_service_blockwise_size_set(int8_t service_id, uint16_t size);
396+
397+
/**
398+
* \brief Set message prevalidation callback function.
399+
*
400+
* Set message prevalidation callback function for the service. Callback will be called for all services using the same listen port.
401+
*
402+
* CoAP service will call this function to allow application prevalidate incoming CoAP message before passing it to application.
403+
*
404+
* \param listen_port Socket port where to set callback.
405+
* \param msg_prevalidate_cb Callback to be called to validate incoming message before processing it. Use NULL to clear callback usage.
406+
*
407+
* \return -1 For failure
408+
* 0 For success
409+
*/
410+
extern int8_t coap_service_msg_prevalidate_callback_set(uint16_t listen_port, coap_service_msg_prevalidate_cb *msg_prevalidate_cb);
411+
376412
#ifdef __cplusplus
377413
}
378414
#endif

mbed_lib.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"name": "coap-service"
3+
}

source/coap_connection_handler.c

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ typedef enum session_state_e {
3636

3737
typedef struct internal_socket_s {
3838
coap_conn_handler_t *parent;
39+
cch_func_cb *cch_function_callback; // callback function
3940

4041
uint32_t timeout_min;
4142
uint32_t timeout_max;
@@ -44,6 +45,7 @@ typedef struct internal_socket_s {
4445

4546
int16_t data_len;
4647
uint8_t *data;
48+
int8_t recv_if_id; // interface ID where data is coming from
4749

4850
int8_t socket; //positive value = socket id, negative value virtual socket id
4951
bool real_socket;
@@ -548,6 +550,7 @@ static int timer_status(int8_t timer_id)
548550
static int read_data(socket_callback_t *sckt_data, internal_socket_t *sock, ns_address_t *src_address, uint8_t dst_address[static 16])
549551
{
550552
sock->data_len = 0;
553+
sock->recv_if_id = -1;
551554
if (sckt_data->event_type == SOCKET_DATA && sckt_data->d_len > 0) {
552555
uint8_t ancillary_databuffer[NS_CMSG_SPACE(sizeof(ns_in6_pktinfo_t))];
553556
ns_iovec_t msg_iov;
@@ -592,6 +595,7 @@ static int read_data(socket_callback_t *sckt_data, internal_socket_t *sock, ns_a
592595
}
593596
if (pkt) {
594597
memcpy(dst_address, pkt->ipi6_addr, 16);
598+
sock->recv_if_id = pkt->ipi6_ifindex;
595599
} else {
596600
goto return_failure;
597601
}
@@ -693,7 +697,7 @@ static void secure_recv_sckt_msg(void *cb_res)
693697
ns_dyn_mem_free(data);
694698
} else {
695699
if (sock->parent->_recv_cb) {
696-
sock->parent->_recv_cb(sock->socket, src_address.address, src_address.identifier, dst_address, data, len);
700+
sock->parent->_recv_cb(sock->socket, sock->recv_if_id, src_address.address, src_address.identifier, dst_address, data, len);
697701
}
698702
ns_dyn_mem_free(data);
699703
}
@@ -712,7 +716,7 @@ static void recv_sckt_msg(void *cb_res)
712716

713717
if (sock && read_data(sckt_data, sock, &src_address, dst_address) == 0) {
714718
if (sock->parent && sock->parent->_recv_cb) {
715-
sock->parent->_recv_cb(sock->socket, src_address.address, src_address.identifier, dst_address, sock->data, sock->data_len);
719+
sock->parent->_recv_cb(sock->socket, sock->recv_if_id, src_address.address, src_address.identifier, dst_address, sock->data, sock->data_len);
716720
}
717721
ns_dyn_mem_free(sock->data);
718722
sock->data = NULL;
@@ -801,7 +805,7 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a
801805
return 0;
802806
} else {
803807
if (sock->parent->_recv_cb) {
804-
sock->parent->_recv_cb(sock->socket, address, port, ns_in6addr_any, data, len);
808+
sock->parent->_recv_cb(sock->socket, sock->recv_if_id, address, port, ns_in6addr_any, data, len);
805809
}
806810
ns_dyn_mem_free(data);
807811
data = NULL;
@@ -812,7 +816,7 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a
812816
} else {
813817
/* unsecure*/
814818
if (sock->parent->_recv_cb) {
815-
sock->parent->_recv_cb(sock->socket, address, port, ns_in6addr_any, sock->data, sock->data_len);
819+
sock->parent->_recv_cb(sock->socket, sock->recv_if_id, address, port, ns_in6addr_any, sock->data, sock->data_len);
816820
}
817821
if (sock->data) {
818822
ns_dyn_mem_free(sock->data);
@@ -1023,3 +1027,32 @@ void coap_connection_handler_exec(uint32_t time)
10231027
}
10241028
}
10251029
}
1030+
1031+
int coap_connection_handler_msg_prevalidate_callback_set(coap_conn_handler_t *handler, cch_func_cb *function_callback)
1032+
{
1033+
if (!handler) {
1034+
return -1;
1035+
}
1036+
handler->socket->cch_function_callback = function_callback;
1037+
return 0;
1038+
}
1039+
1040+
coap_conn_handler_t *coap_connection_handler_find_by_socket_port(uint16_t listen_port)
1041+
{
1042+
ns_list_foreach(internal_socket_t, cur_ptr, &socket_list) {
1043+
if (cur_ptr->listen_port == listen_port) {
1044+
return cur_ptr->parent;
1045+
}
1046+
}
1047+
return NULL;
1048+
}
1049+
1050+
cch_func_cb *coap_connection_handler_msg_prevalidate_callback_get(coap_conn_handler_t *handler, uint16_t *listen_socket_port)
1051+
{
1052+
if (!handler || !listen_socket_port) {
1053+
return NULL;
1054+
}
1055+
1056+
*listen_socket_port = handler->socket->listen_port;
1057+
return handler->socket->cch_function_callback;
1058+
}

source/coap_message_handler.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -293,15 +293,15 @@ coap_transaction_t *coap_message_handler_find_transaction(uint8_t *address_ptr,
293293
return transaction_find_by_address(address_ptr, port);
294294
}
295295

296-
int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t socket_id, const uint8_t source_addr_ptr[static 16], uint16_t port, const uint8_t dst_addr_ptr[static 16],
297-
uint8_t *data_ptr, uint16_t data_len, int16_t (cb)(int8_t, sn_coap_hdr_s *, coap_transaction_t *))
296+
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],
297+
uint8_t *data_ptr, uint16_t data_len, coap_msg_process_cb *msg_process_callback)
298298
{
299299
sn_nsdl_addr_s src_addr;
300300
sn_coap_hdr_s *coap_message;
301301
int16_t ret_val = 0;
302302
coap_transaction_t *this = NULL;
303303

304-
if (!cb || !handle) {
304+
if (!msg_process_callback || !handle) {
305305
return -1;
306306
}
307307

@@ -337,21 +337,21 @@ int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t
337337
goto exit;
338338
}
339339

340-
/* Request received */
341340
if (coap_message->msg_code > 0 && coap_message->msg_code < 32) {
341+
/* Request received */
342342
transaction_ptr->msg_id = coap_message->msg_id;
343343
transaction_ptr->req_msg_type = coap_message->msg_type;
344344
if (coap_message->token_len) {
345345
memcpy(transaction_ptr->token, coap_message->token_ptr, coap_message->token_len);
346346
transaction_ptr->token_len = coap_message->token_len;
347347
}
348-
if (cb(socket_id, coap_message, transaction_ptr) < 0) {
348+
if (msg_process_callback(socket_id, recv_if_id, coap_message, transaction_ptr, dst_addr_ptr) < 0) {
349349
// negative return value = message ignored -> delete transaction
350350
transaction_delete(transaction_ptr);
351351
}
352352
goto exit;
353-
/* Response received */
354353
} else {
354+
/* Response received */
355355
transaction_delete(transaction_ptr); // transaction_ptr not needed in response
356356
if (coap_message->token_ptr) {
357357
this = transaction_find_client_by_token(coap_message->token_ptr, coap_message->token_len, source_addr_ptr, port);

source/coap_security_handler.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,12 @@ static int coap_security_handler_init(coap_security_t *sec)
102102
const int entropy_source_type = MBEDTLS_ENTROPY_SOURCE_WEAK;
103103
#endif
104104

105+
#if defined(MBEDTLS_PLATFORM_C)
106+
if (mbedtls_platform_setup(NULL) != 0) {
107+
return -1;
108+
}
109+
#endif /* MBEDTLS_PLATFORM_C */
110+
105111
mbedtls_ssl_init(&sec->_ssl);
106112
mbedtls_ssl_config_init(&sec->_conf);
107113
mbedtls_ctr_drbg_init(&sec->_ctr_drbg);
@@ -153,6 +159,9 @@ static void coap_security_handler_reset(coap_security_t *sec)
153159
mbedtls_ctr_drbg_free(&sec->_ctr_drbg);
154160
mbedtls_ssl_config_free(&sec->_conf);
155161
mbedtls_ssl_free(&sec->_ssl);
162+
#if defined(MBEDTLS_PLATFORM_C)
163+
mbedtls_platform_teardown(NULL);
164+
#endif /* MBEDTLS_PLATFORM_C */
156165
}
157166

158167

source/coap_service_api.c

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
#include "coap_message_handler.h"
3737
#include "mbed-coap/sn_coap_protocol.h"
3838

39-
static int16_t coap_msg_process_callback(int8_t socket_id, sn_coap_hdr_s *coap_message, coap_transaction_t *transaction_ptr);
39+
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);
4040

4141
typedef struct uri_registration {
4242
char *uri_ptr;
@@ -70,6 +70,13 @@ static uint32_t coap_ticks = 1;
7070

7171
#define COAP_TICK_TIMER 0xf1
7272

73+
//#define TRACE_DEEP
74+
#ifdef TRACE_DEEP
75+
#define tr_deep tr_debug
76+
#else
77+
#define tr_deep(...)
78+
#endif
79+
7380
static uri_registration_t *uri_registration_find(coap_service_t *this, const void *uri_ptr, uint16_t uri_len)
7481
{
7582
ns_list_foreach(uri_registration_t, cur_ptr, &this->uri_list) {
@@ -165,7 +172,7 @@ static uint8_t coap_tx_function(uint8_t *data_ptr, uint16_t data_len, sn_nsdl_ad
165172
return 0;
166173
}
167174

168-
tr_debug("Service %d, CoAP TX Function - mid: %d", transaction_ptr->service_id, common_read_16_bit(data_ptr + 2));
175+
tr_debug("Service %d, CoAP TX - mid: %d", transaction_ptr->service_id, common_read_16_bit(data_ptr + 2));
169176

170177
this = service_find(transaction_ptr->service_id);
171178
if (!this) {
@@ -211,17 +218,44 @@ static void service_event_handler(arm_event_s *event)
211218
eventOS_event_timer_request((uint8_t)COAP_TICK_TIMER, ARM_LIB_SYSTEM_TIMER_EVENT, tasklet_id, 1000);
212219
}
213220

214-
static int16_t coap_msg_process_callback(int8_t socket_id, sn_coap_hdr_s *coap_message, coap_transaction_t *transaction_ptr)
221+
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)
215222
{
216223
coap_service_t *this;
224+
coap_service_msg_prevalidate_cb *msg_prevalidate_callback;
225+
uint16_t listen_socket_port;
226+
217227
if (!coap_message || !transaction_ptr) {
218228
return -1;
219229
}
220230

221-
// Message is request, find correct handle
231+
// Message is request, find correct handle based on URI
222232
this = service_find_by_uri(socket_id, coap_message->uri_path_ptr, coap_message->uri_path_len);
223233
if (!this) {
224-
tr_debug("not registered uri %.*s", coap_message->uri_path_len, coap_message->uri_path_ptr);
234+
tr_deep("URI %.*s not registered", coap_message->uri_path_len, coap_message->uri_path_ptr);
235+
// URI is not available, find any service that holds the same shared socket so that we can get msg_prevalidate_callback to validate addresses
236+
this = service_find_by_socket(socket_id);
237+
if (!this) {
238+
return -1;
239+
}
240+
}
241+
242+
msg_prevalidate_callback = (coap_service_msg_prevalidate_cb *)coap_connection_handler_msg_prevalidate_callback_get(this->conn_handler, &listen_socket_port);
243+
if (msg_prevalidate_callback) {
244+
// message prevalidation activated for the port
245+
char request_uri[coap_message->uri_path_len + 1];
246+
memcpy(request_uri, coap_message->uri_path_ptr, coap_message->uri_path_len);
247+
request_uri[coap_message->uri_path_len] = 0;
248+
249+
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);
250+
if (msg_prevalidate_status >= 1) {
251+
tr_deep("Drop CoAP msg %s from %s to %s", request_uri, trace_ipv6(transaction_ptr->remote_address), trace_ipv6(local_addr));
252+
return -1;
253+
}
254+
}
255+
256+
uri_registration_t *uri_reg_ptr = uri_registration_find(this, coap_message->uri_path_ptr, coap_message->uri_path_len);
257+
if (!uri_reg_ptr) {
258+
/* URI is not available, stop further processing */
225259
if (coap_message->msg_type == COAP_MSG_TYPE_CONFIRMABLE) {
226260
coap_message_handler_response_send(coap_service_handle, transaction_ptr->service_id, COAP_SERVICE_OPTIONS_NONE, coap_message,
227261
COAP_MSG_CODE_RESPONSE_NOT_FOUND, COAP_CT_NONE, NULL, 0);
@@ -230,22 +264,22 @@ static int16_t coap_msg_process_callback(int8_t socket_id, sn_coap_hdr_s *coap_m
230264
return -1;
231265
}
232266

233-
uri_registration_t *uri_reg_ptr = uri_registration_find(this, coap_message->uri_path_ptr, coap_message->uri_path_len);
234-
if (uri_reg_ptr && uri_reg_ptr->request_recv_cb) {
235-
tr_debug("Service %d, call request recv cb uri %.*s", this->service_id, coap_message->uri_path_len, coap_message->uri_path_ptr);
236-
267+
if (uri_reg_ptr->request_recv_cb) {
237268
if ((this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS) == COAP_SERVICE_OPTIONS_SECURE_BYPASS) { //TODO Add secure bypass option
238269
// Service has secure bypass active TODO this is not defined in interface
239270
// this check can be removed I think
240271
transaction_ptr->options = COAP_REQUEST_OPTIONS_SECURE_BYPASS;
241272
}
273+
242274
transaction_ptr->service_id = this->service_id;
275+
tr_debug("Service %d, recv msg: %.*s", this->service_id, coap_message->uri_path_len, coap_message->uri_path_ptr);
243276
return uri_reg_ptr->request_recv_cb(this->service_id, transaction_ptr->remote_address, transaction_ptr->remote_port, coap_message);
244277
}
278+
245279
return -1;
246280
}
247281

248-
static int recv_cb(int8_t socket_id, uint8_t src_address[static 16], uint16_t port, const uint8_t dst_address[static 16], unsigned char *data, int len)
282+
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)
249283
{
250284
uint8_t *data_ptr = NULL;
251285
uint16_t data_len = 0;
@@ -261,10 +295,9 @@ static int recv_cb(int8_t socket_id, uint8_t src_address[static 16], uint16_t po
261295
}
262296
memcpy(data_ptr, data, len);
263297
data_len = len;
264-
tr_debug("service recv socket data len %d ", data_len);
265298

266299
//parse coap message what CoAP to use
267-
int ret = coap_message_handler_coap_msg_process(coap_service_handle, socket_id, src_address, port, dst_address, data_ptr, data_len, &coap_msg_process_callback);
300+
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);
268301
own_free(data_ptr);
269302
return ret;
270303
}
@@ -626,3 +659,12 @@ int8_t coap_service_blockwise_size_set(int8_t service_id, uint16_t size)
626659

627660
return sn_coap_protocol_set_block_size(coap_service_handle->coap, size);
628661
}
662+
663+
int8_t coap_service_msg_prevalidate_callback_set(uint16_t listen_socket, coap_service_msg_prevalidate_cb *msg_prevalidate_cb)
664+
{
665+
coap_conn_handler_t *conn_handler = coap_connection_handler_find_by_socket_port(listen_socket);
666+
if (conn_handler) {
667+
return (int8_t)coap_connection_handler_msg_prevalidate_callback_set(conn_handler, (cch_func_cb *)msg_prevalidate_cb);
668+
}
669+
return -1;
670+
}

0 commit comments

Comments
 (0)