[csl] prevent CslTxScheduler from entering the incorrect state (#7070)

Problem:

I have encountered CslTxScheduler entering the incorrect state causing
the device to be unable to perform csl transmission.  The state is
when mCslTxChild is null but mCslTxMessage is not null. As a result
Update() call does not have any effect.

I think that we enter the incorrect state when the following happens:

1. CSL transmission on mac is requested (mCslTxChild is set to the
   best child found in RescheduleCslTx(), mCslTxMessage is set to the
   child's IndirectMessage in HandleFrameRequest())

2. During the ongoing mac CSL transmission, Update() is called (this
   method can be called from multiple places)

3. The mCslTxChild's IndirectMessage differs from the mCslTxMessage
   ==> mCslTxChild is set to nullptr

4. After the finished csl transmission on mac, the HandleSentFrame()
   is called but it does not call RescheduleCslTx() so the mCslTxChild
   remains nullptr

Then every Update() call does not have any effect. To change that we
would have to call RescheduleCslTx() or set the mCslTxMessage to null
but there is no way of doing that.

Solution:

I believe that mCslTxMessage is "tracking" the mac transmission - it
is to be set when transmission is requested, and to be cleared when
the transmission ends. In this commit we are doing it in a clear way.
This commit is contained in:
Piotr Koziar
2021-10-13 22:05:37 -07:00
committed by GitHub
parent 7dd7a5d7d6
commit 3f40cf78e6
+3 -2
View File
@@ -228,10 +228,11 @@ void CslTxScheduler::HandleSentFrame(const Mac::TxFrame &aFrame, Error aError)
{
Child *child = mCslTxChild;
mCslTxMessage = nullptr;
VerifyOrExit(child != nullptr); // The result is no longer interested by upper layer
mCslTxChild = nullptr;
mCslTxMessage = nullptr;
mCslTxChild = nullptr;
HandleSentFrame(aFrame, aError, *child);