diff --git a/src/core/api/backbone_router_api.cpp b/src/core/api/backbone_router_api.cpp index e312a903f..9da2dae45 100644 --- a/src/core/api/backbone_router_api.cpp +++ b/src/core/api/backbone_router_api.cpp @@ -46,7 +46,7 @@ otError otBackboneRouterGetPrimary(otInstance *aInstance, otBackboneRouterConfig { AssertPointerIsNotNull(aConfig); - return AsCoreType(aInstance).Get().GetConfig(*aConfig); + return AsCoreType(aInstance).Get().GetConfig(AsCoreType(aConfig)); } #endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) diff --git a/src/core/api/backbone_router_ftd_api.cpp b/src/core/api/backbone_router_ftd_api.cpp index 3489561de..ed7363b54 100644 --- a/src/core/api/backbone_router_ftd_api.cpp +++ b/src/core/api/backbone_router_ftd_api.cpp @@ -57,14 +57,14 @@ void otBackboneRouterGetConfig(otInstance *aInstance, otBackboneRouterConfig *aC { AssertPointerIsNotNull(aConfig); - AsCoreType(aInstance).Get().GetConfig(*aConfig); + AsCoreType(aInstance).Get().GetConfig(AsCoreType(aConfig)); } otError otBackboneRouterSetConfig(otInstance *aInstance, const otBackboneRouterConfig *aConfig) { AssertPointerIsNotNull(aConfig); - return AsCoreType(aInstance).Get().SetConfig(*aConfig); + return AsCoreType(aInstance).Get().SetConfig(AsCoreType(aConfig)); } otError otBackboneRouterRegister(otInstance *aInstance) diff --git a/src/core/backbone_router/bbr_leader.cpp b/src/core/backbone_router/bbr_leader.cpp index b37eabc79..fa7f29bcd 100644 --- a/src/core/backbone_router/bbr_leader.cpp +++ b/src/core/backbone_router/bbr_leader.cpp @@ -42,6 +42,43 @@ namespace BackboneRouter { RegisterLogModule("BbrLeader"); +//--------------------------------------------------------------------------------------------------------------------- +// Config + +void Config::AdjustMlrTimeout(void) +{ + uint32_t origTimeout; + + VerifyOrExit(IsPresent()); + + origTimeout = GetMlrTimeout(); + mMlrTimeout = Clamp(mMlrTimeout, kMinMlrTimeout, kMaxMlrTimeout); + + VerifyOrExit(mMlrTimeout != origTimeout); + LogNote("MLR timeout adjusted: %lu -> %lu", ToUlong(origTimeout), ToUlong(mMlrTimeout)); + +exit: + return; +} + +#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO) +void Config::Log(const char *aTitle) const +{ + if (IsPresent()) + { + LogInfo(" %s: 0x%04x seqno:%u delay:%u timeout:%lu", aTitle, mServer16, mSequenceNumber, mReregistrationDelay, + ToUlong(mMlrTimeout)); + } + else + { + LogInfo(" %s: none", aTitle); + } +} +#endif + +//--------------------------------------------------------------------------------------------------------------------- +// Leader + Leader::Leader(Instance &aInstance) : InstanceLocator(aInstance) { @@ -50,8 +87,7 @@ Leader::Leader(Instance &aInstance) void Leader::Reset(void) { - // Invalid server short address indicates no available Backbone Router service in the Thread Network. - mConfig.mServer16 = Mle::kInvalidRloc16; + mConfig.MarkAsAbsent(); // Domain Prefix Length 0 indicates no available Domain Prefix in the Thread network. mDomainPrefix.SetLength(0); @@ -82,19 +118,6 @@ exit: #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO) -void Leader::LogBackboneRouterPrimary(State aState, const Config &aConfig) const -{ - OT_UNUSED_VARIABLE(aConfig); - - LogInfo("PBBR state: %s", StateToString(aState)); - - if (aState != kStateRemoved && aState != kStateNone) - { - LogInfo("Rloc16:0x%4x, seqno:%u, delay:%u, timeout:%lu", aConfig.mServer16, aConfig.mSequenceNumber, - aConfig.mReregistrationDelay, ToUlong(aConfig.mMlrTimeout)); - } -} - const char *Leader::StateToString(State aState) { #define StateMapList(_) \ @@ -135,18 +158,20 @@ void Leader::HandleNotifierEvents(Events aEvents) void Leader::UpdateBackboneRouterPrimary(void) { - Config config; + Config newConfig; State state; - Get().GetBackboneRouterPrimary(config); + Get().GetBackboneRouterPrimary(newConfig); - if (config.mServer16 != mConfig.mServer16) + newConfig.AdjustMlrTimeout(); + + if (newConfig.GetServer16() != mConfig.GetServer16()) { - if (config.mServer16 == Mle::kInvalidRloc16) + if (!newConfig.IsPresent()) { state = kStateRemoved; } - else if (mConfig.mServer16 == Mle::kInvalidRloc16) + else if (!mConfig.IsPresent()) { state = kStateAdded; } @@ -156,16 +181,17 @@ void Leader::UpdateBackboneRouterPrimary(void) state = kStateToTriggerRereg; } } - else if (config.mServer16 == Mle::kInvalidRloc16) + else if (!newConfig.IsPresent()) { // If no Primary all the time. state = kStateNone; } - else if (config.mSequenceNumber != mConfig.mSequenceNumber) + else if (newConfig.GetSequenceNumber() != mConfig.GetSequenceNumber()) { state = kStateToTriggerRereg; } - else if (config.mReregistrationDelay != mConfig.mReregistrationDelay || config.mMlrTimeout != mConfig.mMlrTimeout) + else if (newConfig.GetReregistrationDelay() != mConfig.GetReregistrationDelay() || + newConfig.GetMlrTimeout() != mConfig.GetMlrTimeout()) { state = kStateRefreshed; } @@ -174,22 +200,13 @@ void Leader::UpdateBackboneRouterPrimary(void) state = kStateUnchanged; } - // Restrain the range of MLR timeout to be always valid - if (config.mServer16 != Mle::kInvalidRloc16) - { - uint32_t origTimeout = config.mMlrTimeout; +#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO) + LogInfo("PBBR event: %s", StateToString(state)); + mConfig.Log("Old"); + newConfig.Log("New"); +#endif - config.mMlrTimeout = Clamp(config.mMlrTimeout, kMinMlrTimeout, kMaxMlrTimeout); - - if (config.mMlrTimeout != origTimeout) - { - LogNote("Leader MLR Timeout is normalized from %lu to %lu", ToUlong(origTimeout), - ToUlong(config.mMlrTimeout)); - } - } - - mConfig = config; - LogBackboneRouterPrimary(state, mConfig); + mConfig = newConfig; #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE Get().HandleBackboneRouterPrimaryUpdate(state, mConfig); @@ -202,6 +219,8 @@ void Leader::UpdateBackboneRouterPrimary(void) #if OPENTHREAD_CONFIG_DUA_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE) Get().HandleBackboneRouterPrimaryUpdate(state, mConfig); #endif + + OT_UNUSED_VARIABLE(state); } void Leader::UpdateDomainPrefixConfig(void) diff --git a/src/core/backbone_router/bbr_leader.hpp b/src/core/backbone_router/bbr_leader.hpp index 9465c72c6..24325c77c 100644 --- a/src/core/backbone_router/bbr_leader.hpp +++ b/src/core/backbone_router/bbr_leader.hpp @@ -48,14 +48,13 @@ #include "common/log.hpp" #include "common/non_copyable.hpp" #include "common/notifier.hpp" +#include "common/string.hpp" #include "net/ip6_address.hpp" namespace ot { namespace BackboneRouter { -typedef otBackboneRouterConfig Config; - constexpr uint16_t kDefaultRegistrationDelay = 5; ///< Default registration delay (in sec). constexpr uint32_t kDefaultMlrTimeout = 3600; ///< Default MLR Timeout (in sec). constexpr uint32_t kMinMlrTimeout = 300; ///< Minimum MLR Timeout (in sec). @@ -78,6 +77,69 @@ enum DomainPrefixEvent : uint8_t kDomainPrefixRefreshed = OT_BACKBONE_ROUTER_DOMAIN_PREFIX_CHANGED, ///< Domain Prefix Changed. }; +class Leader; + +/** + * Represents a Backbone Router configuration. + */ +class Config : public otBackboneRouterConfig +{ + friend class Leader; + +public: + /** + * Marks the configuration as absent. + * + * This is done by setting the Primary Backbone Router short address (`GetServer16()`) to `Mle::kInvalidRloc16`. + */ + void MarkAsAbsent(void) { mServer16 = Mle::kInvalidRloc16; } + + /** + * Indicates whether the configuration is present (i.e., it is derived from a Primary Backbone Router). + * + * The presence state is tracked using the Primary Backbone Router short address (`GetServer16()`). + * + * @retval TRUE The configuration is present. + * @retval FALSE The configuration is not present. + */ + bool IsPresent(void) const { return mServer16 != Mle::kInvalidRloc16; } + + /** + * Gets the Primary Backbone Router short address. + * + * @returns The Primary Backbone Router short address, or `Mle::kInvalidRloc16` if not present. + */ + uint16_t GetServer16(void) const { return mServer16; } + + /** + * Gets the Reregistration Delay value. + * + * @returns The Reregistration Delay value (in seconds). + */ + uint16_t GetReregistrationDelay(void) const { return mReregistrationDelay; } + + /** + * Gets the Multicast Listener Registration (MLR) Timeout value. + * + * @returns The MLR Timeout value (in seconds). + */ + uint32_t GetMlrTimeout(void) const { return mMlrTimeout; } + + /** + * Gets the Sequence Number. + * + * @returns The Sequence Number. + */ + uint8_t GetSequenceNumber(void) const { return mSequenceNumber; } + +private: + void AdjustMlrTimeout(void); + +#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO) + void Log(const char *aTitle) const; +#endif +}; + /** * Implements the basic Primary Backbone Router service operations. */ @@ -143,7 +205,7 @@ public: * @retval TRUE If there is Primary Backbone Router. * @retval FALSE If there is no Primary Backbone Router. */ - bool HasPrimary(void) const { return mConfig.mServer16 != Mle::kInvalidRloc16; } + bool HasPrimary(void) const { return mConfig.IsPresent(); } /** * Gets the Domain Prefix in the Thread Network. @@ -175,11 +237,8 @@ private: void UpdateBackboneRouterPrimary(void); void UpdateDomainPrefixConfig(void); #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO) - void LogBackboneRouterPrimary(State aState, const Config &aConfig) const; static const char *StateToString(State aState); static const char *DomainPrefixEventToString(DomainPrefixEvent aEvent); -#else - void LogBackboneRouterPrimary(State, const Config &) const {} #endif Config mConfig; @@ -189,6 +248,7 @@ private: } // namespace BackboneRouter DefineMapEnum(otBackboneRouterDomainPrefixEvent, BackboneRouter::DomainPrefixEvent); +DefineCoreType(otBackboneRouterConfig, BackboneRouter::Config); } // namespace ot diff --git a/src/core/thread/network_data_service.cpp b/src/core/thread/network_data_service.cpp index dce8f14b0..c64123867 100644 --- a/src/core/thread/network_data_service.cpp +++ b/src/core/thread/network_data_service.cpp @@ -382,7 +382,7 @@ void Manager::GetBackboneRouterPrimary(ot::BackboneRouter::Config &aConfig) cons serviceData.InitFrom(bbrServiceNumber); - aConfig.mServer16 = Mle::kInvalidRloc16; + aConfig.MarkAsAbsent(); while ((serviceTlv = Get().FindNextThreadService(serviceTlv, serviceData, NetworkData::kServicePrefixMatch)) != nullptr)