diff --git a/src/core/mac/mac_frame.cpp b/src/core/mac/mac_frame.cpp index 474b6709a..87af6ecca 100644 --- a/src/core/mac/mac_frame.cpp +++ b/src/core/mac/mac_frame.cpp @@ -168,6 +168,15 @@ void TxFrame::Info::PrepareHeadersIn(TxFrame &aTxFrame) const fcf |= kFcfSequenceSuppression; } +#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT +#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE + fcf |= (mAppendTimeIe ? kFcfIePresent : 0); +#endif +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE + fcf |= (mAppendCslIe ? kFcfIePresent : 0); +#endif +#endif + builder.Init(aTxFrame.mPsdu, aTxFrame.GetMtu()); IgnoreError(builder.AppendLittleEndianUint16(fcf)); @@ -202,6 +211,31 @@ void TxFrame::Info::PrepareHeadersIn(TxFrame &aTxFrame) const micSize = CalculateMicSize(secCtl); } +#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT + +#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE + if (mAppendTimeIe) + { + builder.Append()->Init(TimeIe::kHeaderIeId, sizeof(TimeIe)); + builder.Append()->Init(); + } +#endif + +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE + if (mAppendCslIe) + { + builder.Append()->Init(CslIe::kHeaderIeId, sizeof(CslIe)); + builder.Append(); + } +#endif + + if ((fcf & kFcfIePresent) && ((mType == kTypeMacCmd) || !mEmptyPayload)) + { + builder.Append()->Init(Termination2Ie::kHeaderIeId, Termination2Ie::kIeContentSize); + } + +#endif // OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT + if (mType == kTypeMacCmd) { builder.Append(); // Placeholder for Command ID @@ -1098,65 +1132,6 @@ exit: return index; } -#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT -template Error Frame::AppendHeaderIeAt(uint8_t &aIndex) -{ - Error error = kErrorNone; - - SuccessOrExit(error = InitIeHeaderAt(aIndex, IeType::kHeaderIeId, IeType::kIeContentSize)); - - InitIeContentAt(aIndex); - -exit: - return error; -} - -Error Frame::InitIeHeaderAt(uint8_t &aIndex, uint8_t ieId, uint8_t ieContentSize) -{ - Error error = kErrorNone; - - SetIePresent(true); - - if (aIndex == 0) - { - aIndex = FindHeaderIeIndex(); - } - - VerifyOrExit(aIndex != kInvalidIndex, error = kErrorNotFound); - - reinterpret_cast(mPsdu + aIndex)->Init(ieId, ieContentSize); - aIndex += sizeof(HeaderIe); - - mLength += sizeof(HeaderIe) + ieContentSize; -exit: - return error; -} - -#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE -template <> void Frame::InitIeContentAt(uint8_t &aIndex) -{ - reinterpret_cast(mPsdu + aIndex)->Init(); - aIndex += sizeof(TimeIe); -} -#endif - -#if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE -template <> void Frame::InitIeContentAt(uint8_t &aIndex) { aIndex += sizeof(RendezvousTimeIe); } - -template <> void Frame::InitIeContentAt(uint8_t &aIndex) -{ - reinterpret_cast(mPsdu + aIndex)->Init(); - aIndex += sizeof(ConnectionIe); -} -#endif - -#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE -template <> void Frame::InitIeContentAt(uint8_t &aIndex) { aIndex += sizeof(CslIe); } -#endif - -template <> void Frame::InitIeContentAt(uint8_t &aIndex) { OT_UNUSED_VARIABLE(aIndex); } -#endif // OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT - const uint8_t *Frame::GetHeaderIe(uint8_t aIeId) const { uint8_t index = FindHeaderIeIndex(); @@ -1338,21 +1313,6 @@ uint16_t Frame::GetMtu(void) const { return Trel::Link::kMtuSize; } uint8_t Frame::GetFcsSize(void) const { return Trel::Link::kFcsSize; } #endif -// Explicit instantiation -#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT -#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE -template Error Frame::AppendHeaderIeAt(uint8_t &aIndex); -#endif -#if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE -template Error Frame::AppendHeaderIeAt(uint8_t &aIndex); -template Error Frame::AppendHeaderIeAt(uint8_t &aIndex); -#endif -#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE -template Error Frame::AppendHeaderIeAt(uint8_t &aIndex); -#endif -template Error Frame::AppendHeaderIeAt(uint8_t &aIndex); -#endif - void TxFrame::CopyFrom(const TxFrame &aFromFrame) { uint8_t *psduBuffer = mPsdu; @@ -1532,7 +1492,6 @@ Error TxFrame::GenerateWakeupFrame(PanId aPanId, const Address &aDest, const Add Error error = kErrorNone; uint16_t fcf; uint8_t secCtl; - uint8_t index = 0; FrameBuilder builder; fcf = kTypeMultipurpose | kMpFcfLongFrame | kMpFcfPanidPresent | kMpFcfSecurityEnabled | kMpFcfSequenceSuppression | @@ -1554,13 +1513,16 @@ Error TxFrame::GenerateWakeupFrame(PanId aPanId, const Address &aDest, const Add IgnoreError(builder.AppendUint8(secCtl)); builder.AppendLength(CalculateSecurityHeaderSize(secCtl) - sizeof(secCtl)); + builder.Append()->Init(RendezvousTimeIe::kHeaderIeId, sizeof(RendezvousTimeIe)); + builder.Append(); + + builder.Append()->Init(ConnectionIe::kHeaderIeId, sizeof(ConnectionIe)); + builder.Append()->Init(); + builder.AppendLength(CalculateMicSize(secCtl) + GetFcsSize()); mLength = builder.GetLength(); - SuccessOrExit(error = AppendHeaderIeAt(index)); - SuccessOrExit(error = AppendHeaderIeAt(index)); - exit: return error; } diff --git a/src/core/mac/mac_frame.hpp b/src/core/mac/mac_frame.hpp index 9f9164472..a2d116314 100644 --- a/src/core/mac/mac_frame.hpp +++ b/src/core/mac/mac_frame.hpp @@ -627,25 +627,6 @@ public: #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT - /** - * Appends an Header IE at specified index in this frame. - * - * Also sets the IE present bit in the Frame Control Field (FCF). - * - * @param[in,out] aIndex The index to append IE. If `aIndex` is `0` on input, this method finds the index - * for the first IE and appends the IE at that position. If the position is not found - * successfully, `aIndex` will be set to `kInvalidIndex`. Otherwise the IE will be - * appended at `aIndex` on input. And on output, `aIndex` will be set to the end of the - * IE just appended. - * - * @tparam IeType The Header IE type, it MUST contain a constant `kHeaderIeId` equal to the IE's Id - * and a constant `kIeContentSize` indicating the IE body's size. - * - * @retval kErrorNone Successfully appended the Header IE. - * @retval kErrorNotFound The position for first IE is not found. - */ - template Error AppendHeaderIeAt(uint8_t &aIndex); - /** * Returns a pointer to the Header IE. * @@ -884,9 +865,6 @@ protected: uint8_t FindPayloadIndex(void) const; #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT uint8_t FindHeaderIeIndex(void) const; - - Error InitIeHeaderAt(uint8_t &aIndex, uint8_t ieId, uint8_t ieContentSize); - template void InitIeContentAt(uint8_t &aIndex); #endif static uint8_t GetKeySourceLength(uint8_t aKeyIdMode); @@ -1071,8 +1049,11 @@ public: * - The destination address is not the broadcast address * - The frame type is not an ACK frame * - * The Frame Pending and IE Present flags in the FCF are not set. They may need to be set separately depending - * on the specific requirements of the frame being transmitted. + * The header IE entries are prepared based on `mAppendTimeIe` and `mAppendCslIe` flags and the IE Present + * flag in FCF is determined accordingly. + * + * The Frame Pending flag in FCF is not set. It may need to be set separately depending on the specific + * requirements of the frame being transmitted. * * @param[in,out] aTxFrame The `TxFrame` instance in which to prepare and append the MAC headers. */ @@ -1085,6 +1066,16 @@ public: SecurityLevel mSecurityLevel; ///< Frame security level. KeyIdMode mKeyIdMode; ///< Frame security key ID mode. bool mSuppressSequence : 1; ///< Whether to suppress seq number. + +#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT +#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE + bool mAppendTimeIe : 1; ///< Whether to append Time IE. +#endif +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE + bool mAppendCslIe : 1; ///< Whether to append CSL IE. +#endif + bool mEmptyPayload : 1; ///< Whether payload is empty (to decide about appending Termination2 IE). +#endif }; /** diff --git a/src/core/thread/mesh_forwarder.cpp b/src/core/thread/mesh_forwarder.cpp index e7b16066b..ee9e1226b 100644 --- a/src/core/thread/mesh_forwarder.cpp +++ b/src/core/thread/mesh_forwarder.cpp @@ -840,20 +840,66 @@ exit: void MeshForwarder::PrepareMacHeaders(Mac::TxFrame &aTxFrame, Mac::TxFrame::Info &aTxFrameInfo, const Message *aMessage) { - bool iePresent; + aTxFrameInfo.mVersion = Mac::Frame::kVersion2006; - iePresent = CalcIePresent(aMessage); - aTxFrameInfo.mVersion = - CalcFrameVersion(Get().FindNeighbor(aTxFrameInfo.mAddrs.mDestination), iePresent); + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Determine Header IE entries + +#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT + +#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE + if ((aMessage != nullptr) && aMessage->IsTimeSync()) + { + aTxFrameInfo.mAppendTimeIe = true; + aTxFrameInfo.mVersion = Mac::Frame::kVersion2015; + } +#endif +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE + if (Get().IsCslEnabled() && + !(aMessage != nullptr && aMessage->GetSubType() == Message::kSubTypeMleDiscoverRequest)) + { + aTxFrameInfo.mAppendCslIe = true; + aTxFrameInfo.mVersion = Mac::Frame::kVersion2015; + } +#endif + + aTxFrameInfo.mEmptyPayload = (aMessage == nullptr) || (aMessage->GetLength() == 0); + +#endif // OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT + +#if (OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE) || \ + OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Determine frame version + + if (aTxFrameInfo.mVersion == Mac::Frame::kVersion2006) + { + const Neighbor *neighbor = Get().FindNeighbor(aTxFrameInfo.mAddrs.mDestination); + +#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE + if ((neighbor != nullptr) && Get().Contains(*neighbor) && + static_cast(neighbor)->IsCslSynchronized()) + { + aTxFrameInfo.mVersion = Mac::Frame::kVersion2015; + } +#endif +#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE + if ((neighbor != nullptr) && neighbor->IsEnhAckProbingActive()) + { + aTxFrameInfo.mVersion = Mac::Frame::kVersion2015; + } +#endif + } + +#endif // OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Prepare MAC headers aTxFrameInfo.PrepareHeadersIn(aTxFrame); -#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT - if (iePresent) - { - AppendHeaderIe(aMessage, aTxFrame); - } -#endif + OT_UNUSED_VARIABLE(aMessage); } // This method constructs a MAC data from from a given IPv6 message. @@ -1718,85 +1764,6 @@ exit: } #endif -bool MeshForwarder::CalcIePresent(const Message *aMessage) -{ - bool iePresent = false; - - OT_UNUSED_VARIABLE(aMessage); - -#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT -#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE - iePresent |= (aMessage != nullptr && aMessage->IsTimeSync()); -#endif -#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE - if (!(aMessage != nullptr && aMessage->GetSubType() == Message::kSubTypeMleDiscoverRequest)) - { - iePresent |= Get().IsCslEnabled(); - } -#endif -#endif - - return iePresent; -} - -#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT -void MeshForwarder::AppendHeaderIe(const Message *aMessage, Mac::TxFrame &aFrame) -{ - uint8_t index = 0; - bool iePresent = false; - bool payloadPresent = - (aFrame.GetType() == Mac::Frame::kTypeMacCmd) || (aMessage != nullptr && aMessage->GetLength() != 0); - -#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE - if (aMessage != nullptr && aMessage->IsTimeSync()) - { - IgnoreError(aFrame.AppendHeaderIeAt(index)); - iePresent = true; - } -#endif -#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE - if (Get().IsCslEnabled()) - { - IgnoreError(aFrame.AppendHeaderIeAt(index)); - aFrame.SetCslIePresent(true); - iePresent = true; - } -#endif - - if (iePresent && payloadPresent) - { - // Assume no Payload IE in current implementation - IgnoreError(aFrame.AppendHeaderIeAt(index)); - } -} -#endif - -Mac::Frame::Version MeshForwarder::CalcFrameVersion(const Neighbor *aNeighbor, bool aIePresent) const -{ - Mac::Frame::Version version = Mac::Frame::kVersion2006; - OT_UNUSED_VARIABLE(aNeighbor); - - if (aIePresent) - { - version = Mac::Frame::kVersion2015; - } -#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE - else if ((aNeighbor != nullptr) && Get().Contains(*aNeighbor) && - static_cast(aNeighbor)->IsCslSynchronized()) - { - version = Mac::Frame::kVersion2015; - } -#endif -#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE - else if (aNeighbor != nullptr && aNeighbor->IsEnhAckProbingActive()) - { - version = Mac::Frame::kVersion2015; ///< Set version to 2015 to fetch Link Metrics data in Enh-ACK. - } -#endif - - return version; -} - // LCOV_EXCL_START #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_NOTE) diff --git a/src/core/thread/mesh_forwarder.hpp b/src/core/thread/mesh_forwarder.hpp index 8609f7a20..932da99a9 100644 --- a/src/core/thread/mesh_forwarder.hpp +++ b/src/core/thread/mesh_forwarder.hpp @@ -560,12 +560,6 @@ private: void GetForwardFramePriority(RxInfo &aRxInfo, Message::Priority &aPriority); #endif - bool CalcIePresent(const Message *aMessage); - Mac::Frame::Version CalcFrameVersion(const Neighbor *aNeighbor, bool aIePresent) const; -#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT - void AppendHeaderIe(const Message *aMessage, Mac::TxFrame &aFrame); -#endif - void PauseMessageTransmissions(void) { mTxPaused = true; } void ResumeMessageTransmissions(void);