1 /*
2  *  Copyright (c) 2016-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 MAC types.
32  */
33 
34 #ifndef MAC_TYPES_HPP_
35 #define MAC_TYPES_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include <stdint.h>
40 #include <string.h>
41 
42 #include <openthread/link.h>
43 #include <openthread/thread.h>
44 
45 #include "common/as_core_type.hpp"
46 #include "common/clearable.hpp"
47 #include "common/data.hpp"
48 #include "common/equatable.hpp"
49 #include "common/string.hpp"
50 #include "crypto/storage.hpp"
51 
52 namespace ot {
53 namespace Mac {
54 
55 /**
56  * @addtogroup core-mac
57  *
58  * @{
59  */
60 
61 /**
62  * Represents the IEEE 802.15.4 PAN ID.
63  */
64 typedef otPanId PanId;
65 
66 constexpr PanId kPanIdBroadcast = 0xffff; ///< Broadcast PAN ID.
67 
68 /**
69  * Represents the IEEE 802.15.4 Short Address.
70  */
71 typedef otShortAddress ShortAddress;
72 
73 constexpr ShortAddress kShortAddrBroadcast = OT_RADIO_BROADCAST_SHORT_ADDR; ///< Broadcast Short Address.
74 constexpr ShortAddress kShortAddrInvalid   = OT_RADIO_INVALID_SHORT_ADDR;   ///< Invalid Short Address.
75 
76 /**
77  * Generates a random IEEE 802.15.4 PAN ID.
78  *
79  * @returns A randomly generated IEEE 802.15.4 PAN ID (excluding `kPanIdBroadcast`).
80  */
81 PanId GenerateRandomPanId(void);
82 
83 /**
84  * Represents an IEEE 802.15.4 Extended Address.
85  */
86 OT_TOOL_PACKED_BEGIN
87 class ExtAddress : public otExtAddress, public Equatable<ExtAddress>, public Clearable<ExtAddress>
88 {
89 public:
90     static constexpr uint16_t kInfoStringSize = 17; ///< Max chars for the info string (`ToString()`).
91 
92     /**
93      * Defines the fixed-length `String` object returned from `ToString()`.
94      */
95     typedef String<kInfoStringSize> InfoString;
96 
97     /**
98      * Type specifies the copy byte order when Extended Address is being copied to/from a buffer.
99      */
100     enum CopyByteOrder : uint8_t
101     {
102         kNormalByteOrder,  ///< Copy address bytes in normal order (as provided in array buffer).
103         kReverseByteOrder, ///< Copy address bytes in reverse byte order.
104     };
105 
106     /**
107      * Fills all bytes of address with a given byte value.
108      *
109      * @param[in] aByte A byte value to fill address with.
110      */
Fill(uint8_t aByte)111     void Fill(uint8_t aByte) { memset(this, aByte, sizeof(*this)); }
112 
113     /**
114      * Generates a random IEEE 802.15.4 Extended Address.
115      */
116     void GenerateRandom(void);
117 
118     /**
119      * Sets the Extended Address from a given byte array.
120      *
121      * @param[in] aBuffer    Pointer to an array containing the Extended Address. `OT_EXT_ADDRESS_SIZE` bytes from
122      *                       buffer are copied to form the Extended Address.
123      * @param[in] aByteOrder The byte order to use when copying the address.
124      */
Set(const uint8_t * aBuffer,CopyByteOrder aByteOrder=kNormalByteOrder)125     void Set(const uint8_t *aBuffer, CopyByteOrder aByteOrder = kNormalByteOrder)
126     {
127         CopyAddress(m8, aBuffer, aByteOrder);
128     }
129 
130     /**
131      * Indicates whether or not the Group bit is set.
132      *
133      * @retval TRUE   If the group bit is set.
134      * @retval FALSE  If the group bit is not set.
135      */
IsGroup(void) const136     bool IsGroup(void) const { return (m8[0] & kGroupFlag) != 0; }
137 
138     /**
139      * Sets the Group bit.
140      *
141      * @param[in]  aGroup  TRUE if group address, FALSE otherwise.
142      */
SetGroup(bool aGroup)143     void SetGroup(bool aGroup)
144     {
145         if (aGroup)
146         {
147             m8[0] |= kGroupFlag;
148         }
149         else
150         {
151             m8[0] &= ~kGroupFlag;
152         }
153     }
154 
155     /**
156      * Toggles the Group bit.
157      */
ToggleGroup(void)158     void ToggleGroup(void) { m8[0] ^= kGroupFlag; }
159 
160     /**
161      * Indicates whether or not the Local bit is set.
162      *
163      * @retval TRUE   If the local bit is set.
164      * @retval FALSE  If the local bit is not set.
165      */
IsLocal(void) const166     bool IsLocal(void) const { return (m8[0] & kLocalFlag) != 0; }
167 
168     /**
169      * Sets the Local bit.
170      *
171      * @param[in]  aLocal  TRUE if locally administered, FALSE otherwise.
172      */
SetLocal(bool aLocal)173     void SetLocal(bool aLocal)
174     {
175         if (aLocal)
176         {
177             m8[0] |= kLocalFlag;
178         }
179         else
180         {
181             m8[0] &= ~kLocalFlag;
182         }
183     }
184 
185     /**
186      * Toggles the Local bit.
187      */
ToggleLocal(void)188     void ToggleLocal(void) { m8[0] ^= kLocalFlag; }
189 
190     /**
191      * Copies the Extended Address into a given buffer.
192      *
193      * @param[out] aBuffer     A pointer to a buffer to copy the Extended Address into.
194      * @param[in]  aByteOrder  The byte order to copy the address.
195      */
CopyTo(uint8_t * aBuffer,CopyByteOrder aByteOrder=kNormalByteOrder) const196     void CopyTo(uint8_t *aBuffer, CopyByteOrder aByteOrder = kNormalByteOrder) const
197     {
198         CopyAddress(aBuffer, m8, aByteOrder);
199     }
200 
201     /**
202      * Overloads operator `==` to evaluate whether or not two `ExtAddress` instances are equal.
203      *
204      * @param[in]  aOther  The other `ExtAddress` instance to compare with.
205      *
206      * @retval TRUE   If the two `ExtAddress` instances are equal.
207      * @retval FALSE  If the two `ExtAddress` instances are not equal.
208      */
209     bool operator==(const ExtAddress &aOther) const;
210 
211     /**
212      * Converts an address to a string.
213      *
214      * @returns An `InfoString` containing the string representation of the Extended Address.
215      */
216     InfoString ToString(void) const;
217 
218 private:
219     static constexpr uint8_t kGroupFlag = (1 << 0);
220     static constexpr uint8_t kLocalFlag = (1 << 1);
221 
222     static void CopyAddress(uint8_t *aDst, const uint8_t *aSrc, CopyByteOrder aByteOrder);
223 } OT_TOOL_PACKED_END;
224 
225 /**
226  * Represents an IEEE 802.15.4 Short or Extended Address.
227  */
228 class Address
229 {
230 public:
231     /**
232      * Defines the fixed-length `String` object returned from `ToString()`.
233      */
234     typedef ExtAddress::InfoString InfoString;
235 
236     /**
237      * Specifies the IEEE 802.15.4 Address type.
238      */
239     enum Type : uint8_t
240     {
241         kTypeNone,     ///< No address.
242         kTypeShort,    ///< IEEE 802.15.4 Short Address.
243         kTypeExtended, ///< IEEE 802.15.4 Extended Address.
244     };
245 
246     /**
247      * Initializes an Address.
248      */
Address(void)249     Address(void)
250         : mType(kTypeNone)
251     {
252     }
253 
254     /**
255      * Gets the address type (Short Address, Extended Address, or none).
256      *
257      * @returns The address type.
258      */
GetType(void) const259     Type GetType(void) const { return mType; }
260 
261     /**
262      * Indicates whether or not there is an address.
263      *
264      * @returns TRUE if there is no address (i.e. address type is `kTypeNone`), FALSE otherwise.
265      */
IsNone(void) const266     bool IsNone(void) const { return (mType == kTypeNone); }
267 
268     /**
269      * Indicates whether or not the Address is a Short Address.
270      *
271      * @returns TRUE if it is a Short Address, FALSE otherwise.
272      */
IsShort(void) const273     bool IsShort(void) const { return (mType == kTypeShort); }
274 
275     /**
276      * Indicates whether or not the Address is an Extended Address.
277      *
278      * @returns TRUE if it is an Extended Address, FALSE otherwise.
279      */
IsExtended(void) const280     bool IsExtended(void) const { return (mType == kTypeExtended); }
281 
282     /**
283      * Gets the address as a Short Address.
284      *
285      * MUST be used only if the address type is Short Address.
286      *
287      * @returns The Short Address.
288      */
GetShort(void) const289     ShortAddress GetShort(void) const { return mShared.mShortAddress; }
290 
291     /**
292      * Gets the address as an Extended Address.
293      *
294      * MUST be used only if the address type is Extended Address.
295      *
296      * @returns A constant reference to the Extended Address.
297      */
GetExtended(void) const298     const ExtAddress &GetExtended(void) const { return mShared.mExtAddress; }
299 
300     /**
301      * Gets the address as an Extended Address.
302      *
303      * MUST be used only if the address type is Extended Address.
304      *
305      * @returns A reference to the Extended Address.
306      */
GetExtended(void)307     ExtAddress &GetExtended(void) { return mShared.mExtAddress; }
308 
309     /**
310      * Sets the address to none (i.e., clears the address).
311      *
312      * Address type will be updated to `kTypeNone`.
313      */
SetNone(void)314     void SetNone(void) { mType = kTypeNone; }
315 
316     /**
317      * Sets the address with a Short Address.
318      *
319      * The type is also updated to indicate that address is Short.
320      *
321      * @param[in]  aShortAddress  A Short Address
322      */
SetShort(ShortAddress aShortAddress)323     void SetShort(ShortAddress aShortAddress)
324     {
325         mShared.mShortAddress = aShortAddress;
326         mType                 = kTypeShort;
327     }
328 
329     /**
330      * Sets the address with an Extended Address.
331      *
332      * The type is also updated to indicate that the address is Extended.
333      *
334      * @param[in]  aExtAddress  An Extended Address
335      */
SetExtended(const ExtAddress & aExtAddress)336     void SetExtended(const ExtAddress &aExtAddress)
337     {
338         mShared.mExtAddress = aExtAddress;
339         mType               = kTypeExtended;
340     }
341 
342     /**
343      * Sets the address with an Extended Address given as a byte array.
344      *
345      * The type is also updated to indicate that the address is Extended.
346      *
347      * @param[in] aBuffer    Pointer to an array containing the Extended Address. `OT_EXT_ADDRESS_SIZE` bytes from
348      *                       buffer are copied to form the Extended Address.
349      * @param[in] aByteOrder The byte order to copy the address from @p aBuffer.
350      */
SetExtended(const uint8_t * aBuffer,ExtAddress::CopyByteOrder aByteOrder=ExtAddress::kNormalByteOrder)351     void SetExtended(const uint8_t *aBuffer, ExtAddress::CopyByteOrder aByteOrder = ExtAddress::kNormalByteOrder)
352     {
353         mShared.mExtAddress.Set(aBuffer, aByteOrder);
354         mType = kTypeExtended;
355     }
356 
357     /**
358      * Indicates whether or not the address is a Short Broadcast Address.
359      *
360      * @returns TRUE if address is Short Broadcast Address, FALSE otherwise.
361      */
IsBroadcast(void) const362     bool IsBroadcast(void) const { return ((mType == kTypeShort) && (GetShort() == kShortAddrBroadcast)); }
363 
364     /**
365      * Indicates whether or not the address is a Short Invalid Address.
366      *
367      * @returns TRUE if address is Short Invalid Address, FALSE otherwise.
368      */
IsShortAddrInvalid(void) const369     bool IsShortAddrInvalid(void) const { return ((mType == kTypeShort) && (GetShort() == kShortAddrInvalid)); }
370 
371     /**
372      * Overloads operator `==` to evaluate whether or not two `Address` instances are equal.
373      *
374      * @param[in]  aOther  The other `Address` instance to compare with.
375      *
376      * @retval TRUE   If the two `Address` instances are equal.
377      * @retval FALSE  If the two `Address` instances are not equal.
378      */
379     bool operator==(const Address &aOther) const;
380 
381     /**
382      * Converts an address to a null-terminated string
383      *
384      * @returns A `String` representing the address.
385      */
386     InfoString ToString(void) const;
387 
388 private:
389     union
390     {
391         ShortAddress mShortAddress; ///< The IEEE 802.15.4 Short Address.
392         ExtAddress   mExtAddress;   ///< The IEEE 802.15.4 Extended Address.
393     } mShared;
394 
395     Type mType; ///< The address type (Short, Extended, or none).
396 };
397 
398 /**
399  * Represents two MAC addresses corresponding to source and destination.
400  */
401 struct Addresses
402 {
403     Address mSource;      ///< Source address.
404     Address mDestination; ///< Destination address.
405 };
406 
407 /**
408  * Represents two PAN IDs corresponding to source and destination.
409  */
410 class PanIds : public Clearable<PanIds>
411 {
412 public:
413     /**
414      * Initializes PAN IDs as empty (no source or destination PAN ID).
415      */
PanIds(void)416     PanIds(void) { Clear(); }
417 
418     /**
419      * Indicates whether or not source PAN ID is present.
420      *
421      * @retval TRUE   The source PAN ID is present.
422      * @retval FALSE  The source PAN ID is not present.
423      */
IsSourcePresent(void) const424     bool IsSourcePresent(void) const { return mIsSourcePresent; }
425 
426     /**
427      * Gets the source PAN ID when it is present.
428      *
429      * @returns The source PAN ID.
430      */
GetSource(void) const431     PanId GetSource(void) const { return mSource; }
432 
433     /**
434      * Indicates whether or not destination PAN ID is present.
435      *
436      * @retval TRUE   The destination PAN ID is present.
437      * @retval FALSE  The destination PAN ID is not present.
438      */
IsDestinationPresent(void) const439     bool IsDestinationPresent(void) const { return mIsDestinationPresent; }
440 
441     /**
442      * Gets the destination PAN ID when it is present.
443      *
444      * @returns The destination PAN ID.
445      */
GetDestination(void) const446     PanId GetDestination(void) const { return mDestination; }
447 
448     /**
449      * Sets the source PAN ID.
450      *
451      * @param[in] aPanId  The source PAN ID.
452      */
453     void SetSource(PanId aPanId);
454 
455     /**
456      * Sets the destination PAN ID.
457      *
458      * @param[in] aPanId  The source PAN ID.
459      */
460     void SetDestination(PanId aPanId);
461 
462     /**
463      * Sets both source and destination PAN IDs to the same value.
464      *
465      * @param[in] aPanId  The PAN ID.
466      */
467     void SetBothSourceDestination(PanId aPanId);
468 
469 private:
470     PanId mSource;
471     PanId mDestination;
472     bool  mIsSourcePresent;
473     bool  mIsDestinationPresent;
474 };
475 
476 /**
477  * Represents a MAC key.
478  */
479 OT_TOOL_PACKED_BEGIN
480 class Key : public otMacKey, public Equatable<Key>, public Clearable<Key>
481 {
482 public:
483     static constexpr uint16_t kSize = OT_MAC_KEY_SIZE; ///< Key size in bytes.
484 
485     /**
486      * Gets a pointer to the bytes array containing the key
487      *
488      * @returns A pointer to the byte array containing the key.
489      */
GetBytes(void) const490     const uint8_t *GetBytes(void) const { return m8; }
491 
492 } OT_TOOL_PACKED_END;
493 
494 /**
495  * Represents a MAC Key Ref used by PSA.
496  */
497 typedef otMacKeyRef KeyRef;
498 
499 /**
500  * Represents a MAC Key Material.
501  */
502 class KeyMaterial : public otMacKeyMaterial, public Unequatable<KeyMaterial>
503 {
504 public:
505     /**
506      * Initializes a `KeyMaterial`.
507      */
KeyMaterial(void)508     KeyMaterial(void)
509     {
510         GetKey().Clear();
511 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
512         SetKeyRef(kInvalidKeyRef);
513 #endif
514     }
515 
516 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
517     /**
518      * Overload `=` operator to assign the `KeyMaterial` from another one.
519      *
520      * If the `KeyMaterial` currently stores a valid and different `KeyRef`, the assignment of new value will ensure to
521      * delete the previous one before using the new `KeyRef` from @p aOther.
522      *
523      * @param[in] aOther  aOther  The other `KeyMaterial` instance to assign from.
524      *
525      * @returns A reference to the current `KeyMaterial`
526      */
527     KeyMaterial &operator=(const KeyMaterial &aOther);
528 
529     KeyMaterial(const KeyMaterial &) = delete;
530 #endif
531 
532     /**
533      *  This method clears the `KeyMaterial`.
534      *
535      * Under `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE`, if the `KeyMaterial` currently stores a valid previous
536      * `KeyRef`, the `Clear()` call will ensure to delete the previous `KeyRef` and set it to `kInvalidKeyRef`.
537      */
538     void Clear(void);
539 
540 #if !OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
541     /**
542      * Gets the literal `Key`.
543      *
544      * @returns The literal `Key`
545      */
GetKey(void) const546     const Key &GetKey(void) const { return static_cast<const Key &>(mKeyMaterial.mKey); }
547 
548 #else
549     /**
550      * Gets the stored `KeyRef`
551      *
552      * @returns The `KeyRef`
553      */
GetKeyRef(void) const554     KeyRef GetKeyRef(void) const { return mKeyMaterial.mKeyRef; }
555 #endif
556 
557     /**
558      * Sets the `KeyMaterial` from a given Key.
559      *
560      * If the `KeyMaterial` currently stores a valid `KeyRef`, the `SetFrom()` call will ensure to delete the previous
561      * one before creating and using a new `KeyRef` associated with the new `Key`.
562      *
563      * @param[in] aKey           A reference to the new key.
564      * @param[in] aIsExportable  Boolean indicating if the key is exportable (this is only applicable under
565      *                           `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` config).
566      */
567     void SetFrom(const Key &aKey, bool aIsExportable = false);
568 
569     /**
570      * Extracts the literal key from `KeyMaterial`
571      *
572      * @param[out] aKey  A reference to the output the key.
573      */
574     void ExtractKey(Key &aKey) const;
575 
576     /**
577      * Converts `KeyMaterial` to a `Crypto::Key`.
578      *
579      * @param[out]  aCryptoKey  A reference to a `Crypto::Key` to populate.
580      */
581     void ConvertToCryptoKey(Crypto::Key &aCryptoKey) const;
582 
583     /**
584      * Overloads operator `==` to evaluate whether or not two `KeyMaterial` instances are equal.
585      *
586      * @param[in]  aOther  The other `KeyMaterial` instance to compare with.
587      *
588      * @retval TRUE   If the two `KeyMaterial` instances are equal.
589      * @retval FALSE  If the two `KeyMaterial` instances are not equal.
590      */
591     bool operator==(const KeyMaterial &aOther) const;
592 
593 private:
594 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
595     static constexpr KeyRef kInvalidKeyRef = Crypto::Storage::kInvalidKeyRef;
596 
597     void DestroyKey(void);
SetKeyRef(KeyRef aKeyRef)598     void SetKeyRef(KeyRef aKeyRef) { mKeyMaterial.mKeyRef = aKeyRef; }
599 #endif
GetKey(void)600     Key &GetKey(void) { return static_cast<Key &>(mKeyMaterial.mKey); }
SetKey(const Key & aKey)601     void SetKey(const Key &aKey) { mKeyMaterial.mKey = aKey; }
602 };
603 
604 #if OPENTHREAD_CONFIG_MULTI_RADIO
605 
606 /**
607  * Defines the radio link types.
608  */
609 enum RadioType : uint8_t
610 {
611 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
612     kRadioTypeIeee802154, ///< IEEE 802.15.4 (2.4GHz) link type.
613 #endif
614 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
615     kRadioTypeTrel, ///< Thread Radio Encapsulation link type.
616 #endif
617 };
618 
619 /**
620  * This constant specifies the number of supported radio link types.
621  */
622 constexpr uint8_t kNumRadioTypes = (((OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE) ? 1 : 0) +
623                                     ((OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE) ? 1 : 0));
624 
625 /**
626  * Represents a set of radio links.
627  */
628 class RadioTypes
629 {
630 public:
631     static constexpr uint16_t kInfoStringSize = 32; ///< Max chars for the info string (`ToString()`).
632 
633     /**
634      * Defines the fixed-length `String` object returned from `ToString()`.
635      */
636     typedef String<kInfoStringSize> InfoString;
637 
638     /**
639      * This static class variable defines an array containing all supported radio link types.
640      */
641     static const RadioType kAllRadioTypes[kNumRadioTypes];
642 
643     /**
644      * Initializes a `RadioTypes` object as empty set
645      */
RadioTypes(void)646     RadioTypes(void)
647         : mBitMask(0)
648     {
649     }
650 
651     /**
652      * Initializes a `RadioTypes` object with a given bit-mask.
653      *
654      * @param[in] aMask   A bit-mask representing the radio types (the first bit corresponds to radio type 0, and so on)
655      */
RadioTypes(uint8_t aMask)656     explicit RadioTypes(uint8_t aMask)
657         : mBitMask(aMask)
658     {
659     }
660 
661     /**
662      * Clears the set.
663      */
Clear(void)664     void Clear(void) { mBitMask = 0; }
665 
666     /**
667      * Indicates whether the set is empty or not
668      *
669      * @returns TRUE if the set is empty, FALSE otherwise.
670      */
IsEmpty(void) const671     bool IsEmpty(void) const { return (mBitMask == 0); }
672 
673     /**
674      *  This method indicates whether the set contains only a single radio type.
675      *
676      * @returns TRUE if the set contains a single radio type, FALSE otherwise.
677      */
ContainsSingleRadio(void) const678     bool ContainsSingleRadio(void) const { return !IsEmpty() && ((mBitMask & (mBitMask - 1)) == 0); }
679 
680     /**
681      * Indicates whether or not the set contains a given radio type.
682      *
683      * @param[in] aType  A radio link type.
684      *
685      * @returns TRUE if the set contains @p aType, FALSE otherwise.
686      */
Contains(RadioType aType) const687     bool Contains(RadioType aType) const { return ((mBitMask & BitFlag(aType)) != 0); }
688 
689     /**
690      * Adds a radio type to the set.
691      *
692      * @param[in] aType  A radio link type.
693      */
Add(RadioType aType)694     void Add(RadioType aType) { mBitMask |= BitFlag(aType); }
695 
696     /**
697      * Adds another radio types set to the current one.
698      *
699      * @param[in] aTypes   A radio link type set to add.
700      */
Add(RadioTypes aTypes)701     void Add(RadioTypes aTypes) { mBitMask |= aTypes.mBitMask; }
702 
703     /**
704      * Adds all radio types supported by device to the set.
705      */
706     void AddAll(void);
707 
708     /**
709      * Removes a given radio type from the set.
710      *
711      * @param[in] aType  A radio link type.
712      */
Remove(RadioType aType)713     void Remove(RadioType aType) { mBitMask &= ~BitFlag(aType); }
714 
715     /**
716      * Gets the radio type set as a bitmask.
717      *
718      * The first bit in the mask corresponds to first radio type (radio type with value zero), and so on.
719      *
720      * @returns A bitmask representing the set of radio types.
721      */
GetAsBitMask(void) const722     uint8_t GetAsBitMask(void) const { return mBitMask; }
723 
724     /**
725      * Overloads operator `-` to return a new set which is the set difference between current set and
726      * a given set.
727      *
728      * @param[in] aOther  Another radio type set.
729      *
730      * @returns A new set which is set difference between current one and @p aOther.
731      */
operator -(const RadioTypes & aOther) const732     RadioTypes operator-(const RadioTypes &aOther) const { return RadioTypes(mBitMask & ~aOther.mBitMask); }
733 
734     /**
735      * Converts the radio set to human-readable string.
736      *
737      * @return A string representation of the set of radio types.
738      */
739     InfoString ToString(void) const;
740 
741 private:
BitFlag(RadioType aType)742     static uint8_t BitFlag(RadioType aType) { return static_cast<uint8_t>(1U << static_cast<uint8_t>(aType)); }
743 
744     uint8_t mBitMask;
745 };
746 
747 /**
748  * Converts a link type to a string
749  *
750  * @param[in] aRadioType  A link type value.
751  *
752  * @returns A string representation of the link type.
753  */
754 const char *RadioTypeToString(RadioType aRadioType);
755 
756 #endif // OPENTHREAD_CONFIG_MULTI_RADIO
757 
758 /**
759  * Represents Link Frame Counters for all supported radio links.
760  */
761 class LinkFrameCounters
762 {
763 public:
764     /**
765      * Resets all counters (set them all to zero).
766      */
Reset(void)767     void Reset(void) { SetAll(0); }
768 
769 #if OPENTHREAD_CONFIG_MULTI_RADIO
770 
771     /**
772      * Gets the link Frame Counter for a given radio link.
773      *
774      * @param[in] aRadioType  A radio link type.
775      *
776      * @returns The Link Frame Counter for radio link @p aRadioType.
777      */
778     uint32_t Get(RadioType aRadioType) const;
779 
780     /**
781      * Sets the Link Frame Counter for a given radio link.
782      *
783      * @param[in] aRadioType  A radio link type.
784      * @param[in] aCounter    The new counter value.
785      */
786     void Set(RadioType aRadioType, uint32_t aCounter);
787 
788 #else
789 
790     /**
791      * Gets the Link Frame Counter value.
792      *
793      * @return The Link Frame Counter value.
794      */
Get(void) const795     uint32_t Get(void) const
796 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
797     {
798         return m154Counter;
799     }
800 #elif OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
801     {
802         return mTrelCounter;
803     }
804 #endif
805 
806     /**
807      * Sets the Link Frame Counter for a given radio link.
808      *
809      * @param[in] aCounter    The new counter value.
810      */
Set(uint32_t aCounter)811     void Set(uint32_t aCounter)
812 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
813     {
814         m154Counter = aCounter;
815     }
816 #elif OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
817     {
818         mTrelCounter = aCounter;
819     }
820 #endif
821 
822 #endif // OPENTHREAD_CONFIG_MULTI_RADIO
823 
824 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
825     /**
826      * Gets the Link Frame Counter for 802.15.4 radio link.
827      *
828      * @returns The Link Frame Counter for 802.15.4 radio link.
829      */
Get154(void) const830     uint32_t Get154(void) const { return m154Counter; }
831 
832     /**
833      * Sets the Link Frame Counter for 802.15.4 radio link.
834      *
835      * @param[in] aCounter   The new counter value.
836      */
Set154(uint32_t aCounter)837     void Set154(uint32_t aCounter) { m154Counter = aCounter; }
838 #endif
839 
840 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
841     /**
842      * Gets the Link Frame Counter for TREL radio link.
843      *
844      * @returns The Link Frame Counter for TREL radio link.
845      */
GetTrel(void) const846     uint32_t GetTrel(void) const { return mTrelCounter; }
847 
848     /**
849      * Increments the Link Frame Counter for TREL radio link.
850      */
IncrementTrel(void)851     void IncrementTrel(void) { mTrelCounter++; }
852 #endif
853 
854     /**
855      * Gets the maximum Link Frame Counter among all supported radio links.
856      *
857      * @return The maximum Link frame Counter among all supported radio links.
858      */
859     uint32_t GetMaximum(void) const;
860 
861     /**
862      * Sets the Link Frame Counter value for all radio links.
863      *
864      * @param[in]  aCounter  The Link Frame Counter value.
865      */
866     void SetAll(uint32_t aCounter);
867 
868 private:
869 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
870     uint32_t m154Counter;
871 #endif
872 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
873     uint32_t mTrelCounter;
874 #endif
875 };
876 
877 /**
878  * Represents CSL accuracy.
879  */
880 class CslAccuracy
881 {
882 public:
883     static constexpr uint8_t kWorstClockAccuracy = 255; ///< Worst possible crystal accuracy, in units of ± ppm.
884     static constexpr uint8_t kWorstUncertainty   = 255; ///< Worst possible uncertainty, in units of 10 microseconds.
885 
886     /**
887      * Initializes the CSL accuracy using `kWorstClockAccuracy` and `kWorstUncertainty` values.
888      */
Init(void)889     void Init(void)
890     {
891         mClockAccuracy = kWorstClockAccuracy;
892         mUncertainty   = kWorstUncertainty;
893     }
894 
895     /**
896      * Returns the CSL clock accuracy.
897      *
898      * @returns The CSL clock accuracy in ± ppm.
899      */
GetClockAccuracy(void) const900     uint8_t GetClockAccuracy(void) const { return mClockAccuracy; }
901 
902     /**
903      * Sets the CSL clock accuracy.
904      *
905      * @param[in]  aClockAccuracy  The CSL clock accuracy in ± ppm.
906      */
SetClockAccuracy(uint8_t aClockAccuracy)907     void SetClockAccuracy(uint8_t aClockAccuracy) { mClockAccuracy = aClockAccuracy; }
908 
909     /**
910      * Returns the CSL uncertainty.
911      *
912      * @returns The uncertainty in units 10 microseconds.
913      */
GetUncertainty(void) const914     uint8_t GetUncertainty(void) const { return mUncertainty; }
915 
916     /**
917      * Gets the CLS uncertainty in microseconds.
918      *
919      * @returns the CLS uncertainty in microseconds.
920      */
GetUncertaintyInMicrosec(void) const921     uint16_t GetUncertaintyInMicrosec(void) const { return static_cast<uint16_t>(mUncertainty) * kUsPerUncertUnit; }
922 
923     /**
924      * Sets the CSL uncertainty.
925      *
926      * @param[in]  aUncertainty  The CSL uncertainty in units 10 microseconds.
927      */
SetUncertainty(uint8_t aUncertainty)928     void SetUncertainty(uint8_t aUncertainty) { mUncertainty = aUncertainty; }
929 
930 private:
931     static constexpr uint8_t kUsPerUncertUnit = 10;
932 
933     uint8_t mClockAccuracy;
934     uint8_t mUncertainty;
935 };
936 
937 /**
938  * @}
939  */
940 
941 } // namespace Mac
942 
943 DefineCoreType(otExtAddress, Mac::ExtAddress);
944 DefineCoreType(otMacKey, Mac::Key);
945 
946 } // namespace ot
947 
948 #endif // MAC_TYPES_HPP_
949