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