diff --git a/examples/config/ot-core-config-check-size-br.h b/examples/config/ot-core-config-check-size-br.h index dc34a3446..0d821186d 100644 --- a/examples/config/ot-core-config-check-size-br.h +++ b/examples/config/ot-core-config-check-size-br.h @@ -71,6 +71,7 @@ #define OPENTHREAD_CONFIG_LOG_LEVEL OT_LOG_LEVEL_INFO #define OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE 1 #define OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 1 +#define OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE 1 #define OPENTHREAD_CONFIG_MAC_FILTER_ENABLE 1 #define OPENTHREAD_CONFIG_MESH_DIAG_ENABLE 1 #define OPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE 1 diff --git a/examples/config/ot-core-config-check-size-ftd.h b/examples/config/ot-core-config-check-size-ftd.h index 2c663f2b6..2b4bd4a5d 100644 --- a/examples/config/ot-core-config-check-size-ftd.h +++ b/examples/config/ot-core-config-check-size-ftd.h @@ -71,6 +71,7 @@ #define OPENTHREAD_CONFIG_LOG_LEVEL OT_LOG_LEVEL_INFO #define OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE 0 #define OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 1 +#define OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE 1 #define OPENTHREAD_CONFIG_MAC_FILTER_ENABLE 1 #define OPENTHREAD_CONFIG_MESH_DIAG_ENABLE 1 #define OPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE 1 diff --git a/examples/config/ot-core-config-check-size-mtd.h b/examples/config/ot-core-config-check-size-mtd.h index 56e5454ae..c33998925 100644 --- a/examples/config/ot-core-config-check-size-mtd.h +++ b/examples/config/ot-core-config-check-size-mtd.h @@ -71,6 +71,7 @@ #define OPENTHREAD_CONFIG_LOG_LEVEL OT_LOG_LEVEL_INFO #define OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE 0 #define OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 1 +#define OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE 0 #define OPENTHREAD_CONFIG_MAC_FILTER_ENABLE 1 #define OPENTHREAD_CONFIG_MESH_DIAG_ENABLE 0 #define OPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE 1 diff --git a/src/core/instance/instance.hpp b/src/core/instance/instance.hpp index 3f7aa2977..fa1699ad2 100644 --- a/src/core/instance/instance.hpp +++ b/src/core/instance/instance.hpp @@ -821,9 +821,15 @@ template <> inline Ip6::Filter &Instance::Get(void) { return mIp6Filter; } template <> inline AddressResolver &Instance::Get(void) { return mAddressResolver; } -#if OPENTHREAD_FTD - +#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE template <> inline IndirectSender &Instance::Get(void) { return mMeshForwarder.mIndirectSender; } +#endif + +#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE +template <> inline CslTxScheduler &Instance::Get(void) { return mMeshForwarder.mIndirectSender.mCslTxScheduler; } +#endif + +#if OPENTHREAD_FTD template <> inline SourceMatchController &Instance::Get(void) { @@ -832,10 +838,6 @@ template <> inline SourceMatchController &Instance::Get(void) template <> inline DataPollHandler &Instance::Get(void) { return mMeshForwarder.mIndirectSender.mDataPollHandler; } -#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE -template <> inline CslTxScheduler &Instance::Get(void) { return mMeshForwarder.mIndirectSender.mCslTxScheduler; } -#endif - template <> inline MeshCoP::Leader &Instance::Get(void) { return mLeader; } template <> inline MeshCoP::JoinerRouter &Instance::Get(void) { return mJoinerRouter; } diff --git a/src/core/mac/data_poll_handler.hpp b/src/core/mac/data_poll_handler.hpp index 22b4a3831..755f735ed 100644 --- a/src/core/mac/data_poll_handler.hpp +++ b/src/core/mac/data_poll_handler.hpp @@ -36,8 +36,6 @@ #include "openthread-core-config.h" -#if OPENTHREAD_FTD - #include "common/code_utils.hpp" #include "common/locator.hpp" #include "common/non_copyable.hpp" @@ -57,7 +55,11 @@ namespace ot { * @{ */ +#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE + +#if OPENTHREAD_FTD class Child; +#endif /** * Implements the data poll (mac data request command) handler. @@ -79,14 +81,14 @@ public: }; /** - * Defines all the child info required for handling of data polls and indirect frame transmissions. + * Defines all the neighbor info required for handling of data polls and indirect frame transmissions. * - * `Child` class publicly inherits from this class. + * `Child` (and `CslNeighbor`) class publicly inherits from this class. */ - class ChildInfo + class NeighborInfo { friend class DataPollHandler; -#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE +#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE friend class CslTxScheduler; #endif @@ -132,6 +134,8 @@ public: static_assert(kMaxPollTriggeredTxAttempts < (1 << 5), "mIndirectTxAttempts cannot fit max!"); }; +#if OPENTHREAD_FTD + /** * Initializes the data poll handler object. * @@ -191,14 +195,16 @@ private: Child *mIndirectTxChild; // The child being handled (`nullptr` indicates no active indirect tx). FrameContext mFrameContext; // Context for the prepared frame for the current indirect tx (if any) + +#endif // OPENTHREAD_FTD }; +#endif // OPENTHREAD_FTD || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE + /** * @} */ } // namespace ot -#endif // OPENTHREAD_FTD - #endif // DATA_POLL_HANDLER_HPP_ diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index d41856e41..0ea79cefc 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -200,9 +200,9 @@ bool Mac::IsInTransmitState(void) const case kOperationTransmitDataDirect: #if OPENTHREAD_FTD case kOperationTransmitDataIndirect: +#endif #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE case kOperationTransmitDataCsl: -#endif #endif case kOperationTransmitBeacon: case kOperationTransmitPoll: @@ -508,6 +508,7 @@ void Mac::RequestIndirectFrameTransmission(void) exit: return; } +#endif #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE void Mac::RequestCslFrameTransmission(uint32_t aDelay) @@ -522,7 +523,6 @@ exit: return; } #endif -#endif // OPENTHREAD_FTD #if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE void Mac::RequestWakeupFrameTransmission(void) @@ -577,7 +577,7 @@ void Mac::UpdateIdleMode(void) } #endif } -#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE +#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE else if (IsPending(kOperationTransmitDataCsl)) { mTimer.FireAt(mCslTxFireTime); @@ -661,7 +661,7 @@ void Mac::PerformNextOperation(void) mOperation = kOperationTransmitWakeup; } #endif -#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE +#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE else if (IsPending(kOperationTransmitDataCsl) && TimerMilli::GetNow() >= mCslTxFireTime) { mOperation = kOperationTransmitDataCsl; @@ -727,9 +727,9 @@ void Mac::PerformNextOperation(void) case kOperationTransmitDataDirect: #if OPENTHREAD_FTD case kOperationTransmitDataIndirect: +#endif #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE case kOperationTransmitDataCsl: -#endif #endif case kOperationTransmitPoll: #if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE @@ -1036,6 +1036,7 @@ void Mac::BeginTransmit(void) frame->SetSequence(mDataSequence++); } break; +#endif #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE case kOperationTransmitDataCsl: @@ -1053,7 +1054,6 @@ void Mac::BeginTransmit(void) break; #endif -#endif // OPENTHREAD_FTD #if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE case kOperationTransmitWakeup: @@ -1352,7 +1352,7 @@ void Mac::HandleTransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aError) #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE ProcessEnhAckProbing(*aAckFrame, *neighbor); #endif -#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE +#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE ProcessCsl(*aAckFrame, dstAddr); #endif #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE @@ -1473,7 +1473,6 @@ void Mac::HandleTransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aError) PerformNextOperation(); break; -#if OPENTHREAD_FTD #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE case kOperationTransmitDataCsl: mCounters.mTxData++; @@ -1485,6 +1484,8 @@ void Mac::HandleTransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aError) break; #endif + +#if OPENTHREAD_FTD case kOperationTransmitDataIndirect: mCounters.mTxData++; @@ -1550,7 +1551,7 @@ void Mac::HandleTimer(void) } #endif } -#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE +#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE else if (IsPending(kOperationTransmitDataCsl)) { PerformNextOperation(); @@ -1962,7 +1963,7 @@ void Mac::HandleReceivedFrame(RxFrame *aFrame, Error aError) ExitNow(); } -#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE +#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE ProcessCsl(*aFrame, srcaddr); #endif @@ -2282,10 +2283,10 @@ const char *Mac::OperationToString(Operation aOperation) "WaitingForData", // (6) kOperationWaitingForData #if OPENTHREAD_FTD "TransmitDataIndirect", // (7) kOperationTransmitDataIndirect +#endif #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE "TransmitDataCsl", // (8) kOperationTransmitDataCsl #endif -#endif #if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE "TransmitWakeup", // kOperationTransmitWakeup #endif @@ -2304,9 +2305,9 @@ const char *Mac::OperationToString(Operation aOperation) ValidateNextEnum(kOperationWaitingForData); #if OPENTHREAD_FTD ValidateNextEnum(kOperationTransmitDataIndirect); +#endif #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE ValidateNextEnum(kOperationTransmitDataCsl); -#endif #endif }; @@ -2467,10 +2468,11 @@ bool Mac::IsCslSupported(void) const } #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE -#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE +#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE + void Mac::ProcessCsl(const RxFrame &aFrame, const Address &aSrcAddr) { - Child *child; + CslNeighbor *neighbor = nullptr; const CslIe *csl; VerifyOrExit(aFrame.IsVersion2015() && aFrame.GetSecurityEnabled()); @@ -2478,26 +2480,33 @@ void Mac::ProcessCsl(const RxFrame &aFrame, const Address &aSrcAddr) csl = aFrame.GetCslIe(); VerifyOrExit(csl != nullptr); - child = Get().FindChild(aSrcAddr, Child::kInStateAnyExceptInvalid); - VerifyOrExit(child != nullptr); +#if OPENTHREAD_FTD + neighbor = Get().FindChild(aSrcAddr, Child::kInStateAnyExceptInvalid); +#else + OT_UNUSED_VARIABLE(aSrcAddr); +#endif + + VerifyOrExit(neighbor != nullptr); VerifyOrExit(csl->GetPeriod() >= kMinCslIePeriod); - child->SetCslPeriod(csl->GetPeriod()); - child->SetCslPhase(csl->GetPhase()); - child->SetCslSynchronized(true); - child->SetCslLastHeard(TimerMilli::GetNow()); - child->SetLastRxTimestamp(aFrame.GetTimestamp()); + neighbor->SetCslPeriod(csl->GetPeriod()); + neighbor->SetCslPhase(csl->GetPhase()); + neighbor->SetCslSynchronized(true); + neighbor->SetCslLastHeard(TimerMilli::GetNow()); + neighbor->SetLastRxTimestamp(aFrame.GetTimestamp()); LogDebg("Timestamp=%lu Sequence=%u CslPeriod=%u CslPhase=%u TransmitPhase=%u", ToUlong(static_cast(aFrame.GetTimestamp())), aFrame.GetSequence(), csl->GetPeriod(), - csl->GetPhase(), child->GetCslPhase()); + csl->GetPhase(), neighbor->GetCslPhase()); +#if OPENTHREAD_FTD Get().Update(); +#endif exit: return; } -#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE +#endif // OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE void Mac::ProcessEnhAckProbing(const RxFrame &aFrame, const Neighbor &aNeighbor) diff --git a/src/core/mac/mac.hpp b/src/core/mac/mac.hpp index 40322a0c8..bb0ab4997 100644 --- a/src/core/mac/mac.hpp +++ b/src/core/mac/mac.hpp @@ -209,6 +209,7 @@ public: * Requests an indirect data frame transmission. */ void RequestIndirectFrameTransmission(void); +#endif #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE /** @@ -219,8 +220,6 @@ public: void RequestCslFrameTransmission(uint32_t aDelay); #endif -#endif - #if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE /** * Requests `Mac` to start a wake-up frame transmission. @@ -786,10 +785,10 @@ private: kOperationWaitingForData, #if OPENTHREAD_FTD kOperationTransmitDataIndirect, +#endif #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE kOperationTransmitDataCsl, #endif -#endif #if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE kOperationTransmitWakeup, #endif @@ -858,7 +857,7 @@ private: uint8_t GetTimeIeOffset(const Frame &aFrame); #endif -#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE +#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE void ProcessCsl(const RxFrame &aFrame, const Address &aSrcAddr); #endif #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE @@ -903,10 +902,10 @@ private: uint8_t mMaxFrameRetriesDirect; #if OPENTHREAD_FTD uint8_t mMaxFrameRetriesIndirect; +#endif #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE TimeMilli mCslTxFireTime; #endif -#endif #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE // When Mac::mCslChannel is 0, it indicates that CSL channel has not been specified by the upper layer. uint8_t mCslChannel; diff --git a/src/core/mac/mac_frame.cpp b/src/core/mac/mac_frame.cpp index 5e4688691..14364abea 100644 --- a/src/core/mac/mac_frame.cpp +++ b/src/core/mac/mac_frame.cpp @@ -1196,7 +1196,7 @@ exit: bool Frame::HasCslIe(void) const { return GetHeaderIe(CslIe::kHeaderIeId) != nullptr; } #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE -#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE) +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE const CslIe *Frame::GetCslIe(void) const { const uint8_t *cur; diff --git a/src/core/mac/mac_frame.hpp b/src/core/mac/mac_frame.hpp index 7b47d2df4..71bc2c702 100644 --- a/src/core/mac/mac_frame.hpp +++ b/src/core/mac/mac_frame.hpp @@ -676,7 +676,7 @@ public: bool HasCslIe(void) const; #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE -#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE) +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE /** * Returns a pointer to a CSL IE. * @@ -690,7 +690,7 @@ public: * @returns A pointer to the CSL IE, `nullptr` if not found. */ CslIe *GetCslIe(void) { return AsNonConst(AsConst(this)->GetCslIe()); } -#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE) +#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE /** diff --git a/src/core/thread/child.hpp b/src/core/thread/child.hpp index de0ee7b35..1fd235ef3 100644 --- a/src/core/thread/child.hpp +++ b/src/core/thread/child.hpp @@ -50,13 +50,7 @@ namespace ot { /** * Represents a Thread Child. */ -class Child : public Neighbor, - public IndirectSender::ChildInfo, - public DataPollHandler::ChildInfo -#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE - , - public CslTxScheduler::ChildInfo -#endif +class Child : public CslNeighbor { public: static constexpr uint8_t kMaxRequestTlvs = 6; diff --git a/src/core/thread/csl_tx_scheduler.cpp b/src/core/thread/csl_tx_scheduler.cpp index 4b4e026f2..96717dbbd 100644 --- a/src/core/thread/csl_tx_scheduler.cpp +++ b/src/core/thread/csl_tx_scheduler.cpp @@ -28,7 +28,7 @@ #include "csl_tx_scheduler.hpp" -#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE +#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE #include "instance/instance.hpp" @@ -38,7 +38,7 @@ RegisterLogModule("CslTxScheduler"); CslTxScheduler::CslTxScheduler(Instance &aInstance) : InstanceLocator(aInstance) - , mCslTxChild(nullptr) + , mCslTxNeighbor(nullptr) , mCslTxMessage(nullptr) , mFrameContext() { @@ -71,18 +71,19 @@ void CslTxScheduler::Update(void) { RescheduleCslTx(); } - else if ((mCslTxChild != nullptr) && (mCslTxChild->GetIndirectMessage() != mCslTxMessage)) + else if ((mCslTxNeighbor != nullptr) && (mCslTxNeighbor->GetIndirectMessage() != mCslTxMessage)) { // `Mac` has already started the CSL tx, so wait for tx done callback // to call `RescheduleCslTx` - mCslTxChild->ResetCslTxAttempts(); - mCslTxChild = nullptr; + mCslTxNeighbor->ResetCslTxAttempts(); + mCslTxNeighbor = nullptr; mFrameContext.mMessageNextOffset = 0; } } void CslTxScheduler::Clear(void) { +#if OPENTHREAD_FTD for (Child &child : Get().Iterate(Child::kInStateAnyExceptInvalid)) { child.ResetCslTxAttempts(); @@ -93,9 +94,10 @@ void CslTxScheduler::Clear(void) child.SetCslPhase(0); child.SetCslLastHeard(TimeMilli(0)); } +#endif mFrameContext.mMessageNextOffset = 0; - mCslTxChild = nullptr; + mCslTxNeighbor = nullptr; mCslTxMessage = nullptr; } @@ -106,9 +108,10 @@ void CslTxScheduler::Clear(void) */ void CslTxScheduler::RescheduleCslTx(void) { - uint32_t minDelayTime = Time::kMaxDuration; - Child *bestChild = nullptr; + uint32_t minDelayTime = Time::kMaxDuration; + CslNeighbor *bestNeighbor = nullptr; +#if OPENTHREAD_FTD for (Child &child : Get().Iterate(Child::kInStateAnyExceptInvalid)) { uint32_t delay; @@ -124,27 +127,28 @@ void CslTxScheduler::RescheduleCslTx(void) if (delay < minDelayTime) { minDelayTime = delay; - bestChild = &child; + bestNeighbor = &child; } } +#endif - if (bestChild != nullptr) + if (bestNeighbor != nullptr) { Get().RequestCslFrameTransmission(minDelayTime / 1000UL); } - mCslTxChild = bestChild; + mCslTxNeighbor = bestNeighbor; } -uint32_t CslTxScheduler::GetNextCslTransmissionDelay(const Child &aChild, - uint32_t &aDelayFromLastRx, - uint32_t aAheadUs) const +uint32_t CslTxScheduler::GetNextCslTransmissionDelay(const CslNeighbor &aCslNeighbor, + uint32_t &aDelayFromLastRx, + uint32_t aAheadUs) const { uint64_t radioNow = Get().GetNow(); - uint32_t periodInUs = aChild.GetCslPeriod() * kUsPerTenSymbols; + uint32_t periodInUs = aCslNeighbor.GetCslPeriod() * kUsPerTenSymbols; - /* see CslTxScheduler::ChildInfo::mCslPhase */ - uint64_t firstTxWindow = aChild.GetLastRxTimestamp() + aChild.GetCslPhase() * kUsPerTenSymbols; + /* see CslTxScheduler::NeighborInfo::mCslPhase */ + uint64_t firstTxWindow = aCslNeighbor.GetLastRxTimestamp() + aCslNeighbor.GetCslPhase() * kUsPerTenSymbols; uint64_t nextTxWindow = radioNow - (radioNow % periodInUs) + (firstTxWindow % periodInUs); while (nextTxWindow < radioNow + aAheadUs) @@ -152,7 +156,7 @@ uint32_t CslTxScheduler::GetNextCslTransmissionDelay(const Child &aChild, nextTxWindow += periodInUs; } - aDelayFromLastRx = static_cast(nextTxWindow - aChild.GetLastRxTimestamp()); + aDelayFromLastRx = static_cast(nextTxWindow - aCslNeighbor.GetLastRxTimestamp()); return static_cast(nextTxWindow - radioNow - aAheadUs); } @@ -165,8 +169,8 @@ Mac::TxFrame *CslTxScheduler::HandleFrameRequest(Mac::TxFrames &aTxFrames) uint32_t txDelay; uint32_t delay; - VerifyOrExit(mCslTxChild != nullptr); - VerifyOrExit(mCslTxChild->IsCslSynchronized()); + VerifyOrExit(mCslTxNeighbor != nullptr); + VerifyOrExit(mCslTxNeighbor->IsCslSynchronized()); #if OPENTHREAD_CONFIG_MULTI_RADIO frame = &aTxFrames.GetTxFrame(Mac::kRadioTypeIeee802154); @@ -174,24 +178,24 @@ Mac::TxFrame *CslTxScheduler::HandleFrameRequest(Mac::TxFrames &aTxFrames) frame = &aTxFrames.GetTxFrame(); #endif - VerifyOrExit(Get().PrepareFrameForChild(*frame, mFrameContext, *mCslTxChild) == kErrorNone, + VerifyOrExit(Get().PrepareFrameForCslNeighbor(*frame, mFrameContext, *mCslTxNeighbor) == kErrorNone, frame = nullptr); - mCslTxMessage = mCslTxChild->GetIndirectMessage(); + mCslTxMessage = mCslTxNeighbor->GetIndirectMessage(); VerifyOrExit(mCslTxMessage != nullptr, frame = nullptr); - if (mCslTxChild->GetIndirectTxAttempts() > 0 || mCslTxChild->GetCslTxAttempts() > 0) + if (mCslTxNeighbor->GetIndirectTxAttempts() > 0 || mCslTxNeighbor->GetCslTxAttempts() > 0) { // For a re-transmission of an indirect frame to a sleepy // child, we ensure to use the same frame counter, key id, and // data sequence number as the previous attempt. frame->SetIsARetransmission(true); - frame->SetSequence(mCslTxChild->GetIndirectDataSequenceNumber()); + frame->SetSequence(mCslTxNeighbor->GetIndirectDataSequenceNumber()); if (frame->GetSecurityEnabled()) { - frame->SetFrameCounter(mCslTxChild->GetIndirectFrameCounter()); - frame->SetKeyId(mCslTxChild->GetIndirectKeyId()); + frame->SetFrameCounter(mCslTxNeighbor->GetIndirectFrameCounter()); + frame->SetKeyId(mCslTxNeighbor->GetIndirectKeyId()); } } else @@ -199,15 +203,15 @@ Mac::TxFrame *CslTxScheduler::HandleFrameRequest(Mac::TxFrames &aTxFrames) frame->SetIsARetransmission(false); } - frame->SetChannel(mCslTxChild->GetCslChannel() == 0 ? Get().GetPanChannel() - : mCslTxChild->GetCslChannel()); + frame->SetChannel(mCslTxNeighbor->GetCslChannel() == 0 ? Get().GetPanChannel() + : mCslTxNeighbor->GetCslChannel()); if (frame->GetChannel() != Get().GetPanChannel()) { frame->SetRxChannelAfterTxDone(Get().GetPanChannel()); } - delay = GetNextCslTransmissionDelay(*mCslTxChild, txDelay, /* aAheadUs */ 0); + delay = GetNextCslTransmissionDelay(*mCslTxNeighbor, txDelay, /* aAheadUs */ 0); // We make sure that delay is less than `mCslFrameRequestAheadUs` // plus some guard time. Note that we used `mCslFrameRequestAheadUs` @@ -228,7 +232,7 @@ Mac::TxFrame *CslTxScheduler::HandleFrameRequest(Mac::TxFrames &aTxFrames) frame->SetTxDelay(txDelay); frame->SetTxDelayBaseTime( - static_cast(mCslTxChild->GetLastRxTimestamp())); // Only LSB part of the time is required. + static_cast(mCslTxNeighbor->GetLastRxTimestamp())); // Only LSB part of the time is required. frame->SetCsmaCaEnabled(false); exit: @@ -243,41 +247,41 @@ Mac::TxFrame *CslTxScheduler::HandleFrameRequest(Mac::TxFrames &) { return nullp void CslTxScheduler::HandleSentFrame(const Mac::TxFrame &aFrame, Error aError) { - Child *child = mCslTxChild; + CslNeighbor *neighbor = mCslTxNeighbor; mCslTxMessage = nullptr; - VerifyOrExit(child != nullptr); // The result is no longer interested by upper layer + VerifyOrExit(neighbor != nullptr); - mCslTxChild = nullptr; + mCslTxNeighbor = nullptr; - HandleSentFrame(aFrame, aError, *child); + HandleSentFrame(aFrame, aError, *neighbor); exit: RescheduleCslTx(); } -void CslTxScheduler::HandleSentFrame(const Mac::TxFrame &aFrame, Error aError, Child &aChild) +void CslTxScheduler::HandleSentFrame(const Mac::TxFrame &aFrame, Error aError, CslNeighbor &aCslNeighbor) { switch (aError) { case kErrorNone: - aChild.ResetCslTxAttempts(); - aChild.ResetIndirectTxAttempts(); + aCslNeighbor.ResetCslTxAttempts(); + aCslNeighbor.ResetIndirectTxAttempts(); break; case kErrorNoAck: OT_ASSERT(!aFrame.GetSecurityEnabled() || aFrame.IsHeaderUpdated()); - aChild.IncrementCslTxAttempts(); - LogInfo("CSL tx to child %04x failed, attempt %d/%d", aChild.GetRloc16(), aChild.GetCslTxAttempts(), + aCslNeighbor.IncrementCslTxAttempts(); + LogInfo("CSL tx to %04x failed, attempt %d/%d", aCslNeighbor.GetRloc16(), aCslNeighbor.GetCslTxAttempts(), kMaxCslTriggeredTxAttempts); - if (aChild.GetCslTxAttempts() >= kMaxCslTriggeredTxAttempts) + if (aCslNeighbor.GetCslTxAttempts() >= kMaxCslTriggeredTxAttempts) { // CSL transmission attempts reach max, consider child out of sync - aChild.SetCslSynchronized(false); - aChild.ResetCslTxAttempts(); + aCslNeighbor.SetCslSynchronized(false); + aCslNeighbor.ResetCslTxAttempts(); } OT_FALL_THROUGH; @@ -291,7 +295,7 @@ void CslTxScheduler::HandleSentFrame(const Mac::TxFrame &aFrame, Error aError, C if (!aFrame.IsEmpty()) { - aChild.SetIndirectDataSequenceNumber(aFrame.GetSequence()); + aCslNeighbor.SetIndirectDataSequenceNumber(aFrame.GetSequence()); if (aFrame.GetSecurityEnabled() && aFrame.IsHeaderUpdated()) { @@ -299,10 +303,10 @@ void CslTxScheduler::HandleSentFrame(const Mac::TxFrame &aFrame, Error aError, C uint8_t keyId; IgnoreError(aFrame.GetFrameCounter(frameCounter)); - aChild.SetIndirectFrameCounter(frameCounter); + aCslNeighbor.SetIndirectFrameCounter(frameCounter); IgnoreError(aFrame.GetKeyId(keyId)); - aChild.SetIndirectKeyId(keyId); + aCslNeighbor.SetIndirectKeyId(keyId); } } @@ -313,7 +317,7 @@ void CslTxScheduler::HandleSentFrame(const Mac::TxFrame &aFrame, Error aError, C OT_UNREACHABLE_CODE(break); } - Get().HandleSentFrameToChild(aFrame, mFrameContext, aError, aChild); + Get().HandleSentFrameToCslNeighbor(aFrame, mFrameContext, aError, aCslNeighbor); exit: return; @@ -321,4 +325,4 @@ exit: } // namespace ot -#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE +#endif // OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE diff --git a/src/core/thread/csl_tx_scheduler.hpp b/src/core/thread/csl_tx_scheduler.hpp index 91e8249fa..13fb800e2 100644 --- a/src/core/thread/csl_tx_scheduler.hpp +++ b/src/core/thread/csl_tx_scheduler.hpp @@ -31,7 +31,7 @@ #include "openthread-core-config.h" -#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE +#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE #include "common/locator.hpp" #include "common/message.hpp" @@ -52,7 +52,7 @@ namespace ot { * @{ */ -class Child; +class CslNeighbor; /** * Implements CSL tx scheduling functionality. @@ -66,11 +66,11 @@ public: static constexpr uint8_t kMaxCslTriggeredTxAttempts = OPENTHREAD_CONFIG_MAC_MAX_TX_ATTEMPTS_INDIRECT_POLLS; /** - * Defines all the child info required for scheduling CSL transmissions. + * Defines all the neighbor info required for scheduling CSL transmissions. * - * `Child` class publicly inherits from this class. + * `CslNeighbor` publicly inherits from this class. */ - class ChildInfo + class NeighborInfo { public: uint8_t GetCslTxAttempts(void) const { return mCslTxAttempts; } @@ -167,7 +167,7 @@ public: * Updates the next CSL transmission (finds the nearest child). * * It would then request the `Mac` to do the CSL tx. If the last CSL tx has been fired at `Mac` but hasn't been - * done yet, and it's aborted, this method would set `mCslTxChild` to `nullptr` to notify the `HandleTransmitDone` + * done yet, and it's aborted, this method would clear current tx CSL neighbor to notify the `HandleTransmitDone` * that the operation has been aborted. */ void Update(void); @@ -190,16 +190,18 @@ private: void RescheduleCslTx(void); - uint32_t GetNextCslTransmissionDelay(const Child &aChild, uint32_t &aDelayFromLastRx, uint32_t aAheadUs) const; + uint32_t GetNextCslTransmissionDelay(const CslNeighbor &aCslNeighbor, + uint32_t &aDelayFromLastRx, + uint32_t aAheadUs) const; // Callbacks from `Mac` Mac::TxFrame *HandleFrameRequest(Mac::TxFrames &aTxFrames); void HandleSentFrame(const Mac::TxFrame &aFrame, Error aError); - void HandleSentFrame(const Mac::TxFrame &aFrame, Error aError, Child &aChild); + void HandleSentFrame(const Mac::TxFrame &aFrame, Error aError, CslNeighbor &aaCslNeighbor); uint32_t mCslFrameRequestAheadUs; - Child *mCslTxChild; + CslNeighbor *mCslTxNeighbor; Message *mCslTxMessage; FrameContext mFrameContext; }; @@ -210,6 +212,6 @@ private: } // namespace ot -#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE +#endif // OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE #endif // CSL_TX_SCHEDULER_HPP_ diff --git a/src/core/thread/indirect_sender.cpp b/src/core/thread/indirect_sender.cpp index e4b504c68..b18bbf6ea 100644 --- a/src/core/thread/indirect_sender.cpp +++ b/src/core/thread/indirect_sender.cpp @@ -33,21 +33,21 @@ #include "indirect_sender.hpp" -#if OPENTHREAD_FTD - #include "instance/instance.hpp" namespace ot { -const Mac::Address &IndirectSender::ChildInfo::GetMacAddress(Mac::Address &aMacAddress) const +#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE + +const Mac::Address &IndirectSender::NeighborInfo::GetMacAddress(Mac::Address &aMacAddress) const { if (mUseShortAddress) { - aMacAddress.SetShort(static_cast(this)->GetRloc16()); + aMacAddress.SetShort(static_cast(this)->GetRloc16()); } else { - aMacAddress.SetExtended(static_cast(this)->GetExtAddress()); + aMacAddress.SetExtended(static_cast(this)->GetExtAddress()); } return aMacAddress; @@ -56,8 +56,10 @@ const Mac::Address &IndirectSender::ChildInfo::GetMacAddress(Mac::Address &aMacA IndirectSender::IndirectSender(Instance &aInstance) : InstanceLocator(aInstance) , mEnabled(false) +#if OPENTHREAD_FTD , mSourceMatchController(aInstance) , mDataPollHandler(aInstance) +#endif #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE , mCslTxScheduler(aInstance) #endif @@ -68,6 +70,7 @@ void IndirectSender::Stop(void) { VerifyOrExit(mEnabled); +#if OPENTHREAD_FTD for (Child &child : Get().Iterate(Child::kInStateAnyExceptInvalid)) { child.SetIndirectMessage(nullptr); @@ -75,6 +78,8 @@ void IndirectSender::Stop(void) } mDataPollHandler.Clear(); +#endif + #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE mCslTxScheduler.Clear(); #endif @@ -83,6 +88,8 @@ exit: mEnabled = false; } +#if OPENTHREAD_FTD + void IndirectSender::AddMessageForSleepyChild(Message &aMessage, Child &aChild) { uint16_t childIndex; @@ -563,6 +570,45 @@ bool IndirectSender::AcceptSupervisionMessage(const Message &aMessage) return aMessage.GetType() == Message::kTypeSupervision; } -} // namespace ot +#endif // OPENTHREAD_FTD -#endif // #if OPENTHREAD_FTD +#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE + +Error IndirectSender::PrepareFrameForCslNeighbor(Mac::TxFrame &aFrame, + FrameContext &aContext, + CslNeighbor &aCslNeighbor) +{ + Error error = kErrorNotFound; + +#if OPENTHREAD_FTD + // `CslNeighbor` can only be a `Child` for now, but can be changed later. + error = PrepareFrameForChild(aFrame, aContext, static_cast(aCslNeighbor)); +#else + OT_UNUSED_VARIABLE(aFrame); + OT_UNUSED_VARIABLE(aContext); + OT_UNUSED_VARIABLE(aCslNeighbor); +#endif + + return error; +} + +void IndirectSender::HandleSentFrameToCslNeighbor(const Mac::TxFrame &aFrame, + const FrameContext &aContext, + Error aError, + CslNeighbor &aCslNeighbor) +{ +#if OPENTHREAD_FTD + HandleSentFrameToChild(aFrame, aContext, aError, static_cast(aCslNeighbor)); +#else + OT_UNUSED_VARIABLE(aFrame); + OT_UNUSED_VARIABLE(aContext); + OT_UNUSED_VARIABLE(aError); + OT_UNUSED_VARIABLE(aCslNeighbor); +#endif +} + +#endif // OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE + +#endif // OPENTHREAD_FTD || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE + +} // namespace ot diff --git a/src/core/thread/indirect_sender.hpp b/src/core/thread/indirect_sender.hpp index ef96d4eaf..fcc120f93 100644 --- a/src/core/thread/indirect_sender.hpp +++ b/src/core/thread/indirect_sender.hpp @@ -36,8 +36,6 @@ #include "openthread-core-config.h" -#if OPENTHREAD_FTD - #include "common/locator.hpp" #include "common/message.hpp" #include "common/non_copyable.hpp" @@ -59,7 +57,12 @@ namespace ot { * @{ */ +#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE + +class CslNeighbor; +#if OPENTHREAD_FTD class Child; +#endif /** * Implements indirect transmission. @@ -67,23 +70,27 @@ class Child; class IndirectSender : public InstanceLocator, public IndirectSenderBase, private NonCopyable { friend class Instance; +#if OPENTHREAD_FTD friend class DataPollHandler; -#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE +#endif +#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE friend class CslTxScheduler; #endif public: /** - * Defines all the child info required for indirect transmission. + * Defines all the neighbor info required for indirect (CSL or data-poll) transmission. * - * `Child` class publicly inherits from this class. + * Sub-classes of `Neighbor`, e.g., `CslNeighbor` or `Child` publicly inherits from this class. */ - class ChildInfo + class NeighborInfo { friend class IndirectSender; +#if OPENTHREAD_FTD friend class DataPollHandler; - friend class CslTxScheduler; friend class SourceMatchController; +#endif + friend class CslTxScheduler; public: /** @@ -159,6 +166,7 @@ public: */ void Stop(void); +#if OPENTHREAD_FTD /** * Adds a message for indirect transmission to a sleepy child. * @@ -247,8 +255,20 @@ public: */ void HandleChildModeChange(Child &aChild, Mle::DeviceMode aOldMode); +#endif // OPENTHREAD_FTD + private: - // Callbacks from `DataPollHandler` or `CslTxScheduler` +#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE + // Callbacks from `CslTxScheduler` + Error PrepareFrameForCslNeighbor(Mac::TxFrame &aFrame, FrameContext &aContext, CslNeighbor &aCslNeighbor); + void HandleSentFrameToCslNeighbor(const Mac::TxFrame &aFrame, + const FrameContext &aContext, + Error aError, + CslNeighbor &aCslNeighbor); +#endif + +#if OPENTHREAD_FTD + // Callbacks from `DataPollHandler` Error PrepareFrameForChild(Mac::TxFrame &aFrame, FrameContext &aContext, Child &aChild); void HandleSentFrameToChild(const Mac::TxFrame &aFrame, const FrameContext &aContext, Error aError, Child &aChild); void HandleFrameChangeDone(Child &aChild); @@ -261,21 +281,24 @@ private: static bool AcceptAnyMessage(const Message &aMessage); static bool AcceptSupervisionMessage(const Message &aMessage); +#endif // OPENTHREAD_FTD - bool mEnabled; + bool mEnabled; +#if OPENTHREAD_FTD SourceMatchController mSourceMatchController; DataPollHandler mDataPollHandler; -#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE +#endif +#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE CslTxScheduler mCslTxScheduler; #endif }; +#endif // #if OPENTHREAD_FTD || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE + /** * @} */ } // namespace ot -#endif // OPENTHREAD_FTD - #endif // INDIRECT_SENDER_HPP_ diff --git a/src/core/thread/mesh_forwarder.cpp b/src/core/thread/mesh_forwarder.cpp index b288e5cd4..9999b36be 100644 --- a/src/core/thread/mesh_forwarder.cpp +++ b/src/core/thread/mesh_forwarder.cpp @@ -105,7 +105,7 @@ MeshForwarder::MeshForwarder(Instance &aInstance) , mTxDelayTimer(aInstance) #endif , mScheduleTransmissionTask(aInstance) -#if OPENTHREAD_FTD +#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE , mIndirectSender(aInstance) #endif , mDataPollSender(aInstance) diff --git a/src/core/thread/mesh_forwarder.hpp b/src/core/thread/mesh_forwarder.hpp index 1714bba1a..4a27db389 100644 --- a/src/core/thread/mesh_forwarder.hpp +++ b/src/core/thread/mesh_forwarder.hpp @@ -643,8 +643,11 @@ private: otIpCounters mIpCounters; +#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE + IndirectSender mIndirectSender; +#endif + #if OPENTHREAD_FTD - IndirectSender mIndirectSender; FwdFrameInfoArray mFwdFrameInfoArray; #endif diff --git a/src/core/thread/neighbor.hpp b/src/core/thread/neighbor.hpp index dfc16feec..b7e90e647 100644 --- a/src/core/thread/neighbor.hpp +++ b/src/core/thread/neighbor.hpp @@ -769,6 +769,22 @@ private: DefineCoreType(otNeighborInfo, Neighbor::Info); +/** + * Represents a CSL neighbor. + */ +class CslNeighbor : public Neighbor +#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE + , + public IndirectSender::NeighborInfo, + public DataPollHandler::NeighborInfo +#endif +#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE + , + public CslTxScheduler::NeighborInfo +#endif +{ +}; + } // namespace ot #endif // NEIGHBOR_HPP_