diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index 90b10bd23c..4253527718 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -1152,6 +1152,7 @@ lorawan_status_t LoRaMac::schedule_tx(void) { lorawan_time_t dutyCycleTimeOff = 0; channel_selection_params_t nextChan; + lorawan_status_t status = LORAWAN_STATUS_PARAMETER_INVALID; // Check if the device is off if (_params.sys_params.max_duty_cycle == 255) { @@ -1173,12 +1174,23 @@ lorawan_status_t LoRaMac::schedule_tx(void) nextChan.last_aggregate_tx_time = _params.timers.aggregated_last_tx_time; // Select channel - while (lora_phy->set_next_channel(&nextChan, &_params.channel, - &dutyCycleTimeOff, - &_params.timers.aggregated_timeoff) == false) { - _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; + status = lora_phy->set_next_channel(&nextChan, &_params.channel, + &dutyCycleTimeOff, + &_params.timers.aggregated_timeoff); + switch (status) { + case LORAWAN_STATUS_NO_CHANNEL_FOUND: + case LORAWAN_STATUS_NO_FREE_CHANNEL_FOUND: + return status; + case LORAWAN_STATUS_DUTYCYCLE_RESTRICTED: + if (dutyCycleTimeOff != 0) { + // Send later - prepare timer + tr_debug("Next Transmission in %lu ms", dutyCycleTimeOff); + _params.mac_state |= LORAMAC_TX_DELAYED; + _lora_time.start(_params.timers.tx_delayed_timer, dutyCycleTimeOff); + } + return LORAWAN_STATUS_OK; + default: + break; } tr_debug("Next Channel Idx=%d, DR=%d", _params.channel, nextChan.current_datarate); @@ -1214,19 +1226,8 @@ lorawan_status_t LoRaMac::schedule_tx(void) + _params.rx_window2_config.window_offset; } - // Schedule transmission of frame - if (dutyCycleTimeOff == 0) { - // Try to send now - return send_frame_on_channel(_params.channel); - } else { - // Send later - prepare timer - _params.mac_state |= LORAMAC_TX_DELAYED; - tr_debug("Next Transmission in %lu ms", dutyCycleTimeOff); - - _lora_time.start(_params.timers.tx_delayed_timer, dutyCycleTimeOff); - - return LORAWAN_STATUS_OK; - } + // Try to send now + return send_frame_on_channel(_params.channel); } void LoRaMac::calculate_backOff(uint8_t channel) diff --git a/features/lorawan/lorastack/phy/LoRaPHY.cpp b/features/lorawan/lorastack/phy/LoRaPHY.cpp index c362f4d31c..3af695778e 100644 --- a/features/lorawan/lorastack/phy/LoRaPHY.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHY.cpp @@ -1195,9 +1195,9 @@ void LoRaPHY::calculate_backoff(backoff_params_t* calc_backoff) } } -bool LoRaPHY::set_next_channel(channel_selection_params_t* params, - uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregate_timeoff) +lorawan_status_t LoRaPHY::set_next_channel(channel_selection_params_t* params, + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregate_timeoff) { uint8_t channel_count = 0; uint8_t delay_tx = 0; @@ -1247,13 +1247,13 @@ bool LoRaPHY::set_next_channel(channel_selection_params_t* params, // We found a valid channel *channel = enabled_channels[get_random(0, channel_count - 1)]; *time = 0; - return true; + return LORAWAN_STATUS_OK; } if (delay_tx > 0) { // Delay transmission due to AggregatedTimeOff or to a band time off *time = next_tx_delay; - return true; + return LORAWAN_STATUS_DUTYCYCLE_RESTRICTED; } // Datarate not supported by any channel, restore defaults @@ -1261,7 +1261,7 @@ bool LoRaPHY::set_next_channel(channel_selection_params_t* params, phy_params.channels.default_mask, phy_params.channels.mask_size); *time = 0; - return false; + return LORAWAN_STATUS_NO_CHANNEL_FOUND; } lorawan_status_t LoRaPHY::add_channel(channel_params_t* new_channel, uint8_t id) diff --git a/features/lorawan/lorastack/phy/LoRaPHY.h b/features/lorawan/lorastack/phy/LoRaPHY.h index 4023b4396b..ca895bde7d 100644 --- a/features/lorawan/lorastack/phy/LoRaPHY.h +++ b/features/lorawan/lorastack/phy/LoRaPHY.h @@ -332,9 +332,9 @@ public: * * @return Function status [1: OK, 0: Unable to find a channel on the current datarate]. */ - virtual bool set_next_channel(channel_selection_params_t* nextChanParams, - uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregatedTimeOff); + virtual lorawan_status_t set_next_channel(channel_selection_params_t* nextChanParams, + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregatedTimeOff); /** Adds a channel to the channel list. * diff --git a/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp b/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp index bd9ededc37..4ce26dd84c 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp @@ -334,9 +334,9 @@ int8_t LoRaPHYAS923::get_alternate_DR(uint8_t nb_trials) return AS923_DWELL_LIMIT_DATARATE; } -bool LoRaPHYAS923::set_next_channel(channel_selection_params_t* next_channel_prams, - uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregate_timeoff) +lorawan_status_t LoRaPHYAS923::set_next_channel(channel_selection_params_t* next_channel_prams, + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregate_timeoff) { uint8_t next_channel_idx = 0; uint8_t nb_enabled_channels = 0; @@ -387,23 +387,23 @@ bool LoRaPHYAS923::set_next_channel(channel_selection_params_t* next_channel_pra _radio->unlock(); *channel = next_channel_idx; *time = 0; - return true; + return LORAWAN_STATUS_OK; } } _radio->unlock(); - return false; + return LORAWAN_STATUS_NO_FREE_CHANNEL_FOUND; } else { if (delay_tx > 0) { // Delay transmission due to AggregatedTimeOff or to a band time off *time = next_tx_delay; - return true; + return LORAWAN_STATUS_DUTYCYCLE_RESTRICTED; } // Datarate not supported by any channel, restore defaults channel_mask[0] |= LC( 1 ) + LC( 2 ); *time = 0; - return false; + return LORAWAN_STATUS_NO_CHANNEL_FOUND; } } diff --git a/features/lorawan/lorastack/phy/LoRaPHYAS923.h b/features/lorawan/lorastack/phy/LoRaPHYAS923.h index 17f943dbce..88030339ad 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAS923.h +++ b/features/lorawan/lorastack/phy/LoRaPHYAS923.h @@ -55,9 +55,9 @@ public: virtual int8_t get_alternate_DR(uint8_t nb_trials); - virtual bool set_next_channel(channel_selection_params_t* nextChanParams, - uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregatedTimeOff ); + virtual lorawan_status_t set_next_channel(channel_selection_params_t* nextChanParams, + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregatedTimeOff ); virtual uint8_t apply_DR_offset(int8_t dr, int8_t drOffset ); diff --git a/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp b/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp index 9c262a9a62..7964abdd4a 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp @@ -555,9 +555,9 @@ int8_t LoRaPHYAU915::get_alternate_DR(uint8_t nb_trials) return datarate; } -bool LoRaPHYAU915::set_next_channel(channel_selection_params_t* next_chan_params, - uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregated_timeOff) +lorawan_status_t LoRaPHYAU915::set_next_channel(channel_selection_params_t* next_chan_params, + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregated_timeOff) { uint8_t nb_enabled_channels = 0; uint8_t delay_tx = 0; @@ -605,16 +605,16 @@ bool LoRaPHYAU915::set_next_channel(channel_selection_params_t* next_chan_params AU915_MAX_NB_CHANNELS - 8); *time = 0; - return true; + return LORAWAN_STATUS_OK; } else { if (delay_tx > 0) { // Delay transmission due to AggregatedTimeOff or to a band time off *time = next_tx_delay; - return true; + return LORAWAN_STATUS_DUTYCYCLE_RESTRICTED; } // Datarate not supported by any channel *time = 0; - return false; + return LORAWAN_STATUS_NO_CHANNEL_FOUND; } } diff --git a/features/lorawan/lorastack/phy/LoRaPHYAU915.h b/features/lorawan/lorastack/phy/LoRaPHYAU915.h index 5c7c358f61..027a3fcdb1 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAU915.h +++ b/features/lorawan/lorastack/phy/LoRaPHYAU915.h @@ -70,9 +70,9 @@ public: virtual int8_t get_alternate_DR(uint8_t nb_trials); - virtual bool set_next_channel(channel_selection_params_t* next_chan_params, - uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregate_timeoff); + virtual lorawan_status_t set_next_channel(channel_selection_params_t* next_chan_params, + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregate_timeoff); virtual uint8_t apply_DR_offset(int8_t dr, int8_t dr_offset); diff --git a/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp b/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp index b8afc36b7c..4c653a85ff 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp @@ -404,9 +404,9 @@ bool LoRaPHYKR920::tx_config(tx_config_params_t* config, int8_t* tx_power, return true; } -bool LoRaPHYKR920::set_next_channel(channel_selection_params_t* params, - uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregate_timeoff) +lorawan_status_t LoRaPHYKR920::set_next_channel(channel_selection_params_t* params, + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregate_timeoff) { uint8_t next_channel_idx = 0; uint8_t nb_enabled_channels = 0; @@ -455,26 +455,26 @@ bool LoRaPHYKR920::set_next_channel(channel_selection_params_t* params, *channel = next_channel_idx; *time = 0; _radio->unlock(); - return true; + return LORAWAN_STATUS_OK; } _radio->unlock(); } - return false; + return LORAWAN_STATUS_NO_FREE_CHANNEL_FOUND; } else { if (delay_tx > 0) { // Delay transmission due to AggregatedTimeOff or to a band time off *time = nextTxDelay; - return true; + return LORAWAN_STATUS_DUTYCYCLE_RESTRICTED; } // Datarate not supported by any channel, restore defaults channel_mask[0] |= LC(1) + LC(2) + LC(3); *time = 0; - return false; + return LORAWAN_STATUS_NO_CHANNEL_FOUND; } } diff --git a/features/lorawan/lorastack/phy/LoRaPHYKR920.h b/features/lorawan/lorastack/phy/LoRaPHYKR920.h index b95c902a14..717cb79115 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYKR920.h +++ b/features/lorawan/lorastack/phy/LoRaPHYKR920.h @@ -59,9 +59,9 @@ public: virtual bool tx_config(tx_config_params_t* config, int8_t* tx_power, lorawan_time_t* tx_toa); - virtual bool set_next_channel(channel_selection_params_t* params, uint8_t* channel, - lorawan_time_t* time, - lorawan_time_t* aggregate_timeOff); + virtual lorawan_status_t set_next_channel(channel_selection_params_t* params, uint8_t* channel, + lorawan_time_t* time, + lorawan_time_t* aggregate_timeOff); virtual void set_tx_cont_mode(cw_mode_params_t* continuousWave, uint32_t frequency = 0); diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp b/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp index 13a33a339b..bf73b53fb6 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp @@ -602,9 +602,9 @@ int8_t LoRaPHYUS915::get_alternate_DR(uint8_t nb_trials) return datarate; } -bool LoRaPHYUS915::set_next_channel(channel_selection_params_t* params, - uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregate_timeOff) +lorawan_status_t LoRaPHYUS915::set_next_channel(channel_selection_params_t* params, + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregate_timeOff) { uint8_t nb_enabled_channels = 0; uint8_t delay_tx = 0; @@ -649,19 +649,19 @@ bool LoRaPHYUS915::set_next_channel(channel_selection_params_t* params, disable_channel(current_channel_mask, *channel, US915_MAX_NB_CHANNELS - 8); *time = 0; - return true; + return LORAWAN_STATUS_OK; } else { if (delay_tx > 0) { // Delay transmission due to AggregatedTimeOff or to a band time off *time = next_tx_delay; - return true; + return LORAWAN_STATUS_DUTYCYCLE_RESTRICTED; } // Datarate not supported by any channel *time = 0; - return false; + return LORAWAN_STATUS_NO_CHANNEL_FOUND; } } diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915.h b/features/lorawan/lorastack/phy/LoRaPHYUS915.h index f08944e6e7..479695f651 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915.h +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915.h @@ -70,8 +70,8 @@ public: virtual int8_t get_alternate_DR(uint8_t nb_trials); - virtual bool set_next_channel(channel_selection_params_t* params, uint8_t* channel, - lorawan_time_t* time, lorawan_time_t* aggregate_timeOff); + virtual lorawan_status_t set_next_channel(channel_selection_params_t* params, uint8_t* channel, + lorawan_time_t* time, lorawan_time_t* aggregate_timeOff); virtual void set_tx_cont_mode(cw_mode_params_t* continuousWave, uint32_t frequency = 0); diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp index babac4d70f..99a2858502 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp @@ -601,9 +601,9 @@ int8_t LoRaPHYUS915Hybrid::get_alternate_DR(uint8_t nb_trials) return datarate; } -bool LoRaPHYUS915Hybrid::set_next_channel(channel_selection_params_t* params, - uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregate_timeOff) +lorawan_status_t LoRaPHYUS915Hybrid::set_next_channel(channel_selection_params_t* params, + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregate_timeOff) { uint8_t nb_enabled_channels = 0; uint8_t delay_tx = 0; @@ -650,19 +650,19 @@ bool LoRaPHYUS915Hybrid::set_next_channel(channel_selection_params_t* params, disable_channel(current_channel_mask, *channel, US915_HYBRID_MAX_NB_CHANNELS - 8); *time = 0; - return true; + return LORAWAN_STATUS_OK; } else { if (delay_tx > 0) { // Delay transmission due to AggregatedTimeOff or to a band time off *time = next_tx_delay; - return true; + return LORAWAN_STATUS_DUTYCYCLE_RESTRICTED; } // Datarate not supported by any channel *time = 0; - return false; + return LORAWAN_STATUS_NO_CHANNEL_FOUND; } } diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h index 08f1b58a71..357ee326dc 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h @@ -74,9 +74,9 @@ public: virtual int8_t get_alternate_DR(uint8_t nb_trials); - virtual bool set_next_channel(channel_selection_params_t* params, - uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregate_timeoff); + virtual lorawan_status_t set_next_channel(channel_selection_params_t* params, + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregate_timeoff); virtual void set_tx_cont_mode(cw_mode_params_t* continuousWave, uint32_t frequency = 0); diff --git a/features/lorawan/system/lorawan_data_structures.h b/features/lorawan/system/lorawan_data_structures.h index 183e1f9968..4dfc9ebf65 100644 --- a/features/lorawan/system/lorawan_data_structures.h +++ b/features/lorawan/system/lorawan_data_structures.h @@ -1575,6 +1575,9 @@ typedef enum lorawan_status { #if defined(LORAWAN_COMPLIANCE_TEST) LORAWAN_STATUS_COMPLIANCE_TEST_ON = -1019, /**< Compliance test - is on-going */ #endif + LORAWAN_STATUS_DUTYCYCLE_RESTRICTED = -1020, + LORAWAN_STATUS_NO_CHANNEL_FOUND = -1021, + LORAWAN_STATUS_NO_FREE_CHANNEL_FOUND = -1022, } lorawan_status_t; /*!