Skip to content

Commit

Permalink
Wi-SUN fhss refactor
Browse files Browse the repository at this point in the history
removed the configuration learn from other than fixed channel
separated the learning of broadcast schedule and only do it from primary parent
Added fixed channel information for neighbour timing info
created user channel mask and channel plan channel mask and combine those
Defined default settings
improved tracing on FHSS
  • Loading branch information
Mika Tervonen committed Aug 15, 2018
1 parent 0ca78d6 commit 1a9acbd
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 57 deletions.
1 change: 1 addition & 0 deletions nanostack/fhss_ws_extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ typedef struct unicast_timing_info {
unsigned unicast_channel_function:3; /**< Unicast schedule channel function */
uint8_t unicast_dwell_interval; /**< Unicast dwell interval */
uint16_t unicast_number_of_channels; /**< Unicast number of channels */
uint16_t fixed_channel; /**< fixed channel*/
uint_fast24_t ufsi; /**< Unicast fractional sequence interval */
uint32_t utt_rx_timestamp; /**< UTT-IE reception timestamp */
} unicast_timing_info_t;
Expand Down
177 changes: 129 additions & 48 deletions source/6LoWPAN/ws/ws_bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,41 +175,92 @@ static fhss_ws_neighbor_timing_info_t *ws_get_neighbor_info(const fhss_api_t *ap
}
return &ws_neighbor->fhss_data;
}
static void ws_bootstrap_llc_hopping_update(struct protocol_interface_info_entry *cur, const fhss_ws_configuration_t *fhss_configuration)
{
memcpy(cur->ws_info->hopping_schdule.channel_mask, fhss_configuration->channel_mask, sizeof(uint32_t) * 8);
cur->ws_info->hopping_schdule.channel_function = fhss_configuration->ws_channel_function;
cur->ws_info->hopping_schdule.fhss_bc_dwell_interval = fhss_configuration->fhss_bc_dwell_interval;
cur->ws_info->hopping_schdule.fhss_broadcast_interval = fhss_configuration->fhss_broadcast_interval;
cur->ws_info->hopping_schdule.fhss_uc_dwell_interval = fhss_configuration->fhss_uc_dwell_interval;
cur->ws_info->hopping_schdule.fhss_bsi = fhss_configuration->bsi;
}

