diff --git a/UNITTESTS/stubs/LoRaWANTimer_stub.cpp b/UNITTESTS/stubs/LoRaWANTimer_stub.cpp index 5ca68b29e76..dc0b8d793ec 100644 --- a/UNITTESTS/stubs/LoRaWANTimer_stub.cpp +++ b/UNITTESTS/stubs/LoRaWANTimer_stub.cpp @@ -62,3 +62,8 @@ void LoRaWANTimeHandler::stop(timer_event_t &obj) { obj.timer_id = 0; } + +void LoRaWANTimeHandler::clear(timer_event_t &obj) +{ + obj.timer_id = 0; +} diff --git a/connectivity/lorawan/lorastack/mac/LoRaMac.cpp b/connectivity/lorawan/lorastack/mac/LoRaMac.cpp index 6f0f0b1c190..7ea1ec2f195 100644 --- a/connectivity/lorawan/lorastack/mac/LoRaMac.cpp +++ b/connectivity/lorawan/lorastack/mac/LoRaMac.cpp @@ -1419,7 +1419,13 @@ void LoRaMac::set_device_class(const device_class_t &device_class, _device_class = device_class; _rx2_would_be_closure_for_class_c = rx2_would_be_closure_handler; - _lora_time.init(_rx2_closure_timer_for_class_c, _rx2_would_be_closure_for_class_c); + _lora_time.init(_rx2_closure_timer_for_class_c, [this] { + { + Lock lock(*this); + _lora_time.clear(_rx2_closure_timer_for_class_c); + } + _rx2_would_be_closure_for_class_c(); + }); if (CLASS_A == _device_class) { tr_debug("Changing device class to -> CLASS_A"); @@ -1805,14 +1811,34 @@ lorawan_status_t LoRaMac::initialize(EventQueue *queue, _lora_phy->setup_public_network_mode(_params.is_nwk_public); _lora_phy->put_radio_to_sleep(); - _lora_time.init(_params.timers.backoff_timer, - mbed::callback(this, &LoRaMac::on_backoff_timer_expiry)); - _lora_time.init(_params.timers.rx_window1_timer, - mbed::callback(this, &LoRaMac::open_rx1_window)); - _lora_time.init(_params.timers.rx_window2_timer, - mbed::callback(this, &LoRaMac::open_rx2_window)); - _lora_time.init(_params.timers.ack_timeout_timer, - mbed::callback(this, &LoRaMac::on_ack_timeout_timer_event)); + _lora_time.init(_params.timers.backoff_timer, [this] { + { + Lock lock(*this); + _lora_time.clear(_params.timers.backoff_timer); + } + on_backoff_timer_expiry(); + }); + _lora_time.init(_params.timers.rx_window1_timer, [this] { + { + Lock lock(*this); + _lora_time.clear(_params.timers.rx_window1_timer); + } + open_rx1_window(); + }); + _lora_time.init(_params.timers.rx_window2_timer, [this] { + { + Lock lock(*this); + _lora_time.clear(_params.timers.rx_window2_timer); + } + open_rx2_window(); + }); + _lora_time.init(_params.timers.ack_timeout_timer, [this] { + { + Lock lock(*this); + _lora_time.clear(_params.timers.ack_timeout_timer); + } + on_ack_timeout_timer_event(); + }); _params.timers.mac_init_time = _lora_time.get_current_time(); diff --git a/connectivity/lorawan/system/LoRaWANTimer.cpp b/connectivity/lorawan/system/LoRaWANTimer.cpp index d17b96b49e6..8608303396a 100644 --- a/connectivity/lorawan/system/LoRaWANTimer.cpp +++ b/connectivity/lorawan/system/LoRaWANTimer.cpp @@ -64,3 +64,8 @@ void LoRaWANTimeHandler::stop(timer_event_t &obj) _queue->cancel(obj.timer_id); obj.timer_id = 0; } + +void LoRaWANTimeHandler::clear(timer_event_t &obj) +{ + obj.timer_id = 0; +} diff --git a/connectivity/lorawan/system/LoRaWANTimer.h b/connectivity/lorawan/system/LoRaWANTimer.h index e66d2680b67..c2fb3196fdb 100644 --- a/connectivity/lorawan/system/LoRaWANTimer.h +++ b/connectivity/lorawan/system/LoRaWANTimer.h @@ -76,6 +76,13 @@ class LoRaWANTimeHandler { */ void stop(timer_event_t &obj); + /** Clear timer state so it is not inadvertently canceled. This function + * must be called by the callback registered in init. + * + * @param [in] obj The structure containing the timer object parameters. + */ + void clear(timer_event_t &obj); + private: events::EventQueue *_queue; };