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