mirror of
https://github.com/espressif/openthread.git
synced 2026-09-19 15:40:07 +00:00
[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:
+38
-10
@@ -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:
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user