This is a initial version of Wi-Sun interface implementation.

To get Wi-Sun mesh network working, also nanostack with Wi-Sun support
is needed. ws_empty_functions.c and ws_management_api.h are temporary
included here, so that wisun_tasklet will compiled without problems.
They will replaced with the official versions with next nanostack release.
pull/8600/head
Kari Haapalehto 2018-10-29 14:08:08 +02:00
parent 870c3bce59
commit 4440612d42
11 changed files with 1186 additions and 1 deletions

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2018 ARM Limited. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef WISUNINTERFACE_H
#define WISUNINTERFACE_H
#include "MeshInterfaceNanostack.h"
/** Wi-SUN mesh network interface class
*
* Configure Nanostack to use Wi-SUN protocol.
*/
class WisunInterface : public MeshInterfaceNanostack {
public:
/** Create an uninitialized WisunInterface
*
* Must initialize to initialize the mesh on a phy.
*/
WisunInterface() { }
/** Create an initialized WisunInterface
*
*/
WisunInterface(NanostackRfPhy *phy) : MeshInterfaceNanostack(phy) { }
bool getRouterIpAddress(char *address, int8_t len);
protected:
Nanostack::WisunInterface *get_interface() const;
virtual nsapi_error_t do_initialize();
};
#endif

View File

