Skip to content

Commit 04d8eeb

Browse files
author
Arto Kinnunen
authored
Merge pull request #13412 from mikaleppanen/wisun_radius_conf
Add support for RADIUS configuration options to Wi-SUN
2 parents 3036b39 + befd783 commit 04d8eeb

File tree

4 files changed

+212
-8
lines changed

4 files changed

+212
-8
lines changed

features/nanostack/mbed-mesh-api/mbed-mesh-api/WisunBorderRouter.h

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class WisunBorderRouter {
6060
/** Create WisunBorderRouter
6161
*
6262
* */
63-
WisunBorderRouter() { }
63+
WisunBorderRouter();
6464

6565
/**
6666
* \brief Start Wi-SUN Border Router
@@ -209,9 +209,65 @@ class WisunBorderRouter {
209209
* */
210210
int routing_table_get(ws_br_route_info_t *table_ptr, uint16_t table_len);
211211

212+
/**
213+
* \brief Set Wi-SUN RADIUS server IPv6 address.
214+
*
215+
* Function sets external RADIUS server IPv6 address to Border Router. Setting the address enables
216+
* external RADIUS server interface on Border Router. To disable external RADIUS server interface,
217+
* call the function with address set to NULL. The RADIUS shared secret must be set before address
218+
* is set using set_radius_shared_secret() call.
219+
*
220+
* \param address Pointer to IPv6 address string or NULL to disable RADIUS. Address string format is e.g. 2001:1234::1 and it is NUL terminated.
221+
* \return MESH_ERROR_NONE on success.
222+
* \return MESH_ERROR_UNKNOWN in case of failure.
223+
* */
224+
mesh_error_t set_radius_server_ipv6_address(const char *address);
225+
226+
/**
227+
* \brief Get Wi-SUN RADIUS server IPv6 address.
228+
*
229+
* Function gets external RADIUS server IPv6 address from Border Router.
230+
*
231+
* \param address Pointer to buffer where to write IPv6 address string. Must have space at least for 39 characters and NUL terminator.
232+
* \return MESH_ERROR_NONE on success.
233+
* \return error value in case of failure, e.g. if address has not been set to Border Router.
234+
* */
235+
mesh_error_t get_radius_server_ipv6_address(char *address);
236+
237+
/**
238+
* \brief Set Wi-SUN RADIUS shared secret.
239+
*
240+
* Function sets RADIUS shared secret to Border Router. Shared secret may be an ASCII string. Check
241+
* the format and length constraints for the shared secret from the documentation of RADIUS server you
242+
* are connecting to.
243+
*
244+
* \param shared_secret_len The length of the shared secret in bytes.
245+
* \param shared_secret Pointer to shared secret. Can be 8-bit ASCII string or byte array. Is not NUL terminated.
246+
* \return MESH_ERROR_NONE on success.
247+
* \return error value in case of failure.
248+
* */
249+
mesh_error_t set_radius_shared_secret(uint16_t shared_secret_len, const uint8_t *shared_secret);
250+
251+
/**
252+
* \brief Get Wi-SUN RADIUS shared secret.
253+
*
254+
* Function gets RADIUS shared secret from Border Router.
255+
*
256+
* \param shared_secret_len On function call, is the size of the shared secret write buffer in bytes, on return is the shared secret length in bytes.
257+
* \param shared_secret Pointer to buffer where to write shared secret or NULL. At maximum, bytes set by the length parameter are written. If NULL only buffer length is returned.
258+
* \return MESH_ERROR_NONE on success.
259+
* \return error value in case of failure.
260+
* */
261+
mesh_error_t get_radius_shared_secret(uint16_t *shared_secret_len, uint8_t *shared_secret);
262+
212263
private:
264+
mesh_error_t configure();
265+
mesh_error_t apply_configuration(int8_t mesh_if_id);
266+
mesh_error_t set_bbr_radius_address(void);
267+
char _radius_ipv6_addr[40];
213268
int8_t _mesh_if_id = -1;
214-
269+
bool _radius_ipv6_addr_set = false;
270+
bool _configured = false;
215271
};
216272

