diff --git a/src/core/mac/data_poll_sender.cpp b/src/core/mac/data_poll_sender.cpp index 80e18f7a5be..ef3d4b662d1 100644 --- a/src/core/mac/data_poll_sender.cpp +++ b/src/core/mac/data_poll_sender.cpp @@ -255,16 +255,14 @@ void DataPollSender::HandlePollSent(Mac::TxFrame &aFrame, Error aError) #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE LogInfo("Failed to send data poll, error:%s, retx:%d/%d", ErrorToString(aError), mPollTxFailureCounter, - (aFrame.GetHeaderIe(Mac::CslIe::kHeaderIeId) != nullptr) ? kMaxCslPollRetxAttempts - : kMaxPollRetxAttempts); + aFrame.HasCslIe() ? kMaxCslPollRetxAttempts : kMaxPollRetxAttempts); #else LogInfo("Failed to send data poll, error:%s, retx:%d/%d", ErrorToString(aError), mPollTxFailureCounter, kMaxPollRetxAttempts); #endif #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE - if (mPollTxFailureCounter < - ((aFrame.GetHeaderIe(Mac::CslIe::kHeaderIeId) != nullptr) ? kMaxCslPollRetxAttempts : kMaxPollRetxAttempts)) + if (mPollTxFailureCounter < (aFrame.HasCslIe() ? kMaxCslPollRetxAttempts : kMaxPollRetxAttempts)) #else if (mPollTxFailureCounter < kMaxPollRetxAttempts) #endif @@ -344,7 +342,7 @@ void DataPollSender::ProcessTxDone(const Mac::TxFrame &aFrame, const Mac::RxFram VerifyOrExit(aFrame.GetSecurityEnabled()); #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE - if (aFrame.mInfo.mTxInfo.mIsARetx && (aFrame.GetHeaderIe(Mac::CslIe::kHeaderIeId) != nullptr)) + if (aFrame.mInfo.mTxInfo.mIsARetx && aFrame.HasCslIe()) { // For retransmission frame, use a data poll to resync its parent with correct CSL phase sendDataPoll = true; @@ -583,7 +581,7 @@ Mac::TxFrame *DataPollSender::PrepareDataRequest(Mac::TxFrames &aTxFrames) Mac::Frame::kSecurityEncMic32, Mac::Frame::kKeyIdMode1, nullptr); #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT && OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE - if (frame->GetHeaderIe(Mac::CslIe::kHeaderIeId) != nullptr) + if (frame->HasCslIe()) { // Disable frame retransmission when the data poll has CSL IE included aTxFrames.SetMaxFrameRetries(0); diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index d1fbd0a8e2d..98b06ed1dc1 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -1316,7 +1316,7 @@ void Mac::HandleTransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aError) ProcessCsl(*aAckFrame, dstAddr); #endif #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE - if (!mRxOnWhenIdle && aFrame.GetHeaderIe(CslIe::kHeaderIeId) != nullptr) + if (!mRxOnWhenIdle && aFrame.HasCslIe()) { Get().ResetKeepAliveTimer(); } @@ -2356,19 +2356,17 @@ bool Mac::IsCslSupported(void) const #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE void Mac::ProcessCsl(const RxFrame &aFrame, const Address &aSrcAddr) { - const uint8_t *cur; - Child *child; - const CslIe *csl; + Child *child; + const CslIe *csl; VerifyOrExit(aFrame.IsVersion2015() && aFrame.GetSecurityEnabled()); - cur = aFrame.GetHeaderIe(CslIe::kHeaderIeId); - VerifyOrExit(cur != nullptr); + csl = aFrame.GetCslIe(); + VerifyOrExit(csl != nullptr); child = Get().FindChild(aSrcAddr, Child::kInStateAnyExceptInvalid); VerifyOrExit(child != nullptr); - csl = reinterpret_cast(cur + sizeof(HeaderIe)); VerifyOrExit(csl->GetPeriod() >= kMinCslIePeriod); child->SetCslPeriod(csl->GetPeriod()); diff --git a/src/core/mac/mac_frame.cpp b/src/core/mac/mac_frame.cpp index 035319b270c..0c6f59e9fe1 100644 --- a/src/core/mac/mac_frame.cpp +++ b/src/core/mac/mac_frame.cpp @@ -1232,19 +1232,34 @@ const uint8_t *Frame::GetThreadIe(uint8_t aSubType) const #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE void Frame::SetCslIe(uint16_t aCslPeriod, uint16_t aCslPhase) { - uint8_t *cur = GetHeaderIe(CslIe::kHeaderIeId); - CslIe *csl; + CslIe *csl = GetCslIe(); - VerifyOrExit(cur != nullptr); - - csl = reinterpret_cast(cur + sizeof(HeaderIe)); + VerifyOrExit(csl != nullptr); csl->SetPeriod(aCslPeriod); csl->SetPhase(aCslPhase); + exit: return; } + +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) +const CslIe *Frame::GetCslIe(void) const +{ + const uint8_t *cur; + const CslIe *csl = nullptr; + + cur = GetHeaderIe(CslIe::kHeaderIeId); + VerifyOrExit(cur != nullptr); + csl = reinterpret_cast(cur + sizeof(HeaderIe)); + +exit: + return csl; +} +#endif + #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE void Frame::SetEnhAckProbingIe(const uint8_t *aValue, uint8_t aLen) { diff --git a/src/core/mac/mac_frame.hpp b/src/core/mac/mac_frame.hpp index eef63aae453..4ce92410361 100644 --- a/src/core/mac/mac_frame.hpp +++ b/src/core/mac/mac_frame.hpp @@ -134,6 +134,67 @@ class HeaderIe } OT_TOOL_PACKED_END; +/** + * Implements CSL IE data structure. + * + */ +OT_TOOL_PACKED_BEGIN +class CslIe +{ +public: + static constexpr uint8_t kHeaderIeId = 0x1a; + static constexpr uint8_t kIeContentSize = sizeof(uint16_t) * 2; + + /** + * Returns the CSL Period. + * + * @returns the CSL Period. + * + */ + uint16_t GetPeriod(void) const { return LittleEndian::HostSwap16(mPeriod); } + + /** + * Sets the CSL Period. + * + * @param[in] aPeriod The CSL Period. + * + */ + void SetPeriod(uint16_t aPeriod) { mPeriod = LittleEndian::HostSwap16(aPeriod); } + + /** + * Returns the CSL Phase. + * + * @returns the CSL Phase. + * + */ + uint16_t GetPhase(void) const { return LittleEndian::HostSwap16(mPhase); } + + /** + * Sets the CSL Phase. + * + * @param[in] aPhase The CSL Phase. + * + */ + void SetPhase(uint16_t aPhase) { mPhase = LittleEndian::HostSwap16(aPhase); } + +private: + uint16_t mPhase; + uint16_t mPeriod; +} OT_TOOL_PACKED_END; + +/** + * Implements Termination2 IE. + * + * Is empty for template specialization. + * + */ +class Termination2Ie +{ +public: + static constexpr uint8_t kHeaderIeId = 0x7f; + static constexpr uint8_t kIeContentSize = 0; +}; + #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || \ OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE /** @@ -1023,8 +1084,35 @@ class Frame : public otRadioFrame * */ void SetCslIe(uint16_t aCslPeriod, uint16_t aCslPhase); + + /** + * Indicates whether or not the frame contains CSL IE. + * + * @retval TRUE If the frame contains CSL IE. + * @retval FALSE If the frame doesn't contain CSL IE. + * + */ + 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) + /** + * Returns a pointer to a CSL IE. + * + * @returns A pointer to the CSL IE, `nullptr` if not found. + * + */ + const CslIe *GetCslIe(void) const; + + /** + * Returns a pointer to a CSL IE. + * + * @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) + #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE /** * Finds Enhanced ACK Probing (Vendor Specific) IE and set its value. @@ -1766,67 +1854,6 @@ class BeaconPayload otExtendedPanId mExtendedPanId; } OT_TOOL_PACKED_END; -/** - * Implements CSL IE data structure. - * - */ -OT_TOOL_PACKED_BEGIN -class CslIe -{ -public: - static constexpr uint8_t kHeaderIeId = 0x1a; - static constexpr uint8_t kIeContentSize = sizeof(uint16_t) * 2; - - /** - * Returns the CSL Period. - * - * @returns the CSL Period. - * - */ - uint16_t GetPeriod(void) const { return LittleEndian::HostSwap16(mPeriod); } - - /** - * Sets the CSL Period. - * - * @param[in] aPeriod The CSL Period. - * - */ - void SetPeriod(uint16_t aPeriod) { mPeriod = LittleEndian::HostSwap16(aPeriod); } - - /** - * Returns the CSL Phase. - * - * @returns the CSL Phase. - * - */ - uint16_t GetPhase(void) const { return LittleEndian::HostSwap16(mPhase); } - - /** - * Sets the CSL Phase. - * - * @param[in] aPhase The CSL Phase. - * - */ - void SetPhase(uint16_t aPhase) { mPhase = LittleEndian::HostSwap16(aPhase); } - -private: - uint16_t mPhase; - uint16_t mPeriod; -} OT_TOOL_PACKED_END; - -/** - * Implements Termination2 IE. - * - * Is empty for template specialization. - * - */ -class Termination2Ie -{ -public: - static constexpr uint8_t kHeaderIeId = 0x7f; - static constexpr uint8_t kIeContentSize = 0; -}; - /** * @} * diff --git a/src/core/mac/sub_mac_csl_receiver.cpp b/src/core/mac/sub_mac_csl_receiver.cpp index 85611f95b60..e890687d661 100644 --- a/src/core/mac/sub_mac_csl_receiver.cpp +++ b/src/core/mac/sub_mac_csl_receiver.cpp @@ -60,7 +60,7 @@ void SubMac::UpdateCslLastSyncTimestamp(TxFrame &aFrame, RxFrame *aAckFrame) { // Actual synchronization timestamp should be from the sent frame instead of the current time. // Assuming the error here since it is bounded and has very small effect on the final window duration. - if (aAckFrame != nullptr && aFrame.GetHeaderIe(CslIe::kHeaderIeId) != nullptr) + if (aAckFrame != nullptr && aFrame.HasCslIe()) { mCslLastSync = TimeMicro(GetLocalTime()); } diff --git a/src/core/thread/mesh_forwarder.cpp b/src/core/thread/mesh_forwarder.cpp index 004bbe834c8..085b4018879 100644 --- a/src/core/thread/mesh_forwarder.cpp +++ b/src/core/thread/mesh_forwarder.cpp @@ -1138,7 +1138,7 @@ Neighbor *MeshForwarder::UpdateNeighborOnSentFrame(Mac::TxFrame &aFrame, #endif // OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE - if ((aFrame.GetHeaderIe(Mac::CslIe::kHeaderIeId) != nullptr) && aIsDataPoll) + if (aFrame.HasCslIe() && aIsDataPoll) { failLimit = kFailedCslDataPollTransmissions; }