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());