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 Router and Leader roles.
32  */
33 
34 #ifndef MLE_ROUTER_HPP_
35 #define MLE_ROUTER_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include <openthread/thread_ftd.h>
40 
41 #include "coap/coap_message.hpp"
42 #include "common/callback.hpp"
43 #include "common/time_ticker.hpp"
44 #include "common/timer.hpp"
45 #include "common/trickle_timer.hpp"
46 #include "mac/mac_types.hpp"
47 #include "meshcop/meshcop_tlvs.hpp"
48 #include "net/icmp6.hpp"
49 #include "net/udp6.hpp"
50 #include "thread/child.hpp"
51 #include "thread/child_table.hpp"
52 #include "thread/mle.hpp"
53 #include "thread/mle_tlvs.hpp"
54 #include "thread/router.hpp"
55 #include "thread/router_table.hpp"
56 #include "thread/thread_tlvs.hpp"
57 #include "thread/tmf.hpp"
58 
59 namespace ot {
60 namespace Mle {
61 
62 /**
63  * @addtogroup core-mle-router
64  *
65  * @brief
66  *   This module includes definitions for MLE functionality required by the Thread Router and Leader roles.
67  *
68  * @{
69  */
70 
71 #if OPENTHREAD_FTD
72 
73 /**
74  * Implements MLE functionality required by the Thread Router and Leader roles.
75  *
76  */
77 class MleRouter : public Mle
78 {
79     friend class Mle;
80     friend class ot::Instance;
81     friend class ot::TimeTicker;
82     friend class Tmf::Agent;
83 
84 public:
85     /**
86      * Initializes the object.
87      *
88      * @param[in]  aInstance     A reference to the OpenThread instance.
89      *
90      */
91     explicit MleRouter(Instance &aInstance);
92 
93     /**
94      * Indicates whether or not the device is router-eligible.
95      *
96      * @retval true   If device is router-eligible.
97      * @retval false  If device is not router-eligible.
98      *
99      */
100     bool IsRouterEligible(void) const;
101 
102     /**
103      * Sets whether or not the device is router-eligible.
104      *
105      * If @p aEligible is false and the device is currently operating as a router, this call will cause the device to
106      * detach and attempt to reattach as a child.
107      *
108      * @param[in]  aEligible  TRUE to configure device router-eligible, FALSE otherwise.
109      *
110      * @retval kErrorNone         Successfully set the router-eligible configuration.
111      * @retval kErrorNotCapable   The device is not capable of becoming a router.
112      *
113      */
114     Error SetRouterEligible(bool aEligible);
115 
116     /**
117      * Indicates whether a node is the only router on the network.
118      *
119      * @retval TRUE   It is the only router in the network.
120      * @retval FALSE  It is a child or is not a single router in the network.
121      *
122      */
123     bool IsSingleton(void) const;
124 
125     /**
126      * Generates an Address Solicit request for a Router ID.
127      *
128      * @param[in]  aStatus  The reason for requesting a Router ID.
129      *
130      * @retval kErrorNone           Successfully generated an Address Solicit message.
131      * @retval kErrorNotCapable     Device is not capable of becoming a router
132      * @retval kErrorInvalidState   Thread is not enabled
133      *
134      */
135     Error BecomeRouter(ThreadStatusTlv::Status aStatus);
136 
137     /**
138      * Causes the Thread interface to become a Leader and start a new partition.
139      *
140      * @retval kErrorNone           Successfully become a Leader and started a new partition.
141      * @retval kErrorNotCapable     Device is not capable of becoming a leader
142      * @retval kErrorInvalidState   Thread is not enabled
143      *
144      */
145     Error BecomeLeader(void);
146 
147 #if OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE
148     /**
149      * Gets the device properties which are used to determine the Leader Weight.
150      *
151      * @returns The current device properties.
152      *
153      */
GetDeviceProperties(void) const154     const DeviceProperties &GetDeviceProperties(void) const { return mDeviceProperties; }
155 
156     /**
157      * Sets the device properties which are then used to determine and set the Leader Weight.
158      *
159      * @param[in]  aDeviceProperties    The device properties.
160      *
161      */
162     void SetDeviceProperties(const DeviceProperties &aDeviceProperties);
163 #endif
164 
165     /**
166      * Returns the Leader Weighting value for this Thread interface.
167      *
168      * @returns The Leader Weighting value for this Thread interface.
169      *
170      */
GetLeaderWeight(void) const171     uint8_t GetLeaderWeight(void) const { return mLeaderWeight; }
172 
173     /**
174      * Sets the Leader Weighting value for this Thread interface.
175      *
176      * Directly sets the Leader Weight to the new value replacing its previous value (which may have been
177      * determined from a previous call to `SetDeviceProperties()`).
178      *
179      * @param[in]  aWeight  The Leader Weighting value.
180      *
181      */
SetLeaderWeight(uint8_t aWeight)182     void SetLeaderWeight(uint8_t aWeight) { mLeaderWeight = aWeight; }
183 
184 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
185 
186     /**
187      * Returns the preferred Partition Id when operating in the Leader role for certification testing.
188      *
189      * @returns The preferred Partition Id value.
190      *
191      */
GetPreferredLeaderPartitionId(void) const192     uint32_t GetPreferredLeaderPartitionId(void) const { return mPreferredLeaderPartitionId; }
193 
194     /**
195      * Sets the preferred Partition Id when operating in the Leader role for certification testing.
196      *
197      * @param[in]  aPartitionId  The preferred Leader Partition Id.
198      *
199      */
SetPreferredLeaderPartitionId(uint32_t aPartitionId)200     void SetPreferredLeaderPartitionId(uint32_t aPartitionId) { mPreferredLeaderPartitionId = aPartitionId; }
201 #endif
202 
203     /**
204      * Sets the preferred Router Id. Upon becoming a router/leader the node
205      * attempts to use this Router Id. If the preferred Router Id is not set or if it
206      * can not be used, a randomly generated router Id is picked.
207      * This property can be set when he device role is detached or disabled.
208      *
209      * @param[in]  aRouterId             The preferred Router Id.
210      *
211      * @retval kErrorNone          Successfully set the preferred Router Id.
212      * @retval kErrorInvalidState  Could not set (role is other than detached and disabled)
213      *
214      */
215     Error SetPreferredRouterId(uint8_t aRouterId);
216 
217     /**
218      * Gets the Partition Id which the device joined successfully once.
219      *
220      */
GetPreviousPartitionId(void) const221     uint32_t GetPreviousPartitionId(void) const { return mPreviousPartitionId; }
222 
223     /**
224      * Sets the Partition Id which the device joins successfully.
225      *
226      * @param[in]  aPartitionId   The Partition Id.
227      *
228      */
SetPreviousPartitionId(uint32_t aPartitionId)229     void SetPreviousPartitionId(uint32_t aPartitionId) { mPreviousPartitionId = aPartitionId; }
230 
231     /**
232      * Sets the Router Id.
233      *
234      * @param[in]  aRouterId   The Router Id.
235      *
236      */
237     void SetRouterId(uint8_t aRouterId);
238 
239     /**
240      * Returns the next hop towards an RLOC16 destination.
241      *
242      * @param[in]  aDestination  The RLOC16 of the destination.
243      *
244      * @returns A RLOC16 of the next hop if a route is known, kInvalidRloc16 otherwise.
245      *
246      */
GetNextHop(uint16_t aDestination)247     uint16_t GetNextHop(uint16_t aDestination) { return mRouterTable.GetNextHop(aDestination); }
248 
249     /**
250      * Returns the NETWORK_ID_TIMEOUT value.
251      *
252      * @returns The NETWORK_ID_TIMEOUT value.
253      *
254      */
GetNetworkIdTimeout(void) const255     uint8_t GetNetworkIdTimeout(void) const { return mNetworkIdTimeout; }
256 
257     /**
258      * Sets the NETWORK_ID_TIMEOUT value.
259      *
260      * @param[in]  aTimeout  The NETWORK_ID_TIMEOUT value.
261      *
262      */
SetNetworkIdTimeout(uint8_t aTimeout)263     void SetNetworkIdTimeout(uint8_t aTimeout) { mNetworkIdTimeout = aTimeout; }
264 
265     /**
266      * Returns the ROUTER_SELECTION_JITTER value.
267      *
268      * @returns The ROUTER_SELECTION_JITTER value.
269      *
270      */
GetRouterSelectionJitter(void) const271     uint8_t GetRouterSelectionJitter(void) const { return mRouterSelectionJitter; }
272 
273     /**
274      * Sets the ROUTER_SELECTION_JITTER value.
275      *
276      * @returns The ROUTER_SELECTION_JITTER value.
277      *
278      */
279     Error SetRouterSelectionJitter(uint8_t aRouterJitter);
280 
281     /**
282      * Returns the current router selection jitter timeout value.
283      *
284      * @returns The current router selection jitter timeout value.
285      *
286      */
GetRouterSelectionJitterTimeout(void) const287     uint8_t GetRouterSelectionJitterTimeout(void) const { return mRouterSelectionJitterTimeout; }
288 
289     /**
290      * Returns the ROUTER_UPGRADE_THRESHOLD value.
291      *
292      * @returns The ROUTER_UPGRADE_THRESHOLD value.
293      *
294      */
GetRouterUpgradeThreshold(void) const295     uint8_t GetRouterUpgradeThreshold(void) const { return mRouterUpgradeThreshold; }
296 
297     /**
298      * Sets the ROUTER_UPGRADE_THRESHOLD value.
299      *
300      * @param[in]  aThreshold  The ROUTER_UPGRADE_THRESHOLD value.
301      *
302      */
SetRouterUpgradeThreshold(uint8_t aThreshold)303     void SetRouterUpgradeThreshold(uint8_t aThreshold) { mRouterUpgradeThreshold = aThreshold; }
304 
305     /**
306      * Returns the ROUTER_DOWNGRADE_THRESHOLD value.
307      *
308      * @returns The ROUTER_DOWNGRADE_THRESHOLD value.
309      *
310      */
GetRouterDowngradeThreshold(void) const311     uint8_t GetRouterDowngradeThreshold(void) const { return mRouterDowngradeThreshold; }
312 
313     /**
314      * Sets the ROUTER_DOWNGRADE_THRESHOLD value.
315      *
316      * @param[in]  aThreshold  The ROUTER_DOWNGRADE_THRESHOLD value.
317      *
318      */
SetRouterDowngradeThreshold(uint8_t aThreshold)319     void SetRouterDowngradeThreshold(uint8_t aThreshold) { mRouterDowngradeThreshold = aThreshold; }
320 
321     /**
322      * Returns the MLE_CHILD_ROUTER_LINKS value.
323      *
324      * @returns The MLE_CHILD_ROUTER_LINKS value.
325      *
326      */
GetChildRouterLinks(void) const327     uint8_t GetChildRouterLinks(void) const { return mChildRouterLinks; }
328 
329     /**
330      * Sets the MLE_CHILD_ROUTER_LINKS value.
331      *
332      * @param[in]  aChildRouterLinks  The MLE_CHILD_ROUTER_LINKS value.
333      *
334      * @retval kErrorNone          Successfully set the value.
335      * @retval kErrorInvalidState  Thread protocols are enabled.
336      */
337     Error SetChildRouterLinks(uint8_t aChildRouterLinks);
338 
339     /**
340      * Returns if the REED is expected to become Router soon.
341      *
342      * @retval TRUE   If the REED is going to become a Router soon.
343      * @retval FALSE  If the REED is not going to become a Router soon.
344      *
345      */
346     bool IsExpectedToBecomeRouterSoon(void) const;
347 
348     /**
349      * Removes a link to a neighbor.
350      *
351      * @param[in]  aNeighbor  A reference to the neighbor object.
352      *
353      */
354     void RemoveNeighbor(Neighbor &aNeighbor);
355 
356     /**
357      * Invalidates a direct link to a neighboring router (due to failed link-layer acks).
358      *
359      * @param[in]  aRouter  A reference to the router object.
360      *
361      */
362     void RemoveRouterLink(Router &aRouter);
363 
364     /**
365      * Indicates whether or not the RLOC16 is an MTD child of this device.
366      *
367      * @param[in]  aRloc16  The RLOC16.
368      *
369      * @retval TRUE if @p aRloc16 is an MTD child of this device.
370      * @retval FALSE if @p aRloc16 is not an MTD child of this device.
371      *
372      */
373     bool IsMinimalChild(uint16_t aRloc16);
374 
375     /**
376      * Indicates whether or not the given Thread partition attributes are preferred.
377      *
378      * @param[in]  aSingletonA   Whether or not the Thread Partition A has a single router.
379      * @param[in]  aLeaderDataA  A reference to Thread Partition A's Leader Data.
380      * @param[in]  aSingletonB   Whether or not the Thread Partition B has a single router.
381      * @param[in]  aLeaderDataB  A reference to Thread Partition B's Leader Data.
382      *
383      * @retval 1   If partition A is preferred.
384      * @retval 0   If partition A and B have equal preference.
385      * @retval -1  If partition B is preferred.
386      *
387      */
388     static int ComparePartitions(bool              aSingletonA,
389                                  const LeaderData &aLeaderDataA,
390                                  bool              aSingletonB,
391                                  const LeaderData &aLeaderDataB);
392 
393     /**
394      * Checks if the destination is reachable.
395      *
396      * @param[in]  aMeshDest   The RLOC16 of the destination.
397      * @param[in]  aIp6Header  A reference to the IPv6 header of the message.
398      *
399      * @retval kErrorNone      The destination is reachable.
400      * @retval kErrorNoRoute   The destination is not reachable and the message should be dropped.
401      *
402      */
403     Error CheckReachability(uint16_t aMeshDest, const Ip6::Header &aIp6Header);
404 
405     /**
406      * Resolves 2-hop routing loops.
407      *
408      * @param[in]  aSourceMac   The RLOC16 of the previous hop.
409      * @param[in]  aDestRloc16  The RLOC16 of the final destination.
410      *
411      */
412     void ResolveRoutingLoops(uint16_t aSourceMac, uint16_t aDestRloc16);
413 
414     /**
415      * Checks if a given Router ID has correct value.
416      *
417      * @param[in]  aRouterId  The Router ID value.
418      *
419      * @retval TRUE   If @p aRouterId is in correct range [0..62].
420      * @retval FALSE  If @p aRouterId is not a valid Router ID.
421      *
422      */
IsRouterIdValid(uint8_t aRouterId)423     static bool IsRouterIdValid(uint8_t aRouterId) { return aRouterId <= kMaxRouterId; }
424 
425     /**
426      * Fills an ConnectivityTlv.
427      *
428      * @param[out]  aTlv  A reference to the tlv to be filled.
429      *
430      */
431     void FillConnectivityTlv(ConnectivityTlv &aTlv);
432 
433     /**
434      * Generates an MLE Child Update Request message to be sent to the parent.
435      *
436      * @retval kErrorNone     Successfully generated an MLE Child Update Request message.
437      * @retval kErrorNoBufs   Insufficient buffers to generate the MLE Child Update Request message.
438      *
439      */
SendChildUpdateRequest(void)440     Error SendChildUpdateRequest(void) { return Mle::SendChildUpdateRequest(); }
441 
442     Error SendLinkRequest(Neighbor *aNeighbor);
443 
444 #if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
445     /**
446      * Sets steering data out of band
447      *
448      * @param[in]  aExtAddress  Value used to set steering data
449      *                          All zeros clears steering data
450      *                          All 0xFFs sets steering data to 0xFF
451      *                          Anything else is used to compute the bloom filter
452      *
453      */
454     void SetSteeringData(const Mac::ExtAddress *aExtAddress);
455 #endif
456 
457     /**
458      * Gets the assigned parent priority.
459      *
460      * @returns The assigned parent priority value, -2 means not assigned.
461      *
462      */
GetAssignParentPriority(void) const463     int8_t GetAssignParentPriority(void) const { return mParentPriority; }
464 
465     /**
466      * Sets the parent priority.
467      *
468      * @param[in]  aParentPriority  The parent priority value.
469      *
470      * @retval kErrorNone           Successfully set the parent priority.
471      * @retval kErrorInvalidArgs    If the parent priority value is not among 1, 0, -1 and -2.
472      *
473      */
474     Error SetAssignParentPriority(int8_t aParentPriority);
475 
476     /**
477      * Gets the longest MLE Timeout TLV for all active MTD children.
478      *
479      * @param[out]  aTimeout  A reference to where the information is placed.
480      *
481      * @retval kErrorNone           Successfully get the max child timeout
482      * @retval kErrorInvalidState   Not an active router
483      * @retval kErrorNotFound       NO MTD child
484      *
485      */
486     Error GetMaxChildTimeout(uint32_t &aTimeout) const;
487 
488     /**
489      * Sets the callback that is called when processing an MLE Discovery Request message.
490      *
491      * @param[in]  aCallback A pointer to a function that is called to deliver MLE Discovery Request data.
492      * @param[in]  aContext  A pointer to application-specific context.
493      *
494      */
SetDiscoveryRequestCallback(otThreadDiscoveryRequestCallback aCallback,void * aContext)495     void SetDiscoveryRequestCallback(otThreadDiscoveryRequestCallback aCallback, void *aContext)
496     {
497         mDiscoveryRequestCallback.Set(aCallback, aContext);
498     }
499 
500     /**
501      * Resets the MLE Advertisement Trickle timer interval.
502      *
503      */
504     void ResetAdvertiseInterval(void);
505 
506     /**
507      * Updates the MLE Advertisement Trickle timer max interval (if timer is running).
508      *
509      * This is called when there is change in router table.
510      *
511      */
512     void UpdateAdvertiseInterval(void);
513 
514 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
515     /**
516      * Generates an MLE Time Synchronization message.
517      *
518      * @retval kErrorNone     Successfully sent an MLE Time Synchronization message.
519      * @retval kErrorNoBufs   Insufficient buffers to generate the MLE Time Synchronization message.
520      *
521      */
522     Error SendTimeSync(void);
523 #endif
524 
525 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
526     /**
527      * Sets the delay before registering Backbone Router service.
528      *
529      * @param[in]  aDelay  The delay before registering Backbone Router service.
530      *
531      */
SetBackboneRouterRegistrationDelay(uint8_t aDelay)532     void SetBackboneRouterRegistrationDelay(uint8_t aDelay) { mBackboneRouterRegistrationDelay = aDelay; }
533 #endif
534 
535     /**
536      * Gets the maximum number of IP addresses that each MTD child may register with this device as parent.
537      *
538      * @returns The maximum number of IP addresses that each MTD child may register with this device as parent.
539      *
540      */
541     uint8_t GetMaxChildIpAddresses(void) const;
542 
543 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
544 
545     /**
546      * Sets/restores the maximum number of IP addresses that each MTD child may register with this
547      * device as parent.
548      *
549      * @param[in]  aMaxIpAddresses  The maximum number of IP addresses that each MTD child may register with this
550      *                              device as parent. 0 to clear the setting and restore the default.
551      *
552      * @retval kErrorNone           Successfully set/cleared the number.
553      * @retval kErrorInvalidArgs    If exceeds the allowed maximum number.
554      *
555      */
556     Error SetMaxChildIpAddresses(uint8_t aMaxIpAddresses);
557 
558     /**
559      * Sets whether the device was commissioned using CCM.
560      *
561      * @param[in]  aEnabled  TRUE if the device was commissioned using CCM, FALSE otherwise.
562      *
563      */
SetCcmEnabled(bool aEnabled)564     void SetCcmEnabled(bool aEnabled) { mCcmEnabled = aEnabled; }
565 
566     /**
567      * Sets whether the Security Policy TLV version-threshold for routing (VR field) is enabled.
568      *
569      * @param[in]  aEnabled  TRUE to enable Security Policy TLV version-threshold for routing, FALSE otherwise.
570      *
571      */
SetThreadVersionCheckEnabled(bool aEnabled)572     void SetThreadVersionCheckEnabled(bool aEnabled) { mThreadVersionCheckEnabled = aEnabled; }
573 
574     /**
575      * Gets the current Interval Max value used by Advertisement trickle timer.
576      *
577      * @returns The Interval Max of Advertisement trickle timer in milliseconds.
578      *
579      */
GetAdvertisementTrickleIntervalMax(void) const580     uint32_t GetAdvertisementTrickleIntervalMax(void) const { return mAdvertiseTrickleTimer.GetIntervalMax(); }
581 
582 #endif // OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
583 
584 private:
585     // Advertisement trickle timer constants - all times are in milliseconds.
586     static constexpr uint32_t kAdvIntervalMin                = 1000;  // I_MIN
587     static constexpr uint32_t kAdvIntervalNeighborMultiplier = 4000;  // Multiplier for I_MAX per router neighbor
588     static constexpr uint32_t kAdvIntervalMaxLowerBound      = 12000; // Lower bound for I_MAX
589     static constexpr uint32_t kAdvIntervalMaxUpperBound      = 32000; // Upper bound for I_MAX
590     static constexpr uint32_t kReedAdvIntervalMin            = 570000;
591     static constexpr uint32_t kReedAdvIntervalMax            = 630000;
592 #if OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
593     static constexpr uint32_t kAdvIntervalMaxLogRoutes = 5000;
594 #endif
595 
596     static constexpr uint32_t kMaxNeighborAge                = 100000; // Max neighbor age (in msec)
597     static constexpr uint32_t kMaxLeaderToRouterTimeout      = 90000;  // (in msec)
598     static constexpr uint8_t  kMinDowngradeNeighbors         = 7;
599     static constexpr uint8_t  kNetworkIdTimeout              = 120; // (in sec)
600     static constexpr uint8_t  kRouterSelectionJitter         = 120; // (in sec)
601     static constexpr uint8_t  kRouterDowngradeThreshold      = 23;
602     static constexpr uint8_t  kRouterUpgradeThreshold        = 16;
603     static constexpr uint16_t kDiscoveryMaxJitter            = 250; // Max jitter delay Discovery Responses (in msec).
604     static constexpr uint16_t kChallengeTimeout              = 2;   // Challenge timeout (in sec).
605     static constexpr uint16_t kUnsolicitedDataResponseJitter = 500; // Max delay for unsol Data Response (in msec).
606     static constexpr uint8_t  kLeaderDowngradeExtraDelay     = 10;  // Extra delay to downgrade leader (in sec).
607     static constexpr uint8_t  kDefaultLeaderWeight           = 64;
608 
609     // Threshold to accept a router upgrade request with reason
610     // `kBorderRouterRequest` (number of BRs acting as router in
611     // Network Data).
612     static constexpr uint8_t kRouterUpgradeBorderRouterRequestThreshold = 2;
613 
614     static constexpr uint8_t kLinkRequestMinMargin    = OPENTHREAD_CONFIG_MLE_LINK_REQUEST_MARGIN_MIN;
615     static constexpr uint8_t kPartitionMergeMinMargin = OPENTHREAD_CONFIG_MLE_PARTITION_MERGE_MARGIN_MIN;
616     static constexpr uint8_t kChildRouterLinks        = OPENTHREAD_CONFIG_MLE_CHILD_ROUTER_LINKS;
617     static constexpr uint8_t kMaxChildIpAddresses     = OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD;
618 
619     static constexpr uint8_t kMinCriticalChildrenCount = 6;
620 
621     static constexpr uint16_t kChildSupervisionDefaultIntervalForOlderVersion =
622         OPENTHREAD_CONFIG_CHILD_SUPERVISION_OLDER_VERSION_CHILD_DEFAULT_INTERVAL;
623 
624     static constexpr int8_t kParentPriorityHigh        = 1;
625     static constexpr int8_t kParentPriorityMedium      = 0;
626     static constexpr int8_t kParentPriorityLow         = -1;
627     static constexpr int8_t kParentPriorityUnspecified = -2;
628 
629     void  HandleDetachStart(void);
630     void  HandleChildStart(AttachMode aMode);
631     void  HandleSecurityPolicyChanged(void);
632     void  HandleLinkRequest(RxInfo &aRxInfo);
633     void  HandleLinkAccept(RxInfo &aRxInfo);
634     Error HandleLinkAccept(RxInfo &aRxInfo, bool aRequest);
635     void  HandleLinkAcceptAndRequest(RxInfo &aRxInfo);
636     Error HandleAdvertisement(RxInfo &aRxInfo, uint16_t aSourceAddress, const LeaderData &aLeaderData);
637     void  HandleParentRequest(RxInfo &aRxInfo);
638     void  HandleChildIdRequest(RxInfo &aRxInfo);
639     void  HandleChildUpdateRequest(RxInfo &aRxInfo);
640     void  HandleChildUpdateResponse(RxInfo &aRxInfo);
641     void  HandleDataRequest(RxInfo &aRxInfo);
642     void  HandleNetworkDataUpdateRouter(void);
643     void  HandleDiscoveryRequest(RxInfo &aRxInfo);
644 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
645     void HandleTimeSync(RxInfo &aRxInfo);
646 #endif
647 
648     Error ProcessRouteTlv(const RouteTlv &aRouteTlv, RxInfo &aRxInfo);
649     Error ReadAndProcessRouteTlvOnFed(RxInfo &aRxInfo, uint8_t aParentId);
650 
651     void     StopAdvertiseTrickleTimer(void);
652     uint32_t DetermineAdvertiseIntervalMax(void) const;
653 
654     Error SendAddressSolicit(ThreadStatusTlv::Status aStatus);
655     void  SendAddressSolicitResponse(const Coap::Message    &aRequest,
656                                      ThreadStatusTlv::Status aResponseStatus,
657                                      const Router           *aRouter,
658                                      const Ip6::MessageInfo &aMessageInfo);
659     void  SendAddressRelease(void);
660     void  SendAdvertisement(void);
661     Error SendLinkAccept(const Ip6::MessageInfo &aMessageInfo,
662                          Neighbor               *aNeighbor,
663                          const TlvList          &aRequestedTlvList,
664                          const RxChallenge      &aChallenge);
665     void  SendParentResponse(Child *aChild, const RxChallenge &aChallenge, bool aRoutersOnlyRequest);
666     Error SendChildIdResponse(Child &aChild);
667     Error SendChildUpdateRequest(Child &aChild);
668     void  SendChildUpdateResponse(Child                  *aChild,
669                                   const Ip6::MessageInfo &aMessageInfo,
670                                   const TlvList          &aTlvList,
671                                   const RxChallenge      &aChallenge);
672     void  SendDataResponse(const Ip6::Address &aDestination,
673                            const TlvList      &aTlvList,
674                            uint16_t            aDelay,
675                            const Message      *aRequestMessage = nullptr);
676     Error SendDiscoveryResponse(const Ip6::Address &aDestination, const Message &aDiscoverRequestMessage);
677     void  SetStateRouter(uint16_t aRloc16);
678     void  SetStateLeader(uint16_t aRloc16, LeaderStartMode aStartMode);
679     void  SetStateRouterOrLeader(DeviceRole aRole, uint16_t aRloc16, LeaderStartMode aStartMode);
680     void  StopLeader(void);
681     void  SynchronizeChildNetworkData(void);
682     Error ProcessAddressRegistrationTlv(RxInfo &aRxInfo, Child &aChild);
683     Error UpdateChildAddresses(const Message &aMessage, uint16_t aOffset, uint16_t aLength, Child &aChild);
684     bool  HasNeighborWithGoodLinkQuality(void) const;
685 
686     static void HandleAddressSolicitResponse(void                *aContext,
687                                              otMessage           *aMessage,
688                                              const otMessageInfo *aMessageInfo,
689                                              Error                aResult);
690     void HandleAddressSolicitResponse(Coap::Message *aMessage, const Ip6::MessageInfo *aMessageInfo, Error aResult);
691 
692     template <Uri kUri> void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
693 
694     void HandlePartitionChange(void);
695 
696     void SetChildStateToValid(Child &aChild);
697     bool HasChildren(void);
698     void RemoveChildren(void);
699     bool ShouldDowngrade(uint8_t aNeighborId, const RouteTlv &aRouteTlv) const;
700     bool NeighborHasComparableConnectivity(const RouteTlv &aRouteTlv, uint8_t aNeighborId) const;
701 
702     static void HandleAdvertiseTrickleTimer(TrickleTimer &aTimer);
703     void        HandleAdvertiseTrickleTimer(void);
704     void        HandleTimeTick(void);
705 
706     TrickleTimer mAdvertiseTrickleTimer;
707 
708 #if OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE
709     DeviceProperties mDeviceProperties;
710 #endif
711 
712     ChildTable  mChildTable;
713     RouterTable mRouterTable;
714 
715     uint8_t     mChallengeTimeout;
716     TxChallenge mChallenge;
717 
718     uint16_t mNextChildId;
719     uint8_t  mNetworkIdTimeout;
720     uint8_t  mRouterUpgradeThreshold;
721     uint8_t  mRouterDowngradeThreshold;
722     uint8_t  mLeaderWeight;
723 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
724     uint32_t mPreferredLeaderPartitionId; ///< only for certification testing
725     bool     mCcmEnabled : 1;
726     bool     mThreadVersionCheckEnabled : 1;
727 #endif
728     bool mRouterEligible : 1;
729     bool mAddressSolicitPending : 1;
730     bool mAddressSolicitRejected : 1;
731 
732     uint8_t mRouterId;
733     uint8_t mPreviousRouterId;
734 
735     uint32_t mPreviousPartitionIdRouter;         ///< The partition ID when last operating as a router
736     uint32_t mPreviousPartitionId;               ///< The partition ID when last attached
737     uint8_t  mPreviousPartitionRouterIdSequence; ///< The router ID sequence when last attached
738     uint8_t  mPreviousPartitionIdTimeout;        ///< The partition ID timeout when last attached
739 
740     uint8_t mRouterSelectionJitter;        ///< The variable to save the assigned jitter value.
741     uint8_t mRouterSelectionJitterTimeout; ///< The Timeout prior to request/release Router ID.
742 
743     uint8_t mChildRouterLinks;
744 
745     int8_t mParentPriority; ///< The assigned parent priority value, -2 means not assigned.
746 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
747     uint8_t mBackboneRouterRegistrationDelay; ///< Delay before registering Backbone Router service.
748 #endif
749 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
750     uint8_t mMaxChildIpAddresses;
751 #endif
752 
753 #if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
754     MeshCoP::SteeringData mSteeringData;
755 #endif
756 
757     Callback<otThreadDiscoveryRequestCallback> mDiscoveryRequestCallback;
758 };
759 
760 DeclareTmfHandler(MleRouter, kUriAddressSolicit);
761 DeclareTmfHandler(MleRouter, kUriAddressRelease);
762 
763 #endif // OPENTHREAD_FTD
764 
765 #if OPENTHREAD_MTD
766 
767 class MleRouter : public Mle
768 {
769     friend class Mle;
770     friend class ot::Instance;
771 
772 public:
MleRouter(Instance & aInstance)773     explicit MleRouter(Instance &aInstance)
774         : Mle(aInstance)
775     {
776     }
777 
IsSingleton(void) const778     bool IsSingleton(void) const { return false; }
779 
GetNextHop(uint16_t aDestination) const780     uint16_t GetNextHop(uint16_t aDestination) const { return Mle::GetNextHop(aDestination); }
781 
RemoveNeighbor(Neighbor &)782     Error RemoveNeighbor(Neighbor &) { return BecomeDetached(); }
RemoveRouterLink(Router &)783     void  RemoveRouterLink(Router &) { IgnoreError(BecomeDetached()); }
784 
IsRouterIdValid(uint8_t aRouterId)785     static bool IsRouterIdValid(uint8_t aRouterId) { return aRouterId <= kMaxRouterId; }
786 
SendChildUpdateRequest(void)787     Error SendChildUpdateRequest(void) { return Mle::SendChildUpdateRequest(); }
788 
CheckReachability(uint16_t aMeshDest,const Ip6::Header & aIp6Header)789     Error CheckReachability(uint16_t aMeshDest, const Ip6::Header &aIp6Header)
790     {
791         return Mle::CheckReachability(aMeshDest, aIp6Header);
792     }
793 };
794 
795 #endif // OPENTHREAD_MTD
796 
797 } // namespace Mle
798 
799 /**
800  * @}
801  */
802 
803 } // namespace ot
804 
805 #endif // MLE_ROUTER_HPP_
806