From 70f2e54d06bcd58e5dca5404a57c6b8877ebf2d5 Mon Sep 17 00:00:00 2001 From: Li Cao Date: Tue, 2 Jun 2020 12:59:01 +0800 Subject: [PATCH] [low-power] encapsulate method to update header IE (#4999) OpenThread currently implements a TIME_SYNC IE. The presence of IEs also affects the frame version and IE present field. This commit encapsulates the process to update these things so that it could be easily extended to support other IEs that are introduced later. --- src/core/common/message.cpp | 9 ++++ src/core/common/message.hpp | 6 ++- src/core/mac/mac.cpp | 68 +++++++++++++++++++++++++- src/core/mac/mac.hpp | 28 +++++++++++ src/core/mac/mac_frame.cpp | 2 +- src/core/thread/mesh_forwarder.cpp | 33 ++----------- src/core/thread/mesh_forwarder_ftd.cpp | 6 +-- 7 files changed, 114 insertions(+), 38 deletions(-) diff --git a/src/core/common/message.cpp b/src/core/common/message.cpp index 1d5ff3409..cb1be9f87 100644 --- a/src/core/common/message.cpp +++ b/src/core/common/message.cpp @@ -763,6 +763,15 @@ uint16_t Message::UpdateChecksum(uint16_t aChecksum, uint16_t aOffset, uint16_t return aChecksum; } +bool Message::IsTimeSync(void) const +{ +#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE + return GetMetadata().mTimeSync; +#else + return false; +#endif +} + void Message::SetMessageQueue(MessageQueue *aMessageQueue) { GetMetadata().mQueue.mMessage = aMessageQueue; diff --git a/src/core/common/message.hpp b/src/core/common/message.hpp index 3e1f0bc0d..f4cac407f 100644 --- a/src/core/common/message.hpp +++ b/src/core/common/message.hpp @@ -854,16 +854,18 @@ public: return (GetMetadata().mInPriorityQ) ? GetMetadata().mQueue.mPriority : NULL; } -#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE /** * This method indicates whether or not the message is also used for time sync purpose. * + * When OPENTHREAD_CONFIG_TIME_SYNC_ENABLE is 0, this method always return false. + * * @retval TRUE If the message is also used for time sync purpose. * @retval FALSE If the message is not used for time sync purpose. * */ - bool IsTimeSync(void) const { return GetMetadata().mTimeSync; } + bool IsTimeSync(void) const; +#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE /** * This method sets whether or not the message is also used for time sync purpose. * diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index 9fda3368e..34b026433 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -832,8 +832,8 @@ otError Mac::PrepareDataRequest(TxFrame &aFrame) SuccessOrExit(error = Get().GetPollDestinationAddress(dst)); VerifyOrExit(!dst.IsNone(), error = OT_ERROR_ABORT); - fcf = Frame::kFcfFrameMacCmd | Frame::kFcfPanidCompression | Frame::kFcfFrameVersion2006 | Frame::kFcfAckRequest | - Frame::kFcfSecurityEnabled; + fcf = Frame::kFcfFrameMacCmd | Frame::kFcfPanidCompression | Frame::kFcfAckRequest | Frame::kFcfSecurityEnabled; + UpdateFrameControlField(/* aIsTimeSync */ false, fcf); if (dst.IsExtended()) { @@ -2061,5 +2061,69 @@ exit: } #endif +#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT +otError Mac::AppendHeaderIe(bool aIsTimeSync, TxFrame &aFrame) +{ + OT_UNUSED_VARIABLE(aIsTimeSync); + + const size_t kMaxNumHeaderIe = 3; // TimeSync + Csl + Termination2 + HeaderIe ieList[kMaxNumHeaderIe]; + otError error = OT_ERROR_NONE; + uint8_t ieCount = 0; + + VerifyOrExit(aFrame.IsVersion2015() && aFrame.IsIePresent(), OT_NOOP); + +#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE + if (aIsTimeSync) + { + ieList[ieCount].Init(); + ieList[ieCount].SetId(Frame::kHeaderIeVendor); + ieList[ieCount].SetLength(sizeof(TimeIe)); + ieCount++; + } +#endif + + if (ieCount > 0) + { + ieList[ieCount].Init(); + ieList[ieCount].SetId(Frame::kHeaderIeTermination2); + ieList[ieCount].SetLength(0); + + SuccessOrExit(error = aFrame.AppendHeaderIe(ieList, ++ieCount)); + } + +#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE + if (aIsTimeSync) + { + uint8_t *cur = aFrame.GetHeaderIe(Frame::kHeaderIeVendor); + TimeIe * ie = reinterpret_cast(cur + sizeof(HeaderIe)); + + ie->Init(); + } +#endif + +exit: + return error; +} +#endif // OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT + +void Mac::UpdateFrameControlField(bool aIsTimeSync, uint16_t &aFcf) +{ + OT_UNUSED_VARIABLE(aIsTimeSync); + +#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT +#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE + if (aIsTimeSync) + { + aFcf |= Frame::kFcfFrameVersion2015 | Frame::kFcfIePresent; + } + else +#endif +#endif + { + aFcf |= Frame::kFcfFrameVersion2006; + } +} + } // namespace Mac } // namespace ot diff --git a/src/core/mac/mac.hpp b/src/core/mac/mac.hpp index 01dd080e4..838681bd5 100644 --- a/src/core/mac/mac.hpp +++ b/src/core/mac/mac.hpp @@ -663,6 +663,34 @@ public: */ bool IsEnabled(void) const { return mEnabled; } +#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT + /** + * This method appends header IEs to a TX-frame according to its + * frame control field and if time sync is enabled. + * + * @param[in] aIsTimeSync A boolean indicates if time sync is being used. + * @param[in,out] aFrame A reference to the TX-frame to which the IEs will be appended. + * + * @retval OT_ERROR_NONE If append header IEs successfully. + * @retval OT_ERROR_NOT_FOUND If cannot find header IE position in the frame. + * + */ + static otError AppendHeaderIe(bool aIsTimeSync, TxFrame &aFrame); +#endif + + /** + * This method updates frame control field. + * + * If the frame would contain header IEs, IE present field would be set. + * If this is a csl transmission frame or header IE is present in this frame, + * the version should be set to 2015. Otherwise, the version would be set to 2006. + * + * @param[in] aIsTimeSync A boolean indicates if time sync is being used. + * @param[out] aFcf A reference to the frame control field to set. + * + */ + static void UpdateFrameControlField(bool aIsTimeSync, uint16_t &aFcf); + private: enum { diff --git a/src/core/mac/mac_frame.cpp b/src/core/mac/mac_frame.cpp index b3124443b..d11a8c871 100644 --- a/src/core/mac/mac_frame.cpp +++ b/src/core/mac/mac_frame.cpp @@ -918,7 +918,7 @@ otError Frame::AppendHeaderIe(HeaderIe *aIeList, uint8_t aIeCount) uint8_t *cur; uint8_t *base; - VerifyOrExit(index != kInvalidIndex, error = OT_ERROR_FAILED); + VerifyOrExit(index != kInvalidIndex, error = OT_ERROR_NOT_FOUND); cur = GetPsdu() + index; base = cur; diff --git a/src/core/thread/mesh_forwarder.cpp b/src/core/thread/mesh_forwarder.cpp index 424e55977..7c0d732a7 100644 --- a/src/core/thread/mesh_forwarder.cpp +++ b/src/core/thread/mesh_forwarder.cpp @@ -523,16 +523,7 @@ start: // Initialize MAC header fcf = Mac::Frame::kFcfFrameData; -#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE - if (aMessage.IsTimeSync()) - { - fcf |= Mac::Frame::kFcfFrameVersion2015 | Mac::Frame::kFcfIePresent; - } - else -#endif - { - fcf |= Mac::Frame::kFcfFrameVersion2006; - } + Get().UpdateFrameControlField(aMessage.IsTimeSync(), fcf); fcf |= (aMacDest.IsShort()) ? Mac::Frame::kFcfDstAddrShort : Mac::Frame::kFcfDstAddrExt; fcf |= (aMacSource.IsShort()) ? Mac::Frame::kFcfSrcAddrShort : Mac::Frame::kFcfSrcAddrExt; @@ -613,26 +604,8 @@ start: aFrame.SetDstAddr(aMacDest); aFrame.SetSrcAddr(aMacSource); -#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE - if (aMessage.IsTimeSync()) - { - Mac::TimeIe * ie; - uint8_t * cur = NULL; - Mac::HeaderIe ieList[2]; - - ieList[0].Init(); - ieList[0].SetId(Mac::Frame::kHeaderIeVendor); - ieList[0].SetLength(sizeof(Mac::TimeIe)); - ieList[1].Init(); - ieList[1].SetId(Mac::Frame::kHeaderIeTermination2); - ieList[1].SetLength(0); - IgnoreError(aFrame.AppendHeaderIe(ieList, 2)); - - cur = aFrame.GetHeaderIe(Mac::Frame::kHeaderIeVendor); - ie = reinterpret_cast(cur + sizeof(Mac::HeaderIe)); - ie->Init(); - } - +#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT + IgnoreError(Get().AppendHeaderIe(aMessage.IsTimeSync(), aFrame)); #endif payload = aFrame.GetPayload(); diff --git a/src/core/thread/mesh_forwarder_ftd.cpp b/src/core/thread/mesh_forwarder_ftd.cpp index a756452ec..24e3765ff 100644 --- a/src/core/thread/mesh_forwarder_ftd.cpp +++ b/src/core/thread/mesh_forwarder_ftd.cpp @@ -351,9 +351,9 @@ void MeshForwarder::SendMesh(Message &aMessage, Mac::TxFrame &aFrame) uint16_t fcf; // initialize MAC header - fcf = Mac::Frame::kFcfFrameData | Mac::Frame::kFcfPanidCompression | Mac::Frame::kFcfFrameVersion2006 | - Mac::Frame::kFcfDstAddrShort | Mac::Frame::kFcfSrcAddrShort | Mac::Frame::kFcfAckRequest | - Mac::Frame::kFcfSecurityEnabled; + fcf = Mac::Frame::kFcfFrameData | Mac::Frame::kFcfPanidCompression | Mac::Frame::kFcfDstAddrShort | + Mac::Frame::kFcfSrcAddrShort | Mac::Frame::kFcfAckRequest | Mac::Frame::kFcfSecurityEnabled; + Get().UpdateFrameControlField(aMessage.IsTimeSync(), fcf); aFrame.InitMacHeader(fcf, Mac::Frame::kKeyIdMode1 | Mac::Frame::kSecEncMic32); aFrame.SetDstPanId(Get().GetPanId());