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/link_metrics.hpp" 52 #include "thread/link_metrics_tlvs.hpp" 53 #include "thread/mle_tlvs.hpp" 54 #include "thread/mle_types.hpp" 55 #include "thread/neighbor_table.hpp" 56 #include "thread/network_data_types.hpp" 57 #include "thread/topology.hpp" 58 59 namespace ot { 60 61 /** 62 * @addtogroup core-mle MLE 63 * 64 * @brief 65 * This module includes definitions for the MLE protocol. 66 * 67 * @{ 68 * 69 * @defgroup core-mle-core Core 70 * @defgroup core-mle-router Router 71 * @defgroup core-mle-tlvs TLVs 72 * 73 * @} 74 */ 75 76 class SupervisionListener; 77 78 /** 79 * @namespace ot::Mle 80 * 81 * @brief 82 * This namespace includes definitions for the MLE protocol. 83 */ 84 85 namespace Mle { 86 87 /** 88 * @addtogroup core-mle-core 89 * 90 * @brief 91 * This module includes definitions for MLE functionality required by the Thread Child, Router, and Leader roles. 92 * 93 * @{ 94 * 95 */ 96 97 /** 98 * This class implements MLE functionality required by the Thread EndDevices, Router, and Leader roles. 99 * 100 */ 101 class Mle : public InstanceLocator, private NonCopyable 102 { 103 friend class DiscoverScanner; 104 friend class ot::Notifier; 105 friend class ot::SupervisionListener; 106 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE 107 friend class ot::LinkMetrics::Initiator; 108 #endif 109 110 public: 111 /** 112 * This constructor initializes the MLE object. 113 * 114 * @param[in] aInstance A reference to the OpenThread instance. 115 * 116 */ 117 explicit Mle(Instance &aInstance); 118 119 /** 120 * This method enables MLE. 121 * 122 * @retval kErrorNone Successfully enabled MLE. 123 * @retval kErrorAlready MLE was already enabled. 124 * 125 */ 126 Error Enable(void); 127 128 /** 129 * This method disables MLE. 130 * 131 * @retval kErrorNone Successfully disabled MLE. 132 * 133 */ 134 Error Disable(void); 135 136 /** 137 * This method starts the MLE protocol operation. 138 * 139 * @retval kErrorNone Successfully started the protocol operation. 140 * @retval kErrorInvalidState IPv6 interface is down or device is in raw-link mode. 141 * 142 */ Start(void)143 Error Start(void) { return Start(kNormalAttach); } 144 145 /** 146 * This method stops the MLE protocol operation. 147 * 148 */ Stop(void)149 void Stop(void) { Stop(kUpdateNetworkDatasets); } 150 151 /** 152 * This method restores network information from non-volatile memory (if any). 153 * 154 */ 155 void Restore(void); 156 157 /** 158 * This method stores network information into non-volatile memory. 159 * 160 * @retval kErrorNone Successfully store the network information. 161 * @retval kErrorNoBufs Could not store the network information due to insufficient memory space. 162 * 163 */ 164 Error Store(void); 165 166 /** 167 * This method generates an MLE Announce message. 168 * 169 * @param[in] aChannel The channel to use when transmitting. 170 * 171 */ SendAnnounce(uint8_t aChannel)172 void SendAnnounce(uint8_t aChannel) { SendAnnounce(aChannel, kNormalAnnounce); } 173 174 /** 175 * This method causes the Thread interface to detach from the Thread network. 176 * 177 * @retval kErrorNone Successfully detached from the Thread network. 178 * @retval kErrorInvalidState MLE is Disabled. 179 * 180 */ 181 Error BecomeDetached(void); 182 183 /** 184 * This method causes the Thread interface to attempt an MLE attach. 185 * 186 * @retval kErrorNone Successfully began the attach process. 187 * @retval kErrorInvalidState MLE is Disabled. 188 * @retval kErrorBusy An attach process is in progress. 189 * 190 */ 191 Error BecomeChild(void); 192 193 /** 194 * This function notifies other nodes in the network (if any) and then stops Thread protocol operation. 195 * 196 * It sends an Address Release if it's a router, or sets its child timeout to 0 if it's a child. 197 * 198 * @param[in] aCallback A pointer to a function that is called upon finishing detaching. 199 * @param[in] aContext A pointer to callback application-specific context. 200 * 201 * @retval kErrorNone Successfully started detaching. 202 * @retval kErrorBusy Detaching is already in progress. 203 * 204 */ 205 Error DetachGracefully(otDetachGracefullyCallback aCallback, void *aContext); 206 207 /** 208 * This method indicates whether or not the Thread device is attached to a Thread network. 209 * 210 * @retval TRUE Attached to a Thread network. 211 * @retval FALSE Not attached to a Thread network. 212 * 213 */ 214 bool IsAttached(void) const; 215 216 /** 217 * This method indicates whether device is currently attaching or not. 218 * 219 * Note that an already attached device may also be in attaching state. Examples of this include a leader/router 220 * trying to attach to a better partition, or a child trying to find a better parent (when feature 221 * `OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE` is enabled). 222 * 223 * @retval TRUE Device is currently trying to attach. 224 * @retval FALSE Device is not in middle of attach process. 225 * 226 */ IsAttaching(void) const227 bool IsAttaching(void) const { return (mAttachState != kAttachStateIdle); } 228 229 /** 230 * This method returns the current Thread device role. 231 * 232 * @returns The current Thread device role. 233 * 234 */ GetRole(void) const235 DeviceRole GetRole(void) const { return mRole; } 236 237 /** 238 * This method indicates whether device role is disabled. 239 * 240 * @retval TRUE Device role is disabled. 241 * @retval FALSE Device role is not disabled. 242 * 243 */ IsDisabled(void) const244 bool IsDisabled(void) const { return (mRole == kRoleDisabled); } 245 246 /** 247 * This method indicates whether device role is detached. 248 * 249 * @retval TRUE Device role is detached. 250 * @retval FALSE Device role is not detached. 251 * 252 */ IsDetached(void) const253 bool IsDetached(void) const { return (mRole == kRoleDetached); } 254 255 /** 256 * This method indicates whether device role is child. 257 * 258 * @retval TRUE Device role is child. 259 * @retval FALSE Device role is not child. 260 * 261 */ IsChild(void) const262 bool IsChild(void) const { return (mRole == kRoleChild); } 263 264 /** 265 * This method indicates whether device role is router. 266 * 267 * @retval TRUE Device role is router. 268 * @retval FALSE Device role is not router. 269 * 270 */ IsRouter(void) const271 bool IsRouter(void) const { return (mRole == kRoleRouter); } 272 273 /** 274 * This method indicates whether device role is leader. 275 * 276 * @retval TRUE Device role is leader. 277 * @retval FALSE Device role is not leader. 278 * 279 */ IsLeader(void) const280 bool IsLeader(void) const { return (mRole == kRoleLeader); } 281 282 /** 283 * This method indicates whether device role is either router or leader. 284 * 285 * @retval TRUE Device role is either router or leader. 286 * @retval FALSE Device role is neither router nor leader. 287 * 288 */ 289 bool IsRouterOrLeader(void) const; 290 291 /** 292 * This method returns the Device Mode as reported in the Mode TLV. 293 * 294 * @returns The Device Mode as reported in the Mode TLV. 295 * 296 */ GetDeviceMode(void) const297 DeviceMode GetDeviceMode(void) const { return mDeviceMode; } 298 299 /** 300 * This method sets the Device Mode as reported in the Mode TLV. 301 * 302 * @param[in] aDeviceMode The device mode to set. 303 * 304 * @retval kErrorNone Successfully set the Mode TLV. 305 * @retval kErrorInvalidArgs The mode combination specified in @p aMode is invalid. 306 * 307 */ 308 Error SetDeviceMode(DeviceMode aDeviceMode); 309 310 /** 311 * This method indicates whether or not the device is rx-on-when-idle. 312 * 313 * @returns TRUE if rx-on-when-idle, FALSE otherwise. 314 * 315 */ IsRxOnWhenIdle(void) const316 bool IsRxOnWhenIdle(void) const { return mDeviceMode.IsRxOnWhenIdle(); } 317 318 /** 319 * This method indicates whether or not the device is a Full Thread Device. 320 * 321 * @returns TRUE if a Full Thread Device, FALSE otherwise. 322 * 323 */ IsFullThreadDevice(void) const324 bool IsFullThreadDevice(void) const { return mDeviceMode.IsFullThreadDevice(); } 325 326 /** 327 * This method indicates whether or not the device is a Minimal End Device. 328 * 329 * @returns TRUE if the device is a Minimal End Device, FALSE otherwise. 330 * 331 */ IsMinimalEndDevice(void) const332 bool IsMinimalEndDevice(void) const { return mDeviceMode.IsMinimalEndDevice(); } 333 334 /** 335 * This method gets the Network Data type (full set or stable subset) that this device requests. 336 * 337 * @returns The Network Data type requested by this device. 338 * 339 */ GetNetworkDataType(void) const340 NetworkData::Type GetNetworkDataType(void) const { return mDeviceMode.GetNetworkDataType(); } 341 342 /** 343 * This method returns a pointer to the Mesh Local Prefix. 344 * 345 * @returns A reference to the Mesh Local Prefix. 346 * 347 */ GetMeshLocalPrefix(void) const348 const Ip6::NetworkPrefix &GetMeshLocalPrefix(void) const { return mMeshLocal16.GetAddress().GetPrefix(); } 349 350 /** 351 * This method sets the Mesh Local Prefix. 352 * 353 * @param[in] aMeshLocalPrefix A reference to the Mesh Local Prefix. 354 * 355 */ 356 void SetMeshLocalPrefix(const Ip6::NetworkPrefix &aMeshLocalPrefix); 357 358 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 359 /** 360 * This method sets the Mesh Local IID. 361 * 362 * Available only when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled. 363 * 364 * @param[in] aMlIid The Mesh Local IID. 365 * 366 * @retval kErrorNone Successfully configured Mesh Local IID. 367 * @retval kErrorInvalidState If the Thread stack is already enabled. 368 * 369 */ 370 Error SetMeshLocalIid(const Ip6::InterfaceIdentifier &aMlIid); 371 #endif 372 373 /** 374 * This method applies the Mesh Local Prefix. 375 * 376 */ 377 void ApplyMeshLocalPrefix(void); 378 379 /** 380 * This method returns a reference to the Thread link-local address. 381 * 382 * The Thread link local address is derived using IEEE802.15.4 Extended Address as Interface Identifier. 383 * 384 * @returns A reference to the Thread link local address. 385 * 386 */ GetLinkLocalAddress(void) const387 const Ip6::Address &GetLinkLocalAddress(void) const { return mLinkLocal64.GetAddress(); } 388 389 /** 390 * This method updates the link local address. 391 * 392 * Call this method when the IEEE 802.15.4 Extended Address has changed. 393 * 394 */ 395 void UpdateLinkLocalAddress(void); 396 397 /** 398 * This method returns a reference to the link-local all Thread nodes multicast address. 399 * 400 * @returns A reference to the link-local all Thread nodes multicast address. 401 * 402 */ GetLinkLocalAllThreadNodesAddress(void) const403 const Ip6::Address &GetLinkLocalAllThreadNodesAddress(void) const { return mLinkLocalAllThreadNodes.GetAddress(); } 404 405 /** 406 * This method returns a reference to the realm-local all Thread nodes multicast address. 407 * 408 * @returns A reference to the realm-local all Thread nodes multicast address. 409 * 410 */ GetRealmLocalAllThreadNodesAddress(void) const411 const Ip6::Address &GetRealmLocalAllThreadNodesAddress(void) const 412 { 413 return mRealmLocalAllThreadNodes.GetAddress(); 414 } 415 416 /** 417 * This method gets the parent when operating in End Device mode. 418 * 419 * @returns A reference to the parent. 420 * 421 */ GetParent(void)422 Parent &GetParent(void) { return mParent; } 423 424 /** 425 * This method gets the parent when operating in End Device mode. 426 * 427 * @returns A reference to the parent. 428 * 429 */ GetParent(void) const430 const Parent &GetParent(void) const { return mParent; } 431 432 /** 433 * The method retrieves information about the parent. 434 * 435 * @param[out] aParentInfo Reference to a parent information structure. 436 * 437 * @retval kErrorNone Successfully retrieved the parent info and updated @p aParentInfo. 438 * @retval kErrorInvalidState Device role is not child. 439 * 440 */ 441 Error GetParentInfo(Router::Info &aParentInfo) const; 442 443 /** 444 * This method get the parent candidate. 445 * 446 * The parent candidate is valid when attempting to attach to a new parent. 447 * 448 */ GetParentCandidate(void)449 Parent &GetParentCandidate(void) { return mParentCandidate; } 450 451 /** 452 * This method starts the process for child to search for a better parent while staying attached to its current 453 * parent 454 * 455 * @retval kErrorNone Successfully started the process to search for a better parent. 456 * @retval kErrorInvalidState Device role is not child. 457 * 458 */ 459 Error SearchForBetterParent(void); 460 461 /** 462 * This method indicates whether or not an IPv6 address is an RLOC. 463 * 464 * @retval TRUE If @p aAddress is an RLOC. 465 * @retval FALSE If @p aAddress is not an RLOC. 466 * 467 */ 468 bool IsRoutingLocator(const Ip6::Address &aAddress) const; 469 470 /** 471 * This method indicates whether or not an IPv6 address is an ALOC. 472 * 473 * @retval TRUE If @p aAddress is an ALOC. 474 * @retval FALSE If @p aAddress is not an ALOC. 475 * 476 */ 477 bool IsAnycastLocator(const Ip6::Address &aAddress) const; 478 479 /** 480 * This method indicates whether or not an IPv6 address is a Mesh Local Address. 481 * 482 * @retval TRUE If @p aAddress is a Mesh Local Address. 483 * @retval FALSE If @p aAddress is not a Mesh Local Address. 484 * 485 */ 486 bool IsMeshLocalAddress(const Ip6::Address &aAddress) const; 487 488 /** 489 * This method returns the MLE Timeout value. 490 * 491 * @returns The MLE Timeout value in seconds. 492 * 493 */ GetTimeout(void) const494 uint32_t GetTimeout(void) const { return mTimeout; } 495 496 /** 497 * This method sets the MLE Timeout value. 498 * 499 * @param[in] aTimeout The Timeout value in seconds. 500 * 501 */ 502 void SetTimeout(uint32_t aTimeout); 503 504 /** 505 * This method returns the RLOC16 assigned to the Thread interface. 506 * 507 * @returns The RLOC16 assigned to the Thread interface. 508 * 509 */ GetRloc16(void) const510 uint16_t GetRloc16(void) const { return mRloc16; } 511 512 /** 513 * This method returns a reference to the RLOC assigned to the Thread interface. 514 * 515 * @returns A reference to the RLOC assigned to the Thread interface. 516 * 517 */ GetMeshLocal16(void) const518 const Ip6::Address &GetMeshLocal16(void) const { return mMeshLocal16.GetAddress(); } 519 520 /** 521 * This method returns a reference to the ML-EID assigned to the Thread interface. 522 * 523 * @returns A reference to the ML-EID assigned to the Thread interface. 524 * 525 */ GetMeshLocal64(void) const526 const Ip6::Address &GetMeshLocal64(void) const { return mMeshLocal64.GetAddress(); } 527 528 /** 529 * This method returns the Router ID of the Leader. 530 * 531 * @returns The Router ID of the Leader. 532 * 533 */ GetLeaderId(void) const534 uint8_t GetLeaderId(void) const { return mLeaderData.GetLeaderRouterId(); } 535 536 /** 537 * This method retrieves the Leader's RLOC. 538 * 539 * @param[out] aAddress A reference to the Leader's RLOC. 540 * 541 * @retval kErrorNone Successfully retrieved the Leader's RLOC. 542 * @retval kErrorDetached The Thread interface is not currently attached to a Thread Partition. 543 * 544 */ 545 Error GetLeaderAddress(Ip6::Address &aAddress) const; 546 547 /** 548 * This method retrieves the Leader's ALOC. 549 * 550 * @param[out] aAddress A reference to the Leader's ALOC. 551 * 552 * @retval kErrorNone Successfully retrieved the Leader's ALOC. 553 * @retval kErrorDetached The Thread interface is not currently attached to a Thread Partition. 554 * 555 */ GetLeaderAloc(Ip6::Address & aAddress) const556 Error GetLeaderAloc(Ip6::Address &aAddress) const { return GetLocatorAddress(aAddress, kAloc16Leader); } 557 558 /** 559 * This method computes the Commissioner's ALOC. 560 * 561 * @param[out] aAddress A reference to the Commissioner's ALOC. 562 * @param[in] aSessionId Commissioner session id. 563 * 564 * @retval kErrorNone Successfully retrieved the Commissioner's ALOC. 565 * @retval kErrorDetached The Thread interface is not currently attached to a Thread Partition. 566 * 567 */ GetCommissionerAloc(Ip6::Address & aAddress,uint16_t aSessionId) const568 Error GetCommissionerAloc(Ip6::Address &aAddress, uint16_t aSessionId) const 569 { 570 return GetLocatorAddress(aAddress, CommissionerAloc16FromId(aSessionId)); 571 } 572 573 /** 574 * This method retrieves the Service ALOC for given Service ID. 575 * 576 * @param[in] aServiceId Service ID to get ALOC for. 577 * @param[out] aAddress A reference to the Service ALOC. 578 * 579 * @retval kErrorNone Successfully retrieved the Service ALOC. 580 * @retval kErrorDetached The Thread interface is not currently attached to a Thread Partition. 581 * 582 */ 583 Error GetServiceAloc(uint8_t aServiceId, Ip6::Address &aAddress) const; 584 585 /** 586 * This method returns the most recently received Leader Data. 587 * 588 * @returns A reference to the most recently received Leader Data. 589 * 590 */ 591 const LeaderData &GetLeaderData(void); 592 593 /** 594 * This method returns a reference to the send queue. 595 * 596 * @returns A reference to the send queue. 597 * 598 */ GetMessageQueue(void) const599 const MessageQueue &GetMessageQueue(void) const { return mDelayedResponses; } 600 601 /** 602 * This method frees multicast MLE Data Response from Delayed Message Queue if any. 603 * 604 */ 605 void RemoveDelayedDataResponseMessage(void); 606 607 /** 608 * This method gets the MLE counters. 609 * 610 * @returns A reference to the MLE counters. 611 * 612 */ GetCounters(void)613 const Counters &GetCounters(void) 614 { 615 #if OPENTHREAD_CONFIG_UPTIME_ENABLE 616 UpdateRoleTimeCounters(mRole); 617 #endif 618 return mCounters; 619 } 620 621 /** 622 * This method resets the MLE counters. 623 * 624 */ 625 void ResetCounters(void); 626 627 #if OPENTHREAD_CONFIG_MLE_PARENT_RESPONSE_CALLBACK_API_ENABLE 628 /** 629 * This function registers the client callback that is called when processing an MLE Parent Response message. 630 * 631 * @param[in] aCallback A pointer to a function that is called to deliver MLE Parent Response data. 632 * @param[in] aContext A pointer to application-specific context. 633 * 634 */ RegisterParentResponseStatsCallback(otThreadParentResponseCallback aCallback,void * aContext)635 void RegisterParentResponseStatsCallback(otThreadParentResponseCallback aCallback, void *aContext) 636 { 637 mParentResponseCallback.Set(aCallback, aContext); 638 } 639 #endif 640 641 /** 642 * This method requests MLE layer to prepare and send a shorter version of Child ID Request message by only 643 * including the mesh-local IPv6 address in the Address Registration TLV. 644 * 645 * This method should be called when a previous MLE Child ID Request message would require fragmentation at 6LoWPAN 646 * layer. 647 * 648 */ 649 void RequestShorterChildIdRequest(void); 650 651 /** 652 * This method gets the RLOC or ALOC of a given RLOC16 or ALOC16. 653 * 654 * @param[out] aAddress A reference to the RLOC or ALOC. 655 * @param[in] aLocator RLOC16 or ALOC16. 656 * 657 * @retval kErrorNone If got the RLOC or ALOC successfully. 658 * @retval kErrorDetached If device is detached. 659 * 660 */ 661 Error GetLocatorAddress(Ip6::Address &aAddress, uint16_t aLocator) const; 662 663 /** 664 * This method schedules a Child Update Request. 665 * 666 */ 667 void ScheduleChildUpdateRequest(void); 668 669 /* 670 * This method indicates whether or not the device has restored the network information from 671 * non-volatile settings after boot. 672 * 673 * @retval true Successfully restored the network information. 674 * @retval false No valid network information was found. 675 * 676 */ HasRestored(void) const677 bool HasRestored(void) const { return mHasRestored; } 678 679 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 680 /** 681 * This method gets the CSL timeout. 682 * 683 * @returns CSL timeout 684 * 685 */ GetCslTimeout(void) const686 uint32_t GetCslTimeout(void) const { return mCslTimeout; } 687 688 /** 689 * This method sets the CSL timeout. 690 * 691 * @param[in] aTimeout The CSL timeout in seconds. 692 * 693 */ 694 void SetCslTimeout(uint32_t aTimeout); 695 696 /** 697 * This method calculates CSL metric of parent. 698 * 699 * @param[in] aCslAccuracy The CSL accuracy. 700 * 701 * @returns CSL metric. 702 * 703 */ 704 uint64_t CalcParentCslMetric(const Mac::CslAccuracy &aCslAccuracy) const; 705 706 #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 707 708 protected: 709 /** 710 * MLE Command Types. 711 * 712 */ 713 enum Command : uint8_t 714 { 715 kCommandLinkRequest = 0, ///< Link Request 716 kCommandLinkAccept = 1, ///< Link Accept 717 kCommandLinkAcceptAndRequest = 2, ///< Link Accept and Reject 718 kCommandLinkReject = 3, ///< Link Reject 719 kCommandAdvertisement = 4, ///< Advertisement 720 kCommandUpdate = 5, ///< Update 721 kCommandUpdateRequest = 6, ///< Update Request 722 kCommandDataRequest = 7, ///< Data Request 723 kCommandDataResponse = 8, ///< Data Response 724 kCommandParentRequest = 9, ///< Parent Request 725 kCommandParentResponse = 10, ///< Parent Response 726 kCommandChildIdRequest = 11, ///< Child ID Request 727 kCommandChildIdResponse = 12, ///< Child ID Response 728 kCommandChildUpdateRequest = 13, ///< Child Update Request 729 kCommandChildUpdateResponse = 14, ///< Child Update Response 730 kCommandAnnounce = 15, ///< Announce 731 kCommandDiscoveryRequest = 16, ///< Discovery Request 732 kCommandDiscoveryResponse = 17, ///< Discovery Response 733 kCommandLinkMetricsManagementRequest = 18, ///< Link Metrics Management Request 734 kCommandLinkMetricsManagementResponse = 19, ///< Link Metrics Management Response 735 kCommandLinkProbe = 20, ///< Link Probe 736 kCommandTimeSync = 99, ///< Time Sync (when OPENTHREAD_CONFIG_TIME_SYNC_ENABLE enabled) 737 }; 738 739 /** 740 * Attach mode. 741 * 742 */ 743 enum AttachMode : uint8_t 744 { 745 kAnyPartition, ///< Attach to any Thread partition. 746 kSamePartition, ///< Attach to the same Thread partition (attempt 1 when losing connectivity). 747 kSamePartitionRetry, ///< Attach to the same Thread partition (attempt 2 when losing connectivity). 748 kBetterPartition, ///< Attach to a better (i.e. higher weight/partition id) Thread partition. 749 kDowngradeToReed, ///< Attach to the same Thread partition during downgrade process. 750 kBetterParent, ///< Attach to a better parent. 751 }; 752 753 /** 754 * States during attach (when searching for a parent). 755 * 756 */ 757 enum AttachState : uint8_t 758 { 759 kAttachStateIdle, ///< Not currently searching for a parent. 760 kAttachStateProcessAnnounce, ///< Waiting to process a received Announce (to switch channel/pan-id). 761 kAttachStateStart, ///< Starting to look for a parent. 762 kAttachStateParentRequest, ///< Send Parent Request (current number tracked by `mParentRequestCounter`). 763 kAttachStateAnnounce, ///< Send Announce messages 764 kAttachStateChildIdRequest, ///< Sending a Child ID Request message. 765 }; 766 767 /** 768 * States when reattaching network using stored dataset 769 * 770 */ 771 enum ReattachState : uint8_t 772 { 773 kReattachStop, ///< Reattach process is disabled or finished 774 kReattachStart, ///< Start reattach process 775 kReattachActive, ///< Reattach using stored Active Dataset 776 kReattachPending, ///< Reattach using stored Pending Dataset 777 }; 778 779 static constexpr uint16_t kMleMaxResponseDelay = 1000u; ///< Max delay before responding to a multicast request. 780 781 /** 782 * This enumeration type is used in `AppendAddressRegistrationTlv()` to determine which addresses to include in the 783 * appended Address Registration TLV. 784 * 785 */ 786 enum AddressRegistrationMode : uint8_t 787 { 788 kAppendAllAddresses, ///< Append all addresses (unicast/multicast) in Address Registration TLV. 789 kAppendMeshLocalOnly, ///< Only append the Mesh Local (ML-EID) address in Address Registration TLV. 790 }; 791 792 /** 793 * This enumeration represents the message actions used in `Log()` methods. 794 * 795 */ 796 enum MessageAction : uint8_t 797 { 798 kMessageSend, 799 kMessageReceive, 800 kMessageDelay, 801 kMessageRemoveDelayed, 802 }; 803 804 /** 805 * This enumeration represents message types used in `Log()` methods. 806 * 807 */ 808 enum MessageType : uint8_t 809 { 810 kTypeAdvertisement, 811 kTypeAnnounce, 812 kTypeChildIdRequest, 813 kTypeChildIdRequestShort, 814 kTypeChildIdResponse, 815 kTypeChildUpdateRequestOfParent, 816 kTypeChildUpdateResponseOfParent, 817 kTypeDataRequest, 818 kTypeDataResponse, 819 kTypeDiscoveryRequest, 820 kTypeDiscoveryResponse, 821 kTypeGenericDelayed, 822 kTypeGenericUdp, 823 kTypeParentRequestToRouters, 824 kTypeParentRequestToRoutersReeds, 825 kTypeParentResponse, 826 #if OPENTHREAD_FTD 827 kTypeAddressRelease, 828 kTypeAddressReleaseReply, 829 kTypeAddressReply, 830 kTypeAddressSolicit, 831 kTypeChildUpdateRequestOfChild, 832 kTypeChildUpdateResponseOfChild, 833 kTypeChildUpdateResponseOfUnknownChild, 834 kTypeLinkAccept, 835 kTypeLinkAcceptAndRequest, 836 kTypeLinkReject, 837 kTypeLinkRequest, 838 kTypeParentRequest, 839 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 840 kTypeTimeSync, 841 #endif 842 #endif 843 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 844 kTypeLinkMetricsManagementRequest, 845 kTypeLinkMetricsManagementResponse, 846 kTypeLinkProbe, 847 #endif 848 }; 849 850 static constexpr uint8_t kMaxTlvListSize = 32; ///< Maximum number of TLVs in a `TlvList`. 851 852 /** 853 * This type represents a list of TLVs (array of TLV types). 854 * 855 */ 856 class TlvList : public Array<uint8_t, kMaxTlvListSize> 857 { 858 public: 859 /** 860 * This constructor initializes the `TlvList` as empty. 861 * 862 */ 863 TlvList(void) = default; 864 865 /** 866 * This method checks if a given TLV type is not already present in the list and adds it in the list. 867 * 868 * If the list is full, this method logs it as a warning. 869 * 870 * @param[in] aTlvType The TLV type to add to the list. 871 * 872 */ 873 void Add(uint8_t aTlvType); 874 875 /** 876 * This method adds elements from a given list to this TLV list (if not already present in the list). 877 * 878 * @param[in] aTlvList The TLV list to add elements from. 879 * 880 */ 881 void AddElementsFrom(const TlvList &aTlvList); 882 }; 883 884 /** 885 * This type represents a Challenge (or Response) data. 886 * 887 */ 888 struct Challenge 889 { 890 uint8_t mBuffer[kMaxChallengeSize]; ///< Buffer containing the challenge/response byte sequence. 891 uint8_t mLength; ///< Challenge length (in bytes). 892 893 /** 894 * This method generates a cryptographically secure random sequence to populate the challenge data. 895 * 896 */ 897 void GenerateRandom(void); 898 899 /** 900 * This method indicates whether the Challenge matches a given buffer. 901 * 902 * @param[in] aBuffer A pointer to a buffer to compare with the Challenge. 903 * @param[in] aLength Length of @p aBuffer (in bytes). 904 * 905 * @retval TRUE If the Challenge matches the given buffer. 906 * @retval FALSE If the Challenge does not match the given buffer. 907 * 908 */ 909 bool Matches(const uint8_t *aBuffer, uint8_t aLength) const; 910 911 /** 912 * This method indicates whether two Challenge data byte sequences are equal or not. 913 * 914 * @param[in] aOther Another Challenge data to compare. 915 * 916 * @retval TRUE If the two Challenges match. 917 * @retval FALSE If the two Challenges do not match. 918 * 919 */ operator ==ot::Mle::Mle::Challenge920 bool operator==(const Challenge &aOther) const { return Matches(aOther.mBuffer, aOther.mLength); } 921 }; 922 923 /** 924 * This class represents an MLE Tx message. 925 * 926 */ 927 class TxMessage : public Message 928 { 929 public: 930 /** 931 * This method appends a Source Address TLV to the message. 932 * 933 * @retval kErrorNone Successfully appended the Source Address TLV. 934 * @retval kErrorNoBufs Insufficient buffers available to append the Source Address TLV. 935 * 936 */ 937 Error AppendSourceAddressTlv(void); 938 939 /** 940 * This method appends a Mode TLV to the message. 941 * 942 * @param[in] aMode The Device Mode. 943 * 944 * @retval kErrorNone Successfully appended the Mode TLV. 945 * @retval kErrorNoBufs Insufficient buffers available to append the Mode TLV. 946 * 947 */ 948 Error AppendModeTlv(DeviceMode aMode); 949 950 /** 951 * This method appends a Timeout TLV to the message. 952 * 953 * @param[in] aTimeout The Timeout value. 954 * 955 * @retval kErrorNone Successfully appended the Timeout TLV. 956 * @retval kErrorNoBufs Insufficient buffers available to append the Timeout TLV. 957 * 958 */ 959 Error AppendTimeoutTlv(uint32_t aTimeout); 960 961 /** 962 * This method appends a Challenge TLV to the message. 963 * 964 * @param[in] aChallenge A pointer to the Challenge value. 965 * @param[in] aChallengeLength The length of the Challenge value in bytes. 966 * 967 * @retval kErrorNone Successfully appended the Challenge TLV. 968 * @retval kErrorNoBufs Insufficient buffers available to append the Challenge TLV. 969 * 970 */ 971 Error AppendChallengeTlv(const uint8_t *aChallenge, uint8_t aChallengeLength); 972 973 /** 974 * This method appends a Challenge TLV to the message. 975 * 976 * @param[in] aChallenge A reference to the Challenge data. 977 * 978 * @retval kErrorNone Successfully appended the Challenge TLV. 979 * @retval kErrorNoBufs Insufficient buffers available to append the Challenge TLV. 980 * 981 */ 982 Error AppendChallengeTlv(const Challenge &aChallenge); 983 984 /** 985 * This method appends a Response TLV to the message. 986 * 987 * @param[in] aResponse A reference to the Response data. 988 * 989 * @retval kErrorNone Successfully appended the Response TLV. 990 * @retval kErrorNoBufs Insufficient buffers available to append the Response TLV. 991 * 992 */ 993 Error AppendResponseTlv(const Challenge &aResponse); 994 995 /** 996 * This method appends a Link Frame Counter TLV to the message. 997 * 998 * @retval kErrorNone Successfully appended the Link Frame Counter TLV. 999 * @retval kErrorNoBufs Insufficient buffers available to append the Link Frame Counter TLV. 1000 * 1001 */ 1002 Error AppendLinkFrameCounterTlv(void); 1003 1004 /** 1005 * This method appends an MLE Frame Counter TLV to the message. 1006 * 1007 * @retval kErrorNone Successfully appended the Frame Counter TLV. 1008 * @retval kErrorNoBufs Insufficient buffers available to append the MLE Frame Counter TLV. 1009 * 1010 */ 1011 Error AppendMleFrameCounterTlv(void); 1012 1013 /** 1014 * This method appends an Address16 TLV to the message. 1015 * 1016 * @param[in] aRloc16 The RLOC16 value. 1017 * 1018 * @retval kErrorNone Successfully appended the Address16 TLV. 1019 * @retval kErrorNoBufs Insufficient buffers available to append the Address16 TLV. 1020 * 1021 */ 1022 Error AppendAddress16Tlv(uint16_t aRloc16); 1023 1024 /** 1025 * This method appends a Network Data TLV to the message. 1026 * 1027 * @param[in] aType The Network Data type to append, full set or stable subset. 1028 * 1029 * @retval kErrorNone Successfully appended the Network Data TLV. 1030 * @retval kErrorNoBufs Insufficient buffers available to append the Network Data TLV. 1031 * 1032 */ 1033 Error AppendNetworkDataTlv(NetworkData::Type aType); 1034 1035 /** 1036 * This method appends a TLV Request TLV to the message. 1037 * 1038 * @param[in] aTlvs A pointer to the list of TLV types. 1039 * @param[in] aTlvsLength The number of TLV types in @p aTlvs 1040 * 1041 * @retval kErrorNone Successfully appended the TLV Request TLV. 1042 * @retval kErrorNoBufs Insufficient buffers available to append the TLV Request TLV. 1043 * 1044 */ 1045 Error AppendTlvRequestTlv(const uint8_t *aTlvs, uint8_t aTlvsLength); 1046 1047 /** 1048 * This method appends a TLV Request TLV to the message. 1049 * 1050 * @tparam kArrayLength The TLV array length. 1051 * 1052 * @param[in] aTlvArray A reference to an array of TLV types of @p kArrayLength length. 1053 * 1054 * @retval kErrorNone Successfully appended the TLV Request TLV. 1055 * @retval kErrorNoBufs Insufficient buffers available to append the TLV Request TLV. 1056 * 1057 */ AppendTlvRequestTlv(const uint8_t (& aTlvArray)[kArrayLength])1058 template <uint8_t kArrayLength> Error AppendTlvRequestTlv(const uint8_t (&aTlvArray)[kArrayLength]) 1059 { 1060 return AppendTlvRequestTlv(aTlvArray, kArrayLength); 1061 } 1062 1063 /** 1064 * This method appends a Leader Data TLV to the message. 1065 * 1066 * @retval kErrorNone Successfully appended the Leader Data TLV. 1067 * @retval kErrorNoBufs Insufficient buffers available to append the Leader Data TLV. 1068 * 1069 */ 1070 Error AppendLeaderDataTlv(void); 1071 1072 /** 1073 * This method appends a Scan Mask TLV to th message. 1074 * 1075 * @param[in] aScanMask The Scan Mask value. 1076 * 1077 * @retval kErrorNone Successfully appended the Scan Mask TLV. 1078 * @retval kErrorNoBufs Insufficient buffers available to append the Scan Mask TLV. 1079 * 1080 */ 1081 Error AppendScanMaskTlv(uint8_t aScanMask); 1082 1083 /** 1084 * This method appends a Status TLV to the message. 1085 * 1086 * @param[in] aStatus The Status value. 1087 * 1088 * @retval kErrorNone Successfully appended the Status TLV. 1089 * @retval kErrorNoBufs Insufficient buffers available to append the Status TLV. 1090 * 1091 */ 1092 Error AppendStatusTlv(StatusTlv::Status aStatus); 1093 1094 /** 1095 * This method appends a Link Margin TLV to the message. 1096 * 1097 * @param[in] aLinkMargin The Link Margin value. 1098 * 1099 * @retval kErrorNone Successfully appended the Link Margin TLV. 1100 * @retval kErrorNoBufs Insufficient buffers available to append the Link Margin TLV. 1101 * 1102 */ 1103 Error AppendLinkMarginTlv(uint8_t aLinkMargin); 1104 1105 /** 1106 * This method appends a Version TLV to the message. 1107 * 1108 * @retval kErrorNone Successfully appended the Version TLV. 1109 * @retval kErrorNoBufs Insufficient buffers available to append the Version TLV. 1110 * 1111 */ 1112 Error AppendVersionTlv(void); 1113 1114 /** 1115 * This method appends an Address Registration TLV to the message. 1116 * 1117 * @param[in] aMode Determines which addresses to include in the TLV (see `AddressRegistrationMode`). 1118 * 1119 * @retval kErrorNone Successfully appended the Address Registration TLV. 1120 * @retval kErrorNoBufs Insufficient buffers available to append the Address Registration TLV. 1121 * 1122 */ 1123 Error AppendAddressRegistrationTlv(AddressRegistrationMode aMode = kAppendAllAddresses); 1124 1125 /** 1126 * This method appends a Supervision Interval TLV to the message. 1127 * 1128 * @param[in] aInterval The interval value. 1129 * 1130 * @retval kErrorNone Successfully appended the Supervision Interval TLV. 1131 * @retval kErrorNoBufs Insufficient buffers available to append the Supervision Interval TLV. 1132 * 1133 */ 1134 Error AppendSupervisionIntervalTlv(uint16_t aInterval); 1135 1136 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 1137 /** 1138 * This method appends a Time Request TLV to the message. 1139 * 1140 * @retval kErrorNone Successfully appended the Time Request TLV. 1141 * @retval kErrorNoBufs Insufficient buffers available to append the Time Request TLV. 1142 * 1143 */ 1144 Error AppendTimeRequestTlv(void); 1145 1146 /** 1147 * This method appends a Time Parameter TLV to the message. 1148 * 1149 * @retval kErrorNone Successfully appended the Time Parameter TLV. 1150 * @retval kErrorNoBufs Insufficient buffers available to append the Time Parameter TLV. 1151 * 1152 */ 1153 Error AppendTimeParameterTlv(void); 1154 #endif 1155 /** 1156 * This method appends a XTAL Accuracy TLV to the message. 1157 * 1158 * @retval kErrorNone Successfully appended the XTAL Accuracy TLV. 1159 * @retval kErrorNoBufs Insufficient buffers available to append the XTAl Accuracy TLV. 1160 * 1161 */ 1162 Error AppendXtalAccuracyTlv(void); 1163 1164 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 1165 /** 1166 * This method appends a CSL Channel TLV to the message. 1167 * 1168 * @retval kErrorNone Successfully appended the CSL Channel TLV. 1169 * @retval kErrorNoBufs Insufficient buffers available to append the CSL Channel TLV. 1170 * 1171 */ 1172 Error AppendCslChannelTlv(void); 1173 1174 /** 1175 * This method appends a CSL Sync Timeout TLV to the message. 1176 * 1177 * @retval kErrorNone Successfully appended the CSL Timeout TLV. 1178 * @retval kErrorNoBufs Insufficient buffers available to append the CSL Timeout TLV. 1179 * 1180 */ 1181 Error AppendCslTimeoutTlv(void); 1182 #endif 1183 1184 #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE 1185 /** 1186 * This method appends a CSL Clock Accuracy TLV to the message. 1187 * 1188 * @retval kErrorNone Successfully appended the CSL Accuracy TLV. 1189 * @retval kErrorNoBufs Insufficient buffers available to append the CSL Accuracy TLV. 1190 * 1191 */ 1192 Error AppendCslClockAccuracyTlv(void); 1193 #endif 1194 1195 /** 1196 * This method appends a Active Timestamp TLV to the message. 1197 * 1198 * @retval kErrorNone Successfully appended the Active Timestamp TLV. 1199 * @retval kErrorNoBufs Insufficient buffers available to append the Active Timestamp TLV. 1200 * 1201 */ 1202 Error AppendActiveTimestampTlv(void); 1203 1204 /** 1205 * This method appends a Pending Timestamp TLV to the message. 1206 * 1207 * @retval kErrorNone Successfully appended the Pending Timestamp TLV. 1208 * @retval kErrorNoBufs Insufficient buffers available to append the Pending Timestamp TLV. 1209 * 1210 */ 1211 Error AppendPendingTimestampTlv(void); 1212 1213 #if OPENTHREAD_FTD 1214 /** 1215 * This method appends a Route TLV to the message. 1216 * 1217 * @param[in] aNeighbor A pointer to the intended destination (can be `nullptr`). 1218 * 1219 * @retval kErrorNone Successfully appended the Route TLV. 1220 * @retval kErrorNoBufs Insufficient buffers available to append the Route TLV. 1221 * 1222 */ 1223 Error AppendRouteTlv(Neighbor *aNeighbor = nullptr); 1224 1225 /** 1226 * This method appends a Active Dataset TLV to the message. 1227 * 1228 * @retval kErrorNone Successfully appended the Active Dataset TLV. 1229 * @retval kErrorNoBufs Insufficient buffers available to append the Active Dataset TLV. 1230 * 1231 */ 1232 Error AppendActiveDatasetTlv(void); 1233 1234 /** 1235 * This method appends a Pending Dataset TLV to the message. 1236 * 1237 * @retval kErrorNone Successfully appended the Pending Dataset TLV. 1238 * @retval kErrorNoBufs Insufficient buffers available to append the Pending Dataset TLV. 1239 * 1240 */ 1241 Error AppendPendingDatasetTlv(void); 1242 1243 /** 1244 * This method appends a Connectivity TLV to the message. 1245 * 1246 * @retval kErrorNone Successfully appended the Connectivity TLV. 1247 * @retval kErrorNoBufs Insufficient buffers available to append the Connectivity TLV. 1248 * 1249 */ 1250 Error AppendConnectivityTlv(void); 1251 1252 /** 1253 * This method appends a Address Registration TLV to the message with addresses from a given child. 1254 * 1255 * @param[in] aChild The child to include its list of addresses in the Address Registration TLV. 1256 * 1257 * @retval kErrorNone Successfully appended the Connectivity TLV. 1258 * @retval kErrorNoBufs Insufficient buffers available to append the Connectivity TLV. 1259 * 1260 */ 1261 Error AppendAddressRegistrationTlv(Child &aChild); 1262 #endif // OPENTHREAD_FTD 1263 1264 /** 1265 * This method submits the MLE message to the UDP socket to be sent. 1266 * 1267 * @param[in] aDestination A reference to the IPv6 address of the destination. 1268 * 1269 * @retval kErrorNone Successfully submitted the MLE message. 1270 * @retval kErrorNoBufs Insufficient buffers to form the rest of the MLE message. 1271 * 1272 */ 1273 Error SendTo(const Ip6::Address &aDestination); 1274 1275 /** 1276 * This method enqueues the message to be sent after a given delay. 1277 * 1278 * @param[in] aDestination The IPv6 address of the recipient of the message. 1279 * @param[in] aDelay The delay in milliseconds before transmission of the message. 1280 * 1281 * @retval kErrorNone Successfully queued the message to transmit after the delay. 1282 * @retval kErrorNoBufs Insufficient buffers to queue the message. 1283 * 1284 */ 1285 Error SendAfterDelay(const Ip6::Address &aDestination, uint16_t aDelay); 1286 1287 private: 1288 Error AppendCompressedAddressEntry(uint8_t aContextId, const Ip6::Address &aAddress); 1289 Error AppendAddressEntry(const Ip6::Address &aAddress); 1290 }; 1291 1292 /** 1293 * This class represents an MLE Rx message. 1294 * 1295 */ 1296 class RxMessage : public Message 1297 { 1298 public: 1299 /** 1300 * This method reads Challenge TLV from the message. 1301 * 1302 * @param[out] aChallenge A reference to the Challenge data where to output the read value. 1303 * 1304 * @retval kErrorNone Successfully read the Challenge TLV. 1305 * @retval kErrorNotFound Challenge TLV was not found in the message. 1306 * @retval kErrorParse Challenge TLV was found but could not be parsed. 1307 * 1308 */ 1309 Error ReadChallengeTlv(Challenge &aChallenge) const; 1310 1311 /** 1312 * This method reads Response TLV from the message. 1313 * 1314 * @param[out] aResponse A reference to the Response data where to output the read value. 1315 * 1316 * @retval kErrorNone Successfully read the Response TLV. 1317 * @retval kErrorNotFound Response TLV was not found in the message. 1318 * @retval kErrorParse Response TLV was found but could not be parsed. 1319 * 1320 */ 1321 Error ReadResponseTlv(Challenge &aResponse) const; 1322 1323 /** 1324 * This method reads Link and MLE Frame Counters from the message. 1325 * 1326 * Link Frame Counter TLV must be present in the message and its value is read into @p aLinkFrameCounter. If MLE 1327 * Frame Counter TLV is present in the message, its value is read into @p aMleFrameCounter. If the MLE Frame 1328 * Counter TLV is not present in the message, then @p aMleFrameCounter is set to the same value as 1329 * @p aLinkFrameCounter. 1330 * 1331 * @param[out] aLinkFrameCounter A reference to an `uint32_t` to output the Link Frame Counter. 1332 * @param[out] aMleFrameCounter A reference to an `uint32_t` to output the MLE Frame Counter. 1333 * 1334 * @retval kErrorNone Successfully read the counters. 1335 * @retval kErrorNotFound Link Frame Counter TLV was not found in the message. 1336 * @retval kErrorParse TLVs are not well-formed. 1337 * 1338 */ 1339 Error ReadFrameCounterTlvs(uint32_t &aLinkFrameCounter, uint32_t &aMleFrameCounter) const; 1340 1341 /** 1342 * This method reads TLV Request TLV from the message. 1343 * 1344 * @param[out] aTlvList A reference to output the read list of requested TLVs. 1345 * 1346 * @retval kErrorNone Successfully read the TLV. 1347 * @retval kErrorNotFound TLV was not found in the message. 1348 * @retval kErrorParse TLV was found but could not be parsed. 1349 * 1350 */ 1351 Error ReadTlvRequestTlv(TlvList &aTlvList) const; 1352 1353 /** 1354 * This method reads Leader Data TLV from a message. 1355 * 1356 * @param[out] aLeaderData A reference to output the Leader Data. 1357 * 1358 * @retval kErrorNone Successfully read the TLV. 1359 * @retval kErrorNotFound TLV was not found in the message. 1360 * @retval kErrorParse TLV was found but could not be parsed. 1361 * 1362 */ 1363 Error ReadLeaderDataTlv(LeaderData &aLeaderData) const; 1364 1365 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 1366 /** 1367 * This method reads CSL Clock Accuracy TLV from a message. 1368 * 1369 * @param[out] aCslAccuracy A reference to output the CSL accuracy. 1370 * 1371 * @retval kErrorNone Successfully read the TLV. 1372 * @retval kErrorNotFound TLV was not found in the message. 1373 * @retval kErrorParse TLV was found but could not be parsed. 1374 * 1375 */ 1376 Error ReadCslClockAccuracyTlv(Mac::CslAccuracy &aCslAccuracy) const; 1377 #endif 1378 1379 #if OPENTHREAD_FTD 1380 /** 1381 * This method reads and validates Route TLV from a message. 1382 * 1383 * @param[out] aRouteTlv A reference to output the read Route TLV. 1384 * 1385 * @retval kErrorNone Successfully read and validated the Route TLV. 1386 * @retval kErrorNotFound TLV was not found in the message. 1387 * @retval kErrorParse TLV was found but could not be parsed or is not valid. 1388 * 1389 */ 1390 Error ReadRouteTlv(RouteTlv &aRouteTlv) const; 1391 #endif 1392 1393 private: 1394 Error ReadChallengeOrResponse(uint8_t aTlvType, Challenge &aBuffer) const; 1395 }; 1396 1397 /** 1398 * This structure represents a received MLE message containing additional information about the message (e.g. 1399 * key sequence, neighbor from which it was received). 1400 * 1401 */ 1402 struct RxInfo 1403 { 1404 /** 1405 * This enumeration represents a received MLE message class. 1406 * 1407 */ 1408 enum Class : uint8_t 1409 { 1410 kUnknown, ///< Unknown (default value, also indicates MLE message parse error). 1411 kAuthoritativeMessage, ///< Authoritative message (larger received key seq MUST be adopted). 1412 kPeerMessage, ///< Peer message (adopt only if from a known neighbor and is greater by one). 1413 }; 1414 1415 /** 1416 * This constructor initializes the `RxInfo`. 1417 * 1418 * @param[in] aMessage The received MLE message. 1419 * @param[in] aMessageInfo The `Ip6::MessageInfo` associated with message. 1420 * 1421 */ RxInfoot::Mle::Mle::RxInfo1422 RxInfo(Message &aMessage, const Ip6::MessageInfo &aMessageInfo) 1423 : mMessage(static_cast<RxMessage &>(aMessage)) 1424 , mMessageInfo(aMessageInfo) 1425 , mFrameCounter(0) 1426 , mKeySequence(0) 1427 , mNeighbor(nullptr) 1428 , mClass(kUnknown) 1429 { 1430 } 1431 1432 /** 1433 * This method indicates whether the `mNeighbor` (neighbor from which message was received) is non-null and 1434 * in valid state. 1435 * 1436 * @retval TRUE If `mNeighbor` is non-null and in valid state. 1437 * @retval FALSE If `mNeighbor` is `nullptr` or not in valid state. 1438 * 1439 */ IsNeighborStateValidot::Mle::Mle::RxInfo1440 bool IsNeighborStateValid(void) const { return (mNeighbor != nullptr) && mNeighbor->IsStateValid(); } 1441 1442 RxMessage &mMessage; ///< The MLE message. 1443 const Ip6::MessageInfo &mMessageInfo; ///< The `MessageInfo` associated with the message. 1444 uint32_t mFrameCounter; ///< The frame counter from aux security header. 1445 uint32_t mKeySequence; ///< The key sequence from aux security header. 1446 Neighbor *mNeighbor; ///< Neighbor from which message was received (can be `nullptr`). 1447 Class mClass; ///< The message class (authoritative, peer, or unknown). 1448 }; 1449 1450 /** 1451 * This method allocates and initializes new MLE message for a given command. 1452 * 1453 * @param[in] aCommand The MLE command. 1454 * 1455 * @returns A pointer to the message or `nullptr` if insufficient message buffers are available. 1456 * 1457 */ 1458 TxMessage *NewMleMessage(Command aCommand); 1459 1460 /** 1461 * This method sets the device role. 1462 * 1463 * @param[in] aRole A device role. 1464 * 1465 */ 1466 void SetRole(DeviceRole aRole); 1467 1468 /** 1469 * This method causes the Thread interface to attempt an MLE attach. 1470 * 1471 * @param[in] aMode Indicates what partitions to attach to. 1472 * 1473 */ 1474 void Attach(AttachMode aMode); 1475 1476 /** 1477 * This method sets the attach state 1478 * 1479 * @param[in] aState An attach state 1480 * 1481 */ 1482 void SetAttachState(AttachState aState); 1483 1484 /** 1485 * This method initializes a given @p aNeighbor with information from @p aRxInfo. 1486 * 1487 * This method updates the following properties on @p aNeighbor from @p aRxInfo: 1488 * 1489 * - Sets the Extended MAC address from `MessageInfo` peer IPv6 address IID. 1490 * - Clears the `GetLinkInfo()` and adds RSS from the `GetThreadLinkInfo()`. 1491 * - Resets the link failure counter (`ResetLinkFailures()`). 1492 * - Sets the "last heard" time to now (`SetLastHeard()`). 1493 * 1494 * @param[in,out] aNeighbor The `Neighbor` to initialize. 1495 * @param[in] aRxInfo The `RxtInfo` to use for initialization. 1496 * 1497 */ 1498 void InitNeighbor(Neighbor &aNeighbor, const RxInfo &aRxInfo); 1499 1500 /** 1501 * This method clears the parent candidate. 1502 * 1503 */ ClearParentCandidate(void)1504 void ClearParentCandidate(void) { mParentCandidate.Clear(); } 1505 1506 /** 1507 * This method checks if the destination is reachable. 1508 * 1509 * @param[in] aMeshDest The RLOC16 of the destination. 1510 * @param[in] aIp6Header The IPv6 header of the message. 1511 * 1512 * @retval kErrorNone The destination is reachable. 1513 * @retval kErrorNoRoute The destination is not reachable and the message should be dropped. 1514 * 1515 */ 1516 Error CheckReachability(uint16_t aMeshDest, const Ip6::Header &aIp6Header); 1517 1518 /** 1519 * This method returns the next hop towards an RLOC16 destination. 1520 * 1521 * @param[in] aDestination The RLOC16 of the destination. 1522 * 1523 * @returns A RLOC16 of the next hop if a route is known, kInvalidRloc16 otherwise. 1524 * 1525 */ 1526 Mac::ShortAddress GetNextHop(uint16_t aDestination) const; 1527 1528 /** 1529 * This method generates an MLE Data Request message. 1530 * 1531 * @param[in] aDestination The IPv6 destination address. 1532 * 1533 * @retval kErrorNone Successfully generated an MLE Data Request message. 1534 * @retval kErrorNoBufs Insufficient buffers to generate the MLE Data Request message. 1535 * 1536 */ 1537 Error SendDataRequest(const Ip6::Address &aDestination); 1538 1539 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE 1540 /** 1541 * This method generates an MLE Data Request message which request Link Metrics Report TLV. 1542 * 1543 * @param[in] aDestination A reference to the IPv6 address of the destination. 1544 * @param[in] aQueryInfo A Link Metrics query info. 1545 * 1546 * @retval kErrorNone Successfully generated an MLE Data Request message. 1547 * @retval kErrorNoBufs Insufficient buffers to generate the MLE Data Request message. 1548 * 1549 */ 1550 Error SendDataRequestForLinkMetricsReport(const Ip6::Address &aDestination, 1551 const LinkMetrics::Initiator::QueryInfo &aQueryInfo); 1552 #endif 1553 1554 /** 1555 * This method generates an MLE Child Update Request message. 1556 * 1557 * @retval kErrorNone Successfully generated an MLE Child Update Request message. 1558 * @retval kErrorNoBufs Insufficient buffers to generate the MLE Child Update Request message. 1559 * 1560 */ 1561 Error SendChildUpdateRequest(void); 1562 1563 /** 1564 * This method generates an MLE Child Update Response message. 1565 * 1566 * @param[in] aTlvList A list of requested TLV types. 1567 * @param[in] aChallenge The Challenge for the response. 1568 * 1569 * @retval kErrorNone Successfully generated an MLE Child Update Response message. 1570 * @retval kErrorNoBufs Insufficient buffers to generate the MLE Child Update Response message. 1571 * 1572 */ 1573 Error SendChildUpdateResponse(const TlvList &aTlvList, const Challenge &aChallenge); 1574 1575 /** 1576 * This method sets the RLOC16 assigned to the Thread interface. 1577 * 1578 * @param[in] aRloc16 The RLOC16 to set. 1579 * 1580 */ 1581 void SetRloc16(uint16_t aRloc16); 1582 1583 /** 1584 * This method sets the Device State to Detached. 1585 * 1586 */ 1587 void SetStateDetached(void); 1588 1589 /** 1590 * This method sets the Device State to Child. 1591 * 1592 */ 1593 void SetStateChild(uint16_t aRloc16); 1594 1595 /** 1596 * This method sets the Leader's Partition ID, Weighting, and Router ID values. 1597 * 1598 * @param[in] aPartitionId The Leader's Partition ID value. 1599 * @param[in] aWeighting The Leader's Weighting value. 1600 * @param[in] aLeaderRouterId The Leader's Router ID value. 1601 * 1602 */ 1603 void SetLeaderData(uint32_t aPartitionId, uint8_t aWeighting, uint8_t aLeaderRouterId); 1604 1605 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO) 1606 /** 1607 * This static method emits a log message with an IPv6 address. 1608 * 1609 * @param[in] aAction The message action (send/receive/delay, etc). 1610 * @param[in] aType The message type. 1611 * @param[in] aAddress The IPv6 address of the peer. 1612 * 1613 */ 1614 static void Log(MessageAction aAction, MessageType aType, const Ip6::Address &aAddress); 1615 1616 /** 1617 * This static method emits a log message with an IPv6 address and RLOC16. 1618 * 1619 * @param[in] aAction The message action (send/receive/delay, etc). 1620 * @param[in] aType The message type. 1621 * @param[in] aAddress The IPv6 address of the peer. 1622 * @param[in] aRloc The RLOC16. 1623 * 1624 */ 1625 static void Log(MessageAction aAction, MessageType aType, const Ip6::Address &aAddress, uint16_t aRloc); 1626 #else Log(MessageAction,MessageType,const Ip6::Address &)1627 static void Log(MessageAction, MessageType, const Ip6::Address &) {} Log(MessageAction,MessageType,const Ip6::Address &,uint16_t)1628 static void Log(MessageAction, MessageType, const Ip6::Address &, uint16_t) {} 1629 #endif // #if OT_SHOULD_LOG_AT( OT_LOG_LEVEL_INFO) 1630 1631 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN) 1632 /** 1633 * This static method emits a log message indicating an error in processing of a message. 1634 * 1635 * Note that log message is emitted only if there is an error, i.e., @p aError is not `kErrorNone`. The log 1636 * message will have the format "Failed to process {aMessageString} : {ErrorString}". 1637 * 1638 * @param[in] aType The message type. 1639 * @param[in] aError The error in processing of the message. 1640 * 1641 */ 1642 static void LogProcessError(MessageType aType, Error aError); 1643 1644 /** 1645 * This static method emits a log message indicating an error when sending a message. 1646 * 1647 * Note that log message is emitted only if there is an error, i.e. @p aError is not `kErrorNone`. The log 1648 * message will have the format "Failed to send {Message Type} : {ErrorString}". 1649 * 1650 * @param[in] aType The message type. 1651 * @param[in] aError The error in sending the message. 1652 * 1653 */ 1654 static void LogSendError(MessageType aType, Error aError); 1655 #else LogProcessError(MessageType,Error)1656 static void LogProcessError(MessageType, Error) {} LogSendError(MessageType,Error)1657 static void LogSendError(MessageType, Error) {} 1658 #endif // #if OT_SHOULD_LOG_AT( OT_LOG_LEVEL_WARN) 1659 1660 /** 1661 * This method triggers MLE Announce on previous channel after the Thread device successfully 1662 * attaches and receives the new Active Commissioning Dataset if needed. 1663 * 1664 * MTD would send Announce immediately after attached. 1665 * FTD would delay to send Announce after tried to become Router or decided to stay in REED role. 1666 * 1667 */ 1668 void InformPreviousChannel(void); 1669 1670 /** 1671 * This method indicates whether or not in announce attach process. 1672 * 1673 * @retval true if attaching/attached on the announced parameters, false otherwise. 1674 * 1675 */ IsAnnounceAttach(void) const1676 bool IsAnnounceAttach(void) const { return mAlternatePanId != Mac::kPanIdBroadcast; } 1677 1678 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_NOTE) 1679 /** 1680 * This method converts an `AttachMode` enumeration value into a human-readable string. 1681 * 1682 * @param[in] aMode An attach mode 1683 * 1684 * @returns A human-readable string corresponding to the attach mode. 1685 * 1686 */ 1687 static const char *AttachModeToString(AttachMode aMode); 1688 1689 /** 1690 * This method converts an `AttachState` enumeration value into a human-readable string. 1691 * 1692 * @param[in] aState An attach state 1693 * 1694 * @returns A human-readable string corresponding to the attach state. 1695 * 1696 */ 1697 static const char *AttachStateToString(AttachState aState); 1698 1699 /** 1700 * This method converts a `ReattachState` enumeration value into a human-readable string. 1701 * 1702 * @param[in] aState A reattach state 1703 * 1704 * @returns A human-readable string corresponding to the reattach state. 1705 * 1706 */ 1707 static const char *ReattachStateToString(ReattachState aState); 1708 #endif 1709 1710 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE 1711 /** 1712 * This method sends a Link Metrics Management Request message. 1713 * 1714 * @param[in] aDestination A reference to the IPv6 address of the destination. 1715 * @param[in] aSubTlv A reference to the sub-TLV to include. 1716 * 1717 * @retval kErrorNone Successfully sent a Link Metrics Management Request. 1718 * @retval kErrorNoBufs Insufficient buffers to generate the MLE Link Metrics Management Request message. 1719 * 1720 */ 1721 Error SendLinkMetricsManagementRequest(const Ip6::Address &aDestination, const ot::Tlv &aSubTlv); 1722 1723 /** 1724 * This method sends an MLE Link Probe message. 1725 * 1726 * @param[in] aDestination A reference to the IPv6 address of the destination. 1727 * @param[in] aSeriesId The Series ID [1, 254] which the Probe message targets at. 1728 * @param[in] aBuf A pointer to the data payload. 1729 * @param[in] aLength The length of the data payload in Link Probe TLV, [0, 64]. 1730 * 1731 * @retval kErrorNone Successfully sent a Link Metrics Management Request. 1732 * @retval kErrorNoBufs Insufficient buffers to generate the MLE Link Metrics Management Request message. 1733 * @retval kErrorInvalidArgs Series ID is not a valid value, not within range [1, 254]. 1734 * 1735 */ 1736 Error SendLinkProbe(const Ip6::Address &aDestination, uint8_t aSeriesId, uint8_t *aBuf, uint8_t aLength); 1737 1738 #endif 1739 1740 void ScheduleMessageTransmissionTimer(void); 1741 1742 private: 1743 // Declare early so we can use in as `TimerMilli` callbacks. 1744 void HandleAttachTimer(void); 1745 void HandleDelayedResponseTimer(void); 1746 void HandleMessageTransmissionTimer(void); 1747 1748 protected: 1749 using AttachTimer = TimerMilliIn<Mle, &Mle::HandleAttachTimer>; 1750 using DelayTimer = TimerMilliIn<Mle, &Mle::HandleDelayedResponseTimer>; 1751 using MsgTxTimer = TimerMilliIn<Mle, &Mle::HandleMessageTransmissionTimer>; 1752 1753 Ip6::Netif::UnicastAddress mLeaderAloc; ///< Leader anycast locator 1754 1755 LeaderData mLeaderData; ///< Last received Leader Data TLV. 1756 bool mRetrieveNewNetworkData : 1; ///< Indicating new Network Data is needed if set. 1757 bool mRequestRouteTlv : 1; ///< Request Route TLV when sending Data Request. 1758 DeviceRole mRole; ///< Current Thread role. 1759 Parent mParent; ///< Parent information. 1760 NeighborTable mNeighborTable; ///< The neighbor table. 1761 DeviceMode mDeviceMode; ///< Device mode setting. 1762 AttachState mAttachState; ///< The attach state. 1763 uint8_t mParentRequestCounter; ///< Number of parent requests while in `kAttachStateParentRequest`. 1764 ReattachState mReattachState; ///< Reattach state 1765 uint16_t mAttachCounter; ///< Attach attempt counter. 1766 uint16_t mAnnounceDelay; ///< Delay in between sending Announce messages during attach. 1767 AttachTimer mAttachTimer; ///< The timer for driving the attach process. 1768 DelayTimer mDelayedResponseTimer; ///< The timer to delay MLE responses. 1769 MsgTxTimer mMessageTransmissionTimer; ///< The timer for (re-)sending of MLE messages (e.g. Child Update). 1770 #if OPENTHREAD_FTD 1771 uint8_t mLinkRequestAttempts; ///< Number of remaining link requests to send after reset. 1772 bool mWasLeader; ///< Indicating if device was leader before reset. 1773 #endif 1774 1775 private: 1776 static constexpr uint8_t kMleHopLimit = 255; 1777 static constexpr uint8_t kMleSecurityTagSize = 4; // Security tag size in bytes. 1778 1779 // Parameters for "attach backoff" feature (CONFIG_ENABLE_ATTACH_BACKOFF) - Intervals are in milliseconds. 1780 static constexpr uint32_t kAttachBackoffMinInterval = OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_MINIMUM_INTERVAL; 1781 static constexpr uint32_t kAttachBackoffMaxInterval = OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_MAXIMUM_INTERVAL; 1782 static constexpr uint32_t kAttachBackoffJitter = OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_JITTER_INTERVAL; 1783 static constexpr uint32_t kAttachBackoffDelayToResetCounter = 1784 OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_DELAY_TO_RESET_BACKOFF_INTERVAL; 1785 1786 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_3 1787 // First attach cycle includes two Parent Requests to routers, followed by four to routers and REEDs. 1788 static constexpr uint8_t kFirstAttachCycleTotalParentRequests = 6; 1789 static constexpr uint8_t kFirstAttachCycleNumParentRequestToRouters = 2; 1790 #else 1791 // First attach cycle in Thread 1.1/1.2 includes a Parent Requests to routers, followed by one to routers and REEDs. 1792 static constexpr uint8_t kFirstAttachCycleTotalParentRequests = 2; 1793 static constexpr uint8_t kFirstAttachCycleNumParentRequestToRouters = 1; 1794 #endif 1795 1796 // Next attach cycles includes one Parent Request to routers, followed by one to routers and REEDs. 1797 static constexpr uint8_t kNextAttachCycleTotalParentRequests = 2; 1798 static constexpr uint8_t kNextAttachCycleNumParentRequestToRouters = 1; 1799 1800 static constexpr uint32_t kDetachGracefullyTimeout = 1000; 1801 1802 static constexpr uint32_t kStoreFrameCounterAhead = OPENTHREAD_CONFIG_STORE_FRAME_COUNTER_AHEAD; 1803 static constexpr uint8_t kMaxIpAddressesToRegister = OPENTHREAD_CONFIG_MLE_IP_ADDRS_TO_REGISTER; 1804 static constexpr uint32_t kDefaultCslTimeout = OPENTHREAD_CONFIG_CSL_TIMEOUT; 1805 1806 enum StartMode : uint8_t // Used in `Start()`. 1807 { 1808 kNormalAttach, 1809 kAnnounceAttach, // Try to attach on the announced thread network with newer active timestamp. 1810 }; 1811 1812 enum StopMode : uint8_t // Used in `Stop()`. 1813 { 1814 kKeepNetworkDatasets, 1815 kUpdateNetworkDatasets, 1816 }; 1817 1818 enum AnnounceMode : uint8_t // Used in `SendAnnounce()` 1819 { 1820 kNormalAnnounce, 1821 kOrphanAnnounce, 1822 }; 1823 1824 enum ParentRequestType : uint8_t 1825 { 1826 kToRouters, // Parent Request to routers only. 1827 kToRoutersAndReeds, // Parent Request to all routers and REEDs. 1828 }; 1829 1830 enum ChildUpdateRequestState : uint8_t 1831 { 1832 kChildUpdateRequestNone, // No pending or active Child Update Request. 1833 kChildUpdateRequestPending, // Pending Child Update Request due to relative OT_CHANGED event. 1834 kChildUpdateRequestActive, // Child Update Request has been sent and Child Update Response is expected. 1835 }; 1836 1837 enum ChildUpdateRequestMode : uint8_t // Used in `SendChildUpdateRequest()` 1838 { 1839 kNormalChildUpdateRequest, // Normal Child Update Request. 1840 kAppendChallengeTlv, // Append Challenge TLV to Child Update Request even if currently attached. 1841 kAppendZeroTimeout, // Use zero timeout when appending Timeout TLV (used for graceful detach). 1842 }; 1843 1844 enum DataRequestState : uint8_t 1845 { 1846 kDataRequestNone, // Not waiting for a Data Response. 1847 kDataRequestActive, // Data Request has been sent, Data Response is expected. 1848 }; 1849 1850 enum SecuritySuite : uint8_t 1851 { 1852 k154Security = 0, // Security suite value indicating that MLE message is not secured. 1853 kNoSecurity = 255, // Security suite value indicating that MLE message is secured. 1854 }; 1855 1856 struct DelayedResponseMetadata 1857 { AppendToot::Mle::Mle::DelayedResponseMetadata1858 Error AppendTo(Message &aMessage) const { return aMessage.Append(*this); } 1859 void ReadFrom(const Message &aMessage); 1860 void RemoveFrom(Message &aMessage) const; 1861 1862 Ip6::Address mDestination; // IPv6 address of the message destination. 1863 TimeMilli mSendTime; // Time when the message shall be sent. 1864 }; 1865 1866 OT_TOOL_PACKED_BEGIN 1867 class SecurityHeader 1868 { 1869 public: InitSecurityControl(void)1870 void InitSecurityControl(void) { mSecurityControl = kKeyIdMode2Mic32; } IsSecurityControlValid(void) const1871 bool IsSecurityControlValid(void) const { return (mSecurityControl == kKeyIdMode2Mic32); } 1872 GetFrameCounter(void) const1873 uint32_t GetFrameCounter(void) const { return Encoding::LittleEndian::HostSwap32(mFrameCounter); } SetFrameCounter(uint32_t aCounter)1874 void SetFrameCounter(uint32_t aCounter) { mFrameCounter = Encoding::LittleEndian::HostSwap32(aCounter); } 1875 GetKeyId(void) const1876 uint32_t GetKeyId(void) const { return Encoding::BigEndian::HostSwap32(mKeySource); } SetKeyId(uint32_t aKeySequence)1877 void SetKeyId(uint32_t aKeySequence) 1878 { 1879 mKeySource = Encoding::BigEndian::HostSwap32(aKeySequence); 1880 mKeyIndex = (aKeySequence & 0x7f) + 1; 1881 } 1882 1883 private: 1884 static constexpr uint8_t kKeyIdMode2Mic32 = 1885 static_cast<uint8_t>(Mac::Frame::kKeyIdMode2) | static_cast<uint8_t>(Mac::Frame::kSecurityEncMic32); 1886 1887 uint8_t mSecurityControl; 1888 uint32_t mFrameCounter; 1889 uint32_t mKeySource; 1890 uint8_t mKeyIndex; 1891 } OT_TOOL_PACKED_END; 1892 1893 class ParentCandidate : public Parent 1894 { 1895 public: Init(Instance & aInstance)1896 void Init(Instance &aInstance) { Parent::Init(aInstance); } 1897 void Clear(void); 1898 void CopyTo(Parent &aParent) const; 1899 1900 Challenge mChallenge; 1901 int8_t mPriority; 1902 uint8_t mLinkQuality3; 1903 uint8_t mLinkQuality2; 1904 uint8_t mLinkQuality1; 1905 uint16_t mSedBufferSize; 1906 uint8_t mSedDatagramCount; 1907 uint8_t mLinkMargin; 1908 LeaderData mLeaderData; 1909 bool mIsSingleton; 1910 }; 1911 1912 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE 1913 class ServiceAloc : public Ip6::Netif::UnicastAddress 1914 { 1915 public: 1916 static constexpr uint16_t kNotInUse = Mac::kShortAddrInvalid; 1917 1918 ServiceAloc(void); 1919 IsInUse(void) const1920 bool IsInUse(void) const { return GetAloc16() != kNotInUse; } MarkAsNotInUse(void)1921 void MarkAsNotInUse(void) { SetAloc16(kNotInUse); } GetAloc16(void) const1922 uint16_t GetAloc16(void) const { return GetAddress().GetIid().GetLocator(); } SetAloc16(uint16_t aAloc16)1923 void SetAloc16(uint16_t aAloc16) { GetAddress().GetIid().SetLocator(aAloc16); } ApplyMeshLocalPrefix(const Ip6::NetworkPrefix & aPrefix)1924 void ApplyMeshLocalPrefix(const Ip6::NetworkPrefix &aPrefix) { GetAddress().SetPrefix(aPrefix); } 1925 }; 1926 #endif 1927 1928 #if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE HandleParentSearchTimer(void)1929 void HandleParentSearchTimer(void) { mParentSearch.HandleTimer(); } 1930 1931 class ParentSearch : public InstanceLocator 1932 { 1933 public: ParentSearch(Instance & aInstance)1934 explicit ParentSearch(Instance &aInstance) 1935 : InstanceLocator(aInstance) 1936 , mIsInBackoff(false) 1937 , mBackoffWasCanceled(false) 1938 , mRecentlyDetached(false) 1939 , mBackoffCancelTime(0) 1940 , mTimer(aInstance) 1941 { 1942 } 1943 1944 void StartTimer(void); 1945 void UpdateState(void); SetRecentlyDetached(void)1946 void SetRecentlyDetached(void) { mRecentlyDetached = true; } 1947 void HandleTimer(void); 1948 1949 private: 1950 // All timer intervals are converted to milliseconds. 1951 static constexpr uint32_t kCheckInterval = (OPENTHREAD_CONFIG_PARENT_SEARCH_CHECK_INTERVAL * 1000u); 1952 static constexpr uint32_t kBackoffInterval = (OPENTHREAD_CONFIG_PARENT_SEARCH_BACKOFF_INTERVAL * 1000u); 1953 static constexpr uint32_t kJitterInterval = (15 * 1000u); 1954 static constexpr int8_t kRssThreshold = OPENTHREAD_CONFIG_PARENT_SEARCH_RSS_THRESHOLD; 1955 1956 using SearchTimer = TimerMilliIn<Mle, &Mle::HandleParentSearchTimer>; 1957 1958 bool mIsInBackoff : 1; 1959 bool mBackoffWasCanceled : 1; 1960 bool mRecentlyDetached : 1; 1961 TimeMilli mBackoffCancelTime; 1962 SearchTimer mTimer; 1963 }; 1964 #endif // OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE 1965 1966 Error Start(StartMode aMode); 1967 void Stop(StopMode aMode); 1968 void HandleNotifierEvents(Events aEvents); 1969 void SendDelayedResponse(TxMessage &aMessage, const DelayedResponseMetadata &aMetadata); 1970 static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo); 1971 void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 1972 void ReestablishLinkWithNeighbor(Neighbor &aNeighbor); 1973 static void HandleDetachGracefullyTimer(Timer &aTimer); 1974 void HandleDetachGracefullyTimer(void); IsDetachingGracefully(void)1975 bool IsDetachingGracefully(void) { return mDetachGracefullyTimer.IsRunning(); } 1976 Error SendChildUpdateRequest(ChildUpdateRequestMode aMode); 1977 Error SendDataRequestAfterDelay(const Ip6::Address &aDestination, uint16_t aDelay); 1978 1979 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE 1980 Error SendDataRequest(const Ip6::Address &aDestination, 1981 const uint8_t *aTlvs, 1982 uint8_t aTlvsLength, 1983 uint16_t aDelay, 1984 const LinkMetrics::Initiator::QueryInfo *aQueryInfo = nullptr); 1985 #else 1986 Error SendDataRequest(const Ip6::Address &aDestination, const uint8_t *aTlvs, uint8_t aTlvsLength, uint16_t aDelay); 1987 #endif 1988 1989 #if OPENTHREAD_FTD 1990 static void HandleDetachGracefullyAddressReleaseResponse(void *aContext, 1991 otMessage *aMessage, 1992 const otMessageInfo *aMessageInfo, 1993 Error aResult); 1994 void HandleDetachGracefullyAddressReleaseResponse(void); 1995 #endif 1996 1997 void HandleAdvertisement(RxInfo &aRxInfo); 1998 void HandleChildIdResponse(RxInfo &aRxInfo); 1999 void HandleChildUpdateRequest(RxInfo &aRxInfo); 2000 void HandleChildUpdateResponse(RxInfo &aRxInfo); 2001 void HandleDataResponse(RxInfo &aRxInfo); 2002 void HandleParentResponse(RxInfo &aRxInfo); 2003 void HandleAnnounce(RxInfo &aRxInfo); 2004 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 2005 void HandleLinkMetricsManagementRequest(RxInfo &aRxInfo); 2006 void HandleLinkProbe(RxInfo &aRxInfo); 2007 #endif 2008 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE 2009 void HandleLinkMetricsManagementResponse(RxInfo &aRxInfo); 2010 #endif 2011 Error HandleLeaderData(RxInfo &aRxInfo); 2012 void ProcessAnnounce(void); 2013 bool HasUnregisteredAddress(void); 2014 2015 uint32_t GetAttachStartDelay(void) const; 2016 void SendParentRequest(ParentRequestType aType); 2017 Error SendChildIdRequest(void); 2018 Error GetNextAnnounceChannel(uint8_t &aChannel) const; 2019 bool HasMoreChannelsToAnnounce(void) const; 2020 bool PrepareAnnounceState(void); 2021 void SendAnnounce(uint8_t aChannel, AnnounceMode aMode); 2022 void SendAnnounce(uint8_t aChannel, const Ip6::Address &aDestination, AnnounceMode aMode = kNormalAnnounce); 2023 void RemoveDelayedMessage(Message::SubType aSubType, MessageType aMessageType, const Ip6::Address *aDestination); 2024 void RemoveDelayedDataRequestMessage(const Ip6::Address &aDestination); 2025 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 2026 Error SendLinkMetricsManagementResponse(const Ip6::Address &aDestination, LinkMetrics::Status aStatus); 2027 #endif 2028 uint32_t Reattach(void); 2029 bool HasAcceptableParentCandidate(void) const; 2030 Error DetermineParentRequestType(ParentRequestType &aType) const; 2031 2032 bool IsBetterParent(uint16_t aRloc16, 2033 LinkQuality aLinkQuality, 2034 uint8_t aLinkMargin, 2035 const ConnectivityTlv &aConnectivityTlv, 2036 uint16_t aVersion, 2037 const Mac::CslAccuracy &aCslAccuracy); 2038 bool IsNetworkDataNewer(const LeaderData &aLeaderData); 2039 2040 Error ProcessMessageSecurity(Crypto::AesCcm::Mode aMode, 2041 Message &aMessage, 2042 const Ip6::MessageInfo &aMessageInfo, 2043 uint16_t aCmdOffset, 2044 const SecurityHeader &aHeader); 2045 2046 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE 2047 ServiceAloc *FindInServiceAlocs(uint16_t aAloc16); 2048 void UpdateServiceAlocs(void); 2049 #endif 2050 2051 #if OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH 2052 void InformPreviousParent(void); 2053 #endif 2054 2055 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN) 2056 static void LogError(MessageAction aAction, MessageType aType, Error aError); 2057 static const char *MessageActionToString(MessageAction aAction); 2058 static const char *MessageTypeToString(MessageType aType); 2059 static const char *MessageTypeActionToSuffixString(MessageType aType, MessageAction aAction); 2060 #endif 2061 2062 #if OPENTHREAD_CONFIG_UPTIME_ENABLE 2063 void UpdateRoleTimeCounters(DeviceRole aRole); 2064 #endif 2065 2066 using DetachGracefullyTimer = TimerMilliIn<Mle, &Mle::HandleDetachGracefullyTimer>; 2067 2068 MessageQueue mDelayedResponses; 2069 2070 Challenge mParentRequestChallenge; 2071 2072 AttachMode mAttachMode; 2073 ParentCandidate mParentCandidate; 2074 2075 uint8_t mChildUpdateAttempts; 2076 ChildUpdateRequestState mChildUpdateRequestState; 2077 uint8_t mDataRequestAttempts; 2078 DataRequestState mDataRequestState; 2079 2080 AddressRegistrationMode mAddressRegistrationMode; 2081 2082 bool mHasRestored; 2083 bool mReceivedResponseFromParent; 2084 bool mInitiallyAttachedAsSleepy; 2085 2086 Ip6::Udp::Socket mSocket; 2087 uint32_t mTimeout; 2088 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 2089 uint32_t mCslTimeout; 2090 #endif 2091 2092 uint16_t mRloc16; 2093 uint16_t mPreviousParentRloc; 2094 2095 #if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE 2096 ParentSearch mParentSearch; 2097 #endif 2098 2099 uint8_t mAnnounceChannel; 2100 uint8_t mAlternateChannel; 2101 uint16_t mAlternatePanId; 2102 uint64_t mAlternateTimestamp; 2103 2104 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE 2105 ServiceAloc mServiceAlocs[kMaxServiceAlocs]; 2106 #endif 2107 2108 Counters mCounters; 2109 #if OPENTHREAD_CONFIG_UPTIME_ENABLE 2110 uint64_t mLastUpdatedTimestamp; 2111 #endif 2112 2113 static const otMeshLocalPrefix sMeshLocalPrefixInit; 2114 2115 Ip6::Netif::UnicastAddress mLinkLocal64; 2116 Ip6::Netif::UnicastAddress mMeshLocal64; 2117 Ip6::Netif::UnicastAddress mMeshLocal16; 2118 Ip6::Netif::MulticastAddress mLinkLocalAllThreadNodes; 2119 Ip6::Netif::MulticastAddress mRealmLocalAllThreadNodes; 2120 2121 DetachGracefullyTimer mDetachGracefullyTimer; 2122 Callback<otDetachGracefullyCallback> mDetachGracefullyCallback; 2123 2124 #if OPENTHREAD_CONFIG_MLE_PARENT_RESPONSE_CALLBACK_API_ENABLE 2125 Callback<otThreadParentResponseCallback> mParentResponseCallback; 2126 #endif 2127 }; 2128 2129 } // namespace Mle 2130 2131 /** 2132 * @} 2133 * 2134 */ 2135 2136 } // namespace ot 2137 2138 #endif // MLE_HPP_ 2139