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_table.hpp" 51 #include "thread/mle.hpp" 52 #include "thread/mle_tlvs.hpp" 53 #include "thread/router_table.hpp" 54 #include "thread/thread_tlvs.hpp" 55 #include "thread/tmf.hpp" 56 #include "thread/topology.hpp" 57 58 namespace ot { 59 namespace Mle { 60 61 /** 62 * @addtogroup core-mle-router 63 * 64 * @brief 65 * This module includes definitions for MLE functionality required by the Thread Router and Leader roles. 66 * 67 * @{ 68 */ 69 70 #if OPENTHREAD_FTD 71 72 /** 73 * This class implements MLE functionality required by the Thread Router and Leader roles. 74 * 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 * This constructor initializes the object. 86 * 87 * @param[in] aInstance A reference to the OpenThread instance. 88 * 89 */ 90 explicit MleRouter(Instance &aInstance); 91 92 /** 93 * This method indicates whether or not the device is router-eligible. 94 * 95 * @retval true If device is router-eligible. 96 * @retval false If device is not router-eligible. 97 * 98 */ 99 bool IsRouterEligible(void) const; 100 101 /** 102 * This method sets whether or not the device is router-eligible. 103 * 104 * If @p aEligible is false and the device is currently operating as a router, this call will cause the device to 105 * detach and attempt to reattach as a child. 106 * 107 * @param[in] aEligible TRUE to configure device router-eligible, FALSE otherwise. 108 * 109 * @retval kErrorNone Successfully set the router-eligible configuration. 110 * @retval kErrorNotCapable The device is not capable of becoming a router. 111 * 112 */ 113 Error SetRouterEligible(bool aEligible); 114 115 /** 116 * This method indicates whether a node is the only router on the network. 117 * 118 * @retval TRUE It is the only router in the network. 119 * @retval FALSE It is a child or is not a single router in the network. 120 * 121 */ 122 bool IsSingleton(void) const; 123 124 /** 125 * This method generates an Address Solicit request for a Router ID. 126 * 127 * @param[in] aStatus The reason for requesting a Router ID. 128 * 129 * @retval kErrorNone Successfully generated an Address Solicit message. 130 * @retval kErrorNotCapable Device is not capable of becoming a router 131 * @retval kErrorInvalidState Thread is not enabled 132 * 133 */ 134 Error BecomeRouter(ThreadStatusTlv::Status aStatus); 135 136 /** 137 * This method causes the Thread interface to become a Leader and start a new partition. 138 * 139 * @retval kErrorNone Successfully become a Leader and started a new partition. 140 * @retval kErrorNotCapable Device is not capable of becoming a leader 141 * @retval kErrorInvalidState Thread is not enabled 142 * 143 */ 144 Error BecomeLeader(void); 145 146 /** 147 * This method gets the device properties which are used to determine the Leader Weight. 148 * 149 * @returns The current device properties. 150 * 151 */ GetDeviceProperties(void) const152 const DeviceProperties &GetDeviceProperties(void) const { return mDeviceProperties; } 153 154 /** 155 * This method sets the device properties which are then used to determine and set the Leader Weight. 156 * 157 * @param[in] aDeviceProperties The device properties. 158 * 159 */ 160 void SetDeviceProperties(const DeviceProperties &aDeviceProperties); 161 162 /** 163 * This method returns the Leader Weighting value for this Thread interface. 164 * 165 * @returns The Leader Weighting value for this Thread interface. 166 * 167 */ GetLeaderWeight(void) const168 uint8_t GetLeaderWeight(void) const { return mLeaderWeight; } 169 170 /** 171 * This method sets the Leader Weighting value for this Thread interface. 172 * 173 * This method directly sets the Leader Weight to the new value replacing its previous value (which may have been 174 * determined from a previous call to `SetDeviceProperties()`). 175 * 176 * @param[in] aWeight The Leader Weighting value. 177 * 178 */ SetLeaderWeight(uint8_t aWeight)179 void SetLeaderWeight(uint8_t aWeight) { mLeaderWeight = aWeight; } 180 181 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 182 183 /** 184 * This method returns the preferred Partition Id when operating in the Leader role for certification testing. 185 * 186 * @returns The preferred Partition Id value. 187 * 188 */ GetPreferredLeaderPartitionId(void) const189 uint32_t GetPreferredLeaderPartitionId(void) const { return mPreferredLeaderPartitionId; } 190 191 /** 192 * This method sets the preferred Partition Id when operating in the Leader role for certification testing. 193 * 194 * @param[in] aPartitionId The preferred Leader Partition Id. 195 * 196 */ SetPreferredLeaderPartitionId(uint32_t aPartitionId)197 void SetPreferredLeaderPartitionId(uint32_t aPartitionId) { mPreferredLeaderPartitionId = aPartitionId; } 198 #endif 199 200 /** 201 * This method sets the preferred Router Id. Upon becoming a router/leader the node 202 * attempts to use this Router Id. If the preferred Router Id is not set or if it 203 * can not be used, a randomly generated router Id is picked. 204 * This property can be set when he device role is detached or disabled. 205 * 206 * @param[in] aRouterId The preferred Router Id. 207 * 208 * @retval kErrorNone Successfully set the preferred Router Id. 209 * @retval kErrorInvalidState Could not set (role is other than detached and disabled) 210 * 211 */ 212 Error SetPreferredRouterId(uint8_t aRouterId); 213 214 /** 215 * This method gets the Partition Id which the device joined successfully once. 216 * 217 */ GetPreviousPartitionId(void) const218 uint32_t GetPreviousPartitionId(void) const { return mPreviousPartitionId; } 219 220 /** 221 * This method sets the Partition Id which the device joins successfully. 222 * 223 * @param[in] aPartitionId The Partition Id. 224 * 225 */ SetPreviousPartitionId(uint32_t aPartitionId)226 void SetPreviousPartitionId(uint32_t aPartitionId) { mPreviousPartitionId = aPartitionId; } 227 228 /** 229 * This method sets the Router Id. 230 * 231 * @param[in] aRouterId The Router Id. 232 * 233 */ 234 void SetRouterId(uint8_t aRouterId); 235 236 /** 237 * This method returns the next hop towards an RLOC16 destination. 238 * 239 * @param[in] aDestination The RLOC16 of the destination. 240 * 241 * @returns A RLOC16 of the next hop if a route is known, kInvalidRloc16 otherwise. 242 * 243 */ GetNextHop(uint16_t aDestination)244 uint16_t GetNextHop(uint16_t aDestination) { return mRouterTable.GetNextHop(aDestination); } 245 246 /** 247 * This method returns the NETWORK_ID_TIMEOUT value. 248 * 249 * @returns The NETWORK_ID_TIMEOUT value. 250 * 251 */ GetNetworkIdTimeout(void) const252 uint8_t GetNetworkIdTimeout(void) const { return mNetworkIdTimeout; } 253 254 /** 255 * This method sets the NETWORK_ID_TIMEOUT value. 256 * 257 * @param[in] aTimeout The NETWORK_ID_TIMEOUT value. 258 * 259 */ SetNetworkIdTimeout(uint8_t aTimeout)260 void SetNetworkIdTimeout(uint8_t aTimeout) { mNetworkIdTimeout = aTimeout; } 261 262 /** 263 * This method returns the ROUTER_SELECTION_JITTER value. 264 * 265 * @returns The ROUTER_SELECTION_JITTER value. 266 * 267 */ GetRouterSelectionJitter(void) const268 uint8_t GetRouterSelectionJitter(void) const { return mRouterSelectionJitter; } 269 270 /** 271 * This method sets the ROUTER_SELECTION_JITTER value. 272 * 273 * @returns The ROUTER_SELECTION_JITTER value. 274 * 275 */ 276 Error SetRouterSelectionJitter(uint8_t aRouterJitter); 277 278 /** 279 * This method returns the current router selection jitter timeout value. 280 * 281 * @returns The current router selection jitter timeout value. 282 * 283 */ GetRouterSelectionJitterTimeout(void) const284 uint8_t GetRouterSelectionJitterTimeout(void) const { return mRouterSelectionJitterTimeout; } 285 286 /** 287 * This method returns the ROUTER_UPGRADE_THRESHOLD value. 288 * 289 * @returns The ROUTER_UPGRADE_THRESHOLD value. 290 * 291 */ GetRouterUpgradeThreshold(void) const292 uint8_t GetRouterUpgradeThreshold(void) const { return mRouterUpgradeThreshold; } 293 294 /** 295 * This method sets the ROUTER_UPGRADE_THRESHOLD value. 296 * 297 * @param[in] aThreshold The ROUTER_UPGRADE_THRESHOLD value. 298 * 299 */ SetRouterUpgradeThreshold(uint8_t aThreshold)300 void SetRouterUpgradeThreshold(uint8_t aThreshold) { mRouterUpgradeThreshold = aThreshold; } 301 302 /** 303 * This method returns the ROUTER_DOWNGRADE_THRESHOLD value. 304 * 305 * @returns The ROUTER_DOWNGRADE_THRESHOLD value. 306 * 307 */ GetRouterDowngradeThreshold(void) const308 uint8_t GetRouterDowngradeThreshold(void) const { return mRouterDowngradeThreshold; } 309 310 /** 311 * This method sets the ROUTER_DOWNGRADE_THRESHOLD value. 312 * 313 * @param[in] aThreshold The ROUTER_DOWNGRADE_THRESHOLD value. 314 * 315 */ SetRouterDowngradeThreshold(uint8_t aThreshold)316 void SetRouterDowngradeThreshold(uint8_t aThreshold) { mRouterDowngradeThreshold = aThreshold; } 317 318 /** 319 * This method returns the MLE_CHILD_ROUTER_LINKS value. 320 * 321 * @returns The MLE_CHILD_ROUTER_LINKS value. 322 * 323 */ GetChildRouterLinks(void) const324 uint8_t GetChildRouterLinks(void) const { return mChildRouterLinks; } 325 326 /** 327 * This method sets the MLE_CHILD_ROUTER_LINKS value. 328 * 329 * @param[in] aChildRouterLinks The MLE_CHILD_ROUTER_LINKS value. 330 * 331 * @retval kErrorNone Successfully set the value. 332 * @retval kErrorInvalidState Thread protocols are enabled. 333 */ 334 Error SetChildRouterLinks(uint8_t aChildRouterLinks); 335 336 /** 337 * This method returns if the REED is expected to become Router soon. 338 * 339 * @retval TRUE If the REED is going to become a Router soon. 340 * @retval FALSE If the REED is not going to become a Router soon. 341 * 342 */ 343 bool IsExpectedToBecomeRouterSoon(void) const; 344 345 /** 346 * This method removes a link to a neighbor. 347 * 348 * @param[in] aNeighbor A reference to the neighbor object. 349 * 350 */ 351 void RemoveNeighbor(Neighbor &aNeighbor); 352 353 /** 354 * This method invalidates a direct link to a neighboring router (due to failed link-layer acks). 355 * 356 * @param[in] aRouter A reference to the router object. 357 * 358 */ 359 void RemoveRouterLink(Router &aRouter); 360 361 /** 362 * This method indicates whether or not the RLOC16 is an MTD child of this device. 363 * 364 * @param[in] aRloc16 The RLOC16. 365 * 366 * @retval TRUE if @p aRloc16 is an MTD child of this device. 367 * @retval FALSE if @p aRloc16 is not an MTD child of this device. 368 * 369 */ 370 bool IsMinimalChild(uint16_t aRloc16); 371 372 /** 373 * This method indicates whether or not the given Thread partition attributes are preferred. 374 * 375 * @param[in] aSingletonA Whether or not the Thread Partition A has a single router. 376 * @param[in] aLeaderDataA A reference to Thread Partition A's Leader Data. 377 * @param[in] aSingletonB Whether or not the Thread Partition B has a single router. 378 * @param[in] aLeaderDataB A reference to Thread Partition B's Leader Data. 379 * 380 * @retval 1 If partition A is preferred. 381 * @retval 0 If partition A and B have equal preference. 382 * @retval -1 If partition B is preferred. 383 * 384 */ 385 static int ComparePartitions(bool aSingletonA, 386 const LeaderData &aLeaderDataA, 387 bool aSingletonB, 388 const LeaderData &aLeaderDataB); 389 390 /** 391 * This method checks if the destination is reachable. 392 * 393 * @param[in] aMeshDest The RLOC16 of the destination. 394 * @param[in] aIp6Header A reference to the IPv6 header of the message. 395 * 396 * @retval kErrorNone The destination is reachable. 397 * @retval kErrorNoRoute The destination is not reachable and the message should be dropped. 398 * 399 */ 400 Error CheckReachability(uint16_t aMeshDest, const Ip6::Header &aIp6Header); 401 402 /** 403 * This method resolves 2-hop routing loops. 404 * 405 * @param[in] aSourceMac The RLOC16 of the previous hop. 406 * @param[in] aDestRloc16 The RLOC16 of the final destination. 407 * 408 */ 409 void ResolveRoutingLoops(uint16_t aSourceMac, uint16_t aDestRloc16); 410 411 /** 412 * This method checks if a given Router ID has correct value. 413 * 414 * @param[in] aRouterId The Router ID value. 415 * 416 * @retval TRUE If @p aRouterId is in correct range [0..62]. 417 * @retval FALSE If @p aRouterId is not a valid Router ID. 418 * 419 */ IsRouterIdValid(uint8_t aRouterId)420 static bool IsRouterIdValid(uint8_t aRouterId) { return aRouterId <= kMaxRouterId; } 421 422 /** 423 * This method fills an ConnectivityTlv. 424 * 425 * @param[out] aTlv A reference to the tlv to be filled. 426 * 427 */ 428 void FillConnectivityTlv(ConnectivityTlv &aTlv); 429 430 /** 431 * This method generates an MLE Child Update Request message to be sent to the parent. 432 * 433 * @retval kErrorNone Successfully generated an MLE Child Update Request message. 434 * @retval kErrorNoBufs Insufficient buffers to generate the MLE Child Update Request message. 435 * 436 */ SendChildUpdateRequest(void)437 Error SendChildUpdateRequest(void) { return Mle::SendChildUpdateRequest(); } 438 439 Error SendLinkRequest(Neighbor *aNeighbor); 440 441 #if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE 442 /** 443 * This method sets steering data out of band 444 * 445 * @param[in] aExtAddress Value used to set steering data 446 * All zeros clears steering data 447 * All 0xFFs sets steering data to 0xFF 448 * Anything else is used to compute the bloom filter 449 * 450 */ 451 void SetSteeringData(const Mac::ExtAddress *aExtAddress); 452 #endif 453 454 /** 455 * This method gets the assigned parent priority. 456 * 457 * @returns The assigned parent priority value, -2 means not assigned. 458 * 459 */ GetAssignParentPriority(void) const460 int8_t GetAssignParentPriority(void) const { return mParentPriority; } 461 462 /** 463 * This method sets the parent priority. 464 * 465 * @param[in] aParentPriority The parent priority value. 466 * 467 * @retval kErrorNone Successfully set the parent priority. 468 * @retval kErrorInvalidArgs If the parent priority value is not among 1, 0, -1 and -2. 469 * 470 */ 471 Error SetAssignParentPriority(int8_t aParentPriority); 472 473 /** 474 * This method gets the longest MLE Timeout TLV for all active MTD children. 475 * 476 * @param[out] aTimeout A reference to where the information is placed. 477 * 478 * @retval kErrorNone Successfully get the max child timeout 479 * @retval kErrorInvalidState Not an active router 480 * @retval kErrorNotFound NO MTD child 481 * 482 */ 483 Error GetMaxChildTimeout(uint32_t &aTimeout) const; 484 485 /** 486 * This function sets the callback that is called when processing an MLE Discovery Request message. 487 * 488 * @param[in] aCallback A pointer to a function that is called to deliver MLE Discovery Request data. 489 * @param[in] aContext A pointer to application-specific context. 490 * 491 */ SetDiscoveryRequestCallback(otThreadDiscoveryRequestCallback aCallback,void * aContext)492 void SetDiscoveryRequestCallback(otThreadDiscoveryRequestCallback aCallback, void *aContext) 493 { 494 mDiscoveryRequestCallback.Set(aCallback, aContext); 495 } 496 497 /** 498 * This method resets the MLE Advertisement Trickle timer interval. 499 * 500 */ 501 void ResetAdvertiseInterval(void); 502 503 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 504 /** 505 * This method generates an MLE Time Synchronization message. 506 * 507 * @retval kErrorNone Successfully sent an MLE Time Synchronization message. 508 * @retval kErrorNoBufs Insufficient buffers to generate the MLE Time Synchronization message. 509 * 510 */ 511 Error SendTimeSync(void); 512 #endif 513 514 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE 515 /** 516 * This method sets the delay before registering Backbone Router service. 517 * 518 * @param[in] aDelay The delay before registering Backbone Router service. 519 * 520 */ SetBackboneRouterRegistrationDelay(uint8_t aDelay)521 void SetBackboneRouterRegistrationDelay(uint8_t aDelay) { mBackboneRouterRegistrationDelay = aDelay; } 522 #endif 523 524 /** 525 * This method 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 * This method sets/restores the maximum number of IP addresses that each MTD child may register with this 535 * device as parent. 536 * 537 * @param[in] aMaxIpAddresses The maximum number of IP addresses that each MTD child may register with this 538 * device as parent. 0 to clear the setting and restore the default. 539 * 540 * @retval kErrorNone Successfully set/cleared the number. 541 * @retval kErrorInvalidArgs If exceeds the allowed maximum number. 542 * 543 */ 544 Error SetMaxChildIpAddresses(uint8_t aMaxIpAddresses); 545 546 /** 547 * This method sets whether the device was commissioned using CCM. 548 * 549 * @param[in] aEnabled TRUE if the device was commissioned using CCM, FALSE otherwise. 550 * 551 */ SetCcmEnabled(bool aEnabled)552 void SetCcmEnabled(bool aEnabled) { mCcmEnabled = aEnabled; } 553 554 /** 555 * This function sets whether the Security Policy TLV version-threshold for routing (VR field) is enabled. 556 * 557 * @param[in] aEnabled TRUE to enable Security Policy TLV version-threshold for routing, FALSE otherwise. 558 * 559 */ SetThreadVersionCheckEnabled(bool aEnabled)560 void SetThreadVersionCheckEnabled(bool aEnabled) { mThreadVersionCheckEnabled = aEnabled; } 561 #endif 562 563 private: 564 static constexpr uint16_t kDiscoveryMaxJitter = 250; // Max jitter delay Discovery Responses (in msec). 565 static constexpr uint16_t kChallengeTimeout = 2; // Challenge timeout (in sec). 566 static constexpr uint16_t kUnsolicitedDataResponseJitter = 500; // Max delay for unsol Data Response (in msec). 567 568 // Threshold to accept a router upgrade request with reason 569 // `kBorderRouterRequest` (number of BRs acting as router in 570 // Network Data). 571 static constexpr uint8_t kRouterUpgradeBorderRouterRequestThreshold = 2; 572 573 static constexpr uint8_t kLinkRequestMinMargin = OPENTHREAD_CONFIG_MLE_LINK_REQUEST_MARGIN_MIN; 574 static constexpr uint8_t kPartitionMergeMinMargin = OPENTHREAD_CONFIG_MLE_PARTITION_MERGE_MARGIN_MIN; 575 static constexpr uint8_t kChildRouterLinks = OPENTHREAD_CONFIG_MLE_CHILD_ROUTER_LINKS; 576 static constexpr uint8_t kMaxChildIpAddresses = OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD; 577 578 static constexpr uint8_t kMinCriticalChildrenCount = 6; 579 580 static constexpr uint16_t kChildSupervisionDefaultIntervalForOlderVersion = 581 OPENTHREAD_CONFIG_CHILD_SUPERVISION_OLDER_VERSION_CHILD_DEFAULT_INTERVAL; 582 583 void HandleDetachStart(void); 584 void HandleChildStart(AttachMode aMode); 585 void HandleLinkRequest(RxInfo &aRxInfo); 586 void HandleLinkAccept(RxInfo &aRxInfo); 587 Error HandleLinkAccept(RxInfo &aRxInfo, bool aRequest); 588 void HandleLinkAcceptAndRequest(RxInfo &aRxInfo); 589 Error HandleAdvertisement(RxInfo &aRxInfo, uint16_t aSourceAddress, const LeaderData &aLeaderData); 590 void HandleParentRequest(RxInfo &aRxInfo); 591 void HandleChildIdRequest(RxInfo &aRxInfo); 592 void HandleChildUpdateRequest(RxInfo &aRxInfo); 593 void HandleChildUpdateResponse(RxInfo &aRxInfo); 594 void HandleDataRequest(RxInfo &aRxInfo); 595 void HandleNetworkDataUpdateRouter(void); 596 void HandleDiscoveryRequest(RxInfo &aRxInfo); 597 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 598 void HandleTimeSync(RxInfo &aRxInfo); 599 #endif 600 601 Error ProcessRouteTlv(const RouteTlv &aRouteTlv, RxInfo &aRxInfo); 602 Error ReadAndProcessRouteTlvOnFed(RxInfo &aRxInfo, uint8_t aParentId); 603 604 void StopAdvertiseTrickleTimer(void); 605 Error SendAddressSolicit(ThreadStatusTlv::Status aStatus); 606 void SendAddressSolicitResponse(const Coap::Message &aRequest, 607 ThreadStatusTlv::Status aResponseStatus, 608 const Router *aRouter, 609 const Ip6::MessageInfo &aMessageInfo); 610 void SendAddressRelease(void); 611 void SendAdvertisement(void); 612 Error SendLinkAccept(const Ip6::MessageInfo &aMessageInfo, 613 Neighbor *aNeighbor, 614 const TlvList &aRequestedTlvList, 615 const Challenge &aChallenge); 616 void SendParentResponse(Child *aChild, const Challenge &aChallenge, bool aRoutersOnlyRequest); 617 Error SendChildIdResponse(Child &aChild); 618 Error SendChildUpdateRequest(Child &aChild); 619 void SendChildUpdateResponse(Child *aChild, 620 const Ip6::MessageInfo &aMessageInfo, 621 const TlvList &aTlvList, 622 const Challenge &aChallenge); 623 void SendDataResponse(const Ip6::Address &aDestination, 624 const TlvList &aTlvList, 625 uint16_t aDelay, 626 const Message *aRequestMessage = nullptr); 627 Error SendDiscoveryResponse(const Ip6::Address &aDestination, const Message &aDiscoverRequestMessage); 628 void SetStateRouter(uint16_t aRloc16); 629 void SetStateLeader(uint16_t aRloc16, LeaderStartMode aStartMode); 630 void SetStateRouterOrLeader(DeviceRole aRole, uint16_t aRloc16, LeaderStartMode aStartMode); 631 void StopLeader(void); 632 void SynchronizeChildNetworkData(void); 633 Error ProcessAddressRegistrationTlv(RxInfo &aRxInfo, Child &aChild); 634 Error UpdateChildAddresses(const Message &aMessage, uint16_t aOffset, uint16_t aLength, Child &aChild); 635 bool HasNeighborWithGoodLinkQuality(void) const; 636 637 static void HandleAddressSolicitResponse(void *aContext, 638 otMessage *aMessage, 639 const otMessageInfo *aMessageInfo, 640 Error aResult); 641 void HandleAddressSolicitResponse(Coap::Message *aMessage, const Ip6::MessageInfo *aMessageInfo, Error aResult); 642 643 template <Uri kUri> void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 644 645 void HandlePartitionChange(void); 646 647 void SetChildStateToValid(Child &aChild); 648 bool HasChildren(void); 649 void RemoveChildren(void); 650 bool ShouldDowngrade(uint8_t aNeighborId, const RouteTlv &aRouteTlv) const; 651 bool NeighborHasComparableConnectivity(const RouteTlv &aRouteTlv, uint8_t aNeighborId) const; 652 653 static void HandleAdvertiseTrickleTimer(TrickleTimer &aTimer); 654 void HandleAdvertiseTrickleTimer(void); 655 void HandleTimeTick(void); 656 657 TrickleTimer mAdvertiseTrickleTimer; 658 659 DeviceProperties mDeviceProperties; 660 661 ChildTable mChildTable; 662 RouterTable mRouterTable; 663 664 uint8_t mChallengeTimeout; 665 Challenge mChallenge; 666 667 uint16_t mNextChildId; 668 uint8_t mNetworkIdTimeout; 669 uint8_t mRouterUpgradeThreshold; 670 uint8_t mRouterDowngradeThreshold; 671 uint8_t mLeaderWeight; 672 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 673 uint32_t mPreferredLeaderPartitionId; ///< only for certification testing 674 bool mCcmEnabled : 1; 675 bool mThreadVersionCheckEnabled : 1; 676 #endif 677 bool mRouterEligible : 1; 678 bool mAddressSolicitPending : 1; 679 bool mAddressSolicitRejected : 1; 680 681 uint8_t mRouterId; 682 uint8_t mPreviousRouterId; 683 684 uint32_t mPreviousPartitionIdRouter; ///< The partition ID when last operating as a router 685 uint32_t mPreviousPartitionId; ///< The partition ID when last attached 686 uint8_t mPreviousPartitionRouterIdSequence; ///< The router ID sequence when last attached 687 uint8_t mPreviousPartitionIdTimeout; ///< The partition ID timeout when last attached 688 689 uint8_t mRouterSelectionJitter; ///< The variable to save the assigned jitter value. 690 uint8_t mRouterSelectionJitterTimeout; ///< The Timeout prior to request/release Router ID. 691 692 uint8_t mChildRouterLinks; 693 694 int8_t mParentPriority; ///< The assigned parent priority value, -2 means not assigned. 695 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE 696 uint8_t mBackboneRouterRegistrationDelay; ///< Delay before registering Backbone Router service. 697 #endif 698 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 699 uint8_t mMaxChildIpAddresses; 700 #endif 701 702 #if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE 703 MeshCoP::SteeringData mSteeringData; 704 #endif 705 706 Callback<otThreadDiscoveryRequestCallback> mDiscoveryRequestCallback; 707 }; 708 709 DeclareTmfHandler(MleRouter, kUriAddressSolicit); 710 DeclareTmfHandler(MleRouter, kUriAddressRelease); 711 712 #endif // OPENTHREAD_FTD 713 714 #if OPENTHREAD_MTD 715 716 class MleRouter : public Mle 717 { 718 friend class Mle; 719 friend class ot::Instance; 720 721 public: MleRouter(Instance & aInstance)722 explicit MleRouter(Instance &aInstance) 723 : Mle(aInstance) 724 { 725 } 726 IsSingleton(void) const727 bool IsSingleton(void) const { return false; } 728 GetNextHop(uint16_t aDestination) const729 uint16_t GetNextHop(uint16_t aDestination) const { return Mle::GetNextHop(aDestination); } 730 RemoveNeighbor(Neighbor &)731 Error RemoveNeighbor(Neighbor &) { return BecomeDetached(); } RemoveRouterLink(Router &)732 void RemoveRouterLink(Router &) { IgnoreError(BecomeDetached()); } 733 IsRouterIdValid(uint8_t aRouterId)734 static bool IsRouterIdValid(uint8_t aRouterId) { return aRouterId <= kMaxRouterId; } 735 SendChildUpdateRequest(void)736 Error SendChildUpdateRequest(void) { return Mle::SendChildUpdateRequest(); } 737 CheckReachability(uint16_t aMeshDest,Ip6::Header & aIp6Header)738 Error CheckReachability(uint16_t aMeshDest, Ip6::Header &aIp6Header) 739 { 740 return Mle::CheckReachability(aMeshDest, aIp6Header); 741 } 742 }; 743 744 #endif // OPENTHREAD_MTD 745 746 } // namespace Mle 747 748 /** 749 * @} 750 */ 751 752 } // namespace ot 753 754 #endif // MLE_ROUTER_HPP_ 755