mirror of
https://github.com/espressif/openthread.git
synced 2026-09-10 19:20:06 +00:00
[mlr] extract registration delay scheduling into a helper method (#13074)
This commit refactors the logic for scheduling Multicast Listener Registration (MLR) delays by replacing `UpdateReregistrationDelay(bool)` with a new, more expressive method: `ScheduleNextRegistration()`. The new method takes a `RegistrationRequest` enum (`kReregister` or `kRenew`), clearly distinguishing between the two different scheduling scenarios: - `kReregister`: Triggered after re-attaching or when a Primary BBR is added/updated. This schedules a rapid registration attempt using a random delay between 1 and the configured BBR reregistration delay. - `kRenew`: Triggered periodically. This schedules a standard registration renewal using a delay randomized between half the MLR timeout and the timeout minus a 9-second guard time (`kRenewGuardTime`), as mandated by Thread Spec. This change also introduces constants for `kLongRenewTimeout` and `kRenewGuardTime` to replace magic numbers, improving overall code readability and maintainability.
This commit is contained in:
@@ -64,8 +64,7 @@ void Manager::HandleNotifierEvents(Events aEvents)
|
||||
|
||||
if (aEvents.Contains(kEventThreadRoleChanged) && Get<Mle::Mle>().IsChild())
|
||||
{
|
||||
// Reregistration after re-attach
|
||||
UpdateReregistrationDelay(true);
|
||||
ScheduleNextRegistration(kReregister);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,10 +73,19 @@ void Manager::HandleBackboneRouterPrimaryUpdate(BackboneRouter::Leader::State aS
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aConfig);
|
||||
|
||||
bool needRereg =
|
||||
aState == BackboneRouter::Leader::kStateAdded || aState == BackboneRouter::Leader::kStateToTriggerRereg;
|
||||
RegistrationRequest request = kRenew;
|
||||
|
||||
UpdateReregistrationDelay(needRereg);
|
||||
switch (aState)
|
||||
{
|
||||
case BackboneRouter::Leader::kStateAdded:
|
||||
case BackboneRouter::Leader::kStateToTriggerRereg:
|
||||
request = kReregister;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ScheduleNextRegistration(request);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLR_ENABLE
|
||||
@@ -433,17 +441,13 @@ void Manager::HandleResponse(Coap::Msg *aMsg, Error aResult)
|
||||
else
|
||||
{
|
||||
BackboneRouter::Config config;
|
||||
uint16_t reregDelay;
|
||||
|
||||
// The Device has just attempted a Multicast Listener Registration which failed, and it retries the same
|
||||
// registration with a random time delay chosen in the interval [0, Reregistration Delay].
|
||||
// This is required by Thread 1.2 Specification 5.24.2.3
|
||||
// If a registration attempt fails, retry it after a random
|
||||
// delay (same as re-registration delay).
|
||||
|
||||
if (Get<BackboneRouter::Leader>().GetConfig(config) == kErrorNone)
|
||||
{
|
||||
reregDelay = config.mReregistrationDelay > 1
|
||||
? Random::NonCrypto::GetUint16InRange(1, config.mReregistrationDelay)
|
||||
: 1;
|
||||
ScheduleSend(reregDelay);
|
||||
ScheduleSend(DetermineReregistrationDelay(config));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -603,50 +607,69 @@ void Manager::Reregister(void)
|
||||
|
||||
ScheduleSend(0);
|
||||
|
||||
// Schedule for the next renewing.
|
||||
UpdateReregistrationDelay(false);
|
||||
ScheduleNextRegistration(kRenew);
|
||||
}
|
||||
|
||||
void Manager::UpdateReregistrationDelay(bool aRereg)
|
||||
uint16_t Manager::DetermineReregistrationDelay(const BackboneRouter::Config &aConfig)
|
||||
{
|
||||
bool needSend = ShouldRegister();
|
||||
uint16_t delay = 1;
|
||||
|
||||
if (!needSend)
|
||||
VerifyOrExit(aConfig.mReregistrationDelay > 1);
|
||||
delay = Random::NonCrypto::GetUint16InRange(1, aConfig.mReregistrationDelay);
|
||||
|
||||
exit:
|
||||
return delay;
|
||||
}
|
||||
|
||||
uint32_t Manager::DetermineRenewDelay(const BackboneRouter::Config &aConfig)
|
||||
{
|
||||
// As per Thread spec, the renew delay is randomly chosen
|
||||
// between (0.5 * MLR-Timeout) and (MLR-Timeout - 9 seconds).
|
||||
// The `kRenewGuardTime`(9 sec) allows time for transmission,
|
||||
// potential retransmissions, and acknowledgment before the
|
||||
// actual timeout.
|
||||
|
||||
uint32_t timeout = Clamp<uint32_t>(aConfig.mMlrTimeout, BackboneRouter::kMinMlrTimeout, kLongRenewTimeout);
|
||||
|
||||
return Random::NonCrypto::GetUint32InRange((timeout / 2) + 1, timeout - kRenewGuardTime);
|
||||
}
|
||||
|
||||
void Manager::ScheduleNextRegistration(RegistrationRequest aRequest)
|
||||
{
|
||||
uint32_t delay;
|
||||
BackboneRouter::Config config;
|
||||
|
||||
if (!ShouldRegister())
|
||||
{
|
||||
mReregistrationDelay = 0;
|
||||
ExitNow();
|
||||
}
|
||||
else
|
||||
|
||||
IgnoreError(Get<BackboneRouter::Leader>().GetConfig(config));
|
||||
|
||||
switch (aRequest)
|
||||
{
|
||||
BackboneRouter::Config config;
|
||||
uint32_t reregDelay;
|
||||
uint32_t effectiveTimeout;
|
||||
case kReregister:
|
||||
delay = DetermineReregistrationDelay(config);
|
||||
break;
|
||||
|
||||
IgnoreError(Get<BackboneRouter::Leader>().GetConfig(config));
|
||||
case kRenew:
|
||||
delay = DetermineRenewDelay(config);
|
||||
break;
|
||||
|
||||
if (aRereg)
|
||||
{
|
||||
reregDelay = config.mReregistrationDelay > 1
|
||||
? Random::NonCrypto::GetUint16InRange(1, config.mReregistrationDelay)
|
||||
: 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Calculate renewing period according to Thread Spec. 5.24.2.3.2
|
||||
// The random time t SHOULD be chosen such that (0.5* MLR-Timeout) < t < (MLR-Timeout – 9 seconds).
|
||||
effectiveTimeout = Max(config.mMlrTimeout, BackboneRouter::kMinMlrTimeout);
|
||||
reregDelay = Random::NonCrypto::GetUint32InRange((effectiveTimeout >> 1u) + 1, effectiveTimeout - 9);
|
||||
}
|
||||
|
||||
if (mReregistrationDelay == 0 || mReregistrationDelay > reregDelay)
|
||||
{
|
||||
mReregistrationDelay = reregDelay;
|
||||
}
|
||||
default:
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
UpdateTimeTickerRegistration();
|
||||
if (mReregistrationDelay == 0 || mReregistrationDelay > delay)
|
||||
{
|
||||
mReregistrationDelay = delay;
|
||||
|
||||
LogDebg("Manager::UpdateReregistrationDelay: rereg=%d, needSend=%d, ReregDelay=%lu", aRereg, needSend,
|
||||
ToUlong(mReregistrationDelay));
|
||||
LogDebg("ScheduleNextRegistration() delay:%lu", ToUlong(delay));
|
||||
}
|
||||
|
||||
exit:
|
||||
UpdateTimeTickerRegistration();
|
||||
}
|
||||
|
||||
void Manager::LogMulticastAddresses(void)
|
||||
|
||||
@@ -143,6 +143,15 @@ public:
|
||||
#endif
|
||||
|
||||
private:
|
||||
static constexpr uint32_t kLongRenewTimeout = 4 * Time::kOneHourInSec; // `MLR_TIMEOUT_LONG` (in sec)
|
||||
static constexpr uint32_t kRenewGuardTime = 9; // (in sec).
|
||||
|
||||
enum RegistrationRequest : uint8_t
|
||||
{
|
||||
kReregister,
|
||||
kRenew,
|
||||
};
|
||||
|
||||
class AddressArray : public Array<Ip6::Address, kMaxIp6Addresses>
|
||||
{
|
||||
public:
|
||||
@@ -159,6 +168,9 @@ private:
|
||||
|
||||
DeclareTmfResponseHandlerIn(Manager, HandleResponse);
|
||||
|
||||
static uint16_t DetermineReregistrationDelay(const BackboneRouter::Config &aConfig);
|
||||
static uint32_t DetermineRenewDelay(const BackboneRouter::Config &aConfig);
|
||||
|
||||
static Error ParseResponse(Error aResult, Coap::Msg *aMsg, uint8_t &aStatus, AddressArray &aFailedAddresses);
|
||||
static bool DidRegisterSuccessfully(const Ip6::Address &aAddress,
|
||||
bool aSuccess,
|
||||
@@ -184,10 +196,9 @@ private:
|
||||
|
||||
void SetMulticastAddressState(State aFromState, State aToState);
|
||||
void Finish(bool aSuccess, const AddressArray &aFailedAddresses);
|
||||
|
||||
void ScheduleSend(uint16_t aDelay);
|
||||
void UpdateTimeTickerRegistration(void);
|
||||
void UpdateReregistrationDelay(bool aRereg);
|
||||
void ScheduleNextRegistration(RegistrationRequest aRequest);
|
||||
void Reregister(void);
|
||||
void HandleTimeTick(void);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user