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