@ -108,6 +108,70 @@
"thread-security-policy": {
"help": "Commissioning security policy bits [0-0xFF]",
"value": 255
},
"wisun-network-name": {
"help": "default network name for wisun network",
"value": "\"NETWORK_NAME\""
},
"wisun-regulator-domain": {
"help": "Regulator domain.",
"value": "3"
},
"wisun-operating-class": {
"help": "Operating class.",
"value": "255"
},
"wisun-operating-mode": {
"help": "Operating mode.",
"value": "255"
},
"wisun-uc-channel-function": {
"help": "Unicast channel function.",
"value": "255"
},
"wisun-bc-channel-function": {
"help": "Broadcast channel function.",
"value": "255"
},
"wisun-uc-fixed-channel": {
"help": "Default fixed channel",
"value": "0xffff"
},
"wisun-bc-fixed-channel": {
"help": "Default fixed channel",
"value": "0xffff"
},
"wisun-bc-interval": {
"help": "Broadcast interval. Duration between broadcast dwell intervals. Range: 0-16777216 milliseconds",
"value": 0
},
"wisun-bc-dwell-interval": {
"help": "Broadcast dwell interval. Range: 15-250 milliseconds",
"value": 0
},
"wisun-uc-dwell-interval": {
"help": "Unicast dwell interval. Range: 15-250 milliseconds",
"value": 0
},
"wisun-device-type": {
"help": "Device mode (NET_6LOWPAN_ROUTER or NET_6LOWPAN_HOST). Router is routing packets from other device, creating a mesh network.",
"value": "NET_6LOWPAN_ROUTER"
},
"wisun-nd-channel-mask": {
"help": "Channel mask, bit-mask of channels to use. [0-0x07fff800]",
"value": "0x7fff800"
},
"wisun-nd-channel-page": {
"help": "0 for 2.4 GHz and 2 for sub-GHz radios.",
"value": 0
},
"wisun-nd-channel": {
"help": "RF channel to use when `channel_mask` is not defined. [0-26].",
"value": 0
},
"wisun-nd-panid-filter": {
"help": "Beacon PAN ID filter, 0xffff means no filtering. [0-0xffff]",
"value": "0xffff"
}
},
"target_overrides": {

View File

@ -1,3 +1,19 @@
/*
* Copyright (c) 2018 ARM Limited. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LoWPANNDInterface.h"
#include "include/nd_tasklet.h"
#include "callback_handler.h"

View File

@ -1,3 +1,19 @@
/*
* Copyright (c) 2018 ARM Limited. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ThreadInterface.h"
#include "include/thread_tasklet.h"
#include "callback_handler.h"

View File

@ -0,0 +1,185 @@
/*
* Copyright (c) 2018 ARM Limited. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "WisunInterface.h"
#include "include/wisun_tasklet.h"
#include "callback_handler.h"
#include "NanostackLockGuard.h"
#include "mesh_system.h"
#include "randLIB.h"
#include "ns_trace.h"
#define TRACE_GROUP "wisuI"
class Nanostack::WisunInterface : public Nanostack::MeshInterface {
public:
virtual nsapi_error_t bringup(bool dhcp, const char *ip,
const char *netmask, const char *gw,
nsapi_ip_stack_t stack = IPV6_STACK,
bool blocking = true);
virtual nsapi_error_t bringdown();
virtual char *get_gateway(char *buf, nsapi_size_t buflen);
friend Nanostack;
friend class ::WisunInterface;
private:
WisunInterface(NanostackRfPhy &phy) : MeshInterface(phy) { }
mesh_error_t init();
mesh_error_t mesh_connect();
mesh_error_t mesh_disconnect();
};
Nanostack::WisunInterface *WisunInterface::get_interface() const
{
return static_cast<Nanostack::WisunInterface *>(_interface);
}
nsapi_error_t WisunInterface::do_initialize()
{
if (!_interface) {
_interface = new (nothrow) Nanostack::WisunInterface(*_phy);
if (!_interface) {
return NSAPI_ERROR_NO_MEMORY;
}
_interface->attach(_connection_status_cb);
}
return NSAPI_ERROR_OK;
}
nsapi_error_t Nanostack::WisunInterface::bringup(bool dhcp, const char *ip,
const char *netmask, const char *gw,
nsapi_ip_stack_t stack, bool blocking)
{
nanostack_lock();
if (register_phy() < 0) {
nanostack_unlock();
return NSAPI_ERROR_DEVICE_ERROR;
}
_blocking = blocking;
// After the RF is up, we can seed the random from it.
randLIB_seed_random();
mesh_error_t status = init();
if (status != MESH_ERROR_NONE) {
nanostack_unlock();
return map_mesh_error(status);
}
status = mesh_connect();
if (status != MESH_ERROR_NONE) {
nanostack_unlock();
return map_mesh_error(status);
}
// Release mutex before blocking
nanostack_unlock();
if (blocking) {
// wait connection for ever
int32_t count = connect_semaphore.wait(osWaitForever);
if (count <= 0) {
return NSAPI_ERROR_DHCP_FAILURE; // sort of...
}
}
return 0;
}
nsapi_error_t Nanostack::WisunInterface::bringdown()
{
NanostackLockGuard lock;
mesh_error_t status = mesh_disconnect();
return map_mesh_error(status);
}
mesh_error_t Nanostack::WisunInterface::init()
{
wisun_tasklet_init();
__mesh_handler_set_callback(this);
interface_id = wisun_tasklet_network_init(_device_id);
if (interface_id == -2) {
return MESH_ERROR_PARAM;
} else if (interface_id == -3) {
return MESH_ERROR_MEMORY;
} else if (interface_id < 0) {
return MESH_ERROR_UNKNOWN;
}
return MESH_ERROR_NONE;
}
mesh_error_t Nanostack::WisunInterface::mesh_connect()
{
int8_t status = -9; // init to unknown error
tr_debug("connect()");
status = wisun_tasklet_connect(&__mesh_handler_c_callback, interface_id);
if (status >= 0) {
return MESH_ERROR_NONE;
} else if (status == -1) {
return MESH_ERROR_PARAM;
} else if (status == -2) {
return MESH_ERROR_MEMORY;
} else if (status == -3) {
return MESH_ERROR_STATE;
} else {
return MESH_ERROR_UNKNOWN;
}
}
mesh_error_t Nanostack::WisunInterface::mesh_disconnect()
{
int8_t status = -1;
status = wisun_tasklet_disconnect(true);
if (status >= 0) {
return MESH_ERROR_NONE;
}
return MESH_ERROR_UNKNOWN;
}
char *Nanostack::WisunInterface::get_gateway(char *buf, nsapi_size_t buflen)
{
NanostackLockGuard lock;
if (wisun_tasklet_get_router_ip_address(buf, buflen) == 0) {
return buf;
}
return NULL;
}
bool WisunInterface::getRouterIpAddress(char *address, int8_t len)
{
return _interface->get_gateway(address, len);
}
#define WISUN 0x2345
#if MBED_CONF_NSAPI_DEFAULT_MESH_TYPE == WISUN && DEVICE_802_15_4_PHY
MBED_WEAK MeshInterface *MeshInterface::get_target_default_instance()
{
static WisunInterface wisun(&NanostackRfPhy::get_default_instance());
return &wisun;
}
#endif

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 2018 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __INCLUDE_WISUN_TASKLET__
#define __INCLUDE_WISUN_TASKLET__
#include "ns_types.h"
#include "eventOS_event.h"
#include "mbed-mesh-api/mesh_interface_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Type of the network status callback.
*/
typedef void (*mesh_interface_cb)(mesh_connection_status_t mesh_status);
/*
* \brief Read border router IP address
*
* \param address where router IP address will be written
* \param len length of provided address buffer
*
* \return 0 on success
* \return -1 if address reading fails
*/
int8_t wisun_tasklet_get_router_ip_address(char *address, int8_t len);
/*
* \brief Connect to mesh network
*
* \param callback to be called when network state changes
* \param nwk_interface_id to use for networking
*
* \return >= 0 on success
* \return -1 if callback function is used in another tasklet
* \return -2 if memory allocation fails
* \return -3 if network is already connected
*/
int8_t wisun_tasklet_connect(mesh_interface_cb callback, int8_t nwk_interface_id);
/*
* \brief Initialize mesh system.
* Memory pool, timers, traces and support are initialized.
*/
void wisun_tasklet_init(void);
/*
* \brief Create network interface.
*
* \param device_id registered physical device
* \return interface ID that can be used to communication with this interface
*/
int8_t wisun_tasklet_network_init(int8_t device_id);
/*
* \brief Disconnect network interface.
*
* \param send_cb send possible network status change event if set to true.
* \return >= 0 if disconnected successfully.
* \return < 0 in case of errors
*/
int8_t wisun_tasklet_disconnect(bool send_cb);
#ifdef __cplusplus
}
#endif
#endif /* __INCLUDE_WISUN_TASKLET__ */

