[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:
rongli
2018-01-19 16:48:55 +00:00
committed by Jonathan Hui
parent 9339230acd
commit bb9e6003f7
7 changed files with 82 additions and 0 deletions
+1
View File
@@ -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;
+1
View File
@@ -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
+6
View File
@@ -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.
*
+37
View File
@@ -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;
+23
View File
@@ -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;
+6
View File
@@ -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
{
+8
View File
@@ -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);
}