mirror of
https://github.com/espressif/openthread.git
synced 2026-07-30 15:47:46 +00:00
[mle] fix some corner cases when trying to attach to a better partition (#2461)
This commit is contained in:
+16
-4
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user