[mle] update parent selection rulesi (#4423)

This commit updates parent selection rules according to Thread 1.2
Specification section 4.5.2.1, which supplements serveral Child Impacting
rules to existing rules defined in Thread 1.1 Specification.

These additional rules are not wrapped by `OT_THREAD_VERSION_1_2'
macro as Thread 1.1 has no restrictions regarding introducing extra rules.
This commit is contained in:
Rongli Sun
2020-02-25 14:34:53 -08:00
committed by Jonathan Hui
parent c32a0ee561
commit 835d9e2505
2 changed files with 45 additions and 11 deletions
+38 -10
View File
@@ -78,6 +78,8 @@ Mle::Mle(Instance &aInstance)
, mParentLinkQuality3(0)
, mParentLinkQuality2(0)
, mParentLinkQuality1(0)
, mParentSedBufferSize(0)
, mParentSedDatagramCount(0)
, mChildUpdateAttempts(0)
, mChildUpdateRequestState(kChildUpdateRequestNone)
, mDataRequestAttempts(0)
@@ -3123,7 +3125,11 @@ exit:
return error;
}
bool Mle::IsBetterParent(uint16_t aRloc16, uint8_t aLinkQuality, uint8_t aLinkMargin, ConnectivityTlv &aConnectivityTlv)
bool Mle::IsBetterParent(uint16_t aRloc16,
uint8_t aLinkQuality,
uint8_t aLinkMargin,
const ConnectivityTlv &aConnectivityTlv,
VersionTlv & aVersionTlv)
{
bool rval = false;
@@ -3132,6 +3138,7 @@ bool Mle::IsBetterParent(uint16_t aRloc16, uint8_t aLinkQuality, uint8_t aLinkMa
? candidateLinkQualityIn
: mParentCandidate.GetLinkQualityOut();
// Mesh Impacting Criteria
if (aLinkQuality != candidateTwoWayLinkQuality)
{
ExitNow(rval = (aLinkQuality > candidateTwoWayLinkQuality));
@@ -3147,11 +3154,29 @@ bool Mle::IsBetterParent(uint16_t aRloc16, uint8_t aLinkQuality, uint8_t aLinkMa
ExitNow(rval = (aConnectivityTlv.GetParentPriority() > mParentPriority));
}
// Prefer the parent with highest quality links (Link Quality 3 field in Connectivity TLV) to neighbors
if (aConnectivityTlv.GetLinkQuality3() != mParentLinkQuality3)
{
ExitNow(rval = (aConnectivityTlv.GetLinkQuality3() > mParentLinkQuality3));
}
// Thread 1.2 Specification 4.5.2.1.2 Child Impacting Criteria
if (aVersionTlv.GetVersion() != mParentCandidate.GetVersion())
{
ExitNow(rval = (aVersionTlv.GetVersion() > mParentCandidate.GetVersion()));
}
if (aConnectivityTlv.GetSedBufferSize() != mParentSedBufferSize)
{
ExitNow(rval = (aConnectivityTlv.GetSedBufferSize() > mParentSedBufferSize));
}
if (aConnectivityTlv.GetSedDatagramCount() != mParentSedDatagramCount)
{
ExitNow(rval = (aConnectivityTlv.GetSedDatagramCount() > mParentSedDatagramCount));
}
// Extra rules
if (aConnectivityTlv.GetLinkQuality2() != mParentLinkQuality2)
{
ExitNow(rval = (aConnectivityTlv.GetLinkQuality2() > mParentLinkQuality2));
@@ -3300,7 +3325,8 @@ otError Mle::HandleParentResponse(const Message &aMessage, const Ip6::MessageInf
VerifyOrExit(compare >= 0);
// only consider better parents if the partitions are the same
VerifyOrExit(compare != 0 || IsBetterParent(sourceAddress.GetRloc16(), linkQuality, linkMargin, connectivity));
VerifyOrExit(compare != 0 ||
IsBetterParent(sourceAddress.GetRloc16(), linkQuality, linkMargin, connectivity, version));
}
// Link Frame Counter
@@ -3358,14 +3384,16 @@ otError Mle::HandleParentResponse(const Message &aMessage, const Ip6::MessageInf
mParentCandidate.SetState(Neighbor::kStateParentResponse);
mParentCandidate.SetKeySequence(aKeySequence);
mParentPriority = connectivity.GetParentPriority();
mParentLinkQuality3 = connectivity.GetLinkQuality3();
mParentLinkQuality2 = connectivity.GetLinkQuality2();
mParentLinkQuality1 = connectivity.GetLinkQuality1();
mParentLeaderCost = connectivity.GetLeaderCost();
mParentLeaderData = leaderData;
mParentIsSingleton = connectivity.GetActiveRouters() <= 1;
mParentLinkMargin = linkMargin;
mParentPriority = connectivity.GetParentPriority();
mParentLinkQuality3 = connectivity.GetLinkQuality3();
mParentLinkQuality2 = connectivity.GetLinkQuality2();
mParentLinkQuality1 = connectivity.GetLinkQuality1();
mParentLeaderCost = connectivity.GetLeaderCost();
mParentSedBufferSize = connectivity.GetSedBufferSize();
mParentSedDatagramCount = connectivity.GetSedDatagramCount();
mParentLeaderData = leaderData;
mParentIsSingleton = connectivity.GetActiveRouters() <= 1;
mParentLinkMargin = linkMargin;
exit:
+7 -1
View File
@@ -1720,7 +1720,11 @@ private:
otError SendAnnounce(uint8_t aChannel, bool aOrphanAnnounce, const Ip6::Address &aDestination);
uint32_t Reattach(void);
bool IsBetterParent(uint16_t aRloc16, uint8_t aLinkQuality, uint8_t aLinkMargin, ConnectivityTlv &aConnectivityTlv);
bool IsBetterParent(uint16_t aRloc16,
uint8_t aLinkQuality,
uint8_t aLinkMargin,
const ConnectivityTlv &aConnectivityTlv,
VersionTlv & aVersionTlv);
bool IsNetworkDataNewer(const LeaderDataTlv &aLeaderData);
otError GetAlocAddress(Ip6::Address &aAddress, uint16_t aAloc16) const;
@@ -1761,6 +1765,8 @@ private:
uint8_t mParentLinkQuality3;
uint8_t mParentLinkQuality2;
uint8_t mParentLinkQuality1;
uint16_t mParentSedBufferSize;
uint8_t mParentSedDatagramCount;
uint8_t mChildUpdateAttempts;
ChildUpdateRequestState mChildUpdateRequestState;