Skip to content

Commit 6e8570e

Browse files
authored
[mac] enforce single initialization lifecycle for TxFrames (openthread#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.
1 parent ff121bf commit 6e8570e

3 files changed

Lines changed: 30 additions & 17 deletions

File tree

src/core/mac/mac.cpp

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -703,9 +703,9 @@ void Mac::FinishOperation(void)
703703
mOperation = kOperationIdle;
704704
}
705705

706-
TxFrame *Mac::PrepareBeaconRequest(void)
706+
TxFrame *Mac::PrepareBeaconRequest(TxFrames &aTxFrames)
707707
{
708-
TxFrame &frame = mLinks.GetTxFrames().GetBroadcastTxFrame();
708+
TxFrame &frame = aTxFrames.GetBroadcastTxFrame();
709709
TxFrame::Info frameInfo;
710710

711711
frameInfo.mAddrs.mSource.SetNone();
@@ -723,7 +723,7 @@ TxFrame *Mac::PrepareBeaconRequest(void)
723723
return &frame;
724724
}
725725

726-
TxFrame *Mac::PrepareBeacon(void)
726+
TxFrame *Mac::PrepareBeacon(TxFrames &aTxFrames)
727727
{
728728
TxFrame *frame;
729729
TxFrame::Info frameInfo;
@@ -735,10 +735,10 @@ TxFrame *Mac::PrepareBeacon(void)
735735

736736
#if OPENTHREAD_CONFIG_MULTI_RADIO
737737
OT_ASSERT(!mTxBeaconRadioLinks.IsEmpty());
738-
frame = &mLinks.GetTxFrames().GetTxFrame(mTxBeaconRadioLinks);
738+
frame = &aTxFrames.GetTxFrame(mTxBeaconRadioLinks);
739739
mTxBeaconRadioLinks.Clear();
740740
#else
741-
frame = &mLinks.GetTxFrames().GetBroadcastTxFrame();
741+
frame = &aTxFrames.GetBroadcastTxFrame();
742742
#endif
743743

744744
frameInfo.mAddrs.mSource.SetExtended(GetExtAddress());
@@ -917,11 +917,9 @@ void Mac::ProcessTransmitSecurity(TxFrame &aFrame)
917917
void Mac::BeginTransmit(void)
918918
{
919919
TxFrame *frame = nullptr;
920-
TxFrames &txFrames = mLinks.GetTxFrames();
920+
TxFrames &txFrames = mLinks.InitTxFrames();
921921
Address dstAddr;
922922

923-
txFrames.Clear();
924-
925923
#if OPENTHREAD_CONFIG_MULTI_RADIO
926924
mTxPendingRadioLinks.Clear();
927925
mTxError = kErrorAbort;
@@ -933,7 +931,7 @@ void Mac::BeginTransmit(void)
933931
{
934932
case kOperationActiveScan:
935933
mLinks.SetPanId(kPanIdBroadcast);
936-
frame = PrepareBeaconRequest();
934+
frame = PrepareBeaconRequest(txFrames);
937935
VerifyOrExit(frame != nullptr);
938936
frame->SetChannel(mScanChannel);
939937
frame->SetSequence(0);
@@ -942,7 +940,7 @@ void Mac::BeginTransmit(void)
942940
break;
943941

944942
case kOperationTransmitBeacon:
945-
frame = PrepareBeacon();
943+
frame = PrepareBeacon(txFrames);
946944
VerifyOrExit(frame != nullptr);
947945
frame->SetChannel(mRadioChannel);
948946
frame->SetSequence(mBeaconSequence++);
@@ -1319,7 +1317,7 @@ void Mac::HandleTransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aError)
13191317
if (!aFrame.IsEmpty())
13201318
{
13211319
RadioType radio = aFrame.GetRadioType();
1322-
RadioTypes requiredRadios = mLinks.GetTxFrames().GetRequiredRadioTypes();
1320+
RadioTypes requiredRadios = mLinks.GetTxFramesRequiredRadioTypes();
13231321

13241322
Get<RadioSelector>().UpdateOnSendDone(aFrame, aError);
13251323

src/core/mac/mac.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -832,8 +832,8 @@ class Mac : public InstanceLocator, private NonCopyable
832832
void StartOperation(Operation aOperation);
833833
void FinishOperation(void);
834834
void PerformNextOperation(void);
835-
TxFrame *PrepareBeaconRequest(void);
836-
TxFrame *PrepareBeacon(void);
835+
TxFrame *PrepareBeaconRequest(TxFrames &aTxFrames);
836+
TxFrame *PrepareBeacon(TxFrames &aTxFrames);
837837
bool ShouldSendBeacon(void) const;
838838
bool IsJoinable(void) const;
839839
void BeginTransmit(void);

src/core/mac/mac_links.hpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -517,18 +517,22 @@ class Links : public InstanceLocator
517517
}
518518

519519
/**
520-
* Gets the radio transmit frames.
520+
* Initializes and retrieves the radio transmit frames `TxFrames`.
521521
*
522522
* @returns The transmit frames.
523523
*/
524-
TxFrames &GetTxFrames(void) { return mTxFrames; }
524+
TxFrames &InitTxFrames(void)
525+
{
526+
mTxFrames.Clear();
527+
return mTxFrames;
528+
}
525529

526530
#if !OPENTHREAD_CONFIG_MULTI_RADIO
527531

528532
/**
529533
* Sends a prepared frame.
530534
*
531-
* The prepared frame is from `GetTxFrames()`. This method is available only in single radio link mode.
535+
* The prepared frame is from `InitTxFrames()`. This method is available only in single radio link mode.
532536
*/
533537
void Send(void)
534538
{
@@ -545,13 +549,24 @@ class Links : public InstanceLocator
545549
/**
546550
* Sends prepared frames over a given set of radio links.
547551
*
548-
* The prepared frame must be from `GetTxFrames()`. This method is available only in multi radio link mode.
552+
* The prepared frame must be from `InitTxFrames()`. This method is available only in multi radio link mode.
549553
*
550554
* @param[in] aFrame A reference to a prepared frame.
551555
* @param[in] aRadioTypes A set of radio types to send on.
552556
*/
553557
void Send(TxFrame &aFrame, RadioTypes aRadioTypes);
554558

559+
/**
560+
* Gets the required radio types (`GetRequiredRadioTypes()`) from `TxFrames`.
561+
*
562+
* This set specifies the radio links for which we expect the frame tx to be successful to consider the overall tx
563+
* successful. If the set is empty, successful tx over any radio link is sufficient for overall tx to be considered
564+
* successful. The required radio type set is expected to be a subset of selected radio types.
565+
*
566+
* @returns The required radio types.
567+
*/
568+
RadioTypes GetTxFramesRequiredRadioTypes(void) const { return mTxFrames.GetRequiredRadioTypes(); }
569+
555570
#endif // !OPENTHREAD_CONFIG_MULTI_RADIO
556571

557572
/**

0 commit comments

Comments
 (0)