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