@@ -771,7 +771,7 @@ class Mle : public InstanceLocator, private NonCopyable
771771 * @retval kErrorNone Successfully set the router-eligible configuration.
772772 * @retval kErrorNotCapable The device is not capable of becoming a router.
773773 */
774- Error SetRouterEligible (bool aEligible) { return mRoleTransitioner . SetRouterEligible (aEligible); }
774+ Error SetRouterEligible (bool aEligible);
775775
776776 /* *
777777 * Indicates whether the router role is currently allowed.
@@ -1022,7 +1022,7 @@ class Mle : public InstanceLocator, private NonCopyable
10221022 * @retval TRUE If the REED is going to become a Router soon.
10231023 * @retval FALSE If the REED is not going to become a Router soon.
10241024 */
1025- bool WillBecomeRouterSoon (void ) const { return mRoleTransitioner .WillBecomeRouterSoon (); }
1025+ bool MayBecomeRouterSoon (void ) const { return IsChild () && mRoleTransitioner .MayBecomeRouterSoon (); }
10261026
10271027 /* *
10281028 * Removes a link to a neighbor.
@@ -1179,14 +1179,14 @@ class Mle : public InstanceLocator, private NonCopyable
11791179 *
11801180 * @param[in] aEnabled TRUE if the device was commissioned using CCM, FALSE otherwise.
11811181 */
1182- void SetCcmEnabled (bool aEnabled) { mRoleTransitioner . SetCcmEnabled (aEnabled); }
1182+ void SetCcmEnabled (bool aEnabled);
11831183
11841184 /* *
11851185 * Sets whether the Security Policy TLV version-threshold for routing (VR field) is enabled.
11861186 *
11871187 * @param[in] aEnabled TRUE to enable Security Policy TLV version-threshold for routing, FALSE otherwise.
11881188 */
1189- void SetThreadVersionCheckEnabled (bool aEnabled) { mRoleTransitioner . SetThreadVersionCheckEnabled (aEnabled); }
1189+ void SetThreadVersionCheckEnabled (bool aEnabled);
11901190
11911191 /* *
11921192 * Gets the current Interval Max value used by Advertisement trickle timer.
@@ -1344,12 +1344,8 @@ class Mle : public InstanceLocator, private NonCopyable
13441344 static constexpr uint32_t kMaxLeaderToRouterTimeout = 90000 ; // (in msec)
13451345 static constexpr uint8_t kMinDowngradeNeighbors = 7 ;
13461346 static constexpr uint8_t kNetworkIdTimeout = 120 ; // (in sec)
1347- static constexpr uint8_t kRouterSelectionJitter = 120 ; // (in sec)
1348- static constexpr uint8_t kRouterDowngradeThreshold = 23 ;
1349- static constexpr uint8_t kRouterUpgradeThreshold = 16 ;
13501347 static constexpr uint16_t kDiscoveryMaxJitter = 250 ; // Max jitter delay Discovery Responses (in msec).
13511348 static constexpr uint16_t kUnsolicitedDataResponseJitter = 500 ; // Max delay for unsol Data Response (in msec).
1352- static constexpr uint8_t kLeaderDowngradeExtraDelay = 10 ; // Extra delay to downgrade leader (in sec).
13531349 static constexpr uint8_t kDefaultLeaderWeight = 64 ;
13541350 static constexpr uint8_t kAlternateRloc16Timeout = 8 ; // Time to use alternate RLOC16 (in sec).
13551351
@@ -2204,58 +2200,103 @@ class Mle : public InstanceLocator, private NonCopyable
22042200
22052201#if OPENTHREAD_FTD
22062202
2207- class RoleTransitioner : public InstanceLocator
2203+ class RoleTransitioner
22082204 {
2209- // Manages the router role upgrade/downgrade transitions
2210-
22112205 public:
2212- enum UpdateRouterRoleAllowedReason : uint8_t // Used in `UpdateRouterRoleAllowed()`
2206+ enum AddressSolicitState : uint8_t
22132207 {
2214- kReasonMleInit ,
2215- kReasonDeviceModeChanged ,
2216- kReasonConfigParameterChanged ,
2217- kReasonSecurityPolicyChanged ,
2208+ kAddressSolicitStateIdle ,
2209+ kAddressSolicitStatePending ,
2210+ kAddressSolicitStateRejected ,
22182211 };
22192212
2220- explicit RoleTransitioner (Instance &aInstance);
2213+ explicit RoleTransitioner (void );
2214+
2215+ bool IsAddressSolicitPending (void ) const { return mAddressSolicitState == kAddressSolicitStatePending ; }
2216+ bool IsAddressSolicitRejected (void ) const { return mAddressSolicitState == kAddressSolicitStateRejected ; }
2217+ bool IsRouterEligible (void ) const { return mRouterEligible ; }
2218+ bool IsRouterRoleAllowed (void ) const { return mRouterRoleAllowed ; }
2219+ bool IsTransitionPending (void ) const { return (mTimeout != 0 ); }
2220+ bool IsDowngradeBlocked (void ) const { return mDowngradeBlocked ; }
2221+
2222+ #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
2223+ bool IsCcmEnabled (void ) const { return mCcmEnabled ; }
2224+ bool IsThreadVersionCheckEnabled (void ) const { return mThreadVersionCheckEnabled ; }
2225+ #endif
2226+
2227+ bool MayBeginDowngradeTimer (uint8_t aRouterCount, uint16_t aValidChildren) const ;
2228+ bool MayCompleteTimedDowngrade (uint8_t aRouterCount) const ;
2229+ bool MayUpgrade (uint8_t aRouterCount) const ;
2230+ bool MayBecomeRouterSoon (void ) const ;
22212231
2222- bool IsRouterRoleAllowed (void ) const { return mRouterRoleAllowed ; }
2223- void UpdateRouterRoleAllowed (UpdateRouterRoleAllowedReason aReason);
2224- Error SetRouterEligible (bool aEligible);
2232+ uint8_t GetTimeout (void ) const { return mTimeout ; }
22252233 uint8_t GetJitter (void ) const { return mJitter ; }
2226- void SetJitter (uint8_t aJitter) { mJitter = aJitter; }
22272234 uint8_t GetUpgradeThreshold (void ) const { return mUpgradeThreshold ; }
2228- void SetUpgradeThreshold (uint8_t aThreshold) { mUpgradeThreshold = aThreshold; }
22292235 uint8_t GetDowngradeThreshold (void ) const { return mDowngradeThreshold ; }
2230- void SetDowngradeThreshold (uint8_t aThreshold) { mDowngradeThreshold = aThreshold; }
2231- bool IsDowngradeBlocked (void ) const { return mDowngradeBlocked ; }
2232- void SetDowngradeBlocked (bool aBlocked) { mDowngradeBlocked = aBlocked; }
2233- bool IsTransitionPending (void ) const { return (mTimeout != 0 ); }
2234- bool WillBecomeRouterSoon (void ) const ;
2235- void StartTimeout (void );
2236- void StopTimeout (void ) { mTimeout = 0 ; }
2237- void IncreaseTimeout (uint8_t aIncrement) { mTimeout += aIncrement; }
2238- uint8_t GetTimeout (void ) const { return mTimeout ; }
2239- bool IsRouterCountBelowUpgradeThreshold (void ) const ;
2240- void HandleTimeTick (void );
2241- void DecideWhetherToUpgrade (void );
2242- void DecideWhetherToDowngrade (uint8_t aNeighborId, const RouteTlv &aRouteTlv);
2236+
2237+ bool SetRouterEligibleAndGetChanged (bool aStatus);
2238+ bool SetRouterRoleAllowedAndGetChanged (bool aStatus);
2239+
2240+ void SetJitter (uint8_t aJitter) { mJitter = aJitter; }
2241+ void SetUpgradeThreshold (uint8_t aThreshold) { mUpgradeThreshold = aThreshold; }
2242+ void SetDowngradeThreshold (uint8_t aThreshold) { mDowngradeThreshold = aThreshold; }
2243+
2244+ bool HandleTimeTick (void );
2245+ void StartRouterUpgradeIfConditionsAllow (uint8_t aRouterCount);
2246+
2247+ // ------------------------
2248+ // Transition signals
2249+ void SignalAddressSolicitFinished (void );
2250+ void SignalAddressSolicitPending (void ) { mAddressSolicitState = kAddressSolicitStatePending ; }
2251+ void SignalAddressSolicitRejected (void ) { mAddressSolicitState = kAddressSolicitStateRejected ; }
2252+ void SignalBecomingRouter (void ) { StopTimer (); }
2253+ void SignalBeginTimedLeaderDowngrade (void );
2254+ void SignalBeginTimedRouterDowngrade (void );
2255+ void SignalChildUpgradeStart (void );
2256+ void SignalDowngradeAborted (void );
2257+ void SignalDowngradeBlocked (bool aShouldBlock);
2258+ void SignalRoleChanged (void );
2259+
2260+ // ------------------------
2261+ // State transition signals affecting the Router role allowed status
2262+ void SignalFtdModeChanged (bool aIsFtdMode, DeviceRole aRole);
2263+ void SignalRouterEligible (bool aEligible, DeviceRole aRole);
2264+ void SignalRouterRoleAllowedBySecurityPolicy (bool aAllowed, DeviceRole aRole);
2265+
22432266#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
2244- void SetCcmEnabled (bool aEnabled);
2245- void SetThreadVersionCheckEnabled (bool aEnabled);
2267+ void SetCcmEnabled (bool aCcmEnabled) { mCcmEnabled = aCcmEnabled; }
2268+ void SetThreadVersionCheckEnabled (bool aThreadVersionCheckEnabled)
2269+ {
2270+ mThreadVersionCheckEnabled = aThreadVersionCheckEnabled;
2271+ }
22462272#endif
22472273
22482274 private:
2249- bool DetermineIfRouterRoleAllowed (void ) const ;
2250- bool NeighborHasComparableConnectivity (uint8_t aNeighborId, const RouteTlv &aRouteTlv) const ;
2275+ void BeginTimer (void );
2276+ void StopTimer (void );
2277+ void SignalRouterRoleAllowedUpdate (DeviceRole aRole);
2278+
2279+ static constexpr uint8_t kMaxDelayToTransitionSoon = 10 ;
2280+
2281+ static constexpr uint8_t kRouterSelectionJitterDefault = 120 ; // /< (in sec)
2282+ static constexpr uint8_t kLeaderDowngradeExtraDelay = 10 ; // /< Extra delay to downgrade leader (in sec).
2283+
2284+ static constexpr uint8_t kRouterUpgradeThresholdDefault = 16 ;
2285+ static constexpr uint8_t kRouterDowngradeThresholdDefault = 23 ;
22512286
2252- bool mRouterEligible : 1 ;
2253- bool mRouterRoleAllowed : 1 ;
2254- bool mDowngradeBlocked : 1 ;
2287+ // Router Role Allowed statuses
2288+ bool mRouterRoleAllowed : 1 ; // /< Cached state of the router role allowed status
2289+ bool mRouterEligible : 1 ; // /< Router Eligible configuration affecting the role allowed status
2290+ bool mUsingFtdMode : 1 ; // /< FTD mode
2291+ bool mRouterRoleAllowedBySecurityPolicy : 1 ; // /< Cached state of the security policy router role allowed status
2292+ bool mDowngradeBlocked : 1 ; // /< Router role blocked from downgrading
22552293#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
2256- bool mCcmEnabled : 1 ;
2257- bool mThreadVersionCheckEnabled : 1 ;
2294+ bool mCcmEnabled : 1 ; // /< Whether to allow the security policy CCM commissioned check
2295+ bool mThreadVersionCheckEnabled : 1 ; // /< Whether to allow the security policy version check
22582296#endif
2297+
2298+ AddressSolicitState mAddressSolicitState ;
2299+
22592300 uint8_t mTimeout ;
22602301 uint8_t mJitter ;
22612302 uint8_t mUpgradeThreshold ;
@@ -2446,6 +2487,8 @@ class Mle : public InstanceLocator, private NonCopyable
24462487 void ClearAlternateRloc16 (void );
24472488 uint8_t SelectLeaderId (void ) const ;
24482489 uint32_t SelectPartitionId (void ) const ;
2490+ void HandleRouterRoleAllowedFromSecurityPolicy (void );
2491+ void HandleRoleAllowedChangedFromConfig (void );
24492492 void DetermineConnectivity (Connectivity &aConnectivity) const ;
24502493 void HandleDetachStart (void );
24512494 void HandleChildStart (void );
@@ -2493,6 +2536,8 @@ class Mle : public InstanceLocator, private NonCopyable
24932536 void SetChildStateToValid (Child &aChild);
24942537 bool HasChildren (void );
24952538 void RemoveChildren (void );
2539+ void CheckOrBeginRouterDowngrade (uint8_t aNeighborId, const RouteTlv &aRouteTlv);
2540+ bool NeighborHasComparableConnectivity (const RouteTlv &aRouteTlv, uint8_t aNeighborId) const ;
24962541 void HandleAdvertiseTrickleTimer (void );
24972542 void HandleTimeTick (void );
24982543 void HandleRouterTableEvent (RouterTable::Events aEvents);
@@ -2571,13 +2616,13 @@ class Mle : public InstanceLocator, private NonCopyable
25712616
25722617#if OPENTHREAD_FTD
25732618
2574- bool mAddressSolicitPending : 1 ;
2575- bool mAddressSolicitRejected : 1 ;
2619+ #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
2620+ bool mCcmEnabled : 1 ;
2621+ bool mThreadVersionCheckEnabled : 1 ;
2622+ #endif
25762623 uint8_t mRouterId ;
25772624 uint8_t mPreviousRouterId ;
25782625 uint8_t mNetworkIdTimeout ;
2579- uint8_t mRouterUpgradeThreshold ;
2580- uint8_t mRouterDowngradeThreshold ;
25812626 uint8_t mLeaderWeight ;
25822627 uint8_t mPreviousPartitionRouterIdSequence ;
25832628 uint8_t mPreviousPartitionIdTimeout ;
0 commit comments