Skip to content

Commit 0b48e5c

Browse files
author
Juha Heiskanen
committed
Channel Mask update ,support for excluded Channels and FHSS API pdate
Excluded Channel Parsing, write and storage support Support for RX excluded channel information and generate active unicast channel list and keep updated that. Support for write unicast excluded channels. Support to store node own excluded data. Simplify Domain / Unicast channel mask and exclude mask build operation Seperate Unicast and Domain mask for wi-sun FHSS and integrate channel selection. Fixed Channel Plan 1 parsing and writing. Removed wrong channel compare we must support 1 & 0 both.
1 parent ead1ade commit 0b48e5c

File tree

10 files changed

+445
-54
lines changed

10 files changed

+445
-54
lines changed

nanostack/fhss_config.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,12 @@ typedef struct fhss_ws_configuration {
116116
/** Broadcast fixed channel */
117117
uint8_t broadcast_fixed_channel;
118118

119-
/** Channel mask. */
119+
/** Channel mask. Wi-SUN will use this for broadcast */
120120
uint32_t channel_mask[8];
121121

122+
/** Wi-SUN specific unicast channel mask */
123+
uint32_t unicast_channel_mask[8];
124+
122125
/** Vendor defined channel function. */
123126
fhss_vendor_defined_cf *vendor_defined_cf;
124127

nanostack/fhss_ws_extension.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@
3030
extern "C" {
3131
#endif
3232

33+
/**
34+
* @brief ws_channel_mask_t WS neighbour supported channel mask
35+
*/
36+
typedef struct ws_channel_mask {
37+
uint16_t channel_count; /**<active channels at mask */
38+
uint32_t channel_mask[8]; /**< Supported channels */
39+
} ws_channel_mask_t;
40+
3341
/**
3442
* @brief unicast_timing_info Unicast timing/hopping schedule information structure.
3543
*/
@@ -64,6 +72,7 @@ typedef struct fhss_ws_neighbor_timing_info {
6472
uint8_t timing_accuracy; /**< Neighbor timing accuracy */
6573
unicast_timing_info_t uc_timing_info; /**< Neighbor unicast timing info */
6674
broadcast_timing_info_t bc_timing_info; /**< Neighbor broadcast timing info */
75+
ws_channel_mask_t uc_channel_list; /**< Neighbor Unicast channel list */
6776
uint32_t *excluded_channels; /**< Neighbor excluded channels (bit mask) */
6877
} fhss_ws_neighbor_timing_info_t;
6978

source/6LoWPAN/ws/ws_bootstrap.c

Lines changed: 135 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,6 @@ static fhss_ws_neighbor_timing_info_t *ws_get_neighbor_info(const fhss_api_t *ap
417417
}
418418
static void ws_bootstrap_llc_hopping_update(struct protocol_interface_info_entry *cur, const fhss_ws_configuration_t *fhss_configuration)
419419
{
420-
memcpy(cur->ws_info->hopping_schdule.channel_mask, fhss_configuration->channel_mask, sizeof(uint32_t) * 8);
421420
cur->ws_info->hopping_schdule.uc_fixed_channel = fhss_configuration->unicast_fixed_channel;
422421
cur->ws_info->hopping_schdule.bc_fixed_channel = fhss_configuration->broadcast_fixed_channel;
423422
// Read UC channel function from WS info because FHSS might be temporarily configured to fixed channel during discovery.
@@ -429,19 +428,80 @@ static void ws_bootstrap_llc_hopping_update(struct protocol_interface_info_entry
429428
cur->ws_info->hopping_schdule.fhss_bsi = fhss_configuration->bsi;
430429
}
431430

431+
static uint8_t ws_generate_exluded_channel_list_from_active_channels(ws_excluded_channel_data_t *excluded_data, const uint32_t *selected_channel_mask, uint16_t number_of_channels)
432+
{
433+
bool active_range = false;
434+
435+
//Clear Old Data
436+
memset(excluded_data, 0, sizeof(ws_excluded_channel_data_t));
437+
438+
for (uint8_t i = 0; i < number_of_channels; i++) {
439+
if (selected_channel_mask[0 + (i / 32)] & (1 << (i % 32))) {
440+
if (active_range) {
441+
//Mark range stop here
442+
active_range = false;
443+
}
444+
} else {
445+
//Mark excluded channel
446+
//Swap Order already here
447+
excluded_data->channel_mask[0 + (i / 32)] |= 1 << (31 - (i % 32));
448+
excluded_data->excluded_channel_count++;
449+
450+
if (excluded_data->excluded_range_length < WS_EXCLUDED_MAX_RANGE_TO_SEND) {
451+
if (!active_range) {
452+
excluded_data->excluded_range_length++;
453+
active_range = true;
454+
//Set start channel
455+
excluded_data->exluded_range[excluded_data->excluded_range_length - 1].range_start = i;
456+
} else {
457+
excluded_data->exluded_range[excluded_data->excluded_range_length - 1].range_end = i;
458+
}
459+
}
460+
}
461+
}
462+
463+
excluded_data->channel_mask_bytes_inline = ((number_of_channels + 7) / 8);
464+
465+
uint8_t channel_plan = 0;
466+
if (excluded_data->excluded_range_length == 0) {
467+
excluded_data->excuded_channel_ctrl = WS_EXC_CHAN_CTRL_NONE;
468+
} else if (excluded_data->excluded_range_length <= WS_EXCLUDED_MAX_RANGE_TO_SEND) {
469+
470+
uint8_t range_length = (excluded_data->excluded_range_length * 4) + 3;
471+
if (range_length <= ((number_of_channels + 7) / 8) + 6) {
472+
excluded_data->excuded_channel_ctrl = WS_EXC_CHAN_CTRL_RANGE;
473+
} else {
474+
excluded_data->excuded_channel_ctrl = WS_EXC_CHAN_CTRL_BITMASK;
475+
channel_plan = 1;
476+
}
477+
} else {
478+
excluded_data->excuded_channel_ctrl = WS_EXC_CHAN_CTRL_BITMASK;
479+
channel_plan = 1;
480+
}
481+
tr_debug("Excluded ctrl %u, exluded channel count %u, total domain channels %u", excluded_data->excuded_channel_ctrl, excluded_data->excluded_channel_count, number_of_channels);
482+
return channel_plan;
483+
}
484+
485+
static void ws_fhss_configure_channel_masks(protocol_interface_info_entry_t *cur, fhss_ws_configuration_t *fhss_configuration)
486+
{
487+
ws_generate_channel_list(fhss_configuration->channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain);
488+
ws_generate_channel_list(fhss_configuration->unicast_channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain);
489+
// using bitwise AND operation for user set channel mask to remove channels not allowed in this device
490+
for (uint8_t n = 0; n < 8; n++) {
491+
fhss_configuration->unicast_channel_mask[n] &= cur->ws_info->cfg->fhss.fhss_channel_mask[n];
492+
}
493+
//Update Exluded channels
494+
cur->ws_info->hopping_schdule.channel_plan = ws_generate_exluded_channel_list_from_active_channels(&cur->ws_info->hopping_schdule.excluded_channels, fhss_configuration->unicast_channel_mask, cur->ws_info->hopping_schdule.number_of_channels);
495+
}
496+
432497
static int8_t ws_fhss_initialize(protocol_interface_info_entry_t *cur)
433498
{
434499
fhss_api_t *fhss_api = ns_sw_mac_get_fhss_api(cur->mac_api);
500+
fhss_ws_configuration_t fhss_configuration;
501+
memset(&fhss_configuration, 0, sizeof(fhss_ws_configuration_t));
435502
if (!fhss_api) {
436503
// When FHSS doesn't exist yet, create one
437-
fhss_ws_configuration_t fhss_configuration;
438-
memset(&fhss_configuration, 0, sizeof(fhss_ws_configuration_t));
439-
ws_generate_channel_list(fhss_configuration.channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain);
440-
441-
// using bitwise AND operation for user set channel mask to remove channels not allowed in this device
442-
for (uint8_t n = 0; n < 8; n++) {
443-
fhss_configuration.channel_mask[n] &= cur->ws_info->cfg->fhss.fhss_channel_mask[n];
444-
}
504+
ws_fhss_configure_channel_masks(cur, &fhss_configuration);
445505

446506
fhss_configuration.fhss_uc_dwell_interval = cur->ws_info->cfg->fhss.fhss_uc_dwell_interval;
447507
fhss_configuration.ws_uc_channel_function = (fhss_ws_channel_functions)cur->ws_info->cfg->fhss.fhss_uc_channel_function;
@@ -456,22 +516,27 @@ static int8_t ws_fhss_initialize(protocol_interface_info_entry_t *cur)
456516
ns_sw_mac_fhss_register(cur->mac_api, fhss_api);
457517
} else {
458518
// Read defaults from the configuration to help FHSS testing
459-
const fhss_ws_configuration_t *fhss_configuration = ns_fhss_ws_configuration_get(fhss_api);
460-
if (!fhss_configuration) {
519+
const fhss_ws_configuration_t *fhss_configuration_copy = ns_fhss_ws_configuration_get(fhss_api);
520+
if (!fhss_configuration_copy) {
461521
// no configuration set yet
462522
return 0;
463523
}
464-
memcpy(cur->ws_info->cfg->fhss.fhss_channel_mask, fhss_configuration->channel_mask, sizeof(uint32_t) * 8);
465-
cur->ws_info->cfg->fhss.fhss_uc_channel_function = fhss_configuration->ws_uc_channel_function;
466-
cur->ws_info->cfg->fhss.fhss_bc_channel_function = fhss_configuration->ws_bc_channel_function;
467-
cur->ws_info->cfg->fhss.fhss_bc_dwell_interval = fhss_configuration->fhss_bc_dwell_interval;
468-
cur->ws_info->cfg->fhss.fhss_bc_interval = fhss_configuration->fhss_broadcast_interval;
469-
cur->ws_info->cfg->fhss.fhss_uc_dwell_interval = fhss_configuration->fhss_uc_dwell_interval;
470-
cur->ws_info->cfg->fhss.fhss_bc_fixed_channel = fhss_configuration->broadcast_fixed_channel;
471-
cur->ws_info->cfg->fhss.fhss_uc_fixed_channel = fhss_configuration->unicast_fixed_channel;
524+
fhss_configuration = *fhss_configuration_copy;
525+
memcpy(cur->ws_info->cfg->fhss.fhss_channel_mask, fhss_configuration_copy->unicast_channel_mask, sizeof(uint32_t) * 8);
526+
cur->ws_info->cfg->fhss.fhss_uc_channel_function = fhss_configuration_copy->ws_uc_channel_function;
527+
cur->ws_info->cfg->fhss.fhss_bc_channel_function = fhss_configuration_copy->ws_bc_channel_function;
528+
cur->ws_info->cfg->fhss.fhss_bc_dwell_interval = fhss_configuration_copy->fhss_bc_dwell_interval;
529+
cur->ws_info->cfg->fhss.fhss_bc_interval = fhss_configuration_copy->fhss_broadcast_interval;
530+
cur->ws_info->cfg->fhss.fhss_uc_dwell_interval = fhss_configuration_copy->fhss_uc_dwell_interval;
531+
cur->ws_info->cfg->fhss.fhss_bc_fixed_channel = fhss_configuration_copy->broadcast_fixed_channel;
532+
cur->ws_info->cfg->fhss.fhss_uc_fixed_channel = fhss_configuration_copy->unicast_fixed_channel;
533+
ws_fhss_configure_channel_masks(cur, &fhss_configuration);
534+
ns_fhss_ws_configuration_set(fhss_api, &fhss_configuration);
472535
}
536+
473537
return 0;
474538
}
539+
475540
static int8_t ws_fhss_set_defaults(protocol_interface_info_entry_t *cur, fhss_ws_configuration_t *fhss_configuration)
476541
{
477542
fhss_configuration->fhss_uc_dwell_interval = cur->ws_info->cfg->fhss.fhss_uc_dwell_interval;
@@ -483,12 +548,6 @@ static int8_t ws_fhss_set_defaults(protocol_interface_info_entry_t *cur, fhss_ws
483548
fhss_configuration->unicast_fixed_channel = cur->ws_info->cfg->fhss.fhss_uc_fixed_channel;
484549
}
485550
fhss_configuration->broadcast_fixed_channel = cur->ws_info->cfg->fhss.fhss_bc_fixed_channel;
486-
ws_generate_channel_list(fhss_configuration->channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain);
487-
488-
// using bitwise AND operation for user set channel mask to remove channels not allowed in this device
489-
for (uint8_t n = 0; n < 8; n++) {
490-
fhss_configuration->channel_mask[n] &= cur->ws_info->cfg->fhss.fhss_channel_mask[n];
491-
}
492551
return 0;
493552
}
494553
static int8_t ws_fhss_border_router_configure(protocol_interface_info_entry_t *cur)
@@ -501,6 +560,7 @@ static int8_t ws_fhss_border_router_configure(protocol_interface_info_entry_t *c
501560
memcpy(&fhss_configuration, ns_fhss_ws_configuration_get(cur->ws_info->fhss_api), sizeof(fhss_ws_configuration_t));
502561
}
503562
ws_fhss_set_defaults(cur, &fhss_configuration);
563+
ws_fhss_configure_channel_masks(cur, &fhss_configuration);
504564
ns_fhss_ws_configuration_set(cur->ws_info->fhss_api, &fhss_configuration);
505565
ws_bootstrap_llc_hopping_update(cur, &fhss_configuration);
506566

@@ -525,6 +585,7 @@ static int8_t ws_fhss_configure(protocol_interface_info_entry_t *cur, bool disco
525585
if (ns_fhss_ws_configuration_get(cur->ws_info->fhss_api)) {
526586
memcpy(&fhss_configuration, ns_fhss_ws_configuration_get(cur->ws_info->fhss_api), sizeof(fhss_ws_configuration_t));
527587
ws_fhss_set_defaults(cur, &fhss_configuration);
588+
ws_fhss_configure_channel_masks(cur, &fhss_configuration);
528589
}
529590
// Discovery is done using fixed channel
530591
if (discovery) {
@@ -907,12 +968,54 @@ static parent_info_t *ws_bootstrap_candidate_parent_get_best(protocol_interface_
907968
return ns_list_get_first(&cur->ws_info->parent_list_reserved);
908969
}
909970

971+
static void ws_bootstrap_decode_exclude_range_to_mask_by_range(void *mask_buffer, ws_excluded_channel_range_t *range_info, uint16_t number_of_channels)
972+
{
973+
uint16_t range_start, range_stop;
974+
uint8_t mask_index = 0;
975+
//uint8_t channel_index = 0;
976+
uint8_t *range_ptr = range_info->range_start;
977+
uint32_t *mask_ptr = mask_buffer;
978+
while (range_info->number_of_range) {
979+
range_start = common_read_16_bit_inverse(range_ptr);
980+
range_ptr += 2;
981+
range_stop = common_read_16_bit_inverse(range_ptr);
982+
range_ptr += 2;
983+
range_info->number_of_range--;
984+
for (uint16_t channel = 0; channel < number_of_channels; channel++) {
985+
986+
if (channel && (channel % 32 == 0)) {
987+
mask_index++;
988+
//channel_index = 0;
989+
}
990+
if (channel >= range_start && channel <= range_stop) {
991+
//mask_ptr[mask_index] |= 1 << (31 - channel_index);
992+
mask_ptr[0 + (channel / 32)] |= 1 << (31 - (channel % 32));
993+
} else if (channel > range_stop) {
994+
break;
995+
}
996+
}
997+
}
998+
}
999+
9101000
static void ws_bootstrap_candidate_parent_store(parent_info_t *parent, const struct mcps_data_ind_s *data, ws_utt_ie_t *ws_utt, ws_us_ie_t *ws_us, ws_pan_information_t *pan_information)
9111001
{
9121002
parent->ws_utt = *ws_utt;
9131003
// Saved from unicast IE
9141004
parent->ws_us = *ws_us;
9151005

1006+
//copy excluded channel here if it is inline
1007+
if (ws_us->excluded_channel_ctrl == WS_EXC_CHAN_CTRL_RANGE) {
1008+
memset(parent->excluded_channel_data, 0, 32);
1009+
//Decode Range to mask here
1010+
ws_bootstrap_decode_exclude_range_to_mask_by_range(parent->excluded_channel_data, &parent->ws_us.excluded_channels.range, 256);
1011+
parent->ws_us.excluded_channels.mask.channel_mask = parent->excluded_channel_data;
1012+
parent->ws_us.excluded_channels.mask.mask_len_inline = 32;
1013+
parent->ws_us.excluded_channel_ctrl = WS_EXC_CHAN_CTRL_BITMASK;
1014+
} else if (ws_us->excluded_channel_ctrl == WS_EXC_CHAN_CTRL_BITMASK) {
1015+
parent->ws_us.excluded_channels.mask.channel_mask = parent->excluded_channel_data;
1016+
memcpy(parent->excluded_channel_data, ws_us->excluded_channels.mask.channel_mask, ws_us->excluded_channels.mask.mask_len_inline);
1017+
}
1018+
9161019
// Saved from Pan information, do not overwrite pan_version as it is not valid here
9171020
parent->pan_information.pan_size = pan_information->pan_size;
9181021
parent->pan_information.routing_cost = pan_information->routing_cost;
@@ -1099,6 +1202,13 @@ static void ws_bootstrap_pan_advertisement_analyse(struct protocol_interface_inf
10991202
return;
11001203
}
11011204

1205+
if (ws_us->excluded_channel_ctrl) {
1206+
//Validate that we can storage data
1207+
if (ws_us->excluded_channel_ctrl == WS_EXC_CHAN_CTRL_BITMASK && ws_us->excluded_channels.mask.mask_len_inline > 32) {
1208+
return;
1209+
}
1210+
}
1211+
11021212
// Check pan flags so that it is valid
11031213
if (!pan_information.rpl_routing_method) {
11041214
// NOT RPL routing
@@ -1415,11 +1525,6 @@ static void ws_bootstrap_asynch_ind(struct protocol_interface_info_entry *cur, c
14151525
return;
14161526
}
14171527

1418-
//Compare Unicast channel Plan
1419-
if (ws_us.channel_plan != cur->ws_info->hopping_schdule.channel_plan) {
1420-
return;
1421-
}
1422-
14231528
if (ws_us.channel_plan == 0) {
14241529
if (!ws_channel_plan_zero_compare(&ws_us.plan.zero, &cur->ws_info->hopping_schdule)) {
14251530
return;

source/6LoWPAN/ws/ws_common.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,6 @@ int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur,
203203
}
204204

205205
if (cur) {
206-
// Note: doesn't work for Brazil region
207-
ws_generate_channel_list(hopping_schdule->channel_mask, hopping_schdule->number_of_channels, hopping_schdule->regulatory_domain);
208206
ws_set_domain_rf_config(cur);
209207
}
210208
return 0;
@@ -293,9 +291,9 @@ int8_t ws_common_allocate_and_init(protocol_interface_info_entry_t *cur)
293291
// Timing accuracy is given from 0 to 2.55msec with 10usec resolution
294292
cur->ws_info->hopping_schdule.timing_accurancy = 100;
295293
ws_common_regulatory_domain_config(cur, &cur->ws_info->hopping_schdule);
296-
297294
cur->ws_info->pending_key_index_info.state = NO_PENDING_PROCESS;
298295

296+
299297
return 0;
300298
}
301299

source/6LoWPAN/ws/ws_common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ extern uint16_t test_max_child_count_override;
3535

3636
struct ws_pan_information_s;
3737
struct ws_neighbor_class_s;
38+
struct ws_excluded_channel_data_s;
3839
struct ws_cfg_s;
3940

4041
typedef struct parent_info_s {
@@ -47,6 +48,7 @@ typedef struct parent_info_s {
4748
ws_us_ie_t ws_us;
4849
uint32_t timestamp; /**< Timestamp when packet was received */
4950
uint32_t age; /**< Age of entry in 100ms ticks */
51+
uint8_t excluded_channel_data[32]; //Channel mask Max length and it accept 8 different range
5052
ns_list_link_t link;
5153
} parent_info_t;
5254

0 commit comments

Comments
 (0)