static int8_t ws_enable_fhss(protocol_interface_info_entry_t *cur)
static int8_t ws_fhss_initialize(protocol_interface_info_entry_t *cur)
{
fhss_api_t *fhss_api = ns_sw_mac_get_fhss_api(cur->mac_api);

if (!fhss_api) {
// When FHSS doesn't exist yet, create one
fhss_ws_configuration_t fhss_configuration;
memset(&fhss_configuration, 0, sizeof(fhss_ws_configuration_t));
fhss_configuration.bsi = cur->ws_info->hopping_schdule.fhss_bsi;
memcpy(fhss_configuration.channel_mask, cur->ws_info->hopping_schdule.channel_mask, sizeof(uint32_t) * 8);
fhss_configuration.fhss_uc_dwell_interval = cur->ws_info->hopping_schdule.fhss_uc_dwell_interval;
fhss_configuration.ws_channel_function = cur->ws_info->hopping_schdule.channel_function;
if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
fhss_configuration.fhss_bc_dwell_interval = cur->ws_info->hopping_schdule.fhss_bc_dwell_interval;
fhss_configuration.fhss_broadcast_interval = cur->ws_info->hopping_schdule.fhss_broadcast_interval;
fhss_configuration.bsi = cur->ws_info->hopping_schdule.fhss_bsi;
ws_generate_channel_list(fhss_configuration.channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain);

// using bitwise AND operation for user set channel mask to remove channels not allowed in this device
for (uint8_t n = 0;n < 8;n++) {
fhss_configuration.channel_mask[n] &= cur->ws_info->fhss_channel_mask[n];
}

fhss_configuration.fhss_uc_dwell_interval = cur->ws_info->fhss_uc_dwell_interval;
fhss_configuration.ws_channel_function = cur->ws_info->fhss_channel_function;
fhss_configuration.fhss_bc_dwell_interval = cur->ws_info->fhss_bc_dwell_interval;
fhss_configuration.fhss_broadcast_interval = cur->ws_info->fhss_bc_interval;

fhss_api = ns_fhss_ws_create(&fhss_configuration, cur->ws_info->fhss_timer_ptr);
if (!fhss_api) {
tr_error("fhss create failed");
return -1;
}
ns_sw_mac_fhss_register(cur->mac_api, fhss_api);
} else {
// Read configuration of existing FHSS
// Read defaults from the configuration to help FHSS testing
const fhss_ws_configuration_t *fhss_configuration = ns_fhss_ws_configuration_get(fhss_api);
if (!fhss_configuration) {
return -1;
// no configuration set yet
return 0;
}
memcpy(cur->ws_info->hopping_schdule.channel_mask, fhss_configuration->channel_mask, sizeof(uint32_t) * 8);
cur->ws_info->hopping_schdule.channel_function = fhss_configuration->ws_channel_function;
cur->ws_info->hopping_schdule.fhss_bc_dwell_interval = fhss_configuration->fhss_bc_dwell_interval;
cur->ws_info->hopping_schdule.fhss_broadcast_interval = fhss_configuration->fhss_broadcast_interval;
cur->ws_info->hopping_schdule.fhss_uc_dwell_interval = fhss_configuration->fhss_uc_dwell_interval;
cur->ws_info->hopping_schdule.fhss_bsi = fhss_configuration->bsi;
memcpy(cur->ws_info->fhss_channel_mask, fhss_configuration->channel_mask, sizeof(uint32_t) * 8);
cur->ws_info->fhss_channel_function = fhss_configuration->ws_channel_function;
cur->ws_info->fhss_bc_dwell_interval = fhss_configuration->fhss_bc_dwell_interval;
cur->ws_info->fhss_bc_interval = fhss_configuration->fhss_broadcast_interval;
cur->ws_info->fhss_uc_dwell_interval = fhss_configuration->fhss_uc_dwell_interval;
}
return 0;
}
static int8_t ws_fhss_set_defaults(protocol_interface_info_entry_t *cur)
{
// Read configuration of existing FHSS and start using the default values for any network
fhss_ws_configuration_t fhss_configuration = {0};
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));
}

fhss_configuration.fhss_uc_dwell_interval = cur->ws_info->fhss_uc_dwell_interval;
fhss_configuration.ws_channel_function = cur->ws_info->fhss_channel_function;
fhss_configuration.fhss_bc_dwell_interval = cur->ws_info->fhss_bc_dwell_interval;
fhss_configuration.fhss_broadcast_interval = cur->ws_info->fhss_bc_interval;
ws_generate_channel_list(fhss_configuration.channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain);

// using bitwise AND operation for user set channel mask to remove channels not allowed in this device
for (uint8_t n = 0;n < 8;n++) {
fhss_configuration.channel_mask[n] &= cur->ws_info->fhss_channel_mask[n];
}

ns_fhss_ws_configuration_set(cur->ws_info->fhss_api,&fhss_configuration);

return 0;
}

