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 */ 77 class MleRouter : public Mle 78 { 79 friend class Mle; 80 friend class ot::Instance; 81 friend class ot::TimeTicker; 82 friend class Tmf::Agent; 83 84 public: 85 /** 86 * Initializes the object. 87 * 88 * @param[in] aInstance A reference to the OpenThread instance. 89 * 90 */ 91 explicit MleRouter(Instance &aInstance); 92 93 /** 94 * Indicates whether or not the device is router-eligible. 95 * 96 * @retval true If device is router-eligible. 97 * @retval false If device is not router-eligible. 98 * 99 */ 100 bool IsRouterEligible(void) const; 101 102 /** 103 * Sets whether or not the device is router-eligible. 104 * 105 * If @p aEligible is false and the device is currently operating as a router, this call will cause the device to 106 * detach and attempt to reattach as a child. 107 * 108 * @param[in] aEligible TRUE to configure device router-eligible, FALSE otherwise. 109 * 110 * @retval kErrorNone Successfully set the router-eligible configuration. 111 * @retval kErrorNotCapable The device is not capable of becoming a router. 112 * 113 */ 114 Error SetRouterEligible(bool aEligible); 115 116 /** 117 * Indicates whether a node is the only router on the network. 118 * 119 * @retval TRUE It is the only router in the network. 120 * @retval FALSE It is a child or is not a single router in the network. 121 * 122 */ 123 bool IsSingleton(void) const; 124 125 /** 126 * Generates an Address Solicit request for a Router ID. 127 * 128 * @param[in] aStatus The reason for requesting a Router ID. 129 * 130 * @retval kErrorNone Successfully generated an Address Solicit message. 131 * @retval kErrorNotCapable Device is not capable of becoming a router 132 * @retval kErrorInvalidState Thread is not enabled 133 * 134 */ 135 Error BecomeRouter(ThreadStatusTlv::Status aStatus); 136 137 /** 138 * Causes the Thread interface to become a Leader and start a new partition. 139 * 140 * @retval kErrorNone Successfully become a Leader and started a new partition. 141 * @retval kErrorNotCapable Device is not capable of becoming a leader 142 * @retval kErrorInvalidState Thread is not enabled 143 * 144 */ 145 Error BecomeLeader(void); 146 147 #if OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE 148 /** 149 * Gets the device properties which are used to determine the Leader Weight. 150 * 151 * @returns The current device properties. 152 * 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 */ 162 void SetDeviceProperties(const DeviceProperties &aDeviceProperties); 163 #endif 164 165 /** 166 * Returns the Leader Weighting value for this Thread interface. 167 * 168 * @returns The Leader Weighting value for this Thread interface. 169 * 170 */ GetLeaderWeight(void) const171 uint8_t GetLeaderWeight(void) const { return mLeaderWeight; } 172 173 /** 174 * Sets the Leader Weighting value for this Thread interface. 175 * 176 * Directly sets the Leader Weight to the new value replacing its previous value (which may have been 177 * determined from a previous call to `SetDeviceProperties()`). 178 * 179 * @param[in] aWeight The Leader Weighting value. 180 * 181 */ SetLeaderWeight(uint8_t aWeight)182 void SetLeaderWeight(uint8_t aWeight) { mLeaderWeight = aWeight; } 183 184 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 185 186 /** 187 * Returns the preferred Partition Id when operating in the Leader role for certification testing. 188 * 189 * @returns The preferred Partition Id value. 190 * 191 */ GetPreferredLeaderPartitionId(void) const192 uint32_t GetPreferredLeaderPartitionId(void) const { return mPreferredLeaderPartitionId; } 193 194 /** 195 * Sets the preferred Partition Id when operating in the Leader role for certification testing. 196 * 197 * @param[in] aPartitionId The preferred Leader Partition Id. 198 * 199 */ SetPreferredLeaderPartitionId(uint32_t aPartitionId)200 void SetPreferredLeaderPartitionId(uint32_t aPartitionId) { mPreferredLeaderPartitionId = aPartitionId; } 201 #endif 202 203 /** 204 * Sets the preferred Router Id. Upon becoming a router/leader the node 205 * attempts to use this Router Id. If the preferred Router Id is not set or if it 206 * can not be used, a randomly generated router Id is picked. 207 * This property can be set when he device role is detached or disabled. 208 * 209 * @param[in] aRouterId The preferred Router Id. 210 * 211 * @retval kErrorNone Successfully set the preferred Router Id. 212 * @retval kErrorInvalidState Could not set (role is other than detached and disabled) 213 * 214 */ 215 Error SetPreferredRouterId(uint8_t aRouterId); 216 217 /** 218 * Gets the Partition Id which the device joined successfully once. 219 * 220 */ GetPreviousPartitionId(void) const221 uint32_t GetPreviousPartitionId(void) const { return mPreviousPartitionId; } 222 223 /** 224 * Sets the Partition Id which the device joins successfully. 225 * 226 * @param[in] aPartitionId The Partition Id. 227 * 228 */ SetPreviousPartitionId(uint32_t aPartitionId)229 void SetPreviousPartitionId(uint32_t aPartitionId) { mPreviousPartitionId = aPartitionId; } 230 231 /** 232 * Sets the Router Id. 233 * 234 * @param[in] aRouterId The Router Id. 235 * 236 */ 237 void SetRouterId(uint8_t aRouterId); 238 239 /** 240 * Returns the next hop towards an RLOC16 destination. 241 * 242 * @param[in] aDestination The RLOC16 of the destination. 243 * 244 * @returns A RLOC16 of the next hop if a route is known, kInvalidRloc16 otherwise. 245 * 246 */ GetNextHop(uint16_t aDestination)247 uint16_t GetNextHop(uint16_t aDestination) { return mRouterTable.GetNextHop(aDestination); } 248 249 /** 250 * Returns the NETWORK_ID_TIMEOUT value. 251 * 252 * @returns The NETWORK_ID_TIMEOUT value. 253 * 254 */ GetNetworkIdTimeout(void) const255 uint8_t GetNetworkIdTimeout(void) const { return mNetworkIdTimeout; } 256 257 /** 258 * Sets the NETWORK_ID_TIMEOUT value. 259 * 260 * @param[in] aTimeout The NETWORK_ID_TIMEOUT value. 261 * 262 */ SetNetworkIdTimeout(uint8_t aTimeout)263 void SetNetworkIdTimeout(uint8_t aTimeout) { mNetworkIdTimeout = aTimeout; } 264 265 /** 266 * Returns the ROUTER_SELECTION_JITTER value. 267 * 268 * @returns The ROUTER_SELECTION_JITTER value in seconds. 269 * 270 */ GetRouterSelectionJitter(void) const271 uint8_t GetRouterSelectionJitter(void) const { return mRouterRoleTransition.GetJitter(); } 272 273 /** 274 * Sets the ROUTER_SELECTION_JITTER value. 275 * 276 * @param[in] aRouterJitter The router selection jitter value (in seconds). 277 * 278 */ SetRouterSelectionJitter(uint8_t aRouterJitter)279 void SetRouterSelectionJitter(uint8_t aRouterJitter) { mRouterRoleTransition.SetJitter(aRouterJitter); } 280 281 /** 282 * Indicates whether or not router role transition (upgrade from REED or downgrade to REED) is pending. 283 * 284 * @retval TRUE Router role transition is pending. 285 * @retval FALSE Router role transition is not pending 286 * 287 */ IsRouterRoleTransitionPending(void) const288 bool IsRouterRoleTransitionPending(void) const { return mRouterRoleTransition.IsPending(); } 289 290 /** 291 * Returns the current timeout delay in seconds till router role transition (upgrade from REED or downgrade to 292 * REED). 293 * 294 * @returns The timeout in seconds till router role transition, or zero if not pending role transition. 295 * 296 */ GetRouterRoleTransitionTimeout(void) const297 uint8_t GetRouterRoleTransitionTimeout(void) const { return mRouterRoleTransition.GetTimeout(); } 298 299 /** 300 * Returns the ROUTER_UPGRADE_THRESHOLD value. 301 * 302 * @returns The ROUTER_UPGRADE_THRESHOLD value. 303 * 304 */ GetRouterUpgradeThreshold(void) const305 uint8_t GetRouterUpgradeThreshold(void) const { return mRouterUpgradeThreshold; } 306 307 /** 308 * Sets the ROUTER_UPGRADE_THRESHOLD value. 309 * 310 * @param[in] aThreshold The ROUTER_UPGRADE_THRESHOLD value. 311 * 312 */ SetRouterUpgradeThreshold(uint8_t aThreshold)313 void SetRouterUpgradeThreshold(uint8_t aThreshold) { mRouterUpgradeThreshold = aThreshold; } 314 315 /** 316 * Returns the ROUTER_DOWNGRADE_THRESHOLD value. 317 * 318 * @returns The ROUTER_DOWNGRADE_THRESHOLD value. 319 * 320 */ GetRouterDowngradeThreshold(void) const321 uint8_t GetRouterDowngradeThreshold(void) const { return mRouterDowngradeThreshold; } 322 323 /** 324 * Sets the ROUTER_DOWNGRADE_THRESHOLD value. 325 * 326 * @param[in] aThreshold The ROUTER_DOWNGRADE_THRESHOLD value. 327 * 328 */ SetRouterDowngradeThreshold(uint8_t aThreshold)329 void SetRouterDowngradeThreshold(uint8_t aThreshold) { mRouterDowngradeThreshold = aThreshold; } 330 331 /** 332 * Returns the MLE_CHILD_ROUTER_LINKS value. 333 * 334 * @returns The MLE_CHILD_ROUTER_LINKS value. 335 * 336 */ GetChildRouterLinks(void) const337 uint8_t GetChildRouterLinks(void) const { return mChildRouterLinks; } 338 339 /** 340 * Sets the MLE_CHILD_ROUTER_LINKS value. 341 * 342 * @param[in] aChildRouterLinks The MLE_CHILD_ROUTER_LINKS value. 343 * 344 * @retval kErrorNone Successfully set the value. 345 * @retval kErrorInvalidState Thread protocols are enabled. 346 */ 347 Error SetChildRouterLinks(uint8_t aChildRouterLinks); 348 349 /** 350 * Returns if the REED is expected to become Router soon. 351 * 352 * @retval TRUE If the REED is going to become a Router soon. 353 * @retval FALSE If the REED is not going to become a Router soon. 354 * 355 */ 356 bool IsExpectedToBecomeRouterSoon(void) const; 357 358 /** 359 * Removes a link to a neighbor. 360 * 361 * @param[in] aNeighbor A reference to the neighbor object. 362 * 363 */ 364 void RemoveNeighbor(Neighbor &aNeighbor); 365 366 /** 367 * Invalidates a direct link to a neighboring router (due to failed link-layer acks). 368 * 369 * @param[in] aRouter A reference to the router object. 370 * 371 */ 372 void RemoveRouterLink(Router &aRouter); 373 374 /** 375 * Indicates whether or not the RLOC16 is an MTD child of this device. 376 * 377 * @param[in] aRloc16 The RLOC16. 378 * 379 * @retval TRUE if @p aRloc16 is an MTD child of this device. 380 * @retval FALSE if @p aRloc16 is not an MTD child of this device. 381 * 382 */ 383 bool IsMinimalChild(uint16_t aRloc16); 384 385 /** 386 * Indicates whether or not the given Thread partition attributes are preferred. 387 * 388 * @param[in] aSingletonA Whether or not the Thread Partition A has a single router. 389 * @param[in] aLeaderDataA A reference to Thread Partition A's Leader Data. 390 * @param[in] aSingletonB Whether or not the Thread Partition B has a single router. 391 * @param[in] aLeaderDataB A reference to Thread Partition B's Leader Data. 392 * 393 * @retval 1 If partition A is preferred. 394 * @retval 0 If partition A and B have equal preference. 395 * @retval -1 If partition B is preferred. 396 * 397 */ 398 static int ComparePartitions(bool aSingletonA, 399 const LeaderData &aLeaderDataA, 400 bool aSingletonB, 401 const LeaderData &aLeaderDataB); 402 403 /** 404 * Checks if the destination is reachable. 405 * 406 * @param[in] aMeshDest The RLOC16 of the destination. 407 * @param[in] aIp6Header A reference to the IPv6 header of the message. 408 * 409 * @retval kErrorNone The destination is reachable. 410 * @retval kErrorNoRoute The destination is not reachable and the message should be dropped. 411 * 412 */ 413 Error CheckReachability(uint16_t aMeshDest, const Ip6::Header &aIp6Header); 414 415 /** 416 * Resolves 2-hop routing loops. 417 * 418 * @param[in] aSourceMac The RLOC16 of the previous hop. 419 * @param[in] aDestRloc16 The RLOC16 of the final destination. 420 * 421 */ 422 void ResolveRoutingLoops(uint16_t aSourceMac, uint16_t aDestRloc16); 423 424 /** 425 * Fills an ConnectivityTlv. 426 * 427 * @param[out] aTlv A reference to the tlv to be filled. 428 * 429 */ 430 void FillConnectivityTlv(ConnectivityTlv &aTlv); 431 432 /** 433 * Generates an MLE Child Update Request message to be sent to the parent. 434 * 435 * @retval kErrorNone Successfully generated an MLE Child Update Request message. 436 * @retval kErrorNoBufs Insufficient buffers to generate the MLE Child Update Request message. 437 * 438 */ SendChildUpdateRequest(void)439 Error SendChildUpdateRequest(void) { return Mle::SendChildUpdateRequest(); } 440 441 Error SendLinkRequest(Neighbor *aNeighbor); 442 443 #if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE 444 /** 445 * Sets steering data out of band 446 * 447 * @param[in] aExtAddress Value used to set steering data 448 * All zeros clears steering data 449 * All 0xFFs sets steering data to 0xFF 450 * Anything else is used to compute the bloom filter 451 * 452 */ 453 void SetSteeringData(const Mac::ExtAddress *aExtAddress); 454 #endif 455 456 /** 457 * Gets the assigned parent priority. 458 * 459 * @returns The assigned parent priority value, -2 means not assigned. 460 * 461 */ GetAssignParentPriority(void) const462 int8_t GetAssignParentPriority(void) const { return mParentPriority; } 463 464 /** 465 * Sets the parent priority. 466 * 467 * @param[in] aParentPriority The parent priority value. 468 * 469 * @retval kErrorNone Successfully set the parent priority. 470 * @retval kErrorInvalidArgs If the parent priority value is not among 1, 0, -1 and -2. 471 * 472 */ 473 Error SetAssignParentPriority(int8_t aParentPriority); 474 475 /** 476 * Gets the longest MLE Timeout TLV for all active MTD children. 477 * 478 * @param[out] aTimeout A reference to where the information is placed. 479 * 480 * @retval kErrorNone Successfully get the max child timeout 481 * @retval kErrorInvalidState Not an active router 482 * @retval kErrorNotFound NO MTD child 483 * 484 */ 485 Error GetMaxChildTimeout(uint32_t &aTimeout) const; 486 487 /** 488 * Sets the callback that is called when processing an MLE Discovery Request message. 489 * 490 * @param[in] aCallback A pointer to a function that is called to deliver MLE Discovery Request data. 491 * @param[in] aContext A pointer to application-specific context. 492 * 493 */ SetDiscoveryRequestCallback(otThreadDiscoveryRequestCallback aCallback,void * aContext)494 void SetDiscoveryRequestCallback(otThreadDiscoveryRequestCallback aCallback, void *aContext) 495 { 496 mDiscoveryRequestCallback.Set(aCallback, aContext); 497 } 498 499 /** 500 * Resets the MLE Advertisement Trickle timer interval. 501 * 502 */ 503 void ResetAdvertiseInterval(void); 504 505 /** 506 * Updates the MLE Advertisement Trickle timer max interval (if timer is running). 507 * 508 * This is called when there is change in router table. 509 * 510 */ 511 void UpdateAdvertiseInterval(void); 512 513 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 514 /** 515 * Generates an MLE Time Synchronization message. 516 * 517 * @retval kErrorNone Successfully sent an MLE Time Synchronization message. 518 * @retval kErrorNoBufs Insufficient buffers to generate the MLE Time Synchronization message. 519 * 520 */ 521 Error SendTimeSync(void); 522 #endif 523 524 /** 525 * Gets the maximum number of IP addresses that each MTD child may register with this device as parent. 526 * 527 * @returns The maximum number of IP addresses that each MTD child may register with this device as parent. 528 * 529 */ 530 uint8_t GetMaxChildIpAddresses(void) const; 531 532 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 533 534 /** 535 * Sets/restores the maximum number of IP addresses that each MTD child may register with this 536 * device as parent. 537 * 538 * @param[in] aMaxIpAddresses The maximum number of IP addresses that each MTD child may register with this 539 * device as parent. 0 to clear the setting and restore the default. 540 * 541 * @retval kErrorNone Successfully set/cleared the number. 542 * @retval kErrorInvalidArgs If exceeds the allowed maximum number. 543 * 544 */ 545 Error SetMaxChildIpAddresses(uint8_t aMaxIpAddresses); 546 547 /** 548 * Sets whether the device was commissioned using CCM. 549 * 550 * @param[in] aEnabled TRUE if the device was commissioned using CCM, FALSE otherwise. 551 * 552 */ SetCcmEnabled(bool aEnabled)553 void SetCcmEnabled(bool aEnabled) { mCcmEnabled = aEnabled; } 554 555 /** 556 * Sets whether the Security Policy TLV version-threshold for routing (VR field) is enabled. 557 * 558 * @param[in] aEnabled TRUE to enable Security Policy TLV version-threshold for routing, FALSE otherwise. 559 * 560 */ SetThreadVersionCheckEnabled(bool aEnabled)561 void SetThreadVersionCheckEnabled(bool aEnabled) { mThreadVersionCheckEnabled = aEnabled; } 562 563 /** 564 * Gets the current Interval Max value used by Advertisement trickle timer. 565 * 566 * @returns The Interval Max of Advertisement trickle timer in milliseconds. 567 * 568 */ GetAdvertisementTrickleIntervalMax(void) const569 uint32_t GetAdvertisementTrickleIntervalMax(void) const { return mAdvertiseTrickleTimer.GetIntervalMax(); } 570 571 #endif // OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 572 573 private: 574 // Advertisement trickle timer constants - all times are in milliseconds. 575 static constexpr uint32_t kAdvIntervalMin = 1000; // I_MIN 576 static constexpr uint32_t kAdvIntervalNeighborMultiplier = 4000; // Multiplier for I_MAX per router neighbor 577 static constexpr uint32_t kAdvIntervalMaxLowerBound = 12000; // Lower bound for I_MAX 578 static constexpr uint32_t kAdvIntervalMaxUpperBound = 32000; // Upper bound for I_MAX 579 static constexpr uint32_t kReedAdvIntervalMin = 570000; 580 static constexpr uint32_t kReedAdvIntervalMax = 630000; 581 #if OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE 582 static constexpr uint32_t kAdvIntervalMaxLogRoutes = 5000; 583 #endif 584 585 static constexpr uint32_t kMaxNeighborAge = 100000; // Max neighbor age (in msec) 586 static constexpr uint32_t kMaxLeaderToRouterTimeout = 90000; // (in msec) 587 static constexpr uint8_t kMinDowngradeNeighbors = 7; 588 static constexpr uint8_t kNetworkIdTimeout = 120; // (in sec) 589 static constexpr uint8_t kRouterSelectionJitter = 120; // (in sec) 590 static constexpr uint8_t kRouterDowngradeThreshold = 23; 591 static constexpr uint8_t kRouterUpgradeThreshold = 16; 592 static constexpr uint16_t kDiscoveryMaxJitter = 250; // Max jitter delay Discovery Responses (in msec). 593 static constexpr uint16_t kChallengeTimeout = 2; // Challenge timeout (in sec). 594 static constexpr uint16_t kUnsolicitedDataResponseJitter = 500; // Max delay for unsol Data Response (in msec). 595 static constexpr uint8_t kLeaderDowngradeExtraDelay = 10; // Extra delay to downgrade leader (in sec). 596 static constexpr uint8_t kDefaultLeaderWeight = 64; 597 598 // Threshold to accept a router upgrade request with reason 599 // `kBorderRouterRequest` (number of BRs acting as router in 600 // Network Data). 601 static constexpr uint8_t kRouterUpgradeBorderRouterRequestThreshold = 2; 602 603 static constexpr uint8_t kLinkRequestMinMargin = OPENTHREAD_CONFIG_MLE_LINK_REQUEST_MARGIN_MIN; 604 static constexpr uint8_t kPartitionMergeMinMargin = OPENTHREAD_CONFIG_MLE_PARTITION_MERGE_MARGIN_MIN; 605 static constexpr uint8_t kChildRouterLinks = OPENTHREAD_CONFIG_MLE_CHILD_ROUTER_LINKS; 606 static constexpr uint8_t kMaxChildIpAddresses = OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD; 607 608 static constexpr uint8_t kMinCriticalChildrenCount = 6; 609 610 static constexpr uint16_t kChildSupervisionDefaultIntervalForOlderVersion = 611 OPENTHREAD_CONFIG_CHILD_SUPERVISION_OLDER_VERSION_CHILD_DEFAULT_INTERVAL; 612 613 static constexpr int8_t kParentPriorityHigh = 1; 614 static constexpr int8_t kParentPriorityMedium = 0; 615 static constexpr int8_t kParentPriorityLow = -1; 616 static constexpr int8_t kParentPriorityUnspecified = -2; 617 618 class RouterRoleTransition 619 { 620 public: 621 RouterRoleTransition(void); 622 IsPending(void) const623 bool IsPending(void) const { return (mTimeout != 0); } 624 void StartTimeout(void); StopTimeout(void)625 void StopTimeout(void) { mTimeout = 0; } IncreaseTimeout(uint8_t aIncrement)626 void IncreaseTimeout(uint8_t aIncrement) { mTimeout += aIncrement; } GetTimeout(void) const627 uint8_t GetTimeout(void) const { return mTimeout; } 628 bool HandleTimeTick(void); GetJitter(void) const629 uint8_t GetJitter(void) const { return mJitter; } SetJitter(uint8_t aJitter)630 void SetJitter(uint8_t aJitter) { mJitter = aJitter; } 631 632 private: 633 uint8_t mTimeout; 634 uint8_t mJitter; 635 }; 636 637 void HandleDetachStart(void); 638 void HandleChildStart(AttachMode aMode); 639 void HandleSecurityPolicyChanged(void); 640 void HandleLinkRequest(RxInfo &aRxInfo); 641 void HandleLinkAccept(RxInfo &aRxInfo); 642 Error HandleLinkAccept(RxInfo &aRxInfo, bool aRequest); 643 void HandleLinkAcceptAndRequest(RxInfo &aRxInfo); 644 Error HandleAdvertisement(RxInfo &aRxInfo, uint16_t aSourceAddress, const LeaderData &aLeaderData); 645 void HandleParentRequest(RxInfo &aRxInfo); 646 void HandleChildIdRequest(RxInfo &aRxInfo); 647 void HandleChildUpdateRequest(RxInfo &aRxInfo); 648 void HandleChildUpdateResponse(RxInfo &aRxInfo); 649 void HandleDataRequest(RxInfo &aRxInfo); 650 void HandleNetworkDataUpdateRouter(void); 651 void HandleDiscoveryRequest(RxInfo &aRxInfo); 652 653 Error ProcessRouteTlv(const RouteTlv &aRouteTlv, RxInfo &aRxInfo); 654 Error ReadAndProcessRouteTlvOnFed(RxInfo &aRxInfo, uint8_t aParentId); 655 656 void StopAdvertiseTrickleTimer(void); 657 uint32_t DetermineAdvertiseIntervalMax(void) const; 658 659 Error SendAddressSolicit(ThreadStatusTlv::Status aStatus); 660 void SendAddressSolicitResponse(const Coap::Message &aRequest, 661 ThreadStatusTlv::Status aResponseStatus, 662 const Router *aRouter, 663 const Ip6::MessageInfo &aMessageInfo); 664 void SendAddressRelease(void); 665 void SendAdvertisement(void); 666 Error SendLinkAccept(const RxInfo &aRxInfo, 667 Neighbor *aNeighbor, 668 const TlvList &aRequestedTlvList, 669 const RxChallenge &aChallenge); 670 void SendParentResponse(Child *aChild, const RxChallenge &aChallenge, bool aRoutersOnlyRequest); 671 Error SendChildIdResponse(Child &aChild); 672 Error SendChildUpdateRequest(Child &aChild); 673 void SendChildUpdateResponse(Child *aChild, 674 const Ip6::MessageInfo &aMessageInfo, 675 const TlvList &aTlvList, 676 const RxChallenge &aChallenge); 677 void SendDataResponse(const Ip6::Address &aDestination, 678 const TlvList &aTlvList, 679 uint16_t aDelay, 680 const Message *aRequestMessage = nullptr); 681 Error SendDiscoveryResponse(const Ip6::Address &aDestination, const Message &aDiscoverRequestMessage); 682 void SetStateRouter(uint16_t aRloc16); 683 void SetStateLeader(uint16_t aRloc16, LeaderStartMode aStartMode); 684 void SetStateRouterOrLeader(DeviceRole aRole, uint16_t aRloc16, LeaderStartMode aStartMode); 685 void StopLeader(void); 686 void SynchronizeChildNetworkData(void); 687 Error ProcessAddressRegistrationTlv(RxInfo &aRxInfo, Child &aChild); 688 Error UpdateChildAddresses(const Message &aMessage, uint16_t aOffset, uint16_t aLength, Child &aChild); 689 bool HasNeighborWithGoodLinkQuality(void) const; 690 #if OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE 691 void SignalDuaAddressEvent(const Child &aChild, const Ip6::Address &aOldDua) const; 692 #endif 693 694 static void HandleAddressSolicitResponse(void *aContext, 695 otMessage *aMessage, 696 const otMessageInfo *aMessageInfo, 697 Error aResult); 698 void HandleAddressSolicitResponse(Coap::Message *aMessage, const Ip6::MessageInfo *aMessageInfo, Error aResult); 699 700 template <Uri kUri> void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 701 702 void HandlePartitionChange(void); 703 704 void SetChildStateToValid(Child &aChild); 705 bool HasChildren(void); 706 void RemoveChildren(void); 707 bool ShouldDowngrade(uint8_t aNeighborId, const RouteTlv &aRouteTlv) const; 708 bool NeighborHasComparableConnectivity(const RouteTlv &aRouteTlv, uint8_t aNeighborId) const; 709 710 static void HandleAdvertiseTrickleTimer(TrickleTimer &aTimer); 711 void HandleAdvertiseTrickleTimer(void); 712 void HandleTimeTick(void); 713 714 TrickleTimer mAdvertiseTrickleTimer; 715 716 #if OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE 717 DeviceProperties mDeviceProperties; 718 #endif 719 720 ChildTable mChildTable; 721 RouterTable mRouterTable; 722 723 uint8_t mChallengeTimeout; 724 TxChallenge mChallenge; 725 726 uint16_t mNextChildId; 727 uint8_t mNetworkIdTimeout; 728 uint8_t mRouterUpgradeThreshold; 729 uint8_t mRouterDowngradeThreshold; 730 uint8_t mLeaderWeight; 731 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 732 uint32_t mPreferredLeaderPartitionId; ///< only for certification testing 733 bool mCcmEnabled : 1; 734 bool mThreadVersionCheckEnabled : 1; 735 #endif 736 bool mRouterEligible : 1; 737 bool mAddressSolicitPending : 1; 738 bool mAddressSolicitRejected : 1; 739 740 uint8_t mRouterId; 741 uint8_t mPreviousRouterId; 742 743 uint32_t mPreviousPartitionIdRouter; ///< The partition ID when last operating as a router 744 uint32_t mPreviousPartitionId; ///< The partition ID when last attached 745 uint8_t mPreviousPartitionRouterIdSequence; ///< The router ID sequence when last attached 746 uint8_t mPreviousPartitionIdTimeout; ///< The partition ID timeout when last attached 747 748 RouterRoleTransition mRouterRoleTransition; 749 750 uint8_t mChildRouterLinks; 751 752 int8_t mParentPriority; ///< The assigned parent priority value, -2 means not assigned. 753 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 754 uint8_t mMaxChildIpAddresses; 755 #endif 756 757 #if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE 758 MeshCoP::SteeringData mSteeringData; 759 #endif 760 761 Ip6::Netif::UnicastAddress mLeaderAloc; 762 763 Callback<otThreadDiscoveryRequestCallback> mDiscoveryRequestCallback; 764 }; 765 766 DeclareTmfHandler(MleRouter, kUriAddressSolicit); 767 DeclareTmfHandler(MleRouter, kUriAddressRelease); 768 769 #endif // OPENTHREAD_FTD 770 771 #if OPENTHREAD_MTD 772 773 typedef Mle MleRouter; 774 775 #endif 776 777 } // namespace Mle 778 779 /** 780 * @} 781 */ 782 783 } // namespace ot 784 785 #endif // MLE_ROUTER_HPP_ 786