Skip to content

Commit ca15df3

Browse files
author
Arto Kinnunen
committed
Merge commit '9d5a9f5a29d19b2e67402e4e452e13ce75baca7c'
* commit '9d5a9f5a29d19b2e67402e4e452e13ce75baca7c': Squashed 'features/nanostack/FEATURE_NANOSTACK/coap-service/' changes from e125164..d65b6b0
2 parents a24fb4e + 9d5a9f5 commit ca15df3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+330
-89
lines changed

features/nanostack/FEATURE_NANOSTACK/coap-service/coap-service/coap_service_api.h

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015-2016 ARM Limited. All Rights Reserved.
2+
* Copyright (c) 2015-2017 ARM Limited. All Rights Reserved.
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*
@@ -45,6 +45,10 @@ extern "C" {
4545
#define COAP_SERVICE_OPTIONS_VIRTUAL_SOCKET 0x01
4646
#define COAP_SERVICE_OPTIONS_SECURE 0x02
4747
#define COAP_SERVICE_OPTIONS_EPHEMERAL_PORT 0x04
48+
/** Coap interface selected as socket interface */
49+
#define COAP_SERVICE_OPTIONS_SELECT_SOCKET_IF 0x08
50+
/** Register to COAP multicast groups */
51+
#define COAP_SERVICE_OPTIONS_MULTICAST_JOIN 0x10
4852
/** Link-layer security bypass option is set*/
4953
#define COAP_SERVICE_OPTIONS_SECURE_BYPASS 0x80
5054

@@ -56,6 +60,10 @@ extern "C" {
5660
#define COAP_REQUEST_OPTIONS_MULTICAST 0x04 //!< indicates that CoAP library support multicasting
5761
#define COAP_REQUEST_OPTIONS_SECURE_BYPASS 0x08
5862

63+
extern const uint8_t COAP_MULTICAST_ADDR_LINK_LOCAL[16]; //!< ff02::fd, COAP link local multicast address
64+
extern const uint8_t COAP_MULTICAST_ADDR_ADMIN_LOCAL[16]; //!< ff03::fd, COAP admin-local multicast address
65+
extern const uint8_t COAP_MULTICAST_ADDR_SITE_LOCAL[16]; //!> ff05::fd, COAP site-local multicast address
66+
5967
/**
6068
* \brief Service message response receive callback.
6169
*
@@ -262,7 +270,45 @@ extern uint16_t coap_service_request_send(int8_t service_id, uint8_t options, co
262270
*/
263271
extern 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);
264272

273+
/**
274+
* \brief Delete CoAP request transaction
275+
*
276+
* Removes pending CoAP transaction from service.
277+
*
278+
* \param service_id Id number of the current service.
279+
* \param msg_id Message ID number.
280+
*
281+
* \return -1 For failure
282+
*- 0 For success
283+
*/
284+
extern int8_t coap_service_request_delete(int8_t service_id, uint16_t msg_id);
285+
286+
/**
287+
* \brief Set DTLS handshake timeout values
288+
*
289+
* Configures the DTLS handshake timeout values.
290+
*
291+
* \param service_id Id number of the current service.
292+
* \param min Initial timeout value.
293+
* \param max Maximum value of timeout.
294+
*
295+
* \return -1 For failure
296+
*- 0 For success
297+
*/
265298
extern int8_t coap_service_set_handshake_timeout(int8_t service_id, uint32_t min, uint32_t max);
299+
300+
/**
301+
* \brief Set CoAP duplication message buffer size
302+
*
303+
* Configures the CoAP duplication message buffer size.
304+
*
305+
* \param service_id Id number of the current service.
306+
* \param size Buffer size (messages)
307+
*
308+
* \return -1 For failure
309+
*- 0 For success
310+
*/
311+
extern int8_t coap_service_set_duplicate_message_buffer(int8_t service_id, uint8_t size);
266312
#ifdef __cplusplus
267313
}
268314
#endif

