Skip to content

Commit

Permalink
Support channel plan IDs 1, 2 and 5 with NA and BZ bands (ARMmbed#2526)
Browse files Browse the repository at this point in the history
* Support channel plan IDs 1, 2 and 5 with NA and BZ bands

* Update CHANGELOG.md

Co-authored-by: Arto Kinnunen <Arto.Kinnunen@arm.com>

* Added empty functions

Co-authored-by: Arto Kinnunen <Arto.Kinnunen@arm.com>
  • Loading branch information
Jarkko Paso and Arto Kinnunen committed Dec 17, 2020
1 parent ee4333d commit 0a12aeb
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 66 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Release vxx.x.x

### Features
* Add support for FAN 1.1 PHY mode IDs (all) and Channel plan IDs 1, 2, and 5 for North American and Brazil domains. This change enables OFDM modulation usage for mentioned frequency bands.
* Wi-SUN timing parameters are selected based on Data rate and network size.
*

Expand Down
12 changes: 7 additions & 5 deletions nanostack/ws_management_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,13 @@ extern "C" {
#define CHANNEL_FUNCTION_DH1CF 0x02 // Direct Hash
#define CHANNEL_FUNCTION_VENDOR_DEFINED 0x03 // vendor given channel hop schedule

#define CHANNEL_SPACING_200 0x00 // 200 khz
#define CHANNEL_SPACING_400 0x01 // 400 khz
#define CHANNEL_SPACING_600 0x02 // 600 khz
#define CHANNEL_SPACING_100 0x03 // 100 khz
#define CHANNEL_SPACING_250 0x04 // 250 khz
#define CHANNEL_SPACING_200 0x00 // 200 khz
#define CHANNEL_SPACING_400 0x01 // 400 khz
#define CHANNEL_SPACING_600 0x02 // 600 khz
#define CHANNEL_SPACING_100 0x03 // 100 khz
#define CHANNEL_SPACING_250 0x04 // 250 khz
#define CHANNEL_SPACING_800 0x05 // 800 khz
#define CHANNEL_SPACING_1200 0x06 // 1200 khz

/*
* Network Size definitions are device amount in hundreds of devices.
Expand Down
6 changes: 3 additions & 3 deletions source/6LoWPAN/ws/ws_bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -624,8 +624,8 @@ static uint8_t ws_generate_exluded_channel_list_from_active_channels(ws_excluded

static void ws_fhss_configure_channel_masks(protocol_interface_info_entry_t *cur, fhss_ws_configuration_t *fhss_configuration)
{
ws_generate_channel_list(fhss_configuration->channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain, cur->ws_info->hopping_schdule.operating_class);
ws_generate_channel_list(fhss_configuration->unicast_channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain, cur->ws_info->hopping_schdule.operating_class);
ws_generate_channel_list(fhss_configuration->channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain, cur->ws_info->hopping_schdule.operating_class, cur->ws_info->hopping_schdule.channel_plan_id);
ws_generate_channel_list(fhss_configuration->unicast_channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain, cur->ws_info->hopping_schdule.operating_class, cur->ws_info->hopping_schdule.channel_plan_id);
// 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->unicast_channel_mask[n] &= cur->ws_info->cfg->fhss.fhss_channel_mask[n];
Expand Down Expand Up @@ -3133,7 +3133,7 @@ static void ws_set_asynch_channel_list(protocol_interface_info_entry_t *cur, asy
uint16_t channel_number = cur->ws_info->cfg->fhss.fhss_uc_fixed_channel;
async_req->channel_list.channel_mask[0 + (channel_number / 32)] = (1 << (channel_number % 32));
} else {
ws_generate_channel_list(async_req->channel_list.channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain, cur->ws_info->hopping_schdule.operating_class);
ws_generate_channel_list(async_req->channel_list.channel_mask, cur->ws_info->hopping_schdule.number_of_channels, cur->ws_info->hopping_schdule.regulatory_domain, cur->ws_info->hopping_schdule.operating_class, cur->ws_info->hopping_schdule.channel_plan_id);
}

async_req->channel_list.channel_page = CHANNEL_PAGE_10;
Expand Down
182 changes: 130 additions & 52 deletions source/6LoWPAN/ws/ws_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,33 +53,57 @@ uint8_t DEVICE_MIN_SENS = 174 - 93;

uint16_t test_max_child_count_override = 0xffff;

int8_t ws_generate_channel_list(uint32_t *channel_mask, uint16_t number_of_channels, uint8_t regulatory_domain, uint8_t operating_class)
static int8_t ws_disable_channels_in_range(uint32_t *channel_mask, uint16_t number_of_channels, uint16_t range_start, uint16_t range_stop)
{
uint32_t excluded_start_channel = 0xFFFFFFFF;
uint32_t excluded_end_channel = 0xFFFFFFFF;

if (regulatory_domain == REG_DOMAIN_BZ) {
if (operating_class == 1) {
excluded_start_channel = 26;
excluded_end_channel = 64;
} else if (operating_class == 2) {
excluded_start_channel = 12;
excluded_end_channel = 32;
} else if (operating_class == 3) {
excluded_start_channel = 7;
excluded_end_channel = 21;
for (uint16_t i = 0; i < number_of_channels; i++) {
if (i >= range_start && i <= range_stop) {
channel_mask[0 + (i / 32)] &= ~(1 << (i % 32));
}
}
return 0;
}

int8_t ws_generate_channel_list(uint32_t *channel_mask, uint16_t number_of_channels, uint8_t regulatory_domain, uint8_t operating_class, uint8_t channel_plan_id)
{
// Clear channel mask
for (uint8_t i = 0; i < 8; i++) {
channel_mask[i] = 0;
}

// Set channel maks outside excluded channels
// Enable all channels
for (uint16_t i = 0; i < number_of_channels; i++) {
if (i < excluded_start_channel || i > excluded_end_channel) {
channel_mask[0 + (i / 32)] |= (1 << (i % 32));
channel_mask[0 + (i / 32)] |= (1 << (i % 32));
}
// Disable unsupported channels per regional frequency bands
if (regulatory_domain == REG_DOMAIN_NA) {
if (channel_plan_id == 1) {
ws_disable_channels_in_range(channel_mask, number_of_channels, 1, 7);
} else if (channel_plan_id == 5) {
ws_disable_channels_in_range(channel_mask, number_of_channels, 5, 7);
}
}
if (regulatory_domain == REG_DOMAIN_BZ) {
if (channel_plan_id == 255) {
if (operating_class == 1) {
ws_disable_channels_in_range(channel_mask, number_of_channels, 26, 64);
} else if (operating_class == 2) {
ws_disable_channels_in_range(channel_mask, number_of_channels, 12, 32);
} else if (operating_class == 3) {
ws_disable_channels_in_range(channel_mask, number_of_channels, 7, 21);
}
} else {
if (channel_plan_id == 1) {
ws_disable_channels_in_range(channel_mask, number_of_channels, 1, 7);
ws_disable_channels_in_range(channel_mask, number_of_channels, 64, 64);
ws_disable_channels_in_range(channel_mask, number_of_channels, 72, 103);
ws_disable_channels_in_range(channel_mask, number_of_channels, 106, 111);
} else if (channel_plan_id == 2) {
ws_disable_channels_in_range(channel_mask, number_of_channels, 24, 24);
ws_disable_channels_in_range(channel_mask, number_of_channels, 32, 47);
ws_disable_channels_in_range(channel_mask, number_of_channels, 52, 55);
} else if (channel_plan_id == 5) {
ws_disable_channels_in_range(channel_mask, number_of_channels, 5, 10);
ws_disable_channels_in_range(channel_mask, number_of_channels, 19, 23);
}
}
}
return 0;
Expand Down Expand Up @@ -109,6 +133,10 @@ uint32_t ws_decode_channel_spacing(uint8_t channel_spacing)
return 400000;
} else if (CHANNEL_SPACING_600 == channel_spacing) {
return 600000;
} else if (CHANNEL_SPACING_800 == channel_spacing) {
return 800000;
} else if (CHANNEL_SPACING_1200 == channel_spacing) {
return 1200000;
}
return 0;
}
Expand Down Expand Up @@ -271,30 +299,60 @@ int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur,
return -1;
}
} else if (hopping_schdule->regulatory_domain == REG_DOMAIN_NA) {
if (hopping_schdule->operating_class == 1) {
hopping_schdule->ch0_freq = 9022;
hopping_schdule->channel_spacing = CHANNEL_SPACING_200;
} else if (hopping_schdule->operating_class == 2) {
hopping_schdule->ch0_freq = 9024;
hopping_schdule->channel_spacing = CHANNEL_SPACING_400;
} else if (hopping_schdule->operating_class == 3) {
hopping_schdule->ch0_freq = 9026;
hopping_schdule->channel_spacing = CHANNEL_SPACING_600;
if (hopping_schdule->channel_plan_id == 255) {
if (hopping_schdule->operating_class == 1) {
hopping_schdule->ch0_freq = 9022;
hopping_schdule->channel_spacing = CHANNEL_SPACING_200;
} else if (hopping_schdule->operating_class == 2) {
hopping_schdule->ch0_freq = 9024;
hopping_schdule->channel_spacing = CHANNEL_SPACING_400;
} else if (hopping_schdule->operating_class == 3) {
hopping_schdule->ch0_freq = 9026;
hopping_schdule->channel_spacing = CHANNEL_SPACING_600;
} else {
return -1;
}
} else {
return -1;
if (hopping_schdule->channel_plan_id == 1) {
hopping_schdule->ch0_freq = 9022;
hopping_schdule->channel_spacing = CHANNEL_SPACING_200;
} else if (hopping_schdule->channel_plan_id == 2) {
hopping_schdule->ch0_freq = 9024;
hopping_schdule->channel_spacing = CHANNEL_SPACING_400;
} else if (hopping_schdule->channel_plan_id == 5) {
hopping_schdule->ch0_freq = 9032;
hopping_schdule->channel_spacing = CHANNEL_SPACING_1200;
} else {
return -1;
}
}
} else if (hopping_schdule->regulatory_domain == REG_DOMAIN_BZ) {
if (hopping_schdule->operating_class == 1) {
hopping_schdule->ch0_freq = 9022;
hopping_schdule->channel_spacing = CHANNEL_SPACING_200;
} else if (hopping_schdule->operating_class == 2) {
hopping_schdule->ch0_freq = 9024;
hopping_schdule->channel_spacing = CHANNEL_SPACING_400;
} else if (hopping_schdule->operating_class == 3) {
hopping_schdule->ch0_freq = 9026;
hopping_schdule->channel_spacing = CHANNEL_SPACING_600;
if (hopping_schdule->channel_plan_id == 255) {
if (hopping_schdule->operating_class == 1) {
hopping_schdule->ch0_freq = 9022;
hopping_schdule->channel_spacing = CHANNEL_SPACING_200;
} else if (hopping_schdule->operating_class == 2) {
hopping_schdule->ch0_freq = 9024;
hopping_schdule->channel_spacing = CHANNEL_SPACING_400;
} else if (hopping_schdule->operating_class == 3) {
hopping_schdule->ch0_freq = 9026;
hopping_schdule->channel_spacing = CHANNEL_SPACING_600;
} else {
return -1;
}
} else {
return -1;
if (hopping_schdule->channel_plan_id == 1) {
hopping_schdule->ch0_freq = 9022;
hopping_schdule->channel_spacing = CHANNEL_SPACING_200;
} else if (hopping_schdule->channel_plan_id == 2) {
hopping_schdule->ch0_freq = 9024;
hopping_schdule->channel_spacing = CHANNEL_SPACING_400;
} else if (hopping_schdule->channel_plan_id == 5) {
hopping_schdule->ch0_freq = 9032;
hopping_schdule->channel_spacing = CHANNEL_SPACING_1200;
} else {
return -1;
}
}
} else if (hopping_schdule->regulatory_domain == REG_DOMAIN_JP) {
if (hopping_schdule->operating_class == 1) {
Expand Down Expand Up @@ -322,15 +380,15 @@ int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur,
} else {
return -1;
}
hopping_schdule->number_of_channels = (uint8_t)ws_common_channel_number_calc(hopping_schdule->regulatory_domain, hopping_schdule->operating_class);
hopping_schdule->number_of_channels = (uint8_t)ws_common_channel_number_calc(hopping_schdule->regulatory_domain, hopping_schdule->operating_class, hopping_schdule->channel_plan_id);
if (!hopping_schdule->number_of_channels) {
return -1;
}

return 0;
}

uint16_t ws_common_channel_number_calc(uint8_t regulatory_domain, uint8_t operating_class)
uint16_t ws_common_channel_number_calc(uint8_t regulatory_domain, uint8_t operating_class, uint8_t channel_plan_id)
{
if (regulatory_domain == REG_DOMAIN_KR) {
if (operating_class == 1) {
Expand All @@ -355,12 +413,22 @@ uint16_t ws_common_channel_number_calc(uint8_t regulatory_domain, uint8_t operat
return 10;
}
} else if (regulatory_domain == REG_DOMAIN_NA) {
if (operating_class == 1) {
return 129;
} else if (operating_class == 2) {
return 64;
} else if (operating_class == 3) {
return 42;
if (channel_plan_id == 255) {
if (operating_class == 1) {
return 129;
} else if (operating_class == 2) {
return 64;
} else if (operating_class == 3) {
return 42;
}
} else {
if (channel_plan_id == 1) {
return 136;
} else if (channel_plan_id == 2) {
return 64;
} else if (channel_plan_id == 5) {
return 24;
}
}
} else if (regulatory_domain == REG_DOMAIN_JP) {
if (operating_class == 1) {
Expand All @@ -371,12 +439,22 @@ uint16_t ws_common_channel_number_calc(uint8_t regulatory_domain, uint8_t operat
return 12;
}
} else if (regulatory_domain == REG_DOMAIN_BZ) {
if (operating_class == 1) {
return 129;
} else if (operating_class == 2) {
return 64;
} else if (operating_class == 3) {
return 42;
if (channel_plan_id == 255) {
if (operating_class == 1) {
return 129;
} else if (operating_class == 2) {
return 64;
} else if (operating_class == 3) {
return 42;
}
} else {
if (channel_plan_id == 1) {
return 136;
} else if (channel_plan_id == 2) {
return 64;
} else if (channel_plan_id == 5) {
return 24;
}
}
} else if (regulatory_domain == REG_DOMAIN_WW) {
if (operating_class == 1) {
Expand Down
4 changes: 2 additions & 2 deletions source/6LoWPAN/ws/ws_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ 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, uint8_t operating_class);
int8_t ws_generate_channel_list(uint32_t *channel_mask, uint16_t number_of_channels, uint8_t regulatory_domain, uint8_t operating_class, uint8_t channel_plan_id);

uint16_t ws_active_channel_count(uint32_t *channel_mask, uint16_t number_of_channels);

Expand All @@ -140,7 +140,7 @@ phy_modulation_index_e ws_get_modulation_index_using_operating_mode(uint8_t oper

int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur, ws_hopping_schedule_t *hopping_schdule);

uint16_t ws_common_channel_number_calc(uint8_t regulatory_domain, uint8_t operating_class);
uint16_t ws_common_channel_number_calc(uint8_t regulatory_domain, uint8_t operating_class, uint8_t channel_plan_id);

int8_t ws_common_allocate_and_init(protocol_interface_info_entry_t *cur);

Expand Down
18 changes: 18 additions & 0 deletions source/6LoWPAN/ws/ws_empty_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,24 @@ int ws_management_network_name_validate(
return -1;
}

int ws_management_phy_mode_id_set(
int8_t interface_id,
uint8_t phy_mode_id)
{
(void)interface_id;
(void)phy_mode_id;
return -1;
}

int ws_management_channel_plan_id_set(
int8_t interface_id,
uint8_t channel_plan_id)
{
(void)interface_id;
(void)channel_plan_id;
return -1;
}

int ws_management_regulatory_domain_set(
int8_t interface_id,
uint8_t regulatory_domain,
Expand Down
8 changes: 4 additions & 4 deletions source/6LoWPAN/ws/ws_neighbor_class.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,24 +254,24 @@ void ws_neighbor_class_neighbor_unicast_schedule_set(ws_neighbor_class_entry_t *
} else {

if (ws_us->channel_plan == 0) {
ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels = ws_common_channel_number_calc(ws_us->plan.zero.regulator_domain, ws_us->plan.zero.operation_class);
ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels = ws_common_channel_number_calc(ws_us->plan.zero.regulator_domain, ws_us->plan.zero.operation_class, own_shedule->channel_plan_id);
} else if (ws_us->channel_plan == 1) {
ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels = ws_us->plan.one.number_of_channel;

}

//Handle excluded channel and generate activate channel list
if (ws_us->excluded_channel_ctrl == WS_EXC_CHAN_CTRL_RANGE) {
ws_generate_channel_list(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels, own_shedule->regulatory_domain, own_shedule->operating_class);
ws_generate_channel_list(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels, own_shedule->regulatory_domain, own_shedule->operating_class, own_shedule->channel_plan_id);
ws_neighbor->fhss_data.uc_channel_list.channel_count = ws_active_channel_count(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels);
ws_neighbour_excluded_mask_by_range(&ws_neighbor->fhss_data.uc_channel_list, &ws_us->excluded_channels.range, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels);
} else if (ws_us->excluded_channel_ctrl == WS_EXC_CHAN_CTRL_BITMASK) {
ws_generate_channel_list(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels, own_shedule->regulatory_domain, own_shedule->operating_class);
ws_generate_channel_list(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels, own_shedule->regulatory_domain, own_shedule->operating_class, own_shedule->channel_plan_id);
ws_neighbor->fhss_data.uc_channel_list.channel_count = ws_active_channel_count(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels);
ws_neighbour_excluded_mask_by_mask(&ws_neighbor->fhss_data.uc_channel_list, &ws_us->excluded_channels.mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels);
} else if (ws_us->excluded_channel_ctrl == WS_EXC_CHAN_CTRL_NONE) {
if (ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels != ws_neighbor->fhss_data.uc_channel_list.channel_count) {
ws_generate_channel_list(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels, own_shedule->regulatory_domain, own_shedule->operating_class);
ws_generate_channel_list(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels, own_shedule->regulatory_domain, own_shedule->operating_class, own_shedule->channel_plan_id);
ws_neighbor->fhss_data.uc_channel_list.channel_count = ws_active_channel_count(ws_neighbor->fhss_data.uc_channel_list.channel_mask, ws_neighbor->fhss_data.uc_timing_info.unicast_number_of_channels);
}
}
Expand Down

0 comments on commit 0a12aeb

Please sign in to comment.