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