diff --git a/src/core/common/message.hpp b/src/core/common/message.hpp index ab3e1f17e..5416a8ece 100644 --- a/src/core/common/message.hpp +++ b/src/core/common/message.hpp @@ -291,6 +291,7 @@ public: kSubTypeMleChildUpdateRequest = 8, ///< MLE Child Update Request kSubTypeMleDataResponse = 9, ///< MLE Data Response kSubTypeMleChildIdRequest = 10, ///< MLE Child ID Request + kSubTypeMleDataRequest = 11, ///< MLE Data Request }; enum Priority : uint8_t diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 24773514f..2aaa809f0 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -1964,7 +1964,7 @@ void Mle::HandleDelayedResponseTimer(void) mDelayedResponses.Dequeue(*message); metadata.RemoveFrom(*message); - if (metadata.mAppendTimestamps) + if (message->GetSubType() == Message::kSubTypeMleDataRequest) { error = AppendActiveTimestamp(*message); error = (error == kErrorNone) ? AppendPendingTimestamp(*message) : error; @@ -2021,6 +2021,25 @@ void Mle::RemoveDelayedDataResponseMessage(void) } } +void Mle::RemoveDelayedDataRequestMessage(const Ip6::Address &aDestination) +{ + for (Message *message = mDelayedResponses.GetHead(); message != nullptr; message = message->GetNext()) + { + DelayedResponseMetadata metadata; + + metadata.ReadFrom(*message); + + if (message->GetSubType() == Message::kSubTypeMleDataRequest && metadata.mDestination == aDestination) + { + mDelayedResponses.DequeueAndFree(*message); + Log(kMessageRemoveDelayed, kTypeDataRequest, metadata.mDestination); + + // no more than one MLE Data Request for the destination in Delayed Message Queue. + break; + } + } +} + Error Mle::SendParentRequest(ParentRequestType aType) { Error error = kErrorNone; @@ -2160,7 +2179,10 @@ Error Mle::SendDataRequest(const Ip6::Address &aDestination, Error error = kErrorNone; Message *message; + RemoveDelayedDataRequestMessage(aDestination); + VerifyOrExit((message = NewMleMessage()) != nullptr, error = kErrorNoBufs); + message->SetSubType(Message::kSubTypeMleDataRequest); SuccessOrExit(error = AppendHeader(*message, kCommandDataRequest)); SuccessOrExit(error = AppendTlvRequest(*message, aTlvs, aTlvsLength)); @@ -2171,7 +2193,7 @@ Error Mle::SendDataRequest(const Ip6::Address &aDestination, if (aDelay) { - SuccessOrExit(error = AddDelayedResponse(*message, aDestination, aDelay, /* aAppendTimestamps */ true)); + SuccessOrExit(error = AddDelayedResponse(*message, aDestination, aDelay)); Log(kMessageDelay, kTypeDataRequest, aDestination); } else @@ -2662,17 +2684,13 @@ exit: return error; } -Error Mle::AddDelayedResponse(Message & aMessage, - const Ip6::Address &aDestination, - uint16_t aDelay, - bool aAppendTimestamps) +Error Mle::AddDelayedResponse(Message &aMessage, const Ip6::Address &aDestination, uint16_t aDelay) { Error error = kErrorNone; DelayedResponseMetadata metadata; - metadata.mSendTime = TimerMilli::GetNow() + aDelay; - metadata.mDestination = aDestination; - metadata.mAppendTimestamps = aAppendTimestamps; + metadata.mSendTime = TimerMilli::GetNow() + aDelay; + metadata.mDestination = aDestination; SuccessOrExit(error = metadata.AppendTo(aMessage)); mDelayedResponses.Enqueue(aMessage); diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index 436d42a4e..71c27e2f3 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -1445,16 +1445,12 @@ protected: * @param[in] aMessage The message to transmit after given delay. * @param[in] aDestination The IPv6 address of the recipient of the message. * @param[in] aDelay The delay in milliseconds before transmission of the message. - * @param[in] aAppendTimestamps Whether or not to append Active and Pending Timestamps before sending. * * @retval kErrorNone Successfully queued the message to transmit after the delay. * @retval kErrorNoBufs Insufficient buffers to queue the message. * */ - Error AddDelayedResponse(Message & aMessage, - const Ip6::Address &aDestination, - uint16_t aDelay, - bool aAppendTimestamps = false); + Error AddDelayedResponse(Message &aMessage, const Ip6::Address &aDestination, uint16_t aDelay); #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_MLE == 1) /** @@ -1671,9 +1667,8 @@ private: 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. - bool mAppendTimestamps : 1; // Append Active Timestamp and Pending Timestamp before sending. + Ip6::Address mDestination; // IPv6 address of the message destination. + TimeMilli mSendTime; // Time when the message shall be sent. }; OT_TOOL_PACKED_BEGIN @@ -1818,6 +1813,7 @@ private: bool PrepareAnnounceState(void); void SendAnnounce(uint8_t aChannel, AnnounceMode aMode); void SendAnnounce(uint8_t aChannel, const Ip6::Address &aDestination, AnnounceMode aMode = kNormalAnnounce); + void RemoveDelayedDataRequestMessage(const Ip6::Address &aDestination); #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE Error SendLinkMetricsManagementResponse(const Ip6::Address &aDestination, LinkMetrics::Status aStatus); #endif