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. 269 * 270 */ GetRouterSelectionJitter(void) const271 uint8_t GetRouterSelectionJitter(void) const { return mRouterSelectionJitter; } 272 273 /** 274 * Sets the ROUTER_SELECTION_JITTER value. 275 * 276 * @returns The ROUTER_SELECTION_JITTER value. 277 * 278 */ 279 Error SetRouterSelectionJitter(uint8_t aRouterJitter); 280 281 /** 282 * Returns the current router selection jitter timeout value. 283 * 284 * @returns The current router selection jitter timeout value. 285 * 286 */ GetRouterSelectionJitterTimeout(void) const287 uint8_t GetRouterSelectionJitterTimeout(void) const { return mRouterSelectionJitterTimeout; } 288 289 /** 290 * Returns the ROUTER_UPGRADE_THRESHOLD value. 291 * 292 * @returns The ROUTER_UPGRADE_THRESHOLD value. 293 * 294 */ GetRouterUpgradeThreshold(void) const295 uint8_t GetRouterUpgradeThreshold(void) const { return mRouterUpgradeThreshold; } 296 297 /** 298 * Sets the ROUTER_UPGRADE_THRESHOLD value. 299 * 300 * @param[in] aThreshold The ROUTER_UPGRADE_THRESHOLD value. 301 * 302 */ SetRouterUpgradeThreshold(uint8_t aThreshold)303 void SetRouterUpgradeThreshold(uint8_t aThreshold) { mRouterUpgradeThreshold = aThreshold; } 304 305 /** 306 * Returns the ROUTER_DOWNGRADE_THRESHOLD value. 307 * 308 * @returns The ROUTER_DOWNGRADE_THRESHOLD value. 309 * 310 */ GetRouterDowngradeThreshold(void) const311 uint8_t GetRouterDowngradeThreshold(void) const { return mRouterDowngradeThreshold; } 312 313 /** 314 * Sets the ROUTER_DOWNGRADE_THRESHOLD value. 315 * 316 * @param[in] aThreshold The ROUTER_DOWNGRADE_THRESHOLD value. 317 * 318 */ SetRouterDowngradeThreshold(uint8_t aThreshold)319 void SetRouterDowngradeThreshold(uint8_t aThreshold) { mRouterDowngradeThreshold = aThreshold; } 320 321 /** 322 * Returns the MLE_CHILD_ROUTER_LINKS value. 323 * 324 * @returns The MLE_CHILD_ROUTER_LINKS value. 325 * 326 */ GetChildRouterLinks(void) const327 uint8_t GetChildRouterLinks(void) const { return mChildRouterLinks; } 328 329 /** 330 * Sets the MLE_CHILD_ROUTER_LINKS value. 331 * 332 * @param[in] aChildRouterLinks The MLE_CHILD_ROUTER_LINKS value. 333 * 334 * @retval kErrorNone Successfully set the value. 335 * @retval kErrorInvalidState Thread protocols are enabled. 336 */ 337 Error SetChildRouterLinks(uint8_t aChildRouterLinks); 338 339 /** 340 * Returns if the REED is expected to become Router soon. 341 * 342 * @retval TRUE If the REED is going to become a Router soon. 343 * @retval FALSE If the REED is not going to become a Router soon. 344 * 345 */ 346 bool IsExpectedToBecomeRouterSoon(void) const; 347 348 /** 349 * Removes a link to a neighbor. 350 * 351 * @param[in] aNeighbor A reference to the neighbor object. 352 * 353 */ 354 void RemoveNeighbor(Neighbor &aNeighbor); 355 356 /** 357 * Invalidates a direct link to a neighboring router (due to failed link-layer acks). 358 * 359 * @param[in] aRouter A reference to the router object. 360 * 361 */ 362 void RemoveRouterLink(Router &aRouter); 363 364 /** 365 * Indicates whether or not the RLOC16 is an MTD child of this device. 366 * 367 * @param[in] aRloc16 The RLOC16. 368 * 369 * @retval TRUE if @p aRloc16 is an MTD child of this device. 370 * @retval FALSE if @p aRloc16 is not an MTD child of this device. 371 * 372 */ 373 bool IsMinimalChild(uint16_t aRloc16); 374 375 /** 376 * Indicates whether or not the given Thread partition attributes are preferred. 377 * 378 * @param[in] aSingletonA Whether or not the Thread Partition A has a single router. 379 * @param[in] aLeaderDataA A reference to Thread Partition A's Leader Data. 380 * @param[in] aSingletonB Whether or not the Thread Partition B has a single router. 381 * @param[in] aLeaderDataB A reference to Thread Partition B's Leader Data. 382 * 383 * @retval 1 If partition A is preferred. 384 * @retval 0 If partition A and B have equal preference. 385 * @retval -1 If partition B is preferred. 386 * 387 */ 388 static int ComparePartitions(bool aSingletonA, 389 const LeaderData &aLeaderDataA, 390 bool aSingletonB, 391 const LeaderData &aLeaderDataB); 392 393 /** 394 * Checks if the destination is reachable. 395 * 396 * @param[in] aMeshDest The RLOC16 of the destination. 397 * @param[in] aIp6Header A reference to the IPv6 header of the message. 398 * 399 * @retval kErrorNone The destination is reachable. 400 * @retval kErrorNoRoute The destination is not reachable and the message should be dropped. 401 * 402 */ 403 Error CheckReachability(uint16_t aMeshDest, const Ip6::Header &aIp6Header); 404 405 /** 406 * Resolves 2-hop routing loops. 407 * 408 * @param[in] aSourceMac The RLOC16 of the previous hop. 409 * @param[in] aDestRloc16 The RLOC16 of the final destination. 410 * 411 */ 412 void ResolveRoutingLoops(uint16_t aSourceMac, uint16_t aDestRloc16); 413 414 /** 415 * Checks if a given Router ID has correct value. 416 * 417 * @param[in] aRouterId The Router ID value. 418 * 419 * @retval TRUE If @p aRouterId is in correct range [0..62]. 420 * @retval FALSE If @p aRouterId is not a valid Router ID. 421 * 422 */ IsRouterIdValid(uint8_t aRouterId)423 static bool IsRouterIdValid(uint8_t aRouterId) { return aRouterId <= kMaxRouterId; } 424 425 /** 426 * Fills an ConnectivityTlv. 427 * 428 * @param[out] aTlv A reference to the tlv to be filled. 429 * 430 */ 431 void FillConnectivityTlv(ConnectivityTlv &aTlv); 432 433 /** 434 * Generates an MLE Child Update Request message to be sent to the parent. 435 * 436 * @retval kErrorNone Successfully generated an MLE Child Update Request message. 437 * @retval kErrorNoBufs Insufficient buffers to generate the MLE Child Update Request message. 438 * 439 */ SendChildUpdateRequest(void)440 Error SendChildUpdateRequest(void) { return Mle::SendChildUpdateRequest(); } 441 442 Error SendLinkRequest(Neighbor *aNeighbor); 443 444 #if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE 445 /** 446 * Sets steering data out of band 447 * 448 * @param[in] aExtAddress Value used to set steering data 449 * All zeros clears steering data 450 * All 0xFFs sets steering data to 0xFF 451 * Anything else is used to compute the bloom filter 452 * 453 */ 454 void SetSteeringData(const Mac::ExtAddress *aExtAddress); 455 #endif 456 457 /** 458 * Gets the assigned parent priority. 459 * 460 * @returns The assigned parent priority value, -2 means not assigned. 461 * 462 */ GetAssignParentPriority(void) const463 int8_t GetAssignParentPriority(void) const { return mParentPriority; } 464 465 /** 466 * Sets the parent priority. 467 * 468 * @param[in] aParentPriority The parent priority value. 469 * 470 * @retval kErrorNone Successfully set the parent priority. 471 * @retval kErrorInvalidArgs If the parent priority value is not among 1, 0, -1 and -2. 472 * 473 */ 474 Error SetAssignParentPriority(int8_t aParentPriority); 475 476 /** 477 * Gets the longest MLE Timeout TLV for all active MTD children. 478 * 479 * @param[out] aTimeout A reference to where the information is placed. 480 * 481 * @retval kErrorNone Successfully get the max child timeout 482 * @retval kErrorInvalidState Not an active router 483 * @retval kErrorNotFound NO MTD child 484 * 485 */ 486 Error GetMaxChildTimeout(uint32_t &aTimeout) const; 487 488 /** 489 * Sets the callback that is called when processing an MLE Discovery Request message. 490 * 491 * @param[in] aCallback A pointer to a function that is called to deliver MLE Discovery Request data. 492 * @param[in] aContext A pointer to application-specific context. 493 * 494 */ SetDiscoveryRequestCallback(otThreadDiscoveryRequestCallback aCallback,void * aContext)495 void SetDiscoveryRequestCallback(otThreadDiscoveryRequestCallback aCallback, void *aContext) 496 { 497 mDiscoveryRequestCallback.Set(aCallback, aContext); 498 } 499 500 /** 501 * Resets the MLE Advertisement Trickle timer interval. 502 * 503 */ 504 void ResetAdvertiseInterval(void); 505 506 /** 507 * Updates the MLE Advertisement Trickle timer max interval (if timer is running). 508 * 509 * This is called when there is change in router table. 510 * 511 */ 512 void UpdateAdvertiseInterval(void); 513 514 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 515 /** 516 * Generates an MLE Time Synchronization message. 517 * 518 * @retval kErrorNone Successfully sent an MLE Time Synchronization message. 519 * @retval kErrorNoBufs Insufficient buffers to generate the MLE Time Synchronization message. 520 * 521 */ 522 Error SendTimeSync(void); 523 #endif 524 525 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE 526 /** 527 * Sets the delay before registering Backbone Router service. 528 * 529 * @param[in] aDelay The delay before registering Backbone Router service. 530 * 531 */ SetBackboneRouterRegistrationDelay(uint8_t aDelay)532 void SetBackboneRouterRegistrationDelay(uint8_t aDelay) { mBackboneRouterRegistrationDelay = aDelay; } 533 #endif 534 535 /** 536 * Gets the maximum number of IP addresses that each MTD child may register with this device as parent. 537 * 538 * @returns The maximum number of IP addresses that each MTD child may register with this device as parent. 539 * 540 */ 541 uint8_t GetMaxChildIpAddresses(void) const; 542 543 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 544 545 /** 546 * Sets/restores the maximum number of IP addresses that each MTD child may register with this 547 * device as parent. 548 * 549 * @param[in] aMaxIpAddresses The maximum number of IP addresses that each MTD child may register with this 550 * device as parent. 0 to clear the setting and restore the default. 551 * 552 * @retval kErrorNone Successfully set/cleared the number. 553 * @retval kErrorInvalidArgs If exceeds the allowed maximum number. 554 * 555 */ 556 Error SetMaxChildIpAddresses(uint8_t aMaxIpAddresses); 557 558 /** 559 * Sets whether the device was commissioned using CCM. 560 * 561 * @param[in] aEnabled TRUE if the device was commissioned using CCM, FALSE otherwise. 562 * 563 */ SetCcmEnabled(bool aEnabled)564 void SetCcmEnabled(bool aEnabled) { mCcmEnabled = aEnabled; } 565 566 /** 567 * Sets whether the Security Policy TLV version-threshold for routing (VR field) is enabled. 568 * 569 * @param[in] aEnabled TRUE to enable Security Policy TLV version-threshold for routing, FALSE otherwise. 570 * 571 */ SetThreadVersionCheckEnabled(bool aEnabled)572 void SetThreadVersionCheckEnabled(bool aEnabled) { mThreadVersionCheckEnabled = aEnabled; } 573 574 /** 575 * Gets the current Interval Max value used by Advertisement trickle timer. 576 * 577 * @returns The Interval Max of Advertisement trickle timer in milliseconds. 578 * 579 */ GetAdvertisementTrickleIntervalMax(void) const580 uint32_t GetAdvertisementTrickleIntervalMax(void) const { return mAdvertiseTrickleTimer.GetIntervalMax(); } 581 582 #endif // OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 583 584 private: 585 // Advertisement trickle timer constants - all times are in milliseconds. 586 static constexpr uint32_t kAdvIntervalMin = 1000; // I_MIN 587 static constexpr uint32_t kAdvIntervalNeighborMultiplier = 4000; // Multiplier for I_MAX per router neighbor 588 static constexpr uint32_t kAdvIntervalMaxLowerBound = 12000; // Lower bound for I_MAX 589 static constexpr uint32_t kAdvIntervalMaxUpperBound = 32000; // Upper bound for I_MAX 590 static constexpr uint32_t kReedAdvIntervalMin = 570000; 591 static constexpr uint32_t kReedAdvIntervalMax = 630000; 592 #if OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE 593 static constexpr uint32_t kAdvIntervalMaxLogRoutes = 5000; 594 #endif 595 596 static constexpr uint32_t kMaxNeighborAge = 100000; // Max neighbor age (in msec) 597 static constexpr uint32_t kMaxLeaderToRouterTimeout = 90000; // (in msec) 598 static constexpr uint8_t kMinDowngradeNeighbors = 7; 599 static constexpr uint8_t kNetworkIdTimeout = 120; // (in sec) 600 static constexpr uint8_t kRouterSelectionJitter = 120; // (in sec) 601 static constexpr uint8_t kRouterDowngradeThreshold = 23; 602 static constexpr uint8_t kRouterUpgradeThreshold = 16; 603 static constexpr uint16_t kDiscoveryMaxJitter = 250; // Max jitter delay Discovery Responses (in msec). 604 static constexpr uint16_t kChallengeTimeout = 2; // Challenge timeout (in sec). 605 static constexpr uint16_t kUnsolicitedDataResponseJitter = 500; // Max delay for unsol Data Response (in msec). 606 static constexpr uint8_t kLeaderDowngradeExtraDelay = 10; // Extra delay to downgrade leader (in sec). 607 static constexpr uint8_t kDefaultLeaderWeight = 64; 608 609 // Threshold to accept a router upgrade request with reason 610 // `kBorderRouterRequest` (number of BRs acting as router in 611 // Network Data). 612 static constexpr uint8_t kRouterUpgradeBorderRouterRequestThreshold = 2; 613 614 static constexpr uint8_t kLinkRequestMinMargin = OPENTHREAD_CONFIG_MLE_LINK_REQUEST_MARGIN_MIN; 615 static constexpr uint8_t kPartitionMergeMinMargin = OPENTHREAD_CONFIG_MLE_PARTITION_MERGE_MARGIN_MIN; 616 static constexpr uint8_t kChildRouterLinks = OPENTHREAD_CONFIG_MLE_CHILD_ROUTER_LINKS; 617 static constexpr uint8_t kMaxChildIpAddresses = OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD; 618 619 static constexpr uint8_t kMinCriticalChildrenCount = 6; 620 621 static constexpr uint16_t kChildSupervisionDefaultIntervalForOlderVersion = 622 OPENTHREAD_CONFIG_CHILD_SUPERVISION_OLDER_VERSION_CHILD_DEFAULT_INTERVAL; 623 624 static constexpr int8_t kParentPriorityHigh = 1; 625 static constexpr int8_t kParentPriorityMedium = 0; 626 static constexpr int8_t kParentPriorityLow = -1; 627 static constexpr int8_t kParentPriorityUnspecified = -2; 628 629 void HandleDetachStart(void); 630 void HandleChildStart(AttachMode aMode); 631 void HandleSecurityPolicyChanged(void); 632 void HandleLinkRequest(RxInfo &aRxInfo); 633 void HandleLinkAccept(RxInfo &aRxInfo); 634 Error HandleLinkAccept(RxInfo &aRxInfo, bool aRequest); 635 void HandleLinkAcceptAndRequest(RxInfo &aRxInfo); 636 Error HandleAdvertisement(RxInfo &aRxInfo, uint16_t aSourceAddress, const LeaderData &aLeaderData); 637 void HandleParentRequest(RxInfo &aRxInfo); 638 void HandleChildIdRequest(RxInfo &aRxInfo); 639 void HandleChildUpdateRequest(RxInfo &aRxInfo); 640 void HandleChildUpdateResponse(RxInfo &aRxInfo); 641 void HandleDataRequest(RxInfo &aRxInfo); 642 void HandleNetworkDataUpdateRouter(void); 643 void HandleDiscoveryRequest(RxInfo &aRxInfo); 644 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 645 void HandleTimeSync(RxInfo &aRxInfo); 646 #endif 647 648 Error ProcessRouteTlv(const RouteTlv &aRouteTlv, RxInfo &aRxInfo); 649 Error ReadAndProcessRouteTlvOnFed(RxInfo &aRxInfo, uint8_t aParentId); 650 651 void StopAdvertiseTrickleTimer(void); 652 uint32_t DetermineAdvertiseIntervalMax(void) const; 653 654 Error SendAddressSolicit(ThreadStatusTlv::Status aStatus); 655 void SendAddressSolicitResponse(const Coap::Message &aRequest, 656 ThreadStatusTlv::Status aResponseStatus, 657 const Router *aRouter, 658 const Ip6::MessageInfo &aMessageInfo); 659 void SendAddressRelease(void); 660 void SendAdvertisement(void); 661 Error SendLinkAccept(const Ip6::MessageInfo &aMessageInfo, 662 Neighbor *aNeighbor, 663 const TlvList &aRequestedTlvList, 664 const RxChallenge &aChallenge); 665 void SendParentResponse(Child *aChild, const RxChallenge &aChallenge, bool aRoutersOnlyRequest); 666 Error SendChildIdResponse(Child &aChild); 667 Error SendChildUpdateRequest(Child &aChild); 668 void SendChildUpdateResponse(Child *aChild, 669 const Ip6::MessageInfo &aMessageInfo, 670 const TlvList &aTlvList, 671 const RxChallenge &aChallenge); 672 void SendDataResponse(const Ip6::Address &aDestination, 673 const TlvList &aTlvList, 674 uint16_t aDelay, 675 const Message *aRequestMessage = nullptr); 676 Error SendDiscoveryResponse(const Ip6::Address &aDestination, const Message &aDiscoverRequestMessage); 677 void SetStateRouter(uint16_t aRloc16); 678 void SetStateLeader(uint16_t aRloc16, LeaderStartMode aStartMode); 679 void SetStateRouterOrLeader(DeviceRole aRole, uint16_t aRloc16, LeaderStartMode aStartMode); 680 void StopLeader(void); 681 void SynchronizeChildNetworkData(void); 682 Error ProcessAddressRegistrationTlv(RxInfo &aRxInfo, Child &aChild); 683 Error UpdateChildAddresses(const Message &aMessage, uint16_t aOffset, uint16_t aLength, Child &aChild); 684 bool HasNeighborWithGoodLinkQuality(void) const; 685 686 static void HandleAddressSolicitResponse(void *aContext, 687 otMessage *aMessage, 688 const otMessageInfo *aMessageInfo, 689 Error aResult); 690 void HandleAddressSolicitResponse(Coap::Message *aMessage, const Ip6::MessageInfo *aMessageInfo, Error aResult); 691 692 template <Uri kUri> void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 693 694 void HandlePartitionChange(void); 695 696 void SetChildStateToValid(Child &aChild); 697 bool HasChildren(void); 698 void RemoveChildren(void); 699 bool ShouldDowngrade(uint8_t aNeighborId, const RouteTlv &aRouteTlv) const; 700 bool NeighborHasComparableConnectivity(const RouteTlv &aRouteTlv, uint8_t aNeighborId) const; 701 702 static void HandleAdvertiseTrickleTimer(TrickleTimer &aTimer); 703 void HandleAdvertiseTrickleTimer(void); 704 void HandleTimeTick(void); 705 706 TrickleTimer mAdvertiseTrickleTimer; 707 708 #if OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE 709 DeviceProperties mDeviceProperties; 710 #endif 711 712 ChildTable mChildTable; 713 RouterTable mRouterTable; 714 715 uint8_t mChallengeTimeout; 716 TxChallenge mChallenge; 717 718 uint16_t mNextChildId; 719 uint8_t mNetworkIdTimeout; 720 uint8_t mRouterUpgradeThreshold; 721 uint8_t mRouterDowngradeThreshold; 722 uint8_t mLeaderWeight; 723 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 724 uint32_t mPreferredLeaderPartitionId; ///< only for certification testing 725 bool mCcmEnabled : 1; 726 bool mThreadVersionCheckEnabled : 1; 727 #endif 728 bool mRouterEligible : 1; 729 bool mAddressSolicitPending : 1; 730 bool mAddressSolicitRejected : 1; 731 732 uint8_t mRouterId; 733 uint8_t mPreviousRouterId; 734 735 uint32_t mPreviousPartitionIdRouter; ///< The partition ID when last operating as a router 736 uint32_t mPreviousPartitionId; ///< The partition ID when last attached 737 uint8_t mPreviousPartitionRouterIdSequence; ///< The router ID sequence when last attached 738 uint8_t mPreviousPartitionIdTimeout; ///< The partition ID timeout when last attached 739 740 uint8_t mRouterSelectionJitter; ///< The variable to save the assigned jitter value. 741 uint8_t mRouterSelectionJitterTimeout; ///< The Timeout prior to request/release Router ID. 742 743 uint8_t mChildRouterLinks; 744 745 int8_t mParentPriority; ///< The assigned parent priority value, -2 means not assigned. 746 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE 747 uint8_t mBackboneRouterRegistrationDelay; ///< Delay before registering Backbone Router service. 748 #endif 749 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 750 uint8_t mMaxChildIpAddresses; 751 #endif 752 753 #if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE 754 MeshCoP::SteeringData mSteeringData; 755 #endif 756 757 Callback<otThreadDiscoveryRequestCallback> mDiscoveryRequestCallback; 758 }; 759 760 DeclareTmfHandler(MleRouter, kUriAddressSolicit); 761 DeclareTmfHandler(MleRouter, kUriAddressRelease); 762 763 #endif // OPENTHREAD_FTD 764 765 #if OPENTHREAD_MTD 766 767 class MleRouter : public Mle 768 { 769 friend class Mle; 770 friend class ot::Instance; 771 772 public: MleRouter(Instance & aInstance)773 explicit MleRouter(Instance &aInstance) 774 : Mle(aInstance) 775 { 776 } 777 IsSingleton(void) const778 bool IsSingleton(void) const { return false; } 779 GetNextHop(uint16_t aDestination) const780 uint16_t GetNextHop(uint16_t aDestination) const { return Mle::GetNextHop(aDestination); } 781 RemoveNeighbor(Neighbor &)782 Error RemoveNeighbor(Neighbor &) { return BecomeDetached(); } RemoveRouterLink(Router &)783 void RemoveRouterLink(Router &) { IgnoreError(BecomeDetached()); } 784 IsRouterIdValid(uint8_t aRouterId)785 static bool IsRouterIdValid(uint8_t aRouterId) { return aRouterId <= kMaxRouterId; } 786 SendChildUpdateRequest(void)787 Error SendChildUpdateRequest(void) { return Mle::SendChildUpdateRequest(); } 788 CheckReachability(uint16_t aMeshDest,const Ip6::Header & aIp6Header)789 Error CheckReachability(uint16_t aMeshDest, const Ip6::Header &aIp6Header) 790 { 791 return Mle::CheckReachability(aMeshDest, aIp6Header); 792 } 793 }; 794 795 #endif // OPENTHREAD_MTD 796 797 } // namespace Mle 798 799 /** 800 * @} 801 */ 802 803 } // namespace ot 804 805 #endif // MLE_ROUTER_HPP_ 806