From 3f40cf78e61215f8841877ab7327d06e47485e55 Mon Sep 17 00:00:00 2001 From: Piotr Koziar <44554861+piotrkoziar@users.noreply.github.com> Date: Thu, 14 Oct 2021 07:05:37 +0200 Subject: [PATCH] [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. --- src/core/thread/csl_tx_scheduler.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/thread/csl_tx_scheduler.cpp b/src/core/thread/csl_tx_scheduler.cpp index 552a429ed..5347fd71b 100644 --- a/src/core/thread/csl_tx_scheduler.cpp +++ b/src/core/thread/csl_tx_scheduler.cpp @@ -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);