[mle] fix some corner cases when trying to attach to a better partition (#2461)

This commit is contained in:
rongli
2018-01-11 17:01:58 +00:00
committed by Jonathan Hui
parent e668f0cc3e
commit e25f97d0fb
2 changed files with 24 additions and 5 deletions
+16 -4
View File
@@ -1647,11 +1647,23 @@ otError Mle::SendChildIdRequest(void)
Message *message = NULL;
Ip6::Address destination;
if (mRole == OT_DEVICE_ROLE_CHILD &&
mParent.GetExtAddress() == mParentCandidate.GetExtAddress())
if (mParent.GetExtAddress() == mParentCandidate.GetExtAddress())
{
otLogInfoMle(GetInstance(), "Already attached to candidate parent");
ExitNow(error = OT_ERROR_ALREADY);
if (mRole == OT_DEVICE_ROLE_CHILD)
{
otLogInfoMle(GetInstance(), "Already attached to candidate parent");
ExitNow(error = OT_ERROR_ALREADY);
}
else
{
// Invalidate stale parent state.
//
// Parent state is not normally invalidated after becoming a Router/Leader (see #1875). When trying to
// attach to a better partition, invalidating old parent state (especially when in kStateRestored) ensures
// that GetNeighbor() returns mParentCandidate when processing the Child ID Response.
mParent.SetState(Neighbor::kStateInvalid);
otPlatSettingsDelete(&GetInstance(), Settings::kKeyParentInfo, -1);
}
}
VerifyOrExit((message = NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS);
+8 -1
View File
@@ -551,7 +551,14 @@ otError MleRouter::SendAdvertisement(void)
{
otError error = OT_ERROR_NONE;
Ip6::Address destination;
Message *message;
Message *message = NULL;
// Suppress MLE Advertisements when trying to attach to a better partition.
//
// Without this suppression, a device may send an MLE Advertisement before receiving the MLE Child ID Response.
// The candidate parent then removes the attaching device because the Source Address TLV includes an RLOC16 that
// indicates a Router role (i.e. a Child ID equal to zero).
VerifyOrExit(mParentRequestState == kParentIdle);
VerifyOrExit((message = NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS);
SuccessOrExit(error = AppendHeader(*message, Header::kCommandAdvertisement));