@@ -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,98 @@ 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()`
2213- {
2214- kReasonMleInit ,
2215- kReasonDeviceModeChanged ,
2216- kReasonConfigParameterChanged ,
2217- kReasonSecurityPolicyChanged ,
2218- };
2206+ explicit RoleTransitioner (void );
22192207
2220- explicit RoleTransitioner (Instance &aInstance);
2208+ bool IsAddressSolicitPending (void ) const { return mAddressSolicitState == kAddressSolicitStatePending ; }
2209+ bool IsRouterRoleAllowed (void ) const { return mRouterRoleAllowed ; }
2210+ bool IsTransitionPending (void ) const { return (mTimeout != 0 ); }
2211+ bool IsDowngradeBlocked (void ) const { return mDowngradeBlocked ; }
2212+
2213+ #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
2214+ bool IsCcmEnabled (void ) const { return mCcmEnabled ; }
2215+ bool IsThreadVersionCheckEnabled (void ) const { return mThreadVersionCheckEnabled ; }
2216+ #endif
22212217
2222- bool IsRouterRoleAllowed (void ) const { return mRouterRoleAllowed ; }
2223- void UpdateRouterRoleAllowed (UpdateRouterRoleAllowedReason aReason);
2224- Error SetRouterEligible (bool aEligible);
2218+ bool MayBecomeRouterSoon (void ) const ;
2219+ bool MayBeginDowngradeTimer (uint8_t aRouterCount, uint16_t aValidChildren) const ;
2220+ bool MayCompleteTimedDowngrade (uint8_t aRouterCount) const ;
2221+ bool MayUpgrade (uint8_t aRouterCount) const ;
2222+
2223+ uint8_t GetTimeout (void ) const { return mTimeout ; }
22252224 uint8_t GetJitter (void ) const { return mJitter ; }
2226- void SetJitter (uint8_t aJitter) { mJitter = aJitter; }
22272225 uint8_t GetUpgradeThreshold (void ) const { return mUpgradeThreshold ; }
2228- void SetUpgradeThreshold (uint8_t aThreshold) { mUpgradeThreshold = aThreshold; }
22292226 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);
2227+
2228+ bool HandleTimeTick (void );
2229+
2230+ void SetJitter (uint8_t aJitter) { mJitter = aJitter; }
2231+ void SetUpgradeThreshold (uint8_t aThreshold) { mUpgradeThreshold = aThreshold; }
2232+ void SetDowngradeThreshold (uint8_t aThreshold) { mDowngradeThreshold = aThreshold; }
2233+
2234+ // ------------------------
2235+ // State transition signals
2236+ void SignalAddressSolicitFinished (void );
2237+ void SignalAddressSolicitPending (void ) { mAddressSolicitState = kAddressSolicitStatePending ; }
2238+ void SignalAddressSolicitRejected (void ) { mAddressSolicitState = kAddressSolicitStateRejected ; }
2239+ void SignalBecomingRouter (void ) { StopTimer (); }
2240+ void SignalBeginTimedLeaderDowngrade (void );
2241+ void SignalBeginTimedRouterDowngrade (void );
2242+ void SignalChildUpgradeStart (void );
2243+ void SignalDowngradeAborted (void );
2244+ void SignalDowngradeBlocked (bool aShouldBlock);
2245+ void SignalParentAdvertisementReceived (uint8_t aRouterCount);
2246+ void SignalRoleChanged (void );
2247+
2248+ // -----------------------------------------------------------------
2249+ // State transition signals affecting the Router role allowed status
2250+ void SignalFtdModeChanged (bool aIsFtdMode, DeviceRole aRole);
2251+ void SignalRouterEligible (bool aEligible, DeviceRole aRole);
2252+ void SignalRouterRoleAllowedBySecurityPolicy (bool aAllowed, DeviceRole aRole);
2253+
22432254#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
2244- void SetCcmEnabled (bool aEnabled);
2245- void SetThreadVersionCheckEnabled (bool aEnabled);
2255+ // Setters for additional states affecting the SecurityPolicy router-role-allowed status
2256+ void SetCcmEnabled (bool aCcmEnabled) { mCcmEnabled = aCcmEnabled; }
2257+ void SetThreadVersionCheckEnabled (bool aThreadVersionCheckEnabled)
2258+ {
2259+ mThreadVersionCheckEnabled = aThreadVersionCheckEnabled;
2260+ }
22462261#endif
22472262
22482263 private:
2249- bool DetermineIfRouterRoleAllowed (void ) const ;
2250- bool NeighborHasComparableConnectivity (uint8_t aNeighborId, const RouteTlv &aRouteTlv) const ;
2264+ enum AddressSolicitState : uint8_t
2265+ {
2266+ kAddressSolicitStateIdle ,
2267+ kAddressSolicitStatePending ,
2268+ kAddressSolicitStateRejected ,
2269+ };
2270+
2271+ void BeginTimer (void );
2272+ void StopTimer (void );
2273+ void SignalRouterRoleAllowedUpdate (DeviceRole aRole);
2274+
2275+ static constexpr uint8_t kLeaderDowngradeExtraDelay = 10 ; // /< Extra delay to downgrade leader (in sec).
2276+ static constexpr uint8_t kMaxDelayToTransitionSoon = 10 ; // /< Time window considered "soon" (in sec).
2277+ static constexpr uint8_t kRouterSelectionJitterDefault = 120 ; // /< Timeout jitter (in sec).
22512278
2252- bool mRouterEligible : 1 ;
2253- bool mRouterRoleAllowed : 1 ;
2254- bool mDowngradeBlocked : 1 ;
2279+ static constexpr uint8_t kRouterDowngradeThresholdDefault = 23 ; // /< Default downgrade threshold
2280+ static constexpr uint8_t kRouterUpgradeThresholdDefault = 16 ; // /< Default upgrade threshold
2281+
2282+ // Router Role Allowed statuses
2283+ bool mRouterRoleAllowed : 1 ; // /< Cached state of the router role allowed status
2284+ bool mRouterEligible : 1 ; // /< Router Eligible configuration affecting the role allowed status
2285+ bool mUsingFtdMode : 1 ; // /< FTD mode
2286+ bool mRouterRoleAllowedBySecurityPolicy : 1 ; // /< Cached state of the security policy router role allowed status
2287+ bool mDowngradeBlocked : 1 ; // /< Router role blocked from downgrading
22552288#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
2256- bool mCcmEnabled : 1 ;
2257- bool mThreadVersionCheckEnabled : 1 ;
2289+ bool mCcmEnabled : 1 ; // /< Whether to allow the security policy CCM commissioned check
2290+ bool mThreadVersionCheckEnabled : 1 ; // /< Whether to allow the security policy version check
22582291#endif
2292+
2293+ AddressSolicitState mAddressSolicitState ;
2294+
22592295 uint8_t mTimeout ;
22602296 uint8_t mJitter ;
22612297 uint8_t mUpgradeThreshold ;
@@ -2446,6 +2482,8 @@ class Mle : public InstanceLocator, private NonCopyable
24462482 void ClearAlternateRloc16 (void );
24472483 uint8_t SelectLeaderId (void ) const ;
24482484 uint32_t SelectPartitionId (void ) const ;
2485+ void HandleRouterRoleAllowedFromSecurityPolicy (void );
2486+ void HandleRoleAllowedChangedFromConfig (void );
24492487 void DetermineConnectivity (Connectivity &aConnectivity) const ;
24502488 void HandleDetachStart (void );
24512489 void HandleChildStart (void );
@@ -2493,6 +2531,8 @@ class Mle : public InstanceLocator, private NonCopyable
24932531 void SetChildStateToValid (Child &aChild);
24942532 bool HasChildren (void );
24952533 void RemoveChildren (void );
2534+ void CheckOrBeginRouterDowngrade (uint8_t aNeighborId, const RouteTlv &aRouteTlv);
2535+ bool NeighborHasComparableConnectivity (const RouteTlv &aRouteTlv, uint8_t aNeighborId) const ;
24962536 void HandleAdvertiseTrickleTimer (void );
24972537 void HandleTimeTick (void );
24982538 void HandleRouterTableEvent (RouterTable::Events aEvents);
@@ -2571,13 +2611,13 @@ class Mle : public InstanceLocator, private NonCopyable
25712611
25722612#if OPENTHREAD_FTD
25732613
2574- bool mAddressSolicitPending : 1 ;
2575- bool mAddressSolicitRejected : 1 ;
2614+ #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
2615+ bool mCcmEnabled : 1 ;
2616+ bool mThreadVersionCheckEnabled : 1 ;
2617+ #endif
25762618 uint8_t mRouterId ;
25772619 uint8_t mPreviousRouterId ;
25782620 uint8_t mNetworkIdTimeout ;
2579- uint8_t mRouterUpgradeThreshold ;
2580- uint8_t mRouterDowngradeThreshold ;
25812621 uint8_t mLeaderWeight ;
25822622 uint8_t mPreviousPartitionRouterIdSequence ;
25832623 uint8_t mPreviousPartitionIdTimeout ;
0 commit comments