Clean up indirect messages when a child is removed. (#941)

This commit is contained in:
Jonathan Hui
2016-11-07 23:14:50 -08:00
committed by GitHub
parent d44f39769f
commit 266232e2a4
4 changed files with 68 additions and 2 deletions
+42
View File
@@ -181,6 +181,46 @@ void MeshForwarder::ScheduleTransmissionTask(void *aContext)
static_cast<MeshForwarder *>(aContext)->ScheduleTransmissionTask();
}
void MeshForwarder::UpdateIndirectMessages(void)
{
Child *children;
uint8_t numChildren;
VerifyOrExit(mSendBusy == false,);
children = mMle.GetChildren(&numChildren);
for (uint8_t i = 0; i < numChildren; i++)
{
Child *child = &children[i];
Message *nextMessage;
if (child->mState == Child::kStateValid || child->mQueuedIndirectMessageCnt == 0)
{
continue;
}
for (Message *message = mSendQueue.GetHead(); message; message = nextMessage)
{
nextMessage = message->GetNext();
message->ClearChildMask(i);
if (!message->IsChildPending())
{
mSendQueue.Dequeue(*message);
message->Free();
}
}
child->mQueuedIndirectMessageCnt = 0;
ClearSrcMatchEntry(*child);
}
exit:
return;
}
void MeshForwarder::ScheduleTransmissionTask()
{
ThreadError error = kThreadError_None;
@@ -189,6 +229,8 @@ void MeshForwarder::ScheduleTransmissionTask()
VerifyOrExit(mSendBusy == false, error = kThreadError_Busy);
UpdateIndirectMessages();
children = mMle.GetChildren(&numChildren);
for (int i = 0; i < numChildren; i++)
+6
View File
@@ -171,6 +171,12 @@ public:
*/
void SetDiscoverParameters(uint32_t aScanChannels, uint16_t aScanDuration);
/**
* This method frees any indirect messages queued for children that are no longer attached.
*
*/
void UpdateIndirectMessages(void);
/**
* This method returns a reference to the send queue.
*
+1
View File
@@ -62,6 +62,7 @@ enum
kParentResponseMaxDelayRouters = 500, ///< Maximum delay for response for Parent Request sent to routers only
kParentResponseMaxDelayAll = 1000, ///< Maximum delay for response for Parent Request sent to all devices
kMaxResponseDelay = 1000, ///< Maximum delay before responding to a multicast request
kMaxChildIdRequestTimeout = 5000, ///< Maximum delay for receiving a Child ID Request
};
enum
+19 -2
View File
@@ -1701,12 +1701,28 @@ void MleRouter::HandleStateUpdateTimer(void)
// update children state
for (int i = 0; i < mMaxChildrenAllowed; i++)
{
if (mChildren[i].mState == Neighbor::kStateInvalid)
uint32_t timeout = 0;
switch (mChildren[i].mState)
{
case Neighbor::kStateInvalid:
case Neighbor::kStateChildIdRequest:
continue;
case Neighbor::kStateParentRequest:
timeout = kMaxChildIdRequestTimeout;
break;
case Neighbor::kStateValid:
timeout = Timer::SecToMsec(mChildren[i].mTimeout);
break;
case Neighbor::kStateLinkRequest:
assert(false);
break;
}
if ((Timer::GetNow() - mChildren[i].mLastHeard) >= Timer::SecToMsec(mChildren[i].mTimeout))
if ((Timer::GetNow() - mChildren[i].mLastHeard) >= timeout)
{
RemoveNeighbor(mChildren[i]);
}
@@ -2565,6 +2581,7 @@ ThreadError MleRouter::RemoveNeighbor(Neighbor &aNeighbor)
case kDeviceStateLeader:
if (aNeighbor.mState == Neighbor::kStateValid && !IsActiveRouter(aNeighbor.mValid.mRloc16))
{
mMesh.UpdateIndirectMessages();
mNetif.SetStateChangedFlags(OT_THREAD_CHILD_REMOVED);
mNetworkData.SendServerDataNotification(aNeighbor.mValid.mRloc16);
}