Nanostack Border Router is a generic mbed border router implementation that provides the 6LoWPAN ND or Thread border router initialization logic.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers border_router_main.cpp Source File

border_router_main.cpp

00001 /*
00002  * Copyright (c) 2016-2019 ARM Limited. All rights reserved.
00003  */
00004 
00005 #include <string.h>
00006 
00007 
00008 #include "mbed.h"
00009 #include "borderrouter_tasklet.h"
00010 #include "drivers/eth_driver.h"
00011 #include "sal-stack-nanostack-slip/Slip.h"
00012 
00013 #include "Nanostack.h"
00014 #include "NanostackEthernetInterface.h"
00015 #include "MeshInterfaceNanostack.h"
00016 #include "EMACInterface.h"
00017 #include "EMAC.h"
00018 
00019 #undef ETH
00020 #undef SLIP
00021 #undef EMAC
00022 #undef CELL
00023 #define ETH 1
00024 #define SLIP 2
00025 #define EMAC 3
00026 #define CELL 4
00027 
00028 #if MBED_CONF_APP_BACKHAUL_DRIVER == CELL
00029 #include "NanostackPPPInterface.h"
00030 #include "PPPInterface.h"
00031 #include "PPP.h"
00032 #endif
00033 
00034 #ifdef  MBED_CONF_APP_DEBUG_TRACE
00035 #if MBED_CONF_APP_DEBUG_TRACE == 1
00036 #define APP_TRACE_LEVEL TRACE_ACTIVE_LEVEL_DEBUG
00037 #else
00038 #define APP_TRACE_LEVEL TRACE_ACTIVE_LEVEL_INFO
00039 #endif
00040 #endif //MBED_CONF_APP_DEBUG_TRACE
00041 
00042 #include "ns_hal_init.h"
00043 #include "mesh_system.h"
00044 #include "cmsis_os.h"
00045 #include "arm_hal_interrupt.h"
00046 #include "nanostack_heap_region.h"
00047 
00048 #include "mbed_trace.h"
00049 #define TRACE_GROUP "app"
00050 
00051 #define BOARD 1
00052 #define CONFIG 2
00053 #if MBED_CONF_APP_BACKHAUL_MAC_SRC == BOARD
00054 static uint8_t mac[6];
00055 #elif MBED_CONF_APP_BACKHAUL_MAC_SRC == CONFIG
00056 static const uint8_t mac[] = MBED_CONF_APP_BACKHAUL_MAC;
00057 #else
00058 #error "MAC address not defined"
00059 #endif
00060 
00061 static DigitalOut led1(MBED_CONF_APP_LED);
00062 
00063 static Ticker led_ticker;
00064 
00065 static void toggle_led1()
00066 {
00067     led1 = !led1;
00068 }
00069 
00070 /**
00071  * \brief Prints string to serial (adds CRLF).
00072  */
00073 static void trace_printer(const char *str)
00074 {
00075     printf("%s\n", str);
00076 }
00077 
00078 #if MBED_CONF_APP_BACKHAUL_DRIVER == EMAC
00079 static void (*emac_actual_cb)(uint8_t, int8_t);
00080 static int8_t emac_driver_id;
00081 static void emac_link_cb(bool up)
00082 {
00083     if (emac_actual_cb) {
00084         emac_actual_cb(up, emac_driver_id);
00085     }
00086 }
00087 #endif
00088 
00089 /**
00090  * \brief Initializes the MAC backhaul driver.
00091  * This function is called by the border router module.
00092  */
00093 void backhaul_driver_init(void (*backhaul_driver_status_cb)(uint8_t, int8_t))
00094 {
00095 // Values allowed in "backhaul-driver" option
00096 #if MBED_CONF_APP_BACKHAUL_DRIVER == SLIP
00097     SlipMACDriver *pslipmacdriver;
00098     int8_t slipdrv_id = -1;
00099 #if defined(MBED_CONF_APP_SLIP_HW_FLOW_CONTROL)
00100     pslipmacdriver = new SlipMACDriver(SERIAL_TX, SERIAL_RX, SERIAL_RTS, SERIAL_CTS);
00101 #else
00102     pslipmacdriver = new SlipMACDriver(SERIAL_TX, SERIAL_RX);
00103 #endif
00104 
00105     if (pslipmacdriver == NULL) {
00106         tr_error("Unable to create SLIP driver");
00107         return;
00108     }
00109 
00110     tr_info("Using SLIP backhaul driver...");
00111 
00112 #ifdef MBED_CONF_APP_SLIP_SERIAL_BAUD_RATE
00113     slipdrv_id = pslipmacdriver->Slip_Init(mac, MBED_CONF_APP_SLIP_SERIAL_BAUD_RATE);
00114 #else
00115     tr_warning("baud rate for slip not defined");
00116 #endif
00117 
00118     if (slipdrv_id >= 0) {
00119         backhaul_driver_status_cb(1, slipdrv_id);
00120         return;
00121     }
00122 
00123     tr_error("Backhaul driver init failed, retval = %d", slipdrv_id);
00124 #elif MBED_CONF_APP_BACKHAUL_DRIVER == EMAC
00125 #undef EMAC
00126     tr_info("Using EMAC backhaul driver...");
00127     NetworkInterface *net = NetworkInterface::get_default_instance();
00128     if (!net) {
00129         tr_error("Default network interface not found");
00130         exit(1);
00131     }
00132     EMACInterface *emacif = net->emacInterface();
00133     if (!emacif) {
00134         tr_error("Default interface is not EMAC-based");
00135         exit(1);
00136     }
00137     EMAC &emac = emacif->get_emac();
00138     Nanostack::EthernetInterface *ns_if;
00139 #if MBED_CONF_APP_BACKHAUL_MAC_SRC == BOARD
00140     /* Let the core code choose address - either from board or EMAC (for
00141      * ETH and SLIP we pass in the board address already in mac[]) */
00142     nsapi_error_t err = Nanostack::get_instance().add_ethernet_interface(emac, true, &ns_if);
00143     /* Read back what they chose into our mac[] */
00144     ns_if->get_mac_address(mac);
00145 #else
00146     nsapi_error_t err = Nanostack::get_instance().add_ethernet_interface(emac, true, &ns_if, mac);
00147 #endif
00148     if (err < 0) {
00149         tr_error("Backhaul driver init failed, retval = %d", err);
00150     } else {
00151         emac_actual_cb = backhaul_driver_status_cb;
00152         emac_driver_id = ns_if->get_driver_id();
00153         emac.set_link_state_cb(emac_link_cb);
00154     }
00155 #elif MBED_CONF_APP_BACKHAUL_DRIVER == CELL
00156     tr_info("Using CELLULAR backhaul driver...");
00157     /* Creates PPP service and onboard network stack already here for cellular
00158      * connection to be able to override the link state changed callback */
00159     PPP *ppp = &PPP::get_default_instance();
00160     if (!ppp) {
00161         tr_error("PPP not found");
00162         exit(1);
00163     }
00164     OnboardNetworkStack *stack = &OnboardNetworkStack::get_default_instance();
00165     if (!stack) {
00166         tr_error("Onboard network stack not found");
00167         exit(1);
00168     }
00169     OnboardNetworkStack::Interface *interface;
00170     if (stack->add_ppp_interface(*ppp, true, &interface) != NSAPI_ERROR_OK) {
00171         tr_error("Cannot add PPP interface");
00172         exit(1);
00173     }
00174     Nanostack::PPPInterface *ns_if = static_cast<Nanostack::PPPInterface *>(interface);
00175     ns_if->set_link_state_changed_callback(backhaul_driver_status_cb);
00176 
00177     // Cellular interface configures it to PPP service and onboard stack created above
00178     CellularInterface *net = CellularInterface::get_default_instance();
00179     if (!net) {
00180         tr_error("Default cellular interface not found");
00181         exit(1);
00182     }
00183     net->set_default_parameters(); // from cellular nsapi .json configuration
00184     net->set_blocking(false);
00185     if (net->connect() != NSAPI_ERROR_OK) {
00186         tr_error("Connect failure");
00187         exit(1);
00188     }
00189 #elif MBED_CONF_APP_BACKHAUL_DRIVER == ETH
00190     tr_info("Using ETH backhaul driver...");
00191     arm_eth_phy_device_register(mac, backhaul_driver_status_cb);
00192     return;
00193 #else
00194 #error "Unsupported backhaul driver"
00195 #endif
00196 #undef ETH
00197 #undef SLIP
00198 #undef EMAC
00199 #undef CELL
00200 }
00201 
00202 
00203 void appl_info_trace(void)
00204 {
00205     tr_info("Starting NanoStack Border Router...");
00206     tr_info("Build date: %s %s", __DATE__, __TIME__);
00207 #ifdef MBED_MAJOR_VERSION
00208     tr_info("Mbed OS: %d", MBED_VERSION);
00209 #endif
00210 
00211 #if defined(MBED_SYS_STATS_ENABLED)
00212     mbed_stats_sys_t stats;
00213     mbed_stats_sys_get(&stats);
00214 
00215     /* ARM = 1, GCC_ARM = 2, IAR = 3 */
00216     tr_info("Compiler ID: %d", stats.compiler_id);
00217     /* Compiler versions:
00218        ARM: PVVbbbb (P = Major; VV = Minor; bbbb = build number)
00219        GCC: VVRRPP  (VV = Version; RR = Revision; PP = Patch)
00220        IAR: VRRRPPP (V = Version; RRR = Revision; PPP = Patch)
00221     */
00222     tr_info("Compiler Version: %d", stats.compiler_version);
00223 #endif
00224 }
00225 
00226 /**
00227  * \brief The entry point for this application.
00228  * Sets up the application and starts the border router module.
00229  */
00230 int main()
00231 {
00232     mbed_trace_init(); // set up the tracing library
00233     mbed_trace_print_function_set(trace_printer);
00234     mbed_trace_config_set(TRACE_MODE_COLOR | APP_TRACE_LEVEL | TRACE_CARRIAGE_RETURN);
00235 
00236     // Have to let mesh_system do net_init_core in case we use
00237     // Nanostack::add_ethernet_interface()
00238     mesh_system_init();
00239 
00240     nanostack_heap_region_add();
00241 
00242 #if MBED_CONF_APP_BACKHAUL_MAC_SRC == BOARD
00243     mbed_mac_address((char *)mac);
00244 #endif
00245 
00246     if (MBED_CONF_APP_LED != NC) {
00247         led_ticker.attach_us(toggle_led1, 500000);
00248     }
00249     border_router_tasklet_start();
00250 }