mirror of
https://github.com/espressif/openthread.git
synced 2026-10-16 20:57:41 +00:00
[csl-tx-scheduler] simplify HandleSentFrame() implementation (#13390)
This commit simplifies `CslTxScheduler::HandleSentFrame()` by inlining the helper method directly into the main callback. Since `mCslTxNeighbor` is already a member variable, passing it as a reference parameter to a helper method was unnecessary. Additionally, clearing of `mCslTxMessage` and `mCslTxNeighbor` is moved to the `exit:` block after calling `HandleSentFrameToCslNeighbor()`. Keeping `mCslTxMessage` non-null while `HandleSentFrameToCslNeighbor()` runs ensures that nested calls to `CslTxScheduler::Update()` do not trigger a premature `RescheduleCslTx()` while the TX done callback is in progress. All state cleanup and rescheduling now occur cleanly at `exit:`.
This commit is contained in:
@@ -62,15 +62,29 @@ void CslTxScheduler::Update(void)
|
|||||||
if (mCslTxMessage == nullptr)
|
if (mCslTxMessage == nullptr)
|
||||||
{
|
{
|
||||||
RescheduleCslTx();
|
RescheduleCslTx();
|
||||||
|
ExitNow();
|
||||||
}
|
}
|
||||||
else if ((mCslTxNeighbor != nullptr) && (mCslTxNeighbor->GetIndirectMessage() != mCslTxMessage))
|
|
||||||
|
// A non-null `mCslTxMessage` indicates we are in the middle of MAC
|
||||||
|
// CSL TX, i.e., a frame was prepared for `Mac` and we are waiting
|
||||||
|
// for the TX done callback which will call `RescheduleCslTx()`.
|
||||||
|
//
|
||||||
|
// While in this state, if the indirect message being sent for the
|
||||||
|
// currently chosen neighbor is modified or removed, we clear
|
||||||
|
// `mCslTxNeighbor` to avoid processing it in the TX done
|
||||||
|
// callback.
|
||||||
|
|
||||||
|
VerifyOrExit(mCslTxNeighbor != nullptr);
|
||||||
|
|
||||||
|
if (mCslTxNeighbor->GetIndirectMessage() != mCslTxMessage)
|
||||||
{
|
{
|
||||||
// `Mac` has already started the CSL tx, so wait for tx done callback
|
|
||||||
// to call `RescheduleCslTx`
|
|
||||||
mCslTxNeighbor->ResetCslTxAttempts();
|
mCslTxNeighbor->ResetCslTxAttempts();
|
||||||
mCslTxNeighbor = nullptr;
|
mCslTxNeighbor = nullptr;
|
||||||
mFrameContext.mMessageNextOffset = 0;
|
mFrameContext.mMessageNextOffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CslTxScheduler::Clear(void)
|
void CslTxScheduler::Clear(void)
|
||||||
@@ -296,41 +310,27 @@ Mac::TxFrame *CslTxScheduler::HandleFrameRequest(Mac::TxFrames &) { return nullp
|
|||||||
|
|
||||||
void CslTxScheduler::HandleSentFrame(const Mac::TxFrame &aFrame, Error aError)
|
void CslTxScheduler::HandleSentFrame(const Mac::TxFrame &aFrame, Error aError)
|
||||||
{
|
{
|
||||||
CslNeighbor *neighbor = mCslTxNeighbor;
|
VerifyOrExit(mCslTxNeighbor != nullptr);
|
||||||
|
|
||||||
mCslTxMessage = nullptr;
|
|
||||||
|
|
||||||
VerifyOrExit(neighbor != nullptr);
|
|
||||||
|
|
||||||
mCslTxNeighbor = nullptr;
|
|
||||||
|
|
||||||
HandleSentFrame(aFrame, aError, *neighbor);
|
|
||||||
|
|
||||||
exit:
|
|
||||||
RescheduleCslTx();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CslTxScheduler::HandleSentFrame(const Mac::TxFrame &aFrame, Error aError, CslNeighbor &aCslNeighbor)
|
|
||||||
{
|
|
||||||
switch (aError)
|
switch (aError)
|
||||||
{
|
{
|
||||||
case kErrorNone:
|
case kErrorNone:
|
||||||
aCslNeighbor.ResetCslTxAttempts();
|
mCslTxNeighbor->ResetCslTxAttempts();
|
||||||
aCslNeighbor.ResetIndirectTxAttempts();
|
mCslTxNeighbor->ResetIndirectTxAttempts();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kErrorNoAck:
|
case kErrorNoAck:
|
||||||
OT_ASSERT(!aFrame.GetSecurityEnabled() || aFrame.IsHeaderUpdated());
|
OT_ASSERT(!aFrame.GetSecurityEnabled() || aFrame.IsHeaderUpdated());
|
||||||
|
|
||||||
aCslNeighbor.IncrementCslTxAttempts();
|
mCslTxNeighbor->IncrementCslTxAttempts();
|
||||||
LogInfo("CSL tx to %04x failed, attempt %d/%d", aCslNeighbor.GetRloc16(), aCslNeighbor.GetCslTxAttempts(),
|
LogInfo("CSL tx to %04x failed, attempt %d/%d", mCslTxNeighbor->GetRloc16(), mCslTxNeighbor->GetCslTxAttempts(),
|
||||||
kMaxCslTriggeredTxAttempts);
|
kMaxCslTriggeredTxAttempts);
|
||||||
|
|
||||||
if (aCslNeighbor.GetCslTxAttempts() >= kMaxCslTriggeredTxAttempts)
|
if (mCslTxNeighbor->GetCslTxAttempts() >= kMaxCslTriggeredTxAttempts)
|
||||||
{
|
{
|
||||||
// CSL transmission attempts reach max, consider child out of sync
|
// CSL transmission attempts reach max, consider child out of sync
|
||||||
aCslNeighbor.SetCslSynchronized(false);
|
mCslTxNeighbor->SetCslSynchronized(false);
|
||||||
aCslNeighbor.ResetCslTxAttempts();
|
mCslTxNeighbor->ResetCslTxAttempts();
|
||||||
}
|
}
|
||||||
|
|
||||||
OT_FALL_THROUGH;
|
OT_FALL_THROUGH;
|
||||||
@@ -344,7 +344,7 @@ void CslTxScheduler::HandleSentFrame(const Mac::TxFrame &aFrame, Error aError, C
|
|||||||
|
|
||||||
if (!aFrame.IsEmpty())
|
if (!aFrame.IsEmpty())
|
||||||
{
|
{
|
||||||
aCslNeighbor.SetIndirectDataSequenceNumber(aFrame.GetSequence());
|
mCslTxNeighbor->SetIndirectDataSequenceNumber(aFrame.GetSequence());
|
||||||
|
|
||||||
if (aFrame.GetSecurityEnabled() && aFrame.IsHeaderUpdated())
|
if (aFrame.GetSecurityEnabled() && aFrame.IsHeaderUpdated())
|
||||||
{
|
{
|
||||||
@@ -352,10 +352,10 @@ void CslTxScheduler::HandleSentFrame(const Mac::TxFrame &aFrame, Error aError, C
|
|||||||
uint8_t keyIndex;
|
uint8_t keyIndex;
|
||||||
|
|
||||||
IgnoreError(aFrame.GetFrameCounter(frameCounter));
|
IgnoreError(aFrame.GetFrameCounter(frameCounter));
|
||||||
aCslNeighbor.SetIndirectFrameCounter(frameCounter);
|
mCslTxNeighbor->SetIndirectFrameCounter(frameCounter);
|
||||||
|
|
||||||
IgnoreError(aFrame.GetKeyIndex(keyIndex));
|
IgnoreError(aFrame.GetKeyIndex(keyIndex));
|
||||||
aCslNeighbor.SetIndirectKeyIndex(keyIndex);
|
mCslTxNeighbor->SetIndirectKeyIndex(keyIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,10 +366,12 @@ void CslTxScheduler::HandleSentFrame(const Mac::TxFrame &aFrame, Error aError, C
|
|||||||
OT_UNREACHABLE_CODE(break);
|
OT_UNREACHABLE_CODE(break);
|
||||||
}
|
}
|
||||||
|
|
||||||
Get<IndirectSender>().HandleSentFrameToCslNeighbor(aFrame, mFrameContext, aError, aCslNeighbor);
|
Get<IndirectSender>().HandleSentFrameToCslNeighbor(aFrame, mFrameContext, aError, *mCslTxNeighbor);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
return;
|
mCslTxMessage = nullptr;
|
||||||
|
mCslTxNeighbor = nullptr;
|
||||||
|
RescheduleCslTx();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ot
|
} // namespace ot
|
||||||
|
|||||||
@@ -251,8 +251,6 @@ private:
|
|||||||
// Callback from `Radio`
|
// Callback from `Radio`
|
||||||
void HandleRadioBusLatencyChanged(void);
|
void HandleRadioBusLatencyChanged(void);
|
||||||
|
|
||||||
void HandleSentFrame(const Mac::TxFrame &aFrame, Error aError, CslNeighbor &aaCslNeighbor);
|
|
||||||
|
|
||||||
using CslTxTimer = TimerMilliIn<CslTxScheduler, &CslTxScheduler::HandleTimer>;
|
using CslTxTimer = TimerMilliIn<CslTxScheduler, &CslTxScheduler::HandleTimer>;
|
||||||
|
|
||||||
uint32_t mCslFrameRequestAheadUs;
|
uint32_t mCslFrameRequestAheadUs;
|
||||||
|
|||||||
Reference in New Issue
Block a user