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/array.hpp"
49 #include "common/as_core_type.hpp"
50 #include "common/clearable.hpp"
51 #include "common/code_utils.hpp"
52 #include "common/encoding.hpp"
53 #include "common/equatable.hpp"
54 #include "common/string.hpp"
55 #include "mac/mac_types.hpp"
56 #include "meshcop/extended_panid.hpp"
57 #include "net/ip6_address.hpp"
58 #include "thread/network_data_types.hpp"
59 
60 namespace ot {
61 
62 class Message;
63 
64 namespace Mle {
65 
66 /**
67  * @addtogroup core-mle-core
68  *
69  * @brief
70  *   This module includes definition for MLE types and constants.
71  *
72  * @{
73  *
74  */
75 
76 constexpr uint16_t kUdpPort = 19788; ///< MLE UDP Port
77 
78 constexpr uint16_t kMaxChildren     = OPENTHREAD_CONFIG_MLE_MAX_CHILDREN; ///< Maximum number of children
79 constexpr uint16_t kMinChildId      = 1;                                  ///< Minimum Child ID
80 constexpr uint16_t kMaxChildId      = 511;                                ///< Maximum Child ID
81 constexpr uint8_t  kMaxRouters      = OPENTHREAD_CONFIG_MLE_MAX_ROUTERS;  ///< Maximum number of routers
82 constexpr uint8_t  kMaxRouterId     = OT_NETWORK_MAX_ROUTER_ID;           ///< Max Router ID
83 constexpr uint8_t  kInvalidRouterId = kMaxRouterId + 1;                   ///< Value indicating invalid Router ID
84 constexpr uint8_t  kRouterIdOffset  = 10;                                 ///< Bit offset of router ID in RLOC16
85 constexpr uint16_t kInvalidRloc16   = Mac::kShortAddrInvalid;             ///< Invalid RLOC16.
86 
87 #if OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
88 constexpr uint8_t kMaxRouteCost = 127; ///< Maximum path cost
89 #else
90 constexpr uint8_t kMaxRouteCost = 16; ///< Maximum path cost
91 #endif
92 
93 constexpr uint8_t kMeshLocalPrefixContextId = 0; ///< Reserved 6lowpan context ID for Mesh Local Prefix
94 
95 /**
96  * Number of consecutive tx failures to child (with no-ack error) to consider child-parent link broken.
97  *
98  */
99 constexpr uint8_t kFailedChildTransmissions = OPENTHREAD_CONFIG_FAILED_CHILD_TRANSMISSIONS;
100 
101 /**
102  * Threshold to accept a router upgrade request with reason `kBorderRouterRequest` (number of BRs acting as router in
103  * Network Data).
104  *
105  */
106 constexpr uint8_t kRouterUpgradeBorderRouterRequestThreshold = 2;
107 
108 /**
109  * Represents a Thread device role.
110  *
111  */
112 enum DeviceRole : uint8_t
113 {
114     kRoleDisabled = OT_DEVICE_ROLE_DISABLED, ///< The Thread stack is disabled.
115     kRoleDetached = OT_DEVICE_ROLE_DETACHED, ///< Not currently participating in a Thread network/partition.
116     kRoleChild    = OT_DEVICE_ROLE_CHILD,    ///< The Thread Child role.
117     kRoleRouter   = OT_DEVICE_ROLE_ROUTER,   ///< The Thread Router role.
118     kRoleLeader   = OT_DEVICE_ROLE_LEADER,   ///< The Thread Leader role.
119 };
120 
121 constexpr uint16_t kAloc16Leader                      = 0xfc00;
122 constexpr uint16_t kAloc16DhcpAgentStart              = 0xfc01;
123 constexpr uint16_t kAloc16DhcpAgentEnd                = 0xfc0f;
124 constexpr uint16_t kAloc16ServiceStart                = 0xfc10;
125 constexpr uint16_t kAloc16ServiceEnd                  = 0xfc2f;
126 constexpr uint16_t kAloc16CommissionerStart           = 0xfc30;
127 constexpr uint16_t kAloc16CommissionerEnd             = 0xfc37;
128 constexpr uint16_t kAloc16BackboneRouterPrimary       = 0xfc38;
129 constexpr uint16_t kAloc16CommissionerMask            = 0x0007;
130 constexpr uint16_t kAloc16NeighborDiscoveryAgentStart = 0xfc40;
131 constexpr uint16_t kAloc16NeighborDiscoveryAgentEnd   = 0xfc4e;
132 
133 /**
134  * Specifies the leader role start mode.
135  *
136  * The start mode indicates whether device is starting normally as leader or restoring its role after reset.
137  *
138  */
139 enum LeaderStartMode : uint8_t
140 {
141     kStartingAsLeader,              ///< Starting as leader normally.
142     kRestoringLeaderRoleAfterReset, ///< Restoring leader role after reset.
143 };
144 
145 /**
146  * Represents a MLE device mode.
147  *
148  */
149 class DeviceMode : public Equatable<DeviceMode>
150 {
151 public:
152     static constexpr uint8_t kModeRxOnWhenIdle     = 1 << 3; ///< If to keep receiver on when not transmitting.
153     static constexpr uint8_t kModeReserved         = 1 << 2; ///< Set on transmission, ignore on reception.
154     static constexpr uint8_t kModeFullThreadDevice = 1 << 1; ///< If the device is an FTD.
155     static constexpr uint8_t kModeFullNetworkData  = 1 << 0; ///< If the device requires the full Network Data.
156 
157     static constexpr uint16_t kInfoStringSize = 45; ///< String buffer size used for `ToString()`.
158 
159     /**
160      * Defines the fixed-length `String` object returned from `ToString()`.
161      *
162      */
163     typedef String<kInfoStringSize> InfoString;
164 
165     /**
166      *  This structure represents an MLE Mode configuration.
167      *
168      */
169     typedef otLinkModeConfig ModeConfig;
170 
171     /**
172      * This is the default constructor for `DeviceMode` object.
173      *
174      */
175     DeviceMode(void) = default;
176 
177     /**
178      * Initializes a `DeviceMode` object from a given mode TLV bitmask.
179      *
180      * @param[in] aMode   A mode TLV bitmask to initialize the `DeviceMode` object.
181      *
182      */
DeviceMode(uint8_t aMode)183     explicit DeviceMode(uint8_t aMode) { Set(aMode); }
184 
185     /**
186      * Initializes a `DeviceMode` object from a given mode configuration structure.
187      *
188      * @param[in] aModeConfig   A mode configuration to initialize the `DeviceMode` object.
189      *
190      */
DeviceMode(ModeConfig aModeConfig)191     explicit DeviceMode(ModeConfig aModeConfig) { Set(aModeConfig); }
192 
193     /**
194      * Gets the device mode as a mode TLV bitmask.
195      *
196      * @returns The device mode as a mode TLV bitmask.
197      *
198      */
Get(void) const199     uint8_t Get(void) const { return mMode; }
200 
201     /**
202      * Sets the device mode from a given mode TLV bitmask.
203      *
204      * @param[in] aMode   A mode TLV bitmask.
205      *
206      */
Set(uint8_t aMode)207     void Set(uint8_t aMode) { mMode = aMode | kModeReserved; }
208 
209     /**
210      * Gets the device mode as a mode configuration structure.
211      *
212      * @param[out] aModeConfig   A reference to a mode configuration structure to output the device mode.
213      *
214      */
215     void Get(ModeConfig &aModeConfig) const;
216 
217     /**
218      * this method sets the device mode from a given mode configuration structure.
219      *
220      * @param[in] aModeConfig   A mode configuration structure.
221      *
222      */
223     void Set(const ModeConfig &aModeConfig);
224 
225     /**
226      * Indicates whether or not the device is rx-on-when-idle.
227      *
228      * @retval TRUE   If the device is rx-on-when-idle (non-sleepy).
229      * @retval FALSE  If the device is not rx-on-when-idle (sleepy).
230      *
231      */
IsRxOnWhenIdle(void) const232     bool IsRxOnWhenIdle(void) const { return (mMode & kModeRxOnWhenIdle) != 0; }
233 
234     /**
235      * Indicates whether or not the device is a Full Thread Device.
236      *
237      * @retval TRUE   If the device is Full Thread Device.
238      * @retval FALSE  If the device if not Full Thread Device.
239      *
240      */
IsFullThreadDevice(void) const241     bool IsFullThreadDevice(void) const { return (mMode & kModeFullThreadDevice) != 0; }
242 
243     /**
244      * Gets the Network Data type (full set or stable subset) that the device requests.
245      *
246      * @returns The Network Data type requested by this device.
247      *
248      */
GetNetworkDataType(void) const249     NetworkData::Type GetNetworkDataType(void) const
250     {
251         return (mMode & kModeFullNetworkData) ? NetworkData::kFullSet : NetworkData::kStableSubset;
252     }
253 
254     /**
255      * Indicates whether or not the device is a Minimal End Device.
256      *
257      * @retval TRUE   If the device is a Minimal End Device.
258      * @retval FALSE  If the device is not a Minimal End Device.
259      *
260      */
IsMinimalEndDevice(void) const261     bool IsMinimalEndDevice(void) const
262     {
263         return (mMode & (kModeFullThreadDevice | kModeRxOnWhenIdle)) != (kModeFullThreadDevice | kModeRxOnWhenIdle);
264     }
265 
266     /**
267      * Indicates whether or not the device mode flags are valid.
268      *
269      * An FTD which is not rx-on-when-idle (is sleepy) is considered invalid.
270      *
271      * @returns TRUE if , FALSE otherwise.
272      * @retval TRUE   If the device mode flags are valid.
273      * @retval FALSE  If the device mode flags are not valid.
274      *
275      */
IsValid(void) const276     bool IsValid(void) const { return !IsFullThreadDevice() || IsRxOnWhenIdle(); }
277 
278     /**
279      * Converts the device mode into a human-readable string.
280      *
281      * @returns An `InfoString` object representing the device mode.
282      *
283      */
284     InfoString ToString(void) const;
285 
286 private:
287     uint8_t mMode;
288 };
289 
290 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE
291 /**
292  * Represents device properties.
293  *
294  * The device properties are used for calculating the local leader weight on the device.
295  *
296  */
297 class DeviceProperties : public otDeviceProperties, public Clearable<DeviceProperties>
298 {
299 public:
300     /**
301      * Represents the device's power supply property.
302      *
303      */
304     enum PowerSupply : uint8_t
305     {
306         kPowerSupplyBattery          = OT_POWER_SUPPLY_BATTERY,           ///< Battery powered.
307         kPowerSupplyExternal         = OT_POWER_SUPPLY_EXTERNAL,          ///< External powered.
308         kPowerSupplyExternalStable   = OT_POWER_SUPPLY_EXTERNAL_STABLE,   ///< Stable external power with backup.
309         kPowerSupplyExternalUnstable = OT_POWER_SUPPLY_EXTERNAL_UNSTABLE, ///< Unstable external power.
310     };
311 
312     /**
313      * Initializes `DeviceProperties` with default values.
314      *
315      */
316     DeviceProperties(void);
317 
318     /**
319      * Clamps the `mLeaderWeightAdjustment` value to the valid range.
320      *
321      */
322     void ClampWeightAdjustment(void);
323 
324     /**
325      * Calculates the leader weight based on the device properties.
326      *
327      * @returns The calculated leader weight.
328      *
329      */
330     uint8_t CalculateLeaderWeight(void) const;
331 
332 private:
333     static constexpr int8_t  kDefaultAdjustment        = OPENTHREAD_CONFIG_MLE_DEFAULT_LEADER_WEIGHT_ADJUSTMENT;
334     static constexpr uint8_t kBaseWeight               = 64;
335     static constexpr int8_t  kBorderRouterInc          = +1;
336     static constexpr int8_t  kCcmBorderRouterInc       = +8;
337     static constexpr int8_t  kIsUnstableInc            = -4;
338     static constexpr int8_t  kPowerBatteryInc          = -8;
339     static constexpr int8_t  kPowerExternalInc         = 0;
340     static constexpr int8_t  kPowerExternalStableInc   = +4;
341     static constexpr int8_t  kPowerExternalUnstableInc = -4;
342     static constexpr int8_t  kMinAdjustment            = -16;
343     static constexpr int8_t  kMaxAdjustment            = +16;
344 
345     static_assert(kDefaultAdjustment >= kMinAdjustment, "Invalid default weight adjustment");
346     static_assert(kDefaultAdjustment <= kMaxAdjustment, "Invalid default weight adjustment");
347 };
348 
349 #endif // #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE
350 
351 /**
352  * Represents the Thread Leader Data.
353  *
354  */
355 class LeaderData : public otLeaderData, public Clearable<LeaderData>
356 {
357 public:
358     /**
359      * Returns the Partition ID value.
360      *
361      * @returns The Partition ID value.
362      *
363      */
GetPartitionId(void) const364     uint32_t GetPartitionId(void) const { return mPartitionId; }
365 
366     /**
367      * Sets the Partition ID value.
368      *
369      * @param[in]  aPartitionId  The Partition ID value.
370      *
371      */
SetPartitionId(uint32_t aPartitionId)372     void SetPartitionId(uint32_t aPartitionId) { mPartitionId = aPartitionId; }
373 
374     /**
375      * Returns the Weighting value.
376      *
377      * @returns The Weighting value.
378      *
379      */
GetWeighting(void) const380     uint8_t GetWeighting(void) const { return mWeighting; }
381 
382     /**
383      * Sets the Weighting value.
384      *
385      * @param[in]  aWeighting  The Weighting value.
386      *
387      */
SetWeighting(uint8_t aWeighting)388     void SetWeighting(uint8_t aWeighting) { mWeighting = aWeighting; }
389 
390     /**
391      * Returns the Data Version value for a type (full set or stable subset).
392      *
393      * @param[in] aType   The Network Data type (full set or stable subset).
394      *
395      * @returns The Data Version value for @p aType.
396      *
397      */
GetDataVersion(NetworkData::Type aType) const398     uint8_t GetDataVersion(NetworkData::Type aType) const
399     {
400         return (aType == NetworkData::kFullSet) ? mDataVersion : mStableDataVersion;
401     }
402 
403     /**
404      * Sets the Data Version value.
405      *
406      * @param[in]  aVersion  The Data Version value.
407      *
408      */
SetDataVersion(uint8_t aVersion)409     void SetDataVersion(uint8_t aVersion) { mDataVersion = aVersion; }
410 
411     /**
412      * Sets the Stable Data Version value.
413      *
414      * @param[in]  aVersion  The Stable Data Version value.
415      *
416      */
SetStableDataVersion(uint8_t aVersion)417     void SetStableDataVersion(uint8_t aVersion) { mStableDataVersion = aVersion; }
418 
419     /**
420      * Returns the Leader Router ID value.
421      *
422      * @returns The Leader Router ID value.
423      *
424      */
GetLeaderRouterId(void) const425     uint8_t GetLeaderRouterId(void) const { return mLeaderRouterId; }
426 
427     /**
428      * Sets the Leader Router ID value.
429      *
430      * @param[in]  aRouterId  The Leader Router ID value.
431      *
432      */
SetLeaderRouterId(uint8_t aRouterId)433     void SetLeaderRouterId(uint8_t aRouterId) { mLeaderRouterId = aRouterId; }
434 };
435 
436 OT_TOOL_PACKED_BEGIN
437 class RouterIdSet : public Equatable<RouterIdSet>
438 {
439 public:
440     /**
441      * Clears the Router Id Set.
442      *
443      */
Clear(void)444     void Clear(void) { memset(mRouterIdSet, 0, sizeof(mRouterIdSet)); }
445 
446     /**
447      * Indicates whether or not a Router ID bit is set.
448      *
449      * @param[in]  aRouterId  The Router ID.
450      *
451      * @retval TRUE   If the Router ID bit is set.
452      * @retval FALSE  If the Router ID bit is not set.
453      *
454      */
Contains(uint8_t aRouterId) const455     bool Contains(uint8_t aRouterId) const { return (mRouterIdSet[aRouterId / 8] & MaskFor(aRouterId)) != 0; }
456 
457     /**
458      * Sets a given Router ID.
459      *
460      * @param[in]  aRouterId  The Router ID to set.
461      *
462      */
Add(uint8_t aRouterId)463     void Add(uint8_t aRouterId) { mRouterIdSet[aRouterId / 8] |= MaskFor(aRouterId); }
464 
465     /**
466      * Removes a given Router ID.
467      *
468      * @param[in]  aRouterId  The Router ID to remove.
469      *
470      */
Remove(uint8_t aRouterId)471     void Remove(uint8_t aRouterId) { mRouterIdSet[aRouterId / 8] &= ~MaskFor(aRouterId); }
472 
473     /**
474      * Calculates the number of allocated Router IDs in the set.
475      *
476      * @returns The number of allocated Router IDs in the set.
477      *
478      */
479     uint8_t GetNumberOfAllocatedIds(void) const;
480 
481 private:
MaskFor(uint8_t aRouterId)482     static uint8_t MaskFor(uint8_t aRouterId) { return (0x80 >> (aRouterId % 8)); }
483 
484     uint8_t mRouterIdSet[BitVectorBytes(Mle::kMaxRouterId + 1)];
485 } OT_TOOL_PACKED_END;
486 
487 class TxChallenge;
488 
489 /**
490  * Represents a received Challenge data from an MLE message.
491  *
492  */
493 class RxChallenge
494 {
495 public:
496     static constexpr uint8_t kMinSize = 4; ///< Minimum Challenge size in bytes.
497     static constexpr uint8_t kMaxSize = 8; ///< Maximum Challenge size in bytes.
498 
499     /**
500      * Clears the challenge.
501      *
502      */
Clear(void)503     void Clear(void) { mArray.Clear(); }
504 
505     /**
506      * Indicates whether or not the challenge data is empty.
507      *
508      * @retval TRUE  The challenge is empty.
509      * @retval FALSE The challenge is not empty.
510      *
511      */
IsEmpty(void) const512     bool IsEmpty(void) const { return mArray.GetLength() == 0; }
513 
514     /**
515      * Gets a pointer to challenge data bytes.
516      *
517      * @return A pointer to the challenge data bytes.
518      *
519      */
GetBytes(void) const520     const uint8_t *GetBytes(void) const { return mArray.GetArrayBuffer(); }
521 
522     /**
523      * Gets the length of challenge data.
524      *
525      * @returns The length of challenge data in bytes.
526      *
527      */
GetLength(void) const528     uint8_t GetLength(void) const { return mArray.GetLength(); }
529 
530     /**
531      * Reads the challenge bytes from given message.
532      *
533      * If the given @p aLength is longer than `kMaxSize`, only `kMaxSize` bytes will be read.
534      *
535      * @param[in] aMessage   The message to read the challenge from.
536      * @param[in] aOffset    The offset in @p aMessage to read from.
537      * @param[in] aLength    Number of bytes to read.
538      *
539      * @retval kErrorNone     Successfully read the challenge data from @p aMessage.
540      * @retval kErrorParse    Not enough bytes to read, or invalid @p aLength (smaller than `kMinSize`).
541      *
542      */
543     Error ReadFrom(const Message &aMessage, uint16_t aOffset, uint16_t aLength);
544 
545     /**
546      * Compares the `RxChallenge` with a given `TxChallenge`.
547      *
548      * @param[in] aTxChallenge  The `TxChallenge` to compare with.
549      *
550      * @retval TRUE  The two challenges are equal.
551      * @retval FALSE The two challenges are not equal.
552      *
553      */
554     bool operator==(const TxChallenge &aTxChallenge) const;
555 
556 private:
557     Array<uint8_t, kMaxSize> mArray;
558 };
559 
560 /**
561  * Represents a max-sized challenge data to send in MLE message.
562  *
563  * OpenThread always uses max size challenge when sending MLE messages.
564  *
565  */
566 class TxChallenge : public Clearable<TxChallenge>
567 {
568     friend class RxChallenge;
569 
570 public:
571     /**
572      * Generates a cryptographically secure random sequence to populate the challenge data.
573      *
574      */
575     void GenerateRandom(void);
576 
577 private:
578     uint8_t m8[RxChallenge::kMaxSize];
579 };
580 
581 /**
582  * Represents a MLE Key Material
583  *
584  */
585 typedef Mac::KeyMaterial KeyMaterial;
586 
587 /**
588  * Represents a MLE Key.
589  *
590  */
591 typedef Mac::Key Key;
592 
593 /**
594  * Represents the Thread MLE counters.
595  *
596  */
597 typedef otMleCounters Counters;
598 
599 /**
600  * Derives the Child ID from a given RLOC16.
601  *
602  * @param[in]  aRloc16  The RLOC16 value.
603  *
604  * @returns The Child ID portion of an RLOC16.
605  *
606  */
ChildIdFromRloc16(uint16_t aRloc16)607 inline uint16_t ChildIdFromRloc16(uint16_t aRloc16) { return aRloc16 & kMaxChildId; }
608 
609 /**
610  * Derives the Router ID portion from a given RLOC16.
611  *
612  * @param[in]  aRloc16  The RLOC16 value.
613  *
614  * @returns The Router ID portion of an RLOC16.
615  *
616  */
RouterIdFromRloc16(uint16_t aRloc16)617 inline uint8_t RouterIdFromRloc16(uint16_t aRloc16) { return aRloc16 >> kRouterIdOffset; }
618 
619 /**
620  * Returns whether the two RLOC16 have the same Router ID.
621  *
622  * @param[in]  aRloc16A  The first RLOC16 value.
623  * @param[in]  aRloc16B  The second RLOC16 value.
624  *
625  * @returns true if the two RLOC16 have the same Router ID, false otherwise.
626  *
627  */
RouterIdMatch(uint16_t aRloc16A,uint16_t aRloc16B)628 inline bool RouterIdMatch(uint16_t aRloc16A, uint16_t aRloc16B)
629 {
630     return RouterIdFromRloc16(aRloc16A) == RouterIdFromRloc16(aRloc16B);
631 }
632 
633 /**
634  * Returns the Service ID corresponding to a Service ALOC16.
635  *
636  * @param[in]  aAloc16  The Service ALOC16 value.
637  *
638  * @returns The Service ID corresponding to given ALOC16.
639  *
640  */
ServiceIdFromAloc(uint16_t aAloc16)641 inline uint8_t ServiceIdFromAloc(uint16_t aAloc16) { return static_cast<uint8_t>(aAloc16 - kAloc16ServiceStart); }
642 
643 /**
644  * Returns the Service ALOC16 corresponding to a Service ID.
645  *
646  * @param[in]  aServiceId  The Service ID value.
647  *
648  * @returns The Service ALOC16 corresponding to given ID.
649  *
650  */
ServiceAlocFromId(uint8_t aServiceId)651 inline uint16_t ServiceAlocFromId(uint8_t aServiceId)
652 {
653     return static_cast<uint16_t>(aServiceId + kAloc16ServiceStart);
654 }
655 
656 /**
657  * Returns the Commissioner Aloc corresponding to a Commissioner Session ID.
658  *
659  * @param[in]  aSessionId   The Commissioner Session ID value.
660  *
661  * @returns The Commissioner ALOC16 corresponding to given ID.
662  *
663  */
CommissionerAloc16FromId(uint16_t aSessionId)664 inline uint16_t CommissionerAloc16FromId(uint16_t aSessionId)
665 {
666     return static_cast<uint16_t>((aSessionId & kAloc16CommissionerMask) + kAloc16CommissionerStart);
667 }
668 
669 /**
670  * Derives RLOC16 from a given Router ID.
671  *
672  * @param[in]  aRouterId  The Router ID value.
673  *
674  * @returns The RLOC16 corresponding to the given Router ID.
675  *
676  */
Rloc16FromRouterId(uint8_t aRouterId)677 inline uint16_t Rloc16FromRouterId(uint8_t aRouterId) { return static_cast<uint16_t>(aRouterId << kRouterIdOffset); }
678 
679 /**
680  * Indicates whether or not @p aRloc16 refers to an active router.
681  *
682  * @param[in]  aRloc16  The RLOC16 value.
683  *
684  * @retval TRUE   If @p aRloc16 refers to an active router.
685  * @retval FALSE  If @p aRloc16 does not refer to an active router.
686  *
687  */
IsActiveRouter(uint16_t aRloc16)688 inline bool IsActiveRouter(uint16_t aRloc16) { return ChildIdFromRloc16(aRloc16) == 0; }
689 
690 /**
691  * Converts a device role into a human-readable string.
692  *
693  * @param[in] aRole  The device role to convert.
694  *
695  * @returns The string representation of @p aRole.
696  *
697  */
698 const char *RoleToString(DeviceRole aRole);
699 
700 /**
701  * @}
702  *
703  */
704 
705 } // namespace Mle
706 
707 DefineCoreType(otLeaderData, Mle::LeaderData);
708 DefineMapEnum(otDeviceRole, Mle::DeviceRole);
709 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE
710 DefineCoreType(otDeviceProperties, Mle::DeviceProperties);
711 DefineMapEnum(otPowerSupply, Mle::DeviceProperties::PowerSupply);
712 #endif
713 
714 } // namespace ot
715 
716 #endif // MLE_TYPES_HPP_
717