mirror of
https://github.com/espressif/openthread.git
synced 2026-08-06 10:47:46 +00:00
[mle] track remaining Link Request attempts when re-establishing links (#11160)
This commit updates `Router` to track the number of remaining Link Request attempts during link re-establishment (when no Advertisement is received from a router, and the router is aged out). This helps simplify the code managing link re-establishment.
This commit is contained in:
@@ -4614,6 +4614,15 @@ void Mle::DelayedSender::RemoveScheduledLinkRequest(const Router &aRouter)
|
||||
RemoveMatchingSchedules(kTypeLinkRequest, destination);
|
||||
}
|
||||
|
||||
bool Mle::DelayedSender::HasAnyScheduledLinkRequest(const Router &aRouter) const
|
||||
{
|
||||
Ip6::Address destination;
|
||||
|
||||
destination.SetToLinkLocalAddress(aRouter.GetExtAddress());
|
||||
|
||||
return HasMatchingSchedule(kTypeLinkRequest, destination);
|
||||
}
|
||||
|
||||
void Mle::DelayedSender::ScheduleLinkAccept(const LinkAcceptInfo &aInfo, uint16_t aDelay)
|
||||
{
|
||||
Ip6::Address destination;
|
||||
|
||||
@@ -1142,11 +1142,12 @@ private:
|
||||
void ScheduleAdvertisement(const Ip6::Address &aDestination, uint16_t aDelay);
|
||||
void ScheduleMulticastDataResponse(uint16_t aDelay);
|
||||
void ScheduleLinkRequest(const Router &aRouter, uint16_t aDelay);
|
||||
void RemoveScheduledLinkRequest(const Router &aRouter);
|
||||
bool HasAnyScheduledLinkRequest(const Router &aRouter) const;
|
||||
void ScheduleLinkAccept(const LinkAcceptInfo &aInfo, uint16_t aDelay);
|
||||
void ScheduleDiscoveryResponse(const Ip6::Address &aDestination,
|
||||
const DiscoveryResponseInfo &aInfo,
|
||||
uint16_t aDelay);
|
||||
void RemoveScheduledLinkRequest(const Router &aRouter);
|
||||
#endif
|
||||
void RemoveScheduledChildUpdateRequestToParent(void);
|
||||
|
||||
|
||||
@@ -1720,32 +1720,6 @@ void MleRouter::HandleTimeTick(void)
|
||||
|
||||
age = TimerMilli::GetNow() - router.GetLastHeard();
|
||||
|
||||
if (router.IsStateValid() && (age >= kMaxNeighborAge))
|
||||
{
|
||||
bool sendLinkRequest = true;
|
||||
|
||||
// Once router age expires, we send Link Request every
|
||||
// time tick (second), up to `kMaxTxCount`. Each rx is
|
||||
// randomly delayed (one second window). After the last
|
||||
// attempt, we wait for the "Link Accept" timeout
|
||||
// (~3 seconds), before the router is removed.
|
||||
|
||||
if (!router.IsWaitingForLinkAccept())
|
||||
{
|
||||
LogInfo("No Adv from router 0x%04x - sending Link Request", router.GetRloc16());
|
||||
}
|
||||
else
|
||||
{
|
||||
sendLinkRequest = (age < kMaxNeighborAge + kMaxTxCount * TimeMilli::kOneSecondInMsec);
|
||||
}
|
||||
|
||||
if (sendLinkRequest)
|
||||
{
|
||||
mDelayedSender.ScheduleLinkRequest(
|
||||
router, Random::NonCrypto::GetUint32InRange(0, kMaxLinkRequestDelayOnRouter));
|
||||
}
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE
|
||||
router.DecrementParentReselectTimeout();
|
||||
|
||||
@@ -1755,6 +1729,28 @@ void MleRouter::HandleTimeTick(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (router.IsStateValid() && (age >= kMaxNeighborAge))
|
||||
{
|
||||
// Once router age expires, we send Link Request every
|
||||
// time tick (second), up to max attempts. Each rx is
|
||||
// randomly delayed (one second window). After the last
|
||||
// attempt, we wait for the "Link Accept" timeout
|
||||
// (~3 seconds), before the router is removed.
|
||||
|
||||
if (!mDelayedSender.HasAnyScheduledLinkRequest(router) && !router.IsWaitingForLinkAccept())
|
||||
{
|
||||
LogInfo("No Adv from router 0x%04x - sending Link Request", router.GetRloc16());
|
||||
router.SetLinkRequestAttemptsToMax();
|
||||
}
|
||||
|
||||
if (router.HasRemainingLinkRequestAttempts())
|
||||
{
|
||||
router.DecrementLinkRequestAttempts();
|
||||
mDelayedSender.ScheduleLinkRequest(
|
||||
router, Random::NonCrypto::GetUint32InRange(0, kMaxLinkRequestDelayOnRouter));
|
||||
}
|
||||
}
|
||||
|
||||
if (router.IsWaitingForLinkAccept() && (router.DecrementLinkAcceptTimeout() == 0))
|
||||
{
|
||||
LogInfo("Router 0x%04x - Link Accept timeout expired", router.GetRloc16());
|
||||
|
||||
@@ -91,7 +91,9 @@ constexpr uint8_t kMaxRouteCost = 16; ///< Maximum path cost
|
||||
#endif
|
||||
|
||||
constexpr uint8_t kMeshLocalPrefixContextId = 0; ///< Reserved 6lowpan context ID for Mesh Local Prefix
|
||||
constexpr uint8_t kLinkAcceptTimeout = 3; ///< Timeout in seconds to rx Link Accept after Link Request tx.
|
||||
|
||||
constexpr uint8_t kLinkRequestAttempts = 3; ///< Number of Link Request attempts when re-establishing link.
|
||||
constexpr uint8_t kLinkAcceptTimeout = 3; ///< Timeout in seconds to rx Link Accept after Link Request tx.
|
||||
|
||||
/**
|
||||
* Specifies parent reselect timeout duration in seconds used on FTD child devices.
|
||||
|
||||
@@ -118,6 +118,27 @@ public:
|
||||
*/
|
||||
uint8_t DecrementLinkAcceptTimeout(void) { return --mLinkAcceptTimeout; }
|
||||
|
||||
/**
|
||||
* Sets the counter tracking the number of Link Request attempts during link re-establishment to its maximum value
|
||||
* `Mle::kLinkRequestAttempts`.
|
||||
*/
|
||||
void SetLinkRequestAttemptsToMax(void) { mLinkRequestAttempts = Mle::kLinkRequestAttempts; }
|
||||
|
||||
/**
|
||||
* Indicates whether there are remaining Link Request attempts (during link re-establishment).
|
||||
*
|
||||
* @retval TRUE There are remaining Link Request attempts.
|
||||
* @retval FALSE There are no more Link Request attempts (the counter is zero).
|
||||
*/
|
||||
bool HasRemainingLinkRequestAttempts(void) const { return mLinkRequestAttempts > 0; }
|
||||
|
||||
/**
|
||||
* Decrements the counter tracking the number of remaining Link Request attempts during link re-establishment.
|
||||
*
|
||||
* Caller MUST ensure the current counter is non-zero by checking `HasRemainingLinkRequestAttempts()`.
|
||||
*/
|
||||
void DecrementLinkRequestAttempts(void) { mLinkRequestAttempts--; }
|
||||
|
||||
/**
|
||||
* Gets the router ID of the next hop to this router.
|
||||
*
|
||||
@@ -208,14 +229,16 @@ public:
|
||||
|
||||
private:
|
||||
static_assert(Mle::kLinkAcceptTimeout < 4, "kLinkAcceptTimeout won't fit in mLinkAcceptTimeout (2-bit field)");
|
||||
static_assert(Mle::kLinkRequestAttempts < 4, "kLinkRequestAttempts won't fit in mLinkRequestAttempts (2-bit field");
|
||||
|
||||
#if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE
|
||||
static_assert(Mle::kParentReselectTimeout <= (1U << 15) - 1,
|
||||
"kParentReselectTimeout won't fit in mParentReselectTimeout (15-bit filed)");
|
||||
#endif
|
||||
|
||||
uint8_t mNextHop; // The next hop towards this router
|
||||
uint8_t mLinkAcceptTimeout : 2; // Timeout (in seconds) after sending Link Request waiting for Link Accept
|
||||
uint8_t mNextHop; // The next hop towards this router
|
||||
uint8_t mLinkRequestAttempts : 2; // Number of Link Request attempts
|
||||
uint8_t mLinkAcceptTimeout : 2; // Timeout (in seconds) after sending Link Request waiting for Link Accept
|
||||
#if !OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
|
||||
uint8_t mCost : 4; // The cost to this router via neighbor router
|
||||
#else
|
||||
|
||||
Reference in New Issue
Block a user