1 /*
2  *  Copyright (c) 2016, 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 generating and processing MLE TLVs.
32  */
33 
34 #ifndef MLE_TLVS_HPP_
35 #define MLE_TLVS_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include "common/encoding.hpp"
40 #include "common/message.hpp"
41 #include "common/preference.hpp"
42 #include "common/tlvs.hpp"
43 #include "meshcop/timestamp.hpp"
44 #include "net/ip6_address.hpp"
45 #include "thread/link_metrics_tlvs.hpp"
46 #include "thread/mle_types.hpp"
47 
48 namespace ot {
49 
50 namespace Mle {
51 
52 /**
53  * @addtogroup core-mle-tlvs
54  *
55  * @brief
56  *   This module includes definitions for generating and processing MLE TLVs.
57  *
58  * @{
59  *
60  */
61 
62 /**
63  * Implements MLE TLV generation and parsing.
64  *
65  */
66 OT_TOOL_PACKED_BEGIN
67 class Tlv : public ot::Tlv
68 {
69 public:
70     /**
71      * MLE TLV Types.
72      *
73      */
74     enum Type : uint8_t
75     {
76         kSourceAddress         = 0,  ///< Source Address TLV
77         kMode                  = 1,  ///< Mode TLV
78         kTimeout               = 2,  ///< Timeout TLV
79         kChallenge             = 3,  ///< Challenge TLV
80         kResponse              = 4,  ///< Response TLV
81         kLinkFrameCounter      = 5,  ///< Link-Layer Frame Counter TLV
82         kLinkQuality           = 6,  ///< Link Quality TLV
83         kNetworkParameter      = 7,  ///< Network Parameter TLV
84         kMleFrameCounter       = 8,  ///< MLE Frame Counter TLV
85         kRoute                 = 9,  ///< Route64 TLV
86         kAddress16             = 10, ///< Address16 TLV
87         kLeaderData            = 11, ///< Leader Data TLV
88         kNetworkData           = 12, ///< Network Data TLV
89         kTlvRequest            = 13, ///< TLV Request TLV
90         kScanMask              = 14, ///< Scan Mask TLV
91         kConnectivity          = 15, ///< Connectivity TLV
92         kLinkMargin            = 16, ///< Link Margin TLV
93         kStatus                = 17, ///< Status TLV
94         kVersion               = 18, ///< Version TLV
95         kAddressRegistration   = 19, ///< Address Registration TLV
96         kChannel               = 20, ///< Channel TLV
97         kPanId                 = 21, ///< PAN ID TLV
98         kActiveTimestamp       = 22, ///< Active Timestamp TLV
99         kPendingTimestamp      = 23, ///< Pending Timestamp TLV
100         kActiveDataset         = 24, ///< Active Operational Dataset TLV
101         kPendingDataset        = 25, ///< Pending Operational Dataset TLV
102         kDiscovery             = 26, ///< Thread Discovery TLV
103         kSupervisionInterval   = 27, ///< Supervision Interval TLV
104         kCslChannel            = 80, ///< CSL Channel TLV
105         kCslTimeout            = 85, ///< CSL Timeout TLV
106         kCslClockAccuracy      = 86, ///< CSL Clock Accuracy TLV
107         kLinkMetricsQuery      = 87, ///< Link Metrics Query TLV
108         kLinkMetricsManagement = 88, ///< Link Metrics Management TLV
109         kLinkMetricsReport     = 89, ///< Link Metrics Report TLV
110         kLinkProbe             = 90, ///< Link Probe TLV
111 
112         /**
113          * Applicable/Required only when time synchronization service
114          * (`OPENTHREAD_CONFIG_TIME_SYNC_ENABLE`) is enabled.
115          *
116          */
117         kTimeRequest   = 252, ///< Time Request TLV
118         kTimeParameter = 253, ///< Time Parameter TLV
119         kXtalAccuracy  = 254, ///< XTAL Accuracy TLV
120 
121         kInvalid = 255,
122     };
123 
124     /**
125      * Returns the Type value.
126      *
127      * @returns The Type value.
128      *
129      */
GetType(void) const130     Type GetType(void) const { return static_cast<Type>(ot::Tlv::GetType()); }
131 
132     /**
133      * Sets the Type value.
134      *
135      * @param[in]  aType  The Type value.
136      *
137      */
SetType(Type aType)138     void SetType(Type aType) { ot::Tlv::SetType(static_cast<uint8_t>(aType)); }
139 
140 } OT_TOOL_PACKED_END;
141 
142 /**
143  * Defines Source Address TLV constants and types.
144  *
145  */
146 typedef UintTlvInfo<Tlv::kSourceAddress, uint16_t> SourceAddressTlv;
147 
148 /**
149  * Defines Mode TLV constants and types.
150  *
151  */
152 typedef UintTlvInfo<Tlv::kMode, uint8_t> ModeTlv;
153 
154 /**
155  * Defines Timeout TLV constants and types.
156  *
157  */
158 typedef UintTlvInfo<Tlv::kTimeout, uint32_t> TimeoutTlv;
159 
160 /**
161  * Defines Challenge TLV constants and types.
162  *
163  */
164 typedef TlvInfo<Tlv::kChallenge> ChallengeTlv;
165 
166 /**
167  * Defines Response TLV constants and types.
168  *
169  */
170 typedef TlvInfo<Tlv::kResponse> ResponseTlv;
171 
172 /**
173  * Defines Link Frame Counter TLV constants and types.
174  *
175  */
176 typedef UintTlvInfo<Tlv::kLinkFrameCounter, uint32_t> LinkFrameCounterTlv;
177 
178 /**
179  * Defines MLE Frame Counter TLV constants and types.
180  *
181  */
182 typedef UintTlvInfo<Tlv::kMleFrameCounter, uint32_t> MleFrameCounterTlv;
183 
184 /**
185  * Defines Address16 TLV constants and types.
186  *
187  */
188 typedef UintTlvInfo<Tlv::kAddress16, uint16_t> Address16Tlv;
189 
190 /**
191  * Defines Network Data TLV constants and types.
192  *
193  */
194 typedef TlvInfo<Tlv::kNetworkData> NetworkDataTlv;
195 
196 /**
197  * Defines TLV Request TLV constants and types.
198  *
199  */
200 typedef TlvInfo<Tlv::kTlvRequest> TlvRequestTlv;
201 
202 /**
203  * Defines Link Margin TLV constants and types.
204  *
205  */
206 typedef UintTlvInfo<Tlv::kLinkMargin, uint8_t> LinkMarginTlv;
207 
208 /**
209  * Defines Version TLV constants and types.
210  *
211  */
212 typedef UintTlvInfo<Tlv::kVersion, uint16_t> VersionTlv;
213 
214 /**
215  * Defines PAN ID TLV constants and types.
216  *
217  */
218 typedef UintTlvInfo<Tlv::kPanId, uint16_t> PanIdTlv;
219 
220 /**
221  * Defines Active Timestamp TLV constants and types.
222  *
223  */
224 typedef SimpleTlvInfo<Tlv::kActiveTimestamp, MeshCoP::Timestamp> ActiveTimestampTlv;
225 
226 /**
227  * Defines Pending Timestamp TLV constants and types.
228  *
229  */
230 typedef SimpleTlvInfo<Tlv::kPendingTimestamp, MeshCoP::Timestamp> PendingTimestampTlv;
231 
232 /**
233  * Defines Timeout TLV constants and types.
234  *
235  */
236 typedef UintTlvInfo<Tlv::kSupervisionInterval, uint16_t> SupervisionIntervalTlv;
237 
238 /**
239  * Defines CSL Timeout TLV constants and types.
240  *
241  */
242 typedef UintTlvInfo<Tlv::kCslTimeout, uint32_t> CslTimeoutTlv;
243 
244 /**
245  * Defines XTAL Accuracy TLV constants and types.
246  *
247  */
248 typedef UintTlvInfo<Tlv::kXtalAccuracy, uint16_t> XtalAccuracyTlv;
249 
250 #if !OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
251 
252 /**
253  * Implements Route TLV generation and parsing.
254  *
255  */
256 OT_TOOL_PACKED_BEGIN
257 class RouteTlv : public Tlv, public TlvInfo<Tlv::kRoute>
258 {
259 public:
260     /**
261      * Initializes the TLV.
262      *
263      */
264     void Init(void);
265 
266     /**
267      * Indicates whether or not the TLV appears to be well-formed.
268      *
269      * @retval TRUE   If the TLV appears to be well-formed.
270      * @retval FALSE  If the TLV does not appear to be well-formed.
271      *
272      */
273     bool IsValid(void) const;
274 
275     /**
276      * Returns the Router ID Sequence value.
277      *
278      * @returns The Router ID Sequence value.
279      *
280      */
GetRouterIdSequence(void) const281     uint8_t GetRouterIdSequence(void) const { return mRouterIdSequence; }
282 
283     /**
284      * Sets the Router ID Sequence value.
285      *
286      * @param[in]  aSequence  The Router ID Sequence value.
287      *
288      */
SetRouterIdSequence(uint8_t aSequence)289     void SetRouterIdSequence(uint8_t aSequence) { mRouterIdSequence = aSequence; }
290 
291     /**
292      * Gets the Router ID Mask.
293      *
294      */
GetRouterIdMask(void) const295     const RouterIdSet &GetRouterIdMask(void) const { return mRouterIdMask; }
296 
297     /**
298      * Sets the Router ID Mask.
299      *
300      * @param[in]  aRouterIdSet The Router ID Mask to set.
301      *
302      */
SetRouterIdMask(const RouterIdSet & aRouterIdSet)303     void SetRouterIdMask(const RouterIdSet &aRouterIdSet) { mRouterIdMask = aRouterIdSet; }
304 
305     /**
306      * Indicates whether or not a Router ID bit is set.
307      *
308      * @param[in]  aRouterId  The Router ID bit.
309      *
310      * @retval TRUE   If the Router ID bit is set.
311      * @retval FALSE  If the Router ID bit is not set.
312      *
313      */
IsRouterIdSet(uint8_t aRouterId) const314     bool IsRouterIdSet(uint8_t aRouterId) const { return mRouterIdMask.Contains(aRouterId); }
315 
316     /**
317      * Indicates whether the `RouteTlv` is a singleton, i.e., only one router is allocated.
318      *
319      * @retval TRUE   It is a singleton.
320      * @retval FALSE  It is not a singleton.
321      *
322      */
IsSingleton(void) const323     bool IsSingleton(void) const { return IsValid() && (mRouterIdMask.GetNumberOfAllocatedIds() <= 1); }
324 
325     /**
326      * Returns the Route Data Length value.
327      *
328      * @returns The Route Data Length value.
329      *
330      */
GetRouteDataLength(void) const331     uint8_t GetRouteDataLength(void) const { return GetLength() - sizeof(mRouterIdSequence) - sizeof(mRouterIdMask); }
332 
333     /**
334      * Sets the Route Data Length value.
335      *
336      * @param[in]  aLength  The Route Data Length value.
337      *
338      */
SetRouteDataLength(uint8_t aLength)339     void SetRouteDataLength(uint8_t aLength) { SetLength(sizeof(mRouterIdSequence) + sizeof(mRouterIdMask) + aLength); }
340 
341     /**
342      * Returns the Route Cost value for a given Router index.
343      *
344      * @param[in]  aRouterIndex  The Router index.
345      *
346      * @returns The Route Cost value for a given Router index.
347      *
348      */
GetRouteCost(uint8_t aRouterIndex) const349     uint8_t GetRouteCost(uint8_t aRouterIndex) const { return mRouteData[aRouterIndex] & kRouteCostMask; }
350 
351     /**
352      * Returns the Link Quality In value for a given Router index.
353      *
354      * @param[in]  aRouterIndex  The Router index.
355      *
356      * @returns The Link Quality In value for a given Router index.
357      *
358      */
GetLinkQualityIn(uint8_t aRouterIndex) const359     LinkQuality GetLinkQualityIn(uint8_t aRouterIndex) const
360     {
361         return static_cast<LinkQuality>((mRouteData[aRouterIndex] & kLinkQualityInMask) >> kLinkQualityInOffset);
362     }
363 
364     /**
365      * Returns the Link Quality Out value for a given Router index.
366      *
367      * @param[in]  aRouterIndex  The Router index.
368      *
369      * @returns The Link Quality Out value for a given Router index.
370      *
371      */
GetLinkQualityOut(uint8_t aRouterIndex) const372     LinkQuality GetLinkQualityOut(uint8_t aRouterIndex) const
373     {
374         return static_cast<LinkQuality>((mRouteData[aRouterIndex] & kLinkQualityOutMask) >> kLinkQualityOutOffset);
375     }
376 
377     /**
378      * Sets the Route Data (Link Quality In/Out and Route Cost) for a given Router index.
379      *
380      * @param[in]  aRouterIndex    The Router index.
381      * @param[in]  aLinkQualityIn  The Link Quality In value.
382      * @param[in]  aLinkQualityOut The Link Quality Out value.
383      * @param[in]  aRouteCost      The Route Cost value.
384      *
385      */
SetRouteData(uint8_t aRouterIndex,LinkQuality aLinkQualityIn,LinkQuality aLinkQualityOut,uint8_t aRouteCost)386     void SetRouteData(uint8_t aRouterIndex, LinkQuality aLinkQualityIn, LinkQuality aLinkQualityOut, uint8_t aRouteCost)
387     {
388         mRouteData[aRouterIndex] = (((aLinkQualityIn << kLinkQualityInOffset) & kLinkQualityInMask) |
389                                     ((aLinkQualityOut << kLinkQualityOutOffset) & kLinkQualityOutMask) |
390                                     ((aRouteCost << kRouteCostOffset) & kRouteCostMask));
391     }
392 
393 private:
394     static constexpr uint8_t kLinkQualityOutOffset = 6;
395     static constexpr uint8_t kLinkQualityOutMask   = 3 << kLinkQualityOutOffset;
396     static constexpr uint8_t kLinkQualityInOffset  = 4;
397     static constexpr uint8_t kLinkQualityInMask    = 3 << kLinkQualityInOffset;
398     static constexpr uint8_t kRouteCostOffset      = 0;
399     static constexpr uint8_t kRouteCostMask        = 0xf << kRouteCostOffset;
400 
401     uint8_t     mRouterIdSequence;
402     RouterIdSet mRouterIdMask;
403     uint8_t     mRouteData[kMaxRouterId + 1];
404 } OT_TOOL_PACKED_END;
405 
406 #else // OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
407 
408 /**
409  * Implements Route TLV generation and parsing.
410  *
411  */
412 OT_TOOL_PACKED_BEGIN
413 class RouteTlv : public Tlv, public TlvInfo<Tlv::kRoute>
414 {
415 public:
416     /**
417      * Initializes the TLV.
418      *
419      */
Init(void)420     void Init(void)
421     {
422         SetType(kRoute);
423         SetLength(sizeof(*this) - sizeof(Tlv));
424     }
425 
426     /**
427      * Indicates whether or not the TLV appears to be well-formed.
428      *
429      * @retval TRUE   If the TLV appears to be well-formed.
430      * @retval FALSE  If the TLV does not appear to be well-formed.
431      *
432      */
IsValid(void) const433     bool IsValid(void) const { return GetLength() >= sizeof(mRouterIdSequence) + sizeof(mRouterIdMask); }
434 
435     /**
436      * Returns the Router ID Sequence value.
437      *
438      * @returns The Router ID Sequence value.
439      *
440      */
GetRouterIdSequence(void) const441     uint8_t GetRouterIdSequence(void) const { return mRouterIdSequence; }
442 
443     /**
444      * Sets the Router ID Sequence value.
445      *
446      * @param[in]  aSequence  The Router ID Sequence value.
447      *
448      */
SetRouterIdSequence(uint8_t aSequence)449     void SetRouterIdSequence(uint8_t aSequence) { mRouterIdSequence = aSequence; }
450 
451     /**
452      * Gets the Router ID Mask.
453      *
454      */
GetRouterIdMask(void) const455     const RouterIdSet &GetRouterIdMask(void) const { return mRouterIdMask; }
456 
457     /**
458      * Sets the Router ID Mask.
459      *
460      * @param[in]  aRouterIdSet The Router ID Mask to set.
461      *
462      */
SetRouterIdMask(const RouterIdSet & aRouterIdSet)463     void SetRouterIdMask(const RouterIdSet &aRouterIdSet) { mRouterIdMask = aRouterIdSet; }
464 
465     /**
466      * Indicates whether or not a Router ID bit is set.
467      *
468      * @param[in]  aRouterId  The Router ID.
469      *
470      * @retval TRUE   If the Router ID bit is set.
471      * @retval FALSE  If the Router ID bit is not set.
472      *
473      */
IsRouterIdSet(uint8_t aRouterId) const474     bool IsRouterIdSet(uint8_t aRouterId) const { return mRouterIdMask.Contains(aRouterId); }
475 
476     /**
477      * Indicates whether the `RouteTlv` is a singleton, i.e., only one router is allocated.
478      *
479      * @retval TRUE   It is a singleton.
480      * @retval FALSE  It is not a singleton.
481      *
482      */
IsSingleton(void) const483     bool IsSingleton(void) const { return IsValid() && (mRouterIdMask.GetNumberOfAllocatedIds() <= 1); }
484 
485     /**
486      * Sets the Router ID bit.
487      *
488      * @param[in]  aRouterId  The Router ID bit to set.
489      *
490      */
SetRouterId(uint8_t aRouterId)491     void SetRouterId(uint8_t aRouterId) { mRouterIdMask.Add(aRouterId); }
492 
493     /**
494      * Returns the Route Data Length value.
495      *
496      * @returns The Route Data Length value in bytes
497      *
498      */
GetRouteDataLength(void) const499     uint8_t GetRouteDataLength(void) const { return GetLength() - sizeof(mRouterIdSequence) - sizeof(mRouterIdMask); }
500 
501     /**
502      * Sets the Route Data Length value.
503      *
504      * @param[in]  aLength  The Route Data Length value in number of router entries
505      *
506      */
SetRouteDataLength(uint8_t aLength)507     void SetRouteDataLength(uint8_t aLength)
508     {
509         SetLength(sizeof(mRouterIdSequence) + sizeof(mRouterIdMask) + aLength + (aLength + 1) / 2);
510     }
511 
512     /**
513      * Returns the Route Cost value for a given Router index.
514      *
515      * @param[in]  aRouterIndex  The Router index.
516      *
517      * @returns The Route Cost value for a given Router index.
518      *
519      */
GetRouteCost(uint8_t aRouterIndex) const520     uint8_t GetRouteCost(uint8_t aRouterIndex) const
521     {
522         if (aRouterIndex & 1)
523         {
524             return mRouteData[aRouterIndex + aRouterIndex / 2 + 1];
525         }
526         else
527         {
528             return static_cast<uint8_t>((mRouteData[aRouterIndex + aRouterIndex / 2] & kRouteCostMask)
529                                         << kOddEntryOffset) |
530                    ((mRouteData[aRouterIndex + aRouterIndex / 2 + 1] &
531                      static_cast<uint8_t>(kRouteCostMask << kOddEntryOffset)) >>
532                     kOddEntryOffset);
533         }
534     }
535 
536     /**
537      * Returns the Link Quality In value for a given Router index.
538      *
539      * @param[in]  aRouterIndex  The Router index.
540      *
541      * @returns The Link Quality In value for a given Router index.
542      *
543      */
GetLinkQualityIn(uint8_t aRouterIndex) const544     LinkQuality GetLinkQualityIn(uint8_t aRouterIndex) const
545     {
546         int offset = ((aRouterIndex & 1) ? kOddEntryOffset : 0);
547         return static_cast<LinkQuality>(
548             (mRouteData[aRouterIndex + aRouterIndex / 2] & (kLinkQualityInMask >> offset)) >>
549             (kLinkQualityInOffset - offset));
550     }
551 
552     /**
553      * Returns the Link Quality Out value for a given Router index.
554      *
555      * @param[in]  aRouterIndex  The Router index.
556      *
557      * @returns The Link Quality Out value for a given Router index.
558      *
559      */
GetLinkQualityOut(uint8_t aRouterIndex) const560     LinkQuality GetLinkQualityOut(uint8_t aRouterIndex) const
561     {
562         int offset = ((aRouterIndex & 1) ? kOddEntryOffset : 0);
563         return static_cast<LinkQuality>(
564             (mRouteData[aRouterIndex + aRouterIndex / 2] & (kLinkQualityOutMask >> offset)) >>
565             (kLinkQualityOutOffset - offset));
566     }
567 
568     /**
569      * Sets the Route Data (Link Quality In/Out and Route Cost) for a given Router index.
570      *
571      * @param[in]  aRouterIndex    The Router index.
572      * @param[in]  aLinkQualityIn  The Link Quality In value.
573      * @param[in]  aLinkQualityOut The Link Quality Out value.
574      * @param[in]  aRouteCost      The Route Cost value.
575      *
576      */
SetRouteData(uint8_t aRouterIndex,LinkQuality aLinkQualityIn,LinkQuality aLinkQualityOut,uint8_t aRouteCost)577     void SetRouteData(uint8_t aRouterIndex, LinkQuality aLinkQualityIn, LinkQuality aLinkQualityOut, uint8_t aRouteCost)
578     {
579         SetLinkQualityIn(aRouterIndex, aLinkQualityIn);
580         SetLinkQualityOut(aRouterIndex, aLinkQualityOut);
581         SetRouteCost(aRouterIndex, aRouteCost);
582     }
583 
584 private:
585     static constexpr uint8_t kLinkQualityOutOffset = 6;
586     static constexpr uint8_t kLinkQualityOutMask   = 3 << kLinkQualityOutOffset;
587     static constexpr uint8_t kLinkQualityInOffset  = 4;
588     static constexpr uint8_t kLinkQualityInMask    = 3 << kLinkQualityInOffset;
589     static constexpr uint8_t kRouteCostOffset      = 0;
590     static constexpr uint8_t kRouteCostMask        = 0xf << kRouteCostOffset;
591     static constexpr uint8_t kOddEntryOffset       = 4;
592 
SetRouteCost(uint8_t aRouterIndex,uint8_t aRouteCost)593     void SetRouteCost(uint8_t aRouterIndex, uint8_t aRouteCost)
594     {
595         if (aRouterIndex & 1)
596         {
597             mRouteData[aRouterIndex + aRouterIndex / 2 + 1] = aRouteCost;
598         }
599         else
600         {
601             mRouteData[aRouterIndex + aRouterIndex / 2] =
602                 (mRouteData[aRouterIndex + aRouterIndex / 2] & ~kRouteCostMask) |
603                 ((aRouteCost >> kOddEntryOffset) & kRouteCostMask);
604             mRouteData[aRouterIndex + aRouterIndex / 2 + 1] = static_cast<uint8_t>(
605                 (mRouteData[aRouterIndex + aRouterIndex / 2 + 1] & ~(kRouteCostMask << kOddEntryOffset)) |
606                 ((aRouteCost & kRouteCostMask) << kOddEntryOffset));
607         }
608     }
609 
SetLinkQualityIn(uint8_t aRouterIndex,uint8_t aLinkQuality)610     void SetLinkQualityIn(uint8_t aRouterIndex, uint8_t aLinkQuality)
611     {
612         int offset = ((aRouterIndex & 1) ? kOddEntryOffset : 0);
613         mRouteData[aRouterIndex + aRouterIndex / 2] =
614             (mRouteData[aRouterIndex + aRouterIndex / 2] & ~(kLinkQualityInMask >> offset)) |
615             ((aLinkQuality << (kLinkQualityInOffset - offset)) & (kLinkQualityInMask >> offset));
616     }
617 
SetLinkQualityOut(uint8_t aRouterIndex,LinkQuality aLinkQuality)618     void SetLinkQualityOut(uint8_t aRouterIndex, LinkQuality aLinkQuality)
619     {
620         int offset = ((aRouterIndex & 1) ? kOddEntryOffset : 0);
621         mRouteData[aRouterIndex + aRouterIndex / 2] =
622             (mRouteData[aRouterIndex + aRouterIndex / 2] & ~(kLinkQualityOutMask >> offset)) |
623             ((aLinkQuality << (kLinkQualityOutOffset - offset)) & (kLinkQualityOutMask >> offset));
624     }
625 
626     uint8_t     mRouterIdSequence;
627     RouterIdSet mRouterIdMask;
628     // Since we do hold 12 (compressible to 11) bits of data per router, each entry occupies 1.5 bytes,
629     // consecutively. First 4 bits are link qualities, remaining 8 bits are route cost.
630     uint8_t mRouteData[kMaxRouterId + 1 + kMaxRouterId / 2 + 1];
631 } OT_TOOL_PACKED_END;
632 
633 #endif // OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
634 
635 /**
636  * Implements Leader Data TLV generation and parsing.
637  *
638  */
639 OT_TOOL_PACKED_BEGIN
640 class LeaderDataTlv : public Tlv, public TlvInfo<Tlv::kLeaderData>
641 {
642 public:
643     /**
644      * Initializes the TLV.
645      *
646      */
Init(void)647     void Init(void)
648     {
649         SetType(kLeaderData);
650         SetLength(sizeof(*this) - sizeof(Tlv));
651     }
652 
653     /**
654      * Indicates whether or not the TLV appears to be well-formed.
655      *
656      * @retval TRUE   If the TLV appears to be well-formed.
657      * @retval FALSE  If the TLV does not appear to be well-formed.
658      *
659      */
IsValid(void) const660     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
661 
662     /**
663      * Gets the Leader Data info from TLV.
664      *
665      * @param[out] aLeaderData   A reference to output Leader Data info.
666      *
667      */
Get(LeaderData & aLeaderData) const668     void Get(LeaderData &aLeaderData) const
669     {
670         aLeaderData.SetPartitionId(BigEndian::HostSwap32(mPartitionId));
671         aLeaderData.SetWeighting(mWeighting);
672         aLeaderData.SetDataVersion(mDataVersion);
673         aLeaderData.SetStableDataVersion(mStableDataVersion);
674         aLeaderData.SetLeaderRouterId(mLeaderRouterId);
675     }
676 
677     /**
678      * Sets the Leader Data.
679      *
680      * @param[in] aLeaderData   A Leader Data.
681      *
682      */
Set(const LeaderData & aLeaderData)683     void Set(const LeaderData &aLeaderData)
684     {
685         mPartitionId       = BigEndian::HostSwap32(aLeaderData.GetPartitionId());
686         mWeighting         = aLeaderData.GetWeighting();
687         mDataVersion       = aLeaderData.GetDataVersion(NetworkData::kFullSet);
688         mStableDataVersion = aLeaderData.GetDataVersion(NetworkData::kStableSubset);
689         mLeaderRouterId    = aLeaderData.GetLeaderRouterId();
690     }
691 
692 private:
693     uint32_t mPartitionId;
694     uint8_t  mWeighting;
695     uint8_t  mDataVersion;
696     uint8_t  mStableDataVersion;
697     uint8_t  mLeaderRouterId;
698 } OT_TOOL_PACKED_END;
699 
700 /**
701  * Implements Scan Mask TLV generation and parsing.
702  *
703  */
704 class ScanMaskTlv : public UintTlvInfo<Tlv::kScanMask, uint8_t>
705 {
706 public:
707     static constexpr uint8_t kRouterFlag    = 1 << 7; ///< Scan Mask Router Flag.
708     static constexpr uint8_t kEndDeviceFlag = 1 << 6; ///< Scan Mask End Device Flag.
709 
710     /**
711      * Indicates whether or not the Router flag is set.
712      *
713      * @param[in] aMask   A scan mask value.
714      *
715      * @retval TRUE   If the Router flag is set.
716      * @retval FALSE  If the Router flag is not set.
717      */
IsRouterFlagSet(uint8_t aMask)718     static bool IsRouterFlagSet(uint8_t aMask) { return (aMask & kRouterFlag) != 0; }
719 
720     /**
721      * Indicates whether or not the End Device flag is set.
722      *
723      * @param[in] aMask   A scan mask value.
724      *
725      * @retval TRUE   If the End Device flag is set.
726      * @retval FALSE  If the End Device flag is not set.
727      */
IsEndDeviceFlagSet(uint8_t aMask)728     static bool IsEndDeviceFlagSet(uint8_t aMask) { return (aMask & kEndDeviceFlag) != 0; }
729 };
730 
731 /**
732  * Implements Connectivity TLV generation and parsing.
733  *
734  */
735 OT_TOOL_PACKED_BEGIN
736 class ConnectivityTlv : public Tlv, public TlvInfo<Tlv::kConnectivity>
737 {
738 public:
739     /**
740      * Initializes the TLV.
741      *
742      */
Init(void)743     void Init(void)
744     {
745         SetType(kConnectivity);
746         SetLength(sizeof(*this) - sizeof(Tlv));
747     }
748 
749     /**
750      * Indicates whether or not the TLV appears to be well-formed.
751      *
752      * @retval TRUE   If the TLV appears to be well-formed.
753      * @retval FALSE  If the TLV does not appear to be well-formed.
754      *
755      */
IsValid(void) const756     bool IsValid(void) const
757     {
758         return IsSedBufferingIncluded() ||
759                (GetLength() == sizeof(*this) - sizeof(Tlv) - sizeof(mSedBufferSize) - sizeof(mSedDatagramCount));
760     }
761 
762     /**
763      * Indicates whether or not the sed buffer size and datagram count are included.
764      *
765      * @retval TRUE   If the sed buffer size and datagram count are included.
766      * @retval FALSE  If the sed buffer size and datagram count are not included.
767      *
768      */
IsSedBufferingIncluded(void) const769     bool IsSedBufferingIncluded(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
770 
771     /**
772      * Returns the Parent Priority value.
773      *
774      * @returns The Parent Priority value.
775      *
776      */
777     int8_t GetParentPriority(void) const;
778 
779     /**
780      * Sets the Parent Priority value.
781      *
782      * @param[in] aParentPriority  The Parent Priority value.
783      *
784      */
785     void SetParentPriority(int8_t aParentPriority);
786 
787     /**
788      * Returns the Link Quality 3 value.
789      *
790      * @returns The Link Quality 3 value.
791      *
792      */
GetLinkQuality3(void) const793     uint8_t GetLinkQuality3(void) const { return mLinkQuality3; }
794 
795     /**
796      * Sets the Link Quality 3 value.
797      *
798      * @param[in]  aLinkQuality  The Link Quality 3 value.
799      *
800      */
SetLinkQuality3(uint8_t aLinkQuality)801     void SetLinkQuality3(uint8_t aLinkQuality) { mLinkQuality3 = aLinkQuality; }
802 
803     /**
804      * Returns the Link Quality 2 value.
805      *
806      * @returns The Link Quality 2 value.
807      *
808      */
GetLinkQuality2(void) const809     uint8_t GetLinkQuality2(void) const { return mLinkQuality2; }
810 
811     /**
812      * Sets the Link Quality 2 value.
813      *
814      * @param[in]  aLinkQuality  The Link Quality 2 value.
815      *
816      */
SetLinkQuality2(uint8_t aLinkQuality)817     void SetLinkQuality2(uint8_t aLinkQuality) { mLinkQuality2 = aLinkQuality; }
818 
819     /**
820      * Sets the Link Quality 1 value.
821      *
822      * @returns The Link Quality 1 value.
823      *
824      */
GetLinkQuality1(void) const825     uint8_t GetLinkQuality1(void) const { return mLinkQuality1; }
826 
827     /**
828      * Sets the Link Quality 1 value.
829      *
830      * @param[in]  aLinkQuality  The Link Quality 1 value.
831      *
832      */
SetLinkQuality1(uint8_t aLinkQuality)833     void SetLinkQuality1(uint8_t aLinkQuality) { mLinkQuality1 = aLinkQuality; }
834 
835     /**
836      * Increments the Link Quality N field in TLV for a given Link Quality N (1,2,3).
837      *
838      * The Link Quality N field specifies the number of neighboring router devices with which the sender shares a link
839      * of quality N.
840      *
841      * @param[in] aLinkQuality  The Link Quality N (1,2,3) field to update.
842      *
843      */
844     void IncrementLinkQuality(LinkQuality aLinkQuality);
845 
846     /**
847      * Sets the Active Routers value.
848      *
849      * @returns The Active Routers value.
850      *
851      */
GetActiveRouters(void) const852     uint8_t GetActiveRouters(void) const { return mActiveRouters; }
853 
854     /**
855      * Indicates whether or not the partition is a singleton based on Active Routers value.
856      *
857      * @retval TRUE   The partition is a singleton.
858      * @retval FALSE  The partition is not a singleton.
859      *
860      */
IsSingleton(void) const861     bool IsSingleton(void) const { return (mActiveRouters <= 1); }
862 
863     /**
864      * Sets the Active Routers value.
865      *
866      * @param[in]  aActiveRouters  The Active Routers value.
867      *
868      */
SetActiveRouters(uint8_t aActiveRouters)869     void SetActiveRouters(uint8_t aActiveRouters) { mActiveRouters = aActiveRouters; }
870 
871     /**
872      * Returns the Leader Cost value.
873      *
874      * @returns The Leader Cost value.
875      *
876      */
GetLeaderCost(void) const877     uint8_t GetLeaderCost(void) const { return mLeaderCost; }
878 
879     /**
880      * Sets the Leader Cost value.
881      *
882      * @param[in]  aCost  The Leader Cost value.
883      *
884      */
SetLeaderCost(uint8_t aCost)885     void SetLeaderCost(uint8_t aCost) { mLeaderCost = aCost; }
886 
887     /**
888      * Returns the ID Sequence value.
889      *
890      * @returns The ID Sequence value.
891      *
892      */
GetIdSequence(void) const893     uint8_t GetIdSequence(void) const { return mIdSequence; }
894 
895     /**
896      * Sets the ID Sequence value.
897      *
898      * @param[in]  aSequence  The ID Sequence value.
899      *
900      */
SetIdSequence(uint8_t aSequence)901     void SetIdSequence(uint8_t aSequence) { mIdSequence = aSequence; }
902 
903     /**
904      * Returns the SED Buffer Size value.
905      *
906      * @returns The SED Buffer Size value.
907      *
908      */
GetSedBufferSize(void) const909     uint16_t GetSedBufferSize(void) const
910     {
911         uint16_t buffersize = OPENTHREAD_CONFIG_DEFAULT_SED_BUFFER_SIZE;
912 
913         if (IsSedBufferingIncluded())
914         {
915             buffersize = BigEndian::HostSwap16(mSedBufferSize);
916         }
917         return buffersize;
918     }
919 
920     /**
921      * Sets the SED Buffer Size value.
922      *
923      * @param[in]  aSedBufferSize  The SED Buffer Size value.
924      *
925      */
SetSedBufferSize(uint16_t aSedBufferSize)926     void SetSedBufferSize(uint16_t aSedBufferSize) { mSedBufferSize = BigEndian::HostSwap16(aSedBufferSize); }
927 
928     /**
929      * Returns the SED Datagram Count value.
930      *
931      * @returns The SED Datagram Count value.
932      *
933      */
GetSedDatagramCount(void) const934     uint8_t GetSedDatagramCount(void) const
935     {
936         uint8_t count = OPENTHREAD_CONFIG_DEFAULT_SED_DATAGRAM_COUNT;
937 
938         if (IsSedBufferingIncluded())
939         {
940             count = mSedDatagramCount;
941         }
942         return count;
943     }
944 
945     /**
946      * Sets the SED Datagram Count value.
947      *
948      * @param[in]  aSedDatagramCount  The SED Datagram Count value.
949      *
950      */
SetSedDatagramCount(uint8_t aSedDatagramCount)951     void SetSedDatagramCount(uint8_t aSedDatagramCount) { mSedDatagramCount = aSedDatagramCount; }
952 
953 private:
954     static constexpr uint8_t kFlagsParentPriorityOffset = 6;
955     static constexpr uint8_t kFlagsParentPriorityMask   = (3 << kFlagsParentPriorityOffset);
956 
957     uint8_t  mFlags;
958     uint8_t  mLinkQuality3;
959     uint8_t  mLinkQuality2;
960     uint8_t  mLinkQuality1;
961     uint8_t  mLeaderCost;
962     uint8_t  mIdSequence;
963     uint8_t  mActiveRouters;
964     uint16_t mSedBufferSize;
965     uint8_t  mSedDatagramCount;
966 } OT_TOOL_PACKED_END;
967 
968 /**
969  * Specifies Status TLV status values.
970  *
971  */
972 struct StatusTlv : public UintTlvInfo<Tlv::kStatus, uint8_t>
973 {
974     /**
975      * Status values.
976      */
977     enum Status : uint8_t
978     {
979         kError = 1, ///< Error.
980     };
981 };
982 
983 /**
984  * Provides constants and methods for generation and parsing of Address Registration TLV.
985  *
986  */
987 class AddressRegistrationTlv : public TlvInfo<Tlv::kAddressRegistration>
988 {
989 public:
990     /**
991      * This constant defines the control byte to use in an uncompressed entry where the full IPv6 address is included in
992      * the TLV.
993      *
994      */
995     static constexpr uint8_t kControlByteUncompressed = 0;
996 
997     /**
998      * Returns the control byte to use in a compressed entry where the 64-prefix is replaced with a
999      * 6LoWPAN context identifier.
1000      *
1001      * @param[in] aContextId   The 6LoWPAN context ID.
1002      *
1003      * @returns The control byte associated with compressed entry with @p aContextId.
1004      *
1005      */
ControlByteFor(uint8_t aContextId)1006     static uint8_t ControlByteFor(uint8_t aContextId) { return kCompressed | (aContextId & kContextIdMask); }
1007 
1008     /**
1009      * Indicates whether or not an address entry is using compressed format.
1010      *
1011      * @param[in] aControlByte  The control byte (the first byte in the entry).
1012      *
1013      * @retval TRUE   If the entry uses compressed format.
1014      * @retval FALSE  If the entry uses uncompressed format.
1015      *
1016      */
IsEntryCompressed(uint8_t aControlByte)1017     static bool IsEntryCompressed(uint8_t aControlByte) { return (aControlByte & kCompressed); }
1018 
1019     /**
1020      * Gets the context ID in a compressed entry.
1021      *
1022      * @param[in] aControlByte  The control byte (the first byte in the entry).
1023      *
1024      * @returns The 6LoWPAN context ID.
1025      *
1026      */
GetContextId(uint8_t aControlByte)1027     static uint8_t GetContextId(uint8_t aControlByte) { return (aControlByte & kContextIdMask); }
1028 
1029     AddressRegistrationTlv(void) = delete;
1030 
1031 private:
1032     static constexpr uint8_t kCompressed    = 1 << 7;
1033     static constexpr uint8_t kContextIdMask = 0xf;
1034 };
1035 
1036 /**
1037  * Implements Channel TLV value format.
1038  *
1039  * This is used by both Channel TLV and CSL Channel TLV.
1040  *
1041  */
1042 OT_TOOL_PACKED_BEGIN
1043 class ChannelTlvValue
1044 {
1045 public:
1046     /**
1047      * Default constructor.
1048      *
1049      */
1050     ChannelTlvValue(void) = default;
1051 
1052     /**
1053      * Initializes the `ChannelTlvValue` with a given channel page and channel values.
1054      *
1055      * @param[in] aChannelPage   The channel page.
1056      * @param[in] aChannel       The channel.
1057      *
1058      */
ChannelTlvValue(uint8_t aChannelPage,uint16_t aChannel)1059     ChannelTlvValue(uint8_t aChannelPage, uint16_t aChannel)
1060         : mChannelPage(aChannelPage)
1061         , mChannel(BigEndian::HostSwap16(aChannel))
1062     {
1063     }
1064 
1065     /**
1066      * Initializes the `ChannelTlvValue` with zero channel page and a given channel value.
1067      *
1068      * @param[in] aChannel       The channel.
1069      *
1070      */
ChannelTlvValue(uint16_t aChannel)1071     ChannelTlvValue(uint16_t aChannel)
1072         : ChannelTlvValue(0, aChannel)
1073     {
1074     }
1075 
1076     /**
1077      * Returns the Channel Page value.
1078      *
1079      * @returns The Channel Page value.
1080      *
1081      */
GetChannelPage(void) const1082     uint8_t GetChannelPage(void) const { return mChannelPage; }
1083 
1084     /**
1085      * Sets the Channel Page value.
1086      *
1087      * @param[in]  aChannelPage  The Channel Page value.
1088      *
1089      */
SetChannelPage(uint8_t aChannelPage)1090     void SetChannelPage(uint8_t aChannelPage) { mChannelPage = aChannelPage; }
1091 
1092     /**
1093      * Returns the Channel value.
1094      *
1095      * @returns The Channel value.
1096      *
1097      */
GetChannel(void) const1098     uint16_t GetChannel(void) const { return BigEndian::HostSwap16(mChannel); }
1099 
1100     /**
1101      * Sets the Channel value.
1102      *
1103      * @param[in]  aChannel  The Channel value.
1104      *
1105      */
SetChannel(uint16_t aChannel)1106     void SetChannel(uint16_t aChannel) { mChannel = BigEndian::HostSwap16(aChannel); }
1107 
1108     /**
1109      * Sets the Channel and determines and sets the Channel Page from the given channel.
1110      *
1111      * @param[in]  aChannel  The Channel value.
1112      *
1113      */
1114     void SetChannelAndPage(uint16_t aChannel);
1115 
1116     /**
1117      * Indicates whether or not the Channel and Channel Page values are valid.
1118      *
1119      * @retval TRUE   If the Channel and Channel Page values are valid.
1120      * @retval FALSE  If the Channel and Channel Page values are not valid.
1121      *
1122      */
1123     bool IsValid(void) const;
1124 
1125 private:
1126     uint8_t  mChannelPage;
1127     uint16_t mChannel;
1128 } OT_TOOL_PACKED_END;
1129 
1130 /**
1131  * Defines Channel TLV constants and types.
1132  *
1133  */
1134 typedef SimpleTlvInfo<Tlv::kChannel, ChannelTlvValue> ChannelTlv;
1135 
1136 /**
1137  * Defines CSL Channel TLV constants and types.
1138  *
1139  */
1140 typedef SimpleTlvInfo<Tlv::kCslChannel, ChannelTlvValue> CslChannelTlv;
1141 
1142 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
1143 /**
1144  * Defines Time Request TLV constants and types.
1145  *
1146  */
1147 typedef TlvInfo<Tlv::kTimeRequest> TimeRequestTlv;
1148 
1149 /**
1150  * Implements Time Parameter TLV generation and parsing.
1151  *
1152  */
1153 OT_TOOL_PACKED_BEGIN
1154 class TimeParameterTlv : public Tlv, public TlvInfo<Tlv::kTimeParameter>
1155 {
1156 public:
1157     /**
1158      * Initializes the TLV.
1159      *
1160      */
Init(void)1161     void Init(void)
1162     {
1163         SetType(kTimeParameter);
1164         SetLength(sizeof(*this) - sizeof(Tlv));
1165     }
1166 
1167     /**
1168      * Indicates whether or not the TLV appears to be well-formed.
1169      *
1170      * @retval TRUE   If the TLV appears to be well-formed.
1171      * @retval FALSE  If the TLV does not appear to be well-formed.
1172      *
1173      */
IsValid(void) const1174     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1175 
1176     /**
1177      * Returns the time sync period.
1178      *
1179      * @returns The time sync period.
1180      *
1181      */
GetTimeSyncPeriod(void) const1182     uint16_t GetTimeSyncPeriod(void) const { return BigEndian::HostSwap16(mTimeSyncPeriod); }
1183 
1184     /**
1185      * Sets the time sync period.
1186      *
1187      * @param[in]  aTimeSyncPeriod  The time sync period.
1188      *
1189      */
SetTimeSyncPeriod(uint16_t aTimeSyncPeriod)1190     void SetTimeSyncPeriod(uint16_t aTimeSyncPeriod) { mTimeSyncPeriod = BigEndian::HostSwap16(aTimeSyncPeriod); }
1191 
1192     /**
1193      * Returns the XTAL accuracy threshold.
1194      *
1195      * @returns The XTAL accuracy threshold.
1196      *
1197      */
GetXtalThreshold(void) const1198     uint16_t GetXtalThreshold(void) const { return BigEndian::HostSwap16(mXtalThreshold); }
1199 
1200     /**
1201      * Sets the XTAL accuracy threshold.
1202      *
1203      * @param[in]  aXTALThreshold  The XTAL accuracy threshold.
1204      *
1205      */
SetXtalThreshold(uint16_t aXtalThreshold)1206     void SetXtalThreshold(uint16_t aXtalThreshold) { mXtalThreshold = BigEndian::HostSwap16(aXtalThreshold); }
1207 
1208 private:
1209     uint16_t mTimeSyncPeriod;
1210     uint16_t mXtalThreshold;
1211 } OT_TOOL_PACKED_END;
1212 
1213 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
1214 
1215 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
1216 /**
1217  * Implements CSL Clock Accuracy TLV generation and parsing.
1218  *
1219  */
1220 OT_TOOL_PACKED_BEGIN
1221 class CslClockAccuracyTlv : public Tlv, public TlvInfo<Tlv::kCslClockAccuracy>
1222 {
1223 public:
1224     /**
1225      * Initializes the TLV.
1226      *
1227      */
Init(void)1228     void Init(void)
1229     {
1230         SetType(kCslClockAccuracy);
1231         SetLength(sizeof(*this) - sizeof(Tlv));
1232     }
1233 
1234     /**
1235      * Indicates whether or not the TLV appears to be well-formed.
1236      *
1237      * @retval TRUE   If the TLV appears to be well-formed.
1238      * @retval FALSE  If the TLV does not appear to be well-formed.
1239      *
1240      */
IsValid(void) const1241     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1242 
1243     /**
1244      * Returns the CSL Clock Accuracy value.
1245      *
1246      * @returns The CSL Clock Accuracy value.
1247      *
1248      */
GetCslClockAccuracy(void) const1249     uint8_t GetCslClockAccuracy(void) const { return mCslClockAccuracy; }
1250 
1251     /**
1252      * Sets the CSL Clock Accuracy value.
1253      *
1254      * @param[in]  aCslClockAccuracy  The CSL Clock Accuracy value.
1255      *
1256      */
SetCslClockAccuracy(uint8_t aCslClockAccuracy)1257     void SetCslClockAccuracy(uint8_t aCslClockAccuracy) { mCslClockAccuracy = aCslClockAccuracy; }
1258 
1259     /**
1260      * Returns the Clock Uncertainty value.
1261      *
1262      * @returns The Clock Uncertainty value.
1263      *
1264      */
GetCslUncertainty(void) const1265     uint8_t GetCslUncertainty(void) const { return mCslUncertainty; }
1266 
1267     /**
1268      * Sets the CSL Uncertainty value.
1269      *
1270      * @param[in]  aCslUncertainty  The CSL Uncertainty value.
1271      *
1272      */
SetCslUncertainty(uint8_t aCslUncertainty)1273     void SetCslUncertainty(uint8_t aCslUncertainty) { mCslUncertainty = aCslUncertainty; }
1274 
1275 private:
1276     uint8_t mCslClockAccuracy;
1277     uint8_t mCslUncertainty;
1278 } OT_TOOL_PACKED_END;
1279 
1280 #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
1281 /**
1282  * @}
1283  *
1284  */
1285 
1286 } // namespace Mle
1287 
1288 } // namespace ot
1289 
1290 #endif // MLE_TLVS_HPP_
1291