Skip to content

Commit

Permalink
WS: API to set PHY mode and Channel plan IDs as defined by FAN 1.1 (A…
Browse files Browse the repository at this point in the history
  • Loading branch information
Jarkko Paso committed Dec 16, 2020
1 parent b86a044 commit a5b2a26
Show file tree
Hide file tree
Showing 9 changed files with 302 additions and 7 deletions.
77 changes: 77 additions & 0 deletions nanostack/ws_management_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,83 @@ int ws_management_network_name_validate(
int8_t interface_id,
char *network_name_ptr);

/**
* Configure PHY mode ID of Wi-SUN stack as defined by Wi-SUN FAN 1.1.
*
* Change the default configuration for Wi-SUN PHY operation.
*
* Supported values:
* FSK without FEC:
* PHY mode ID | Symbol Rate (kbps) | Modulation Index
* 1 50 0.5
* 2 50 1.0
* 3 100 0.5
* 4 100 1.0
* 5 150 0.5
* 6 200 0.5
* 7 200 1.0
* 8 300 0.5
*
* FSK with FEC:
* PHY mode ID | Symbol Rate (kbps) | Modulation Index
* 17 50 0.5
* 18 50 1.0
* 19 100 0.5
* 20 100 1.0
* 21 150 0.5
* 22 200 0.5
* 23 200 1.0
* 24 300 0.5
*
* OFDM:
* PHY mode ID | Option | MCS | Data rate (kbps)
* 34 1 2 400
* 35 1 3 800
* 36 1 4 1200
* 37 1 5 1600
* 38 1 6 2400
* 51 2 3 400
* 52 2 4 600
* 53 2 5 800
* 54 2 6 1200
* 68 3 4 300
* 69 3 5 400
* 70 3 6 600
* 84 4 4 150
* 85 4 5 200
* 86 4 6 300
*
* if value of 255 is given then previous value is used.
*
* \param interface_id Network interface ID.
* \param phy_mode_id PHY mode ID. Default 255 (not used).
*
* \return 0, Init OK.
* \return <0 Init fail.
*/
int ws_management_phy_mode_id_set(
int8_t interface_id,
uint8_t phy_mode_id);

/**
* Configure Channel plan ID of Wi-SUN stack as defined by Wi-SUN FAN 1.1.
*
* Change the default channel configuration for Wi-SUN.
*
* Supported values: TBD
*
* if value of 255 is given then previous value is used.
*
* \param interface_id Network interface ID.
* \param channel_plan_id Channel plan ID. Default 255 (not used).
*
* \return 0, Init OK.
* \return <0 Init fail.
*/
int ws_management_channel_plan_id_set(
int8_t interface_id,
uint8_t channel_plan_id);

/**
* Configure regulatory domain of Wi-SUN stack.
*
Expand Down
24 changes: 21 additions & 3 deletions source/6LoWPAN/ws/ws_bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -2397,11 +2397,29 @@ static int ws_bootstrap_set_domain_rf_config(protocol_interface_info_entry_t *cu
{
phy_rf_channel_configuration_s rf_configs;
memset(&rf_configs, 0, sizeof(phy_rf_channel_configuration_s));

uint8_t phy_mode_id = cur->ws_info->hopping_schdule.phy_mode_id;
if (((phy_mode_id >= 34) && (phy_mode_id <= 38)) ||
((phy_mode_id >= 51) && (phy_mode_id <= 54)) ||
((phy_mode_id >= 68) && (phy_mode_id <= 70)) ||
((phy_mode_id >= 84) && (phy_mode_id <= 86))) {
rf_configs.modulation = M_OFDM;
rf_configs.datarate = ws_get_datarate_using_phy_mode_id(cur->ws_info->hopping_schdule.phy_mode_id);
rf_configs.ofdm_option = ws_get_ofdm_option_using_phy_mode_id(cur->ws_info->hopping_schdule.phy_mode_id);
rf_configs.ofdm_mcs = ws_get_ofdm_mcs_using_phy_mode_id(cur->ws_info->hopping_schdule.phy_mode_id);
} else {
if ((phy_mode_id >= 17) && (phy_mode_id <= 24)) {
rf_configs.fec = true;
} else {
rf_configs.fec = false;
}
rf_configs.modulation = M_2FSK;
rf_configs.datarate = ws_get_datarate_using_operating_mode(cur->ws_info->hopping_schdule.operating_mode);
rf_configs.modulation_index = ws_get_modulation_index_using_operating_mode(cur->ws_info->hopping_schdule.operating_mode);
}

rf_configs.channel_0_center_frequency = (uint32_t)cur->ws_info->hopping_schdule.ch0_freq * 100000;
rf_configs.channel_spacing = ws_decode_channel_spacing(cur->ws_info->hopping_schdule.channel_spacing);
rf_configs.datarate = ws_get_datarate_using_operating_mode(cur->ws_info->hopping_schdule.operating_mode);
rf_configs.modulation_index = ws_get_modulation_index_using_operating_mode(cur->ws_info->hopping_schdule.operating_mode);
rf_configs.modulation = M_2FSK;
rf_configs.number_of_channels = cur->ws_info->hopping_schdule.number_of_channels;
ws_bootstrap_set_rf_config(cur, rf_configs);
return 0;
Expand Down
34 changes: 30 additions & 4 deletions source/6LoWPAN/ws/ws_cfg_settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,8 @@ int8_t ws_cfg_phy_default_set(ws_phy_cfg_t *cfg)
cfg->regulatory_domain = REG_DOMAIN_EU;
cfg->operating_mode = OPERATING_MODE_3;
cfg->operating_class = 2;
cfg->phy_mode_id = 255;
cfg->channel_plan_id = 255;

return CFG_SETTINGS_OK;
}
Expand All @@ -671,12 +673,16 @@ int8_t ws_cfg_phy_validate(ws_phy_cfg_t *cfg, ws_phy_cfg_t *new_cfg)
// Regulator domain, operating mode or class has changed
if (cfg->regulatory_domain != new_cfg->regulatory_domain ||
cfg->operating_mode != new_cfg->operating_mode ||
cfg->operating_class != new_cfg->operating_class) {
cfg->operating_class != new_cfg->operating_class ||
cfg->phy_mode_id != new_cfg->phy_mode_id ||
cfg->channel_plan_id != new_cfg->channel_plan_id) {

ws_hopping_schedule_t hopping_schdule = {
.regulatory_domain = new_cfg->regulatory_domain,
.operating_mode = new_cfg->operating_mode,
.operating_class = new_cfg->operating_class
.operating_class = new_cfg->operating_class,
.phy_mode_id = new_cfg->phy_mode_id,
.channel_plan_id = new_cfg->channel_plan_id
};

// Check that new settings are valid
Expand All @@ -698,11 +704,31 @@ int8_t ws_cfg_phy_set(protocol_interface_info_entry_t *cur, ws_phy_cfg_t *cfg, w
if (ret != CFG_SETTINGS_CHANGED) {
return ret;
}

// Check settings and configure interface
if (cur && !(cfg_flags & CFG_FLAGS_DISABLE_VAL_SET)) {
// Set operating mode for FSK if given with PHY mode ID
if ((new_cfg->phy_mode_id == 1) || (new_cfg->phy_mode_id == 17)) {
cur->ws_info->hopping_schdule.operating_mode = OPERATING_MODE_1a;
} else if ((new_cfg->phy_mode_id == 2) || (new_cfg->phy_mode_id == 18)) {
cur->ws_info->hopping_schdule.operating_mode = OPERATING_MODE_1b;
} else if ((new_cfg->phy_mode_id == 3) || (new_cfg->phy_mode_id == 19)) {
cur->ws_info->hopping_schdule.operating_mode = OPERATING_MODE_2a;
} else if ((new_cfg->phy_mode_id == 4) || (new_cfg->phy_mode_id == 20)) {
cur->ws_info->hopping_schdule.operating_mode = OPERATING_MODE_2b;
} else if ((new_cfg->phy_mode_id == 5) || (new_cfg->phy_mode_id == 21)) {
cur->ws_info->hopping_schdule.operating_mode = OPERATING_MODE_3;
} else if ((new_cfg->phy_mode_id == 6) || (new_cfg->phy_mode_id == 22)) {
cur->ws_info->hopping_schdule.operating_mode = OPERATING_MODE_4a;
} else if ((new_cfg->phy_mode_id == 7) || (new_cfg->phy_mode_id == 23)) {
cur->ws_info->hopping_schdule.operating_mode = OPERATING_MODE_4b;
} else if ((new_cfg->phy_mode_id == 8) || (new_cfg->phy_mode_id == 24)) {
cur->ws_info->hopping_schdule.operating_mode = OPERATING_MODE_5;
} else {
cur->ws_info->hopping_schdule.operating_mode = new_cfg->operating_mode;
}
cur->ws_info->hopping_schdule.phy_mode_id = new_cfg->phy_mode_id;
cur->ws_info->hopping_schdule.channel_plan_id = new_cfg->channel_plan_id;
cur->ws_info->hopping_schdule.regulatory_domain = new_cfg->regulatory_domain;
cur->ws_info->hopping_schdule.operating_mode = new_cfg->operating_mode;
cur->ws_info->hopping_schdule.operating_class = new_cfg->operating_class;

if (ws_common_regulatory_domain_config(cur, &cur->ws_info->hopping_schdule) < 0) {
Expand Down
2 changes: 2 additions & 0 deletions source/6LoWPAN/ws/ws_cfg_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ typedef struct ws_phy_cfg_s {
uint8_t regulatory_domain; /**< PHY regulatory domain; default "KR" 0x09 */
uint8_t operating_class; /**< PHY operating class; default 1 */
uint8_t operating_mode; /**< PHY operating mode; default "1b" symbol rate 50, modulation index 1 */
uint8_t phy_mode_id; /**< PHY mode ID; default 255 (not used) */
uint8_t channel_plan_id; /**< Channel plan ID; default 255 (not used) */
} ws_phy_cfg_t;

