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  * 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  * 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  * 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  * 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      * Defines the fixed-length `String` object returned from `ToString()`.
99      *
100      */
101     typedef String<kInfoStringSize> InfoString;
102 
103     /**
104      * 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      * 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      * Generates a random IEEE 802.15.4 Extended Address.
123      *
124      */
125     void GenerateRandom(void);
126 
127     /**
128      * 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      * 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      * 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      * Toggles the Group bit.
169      *
170      */
ToggleGroup(void)171     void ToggleGroup(void) { m8[0] ^= kGroupFlag; }
172 
173     /**
174      * 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      * 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      * Toggles the Local bit.
202      *
203      */
ToggleLocal(void)204     void ToggleLocal(void) { m8[0] ^= kLocalFlag; }
205 
206     /**
207      * 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      * 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  * Represents an IEEE 802.15.4 Short or Extended Address.
235  *
236  */
237 class Address
238 {
239 public:
240     /**
241      * Defines the fixed-length `String` object returned from `ToString()`.
242      *
243      */
244     typedef ExtAddress::InfoString InfoString;
245 
246     /**
247      * 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      * Initializes an Address.
259      *
260      */
Address(void)261     Address(void)
262         : mType(kTypeNone)
263     {
264     }
265 
266     /**
267      * 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      * 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      * 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      * 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      * Gets the address as a Short Address.
300      *
301      * 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      * Gets the address as an Extended Address.
310      *
311      * 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      * Gets the address as an Extended Address.
320      *
321      * 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      * 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      * 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      * 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      * 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      * 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      * 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      * 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  * 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  * Represents two PAN IDs corresponding to source and destination.
426  *
427  */
428 class PanIds : public Clearable<PanIds>
429 {
430 public:
431     /**
432      * Initializes PAN IDs as empty (no source or destination PAN ID).
433      *
434      */
PanIds(void)435     PanIds(void) { Clear(); }
436 
437     /**
438      * Indicates whether or not source PAN ID is present.
439      *
440      * @retval TRUE   The source PAN ID is present.
441      * @retval FALSE  The source PAN ID is not present.
442      *
443      */
IsSourcePresent(void) const444     bool IsSourcePresent(void) const { return mIsSourcePresent; }
445 
446     /**
447      * Gets the source PAN ID when it is present.
448      *
449      * @returns The source PAN ID.
450      *
451      */
GetSource(void) const452     PanId GetSource(void) const { return mSource; }
453 
454     /**
455      * Indicates whether or not destination PAN ID is present.
456      *
457      * @retval TRUE   The destination PAN ID is present.
458      * @retval FALSE  The destination PAN ID is not present.
459      *
460      */
IsDestinationPresent(void) const461     bool IsDestinationPresent(void) const { return mIsDestinationPresent; }
462 
463     /**
464      * Gets the destination PAN ID when it is present.
465      *
466      * @returns The destination PAN ID.
467      *
468      */
GetDestination(void) const469     PanId GetDestination(void) const { return mDestination; }
470 
471     /**
472      * Sets the source PAN ID.
473      *
474      * @param[in] aPanId  The source PAN ID.
475      *
476      */
477     void SetSource(PanId aPanId);
478 
479     /**
480      * Sets the destination PAN ID.
481      *
482      * @param[in] aPanId  The source PAN ID.
483      *
484      */
485     void SetDestination(PanId aPanId);
486 
487     /**
488      * Sets both source and destination PAN IDs to the same value.
489      *
490      * @param[in] aPanId  The PAN ID.
491      *
492      */
493     void SetBothSourceDestination(PanId aPanId);
494 
495 private:
496     PanId mSource;
497     PanId mDestination;
498     bool  mIsSourcePresent;
499     bool  mIsDestinationPresent;
500 };
501 
502 /**
503  * Represents a MAC key.
504  *
505  */
506 OT_TOOL_PACKED_BEGIN
507 class Key : public otMacKey, public Equatable<Key>, public Clearable<Key>
508 {
509 public:
510     static constexpr uint16_t kSize = OT_MAC_KEY_SIZE; ///< Key size in bytes.
511 
512     /**
513      * Gets a pointer to the bytes array containing the key
514      *
515      * @returns A pointer to the byte array containing the key.
516      *
517      */
GetBytes(void) const518     const uint8_t *GetBytes(void) const { return m8; }
519 
520 } OT_TOOL_PACKED_END;
521 
522 /**
523  * Represents a MAC Key Ref used by PSA.
524  *
525  */
526 typedef otMacKeyRef KeyRef;
527 
528 /**
529  * Represents a MAC Key Material.
530  *
531  */
532 class KeyMaterial : public otMacKeyMaterial, public Unequatable<KeyMaterial>
533 {
534 public:
535     /**
536      * Initializes a `KeyMaterial`.
537      *
538      */
KeyMaterial(void)539     KeyMaterial(void)
540     {
541         GetKey().Clear();
542 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
543         SetKeyRef(kInvalidKeyRef);
544 #endif
545     }
546 
547 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
548     /**
549      * Overload `=` operator to assign the `KeyMaterial` from another one.
550      *
551      * If the `KeyMaterial` currently stores a valid and different `KeyRef`, the assignment of new value will ensure to
552      * delete the previous one before using the new `KeyRef` from @p aOther.
553      *
554      * @param[in] aOther  aOther  The other `KeyMaterial` instance to assign from.
555      *
556      * @returns A reference to the current `KeyMaterial`
557      *
558      */
559     KeyMaterial &operator=(const KeyMaterial &aOther);
560 
561     KeyMaterial(const KeyMaterial &) = delete;
562 #endif
563 
564     /**
565      *  This method clears the `KeyMaterial`.
566      *
567      * Under `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE`, if the `KeyMaterial` currently stores a valid previous
568      * `KeyRef`, the `Clear()` call will ensure to delete the previous `KeyRef` and set it to `kInvalidKeyRef`.
569      *
570      */
571     void Clear(void);
572 
573 #if !OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
574     /**
575      * Gets the literal `Key`.
576      *
577      * @returns The literal `Key`
578      *
579      */
GetKey(void) const580     const Key &GetKey(void) const { return static_cast<const Key &>(mKeyMaterial.mKey); }
581 
582 #else
583     /**
584      * Gets the stored `KeyRef`
585      *
586      * @returns The `KeyRef`
587      *
588      */
GetKeyRef(void) const589     KeyRef GetKeyRef(void) const { return mKeyMaterial.mKeyRef; }
590 #endif
591 
592     /**
593      * Sets the `KeyMaterial` from a given Key.
594      *
595      * If the `KeyMaterial` currently stores a valid `KeyRef`, the `SetFrom()` call will ensure to delete the previous
596      * one before creating and using a new `KeyRef` associated with the new `Key`.
597      *
598      * @param[in] aKey           A reference to the new key.
599      * @param[in] aIsExportable  Boolean indicating if the key is exportable (this is only applicable under
600      *                           `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` config).
601      *
602      */
603     void SetFrom(const Key &aKey, bool aIsExportable = false);
604 
605     /**
606      * Extracts the literal key from `KeyMaterial`
607      *
608      * @param[out] aKey  A reference to the output the key.
609      *
610      */
611     void ExtractKey(Key &aKey) const;
612 
613     /**
614      * Converts `KeyMaterial` to a `Crypto::Key`.
615      *
616      * @param[out]  aCryptoKey  A reference to a `Crypto::Key` to populate.
617      *
618      */
619     void ConvertToCryptoKey(Crypto::Key &aCryptoKey) const;
620 
621     /**
622      * Overloads operator `==` to evaluate whether or not two `KeyMaterial` instances are equal.
623      *
624      * @param[in]  aOther  The other `KeyMaterial` instance to compare with.
625      *
626      * @retval TRUE   If the two `KeyMaterial` instances are equal.
627      * @retval FALSE  If the two `KeyMaterial` instances are not equal.
628      *
629      */
630     bool operator==(const KeyMaterial &aOther) const;
631 
632 private:
633 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
634     static constexpr KeyRef kInvalidKeyRef = Crypto::Storage::kInvalidKeyRef;
635 
636     void DestroyKey(void);
SetKeyRef(KeyRef aKeyRef)637     void SetKeyRef(KeyRef aKeyRef) { mKeyMaterial.mKeyRef = aKeyRef; }
638 #endif
GetKey(void)639     Key &GetKey(void) { return static_cast<Key &>(mKeyMaterial.mKey); }
SetKey(const Key & aKey)640     void SetKey(const Key &aKey) { mKeyMaterial.mKey = aKey; }
641 };
642 
643 #if OPENTHREAD_CONFIG_MULTI_RADIO
644 
645 /**
646  * Defines the radio link types.
647  *
648  */
649 enum RadioType : uint8_t
650 {
651 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
652     kRadioTypeIeee802154, ///< IEEE 802.15.4 (2.4GHz) link type.
653 #endif
654 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
655     kRadioTypeTrel, ///< Thread Radio Encapsulation link type.
656 #endif
657 };
658 
659 /**
660  * This constant specifies the number of supported radio link types.
661  *
662  */
663 constexpr uint8_t kNumRadioTypes = (((OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE) ? 1 : 0) +
664                                     ((OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE) ? 1 : 0));
665 
666 /**
667  * Represents a set of radio links.
668  *
669  */
670 class RadioTypes
671 {
672 public:
673     static constexpr uint16_t kInfoStringSize = 32; ///< Max chars for the info string (`ToString()`).
674 
675     /**
676      * Defines the fixed-length `String` object returned from `ToString()`.
677      *
678      */
679     typedef String<kInfoStringSize> InfoString;
680 
681     /**
682      * This static class variable defines an array containing all supported radio link types.
683      *
684      */
685     static const RadioType kAllRadioTypes[kNumRadioTypes];
686 
687     /**
688      * Initializes a `RadioTypes` object as empty set
689      *
690      */
RadioTypes(void)691     RadioTypes(void)
692         : mBitMask(0)
693     {
694     }
695 
696     /**
697      * Initializes a `RadioTypes` object with a given bit-mask.
698      *
699      * @param[in] aMask   A bit-mask representing the radio types (the first bit corresponds to radio type 0, and so on)
700      *
701      */
RadioTypes(uint8_t aMask)702     explicit RadioTypes(uint8_t aMask)
703         : mBitMask(aMask)
704     {
705     }
706 
707     /**
708      * Clears the set.
709      *
710      */
Clear(void)711     void Clear(void) { mBitMask = 0; }
712 
713     /**
714      * Indicates whether the set is empty or not
715      *
716      * @returns TRUE if the set is empty, FALSE otherwise.
717      *
718      */
IsEmpty(void) const719     bool IsEmpty(void) const { return (mBitMask == 0); }
720 
721     /**
722      *  This method indicates whether the set contains only a single radio type.
723      *
724      * @returns TRUE if the set contains a single radio type, FALSE otherwise.
725      *
726      */
ContainsSingleRadio(void) const727     bool ContainsSingleRadio(void) const { return !IsEmpty() && ((mBitMask & (mBitMask - 1)) == 0); }
728 
729     /**
730      * Indicates whether or not the set contains a given radio type.
731      *
732      * @param[in] aType  A radio link type.
733      *
734      * @returns TRUE if the set contains @p aType, FALSE otherwise.
735      *
736      */
Contains(RadioType aType) const737     bool Contains(RadioType aType) const { return ((mBitMask & BitFlag(aType)) != 0); }
738 
739     /**
740      * Adds a radio type to the set.
741      *
742      * @param[in] aType  A radio link type.
743      *
744      */
Add(RadioType aType)745     void Add(RadioType aType) { mBitMask |= BitFlag(aType); }
746 
747     /**
748      * Adds another radio types set to the current one.
749      *
750      * @param[in] aTypes   A radio link type set to add.
751      *
752      */
Add(RadioTypes aTypes)753     void Add(RadioTypes aTypes) { mBitMask |= aTypes.mBitMask; }
754 
755     /**
756      * Adds all radio types supported by device to the set.
757      *
758      */
759     void AddAll(void);
760 
761     /**
762      * Removes a given radio type from the set.
763      *
764      * @param[in] aType  A radio link type.
765      *
766      */
Remove(RadioType aType)767     void Remove(RadioType aType) { mBitMask &= ~BitFlag(aType); }
768 
769     /**
770      * Gets the radio type set as a bitmask.
771      *
772      * The first bit in the mask corresponds to first radio type (radio type with value zero), and so on.
773      *
774      * @returns A bitmask representing the set of radio types.
775      *
776      */
GetAsBitMask(void) const777     uint8_t GetAsBitMask(void) const { return mBitMask; }
778 
779     /**
780      * Overloads operator `-` to return a new set which is the set difference between current set and
781      * a given set.
782      *
783      * @param[in] aOther  Another radio type set.
784      *
785      * @returns A new set which is set difference between current one and @p aOther.
786      *
787      */
operator -(const RadioTypes & aOther) const788     RadioTypes operator-(const RadioTypes &aOther) const { return RadioTypes(mBitMask & ~aOther.mBitMask); }
789 
790     /**
791      * Converts the radio set to human-readable string.
792      *
793      * @return A string representation of the set of radio types.
794      *
795      */
796     InfoString ToString(void) const;
797 
798 private:
BitFlag(RadioType aType)799     static uint8_t BitFlag(RadioType aType) { return static_cast<uint8_t>(1U << static_cast<uint8_t>(aType)); }
800 
801     uint8_t mBitMask;
802 };
803 
804 /**
805  * Converts a link type to a string
806  *
807  * @param[in] aRadioType  A link type value.
808  *
809  * @returns A string representation of the link type.
810  *
811  */
812 const char *RadioTypeToString(RadioType aRadioType);
813 
814 #endif // OPENTHREAD_CONFIG_MULTI_RADIO
815 
816 /**
817  * Represents Link Frame Counters for all supported radio links.
818  *
819  */
820 class LinkFrameCounters
821 {
822 public:
823     /**
824      * Resets all counters (set them all to zero).
825      *
826      */
Reset(void)827     void Reset(void) { SetAll(0); }
828 
829 #if OPENTHREAD_CONFIG_MULTI_RADIO
830 
831     /**
832      * Gets the link Frame Counter for a given radio link.
833      *
834      * @param[in] aRadioType  A radio link type.
835      *
836      * @returns The Link Frame Counter for radio link @p aRadioType.
837      *
838      */
839     uint32_t Get(RadioType aRadioType) const;
840 
841     /**
842      * Sets the Link Frame Counter for a given radio link.
843      *
844      * @param[in] aRadioType  A radio link type.
845      * @param[in] aCounter    The new counter value.
846      *
847      */
848     void Set(RadioType aRadioType, uint32_t aCounter);
849 
850 #else
851 
852     /**
853      * Gets the Link Frame Counter value.
854      *
855      * @return The Link Frame Counter value.
856      *
857      */
Get(void) const858     uint32_t Get(void) const
859 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
860     {
861         return m154Counter;
862     }
863 #elif OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
864     {
865         return mTrelCounter;
866     }
867 #endif
868 
869     /**
870      * Sets the Link Frame Counter for a given radio link.
871      *
872      * @param[in] aCounter    The new counter value.
873      *
874      */
Set(uint32_t aCounter)875     void Set(uint32_t aCounter)
876 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
877     {
878         m154Counter = aCounter;
879     }
880 #elif OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
881     {
882         mTrelCounter = aCounter;
883     }
884 #endif
885 
886 #endif // OPENTHREAD_CONFIG_MULTI_RADIO
887 
888 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
889     /**
890      * Gets the Link Frame Counter for 802.15.4 radio link.
891      *
892      * @returns The Link Frame Counter for 802.15.4 radio link.
893      *
894      */
Get154(void) const895     uint32_t Get154(void) const { return m154Counter; }
896 
897     /**
898      * Sets the Link Frame Counter for 802.15.4 radio link.
899      *
900      * @param[in] aCounter   The new counter value.
901      *
902      */
Set154(uint32_t aCounter)903     void Set154(uint32_t aCounter) { m154Counter = aCounter; }
904 #endif
905 
906 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
907     /**
908      * Gets the Link Frame Counter for TREL radio link.
909      *
910      * @returns The Link Frame Counter for TREL radio link.
911      *
912      */
GetTrel(void) const913     uint32_t GetTrel(void) const { return mTrelCounter; }
914 
915     /**
916      * Increments the Link Frame Counter for TREL radio link.
917      *
918      */
IncrementTrel(void)919     void IncrementTrel(void) { mTrelCounter++; }
920 #endif
921 
922     /**
923      * Gets the maximum Link Frame Counter among all supported radio links.
924      *
925      * @return The maximum Link frame Counter among all supported radio links.
926      *
927      */
928     uint32_t GetMaximum(void) const;
929 
930     /**
931      * Sets the Link Frame Counter value for all radio links.
932      *
933      * @param[in]  aCounter  The Link Frame Counter value.
934      *
935      */
936     void SetAll(uint32_t aCounter);
937 
938 private:
939 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
940     uint32_t m154Counter;
941 #endif
942 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
943     uint32_t mTrelCounter;
944 #endif
945 };
946 
947 /**
948  * Represents CSL accuracy.
949  *
950  */
951 class CslAccuracy
952 {
953 public:
954     static constexpr uint8_t kWorstClockAccuracy = 255; ///< Worst possible crystal accuracy, in units of ± ppm.
955     static constexpr uint8_t kWorstUncertainty   = 255; ///< Worst possible uncertainty, in units of 10 microseconds.
956 
957     /**
958      * Initializes the CSL accuracy using `kWorstClockAccuracy` and `kWorstUncertainty` values.
959      *
960      */
Init(void)961     void Init(void)
962     {
963         mClockAccuracy = kWorstClockAccuracy;
964         mUncertainty   = kWorstUncertainty;
965     }
966 
967     /**
968      * Returns the CSL clock accuracy.
969      *
970      * @returns The CSL clock accuracy in ± ppm.
971      *
972      */
GetClockAccuracy(void) const973     uint8_t GetClockAccuracy(void) const { return mClockAccuracy; }
974 
975     /**
976      * Sets the CSL clock accuracy.
977      *
978      * @param[in]  aClockAccuracy  The CSL clock accuracy in ± ppm.
979      *
980      */
SetClockAccuracy(uint8_t aClockAccuracy)981     void SetClockAccuracy(uint8_t aClockAccuracy) { mClockAccuracy = aClockAccuracy; }
982 
983     /**
984      * Returns the CSL uncertainty.
985      *
986      * @returns The uncertainty in units 10 microseconds.
987      *
988      */
GetUncertainty(void) const989     uint8_t GetUncertainty(void) const { return mUncertainty; }
990 
991     /**
992      * Gets the CLS uncertainty in microseconds.
993      *
994      * @returns the CLS uncertainty in microseconds.
995      *
996      */
GetUncertaintyInMicrosec(void) const997     uint16_t GetUncertaintyInMicrosec(void) const { return static_cast<uint16_t>(mUncertainty) * kUsPerUncertUnit; }
998 
999     /**
1000      * Sets the CSL uncertainty.
1001      *
1002      * @param[in]  aUncertainty  The CSL uncertainty in units 10 microseconds.
1003      *
1004      */
SetUncertainty(uint8_t aUncertainty)1005     void SetUncertainty(uint8_t aUncertainty) { mUncertainty = aUncertainty; }
1006 
1007 private:
1008     static constexpr uint8_t kUsPerUncertUnit = 10;
1009 
1010     uint8_t mClockAccuracy;
1011     uint8_t mUncertainty;
1012 };
1013 
1014 /**
1015  * @}
1016  *
1017  */
1018 
1019 } // namespace Mac
1020 
1021 DefineCoreType(otExtAddress, Mac::ExtAddress);
1022 DefineCoreType(otMacKey, Mac::Key);
1023 
1024 } // namespace ot
1025 
1026 #endif // MAC_TYPES_HPP_
1027