static int8_t ws_fhss_enable(protocol_interface_info_entry_t *cur)
{
fhss_api_t *fhss_api = ns_sw_mac_get_fhss_api(cur->mac_api);
const fhss_ws_configuration_t *fhss_configuration = ns_fhss_ws_configuration_get(fhss_api);

if (!fhss_api || !fhss_configuration) {
return -1;
}
// Set the LLC information to follow the actual fhss settings
ws_bootstrap_llc_hopping_update(cur,fhss_configuration);

// Set neighbor info callback
if (ns_fhss_set_neighbor_info_fp(fhss_api, &ws_get_neighbor_info)) {
return -1;
Expand All @@ -220,6 +271,45 @@ static int8_t ws_enable_fhss(protocol_interface_info_entry_t *cur)
cur->ws_info->fhss_api = fhss_api;
return 0;
}

/* Sets the parent and broadcast schedule we are following
*
*/
static void ws_bootstrap_primary_parent_set(struct protocol_interface_info_entry *cur, llc_neighbour_req_t *neighbor_info)
{

fhss_ws_configuration_t fhss_configuration;
memcpy(&fhss_configuration, ns_fhss_ws_configuration_get(cur->ws_info->fhss_api), sizeof(fhss_ws_configuration_t));

// unicast information is only followed from parent if fixed channel is selected
if (neighbor_info->ws_neighbor->fhss_data.uc_timing_info.unicast_channel_function == WS_FIXED_CHANNEL) {
cur->ws_info->hopping_schdule.fixed_channel = neighbor_info->ws_neighbor->fhss_data.uc_timing_info.fixed_channel;
fhss_configuration.ws_channel_function = WS_FIXED_CHANNEL;
tr_info("attaching to fixed channel network following configurtion");
} else if (fhss_configuration.ws_channel_function == WS_FIXED_CHANNEL) {
// fixed channel cannot be mixed with other channel functions as it messes the broadcast schedule
fhss_configuration.ws_channel_function = WS_DH1CF;
tr_info("attaching channel hopping network changing to hopping");
}
// Learn broadcast information from selected parent
fhss_configuration.bsi = neighbor_info->ws_neighbor->fhss_data.bc_timing_info.broadcast_schedule_id;
fhss_configuration.fhss_bc_dwell_interval = neighbor_info->ws_neighbor->fhss_data.bc_timing_info.broadcast_dwell_interval;
fhss_configuration.fhss_broadcast_interval = neighbor_info->ws_neighbor->fhss_data.bc_timing_info.broadcast_interval;
ns_fhss_ws_configuration_set(cur->ws_info->fhss_api, &fhss_configuration);

if (fhss_configuration.fhss_bc_dwell_interval && fhss_configuration.fhss_broadcast_interval) {
// We have broadcast schedule set up set the broadcast parent schedule
ns_fhss_ws_set_parent(cur->ws_info->fhss_api, neighbor_info->neighbor->mac64, &neighbor_info->ws_neighbor->fhss_data.bc_timing_info);
}

// Update LLC to follow updated fhss settings
ws_bootstrap_llc_hopping_update(cur,&fhss_configuration);

// set neighbor as priority parent clear if there is others
protocol_6lowpan_neighbor_priority_clear_all(cur->id, PRIORITY_1ST);
neighbor_info->neighbor->link_role = PRIORITY_PARENT_NEIGHBOUR;

}
/* \return 0x0100 to 0xFFFF ETX value (8 bit fraction)
* \return 0xFFFF address not associated
* \return 0x0000 address unknown or other error
Expand Down Expand Up @@ -271,8 +361,12 @@ static int8_t ws_bootstrap_up(protocol_interface_info_entry_t *cur)
}

if ((cur->configure_flags & INTERFACE_SETUP_MASK) != INTERFACE_SETUP_READY) {
tr_debug("Interface not yet fully configured");
return -5;
tr_error("Interface not yet fully configured");
return -2;
}
if (ws_fhss_initialize(cur) != 0) {
tr_error("fhss initialization failed");
return -3;
}

addr_interface_set_ll64(cur, NULL);
Expand Down Expand Up @@ -602,8 +696,6 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry
}
trickle_consistent_heard(&cur->ws_info->trickle_pan_config);

// TODO update and learn new neighbour

if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
//Border router does not learn network information
return;
Expand All @@ -623,31 +715,21 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry
cur->ws_info->pan_information.pan_version = pan_version;
memcpy(cur->ws_info->gtkhash,gtkhash_ptr,32);

//Broadcast schedule
cur->ws_info->hopping_schdule.fhss_broadcast_interval = ws_bs_ie.broadcast_interval;
cur->ws_info->hopping_schdule.fhss_bsi = ws_bs_ie.broadcast_schedule_identifier;
cur->ws_info->hopping_schdule.fhss_bc_dwell_interval = ws_bs_ie.dwell_interval;

cur->ws_info->hopping_schdule.channel_function = ws_bs_ie.channel_function;
cur->ws_info->hopping_schdule.fhss_uc_dwell_interval = ws_us->dwell_interval;

fhss_ws_configuration_t fhss_configuration;
memcpy(&fhss_configuration, ns_fhss_ws_configuration_get(cur->ws_info->fhss_api), sizeof(fhss_ws_configuration_t));
fhss_configuration.fhss_uc_dwell_interval = neighbor_info.ws_neighbor->fhss_data.uc_timing_info.unicast_dwell_interval;
fhss_configuration.ws_channel_function = neighbor_info.ws_neighbor->fhss_data.uc_timing_info.unicast_channel_function;
fhss_configuration.bsi = neighbor_info.ws_neighbor->fhss_data.bc_timing_info.broadcast_schedule_id;
ns_fhss_ws_configuration_set(cur->ws_info->fhss_api, &fhss_configuration);

ns_fhss_ws_set_parent(cur->ws_info->fhss_api, data->SrcAddr, &neighbor_info.ws_neighbor->fhss_data.bc_timing_info);
if (neighbor_info.neighbor->link_role == PRIORITY_PARENT_NEIGHBOUR) {
// RPL priority parent configuration we must update FHSS data
ws_bootstrap_primary_parent_set(cur, &neighbor_info);
}

if (!cur->ws_info->configuration_learned) {
// Generate own hopping schedules Follow first parent broadcast and plans and also use same unicast dwell
cur->ws_info->configuration_learned = true;
// return to state machine after 1-2 s
cur->bootsrap_state_machine_cnt = randLIB_get_random_in_range(10 ,20);
ws_bootstrap_primary_parent_set(cur, &neighbor_info);
}

}

static void ws_bootstrap_pan_config_solicit_analyse(struct protocol_interface_info_entry *cur, const struct mcps_data_ind_s *data, ws_utt_ie_t *ws_utt, ws_us_ie_t *ws_us)
{
if (data->SrcPANId != cur->ws_info->network_pan_id) {
Expand Down Expand Up @@ -981,7 +1063,7 @@ static void ws_bootstrap_mac_activate(protocol_interface_info_entry_t *cur, uint
static void ws_bootstrap_fhss_activate(protocol_interface_info_entry_t *cur)
{
tr_debug("FHSS activate");
ws_enable_fhss(cur);
ws_fhss_enable(cur);
ws_llc_hopping_schedule_config(cur, &cur->ws_info->hopping_schdule);
// Only supporting fixed channel

Expand All @@ -996,8 +1078,8 @@ static void ws_bootstrap_network_information_learn(protocol_interface_info_entry
{
tr_debug("learn network information from parent");

// Start following network timing schedules
cur->ws_info->hopping_schdule.fhss_uc_dwell_interval = cur->ws_info->parent_info.ws_us.dwell_interval;
// Start following network broadcast timing schedules

// Regulatory domain saving? cant change?

// Save network information
Expand Down Expand Up @@ -1119,9 +1201,9 @@ static void ws_bootstrap_network_discovery_configure(protocol_interface_info_ent
ws_common_regulatory_domain_config(cur);

// Set default schedules for discovery
cur->ws_info->hopping_schdule.fhss_uc_dwell_interval = 250;
cur->ws_info->hopping_schdule.fhss_broadcast_interval = 800;
cur->ws_info->hopping_schdule.fhss_bc_dwell_interval = 200;
cur->ws_info->hopping_schdule.fhss_uc_dwell_interval = WS_FHSS_UC_DWELL_INTERVAL;
cur->ws_info->hopping_schdule.fhss_broadcast_interval = WS_FHSS_BC_INTERVAL;
cur->ws_info->hopping_schdule.fhss_bc_dwell_interval = WS_FHSS_BC_DWELL_INTERVAL;
// By default, uses fixed channel
cur->ws_info->hopping_schdule.channel_function = WS_FIXED_CHANNEL;
cur->ws_info->hopping_schdule.fixed_channel = randLIB_get_random_in_range(11,25);
Expand Down Expand Up @@ -1392,6 +1474,9 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
trickle_stop(&cur->ws_info->trickle_pan_advertisement);
trickle_stop(&cur->ws_info->trickle_pan_config);

// Set default parameters for FHSS when starting a discovery
ws_fhss_set_defaults(cur);

if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
tr_debug("Border router start network");
cur->ws_info->network_pan_id = randLIB_get_random_in_range(0,0xfffd);
Expand Down Expand Up @@ -1482,11 +1567,7 @@ void ws_bootstrap_network_scan_process(protocol_interface_info_entry_t *cur)
return;
}

ws_neighbor_class_neighbor_unicast_time_info_update(neighbor_info.ws_neighbor, &cur->ws_info->parent_info.ws_utt, cur->ws_info->parent_info.timestamp);
ws_neighbor_class_neighbor_unicast_schedule_set(neighbor_info.ws_neighbor, &cur->ws_info->parent_info.ws_us);
//SET parent
neighbor_info.neighbor->link_role = PRIORITY_PARENT_NEIGHBOUR;

ws_bootstrap_primary_parent_set(cur, &neighbor_info);
ws_bootstrap_network_information_learn(cur);
ws_bootstrap_fhss_activate(cur);
ws_bootstrap_event_authentication_start(cur);
Expand Down
25 changes: 17 additions & 8 deletions source/6LoWPAN/ws/ws_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,18 @@
int8_t DEVICE_MIN_SENS = -93;


static int8_t ws_generate_channel_list(ws_hopping_schedule_t *hopping_schedule)
int8_t ws_generate_channel_list(uint32_t *channel_mask, uint16_t number_of_channels, uint8_t regulatory_domain)
{
for (uint8_t i=0; i<hopping_schedule->number_of_channels; i++) {
hopping_schedule->channel_mask[0+(i/32)] |= (1 << (i%32));
(void)regulatory_domain;
for (uint8_t i=0; i<number_of_channels; i++) {
channel_mask[0+(i/32)] |= (1 << (i%32));
}
return 0;
}

int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur)
{
cur->ws_info->hopping_schdule.channel_plan = 0;
cur->ws_info->hopping_schdule.channel_function = CHANNEL_FUNCTION_TR51CF;

if(cur->ws_info->hopping_schdule.regulatory_domain == REG_DOMAIN_KR) {
if(cur->ws_info->hopping_schdule.operating_class == 1) {
Expand Down Expand Up @@ -125,7 +125,7 @@ int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur)
return -1;
}
// Note: doesn't work for Brazil region
ws_generate_channel_list(&cur->ws_info->hopping_schdule);
ws_generate_channel_list(cur->ws_info->hopping_schdule.channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain);
return 0;
}

Expand All @@ -150,10 +150,19 @@ int8_t ws_common_allocate_and_init(protocol_interface_info_entry_t *cur)
cur->ws_info->hopping_schdule.operating_class = 1;
ws_common_regulatory_domain_config(cur);

cur->ws_info->hopping_schdule.fhss_uc_dwell_interval = 250;
cur->ws_info->hopping_schdule.fhss_broadcast_interval = 800;
cur->ws_info->hopping_schdule.fhss_bc_dwell_interval = 200;
// Set defaults for the device. user can modify these.
cur->ws_info->fhss_uc_dwell_interval = WS_FHSS_UC_DWELL_INTERVAL;
cur->ws_info->fhss_bc_interval = WS_FHSS_BC_INTERVAL;
cur->ws_info->fhss_bc_dwell_interval = WS_FHSS_BC_DWELL_INTERVAL;
cur->ws_info->fhss_channel_function = WS_FIXED_CHANNEL;
for (uint8_t n = 0;n < 8;n++) {
cur->ws_info->fhss_channel_mask[n] = 0xffffffff;
}

// By default, uses fixed channel
cur->ws_info->hopping_schdule.fhss_uc_dwell_interval = WS_FHSS_UC_DWELL_INTERVAL;
cur->ws_info->hopping_schdule.fhss_broadcast_interval = WS_FHSS_BC_INTERVAL;
cur->ws_info->hopping_schdule.fhss_bc_dwell_interval = WS_FHSS_BC_DWELL_INTERVAL;
cur->ws_info->hopping_schdule.channel_function = WS_FIXED_CHANNEL;
cur->ws_info->hopping_schdule.fixed_channel = randLIB_get_random_in_range(11,25);

Expand Down
8 changes: 8 additions & 0 deletions source/6LoWPAN/ws/ws_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ typedef struct ws_info_s {
uint32_t pan_version_timeout_timer; /**< routers will fallback to previous state after this */
uint8_t gtkhash[32];
bool configuration_learned:1;
// default fhss parameters for this device
uint8_t fhss_uc_dwell_interval;
uint8_t fhss_bc_dwell_interval;
uint32_t fhss_bc_interval;
uint8_t fhss_channel_function;
uint32_t fhss_channel_mask[8];

struct ws_pan_information_s pan_information;
ws_hopping_schedule_t hopping_schdule;
Expand All @@ -65,6 +71,8 @@ typedef struct ws_info_s {

#ifdef HAVE_WS

int8_t ws_generate_channel_list(uint32_t *channel_mask, uint16_t number_of_channels, uint8_t regulatory_domain);

int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur);

int8_t ws_common_allocate_and_init(protocol_interface_info_entry_t *cur);
Expand Down
8 changes: 8 additions & 0 deletions source/6LoWPAN/ws/ws_common_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,4 +203,12 @@ typedef struct ws_bs_ie {
*/
#define WS_RPL_DIS_TIMEOUT 1800

/* Default FHSS timing information
*
*/
#define WS_FHSS_UC_DWELL_INTERVAL 250;
#define WS_FHSS_BC_INTERVAL 800;
#define WS_FHSS_BC_DWELL_INTERVAL 200;


#endif /* WS_COMMON_DEFINES_H_ */
4 changes: 4 additions & 0 deletions source/6LoWPAN/ws/ws_neighbor_class.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "ns_list.h"
#include "ns_trace.h"
#include "nsdynmemLIB.h"
#include "fhss_config.h"
#include "6LoWPAN/ws/ws_config.h"
#include "6LoWPAN/ws/ws_neighbor_class.h"

Expand Down Expand Up @@ -94,6 +95,9 @@ void ws_neighbor_class_neighbor_unicast_time_info_update(ws_neighbor_class_entry
void ws_neighbor_class_neighbor_unicast_schedule_set(ws_neighbor_class_entry_t *ws_neighbor, ws_us_ie_t *ws_us)
{
ws_neighbor->fhss_data.uc_timing_info.unicast_channel_function = ws_us->channel_function;
if (ws_us->channel_function == WS_FIXED_CHANNEL) {
ws_neighbor->fhss_data.uc_timing_info.fixed_channel = ws_us->function.zero.fixed_channel;
}
ws_neighbor->fhss_data.uc_timing_info.unicast_dwell_interval = ws_us->dwell_interval;
}

Expand Down
Loading

0 comments on commit 1a9acbd

Please sign in to comment.