/**
Expand Down
86 changes: 86 additions & 0 deletions source/6LoWPAN/ws/ws_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,60 @@ uint32_t ws_get_datarate_using_operating_mode(uint8_t operating_mode)
return 0;
}

uint32_t ws_get_datarate_using_phy_mode_id(uint8_t phy_mode_id)
{
if (84 == phy_mode_id) {
return 150000;
} else if (85 == phy_mode_id) {
return 200000;
} else if ((68 == phy_mode_id) || (86 == phy_mode_id)) {
return 300000;
} else if ((34 == phy_mode_id) || (51 == phy_mode_id) || (69 == phy_mode_id)) {
return 400000;
} else if ((52 == phy_mode_id) || (70 == phy_mode_id)) {
return 600000;
} else if ((35 == phy_mode_id) || (53 == phy_mode_id)) {
return 800000;
} else if ((36 == phy_mode_id) || (54 == phy_mode_id)) {
return 1200000;
} else if (37 == phy_mode_id) {
return 1600000;
} else if (38 == phy_mode_id) {
return 2400000;
}
return 0;
}

uint8_t ws_get_ofdm_option_using_phy_mode_id(uint8_t phy_mode_id)
{
if ((phy_mode_id >= 34) && (phy_mode_id <= 38)) {
return OFDM_OPTION_1;
} else if ((phy_mode_id >= 51) && (phy_mode_id <= 54)) {
return OFDM_OPTION_2;
} else if ((phy_mode_id >= 68) && (phy_mode_id <= 70)) {
return OFDM_OPTION_3;
} else if ((phy_mode_id >= 84) && (phy_mode_id <= 86)) {
return OFDM_OPTION_4;
}
return 0;
}

uint8_t ws_get_ofdm_mcs_using_phy_mode_id(uint8_t phy_mode_id)
{
if (34 == phy_mode_id) {
return OFDM_MCS_2;
} else if ((35 == phy_mode_id) || (51 == phy_mode_id)) {
return OFDM_MCS_3;
} else if ((36 == phy_mode_id) || (52 == phy_mode_id) || (68 == phy_mode_id) || (84 == phy_mode_id)) {
return OFDM_MCS_4;
} else if ((37 == phy_mode_id) || (53 == phy_mode_id) || (69 == phy_mode_id) || (85 == phy_mode_id)) {
return OFDM_MCS_5;
} else if ((38 == phy_mode_id) || (54 == phy_mode_id) || (70 == phy_mode_id) || (86 == phy_mode_id)) {
return OFDM_MCS_6;
}
return 0;
}

phy_modulation_index_e ws_get_modulation_index_using_operating_mode(uint8_t operating_mode)
{
if ((OPERATING_MODE_1b == operating_mode) || (OPERATING_MODE_2b == operating_mode) || (OPERATING_MODE_4b == operating_mode)) {
Expand All @@ -146,6 +200,38 @@ int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur,
return -1;
}

// Validate PHY mode ID
if (hopping_schdule->phy_mode_id != 255) {
uint8_t phy_mode_id = hopping_schdule->phy_mode_id;
uint8_t phy_type = phy_mode_id >> 4;
uint8_t phy_mode = phy_mode_id & 0x0f;
// Invalid PHY type
if (phy_type > 5) {
return -1;
}
// Invalid OFDM mode
if (phy_type >= 2 && phy_mode > 6) {
return -1;
}
// Skip if PHY mode is for FSK modulation
if (!phy_mode_id || ((phy_mode_id > 8) && (phy_mode_id < 17)) || phy_mode_id > 24) {
// Validate OFDM configurations
if (((phy_mode_id >= 34) && (phy_mode_id <= 38)) ||
((phy_mode_id >= 51) && (phy_mode_id <= 54)) ||
((phy_mode_id >= 68) && (phy_mode_id <= 70)) ||
((phy_mode_id >= 84) && (phy_mode_id <= 86))) {
if (ws_get_datarate_using_phy_mode_id(phy_mode_id) == 0 ||
ws_get_ofdm_option_using_phy_mode_id(phy_mode_id) == 0 ||
ws_get_ofdm_mcs_using_phy_mode_id(phy_mode_id) == 0) {
//Unsupported PHY mode
return -1;
}
} else {
// Invalid PHY mode ID
return -1;
}
}
}
hopping_schdule->channel_plan = 0;

if (hopping_schdule->regulatory_domain == REG_DOMAIN_KR) {
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 @@ -130,6 +130,12 @@ uint32_t ws_decode_channel_spacing(uint8_t channel_spacing);

uint32_t ws_get_datarate_using_operating_mode(uint8_t operating_mode);

uint32_t ws_get_datarate_using_phy_mode_id(uint8_t phy_mode_id);

uint8_t ws_get_ofdm_option_using_phy_mode_id(uint8_t phy_mode_id);

uint8_t ws_get_ofdm_mcs_using_phy_mode_id(uint8_t phy_mode_id);

phy_modulation_index_e ws_get_modulation_index_using_operating_mode(uint8_t operating_mode);

int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur, ws_hopping_schedule_t *hopping_schdule);
Expand Down
2 changes: 2 additions & 0 deletions source/6LoWPAN/ws/ws_common_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ typedef struct ws_hopping_schedule_s {
uint8_t regulatory_domain; /**< PHY regulatory domain default to "KR" 0x09 */
uint8_t operating_class; /**< PHY operating class default to 1 */
uint8_t operating_mode; /**< PHY operating mode default to "1b" symbol rate 50, modulation index 1 */
uint8_t phy_mode_id; /**< PHY mode ID, default to 255 */
uint8_t channel_plan_id; /**< Channel plan ID, default to 255 */
uint8_t channel_plan; /**< 0: use regulatory domain values 1: application defined plan */
uint8_t uc_channel_function; /**< 0: Fixed channel, 1:TR51CF, 2: Direct Hash, 3: Vendor defined */
uint8_t bc_channel_function; /**< 0: Fixed channel, 1:TR51CF, 2: Direct Hash, 3: Vendor defined */
Expand Down
68 changes: 68 additions & 0 deletions source/6LoWPAN/ws/ws_management_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,74 @@ int ws_management_network_name_validate(
return 0;
}

