Skip to content

Commit

Permalink
Merge pull request #13412 from mikaleppanen/wisun_radius_conf
Browse files Browse the repository at this point in the history
Add support for RADIUS configuration options to Wi-SUN
  • Loading branch information
Arto Kinnunen committed Aug 20, 2020
2 parents 3036b39 + befd783 commit 04d8eeb
Show file tree
Hide file tree
Showing 4 changed files with 212 additions and 8 deletions.
60 changes: 58 additions & 2 deletions features/nanostack/mbed-mesh-api/mbed-mesh-api/WisunBorderRouter.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class WisunBorderRouter {
/** Create WisunBorderRouter
*
* */
WisunBorderRouter() { }
WisunBorderRouter();

/**
* \brief Start Wi-SUN Border Router
Expand Down Expand Up @@ -209,9 +209,65 @@ class WisunBorderRouter {
* */
int routing_table_get(ws_br_route_info_t *table_ptr, uint16_t table_len);

/**
* \brief Set Wi-SUN RADIUS server IPv6 address.
*
* Function sets external RADIUS server IPv6 address to Border Router. Setting the address enables
* external RADIUS server interface on Border Router. To disable external RADIUS server interface,
* call the function with address set to NULL. The RADIUS shared secret must be set before address
* is set using set_radius_shared_secret() call.
*
* \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.
* \return MESH_ERROR_NONE on success.
* \return MESH_ERROR_UNKNOWN in case of failure.
* */
mesh_error_t set_radius_server_ipv6_address(const char *address);

/**
* \brief Get Wi-SUN RADIUS server IPv6 address.
*
* Function gets external RADIUS server IPv6 address from Border Router.
*
* \param address Pointer to buffer where to write IPv6 address string. Must have space at least for 39 characters and NUL terminator.
* \return MESH_ERROR_NONE on success.
* \return error value in case of failure, e.g. if address has not been set to Border Router.
* */
mesh_error_t get_radius_server_ipv6_address(char *address);

/**
* \brief Set Wi-SUN RADIUS shared secret.
*
* Function sets RADIUS shared secret to Border Router. Shared secret may be an ASCII string. Check
* the format and length constraints for the shared secret from the documentation of RADIUS server you
* are connecting to.
*
* \param shared_secret_len The length of the shared secret in bytes.
* \param shared_secret Pointer to shared secret. Can be 8-bit ASCII string or byte array. Is not NUL terminated.
* \return MESH_ERROR_NONE on success.
* \return error value in case of failure.
* */
mesh_error_t set_radius_shared_secret(uint16_t shared_secret_len, const uint8_t *shared_secret);

/**
* \brief Get Wi-SUN RADIUS shared secret.
*
* Function gets RADIUS shared secret from Border Router.
*
* \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.
* \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.
* \return MESH_ERROR_NONE on success.
* \return error value in case of failure.
* */
mesh_error_t get_radius_shared_secret(uint16_t *shared_secret_len, uint8_t *shared_secret);

private:
mesh_error_t configure();
mesh_error_t apply_configuration(int8_t mesh_if_id);
mesh_error_t set_bbr_radius_address(void);
char _radius_ipv6_addr[40];
int8_t _mesh_if_id = -1;

bool _radius_ipv6_addr_set = false;
bool _configured = false;
};