features/nanostack/FEATURE_NANOSTACK/coap-service/run_unit_tests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/bin/bash
2-
# Copyright (c) 2015 ARM Limited. All rights reserved.
2+
# Copyright (c) 2015-2017 ARM Limited. All rights reserved.
33
# SPDX-License-Identifier: Apache-2.0
44
# Licensed under the Apache License, Version 2.0 (the License); you may
55
# not use this file except in compliance with the License.

features/nanostack/FEATURE_NANOSTACK/coap-service/source/coap_connection_handler.c

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015-2016 ARM Limited. All Rights Reserved.
2+
* Copyright (c) 2015-2017 ARM Limited. All Rights Reserved.
33
*/
44

55
#include <string.h>
@@ -42,6 +42,10 @@ typedef struct internal_socket_s {
4242
ns_list_link_t link;
4343
} internal_socket_t;
4444

45+
const uint8_t COAP_MULTICAST_ADDR_LINK_LOCAL[16] = { 0xff, 0x02, [15] = 0xfd }; // ff02::fd, COAP link-local multicast (rfc7390)
46+
const uint8_t COAP_MULTICAST_ADDR_ADMIN_LOCAL[16] = { 0xff, 0x03, [15] = 0xfd }; // ff02::fd, COAP admin-local multicast (rfc7390)
47+
const uint8_t COAP_MULTICAST_ADDR_SITE_LOCAL[16] = { 0xff, 0x05, [15] = 0xfd }; // ff05::fd, COAP site-local multicast (rfc7390)
48+
4549
static NS_LIST_DEFINE(socket_list, internal_socket_t, link);
4650

4751
static void timer_cb(void* param);
@@ -99,7 +103,6 @@ static secure_session_t *secure_session_find_by_timer_id(int8_t timer_id)
99103

