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 Child, Router, and Leader roles. 32 */ 33 34 #ifndef MLE_HPP_ 35 #define MLE_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include "common/callback.hpp" 40 #include "common/encoding.hpp" 41 #include "common/locator.hpp" 42 #include "common/log.hpp" 43 #include "common/non_copyable.hpp" 44 #include "common/notifier.hpp" 45 #include "common/timer.hpp" 46 #include "crypto/aes_ccm.hpp" 47 #include "mac/mac.hpp" 48 #include "meshcop/joiner_router.hpp" 49 #include "meshcop/meshcop.hpp" 50 #include "net/udp6.hpp" 51 #include "thread/child.hpp" 52 #include "thread/link_metrics.hpp" 53 #include "thread/link_metrics_tlvs.hpp" 54 #include "thread/mle_tlvs.hpp" 55 #include "thread/mle_types.hpp" 56 #include "thread/neighbor_table.hpp" 57 #include "thread/network_data_types.hpp" 58 #include "thread/router.hpp" 59 60 namespace ot { 61 62 /** 63 * @addtogroup core-mle MLE 64 * 65 * @brief 66 * This module includes definitions for the MLE protocol. 67 * 68 * @{ 69 * 70 * @defgroup core-mle-core Core 71 * @defgroup core-mle-router Router 72 * @defgroup core-mle-tlvs TLVs 73 * 74 * @} 75 */ 76 77 class SupervisionListener; 78 class UnitTester; 79 80 /** 81 * @namespace ot::Mle 82 * 83 * @brief 84 * This namespace includes definitions for the MLE protocol. 85 */ 86 87 namespace Mle { 88 89 /** 90 * @addtogroup core-mle-core 91 * 92 * @brief 93 * This module includes definitions for MLE functionality required by the Thread Child, Router, and Leader roles. 94 * 95 * @{ 96 * 97 */ 98 99 #if OPENTHREAD_FTD 100 class MleRouter; 101 #endif 102 103 /** 104 * Implements MLE functionality required by the Thread EndDevices, Router, and Leader roles. 105 * 106 */ 107 class Mle : public InstanceLocator, private NonCopyable 108 { 109 #if OPENTHREAD_FTD 110 friend class MleRouter; 111 #endif 112 friend class DiscoverScanner; 113 friend class ot::Instance; 114 friend class ot::Notifier; 115 friend class ot::SupervisionListener; 116 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE 117 friend class ot::LinkMetrics::Initiator; 118 #endif 119 friend class ot::UnitTester; 120 121 public: 122 /** 123 * Initializes the MLE object. 124 * 125 * @param[in] aInstance A reference to the OpenThread instance. 126 * 127 */ 128 explicit Mle(Instance &aInstance); 129 130 /** 131 * Enables MLE. 132 * 133 * @retval kErrorNone Successfully enabled MLE. 134 * @retval kErrorAlready MLE was already enabled. 135 * 136 */ 137 Error Enable(void); 138 139 /** 140 * Disables MLE. 141 * 142 * @retval kErrorNone Successfully disabled MLE. 143 * 144 */ 145 Error Disable(void); 146 147 /** 148 * Starts the MLE protocol operation. 149 * 150 * @retval kErrorNone Successfully started the protocol operation. 151 * @retval kErrorInvalidState IPv6 interface is down or device is in raw-link mode. 152 * 153 */ Start(void)154 Error Start(void) { return Start(kNormalAttach); } 155 156 /** 157 * Stops the MLE protocol operation. 158 * 159 */ Stop(void)160 void Stop(void) { Stop(kUpdateNetworkDatasets); } 161 162 /** 163 * Restores network information from non-volatile memory (if any). 164 * 165 */ 166 void Restore(void); 167 168 /** 169 * Stores network information into non-volatile memory. 170 * 171 * @retval kErrorNone Successfully store the network information. 172 * @retval kErrorNoBufs Could not store the network information due to insufficient memory space. 173 * 174 */ 175 Error Store(void); 176 177 /** 178 * Generates an MLE Announce message. 179 * 180 * @param[in] aChannel The channel to use when transmitting. 181 * 182 */ SendAnnounce(uint8_t aChannel)183 void SendAnnounce(uint8_t aChannel) { SendAnnounce(aChannel, kNormalAnnounce); } 184 185 /** 186 * Causes the Thread interface to detach from the Thread network. 187 * 188 * @retval kErrorNone Successfully detached from the Thread network. 189 * @retval kErrorInvalidState MLE is Disabled. 190 * 191 */ 192 Error BecomeDetached(void); 193 194 /** 195 * Causes the Thread interface to attempt an MLE attach. 196 * 197 * @retval kErrorNone Successfully began the attach process. 198 * @retval kErrorInvalidState MLE is Disabled. 199 * @retval kErrorBusy An attach process is in progress. 200 * 201 */ 202 Error BecomeChild(void); 203 204 /** 205 * Notifies other nodes in the network (if any) and then stops Thread protocol operation. 206 * 207 * It sends an Address Release if it's a router, or sets its child timeout to 0 if it's a child. 208 * 209 * @param[in] aCallback A pointer to a function that is called upon finishing detaching. 210 * @param[in] aContext A pointer to callback application-specific context. 211 * 212 * @retval kErrorNone Successfully started detaching. 213 * @retval kErrorBusy Detaching is already in progress. 214 * 215 */ 216 Error DetachGracefully(otDetachGracefullyCallback aCallback, void *aContext); 217 218 /** 219 * Indicates whether or not the Thread device is attached to a Thread network. 220 * 221 * @retval TRUE Attached to a Thread network. 222 * @retval FALSE Not attached to a Thread network. 223 * 224 */ 225 bool IsAttached(void) const; 226 227 /** 228 * Indicates whether device is currently attaching or not. 229 * 230 * Note that an already attached device may also be in attaching state. Examples of this include a leader/router 231 * trying to attach to a better partition, or a child trying to find a better parent (when feature 232 * `OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE` is enabled). 233 * 234 * @retval TRUE Device is currently trying to attach. 235 * @retval FALSE Device is not in middle of attach process. 236 * 237 */ IsAttaching(void) const238 bool IsAttaching(void) const { return (mAttachState != kAttachStateIdle); } 239 240 /** 241 * Returns the current Thread device role. 242 * 243 * @returns The current Thread device role. 244 * 245 */ GetRole(void) const246 DeviceRole GetRole(void) const { return mRole; } 247 248 /** 249 * Indicates whether device role is disabled. 250 * 251 * @retval TRUE Device role is disabled. 252 * @retval FALSE Device role is not disabled. 253 * 254 */ IsDisabled(void) const255 bool IsDisabled(void) const { return (mRole == kRoleDisabled); } 256 257 /** 258 * Indicates whether device role is detached. 259 * 260 * @retval TRUE Device role is detached. 261 * @retval FALSE Device role is not detached. 262 * 263 */ IsDetached(void) const264 bool IsDetached(void) const { return (mRole == kRoleDetached); } 265 266 /** 267 * Indicates whether device role is child. 268 * 269 * @retval TRUE Device role is child. 270 * @retval FALSE Device role is not child. 271 * 272 */ IsChild(void) const273 bool IsChild(void) const { return (mRole == kRoleChild); } 274 275 /** 276 * Indicates whether device role is router. 277 * 278 * @retval TRUE Device role is router. 279 * @retval FALSE Device role is not router. 280 * 281 */ IsRouter(void) const282 bool IsRouter(void) const { return (mRole == kRoleRouter); } 283 284 /** 285 * Indicates whether device role is leader. 286 * 287 * @retval TRUE Device role is leader. 288 * @retval FALSE Device role is not leader. 289 * 290 */ IsLeader(void) const291 bool IsLeader(void) const { return (mRole == kRoleLeader); } 292 293 /** 294 * Indicates whether device role is either router or leader. 295 * 296 * @retval TRUE Device role is either router or leader. 297 * @retval FALSE Device role is neither router nor leader. 298 * 299 */ 300 bool IsRouterOrLeader(void) const; 301 302 /** 303 * Returns the Device Mode as reported in the Mode TLV. 304 * 305 * @returns The Device Mode as reported in the Mode TLV. 306 * 307 */ GetDeviceMode(void) const308 DeviceMode GetDeviceMode(void) const { return mDeviceMode; } 309 310 /** 311 * Sets the Device Mode as reported in the Mode TLV. 312 * 313 * @param[in] aDeviceMode The device mode to set. 314 * 315 * @retval kErrorNone Successfully set the Mode TLV. 316 * @retval kErrorInvalidArgs The mode combination specified in @p aMode is invalid. 317 * 318 */ 319 Error SetDeviceMode(DeviceMode aDeviceMode); 320 321 /** 322 * Indicates whether or not the device is rx-on-when-idle. 323 * 324 * @returns TRUE if rx-on-when-idle, FALSE otherwise. 325 * 326 */ IsRxOnWhenIdle(void) const327 bool IsRxOnWhenIdle(void) const { return mDeviceMode.IsRxOnWhenIdle(); } 328 329 /** 330 * Indicates whether or not the device is a Full Thread Device. 331 * 332 * @returns TRUE if a Full Thread Device, FALSE otherwise. 333 * 334 */ IsFullThreadDevice(void) const335 bool IsFullThreadDevice(void) const { return mDeviceMode.IsFullThreadDevice(); } 336 337 /** 338 * Indicates whether or not the device is a Minimal End Device. 339 * 340 * @returns TRUE if the device is a Minimal End Device, FALSE otherwise. 341 * 342 */ IsMinimalEndDevice(void) const343 bool IsMinimalEndDevice(void) const { return mDeviceMode.IsMinimalEndDevice(); } 344 345 /** 346 * Gets the Network Data type (full set or stable subset) that this device requests. 347 * 348 * @returns The Network Data type requested by this device. 349 * 350 */ GetNetworkDataType(void) const351 NetworkData::Type GetNetworkDataType(void) const { return mDeviceMode.GetNetworkDataType(); } 352 353 /** 354 * Returns a pointer to the Mesh Local Prefix. 355 * 356 * @returns A reference to the Mesh Local Prefix. 357 * 358 */ GetMeshLocalPrefix(void) const359 const Ip6::NetworkPrefix &GetMeshLocalPrefix(void) const { return mMeshLocalPrefix; } 360 361 /** 362 * Sets the Mesh Local Prefix. 363 * 364 * @param[in] aMeshLocalPrefix A reference to the Mesh Local Prefix. 365 * 366 */ 367 void SetMeshLocalPrefix(const Ip6::NetworkPrefix &aMeshLocalPrefix); 368 369 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 370 /** 371 * Sets the Mesh Local IID. 372 * 373 * Available only when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled. 374 * 375 * @param[in] aMlIid The Mesh Local IID. 376 * 377 * @retval kErrorNone Successfully configured Mesh Local IID. 378 * @retval kErrorInvalidState If the Thread stack is already enabled. 379 * 380 */ 381 Error SetMeshLocalIid(const Ip6::InterfaceIdentifier &aMlIid); 382 #endif 383 384 /** 385 * Returns a reference to the Thread link-local address. 386 * 387 * The Thread link local address is derived using IEEE802.15.4 Extended Address as Interface Identifier. 388 * 389 * @returns A reference to the Thread link local address. 390 * 391 */ GetLinkLocalAddress(void) const392 const Ip6::Address &GetLinkLocalAddress(void) const { return mLinkLocal64.GetAddress(); } 393 394 /** 395 * Updates the link local address. 396 * 397 * Call this method when the IEEE 802.15.4 Extended Address has changed. 398 * 399 */ 400 void UpdateLinkLocalAddress(void); 401 402 /** 403 * Returns a reference to the link-local all Thread nodes multicast address. 404 * 405 * @returns A reference to the link-local all Thread nodes multicast address. 406 * 407 */ GetLinkLocalAllThreadNodesAddress(void) const408 const Ip6::Address &GetLinkLocalAllThreadNodesAddress(void) const { return mLinkLocalAllThreadNodes.GetAddress(); } 409 410 /** 411 * Returns a reference to the realm-local all Thread nodes multicast address. 412 * 413 * @returns A reference to the realm-local all Thread nodes multicast address. 414 * 415 */ GetRealmLocalAllThreadNodesAddress(void) const416 const Ip6::Address &GetRealmLocalAllThreadNodesAddress(void) const 417 { 418 return mRealmLocalAllThreadNodes.GetAddress(); 419 } 420 421 /** 422 * Gets the parent when operating in End Device mode. 423 * 424 * @returns A reference to the parent. 425 * 426 */ GetParent(void)427 Parent &GetParent(void) { return mParent; } 428 429 /** 430 * Gets the parent when operating in End Device mode. 431 * 432 * @returns A reference to the parent. 433 * 434 */ GetParent(void) const435 const Parent &GetParent(void) const { return mParent; } 436 437 /** 438 * The method retrieves information about the parent. 439 * 440 * @param[out] aParentInfo Reference to a parent information structure. 441 * 442 * @retval kErrorNone Successfully retrieved the parent info and updated @p aParentInfo. 443 * @retval kErrorInvalidState Device role is not child. 444 * 445 */ 446 Error GetParentInfo(Router::Info &aParentInfo) const; 447 448 /** 449 * Get the parent candidate. 450 * 451 * The parent candidate is valid when attempting to attach to a new parent. 452 * 453 */ GetParentCandidate(void)454 Parent &GetParentCandidate(void) { return mParentCandidate; } 455 456 /** 457 * Starts the process for child to search for a better parent while staying attached to its current 458 * parent 459 * 460 * @retval kErrorNone Successfully started the process to search for a better parent. 461 * @retval kErrorInvalidState Device role is not child. 462 * 463 */ 464 Error SearchForBetterParent(void); 465 466 /** 467 * Indicates whether or not an IPv6 address is an RLOC. 468 * 469 * @retval TRUE If @p aAddress is an RLOC. 470 * @retval FALSE If @p aAddress is not an RLOC. 471 * 472 */ 473 bool IsRoutingLocator(const Ip6::Address &aAddress) const; 474 475 /** 476 * Indicates whether or not an IPv6 address is an ALOC. 477 * 478 * @retval TRUE If @p aAddress is an ALOC. 479 * @retval FALSE If @p aAddress is not an ALOC. 480 * 481 */ 482 bool IsAnycastLocator(const Ip6::Address &aAddress) const; 483 484 /** 485 * Indicates whether or not an IPv6 address is a Mesh Local Address. 486 * 487 * @retval TRUE If @p aAddress is a Mesh Local Address. 488 * @retval FALSE If @p aAddress is not a Mesh Local Address. 489 * 490 */ 491 bool IsMeshLocalAddress(const Ip6::Address &aAddress) const; 492 493 /** 494 * Returns the MLE Timeout value. 495 * 496 * @returns The MLE Timeout value in seconds. 497 * 498 */ GetTimeout(void) const499 uint32_t GetTimeout(void) const { return mTimeout; } 500 501 /** 502 * Sets the MLE Timeout value. 503 * 504 * @param[in] aTimeout The Timeout value in seconds. 505 * 506 */ 507 void SetTimeout(uint32_t aTimeout); 508 509 /** 510 * Returns the RLOC16 assigned to the Thread interface. 511 * 512 * @returns The RLOC16 assigned to the Thread interface. 513 * 514 */ GetRloc16(void) const515 uint16_t GetRloc16(void) const { return mRloc16; } 516 517 /** 518 * Returns a reference to the RLOC assigned to the Thread interface. 519 * 520 * @returns A reference to the RLOC assigned to the Thread interface. 521 * 522 */ GetMeshLocal16(void) const523 const Ip6::Address &GetMeshLocal16(void) const { return mMeshLocal16.GetAddress(); } 524 525 /** 526 * Returns a reference to the ML-EID assigned to the Thread interface. 527 * 528 * @returns A reference to the ML-EID assigned to the Thread interface. 529 * 530 */ GetMeshLocal64(void) const531 const Ip6::Address &GetMeshLocal64(void) const { return mMeshLocal64.GetAddress(); } 532 533 /** 534 * Returns a reference to the ML-EID as a `Netif::UnicastAddress`. 535 * 536 * @returns A reference to the ML-EID. 537 * 538 */ GetMeshLocal64UnicastAddress(void)539 Ip6::Netif::UnicastAddress &GetMeshLocal64UnicastAddress(void) { return mMeshLocal64; } 540 541 /** 542 * Returns the Router ID of the Leader. 543 * 544 * @returns The Router ID of the Leader. 545 * 546 */ GetLeaderId(void) const547 uint8_t GetLeaderId(void) const { return mLeaderData.GetLeaderRouterId(); } 548 549 /** 550 * Retrieves the Leader's RLOC. 551 * 552 * @param[out] aAddress A reference to the Leader's RLOC. 553 * 554 * @retval kErrorNone Successfully retrieved the Leader's RLOC. 555 * @retval kErrorDetached The Thread interface is not currently attached to a Thread Partition. 556 * 557 */ 558 Error GetLeaderAddress(Ip6::Address &aAddress) const; 559 560 /** 561 * Retrieves the Leader's ALOC. 562 * 563 * @param[out] aAddress A reference to the Leader's ALOC. 564 * 565 * @retval kErrorNone Successfully retrieved the Leader's ALOC. 566 * @retval kErrorDetached The Thread interface is not currently attached to a Thread Partition. 567 * 568 */ GetLeaderAloc(Ip6::Address & aAddress) const569 Error GetLeaderAloc(Ip6::Address &aAddress) const { return GetLocatorAddress(aAddress, kAloc16Leader); } 570 571 /** 572 * Computes the Commissioner's ALOC. 573 * 574 * @param[out] aAddress A reference to the Commissioner's ALOC. 575 * @param[in] aSessionId Commissioner session id. 576 * 577 * @retval kErrorNone Successfully retrieved the Commissioner's ALOC. 578 * @retval kErrorDetached The Thread interface is not currently attached to a Thread Partition. 579 * 580 */ GetCommissionerAloc(Ip6::Address & aAddress,uint16_t aSessionId) const581 Error GetCommissionerAloc(Ip6::Address &aAddress, uint16_t aSessionId) const 582 { 583 return GetLocatorAddress(aAddress, CommissionerAloc16FromId(aSessionId)); 584 } 585 586 /** 587 * Retrieves the Service ALOC for given Service ID. 588 * 589 * @param[in] aServiceId Service ID to get ALOC for. 590 * @param[out] aAddress A reference to the Service ALOC. 591 * 592 * @retval kErrorNone Successfully retrieved the Service ALOC. 593 * @retval kErrorDetached The Thread interface is not currently attached to a Thread Partition. 594 * 595 */ 596 Error GetServiceAloc(uint8_t aServiceId, Ip6::Address &aAddress) const; 597 598 /** 599 * Returns the most recently received Leader Data. 600 * 601 * @returns A reference to the most recently received Leader Data. 602 * 603 */ 604 const LeaderData &GetLeaderData(void); 605 606 /** 607 * Returns a reference to the send queue. 608 * 609 * @returns A reference to the send queue. 610 * 611 */ GetMessageQueue(void) const612 const MessageQueue &GetMessageQueue(void) const { return mDelayedResponses; } 613 614 /** 615 * Frees multicast MLE Data Response from Delayed Message Queue if any. 616 * 617 */ 618 void RemoveDelayedDataResponseMessage(void); 619 620 /** 621 * Gets the MLE counters. 622 * 623 * @returns A reference to the MLE counters. 624 * 625 */ GetCounters(void)626 const Counters &GetCounters(void) 627 { 628 #if OPENTHREAD_CONFIG_UPTIME_ENABLE 629 UpdateRoleTimeCounters(mRole); 630 #endif 631 return mCounters; 632 } 633 634 /** 635 * Resets the MLE counters. 636 * 637 */ 638 void ResetCounters(void); 639 640 #if OPENTHREAD_CONFIG_MLE_PARENT_RESPONSE_CALLBACK_API_ENABLE 641 /** 642 * Registers the client callback that is called when processing an MLE Parent Response message. 643 * 644 * @param[in] aCallback A pointer to a function that is called to deliver MLE Parent Response data. 645 * @param[in] aContext A pointer to application-specific context. 646 * 647 */ RegisterParentResponseStatsCallback(otThreadParentResponseCallback aCallback,void * aContext)648 void RegisterParentResponseStatsCallback(otThreadParentResponseCallback aCallback, void *aContext) 649 { 650 mParentResponseCallback.Set(aCallback, aContext); 651 } 652 #endif 653 /** 654 * Notifies MLE whether the Child ID Request message was transmitted successfully. 655 * 656 * @param[in] aMessage The transmitted message. 657 * 658 */ 659 void HandleChildIdRequestTxDone(Message &aMessage); 660 661 /** 662 * Requests MLE layer to prepare and send a shorter version of Child ID Request message by only 663 * including the mesh-local IPv6 address in the Address Registration TLV. 664 * 665 * Should be called when a previous MLE Child ID Request message would require fragmentation at 6LoWPAN 666 * layer. 667 * 668 */ 669 void RequestShorterChildIdRequest(void); 670 671 /** 672 * Gets the RLOC or ALOC of a given RLOC16 or ALOC16. 673 * 674 * @param[out] aAddress A reference to the RLOC or ALOC. 675 * @param[in] aLocator RLOC16 or ALOC16. 676 * 677 * @retval kErrorNone If got the RLOC or ALOC successfully. 678 * @retval kErrorDetached If device is detached. 679 * 680 */ 681 Error GetLocatorAddress(Ip6::Address &aAddress, uint16_t aLocator) const; 682 683 /** 684 * Schedules a Child Update Request. 685 * 686 */ 687 void ScheduleChildUpdateRequest(void); 688 689 /* 690 * Indicates whether or not the device has restored the network information from 691 * non-volatile settings after boot. 692 * 693 * @retval true Successfully restored the network information. 694 * @retval false No valid network information was found. 695 * 696 */ HasRestored(void) const697 bool HasRestored(void) const { return mHasRestored; } 698 699 /** 700 * Indicates whether or not a given netif multicast address instance is a prefix-based address added by MLE and 701 * uses the mesh local prefix. 702 * 703 * @param[in] aAddress A `Netif::MulticastAddress` address instance. 704 * 705 * @retval TRUE If @p aAddress is a prefix-based address which uses the mesh local prefix. 706 * @retval FALSE If @p aAddress is not a prefix-based address which uses the mesh local prefix. 707 * 708 */ IsMulticastAddressMeshLocalPrefixBased(const Ip6::Netif::MulticastAddress & aAddress) const709 bool IsMulticastAddressMeshLocalPrefixBased(const Ip6::Netif::MulticastAddress &aAddress) const 710 { 711 return (&aAddress == &mLinkLocalAllThreadNodes) || (&aAddress == &mRealmLocalAllThreadNodes); 712 } 713 714 /** 715 * Determines the next hop towards an RLOC16 destination. 716 * 717 * @param[in] aDestination The RLOC16 of the destination. 718 * 719 * @returns A RLOC16 of the next hop if a route is known, kInvalidRloc16 otherwise. 720 * 721 */ 722 uint16_t GetNextHop(uint16_t aDestination) const; 723 724 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 725 /** 726 * Gets the CSL timeout. 727 * 728 * @returns CSL timeout 729 * 730 */ GetCslTimeout(void) const731 uint32_t GetCslTimeout(void) const { return mCslTimeout; } 732 733 /** 734 * Sets the CSL timeout. 735 * 736 * @param[in] aTimeout The CSL timeout in seconds. 737 * 738 */ 739 void SetCslTimeout(uint32_t aTimeout); 740 741 /** 742 * Calculates CSL metric of parent. 743 * 744 * @param[in] aCslAccuracy The CSL accuracy. 745 * 746 * @returns CSL metric. 747 * 748 */ 749 uint64_t CalcParentCslMetric(const Mac::CslAccuracy &aCslAccuracy) const; 750 751 #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 752 753 private: 754 //------------------------------------------------------------------------------------------------------------------ 755 // Constants 756 757 // All time intervals are in milliseconds 758 static constexpr uint32_t kParentRequestRouterTimeout = 750; // Wait time after tx of Parent Req to routers 759 static constexpr uint32_t kParentRequestReedTimeout = 1250; // Wait timer after tx of Parent Req to REEDs 760 static constexpr uint32_t kParentRequestDuplicateMargin = 50; // Margin to detect duplicate received Parent Req 761 static constexpr uint32_t kChildIdResponseTimeout = 1250; // Wait time to receive Child ID Response 762 static constexpr uint32_t kAttachStartJitter = 50; // Max jitter time added to start of attach 763 static constexpr uint32_t kAnnounceProcessTimeout = 250; // Delay after Announce rx before processing 764 static constexpr uint32_t kAnnounceTimeout = 1400; // Total timeout for sending Announce messages 765 static constexpr uint16_t kMinAnnounceDelay = 80; // Min delay between Announcement messages 766 static constexpr uint32_t kParentResponseMaxDelayRouters = 500; // Max response delay for Parent Req to routers 767 static constexpr uint32_t kParentResponseMaxDelayAll = 1000; // Max response delay for Parent Req to all 768 static constexpr uint32_t kChildUpdateRequestPendingDelay = 100; // Delay for aggregating Child Update Req 769 static constexpr uint32_t kMaxLinkAcceptDelay = 1000; // Max delay to tx Link Accept for multicast Req 770 static constexpr uint32_t kChildIdRequestTimeout = 5000; // Max delay to rx a Child ID Req after Parent Res 771 static constexpr uint32_t kLinkRequestTimeout = 2000; // Max delay to rx a Link Accept 772 static constexpr uint32_t kDetachGracefullyTimeout = 1000; // Timeout for graceful detach 773 static constexpr uint32_t kUnicastRetxDelay = 1000; // Base delay for MLE unicast retx 774 static constexpr uint32_t kMulticastRetxDelay = 5000; // Base delay for MLE multicast retx 775 static constexpr uint32_t kMulticastRetxDelayMin = kMulticastRetxDelay * 9 / 10; // 0.9 * base delay 776 static constexpr uint32_t kMulticastRetxDelayMax = kMulticastRetxDelay * 11 / 10; // 1.1 * base delay 777 778 static constexpr uint8_t kMaxTxCount = 3; // Max tx count for MLE message 779 static constexpr uint8_t kMaxCriticalTxCount = 6; // Max tx count for critical MLE message 780 static constexpr uint8_t kMaxChildKeepAliveAttempts = 4; // Max keep alive attempts before reattach 781 782 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 783 // Attach backoff feature (CONFIG_ENABLE_ATTACH_BACKOFF) - Intervals are in milliseconds. 784 785 static constexpr uint32_t kAttachBackoffMinInterval = OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_MINIMUM_INTERVAL; 786 static constexpr uint32_t kAttachBackoffMaxInterval = OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_MAXIMUM_INTERVAL; 787 static constexpr uint32_t kAttachBackoffJitter = OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_JITTER_INTERVAL; 788 static constexpr uint32_t kAttachBackoffDelayToResetCounter = 789 OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_DELAY_TO_RESET_BACKOFF_INTERVAL; 790 791 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 792 // Number of Parent Requests in first and next attach cycles 793 794 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_3 795 // First attach cycle includes two Parent Requests to routers, followed by four to routers and REEDs. 796 static constexpr uint8_t kFirstAttachCycleTotalParentRequests = 6; 797 static constexpr uint8_t kFirstAttachCycleNumParentRequestToRouters = 2; 798 #else 799 // First attach cycle in Thread 1.1/1.2 includes a Parent Requests to routers, followed by one to routers and REEDs. 800 static constexpr uint8_t kFirstAttachCycleTotalParentRequests = 2; 801 static constexpr uint8_t kFirstAttachCycleNumParentRequestToRouters = 1; 802 #endif 803 804 // Next attach cycles includes one Parent Request to routers, followed by one to routers and REEDs. 805 static constexpr uint8_t kNextAttachCycleTotalParentRequests = 2; 806 static constexpr uint8_t kNextAttachCycleNumParentRequestToRouters = 1; 807 808 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 809 810 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE 811 static constexpr uint8_t kMaxServiceAlocs = OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_MAX_ALOCS + 1; 812 #else 813 static constexpr uint8_t kMaxServiceAlocs = OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_MAX_ALOCS; 814 #endif 815 816 static constexpr uint8_t kMleHopLimit = 255; 817 static constexpr uint8_t kMleSecurityTagSize = 4; 818 static constexpr uint32_t kStoreFrameCounterAhead = OPENTHREAD_CONFIG_STORE_FRAME_COUNTER_AHEAD; 819 static constexpr uint8_t kMaxIpAddressesToRegister = OPENTHREAD_CONFIG_MLE_IP_ADDRS_TO_REGISTER; 820 static constexpr uint32_t kDefaultChildTimeout = OPENTHREAD_CONFIG_MLE_CHILD_TIMEOUT_DEFAULT; 821 static constexpr uint32_t kDefaultCslTimeout = OPENTHREAD_CONFIG_CSL_TIMEOUT; 822 823 //------------------------------------------------------------------------------------------------------------------ 824 // Enumerations 825 826 enum Command : uint8_t 827 { 828 kCommandLinkRequest = 0, 829 kCommandLinkAccept = 1, 830 kCommandLinkAcceptAndRequest = 2, 831 kCommandLinkReject = 3, 832 kCommandAdvertisement = 4, 833 kCommandUpdate = 5, 834 kCommandUpdateRequest = 6, 835 kCommandDataRequest = 7, 836 kCommandDataResponse = 8, 837 kCommandParentRequest = 9, 838 kCommandParentResponse = 10, 839 kCommandChildIdRequest = 11, 840 kCommandChildIdResponse = 12, 841 kCommandChildUpdateRequest = 13, 842 kCommandChildUpdateResponse = 14, 843 kCommandAnnounce = 15, 844 kCommandDiscoveryRequest = 16, 845 kCommandDiscoveryResponse = 17, 846 kCommandLinkMetricsManagementRequest = 18, 847 kCommandLinkMetricsManagementResponse = 19, 848 kCommandLinkProbe = 20, 849 kCommandTimeSync = 99, 850 }; 851 852 enum AttachMode : uint8_t 853 { 854 kAnyPartition, // Attach to any Thread partition. 855 kSamePartition, // Attach to the same Thread partition (when losing connectivity). 856 kBetterPartition, // Attach to a better (i.e. higher weight/partition id) Thread partition. 857 kDowngradeToReed, // Attach to the same Thread partition during downgrade process. 858 kBetterParent, // Attach to a better parent. 859 }; 860 861 enum AttachState : uint8_t 862 { 863 kAttachStateIdle, // Not currently searching for a parent. 864 kAttachStateProcessAnnounce, // Waiting to process a received Announce (to switch channel/pan-id). 865 kAttachStateStart, // Starting to look for a parent. 866 kAttachStateParentRequest, // Send Parent Request (current number tracked by `mParentRequestCounter`). 867 kAttachStateAnnounce, // Send Announce messages 868 kAttachStateChildIdRequest, // Sending a Child ID Request message. 869 }; 870 871 enum ReattachState : uint8_t 872 { 873 kReattachStop, // Reattach process is disabled or finished 874 kReattachStart, // Start reattach process 875 kReattachActive, // Reattach using stored Active Dataset 876 kReattachPending, // Reattach using stored Pending Dataset 877 }; 878 879 static constexpr uint16_t kMleMaxResponseDelay = 1000u; // Max delay before responding to a multicast request. 880 881 enum AddressRegistrationMode : uint8_t // Used by `AppendAddressRegistrationTlv()` 882 { 883 kAppendAllAddresses, // Append all addresses (unicast/multicast) in Address Registration TLV. 884 kAppendMeshLocalOnly, // Only append the Mesh Local (ML-EID) address in Address Registration TLV. 885 }; 886 887 enum StartMode : uint8_t // Used in `Start()`. 888 { 889 kNormalAttach, 890 kAnnounceAttach, // Try to attach on the announced thread network with newer active timestamp. 891 }; 892 893 enum StopMode : uint8_t // Used in `Stop()`. 894 { 895 kKeepNetworkDatasets, 896 kUpdateNetworkDatasets, 897 }; 898 899 enum AnnounceMode : uint8_t // Used in `SendAnnounce()` 900 { 901 kNormalAnnounce, 902 kOrphanAnnounce, 903 }; 904 905 enum ParentRequestType : uint8_t 906 { 907 kToRouters, // Parent Request to routers only. 908 kToRoutersAndReeds, // Parent Request to all routers and REEDs. 909 }; 910 911 enum ChildUpdateRequestState : uint8_t 912 { 913 kChildUpdateRequestNone, // No pending or active Child Update Request. 914 kChildUpdateRequestPending, // Pending Child Update Request due to relative OT_CHANGED event. 915 kChildUpdateRequestActive, // Child Update Request has been sent and Child Update Response is expected. 916 }; 917 918 enum ChildUpdateRequestMode : uint8_t // Used in `SendChildUpdateRequest()` 919 { 920 kNormalChildUpdateRequest, // Normal Child Update Request. 921 kAppendChallengeTlv, // Append Challenge TLV to Child Update Request even if currently attached. 922 kAppendZeroTimeout, // Use zero timeout when appending Timeout TLV (used for graceful detach). 923 }; 924 925 enum DataRequestState : uint8_t 926 { 927 kDataRequestNone, // Not waiting for a Data Response. 928 kDataRequestActive, // Data Request has been sent, Data Response is expected. 929 }; 930 931 enum SecuritySuite : uint8_t 932 { 933 k154Security = 0, // Security suite value indicating that MLE message is not secured. 934 kNoSecurity = 255, // Security suite value indicating that MLE message is secured. 935 }; 936 937 enum MessageAction : uint8_t 938 { 939 kMessageSend, 940 kMessageReceive, 941 kMessageDelay, 942 kMessageRemoveDelayed, 943 }; 944 945 enum MessageType : uint8_t 946 { 947 kTypeAdvertisement, 948 kTypeAnnounce, 949 kTypeChildIdRequest, 950 kTypeChildIdRequestShort, 951 kTypeChildIdResponse, 952 kTypeChildUpdateRequestAsChild, 953 kTypeChildUpdateResponseAsChild, 954 kTypeDataRequest, 955 kTypeDataResponse, 956 kTypeDiscoveryRequest, 957 kTypeDiscoveryResponse, 958 kTypeGenericDelayed, 959 kTypeGenericUdp, 960 kTypeParentRequestToRouters, 961 kTypeParentRequestToRoutersReeds, 962 kTypeParentResponse, 963 #if OPENTHREAD_FTD 964 kTypeAddressRelease, 965 kTypeAddressReleaseReply, 966 kTypeAddressReply, 967 kTypeAddressSolicit, 968 kTypeChildUpdateRequestOfChild, 969 kTypeChildUpdateResponseOfChild, 970 kTypeChildUpdateResponseOfUnknownChild, 971 kTypeLinkAccept, 972 kTypeLinkAcceptAndRequest, 973 kTypeLinkReject, 974 kTypeLinkRequest, 975 kTypeParentRequest, 976 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 977 kTypeTimeSync, 978 #endif 979 #endif 980 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 981 kTypeLinkMetricsManagementRequest, 982 kTypeLinkMetricsManagementResponse, 983 kTypeLinkProbe, 984 #endif 985 }; 986 987 //------------------------------------------------------------------------------------------------------------------ 988 // Nested types 989 990 static constexpr uint8_t kMaxTlvListSize = 32; // Maximum number of TLVs in a `TlvList`. 991 992 class TlvList : public Array<uint8_t, kMaxTlvListSize> 993 { 994 public: 995 TlvList(void) = default; 996 997 void Add(uint8_t aTlvType); 998 void AddElementsFrom(const TlvList &aTlvList); 999 }; 1000 1001 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1002 1003 class TxMessage : public Message 1004 { 1005 public: 1006 Error AppendSourceAddressTlv(void); 1007 Error AppendModeTlv(DeviceMode aMode); 1008 Error AppendTimeoutTlv(uint32_t aTimeout); 1009 Error AppendChallengeTlv(const TxChallenge &aChallenge); 1010 Error AppendResponseTlv(const RxChallenge &aResponse); 1011 Error AppendLinkFrameCounterTlv(void); 1012 Error AppendMleFrameCounterTlv(void); 1013 Error AppendAddress16Tlv(uint16_t aRloc16); 1014 Error AppendNetworkDataTlv(NetworkData::Type aType); 1015 Error AppendTlvRequestTlv(const uint8_t *aTlvs, uint8_t aTlvsLength); 1016 Error AppendLeaderDataTlv(void); 1017 Error AppendScanMaskTlv(uint8_t aScanMask); 1018 Error AppendStatusTlv(StatusTlv::Status aStatus); 1019 Error AppendLinkMarginTlv(uint8_t aLinkMargin); 1020 Error AppendVersionTlv(void); 1021 Error AppendAddressRegistrationTlv(AddressRegistrationMode aMode = kAppendAllAddresses); 1022 Error AppendSupervisionIntervalTlv(uint16_t aInterval); 1023 Error AppendXtalAccuracyTlv(void); 1024 Error AppendActiveTimestampTlv(void); 1025 Error AppendPendingTimestampTlv(void); 1026 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 1027 Error AppendTimeRequestTlv(void); 1028 Error AppendTimeParameterTlv(void); 1029 #endif 1030 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 1031 Error AppendCslChannelTlv(void); 1032 Error AppendCslTimeoutTlv(void); 1033 #endif 1034 #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE 1035 Error AppendCslClockAccuracyTlv(void); 1036 #endif 1037 #if OPENTHREAD_FTD 1038 Error AppendRouteTlv(Neighbor *aNeighbor = nullptr); 1039 Error AppendActiveDatasetTlv(void); 1040 Error AppendPendingDatasetTlv(void); 1041 Error AppendConnectivityTlv(void); 1042 Error AppendSteeringDataTlv(void); 1043 Error AppendAddressRegistrationTlv(Child &aChild); 1044 #endif AppendTlvRequestTlv(const uint8_t (& aTlvArray)[kArrayLength])1045 template <uint8_t kArrayLength> Error AppendTlvRequestTlv(const uint8_t (&aTlvArray)[kArrayLength]) 1046 { 1047 return AppendTlvRequestTlv(aTlvArray, kArrayLength); 1048 } 1049 1050 Error SendTo(const Ip6::Address &aDestination); 1051 Error SendAfterDelay(const Ip6::Address &aDestination, uint16_t aDelay); 1052 1053 private: 1054 Error AppendCompressedAddressEntry(uint8_t aContextId, const Ip6::Address &aAddress); 1055 Error AppendAddressEntry(const Ip6::Address &aAddress); 1056 }; 1057 1058 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1059 1060 class RxMessage : public Message 1061 { 1062 public: 1063 Error ReadChallengeTlv(RxChallenge &aChallenge) const; 1064 Error ReadResponseTlv(RxChallenge &aResponse) const; 1065 Error ReadFrameCounterTlvs(uint32_t &aLinkFrameCounter, uint32_t &aMleFrameCounter) const; 1066 Error ReadTlvRequestTlv(TlvList &aTlvList) const; 1067 Error ReadLeaderDataTlv(LeaderData &aLeaderData) const; 1068 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 1069 Error ReadCslClockAccuracyTlv(Mac::CslAccuracy &aCslAccuracy) const; 1070 #endif 1071 #if OPENTHREAD_FTD 1072 Error ReadRouteTlv(RouteTlv &aRouteTlv) const; 1073 #endif 1074 1075 private: 1076 Error ReadChallengeOrResponse(uint8_t aTlvType, RxChallenge &aRxChallenge) const; 1077 }; 1078 1079 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1080 1081 struct RxInfo 1082 { 1083 enum Class : uint8_t 1084 { 1085 kUnknown, // Unknown (default value, also indicates MLE message parse error). 1086 kAuthoritativeMessage, // Authoritative message (larger received key seq MUST be adopted). 1087 kPeerMessage, // Peer message (adopt only if from a known neighbor and is greater by one). 1088 }; 1089 RxInfoot::Mle::Mle::RxInfo1090 RxInfo(Message &aMessage, const Ip6::MessageInfo &aMessageInfo) 1091 : mMessage(static_cast<RxMessage &>(aMessage)) 1092 , mMessageInfo(aMessageInfo) 1093 , mFrameCounter(0) 1094 , mKeySequence(0) 1095 , mNeighbor(nullptr) 1096 , mClass(kUnknown) 1097 { 1098 } 1099 IsNeighborStateValidot::Mle::Mle::RxInfo1100 bool IsNeighborStateValid(void) const { return (mNeighbor != nullptr) && mNeighbor->IsStateValid(); } 1101 1102 RxMessage &mMessage; // The MLE message. 1103 const Ip6::MessageInfo &mMessageInfo; // The `MessageInfo` associated with the message. 1104 uint32_t mFrameCounter; // The frame counter from aux security header. 1105 uint32_t mKeySequence; // The key sequence from aux security header. 1106 Neighbor *mNeighbor; // Neighbor from which message was received (can be `nullptr`). 1107 Class mClass; // The message class (authoritative, peer, or unknown). 1108 }; 1109 1110 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1111 1112 struct DelayedResponseMetadata 1113 { AppendToot::Mle::Mle::DelayedResponseMetadata1114 Error AppendTo(Message &aMessage) const { return aMessage.Append(*this); } 1115 void ReadFrom(const Message &aMessage); 1116 void RemoveFrom(Message &aMessage) const; 1117 1118 Ip6::Address mDestination; // IPv6 address of the message destination. 1119 TimeMilli mSendTime; // Time when the message shall be sent. 1120 }; 1121 1122 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1123 1124 OT_TOOL_PACKED_BEGIN 1125 class SecurityHeader 1126 { 1127 public: InitSecurityControl(void)1128 void InitSecurityControl(void) { mSecurityControl = kKeyIdMode2Mic32; } IsSecurityControlValid(void) const1129 bool IsSecurityControlValid(void) const { return (mSecurityControl == kKeyIdMode2Mic32); } 1130 GetFrameCounter(void) const1131 uint32_t GetFrameCounter(void) const { return LittleEndian::HostSwap32(mFrameCounter); } SetFrameCounter(uint32_t aCounter)1132 void SetFrameCounter(uint32_t aCounter) { mFrameCounter = LittleEndian::HostSwap32(aCounter); } 1133 GetKeyId(void) const1134 uint32_t GetKeyId(void) const { return BigEndian::HostSwap32(mKeySource); } SetKeyId(uint32_t aKeySequence)1135 void SetKeyId(uint32_t aKeySequence) 1136 { 1137 mKeySource = BigEndian::HostSwap32(aKeySequence); 1138 mKeyIndex = (aKeySequence & 0x7f) + 1; 1139 } 1140 1141 private: 1142 static constexpr uint8_t kKeyIdMode2Mic32 = 1143 static_cast<uint8_t>(Mac::Frame::kKeyIdMode2) | static_cast<uint8_t>(Mac::Frame::kSecurityEncMic32); 1144 1145 uint8_t mSecurityControl; 1146 uint32_t mFrameCounter; 1147 uint32_t mKeySource; 1148 uint8_t mKeyIndex; 1149 } OT_TOOL_PACKED_END; 1150 1151 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1152 1153 class ParentCandidate : public Parent 1154 { 1155 public: Init(Instance & aInstance)1156 void Init(Instance &aInstance) { Parent::Init(aInstance); } 1157 void Clear(void); 1158 void CopyTo(Parent &aParent) const; 1159 1160 RxChallenge mRxChallenge; 1161 int8_t mPriority; 1162 uint8_t mLinkQuality3; 1163 uint8_t mLinkQuality2; 1164 uint8_t mLinkQuality1; 1165 uint16_t mSedBufferSize; 1166 uint8_t mSedDatagramCount; 1167 uint8_t mLinkMargin; 1168 LeaderData mLeaderData; 1169 bool mIsSingleton; 1170 }; 1171 1172 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1173 1174 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE 1175 class ServiceAloc : public Ip6::Netif::UnicastAddress 1176 { 1177 public: 1178 static constexpr uint16_t kNotInUse = Mac::kShortAddrInvalid; 1179 1180 ServiceAloc(void); 1181 IsInUse(void) const1182 bool IsInUse(void) const { return GetAloc16() != kNotInUse; } MarkAsNotInUse(void)1183 void MarkAsNotInUse(void) { SetAloc16(kNotInUse); } GetAloc16(void) const1184 uint16_t GetAloc16(void) const { return GetAddress().GetIid().GetLocator(); } SetAloc16(uint16_t aAloc16)1185 void SetAloc16(uint16_t aAloc16) { GetAddress().GetIid().SetLocator(aAloc16); } 1186 }; 1187 #endif 1188 1189 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1190 1191 #if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE HandleParentSearchTimer(void)1192 void HandleParentSearchTimer(void) { mParentSearch.HandleTimer(); } 1193 1194 class ParentSearch : public InstanceLocator 1195 { 1196 public: ParentSearch(Instance & aInstance)1197 explicit ParentSearch(Instance &aInstance) 1198 : InstanceLocator(aInstance) 1199 , mIsInBackoff(false) 1200 , mBackoffWasCanceled(false) 1201 , mRecentlyDetached(false) 1202 , mBackoffCancelTime(0) 1203 , mTimer(aInstance) 1204 { 1205 } 1206 1207 void StartTimer(void); 1208 void UpdateState(void); SetRecentlyDetached(void)1209 void SetRecentlyDetached(void) { mRecentlyDetached = true; } 1210 void HandleTimer(void); 1211 1212 private: 1213 // All timer intervals are converted to milliseconds. 1214 static constexpr uint32_t kCheckInterval = (OPENTHREAD_CONFIG_PARENT_SEARCH_CHECK_INTERVAL * 1000u); 1215 static constexpr uint32_t kBackoffInterval = (OPENTHREAD_CONFIG_PARENT_SEARCH_BACKOFF_INTERVAL * 1000u); 1216 static constexpr uint32_t kJitterInterval = (15 * 1000u); 1217 static constexpr int8_t kRssThreshold = OPENTHREAD_CONFIG_PARENT_SEARCH_RSS_THRESHOLD; 1218 1219 using SearchTimer = TimerMilliIn<Mle, &Mle::HandleParentSearchTimer>; 1220 1221 bool mIsInBackoff : 1; 1222 bool mBackoffWasCanceled : 1; 1223 bool mRecentlyDetached : 1; 1224 TimeMilli mBackoffCancelTime; 1225 SearchTimer mTimer; 1226 }; 1227 #endif // OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE 1228 1229 //------------------------------------------------------------------------------------------------------------------ 1230 // Methods 1231 1232 static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo); 1233 static void HandleDetachGracefullyTimer(Timer &aTimer); 1234 1235 Error Start(StartMode aMode); 1236 void Stop(StopMode aMode); 1237 TxMessage *NewMleMessage(Command aCommand); 1238 void SetRole(DeviceRole aRole); 1239 void Attach(AttachMode aMode); 1240 void SetAttachState(AttachState aState); 1241 void InitNeighbor(Neighbor &aNeighbor, const RxInfo &aRxInfo); ClearParentCandidate(void)1242 void ClearParentCandidate(void) { mParentCandidate.Clear(); } 1243 Error CheckReachability(uint16_t aMeshDest, const Ip6::Header &aIp6Header); 1244 Error SendDataRequest(const Ip6::Address &aDestination); 1245 void HandleNotifierEvents(Events aEvents); 1246 void SendDelayedResponse(TxMessage &aMessage, const DelayedResponseMetadata &aMetadata); 1247 void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 1248 void ReestablishLinkWithNeighbor(Neighbor &aNeighbor); 1249 void HandleDetachGracefullyTimer(void); IsDetachingGracefully(void)1250 bool IsDetachingGracefully(void) { return mDetachGracefullyTimer.IsRunning(); } 1251 Error SendChildUpdateRequest(ChildUpdateRequestMode aMode); 1252 Error SendDataRequestAfterDelay(const Ip6::Address &aDestination, uint16_t aDelay); 1253 Error SendChildUpdateRequest(void); 1254 Error SendChildUpdateResponse(const TlvList &aTlvList, 1255 const RxChallenge &aChallenge, 1256 const Ip6::Address &aDestination); 1257 void SetRloc16(uint16_t aRloc16); 1258 void SetStateDetached(void); 1259 void SetStateChild(uint16_t aRloc16); 1260 void SetLeaderData(uint32_t aPartitionId, uint8_t aWeighting, uint8_t aLeaderRouterId); 1261 void InformPreviousChannel(void); IsAnnounceAttach(void) const1262 bool IsAnnounceAttach(void) const { return mAlternatePanId != Mac::kPanIdBroadcast; } 1263 void ScheduleMessageTransmissionTimer(void); 1264 void HandleAttachTimer(void); 1265 void HandleDelayedResponseTimer(void); 1266 void HandleMessageTransmissionTimer(void); 1267 void ProcessKeySequence(RxInfo &aRxInfo); 1268 void HandleAdvertisement(RxInfo &aRxInfo); 1269 void HandleChildIdResponse(RxInfo &aRxInfo); 1270 void HandleChildUpdateRequest(RxInfo &aRxInfo); 1271 void HandleChildUpdateResponse(RxInfo &aRxInfo); 1272 void HandleDataResponse(RxInfo &aRxInfo); 1273 void HandleParentResponse(RxInfo &aRxInfo); 1274 void HandleAnnounce(RxInfo &aRxInfo); 1275 Error HandleLeaderData(RxInfo &aRxInfo); 1276 void ProcessAnnounce(void); 1277 bool HasUnregisteredAddress(void); 1278 uint32_t GetAttachStartDelay(void) const; 1279 void SendParentRequest(ParentRequestType aType); 1280 Error SendChildIdRequest(void); 1281 Error GetNextAnnounceChannel(uint8_t &aChannel) const; 1282 bool HasMoreChannelsToAnnounce(void) const; 1283 bool PrepareAnnounceState(void); 1284 void SendAnnounce(uint8_t aChannel, AnnounceMode aMode); 1285 void SendAnnounce(uint8_t aChannel, const Ip6::Address &aDestination, AnnounceMode aMode = kNormalAnnounce); 1286 uint32_t Reattach(void); 1287 bool HasAcceptableParentCandidate(void) const; 1288 Error DetermineParentRequestType(ParentRequestType &aType) const; 1289 bool IsBetterParent(uint16_t aRloc16, 1290 LinkQuality aLinkQuality, 1291 uint8_t aLinkMargin, 1292 const ConnectivityTlv &aConnectivityTlv, 1293 uint16_t aVersion, 1294 const Mac::CslAccuracy &aCslAccuracy); 1295 bool IsNetworkDataNewer(const LeaderData &aLeaderData); 1296 Error ProcessMessageSecurity(Crypto::AesCcm::Mode aMode, 1297 Message &aMessage, 1298 const Ip6::MessageInfo &aMessageInfo, 1299 uint16_t aCmdOffset, 1300 const SecurityHeader &aHeader); 1301 void RemoveDelayedMessage(Message::SubType aSubType, MessageType aMessageType, const Ip6::Address *aDestination); 1302 void RemoveDelayedDataRequestMessage(const Ip6::Address &aDestination); 1303 1304 #if OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH 1305 void InformPreviousParent(void); 1306 #endif 1307 1308 #if OPENTHREAD_CONFIG_UPTIME_ENABLE 1309 void UpdateRoleTimeCounters(DeviceRole aRole); 1310 #endif 1311 1312 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE 1313 ServiceAloc *FindInServiceAlocs(uint16_t aAloc16); 1314 void UpdateServiceAlocs(void); 1315 #endif 1316 1317 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 1318 void HandleLinkMetricsManagementRequest(RxInfo &aRxInfo); 1319 void HandleLinkProbe(RxInfo &aRxInfo); 1320 Error SendLinkMetricsManagementResponse(const Ip6::Address &aDestination, LinkMetrics::Status aStatus); 1321 #endif 1322 1323 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE 1324 void HandleLinkMetricsManagementResponse(RxInfo &aRxInfo); 1325 Error SendDataRequestForLinkMetricsReport(const Ip6::Address &aDestination, 1326 const LinkMetrics::Initiator::QueryInfo &aQueryInfo); 1327 Error SendLinkMetricsManagementRequest(const Ip6::Address &aDestination, const ot::Tlv &aSubTlv); 1328 Error SendLinkProbe(const Ip6::Address &aDestination, uint8_t aSeriesId, uint8_t *aBuf, uint8_t aLength); 1329 Error SendDataRequest(const Ip6::Address &aDestination, 1330 const uint8_t *aTlvs, 1331 uint8_t aTlvsLength, 1332 uint16_t aDelay, 1333 const LinkMetrics::Initiator::QueryInfo *aQueryInfo = nullptr); 1334 #else 1335 Error SendDataRequest(const Ip6::Address &aDestination, const uint8_t *aTlvs, uint8_t aTlvsLength, uint16_t aDelay); 1336 #endif 1337 1338 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO) 1339 static void Log(MessageAction aAction, MessageType aType, const Ip6::Address &aAddress); 1340 static void Log(MessageAction aAction, MessageType aType, const Ip6::Address &aAddress, uint16_t aRloc); 1341 #else Log(MessageAction,MessageType,const Ip6::Address &)1342 static void Log(MessageAction, MessageType, const Ip6::Address &) {} Log(MessageAction,MessageType,const Ip6::Address &,uint16_t)1343 static void Log(MessageAction, MessageType, const Ip6::Address &, uint16_t) {} 1344 #endif 1345 1346 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_NOTE) 1347 static const char *AttachModeToString(AttachMode aMode); 1348 static const char *AttachStateToString(AttachState aState); 1349 static const char *ReattachStateToString(ReattachState aState); 1350 #endif 1351 1352 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN) 1353 static void LogError(MessageAction aAction, MessageType aType, Error aError); 1354 static const char *MessageActionToString(MessageAction aAction); 1355 static const char *MessageTypeToString(MessageType aType); 1356 static const char *MessageTypeActionToSuffixString(MessageType aType, MessageAction aAction); 1357 static void LogProcessError(MessageType aType, Error aError); 1358 static void LogSendError(MessageType aType, Error aError); 1359 #else LogProcessError(MessageType,Error)1360 static void LogProcessError(MessageType, Error) {} LogSendError(MessageType,Error)1361 static void LogSendError(MessageType, Error) {} 1362 #endif 1363 1364 //------------------------------------------------------------------------------------------------------------------ 1365 // Variables 1366 1367 using DetachGracefullyTimer = TimerMilliIn<Mle, &Mle::HandleDetachGracefullyTimer>; 1368 using AttachTimer = TimerMilliIn<Mle, &Mle::HandleAttachTimer>; 1369 using DelayTimer = TimerMilliIn<Mle, &Mle::HandleDelayedResponseTimer>; 1370 using MsgTxTimer = TimerMilliIn<Mle, &Mle::HandleMessageTransmissionTimer>; 1371 1372 static const otMeshLocalPrefix kMeshLocalPrefixInit; 1373 1374 bool mRetrieveNewNetworkData : 1; 1375 bool mRequestRouteTlv : 1; 1376 bool mHasRestored : 1; 1377 bool mReceivedResponseFromParent : 1; 1378 bool mInitiallyAttachedAsSleepy : 1; 1379 #if OPENTHREAD_FTD 1380 bool mWasLeader : 1; 1381 #endif 1382 1383 DeviceRole mRole; 1384 DeviceMode mDeviceMode; 1385 AttachState mAttachState; 1386 ReattachState mReattachState; 1387 AttachMode mAttachMode; 1388 DataRequestState mDataRequestState; 1389 AddressRegistrationMode mAddressRegistrationMode; 1390 ChildUpdateRequestState mChildUpdateRequestState; 1391 1392 uint8_t mParentRequestCounter; 1393 uint8_t mChildUpdateAttempts; 1394 uint8_t mDataRequestAttempts; 1395 uint8_t mAnnounceChannel; 1396 uint8_t mAlternateChannel; 1397 #if OPENTHREAD_FTD 1398 uint8_t mLinkRequestAttempts; 1399 #endif 1400 uint16_t mRloc16; 1401 uint16_t mPreviousParentRloc; 1402 uint16_t mAttachCounter; 1403 uint16_t mAnnounceDelay; 1404 uint16_t mAlternatePanId; 1405 uint32_t mTimeout; 1406 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 1407 uint32_t mCslTimeout; 1408 #endif 1409 uint64_t mAlternateTimestamp; 1410 #if OPENTHREAD_CONFIG_UPTIME_ENABLE 1411 uint64_t mLastUpdatedTimestamp; 1412 #endif 1413 1414 LeaderData mLeaderData; 1415 Parent mParent; 1416 NeighborTable mNeighborTable; 1417 MessageQueue mDelayedResponses; 1418 TxChallenge mParentRequestChallenge; 1419 ParentCandidate mParentCandidate; 1420 Ip6::Udp::Socket mSocket; 1421 Counters mCounters; 1422 #if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE 1423 ParentSearch mParentSearch; 1424 #endif 1425 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE 1426 ServiceAloc mServiceAlocs[kMaxServiceAlocs]; 1427 #endif 1428 Callback<otDetachGracefullyCallback> mDetachGracefullyCallback; 1429 #if OPENTHREAD_CONFIG_MLE_PARENT_RESPONSE_CALLBACK_API_ENABLE 1430 Callback<otThreadParentResponseCallback> mParentResponseCallback; 1431 #endif 1432 AttachTimer mAttachTimer; 1433 DelayTimer mDelayedResponseTimer; 1434 MsgTxTimer mMessageTransmissionTimer; 1435 DetachGracefullyTimer mDetachGracefullyTimer; 1436 Ip6::NetworkPrefix mMeshLocalPrefix; 1437 Ip6::Netif::UnicastAddress mLinkLocal64; 1438 Ip6::Netif::UnicastAddress mMeshLocal64; 1439 Ip6::Netif::UnicastAddress mMeshLocal16; 1440 Ip6::Netif::MulticastAddress mLinkLocalAllThreadNodes; 1441 Ip6::Netif::MulticastAddress mRealmLocalAllThreadNodes; 1442 }; 1443 1444 } // namespace Mle 1445 1446 /** 1447 * @} 1448 * 1449 */ 1450 1451 } // namespace ot 1452 1453 #endif // MLE_HPP_ 1454