Skip to content

Commit cf6f6a4

Browse files
authored
Fix a dutycycle-related deadlock in ScheduleTx (#1287)
* Fix a dutycycle-related deadlock in ScheduleTx When RegionNextChannel returns LORAMAC_STATUS_DUTYCYCLE_RESTRICTED with a zero DutyCycleWaitTime value, do not return from the function after skipping the creation of TxDelayedTimer. This would result in a deadlock. Instead, let the rest of the function to proceed. Only return if the delayed timer was actually started. This change ensures that the end of the function with SendFrameOnChannel has a chance to execute, either immediately when DutyCycleWaitTime == 0, or later once this function is re-executed when TxDelayedTimer fires. * Only check if TX can be delayed when really needed When RegionNextChannel returns a zero dutycycle wait time, there is no need to check if allowDelayedTx is true since the function will attempt to transmit right away. Thus, the variable only needs to be tested if there is an actual dutycycle wait time. If allowDelayedTx is false, abort the function with LORAMAC_STATUS_DUTYCYCLE_RESTRICTED.
1 parent e182832 commit cf6f6a4

File tree

1 file changed

+13
-9
lines changed

1 file changed

+13
-9
lines changed

src/mac/LoRaMac.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2901,18 +2901,22 @@ static LoRaMacStatus_t ScheduleTx( bool allowDelayedTx )
29012901

29022902
if( status != LORAMAC_STATUS_OK )
29032903
{
2904-
if( ( status == LORAMAC_STATUS_DUTYCYCLE_RESTRICTED ) &&
2905-
( allowDelayedTx == true ) )
2904+
if( status == LORAMAC_STATUS_DUTYCYCLE_RESTRICTED )
29062905
{
2907-
// Allow delayed transmissions. We have to allow it in case
2908-
// the MAC must retransmit a frame with the frame repetitions
29092906
if( MacCtx.DutyCycleWaitTime != 0 )
2910-
{// Send later - prepare timer
2911-
MacCtx.MacState |= LORAMAC_TX_DELAYED;
2912-
TimerSetValue( &MacCtx.TxDelayedTimer, MacCtx.DutyCycleWaitTime );
2913-
TimerStart( &MacCtx.TxDelayedTimer );
2907+
{
2908+
if( allowDelayedTx == true )
2909+
{
2910+
// Allow delayed transmissions. We have to allow it in case
2911+
// the MAC must retransmit a frame with the frame repetitions
2912+
MacCtx.MacState |= LORAMAC_TX_DELAYED;
2913+
TimerSetValue( &MacCtx.TxDelayedTimer, MacCtx.DutyCycleWaitTime );
2914+
TimerStart( &MacCtx.TxDelayedTimer );
2915+
return LORAMAC_STATUS_OK;
2916+
}
2917+
// Need to delay, but allowDelayedTx does not allow it
2918+
return status;
29142919
}
2915-
return LORAMAC_STATUS_OK;
29162920
}
29172921
else
29182922
{// State where the MAC cannot send a frame

0 commit comments

Comments
 (0)