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 mLinkLocal64.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 when operating in End Device mode. 424 * 425 * @returns A reference to the parent. 426 * 427 */ GetParent(void)428 Parent &GetParent(void) { return mParent; } 429 430 /** 431 * Gets the parent when operating in End Device mode. 432 * 433 * @returns A reference to the parent. 434 * 435 */ GetParent(void) const436 const Parent &GetParent(void) const { return mParent; } 437 438 /** 439 * The method retrieves information about the parent. 440 * 441 * @param[out] aParentInfo Reference to a parent information structure. 442 * 443 * @retval kErrorNone Successfully retrieved the parent info and updated @p aParentInfo. 444 * @retval kErrorInvalidState Device role is not child. 445 * 446 */ 447 Error GetParentInfo(Router::Info &aParentInfo) const; 448 449 /** 450 * Get the parent candidate. 451 * 452 * The parent candidate is valid when attempting to attach to a new parent. 453 * 454 */ GetParentCandidate(void)455 Parent &GetParentCandidate(void) { return mParentCandidate; } 456 457 /** 458 * Starts the process for child to search for a better parent while staying attached to its current 459 * parent 460 * 461 * @retval kErrorNone Successfully started the process to search for a better parent. 462 * @retval kErrorInvalidState Device role is not child. 463 * 464 */ 465 Error SearchForBetterParent(void); 466 467 /** 468 * Indicates whether or not an IPv6 address is an RLOC. 469 * 470 * @retval TRUE If @p aAddress is an RLOC. 471 * @retval FALSE If @p aAddress is not an RLOC. 472 * 473 */ 474 bool IsRoutingLocator(const Ip6::Address &aAddress) const; 475 476 /** 477 * Indicates whether or not an IPv6 address is an ALOC. 478 * 479 * @retval TRUE If @p aAddress is an ALOC. 480 * @retval FALSE If @p aAddress is not an ALOC. 481 * 482 */ 483 bool IsAnycastLocator(const Ip6::Address &aAddress) const; 484 485 /** 486 * Indicates whether or not an IPv6 address is a Mesh Local Address. 487 * 488 * @retval TRUE If @p aAddress is a Mesh Local Address. 489 * @retval FALSE If @p aAddress is not a Mesh Local Address. 490 * 491 */ 492 bool IsMeshLocalAddress(const Ip6::Address &aAddress) const; 493 494 /** 495 * Returns the MLE Timeout value. 496 * 497 * @returns The MLE Timeout value in seconds. 498 * 499 */ GetTimeout(void) const500 uint32_t GetTimeout(void) const { return mTimeout; } 501 502 /** 503 * Sets the MLE Timeout value. 504 * 505 * @param[in] aTimeout The Timeout value in seconds. 506 * 507 */ 508 void SetTimeout(uint32_t aTimeout); 509 510 /** 511 * Returns the RLOC16 assigned to the Thread interface. 512 * 513 * @returns The RLOC16 assigned to the Thread interface. 514 * 515 */ GetRloc16(void) const516 uint16_t GetRloc16(void) const { return mRloc16; } 517 518 /** 519 * Returns a reference to the RLOC assigned to the Thread interface. 520 * 521 * @returns A reference to the RLOC assigned to the Thread interface. 522 * 523 */ GetMeshLocal16(void) const524 const Ip6::Address &GetMeshLocal16(void) const { return mMeshLocal16.GetAddress(); } 525 526 /** 527 * Returns a reference to the ML-EID assigned to the Thread interface. 528 * 529 * @returns A reference to the ML-EID assigned to the Thread interface. 530 * 531 */ GetMeshLocal64(void) const532 const Ip6::Address &GetMeshLocal64(void) const { return mMeshLocal64.GetAddress(); } 533 534 /** 535 * Returns a reference to the ML-EID as a `Netif::UnicastAddress`. 536 * 537 * @returns A reference to the ML-EID. 538 * 539 */ GetMeshLocal64UnicastAddress(void)540 Ip6::Netif::UnicastAddress &GetMeshLocal64UnicastAddress(void) { return mMeshLocal64; } 541 542 /** 543 * Returns the Router ID of the Leader. 544 * 545 * @returns The Router ID of the Leader. 546 * 547 */ GetLeaderId(void) const548 uint8_t GetLeaderId(void) const { return mLeaderData.GetLeaderRouterId(); } 549 550 /** 551 * Retrieves the Leader's RLOC. 552 * 553 * @param[out] aAddress A reference to the Leader's RLOC. 554 * 555 * @retval kErrorNone Successfully retrieved the Leader's RLOC. 556 * @retval kErrorDetached The Thread interface is not currently attached to a Thread Partition. 557 * 558 */ 559 Error GetLeaderAddress(Ip6::Address &aAddress) const; 560 561 /** 562 * Retrieves the Leader's ALOC. 563 * 564 * @param[out] aAddress A reference to the Leader's ALOC. 565 * 566 * @retval kErrorNone Successfully retrieved the Leader's ALOC. 567 * @retval kErrorDetached The Thread interface is not currently attached to a Thread Partition. 568 * 569 */ GetLeaderAloc(Ip6::Address & aAddress) const570 Error GetLeaderAloc(Ip6::Address &aAddress) const { return GetLocatorAddress(aAddress, kAloc16Leader); } 571 572 /** 573 * Computes the Commissioner's ALOC. 574 * 575 * @param[out] aAddress A reference to the Commissioner's ALOC. 576 * @param[in] aSessionId Commissioner session id. 577 * 578 * @retval kErrorNone Successfully retrieved the Commissioner's ALOC. 579 * @retval kErrorDetached The Thread interface is not currently attached to a Thread Partition. 580 * 581 */ GetCommissionerAloc(Ip6::Address & aAddress,uint16_t aSessionId) const582 Error GetCommissionerAloc(Ip6::Address &aAddress, uint16_t aSessionId) const 583 { 584 return GetLocatorAddress(aAddress, CommissionerAloc16FromId(aSessionId)); 585 } 586 587 /** 588 * Retrieves the Service ALOC for given Service ID. 589 * 590 * @param[in] aServiceId Service ID to get ALOC for. 591 * @param[out] aAddress A reference to the Service ALOC. 592 * 593 * @retval kErrorNone Successfully retrieved the Service ALOC. 594 * @retval kErrorDetached The Thread interface is not currently attached to a Thread Partition. 595 * 596 */ 597 Error GetServiceAloc(uint8_t aServiceId, Ip6::Address &aAddress) const; 598 599 /** 600 * Returns the most recently received Leader Data. 601 * 602 * @returns A reference to the most recently received Leader Data. 603 * 604 */ 605 const LeaderData &GetLeaderData(void); 606 607 /** 608 * Returns a reference to the send queue. 609 * 610 * @returns A reference to the send queue. 611 * 612 */ GetMessageQueue(void) const613 const MessageQueue &GetMessageQueue(void) const { return mDelayedResponses; } 614 615 /** 616 * Frees multicast MLE Data Response from Delayed Message Queue if any. 617 * 618 */ 619 void RemoveDelayedDataResponseMessage(void); 620 621 /** 622 * Gets the MLE counters. 623 * 624 * @returns A reference to the MLE counters. 625 * 626 */ GetCounters(void)627 const Counters &GetCounters(void) 628 { 629 #if OPENTHREAD_CONFIG_UPTIME_ENABLE 630 UpdateRoleTimeCounters(mRole); 631 #endif 632 return mCounters; 633 } 634 635 /** 636 * Resets the MLE counters. 637 * 638 */ 639 void ResetCounters(void); 640 641 #if OPENTHREAD_CONFIG_MLE_PARENT_RESPONSE_CALLBACK_API_ENABLE 642 /** 643 * Registers the client callback that is called when processing an MLE Parent Response message. 644 * 645 * @param[in] aCallback A pointer to a function that is called to deliver MLE Parent Response data. 646 * @param[in] aContext A pointer to application-specific context. 647 * 648 */ RegisterParentResponseStatsCallback(otThreadParentResponseCallback aCallback,void * aContext)649 void RegisterParentResponseStatsCallback(otThreadParentResponseCallback aCallback, void *aContext) 650 { 651 mParentResponseCallback.Set(aCallback, aContext); 652 } 653 #endif 654 /** 655 * Notifies MLE whether the Child ID Request message was transmitted successfully. 656 * 657 * @param[in] aMessage The transmitted message. 658 * 659 */ 660 void HandleChildIdRequestTxDone(Message &aMessage); 661 662 /** 663 * Requests MLE layer to prepare and send a shorter version of Child ID Request message by only 664 * including the mesh-local IPv6 address in the Address Registration TLV. 665 * 666 * Should be called when a previous MLE Child ID Request message would require fragmentation at 6LoWPAN 667 * layer. 668 * 669 */ 670 void RequestShorterChildIdRequest(void); 671 672 /** 673 * Gets the RLOC or ALOC of a given RLOC16 or ALOC16. 674 * 675 * @param[out] aAddress A reference to the RLOC or ALOC. 676 * @param[in] aLocator RLOC16 or ALOC16. 677 * 678 * @retval kErrorNone If got the RLOC or ALOC successfully. 679 * @retval kErrorDetached If device is detached. 680 * 681 */ 682 Error GetLocatorAddress(Ip6::Address &aAddress, uint16_t aLocator) const; 683 684 /** 685 * Schedules a Child Update Request. 686 * 687 */ 688 void ScheduleChildUpdateRequest(void); 689 690 /* 691 * Indicates whether or not the device has restored the network information from 692 * non-volatile settings after boot. 693 * 694 * @retval true Successfully restored the network information. 695 * @retval false No valid network information was found. 696 * 697 */ HasRestored(void) const698 bool HasRestored(void) const { return mHasRestored; } 699 700 /** 701 * Indicates whether or not a given netif multicast address instance is a prefix-based address added by MLE and 702 * uses the mesh local prefix. 703 * 704 * @param[in] aAddress A `Netif::MulticastAddress` address instance. 705 * 706 * @retval TRUE If @p aAddress is a prefix-based address which uses the mesh local prefix. 707 * @retval FALSE If @p aAddress is not a prefix-based address which uses the mesh local prefix. 708 * 709 */ IsMulticastAddressMeshLocalPrefixBased(const Ip6::Netif::MulticastAddress & aAddress) const710 bool IsMulticastAddressMeshLocalPrefixBased(const Ip6::Netif::MulticastAddress &aAddress) const 711 { 712 return (&aAddress == &mLinkLocalAllThreadNodes) || (&aAddress == &mRealmLocalAllThreadNodes); 713 } 714 715 /** 716 * Determines the next hop towards an RLOC16 destination. 717 * 718 * @param[in] aDestination The RLOC16 of the destination. 719 * 720 * @returns A RLOC16 of the next hop if a route is known, kInvalidRloc16 otherwise. 721 * 722 */ 723 uint16_t GetNextHop(uint16_t aDestination) const; 724 725 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 726 /** 727 * Gets the CSL timeout. 728 * 729 * @returns CSL timeout 730 * 731 */ GetCslTimeout(void) const732 uint32_t GetCslTimeout(void) const { return mCslTimeout; } 733 734 /** 735 * Sets the CSL timeout. 736 * 737 * @param[in] aTimeout The CSL timeout in seconds. 738 * 739 */ 740 void SetCslTimeout(uint32_t aTimeout); 741 742 /** 743 * Calculates CSL metric of parent. 744 * 745 * @param[in] aCslAccuracy The CSL accuracy. 746 * 747 * @returns CSL metric. 748 * 749 */ 750 uint64_t CalcParentCslMetric(const Mac::CslAccuracy &aCslAccuracy) const; 751 752 #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 753 754 private: 755 //------------------------------------------------------------------------------------------------------------------ 756 // Constants 757 758 // All time intervals are in milliseconds 759 static constexpr uint32_t kParentRequestRouterTimeout = 750; // Wait time after tx of Parent Req to routers 760 static constexpr uint32_t kParentRequestReedTimeout = 1250; // Wait timer after tx of Parent Req to REEDs 761 static constexpr uint32_t kParentRequestDuplicateMargin = 50; // Margin to detect duplicate received Parent Req 762 static constexpr uint32_t kChildIdResponseTimeout = 1250; // Wait time to receive Child ID Response 763 static constexpr uint32_t kAttachStartJitter = 50; // Max jitter time added to start of attach 764 static constexpr uint32_t kAnnounceProcessTimeout = 250; // Delay after Announce rx before processing 765 static constexpr uint32_t kAnnounceTimeout = 1400; // Total timeout for sending Announce messages 766 static constexpr uint16_t kMinAnnounceDelay = 80; // Min delay between Announcement messages 767 static constexpr uint32_t kParentResponseMaxDelayRouters = 500; // Max response delay for Parent Req to routers 768 static constexpr uint32_t kParentResponseMaxDelayAll = 1000; // Max response delay for Parent Req to all 769 static constexpr uint32_t kChildUpdateRequestPendingDelay = 100; // Delay for aggregating Child Update Req 770 static constexpr uint32_t kMaxLinkAcceptDelay = 1000; // Max delay to tx Link Accept for multicast Req 771 static constexpr uint32_t kChildIdRequestTimeout = 5000; // Max delay to rx a Child ID Req after Parent Res 772 static constexpr uint32_t kLinkRequestTimeout = 2000; // Max delay to rx a Link Accept 773 static constexpr uint32_t kDetachGracefullyTimeout = 1000; // Timeout for graceful detach 774 static constexpr uint32_t kUnicastRetxDelay = 1000; // Base delay for MLE unicast retx 775 static constexpr uint32_t kMulticastRetxDelay = 5000; // Base delay for MLE multicast retx 776 static constexpr uint32_t kMulticastRetxDelayMin = kMulticastRetxDelay * 9 / 10; // 0.9 * base delay 777 static constexpr uint32_t kMulticastRetxDelayMax = kMulticastRetxDelay * 11 / 10; // 1.1 * base delay 778 779 static constexpr uint8_t kMaxTxCount = 3; // Max tx count for MLE message 780 static constexpr uint8_t kMaxCriticalTxCount = 6; // Max tx count for critical MLE message 781 static constexpr uint8_t kMaxChildKeepAliveAttempts = 4; // Max keep alive attempts before reattach 782 783 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 784 // Attach backoff feature (CONFIG_ENABLE_ATTACH_BACKOFF) - Intervals are in milliseconds. 785 786 static constexpr uint32_t kAttachBackoffMinInterval = OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_MINIMUM_INTERVAL; 787 static constexpr uint32_t kAttachBackoffMaxInterval = OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_MAXIMUM_INTERVAL; 788 static constexpr uint32_t kAttachBackoffJitter = OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_JITTER_INTERVAL; 789 static constexpr uint32_t kAttachBackoffDelayToResetCounter = 790 OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_DELAY_TO_RESET_BACKOFF_INTERVAL; 791 792 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 793 // Number of Parent Requests in first and next attach cycles 794 795 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_3 796 // First attach cycle includes two Parent Requests to routers, followed by four to routers and REEDs. 797 static constexpr uint8_t kFirstAttachCycleTotalParentRequests = 6; 798 static constexpr uint8_t kFirstAttachCycleNumParentRequestToRouters = 2; 799 #else 800 // First attach cycle in Thread 1.1/1.2 includes a Parent Requests to routers, followed by one to routers and REEDs. 801 static constexpr uint8_t kFirstAttachCycleTotalParentRequests = 2; 802 static constexpr uint8_t kFirstAttachCycleNumParentRequestToRouters = 1; 803 #endif 804 805 // Next attach cycles includes one Parent Request to routers, followed by one to routers and REEDs. 806 static constexpr uint8_t kNextAttachCycleTotalParentRequests = 2; 807 static constexpr uint8_t kNextAttachCycleNumParentRequestToRouters = 1; 808 809 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 810 811 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE 812 static constexpr uint8_t kMaxServiceAlocs = OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_MAX_ALOCS + 1; 813 #else 814 static constexpr uint8_t kMaxServiceAlocs = OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_MAX_ALOCS; 815 #endif 816 817 static constexpr uint8_t kMleHopLimit = 255; 818 static constexpr uint8_t kMleSecurityTagSize = 4; 819 static constexpr uint32_t kStoreFrameCounterAhead = OPENTHREAD_CONFIG_STORE_FRAME_COUNTER_AHEAD; 820 static constexpr uint8_t kMaxIpAddressesToRegister = OPENTHREAD_CONFIG_MLE_IP_ADDRS_TO_REGISTER; 821 static constexpr uint32_t kDefaultChildTimeout = OPENTHREAD_CONFIG_MLE_CHILD_TIMEOUT_DEFAULT; 822 static constexpr uint32_t kDefaultCslTimeout = OPENTHREAD_CONFIG_CSL_TIMEOUT; 823 824 //------------------------------------------------------------------------------------------------------------------ 825 // Enumerations 826 827 enum Command : uint8_t 828 { 829 kCommandLinkRequest = 0, 830 kCommandLinkAccept = 1, 831 kCommandLinkAcceptAndRequest = 2, 832 kCommandLinkReject = 3, 833 kCommandAdvertisement = 4, 834 kCommandUpdate = 5, 835 kCommandUpdateRequest = 6, 836 kCommandDataRequest = 7, 837 kCommandDataResponse = 8, 838 kCommandParentRequest = 9, 839 kCommandParentResponse = 10, 840 kCommandChildIdRequest = 11, 841 kCommandChildIdResponse = 12, 842 kCommandChildUpdateRequest = 13, 843 kCommandChildUpdateResponse = 14, 844 kCommandAnnounce = 15, 845 kCommandDiscoveryRequest = 16, 846 kCommandDiscoveryResponse = 17, 847 kCommandLinkMetricsManagementRequest = 18, 848 kCommandLinkMetricsManagementResponse = 19, 849 kCommandLinkProbe = 20, 850 kCommandTimeSync = 99, 851 }; 852 853 enum AttachMode : uint8_t 854 { 855 kAnyPartition, // Attach to any Thread partition. 856 kSamePartition, // Attach to the same Thread partition (when losing connectivity). 857 kBetterPartition, // Attach to a better (i.e. higher weight/partition id) Thread partition. 858 kDowngradeToReed, // Attach to the same Thread partition during downgrade process. 859 kBetterParent, // Attach to a better parent. 860 }; 861 862 enum AttachState : uint8_t 863 { 864 kAttachStateIdle, // Not currently searching for a parent. 865 kAttachStateProcessAnnounce, // Waiting to process a received Announce (to switch channel/pan-id). 866 kAttachStateStart, // Starting to look for a parent. 867 kAttachStateParentRequest, // Send Parent Request (current number tracked by `mParentRequestCounter`). 868 kAttachStateAnnounce, // Send Announce messages 869 kAttachStateChildIdRequest, // Sending a Child ID Request message. 870 }; 871 872 enum ReattachState : uint8_t 873 { 874 kReattachStop, // Reattach process is disabled or finished 875 kReattachStart, // Start reattach process 876 kReattachActive, // Reattach using stored Active Dataset 877 kReattachPending, // Reattach using stored Pending Dataset 878 }; 879 880 static constexpr uint16_t kMleMaxResponseDelay = 1000u; // Max delay before responding to a multicast request. 881 882 enum AddressRegistrationMode : uint8_t // Used by `AppendAddressRegistrationTlv()` 883 { 884 kAppendAllAddresses, // Append all addresses (unicast/multicast) in Address Registration TLV. 885 kAppendMeshLocalOnly, // Only append the Mesh Local (ML-EID) address in Address Registration TLV. 886 }; 887 888 enum StartMode : uint8_t // Used in `Start()`. 889 { 890 kNormalAttach, 891 kAnnounceAttach, // Try to attach on the announced thread network with newer active timestamp. 892 }; 893 894 enum StopMode : uint8_t // Used in `Stop()`. 895 { 896 kKeepNetworkDatasets, 897 kUpdateNetworkDatasets, 898 }; 899 900 enum AnnounceMode : uint8_t // Used in `SendAnnounce()` 901 { 902 kNormalAnnounce, 903 kOrphanAnnounce, 904 }; 905 906 enum ParentRequestType : uint8_t 907 { 908 kToRouters, // Parent Request to routers only. 909 kToRoutersAndReeds, // Parent Request to all routers and REEDs. 910 }; 911 912 enum ChildUpdateRequestState : uint8_t 913 { 914 kChildUpdateRequestNone, // No pending or active Child Update Request. 915 kChildUpdateRequestPending, // Pending Child Update Request due to relative OT_CHANGED event. 916 kChildUpdateRequestActive, // Child Update Request has been sent and Child Update Response is expected. 917 }; 918 919 enum ChildUpdateRequestMode : uint8_t // Used in `SendChildUpdateRequest()` 920 { 921 kNormalChildUpdateRequest, // Normal Child Update Request. 922 kAppendChallengeTlv, // Append Challenge TLV to Child Update Request even if currently attached. 923 kAppendZeroTimeout, // Use zero timeout when appending Timeout TLV (used for graceful detach). 924 }; 925 926 enum DataRequestState : uint8_t 927 { 928 kDataRequestNone, // Not waiting for a Data Response. 929 kDataRequestActive, // Data Request has been sent, Data Response is expected. 930 }; 931 932 enum SecuritySuite : uint8_t 933 { 934 k154Security = 0, // Security suite value indicating that MLE message is not secured. 935 kNoSecurity = 255, // Security suite value indicating that MLE message is secured. 936 }; 937 938 enum MessageAction : uint8_t 939 { 940 kMessageSend, 941 kMessageReceive, 942 kMessageDelay, 943 kMessageRemoveDelayed, 944 }; 945 946 enum MessageType : uint8_t 947 { 948 kTypeAdvertisement, 949 kTypeAnnounce, 950 kTypeChildIdRequest, 951 kTypeChildIdRequestShort, 952 kTypeChildIdResponse, 953 kTypeChildUpdateRequestAsChild, 954 kTypeChildUpdateResponseAsChild, 955 kTypeDataRequest, 956 kTypeDataResponse, 957 kTypeDiscoveryRequest, 958 kTypeDiscoveryResponse, 959 kTypeGenericDelayed, 960 kTypeGenericUdp, 961 kTypeParentRequestToRouters, 962 kTypeParentRequestToRoutersReeds, 963 kTypeParentResponse, 964 #if OPENTHREAD_FTD 965 kTypeAddressRelease, 966 kTypeAddressReleaseReply, 967 kTypeAddressReply, 968 kTypeAddressSolicit, 969 kTypeChildUpdateRequestOfChild, 970 kTypeChildUpdateResponseOfChild, 971 kTypeChildUpdateResponseOfUnknownChild, 972 kTypeLinkAccept, 973 kTypeLinkAcceptAndRequest, 974 kTypeLinkReject, 975 kTypeLinkRequest, 976 kTypeParentRequest, 977 #endif 978 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 979 kTypeLinkMetricsManagementRequest, 980 kTypeLinkMetricsManagementResponse, 981 kTypeLinkProbe, 982 #endif 983 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 984 kTypeTimeSync, 985 #endif 986 }; 987 988 //------------------------------------------------------------------------------------------------------------------ 989 // Nested types 990 991 static constexpr uint8_t kMaxTlvListSize = 32; // Maximum number of TLVs in a `TlvList`. 992 993 class TlvList : public Array<uint8_t, kMaxTlvListSize> 994 { 995 public: 996 TlvList(void) = default; 997 998 void Add(uint8_t aTlvType); 999 void AddElementsFrom(const TlvList &aTlvList); 1000 }; 1001 1002 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1003 1004 class TxMessage : public Message 1005 { 1006 public: 1007 Error AppendSourceAddressTlv(void); 1008 Error AppendModeTlv(DeviceMode aMode); 1009 Error AppendTimeoutTlv(uint32_t aTimeout); 1010 Error AppendChallengeTlv(const TxChallenge &aChallenge); 1011 Error AppendResponseTlv(const RxChallenge &aResponse); 1012 Error AppendLinkFrameCounterTlv(void); 1013 Error AppendMleFrameCounterTlv(void); 1014 Error AppendAddress16Tlv(uint16_t aRloc16); 1015 Error AppendNetworkDataTlv(NetworkData::Type aType); 1016 Error AppendTlvRequestTlv(const uint8_t *aTlvs, uint8_t aTlvsLength); 1017 Error AppendLeaderDataTlv(void); 1018 Error AppendScanMaskTlv(uint8_t aScanMask); 1019 Error AppendStatusTlv(StatusTlv::Status aStatus); 1020 Error AppendLinkMarginTlv(uint8_t aLinkMargin); 1021 Error AppendVersionTlv(void); 1022 Error AppendAddressRegistrationTlv(AddressRegistrationMode aMode = kAppendAllAddresses); 1023 Error AppendSupervisionIntervalTlv(uint16_t aInterval); 1024 Error AppendXtalAccuracyTlv(void); 1025 Error AppendActiveTimestampTlv(void); 1026 Error AppendPendingTimestampTlv(void); 1027 Error AppendActiveAndPendingTimestampTlvs(void); 1028 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 1029 Error AppendTimeRequestTlv(void); 1030 Error AppendTimeParameterTlv(void); 1031 #endif 1032 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 1033 Error AppendCslChannelTlv(void); 1034 Error AppendCslTimeoutTlv(void); 1035 #endif 1036 #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE 1037 Error AppendCslClockAccuracyTlv(void); 1038 #endif 1039 #if OPENTHREAD_FTD 1040 Error AppendRouteTlv(Neighbor *aNeighbor = nullptr); 1041 Error AppendActiveDatasetTlv(void); 1042 Error AppendPendingDatasetTlv(void); 1043 Error AppendConnectivityTlv(void); 1044 Error AppendSteeringDataTlv(void); 1045 Error AppendAddressRegistrationTlv(Child &aChild); 1046 #endif AppendTlvRequestTlv(const uint8_t (& aTlvArray)[kArrayLength])1047 template <uint8_t kArrayLength> Error AppendTlvRequestTlv(const uint8_t (&aTlvArray)[kArrayLength]) 1048 { 1049 return AppendTlvRequestTlv(aTlvArray, kArrayLength); 1050 } 1051 1052 Error SendTo(const Ip6::Address &aDestination); 1053 Error SendAfterDelay(const Ip6::Address &aDestination, uint16_t aDelay); 1054 1055 private: 1056 Error AppendCompressedAddressEntry(uint8_t aContextId, const Ip6::Address &aAddress); 1057 Error AppendAddressEntry(const Ip6::Address &aAddress); 1058 Error AppendDatasetTlv(MeshCoP::Dataset::Type mDatasetType); 1059 }; 1060 1061 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1062 1063 class RxMessage : public Message 1064 { 1065 public: 1066 bool ContainsTlv(Tlv::Type aTlvType) const; 1067 Error ReadModeTlv(DeviceMode &aMode) const; 1068 Error ReadVersionTlv(uint16_t &aVersion) const; 1069 Error ReadChallengeTlv(RxChallenge &aChallenge) const; 1070 Error ReadResponseTlv(RxChallenge &aResponse) const; 1071 Error ReadAndMatchResponseTlvWith(const TxChallenge &aChallenge) const; 1072 Error ReadFrameCounterTlvs(uint32_t &aLinkFrameCounter, uint32_t &aMleFrameCounter) const; 1073 Error ReadTlvRequestTlv(TlvList &aTlvList) const; 1074 Error ReadLeaderDataTlv(LeaderData &aLeaderData) const; 1075 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 1076 Error ReadCslClockAccuracyTlv(Mac::CslAccuracy &aCslAccuracy) const; 1077 #endif 1078 #if OPENTHREAD_FTD 1079 Error ReadRouteTlv(RouteTlv &aRouteTlv) const; 1080 #endif 1081 1082 private: 1083 Error ReadChallengeOrResponse(uint8_t aTlvType, RxChallenge &aRxChallenge) const; 1084 }; 1085 1086 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1087 1088 struct RxInfo 1089 { 1090 enum Class : uint8_t 1091 { 1092 kUnknown, // Unknown (default value, also indicates MLE message parse error). 1093 kAuthoritativeMessage, // Authoritative message (larger received key seq MUST be adopted). 1094 kPeerMessage, // Peer message (adopt only if from a known neighbor and is greater by one). 1095 }; 1096 RxInfoot::Mle::Mle::RxInfo1097 RxInfo(Message &aMessage, const Ip6::MessageInfo &aMessageInfo) 1098 : mMessage(static_cast<RxMessage &>(aMessage)) 1099 , mMessageInfo(aMessageInfo) 1100 , mFrameCounter(0) 1101 , mKeySequence(0) 1102 , mNeighbor(nullptr) 1103 , mClass(kUnknown) 1104 { 1105 } 1106 IsNeighborStateValidot::Mle::Mle::RxInfo1107 bool IsNeighborStateValid(void) const { return (mNeighbor != nullptr) && mNeighbor->IsStateValid(); } 1108 1109 RxMessage &mMessage; // The MLE message. 1110 const Ip6::MessageInfo &mMessageInfo; // The `MessageInfo` associated with the message. 1111 uint32_t mFrameCounter; // The frame counter from aux security header. 1112 uint32_t mKeySequence; // The key sequence from aux security header. 1113 Neighbor *mNeighbor; // Neighbor from which message was received (can be `nullptr`). 1114 Class mClass; // The message class (authoritative, peer, or unknown). 1115 }; 1116 1117 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1118 1119 struct DelayedResponseMetadata 1120 { AppendToot::Mle::Mle::DelayedResponseMetadata1121 Error AppendTo(Message &aMessage) const { return aMessage.Append(*this); } 1122 void ReadFrom(const Message &aMessage); 1123 void RemoveFrom(Message &aMessage) const; 1124 1125 Ip6::Address mDestination; // IPv6 address of the message destination. 1126 TimeMilli mSendTime; // Time when the message shall be sent. 1127 }; 1128 1129 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1130 1131 OT_TOOL_PACKED_BEGIN 1132 class SecurityHeader 1133 { 1134 public: InitSecurityControl(void)1135 void InitSecurityControl(void) { mSecurityControl = kKeyIdMode2Mic32; } IsSecurityControlValid(void) const1136 bool IsSecurityControlValid(void) const { return (mSecurityControl == kKeyIdMode2Mic32); } 1137 GetFrameCounter(void) const1138 uint32_t GetFrameCounter(void) const { return LittleEndian::HostSwap32(mFrameCounter); } SetFrameCounter(uint32_t aCounter)1139 void SetFrameCounter(uint32_t aCounter) { mFrameCounter = LittleEndian::HostSwap32(aCounter); } 1140 GetKeyId(void) const1141 uint32_t GetKeyId(void) const { return BigEndian::HostSwap32(mKeySource); } SetKeyId(uint32_t aKeySequence)1142 void SetKeyId(uint32_t aKeySequence) 1143 { 1144 mKeySource = BigEndian::HostSwap32(aKeySequence); 1145 mKeyIndex = (aKeySequence & 0x7f) + 1; 1146 } 1147 1148 private: 1149 static constexpr uint8_t kKeyIdMode2Mic32 = 1150 static_cast<uint8_t>(Mac::Frame::kKeyIdMode2) | static_cast<uint8_t>(Mac::Frame::kSecurityEncMic32); 1151 1152 uint8_t mSecurityControl; 1153 uint32_t mFrameCounter; 1154 uint32_t mKeySource; 1155 uint8_t mKeyIndex; 1156 } OT_TOOL_PACKED_END; 1157 1158 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1159 1160 class ParentCandidate : public Parent 1161 { 1162 public: Init(Instance & aInstance)1163 void Init(Instance &aInstance) { Parent::Init(aInstance); } 1164 void Clear(void); 1165 void CopyTo(Parent &aParent) const; 1166 1167 RxChallenge mRxChallenge; 1168 int8_t mPriority; 1169 uint8_t mLinkQuality3; 1170 uint8_t mLinkQuality2; 1171 uint8_t mLinkQuality1; 1172 uint16_t mSedBufferSize; 1173 uint8_t mSedDatagramCount; 1174 uint8_t mLinkMargin; 1175 LeaderData mLeaderData; 1176 bool mIsSingleton; 1177 }; 1178 1179 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1180 1181 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE 1182 class ServiceAloc : public Ip6::Netif::UnicastAddress 1183 { 1184 public: 1185 static constexpr uint16_t kNotInUse = Mac::kShortAddrInvalid; 1186 1187 ServiceAloc(void); 1188 IsInUse(void) const1189 bool IsInUse(void) const { return GetAloc16() != kNotInUse; } MarkAsNotInUse(void)1190 void MarkAsNotInUse(void) { SetAloc16(kNotInUse); } GetAloc16(void) const1191 uint16_t GetAloc16(void) const { return GetAddress().GetIid().GetLocator(); } SetAloc16(uint16_t aAloc16)1192 void SetAloc16(uint16_t aAloc16) { GetAddress().GetIid().SetLocator(aAloc16); } 1193 }; 1194 #endif 1195 1196 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1197 1198 #if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE HandleParentSearchTimer(void)1199 void HandleParentSearchTimer(void) { mParentSearch.HandleTimer(); } 1200 1201 class ParentSearch : public InstanceLocator 1202 { 1203 public: ParentSearch(Instance & aInstance)1204 explicit ParentSearch(Instance &aInstance) 1205 : InstanceLocator(aInstance) 1206 , mIsInBackoff(false) 1207 , mBackoffWasCanceled(false) 1208 , mRecentlyDetached(false) 1209 , mBackoffCancelTime(0) 1210 , mTimer(aInstance) 1211 { 1212 } 1213 1214 void StartTimer(void); 1215 void UpdateState(void); SetRecentlyDetached(void)1216 void SetRecentlyDetached(void) { mRecentlyDetached = true; } 1217 void HandleTimer(void); 1218 1219 private: 1220 // All timer intervals are converted to milliseconds. 1221 static constexpr uint32_t kCheckInterval = (OPENTHREAD_CONFIG_PARENT_SEARCH_CHECK_INTERVAL * 1000u); 1222 static constexpr uint32_t kBackoffInterval = (OPENTHREAD_CONFIG_PARENT_SEARCH_BACKOFF_INTERVAL * 1000u); 1223 static constexpr uint32_t kJitterInterval = (15 * 1000u); 1224 static constexpr int8_t kRssThreshold = OPENTHREAD_CONFIG_PARENT_SEARCH_RSS_THRESHOLD; 1225 1226 using SearchTimer = TimerMilliIn<Mle, &Mle::HandleParentSearchTimer>; 1227 1228 bool mIsInBackoff : 1; 1229 bool mBackoffWasCanceled : 1; 1230 bool mRecentlyDetached : 1; 1231 TimeMilli mBackoffCancelTime; 1232 SearchTimer mTimer; 1233 }; 1234 #endif // OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE 1235 1236 //------------------------------------------------------------------------------------------------------------------ 1237 // Methods 1238 1239 static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo); 1240 static void HandleDetachGracefullyTimer(Timer &aTimer); 1241 1242 Error Start(StartMode aMode); 1243 void Stop(StopMode aMode); 1244 TxMessage *NewMleMessage(Command aCommand); 1245 void SetRole(DeviceRole aRole); 1246 void Attach(AttachMode aMode); 1247 void SetAttachState(AttachState aState); 1248 void InitNeighbor(Neighbor &aNeighbor, const RxInfo &aRxInfo); ClearParentCandidate(void)1249 void ClearParentCandidate(void) { mParentCandidate.Clear(); } 1250 Error SendDataRequest(const Ip6::Address &aDestination); 1251 void HandleNotifierEvents(Events aEvents); 1252 void SendDelayedResponse(TxMessage &aMessage, const DelayedResponseMetadata &aMetadata); 1253 void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 1254 void ReestablishLinkWithNeighbor(Neighbor &aNeighbor); 1255 void HandleDetachGracefullyTimer(void); IsDetachingGracefully(void)1256 bool IsDetachingGracefully(void) { return mDetachGracefullyTimer.IsRunning(); } 1257 Error SendChildUpdateRequest(ChildUpdateRequestMode aMode); 1258 Error SendDataRequestAfterDelay(const Ip6::Address &aDestination, uint16_t aDelay); 1259 Error SendChildUpdateRequest(void); 1260 Error SendChildUpdateResponse(const TlvList &aTlvList, 1261 const RxChallenge &aChallenge, 1262 const Ip6::Address &aDestination); 1263 void SetRloc16(uint16_t aRloc16); 1264 void SetStateDetached(void); 1265 void SetStateChild(uint16_t aRloc16); 1266 void SetLeaderData(uint32_t aPartitionId, uint8_t aWeighting, uint8_t aLeaderRouterId); 1267 void SetLeaderData(const LeaderData &aLeaderData); 1268 void InformPreviousChannel(void); IsAnnounceAttach(void) const1269 bool IsAnnounceAttach(void) const { return mAlternatePanId != Mac::kPanIdBroadcast; } 1270 void ScheduleMessageTransmissionTimer(void); 1271 void HandleAttachTimer(void); 1272 void HandleDelayedResponseTimer(void); 1273 void HandleMessageTransmissionTimer(void); 1274 void ProcessKeySequence(RxInfo &aRxInfo); 1275 void HandleAdvertisement(RxInfo &aRxInfo); 1276 void HandleChildIdResponse(RxInfo &aRxInfo); 1277 void HandleChildUpdateRequest(RxInfo &aRxInfo); 1278 void HandleChildUpdateResponse(RxInfo &aRxInfo); 1279 void HandleDataResponse(RxInfo &aRxInfo); 1280 void HandleParentResponse(RxInfo &aRxInfo); 1281 void HandleAnnounce(RxInfo &aRxInfo); 1282 Error HandleLeaderData(RxInfo &aRxInfo); 1283 void ProcessAnnounce(void); 1284 bool HasUnregisteredAddress(void); 1285 uint32_t GetAttachStartDelay(void) const; 1286 void SendParentRequest(ParentRequestType aType); 1287 Error SendChildIdRequest(void); 1288 Error GetNextAnnounceChannel(uint8_t &aChannel) const; 1289 bool HasMoreChannelsToAnnounce(void) const; 1290 bool PrepareAnnounceState(void); 1291 void SendAnnounce(uint8_t aChannel, AnnounceMode aMode); 1292 void SendAnnounce(uint8_t aChannel, const Ip6::Address &aDestination, AnnounceMode aMode = kNormalAnnounce); 1293 uint32_t Reattach(void); 1294 bool HasAcceptableParentCandidate(void) const; 1295 Error DetermineParentRequestType(ParentRequestType &aType) const; 1296 bool IsBetterParent(uint16_t aRloc16, 1297 uint8_t aTwoWayLinkMargin, 1298 const ConnectivityTlv &aConnectivityTlv, 1299 uint16_t aVersion, 1300 const Mac::CslAccuracy &aCslAccuracy); 1301 bool IsNetworkDataNewer(const LeaderData &aLeaderData); 1302 Error ProcessMessageSecurity(Crypto::AesCcm::Mode aMode, 1303 Message &aMessage, 1304 const Ip6::MessageInfo &aMessageInfo, 1305 uint16_t aCmdOffset, 1306 const SecurityHeader &aHeader); 1307 void RemoveDelayedMessage(Message::SubType aSubType, MessageType aMessageType, const Ip6::Address *aDestination); 1308 void RemoveDelayedDataRequestMessage(const Ip6::Address &aDestination); 1309 1310 #if OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH 1311 void InformPreviousParent(void); 1312 #endif 1313 1314 #if OPENTHREAD_CONFIG_UPTIME_ENABLE 1315 void UpdateRoleTimeCounters(DeviceRole aRole); 1316 #endif 1317 1318 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE 1319 ServiceAloc *FindInServiceAlocs(uint16_t aAloc16); 1320 void UpdateServiceAlocs(void); 1321 #endif 1322 1323 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 1324 void HandleTimeSync(RxInfo &aRxInfo); 1325 #endif 1326 1327 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 1328 void HandleLinkMetricsManagementRequest(RxInfo &aRxInfo); 1329 void HandleLinkProbe(RxInfo &aRxInfo); 1330 Error SendLinkMetricsManagementResponse(const Ip6::Address &aDestination, LinkMetrics::Status aStatus); 1331 #endif 1332 1333 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE 1334 void HandleLinkMetricsManagementResponse(RxInfo &aRxInfo); 1335 Error SendDataRequestForLinkMetricsReport(const Ip6::Address &aDestination, 1336 const LinkMetrics::Initiator::QueryInfo &aQueryInfo); 1337 Error SendLinkMetricsManagementRequest(const Ip6::Address &aDestination, const ot::Tlv &aSubTlv); 1338 Error SendLinkProbe(const Ip6::Address &aDestination, uint8_t aSeriesId, uint8_t *aBuf, uint8_t aLength); 1339 Error SendDataRequest(const Ip6::Address &aDestination, 1340 const uint8_t *aTlvs, 1341 uint8_t aTlvsLength, 1342 uint16_t aDelay, 1343 const LinkMetrics::Initiator::QueryInfo *aQueryInfo = nullptr); 1344 #else 1345 Error SendDataRequest(const Ip6::Address &aDestination, const uint8_t *aTlvs, uint8_t aTlvsLength, uint16_t aDelay); 1346 #endif 1347 1348 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO) 1349 static void Log(MessageAction aAction, MessageType aType, const Ip6::Address &aAddress); 1350 static void Log(MessageAction aAction, MessageType aType, const Ip6::Address &aAddress, uint16_t aRloc); 1351 #else Log(MessageAction,MessageType,const Ip6::Address &)1352 static void Log(MessageAction, MessageType, const Ip6::Address &) {} Log(MessageAction,MessageType,const Ip6::Address &,uint16_t)1353 static void Log(MessageAction, MessageType, const Ip6::Address &, uint16_t) {} 1354 #endif 1355 1356 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_NOTE) 1357 static const char *AttachModeToString(AttachMode aMode); 1358 static const char *AttachStateToString(AttachState aState); 1359 static const char *ReattachStateToString(ReattachState aState); 1360 #endif 1361 1362 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN) 1363 static void LogError(MessageAction aAction, MessageType aType, Error aError); 1364 static const char *MessageActionToString(MessageAction aAction); 1365 static const char *MessageTypeToString(MessageType aType); 1366 static const char *MessageTypeActionToSuffixString(MessageType aType, MessageAction aAction); 1367 static void LogProcessError(MessageType aType, Error aError); 1368 static void LogSendError(MessageType aType, Error aError); 1369 #else LogProcessError(MessageType,Error)1370 static void LogProcessError(MessageType, Error) {} LogSendError(MessageType,Error)1371 static void LogSendError(MessageType, Error) {} 1372 #endif 1373 1374 //------------------------------------------------------------------------------------------------------------------ 1375 // Variables 1376 1377 using DetachGracefullyTimer = TimerMilliIn<Mle, &Mle::HandleDetachGracefullyTimer>; 1378 using AttachTimer = TimerMilliIn<Mle, &Mle::HandleAttachTimer>; 1379 using DelayTimer = TimerMilliIn<Mle, &Mle::HandleDelayedResponseTimer>; 1380 using MsgTxTimer = TimerMilliIn<Mle, &Mle::HandleMessageTransmissionTimer>; 1381 1382 static const otMeshLocalPrefix kMeshLocalPrefixInit; 1383 1384 bool mRetrieveNewNetworkData : 1; 1385 bool mRequestRouteTlv : 1; 1386 bool mHasRestored : 1; 1387 bool mReceivedResponseFromParent : 1; 1388 bool mInitiallyAttachedAsSleepy : 1; 1389 #if OPENTHREAD_FTD 1390 bool mWasLeader : 1; 1391 #endif 1392 1393 DeviceRole mRole; 1394 DeviceMode mDeviceMode; 1395 AttachState mAttachState; 1396 ReattachState mReattachState; 1397 AttachMode mAttachMode; 1398 DataRequestState mDataRequestState; 1399 AddressRegistrationMode mAddressRegistrationMode; 1400 ChildUpdateRequestState mChildUpdateRequestState; 1401 1402 uint8_t mParentRequestCounter; 1403 uint8_t mChildUpdateAttempts; 1404 uint8_t mDataRequestAttempts; 1405 uint8_t mAnnounceChannel; 1406 uint8_t mAlternateChannel; 1407 #if OPENTHREAD_FTD 1408 uint8_t mLinkRequestAttempts; 1409 #endif 1410 uint16_t mRloc16; 1411 uint16_t mPreviousParentRloc; 1412 uint16_t mAttachCounter; 1413 uint16_t mAnnounceDelay; 1414 uint16_t mAlternatePanId; 1415 uint32_t mTimeout; 1416 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 1417 uint32_t mCslTimeout; 1418 #endif 1419 uint64_t mAlternateTimestamp; 1420 #if OPENTHREAD_CONFIG_UPTIME_ENABLE 1421 uint64_t mLastUpdatedTimestamp; 1422 #endif 1423 1424 LeaderData mLeaderData; 1425 Parent mParent; 1426 NeighborTable mNeighborTable; 1427 MessageQueue mDelayedResponses; 1428 TxChallenge mParentRequestChallenge; 1429 ParentCandidate mParentCandidate; 1430 Ip6::Udp::Socket mSocket; 1431 Counters mCounters; 1432 #if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE 1433 ParentSearch mParentSearch; 1434 #endif 1435 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE 1436 ServiceAloc mServiceAlocs[kMaxServiceAlocs]; 1437 #endif 1438 Callback<otDetachGracefullyCallback> mDetachGracefullyCallback; 1439 #if OPENTHREAD_CONFIG_MLE_PARENT_RESPONSE_CALLBACK_API_ENABLE 1440 Callback<otThreadParentResponseCallback> mParentResponseCallback; 1441 #endif 1442 AttachTimer mAttachTimer; 1443 DelayTimer mDelayedResponseTimer; 1444 MsgTxTimer mMessageTransmissionTimer; 1445 DetachGracefullyTimer mDetachGracefullyTimer; 1446 Ip6::NetworkPrefix mMeshLocalPrefix; 1447 Ip6::Netif::UnicastAddress mLinkLocal64; 1448 Ip6::Netif::UnicastAddress mMeshLocal64; 1449 Ip6::Netif::UnicastAddress mMeshLocal16; 1450 Ip6::Netif::MulticastAddress mLinkLocalAllThreadNodes; 1451 Ip6::Netif::MulticastAddress mRealmLocalAllThreadNodes; 1452 }; 1453 1454 } // namespace Mle 1455 1456 /** 1457 * @} 1458 * 1459 */ 1460 1461 } // namespace ot 1462 1463 #endif // MLE_HPP_ 1464