217273
#endif

features/nanostack/mbed-mesh-api/mbed_lib.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,18 @@
195195
"own-certificate-key-len": {
196196
"help": "Own certificate's key length; optional for PEM format, must be defined for DER format",
197197
"value": null
198+
},
199+
"radius-server-ipv6-address": {
200+
"help": "RADIUS Server IPv6 address in string format (e.g. \"2001:1234::1\")",
201+
"value": null
202+
},
203+
"radius-shared-secret": {
204+
"help": "RADIUS shared secret; ASCII string (e.g. \"radiuspassword\") or sequence of bytes (e.g. 0x01, 0x02, 0x03, 0x04, 0x05)",
205+
"value": null
206+
},
207+
"radius-shared-secret-len": {
208+
"help": "RADIUS shared secret length; If length is not defined, strlen() is used to determine RADIUS shared secret length",
209+
"value": null
198210
}
199211
},
200212
"target_overrides": {

features/nanostack/mbed-mesh-api/source/WisunBorderRouter.cpp

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,21 @@
1919
#include "WisunBorderRouter.h"
2020
#include "MeshInterfaceNanostack.h"
2121
#include "net_interface.h"
22+
#include "ip6string.h"
2223

2324
extern "C" {
2425
#include "ws_bbr_api.h"
2526
}
2627

2728
#define TRACE_GROUP "WSBR"
2829

30+
31+
WisunBorderRouter::WisunBorderRouter()
32+
{
33+
// Apply mbed configuration to Wi-SUN BBR
34+
configure();
35+
}
36+
2937
mesh_error_t WisunBorderRouter::start(NetworkInterface *mesh_if, NetworkInterface *backbone_if)
3038
{
3139
if (mesh_if == NULL || backbone_if == NULL) {
@@ -53,6 +61,8 @@ mesh_error_t WisunBorderRouter::start(NetworkInterface *mesh_if, NetworkInterfac
5361
return MESH_ERROR_UNKNOWN;
5462
}
5563

64+
apply_configuration(mesh_if_id);
65+
5666
int ret = ws_bbr_start(mesh_if_id, backbone_if_id);
5767
if (ret < 0) {
5868
return MESH_ERROR_UNKNOWN;
@@ -76,6 +86,8 @@ mesh_error_t WisunBorderRouter::start(NetworkInterface *mesh_if, OnboardNetworkS
7686
return MESH_ERROR_UNKNOWN;
7787
}
7888

89+
apply_configuration(mesh_if_id);
90+
7991
int ret = ws_bbr_start(mesh_if_id, backbone_if_id);
8092
if (ret < 0) {
8193
return MESH_ERROR_UNKNOWN;
@@ -95,6 +107,55 @@ void WisunBorderRouter::stop()
95107
_mesh_if_id = -1;
96108
}
97109

110+
mesh_error_t WisunBorderRouter::configure()
111+
{
112+
#if defined(MBED_CONF_MBED_MESH_API_RADIUS_SHARED_SECRET) || defined(MBED_CONF_MBED_MESH_API_RADIUS_SERVER_IPV6_ADDRESS)
113+
mesh_error_t status;
114+
#endif
115+
116+
if (_configured) {
117+
// Already configured
118+
return MESH_ERROR_NONE;
119+
}
120+
121+
_configured = true;
122+
123+
#ifdef MBED_CONF_MBED_MESH_API_RADIUS_SHARED_SECRET
124+
const char radius_shared_secret[] = {MBED_CONF_MBED_MESH_API_RADIUS_SHARED_SECRET};
125+
#ifdef MBED_CONF_MBED_MESH_API_RADIUS_SHARED_SECRET_LEN
126+
const uint16_t radius_shared_secret_len = MBED_CONF_MBED_MESH_API_RADIUS_SHARED_SECRET_LEN;
127+
#else
128+
uint16_t radius_shared_secret_len = strlen(radius_shared_secret);
129+
#endif
130+
status = set_radius_shared_secret(radius_shared_secret_len, (uint8_t *) radius_shared_secret);
131+
if (status != MESH_ERROR_NONE) {
132+
tr_error("Failed to set RADIUS shared secret!");
133+
return status;
134+
}
135+
#endif
136+
137+
#ifdef MBED_CONF_MBED_MESH_API_RADIUS_SERVER_IPV6_ADDRESS
138+
const char radius_server_ipv6_addr[] = {MBED_CONF_MBED_MESH_API_RADIUS_SERVER_IPV6_ADDRESS};
139+
status = set_radius_server_ipv6_address(radius_server_ipv6_addr);
140+
if (status != MESH_ERROR_NONE) {
141+
tr_error("Failed to set RADIUS server IPv6 address!");
142+
return status;
143+
}
144+
#endif
145+
146+
return MESH_ERROR_NONE;
147+
}
148+
149+
mesh_error_t WisunBorderRouter::apply_configuration(int8_t mesh_if_id)
150+
{
151+
mesh_error_t status = set_bbr_radius_address();
152+
if (status != MESH_ERROR_NONE) {
153+
tr_error("Failed to apply RADIUS server IPv6 address!");
154+
return MESH_ERROR_PARAM;
155+
}
156+
return MESH_ERROR_NONE;
157+
}
158+
98159
mesh_error_t WisunBorderRouter::set_rpl_parameters(uint8_t dio_interval_min, uint8_t dio_interval_doublings, uint8_t dio_redundancy_constant)
99160
{
100161
int status = ws_bbr_rpl_parameters_set(_mesh_if_id, dio_interval_min, dio_interval_doublings, dio_redundancy_constant);
@@ -188,3 +249,78 @@ int WisunBorderRouter::routing_table_get(ws_br_route_info_t *table_ptr, uint16_t
188249

189250
return ws_bbr_routing_table_get(_mesh_if_id, (bbr_route_info_t *)table_ptr, table_len);
190251
}
252+
253+
mesh_error_t WisunBorderRouter::set_radius_server_ipv6_address(const char *address)
254+
{
255+
if (address) {
256+
uint8_t ipv6_addr[16];
257+
if (!stoip6(address, strlen(address), ipv6_addr)) {
258+
return MESH_ERROR_PARAM;
259+
}
260+
// Stored address (returned by get) is in the format given by user of the interface
261+
strcpy(_radius_ipv6_addr, address);
262+
_radius_ipv6_addr_set = true;
263+
} else {
264+
_radius_ipv6_addr_set = false;
265+
}
266+
267+
return set_bbr_radius_address();
268+
}
269+
270+
mesh_error_t WisunBorderRouter::get_radius_server_ipv6_address(char *address)
271+
{
272+
if (!_radius_ipv6_addr_set) {
273+
return MESH_ERROR_UNKNOWN;
274+
}
275+
strcpy(address, _radius_ipv6_addr);
276+
277+
return MESH_ERROR_NONE;
278+
}
279+
280+
mesh_error_t WisunBorderRouter::set_bbr_radius_address(void)
281+
{
282+
int status;
283+
284+
if (_radius_ipv6_addr_set) {
285+
uint8_t ipv6_addr[16];
286+
if (!stoip6(_radius_ipv6_addr, strlen(_radius_ipv6_addr), ipv6_addr)) {
287+
return MESH_ERROR_PARAM;
288+
}
289+
status = ws_bbr_radius_address_set(_mesh_if_id, ipv6_addr);
290+
} else {
291+
status = ws_bbr_radius_address_set(_mesh_if_id, NULL);
292+
}
293+
if (status != 0) {
294+
return MESH_ERROR_UNKNOWN;
295+
}
296+
297+
return MESH_ERROR_NONE;
298+
}
299+
300+
mesh_error_t WisunBorderRouter::set_radius_shared_secret(uint16_t shared_secret_len, const uint8_t *shared_secret)
301+
{
302+
if (shared_secret_len == 0 || !shared_secret) {
303+
return MESH_ERROR_PARAM;
304+
}
305+
306+
int status = ws_bbr_radius_shared_secret_set(_mesh_if_id, shared_secret_len, shared_secret);
307+
if (status != 0) {
308+
return MESH_ERROR_UNKNOWN;
309+
}
310+
311+
return MESH_ERROR_NONE;
312+
}
313+
314+
mesh_error_t WisunBorderRouter::get_radius_shared_secret(uint16_t *shared_secret_len, uint8_t *shared_secret)
315+
{
316+
if (shared_secret_len == NULL) {
317+
return MESH_ERROR_PARAM;
318+
}
319+
320+
int status = ws_bbr_radius_shared_secret_get(_mesh_if_id, shared_secret_len, shared_secret);
321+
if (status != 0) {
322+
return MESH_ERROR_UNKNOWN;
323+
}
324+
325+
return MESH_ERROR_NONE;
326+
}

features/nanostack/mbed-mesh-api/source/WisunInterface.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ nsapi_error_t WisunInterface::do_initialize()
7171

7272
nsapi_error_t WisunInterface::configure()
7373
{
74-
int status;
74+
mesh_error_t status;
7575

7676
if (_configured) {
7777
// Already configured
@@ -82,7 +82,7 @@ nsapi_error_t WisunInterface::configure()
8282
#ifdef MBED_CONF_MBED_MESH_API_WISUN_NETWORK_NAME
8383
char network_name[] = {MBED_CONF_MBED_MESH_API_WISUN_NETWORK_NAME};
8484
status = set_network_name((char *) &network_name);
85-
if (status < 0) {
85+
if (status != MESH_ERROR_NONE) {
8686
tr_error("Failed to set network name!");
8787
return NSAPI_ERROR_PARAMETER;
8888
}
@@ -92,7 +92,7 @@ nsapi_error_t WisunInterface::configure()
9292
status = set_network_regulatory_domain(MBED_CONF_MBED_MESH_API_WISUN_REGULATORY_DOMAIN,
9393
MBED_CONF_MBED_MESH_API_WISUN_OPERATING_CLASS,
9494
MBED_CONF_MBED_MESH_API_WISUN_OPERATING_MODE);
95-
if (status < 0) {
95+
if (status != MESH_ERROR_NONE) {
9696
tr_error("Failed to set regulatory domain!");
9797
return NSAPI_ERROR_PARAMETER;
9898
}
@@ -102,7 +102,7 @@ nsapi_error_t WisunInterface::configure()
102102
status = set_unicast_channel_function(static_cast<mesh_channel_function_t>(MBED_CONF_MBED_MESH_API_WISUN_UC_CHANNEL_FUNCTION),
103103
MBED_CONF_MBED_MESH_API_WISUN_UC_FIXED_CHANNEL,
104104
MBED_CONF_MBED_MESH_API_WISUN_UC_DWELL_INTERVAL);
105-
if (status < 0) {
105+
if (status != MESH_ERROR_NONE) {
106106
tr_error("Failed to set unicast channel function configuration");
107107
return NSAPI_ERROR_PARAMETER;
108108
}
@@ -113,15 +113,15 @@ nsapi_error_t WisunInterface::configure()
113113
MBED_CONF_MBED_MESH_API_WISUN_BC_FIXED_CHANNEL,
114114
MBED_CONF_MBED_MESH_API_WISUN_BC_DWELL_INTERVAL,
115115
MBED_CONF_MBED_MESH_API_WISUN_BC_INTERVAL);
116-
if (status < 0) {
116+
if (status != MESH_ERROR_NONE) {
117117
tr_error("Failed to set broadcast channel function configuration");
118118
return NSAPI_ERROR_PARAMETER;
119119
}
120120
#endif
121121

122122
#ifdef MBED_CONF_MBED_MESH_API_WISUN_NETWORK_SIZE
123123
status = set_network_size(MBED_CONF_MBED_MESH_API_WISUN_NETWORK_SIZE);
124-
if (status < 0) {
124+
if (status != MESH_ERROR_NONE) {
125125
tr_error("Failed to set network size");
126126
return NSAPI_ERROR_PARAMETER;
127127
}

0 commit comments

Comments
 (0)