View File

@ -0,0 +1,408 @@
/*
* Copyright (c) 2018 ARM Limited. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string.h> //memset
#include "eventOS_event_timer.h"
#include "common_functions.h"
#include "ip6string.h" //ip6tos
#include "nsdynmemLIB.h"
#include "include/wisun_tasklet.h"
#include "include/mesh_system.h"
#include "ns_event_loop.h"
#include "fhss_api.h"
#include "fhss_config.h"
#include "multicast_api.h"
#include "mac_api.h"
#include "sw_mac.h"
// For tracing we need to define flag, have include and define group
//#define HAVE_DEBUG
#define TRACE_GROUP "wisuND"
#include "ns_trace.h"
// Tasklet timer events
#define TIMER_EVENT_START_BOOTSTRAP 1
#define INVALID_INTERFACE_ID (-1)
#define INTERFACE_NAME "WiSunInterface"
/*
* Mesh tasklet states.
*/
typedef enum {
TASKLET_STATE_CREATED = 0,
TASKLET_STATE_INITIALIZED,
TASKLET_STATE_BOOTSTRAP_STARTED,
TASKLET_STATE_BOOTSTRAP_FAILED,
TASKLET_STATE_BOOTSTRAP_READY
} tasklet_state_t;
/*
* Mesh tasklet data structure.
*/
typedef struct {
void (*mesh_api_cb)(mesh_connection_status_t nwk_status);
channel_list_s channel_list;
tasklet_state_t tasklet_state;
int8_t tasklet;
net_6lowpan_mode_e operating_mode;
net_6lowpan_mode_extension_e operating_mode_extension;
int8_t network_interface_id;
uint8_t *mac;
} wisun_tasklet_data_str_t;
/* Tasklet data */
static wisun_tasklet_data_str_t *wisun_tasklet_data_ptr = NULL;
static mac_api_t *mac_api = NULL;
static char *network_name = MBED_CONF_MBED_MESH_API_WISUN_NETWORK_NAME;
extern fhss_timer_t fhss_functions;
/* private function prototypes */
static void wisun_tasklet_main(arm_event_s *event);
static void wisun_tasklet_network_state_changed(mesh_connection_status_t status);
static void wisun_tasklet_parse_network_event(arm_event_s *event);
static void wisun_tasklet_configure_and_connect_to_network(void);
//#define TRACE_WISUN_TASKLET
#ifndef TRACE_WISUN_TASKLET
#define wisun_tasklet_trace_bootstrap_info() ((void) 0)
#else
void wisun_tasklet_trace_bootstrap_info(void);
#endif
static void initialize_channel_list(void)
{
uint32_t channel = MBED_CONF_MBED_MESH_API_WISUN_ND_CHANNEL;
const int_fast8_t word_index = channel / 32;
const int_fast8_t bit_index = channel % 32;
memset(&wisun_tasklet_data_ptr->channel_list, 0, sizeof(wisun_tasklet_data_ptr->channel_list));
wisun_tasklet_data_ptr->channel_list.channel_page = (channel_page_e)MBED_CONF_MBED_MESH_API_WISUN_ND_CHANNEL_PAGE;
wisun_tasklet_data_ptr->channel_list.channel_mask[0] = MBED_CONF_MBED_MESH_API_WISUN_ND_CHANNEL_MASK;
if (channel > 0) {
memset(&wisun_tasklet_data_ptr->channel_list.channel_mask, 0, sizeof(wisun_tasklet_data_ptr->channel_list.channel_mask));
wisun_tasklet_data_ptr->channel_list.channel_mask[word_index] |= ((uint32_t) 1 << bit_index);
}
arm_nwk_set_channel_list(wisun_tasklet_data_ptr->network_interface_id, &wisun_tasklet_data_ptr->channel_list);
tr_debug("Channel: %ld", channel);
tr_debug("Channel page: %d", wisun_tasklet_data_ptr->channel_list.channel_page);
tr_debug("Channel mask: 0x%.8lx", wisun_tasklet_data_ptr->channel_list.channel_mask[word_index]);
}
/*
* \brief A function which will be eventually called by NanoStack OS when ever the OS has an event to deliver.
* @param event, describes the sender, receiver and event type.
*
* NOTE: Interrupts requested by HW are possible during this function!
*/
static void wisun_tasklet_main(arm_event_s *event)
{
arm_library_event_type_e event_type;
event_type = (arm_library_event_type_e) event->event_type;
switch (event_type) {
case ARM_LIB_NWK_INTERFACE_EVENT:
/* This event is delivered every and each time when there is new
* information of network connectivity.
*/
wisun_tasklet_parse_network_event(event);
break;
case ARM_LIB_TASKLET_INIT_EVENT:
/* Event with type EV_INIT is an initializer event of NanoStack OS.
* The event is delivered when the NanoStack OS is running fine.
* This event should be delivered ONLY ONCE.
*/
mesh_system_send_connect_event(wisun_tasklet_data_ptr->tasklet);
break;
case ARM_LIB_SYSTEM_TIMER_EVENT:
eventOS_event_timer_cancel(event->event_id, wisun_tasklet_data_ptr->tasklet);
if (event->event_id == TIMER_EVENT_START_BOOTSTRAP) {
tr_debug("Restart bootstrap");
wisun_tasklet_configure_and_connect_to_network();
}
break;
case APPLICATION_EVENT:
if (event->event_id == APPL_EVENT_CONNECT) {
wisun_tasklet_configure_and_connect_to_network();
}
break;
default:
break;
} // switch(event_type)
}
/**
* \brief Network state event handler.
* \param event show network start response or current network state.
*
* - ARM_NWK_BOOTSTRAP_READY: Save NVK persistent data to NVM and Net role
* - ARM_NWK_NWK_SCAN_FAIL: Link Layer Active Scan Fail, Stack is Already at Idle state
* - ARM_NWK_IP_ADDRESS_ALLOCATION_FAIL: No WS Router at current Channel Stack is Already at Idle state
* - ARM_NWK_NWK_CONNECTION_DOWN: Connection to Access point is lost wait for Scan Result
* - ARM_NWK_NWK_PARENT_POLL_FAIL: Host should run net start without any PAN-id filter and all channels
* - ARM_NWK_AUHTENTICATION_FAIL: Pana Authentication fail, Stack is Already at Idle state
*/
static void wisun_tasklet_parse_network_event(arm_event_s *event)
{
arm_nwk_interface_status_type_e status = (arm_nwk_interface_status_type_e) event->event_data;
tr_debug("app_parse_network_event() %d", status);
switch (status) {
case ARM_NWK_BOOTSTRAP_READY:
/* Network is ready and node is connected to Access Point */
if (wisun_tasklet_data_ptr->tasklet_state != TASKLET_STATE_BOOTSTRAP_READY) {
tr_info("Wi-SUN bootstrap ready");
wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_READY;
wisun_tasklet_trace_bootstrap_info();
wisun_tasklet_network_state_changed(MESH_CONNECTED);
}
break;
case ARM_NWK_NWK_SCAN_FAIL:
/* Link Layer Active Scan Fail, Stack is Already at Idle state */
tr_debug("Link Layer Scan Fail: No Beacons");
wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED;
wisun_tasklet_network_state_changed(MESH_BOOTSTRAP_FAILED);
break;
case ARM_NWK_IP_ADDRESS_ALLOCATION_FAIL:
/* No WS Router at current Channel Stack is Already at Idle state */
tr_debug("WS Scan/ GP REG fail");
wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED;
wisun_tasklet_network_state_changed(MESH_BOOTSTRAP_FAILED);
break;
case ARM_NWK_NWK_CONNECTION_DOWN:
/* Connection to Access point is lost wait for Scan Result */
tr_debug("WS/RPL scan new network");
wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED;
wisun_tasklet_network_state_changed(MESH_BOOTSTRAP_FAILED);
break;
case ARM_NWK_NWK_PARENT_POLL_FAIL:
wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED;
wisun_tasklet_network_state_changed(MESH_BOOTSTRAP_FAILED);
break;
case ARM_NWK_AUHTENTICATION_FAIL:
tr_debug("Network authentication fail");
wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED;
wisun_tasklet_network_state_changed(MESH_BOOTSTRAP_FAILED);
break;
default:
tr_warn("Unknown event %d", status);
break;
}
if (wisun_tasklet_data_ptr->tasklet_state != TASKLET_STATE_BOOTSTRAP_READY &&
wisun_tasklet_data_ptr->network_interface_id != INVALID_INTERFACE_ID) {
// Set 5s timer for new network scan
eventOS_event_timer_request(TIMER_EVENT_START_BOOTSTRAP,
ARM_LIB_SYSTEM_TIMER_EVENT,
wisun_tasklet_data_ptr->tasklet,
5000);
}
}
/*
* \brief Configure and establish network connection
*
*/
static void wisun_tasklet_configure_and_connect_to_network(void)
{
int8_t status;
fhss_timer_t *fhss_timer_ptr = &fhss_functions;
arm_nwk_interface_configure_6lowpan_bootstrap_set(
wisun_tasklet_data_ptr->network_interface_id,
wisun_tasklet_data_ptr->operating_mode,
wisun_tasklet_data_ptr->operating_mode_extension);
ws_management_node_init(wisun_tasklet_data_ptr->network_interface_id,
MBED_CONF_MBED_MESH_API_WISUN_REGULATOR_DOMAIN,
network_name,
fhss_timer_ptr);
// configure scan parameters
arm_nwk_6lowpan_link_scan_parameter_set(wisun_tasklet_data_ptr->network_interface_id, 5);
// configure scan channels
initialize_channel_list();
// Configure scan options (NULL disables filter)
arm_nwk_6lowpan_link_nwk_id_filter_for_nwk_scan(wisun_tasklet_data_ptr->network_interface_id, NULL);
arm_nwk_6lowpan_link_panid_filter_for_nwk_scan(
wisun_tasklet_data_ptr->network_interface_id,
MBED_CONF_MBED_MESH_API_WISUN_ND_PANID_FILTER);
// Enable MPL by default
const uint8_t all_mpl_forwarders[16] = {0xff, 0x03, [15] = 0xfc};
multicast_mpl_domain_subscribe(wisun_tasklet_data_ptr->network_interface_id,
all_mpl_forwarders,
MULTICAST_MPL_SEED_ID_DEFAULT,
NULL);
status = arm_nwk_interface_up(wisun_tasklet_data_ptr->network_interface_id);
if (status >= 0) {
wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_STARTED;
tr_info("Start Wi-SUN Bootstrap");
wisun_tasklet_network_state_changed(MESH_BOOTSTRAP_STARTED);
} else {
wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED;
tr_err("Bootstrap start failed, %d", status);
wisun_tasklet_network_state_changed(MESH_BOOTSTRAP_START_FAILED);
}
}
/*
* Inform application about network state change
*/
static void wisun_tasklet_network_state_changed(mesh_connection_status_t status)
{
if (wisun_tasklet_data_ptr->mesh_api_cb) {
(wisun_tasklet_data_ptr->mesh_api_cb)(status);
}
}
/*
* Trace bootstrap information.
*/
#ifdef TRACE_WISUN_TASKLET
void wisun_tasklet_trace_bootstrap_info()
{
network_layer_address_s app_nd_address_info;
link_layer_address_s app_link_address_info;
uint8_t temp_ipv6[16];
if (arm_nwk_nd_address_read(wisun_tasklet_data_ptr->network_interface_id, &app_nd_address_info) != 0) {
tr_error("WS Address read fail");
} else {
tr_debug("WS Access Point: %s", trace_ipv6(app_nd_address_info.border_router));
tr_debug("WS Prefix 64: %s", trace_array(app_nd_address_info.prefix, 8));
if (arm_net_address_get(wisun_tasklet_data_ptr->network_interface_id, ADDR_IPV6_GP, temp_ipv6) == 0) {
tr_debug("GP IPv6: %s", trace_ipv6(temp_ipv6));
}
}
if (arm_nwk_mac_address_read(wisun_tasklet_data_ptr->network_interface_id, &app_link_address_info) != 0) {
tr_error("MAC Address read fail\n");
} else {
uint8_t temp[2];
common_write_16_bit(app_link_address_info.mac_short, temp);
tr_debug("MAC 16-bit: %s", trace_array(temp, 2));
common_write_16_bit(app_link_address_info.PANId, temp);
tr_debug("PAN ID: %s", trace_array(temp, 2));
tr_debug("MAC 64-bit: %s", trace_array(app_link_address_info.mac_long, 8));
tr_debug("IID (Based on MAC 64-bit address): %s", trace_array(app_link_address_info.iid_eui64, 8));
}
tr_debug("Channel: %d", arm_net_get_current_channel(wisun_tasklet_data_ptr->network_interface_id));
}
#endif /* #define TRACE_WISUN_TASKLET */
/* Public functions */
int8_t wisun_tasklet_get_router_ip_address(char *address, int8_t len)
{
network_layer_address_s nd_address;
if ((len >= 40) && (0 == arm_nwk_nd_address_read(wisun_tasklet_data_ptr->network_interface_id, &nd_address))) {
ip6tos(nd_address.border_router, address);
tr_debug("Router IP address: %s", address);
return 0;
} else {
return -1;
}
}
int8_t wisun_tasklet_connect(mesh_interface_cb callback, int8_t nwk_interface_id)
{
int8_t re_connecting = true;
int8_t tasklet_id = wisun_tasklet_data_ptr->tasklet;
if (wisun_tasklet_data_ptr->network_interface_id != INVALID_INTERFACE_ID) {
return -3; // already connected to network
}
if (wisun_tasklet_data_ptr->tasklet_state == TASKLET_STATE_CREATED) {
re_connecting = false;
}
memset(wisun_tasklet_data_ptr, 0, sizeof(wisun_tasklet_data_ptr));
wisun_tasklet_data_ptr->mesh_api_cb = callback;
wisun_tasklet_data_ptr->network_interface_id = nwk_interface_id;
wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_INITIALIZED;
if (re_connecting == false) {
wisun_tasklet_data_ptr->tasklet = eventOS_event_handler_create(&wisun_tasklet_main,
ARM_LIB_TASKLET_INIT_EVENT);
if (wisun_tasklet_data_ptr->tasklet < 0) {
// -1 handler already used by other tasklet
// -2 memory allocation failure
return wisun_tasklet_data_ptr->tasklet;
}
} else {
wisun_tasklet_data_ptr->tasklet = tasklet_id;
mesh_system_send_connect_event(wisun_tasklet_data_ptr->tasklet);
}
return wisun_tasklet_data_ptr->tasklet;
}
int8_t wisun_tasklet_disconnect(bool send_cb)
{
int8_t status = -1;
if (wisun_tasklet_data_ptr != NULL) {
if (wisun_tasklet_data_ptr->network_interface_id != INVALID_INTERFACE_ID) {
status = arm_nwk_interface_down(wisun_tasklet_data_ptr->network_interface_id);
wisun_tasklet_data_ptr->network_interface_id = INVALID_INTERFACE_ID;
if (send_cb == true) {
wisun_tasklet_network_state_changed(MESH_DISCONNECTED);
}
}
wisun_tasklet_data_ptr->mesh_api_cb = NULL;
}
return status;
}
void wisun_tasklet_init(void)
{
if (wisun_tasklet_data_ptr == NULL) {
wisun_tasklet_data_ptr = ns_dyn_mem_alloc(sizeof(wisun_tasklet_data_str_t));
memset(wisun_tasklet_data_ptr, 0, sizeof(wisun_tasklet_data_str_t));
wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_CREATED;
wisun_tasklet_data_ptr->network_interface_id = INVALID_INTERFACE_ID;
wisun_tasklet_data_ptr->operating_mode = NET_6LOWPAN_ROUTER;
wisun_tasklet_data_ptr->operating_mode_extension = NET_6LOWPAN_WS;
}
}
int8_t wisun_tasklet_network_init(int8_t device_id)
{
// TODO, read interface name from configuration
mac_description_storage_size_t storage_sizes;
storage_sizes.device_decription_table_size = 32;
storage_sizes.key_description_table_size = 6;
storage_sizes.key_lookup_size = 1;
storage_sizes.key_usage_size = 3;
if (!mac_api) {
mac_api = ns_sw_mac_create(device_id, &storage_sizes);
}
return arm_nwk_interface_lowpan_init(mac_api, INTERFACE_NAME);
}

