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