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