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 * @returns 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 * @returns 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, 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 #endif 556 557 private: 558 static constexpr uint16_t kDiscoveryMaxJitter = 250; // Max jitter delay Discovery Responses (in msec). 559 static constexpr uint32_t kStateUpdatePeriod = 1000; // State update period (in msec). 560 static constexpr uint16_t kUnsolicitedDataResponseJitter = 500; // Max delay for unsol Data Response (in msec). 561 562 Error AppendConnectivity(Message &aMessage); 563 Error AppendChildAddresses(Message &aMessage, Child &aChild); 564 Error AppendRoute(Message &aMessage, Neighbor *aNeighbor = nullptr); 565 Error AppendActiveDataset(Message &aMessage); 566 Error AppendPendingDataset(Message &aMessage); 567 void HandleDetachStart(void); 568 void HandleChildStart(AttachMode aMode); 569 void HandleLinkRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Neighbor *aNeighbor); 570 void HandleLinkAccept(const Message & aMessage, 571 const Ip6::MessageInfo &aMessageInfo, 572 uint32_t aKeySequence, 573 Neighbor * aNeighbor); 574 Error HandleLinkAccept(const Message & aMessage, 575 const Ip6::MessageInfo &aMessageInfo, 576 uint32_t aKeySequence, 577 Neighbor * aNeighbor, 578 bool aRequest); 579 void HandleLinkAcceptAndRequest(const Message & aMessage, 580 const Ip6::MessageInfo &aMessageInfo, 581 uint32_t aKeySequence, 582 Neighbor * aNeighbor); 583 Error HandleAdvertisement(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Neighbor *); 584 void HandleParentRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 585 void HandleChildIdRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, uint32_t aKeySequence); 586 void HandleChildUpdateRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 587 void HandleChildUpdateResponse(const Message & aMessage, 588 const Ip6::MessageInfo &aMessageInfo, 589 uint32_t aKeySequence, 590 Neighbor * aNeighbor); 591 void HandleDataRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, const Neighbor *aNeighbor); 592 void HandleNetworkDataUpdateRouter(void); 593 void HandleDiscoveryRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 594 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 595 void HandleTimeSync(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, const Neighbor *aNeighbor); 596 #endif 597 598 Error ProcessRouteTlv(const RouteTlv &aRoute); 599 void StopAdvertiseTrickleTimer(void); 600 Error SendAddressSolicit(ThreadStatusTlv::Status aStatus); 601 void SendAddressRelease(void); 602 void SendAddressSolicitResponse(const Coap::Message & aRequest, 603 const Router * aRouter, 604 const Ip6::MessageInfo &aMessageInfo); 605 void SendAdvertisement(void); 606 Error SendLinkAccept(const Ip6::MessageInfo &aMessageInfo, 607 Neighbor * aNeighbor, 608 const RequestedTlvs & aRequestedTlvs, 609 const Challenge & aChallenge); 610 void SendParentResponse(Child *aChild, const Challenge &aChallenge, bool aRoutersOnlyRequest); 611 Error SendChildIdResponse(Child &aChild); 612 Error SendChildUpdateRequest(Child &aChild); 613 void SendChildUpdateResponse(Child * aChild, 614 const Ip6::MessageInfo &aMessageInfo, 615 const uint8_t * aTlvs, 616 uint8_t aTlvsLength, 617 const Challenge & aChallenge); 618 void SendDataResponse(const Ip6::Address &aDestination, 619 const uint8_t * aTlvs, 620 uint8_t aTlvsLength, 621 uint16_t aDelay, 622 const Message * aRequestMessage = nullptr); 623 Error SendDiscoveryResponse(const Ip6::Address &aDestination, const Message &aDiscoverRequestMessage); 624 void SetStateRouter(uint16_t aRloc16); 625 void SetStateLeader(uint16_t aRloc16); 626 void StopLeader(void); 627 void SynchronizeChildNetworkData(void); 628 Error UpdateChildAddresses(const Message &aMessage, uint16_t aOffset, Child &aChild); 629 void UpdateRoutes(const RouteTlv &aRoute, uint8_t aRouterId); 630 bool UpdateLinkQualityOut(const RouteTlv &aRoute, Router &aNeighbor, bool &aResetAdvInterval); 631 632 static void HandleAddressSolicitResponse(void * aContext, 633 otMessage * aMessage, 634 const otMessageInfo *aMessageInfo, 635 Error aResult); 636 void HandleAddressSolicitResponse(Coap::Message *aMessage, const Ip6::MessageInfo *aMessageInfo, Error aResult); 637 static void HandleAddressRelease(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo); 638 void HandleAddressRelease(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 639 static void HandleAddressSolicit(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo); 640 void HandleAddressSolicit(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 641 642 static bool IsSingleton(const RouteTlv &aRouteTlv); 643 644 void HandlePartitionChange(void); 645 646 void SetChildStateToValid(Child &aChild); 647 bool HasChildren(void); 648 void RemoveChildren(void); 649 bool HasMinDowngradeNeighborRouters(void); 650 bool HasOneNeighborWithComparableConnectivity(const RouteTlv &aRoute, uint8_t aRouterId); 651 bool HasSmallNumberOfChildren(void); 652 653 static void HandleAdvertiseTrickleTimer(TrickleTimer &aTimer); 654 void HandleAdvertiseTrickleTimer(void); 655 void HandleTimeTick(void); 656 657 TrickleTimer mAdvertiseTrickleTimer; 658 659 Coap::Resource mAddressSolicit; 660 Coap::Resource mAddressRelease; 661 662 ChildTable mChildTable; 663 RouterTable mRouterTable; 664 665 uint8_t mChallengeTimeout; 666 Challenge mChallenge; 667 668 uint16_t mNextChildId; 669 uint8_t mNetworkIdTimeout; 670 uint8_t mRouterUpgradeThreshold; 671 uint8_t mRouterDowngradeThreshold; 672 uint8_t mLeaderWeight; 673 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 674 uint32_t mPreferredLeaderPartitionId; ///< only for certification testing 675 #endif 676 bool mRouterEligible : 1; 677 bool mAddressSolicitPending : 1; 678 bool mAddressSolicitRejected : 1; 679 680 uint8_t mRouterId; 681 uint8_t mPreviousRouterId; 682 683 uint32_t mPreviousPartitionIdRouter; ///< The partition ID when last operating as a router 684 uint32_t mPreviousPartitionId; ///< The partition ID when last attached 685 uint8_t mPreviousPartitionRouterIdSequence; ///< The router ID sequence when last attached 686 uint8_t mPreviousPartitionIdTimeout; ///< The partition ID timeout when last attached 687 688 uint8_t mRouterSelectionJitter; ///< The variable to save the assigned jitter value. 689 uint8_t mRouterSelectionJitterTimeout; ///< The Timeout prior to request/release Router ID. 690 691 int8_t mParentPriority; ///< The assigned parent priority value, -2 means not assigned. 692 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE 693 uint8_t mBackboneRouterRegistrationDelay; ///< Delay before registering Backbone Router service. 694 #endif 695 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 696 uint8_t mMaxChildIpAddresses; 697 #endif 698 699 #if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE 700 MeshCoP::SteeringData mSteeringData; 701 #endif 702 703 otThreadDiscoveryRequestCallback mDiscoveryRequestCallback; 704 void * mDiscoveryRequestCallbackContext; 705 }; 706 707 #endif // OPENTHREAD_FTD 708 709 #if OPENTHREAD_MTD 710 711 class MleRouter : public Mle 712 { 713 friend class Mle; 714 friend class ot::Instance; 715 716 public: MleRouter(Instance & aInstance)717 explicit MleRouter(Instance &aInstance) 718 : Mle(aInstance) 719 { 720 } 721 IsSingleton(void) const722 bool IsSingleton(void) const { return false; } 723 GetNextHop(uint16_t aDestination) const724 uint16_t GetNextHop(uint16_t aDestination) const { return Mle::GetNextHop(aDestination); } 725 GetCost(uint16_t)726 uint8_t GetCost(uint16_t) { return 0; } 727 RemoveNeighbor(Neighbor &)728 Error RemoveNeighbor(Neighbor &) { return BecomeDetached(); } RemoveRouterLink(Router &)729 void RemoveRouterLink(Router &) { IgnoreError(BecomeDetached()); } 730 IsRouterIdValid(uint8_t aRouterId)731 static bool IsRouterIdValid(uint8_t aRouterId) { return aRouterId <= kMaxRouterId; } 732 SendChildUpdateRequest(void)733 Error SendChildUpdateRequest(void) { return Mle::SendChildUpdateRequest(); } 734 CheckReachability(uint16_t aMeshDest,Ip6::Header & aIp6Header)735 Error CheckReachability(uint16_t aMeshDest, Ip6::Header &aIp6Header) 736 { 737 return Mle::CheckReachability(aMeshDest, aIp6Header); 738 } 739 }; 740 741 #endif // OPENTHREAD_MTD 742 743 } // namespace Mle 744 745 /** 746 * @} 747 */ 748 749 } // namespace ot 750 751 #endif // MLE_ROUTER_HPP_ 752