From 2bb72299d3d91109247001116a1e15a3bbbf8f68 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Sat, 14 Mar 2020 09:26:03 -0700 Subject: [PATCH] [mle] define ResponseHeaderMetadata as inner type of Mle class (#4683) This commit also simplifies `Header` class methods and moves its `enum` definitions to the top of class. --- src/core/thread/mle.cpp | 61 ++++++++----- src/core/thread/mle.hpp | 196 +++++++++++----------------------------- 2 files changed, 90 insertions(+), 167 deletions(-) diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 895f5f4c6..651ff74c8 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -1865,36 +1865,33 @@ void Mle::HandleDelayedResponseTimer(Timer &aTimer) void Mle::HandleDelayedResponseTimer(void) { - DelayedResponseHeader delayedResponse; - TimeMilli now = TimerMilli::GetNow(); - TimeMilli nextSendTime = now.GetDistantFuture(); - Message * message; - Message * nextMessage; + DelayedResponseMetadata metadata; + TimeMilli now = TimerMilli::GetNow(); + TimeMilli nextSendTime = now.GetDistantFuture(); + Message * message; + Message * nextMessage; for (message = mDelayedResponses.GetHead(); message != NULL; message = nextMessage) { nextMessage = message->GetNext(); - delayedResponse.ReadFrom(*message); + metadata.ReadFrom(*message); - if (now < delayedResponse.GetSendTime()) + if (now < metadata.mSendTime) { - if (nextSendTime > delayedResponse.GetSendTime()) + if (nextSendTime > metadata.mSendTime) { - nextSendTime = delayedResponse.GetSendTime(); + nextSendTime = metadata.mSendTime; } } else { mDelayedResponses.Dequeue(*message); + metadata.RemoveFrom(*message); - // Remove the DelayedResponseHeader from the message. - DelayedResponseHeader::RemoveFrom(*message); - - // Send the message. - if (SendMessage(*message, delayedResponse.GetDestination()) == OT_ERROR_NONE) + if (SendMessage(*message, metadata.mDestination) == OT_ERROR_NONE) { - LogMleMessage("Send delayed message", delayedResponse.GetDestination()); + LogMleMessage("Send delayed message", metadata.mDestination); // Here enters fast poll mode, as for Rx-Off-when-idle device, the enqueued msg should // be Mle Data Request. @@ -1921,18 +1918,18 @@ void Mle::HandleDelayedResponseTimer(void) void Mle::RemoveDelayedDataResponseMessage(void) { - Message * message = mDelayedResponses.GetHead(); - DelayedResponseHeader delayedResponse; + Message * message = mDelayedResponses.GetHead(); + DelayedResponseMetadata metadata; while (message != NULL) { - delayedResponse.ReadFrom(*message); + metadata.ReadFrom(*message); if (message->GetSubType() == Message::kSubTypeMleDataResponse) { mDelayedResponses.Dequeue(*message); message->Free(); - LogMleMessage("Remove Delayed Data Response", delayedResponse.GetDestination()); + LogMleMessage("Remove Delayed Data Response", metadata.mDestination); // no more than one multicast MLE Data Response in Delayed Message Queue. break; @@ -2537,13 +2534,16 @@ exit: otError Mle::AddDelayedResponse(Message &aMessage, const Ip6::Address &aDestination, uint16_t aDelay) { - otError error = OT_ERROR_NONE; - DelayedResponseHeader delayedResponse(TimerMilli::GetNow() + aDelay, aDestination); + otError error = OT_ERROR_NONE; + DelayedResponseMetadata metadata; - SuccessOrExit(error = delayedResponse.AppendTo(aMessage)); + metadata.mSendTime = TimerMilli::GetNow() + aDelay; + metadata.mDestination = aDestination; + + SuccessOrExit(error = metadata.AppendTo(aMessage)); mDelayedResponses.Enqueue(aMessage); - mDelayedResponseTimer.FireAtIfEarlier(delayedResponse.GetSendTime()); + mDelayedResponseTimer.FireAtIfEarlier(metadata.mSendTime); exit: return error; @@ -4303,5 +4303,20 @@ bool Mle::Challenge::Matches(const uint8_t *aBuffer, uint8_t aLength) const return (mLength == aLength) && (memcmp(mBuffer, aBuffer, aLength) == 0); } +void Mle::DelayedResponseMetadata::ReadFrom(const Message &aMessage) +{ + uint16_t length = aMessage.GetLength(); + + OT_ASSERT(length >= sizeof(*this)); + aMessage.Read(length - sizeof(*this), sizeof(*this), this); +} + +void Mle::DelayedResponseMetadata::RemoveFrom(Message &aMessage) const +{ + otError error = aMessage.SetLength(aMessage.GetLength() - sizeof(*this)); + OT_ASSERT(error == OT_ERROR_NONE); + OT_UNUSED_VARIABLE(error); +} + } // namespace Mle } // namespace ot diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index 2386817a7..90c5ce6c9 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -90,6 +90,43 @@ OT_TOOL_PACKED_BEGIN class Header { public: + /** + * MLE Command Types. + * + */ + enum Command + { + kCommandLinkRequest = 0, ///< Link Request + kCommandLinkAccept = 1, ///< Link Accept + kCommandLinkAcceptAndRequest = 2, ///< Link Accept and Reject + kCommandLinkReject = 3, ///< Link Reject + kCommandAdvertisement = 4, ///< Advertisement + kCommandUpdate = 5, ///< Update + kCommandUpdateRequest = 6, ///< Update Request + kCommandDataRequest = 7, ///< Data Request + kCommandDataResponse = 8, ///< Data Response + kCommandParentRequest = 9, ///< Parent Request + kCommandParentResponse = 10, ///< Parent Response + kCommandChildIdRequest = 11, ///< Child ID Request + kCommandChildIdResponse = 12, ///< Child ID Response + kCommandChildUpdateRequest = 13, ///< Child Update Request + kCommandChildUpdateResponse = 14, ///< Child Update Response + kCommandAnnounce = 15, ///< Announce + kCommandDiscoveryRequest = 16, ///< Discovery Request + kCommandDiscoveryResponse = 17, ///< Discovery Response + kCommandTimeSync = 99, ///< Time Sync (applicable when OPENTHREAD_CONFIG_TIME_SYNC_ENABLE enabled) + }; + + /** + * MLE Security Suite + * + */ + enum SecuritySuite + { + k154Security = 0, ///< IEEE 802.15.4-2006 security. + kNoSecurity = 255, ///< No security enabled. + }; + /** * This method initializes the MLE header. * @@ -122,22 +159,12 @@ public: */ uint8_t GetLength(void) const { - uint8_t rval = sizeof(mSecuritySuite) + sizeof(mCommand); - - if (mSecuritySuite == k154Security) - { - rval += sizeof(mSecurityControl) + sizeof(mFrameCounter) + sizeof(mKeySource) + sizeof(mKeyIndex); - } - - return rval; + return sizeof(mSecuritySuite) + sizeof(mCommand) + + ((mSecuritySuite == k154Security) + ? sizeof(mSecurityControl) + sizeof(mFrameCounter) + sizeof(mKeySource) + sizeof(mKeyIndex) + : 0); } - enum SecuritySuite - { - k154Security = 0, ///< IEEE 802.15.4-2006 security. - kNoSecurity = 255, ///< No security enabled. - }; - /** * This method returns the Security Suite value. * @@ -235,39 +262,6 @@ public: */ void SetFrameCounter(uint32_t aFrameCounter) { mFrameCounter = Encoding::LittleEndian::HostSwap32(aFrameCounter); } - /** - * MLE Command Types. - * - */ - enum Command - { - kCommandLinkRequest = 0, ///< Link Reject - kCommandLinkAccept = 1, ///< Link Accept - kCommandLinkAcceptAndRequest = 2, ///< Link Accept and Reject - kCommandLinkReject = 3, ///< Link Reject - kCommandAdvertisement = 4, ///< Advertisement - kCommandUpdate = 5, ///< Update - kCommandUpdateRequest = 6, ///< Update Request - kCommandDataRequest = 7, ///< Data Request - kCommandDataResponse = 8, ///< Data Response - kCommandParentRequest = 9, ///< Parent Request - kCommandParentResponse = 10, ///< Parent Response - kCommandChildIdRequest = 11, ///< Child ID Request - kCommandChildIdResponse = 12, ///< Child ID Response - kCommandChildUpdateRequest = 13, ///< Child Update Request - kCommandChildUpdateResponse = 14, ///< Child Update Response - kCommandAnnounce = 15, ///< Announce - kCommandDiscoveryRequest = 16, ///< Discovery Request - kCommandDiscoveryResponse = 17, ///< Discovery Response - - /** - * Applicable/Required only when time synchronization service - * (`OPENTHREAD_CONFIG_TIME_SYNC_ENABLE`) is enabled. - * - */ - kCommandTimeSync = 99, ///< Time Synchronization - }; - /** * This method returns the Command Type value. * @@ -276,14 +270,7 @@ public: */ Command GetCommand(void) const { - if (mSecuritySuite == kNoSecurity) - { - return static_cast(mSecurityControl); - } - else - { - return static_cast(mCommand); - } + return static_cast((mSecuritySuite == kNoSecurity) ? mSecurityControl : mCommand); } /** @@ -313,95 +300,6 @@ private: uint8_t mCommand; } OT_TOOL_PACKED_END; -/** - * This class implements functionality required for delaying MLE responses. - * - */ -class DelayedResponseHeader -{ -public: - /** - * Default constructor for the object. - * - */ - DelayedResponseHeader(void) - : mDestination() - , mSendTime(0) - { - mDestination.Clear(); - } - - /** - * This constructor initializes the object with specific values. - * - * @param[in] aSendTime Time when the message shall be sent. - * @param[in] aDestination IPv6 address of the message destination. - * - */ - DelayedResponseHeader(TimeMilli aSendTime, const Ip6::Address &aDestination) - : mDestination(aDestination) - , mSendTime(aSendTime) - { - } - - /** - * This method appends delayed response header to the message. - * - * @param[in] aMessage A reference to the message. - * - * @retval OT_ERROR_NONE Successfully appended the bytes. - * @retval OT_ERROR_NO_BUFS Insufficient available buffers to grow the message. - * - */ - otError AppendTo(Message &aMessage) { return aMessage.Append(this, sizeof(*this)); } - - /** - * This method reads delayed response header from the message. - * - * @param[in] aMessage A reference to the message. - * - */ - void ReadFrom(const Message &aMessage) - { - uint16_t length = aMessage.Read(aMessage.GetLength() - sizeof(*this), sizeof(*this), this); - OT_ASSERT(length == sizeof(*this)); - OT_UNUSED_VARIABLE(length); - } - - /** - * This method removes delayed response header from the message. - * - * @param[in] aMessage A reference to the message. - * - */ - static void RemoveFrom(Message &aMessage) - { - otError error = aMessage.SetLength(aMessage.GetLength() - sizeof(DelayedResponseHeader)); - OT_ASSERT(error == OT_ERROR_NONE); - OT_UNUSED_VARIABLE(error); - } - - /** - * This method returns a time when the message shall be sent. - * - * @returns A time when the message shall be sent. - * - */ - TimeMilli GetSendTime(void) const { return mSendTime; } - - /** - * This method returns a destination of the delayed message. - * - * @returns A destination of the delayed message. - * - */ - const Ip6::Address &GetDestination(void) const { return mDestination; } - -private: - Ip6::Address mDestination; ///< IPv6 address of the message destination. - TimeMilli mSendTime; ///< Time when the message shall be sent. -}; - /** * This class implements MLE functionality required by the Thread EndDevices, Router, and Leader roles. * @@ -1734,6 +1632,16 @@ private: kDataRequestActive, ///< Data Request has been sent, Data Response is expected. }; + struct DelayedResponseMetadata + { + otError AppendTo(Message &aMessage) const { return aMessage.Append(this, sizeof(*this)); } + void ReadFrom(const Message &aMessage); + void RemoveFrom(Message &aMessage) const; + + Ip6::Address mDestination; // IPv6 address of the message destination. + TimeMilli mSendTime; // Time when the message shall be sent. + }; + static void HandleStateChanged(Notifier::Callback &aCallback, otChangedFlags aFlags); void HandleStateChanged(otChangedFlags aFlags); static void HandleAttachTimer(Timer &aTimer);