View File

@ -36,6 +36,7 @@ public:
class MeshInterface;
class LoWPANNDInterface;
class ThreadInterface;
class WisunInterface;
/* Implement OnboardNetworkStack method */
virtual nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out);

View File

@ -25,5 +25,5 @@
#include "ThreadInterface.h"
#include "NanostackEthernetInterface.h"
#include "MeshInterfaceNanostack.h"
#include "WisunInterface.h"
#endif /* NANOSTACK_INTERFACE_H_ */

View File

@ -0,0 +1,134 @@
/*
* Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string.h>
#include "nsconfig.h"
#include "ns_types.h"
#include "ns_trace.h"
#include <ns_list.h>
#include <nsdynmemLIB.h>
#include "NWK_INTERFACE/Include/protocol.h"
#include "6LoWPAN/ws/ws_common.h"
#include "ws_management_api.h"
#ifndef HAVE_WS
int ws_management_node_init(
int8_t interface_id,
uint8_t regulatory_domain,
char *network_name_ptr,
fhss_timer_t *fhss_timer_ptr)
{
(void)interface_id;
(void)regulatory_domain;
(void)network_name_ptr;
(void)fhss_timer_ptr;
return -1;
}
int ws_management_regulatory_domain_set(
int8_t interface_id,
uint8_t regulatory_domain,
uint8_t operating_class,
uint8_t operating_mode)
{
(void)interface_id;
(void)regulatory_domain;
(void)operating_class;
(void)operating_mode;
return -1;
}
int ws_management_channel_mask_set(
int8_t interface_id,
uint32_t channel_mask[8])
{
(void)interface_id;
(void)channel_mask;
return -1;
}
int ws_management_channel_plan_set(
int8_t interface_id,
uint8_t channel_plan,
uint8_t uc_channel_function,
uint8_t bc_channel_function,
uint32_t ch0_freq, // Stack can not modify this
uint8_t channel_spacing,// Stack can not modify this
uint8_t number_of_channels)
{
(void)interface_id;
(void)channel_plan;
(void)uc_channel_function;
(void)bc_channel_function;
(void)ch0_freq;
(void)channel_spacing;
(void)number_of_channels;
return -1;
}
int ws_management_fhss_timing_configure(
int8_t interface_id,
uint8_t fhss_uc_dwell_interval,
uint32_t fhss_broadcast_interval,
uint8_t fhss_bc_dwell_interval)
{
(void)interface_id;
(void)fhss_uc_dwell_interval;
(void)fhss_broadcast_interval;
(void)fhss_bc_dwell_interval;
return -1;
}
int ws_management_fhss_unicast_channel_function_configure(
int8_t interface_id,
uint8_t channel_function,
uint16_t fixed_channel,
uint8_t dwell_interval)
{
(void)interface_id;
(void)channel_function;
(void)fixed_channel;
(void)dwell_interval;
return -1;
}
int ws_management_fhss_broadcast_channel_function_configure(
int8_t interface_id,
uint8_t channel_function,
uint16_t fixed_channel,
uint8_t dwell_interval,
uint32_t broadcast_interval)
{
(void)interface_id;
(void)channel_function;
(void)fixed_channel;
(void)dwell_interval;
(void)broadcast_interval;
return -1;
}
/* ### test api ### */
int ws_test_pan_size_set(int8_t interface_id, uint16_t pan_size)
{
(void) interface_id;
(void) pan_size;
return -1;
}
#endif // no HAVE_WS

