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