[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.
diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp
index 895f5f4..651ff74 100644
--- a/src/core/thread/mle.cpp
+++ b/src/core/thread/mle.cpp
@@ -1865,36 +1865,33 @@
 
 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::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 @@
 
 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 @@
     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 2386817..90c5ce6 100644
--- a/src/core/thread/mle.hpp
+++ b/src/core/thread/mle.hpp
@@ -91,6 +91,43 @@
 {
 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 @@
      */
     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.
      *
@@ -236,39 +263,6 @@
     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.
      *
      * @returns The Command Type value.
@@ -276,14 +270,7 @@
      */
     Command GetCommand(void) const
     {
-        if (mSecuritySuite == kNoSecurity)
-        {
-            return static_cast<Command>(mSecurityControl);
-        }
-        else
-        {
-            return static_cast<Command>(mCommand);
-        }
+        return static_cast<Command>((mSecuritySuite == kNoSecurity) ? mSecurityControl : mCommand);
     }
 
     /**
@@ -314,95 +301,6 @@
 } 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 @@
         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);