#endif
12 changes: 12 additions & 0 deletions features/nanostack/mbed-mesh-api/mbed_lib.json
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,18 @@
"own-certificate-key-len": {
"help": "Own certificate's key length; optional for PEM format, must be defined for DER format",
"value": null
},
"radius-server-ipv6-address": {
"help": "RADIUS Server IPv6 address in string format (e.g. \"2001:1234::1\")",
"value": null
},
"radius-shared-secret": {
"help": "RADIUS shared secret; ASCII string (e.g. \"radiuspassword\") or sequence of bytes (e.g. 0x01, 0x02, 0x03, 0x04, 0x05)",
"value": null
},
"radius-shared-secret-len": {
"help": "RADIUS shared secret length; If length is not defined, strlen() is used to determine RADIUS shared secret length",
"value": null
}
},
"target_overrides": {
Expand Down
136 changes: 136 additions & 0 deletions features/nanostack/mbed-mesh-api/source/WisunBorderRouter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,21 @@
#include "WisunBorderRouter.h"
#include "MeshInterfaceNanostack.h"
#include "net_interface.h"
#include "ip6string.h"

extern "C" {
#include "ws_bbr_api.h"
}

#define TRACE_GROUP "WSBR"


WisunBorderRouter::WisunBorderRouter()
{
// Apply mbed configuration to Wi-SUN BBR
configure();
}

mesh_error_t WisunBorderRouter::start(NetworkInterface *mesh_if, NetworkInterface *backbone_if)
{
if (mesh_if == NULL || backbone_if == NULL) {
Expand Down Expand Up @@ -53,6 +61,8 @@ mesh_error_t WisunBorderRouter::start(NetworkInterface *mesh_if, NetworkInterfac
return MESH_ERROR_UNKNOWN;
}

apply_configuration(mesh_if_id);

int ret = ws_bbr_start(mesh_if_id, backbone_if_id);
if (ret < 0) {
return MESH_ERROR_UNKNOWN;
Expand All @@ -76,6 +86,8 @@ mesh_error_t WisunBorderRouter::start(NetworkInterface *mesh_if, OnboardNetworkS
return MESH_ERROR_UNKNOWN;
}

apply_configuration(mesh_if_id);

int ret = ws_bbr_start(mesh_if_id, backbone_if_id);
if (ret < 0) {
return MESH_ERROR_UNKNOWN;
Expand All @@ -95,6 +107,55 @@ void WisunBorderRouter::stop()
_mesh_if_id = -1;
}

mesh_error_t WisunBorderRouter::configure()
{
#if defined(MBED_CONF_MBED_MESH_API_RADIUS_SHARED_SECRET) || defined(MBED_CONF_MBED_MESH_API_RADIUS_SERVER_IPV6_ADDRESS)
mesh_error_t status;
#endif

if (_configured) {
// Already configured
return MESH_ERROR_NONE;
}

_configured = true;

#ifdef MBED_CONF_MBED_MESH_API_RADIUS_SHARED_SECRET
const char radius_shared_secret[] = {MBED_CONF_MBED_MESH_API_RADIUS_SHARED_SECRET};
#ifdef MBED_CONF_MBED_MESH_API_RADIUS_SHARED_SECRET_LEN
const uint16_t radius_shared_secret_len = MBED_CONF_MBED_MESH_API_RADIUS_SHARED_SECRET_LEN;
#else
uint16_t radius_shared_secret_len = strlen(radius_shared_secret);
#endif
status = set_radius_shared_secret(radius_shared_secret_len, (uint8_t *) radius_shared_secret);
if (status != MESH_ERROR_NONE) {
tr_error("Failed to set RADIUS shared secret!");
return status;
}
#endif

#ifdef MBED_CONF_MBED_MESH_API_RADIUS_SERVER_IPV6_ADDRESS
const char radius_server_ipv6_addr[] = {MBED_CONF_MBED_MESH_API_RADIUS_SERVER_IPV6_ADDRESS};
status = set_radius_server_ipv6_address(radius_server_ipv6_addr);
if (status != MESH_ERROR_NONE) {
tr_error("Failed to set RADIUS server IPv6 address!");
return status;
}
#endif

return MESH_ERROR_NONE;
}

mesh_error_t WisunBorderRouter::apply_configuration(int8_t mesh_if_id)
{
mesh_error_t status = set_bbr_radius_address();
if (status != MESH_ERROR_NONE) {
tr_error("Failed to apply RADIUS server IPv6 address!");
return MESH_ERROR_PARAM;
}
return MESH_ERROR_NONE;
}

mesh_error_t WisunBorderRouter::set_rpl_parameters(uint8_t dio_interval_min, uint8_t dio_interval_doublings, uint8_t dio_redundancy_constant)
{
int status = ws_bbr_rpl_parameters_set(_mesh_if_id, dio_interval_min, dio_interval_doublings, dio_redundancy_constant);
Expand Down Expand Up @@ -188,3 +249,78 @@ int WisunBorderRouter::routing_table_get(ws_br_route_info_t *table_ptr, uint16_t

return ws_bbr_routing_table_get(_mesh_if_id, (bbr_route_info_t *)table_ptr, table_len);
}

mesh_error_t WisunBorderRouter::set_radius_server_ipv6_address(const char *address)
{
if (address) {
uint8_t ipv6_addr[16];
if (!stoip6(address, strlen(address), ipv6_addr)) {
return MESH_ERROR_PARAM;
}
// Stored address (returned by get) is in the format given by user of the interface
strcpy(_radius_ipv6_addr, address);
_radius_ipv6_addr_set = true;
} else {
_radius_ipv6_addr_set = false;
}

return set_bbr_radius_address();
}

mesh_error_t WisunBorderRouter::get_radius_server_ipv6_address(char *address)
{
if (!_radius_ipv6_addr_set) {
return MESH_ERROR_UNKNOWN;
}
strcpy(address, _radius_ipv6_addr);

return MESH_ERROR_NONE;
}

mesh_error_t WisunBorderRouter::set_bbr_radius_address(void)
{
int status;

if (_radius_ipv6_addr_set) {
uint8_t ipv6_addr[16];
if (!stoip6(_radius_ipv6_addr, strlen(_radius_ipv6_addr), ipv6_addr)) {
return MESH_ERROR_PARAM;
}
status = ws_bbr_radius_address_set(_mesh_if_id, ipv6_addr);
} else {
status = ws_bbr_radius_address_set(_mesh_if_id, NULL);
}
if (status != 0) {
return MESH_ERROR_UNKNOWN;
}

return MESH_ERROR_NONE;
}

mesh_error_t WisunBorderRouter::set_radius_shared_secret(uint16_t shared_secret_len, const uint8_t *shared_secret)
{
if (shared_secret_len == 0 || !shared_secret) {
return MESH_ERROR_PARAM;
}

int status = ws_bbr_radius_shared_secret_set(_mesh_if_id, shared_secret_len, shared_secret);
if (status != 0) {
return MESH_ERROR_UNKNOWN;
}

return MESH_ERROR_NONE;
}

mesh_error_t WisunBorderRouter::get_radius_shared_secret(uint16_t *shared_secret_len, uint8_t *shared_secret)
{
if (shared_secret_len == NULL) {
return MESH_ERROR_PARAM;
}

int status = ws_bbr_radius_shared_secret_get(_mesh_if_id, shared_secret_len, shared_secret);
if (status != 0) {
return MESH_ERROR_UNKNOWN;
}

return MESH_ERROR_NONE;
}
12 changes: 6 additions & 6 deletions features/nanostack/mbed-mesh-api/source/WisunInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ nsapi_error_t WisunInterface::do_initialize()

nsapi_error_t WisunInterface::configure()
{
int status;
mesh_error_t status;

if (_configured) {
// Already configured
Expand All @@ -82,7 +82,7 @@ nsapi_error_t WisunInterface::configure()
#ifdef MBED_CONF_MBED_MESH_API_WISUN_NETWORK_NAME
char network_name[] = {MBED_CONF_MBED_MESH_API_WISUN_NETWORK_NAME};
status = set_network_name((char *) &network_name);
if (status < 0) {
if (status != MESH_ERROR_NONE) {
tr_error("Failed to set network name!");
return NSAPI_ERROR_PARAMETER;
}
Expand All @@ -92,7 +92,7 @@ nsapi_error_t WisunInterface::configure()
status = set_network_regulatory_domain(MBED_CONF_MBED_MESH_API_WISUN_REGULATORY_DOMAIN,
MBED_CONF_MBED_MESH_API_WISUN_OPERATING_CLASS,
MBED_CONF_MBED_MESH_API_WISUN_OPERATING_MODE);
if (status < 0) {
if (status != MESH_ERROR_NONE) {
tr_error("Failed to set regulatory domain!");
return NSAPI_ERROR_PARAMETER;
}
Expand All @@ -102,7 +102,7 @@ nsapi_error_t WisunInterface::configure()
status = set_unicast_channel_function(static_cast<mesh_channel_function_t>(MBED_CONF_MBED_MESH_API_WISUN_UC_CHANNEL_FUNCTION),
MBED_CONF_MBED_MESH_API_WISUN_UC_FIXED_CHANNEL,
MBED_CONF_MBED_MESH_API_WISUN_UC_DWELL_INTERVAL);
if (status < 0) {
if (status != MESH_ERROR_NONE) {
tr_error("Failed to set unicast channel function configuration");
return NSAPI_ERROR_PARAMETER;
}
Expand All @@ -113,15 +113,15 @@ nsapi_error_t WisunInterface::configure()
MBED_CONF_MBED_MESH_API_WISUN_BC_FIXED_CHANNEL,
MBED_CONF_MBED_MESH_API_WISUN_BC_DWELL_INTERVAL,
MBED_CONF_MBED_MESH_API_WISUN_BC_INTERVAL);
if (status < 0) {
if (status != MESH_ERROR_NONE) {
tr_error("Failed to set broadcast channel function configuration");
return NSAPI_ERROR_PARAMETER;
}
#endif

#ifdef MBED_CONF_MBED_MESH_API_WISUN_NETWORK_SIZE
status = set_network_size(MBED_CONF_MBED_MESH_API_WISUN_NETWORK_SIZE);
if (status < 0) {
if (status != MESH_ERROR_NONE) {
tr_error("Failed to set network size");
return NSAPI_ERROR_PARAMETER;
}
Expand Down

0 comments on commit 04d8eeb

Please sign in to comment.