1 /* 2 * Copyright (c) 2016, The OpenThread Authors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the copyright holder nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @file 31 * This file includes definitions for MLE functionality required by the Thread Router and Leader roles. 32 */ 33 34 #ifndef MLE_ROUTER_HPP_ 35 #define MLE_ROUTER_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include <openthread/thread_ftd.h> 40 41 #include "coap/coap_message.hpp" 42 #include "common/callback.hpp" 43 #include "common/time_ticker.hpp" 44 #include "common/timer.hpp" 45 #include "common/trickle_timer.hpp" 46 #include "mac/mac_types.hpp" 47 #include "meshcop/meshcop_tlvs.hpp" 48 #include "net/icmp6.hpp" 49 #include "net/udp6.hpp" 50 #include "thread/child.hpp" 51 #include "thread/child_table.hpp" 52 #include "thread/mle.hpp" 53 #include "thread/mle_tlvs.hpp" 54 #include "thread/router.hpp" 55 #include "thread/router_table.hpp" 56 #include "thread/thread_tlvs.hpp" 57 #include "thread/tmf.hpp" 58 59 namespace ot { 60 namespace Mle { 61 62 /** 63 * @addtogroup core-mle-router 64 * 65 * @brief 66 * This module includes definitions for MLE functionality required by the Thread Router and Leader roles. 67 * 68 * @{ 69 */ 70 71 #if OPENTHREAD_FTD 72 73 /** 74 * Implements MLE functionality required by the Thread Router and Leader roles. 75 */ 76 class MleRouter : public Mle 77 { 78 friend class Mle; 79 friend class ot::Instance; 80 friend class ot::TimeTicker; 81 friend class Tmf::Agent; 82 83 public: 84 /** 85 * Initializes the object. 86 * 87 * @param[in] aInstance A reference to the OpenThread instance. 88 */ 89 explicit MleRouter(Instance &aInstance); 90 91 /** 92 * Indicates whether or not the device is router-eligible. 93 * 94 * @retval true If device is router-eligible. 95 * @retval false If device is not router-eligible. 96 */ 97 bool IsRouterEligible(void) const; 98 99 /** 100 * Sets whether or not the device is router-eligible. 101 * 102 * If @p aEligible is false and the device is currently operating as a router, this call will cause the device to 103 * detach and attempt to reattach as a child. 104 * 105 * @param[in] aEligible TRUE to configure device router-eligible, FALSE otherwise. 106 * 107 * @retval kErrorNone Successfully set the router-eligible configuration. 108 * @retval kErrorNotCapable The device is not capable of becoming a router. 109 */ 110 Error SetRouterEligible(bool aEligible); 111 112 /** 113 * Indicates whether a node is the only router on the network. 114 * 115 * @retval TRUE It is the only router in the network. 116 * @retval FALSE It is a child or is not a single router in the network. 117 */ 118 bool IsSingleton(void) const; 119 120 /** 121 * Generates an Address Solicit request for a Router ID. 122 * 123 * @param[in] aStatus The reason for requesting a Router ID. 124 * 125 * @retval kErrorNone Successfully generated an Address Solicit message. 126 * @retval kErrorNotCapable Device is not capable of becoming a router 127 * @retval kErrorInvalidState Thread is not enabled 128 */ 129 Error BecomeRouter(ThreadStatusTlv::Status aStatus); 130 131 /** 132 * Becomes a leader and starts a new partition. 133 * 134 * If the device is already attached, this method can be used to attempt to take over as the leader, creating a new 135 * partition. For this to work, the local leader weight must be greater than the weight of the current leader. The 136 * @p aCheckWeight can be used to ensure that this check is performed. 137 * 138 * @param[in] aCheckWeight Check that the local leader weight is larger than the weight of the current leader. 139 * 140 * @retval kErrorNone Successfully become a Leader and started a new partition. 141 * @retval kErrorInvalidState Thread is not enabled. 142 * @retval kErrorNotCapable Device is not capable of becoming a leader (not router eligible), or 143 * @p aCheckWeight is true and cannot override the current leader due to its local 144 * leader weight being same or smaller than current leader's weight. 145 */ 146 Error BecomeLeader(bool aCheckWeight); 147 148 #if OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE 149 /** 150 * Gets the device properties which are used to determine the Leader Weight. 151 * 152 * @returns The current device properties. 153 */ GetDeviceProperties(void) const154 const DeviceProperties &GetDeviceProperties(void) const { return mDeviceProperties; } 155 156 /** 157 * Sets the device properties which are then used to determine and set the Leader Weight. 158 * 159 * @param[in] aDeviceProperties The device properties. 160 */ 161 void SetDeviceProperties(const DeviceProperties &aDeviceProperties); 162 #endif 163 164 /** 165 * Returns the Leader Weighting value for this Thread interface. 166 * 167 * @returns The Leader Weighting value for this Thread interface. 168 */ GetLeaderWeight(void) const169 uint8_t GetLeaderWeight(void) const { return mLeaderWeight; } 170 171 /** 172 * Sets the Leader Weighting value for this Thread interface. 173 * 174 * Directly sets the Leader Weight to the new value replacing its previous value (which may have been 175 * determined from a previous call to `SetDeviceProperties()`). 176 * 177 * @param[in] aWeight The Leader Weighting value. 178 */ SetLeaderWeight(uint8_t aWeight)179 void SetLeaderWeight(uint8_t aWeight) { mLeaderWeight = aWeight; } 180 181 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 182 183 /** 184 * Returns the preferred Partition Id when operating in the Leader role for certification testing. 185 * 186 * @returns The preferred Partition Id value. 187 */ GetPreferredLeaderPartitionId(void) const188 uint32_t GetPreferredLeaderPartitionId(void) const { return mPreferredLeaderPartitionId; } 189 190 /** 191 * Sets the preferred Partition Id when operating in the Leader role for certification testing. 192 * 193 * @param[in] aPartitionId The preferred Leader Partition Id. 194 */ SetPreferredLeaderPartitionId(uint32_t aPartitionId)195 void SetPreferredLeaderPartitionId(uint32_t aPartitionId) { mPreferredLeaderPartitionId = aPartitionId; } 196 #endif 197 198 /** 199 * Sets the preferred Router Id. Upon becoming a router/leader the node 200 * attempts to use this Router Id. If the preferred Router Id is not set or if it 201 * can not be used, a randomly generated router Id is picked. 202 * This property can be set when he device role is detached or disabled. 203 * 204 * @param[in] aRouterId The preferred Router Id. 205 * 206 * @retval kErrorNone Successfully set the preferred Router Id. 207 * @retval kErrorInvalidState Could not set (role is other than detached and disabled) 208 */ 209 Error SetPreferredRouterId(uint8_t aRouterId); 210 211 /** 212 * Gets the Partition Id which the device joined successfully once. 213 */ GetPreviousPartitionId(void) const214 uint32_t GetPreviousPartitionId(void) const { return mPreviousPartitionId; } 215 216 /** 217 * Sets the Partition Id which the device joins successfully. 218 * 219 * @param[in] aPartitionId The Partition Id. 220 */ SetPreviousPartitionId(uint32_t aPartitionId)221 void SetPreviousPartitionId(uint32_t aPartitionId) { mPreviousPartitionId = aPartitionId; } 222 223 /** 224 * Sets the Router Id. 225 * 226 * @param[in] aRouterId The Router Id. 227 */ 228 void SetRouterId(uint8_t aRouterId); 229 230 /** 231 * Returns the NETWORK_ID_TIMEOUT value. 232 * 233 * @returns The NETWORK_ID_TIMEOUT value. 234 */ GetNetworkIdTimeout(void) const235 uint8_t GetNetworkIdTimeout(void) const { return mNetworkIdTimeout; } 236 237 /** 238 * Sets the NETWORK_ID_TIMEOUT value. 239 * 240 * @param[in] aTimeout The NETWORK_ID_TIMEOUT value. 241 */ SetNetworkIdTimeout(uint8_t aTimeout)242 void SetNetworkIdTimeout(uint8_t aTimeout) { mNetworkIdTimeout = aTimeout; } 243 244 /** 245 * Returns the ROUTER_SELECTION_JITTER value. 246 * 247 * @returns The ROUTER_SELECTION_JITTER value in seconds. 248 */ GetRouterSelectionJitter(void) const249 uint8_t GetRouterSelectionJitter(void) const { return mRouterRoleTransition.GetJitter(); } 250 251 /** 252 * Sets the ROUTER_SELECTION_JITTER value. 253 * 254 * @param[in] aRouterJitter The router selection jitter value (in seconds). 255 */ SetRouterSelectionJitter(uint8_t aRouterJitter)256 void SetRouterSelectionJitter(uint8_t aRouterJitter) { mRouterRoleTransition.SetJitter(aRouterJitter); } 257 258 /** 259 * Indicates whether or not router role transition (upgrade from REED or downgrade to REED) is pending. 260 * 261 * @retval TRUE Router role transition is pending. 262 * @retval FALSE Router role transition is not pending 263 */ IsRouterRoleTransitionPending(void) const264 bool IsRouterRoleTransitionPending(void) const { return mRouterRoleTransition.IsPending(); } 265 266 /** 267 * Returns the current timeout delay in seconds till router role transition (upgrade from REED or downgrade to 268 * REED). 269 * 270 * @returns The timeout in seconds till router role transition, or zero if not pending role transition. 271 */ GetRouterRoleTransitionTimeout(void) const272 uint8_t GetRouterRoleTransitionTimeout(void) const { return mRouterRoleTransition.GetTimeout(); } 273 274 /** 275 * Returns the ROUTER_UPGRADE_THRESHOLD value. 276 * 277 * @returns The ROUTER_UPGRADE_THRESHOLD value. 278 */ GetRouterUpgradeThreshold(void) const279 uint8_t GetRouterUpgradeThreshold(void) const { return mRouterUpgradeThreshold; } 280 281 /** 282 * Sets the ROUTER_UPGRADE_THRESHOLD value. 283 * 284 * @param[in] aThreshold The ROUTER_UPGRADE_THRESHOLD value. 285 */ SetRouterUpgradeThreshold(uint8_t aThreshold)286 void SetRouterUpgradeThreshold(uint8_t aThreshold) { mRouterUpgradeThreshold = aThreshold; } 287 288 /** 289 * Returns the ROUTER_DOWNGRADE_THRESHOLD value. 290 * 291 * @returns The ROUTER_DOWNGRADE_THRESHOLD value. 292 */ GetRouterDowngradeThreshold(void) const293 uint8_t GetRouterDowngradeThreshold(void) const { return mRouterDowngradeThreshold; } 294 295 /** 296 * Sets the ROUTER_DOWNGRADE_THRESHOLD value. 297 * 298 * @param[in] aThreshold The ROUTER_DOWNGRADE_THRESHOLD value. 299 */ SetRouterDowngradeThreshold(uint8_t aThreshold)300 void SetRouterDowngradeThreshold(uint8_t aThreshold) { mRouterDowngradeThreshold = aThreshold; } 301 302 /** 303 * Returns the MLE_CHILD_ROUTER_LINKS value. 304 * 305 * @returns The MLE_CHILD_ROUTER_LINKS value. 306 */ GetChildRouterLinks(void) const307 uint8_t GetChildRouterLinks(void) const { return mChildRouterLinks; } 308 309 /** 310 * Sets the MLE_CHILD_ROUTER_LINKS value. 311 * 312 * @param[in] aChildRouterLinks The MLE_CHILD_ROUTER_LINKS value. 313 * 314 * @retval kErrorNone Successfully set the value. 315 * @retval kErrorInvalidState Thread protocols are enabled. 316 */ 317 Error SetChildRouterLinks(uint8_t aChildRouterLinks); 318 319 /** 320 * Returns if the REED is expected to become Router soon. 321 * 322 * @retval TRUE If the REED is going to become a Router soon. 323 * @retval FALSE If the REED is not going to become a Router soon. 324 */ 325 bool IsExpectedToBecomeRouterSoon(void) const; 326 327 /** 328 * Removes a link to a neighbor. 329 * 330 * @param[in] aNeighbor A reference to the neighbor object. 331 */ 332 void RemoveNeighbor(Neighbor &aNeighbor); 333 334 /** 335 * Invalidates a direct link to a neighboring router (due to failed link-layer acks). 336 * 337 * @param[in] aRouter A reference to the router object. 338 */ 339 void RemoveRouterLink(Router &aRouter); 340 341 /** 342 * Indicates whether or not the given Thread partition attributes are preferred. 343 * 344 * @param[in] aSingletonA Whether or not the Thread Partition A has a single router. 345 * @param[in] aLeaderDataA A reference to Thread Partition A's Leader Data. 346 * @param[in] aSingletonB Whether or not the Thread Partition B has a single router. 347 * @param[in] aLeaderDataB A reference to Thread Partition B's Leader Data. 348 * 349 * @retval 1 If partition A is preferred. 350 * @retval 0 If partition A and B have equal preference. 351 * @retval -1 If partition B is preferred. 352 */ 353 static int ComparePartitions(bool aSingletonA, 354 const LeaderData &aLeaderDataA, 355 bool aSingletonB, 356 const LeaderData &aLeaderDataB); 357 358 /** 359 * Fills an ConnectivityTlv. 360 * 361 * @param[out] aTlv A reference to the tlv to be filled. 362 */ 363 void FillConnectivityTlv(ConnectivityTlv &aTlv); 364 365 /** 366 * Schedule tx of MLE Advertisement message (unicast) to the given neighboring router after a random delay. 367 * 368 * @param[in] aRouter The router to send the Advertisement to. 369 * 370 */ 371 void ScheduleUnicastAdvertisementTo(const Router &aRouter); 372 373 #if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE 374 /** 375 * Sets steering data out of band 376 * 377 * @param[in] aExtAddress Value used to set steering data 378 * All zeros clears steering data 379 * All 0xFFs sets steering data to 0xFF 380 * Anything else is used to compute the bloom filter 381 */ 382 void SetSteeringData(const Mac::ExtAddress *aExtAddress); 383 #endif 384 385 /** 386 * Gets the assigned parent priority. 387 * 388 * @returns The assigned parent priority value, -2 means not assigned. 389 */ GetAssignParentPriority(void) const390 int8_t GetAssignParentPriority(void) const { return mParentPriority; } 391 392 /** 393 * Sets the parent priority. 394 * 395 * @param[in] aParentPriority The parent priority value. 396 * 397 * @retval kErrorNone Successfully set the parent priority. 398 * @retval kErrorInvalidArgs If the parent priority value is not among 1, 0, -1 and -2. 399 */ 400 Error SetAssignParentPriority(int8_t aParentPriority); 401 402 /** 403 * Gets the longest MLE Timeout TLV for all active MTD children. 404 * 405 * @param[out] aTimeout A reference to where the information is placed. 406 * 407 * @retval kErrorNone Successfully get the max child timeout 408 * @retval kErrorInvalidState Not an active router 409 * @retval kErrorNotFound NO MTD child 410 */ 411 Error GetMaxChildTimeout(uint32_t &aTimeout) const; 412 413 /** 414 * Sets the callback that is called when processing an MLE Discovery Request message. 415 * 416 * @param[in] aCallback A pointer to a function that is called to deliver MLE Discovery Request data. 417 * @param[in] aContext A pointer to application-specific context. 418 */ SetDiscoveryRequestCallback(otThreadDiscoveryRequestCallback aCallback,void * aContext)419 void SetDiscoveryRequestCallback(otThreadDiscoveryRequestCallback aCallback, void *aContext) 420 { 421 mDiscoveryRequestCallback.Set(aCallback, aContext); 422 } 423 424 /** 425 * Resets the MLE Advertisement Trickle timer interval. 426 */ 427 void ResetAdvertiseInterval(void); 428 429 /** 430 * Updates the MLE Advertisement Trickle timer max interval (if timer is running). 431 * 432 * This is called when there is change in router table. 433 */ 434 void UpdateAdvertiseInterval(void); 435 436 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 437 /** 438 * Generates an MLE Time Synchronization message. 439 * 440 * @retval kErrorNone Successfully sent an MLE Time Synchronization message. 441 * @retval kErrorNoBufs Insufficient buffers to generate the MLE Time Synchronization message. 442 */ 443 Error SendTimeSync(void); 444 #endif 445 446 /** 447 * Gets the maximum number of IP addresses that each MTD child may register with this device as parent. 448 * 449 * @returns The maximum number of IP addresses that each MTD child may register with this device as parent. 450 */ 451 uint8_t GetMaxChildIpAddresses(void) const; 452 453 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 454 455 /** 456 * Sets/restores the maximum number of IP addresses that each MTD child may register with this 457 * device as parent. 458 * 459 * @param[in] aMaxIpAddresses The maximum number of IP addresses that each MTD child may register with this 460 * device as parent. 0 to clear the setting and restore the default. 461 * 462 * @retval kErrorNone Successfully set/cleared the number. 463 * @retval kErrorInvalidArgs If exceeds the allowed maximum number. 464 */ 465 Error SetMaxChildIpAddresses(uint8_t aMaxIpAddresses); 466 467 /** 468 * Sets whether the device was commissioned using CCM. 469 * 470 * @param[in] aEnabled TRUE if the device was commissioned using CCM, FALSE otherwise. 471 */ SetCcmEnabled(bool aEnabled)472 void SetCcmEnabled(bool aEnabled) { mCcmEnabled = aEnabled; } 473 474 /** 475 * Sets whether the Security Policy TLV version-threshold for routing (VR field) is enabled. 476 * 477 * @param[in] aEnabled TRUE to enable Security Policy TLV version-threshold for routing, FALSE otherwise. 478 */ SetThreadVersionCheckEnabled(bool aEnabled)479 void SetThreadVersionCheckEnabled(bool aEnabled) { mThreadVersionCheckEnabled = aEnabled; } 480 481 /** 482 * Gets the current Interval Max value used by Advertisement trickle timer. 483 * 484 * @returns The Interval Max of Advertisement trickle timer in milliseconds. 485 */ GetAdvertisementTrickleIntervalMax(void) const486 uint32_t GetAdvertisementTrickleIntervalMax(void) const { return mAdvertiseTrickleTimer.GetIntervalMax(); } 487 488 #endif // OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 489 490 private: 491 //------------------------------------------------------------------------------------------------------------------ 492 // Constants 493 494 // Advertisement trickle timer constants - all times are in milliseconds. 495 static constexpr uint32_t kAdvIntervalMin = 1000; // I_MIN 496 static constexpr uint32_t kAdvIntervalNeighborMultiplier = 4000; // Multiplier for I_MAX per router neighbor 497 static constexpr uint32_t kAdvIntervalMaxLowerBound = 12000; // Lower bound for I_MAX 498 static constexpr uint32_t kAdvIntervalMaxUpperBound = 32000; // Upper bound for I_MAX 499 static constexpr uint32_t kReedAdvIntervalMin = 570000; 500 static constexpr uint32_t kReedAdvIntervalMax = 630000; 501 #if OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE 502 static constexpr uint32_t kAdvIntervalMaxLogRoutes = 5000; 503 #endif 504 505 static constexpr uint32_t kMaxUnicastAdvertisementDelay = 1000; // Max random delay for unciast Adv tx 506 static constexpr uint32_t kMaxNeighborAge = 100000; // Max neighbor age on router (in msec) 507 static constexpr uint32_t kMaxNeighborAgeOnChild = 150000; // Max neighbor age on FTD child (in msec) 508 static constexpr uint32_t kMaxLeaderToRouterTimeout = 90000; // (in msec) 509 static constexpr uint8_t kMinDowngradeNeighbors = 7; 510 static constexpr uint8_t kNetworkIdTimeout = 120; // (in sec) 511 static constexpr uint8_t kRouterSelectionJitter = 120; // (in sec) 512 static constexpr uint8_t kRouterDowngradeThreshold = 23; 513 static constexpr uint8_t kRouterUpgradeThreshold = 16; 514 static constexpr uint16_t kDiscoveryMaxJitter = 250; // Max jitter delay Discovery Responses (in msec). 515 static constexpr uint16_t kUnsolicitedDataResponseJitter = 500; // Max delay for unsol Data Response (in msec). 516 static constexpr uint8_t kLeaderDowngradeExtraDelay = 10; // Extra delay to downgrade leader (in sec). 517 static constexpr uint8_t kDefaultLeaderWeight = 64; 518 static constexpr uint8_t kAlternateRloc16Timeout = 8; // Time to use alternate RLOC16 (in sec). 519 520 // Threshold to accept a router upgrade request with reason 521 // `kBorderRouterRequest` (number of BRs acting as router in 522 // Network Data). 523 static constexpr uint8_t kRouterUpgradeBorderRouterRequestThreshold = 2; 524 525 static constexpr uint8_t kLinkRequestMinMargin = OPENTHREAD_CONFIG_MLE_LINK_REQUEST_MARGIN_MIN; 526 static constexpr uint8_t kPartitionMergeMinMargin = OPENTHREAD_CONFIG_MLE_PARTITION_MERGE_MARGIN_MIN; 527 static constexpr uint8_t kChildRouterLinks = OPENTHREAD_CONFIG_MLE_CHILD_ROUTER_LINKS; 528 static constexpr uint8_t kMaxChildIpAddresses = OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD; 529 530 // Constants for gradual router link establishment (on FTD child) 531 struct GradualChildRouterLink 532 { 533 static constexpr uint8_t kExtraChildRouterLinks = OPENTHREAD_CONFIG_MLE_EXTRA_CHILD_ROUTER_LINKS_GRADUAL; 534 static constexpr uint32_t kWaitDurationAfterAttach = 300; // in seconds (5 minutes) 535 static constexpr uint32_t kMinLinkRequestDelay = 1500; // in msec 536 static constexpr uint32_t kMaxLinkRequestDelay = 10000; // in msec 537 static constexpr uint32_t kProbabilityPercentage = 5; // in percent 538 }; 539 540 static constexpr uint8_t kMinCriticalChildrenCount = 6; 541 542 static constexpr uint16_t kChildSupervisionDefaultIntervalForOlderVersion = 543 OPENTHREAD_CONFIG_CHILD_SUPERVISION_OLDER_VERSION_CHILD_DEFAULT_INTERVAL; 544 545 static constexpr int8_t kParentPriorityHigh = 1; 546 static constexpr int8_t kParentPriorityMedium = 0; 547 static constexpr int8_t kParentPriorityLow = -1; 548 static constexpr int8_t kParentPriorityUnspecified = -2; 549 550 //------------------------------------------------------------------------------------------------------------------ 551 // Nested types 552 553 class RouterRoleTransition 554 { 555 public: 556 RouterRoleTransition(void); 557 IsPending(void) const558 bool IsPending(void) const { return (mTimeout != 0); } 559 void StartTimeout(void); StopTimeout(void)560 void StopTimeout(void) { mTimeout = 0; } IncreaseTimeout(uint8_t aIncrement)561 void IncreaseTimeout(uint8_t aIncrement) { mTimeout += aIncrement; } GetTimeout(void) const562 uint8_t GetTimeout(void) const { return mTimeout; } 563 bool HandleTimeTick(void); GetJitter(void) const564 uint8_t GetJitter(void) const { return mJitter; } SetJitter(uint8_t aJitter)565 void SetJitter(uint8_t aJitter) { mJitter = aJitter; } 566 567 private: 568 uint8_t mTimeout; 569 uint8_t mJitter; 570 }; 571 572 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 573 574 class RouterRoleRestorer : public InstanceLocator 575 { 576 // Attempts to restore the router or leader role after an MLE 577 // restart(e.g., after a device reboot) by sending multicast 578 // Link Requests. 579 580 public: 581 RouterRoleRestorer(Instance &aInstance); 582 IsActive(void) const583 bool IsActive(void) const { return mAttempts > 0; } 584 void Start(DeviceRole aPreviousRole); Stop(void)585 void Stop(void) { mAttempts = 0; } 586 void HandleTimer(void); 587 GenerateRandomChallenge(void)588 void GenerateRandomChallenge(void) { mChallenge.GenerateRandom(); } GetChallenge(void) const589 const TxChallenge &GetChallenge(void) const { return mChallenge; } 590 591 private: 592 void SendMulticastLinkRequest(void); 593 594 uint8_t mAttempts; 595 TxChallenge mChallenge; 596 }; 597 598 //------------------------------------------------------------------------------------------------------------------ 599 // Methods 600 601 void SetAlternateRloc16(uint16_t aRloc16); 602 void ClearAlternateRloc16(void); 603 void HandleDetachStart(void); 604 void HandleChildStart(AttachMode aMode); 605 void HandleSecurityPolicyChanged(void); 606 void HandleLinkRequest(RxInfo &aRxInfo); 607 void HandleLinkAccept(RxInfo &aRxInfo); 608 void HandleLinkAcceptAndRequest(RxInfo &aRxInfo); 609 void HandleLinkAcceptVariant(RxInfo &aRxInfo, MessageType aMessageType); 610 Error HandleAdvertisementOnFtd(RxInfo &aRxInfo, uint16_t aSourceAddress, const LeaderData &aLeaderData); 611 void HandleParentRequest(RxInfo &aRxInfo); 612 void HandleChildIdRequest(RxInfo &aRxInfo); 613 void HandleChildUpdateRequestOnParent(RxInfo &aRxInfo); 614 void HandleChildUpdateResponseOnParent(RxInfo &aRxInfo); 615 void HandleDataRequest(RxInfo &aRxInfo); 616 void HandleNetworkDataUpdateRouter(void); 617 void HandleDiscoveryRequest(RxInfo &aRxInfo); 618 void EstablishRouterLinkOnFtdChild(Router &aRouter, RxInfo &aRxInfo, uint8_t aLinkMargin); 619 Error ProcessRouteTlv(const RouteTlv &aRouteTlv, RxInfo &aRxInfo); 620 Error ReadAndProcessRouteTlvOnFtdChild(RxInfo &aRxInfo, uint8_t aParentId); 621 void StopAdvertiseTrickleTimer(void); 622 uint32_t DetermineAdvertiseIntervalMax(void) const; 623 Error SendAddressSolicit(ThreadStatusTlv::Status aStatus); 624 void SendAddressSolicitResponse(const Coap::Message &aRequest, 625 ThreadStatusTlv::Status aResponseStatus, 626 const Router *aRouter, 627 const Ip6::MessageInfo &aMessageInfo); 628 void SendAddressRelease(void); 629 void SendMulticastAdvertisement(void); 630 void SendAdvertisement(const Ip6::Address &aDestination); 631 void SendLinkRequest(Router *aRouter); 632 Error SendLinkAccept(const LinkAcceptInfo &aInfo); 633 void SendParentResponse(const ParentResponseInfo &aInfo); 634 Error SendChildIdResponse(Child &aChild); 635 Error SendChildUpdateRequestToChild(Child &aChild); 636 void SendChildUpdateResponseToChild(Child *aChild, 637 const Ip6::MessageInfo &aMessageInfo, 638 const TlvList &aTlvList, 639 const RxChallenge &aChallenge); 640 void SendMulticastDataResponse(void); 641 void SendDataResponse(const Ip6::Address &aDestination, 642 const TlvList &aTlvList, 643 const Message *aRequestMessage = nullptr); 644 Error SendDiscoveryResponse(const Ip6::Address &aDestination, const DiscoveryResponseInfo &aInfo); 645 void SetStateRouter(uint16_t aRloc16); 646 void SetStateLeader(uint16_t aRloc16, LeaderStartMode aStartMode); 647 void SetStateRouterOrLeader(DeviceRole aRole, uint16_t aRloc16, LeaderStartMode aStartMode); 648 void StopLeader(void); 649 void SynchronizeChildNetworkData(void); 650 Error ProcessAddressRegistrationTlv(RxInfo &aRxInfo, Child &aChild); 651 bool HasNeighborWithGoodLinkQuality(void) const; 652 void HandlePartitionChange(void); 653 void SetChildStateToValid(Child &aChild); 654 bool HasChildren(void); 655 void RemoveChildren(void); 656 bool ShouldDowngrade(uint8_t aNeighborId, const RouteTlv &aRouteTlv) const; 657 bool NeighborHasComparableConnectivity(const RouteTlv &aRouteTlv, uint8_t aNeighborId) const; 658 void HandleAdvertiseTrickleTimer(void); 659 void HandleAddressSolicitResponse(Coap::Message *aMessage, const Ip6::MessageInfo *aMessageInfo, Error aResult); 660 void HandleTimeTick(void); 661 662 template <Uri kUri> void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 663 664 #if OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE 665 void SignalDuaAddressEvent(const Child &aChild, const Ip6::Address &aOldDua) const; 666 #endif 667 668 static bool IsMessageMleSubType(const Message &aMessage); 669 static bool IsMessageChildUpdateRequest(const Message &aMessage); 670 static void HandleAdvertiseTrickleTimer(TrickleTimer &aTimer); 671 static void HandleAddressSolicitResponse(void *aContext, 672 otMessage *aMessage, 673 const otMessageInfo *aMessageInfo, 674 otError aResult); 675 676 //------------------------------------------------------------------------------------------------------------------ 677 // Variables 678 679 bool mRouterEligible : 1; 680 bool mAddressSolicitPending : 1; 681 bool mAddressSolicitRejected : 1; 682 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 683 bool mCcmEnabled : 1; 684 bool mThreadVersionCheckEnabled : 1; 685 #endif 686 687 uint8_t mRouterId; 688 uint8_t mPreviousRouterId; 689 uint8_t mNetworkIdTimeout; 690 uint8_t mRouterUpgradeThreshold; 691 uint8_t mRouterDowngradeThreshold; 692 uint8_t mLeaderWeight; 693 uint8_t mPreviousPartitionRouterIdSequence; 694 uint8_t mPreviousPartitionIdTimeout; 695 uint8_t mChildRouterLinks; 696 uint8_t mAlternateRloc16Timeout; 697 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 698 uint8_t mMaxChildIpAddresses; 699 #endif 700 int8_t mParentPriority; 701 uint16_t mNextChildId; 702 uint32_t mPreviousPartitionIdRouter; 703 uint32_t mPreviousPartitionId; 704 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 705 uint32_t mPreferredLeaderPartitionId; 706 #endif 707 708 TrickleTimer mAdvertiseTrickleTimer; 709 ChildTable mChildTable; 710 RouterTable mRouterTable; 711 RouterRoleRestorer mRouterRoleRestorer; 712 RouterRoleTransition mRouterRoleTransition; 713 Ip6::Netif::UnicastAddress mLeaderAloc; 714 #if OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE 715 DeviceProperties mDeviceProperties; 716 #endif 717 #if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE 718 MeshCoP::SteeringData mSteeringData; 719 #endif 720 Callback<otThreadDiscoveryRequestCallback> mDiscoveryRequestCallback; 721 }; 722 723 DeclareTmfHandler(MleRouter, kUriAddressSolicit); 724 DeclareTmfHandler(MleRouter, kUriAddressRelease); 725 726 #endif // OPENTHREAD_FTD 727 728 #if OPENTHREAD_MTD 729 730 typedef Mle MleRouter; 731 732 #endif 733 734 } // namespace Mle 735 736 /** 737 * @} 738 */ 739 740 } // namespace ot 741 742 #endif // MLE_ROUTER_HPP_ 743