100104
static bool is_secure_session_valid(secure_session_t *session)
101105
{
102-
secure_session_t *this = NULL;
103106
ns_list_foreach(secure_session_t, cur_ptr, &secure_session_list) {
104107
if (cur_ptr == session) {
105108
return true;
@@ -222,9 +225,32 @@ static secure_session_t *secure_session_find(internal_socket_t *parent, const ui
222225
return this;
223226
}
224227

225-
static internal_socket_t *int_socket_create(uint16_t listen_port, bool use_ephemeral_port, bool is_secure, bool real_socket, bool bypassSec)
228+
static void coap_multicast_group_join_or_leave(int8_t socket_id, uint8_t opt_name, int8_t interface_id)
229+
{
230+
ns_ipv6_mreq_t ns_ipv6_mreq;
231+
int8_t ret_val;
232+
233+
// Join or leave COAP multicast groups
234+
ns_ipv6_mreq.ipv6mr_interface = interface_id;
235+
236+
memcpy(ns_ipv6_mreq.ipv6mr_multiaddr, COAP_MULTICAST_ADDR_LINK_LOCAL, 16);
237+
ret_val = socket_setsockopt(socket_id, SOCKET_IPPROTO_IPV6, opt_name, &ns_ipv6_mreq, sizeof(ns_ipv6_mreq));
238+
239+
memcpy(ns_ipv6_mreq.ipv6mr_multiaddr, COAP_MULTICAST_ADDR_ADMIN_LOCAL, 16);
240+
ret_val |= socket_setsockopt(socket_id, SOCKET_IPPROTO_IPV6, opt_name, &ns_ipv6_mreq, sizeof(ns_ipv6_mreq));
241+
242+
memcpy(ns_ipv6_mreq.ipv6mr_multiaddr, COAP_MULTICAST_ADDR_SITE_LOCAL, 16);
243+
ret_val |= socket_setsockopt(socket_id, SOCKET_IPPROTO_IPV6, opt_name, &ns_ipv6_mreq, sizeof(ns_ipv6_mreq));
244+
245+
if (ret_val) {
246+
tr_error("Multicast group access failed, err=%d, name=%d", ret_val, opt_name);
247+
}
248+
}
249+
250+
static internal_socket_t *int_socket_create(uint16_t listen_port, bool use_ephemeral_port, bool is_secure, bool real_socket, bool bypassSec, int8_t socket_interface_selection, bool multicast_registration)
226251
{
227252
internal_socket_t *this = ns_dyn_mem_alloc(sizeof(internal_socket_t));
253+
228254
if (!this) {
229255
return NULL;
230256
}
@@ -266,7 +292,14 @@ static internal_socket_t *int_socket_create(uint16_t listen_port, bool use_ephem
266292

267293
// Set socket option to receive packet info
268294
socket_setsockopt(this->socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_RECVPKTINFO, &(const bool) {1}, sizeof(bool));
295+
if (socket_interface_selection > 0) {
296+
// Interface selection requested as socket_interface_selection set
297+
socket_setsockopt(this->socket, SOCKET_IPPROTO_IPV6, SOCKET_INTERFACE_SELECT, &socket_interface_selection, sizeof(socket_interface_selection));
298+
}
269299

300+
if (multicast_registration) {
301+
coap_multicast_group_join_or_leave(this->socket, SOCKET_IPV6_JOIN_GROUP, socket_interface_selection);
302+
}
270303
} else {
271304
this->socket = virtual_socket_id_allocate();
272305
}
@@ -773,9 +806,13 @@ coap_conn_handler_t *connection_handler_create(receive_from_socket_cb *recv_from
773806

774807
return handler;
775808
}
776-
void connection_handler_destroy(coap_conn_handler_t *handler)
809+
810+
void connection_handler_destroy(coap_conn_handler_t *handler, bool multicast_group_leave)
777811
{
778812
if(handler){
813+
if (multicast_group_leave) {
814+
coap_multicast_group_join_or_leave(handler->socket->socket, SOCKET_IPV6_LEAVE_GROUP, handler->socket_interface_selection);
815+
}
779816
int_socket_delete(handler->socket);
780817
ns_dyn_mem_free(handler);
781818
}
@@ -810,7 +847,7 @@ int coap_connection_handler_open_connection(coap_conn_handler_t *handler, uint16
810847

811848
internal_socket_t *current = !use_ephemeral_port?int_socket_find(listen_port, is_secure, is_real_socket, bypassSec):NULL;
812849
if (!current) {
813-
handler->socket = int_socket_create(listen_port, use_ephemeral_port, is_secure, is_real_socket, bypassSec);
850+
handler->socket = int_socket_create(listen_port, use_ephemeral_port, is_secure, is_real_socket, bypassSec, handler->socket_interface_selection, handler->registered_to_multicast);
814851
if (!handler->socket) {
815852
return -1;
816853
}

features/nanostack/FEATURE_NANOSTACK/coap-service/source/coap_message_handler.c

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015-2016 ARM Limited. All Rights Reserved.
2+
* Copyright (c) 2015-2017 ARM Limited. All Rights Reserved.
33
*/
44

55
#include <string.h>
@@ -57,6 +57,18 @@ static coap_transaction_t *transaction_find_server(uint16_t msg_id)
5757
return this;
5858
}
5959

60+
static coap_transaction_t *transaction_find_client(uint16_t msg_id)
61+
{
62+
coap_transaction_t *this = NULL;
63+
ns_list_foreach(coap_transaction_t, cur_ptr, &request_list) {
64+
if (cur_ptr->msg_id == msg_id && cur_ptr->client_request) {
65+
this = cur_ptr;
66+
break;
67+
}
68+
}
69+
return this;
70+
}
71+
6072
static coap_transaction_t *transaction_find_by_address(uint8_t *address_ptr, uint16_t port)
6173
{
6274
coap_transaction_t *this = NULL;
@@ -168,6 +180,10 @@ coap_msg_handler_t *coap_message_handler_init(void *(*used_malloc_func_ptr)(uint
168180
used_free_func_ptr(handle);
169181
return NULL;
170182
}
183+
184+
/* Set default buffer size for CoAP duplicate message detection */
185+
sn_coap_protocol_set_duplicate_buffer_size(handle->coap, DUPLICATE_MESSAGE_BUFFER_SIZE);
186+
171187
return handle;
172188
}
173189

@@ -391,6 +407,28 @@ int8_t coap_message_handler_response_send(coap_msg_handler_t *handle, int8_t ser
391407
return 0;
392408
}
393409

410+
int8_t coap_message_handler_request_delete(coap_msg_handler_t *handle, int8_t service_id, uint16_t msg_id)
411+
{
412+
coap_transaction_t *transaction_ptr;
413+
(void)service_id;
414+
415+
416+
tr_debug("Service %d, delete CoAP request %d", service_id, msg_id);
417+
if (!handle) {
418+
tr_error("invalid params");
419+
return -1;
420+
}
421+
sn_coap_protocol_delete_retransmission(handle->coap, msg_id);
422+
423+
transaction_ptr = transaction_find_client(msg_id);
424+
if (!transaction_ptr) {
425+
tr_error("response transaction not found");
426+
return -2;
427+
}
428+
transaction_delete(transaction_ptr);
429+
return 0;
430+
}
431+
394432
int8_t coap_message_handler_exec(coap_msg_handler_t *handle, uint32_t current_time){
395433

396434
if( !handle ){

features/nanostack/FEATURE_NANOSTACK/coap-service/source/coap_security_handler.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015-2016 ARM Limited. All Rights Reserved.
2+
* Copyright (c) 2015-2017 ARM Limited. All Rights Reserved.
33
*/
44

55
#include <string.h>

features/nanostack/FEATURE_NANOSTACK/coap-service/source/coap_service_api.c

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015-2016 ARM Limited. All Rights Reserved.
2+
* Copyright (c) 2015-2017 ARM Limited. All Rights Reserved.
33
*/
44

55

@@ -21,6 +21,7 @@
2121
#include "net_interface.h"
2222
#include "coap_service_api_internal.h"
2323
#include "coap_message_handler.h"
24+
#include "mbed-coap/sn_coap_protocol.h"
2425

2526
static int16_t coap_msg_process_callback(int8_t socket_id, sn_coap_hdr_s *coap_message, coap_transaction_t *transaction_ptr);
2627

@@ -99,6 +100,27 @@ static coap_service_t *service_find_by_uri(uint8_t socket_id, uint8_t *uri_ptr,
99100
return NULL;
100101
}
101102

103+
static bool coap_service_can_leave_multicast_group(coap_conn_handler_t *conn_handler)
104+
{
105+
int mc_count = 0;
106+
bool current_handler_joined_to_mc_group = false;
107+
108+
ns_list_foreach(coap_service_t, cur_ptr, &instance_list) {
109+
if (cur_ptr->conn_handler && cur_ptr->conn_handler->registered_to_multicast) {
110+
if (conn_handler == cur_ptr->conn_handler) {
111+
current_handler_joined_to_mc_group = true;
112+
}
113+
mc_count ++;
114+
}
115+
}
116+
117+
if (mc_count == 1 && current_handler_joined_to_mc_group) {
118+
// current handler is the only one joined to multicast group
119+
return true;
120+
}
121+
122+
return false;
123+
}
102124

103125
/**
104126
* Coap handling functions
@@ -280,9 +302,8 @@ static int get_passwd_cb(int8_t socket_id, uint8_t address[static 16], uint16_t
280302
int8_t coap_service_initialize(int8_t interface_id, uint16_t listen_port, uint8_t service_options,
281303
coap_service_security_start_cb *start_ptr, coap_service_security_done_cb *coap_security_done_cb)
282304
{
283-
(void) interface_id;
284-
285305
coap_service_t *this = ns_dyn_mem_alloc(sizeof(coap_service_t));
306+
286307
if (!this) {
287308
return -1;
288309
}
@@ -293,6 +314,7 @@ int8_t coap_service_initialize(int8_t interface_id, uint16_t listen_port, uint8_
293314
while (service_find(id) && id < 127) {
294315
id++;
295316
}
317+
this->interface_id = interface_id;
296318
this->service_id = id;
297319
this->service_options = service_options;
298320

@@ -310,10 +332,18 @@ int8_t coap_service_initialize(int8_t interface_id, uint16_t listen_port, uint8_
310332
return -1;
311333
}
312334

313-
if (0 > coap_connection_handler_open_connection(this->conn_handler, listen_port, ((this->service_options & COAP_SERVICE_OPTIONS_EPHEMERAL_PORT) == COAP_SERVICE_OPTIONS_EPHEMERAL_PORT),
314-
((this->service_options & COAP_SERVICE_OPTIONS_SECURE) == COAP_SERVICE_OPTIONS_SECURE),
315-
((this->service_options & COAP_SERVICE_OPTIONS_VIRTUAL_SOCKET) != COAP_SERVICE_OPTIONS_VIRTUAL_SOCKET),
316-
((this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS) == COAP_SERVICE_OPTIONS_SECURE_BYPASS))){
335+
this->conn_handler->socket_interface_selection = 0; // zero is illegal interface ID
336+
if (this->service_options & COAP_SERVICE_OPTIONS_SELECT_SOCKET_IF) {
337+
this->conn_handler->socket_interface_selection = this->interface_id;
338+
}
339+
340+
this->conn_handler->registered_to_multicast = this->service_options & COAP_SERVICE_OPTIONS_MULTICAST_JOIN;
341+
342+
if (0 > coap_connection_handler_open_connection(this->conn_handler, listen_port,
343+
(this->service_options & COAP_SERVICE_OPTIONS_EPHEMERAL_PORT),
344+
(this->service_options & COAP_SERVICE_OPTIONS_SECURE),
345+
!(this->service_options & COAP_SERVICE_OPTIONS_VIRTUAL_SOCKET),
346+
(this->service_options & COAP_SERVICE_OPTIONS_SECURE_BYPASS))) {
317347
ns_dyn_mem_free(this->conn_handler);
318348
ns_dyn_mem_free(this);
319349
return -1;
@@ -340,7 +370,12 @@ void coap_service_delete(int8_t service_id)
340370
}
341371

342372
if (this->conn_handler){
343-
connection_handler_destroy(this->conn_handler);
373+
bool leave_multicast_group = false;
374+
if (coap_service_can_leave_multicast_group(this->conn_handler)) {
375+
// This is the last handler joined to multicast group
376+
leave_multicast_group = true;
377+
}
378+
connection_handler_destroy(this->conn_handler, leave_multicast_group);
344379
}
345380

346381
//TODO clear all transactions
@@ -459,6 +494,11 @@ int8_t coap_service_response_send(int8_t service_id, uint8_t options, sn_coap_hd
459494
return coap_message_handler_response_send(coap_service_handle, service_id, options, request_ptr, message_code, content_type, payload_ptr, payload_len);
460495
}
461496

497+
int8_t coap_service_request_delete(int8_t service_id, uint16_t msg_id)
498+
{
499+
return coap_message_handler_request_delete(coap_service_handle, service_id, msg_id);
500+
}
501+
462502
int8_t coap_service_set_handshake_timeout(int8_t service_id, uint32_t min, uint32_t max)
463503
{
464504
coap_service_t *this = service_find(service_id);
@@ -469,6 +509,17 @@ int8_t coap_service_set_handshake_timeout(int8_t service_id, uint32_t min, uint3
469509
return coap_connection_handler_set_timeout(this->conn_handler, min, max);
470510
}
471511

512+
int8_t coap_service_set_duplicate_message_buffer(int8_t service_id, uint8_t size)
513+
{
514+
(void) service_id;
515+
516+
if (!coap_service_handle) {
517+
return -1;
518+
}
519+
520+
return sn_coap_protocol_set_duplicate_buffer_size(coap_service_handle->coap, size);
521+
}
522+
472523
uint32_t coap_service_get_internal_timer_ticks(void)
473524
{
474525
return coap_ticks;

0 commit comments

Comments
 (0)