View File

@ -0,0 +1,233 @@
/*
* Copyright (c) 2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* \file ws_management_if.h
* \brief Wi-SUN management interface.
*
* This interface is used for configuring Wi-SUN devices.
* After creating the Wi-SUN interface, you can use this interface to configure the Wi-SUN device
* behaviour. When you are done with the configurations, you need to call interface up to enable a Wi-SUN node.
*
*/
#ifndef WS_MANAGEMENT_API_H_
#define WS_MANAGEMENT_API_H_
#include "ns_types.h"
#include "net_interface.h" /* Declaration for channel_list_s. */
#ifdef __cplusplus
extern "C" {
#endif
/* Regulatory domain values*/
#define REG_DOMAIN_WW 0x00 // World wide
#define REG_DOMAIN_NA 0x01 // North America
#define REG_DOMAIN_JP 0x02 // Japan
#define REG_DOMAIN_EU 0x03 // European Union
#define REG_DOMAIN_CH 0x04 // China
#define REG_DOMAIN_IN 0x05 // India
#define REG_DOMAIN_MX 0x06 //
#define REG_DOMAIN_BZ 0x07 // Brazil
#define REG_DOMAIN_AZ 0x08 // Australia
#define REG_DOMAIN_NZ 0x08 // New zealand
#define REG_DOMAIN_KR 0x09 // Korea
#define REG_DOMAIN_PH 0x0A //
#define REG_DOMAIN_MY 0x0B //
#define REG_DOMAIN_HK 0x0C //
#define REG_DOMAIN_SG 0x0D // band 866-869
#define REG_DOMAIN_TH 0x0E //
#define REG_DOMAIN_VN 0x0F //
#define REG_DOMAIN_SG_H 0x10 // band 920-925
#define OPERATING_MODE_1a 0x1a
#define OPERATING_MODE_1b 0x1b
#define OPERATING_MODE_2a 0x2a
#define OPERATING_MODE_2b 0x2b
#define OPERATING_MODE_3 0x03
#define OPERATING_MODE_4a 0x4a
#define OPERATING_MODE_4b 0x4b
#define OPERATING_MODE_5 0x05
#define CHANNEL_FUNCTION_FIXED 0x00 // Fixed channel
#define CHANNEL_FUNCTION_TR51CF 0x01 // TR51CF
#define CHANNEL_FUNCTION_DH1CF 0x02 // Direct Hash
#define CHANNEL_FUNCTION_VENDOR_DEFINED 0x03 // vendor given channel hop schedule
#define CHANNEL_SPACING_200 0x00 // 200 khz
#define CHANNEL_SPACING_400 0x01 // 400 khz
#define CHANNEL_SPACING_600 0x02 // 600 khz
#define CHANNEL_SPACING_100 0x03 // 100 khz
#define CHANNEL_SPACING_250 0x04 // 250 khz
/** Temporary API change flag. this will be removed when new version of API is implemented on applications
*
*/
#define WS_MANAGEMENT_API_VER_2
/**
* Initialize Wi-SUN stack.
*
* Generates the default configuration for Wi-SUN operation
*
* \param interface_id Network interface ID.
* \param regulatory_domain Mandatory regulatory domain value of the device.
* \param network_name_ptr Network name where to join if no configuration found from storage.
* \param fhss_timer_ptr FHSS functions for timer adaptation to platform.
*
* \return 0, Init OK.
* \return <0 Init fail.
*/
int ws_management_node_init(
int8_t interface_id,
uint8_t regulatory_domain,
char *network_name_ptr,
fhss_timer_t *fhss_timer_ptr);
/**
* Configure regulatory domain of Wi-SUN stack.
*
* Change the default configuration for Wi-SUN PHY operation.
*
* Supported values:
* Domain: "NA"(0x01), "KR"(0x09)
* Operating class: (1), (2)
* operation mode: "1b" (symbol rate 50, modulation index 1)
*
* if value of 255 is given then previous value is used.
*
* \param interface_id Network interface ID.
* \param regulatory_domain FHSS regulatory domain default to "KR" 0x09.
* \param operating_class FHSS operating class default to 1.
* \param operating_mode FHSS phy operating mode default to "1b".
*
* \return 0, Init OK.
* \return <0 Init fail.
*/
int ws_management_regulatory_domain_set(
int8_t interface_id,
uint8_t regulatory_domain,
uint8_t operating_class,
uint8_t operating_mode);
/**
* Set channel mask for FHSS operation.
*
* Default value: all channels are allowed.
*
* \param interface_id Network interface ID.
* \param channel_mask set bits matching the channel 1 to allow channel 0 to disallow.
*
* \return 0, Init OK.
* \return <0 Init fail.
*/
int ws_management_channel_mask_set(
int8_t interface_id,
uint32_t channel_mask[8]);
/**
* Configure Application defined channel plan.
*
* Change the application defined channel plan.
* This changes our channel plan that is reported to our children.
* PHY driver must be configured to follow these settings to make the configuration active.
*
*
* \param interface_id Network interface ID.
* \param channel_plan Channel plan must be 1 application defined if deviating from regulatory domain (0).
* \param uc_channel_function 0: Fixed channel, 1:TR51CF, 2: Direct Hash, 3: Vendor defined.
* \param bc_channel_function 0: Fixed channel, 1:TR51CF, 2: Direct Hash, 3: Vendor defined.
* \param ch0_freq ch0 center frequency.
* \param channel_spacing Channel spacing value 0:200k, 1:400k, 2:600k, 3:100k.
* \param number_of_channels FHSS phy operating mode default to "1b".
*
* \return 0, Init OK.
* \return <0 Init fail.
*/
int ws_management_channel_plan_set(
int8_t interface_id,
uint8_t channel_plan,
uint8_t uc_channel_function,
uint8_t bc_channel_function,
uint32_t ch0_freq, // Stack can not modify this
uint8_t channel_spacing,// Stack can not modify this
uint8_t number_of_channels);// Stack can not modify this
/**
* Configure timing values for FHSS.
*
* Change the default configuration for Wi-SUN FHSS operation.
*
* \param interface_id Network interface ID.
* \param fhss_uc_dwell_interval default to 250 ms.
* \param fhss_broadcast_interval default to 800 ms.
* \param fhss_bc_dwell_interval default to 200 ms.
*
* \return 0, Init OK.
* \return <0 Init fail.
*/
int ws_management_fhss_timing_configure(
int8_t interface_id,
uint8_t fhss_uc_dwell_interval,
uint32_t fhss_broadcast_interval,
uint8_t fhss_bc_dwell_interval);
/**
* Configure unicast channel function.
*
* Change the default configuration for Wi-SUN FHSS operation.
* if application defined is used the behaviour is undefined
*
* \param interface_id Network interface ID.
* \param channel_function Unicast channel function.
* \param fixed_channel Used channel when channel function is fixed channel. If 0xFFFF, randomly chosen channel is used.
* \param dwell_interval Used dwell interval when channel function is TR51 or DH1.
*
* \return 0, Init OK.
* \return <0 Init fail.
*/
int ws_management_fhss_unicast_channel_function_configure(
int8_t interface_id,
uint8_t channel_function,
uint16_t fixed_channel,
uint8_t dwell_interval);
/**
* Configure broadcast channel function.
*
* Change the default configuration for Wi-SUN FHSS operation.
* if application defined is used the behaviour is undefined
*
* \param interface_id Network interface ID.
* \param channel_function Broadcast channel function.
* \param fixed_channel Used channel when channel function is fixed channel. If 0xFFFF, randomly chosen channel is used.
* \param dwell_interval Broadcast channel dwell interval.
* \param broadcast_interval Broadcast interval.
*
* \return 0, Init OK.
* \return <0 Init fail.
*/
int ws_management_fhss_broadcast_channel_function_configure(
int8_t interface_id,
uint8_t channel_function,
uint16_t fixed_channel,
uint8_t dwell_interval,
uint32_t broadcast_interval);
#endif /* WS_MANAGEMENT_API_H_ */