mirror of
https://github.com/espressif/openthread.git
synced 2026-08-12 05:37:46 +00:00
[mac] enforce single initialization lifecycle for TxFrames (#13264)
This commit refactors `Mac::Links` and `Mac` frame preparation to ensure `TxFrames` buffers are initialized (`Clear()`) exactly once per TX cycle. Specifically, this commit: - Replaces `Links::GetTxFrames()` with `Links::InitTxFrames()`, which encapsulates calling `Clear()` on `mTxFrames` prior to returning its reference. This prevents callers from retrieving uninitialized or dirty transmission buffers from a previous radio cycle. - Updates `PrepareBeaconRequest()` and `PrepareBeacon()` to accept the initialized `TxFrames &` reference directly as a parameter, making the data flow explicit. - Replaces non-const `GetTxFrames()` calls in `HandleTransmitDone()` with `GetTxFramesRequiredRadioTypes()`, enforcing const-correctness during TX completion handling.
This commit is contained in:
+9
-11
@@ -703,9 +703,9 @@ void Mac::FinishOperation(void)
|
||||
mOperation = kOperationIdle;
|
||||
}
|
||||
|
||||
TxFrame *Mac::PrepareBeaconRequest(void)
|
||||
TxFrame *Mac::PrepareBeaconRequest(TxFrames &aTxFrames)
|
||||
{
|
||||
TxFrame &frame = mLinks.GetTxFrames().GetBroadcastTxFrame();
|
||||
TxFrame &frame = aTxFrames.GetBroadcastTxFrame();
|
||||
TxFrame::Info frameInfo;
|
||||
|
||||
frameInfo.mAddrs.mSource.SetNone();
|
||||
@@ -723,7 +723,7 @@ TxFrame *Mac::PrepareBeaconRequest(void)
|
||||
return &frame;
|
||||
}
|
||||
|
||||
TxFrame *Mac::PrepareBeacon(void)
|
||||
TxFrame *Mac::PrepareBeacon(TxFrames &aTxFrames)
|
||||
{
|
||||
TxFrame *frame;
|
||||
TxFrame::Info frameInfo;
|
||||
@@ -735,10 +735,10 @@ TxFrame *Mac::PrepareBeacon(void)
|
||||
|
||||
#if OPENTHREAD_CONFIG_MULTI_RADIO
|
||||
OT_ASSERT(!mTxBeaconRadioLinks.IsEmpty());
|
||||
frame = &mLinks.GetTxFrames().GetTxFrame(mTxBeaconRadioLinks);
|
||||
frame = &aTxFrames.GetTxFrame(mTxBeaconRadioLinks);
|
||||
mTxBeaconRadioLinks.Clear();
|
||||
#else
|
||||
frame = &mLinks.GetTxFrames().GetBroadcastTxFrame();
|
||||
frame = &aTxFrames.GetBroadcastTxFrame();
|
||||
#endif
|
||||
|
||||
frameInfo.mAddrs.mSource.SetExtended(GetExtAddress());
|
||||
@@ -917,11 +917,9 @@ exit:
|
||||
void Mac::BeginTransmit(void)
|
||||
{
|
||||
TxFrame *frame = nullptr;
|
||||
TxFrames &txFrames = mLinks.GetTxFrames();
|
||||
TxFrames &txFrames = mLinks.InitTxFrames();
|
||||
Address dstAddr;
|
||||
|
||||
txFrames.Clear();
|
||||
|
||||
#if OPENTHREAD_CONFIG_MULTI_RADIO
|
||||
mTxPendingRadioLinks.Clear();
|
||||
mTxError = kErrorAbort;
|
||||
@@ -933,7 +931,7 @@ void Mac::BeginTransmit(void)
|
||||
{
|
||||
case kOperationActiveScan:
|
||||
mLinks.SetPanId(kPanIdBroadcast);
|
||||
frame = PrepareBeaconRequest();
|
||||
frame = PrepareBeaconRequest(txFrames);
|
||||
VerifyOrExit(frame != nullptr);
|
||||
frame->SetChannel(mScanChannel);
|
||||
frame->SetSequence(0);
|
||||
@@ -942,7 +940,7 @@ void Mac::BeginTransmit(void)
|
||||
break;
|
||||
|
||||
case kOperationTransmitBeacon:
|
||||
frame = PrepareBeacon();
|
||||
frame = PrepareBeacon(txFrames);
|
||||
VerifyOrExit(frame != nullptr);
|
||||
frame->SetChannel(mRadioChannel);
|
||||
frame->SetSequence(mBeaconSequence++);
|
||||
@@ -1319,7 +1317,7 @@ void Mac::HandleTransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aError)
|
||||
if (!aFrame.IsEmpty())
|
||||
{
|
||||
RadioType radio = aFrame.GetRadioType();
|
||||
RadioTypes requiredRadios = mLinks.GetTxFrames().GetRequiredRadioTypes();
|
||||
RadioTypes requiredRadios = mLinks.GetTxFramesRequiredRadioTypes();
|
||||
|
||||
Get<RadioSelector>().UpdateOnSendDone(aFrame, aError);
|
||||
|
||||
|
||||
@@ -832,8 +832,8 @@ private:
|
||||
void StartOperation(Operation aOperation);
|
||||
void FinishOperation(void);
|
||||
void PerformNextOperation(void);
|
||||
TxFrame *PrepareBeaconRequest(void);
|
||||
TxFrame *PrepareBeacon(void);
|
||||
TxFrame *PrepareBeaconRequest(TxFrames &aTxFrames);
|
||||
TxFrame *PrepareBeacon(TxFrames &aTxFrames);
|
||||
bool ShouldSendBeacon(void) const;
|
||||
bool IsJoinable(void) const;
|
||||
void BeginTransmit(void);
|
||||
|
||||
@@ -517,18 +517,22 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the radio transmit frames.
|
||||
* Initializes and retrieves the radio transmit frames `TxFrames`.
|
||||
*
|
||||
* @returns The transmit frames.
|
||||
*/
|
||||
TxFrames &GetTxFrames(void) { return mTxFrames; }
|
||||
TxFrames &InitTxFrames(void)
|
||||
{
|
||||
mTxFrames.Clear();
|
||||
return mTxFrames;
|
||||
}
|
||||
|
||||
#if !OPENTHREAD_CONFIG_MULTI_RADIO
|
||||
|
||||
/**
|
||||
* Sends a prepared frame.
|
||||
*
|
||||
* The prepared frame is from `GetTxFrames()`. This method is available only in single radio link mode.
|
||||
* The prepared frame is from `InitTxFrames()`. This method is available only in single radio link mode.
|
||||
*/
|
||||
void Send(void)
|
||||
{
|
||||
@@ -545,13 +549,24 @@ public:
|
||||
/**
|
||||
* Sends prepared frames over a given set of radio links.
|
||||
*
|
||||
* The prepared frame must be from `GetTxFrames()`. This method is available only in multi radio link mode.
|
||||
* The prepared frame must be from `InitTxFrames()`. This method is available only in multi radio link mode.
|
||||
*
|
||||
* @param[in] aFrame A reference to a prepared frame.
|
||||
* @param[in] aRadioTypes A set of radio types to send on.
|
||||
*/
|
||||
void Send(TxFrame &aFrame, RadioTypes aRadioTypes);
|
||||
|
||||
/**
|
||||
* Gets the required radio types (`GetRequiredRadioTypes()`) from `TxFrames`.
|
||||
*
|
||||
* This set specifies the radio links for which we expect the frame tx to be successful to consider the overall tx
|
||||
* successful. If the set is empty, successful tx over any radio link is sufficient for overall tx to be considered
|
||||
* successful. The required radio type set is expected to be a subset of selected radio types.
|
||||
*
|
||||
* @returns The required radio types.
|
||||
*/
|
||||
RadioTypes GetTxFramesRequiredRadioTypes(void) const { return mTxFrames.GetRequiredRadioTypes(); }
|
||||
|
||||
#endif // !OPENTHREAD_CONFIG_MULTI_RADIO
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user