1 /*
2  *  Copyright (c) 2019, 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 types and constants.
32  */
33 
34 #ifndef MLE_TYPES_HPP_
35 #define MLE_TYPES_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include <limits.h>
40 #include <stdint.h>
41 #include <string.h>
42 
43 #include <openthread/thread.h>
44 #if OPENTHREAD_FTD
45 #include <openthread/thread_ftd.h>
46 #endif
47 
48 #include "common/as_core_type.hpp"
49 #include "common/clearable.hpp"
50 #include "common/code_utils.hpp"
51 #include "common/encoding.hpp"
52 #include "common/equatable.hpp"
53 #include "common/string.hpp"
54 #include "mac/mac_types.hpp"
55 #include "meshcop/extended_panid.hpp"
56 #include "net/ip6_address.hpp"
57 #include "thread/network_data_types.hpp"
58 
59 namespace ot {
60 namespace Mle {
61 
62 /**
63  * @addtogroup core-mle-core
64  *
65  * @brief
66  *   This module includes definition for MLE types and constants.
67  *
68  * @{
69  *
70  */
71 
72 constexpr uint16_t kMaxChildren               = OPENTHREAD_CONFIG_MLE_MAX_CHILDREN;
73 constexpr uint8_t  kMaxChildKeepAliveAttempts = 4; ///< Max keep alive attempts before reattach to a new Parent.
74 constexpr uint8_t  kFailedChildTransmissions  = OPENTHREAD_CONFIG_FAILED_CHILD_TRANSMISSIONS;
75 
76 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
77 // Extra one for core Backbone Router Service.
78 constexpr uint8_t kMaxServiceAlocs = OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_MAX_ALOCS + 1;
79 #else
80 constexpr uint8_t  kMaxServiceAlocs      = OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_MAX_ALOCS;
81 #endif
82 
83 constexpr uint16_t kUdpPort = 19788; ///< MLE UDP Port
84 
85 /*
86  * MLE Protocol delays and timeouts.
87  *
88  */
89 constexpr uint32_t kParentRequestRouterTimeout     = 750;  ///< Router Parent Request timeout (in msec)
90 constexpr uint32_t kParentRequestDuplicateMargin   = 50;   ///< Margin for duplicate parent request
91 constexpr uint32_t kParentRequestReedTimeout       = 1250; ///< Router and REEDs Parent Request timeout (in msec)
92 constexpr uint32_t kChildIdResponseTimeout         = 1250; ///< Wait time to receive Child ID Response (in msec)
93 constexpr uint32_t kAttachStartJitter              = 50;   ///< Max jitter time added to start of attach (in msec)
94 constexpr uint32_t kAnnounceProcessTimeout         = 250;  ///< Delay after Announce rx before channel/pan-id change
95 constexpr uint32_t kAnnounceTimeout                = 1400; ///< Total timeout for sending Announce messages (in msec)
96 constexpr uint32_t kMinAnnounceDelay               = 80;   ///< Min delay between Announcement messages (in msec)
97 constexpr uint32_t kParentResponseMaxDelayRouters  = 500;  ///< Max response delay for Parent Req to routers (in msec)
98 constexpr uint32_t kParentResponseMaxDelayAll      = 1000; ///< Max response delay for Parent Req to all (in msec)
99 constexpr uint32_t kUnicastRetransmissionDelay     = 1000; ///< Base delay before an MLE unicast retx (in msec)
100 constexpr uint32_t kChildUpdateRequestPendingDelay = 100;  ///< Delay for aggregating Child Update Req (in msec)
101 constexpr uint8_t  kMaxTransmissionCount           = 3;    ///< Max number of times an MLE message may be transmitted
102 constexpr uint32_t kMaxResponseDelay               = 1000; ///< Max response delay for a multicast request (in msec)
103 constexpr uint32_t kChildIdRequestTimeout          = 5000; ///< Max delay to rx a Child ID Request (in msec)
104 constexpr uint32_t kLinkRequestTimeout             = 2000; ///< Max delay to rx a Link Accept
105 constexpr uint8_t  kMulticastLinkRequestDelay      = 5;    ///< Max delay for sending a mcast Link Request (in sec)
106 constexpr uint8_t kMaxCriticalTransmissionCount = 6; ///< Max number of times an critical MLE message may be transmitted
107 
108 constexpr uint32_t kMulticastTransmissionDelay = 5000; ///< Delay for retransmitting a multicast packet (in msec)
109 constexpr uint32_t kMulticastTransmissionDelayMin =
110     kMulticastTransmissionDelay * 9 / 10; ///< Min delay for retransmitting a multicast packet (in msec)
111 constexpr uint32_t kMulticastTransmissionDelayMax =
112     kMulticastTransmissionDelay * 11 / 10; ///< Max delay for retransmitting a multicast packet (in msec)
113 
114 constexpr uint32_t kMinTimeoutKeepAlive = (((kMaxChildKeepAliveAttempts + 1) * kUnicastRetransmissionDelay) / 1000);
115 constexpr uint32_t kMinPollPeriod       = OPENTHREAD_CONFIG_MAC_MINIMUM_POLL_PERIOD;
116 constexpr uint32_t kRetxPollPeriod      = OPENTHREAD_CONFIG_MAC_RETX_POLL_PERIOD;
117 constexpr uint32_t kMinTimeoutDataPoll  = (kMinPollPeriod + kFailedChildTransmissions * kRetxPollPeriod) / 1000;
118 constexpr uint32_t kMinTimeout          = OT_MAX(kMinTimeoutKeepAlive, kMinTimeoutDataPoll); ///< Min timeout (in sec)
119 
120 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
121 constexpr uint8_t kLinkAcceptMaxRouters = 3; ///< Max Route TLV entries in a Link Accept message
122 #else
123 constexpr uint8_t  kLinkAcceptMaxRouters = 20; ///< Max Route TLV entries in a Link Accept message
124 #endif
125 constexpr uint8_t kLinkAcceptSequenceRollback = 64; ///< Route Sequence value rollback in a Link Accept message.
126 
127 constexpr uint16_t kMinChildId = 1;   ///< Minimum Child ID
128 constexpr uint16_t kMaxChildId = 511; ///< Maximum Child ID
129 
130 constexpr uint8_t kRouterIdOffset   = 10; ///< Bit offset of Router ID in RLOC16
131 constexpr uint8_t kRlocPrefixLength = 14; ///< Prefix length of RLOC in bytes
132 
133 constexpr uint16_t kMinChallengeSize = 4; ///< Minimum Challenge size in bytes.
134 constexpr uint16_t kMaxChallengeSize = 8; ///< Maximum Challenge size in bytes.
135 
136 /*
137  * Routing Protocol Constants
138  *
139  */
140 constexpr uint32_t kAdvertiseIntervalMin = 1; ///< Min Advertise interval (in sec)
141 #if OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
142 constexpr uint32_t kAdvertiseIntervalMax = 5; ///< Max Advertise interval (in sec)
143 #else
144 constexpr uint32_t kAdvertiseIntervalMax = 32; ///< Max Advertise interval (in sec)
145 #endif
146 
147 constexpr uint8_t kFailedRouterTransmissions = 4;
148 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
149 constexpr uint8_t kFailedCslDataPollTransmissions = 15;
150 #endif
151 
152 constexpr uint8_t  kRouterIdReuseDelay     = 100; ///< (in sec)
153 constexpr uint32_t kRouterIdSequencePeriod = 10;  ///< (in sec)
154 constexpr uint32_t kMaxNeighborAge         = 100; ///< (in sec)
155 
156 #if OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
157 constexpr uint8_t kMaxRouteCost = 127;
158 #else
159 constexpr uint8_t  kMaxRouteCost         = 16;
160 #endif
161 
162 constexpr uint8_t kMaxRouterId           = OT_NETWORK_MAX_ROUTER_ID; ///< Max Router ID
163 constexpr uint8_t kInvalidRouterId       = kMaxRouterId + 1;         ///< Value indicating incorrect Router ID
164 constexpr uint8_t kMaxRouters            = OPENTHREAD_CONFIG_MLE_MAX_ROUTERS;
165 constexpr uint8_t kMinDowngradeNeighbors = 7;
166 
167 constexpr uint8_t kNetworkIdTimeout           = 120; ///< (in sec)
168 constexpr uint8_t kParentRouteToLeaderTimeout = 20;  ///< (in sec)
169 constexpr uint8_t kRouterSelectionJitter      = 120; ///< (in sec)
170 
171 constexpr uint8_t kRouterDowngradeThreshold = 23;
172 constexpr uint8_t kRouterUpgradeThreshold   = 16;
173 
174 constexpr uint16_t kInvalidRloc16 = Mac::kShortAddrInvalid; ///< Invalid RLOC16.
175 
176 /**
177  * Threshold to accept a router upgrade request with reason `kBorderRouterRequest` (number of BRs acting as router in
178  * Network Data).
179  *
180  */
181 constexpr uint8_t kRouterUpgradeBorderRouterRequestThreshold = 2;
182 
183 constexpr uint32_t kMaxLeaderToRouterTimeout = 90;  ///< (in sec)
184 constexpr uint32_t kReedAdvertiseInterval    = 570; ///< (in sec)
185 constexpr uint32_t kReedAdvertiseJitter      = 60;  ///< (in sec)
186 
187 constexpr uint32_t kMleEndDeviceTimeout      = OPENTHREAD_CONFIG_MLE_CHILD_TIMEOUT_DEFAULT; ///< (in sec)
188 constexpr uint8_t  kMeshLocalPrefixContextId = 0; ///< 0 is reserved for Mesh Local Prefix
189 
190 constexpr int8_t kParentPriorityHigh        = 1;  ///< Parent Priority High
191 constexpr int8_t kParentPriorityMedium      = 0;  ///< Parent Priority Medium (default)
192 constexpr int8_t kParentPriorityLow         = -1; ///< Parent Priority Low
193 constexpr int8_t kParentPriorityUnspecified = -2; ///< Parent Priority Unspecified
194 
195 /**
196  * This type represents a Thread device role.
197  *
198  */
199 enum DeviceRole : uint8_t
200 {
201     kRoleDisabled = OT_DEVICE_ROLE_DISABLED, ///< The Thread stack is disabled.
202     kRoleDetached = OT_DEVICE_ROLE_DETACHED, ///< Not currently participating in a Thread network/partition.
203     kRoleChild    = OT_DEVICE_ROLE_CHILD,    ///< The Thread Child role.
204     kRoleRouter   = OT_DEVICE_ROLE_ROUTER,   ///< The Thread Router role.
205     kRoleLeader   = OT_DEVICE_ROLE_LEADER,   ///< The Thread Leader role.
206 };
207 
208 constexpr uint16_t kAloc16Leader                      = 0xfc00;
209 constexpr uint16_t kAloc16DhcpAgentStart              = 0xfc01;
210 constexpr uint16_t kAloc16DhcpAgentEnd                = 0xfc0f;
211 constexpr uint16_t kAloc16ServiceStart                = 0xfc10;
212 constexpr uint16_t kAloc16ServiceEnd                  = 0xfc2f;
213 constexpr uint16_t kAloc16CommissionerStart           = 0xfc30;
214 constexpr uint16_t kAloc16CommissionerEnd             = 0xfc37;
215 constexpr uint16_t kAloc16BackboneRouterPrimary       = 0xfc38;
216 constexpr uint16_t kAloc16CommissionerMask            = 0x0007;
217 constexpr uint16_t kAloc16NeighborDiscoveryAgentStart = 0xfc40;
218 constexpr uint16_t kAloc16NeighborDiscoveryAgentEnd   = 0xfc4e;
219 
220 constexpr uint8_t kServiceMinId = 0x00; ///< Minimal Service ID.
221 constexpr uint8_t kServiceMaxId = 0x0f; ///< Maximal Service ID.
222 
223 /**
224  * This enumeration specifies the leader role start mode.
225  *
226  * The start mode indicates whether device is starting normally as leader or restoring its role after reset.
227  *
228  */
229 enum LeaderStartMode : uint8_t
230 {
231     kStartingAsLeader,              ///< Starting as leader normally.
232     kRestoringLeaderRoleAfterReset, ///< Restoring leader role after reset.
233 };
234 
235 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
236 
237 /*
238  * Backbone Router / DUA / MLR constants
239  *
240  */
241 constexpr uint16_t kRegistrationDelayDefault         = 5;                 ///< In seconds.
242 constexpr uint32_t kMlrTimeoutDefault                = 3600;              ///< In seconds.
243 constexpr uint32_t kMlrTimeoutMin                    = 300;               ///< In seconds.
244 constexpr uint32_t kMlrTimeoutMax                    = 0x7fffffff / 1000; ///< In seconds (about 24 days).
245 constexpr uint8_t  kBackboneRouterRegistrationJitter = 5;                 ///< In seconds.
246 constexpr uint8_t  kParentAggregateDelay             = 5;                 ///< In seconds.
247 constexpr uint8_t  kNoBufDelay                       = 5;                 ///< In seconds.
248 constexpr uint8_t  kImmediateReRegisterDelay         = 1;                 ///< In seconds.
249 constexpr uint8_t  KResponseTimeoutDelay             = 30;                ///< In seconds.
250 
251 /**
252  * Time period after which the address becomes "Preferred" if no duplicate address error (in seconds).
253  *
254  */
255 constexpr uint32_t kDuaDadPeriod = 100;
256 
257 /**
258  * Maximum number of times the multicast DAD query and wait time DUA_DAD_QUERY_TIMEOUT are repeated by the BBR, as
259  * part of the DAD process.
260  *
261  */
262 constexpr uint8_t kDuaDadRepeats = 3;
263 
264 /**
265  * Time period (in seconds) during which a DUA registration is considered 'recent' at a BBR.
266  *
267  */
268 constexpr uint32_t kDuaRecentTime               = 20;
269 constexpr uint32_t kTimeSinceLastTransactionMax = 10 * 86400; ///< In seconds (10 days).
270 constexpr uint8_t  kDefaultBackboneHoplimit     = 1;          ///< default hoplimit for Backbone Link Protocol messages
271 
272 static_assert(kMlrTimeoutDefault >= kMlrTimeoutMin && kMlrTimeoutDefault <= kMlrTimeoutMax,
273               "kMlrTimeoutDefault must be larger than or equal to kMlrTimeoutMin");
274 
275 static_assert(Mle::kParentAggregateDelay > 1, "kParentAggregateDelay should be larger than 1 second");
276 static_assert(kMlrTimeoutMax * 1000 > kMlrTimeoutMax, "SecToMsec(kMlrTimeoutMax) will overflow");
277 
278 static_assert(kTimeSinceLastTransactionMax * 1000 > kTimeSinceLastTransactionMax,
279               "SecToMsec(kTimeSinceLastTransactionMax) will overflow");
280 
281 /**
282  * State change of Child's DUA
283  *
284  */
285 enum class ChildDuaState : uint8_t
286 {
287     kAdded,     ///< A new DUA registered by the Child via Address Registration.
288     kChanged,   ///< A different DUA registered by the Child via Address Registration.
289     kRemoved,   ///< DUA registered by the Child is removed and not in Address Registration.
290     kUnchanged, ///< The Child registers the same DUA again.
291 };
292 
293 #endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
294 
295 /**
296  * This type represents a MLE device mode.
297  *
298  */
299 class DeviceMode : public Equatable<DeviceMode>
300 {
301 public:
302     static constexpr uint8_t kModeRxOnWhenIdle     = 1 << 3; ///< If to keep receiver on when not transmitting.
303     static constexpr uint8_t kModeReserved         = 1 << 2; ///< Set on transmission, ignore on reception.
304     static constexpr uint8_t kModeFullThreadDevice = 1 << 1; ///< If the device is an FTD.
305     static constexpr uint8_t kModeFullNetworkData  = 1 << 0; ///< If the device requires the full Network Data.
306 
307     static constexpr uint16_t kInfoStringSize = 45; ///< String buffer size used for `ToString()`.
308 
309     /**
310      * This type defines the fixed-length `String` object returned from `ToString()`.
311      *
312      */
313     typedef String<kInfoStringSize> InfoString;
314 
315     /**
316      *  This structure represents an MLE Mode configuration.
317      *
318      */
319     typedef otLinkModeConfig ModeConfig;
320 
321     /**
322      * This is the default constructor for `DeviceMode` object.
323      *
324      */
325     DeviceMode(void) = default;
326 
327     /**
328      * This constructor initializes a `DeviceMode` object from a given mode TLV bitmask.
329      *
330      * @param[in] aMode   A mode TLV bitmask to initialize the `DeviceMode` object.
331      *
332      */
DeviceMode(uint8_t aMode)333     explicit DeviceMode(uint8_t aMode) { Set(aMode); }
334 
335     /**
336      * This constructor initializes a `DeviceMode` object from a given mode configuration structure.
337      *
338      * @param[in] aModeConfig   A mode configuration to initialize the `DeviceMode` object.
339      *
340      */
DeviceMode(ModeConfig aModeConfig)341     explicit DeviceMode(ModeConfig aModeConfig) { Set(aModeConfig); }
342 
343     /**
344      * This method gets the device mode as a mode TLV bitmask.
345      *
346      * @returns The device mode as a mode TLV bitmask.
347      *
348      */
Get(void) const349     uint8_t Get(void) const { return mMode; }
350 
351     /**
352      * This method sets the device mode from a given mode TLV bitmask.
353      *
354      * @param[in] aMode   A mode TLV bitmask.
355      *
356      */
Set(uint8_t aMode)357     void Set(uint8_t aMode) { mMode = aMode | kModeReserved; }
358 
359     /**
360      * This method gets the device mode as a mode configuration structure.
361      *
362      * @param[out] aModeConfig   A reference to a mode configuration structure to output the device mode.
363      *
364      */
365     void Get(ModeConfig &aModeConfig) const;
366 
367     /**
368      * this method sets the device mode from a given mode configuration structure.
369      *
370      * @param[in] aModeConfig   A mode configuration structure.
371      *
372      */
373     void Set(const ModeConfig &aModeConfig);
374 
375     /**
376      * This method indicates whether or not the device is rx-on-when-idle.
377      *
378      * @retval TRUE   If the device is rx-on-when-idle (non-sleepy).
379      * @retval FALSE  If the device is not rx-on-when-idle (sleepy).
380      *
381      */
IsRxOnWhenIdle(void) const382     bool IsRxOnWhenIdle(void) const { return (mMode & kModeRxOnWhenIdle) != 0; }
383 
384     /**
385      * This method indicates whether or not the device is a Full Thread Device.
386      *
387      * @retval TRUE   If the device is Full Thread Device.
388      * @retval FALSE  If the device if not Full Thread Device.
389      *
390      */
IsFullThreadDevice(void) const391     bool IsFullThreadDevice(void) const { return (mMode & kModeFullThreadDevice) != 0; }
392 
393     /**
394      * This method gets the Network Data type (full set or stable subset) that the device requests.
395      *
396      * @returns The Network Data type requested by this device.
397      *
398      */
GetNetworkDataType(void) const399     NetworkData::Type GetNetworkDataType(void) const
400     {
401         return (mMode & kModeFullNetworkData) ? NetworkData::kFullSet : NetworkData::kStableSubset;
402     }
403 
404     /**
405      * This method indicates whether or not the device is a Minimal End Device.
406      *
407      * @retval TRUE   If the device is a Minimal End Device.
408      * @retval FALSE  If the device is not a Minimal End Device.
409      *
410      */
IsMinimalEndDevice(void) const411     bool IsMinimalEndDevice(void) const
412     {
413         return (mMode & (kModeFullThreadDevice | kModeRxOnWhenIdle)) != (kModeFullThreadDevice | kModeRxOnWhenIdle);
414     }
415 
416     /**
417      * This method indicates whether or not the device mode flags are valid.
418      *
419      * An FTD which is not rx-on-when-idle (is sleepy) is considered invalid.
420      *
421      * @returns TRUE if , FALSE otherwise.
422      * @retval TRUE   If the device mode flags are valid.
423      * @retval FALSE  If the device mode flags are not valid.
424      *
425      */
IsValid(void) const426     bool IsValid(void) const { return !IsFullThreadDevice() || IsRxOnWhenIdle(); }
427 
428     /**
429      * This method converts the device mode into a human-readable string.
430      *
431      * @returns An `InfoString` object representing the device mode.
432      *
433      */
434     InfoString ToString(void) const;
435 
436 private:
437     uint8_t mMode;
438 };
439 
440 #if OPENTHREAD_FTD
441 /**
442  * This class represents device properties.
443  *
444  * The device properties are used for calculating the local leader weight on the device.
445  *
446  */
447 class DeviceProperties : public otDeviceProperties, public Clearable<DeviceProperties>
448 {
449 public:
450     /**
451      * This enumeration represents the device's power supply property.
452      *
453      */
454     enum PowerSupply : uint8_t
455     {
456         kPowerSupplyBattery          = OT_POWER_SUPPLY_BATTERY,           ///< Battery powered.
457         kPowerSupplyExternal         = OT_POWER_SUPPLY_EXTERNAL,          ///< External powered.
458         kPowerSupplyExternalStable   = OT_POWER_SUPPLY_EXTERNAL_STABLE,   ///< Stable external power with backup.
459         kPowerSupplyExternalUnstable = OT_POWER_SUPPLY_EXTERNAL_UNSTABLE, ///< Unstable external power.
460     };
461 
462     /**
463      * This constructor initializes `DeviceProperties` with default values.
464      *
465      */
466     DeviceProperties(void);
467 
468     /**
469      * This method clamps the `mLeaderWeightAdjustment` value to the valid range.
470      *
471      */
472     void ClampWeightAdjustment(void);
473 
474     /**
475      * This method calculates the leader weight based on the device properties.
476      *
477      * @returns The calculated leader weight.
478      *
479      */
480     uint8_t CalculateLeaderWeight(void) const;
481 
482 private:
483     static constexpr int8_t  kDefaultAdjustment        = OPENTHREAD_CONFIG_MLE_DEFAULT_LEADER_WEIGHT_ADJUSTMENT;
484     static constexpr uint8_t kBaseWeight               = 64;
485     static constexpr int8_t  kBorderRouterInc          = +1;
486     static constexpr int8_t  kCcmBorderRouterInc       = +8;
487     static constexpr int8_t  kIsUnstableInc            = -4;
488     static constexpr int8_t  kPowerBatteryInc          = -8;
489     static constexpr int8_t  kPowerExternalInc         = 0;
490     static constexpr int8_t  kPowerExternalStableInc   = +4;
491     static constexpr int8_t  kPowerExternalUnstableInc = -4;
492     static constexpr int8_t  kMinAdjustment            = -16;
493     static constexpr int8_t  kMaxAdjustment            = +16;
494 
495     static_assert(kDefaultAdjustment >= kMinAdjustment, "Invalid default weight adjustment");
496     static_assert(kDefaultAdjustment <= kMaxAdjustment, "Invalid default weight adjustment");
497 };
498 
499 #endif // OPENTHREAD_FTD
500 
501 /**
502  * This class represents the Thread Leader Data.
503  *
504  */
505 class LeaderData : public otLeaderData, public Clearable<LeaderData>
506 {
507 public:
508     /**
509      * This method returns the Partition ID value.
510      *
511      * @returns The Partition ID value.
512      *
513      */
GetPartitionId(void) const514     uint32_t GetPartitionId(void) const { return mPartitionId; }
515 
516     /**
517      * This method sets the Partition ID value.
518      *
519      * @param[in]  aPartitionId  The Partition ID value.
520      *
521      */
SetPartitionId(uint32_t aPartitionId)522     void SetPartitionId(uint32_t aPartitionId) { mPartitionId = aPartitionId; }
523 
524     /**
525      * This method returns the Weighting value.
526      *
527      * @returns The Weighting value.
528      *
529      */
GetWeighting(void) const530     uint8_t GetWeighting(void) const { return mWeighting; }
531 
532     /**
533      * This method sets the Weighting value.
534      *
535      * @param[in]  aWeighting  The Weighting value.
536      *
537      */
SetWeighting(uint8_t aWeighting)538     void SetWeighting(uint8_t aWeighting) { mWeighting = aWeighting; }
539 
540     /**
541      * This method returns the Data Version value for a type (full set or stable subset).
542      *
543      * @param[in] aType   The Network Data type (full set or stable subset).
544      *
545      * @returns The Data Version value for @p aType.
546      *
547      */
GetDataVersion(NetworkData::Type aType) const548     uint8_t GetDataVersion(NetworkData::Type aType) const
549     {
550         return (aType == NetworkData::kFullSet) ? mDataVersion : mStableDataVersion;
551     }
552 
553     /**
554      * This method sets the Data Version value.
555      *
556      * @param[in]  aVersion  The Data Version value.
557      *
558      */
SetDataVersion(uint8_t aVersion)559     void SetDataVersion(uint8_t aVersion) { mDataVersion = aVersion; }
560 
561     /**
562      * This method sets the Stable Data Version value.
563      *
564      * @param[in]  aVersion  The Stable Data Version value.
565      *
566      */
SetStableDataVersion(uint8_t aVersion)567     void SetStableDataVersion(uint8_t aVersion) { mStableDataVersion = aVersion; }
568 
569     /**
570      * This method returns the Leader Router ID value.
571      *
572      * @returns The Leader Router ID value.
573      *
574      */
GetLeaderRouterId(void) const575     uint8_t GetLeaderRouterId(void) const { return mLeaderRouterId; }
576 
577     /**
578      * This method sets the Leader Router ID value.
579      *
580      * @param[in]  aRouterId  The Leader Router ID value.
581      *
582      */
SetLeaderRouterId(uint8_t aRouterId)583     void SetLeaderRouterId(uint8_t aRouterId) { mLeaderRouterId = aRouterId; }
584 };
585 
586 OT_TOOL_PACKED_BEGIN
587 class RouterIdSet : public Equatable<RouterIdSet>
588 {
589 public:
590     /**
591      * This method clears the Router Id Set.
592      *
593      */
Clear(void)594     void Clear(void) { memset(mRouterIdSet, 0, sizeof(mRouterIdSet)); }
595 
596     /**
597      * This method indicates whether or not a Router ID bit is set.
598      *
599      * @param[in]  aRouterId  The Router ID.
600      *
601      * @retval TRUE   If the Router ID bit is set.
602      * @retval FALSE  If the Router ID bit is not set.
603      *
604      */
Contains(uint8_t aRouterId) const605     bool Contains(uint8_t aRouterId) const { return (mRouterIdSet[aRouterId / 8] & MaskFor(aRouterId)) != 0; }
606 
607     /**
608      * This method sets a given Router ID.
609      *
610      * @param[in]  aRouterId  The Router ID to set.
611      *
612      */
Add(uint8_t aRouterId)613     void Add(uint8_t aRouterId) { mRouterIdSet[aRouterId / 8] |= MaskFor(aRouterId); }
614 
615     /**
616      * This method removes a given Router ID.
617      *
618      * @param[in]  aRouterId  The Router ID to remove.
619      *
620      */
Remove(uint8_t aRouterId)621     void Remove(uint8_t aRouterId) { mRouterIdSet[aRouterId / 8] &= ~MaskFor(aRouterId); }
622 
623     /**
624      * This method calculates the number of allocated Router IDs in the set.
625      *
626      * @returns The number of allocated Router IDs in the set.
627      *
628      */
629     uint8_t GetNumberOfAllocatedIds(void) const;
630 
631 private:
MaskFor(uint8_t aRouterId)632     static uint8_t MaskFor(uint8_t aRouterId) { return (0x80 >> (aRouterId % 8)); }
633 
634     uint8_t mRouterIdSet[BitVectorBytes(Mle::kMaxRouterId + 1)];
635 } OT_TOOL_PACKED_END;
636 
637 /**
638  * This class represents a MLE Key Material
639  *
640  */
641 typedef Mac::KeyMaterial KeyMaterial;
642 
643 /**
644  * This class represents a MLE Key.
645  *
646  */
647 typedef Mac::Key Key;
648 
649 /**
650  * This structure represents the Thread MLE counters.
651  *
652  */
653 typedef otMleCounters Counters;
654 
655 /**
656  * This function derives the Child ID from a given RLOC16.
657  *
658  * @param[in]  aRloc16  The RLOC16 value.
659  *
660  * @returns The Child ID portion of an RLOC16.
661  *
662  */
ChildIdFromRloc16(uint16_t aRloc16)663 inline uint16_t ChildIdFromRloc16(uint16_t aRloc16) { return aRloc16 & kMaxChildId; }
664 
665 /**
666  * This function derives the Router ID portion from a given RLOC16.
667  *
668  * @param[in]  aRloc16  The RLOC16 value.
669  *
670  * @returns The Router ID portion of an RLOC16.
671  *
672  */
RouterIdFromRloc16(uint16_t aRloc16)673 inline uint8_t RouterIdFromRloc16(uint16_t aRloc16) { return aRloc16 >> kRouterIdOffset; }
674 
675 /**
676  * This function returns whether the two RLOC16 have the same Router ID.
677  *
678  * @param[in]  aRloc16A  The first RLOC16 value.
679  * @param[in]  aRloc16B  The second RLOC16 value.
680  *
681  * @returns true if the two RLOC16 have the same Router ID, false otherwise.
682  *
683  */
RouterIdMatch(uint16_t aRloc16A,uint16_t aRloc16B)684 inline bool RouterIdMatch(uint16_t aRloc16A, uint16_t aRloc16B)
685 {
686     return RouterIdFromRloc16(aRloc16A) == RouterIdFromRloc16(aRloc16B);
687 }
688 
689 /**
690  * This function returns the Service ID corresponding to a Service ALOC16.
691  *
692  * @param[in]  aAloc16  The Service ALOC16 value.
693  *
694  * @returns The Service ID corresponding to given ALOC16.
695  *
696  */
ServiceIdFromAloc(uint16_t aAloc16)697 inline uint8_t ServiceIdFromAloc(uint16_t aAloc16) { return static_cast<uint8_t>(aAloc16 - kAloc16ServiceStart); }
698 
699 /**
700  * This function returns the Service ALOC16 corresponding to a Service ID.
701  *
702  * @param[in]  aServiceId  The Service ID value.
703  *
704  * @returns The Service ALOC16 corresponding to given ID.
705  *
706  */
ServiceAlocFromId(uint8_t aServiceId)707 inline uint16_t ServiceAlocFromId(uint8_t aServiceId)
708 {
709     return static_cast<uint16_t>(aServiceId + kAloc16ServiceStart);
710 }
711 
712 /**
713  * This function returns the Commissioner Aloc corresponding to a Commissioner Session ID.
714  *
715  * @param[in]  aSessionId   The Commissioner Session ID value.
716  *
717  * @returns The Commissioner ALOC16 corresponding to given ID.
718  *
719  */
CommissionerAloc16FromId(uint16_t aSessionId)720 inline uint16_t CommissionerAloc16FromId(uint16_t aSessionId)
721 {
722     return static_cast<uint16_t>((aSessionId & kAloc16CommissionerMask) + kAloc16CommissionerStart);
723 }
724 
725 /**
726  * This function derives RLOC16 from a given Router ID.
727  *
728  * @param[in]  aRouterId  The Router ID value.
729  *
730  * @returns The RLOC16 corresponding to the given Router ID.
731  *
732  */
Rloc16FromRouterId(uint8_t aRouterId)733 inline uint16_t Rloc16FromRouterId(uint8_t aRouterId) { return static_cast<uint16_t>(aRouterId << kRouterIdOffset); }
734 
735 /**
736  * This function indicates whether or not @p aRloc16 refers to an active router.
737  *
738  * @param[in]  aRloc16  The RLOC16 value.
739  *
740  * @retval TRUE   If @p aRloc16 refers to an active router.
741  * @retval FALSE  If @p aRloc16 does not refer to an active router.
742  *
743  */
IsActiveRouter(uint16_t aRloc16)744 inline bool IsActiveRouter(uint16_t aRloc16) { return ChildIdFromRloc16(aRloc16) == 0; }
745 
746 /**
747  * This function converts a device role into a human-readable string.
748  *
749  * @param[in] aRole  The device role to convert.
750  *
751  * @returns The string representation of @p aRole.
752  *
753  */
754 const char *RoleToString(DeviceRole aRole);
755 
756 /**
757  * @}
758  *
759  */
760 
761 } // namespace Mle
762 
763 DefineCoreType(otLeaderData, Mle::LeaderData);
764 DefineMapEnum(otDeviceRole, Mle::DeviceRole);
765 #if OPENTHREAD_FTD
766 DefineCoreType(otDeviceProperties, Mle::DeviceProperties);
767 DefineMapEnum(otPowerSupply, Mle::DeviceProperties::PowerSupply);
768 #endif
769 
770 } // namespace ot
771 
772 #endif // MLE_TYPES_HPP_
773