[mle] remove sleepy child in all roles (#4234)

This commit fixes an issue that indirect messages for sleepy child are
not correctly cleared in some cases.

This issue can cause sleepy nodes unable to reattach for a long time,
or even forever.
This commit is contained in:
Simon Lin
2019-11-01 08:50:22 -07:00
committed by Jonathan Hui
parent 9c54a4ed0e
commit f942d13334
+22 -36
View File
@@ -3132,49 +3132,35 @@ bool MleRouter::IsMinimalChild(uint16_t aRloc16)
void MleRouter::RemoveNeighbor(Neighbor &aNeighbor)
{
switch (mRole)
if (&aNeighbor == &mParent)
{
case OT_DEVICE_ROLE_DISABLED:
case OT_DEVICE_ROLE_DETACHED:
break;
case OT_DEVICE_ROLE_CHILD:
if (&aNeighbor == &mParent)
if (mRole == OT_DEVICE_ROLE_CHILD)
{
BecomeDetached();
}
break;
case OT_DEVICE_ROLE_ROUTER:
case OT_DEVICE_ROLE_LEADER:
if (!IsActiveRouter(aNeighbor.GetRloc16()))
}
else if (!IsActiveRouter(aNeighbor.GetRloc16()))
{
if (aNeighbor.IsStateValidOrRestoring())
{
if (aNeighbor.IsStateValidOrRestoring())
{
Signal(OT_NEIGHBOR_TABLE_EVENT_CHILD_REMOVED, aNeighbor);
}
aNeighbor.SetState(Neighbor::kStateInvalid);
Get<IndirectSender>().ClearAllMessagesForSleepyChild(static_cast<Child &>(aNeighbor));
Get<NetworkData::Leader>().SendServerDataNotification(aNeighbor.GetRloc16());
if (aNeighbor.IsFullThreadDevice())
{
// Clear all EID-to-RLOC entries associated with the child.
Get<AddressResolver>().Remove(aNeighbor.GetRloc16());
}
RemoveStoredChild(aNeighbor.GetRloc16());
}
else if (aNeighbor.IsStateValid())
{
Signal(OT_NEIGHBOR_TABLE_EVENT_ROUTER_REMOVED, aNeighbor);
mRouterTable.RemoveNeighbor(static_cast<Router &>(aNeighbor));
Signal(OT_NEIGHBOR_TABLE_EVENT_CHILD_REMOVED, aNeighbor);
}
break;
Get<IndirectSender>().ClearAllMessagesForSleepyChild(static_cast<Child &>(aNeighbor));
Get<NetworkData::Leader>().SendServerDataNotification(aNeighbor.GetRloc16());
if (aNeighbor.IsFullThreadDevice())
{
// Clear all EID-to-RLOC entries associated with the child.
Get<AddressResolver>().Remove(aNeighbor.GetRloc16());
}
RemoveStoredChild(aNeighbor.GetRloc16());
}
else if (aNeighbor.IsStateValid())
{
Signal(OT_NEIGHBOR_TABLE_EVENT_ROUTER_REMOVED, aNeighbor);
mRouterTable.RemoveNeighbor(static_cast<Router &>(aNeighbor));
}
aNeighbor.GetLinkInfo().Clear();