Skip to content

Commit

Permalink
Wi-SUN recovery and BR BSI update:
Browse files Browse the repository at this point in the history
BSI is randomized at first use.

Border router support BSI update at BootUp process and BBR NVM

BBR NVM information support update

wi-sun bbr read BSI from NVM at boot up process.

BSI is stored to NVM when it is update at discoverty state or manual set from Application.

Node detetc Border router updated BSI at PAN config handler and start discovery and start block old shedule select.

Update PAE controller target address at DAO ACK done event.
  • Loading branch information
Juha Heiskanen committed Oct 30, 2020
1 parent d166c89 commit 7ad7e81
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 7 deletions.
13 changes: 13 additions & 0 deletions nanostack/ws_bbr_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,19 @@ int ws_bbr_pan_configuration_get(int8_t interface_id, uint16_t *pan_id);
*/
int ws_bbr_pan_configuration_validate(int8_t interface_id, uint16_t pan_id);

/**
* Sets Wi-SUN BSI
*
* Sets Wi-SUN PAN BSI.
*
* \param interface_id Network interface ID.
* \param new_bsi Identifier.
*
* \return 0, PAN BSI set.
* \return <0 PAN BSI set failed.
*/
int ws_bbr_bsi_set(int8_t interface_id, uint16_t new_bsi);

/**
* Sets memory used for key storages
*
Expand Down
120 changes: 119 additions & 1 deletion source/6LoWPAN/ws/ws_bbr_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include "ns_types.h"
#include "ns_trace.h"
#include "nsdynmemLIB.h"
#include "randLIB.h"
#include "common_functions.h"
#include "net_interface.h"
#include "socket_api.h"
#include "eventOS_event.h"
Expand All @@ -31,6 +33,7 @@
#include "6LoWPAN/ws/ws_bootstrap.h"
#include "6LoWPAN/ws/ws_cfg_settings.h"
#include "6LoWPAN/ws/ws_pae_key_storage.h"
#include "6LoWPAN/ws/ws_pae_nvm_store.h"
#include "RPL/rpl_control.h"
#include "RPL/rpl_data.h"
#include "Common_Protocols/icmpv6.h"
Expand Down Expand Up @@ -61,6 +64,20 @@ static uint8_t current_instance_id = RPL_INSTANCE_ID;
#define BBR_CHECK_INTERVAL 60
#define BBR_BACKUP_ULA_DELAY 300

//TAG ID This must be update if NVM_BBR_INFO_LEN or data structure
#define NVM_BBR_INFO_TAG 1
// BSI 2 bytes
#define NVM_BBR_INFO_LEN 2

typedef struct bbr_info_nvm_tlv {
uint16_t tag; /**< Unique tag */
uint16_t len; /**< Number of the bytes after the length field */
uint8_t data[NVM_BBR_INFO_LEN]; /**< Data */
} bbr_info_nvm_tlv_t;

//NVM file name
static const char *BBR_INFO_FILE = "pae_bbr_info";

