LoRa: get_phy_params() refactored

- get_phy_params function was very heavy weight and needed to be refactored.
- switch-case clauses have been refactored to be functions now and the complexity of the usage has been improved a lot.
- There are no functional changes, this is internal only change
pull/6279/head
Antti Kauppila 2018-03-04 11:21:26 +02:00
parent 3c7bd1b794
commit d1cdd77290
13 changed files with 404 additions and 791 deletions

View File

@ -224,11 +224,6 @@ lorawan_status_t LoRaWANStack::send_compliance_test_frame_to_mac()
{
loramac_mcps_req_t mcps_req;
get_phy_params_t phy_params;
phy_param_t default_datarate;
phy_params.attribute = PHY_DEF_TX_DR;
default_datarate = _lora_phy.get_phy_params(&phy_params);
prepare_special_tx_frame(_compliance_test.app_port);
if (!_compliance_test.is_tx_confirmed) {
@ -236,7 +231,7 @@ lorawan_status_t LoRaWANStack::send_compliance_test_frame_to_mac()
mcps_req.req.unconfirmed.fport = _compliance_test.app_port;
mcps_req.f_buffer = _tx_msg.f_buffer;
mcps_req.f_buffer_size = _tx_msg.f_buffer_size;
mcps_req.req.unconfirmed.data_rate = default_datarate.value;
mcps_req.req.unconfirmed.data_rate = _lora_phy.get_default_tx_datarate();
tr_info("Transmit unconfirmed compliance test frame %d bytes.", mcps_req.f_buffer_size);
@ -249,7 +244,7 @@ lorawan_status_t LoRaWANStack::send_compliance_test_frame_to_mac()
mcps_req.f_buffer = _tx_msg.f_buffer;
mcps_req.f_buffer_size = _tx_msg.f_buffer_size;
mcps_req.req.confirmed.nb_trials = _num_retry;
mcps_req.req.confirmed.data_rate = default_datarate.value;
mcps_req.req.confirmed.data_rate = _lora_phy.get_default_tx_datarate();
tr_info("Transmit confirmed compliance test frame %d bytes.", mcps_req.f_buffer_size);
@ -286,11 +281,6 @@ lorawan_status_t LoRaWANStack::send_frame_to_mac()
lorawan_status_t status;
loramac_mib_req_confirm_t mib_get_params;
get_phy_params_t phy_params;
phy_param_t default_datarate;
phy_params.attribute = PHY_DEF_TX_DR;
default_datarate = _lora_phy.get_phy_params(&phy_params);
mcps_req.type = _tx_msg.type;
if (MCPS_UNCONFIRMED == mcps_req.type) {
@ -302,7 +292,7 @@ lorawan_status_t LoRaWANStack::send_frame_to_mac()
mib_get_params.type = MIB_CHANNELS_DATARATE;
if(mib_get_request(&mib_get_params) != LORAWAN_STATUS_OK) {
tr_debug("Couldn't get MIB parameters: Using default data rate");
mcps_req.req.unconfirmed.data_rate = default_datarate.value;
mcps_req.req.unconfirmed.data_rate = _lora_phy.get_default_tx_datarate();
} else {
mcps_req.req.unconfirmed.data_rate = mib_get_params.param.channel_data_rate;
}
@ -316,7 +306,7 @@ lorawan_status_t LoRaWANStack::send_frame_to_mac()
mib_get_params.type = MIB_CHANNELS_DATARATE;
if(mib_get_request(&mib_get_params) != LORAWAN_STATUS_OK) {
tr_debug("Couldn't get MIB parameters: Using default data rate");
mcps_req.req.confirmed.data_rate = default_datarate.value;
mcps_req.req.confirmed.data_rate = _lora_phy.get_default_tx_datarate();
} else {
mcps_req.req.confirmed.data_rate = mib_get_params.param.channel_data_rate;
}
@ -328,7 +318,7 @@ lorawan_status_t LoRaWANStack::send_frame_to_mac()
mib_get_params.type = MIB_CHANNELS_DATARATE;
if(mib_get_request(&mib_get_params) != LORAWAN_STATUS_OK) {
tr_debug("Couldn't get MIB parameters: Using default data rate");
mcps_req.req.proprietary.data_rate = default_datarate.value;
mcps_req.req.proprietary.data_rate = _lora_phy.get_default_tx_datarate();
} else {
mcps_req.req.proprietary.data_rate = mib_get_params.param.channel_data_rate;
}

View File

@ -218,8 +218,6 @@ void LoRaMac::handle_rx2_timer_event(void)
**************************************************************************/
void LoRaMac::on_radio_tx_done( void )
{
get_phy_params_t get_phy;
phy_param_t phy_param;
set_band_txdone_params_t tx_done_params;
lorawan_time_t cur_time = _lora_time.get_current_time( );
loramac_mlme_confirm_t mlme_confirm = mlme.get_confirmation();
@ -240,10 +238,8 @@ void LoRaMac::on_radio_tx_done( void )
if ((_params.dev_class == CLASS_C ) ||
(_params.is_node_ack_requested == true)) {
get_phy.attribute = PHY_ACK_TIMEOUT;
phy_param = lora_phy->get_phy_params(&get_phy);
_lora_time.start(_params.timers.ack_timeout_timer,
_params.rx_window2_delay + phy_param.value);
_params.rx_window2_delay + lora_phy->get_ack_timeout());
}
} else {
mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_OK;
@ -303,8 +299,6 @@ void LoRaMac::on_radio_rx_done(uint8_t *payload, uint16_t size, int16_t rssi,
loramac_mhdr_t mac_hdr;
loramac_frame_ctrl_t fctrl;
cflist_params_t cflist;
get_phy_params_t get_phy;
phy_param_t phy_param;
bool skip_indication = false;
uint8_t pkt_header_len = 0;
@ -428,18 +422,9 @@ void LoRaMac::on_radio_rx_done(uint8_t *payload, uint16_t size, int16_t rssi,
case FRAME_TYPE_DATA_CONFIRMED_DOWN:
case FRAME_TYPE_DATA_UNCONFIRMED_DOWN:
{
// Check if the received payload size is valid
get_phy.datarate = mcps.get_indication().rx_datarate;
get_phy.attribute = PHY_MAX_PAYLOAD;
uint8_t value = lora_phy->get_max_payload(mcps.get_indication().rx_datarate, _params.is_repeater_supported);
// Get the maximum payload length
if (_params.is_repeater_supported == true) {
get_phy.attribute = PHY_MAX_PAYLOAD_REPEATER;
}
phy_param = lora_phy->get_phy_params(&get_phy);
if (MAX(0, (int16_t) ((int16_t)size - (int16_t)LORA_MAC_FRMPAYLOAD_OVERHEAD )) > (int32_t)phy_param.value) {
if (MAX(0, (int16_t) ((int16_t)size - (int16_t)LORA_MAC_FRMPAYLOAD_OVERHEAD )) > (int32_t)value) {
mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ERROR;
prepare_rx_done_abort();
return;
@ -516,11 +501,7 @@ void LoRaMac::on_radio_rx_done(uint8_t *payload, uint16_t size, int16_t rssi,
}
}
// Check for a the maximum allowed counter difference
get_phy.attribute = PHY_MAX_FCNT_GAP;
phy_param = lora_phy->get_phy_params(&get_phy);
if (sequence_counter_diff >= phy_param.value) {
if (sequence_counter_diff >= lora_phy->get_maximum_frame_counter_gap()) {
mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS;
mcps.get_indication().dl_frame_counter = downlink_counter;
prepare_rx_done_abort( );
@ -816,8 +797,6 @@ void LoRaMac::on_radio_rx_timeout(void)
**************************************************************************/
void LoRaMac::on_mac_state_check_timer_event(void)
{
get_phy_params_t get_phy;
phy_param_t phy_param;
bool tx_timeout = false;
_lora_time.stop(_params.timers.mac_state_check_timer);
@ -916,10 +895,8 @@ void LoRaMac::on_mac_state_check_timer_event(void)
_params.ack_timeout_retry_counter++;
if ((_params.ack_timeout_retry_counter % 2) == 1) {
get_phy.attribute = PHY_NEXT_LOWER_TX_DR;
get_phy.datarate = _params.sys_params.channel_data_rate;
phy_param = lora_phy->get_phy_params( &get_phy );
_params.sys_params.channel_data_rate = phy_param.value;
_params.sys_params.channel_data_rate = lora_phy->get_next_lower_tx_datarate(
_params.sys_params.channel_data_rate);
}
// Try to send the frame again
@ -1116,21 +1093,10 @@ void LoRaMac::rx_window_setup(bool rx_continuous, uint32_t max_rx_window_time)
bool LoRaMac::validate_payload_length(uint8_t length, int8_t datarate,
uint8_t fopts_len)
{
get_phy_params_t get_phy;
phy_param_t phy_param;
uint16_t max_value = 0;
uint16_t payloadSize = 0;
// Setup PHY request
get_phy.datarate = datarate;
get_phy.attribute = PHY_MAX_PAYLOAD;
// Get the maximum payload length
if (_params.is_repeater_supported == true) {
get_phy.attribute = PHY_MAX_PAYLOAD_REPEATER;
}
phy_param = lora_phy->get_phy_params(&get_phy);
max_value = phy_param.value;
max_value = lora_phy->get_max_payload(datarate, _params.is_repeater_supported);
// Calculate the resulting payload size
payloadSize = (length + fopts_len);
@ -1186,8 +1152,6 @@ lorawan_status_t LoRaMac::schedule_tx(void)
{
lorawan_time_t dutyCycleTimeOff = 0;
channel_selection_params_t nextChan;
get_phy_params_t getPhy;
phy_param_t phyParam;
// Check if the device is off
if (_params.sys_params.max_duty_cycle == 255) {
@ -1212,10 +1176,7 @@ lorawan_status_t LoRaMac::schedule_tx(void)
while (lora_phy->set_next_channel(&nextChan, &_params.channel,
&dutyCycleTimeOff,
&_params.timers.aggregated_timeoff) == false) {
// Set the default datarate
getPhy.attribute = PHY_DEF_TX_DR;
phyParam = lora_phy->get_phy_params(&getPhy);
_params.sys_params.channel_data_rate = phyParam.value;
_params.sys_params.channel_data_rate = lora_phy->get_default_tx_datarate();
// Update datarate in the function parameters
nextChan.current_datarate = _params.sys_params.channel_data_rate;
}
@ -1291,9 +1252,6 @@ void LoRaMac::calculate_backOff(uint8_t channel)
void LoRaMac::reset_mac_parameters(void)
{
get_phy_params_t get_phy;
phy_param_t phy_param;
_params.is_nwk_joined = false;
// Counters
@ -1316,37 +1274,21 @@ void LoRaMac::reset_mac_parameters(void)
_params.is_rx_window_enabled = true;
get_phy.attribute = PHY_DEF_TX_POWER;
phy_param = lora_phy->get_phy_params(&get_phy);
_params.sys_params.channel_tx_power = lora_phy->get_default_tx_power();
_params.sys_params.channel_tx_power = phy_param.value;
_params.sys_params.channel_data_rate = lora_phy->get_default_tx_datarate();
get_phy.attribute = PHY_DEF_TX_DR;
phy_param = lora_phy->get_phy_params(&get_phy);
_params.sys_params.channel_data_rate = phy_param.value;
_params.sys_params.rx1_dr_offset = lora_phy->get_default_datarate1_offset();
get_phy.attribute = PHY_DEF_DR1_OFFSET;
phy_param = lora_phy->get_phy_params(&get_phy);
_params.sys_params.rx1_dr_offset = phy_param.value;
_params.sys_params.rx2_channel.frequency = lora_phy->get_default_rx2_frequency();
get_phy.attribute = PHY_DEF_RX2_FREQUENCY;
phy_param = lora_phy->get_phy_params(&get_phy);
_params.sys_params.rx2_channel.frequency = phy_param.value;
get_phy.attribute = PHY_DEF_RX2_DR;
phy_param = lora_phy->get_phy_params(&get_phy);
_params.sys_params.rx2_channel.datarate = phy_param.value;
_params.sys_params.rx2_channel.datarate = lora_phy->get_default_rx2_datarate();
get_phy.attribute = PHY_DEF_UPLINK_DWELL_TIME;
phy_param = lora_phy->get_phy_params(&get_phy);
_params.sys_params.uplink_dwell_time = phy_param.value;
_params.sys_params.uplink_dwell_time = lora_phy->get_default_uplink_dwell_time();
get_phy.attribute = PHY_DEF_MAX_EIRP;
phy_param = lora_phy->get_phy_params(&get_phy);
_params.sys_params.max_eirp = phy_param.value;
_params.sys_params.max_eirp = lora_phy->get_default_max_eirp();
get_phy.attribute = PHY_DEF_ANTENNA_GAIN;
phy_param = lora_phy->get_phy_params(&get_phy);
_params.sys_params.antenna_gain = phy_param.value;
_params.sys_params.antenna_gain = lora_phy->get_default_antenna_gain();
_params.is_node_ack_requested = false;
_params.is_srv_ack_requested = false;
@ -1654,9 +1596,6 @@ lorawan_status_t LoRaMac::set_tx_continuous_wave1(uint16_t timeout,
lorawan_status_t LoRaMac::initialize(loramac_primitives_t *primitives,
LoRaPHY *phy, EventQueue *queue)
{
get_phy_params_t get_phy;
phy_param_t phy_param;
//store event queue pointer
ev_queue = queue;
@ -1676,7 +1615,7 @@ lorawan_status_t LoRaMac::initialize(loramac_primitives_t *primitives,
mib.activate_mib_subsystem(this, lora_phy);
// Activate channel planning subsystem
channel_plan.activate_channelplan_subsystem(lora_phy, &mib);
channel_plan.activate_channelplan_subsystem(lora_phy);
mac_primitives = primitives;
@ -1693,67 +1632,35 @@ lorawan_status_t LoRaMac::initialize(loramac_primitives_t *primitives,
_params.timers.aggregated_last_tx_time = 0;
_params.timers.aggregated_timeoff = 0;
// Reset to defaults
get_phy.attribute = PHY_DUTY_CYCLE;
phy_param = lora_phy->get_phy_params(&get_phy);
// load default at this moment. Later can be changed using json
_params.is_dutycycle_on = (bool) phy_param.value;
_params.is_dutycycle_on = lora_phy->duty_cycle_enabled();
get_phy.attribute = PHY_DEF_TX_POWER;
phy_param = lora_phy->get_phy_params(&get_phy);
_params.sys_params.channel_tx_power = phy_param.value;
_params.sys_params.channel_tx_power = lora_phy->get_default_tx_power();
get_phy.attribute = PHY_DEF_TX_DR;
phy_param = lora_phy->get_phy_params(&get_phy);
_params.sys_params.channel_data_rate = phy_param.value;
_params.sys_params.channel_data_rate = lora_phy->get_default_tx_datarate();
get_phy.attribute = PHY_MAX_RX_WINDOW;
phy_param = lora_phy->get_phy_params(&get_phy);
_params.sys_params.max_rx_win_time = phy_param.value;
_params.sys_params.max_rx_win_time = lora_phy->get_maximum_receive_window_duration();
get_phy.attribute = PHY_RECEIVE_DELAY1;
phy_param = lora_phy->get_phy_params(&get_phy);
_params.sys_params.recv_delay1 = phy_param.value;
_params.sys_params.recv_delay1 = lora_phy->get_window1_receive_delay();
get_phy.attribute = PHY_RECEIVE_DELAY2;
phy_param = lora_phy->get_phy_params(&get_phy);
_params.sys_params.recv_delay2 = phy_param.value;
_params.sys_params.recv_delay2 = lora_phy->get_window2_receive_delay();
get_phy.attribute = PHY_JOIN_ACCEPT_DELAY1;
phy_param = lora_phy->get_phy_params(&get_phy);
_params.sys_params.join_accept_delay1 = phy_param.value;
_params.sys_params.join_accept_delay1 = lora_phy->get_window1_join_accept_delay();
get_phy.attribute = PHY_JOIN_ACCEPT_DELAY2;
phy_param = lora_phy->get_phy_params(&get_phy);
_params.sys_params.join_accept_delay2 = phy_param.value;
_params.sys_params.join_accept_delay2 = lora_phy->get_window2_join_accept_delay();
get_phy.attribute = PHY_DEF_DR1_OFFSET;
phy_param = lora_phy->get_phy_params(&get_phy);
_params.sys_params.rx1_dr_offset = phy_param.value;
_params.sys_params.rx1_dr_offset = lora_phy->get_default_datarate1_offset();
get_phy.attribute = PHY_DEF_RX2_FREQUENCY;
phy_param = lora_phy->get_phy_params(&get_phy);
_params.sys_params.rx2_channel.frequency = phy_param.value;
_params.sys_params.rx2_channel.frequency = lora_phy->get_default_rx2_frequency();
get_phy.attribute = PHY_DEF_RX2_DR;
phy_param = lora_phy->get_phy_params(&get_phy);
_params.sys_params.rx2_channel.datarate = phy_param.value;
_params.sys_params.rx2_channel.datarate = lora_phy->get_default_rx2_datarate();
get_phy.attribute = PHY_DEF_UPLINK_DWELL_TIME;
phy_param = lora_phy->get_phy_params(&get_phy);
_params.sys_params.uplink_dwell_time = phy_param.value;
_params.sys_params.uplink_dwell_time = lora_phy->get_default_uplink_dwell_time();
get_phy.attribute = PHY_DEF_DOWNLINK_DWELL_TIME;
phy_param = lora_phy->get_phy_params(&get_phy);
_params.sys_params.downlink_dwell_time = phy_param.value;
_params.sys_params.downlink_dwell_time = lora_phy->get_default_downlink_dwell_time();
get_phy.attribute = PHY_DEF_MAX_EIRP;
phy_param = lora_phy->get_phy_params(&get_phy);
_params.sys_params.max_eirp = phy_param.f_value;
_params.sys_params.max_eirp = lora_phy->get_default_max_eirp();
get_phy.attribute = PHY_DEF_ANTENNA_GAIN;
phy_param = lora_phy->get_phy_params(&get_phy);
_params.sys_params.antenna_gain = phy_param.f_value;
_params.sys_params.antenna_gain = lora_phy->get_default_antenna_gain();
// Init parameters which are not set in function ResetMacParameters
_params.sys_params.max_sys_rx_error = 10;
@ -1820,9 +1727,6 @@ void LoRaMac::disconnect()
lorawan_status_t LoRaMac::query_tx_possible(uint8_t size,
loramac_tx_info_t* tx_info)
{
get_phy_params_t get_phy;
phy_param_t phy_param;
uint8_t fopt_len = mac_commands.get_mac_cmd_length()
+ mac_commands.get_repeat_commands_length();
@ -1837,16 +1741,8 @@ lorawan_status_t LoRaMac::query_tx_possible(uint8_t size,
_params.adr_ack_counter);
}
// Setup PHY request
get_phy.datarate = _params.sys_params.channel_data_rate;
get_phy.attribute = PHY_MAX_PAYLOAD;
tx_info->current_payload_size = lora_phy->get_max_payload(_params.sys_params.channel_data_rate, _params.is_repeater_supported);
// Change request in case repeater is supported
if (_params.is_repeater_supported == true) {
get_phy.attribute = PHY_MAX_PAYLOAD_REPEATER;
}
phy_param = lora_phy->get_phy_params(&get_phy);
tx_info->current_payload_size = phy_param.value;
// Verify if the fOpts fit into the maximum payload
if (tx_info->current_payload_size >= fopt_len) {
@ -1894,7 +1790,18 @@ lorawan_status_t LoRaMac::remove_channel_plan()
lorawan_status_t LoRaMac::get_channel_plan(lorawan_channelplan_t& plan)
{
return channel_plan.get_plan(plan, &_params);
// Request Mib to get channels
loramac_mib_req_confirm_t mib_confirm;
memset(&mib_confirm, 0, sizeof(mib_confirm));
mib_confirm.type = MIB_CHANNELS;
lorawan_status_t status = mib.get_request(&mib_confirm, &_params);
if (status != LORAWAN_STATUS_OK) {
return status;
}
return channel_plan.get_plan(plan, &mib_confirm);
}
lorawan_status_t LoRaMac::remove_single_channel(uint8_t id)
@ -1984,7 +1891,9 @@ lorawan_status_t LoRaMac::mcps_request( loramac_mcps_req_t *mcpsRequest )
return LORAWAN_STATUS_BUSY;
}
return mcps.set_request(mcpsRequest, &_params);
lorawan_status_t status = mcps.set_request(mcpsRequest, &_params);
return status;
}
lorawan_status_t LoRaMac::mib_get_request_confirm( loramac_mib_req_confirm_t *mibGet )
@ -2038,11 +1947,7 @@ void LoRaMac::LoRaMacTestSetMic( uint16_t txPacketCounter )
void LoRaMac::LoRaMacTestSetDutyCycleOn( bool enable )
{
VerifyParams_t verify;
verify.DutyCycle = enable;
if(lora_phy->verify(&verify, PHY_DUTY_CYCLE) == true)
if(lora_phy->verify_duty_cycle(enable) == true)
{
_params.is_dutycycle_on = enable;
}

View File

@ -25,7 +25,7 @@ SPDX-License-Identifier: BSD-3-Clause
#include "lorastack/mac/LoRaMacChannelPlan.h"
LoRaMacChannelPlan::LoRaMacChannelPlan() : _lora_phy(NULL), _mib(NULL)
LoRaMacChannelPlan::LoRaMacChannelPlan() : _lora_phy(NULL)
{
}
@ -33,10 +33,9 @@ LoRaMacChannelPlan::~LoRaMacChannelPlan()
{
}
void LoRaMacChannelPlan::activate_channelplan_subsystem(LoRaPHY *phy, LoRaMacMib *mib)
void LoRaMacChannelPlan::activate_channelplan_subsystem(LoRaPHY *phy)
{
_lora_phy = phy;
_mib = mib;
}
lorawan_status_t LoRaMacChannelPlan::set_plan(const lorawan_channelplan_t& plan)
@ -44,22 +43,13 @@ lorawan_status_t LoRaMacChannelPlan::set_plan(const lorawan_channelplan_t& plan)
channel_params_t mac_layer_ch_params;
lorawan_status_t status;
get_phy_params_t get_phy;
phy_param_t phy_param;
uint8_t max_num_channels;
// Check if the PHY layer supports custom channel plans or not.
get_phy.attribute = PHY_CUSTOM_CHANNEL_PLAN_SUPPORT;
phy_param = _lora_phy->get_phy_params(&get_phy);
if (!phy_param.value) {
if (!_lora_phy->is_custom_channel_plan_supported()) {
return LORAWAN_STATUS_SERVICE_UNKNOWN;
}
// Check first how many channels the selected PHY layer supports
get_phy.attribute = PHY_MAX_NB_CHANNELS;
phy_param = _lora_phy->get_phy_params(&get_phy);
max_num_channels = (uint8_t) phy_param.value;
max_num_channels = _lora_phy->get_max_nb_channels();
// check if user is setting more channels than supported
if (plan.nb_channels > max_num_channels) {
@ -87,48 +77,23 @@ lorawan_status_t LoRaMacChannelPlan::set_plan(const lorawan_channelplan_t& plan)
}
lorawan_status_t LoRaMacChannelPlan::get_plan(lorawan_channelplan_t& plan,
loramac_protocol_params *params)
const loramac_mib_req_confirm_t* mib_confirm)
{
if (params == NULL) {
if (mib_confirm == NULL) {
return LORAWAN_STATUS_PARAMETER_INVALID;
}
loramac_mib_req_confirm_t mib_confirm;
lorawan_status_t status;
get_phy_params_t get_phy;
phy_param_t phy_param;
uint8_t max_num_channels;
uint16_t *channel_mask;
uint8_t count = 0;
// Check if the PHY layer supports custom channel plans or not.
get_phy.attribute = PHY_CUSTOM_CHANNEL_PLAN_SUPPORT;
phy_param = _lora_phy->get_phy_params(&get_phy);
if (!phy_param.value) {
if (!_lora_phy->is_custom_channel_plan_supported()) {
return LORAWAN_STATUS_SERVICE_UNKNOWN;
}
// Check first how many channels the selected PHY layer supports
get_phy.attribute = PHY_MAX_NB_CHANNELS;
phy_param = _lora_phy->get_phy_params(&get_phy);
max_num_channels = (uint8_t) phy_param.value;
max_num_channels = _lora_phy->get_max_nb_channels();
// Now check the Default channel mask
get_phy.attribute = PHY_CHANNEL_MASK;
phy_param = _lora_phy->get_phy_params(&get_phy);
channel_mask = phy_param.channel_mask;
// Request Mib to get channels
memset(&mib_confirm, 0, sizeof(mib_confirm));
mib_confirm.type = MIB_CHANNELS;
status = _mib->get_request(&mib_confirm, params);
if (status != LORAWAN_STATUS_OK) {
return status;
}
channel_mask = _lora_phy->get_channel_mask(false);
for (uint8_t i = 0; i < max_num_channels; i++) {
// skip the channels which are not enabled
@ -138,12 +103,12 @@ lorawan_status_t LoRaMacChannelPlan::get_plan(lorawan_channelplan_t& plan,
// otherwise add them to the channel_plan struct
plan.channels[count].id = i;
plan.channels[count].ch_param.frequency = mib_confirm.param.channel_list[i].frequency;
plan.channels[count].ch_param.dr_range.value = mib_confirm.param.channel_list[i].dr_range.value;
plan.channels[count].ch_param.dr_range.fields.min = mib_confirm.param.channel_list[i].dr_range.fields.min;
plan.channels[count].ch_param.dr_range.fields.max = mib_confirm.param.channel_list[i].dr_range.fields.max;
plan.channels[count].ch_param.band = mib_confirm.param.channel_list[i].band;
plan.channels[count].ch_param.rx1_frequency = mib_confirm.param.channel_list[i].rx1_frequency;
plan.channels[count].ch_param.frequency = mib_confirm->param.channel_list[i].frequency;
plan.channels[count].ch_param.dr_range.value = mib_confirm->param.channel_list[i].dr_range.value;
plan.channels[count].ch_param.dr_range.fields.min = mib_confirm->param.channel_list[i].dr_range.fields.min;
plan.channels[count].ch_param.dr_range.fields.max = mib_confirm->param.channel_list[i].dr_range.fields.max;
plan.channels[count].ch_param.band = mib_confirm->param.channel_list[i].band;
plan.channels[count].ch_param.rx1_frequency = mib_confirm->param.channel_list[i].rx1_frequency;
count++;
}
@ -156,34 +121,19 @@ lorawan_status_t LoRaMacChannelPlan::remove_plan()
{
lorawan_status_t status = LORAWAN_STATUS_OK;
get_phy_params_t get_phy;
phy_param_t phy_param;
uint8_t max_num_channels;
uint16_t *channel_mask;
uint16_t *default_channel_mask;
// Check if the PHY layer supports custom channel plans or not.
get_phy.attribute = PHY_CUSTOM_CHANNEL_PLAN_SUPPORT;
phy_param = _lora_phy->get_phy_params(&get_phy);
if (!phy_param.value) {
if (!_lora_phy->is_custom_channel_plan_supported()) {
return LORAWAN_STATUS_SERVICE_UNKNOWN;
}
// Check first how many channels the selected PHY layer supports
get_phy.attribute = PHY_MAX_NB_CHANNELS;
phy_param = _lora_phy->get_phy_params(&get_phy);
max_num_channels = (uint8_t) phy_param.value;
max_num_channels = _lora_phy->get_max_nb_channels();
// Now check the channel mask for enabled channels
get_phy.attribute = PHY_CHANNEL_MASK;
phy_param = _lora_phy->get_phy_params(&get_phy);
channel_mask = phy_param.channel_mask;
channel_mask = _lora_phy->get_channel_mask(false);
// Now check the channel mask for default channels
get_phy.attribute = PHY_DEFAULT_CHANNEL_MASK;
phy_param = _lora_phy->get_phy_params(&get_phy);
default_channel_mask = phy_param.channel_mask;
default_channel_mask = _lora_phy->get_channel_mask(true);
for (uint8_t i = 0; i < max_num_channels; i++) {
// skip any default channels
@ -208,22 +158,13 @@ lorawan_status_t LoRaMacChannelPlan::remove_plan()
lorawan_status_t LoRaMacChannelPlan::remove_single_channel(uint8_t channel_id)
{
get_phy_params_t get_phy;
phy_param_t phy_param;
uint8_t max_num_channels;
// Check if the PHY layer supports custom channel plans or not.
get_phy.attribute = PHY_CUSTOM_CHANNEL_PLAN_SUPPORT;
phy_param = _lora_phy->get_phy_params(&get_phy);
if (!phy_param.value) {
if (!_lora_phy->is_custom_channel_plan_supported()) {
return LORAWAN_STATUS_SERVICE_UNKNOWN;
}
// Check first how many channels the selected PHY layer supports
get_phy.attribute = PHY_MAX_NB_CHANNELS;
phy_param = _lora_phy->get_phy_params(&get_phy);
max_num_channels = (uint8_t) phy_param.value;
max_num_channels = _lora_phy->get_max_nb_channels();
// According to specification channel IDs start from 0 and last valid
// channel ID is N-1 where N=MAX_NUM_CHANNELS.

View File

@ -56,7 +56,7 @@ public:
* @param phy pointer to PHY layer
* @param mib pointer to MIB subsystem
*/
void activate_channelplan_subsystem(LoRaPHY *phy,LoRaMacMib *mib);
void activate_channelplan_subsystem(LoRaPHY *phy);
/** Set a given channel plan
*
@ -83,7 +83,7 @@ public:
* @return LORAWAN_STATUS_OK if everything goes well otherwise
* a negative error code is returned.
*/
lorawan_status_t get_plan(lorawan_channelplan_t& plan, loramac_protocol_params *params);
lorawan_status_t get_plan(lorawan_channelplan_t& plan, const loramac_mib_req_confirm_t *mib_confirm);
/** Remove the active channel plan
*
@ -109,7 +109,6 @@ private:
* Local handles
*/
LoRaPHY *_lora_phy;
LoRaMacMib * _mib;
};

View File

@ -35,6 +35,16 @@ LoRaMacMcps::~LoRaMacMcps()
{
}
loramac_mcps_confirm_t& LoRaMacMcps::get_confirmation()
{
return confirmation;
}
loramac_mcps_indication_t& LoRaMacMcps::get_indication()
{
return indication;
}
void LoRaMacMcps::activate_mcps_subsystem(LoRaMac *mac, LoRaPHY *phy)
{
_lora_mac = mac;
@ -49,11 +59,8 @@ lorawan_status_t LoRaMacMcps::set_request(loramac_mcps_req_t *mcpsRequest,
return LORAWAN_STATUS_PARAMETER_INVALID;
}
get_phy_params_t get_phy;
phy_param_t phyParam;
lorawan_status_t status = LORAWAN_STATUS_SERVICE_UNKNOWN;
loramac_mhdr_t machdr;
verification_params_t verify;
uint8_t fport = 0;
void *fbuffer;
uint16_t fbuffer_size;
@ -114,25 +121,20 @@ lorawan_status_t LoRaMacMcps::set_request(loramac_mcps_req_t *mcpsRequest,
// return LORAWAN_STATUS_PARAMETER_INVALID;
// }
// Get the minimum possible datarate
get_phy.attribute = PHY_MIN_TX_DR;
phyParam = _lora_phy->get_phy_params(&get_phy);
// Apply the minimum possible datarate.
// Some regions have limitations for the minimum datarate.
datarate = MAX(datarate, (int8_t)phyParam.value);
datarate = MAX(datarate, (int8_t)_lora_phy->get_minimum_tx_datarate());
if (ready_to_send == true) {
if (params->sys_params.adr_on == false) {
verify.datarate = datarate;
if (_lora_phy->verify(&verify, PHY_TX_DR) == true) {
params->sys_params.channel_data_rate = verify.datarate;
if (_lora_phy->verify_tx_datarate(datarate, false) == true) {
params->sys_params.channel_data_rate = datarate;
} else {
return LORAWAN_STATUS_PARAMETER_INVALID;
}
}
//nämä lora_maciin
status = _lora_mac->send(&machdr, fport, fbuffer, fbuffer_size);
if (status == LORAWAN_STATUS_OK) {
confirmation.req_type = mcpsRequest->type;

View File

@ -76,20 +76,13 @@ public:
*
* @return a reference to MCPS confirm data structure
*/
inline loramac_mcps_confirm_t& get_confirmation()
{
return confirmation;
}
loramac_mcps_confirm_t& get_confirmation();
/** Grants access to MCPS indication data
*
* @return a reference to MCPS indication data structure
*/
inline loramac_mcps_indication_t& get_indication()
{
return indication;
}
loramac_mcps_indication_t& get_indication();
private:

View File

@ -49,8 +49,6 @@ lorawan_status_t LoRaMacMib::set_request(loramac_mib_req_confirm_t *mibSet,
}
lorawan_status_t status = LORAWAN_STATUS_OK;
verification_params_t verify;
switch (mibSet->type) {
case MIB_DEVICE_CLASS: {
@ -125,9 +123,7 @@ lorawan_status_t LoRaMacMib::set_request(loramac_mib_req_confirm_t *mibSet,
break;
}
case MIB_RX2_CHANNEL: {
verify.datarate = mibSet->param.rx2_channel.datarate;
if (_lora_phy->verify(&verify, PHY_RX_DR) == true) {
if (_lora_phy->verify_rx_datarate(mibSet->param.rx2_channel.datarate) == true) {
params->sys_params.rx2_channel = mibSet->param.rx2_channel;
if ((params->dev_class == CLASS_C)
@ -152,9 +148,7 @@ lorawan_status_t LoRaMacMib::set_request(loramac_mib_req_confirm_t *mibSet,
break;
}
case MIB_RX2_DEFAULT_CHANNEL: {
verify.datarate = mibSet->param.rx2_channel.datarate;
if (_lora_phy->verify(&verify, PHY_RX_DR) == true) {
if (_lora_phy->verify_rx_datarate(mibSet->param.rx2_channel.datarate) == true) {
params->sys_params.rx2_channel = mibSet->param.default_rx2_channel;
} else {
status = LORAWAN_STATUS_PARAMETER_INVALID;
@ -200,40 +194,32 @@ lorawan_status_t LoRaMacMib::set_request(loramac_mib_req_confirm_t *mibSet,
break;
}
case MIB_CHANNELS_DEFAULT_DATARATE: {
verify.datarate = mibSet->param.default_channel_data_rate;
if (_lora_phy->verify(&verify, PHY_DEF_TX_DR) == true) {
params->sys_params.channel_data_rate = verify.datarate;
if (_lora_phy->verify_tx_datarate(mibSet->param.default_channel_data_rate, true)) {
params->sys_params.channel_data_rate = mibSet->param.default_channel_data_rate;
} else {
status = LORAWAN_STATUS_PARAMETER_INVALID;
}
break;
}
case MIB_CHANNELS_DATARATE: {
verify.datarate = mibSet->param.channel_data_rate;
if (_lora_phy->verify(&verify, PHY_TX_DR) == true) {
params->sys_params.channel_data_rate = verify.datarate;
if (_lora_phy->verify_tx_datarate(mibSet->param.channel_data_rate, false) == true) {
params->sys_params.channel_data_rate = mibSet->param.channel_data_rate;
} else {
status = LORAWAN_STATUS_PARAMETER_INVALID;
}
break;
}
case MIB_CHANNELS_DEFAULT_TX_POWER: {
verify.tx_power = mibSet->param.default_channel_tx_pwr;
if (_lora_phy->verify(&verify, PHY_DEF_TX_POWER) == true) {
params->sys_params.channel_tx_power = verify.tx_power;
if (_lora_phy->verify_tx_power(mibSet->param.default_channel_tx_pwr)) {
params->sys_params.channel_tx_power = mibSet->param.default_channel_tx_pwr;
} else {
status = LORAWAN_STATUS_PARAMETER_INVALID;
}
break;
}
case MIB_CHANNELS_TX_POWER: {
verify.tx_power = mibSet->param.channel_tx_pwr;
if (_lora_phy->verify(&verify, PHY_TX_POWER) == true) {
params->sys_params.channel_tx_power = verify.tx_power;
if (_lora_phy->verify_tx_power(mibSet->param.channel_tx_pwr)) {
params->sys_params.channel_tx_power = mibSet->param.channel_tx_pwr;
} else {
status = LORAWAN_STATUS_PARAMETER_INVALID;
}
@ -271,8 +257,6 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet,
loramac_protocol_params *params)
{
lorawan_status_t status = LORAWAN_STATUS_OK;
get_phy_params_t get_phy;
phy_param_t phy_param;
rx2_channel_params rx2_channel;
if( mibGet == NULL )
@ -329,10 +313,7 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet,
}
case MIB_CHANNELS:
{
get_phy.attribute = PHY_CHANNELS;
phy_param = _lora_phy->get_phy_params( &get_phy );
mibGet->param.channel_list = phy_param.channel_params;
mibGet->param.channel_list = _lora_phy->get_phy_channels();
break;
}
case MIB_RX2_CHANNEL:
@ -342,31 +323,19 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet,
}
case MIB_RX2_DEFAULT_CHANNEL:
{
get_phy.attribute = PHY_DEF_RX2_DR;
phy_param = _lora_phy->get_phy_params( &get_phy );
rx2_channel.datarate = phy_param.value;
get_phy.attribute = PHY_DEF_RX2_FREQUENCY;
phy_param = _lora_phy->get_phy_params( &get_phy );
rx2_channel.frequency = phy_param.value;
rx2_channel.datarate = _lora_phy->get_default_rx2_datarate();
rx2_channel.frequency = _lora_phy->get_default_rx2_frequency();
mibGet->param.rx2_channel = rx2_channel;
break;
}
case MIB_CHANNELS_DEFAULT_MASK:
{
get_phy.attribute = PHY_DEFAULT_CHANNEL_MASK;
phy_param = _lora_phy->get_phy_params( &get_phy );
mibGet->param.default_channel_mask = phy_param.channel_mask;
mibGet->param.default_channel_mask = _lora_phy->get_channel_mask(true);
break;
}
case MIB_CHANNELS_MASK:
{
get_phy.attribute = PHY_CHANNEL_MASK;
phy_param = _lora_phy->get_phy_params( &get_phy );
mibGet->param.channel_mask = phy_param.channel_mask;
mibGet->param.channel_mask = _lora_phy->get_channel_mask(false);
break;
}
case MIB_CHANNELS_NB_REP:
@ -401,9 +370,7 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet,
}
case MIB_CHANNELS_DEFAULT_DATARATE:
{
get_phy.attribute = PHY_DEF_TX_DR;
phy_param = _lora_phy->get_phy_params( &get_phy );
mibGet->param.default_channel_data_rate = phy_param.value;
mibGet->param.default_channel_data_rate = _lora_phy->get_default_tx_datarate();
break;
}
case MIB_CHANNELS_DATARATE:
@ -413,9 +380,7 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet,
}
case MIB_CHANNELS_DEFAULT_TX_POWER:
{
get_phy.attribute = PHY_DEF_TX_POWER;
phy_param = _lora_phy->get_phy_params( &get_phy );
mibGet->param.default_channel_tx_pwr = phy_param.value;
mibGet->param.default_channel_tx_pwr = _lora_phy->get_default_tx_power();
break;
}
case MIB_CHANNELS_TX_POWER:

View File

@ -35,6 +35,16 @@ LoRaMacMlme::~LoRaMacMlme()
{
}
loramac_mlme_confirm_t& LoRaMacMlme::get_confirmation()
{
return confirmation;
}
loramac_mlme_indication_t& LoRaMacMlme::get_indication()
{
return indication;
}
void LoRaMacMlme::activate_mlme_subsystem(LoRaMac *mac, LoRaPHY *phy)
{
_lora_mac = mac;
@ -49,11 +59,6 @@ lorawan_status_t LoRaMacMlme::set_request(loramac_mlme_req_t *request,
lorawan_status_t status = LORAWAN_STATUS_SERVICE_UNKNOWN;
loramac_mhdr_t machdr;
verification_params_t verify;
get_phy_params_t get_phy;
phy_param_t phy_param;
if (params->mac_state != LORAMAC_IDLE) {
return LORAWAN_STATUS_BUSY;
}
@ -78,14 +83,9 @@ lorawan_status_t LoRaMacMlme::set_request(loramac_mlme_req_t *request,
return LORAWAN_STATUS_PARAMETER_INVALID;
}
// Verify the parameter NbTrials for the join procedure
verify.nb_join_trials = request->req.join.nb_trials;
if (_lora_phy->verify(&verify, PHY_NB_JOIN_TRIALS) == false) {
if (false == _lora_phy->verify_nb_join_trials(request->req.join.nb_trials)) {
// Value not supported, get default
get_phy.attribute = PHY_DEF_NB_JOIN_TRIALS;
phy_param = _lora_phy->get_phy_params(&get_phy);
request->req.join.nb_trials = (uint8_t) phy_param.value;
request->req.join.nb_trials = _lora_phy->get_nb_join_trials(true);
}
params->flags.bits.mlme_req = 1;

View File

@ -76,19 +76,13 @@ public:
*
* @return a reference to MLME confirm data structure
*/
inline loramac_mlme_confirm_t& get_confirmation()
{
return confirmation;
}
loramac_mlme_confirm_t& get_confirmation();
/** Grants access to MLME indication data
*
* @return a reference to MLME indication data structure
*/
inline loramac_mlme_indication_t& get_indication()
{
return indication;
}
loramac_mlme_indication_t& get_indication();
private:

View File

@ -46,6 +46,18 @@ LoRaPHY::~LoRaPHY()
_radio = NULL;
}
bool LoRaPHY::mask_bit_test(const uint16_t *mask, unsigned bit) {
return mask[bit/16] & (1U << (bit % 16));
}
void LoRaPHY::mask_bit_set(uint16_t *mask, unsigned bit) {
mask[bit/16] |= (1U << (bit % 16));
}
void LoRaPHY::mask_bit_clear(uint16_t *mask, unsigned bit) {
mask[bit/16] &= ~(1U << (bit % 16));
}
void LoRaPHY::set_radio_instance(LoRaRadio& radio)
{
_radio = &radio;
@ -475,151 +487,163 @@ uint8_t LoRaPHY::enabled_channel_count(bool joined, uint8_t datarate,
return count;
}
phy_param_t LoRaPHY::get_phy_params(get_phy_params_t* getPhy)
uint32_t LoRaPHY::get_next_lower_tx_datarate(int8_t datarate)
{
phy_param_t phyParam = { 0 };
switch (getPhy->attribute) {
case PHY_MIN_RX_DR: {
if (phy_params.dl_dwell_time_setting == 0) {
phyParam.value = phy_params.min_rx_datarate;
} else {
phyParam.value = phy_params.dwell_limit_datarate;
}
break;
}
case PHY_MIN_TX_DR: {
if (phy_params.ul_dwell_time_setting == 0) {
phyParam.value = phy_params.min_tx_datarate;
} else {
phyParam.value = phy_params.dwell_limit_datarate;
}
break;
}
case PHY_DEF_TX_DR: {
phyParam.value = phy_params.default_datarate;
break;
}
case PHY_NEXT_LOWER_TX_DR: {
if (phy_params.ul_dwell_time_setting == 0) {
phyParam.value = get_next_lower_dr(getPhy->datarate,
phy_params.min_tx_datarate);
} else {
phyParam.value = get_next_lower_dr(
getPhy->datarate, phy_params.dwell_limit_datarate);
}
break;
}
case PHY_DEF_TX_POWER: {
phyParam.value = phy_params.default_tx_power;
break;
}
case PHY_MAX_PAYLOAD: {
uint8_t *payload_table = (uint8_t *) phy_params.payloads.table;
phyParam.value = payload_table[getPhy->datarate];
break;
}
case PHY_MAX_PAYLOAD_REPEATER: {
uint8_t *payload_table = (uint8_t *) phy_params.payloads_with_repeater.table;
phyParam.value = payload_table[getPhy->datarate];
break;
}
case PHY_DUTY_CYCLE: {
phyParam.value = phy_params.duty_cycle_enabled;
break;
}
case PHY_MAX_RX_WINDOW: {
phyParam.value = phy_params.max_rx_window;
break;
}
case PHY_RECEIVE_DELAY1: {
phyParam.value = phy_params.recv_delay1;
break;
}
case PHY_RECEIVE_DELAY2: {
phyParam.value = phy_params.recv_delay2;
break;
}
case PHY_JOIN_ACCEPT_DELAY1: {
phyParam.value = phy_params.join_accept_delay1;
break;
}
case PHY_JOIN_ACCEPT_DELAY2: {
phyParam.value = phy_params.join_accept_delay2;
break;
}
case PHY_MAX_FCNT_GAP: {
phyParam.value = phy_params.max_fcnt_gap;
break;
}
case PHY_ACK_TIMEOUT: {
uint16_t ack_timeout = phy_params.ack_timeout;
uint16_t ack_timeout_rnd = phy_params.ack_timeout_rnd;
phyParam.value = (ack_timeout
+ get_random(-ack_timeout_rnd, ack_timeout_rnd));
break;
}
case PHY_DEF_DR1_OFFSET: {
phyParam.value = phy_params.default_rx1_dr_offset;
break;
}
case PHY_DEF_RX2_FREQUENCY: {
phyParam.value = phy_params.rx_window2_frequency;
break;
}
case PHY_DEF_RX2_DR: {
phyParam.value = phy_params.rx_window2_datarate;
break;
}
case PHY_CHANNEL_MASK: {
phyParam.channel_mask = phy_params.channels.mask;
break;
}
case PHY_DEFAULT_CHANNEL_MASK: {
phyParam.channel_mask = phy_params.channels.default_mask;
break;
}
case PHY_MAX_NB_CHANNELS: {
phyParam.value = phy_params.max_channel_cnt;
break;
}
case PHY_CHANNELS: {
phyParam.channel_params = phy_params.channels.channel_list;
break;
}
case PHY_CUSTOM_CHANNEL_PLAN_SUPPORT:
// 0 if custom channel plans are not supported (in LoRaWAN terms
// the regions who do not support custom channels are called as
// regions with dynamic channel plans)
phyParam.value = (uint32_t) phy_params.custom_channelplans_supported;
break;
case PHY_DEF_UPLINK_DWELL_TIME: {
phyParam.value = phy_params.ul_dwell_time_setting;
break;
}
case PHY_DEF_DOWNLINK_DWELL_TIME: {
phyParam.value = phy_params.dl_dwell_time_setting;
break;
}
case PHY_DEF_MAX_EIRP: {
phyParam.f_value = phy_params.default_max_eirp;
break;
}
case PHY_DEF_ANTENNA_GAIN: {
phyParam.f_value = phy_params.default_antenna_gain;
break;
}
case PHY_NB_JOIN_TRIALS:
case PHY_DEF_NB_JOIN_TRIALS: {
phyParam.value = MBED_CONF_LORA_NB_TRIALS;
break;
}
default: {
break;
}
if (phy_params.ul_dwell_time_setting == 0) {
return get_next_lower_dr(datarate, phy_params.min_tx_datarate);
}
return phyParam;
return get_next_lower_dr(
datarate, phy_params.dwell_limit_datarate);
}
uint8_t LoRaPHY::get_minimum_rx_datarate()
{
if (phy_params.dl_dwell_time_setting == 0) {
return phy_params.min_rx_datarate;
}
return phy_params.dwell_limit_datarate;
}
uint8_t LoRaPHY::get_minimum_tx_datarate()
{
if (phy_params.ul_dwell_time_setting == 0) {
return phy_params.min_tx_datarate;
}
return phy_params.dwell_limit_datarate;
}
uint8_t LoRaPHY::get_default_tx_datarate()
{
return phy_params.default_datarate;
}
uint8_t LoRaPHY::get_default_tx_power()
{
return phy_params.default_tx_power;
}
uint8_t LoRaPHY::get_max_payload(uint8_t datarate, bool use_repeater)
{
uint8_t *payload_table = NULL;
if (use_repeater) {
// if (datarate >= phy_params.payloads_with_repeater.size) {
// //TODO: Can this ever happen? If yes, should we return 0?
// }
payload_table = (uint8_t *) phy_params.payloads_with_repeater.table;
} else {
payload_table = (uint8_t *) phy_params.payloads.table;
}
return payload_table[datarate];
}
bool LoRaPHY::duty_cycle_enabled()
{
return phy_params.duty_cycle_enabled;
}
uint16_t LoRaPHY::get_maximum_receive_window_duration()
{
return phy_params.max_rx_window;
}
uint16_t LoRaPHY::get_window1_receive_delay()
{
return phy_params.recv_delay1;
}
uint16_t LoRaPHY::get_window2_receive_delay()
{
return phy_params.recv_delay2;
}
uint16_t LoRaPHY::get_window1_join_accept_delay()
{
return phy_params.join_accept_delay1;
}
uint16_t LoRaPHY::get_window2_join_accept_delay()
{
return phy_params.join_accept_delay2;
}
uint16_t LoRaPHY::get_maximum_frame_counter_gap()
{
return phy_params.max_fcnt_gap;
}
uint32_t LoRaPHY::get_ack_timeout()
{
uint16_t ack_timeout_rnd = phy_params.ack_timeout_rnd;
return (phy_params.ack_timeout
+ get_random(-ack_timeout_rnd, ack_timeout_rnd));
}
uint8_t LoRaPHY::get_default_datarate1_offset()
{
return phy_params.default_rx1_dr_offset;
}
uint32_t LoRaPHY::get_default_rx2_frequency()
{
return phy_params.rx_window2_frequency;
}
uint8_t LoRaPHY::get_default_rx2_datarate()
{
return phy_params.rx_window2_datarate;
}
uint16_t* LoRaPHY::get_channel_mask(bool get_default)
{
if (get_default) {
return phy_params.channels.default_mask;
}
return phy_params.channels.mask;
}
uint8_t LoRaPHY::get_max_nb_channels()
{
return phy_params.max_channel_cnt;
}
channel_params_t* LoRaPHY::get_phy_channels()
{
return phy_params.channels.channel_list;
}
bool LoRaPHY::is_custom_channel_plan_supported()
{
return phy_params.custom_channelplans_supported;
}
uint8_t LoRaPHY::get_default_uplink_dwell_time()
{
return phy_params.ul_dwell_time_setting;
}
uint8_t LoRaPHY::get_default_downlink_dwell_time()
{
return phy_params.dl_dwell_time_setting;
}
float LoRaPHY::get_default_max_eirp()
{
return phy_params.default_max_eirp;
}
float LoRaPHY::get_default_antenna_gain()
{
return phy_params.default_antenna_gain;
}
uint8_t LoRaPHY::get_nb_join_trials(bool get_default)
{
(void)get_default;
return MBED_CONF_LORA_NB_TRIALS;
}
void LoRaPHY::restore_default_channels()
@ -630,66 +654,53 @@ void LoRaPHY::restore_default_channels()
}
}
bool LoRaPHY::verify(verification_params_t* verify, phy_attributes_t phy_attribute)
bool LoRaPHY::verify_rx_datarate(uint8_t datarate)
{
switch(phy_attribute) {
case PHY_TX_DR:
{
if (phy_params.ul_dwell_time_setting == 0) {
return val_in_range(verify->datarate,
phy_params.min_tx_datarate,
phy_params.max_tx_datarate);
} else {
return val_in_range(verify->datarate,
phy_params.dwell_limit_datarate,
phy_params.max_tx_datarate);
}
}
case PHY_DEF_TX_DR:
{
return val_in_range(verify->datarate,
phy_params.default_datarate,
phy_params.default_max_datarate);
}
case PHY_RX_DR:
{
if (phy_params.dl_dwell_time_setting == 0) {
return val_in_range(verify->datarate,
phy_params.min_rx_datarate,
phy_params.max_rx_datarate);
} else {
return val_in_range(verify->datarate,
phy_params.dwell_limit_datarate,
phy_params.max_rx_datarate);
}
}
case PHY_DEF_TX_POWER:
case PHY_TX_POWER:
{
// Remark: switched min and max!
return val_in_range(verify->tx_power, phy_params.max_tx_power,
phy_params.min_tx_power);
}
case PHY_DUTY_CYCLE:
{
if (verify->duty_cycle == phy_params.duty_cycle_enabled) {
return true;
}
return false;
}
case PHY_NB_JOIN_TRIALS:
{
if (verify->nb_join_trials < MBED_CONF_LORA_NB_TRIALS) {
return false;
}
break;
}
default:
return false;
if (phy_params.dl_dwell_time_setting == 0) {
//TODO: Check this! datarate must be same as minimum! Can be compared directly if OK
return val_in_range(datarate,
phy_params.min_rx_datarate,
phy_params.min_rx_datarate);
} else {
return val_in_range(datarate,
phy_params.dwell_limit_datarate,
phy_params.min_rx_datarate );
}
}
bool LoRaPHY::verify_tx_datarate(uint8_t datarate, bool use_default)
{
if (use_default) {
return val_in_range(datarate, phy_params.default_datarate,
phy_params.default_max_datarate);
} else if (phy_params.ul_dwell_time_setting == 0) {
return val_in_range(datarate, phy_params.min_tx_datarate,
phy_params.max_tx_datarate);
} else {
return val_in_range(datarate, phy_params.dwell_limit_datarate,
phy_params.max_tx_datarate);
}
}
bool LoRaPHY::verify_tx_power(uint8_t tx_power)
{
return val_in_range(tx_power, phy_params.max_tx_power,
phy_params.min_tx_power);
}
bool LoRaPHY::verify_duty_cycle(bool cycle)
{
if (cycle == phy_params.duty_cycle_enabled) {
return true;
}
return false;
}
bool LoRaPHY::verify_nb_join_trials(uint8_t nb_join_trials)
{
if (nb_join_trials < MBED_CONF_LORA_NB_TRIALS) {
return false;
}
return true;
}
@ -750,8 +761,6 @@ bool LoRaPHY::get_next_ADR(bool restore_channel_mask, int8_t& dr_out,
{
bool set_adr_ack_bit = false;
get_phy_params_t get_phy;
phy_param_t phy_param;
uint16_t ack_limit_plus_delay = phy_params.adr_ack_limit + phy_params.adr_ack_delay;
if (dr_out == phy_params.min_tx_datarate) {
@ -770,10 +779,7 @@ bool LoRaPHY::get_next_ADR(bool restore_channel_mask, int8_t& dr_out,
if (adr_ack_cnt >= ack_limit_plus_delay) {
if ((adr_ack_cnt % phy_params.adr_ack_delay) == 1) {
// Decrease the datarate
get_phy.attribute = PHY_NEXT_LOWER_TX_DR;
get_phy.datarate = dr_out;
phy_param = get_phy_params(&get_phy);
dr_out = phy_param.value;
dr_out = get_next_lower_tx_datarate(dr_out);
if (dr_out == phy_params.min_tx_datarate) {
// We must set adrAckReq to false as soon as we reach the lowest datarate

View File

@ -115,23 +115,17 @@ public:
/**
* Tests if a channel is on or off in the channel mask
*/
inline bool mask_bit_test(const uint16_t *mask, unsigned bit) {
return mask[bit/16] & (1U << (bit % 16));
}
bool mask_bit_test(const uint16_t *mask, unsigned bit);
/**
* Tests if a channel is on or off in the channel mask
*/
inline void mask_bit_set(uint16_t *mask, unsigned bit) {
mask[bit/16] |= (1U << (bit % 16));
}
void mask_bit_set(uint16_t *mask, unsigned bit);
/**
* Tests if a channel is on or off in the channel mask
*/
inline void mask_bit_clear(uint16_t *mask, unsigned bit) {
mask[bit/16] &= ~(1U << (bit % 16));
}
void mask_bit_clear(uint16_t *mask, unsigned bit);
/** Entertain a new channel request MAC command.
*
@ -145,18 +139,6 @@ public:
*/
virtual uint8_t request_new_channel(new_channel_req_params_t* new_channel_req);
/** Grants access to PHY layer parameters.
*
* This is essentially a PHY layer parameter retrieval system.
* A request is made for a certain parameter by setting an appropriate
* attribute.
*
* @param [in] get_phy A pointer to get_phy_params_t
*
* @return A structure containing the requested PHY parameter value.
*/
virtual phy_param_t get_phy_params(get_phy_params_t* get_phy);
/** Process PHY layer state after a successful transmission.
*
* Updates times of the last transmission for the particular channel and
@ -173,17 +155,6 @@ public:
*/
virtual void restore_default_channels();
/** Verify if a parameter is eligible.
*
* @param verify A pointer to the verification_params_t that contains
* parameters which we need to check for validity.
*
* @param phy_attr The attribute for which the verification is needed.
*
* @return True, if the parameter is valid.
*/
virtual bool verify(verification_params_t* verify, phy_attributes_t phy_attr);
/** Processes the incoming CF-list.
*
* Handles the payload containing CF-list and enables channels defined
@ -406,6 +377,71 @@ public:
*/
virtual uint8_t apply_DR_offset(int8_t dr, int8_t dr_offset);
public: //Getters
uint32_t get_next_lower_tx_datarate(int8_t datarate);
uint8_t get_minimum_rx_datarate();
uint8_t get_minimum_tx_datarate();
uint8_t get_default_tx_datarate();
uint8_t get_default_tx_power();
uint8_t get_max_payload(uint8_t datarate, bool use_repeater = false);
bool duty_cycle_enabled();
uint16_t get_maximum_receive_window_duration();
uint16_t get_window1_receive_delay();
uint16_t get_window2_receive_delay();
uint16_t get_window1_join_accept_delay();
uint16_t get_window2_join_accept_delay();
uint16_t get_maximum_frame_counter_gap();
uint32_t get_ack_timeout();
uint8_t get_default_datarate1_offset();
uint32_t get_default_rx2_frequency();
uint8_t get_default_rx2_datarate();
uint16_t* get_channel_mask(bool get_default = false);
uint8_t get_max_nb_channels();
channel_params_t* get_phy_channels();
bool is_custom_channel_plan_supported();
uint8_t get_default_uplink_dwell_time();
uint8_t get_default_downlink_dwell_time();
float get_default_max_eirp();
float get_default_antenna_gain();
uint8_t get_nb_join_trials(bool get_default = false);
public: //Verifiers
bool verify_rx_datarate(uint8_t datarate);
bool verify_tx_datarate(uint8_t datarate, bool use_default = false);
bool verify_tx_power(uint8_t tx_power);
bool verify_duty_cycle(bool cycle);
bool verify_nb_join_trials(uint8_t nb_join_trials);
protected:
LoRaRadio *_radio;
LoRaWANTimeHandler &_lora_time;

View File

@ -334,9 +334,6 @@ bool LoRaPHYUS915Hybrid::get_next_ADR(bool restore_channel_mask, int8_t& dr_out,
{
bool adrAckReq = false;
get_phy_params_t get_phy;
phy_param_t phy_param;
uint16_t ack_limit_plus_delay = phy_params.adr_ack_limit + phy_params.adr_ack_delay;
if (dr_out == phy_params.min_tx_datarate) {
@ -356,10 +353,7 @@ bool LoRaPHYUS915Hybrid::get_next_ADR(bool restore_channel_mask, int8_t& dr_out,
if (adr_ack_cnt >= ack_limit_plus_delay) {
if ((adr_ack_cnt % phy_params.adr_ack_delay) == 1) {
// Decrease the datarate
get_phy.attribute = PHY_NEXT_LOWER_TX_DR;
get_phy.datarate = dr_out;
phy_param = get_phy_params(&get_phy);
dr_out = phy_param.value;
dr_out = get_next_lower_tx_datarate(dr_out);
if (dr_out == phy_params.min_tx_datarate) {
// We must set adrAckReq to false as soon as we reach the lowest datarate

View File

@ -524,194 +524,6 @@
*/
#define TX_POWER_15 15
/*!
* Enumeration of PHY attributes.
*/
typedef enum phy_attributes__e
{
/*!
* The minimum RX datarate.
*/
PHY_MIN_RX_DR,
/*!
* The minimum TX datarate.
*/
PHY_MIN_TX_DR,
/*!
* The maximum RX datarate.
*/
PHY_MAX_RX_DR,
/*!
* The maximum TX datarate.
*/
PHY_MAX_TX_DR,
/*!
* The TX datarate.
*/
PHY_TX_DR,
/*!
* The default TX datarate.
*/
PHY_DEF_TX_DR,
/*!
* The RX datarate.
*/
PHY_RX_DR,
/*!
* The TX power.
*/
PHY_TX_POWER,
/*!
* The default TX power.
*/
PHY_DEF_TX_POWER,
/*!
* Maximum payload possible.
*/
PHY_MAX_PAYLOAD,
/*!
* Maximum payload possible when the repeater support is enabled.
*/
PHY_MAX_PAYLOAD_REPEATER,
/*!
* The duty cycle.
*/
PHY_DUTY_CYCLE,
/*!
* The maximum receive window duration.
*/
PHY_MAX_RX_WINDOW,
/*!
* The receive delay for window 1.
*/
PHY_RECEIVE_DELAY1,
/*!
* The receive delay for window 2.
*/
PHY_RECEIVE_DELAY2,
/*!
* The join accept delay for window 1.
*/
PHY_JOIN_ACCEPT_DELAY1,
/*!
* The join accept delay for window 2.
*/
PHY_JOIN_ACCEPT_DELAY2,
/*!
* The maximum frame counter gap.
*/
PHY_MAX_FCNT_GAP,
/*!
* The acknowledgement time out.
*/
PHY_ACK_TIMEOUT,
/*!
* The default datarate offset for window 1.
*/
PHY_DEF_DR1_OFFSET,
/*!
* The default receive window 2 frequency.
*/
PHY_DEF_RX2_FREQUENCY,
/*!
* The default receive window 2 datarate.
*/
PHY_DEF_RX2_DR,
/*!
* The channels mask.
*/
PHY_CHANNEL_MASK,
/*!
* The default channel mask.
*/
PHY_DEFAULT_CHANNEL_MASK,
/*!
* The maximum number of supported channels.
*/
PHY_MAX_NB_CHANNELS,
/*!
* The channels.
*/
PHY_CHANNELS,
/*!
* The PHYs that support dynamic channel plan (non-custom)
* support do not let the user add/remove to the channel plan.
* The network guides the device for the plan. So only
* EU like regions support custom channel planning.
*/
PHY_CUSTOM_CHANNEL_PLAN_SUPPORT,
/*!
* The default value of the uplink dwell time.
*/
PHY_DEF_UPLINK_DWELL_TIME,
/*!
* The default value of the downlink dwell time.
*/
PHY_DEF_DOWNLINK_DWELL_TIME,
/*!
* The default value of the MaxEIRP.
*/
PHY_DEF_MAX_EIRP,
/*!
* The default value of the antenna gain.
*/
PHY_DEF_ANTENNA_GAIN,
/*!
* The value for the number of join trials.
*/
PHY_NB_JOIN_TRIALS,
/*!
* The default value for the number of join trials.
*/
PHY_DEF_NB_JOIN_TRIALS,
/*!
* The next lower datarate.
*/
PHY_NEXT_LOWER_TX_DR
} phy_attributes_t;
/*!
* Keeps value in response to a call to
* get_phy_params() API.
*/
typedef union phy_param_u
{
/*!
* A parameter value.
*/
uint32_t value;
/*!
* A floating point value.
*/
float f_value;
/*!
* A pointer to the channels mask.
*/
uint16_t* channel_mask;
/*!
* A pointer to the channels.
*/
channel_params_t* channel_params;
} phy_param_t;
/**
* The parameter structure for the function RegionGetPhyParam.
*/
typedef struct
{
/**
* Set up the parameter to get.
*/
phy_attributes_t attribute;
/**
* The parameter is needed for the following queries:
* PHY_MAX_PAYLOAD, PHY_MAX_PAYLOAD_REPEATER, PHY_NEXT_LOWER_TX_DR.
*/
int8_t datarate;
} get_phy_params_t;
/**
* The parameter structure for the function RegionSetBandTxDone.
*/
@ -731,30 +543,6 @@ typedef struct
lorawan_time_t last_tx_done_time;
} set_band_txdone_params_t;
/**
* The parameter verification structure.
*/
typedef union
{
/**
* The TX power to verify.
*/
int8_t tx_power;
/**
* Set to true, if the duty cycle is enabled, otherwise false.
*/
bool duty_cycle;
/**
* The number of join trials.
*/
uint8_t nb_join_trials;
/**
* The datarate to verify.
*/
int8_t datarate;
} verification_params_t;
/**
* The parameter structure for the function RegionApplyCFList.
*/