[mle] implement hysteresis for establishing links and merging (#2409)

This commit applies a hysteresis to establishing new links or merging
partitions.  In particular, this commit introduces new minimum link
margin thresholds that must be met before attempting to establish a
new link or merging to a different partition.  Enforcing a mininmum
link margin threshold before establishing new links helps avoid links
that will quickly become invalid due to normal time-varying link
qualities.
This commit is contained in:
Jonathan Hui
2017-12-13 07:11:53 +00:00
committed by GitHub
parent c4d27e5642
commit 3364688218
4 changed files with 36 additions and 2 deletions
+5
View File
@@ -272,6 +272,11 @@ typedef enum otError
*/
OT_ERROR_DISABLED_FEATURE = 33,
/**
* The link margin was too low.
*/
OT_ERROR_LINK_MARGIN_LOW = 34,
/**
* Generic error (should not use).
*/
+4
View File
@@ -410,6 +410,10 @@ const char *otThreadErrorToString(otError aError)
retval = "GenericError";
break;
case OT_ERROR_LINK_MARGIN_LOW:
retval = "LinkMarginLow";
break;
default:
retval = "UnknownErrorType";
break;
+21 -1
View File
@@ -1079,7 +1079,27 @@
#define OPENTHREAD_CONFIG_MLE_SEND_LINK_REQUEST_ON_ADV_TIMEOUT 0
#endif
/*
/**
* @def OPENTHREAD_CONFIG_MLE_LINK_REQUEST_MARGIN_MIN
*
* Specifies the minimum link margin in dBm required before attempting to establish a link with a neighboring router.
*
*/
#ifndef OPENTHREAD_CONFIG_MLE_LINK_REQUEST_MARGIN_MIN
#define OPENTHREAD_CONFIG_MLE_LINK_REQUEST_MARGIN_MIN 10
#endif
/**
* @def OPENTHREAD_CONFIG_MLE_PARTITION_MERGE_MARGIN_MIN
*
* Specifies the minimum link margin in dBm required before attempting to merge to a different partition.
*
*/
#ifndef OPENTHREAD_CONFIG_MLE_PARTITION_MERGE_MARGIN_MIN
#define OPENTHREAD_CONFIG_MLE_PARTITION_MERGE_MARGIN_MIN 10
#endif
/**
* @def OPENTHREAD_CONFIG_ENABLE_DEBUG_UART
*
* Enable the "Debug Uart" platform feature.
+6 -1
View File
@@ -1305,6 +1305,7 @@ otError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::Messa
ThreadNetif &netif = GetNetif();
otError error = OT_ERROR_NONE;
const otThreadLinkInfo *linkInfo = static_cast<const otThreadLinkInfo *>(aMessageInfo.GetLinkInfo());
uint8_t linkMargin = LinkQualityInfo::ConvertRssToLinkMargin(GetNetif().GetMac().GetNoiseFloor(), linkInfo->mRss);
Mac::ExtAddress macAddr;
SourceAddressTlv sourceAddress;
LeaderDataTlv leaderData;
@@ -1343,6 +1344,8 @@ otError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::Messa
otLogInfoMle(GetInstance(), "Different partition (peer:%d, local:%d)",
leaderData.GetPartitionId(), mLeaderData.GetPartitionId());
VerifyOrExit(linkMargin >= OPENTHREAD_CONFIG_MLE_PARTITION_MERGE_MARGIN_MIN, error = OT_ERROR_LINK_MARGIN_LOW);
if ((mDeviceMode & ModeTlv::kModeFFD) &&
(mLastPartitionIdTimeout > 0) &&
(partitionId == mLastPartitionId))
@@ -1528,7 +1531,9 @@ otError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::Messa
}
// Send link request if no link to router
if ((router->GetState() != Neighbor::kStateValid) && (router->GetState() != Neighbor::kStateLinkRequest))
if ((router->GetState() != Neighbor::kStateValid) &&
(router->GetState() != Neighbor::kStateLinkRequest) &&
(linkMargin >= OPENTHREAD_CONFIG_MLE_LINK_REQUEST_MARGIN_MIN))
{
router->SetExtAddress(macAddr);
router->GetLinkInfo().Clear();