From 18c4dcfc9e5c6a0bb06c2e268692cdb170e501f9 Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Thu, 25 Aug 2016 18:07:34 -0700 Subject: [PATCH] Fix bugs when comparing partitions during parent selection. (#472) --- src/core/thread/mle.cpp | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 3e3dd21b0..739c71abd 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -1816,37 +1816,43 @@ ThreadError Mle::HandleParentResponse(const Message &aMessage, const Ip6::Messag SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kConnectivity, sizeof(connectivity), connectivity)); VerifyOrExit(connectivity.IsValid(), error = kThreadError_Parse); - // if already attached, Router/REED only seeks a better partition - if ((mDeviceMode & ModeTlv::kModeFFD) && - (mDeviceState != kDeviceStateDetached) && - (mParentRequestMode != kMleAttachAnyPartition)) + if ((mDeviceMode & ModeTlv::kModeFFD) && (mDeviceState != kDeviceStateDetached)) { - if (leaderData.GetPartitionId() == mLeaderData.GetPartitionId()) + switch (mParentRequestMode) { - // looking for a larger Sequence ID + case kMleAttachAnyPartition: + break; + + case kMleAttachSamePartition: + VerifyOrExit(leaderData.GetPartitionId() == mLeaderData.GetPartitionId(), ;); diff = static_cast(connectivity.GetIdSequence() - mMleRouter.GetRouterIdSequence()); VerifyOrExit(diff > 0 || (diff == 0 && mMleRouter.GetLeaderAge() < mMleRouter.GetNetworkIdTimeout()), ;); - } - else - { - // looking for a better partition + break; + + case kMleAttachBetterPartition: + VerifyOrExit(leaderData.GetPartitionId() != mLeaderData.GetPartitionId(), ;); VerifyOrExit(mMleRouter.ComparePartitions(connectivity.GetActiveRouters() <= 1, leaderData, mMleRouter.IsSingleton(), mLeaderData) > 0, ;); + break; } } // if already have a candidate parent, only seek a better parent if (mParent.mState == Neighbor::kStateValid) { + int compare = 0; + if (mDeviceMode & ModeTlv::kModeFFD) { - // do not accept worse partitions - VerifyOrExit(mMleRouter.ComparePartitions(connectivity.GetActiveRouters() <= 1, leaderData, - mParentIsSingleton, mParentLeaderData) >= 0, ;); + compare = mMleRouter.ComparePartitions(connectivity.GetActiveRouters() <= 1, leaderData, + mParentIsSingleton, mParentLeaderData); } - // looking for a better parent - VerifyOrExit(IsBetterParent(sourceAddress.GetRloc16(), linkQuality, connectivity), ;); + // only consider partitions that are the same or better + VerifyOrExit(compare >= 0, ;); + + // only consider better parents if the partitions are the same + VerifyOrExit(compare != 0 || IsBetterParent(sourceAddress.GetRloc16(), linkQuality, connectivity), ;); } // Link Frame Counter