Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 19 additions & 7 deletions connectivity/lorawan/lorastack/mac/LoRaMac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1134,14 +1134,19 @@ lorawan_status_t LoRaMac::schedule_tx()
_mcps_confirmation.status = LORAMAC_EVENT_INFO_STATUS_ERROR;
return status;
case LORAWAN_STATUS_DUTYCYCLE_RESTRICTED:
if (backoff_time != 0) {
tr_debug("DC enforced: Transmitting in %lu ms", backoff_time);
_can_cancel_tx = true;
if (_device_class != CLASS_C) {
_lora_phy->put_radio_to_sleep();
}
_lora_time.start(_params.timers.backoff_timer, backoff_time);
// Enforce a minimum backoff of 1ms so the timer always fires.
// If backoff_time is 0, no timer would be started, leaving
// tx_ongoing=true permanently and all future sends returning
// LORAWAN_STATUS_WOULD_BLOCK with no recovery path.
if (backoff_time == 0) {
backoff_time = 1;
}
tr_debug("DC enforced: Transmitting in %lu ms", backoff_time);
_can_cancel_tx = true;
if (_device_class != CLASS_C) {
_lora_phy->put_radio_to_sleep();
}
_lora_time.start(_params.timers.backoff_timer, backoff_time);
return LORAWAN_STATUS_OK;
default:
break;
Expand Down Expand Up @@ -1872,6 +1877,13 @@ void LoRaMac::disconnect()
reset_mcps_confirmation();
reset_mlme_confirmation();
reset_mcps_indication();

// Clear any in-progress TX so that reconnecting after disconnect does not
// permanently return LORAWAN_STATUS_WOULD_BLOCK. All timers that would
// normally drive the state machine to call reset_ongoing_tx() (backoff,
// RX windows, ACK timeout) have already been stopped above, so without
// this explicit reset the tx_ongoing flag would be stuck at true.
reset_ongoing_tx(true);
}

uint8_t LoRaMac::get_max_possible_tx_size(uint8_t fopts_len)
Expand Down
8 changes: 8 additions & 0 deletions connectivity/lorawan/source/LoRaWANStack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1170,6 +1170,14 @@ void LoRaWANStack::process_scheduling_state(lorawan_status_t &op_status)
_ctrl_flags &= ~TX_DONE_FLAG;
_loramac.set_tx_ongoing(true);
_device_current_state = DEVICE_STATE_SENDING;
} else if (_loramac.tx_ongoing()) {
// tx_ongoing was already true from a previous successful send (e.g. a
// QoS nb_trans retry queued via post_process_tx_no_reception). The
// re-send failed with a non-recoverable error and the return value of
// the queued _queue->call() is ignored, so no failure handler would
// otherwise run. Explicitly clean up so tx_ongoing does not get stuck.
_loramac.set_tx_ongoing(false);
_loramac.reset_ongoing_tx();
}
}

Expand Down
Loading