mirror of
https://github.com/espressif/openthread.git
synced 2026-08-06 18:57:47 +00:00
[mle] remove existing MLE Data Response in queues when there is newer Network Data (#2479)
This commit helps to reduce additional message exchanges when multiple network data updates in short time.
This commit is contained in:
@@ -366,6 +366,7 @@ bool Message::IsSubTypeMle(void) const
|
||||
mBuffer.mHead.mInfo.mSubType == kSubTypeMleDiscoverRequest ||
|
||||
mBuffer.mHead.mInfo.mSubType == kSubTypeMleDiscoverResponse ||
|
||||
mBuffer.mHead.mInfo.mSubType == kSubTypeMleChildUpdateRequest ||
|
||||
mBuffer.mHead.mInfo.mSubType == kSubTypeMleDataResponse ||
|
||||
mBuffer.mHead.mInfo.mSubType == kSubTypeMleGeneral)
|
||||
{
|
||||
rval = true;
|
||||
|
||||
@@ -218,6 +218,7 @@ public:
|
||||
kSubTypeMleGeneral = 6, ///< General MLE
|
||||
kSubTypeJoinerFinalizeResponse = 7, ///< Joiner Finalize Response
|
||||
kSubTypeMleChildUpdateRequest = 8, ///< MLE Child Update Request
|
||||
kSubTypeMleDataResponse = 9, ///< MLE Data Response
|
||||
};
|
||||
|
||||
enum
|
||||
|
||||
@@ -174,6 +174,12 @@ public:
|
||||
*/
|
||||
void RemoveMessages(Child &aChild, uint8_t aSubType);
|
||||
|
||||
/**
|
||||
* This method frees unicast/multicast MLE Data Responses from Send Message Queue if any.
|
||||
*
|
||||
*/
|
||||
void RemoveDataResponseMessages(void);
|
||||
|
||||
/**
|
||||
* This method evicts the first indirect message in the indirect send queue.
|
||||
*
|
||||
|
||||
@@ -314,6 +314,43 @@ void MeshForwarder::RemoveMessages(Child &aChild, uint8_t aSubType)
|
||||
}
|
||||
}
|
||||
|
||||
void MeshForwarder::RemoveDataResponseMessages(void)
|
||||
{
|
||||
Ip6::Header ip6Header;
|
||||
|
||||
for (Message *message = mSendQueue.GetHead(); message; message = message->GetNext())
|
||||
{
|
||||
if (message->GetSubType() != Message::kSubTypeMleDataResponse)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
message->Read(0, sizeof(ip6Header), &ip6Header);
|
||||
|
||||
if (!(ip6Header.GetDestination().IsMulticast()))
|
||||
{
|
||||
Child *children;
|
||||
uint8_t numChildren;
|
||||
|
||||
children = GetNetif().GetMle().GetChildren(&numChildren);
|
||||
|
||||
for (uint8_t i = 0; i < numChildren; i++)
|
||||
{
|
||||
IgnoreReturnValue(RemoveMessageFromSleepyChild(*message, children[i]));
|
||||
}
|
||||
}
|
||||
|
||||
if (mSendMessage == message)
|
||||
{
|
||||
mSendMessage = NULL;
|
||||
}
|
||||
|
||||
mSendQueue.Dequeue(*message);
|
||||
LogIp6Message(kMessageDrop, *message, NULL, OT_ERROR_NONE);
|
||||
message->Free();
|
||||
}
|
||||
}
|
||||
|
||||
otError MeshForwarder::GetIndirectTransmission(void)
|
||||
{
|
||||
otError error = OT_ERROR_NOT_FOUND;
|
||||
|
||||
@@ -1565,6 +1565,29 @@ void Mle::HandleDelayedResponseTimer(void)
|
||||
}
|
||||
}
|
||||
|
||||
void Mle::RemoveDelayedDataResponseMessage(void)
|
||||
{
|
||||
Message *message = mDelayedResponses.GetHead();
|
||||
DelayedResponseHeader delayedResponse;
|
||||
|
||||
while (message != NULL)
|
||||
{
|
||||
delayedResponse.ReadFrom(*message);
|
||||
|
||||
if (message->GetSubType() == Message::kSubTypeMleDataResponse)
|
||||
{
|
||||
mDelayedResponses.Dequeue(*message);
|
||||
message->Free();
|
||||
LogMleMessage("Remove Delayed Data Response", delayedResponse.GetDestination());
|
||||
|
||||
// no more than one multicast MLE Data Response in Delayed Message Queue.
|
||||
break;
|
||||
}
|
||||
|
||||
message = message->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
otError Mle::SendParentRequest(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
@@ -937,6 +937,12 @@ public:
|
||||
*/
|
||||
const MessageQueue &GetMessageQueue(void) const { return mDelayedResponses; }
|
||||
|
||||
/**
|
||||
* This method frees multicast MLE Data Response from Delayed Message Queue if any.
|
||||
*
|
||||
*/
|
||||
void RemoveDelayedDataResponseMessage(void);
|
||||
|
||||
protected:
|
||||
enum
|
||||
{
|
||||
|
||||
@@ -2198,6 +2198,7 @@ otError MleRouter::HandleChildIdRequest(const Message &aMessage, const Ip6::Mess
|
||||
// Remove existing MLE messages
|
||||
netif.GetMeshForwarder().RemoveMessages(*child, Message::kSubTypeMleGeneral);
|
||||
netif.GetMeshForwarder().RemoveMessages(*child, Message::kSubTypeMleChildUpdateRequest);
|
||||
netif.GetMeshForwarder().RemoveMessages(*child, Message::kSubTypeMleDataResponse);
|
||||
|
||||
// Link-Layer Frame Counter
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kLinkFrameCounter, sizeof(linkFrameCounter),
|
||||
@@ -3131,6 +3132,7 @@ otError MleRouter::SendDataResponse(const Ip6::Address &aDestination, const uint
|
||||
}
|
||||
|
||||
VerifyOrExit((message = NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS);
|
||||
message->SetSubType(Message::kSubTypeMleDataResponse);
|
||||
SuccessOrExit(error = AppendHeader(*message, Header::kCommandDataResponse));
|
||||
SuccessOrExit(error = AppendSourceAddress(*message));
|
||||
SuccessOrExit(error = AppendLeaderData(*message));
|
||||
@@ -3159,6 +3161,12 @@ otError MleRouter::SendDataResponse(const Ip6::Address &aDestination, const uint
|
||||
|
||||
if (aDelay)
|
||||
{
|
||||
// Remove MLE Data Responses from Send Message Queue.
|
||||
GetNetif().GetMeshForwarder().RemoveDataResponseMessages();
|
||||
|
||||
// Remove multicast MLE Data Response from Delayed Message Queue.
|
||||
RemoveDelayedDataResponseMessage();
|
||||
|
||||
SuccessOrExit(error = AddDelayedResponse(*message, aDestination, aDelay));
|
||||
LogMleMessage("Delay Data Response", aDestination);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user