From 2691b83c4e8f9e28fee71b35b54a067c9a52c88e Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Fri, 22 Mar 2019 15:05:03 +0200 Subject: [PATCH] Fixing premature RX2 abort A bug while setting up RX start timers would result in premature closusre of RX2 window. The 'ack_Timeout_timer' would be invoked prematurely and at that time RX2 window may be being demodulating. This resulted in massive instability with any test that relied on Confirmed traffic or lower data rates. To fix the issue, we must know the length of the RX window in milliseconds and for this purpose we have extended the 'get_rx_window_params(...)' API. The length of the time the window may remain open must be accounted for while setting up 'ack_timeout_timer'. --- features/lorawan/lorastack/mac/LoRaMac.cpp | 12 +++++++++--- features/lorawan/lorastack/phy/LoRaPHY.cpp | 7 +++++-- features/lorawan/lorastack/phy/LoRaPHY.h | 3 ++- features/lorawan/system/lorawan_data_structures.h | 6 +++++- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index a971fb9cd4..132346f8db 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -667,13 +667,14 @@ void LoRaMac::on_radio_tx_done(lorawan_time_t timestamp) if (get_device_class() == CLASS_C) { _lora_time.start(_rx2_closure_timer_for_class_c, (_params.rx_window2_delay - time_diff) + - _params.rx_window2_config.window_timeout); + _params.rx_window2_config.window_timeout_ms); } // start timer after which ack wait will timeout (for Confirmed messages) if (_params.is_node_ack_requested) { _lora_time.start(_params.timers.ack_timeout_timer, (_params.rx_window2_delay - time_diff) + + _params.rx_window2_config.window_timeout_ms + _lora_phy->get_ack_timeout()); } } else { @@ -1097,6 +1098,8 @@ lorawan_status_t LoRaMac::schedule_tx() { channel_selection_params_t next_channel; lorawan_time_t backoff_time = 0; + lorawan_time_t aggregated_timeoff = 0; + uint8_t channel = 0; uint8_t fopts_len = 0; if (_params.sys_params.max_duty_cycle == 255) { @@ -1122,9 +1125,12 @@ lorawan_status_t LoRaMac::schedule_tx() next_channel.last_aggregate_tx_time = _params.timers.aggregated_last_tx_time; lorawan_status_t status = _lora_phy->set_next_channel(&next_channel, - &_params.channel, + &channel, &backoff_time, - &_params.timers.aggregated_timeoff); + &aggregated_timeoff); + + _params.channel = channel; + _params.timers.aggregated_timeoff = aggregated_timeoff; switch (status) { case LORAWAN_STATUS_NO_CHANNEL_FOUND: diff --git a/features/lorawan/lorastack/phy/LoRaPHY.cpp b/features/lorawan/lorastack/phy/LoRaPHY.cpp index 8bf57ee691..c13f07d18a 100644 --- a/features/lorawan/lorastack/phy/LoRaPHY.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHY.cpp @@ -406,7 +406,8 @@ float LoRaPHY::compute_symb_timeout_fsk(uint8_t phy_dr) void LoRaPHY::get_rx_window_params(float t_symb, uint8_t min_rx_symb, float error_fudge, float wakeup_time, - uint32_t *window_length, int32_t *window_offset, + uint32_t *window_length, uint32_t *window_length_ms, + int32_t *window_offset, uint8_t phy_dr) { float target_rx_window_offset; @@ -442,6 +443,7 @@ void LoRaPHY::get_rx_window_params(float t_symb, uint8_t min_rx_symb, // Setting the window_length in terms of 'symbols' for LoRa modulation or // in terms of 'bytes' for FSK *window_length = (uint32_t) ceil(window_len_in_ms / t_symb); + *window_length_ms = window_len_in_ms; } int8_t LoRaPHY::compute_tx_power(int8_t tx_power_idx, float max_eirp, @@ -848,7 +850,8 @@ void LoRaPHY::compute_rx_win_params(int8_t datarate, uint8_t min_rx_symbols, } get_rx_window_params(t_symbol, min_rx_symbols, (float) rx_error, MBED_CONF_LORA_WAKEUP_TIME, - &rx_conf_params->window_timeout, &rx_conf_params->window_offset, + &rx_conf_params->window_timeout, &rx_conf_params->window_timeout_ms, + &rx_conf_params->window_offset, rx_conf_params->datarate); } diff --git a/features/lorawan/lorastack/phy/LoRaPHY.h b/features/lorawan/lorastack/phy/LoRaPHY.h index a522afc4f9..71b8ba094c 100644 --- a/features/lorawan/lorastack/phy/LoRaPHY.h +++ b/features/lorawan/lorastack/phy/LoRaPHY.h @@ -626,7 +626,8 @@ protected: */ void get_rx_window_params(float t_symbol, uint8_t min_rx_symbols, float rx_error, float wakeup_time, - uint32_t *window_length, int32_t *window_offset, + uint32_t *window_length, uint32_t *window_length_ms, + int32_t *window_offset, uint8_t phy_dr); /** diff --git a/features/lorawan/system/lorawan_data_structures.h b/features/lorawan/system/lorawan_data_structures.h index 141f7db0c4..e0aeb14476 100644 --- a/features/lorawan/system/lorawan_data_structures.h +++ b/features/lorawan/system/lorawan_data_structures.h @@ -1007,9 +1007,13 @@ typedef struct { */ uint32_t frequency; /*! - * The RX window timeout + * The RX window timeout - Symbols */ uint32_t window_timeout; + /*! + * The RX window timeout - Milliseconds + */ + uint32_t window_timeout_ms; /*! * The RX window offset */