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