
Nanostack Border Router is a generic mbed border router implementation that provides the 6LoWPAN ND or Thread border router initialization logic.
Revision 89:2f7ae1d76d7a, committed 2019-02-13
- Comitter:
- mbed_official
- Date:
- Wed Feb 13 18:38:23 2019 +0000
- Parent:
- 88:9eeeee1a17a2
- Child:
- 90:74901a61be61
- Commit message:
- Updating mbed-os to mbed-os-5.11.4 (#155)
.
Commit copied from https://github.com/ARMmbed/nanostack-border-router
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/configs/Wisun_Stm_s2lp_RF.json Wed Feb 13 18:38:23 2019 +0000 @@ -0,0 +1,67 @@ +{ + "config": { + "heap-size": { + "help": "The amount of static RAM to reserve for nsdynmemlib heap", + "value": 100000 + }, + "radio-type":{ + "help": "options are ATMEL, MCR20, SPIRIT1, S2LP", + "value": "S2LP" + }, + "backhaul-driver": { + "help": "options are ETH, SLIP, EMAC", + "value": "EMAC" + }, + "mesh-mode": { + "help": "Mesh networking mode. Options are LOWPAN_ND, LOWPAN_WS and THREAD", + "value": "LOWPAN_WS" + }, + "backhaul-mac-src": { + "help": "Where to get EUI48 address. Options are BOARD, CONFIG", + "value": "BOARD" + }, + "backhaul-mld": { + "help": "Enable proxying Multicast Listener Discovery messages to backhaul network", + "value": "false" + }, + "backhaul-mac": "{0x02, 0x00, 0x00, 0x00, 0x00, 0x01}", + "debug-trace": "false", + "backhaul-dynamic-bootstrap": true, + "backhaul-prefix": "fd00:db8:ff1::", + "backhaul-default-route": "::/0", + "backhaul-next-hop": "fe80::1", + "multicast-addr": "ff05::7", + "LED": "NC", + "SERIAL_TX": "NC", + "SERIAL_RX": "NC", + "SERIAL_CTS": "NC", + "SERIAL_RTS": "NC", + "uc-channel-function": 255, + "bc-channel-function": 255, + "regulatory-domain": 3, + "operating-class": 255, + "operating-mode": 255, + "uc-fixed-channel": "0xffff", + "bc-fixed-channel": "0xffff", + "network-name": "\"ARM-WS-TESTING\"" + }, + "target_overrides": { + "*": { + "target.network-default-interface-type": "ETHERNET", + "nsapi.default-stack": "NANOSTACK", + "mbed-trace.enable": 1, + "nanostack.configuration": "ws_border_router", + "platform.stdio-convert-newlines": true, + "platform.stdio-baud-rate": 115200, + "platform.stdio-buffered-serial": true + }, + "K64F": { + "kinetis-emac.tx-ring-len":4, + "kinetis-emac.rx-ring-len":4 + }, + "K66F": { + "kinetis-emac.tx-ring-len":4, + "kinetis-emac.rx-ring-len":4 + } + } +}
--- a/drivers/rf_wrapper.cpp Thu Jan 17 09:30:39 2019 +0000 +++ b/drivers/rf_wrapper.cpp Wed Feb 13 18:38:23 2019 +0000 @@ -8,7 +8,8 @@ #define ATMEL 0 #define MCR20 1 #define NCS36510 2 -#define SPIRIT1 3 +#define SPIRIT1 3 +#define S2LP 4 #if MBED_CONF_APP_RADIO_TYPE == ATMEL #include "NanostackRfPhyAtmel.h" @@ -20,7 +21,14 @@ #elif MBED_CONF_APP_RADIO_TYPE == SPIRIT1 #include "NanostackRfPhySpirit1.h" NanostackRfPhySpirit1 rf_phy(SPIRIT1_SPI_MOSI, SPIRIT1_SPI_MISO, SPIRIT1_SPI_SCLK, - SPIRIT1_DEV_IRQ, SPIRIT1_DEV_CS, SPIRIT1_DEV_SDN, SPIRIT1_BRD_LED); + SPIRIT1_DEV_IRQ, SPIRIT1_DEV_CS, SPIRIT1_DEV_SDN, SPIRIT1_BRD_LED); +#elif MBED_CONF_APP_RADIO_TYPE == S2LP +#include "NanostackRfPhys2lp.h" +NanostackRfPhys2lp rf_phy(S2LP_SPI_SDI, S2LP_SPI_SDO, S2LP_SPI_SCLK, S2LP_SPI_CS, S2LP_SPI_SDN, +#ifdef TEST_GPIOS_ENABLED + S2LP_SPI_TEST1, S2LP_SPI_TEST2, S2LP_SPI_TEST3, S2LP_SPI_TEST4, S2LP_SPI_TEST5, +#endif //TEST_GPIOS_ENABLED + S2LP_SPI_GPIO0, S2LP_SPI_GPIO1, S2LP_SPI_GPIO2, S2LP_SPI_GPIO3); #endif //MBED_CONF_APP_RADIO_TYPE extern "C" int8_t rf_device_register()
--- a/mbed-os.lib Thu Jan 17 09:30:39 2019 +0000 +++ b/mbed-os.lib Wed Feb 13 18:38:23 2019 +0000 @@ -1,1 +1,1 @@ -https://github.com/ARMmbed/mbed-os/#a8f0c33eaa2c52babff9655417c36f4b5edd54d7 +https://github.com/ARMmbed/mbed-os/#ecb3c8c837162c73537bd0f3592c6e2a42994045
--- a/source/borderrouter_tasklet.c Thu Jan 17 09:30:39 2019 +0000 +++ b/source/borderrouter_tasklet.c Wed Feb 13 18:38:23 2019 +0000 @@ -4,6 +4,7 @@ #define LOWPAN_ND 0 #define THREAD 1 +#define LOWPAN_WS 2 #if MBED_CONF_APP_MESH_MODE == LOWPAN_ND #include <string.h>
--- a/source/borderrouter_thread_tasklet.c Thu Jan 17 09:30:39 2019 +0000 +++ b/source/borderrouter_thread_tasklet.c Wed Feb 13 18:38:23 2019 +0000 @@ -4,6 +4,8 @@ #define LOWPAN_ND 0 #define THREAD 1 +#define LOWPAN_WS 2 + #if MBED_CONF_APP_MESH_MODE == THREAD #include <string.h>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/borderrouter_ws.c Wed Feb 13 18:38:23 2019 +0000 @@ -0,0 +1,601 @@ +/* + * Copyright (c) 2019 ARM Limited. All rights reserved. + */ + +#define LOWPAN_ND 0 +#define THREAD 1 +#define LOWPAN_WS 2 +#if MBED_CONF_APP_MESH_MODE == LOWPAN_WS + +#include <string.h> +#include <stdlib.h> +#include <mbed_assert.h> +#include "eventOS_event.h" +#include "eventOS_event_timer.h" +#include "eventOS_scheduler.h" +#include "platform/arm_hal_timer.h" +#include "borderrouter_tasklet.h" +#include "borderrouter_helpers.h" +#include "net_interface.h" +#include "rf_wrapper.h" +#include "fhss_api.h" +#include "fhss_config.h" +#include "ws_management_api.h" +#include "ws_bbr_api.h" +#include "ip6string.h" +#include "mac_api.h" +#include "ethernet_mac_api.h" +#include "sw_mac.h" +#include "nwk_stats_api.h" +#include "randLIB.h" + +#include "ns_trace.h" +#define TRACE_GROUP "brro" + +#define NR_BACKHAUL_INTERFACE_PHY_DRIVER_READY 2 +#define NR_BACKHAUL_INTERFACE_PHY_DOWN 3 +#define MESH_LINK_TIMEOUT 100 +#define MESH_METRIC 1000 + +#define WS_DEFAULT_REGULATORY_DOMAIN 255 +#define WS_DEFAULT_OPERATING_CLASS 255 +#define WS_DEFAULT_OPERATING_MODE 255 +#define WS_DEFAULT_UC_CHANNEL_FUNCTION 255 +#define WS_DEFAULT_BC_CHANNEL_FUNCTION 255 +#define WS_DEFAULT_UC_DWELL_INTERVAL 0 +#define WS_DEFAULT_BC_INTERVAL 0 +#define WS_DEFAULT_BC_DWELL_INTERVAL 0 +#define WS_DEFAULT_UC_FIXED_CHANNEL 0xffff +#define WS_DEFAULT_BC_FIXED_CHANNEL 0xffff + +static mac_api_t *mac_api; +static eth_mac_api_t *eth_mac_api; + +typedef enum { + STATE_UNKNOWN, + STATE_DISCONNECTED, + STATE_LINK_READY, + STATE_BOOTSTRAP, + STATE_CONNECTED, + STATE_MAX_VALUE +} connection_state_e; + +typedef struct { + int8_t prefix_len; + uint8_t prefix[16]; + uint8_t next_hop[16]; +} route_info_t; + +typedef struct { + int8_t ws_interface_id; + int8_t eth_interface_id; +} ws_br_handler_t; + +static ws_br_handler_t ws_br_handler; + +/* Backhaul prefix */ +static uint8_t backhaul_prefix[16] = {0}; + +/* Backhaul default route information */ +static route_info_t backhaul_route; +static int8_t br_tasklet_id = -1; + +/* Network statistics */ +static nwk_stats_t nwk_stats; + +/* Function forward declarations */ + +static void network_interface_event_handler(arm_event_s *event); +static void mesh_network_up(void); +static void eth_network_data_init(void); +static net_ipv6_mode_e backhaul_bootstrap_mode = NET_IPV6_BOOTSTRAP_STATIC; +static void borderrouter_tasklet(arm_event_s *event); +static int wisun_interface_up(void); +static void wisun_interface_event_handler(arm_event_s *event); +static void network_interface_event_handler(arm_event_s *event); +static int backhaul_interface_down(void); +static void borderrouter_backhaul_phy_status_cb(uint8_t link_up, int8_t driver_id); +extern fhss_timer_t fhss_functions; + +typedef struct { + char *network_name; + uint8_t regulatory_domain; + uint8_t operating_class; + uint8_t operating_mode; + uint8_t uc_channel_function; + uint8_t bc_channel_function; + uint8_t uc_dwell_interval; + uint32_t bc_interval; + uint8_t bc_dwell_interval; + uint16_t uc_fixed_channel; + uint16_t bc_fixed_channel; +} ws_config_t; +static ws_config_t ws_conf; + +static const char default_network_name[] = "ARM-WS-TESTING"; + +static void mesh_network_up() +{ + tr_debug("Create Mesh Interface"); + + int status; + int8_t wisun_if_id = ws_br_handler.ws_interface_id; + + status = arm_nwk_interface_configure_6lowpan_bootstrap_set( + wisun_if_id, + NET_6LOWPAN_BORDER_ROUTER, + NET_6LOWPAN_WS); + + if (status < 0) { + tr_error("arm_nwk_interface_configure_6lowpan_bootstrap_set() failed"); + return; + } + + status = wisun_interface_up(); + MBED_ASSERT(!status); + if (status) { + tr_error("wisun_interface_up() failed: %d", status); + } +} + +static void eth_network_data_init() +{ + memset(&backhaul_prefix[8], 0, 8); + + /* Bootstrap mode for the backhaul interface */ +#if MBED_CONF_APP_BACKHAUL_DYNAMIC_BOOTSTRAP == 1 + backhaul_bootstrap_mode = NET_IPV6_BOOTSTRAP_AUTONOMOUS; + tr_info("NET_IPV6_BOOTSTRAP_AUTONOMOUS"); + +#else + tr_info("NET_IPV6_BOOTSTRAP_STATIC"); + backhaul_bootstrap_mode = NET_IPV6_BOOTSTRAP_STATIC; + // done like this so that prefix can be left out in the dynamic case. + const char *param = MBED_CONF_APP_BACKHAUL_PREFIX; + stoip6(param, strlen(param), backhaul_prefix); + tr_info("backhaul_prefix: %s", print_ipv6(backhaul_prefix)); + + /* Backhaul route configuration*/ + memset(&backhaul_route, 0, sizeof(backhaul_route)); +#ifdef MBED_CONF_APP_BACKHAUL_NEXT_HOP + param = MBED_CONF_APP_BACKHAUL_NEXT_HOP; + stoip6(param, strlen(param), backhaul_route.next_hop); + tr_info("next hop: %s", print_ipv6(backhaul_route.next_hop)); +#endif + param = MBED_CONF_APP_BACKHAUL_DEFAULT_ROUTE; + char *prefix, route_buf[255] = {0}; + /* copy the config value to a non-const buffer */ + strncpy(route_buf, param, sizeof(route_buf) - 1); + prefix = strtok(route_buf, "/"); + backhaul_route.prefix_len = atoi(strtok(NULL, "/")); + stoip6(prefix, strlen(prefix), backhaul_route.prefix); + tr_info("backhaul route prefix: %s", print_ipv6(backhaul_route.prefix)); +#endif +} + +void load_config(void) +{ +#ifdef MBED_CONF_APP_NETWORK_NAME + ws_conf.network_name = malloc(sizeof(MBED_CONF_APP_NETWORK_NAME) + 1); + strcpy(ws_conf.network_name, MBED_CONF_APP_NETWORK_NAME); +#else + ws_conf.network_name = malloc(sizeof(default_network_name) + 1); + strcpy(ws_conf.network_name, default_network_name); +#endif //MBED_CONF_APP_NETWORK_NAME +#ifdef MBED_CONF_APP_REGULATORY_DOMAIN + ws_conf.regulatory_domain = MBED_CONF_APP_REGULATORY_DOMAIN; +#else + ws_conf.regulatory_domain = WS_DEFAULT_REGULATORY_DOMAIN; +#endif //MBED_CONF_APP_REGULATORY_DOMAIN +#ifdef MBED_CONF_APP_OPERATING_CLASS + ws_conf.operating_class = MBED_CONF_APP_OPERATING_CLASS; +#else + ws_conf.operating_class = WS_DEFAULT_OPERATING_CLASS; +#endif //MBED_CONF_APP_OPERATING_CLASS +#ifdef MBED_CONF_APP_OPERATING_MODE + ws_conf.operating_mode = MBED_CONF_APP_OPERATING_MODE; +#else + ws_conf.operating_mode = WS_DEFAULT_OPERATING_MODE; +#endif //MBED_CONF_APP_OPERATING_MODE +#ifdef MBED_CONF_APP_UC_CHANNEL_FUNCTION + ws_conf.uc_channel_function = MBED_CONF_APP_UC_CHANNEL_FUNCTION; +#else + ws_conf.uc_channel_function = WS_DEFAULT_UC_CHANNEL_FUNCTION; +#endif //MBED_CONF_APP_UC_CHANNEL_FUNCTION +#ifdef MBED_CONF_APP_BC_CHANNEL_FUNCTION + ws_conf.bc_channel_function = MBED_CONF_APP_BC_CHANNEL_FUNCTION; +#else + ws_conf.bc_channel_function = WS_DEFAULT_BC_CHANNEL_FUNCTION; +#endif //MBED_CONF_APP_UC_CHANNEL_FUNCTION +#ifdef MBED_CONF_APP_UC_DWELL_INTERVAL + ws_conf.uc_dwell_interval = MBED_CONF_APP_UC_DWELL_INTERVAL; +#else + ws_conf.uc_dwell_interval = WS_DEFAULT_UC_DWELL_INTERVAL; +#endif //MBED_CONF_APP_UC_DWELL_INTERVAL +#ifdef MBED_CONF_APP_BC_INTERVAL + ws_conf.bc_interval = MBED_CONF_APP_BC_INTERVAL; +#else + ws_conf.bc_interval = WS_DEFAULT_BC_INTERVAL; +#endif //MBED_CONF_APP_BC_INTERVAL +#ifdef MBED_CONF_APP_BC_DWELL_INTERVAL + ws_conf.bc_dwell_interval = MBED_CONF_APP_BC_DWELL_INTERVAL; +#else + ws_conf.bc_dwell_interval = WS_DEFAULT_BC_DWELL_INTERVAL; +#endif //MBED_CONF_APP_BC_DWELL_INTERVAL +// Using randomized fixed channel by default +#ifdef MBED_CONF_APP_UC_FIXED_CHANNEL + ws_conf.uc_fixed_channel = MBED_CONF_APP_UC_FIXED_CHANNEL; +#else + ws_conf.uc_fixed_channel = WS_DEFAULT_UC_FIXED_CHANNEL; +#endif //MBED_CONF_APP_UC_FIXED_CHANNEL +#ifdef MBED_CONF_APP_BC_FIXED_CHANNEL + ws_conf.bc_fixed_channel = MBED_CONF_APP_BC_FIXED_CHANNEL; +#else + ws_conf.bc_fixed_channel = WS_DEFAULT_BC_FIXED_CHANNEL; +#endif //MBED_CONF_APP_BC_FIXED_CHANNEL +} + +void wisun_rf_init() +{ + mac_description_storage_size_t storage_sizes; + storage_sizes.device_decription_table_size = 32; + storage_sizes.key_description_table_size = 4; + storage_sizes.key_lookup_size = 1; + storage_sizes.key_usage_size = 1; + + int8_t rf_driver_id = rf_device_register(); + MBED_ASSERT(rf_driver_id >= 0); + if (rf_driver_id >= 0) { + randLIB_seed_random(); + if (!mac_api) { + mac_api = ns_sw_mac_create(rf_driver_id, &storage_sizes); + } + + ws_br_handler.ws_interface_id = arm_nwk_interface_lowpan_init(mac_api, ws_conf.network_name); + + if (ws_br_handler.ws_interface_id < 0) { + tr_error("Wi-SUN interface creation failed"); + return; + } + + if (ws_br_handler.ws_interface_id > -1 && + ws_br_handler.eth_interface_id > -1) { + ws_bbr_start(ws_br_handler.ws_interface_id, ws_br_handler.eth_interface_id); + } + } +} + + +static int wisun_interface_up(void) +{ + int32_t ret; + + fhss_timer_t *fhss_timer_ptr = NULL; + + fhss_timer_ptr = &fhss_functions; + + ret = ws_management_node_init(ws_br_handler.ws_interface_id, ws_conf.regulatory_domain, ws_conf.network_name, fhss_timer_ptr); + if (0 != ret) { + tr_error("WS node init fail - code %"PRIi32"", ret); + return -1; + } + + if (ws_conf.uc_channel_function != WS_DEFAULT_UC_CHANNEL_FUNCTION) { + ret = ws_management_fhss_unicast_channel_function_configure(ws_br_handler.ws_interface_id, ws_conf.uc_channel_function, ws_conf.uc_fixed_channel, ws_conf.uc_dwell_interval); + if (ret != 0) { + tr_error("Unicast channel function configuration failed %"PRIi32"", ret); + return -1; + } + } + if (ws_conf.bc_channel_function != WS_DEFAULT_BC_CHANNEL_FUNCTION || + ws_conf.bc_dwell_interval != WS_DEFAULT_BC_DWELL_INTERVAL || + ws_conf.bc_interval != WS_DEFAULT_BC_INTERVAL) { + ret = ws_management_fhss_broadcast_channel_function_configure(ws_br_handler.ws_interface_id, ws_conf.bc_channel_function, ws_conf.bc_fixed_channel, ws_conf.bc_dwell_interval, ws_conf.bc_interval); + if (ret != 0) { + tr_error("Broadcast channel function configuration failed %"PRIi32"", ret); + return -1; + } + } + + if (ws_conf.uc_dwell_interval != WS_DEFAULT_UC_DWELL_INTERVAL || + ws_conf.bc_dwell_interval != WS_DEFAULT_BC_DWELL_INTERVAL || + ws_conf.bc_interval != WS_DEFAULT_BC_INTERVAL) { + ret = ws_management_fhss_timing_configure(ws_br_handler.ws_interface_id, ws_conf.uc_dwell_interval, ws_conf.bc_interval, ws_conf.bc_dwell_interval); + if (ret != 0) { + tr_error("fhss configuration failed %"PRIi32"", ret); + return -1; + } + } + if (ws_conf.regulatory_domain != WS_DEFAULT_REGULATORY_DOMAIN || + ws_conf.operating_mode != WS_DEFAULT_OPERATING_MODE || + ws_conf.operating_class != WS_DEFAULT_OPERATING_CLASS) { + ret = ws_management_regulatory_domain_set(ws_br_handler.ws_interface_id, ws_conf.regulatory_domain, ws_conf.operating_class, ws_conf.operating_mode); + if (ret != 0) { + tr_error("Regulatory domain configuration failed %"PRIi32"", ret); + return -1; + } + } + + ret = arm_nwk_interface_up(ws_br_handler.ws_interface_id); + if (ret != 0) { + tr_error("mesh0 up Fail with code: %"PRIi32"", ret); + return ret; + } + tr_info("mesh0 bootstrap ongoing.."); + return 0; +} + +void border_router_tasklet_start(void) +{ + ws_br_handler.ws_interface_id = -1; + ws_br_handler.eth_interface_id = -1; + + load_config(); + wisun_rf_init(); + protocol_stats_start(&nwk_stats); + + eventOS_event_handler_create( + &borderrouter_tasklet, + ARM_LIB_TASKLET_INIT_EVENT); +} + +static int backhaul_interface_up(int8_t driver_id) +{ + int retval = -1; + tr_debug("backhaul_interface_up: %i", driver_id); + if (ws_br_handler.eth_interface_id != -1) { + tr_debug("Border RouterInterface already at active state"); + return retval; + } + + if (!eth_mac_api) { + eth_mac_api = ethernet_mac_create(driver_id); + } + + ws_br_handler.eth_interface_id = arm_nwk_interface_ethernet_init(eth_mac_api, "bh0"); + + MBED_ASSERT(ws_br_handler.eth_interface_id >= 0); + if (ws_br_handler.eth_interface_id >= 0) { + tr_debug("Backhaul interface ID: %d", ws_br_handler.eth_interface_id); + if (ws_br_handler.ws_interface_id > -1) { + ws_bbr_start(ws_br_handler.ws_interface_id, ws_br_handler.eth_interface_id); + } + arm_nwk_interface_configure_ipv6_bootstrap_set( + ws_br_handler.eth_interface_id, backhaul_bootstrap_mode, backhaul_prefix); + arm_nwk_interface_up(ws_br_handler.eth_interface_id); + retval = 0; + } else { + tr_error("Could not init ethernet"); + } + + return retval; +} + +static int backhaul_interface_down(void) +{ + int retval = -1; + if (ws_br_handler.eth_interface_id != -1) { + arm_nwk_interface_down(ws_br_handler.eth_interface_id); + ws_br_handler.eth_interface_id = -1; + retval = 0; + } else { + tr_debug("Could not set eth down"); + } + return retval; +} + +static void print_interface_addr(int id) +{ + uint8_t address_buf[128]; + int address_count = 0; + char buf[128]; + + if (arm_net_address_list_get(id, 128, address_buf, &address_count) == 0) { + uint8_t *t_buf = address_buf; + for (int i = 0; i < address_count; ++i) { + ip6tos(t_buf, buf); + tr_info(" [%d] %s", i, buf); + t_buf += 16; + } + } +} + +#if MBED_CONF_APP_DEBUG_TRACE +static void print_interface_addresses(void) +{ + tr_info("Backhaul interface addresses:"); + print_interface_addr(ws_br_handler.eth_interface_id); + + tr_info("RF interface addresses:"); + print_interface_addr(ws_br_handler.ws_interface_id); +} +#endif + +/** + * \brief Border Router Main Tasklet + * + * Tasklet Handle next items: + * + * - EV_INIT event: Set Certificate Chain, RF Interface Boot UP, multicast Init + * - SYSTEM_TIMER event: For RF interface Handshake purpose + * + */ +static void borderrouter_tasklet(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: + + if (event->event_id == ws_br_handler.eth_interface_id) { + network_interface_event_handler(event); + } else { + wisun_interface_event_handler(event); + } + + break; + // comes from the backhaul_driver_init. + case APPLICATION_EVENT: + if (event->event_id == NR_BACKHAUL_INTERFACE_PHY_DRIVER_READY) { + int8_t net_backhaul_id = (int8_t) event->event_data; + + if (backhaul_interface_up(net_backhaul_id) != 0) { + tr_debug("Backhaul bootstrap start failed"); + } else { + tr_debug("Backhaul bootstrap started"); + } + } else if (event->event_id == NR_BACKHAUL_INTERFACE_PHY_DOWN) { + if (backhaul_interface_down() == 0) { + tr_debug("Backhaul interface is down"); + } + } + break; + + case ARM_LIB_TASKLET_INIT_EVENT: + br_tasklet_id = event->receiver; + eth_network_data_init(); + backhaul_driver_init(borderrouter_backhaul_phy_status_cb); + mesh_network_up(); + eventOS_event_timer_request(9, ARM_LIB_SYSTEM_TIMER_EVENT, br_tasklet_id, 20000); + break; + + case ARM_LIB_SYSTEM_TIMER_EVENT: + eventOS_event_timer_cancel(event->event_id, event->receiver); + + if (event->event_id == 9) { +#if MBED_CONF_APP_DEBUG_TRACE + arm_print_routing_table(); + arm_print_neigh_cache(); + print_memory_stats(); + // Trace interface addresses. This trace can be removed if nanostack prints added/removed + // addresses. + print_interface_addresses(); +#endif + eventOS_event_timer_request(9, ARM_LIB_SYSTEM_TIMER_EVENT, br_tasklet_id, 20000); + } + break; + + default: + break; + } +} + +static void borderrouter_backhaul_phy_status_cb(uint8_t link_up, int8_t driver_id) +{ + arm_event_s event = { + .sender = br_tasklet_id, + .receiver = br_tasklet_id, + .priority = ARM_LIB_MED_PRIORITY_EVENT, + .event_type = APPLICATION_EVENT, + .event_data = driver_id + }; + + if (link_up) { + event.event_id = NR_BACKHAUL_INTERFACE_PHY_DRIVER_READY; + } else { + event.event_id = NR_BACKHAUL_INTERFACE_PHY_DOWN; + } + + eventOS_event_send(&event); +} + +// ethernet interface +static void network_interface_event_handler(arm_event_s *event) +{ + arm_nwk_interface_status_type_e status = (arm_nwk_interface_status_type_e)event->event_data; + switch (status) { + case (ARM_NWK_BOOTSTRAP_READY): { // Interface configured Bootstrap is ready + + tr_info("BR interface_id: %d", ws_br_handler.eth_interface_id); + if (-1 != ws_br_handler.eth_interface_id) { + // metric set to high priority + if (0 != arm_net_interface_set_metric(ws_br_handler.eth_interface_id, 0)) { + tr_warn("Failed to set metric for eth0."); + } + + if (backhaul_bootstrap_mode == NET_IPV6_BOOTSTRAP_STATIC) { + uint8_t *next_hop_ptr; + + if (memcmp(backhaul_route.next_hop, (const uint8_t[16]) { + 0 + }, 16) == 0) { + next_hop_ptr = NULL; + } else { + next_hop_ptr = backhaul_route.next_hop; + } + tr_debug("Default route prefix: %s/%d", print_ipv6(backhaul_route.prefix), + backhaul_route.prefix_len); + tr_debug("Default route next hop: %s", print_ipv6(backhaul_route.next_hop)); + arm_net_route_add(backhaul_route.prefix, + backhaul_route.prefix_len, + next_hop_ptr, 0xffffffff, 128, + ws_br_handler.eth_interface_id); + } + tr_info("Backhaul interface addresses:"); + print_interface_addr(ws_br_handler.eth_interface_id); + } + break; + } + case (ARM_NWK_RPL_INSTANCE_FLOODING_READY): // RPL instance have been flooded + tr_info("RPL instance have been flooded"); + break; + case (ARM_NWK_SET_DOWN_COMPLETE): // Interface DOWN command successfully + break; + case (ARM_NWK_NWK_SCAN_FAIL): // Interface have not detect any valid network + tr_warning("mesh0 haven't detect any valid nwk"); + break; + case (ARM_NWK_IP_ADDRESS_ALLOCATION_FAIL): // IP address allocation fail(ND, DHCPv4 or DHCPv6) + tr_error("NO GP address detected"); + break; + case (ARM_NWK_DUPLICATE_ADDRESS_DETECTED): // User specific GP16 was not valid + tr_error("Ethernet IPv6 Duplicate addr detected!"); + break; + case (ARM_NWK_AUHTENTICATION_START_FAIL): // No valid Authentication server detected behind access point ; + tr_error("No valid ath server detected behind AP"); + break; + case (ARM_NWK_AUHTENTICATION_FAIL): // Network authentication fail by Handshake + tr_error("Network authentication fail"); + break; + case (ARM_NWK_NWK_CONNECTION_DOWN): // No connection between Access point or Default Router + tr_warning("Prefix timeout"); + break; + case (ARM_NWK_NWK_PARENT_POLL_FAIL): // Sleepy host poll fail 3 time + tr_warning("Parent poll fail"); + break; + case (ARM_NWK_PHY_CONNECTION_DOWN): // Interface PHY cable off or serial port interface not respond anymore + tr_error("eth0 down"); + break; + default: + tr_warning("Unknown nwk if event (type: %02x, id: %02x, data: %02x)", event->event_type, event->event_id, (unsigned int)event->event_data); + break; + } +} + +static void wisun_interface_event_handler(arm_event_s *event) +{ + arm_nwk_interface_status_type_e status = (arm_nwk_interface_status_type_e)event->event_data; + switch (status) { + case (ARM_NWK_BOOTSTRAP_READY): { // Interface configured Bootstrap is ready + tr_info("Wisun bootstrap ready"); + + if (arm_net_interface_set_metric(ws_br_handler.ws_interface_id, MESH_METRIC) != 0) { + tr_warn("Failed to set metric for mesh0."); + } + + tr_info("RF interface addresses:"); + print_interface_addr(ws_br_handler.ws_interface_id); + + break; + } + case (ARM_NWK_SET_DOWN_COMPLETE): + tr_info("Wisun interface down"); + break; + default: + tr_warning("Unknown nwk if event (type: %02x, id: %02x, data: %02x)", event->event_type, event->event_id, (unsigned int)event->event_data); + break; + } + +} + +#endif