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 borderrouter_tasklet.c Source File

borderrouter_tasklet.c

00001 /*
00002  * Copyright (c) 2016 ARM Limited. All rights reserved.
00003  */
00004 
00005 #define LOWPAN_ND 0
00006 #define THREAD 1
00007 #define LOWPAN_WS 2
00008 #if MBED_CONF_APP_MESH_MODE == LOWPAN_ND
00009 
00010 #include <string.h>
00011 #include <stdlib.h>
00012 #include "ns_types.h"
00013 #include "eventOS_event.h"
00014 #include "eventOS_event_timer.h"
00015 #include "eventOS_scheduler.h"
00016 #include "multicast_api.h"
00017 #include "whiteboard_api.h"
00018 #include "platform/arm_hal_timer.h"
00019 #include "borderrouter_tasklet.h"
00020 #include "borderrouter_helpers.h"
00021 #include "net_interface.h"
00022 #include "cfg_parser.h"
00023 #include "rf_wrapper.h"
00024 #include "nwk_stats_api.h"
00025 #include "net_interface.h"
00026 #include "ip6string.h"
00027 #include "net_rpl.h"
00028 #include "mac_api.h"
00029 #include "ethernet_mac_api.h"
00030 #include "sw_mac.h"
00031 
00032 #include "static_6lowpan_config.h"
00033 
00034 #include "ns_trace.h"
00035 #define TRACE_GROUP "brro"
00036 
00037 #define NR_BACKHAUL_INTERFACE_PHY_DRIVER_READY 2
00038 #define NR_BACKHAUL_INTERFACE_PHY_DOWN  3
00039 
00040 const uint8_t addr_unspecified[16] = {0};
00041 static mac_api_t *api;
00042 static eth_mac_api_t *eth_mac_api;
00043 
00044 /* The border router tasklet runs in grounded/non-storing mode */
00045 #define RPL_FLAGS RPL_GROUNDED | BR_DODAG_MOP_NON_STORING | RPL_DODAG_PREF(0)
00046 
00047 typedef enum interface_bootstrap_state {
00048     INTERFACE_IDLE_PHY_NOT_READY,
00049     INTERFACE_IDLE_STATE,
00050     INTERFACE_BOOTSTRAP_ACTIVE,
00051     INTERFACE_CONNECTED
00052 } interface_bootstrap_state_e;
00053 
00054 typedef struct {
00055     uint8_t DODAG_ID[16];
00056     uint8_t rpl_instance_id;
00057     uint8_t rpl_setups;
00058 } rpl_setup_info_t;
00059 
00060 typedef struct {
00061     int8_t prefix_len;
00062     uint8_t prefix[16];
00063     uint8_t next_hop[16];
00064 } route_info_t;
00065 
00066 /* Border router channel list */
00067 static channel_list_s channel_list;
00068 
00069 /* Channel masks for different RF types */
00070 static const uint32_t channel_mask_0_2_4ghz = 0x07fff800;
00071 
00072 /* Border router settings */
00073 static border_router_setup_s br;
00074 
00075 /* RPL routing settings */
00076 static rpl_setup_info_t rpl_setup_info;
00077 
00078 /* DODAG configuration */
00079 static dodag_config_t dodag_config;
00080 
00081 /* Backhaul prefix */
00082 static uint8_t backhaul_prefix[16] = {0};
00083 
00084 /* Backhaul default route information */
00085 static route_info_t backhaul_route;
00086 
00087 /* Should prefix on the backhaul used for PAN as well? */
00088 static uint8_t rf_prefix_from_backhaul = 0;
00089 
00090 static net_6lowpan_mode_e operating_mode = NET_6LOWPAN_BORDER_ROUTER;
00091 static net_6lowpan_mode_extension_e operating_mode_extension = NET_6LOWPAN_ND_WITH_MLE;
00092 static interface_bootstrap_state_e net_6lowpan_state = INTERFACE_IDLE_PHY_NOT_READY;
00093 static interface_bootstrap_state_e net_backhaul_state = INTERFACE_IDLE_PHY_NOT_READY;
00094 static net_ipv6_mode_e backhaul_bootstrap_mode = NET_IPV6_BOOTSTRAP_STATIC;
00095 
00096 static const uint8_t gp16_address_suffix[6] = {0x00, 0x00, 0x00, 0xff, 0xfe, 0x00};
00097 
00098 static int8_t br_tasklet_id = -1;
00099 static int8_t net_6lowpan_id = -1;
00100 static int8_t backhaul_if_id = -1;
00101 
00102 /* Network statistics */
00103 static nwk_stats_t nwk_stats;
00104 
00105 /* Link layer security information */
00106 static net_6lowpan_link_layer_sec_mode_e link_security_mode;
00107 static net_link_layer_psk_security_info_s link_layer_psk;
00108 static net_tls_cipher_e pana_security_suite;
00109 
00110 static uint8_t multicast_addr[16] = {0};
00111 
00112 /* Function forward declarations */
00113 static void app_parse_network_event(arm_event_s *event);
00114 static void borderrouter_tasklet(arm_event_s *event);
00115 static void initialize_channel_list(uint32_t channel);
00116 static void start_6lowpan(const uint8_t *backhaul_address);
00117 static int8_t rf_interface_init(void);
00118 static void load_config(void);
00119 
00120 void border_router_tasklet_start(void)
00121 {
00122     /* initialize Radio module*/
00123     net_6lowpan_id = rf_interface_init();
00124 
00125     load_config();
00126 
00127     protocol_stats_start(&nwk_stats);
00128 
00129     eventOS_event_handler_create(
00130         &borderrouter_tasklet,
00131         ARM_LIB_TASKLET_INIT_EVENT);
00132 }
00133 
00134 static void print_interface_addr(int id)
00135 {
00136     uint8_t address_buf[128];
00137     int address_count = 0;
00138     char buf[128];
00139 
00140     if (arm_net_address_list_get(id, 128, address_buf, &address_count) == 0) {
00141         uint8_t *t_buf = address_buf;
00142         for (int i = 0; i < address_count; ++i) {
00143             ip6tos(t_buf, buf);
00144             tr_info("   [%d] %s", i, buf);
00145             t_buf += 16;
00146         }
00147     }
00148 }
00149 
00150 static void initialize_channel_list(uint32_t channel)
00151 {
00152     const int_fast8_t word_index = channel / 32;
00153     const int_fast8_t bit_index = channel % 32;
00154 
00155     if (channel > 0) {
00156         /* Zero channel value means listen all channels */
00157         memset(&channel_list.channel_mask, 0, sizeof(channel_list.channel_mask));
00158         channel_list.channel_mask[word_index] |= ((uint32_t) 1 << bit_index);
00159     }
00160 }
00161 
00162 static void load_config(void)
00163 {
00164     const char *prefix, *psk;
00165     uint8_t nd_prefix[16];
00166 
00167     prefix = cfg_string(global_config, "PREFIX", NULL);
00168 
00169     if (!prefix) {
00170         tr_error("No RF prefix in configuration!");
00171         return;
00172     }
00173 
00174     stoip6(prefix, strlen(prefix), nd_prefix);
00175 
00176     prefix = cfg_string(global_config, "BACKHAUL_PREFIX", NULL);
00177     if (!prefix) {
00178         tr_error("No backhaul prefix in configuration!");
00179         return;
00180     }
00181 
00182     stoip6(prefix, strlen(prefix), backhaul_prefix);
00183     memset(&backhaul_prefix[8], 0, 8);
00184 
00185     prefix = cfg_string(global_config, "MULTICAST_ADDR", NULL);
00186     if (!prefix) {
00187         tr_error("No multicast address in configuration!");
00188         return;
00189     }
00190 
00191     stoip6(prefix, strlen(prefix), multicast_addr);
00192 
00193     /* Set up channel page and channgel mask */
00194     memset(&channel_list, 0, sizeof(channel_list));
00195     channel_list.channel_page = (channel_page_e)cfg_int(global_config, "RF_CHANNEL_PAGE", CHANNEL_PAGE_0);
00196     channel_list.channel_mask[0] = cfg_int(global_config, "RF_CHANNEL_MASK", channel_mask_0_2_4ghz);
00197 
00198     prefix = cfg_string(global_config, "NETWORK_ID", "NETWORK000000000");
00199     memcpy(br.network_id, prefix, 16);
00200 
00201     br.mac_panid = cfg_int(global_config, "PAN_ID", 0x0691);
00202     tr_info("PANID: %x", br.mac_panid);
00203     br.mac_short_adr = cfg_int(global_config, "SHORT_MAC_ADDRESS", 0xffff);
00204     br.ra_life_time = cfg_int(global_config, "RA_ROUTER_LIFETIME", 1024);
00205     br.beacon_protocol_id = cfg_int(global_config, "BEACON_PROTOCOL_ID", 4);
00206 
00207     memcpy(br.lowpan_nd_prefix, nd_prefix, 8);
00208     br.abro_version_num = 0;
00209 
00210     /* RPL routing setup */
00211     rpl_setup_info.rpl_instance_id = cfg_int(global_config, "RPL_INSTANCE_ID", 1);
00212     rpl_setup_info.rpl_setups = RPL_FLAGS;
00213 
00214     /* generate DODAG ID */
00215     memcpy(rpl_setup_info.DODAG_ID, nd_prefix, 8);
00216     if (br.mac_short_adr < 0xfffe) {
00217         memcpy(&rpl_setup_info.DODAG_ID[8], gp16_address_suffix, 6);
00218         rpl_setup_info.DODAG_ID[14] = (br.mac_short_adr >> 8);
00219         rpl_setup_info.DODAG_ID[15] = br.mac_short_adr;
00220     } else {
00221         rf_read_mac_address(&rpl_setup_info.DODAG_ID[8]);
00222         rpl_setup_info.DODAG_ID[8] ^= 2;
00223     }
00224 
00225     /* DODAG configuration */
00226     dodag_config.DAG_DIO_INT_DOUB = cfg_int(global_config, "RPL_IDOUBLINGS", 12);
00227     dodag_config.DAG_DIO_INT_MIN = cfg_int(global_config, "RPL_IMIN", 9);
00228     dodag_config.DAG_DIO_REDU = cfg_int(global_config, "RPL_K", 10);
00229     dodag_config.DAG_MAX_RANK_INC = cfg_int(global_config, "RPL_MAX_RANK_INC", 2048);
00230     dodag_config.DAG_MIN_HOP_RANK_INC = cfg_int(global_config, "RPL_MIN_HOP_RANK_INC", 128);
00231     dodag_config.LIFE_IN_SECONDS = cfg_int(global_config, "RPL_LIFETIME_UNIT", 64);
00232     dodag_config.LIFETIME_UNIT = cfg_int(global_config, "RPL_DEFAULT_LIFETIME", 60);
00233     dodag_config.DAG_SEC_PCS = cfg_int(global_config, "RPL_PCS", 1);
00234     dodag_config.DAG_OCP = cfg_int(global_config, "RPL_OCP", 1);
00235 
00236     bool dynamic_bootstrap = (net_ipv6_mode_e)cfg_int(global_config, "BACKHAUL_DYNAMIC_BOOTSTRAP", 0);
00237 
00238     if (dynamic_bootstrap == 1) {
00239         backhaul_bootstrap_mode = NET_IPV6_BOOTSTRAP_AUTONOMOUS;
00240         tr_info("NET_IPV6_BOOTSTRAP_AUTONOMOUS");
00241     } else {
00242         tr_info("NET_IPV6_BOOTSTRAP_STATIC");
00243         backhaul_bootstrap_mode = NET_IPV6_BOOTSTRAP_STATIC;
00244     }
00245 
00246     /* Bootstrap mode for the backhaul interface */
00247     rf_prefix_from_backhaul = cfg_int(global_config, "PREFIX_FROM_BACKHAUL", 0);
00248 
00249     /* Backhaul default route */
00250     memset(&backhaul_route, 0, sizeof(backhaul_route));
00251     psk = cfg_string(global_config, "BACKHAUL_NEXT_HOP", NULL);
00252 
00253     if (psk) {
00254         stoip6(psk, strlen(psk), backhaul_route.next_hop);
00255     }
00256 
00257     psk = cfg_string(global_config, "BACKHAUL_DEFAULT_ROUTE", NULL);
00258 
00259     if (psk) {
00260         char *prefix, route_buf[255] = {0};
00261 
00262         /* copy the config value to a non-const buffer */
00263         strncpy(route_buf, psk, sizeof(route_buf) - 1);
00264         prefix = strtok(route_buf, "/");
00265         backhaul_route.prefix_len = atoi(strtok(NULL, "/"));
00266 
00267         stoip6(prefix, strlen(prefix), backhaul_route.prefix);
00268     }
00269 
00270     prefix = cfg_string(global_config, "SECURITY_MODE", "NONE");
00271 
00272     if (strcmp(prefix, "NONE") == 0) {
00273         link_security_mode = NET_SEC_MODE_NO_LINK_SECURITY;
00274         tr_warn("Security NOT enabled");
00275         return;
00276     }
00277 
00278     psk = cfg_string(global_config, "PSK_KEY", NULL);
00279 
00280     if (!psk) {
00281         tr_error("No PSK set in configuration!");
00282         return;
00283     }
00284 
00285     link_layer_psk.key_id = cfg_int(global_config, "PSK_KEY_ID", 1);
00286     memcpy(link_layer_psk.security_key, psk, 16);
00287 
00288     if (strcmp(prefix, "PSK") == 0) {
00289         tr_debug("Using PSK security mode, key ID = %d", link_layer_psk.key_id);
00290         link_security_mode = NET_SEC_MODE_PSK_LINK_SECURITY;
00291     } else if (strcmp(prefix, "PANA") == 0) {
00292         const char *mode = cfg_string(global_config, "PANA_MODE", "PSK");
00293         link_security_mode = NET_SEC_MODE_PANA_LINK_SECURITY;
00294         if (strcmp(mode, "ECC") == 0) {
00295             pana_security_suite = NET_TLS_ECC_CIPHER;
00296         } else if (strcmp(mode, "ECC+PSK") == 0) {
00297             pana_security_suite = NET_TLS_PSK_AND_ECC_CIPHER;
00298         } else {
00299             pana_security_suite = NET_TLS_PSK_CIPHER;
00300         }
00301     }
00302 }
00303 
00304 static int8_t rf_interface_init(void)
00305 {
00306     static char phy_name[] = "mesh0";
00307     int8_t rfid = -1;
00308     int8_t rf_phy_device_register_id = rf_device_register();
00309     tr_debug("RF device ID: %d", rf_phy_device_register_id);
00310 
00311     if (rf_phy_device_register_id >= 0) {
00312         mac_description_storage_size_t storage_sizes;
00313         storage_sizes.device_decription_table_size = 32;
00314         storage_sizes.key_description_table_size = 3;
00315         storage_sizes.key_lookup_size = 1;
00316         storage_sizes.key_usage_size = 3;
00317         if (!api) {
00318             api = ns_sw_mac_create(rf_phy_device_register_id, &storage_sizes);
00319         }
00320         rfid = arm_nwk_interface_lowpan_init(api, phy_name);
00321         tr_debug("RF interface ID: %d", rfid);
00322     }
00323 
00324     return rfid;
00325 }
00326 
00327 static void borderrouter_backhaul_phy_status_cb(uint8_t link_up, int8_t driver_id)
00328 {
00329     arm_event_s event = {
00330         .sender = br_tasklet_id,
00331         .receiver = br_tasklet_id,
00332         .priority = ARM_LIB_MED_PRIORITY_EVENT,
00333         .event_type = APPLICATION_EVENT,
00334         .event_id = NR_BACKHAUL_INTERFACE_PHY_DOWN,
00335         .event_data = driver_id
00336     };
00337 
00338     if (link_up) {
00339         event.event_id = NR_BACKHAUL_INTERFACE_PHY_DRIVER_READY;
00340     }
00341 
00342     eventOS_event_send(&event);
00343 }
00344 
00345 static int backhaul_interface_up(int8_t driver_id)
00346 {
00347     int retval = -1;
00348     if (backhaul_if_id != -1) {
00349         tr_debug("Border RouterInterface already at active state\n");
00350     } else {
00351         if (!eth_mac_api) {
00352             eth_mac_api = ethernet_mac_create(driver_id);
00353         }
00354 
00355         backhaul_if_id = arm_nwk_interface_ethernet_init(eth_mac_api, "bh0");
00356 
00357         if (backhaul_if_id >= 0) {
00358             tr_debug("Backhaul interface ID: %d", backhaul_if_id);
00359             if (memcmp(backhaul_prefix, addr_unspecified, 8) == 0) {
00360                 memcpy(backhaul_prefix, rpl_setup_info.DODAG_ID, 8);
00361             }
00362             arm_nwk_interface_configure_ipv6_bootstrap_set(
00363                 backhaul_if_id, backhaul_bootstrap_mode, backhaul_prefix);
00364             arm_nwk_interface_up(backhaul_if_id);
00365             retval = 0;
00366         }
00367     }
00368     return retval;
00369 }
00370 
00371 static int backhaul_interface_down(void)
00372 {
00373     int retval = -1;
00374     if (backhaul_if_id != -1) {
00375         arm_nwk_interface_down(backhaul_if_id);
00376         backhaul_if_id = -1;
00377         retval = 0;
00378     }
00379     return retval;
00380 }
00381 
00382 /**
00383   * \brief Border Router Main Tasklet
00384   *
00385   *  Tasklet Handle next items:
00386   *
00387   *  - EV_INIT event: Set Certificate Chain, RF Interface Boot UP, multicast Init
00388   *  - SYSTEM_TIMER event: For RF interface Handshake purpose
00389   *
00390   */
00391 static void borderrouter_tasklet(arm_event_s *event)
00392 {
00393     arm_library_event_type_e event_type;
00394     event_type = (arm_library_event_type_e)event->event_type;
00395 
00396     switch (event_type) {
00397         case ARM_LIB_NWK_INTERFACE_EVENT:
00398             app_parse_network_event(event);
00399             break;
00400 
00401         case APPLICATION_EVENT:
00402             if (event->event_id == NR_BACKHAUL_INTERFACE_PHY_DRIVER_READY) {
00403                 int8_t net_backhaul_id = (int8_t) event->event_data;
00404                 if (net_backhaul_state == INTERFACE_IDLE_PHY_NOT_READY) {
00405                     net_backhaul_state = INTERFACE_IDLE_STATE;
00406                 }
00407 
00408                 tr_debug("Backhaul driver ID: %d", net_backhaul_id);
00409 
00410                 if (backhaul_interface_up(net_backhaul_id) != 0) {
00411                     tr_debug("Backhaul bootstrap start failed");
00412                 } else {
00413                     tr_debug("Backhaul bootstrap started");
00414                     net_backhaul_state = INTERFACE_BOOTSTRAP_ACTIVE;
00415                 }
00416             } else if (event->event_id == NR_BACKHAUL_INTERFACE_PHY_DOWN) {
00417                 tr_debug("Backhaul driver ID: %d", (int8_t) event->event_data);
00418                 if (backhaul_interface_down() != 0) {
00419                     tr_error("Backhaul interface down failed");
00420                 } else {
00421                     tr_debug("Backhaul interface is down");
00422                     backhaul_if_id = -1;
00423                     net_backhaul_state = INTERFACE_IDLE_STATE;
00424                 }
00425             }
00426             break;
00427 
00428         case ARM_LIB_TASKLET_INIT_EVENT:
00429             appl_info_trace();
00430             br_tasklet_id = event->receiver;
00431 
00432             /* initialize the backhaul interface */
00433             backhaul_driver_init(borderrouter_backhaul_phy_status_cb);
00434 
00435             if (net_6lowpan_id < 0) {
00436                 tr_error("RF interface initialization failed");
00437                 return;
00438             }
00439             net_6lowpan_state = INTERFACE_IDLE_STATE;
00440             eventOS_event_timer_request(9, ARM_LIB_SYSTEM_TIMER_EVENT, br_tasklet_id, 20000);
00441             break;
00442 
00443         case ARM_LIB_SYSTEM_TIMER_EVENT:
00444             eventOS_event_timer_cancel(event->event_id, event->receiver);
00445 
00446             if (event->event_id == 9) {
00447 #ifdef MBED_CONF_APP_DEBUG_TRACE
00448 #if MBED_CONF_APP_DEBUG_TRACE == 1
00449                 arm_print_routing_table();
00450                 arm_print_neigh_cache();
00451                 print_memory_stats();
00452 #endif
00453 #endif
00454                 eventOS_event_timer_request(9, ARM_LIB_SYSTEM_TIMER_EVENT, br_tasklet_id, 20000);
00455             }
00456             break;
00457 
00458         default:
00459             break;
00460     }
00461 }
00462 
00463 static void start_6lowpan(const uint8_t *backhaul_address)
00464 {
00465     uint8_t p[16] = {0};
00466 
00467     if (arm_net_address_get(backhaul_if_id, ADDR_IPV6_GP, p) == 0) {
00468         uint32_t lifetime = 0xffffffff; // infinite
00469         uint8_t prefix_len = 0;
00470         uint8_t t_flags = 0;
00471         int8_t retval = -1;
00472 
00473         /* Channel list: listen to a channel (default: all channels) */
00474         uint32_t channel = cfg_int(global_config, "RF_CHANNEL", 0);
00475         tr_info("RF channel: %d", (int)channel);
00476         initialize_channel_list(channel);
00477 
00478         // configure as border router and set the operation mode
00479         retval = arm_nwk_interface_configure_6lowpan_bootstrap_set(net_6lowpan_id,
00480                                                                    operating_mode, operating_mode_extension);
00481 
00482         if (retval < 0) {
00483             tr_error("Configuring 6LoWPAN bootstrap failed, retval = %d", retval);
00484             return;
00485         }
00486 
00487         retval = arm_nwk_link_layer_security_mode(net_6lowpan_id, link_security_mode, 5, &link_layer_psk);
00488 
00489         if (retval < 0) {
00490             tr_error("Failed to set link layer security mode, retval = %d", retval);
00491             return;
00492         }
00493 
00494         /* Should we use the backhaul prefix on the PAN as well? */
00495         if (backhaul_address && rf_prefix_from_backhaul) {
00496             memcpy(br.lowpan_nd_prefix, p, 8);
00497             memcpy(rpl_setup_info.DODAG_ID, br.lowpan_nd_prefix, 8);
00498         }
00499 
00500         retval = arm_nwk_6lowpan_border_router_init(net_6lowpan_id, &br);
00501 
00502         if (retval < 0) {
00503             tr_error("Initializing 6LoWPAN border router failed, retval = %d", retval);
00504             return;
00505         }
00506 
00507         /* configure both /64 and /128 context prefixes */
00508         retval = arm_nwk_6lowpan_border_router_context_update(net_6lowpan_id, ((1 << 4) | 0x03),
00509                                                               128, 0xffff, rpl_setup_info.DODAG_ID);
00510 
00511         if (retval < 0) {
00512             tr_error("Setting ND context failed, retval = %d", retval);
00513             return;
00514         }
00515 
00516         // configure the RPL routing protocol for the 6LoWPAN mesh network
00517         if (arm_nwk_6lowpan_rpl_dodag_init(net_6lowpan_id, rpl_setup_info.DODAG_ID,
00518                                            &dodag_config, rpl_setup_info.rpl_instance_id,
00519                                            rpl_setup_info.rpl_setups) == 0) {
00520             prefix_len = 64;
00521             t_flags = RPL_PREFIX_ROUTER_ADDRESS_FLAG;
00522             /* add "/64" prefix with the full BR address (DODAG ID) */
00523             arm_nwk_6lowpan_rpl_dodag_prefix_update(net_6lowpan_id, rpl_setup_info.DODAG_ID,
00524                                                     prefix_len, t_flags, lifetime);
00525 
00526             t_flags = 0;
00527             prefix_len = 0;
00528             /* add default route "::/0" */
00529             arm_nwk_6lowpan_rpl_dodag_route_update(net_6lowpan_id, rpl_setup_info.DODAG_ID,
00530                                                    prefix_len, t_flags, lifetime);
00531         }
00532 
00533         if (link_security_mode == NET_SEC_MODE_PANA_LINK_SECURITY) {
00534             uint8_t *psk = (uint8_t *)cfg_string(global_config, "TLS_PSK_KEY", NULL);
00535 
00536             if (!psk) {
00537                 tr_error("No TLS PSK key set in configuration");
00538                 return;
00539             }
00540 
00541             if (arm_tls_add_psk_key(psk, cfg_int(global_config, "TLS_PSK_KEY_ID", 0)) != 0) {
00542                 tr_error("No TLS PSK key ID set in configuration");
00543                 return;
00544             }
00545 
00546             retval = arm_pana_server_library_init(net_6lowpan_id, pana_security_suite, NULL, 120);
00547 
00548             if (retval) {
00549                 tr_error("Failed to initialize PANA server library, retval = %d", retval);
00550                 return;
00551             }
00552         }
00553 
00554         retval = arm_nwk_set_channel_list(net_6lowpan_id, &channel_list);
00555 
00556         if (retval) {
00557             tr_error("Failed to set channel list, retval = %d", retval);
00558             return;
00559         }
00560 
00561         retval = arm_nwk_interface_up(net_6lowpan_id);
00562 
00563         if (retval < 0) {
00564             tr_error("Failed to bring up the RF interface, retval = %d", retval);
00565             return;
00566         }
00567 
00568         /* mark the RF interface active */
00569         net_6lowpan_state = INTERFACE_BOOTSTRAP_ACTIVE;
00570 
00571         multicast_set_parameters(10, 0, 20, 3, 75);
00572         multicast_add_address(multicast_addr, 1);
00573     }
00574 }
00575 
00576 /**
00577   * \brief Network state event handler.
00578   * \param event show network start response or current network state.
00579   *
00580   */
00581 static void app_parse_network_event(arm_event_s *event)
00582 {
00583     switch ((arm_nwk_interface_status_type_e)event->event_data) {
00584         case ARM_NWK_BOOTSTRAP_READY: {
00585             bool gp_address_available;
00586             uint8_t p[16];
00587             char buf[128];
00588             if (0 == arm_net_address_get(event->event_id, ADDR_IPV6_GP, p)) {
00589                 ip6tos(p, buf);
00590                 gp_address_available = true;
00591             } else {
00592                 gp_address_available = false;
00593             }
00594 
00595             if (backhaul_if_id == event->event_id) {
00596 
00597                 if (gp_address_available) {
00598                     tr_info("Backhaul bootstrap ready, IPv6 = %s", buf);
00599                 } else {
00600                     tr_info("Backhaul interface in ULA Mode");
00601                 }
00602 
00603                 if (backhaul_bootstrap_mode == NET_IPV6_BOOTSTRAP_STATIC) {
00604                     uint8_t *next_hop_ptr;
00605                     int8_t retval;
00606                     if (memcmp(backhaul_route.next_hop, addr_unspecified, 16) == 0) {
00607                         tr_info("Next hop not defined");
00608                         next_hop_ptr = NULL;
00609                     } else {
00610                         next_hop_ptr = backhaul_route.next_hop;
00611                     }
00612 
00613                     tr_info("Backhaul default route:");
00614                     tr_info("   prefix:   %s", print_ipv6_prefix(backhaul_route.prefix, backhaul_route.prefix_len));
00615                     tr_info("   next hop: %s", next_hop_ptr ? print_ipv6(backhaul_route.next_hop) : "on-link");
00616 
00617                     retval = arm_net_route_add(backhaul_route.prefix, backhaul_route.prefix_len,
00618                                                next_hop_ptr, 0xffffffff, 128, backhaul_if_id);
00619 
00620                     if (retval < 0) {
00621                         tr_error("Failed to add backhaul default route, retval = %d", retval);
00622                     }
00623                 }
00624 
00625                 tr_info("Backhaul interface addresses:");
00626                 print_interface_addr(backhaul_if_id);
00627 
00628                 net_backhaul_state = INTERFACE_CONNECTED;
00629                 if (net_6lowpan_state == INTERFACE_IDLE_STATE) {
00630                     //Start 6lowpan
00631                     start_6lowpan(p);
00632                 }
00633             } else {
00634                 tr_info("RF bootstrap ready, IPv6 = %s", buf);
00635                 arm_nwk_6lowpan_rpl_dodag_start(net_6lowpan_id);
00636                 net_6lowpan_state = INTERFACE_CONNECTED;
00637                 tr_info("RF interface addresses:");
00638                 print_interface_addr(net_6lowpan_id);
00639                 tr_info("6LoWPAN Border Router Bootstrap Complete.");
00640             }
00641         }
00642             /* Network connection Ready */
00643         break;
00644         case ARM_NWK_NWK_SCAN_FAIL:
00645             /* Link Layer Active Scan Fail, Stack is Already in Idle state */
00646             break;
00647         case ARM_NWK_IP_ADDRESS_ALLOCATION_FAIL:
00648             /* No ND Router at current Channel Stack is Already at Idle state */
00649             break;
00650         case ARM_NWK_NWK_CONNECTION_DOWN:
00651             /* Connection to Access point is lost wait for Scan Result */
00652             break;
00653         case ARM_NWK_NWK_PARENT_POLL_FAIL:
00654             break;
00655         case ARM_NWK_AUHTENTICATION_FAIL:
00656             /* Network authentication fail */
00657             break;
00658         case ARM_NWK_DUPLICATE_ADDRESS_DETECTED:
00659             if (backhaul_if_id == event->event_id) {
00660                 tr_error("Backhaul DAD failed.");
00661             }
00662             break;
00663         default:
00664             /* Unknow event */
00665             break;
00666     }
00667 }
00668 
00669 #endif // MBED_CONF_APP_MESH_MODE