/* when creating BBR make ULA dodag ID always and when network becomes available add prefix to DHCP
*
*
Expand Down Expand Up @@ -105,6 +122,52 @@ typedef struct dns_resolution {
#define MAX_DNS_RESOLUTIONS 4

static dns_resolution_t pre_resolved_dns_queries[MAX_DNS_RESOLUTIONS] = {0};
//BBR NVM info buffer

#define BBR_NVM_BSI_OFFSET 0
static bbr_info_nvm_tlv_t bbr_info_nvm_tlv = {
.tag = NVM_BBR_INFO_TAG,
.len = 0,
.data = {0}
};

static uint16_t ws_bbr_fhss_bsi = 0;

static int8_t ws_bbr_nvm_info_read(bbr_info_nvm_tlv_t *tlv_entry)
{
tlv_entry->tag = NVM_BBR_INFO_TAG;
tlv_entry->len = NVM_BBR_INFO_LEN;

int8_t ret_val = ws_pae_nvm_store_tlv_file_read(BBR_INFO_FILE, (nvm_tlv_t *) &bbr_info_nvm_tlv);

if (ret_val < 0 || tlv_entry->tag != NVM_BBR_INFO_TAG || tlv_entry->len != NVM_BBR_INFO_LEN) {
ws_pae_nvm_store_tlv_file_remove(BBR_INFO_FILE);
tlv_entry->len = 0;
return -1;
}
return 0;
}

static void ws_bbr_nvm_info_write(bbr_info_nvm_tlv_t *tlv_entry)
{
tlv_entry->tag = NVM_BBR_INFO_TAG;
tlv_entry->len = NVM_BBR_INFO_LEN;
ws_pae_nvm_store_tlv_file_write(BBR_INFO_FILE, (nvm_tlv_t *) tlv_entry);
tr_debug("BBR info NVM update");
}

static uint16_t ws_bbr_bsi_read(bbr_info_nvm_tlv_t *tlv_entry)
{
if (tlv_entry->tag != NVM_BBR_INFO_TAG || tlv_entry->len != NVM_BBR_INFO_LEN) {
return 0;
}
return common_read_16_bit(tlv_entry->data + BBR_NVM_BSI_OFFSET);
}

static void ws_bbr_bsi_write(bbr_info_nvm_tlv_t *tlv_entry, uint16_t bsi)
{
common_write_16_bit(bsi, tlv_entry->data + BBR_NVM_BSI_OFFSET);
}

static void ws_bbr_rpl_version_timer_start(protocol_interface_info_entry_t *cur, uint8_t version)
{
Expand Down Expand Up @@ -134,7 +197,6 @@ static void ws_bbr_rpl_version_increase(protocol_interface_info_entry_t *cur)
ws_bbr_rpl_version_timer_start(cur, rpl_control_increment_dodag_version(protocol_6lowpan_rpl_root_dodag));
}


void ws_bbr_rpl_config(protocol_interface_info_entry_t *cur, uint8_t imin, uint8_t doubling, uint8_t redundancy, uint16_t dag_max_rank_increase, uint16_t min_hop_rank_increase)
{
if (imin == 0 || doubling == 0) {
Expand Down Expand Up @@ -785,6 +847,35 @@ bool ws_bbr_ready_to_start(protocol_interface_info_entry_t *cur)

return true;
}

void ws_bbr_init(protocol_interface_info_entry_t *interface)
{
(void) interface;
//Read From NVM
if (ws_bbr_nvm_info_read(&bbr_info_nvm_tlv) < 0) {
//NVM value not available Randomize Value Here by first time
ws_bbr_fhss_bsi = randLIB_get_16bit();
tr_debug("Randomized init value BSI %u", ws_bbr_fhss_bsi);
} else {
ws_bbr_fhss_bsi = ws_bbr_bsi_read(&bbr_info_nvm_tlv);
tr_debug("Read BSI %u from NVM", ws_bbr_fhss_bsi);
}
}


uint16_t ws_bbr_bsi_generate(protocol_interface_info_entry_t *interface)
{
(void) interface;
//Give current one
uint16_t bsi = ws_bbr_fhss_bsi;
//Update value for next round
ws_bbr_fhss_bsi++;
//Store To NVN
ws_bbr_bsi_write(&bbr_info_nvm_tlv, ws_bbr_fhss_bsi);
ws_bbr_nvm_info_write(&bbr_info_nvm_tlv);
return bsi;
}

#endif //HAVE_WS_BORDER_ROUTER

/* Public APIs
Expand Down Expand Up @@ -1070,6 +1161,33 @@ int ws_bbr_rpl_parameters_validate(int8_t interface_id, uint8_t dio_interval_min
#endif
}

int ws_bbr_bsi_set(int8_t interface_id, uint16_t new_bsi)
{
(void) interface_id;
#ifdef HAVE_WS_BORDER_ROUTER

protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);

//Check if new value is different than current active
if (cur && cur->ws_info && cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
if (cur->ws_info->hopping_schdule.fhss_bsi == new_bsi) {
return 0;
}
tr_debug("New BSI %u to delayed activate", new_bsi);
ws_bootstrap_restart_delayed(cur->id);
}

ws_bbr_bsi_write(&bbr_info_nvm_tlv, new_bsi);
ws_bbr_nvm_info_write(&bbr_info_nvm_tlv);
ws_bbr_fhss_bsi = new_bsi;
return 0;
#else
(void) new_bsi;
return -1;
#endif
}


int ws_bbr_pan_configuration_set(int8_t interface_id, uint16_t pan_id)
{
(void) interface_id;
Expand Down
5 changes: 5 additions & 0 deletions source/6LoWPAN/ws/ws_bbr_api_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ bool ws_bbr_ready_to_start(protocol_interface_info_entry_t *cur);

bool ws_bbr_backbone_address_get(uint8_t *address);

uint16_t ws_bbr_bsi_generate(protocol_interface_info_entry_t *interface);
void ws_bbr_init(protocol_interface_info_entry_t *interface);

#else

#define ws_bbr_seconds_timer( cur, seconds)
Expand All @@ -46,6 +49,8 @@ bool ws_bbr_backbone_address_get(uint8_t *address);
#define ws_bbr_dhcp_address_lifetime_set(cur, dhcp_address_lifetime)
#define ws_bbr_ready_to_start(cur) true
#define ws_bbr_backbone_address_get(address) 0
#define ws_bbr_bsi_generate(interface) 0
#define ws_bbr_init(interface) (void) 0

#endif //HAVE_WS_BORDER_ROUTER

Expand Down
47 changes: 45 additions & 2 deletions source/6LoWPAN/ws/ws_bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,9 @@ static int8_t ws_fhss_border_router_configure(protocol_interface_info_entry_t *c
if (ns_fhss_ws_configuration_get(cur->ws_info->fhss_api)) {
memcpy(&fhss_configuration, ns_fhss_ws_configuration_get(cur->ws_info->fhss_api), sizeof(fhss_ws_configuration_t));
}

//GET BSI from BBR module
fhss_configuration.bsi = ws_bbr_bsi_generate(cur);
ws_fhss_set_defaults(cur, &fhss_configuration);
ws_fhss_configure_channel_masks(cur, &fhss_configuration);
ns_fhss_ws_configuration_set(cur->ws_info->fhss_api, &fhss_configuration);
Expand Down Expand Up @@ -988,15 +991,17 @@ static int8_t ws_bootstrap_up(protocol_interface_info_entry_t *cur)
tr_error("fhss initialization failed");
return -3;
}

if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
//BBR init like NVM read
ws_bbr_init(cur);
}
// Save FHSS api
cur->ws_info->fhss_api = ns_sw_mac_get_fhss_api(cur->mac_api);

ws_bootstrap_ll_address_validate(cur);

addr_interface_set_ll64(cur, NULL);
cur->nwk_nd_re_scan_count = 0;
//WS_interface_up(cur);
// Trigger discovery for bootstrap
ret_val = nwk_6lowpan_up(cur);
if (ret_val) {
Expand Down Expand Up @@ -1584,6 +1589,27 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry
llc_neighbour_req_t neighbor_info;
bool neighbour_pointer_valid;

//Validate BSI
if (cur->bootsrap_mode != ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {

if (cur->ws_info->ws_bsi_block.block_time && cur->ws_info->ws_bsi_block.old_bsi == ws_bs_ie.broadcast_schedule_identifier) {
tr_debug("Do not accept a old BSI: %u in time %"PRIu32, cur->ws_info->ws_bsi_block.old_bsi, cur->ws_info->ws_bsi_block.block_time);
//Refresh Block time when hear a old BSI
cur->ws_info->ws_bsi_block.block_time = cur->ws_info->cfg->timing.pan_timeout;
return;
}

//When Config is learned and USE Parent BS is enabled compare is this new BSI
if (cur->ws_info->configuration_learned && cur->ws_info->pan_information.use_parent_bs && ws_bs_ie.broadcast_schedule_identifier != cur->ws_info->hopping_schdule.fhss_bsi) {
tr_debug("NEW Brodcast Schedule %u...BR rebooted", ws_bs_ie.broadcast_schedule_identifier);
cur->ws_info->ws_bsi_block.block_time = cur->ws_info->cfg->timing.pan_timeout;
cur->ws_info->ws_bsi_block.old_bsi = cur->ws_info->hopping_schdule.fhss_bsi;
ws_bootstrap_event_discovery_start(cur);
return;
}
}


if (cur->ws_info->configuration_learned || cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
//If we are border router or learned configuration we only update already learned neighbours.
neighbour_pointer_valid = ws_bootstrap_neighbor_info_request(cur, data->SrcAddr, &neighbor_info, false);
Expand Down Expand Up @@ -2491,6 +2517,13 @@ static void ws_bootstrap_rpl_callback(rpl_event_t event, void *handle)
ws_pae_controller_nw_info_set(cur, cur->ws_info->network_pan_id, cur->ws_info->pan_information.pan_version, cur->ws_info->cfg->gen.network_name);
// Network key is valid, indicate border router IID to controller
ws_pae_controller_nw_key_valid(cur, &dodag_info.dodag_id[8]);
//Update here Suplikant target by validated Primary Parent
if (cur->bootsrap_mode != ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
mac_neighbor_table_entry_t *mac_neighbor = mac_neighbor_entry_get_priority(mac_neighbor_info(cur));
if (mac_neighbor) {
ws_pae_controller_set_target(cur, cur->ws_info->network_pan_id, mac_neighbor->mac64);
}
}

// After successful DAO ACK connection to border router is verified
cur->ws_info->pan_timeout_timer = cur->ws_info->cfg->timing.pan_timeout;
Expand Down Expand Up @@ -3657,6 +3690,16 @@ void ws_bootstrap_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t s
}
}

if (cur->ws_info->ws_bsi_block.block_time) {
if (cur->ws_info->ws_bsi_block.block_time > seconds) {
cur->ws_info->ws_bsi_block.block_time -= seconds;
} else {
//Clear A BSI blokker
cur->ws_info->ws_bsi_block.block_time = 0;
cur->ws_info->ws_bsi_block.old_bsi = 0;
}
}

ws_llc_timer_seconds(cur, seconds);

}
Expand Down
8 changes: 4 additions & 4 deletions source/6LoWPAN/ws/ws_cfg_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ typedef struct ws_timing_cfg_s {
* \brief Struct ws_rpl_cfg_t RPL configuration
*/
typedef struct ws_bbr_cfg_s {
uint8_t dio_interval_min; /**> DIO interval min; DEFAULT_DIO_INTERVAL_MIN; 2^value in milliseconds; range 1-255; default */
uint8_t dio_interval_doublings; /**> DIO interval doublings; DEFAULT_DIO_INTERVAL_DOUBLINGS; range 1-8; default */
uint8_t dio_redundancy_constant; /**> DIO redundancy constant; DEFAULT_DIO_REDUNDANCY_CONSTANT; range 0-10; default */
uint8_t dio_interval_min; /**< DIO interval min; DEFAULT_DIO_INTERVAL_MIN; 2^value in milliseconds; range 1-255; default */
uint8_t dio_interval_doublings; /**< DIO interval doublings; DEFAULT_DIO_INTERVAL_DOUBLINGS; range 1-8; default */
uint8_t dio_redundancy_constant; /**< DIO redundancy constant; DEFAULT_DIO_REDUNDANCY_CONSTANT; range 0-10; default */
uint16_t dag_max_rank_increase;
uint16_t min_hop_rank_increase;
uint32_t dhcp_address_lifetime; /**> DHCP address lifetime in seconds minimum 2 hours and maximum as days hours*/
uint32_t dhcp_address_lifetime; /**< DHCP address lifetime in seconds minimum 2 hours and maximum as days hours*/
} ws_bbr_cfg_t;

/**
Expand Down
6 changes: 6 additions & 0 deletions source/6LoWPAN/ws/ws_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ typedef struct {
uint8_t index;
} ws_pending_key_index_t;

typedef struct {
uint32_t block_time;
uint16_t old_bsi;
} ws_bsi_block_t;

typedef NS_LIST_HEAD(ws_nud_table_entry_t, link) ws_nud_table_list_t;

typedef struct ws_info_s {
Expand All @@ -89,6 +94,7 @@ typedef struct ws_info_s {
parent_info_t parent_info[WS_PARENT_LIST_SIZE];
parent_info_list_t parent_list_free;
parent_info_list_t parent_list_reserved;
ws_bsi_block_t ws_bsi_block;
uint16_t aro_registration_timer; /**< Aro registration timer */
uint16_t rpl_version_timer; /**< RPL version update timeout */
uint32_t pan_timeout_timer; /**< routers will fallback to previous state after this */
Expand Down

0 comments on commit 7ad7e81

Please sign in to comment.