int ws_management_phy_mode_id_set(
int8_t interface_id,
uint8_t phy_mode_id)
{
protocol_interface_info_entry_t *cur;

cur = protocol_stack_interface_info_get_by_id(interface_id);
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}

ws_phy_cfg_t cfg;
ws_phy_cfg_t cfg_default;
if (ws_cfg_phy_get(&cfg, NULL) < 0) {
return -3;
}

if (ws_cfg_phy_default_set(&cfg_default) < 0) {
return -3;
}

if (phy_mode_id != 255) {
cfg.phy_mode_id = phy_mode_id;
} else {
cfg.phy_mode_id = cfg_default.phy_mode_id;
}

if (ws_cfg_phy_set(cur, NULL, &cfg, 0) < 0) {
return -4;
}

return 0;
}

int ws_management_channel_plan_id_set(
int8_t interface_id,
uint8_t channel_plan_id)
{
protocol_interface_info_entry_t *cur;

cur = protocol_stack_interface_info_get_by_id(interface_id);
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
return -1;
}

ws_phy_cfg_t cfg;
ws_phy_cfg_t cfg_default;
if (ws_cfg_phy_get(&cfg, NULL) < 0) {
return -3;
}

if (ws_cfg_phy_default_set(&cfg_default) < 0) {
return -3;
}

if (channel_plan_id != 255) {
cfg.channel_plan_id = channel_plan_id;
} else {
cfg.channel_plan_id = cfg_default.channel_plan_id;
}

if (ws_cfg_phy_set(cur, NULL, &cfg, 0) < 0) {
return -4;
}

return 0;
}

int ws_management_regulatory_domain_set(
int8_t interface_id,
uint8_t regulatory_domain,
Expand Down

0 comments on commit a5b2a26

Please sign in to comment.