• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 MeshCoP TLVs.
32  *
33  */
34 
35 #ifndef MESHCOP_TLVS_HPP_
36 #define MESHCOP_TLVS_HPP_
37 
38 #include "openthread-core-config.h"
39 
40 #include <openthread/commissioner.h>
41 #include <openthread/dataset.h>
42 #include <openthread/platform/radio.h>
43 
44 #include "common/const_cast.hpp"
45 #include "common/encoding.hpp"
46 #include "common/message.hpp"
47 #include "common/string.hpp"
48 #include "common/tlvs.hpp"
49 #include "mac/mac_types.hpp"
50 #include "meshcop/extended_panid.hpp"
51 #include "meshcop/network_name.hpp"
52 #include "meshcop/timestamp.hpp"
53 #include "net/ip6_address.hpp"
54 #include "radio/radio.hpp"
55 #include "thread/key_manager.hpp"
56 #include "thread/mle_types.hpp"
57 
58 namespace ot {
59 namespace MeshCoP {
60 
61 using ot::Encoding::BigEndian::HostSwap16;
62 using ot::Encoding::BigEndian::HostSwap32;
63 using ot::Encoding::BigEndian::ReadUint24;
64 using ot::Encoding::BigEndian::WriteUint24;
65 
66 /**
67  * This class implements MeshCoP TLV generation and parsing.
68  *
69  */
70 OT_TOOL_PACKED_BEGIN
71 class Tlv : public ot::Tlv
72 {
73 public:
74     /**
75      * MeshCoP TLV Types.
76      *
77      */
78     enum Type : uint8_t
79     {
80         kChannel                 = OT_MESHCOP_TLV_CHANNEL,                  ///< Channel TLV
81         kPanId                   = OT_MESHCOP_TLV_PANID,                    ///< PAN ID TLV
82         kExtendedPanId           = OT_MESHCOP_TLV_EXTPANID,                 ///< Extended PAN ID TLV
83         kNetworkName             = OT_MESHCOP_TLV_NETWORKNAME,              ///< Network Name TLV
84         kPskc                    = OT_MESHCOP_TLV_PSKC,                     ///< PSKc TLV
85         kNetworkKey              = OT_MESHCOP_TLV_NETWORKKEY,               ///< Network Network Key TLV
86         kNetworkKeySequence      = OT_MESHCOP_TLV_NETWORK_KEY_SEQUENCE,     ///< Network Key Sequence TLV
87         kMeshLocalPrefix         = OT_MESHCOP_TLV_MESHLOCALPREFIX,          ///< Mesh Local Prefix TLV
88         kSteeringData            = OT_MESHCOP_TLV_STEERING_DATA,            ///< Steering Data TLV
89         kBorderAgentLocator      = OT_MESHCOP_TLV_BORDER_AGENT_RLOC,        ///< Border Agent Locator TLV
90         kCommissionerId          = OT_MESHCOP_TLV_COMMISSIONER_ID,          ///< Commissioner ID TLV
91         kCommissionerSessionId   = OT_MESHCOP_TLV_COMM_SESSION_ID,          ///< Commissioner Session ID TLV
92         kSecurityPolicy          = OT_MESHCOP_TLV_SECURITYPOLICY,           ///< Security Policy TLV
93         kGet                     = OT_MESHCOP_TLV_GET,                      ///< Get TLV
94         kActiveTimestamp         = OT_MESHCOP_TLV_ACTIVETIMESTAMP,          ///< Active Timestamp TLV
95         kCommissionerUdpPort     = OT_MESHCOP_TLV_COMMISSIONER_UDP_PORT,    ///< Commissioner UDP Port TLV
96         kState                   = OT_MESHCOP_TLV_STATE,                    ///< State TLV
97         kJoinerDtlsEncapsulation = OT_MESHCOP_TLV_JOINER_DTLS,              ///< Joiner DTLS Encapsulation TLV
98         kJoinerUdpPort           = OT_MESHCOP_TLV_JOINER_UDP_PORT,          ///< Joiner UDP Port TLV
99         kJoinerIid               = OT_MESHCOP_TLV_JOINER_IID,               ///< Joiner IID TLV
100         kJoinerRouterLocator     = OT_MESHCOP_TLV_JOINER_RLOC,              ///< Joiner Router Locator TLV
101         kJoinerRouterKek         = OT_MESHCOP_TLV_JOINER_ROUTER_KEK,        ///< Joiner Router KEK TLV
102         kProvisioningUrl         = OT_MESHCOP_TLV_PROVISIONING_URL,         ///< Provisioning URL TLV
103         kVendorName              = OT_MESHCOP_TLV_VENDOR_NAME_TLV,          ///< meshcop Vendor Name TLV
104         kVendorModel             = OT_MESHCOP_TLV_VENDOR_MODEL_TLV,         ///< meshcop Vendor Model TLV
105         kVendorSwVersion         = OT_MESHCOP_TLV_VENDOR_SW_VERSION_TLV,    ///< meshcop Vendor SW Version TLV
106         kVendorData              = OT_MESHCOP_TLV_VENDOR_DATA_TLV,          ///< meshcop Vendor Data TLV
107         kVendorStackVersion      = OT_MESHCOP_TLV_VENDOR_STACK_VERSION_TLV, ///< meshcop Vendor Stack Version TLV
108         kUdpEncapsulation        = OT_MESHCOP_TLV_UDP_ENCAPSULATION_TLV,    ///< meshcop UDP encapsulation TLV
109         kIp6Address              = OT_MESHCOP_TLV_IPV6_ADDRESS_TLV,         ///< meshcop IPv6 address TLV
110         kPendingTimestamp        = OT_MESHCOP_TLV_PENDINGTIMESTAMP,         ///< Pending Timestamp TLV
111         kDelayTimer              = OT_MESHCOP_TLV_DELAYTIMER,               ///< Delay Timer TLV
112         kChannelMask             = OT_MESHCOP_TLV_CHANNELMASK,              ///< Channel Mask TLV
113         kCount                   = OT_MESHCOP_TLV_COUNT,                    ///< Count TLV
114         kPeriod                  = OT_MESHCOP_TLV_PERIOD,                   ///< Period TLV
115         kScanDuration            = OT_MESHCOP_TLV_SCAN_DURATION,            ///< Scan Duration TLV
116         kEnergyList              = OT_MESHCOP_TLV_ENERGY_LIST,              ///< Energy List TLV
117         kDiscoveryRequest        = OT_MESHCOP_TLV_DISCOVERYREQUEST,         ///< Discovery Request TLV
118         kDiscoveryResponse       = OT_MESHCOP_TLV_DISCOVERYRESPONSE,        ///< Discovery Response TLV
119         kJoinerAdvertisement     = OT_MESHCOP_TLV_JOINERADVERTISEMENT,      ///< Joiner Advertisement TLV
120     };
121 
122     /**
123      * This method returns the Type value.
124      *
125      * @returns The Type value.
126      *
127      */
GetType(void) const128     Type GetType(void) const { return static_cast<Type>(ot::Tlv::GetType()); }
129 
130     /**
131      * This method sets the Type value.
132      *
133      * @param[in]  aType  The Type value.
134      *
135      */
SetType(Type aType)136     void SetType(Type aType) { ot::Tlv::SetType(static_cast<uint8_t>(aType)); }
137 
138     /**
139      * This method returns a pointer to the next TLV.
140      *
141      * @returns A pointer to the next TLV.
142      *
143      */
GetNext(void)144     Tlv *GetNext(void) { return As<Tlv>(ot::Tlv::GetNext()); }
145 
146     /**
147      * This method returns a pointer to the next TLV.
148      *
149      * @returns A pointer to the next TLV.
150      *
151      */
GetNext(void) const152     const Tlv *GetNext(void) const { return As<Tlv>(ot::Tlv::GetNext()); }
153 
154     /**
155      * This static method reads the requested TLV out of @p aMessage.
156      *
157      * @param[in]   aMessage    A reference to the message.
158      * @param[in]   aType       The Type value to search for.
159      * @param[in]   aMaxLength  Maximum number of bytes to read.
160      * @param[out]  aTlv        A reference to the TLV that will be copied to.
161      *
162      * @retval kErrorNone      Successfully copied the TLV.
163      * @retval kErrorNotFound  Could not find the TLV with Type @p aType.
164      *
165      */
FindTlv(const Message & aMessage,Type aType,uint16_t aMaxLength,Tlv & aTlv)166     static Error FindTlv(const Message &aMessage, Type aType, uint16_t aMaxLength, Tlv &aTlv)
167     {
168         return ot::Tlv::FindTlv(aMessage, static_cast<uint8_t>(aType), aMaxLength, aTlv);
169     }
170 
171     /**
172      * This static method reads the requested TLV out of @p aMessage.
173      *
174      * This method can be used independent of whether the read TLV (from message) is an Extended TLV or not.
175      *
176      * @tparam      TlvType     The TlvType to search for (must be a sub-class of `Tlv`).
177      *
178      * @param[in]   aMessage    A reference to the message.
179      * @param[out]  aTlv        A reference to the TLV that will be copied to.
180      *
181      * @retval kErrorNone      Successfully copied the TLV.
182      * @retval kErrorNotFound  Could not find the TLV with Type @p aType.
183      *
184      */
185 
FindTlv(const Message & aMessage,TlvType & aTlv)186     template <typename TlvType> static Error FindTlv(const Message &aMessage, TlvType &aTlv)
187     {
188         return ot::Tlv::FindTlv(aMessage, aTlv);
189     }
190 
191     /**
192      * This static method indicates whether a TLV appears to be well-formed.
193      *
194      * @param[in]  aTlv  A reference to the TLV.
195      *
196      * @returns TRUE if the TLV appears to be well-formed, FALSE otherwise.
197      *
198      */
199     static bool IsValid(const Tlv &aTlv);
200 
201     /**
202      * This static method searches in a given sequence of TLVs to find the first TLV with a given template Type.
203      *
204      * @param[in]  aTlvsStart  A pointer to the start of the sequence of TLVs to search within.
205      * @param[in]  aTlvsLength The length (number of bytes) in TLV sequence.
206      * @param[in]  aType       The TLV Type to search for.
207      *
208      * @returns A pointer to the TLV if found, or `nullptr` if not found.
209      *
210      */
FindTlv(uint8_t * aTlvsStart,uint16_t aTlvsLength,Type aType)211     static Tlv *FindTlv(uint8_t *aTlvsStart, uint16_t aTlvsLength, Type aType)
212     {
213         return AsNonConst(FindTlv(AsConst(aTlvsStart), aTlvsLength, aType));
214     }
215 
216     /**
217      * This static method searches in a given sequence of TLVs to find the first TLV with a given template Type.
218      *
219      * @param[in]  aTlvsStart  A pointer to the start of the sequence of TLVs to search within.
220      * @param[in]  aTlvsLength The length (number of bytes) in TLV sequence.
221      * @param[in]  aType       The TLV Type to search for.
222      *
223      * @returns A pointer to the TLV if found, or `nullptr` if not found.
224      *
225      */
226     static const Tlv *FindTlv(const uint8_t *aTlvsStart, uint16_t aTlvsLength, Type aType);
227 
228     /**
229      * This static template method searches in a given sequence of TLVs to find the first TLV with a give template
230      * `TlvType`.
231      *
232      * @param[in]  aTlvsStart  A pointer to the start of the sequence of TLVs to search within.
233      * @param[in]  aTlvsLength The length (number of bytes) in TLV sequence.
234      *
235      * @returns A pointer to the TLV if found, or `nullptr` if not found.
236      *
237      */
FindTlv(uint8_t * aTlvsStart,uint16_t aTlvsLength)238     template <typename TlvType> static TlvType *FindTlv(uint8_t *aTlvsStart, uint16_t aTlvsLength)
239     {
240         return As<TlvType>(FindTlv(aTlvsStart, aTlvsLength, static_cast<Tlv::Type>(TlvType::kType)));
241     }
242 
243     /**
244      * This static template method searches in a given sequence of TLVs to find the first TLV with a give template
245      * `TlvType`.
246      *
247      * @param[in]  aTlvsStart  A pointer to the start of the sequence of TLVs to search within.
248      * @param[in]  aTlvsLength The length (number of bytes) in TLV sequence.
249      *
250      * @returns A pointer to the TLV if found, or `nullptr` if not found.
251      *
252      */
FindTlv(const uint8_t * aTlvsStart,uint16_t aTlvsLength)253     template <typename TlvType> static const TlvType *FindTlv(const uint8_t *aTlvsStart, uint16_t aTlvsLength)
254     {
255         return As<TlvType>(FindTlv(aTlvsStart, aTlvsLength, static_cast<Tlv::Type>(TlvType::kType)));
256     }
257 
258 } OT_TOOL_PACKED_END;
259 
260 /**
261  * This class implements extended MeshCoP TLV generation and parsing.
262  *
263  */
264 OT_TOOL_PACKED_BEGIN
265 class ExtendedTlv : public ot::ExtendedTlv
266 {
267 public:
268     /**
269      * This method returns the Type value.
270      *
271      * @returns The Type value.
272      *
273      */
GetType(void) const274     MeshCoP::Tlv::Type GetType(void) const { return static_cast<MeshCoP::Tlv::Type>(ot::ExtendedTlv::GetType()); }
275 
276     /**
277      * This method sets the Type value.
278      *
279      * @param[in]  aType  The Type value.
280      *
281      */
SetType(MeshCoP::Tlv::Type aType)282     void SetType(MeshCoP::Tlv::Type aType) { ot::ExtendedTlv::SetType(static_cast<uint8_t>(aType)); }
283 } OT_TOOL_PACKED_END;
284 
285 /**
286  * This class defines Commissioner UDP Port TLV constants and types.
287  *
288  */
289 typedef UintTlvInfo<Tlv::kCommissionerUdpPort, uint16_t> CommissionerUdpPortTlv;
290 
291 /**
292  * This class defines IPv6 Address TLV constants and types.
293  *
294  */
295 typedef SimpleTlvInfo<Tlv::kIp6Address, Ip6::Address> Ip6AddressTlv;
296 
297 /**
298  * This class defines Joiner IID TLV constants and types.
299  *
300  */
301 typedef SimpleTlvInfo<Tlv::kJoinerIid, Ip6::InterfaceIdentifier> JoinerIidTlv;
302 
303 /**
304  * This class defines Joiner Router Locator TLV constants and types.
305  *
306  */
307 typedef UintTlvInfo<Tlv::kJoinerRouterLocator, uint16_t> JoinerRouterLocatorTlv;
308 
309 /**
310  * This class defines Joiner Router KEK TLV constants and types.
311  *
312  */
313 typedef SimpleTlvInfo<Tlv::kJoinerRouterKek, Kek> JoinerRouterKekTlv;
314 
315 /**
316  * This class defines Count TLV constants and types.
317  *
318  */
319 typedef UintTlvInfo<Tlv::kCount, uint8_t> CountTlv;
320 
321 /**
322  * This class defines Period TLV constants and types.
323  *
324  */
325 typedef UintTlvInfo<Tlv::kPeriod, uint16_t> PeriodTlv;
326 
327 /**
328  * This class defines Scan Duration TLV constants and types.
329  *
330  */
331 typedef UintTlvInfo<Tlv::kScanDuration, uint16_t> ScanDurationTlv;
332 
333 /**
334  * This class implements Channel TLV generation and parsing.
335  *
336  */
337 OT_TOOL_PACKED_BEGIN
338 class ChannelTlv : public Tlv, public TlvInfo<Tlv::kChannel>
339 {
340 public:
341     /**
342      * This method initializes the TLV.
343      *
344      */
Init(void)345     void Init(void)
346     {
347         SetType(kChannel);
348         SetLength(sizeof(*this) - sizeof(Tlv));
349     }
350 
351     /**
352      * This method indicates whether or not the TLV appears to be well-formed.
353      *
354      * @retval TRUE   If the TLV appears to be well-formed.
355      * @retval FALSE  If the TLV does not appear to be well-formed.
356      *
357      */
358     bool IsValid(void) const;
359 
360     /**
361      * This method returns the ChannelPage value.
362      *
363      * @returns The ChannelPage value.
364      *
365      */
GetChannelPage(void) const366     uint8_t GetChannelPage(void) const { return mChannelPage; }
367 
368     /**
369      * This method sets the ChannelPage value.
370      *
371      * @param[in]  aChannelPage  The ChannelPage value.
372      *
373      */
SetChannelPage(uint8_t aChannelPage)374     void SetChannelPage(uint8_t aChannelPage) { mChannelPage = aChannelPage; }
375 
376     /**
377      * This method returns the Channel value.
378      *
379      * @returns The Channel value.
380      *
381      */
GetChannel(void) const382     uint16_t GetChannel(void) const { return HostSwap16(mChannel); }
383 
384     /**
385      * This method sets the Channel value.
386      * Note: This method also sets the channel page according to the channel value.
387      *
388      * @param[in]  aChannel  The Channel value.
389      *
390      */
391     void SetChannel(uint16_t aChannel);
392 
393 private:
394     uint8_t  mChannelPage;
395     uint16_t mChannel;
396 } OT_TOOL_PACKED_END;
397 
398 /**
399  * This class implements PAN ID TLV generation and parsing.
400  *
401  */
402 OT_TOOL_PACKED_BEGIN
403 class PanIdTlv : public Tlv, public UintTlvInfo<Tlv::kPanId, uint16_t>
404 {
405 public:
406     /**
407      * This method initializes the TLV.
408      *
409      */
Init(void)410     void Init(void)
411     {
412         SetType(kPanId);
413         SetLength(sizeof(*this) - sizeof(Tlv));
414     }
415 
416     /**
417      * This method indicates whether or not the TLV appears to be well-formed.
418      *
419      * @retval TRUE   If the TLV appears to be well-formed.
420      * @retval FALSE  If the TLV does not appear to be well-formed.
421      *
422      */
IsValid(void) const423     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
424 
425     /**
426      * This method returns the PAN ID value.
427      *
428      * @returns The PAN ID value.
429      *
430      */
GetPanId(void) const431     uint16_t GetPanId(void) const { return HostSwap16(mPanId); }
432 
433     /**
434      * This method sets the PAN ID value.
435      *
436      * @param[in]  aPanId  The PAN ID value.
437      *
438      */
SetPanId(uint16_t aPanId)439     void SetPanId(uint16_t aPanId) { mPanId = HostSwap16(aPanId); }
440 
441 private:
442     uint16_t mPanId;
443 } OT_TOOL_PACKED_END;
444 
445 /**
446  * This class implements Extended PAN ID TLV generation and parsing.
447  *
448  */
449 OT_TOOL_PACKED_BEGIN
450 class ExtendedPanIdTlv : public Tlv, public SimpleTlvInfo<Tlv::kExtendedPanId, ExtendedPanId>
451 {
452 public:
453     /**
454      * This method initializes the TLV.
455      *
456      */
Init(void)457     void Init(void)
458     {
459         SetType(kExtendedPanId);
460         SetLength(sizeof(*this) - sizeof(Tlv));
461     }
462 
463     /**
464      * This method indicates whether or not the TLV appears to be well-formed.
465      *
466      * @retval TRUE   If the TLV appears to be well-formed.
467      * @retval FALSE  If the TLV does not appear to be well-formed.
468      *
469      */
IsValid(void) const470     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
471 
472     /**
473      * This method returns the Extended PAN ID value.
474      *
475      * @returns The Extended PAN ID value.
476      *
477      */
GetExtendedPanId(void) const478     const ExtendedPanId &GetExtendedPanId(void) const { return mExtendedPanId; }
479 
480     /**
481      * This method sets the Extended PAN ID value.
482      *
483      * @param[in]  aExtendedPanId  An Extended PAN ID value.
484      *
485      */
SetExtendedPanId(const ExtendedPanId & aExtendedPanId)486     void SetExtendedPanId(const ExtendedPanId &aExtendedPanId) { mExtendedPanId = aExtendedPanId; }
487 
488 private:
489     ExtendedPanId mExtendedPanId;
490 } OT_TOOL_PACKED_END;
491 
492 /**
493  * This class implements Network Name TLV generation and parsing.
494  *
495  */
496 OT_TOOL_PACKED_BEGIN
497 class NetworkNameTlv : public Tlv, public TlvInfo<Tlv::kNetworkName>
498 {
499 public:
500     /**
501      * This method initializes the TLV.
502      *
503      */
Init(void)504     void Init(void)
505     {
506         SetType(kNetworkName);
507         SetLength(sizeof(*this) - sizeof(Tlv));
508     }
509 
510     /**
511      * This method indicates whether or not the TLV appears to be well-formed.
512      *
513      * @retval TRUE   If the TLV appears to be well-formed.
514      * @retval FALSE  If the TLV does not appear to be well-formed.
515      *
516      */
517     bool IsValid(void) const;
518 
519     /**
520      * This method gets the Network Name value.
521      *
522      * @returns The Network Name value (as `NameData`).
523      *
524      */
525     NameData GetNetworkName(void) const;
526 
527     /**
528      * This method sets the Network Name value.
529      *
530      * @param[in] aNameData   A Network Name value (as `NameData`).
531      *
532      */
533     void SetNetworkName(const NameData &aNameData);
534 
535 private:
536     char mNetworkName[NetworkName::kMaxSize];
537 } OT_TOOL_PACKED_END;
538 
539 /**
540  * This class implements PSKc TLV generation and parsing.
541  *
542  */
543 OT_TOOL_PACKED_BEGIN
544 class PskcTlv : public Tlv, public SimpleTlvInfo<Tlv::kPskc, Pskc>
545 {
546 public:
547     /**
548      * This method initializes the TLV.
549      *
550      */
Init(void)551     void Init(void)
552     {
553         SetType(kPskc);
554         SetLength(sizeof(*this) - sizeof(Tlv));
555     }
556 
557     /**
558      * This method indicates whether or not the TLV appears to be well-formed.
559      *
560      * @retval TRUE   If the TLV appears to be well-formed.
561      * @retval FALSE  If the TLV does not appear to be well-formed.
562      *
563      */
IsValid(void) const564     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
565 
566     /**
567      * This method returns the PSKc value.
568      *
569      * @returns The PSKc value.
570      *
571      */
GetPskc(void) const572     const Pskc &GetPskc(void) const { return mPskc; }
573 
574     /**
575      * This method sets the PSKc value.
576      *
577      * @param[in]  aPskc  A pointer to the PSKc value.
578      *
579      */
SetPskc(const Pskc & aPskc)580     void SetPskc(const Pskc &aPskc) { mPskc = aPskc; }
581 
582 private:
583     Pskc mPskc;
584 } OT_TOOL_PACKED_END;
585 
586 /**
587  * This class implements Network Network Key TLV generation and parsing.
588  *
589  */
590 OT_TOOL_PACKED_BEGIN
591 class NetworkKeyTlv : public Tlv, public SimpleTlvInfo<Tlv::kNetworkKey, NetworkKey>
592 {
593 public:
594     /**
595      * This method initializes the TLV.
596      *
597      */
Init(void)598     void Init(void)
599     {
600         SetType(kNetworkKey);
601         SetLength(sizeof(*this) - sizeof(Tlv));
602     }
603 
604     /**
605      * This method indicates whether or not the TLV appears to be well-formed.
606      *
607      * @retval TRUE   If the TLV appears to be well-formed.
608      * @retval FALSE  If the TLV does not appear to be well-formed.
609      *
610      */
IsValid(void) const611     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
612 
613     /**
614      * This method returns the Network Network Key value.
615      *
616      * @returns The Network Network Key value.
617      *
618      */
GetNetworkKey(void) const619     const NetworkKey &GetNetworkKey(void) const { return mNetworkKey; }
620 
621     /**
622      * This method sets the Network Network Key value.
623      *
624      * @param[in]  aNetworkKey  The Network Network Key.
625      *
626      */
SetNetworkKey(const NetworkKey & aNetworkKey)627     void SetNetworkKey(const NetworkKey &aNetworkKey) { mNetworkKey = aNetworkKey; }
628 
629 private:
630     NetworkKey mNetworkKey;
631 } OT_TOOL_PACKED_END;
632 
633 /**
634  * This class implements Network Key Sequence TLV generation and parsing.
635  *
636  */
637 OT_TOOL_PACKED_BEGIN
638 class NetworkKeySequenceTlv : public Tlv, public UintTlvInfo<Tlv::kNetworkKeySequence, uint32_t>
639 {
640 public:
641     /**
642      * This method initializes the TLV.
643      *
644      */
Init(void)645     void Init(void)
646     {
647         SetType(kNetworkKeySequence);
648         SetLength(sizeof(*this) - sizeof(Tlv));
649     }
650 
651     /**
652      * This method indicates whether or not the TLV appears to be well-formed.
653      *
654      * @retval TRUE   If the TLV appears to be well-formed.
655      * @retval FALSE  If the TLV does not appear to be well-formed.
656      *
657      */
IsValid(void) const658     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
659 
660     /**
661      * This method returns the Network Key Sequence value.
662      *
663      * @returns The Network Key Sequence value.
664      *
665      */
GetNetworkKeySequence(void) const666     uint32_t GetNetworkKeySequence(void) const { return HostSwap32(mNetworkKeySequence); }
667 
668     /**
669      * This method sets the Network Key Sequence value.
670      *
671      * @param[in]  aNetworkKeySequence  The Network Key Sequence value.
672      *
673      */
SetNetworkKeySequence(uint32_t aNetworkKeySequence)674     void SetNetworkKeySequence(uint32_t aNetworkKeySequence) { mNetworkKeySequence = HostSwap32(aNetworkKeySequence); }
675 
676 private:
677     uint32_t mNetworkKeySequence;
678 } OT_TOOL_PACKED_END;
679 
680 /**
681  * This class implements Mesh Local Prefix TLV generation and parsing.
682  *
683  */
684 OT_TOOL_PACKED_BEGIN
685 class MeshLocalPrefixTlv : public Tlv, public SimpleTlvInfo<Tlv::kMeshLocalPrefix, Ip6::NetworkPrefix>
686 {
687 public:
688     /**
689      * This method initializes the TLV.
690      *
691      */
Init(void)692     void Init(void)
693     {
694         SetType(kMeshLocalPrefix);
695         SetLength(sizeof(*this) - sizeof(Tlv));
696     }
697 
698     /**
699      * This method indicates whether or not the TLV appears to be well-formed.
700      *
701      * @retval TRUE   If the TLV appears to be well-formed.
702      * @retval FALSE  If the TLV does not appear to be well-formed.
703      *
704      */
IsValid(void) const705     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
706 
707     /**
708      * This method returns the size (in bytes) of the Mesh Local Prefix field.
709      *
710      * @returns The size (in bytes) of the Mesh Local Prefix field (8 bytes).
711      *
712      */
GetMeshLocalPrefixLength(void) const713     uint8_t GetMeshLocalPrefixLength(void) const { return sizeof(mMeshLocalPrefix); }
714 
715     /**
716      * This method returns the Mesh Local Prefix value.
717      *
718      * @returns The Mesh Local Prefix value.
719      *
720      */
GetMeshLocalPrefix(void) const721     const Ip6::NetworkPrefix &GetMeshLocalPrefix(void) const { return mMeshLocalPrefix; }
722 
723     /**
724      * This method sets the Mesh Local Prefix value.
725      *
726      * @param[in]  aMeshLocalPrefix  A pointer to the Mesh Local Prefix value.
727      *
728      */
SetMeshLocalPrefix(const Ip6::NetworkPrefix & aMeshLocalPrefix)729     void SetMeshLocalPrefix(const Ip6::NetworkPrefix &aMeshLocalPrefix) { mMeshLocalPrefix = aMeshLocalPrefix; }
730 
731 private:
732     Ip6::NetworkPrefix mMeshLocalPrefix;
733 } OT_TOOL_PACKED_END;
734 
735 class SteeringData;
736 
737 /**
738  * This class implements Steering Data TLV generation and parsing.
739  *
740  */
741 OT_TOOL_PACKED_BEGIN
742 class SteeringDataTlv : public Tlv, public TlvInfo<Tlv::kSteeringData>
743 {
744 public:
745     /**
746      * This method initializes the TLV.
747      *
748      */
Init(void)749     void Init(void)
750     {
751         SetType(kSteeringData);
752         SetLength(sizeof(*this) - sizeof(Tlv));
753         Clear();
754     }
755 
756     /**
757      * This method indicates whether or not the TLV appears to be well-formed.
758      *
759      * @retval TRUE   If the TLV appears to be well-formed.
760      * @retval FALSE  If the TLV does not appear to be well-formed.
761      *
762      */
IsValid(void) const763     bool IsValid(void) const { return GetLength() > 0; }
764 
765     /**
766      * This method returns the Steering Data length.
767      *
768      * @returns The Steering Data length.
769      *
770      */
GetSteeringDataLength(void) const771     uint8_t GetSteeringDataLength(void) const
772     {
773         return GetLength() <= sizeof(mSteeringData) ? GetLength() : sizeof(mSteeringData);
774     }
775 
776     /**
777      * This method sets all bits in the Bloom Filter to zero.
778      *
779      */
Clear(void)780     void Clear(void) { memset(mSteeringData, 0, GetSteeringDataLength()); }
781 
782     /**
783      * This method copies the Steering Data from the TLV into a given `SteeringData` variable.
784      *
785      * @param[out]  aSteeringData   A reference to a `SteeringData` to copy into.
786      *
787      */
788     void CopyTo(SteeringData &aSteeringData) const;
789 
790 private:
791     uint8_t mSteeringData[OT_STEERING_DATA_MAX_LENGTH];
792 } OT_TOOL_PACKED_END;
793 
794 /**
795  * This class implements Border Agent Locator TLV generation and parsing.
796  *
797  */
798 OT_TOOL_PACKED_BEGIN
799 class BorderAgentLocatorTlv : public Tlv, public UintTlvInfo<Tlv::kBorderAgentLocator, uint16_t>
800 {
801 public:
802     /**
803      * This method initializes the TLV.
804      *
805      */
Init(void)806     void Init(void)
807     {
808         SetType(kBorderAgentLocator);
809         SetLength(sizeof(*this) - sizeof(Tlv));
810     }
811 
812     /**
813      * This method indicates whether or not the TLV appears to be well-formed.
814      *
815      * @retval TRUE   If the TLV appears to be well-formed.
816      * @retval FALSE  If the TLV does not appear to be well-formed.
817      *
818      */
IsValid(void) const819     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
820 
821     /**
822      * This method returns the Border Agent Locator value.
823      *
824      * @returns The Border Agent Locator value.
825      *
826      */
GetBorderAgentLocator(void) const827     uint16_t GetBorderAgentLocator(void) const { return HostSwap16(mLocator); }
828 
829     /**
830      * This method sets the Border Agent Locator value.
831      *
832      * @param[in]  aLocator  The Border Agent Locator value.
833      *
834      */
SetBorderAgentLocator(uint16_t aLocator)835     void SetBorderAgentLocator(uint16_t aLocator) { mLocator = HostSwap16(aLocator); }
836 
837 private:
838     uint16_t mLocator;
839 } OT_TOOL_PACKED_END;
840 
841 /**
842  * This class implements the Commissioner ID TLV generation and parsing.
843  *
844  */
845 OT_TOOL_PACKED_BEGIN
846 class CommissionerIdTlv : public Tlv, public TlvInfo<Tlv::kCommissionerId>
847 {
848 public:
849     static constexpr uint8_t kMaxLength = 64; ///< maximum length (bytes)
850 
851     /**
852      * This method initializes the TLV.
853      *
854      */
Init(void)855     void Init(void)
856     {
857         SetType(kCommissionerId);
858         SetLength(sizeof(*this) - sizeof(Tlv));
859     }
860 
861     /**
862      * This method returns the Commissioner ID length.
863      *
864      * @returns The Commissioner ID length.
865      *
866      */
GetCommissionerIdLength(void) const867     uint8_t GetCommissionerIdLength(void) const
868     {
869         return GetLength() <= sizeof(mCommissionerId) ? GetLength() : sizeof(mCommissionerId);
870     }
871 
872     /**
873      * This method returns the Commissioner ID value.
874      *
875      * @returns The Commissioner ID value.
876      *
877      */
GetCommissionerId(void) const878     const char *GetCommissionerId(void) const { return mCommissionerId; }
879 
880     /**
881      * This method sets the Commissioner ID value.
882      *
883      * @param[in]  aCommissionerId  A pointer to the Commissioner ID value.
884      *
885      */
SetCommissionerId(const char * aCommissionerId)886     void SetCommissionerId(const char *aCommissionerId)
887     {
888         uint16_t length = StringLength(aCommissionerId, sizeof(mCommissionerId));
889         memcpy(mCommissionerId, aCommissionerId, length);
890         SetLength(static_cast<uint8_t>(length));
891     }
892 
893 private:
894     char mCommissionerId[kMaxLength];
895 } OT_TOOL_PACKED_END;
896 
897 /**
898  * This class implements Commissioner Session ID TLV generation and parsing.
899  *
900  */
901 OT_TOOL_PACKED_BEGIN
902 class CommissionerSessionIdTlv : public Tlv, public UintTlvInfo<Tlv::kCommissionerSessionId, uint16_t>
903 {
904 public:
905     /**
906      * This method initializes the TLV.
907      *
908      */
Init(void)909     void Init(void)
910     {
911         SetType(kCommissionerSessionId);
912         SetLength(sizeof(*this) - sizeof(Tlv));
913     }
914 
915     /**
916      * This method indicates whether or not the TLV appears to be well-formed.
917      *
918      * @retval TRUE   If the TLV appears to be well-formed.
919      * @retval FALSE  If the TLV does not appear to be well-formed.
920      *
921      */
IsValid(void) const922     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
923 
924     /**
925      * This method returns the Commissioner Session ID value.
926      *
927      * @returns The Commissioner Session ID value.
928      *
929      */
GetCommissionerSessionId(void) const930     uint16_t GetCommissionerSessionId(void) const { return HostSwap16(mSessionId); }
931 
932     /**
933      * This method sets the Commissioner Session ID value.
934      *
935      * @param[in]  aSessionId  The Commissioner Session ID value.
936      *
937      */
SetCommissionerSessionId(uint16_t aSessionId)938     void SetCommissionerSessionId(uint16_t aSessionId) { mSessionId = HostSwap16(aSessionId); }
939 
940 private:
941     uint16_t mSessionId;
942 } OT_TOOL_PACKED_END;
943 
944 /**
945  * This class implements Security Policy TLV generation and parsing.
946  *
947  */
948 OT_TOOL_PACKED_BEGIN
949 class SecurityPolicyTlv : public Tlv, public TlvInfo<Tlv::kSecurityPolicy>
950 {
951 public:
952     /**
953      * This method initializes the TLV.
954      *
955      */
Init(void)956     void Init(void)
957     {
958         SetType(kSecurityPolicy);
959         SetLength(sizeof(*this) - sizeof(Tlv));
960     }
961 
962     /**
963      * This method indicates whether or not the TLV appears to be well-formed.
964      *
965      * @retval TRUE   If the TLV appears to be well-formed.
966      * @retval FALSE  If the TLV does not appear to be well-formed.
967      *
968      */
969     bool IsValid(void) const;
970 
971     /**
972      * This method returns the Security Policy.
973      *
974      * @returns  The Security Policy.
975      *
976      */
977     SecurityPolicy GetSecurityPolicy(void) const;
978 
979     /**
980      * This method sets the Security Policy.
981      *
982      * @param[in]  aSecurityPolicy  The Security Policy which will be set.
983      *
984      */
985     void SetSecurityPolicy(const SecurityPolicy &aSecurityPolicy);
986 
987 private:
988     static constexpr uint8_t kThread11FlagsLength = 1; // The Thread 1.1 Security Policy Flags length.
989     static constexpr uint8_t kThread12FlagsLength = 2; // The Thread 1.2 Security Policy Flags length.
990 
SetRotationTime(uint16_t aRotationTime)991     void     SetRotationTime(uint16_t aRotationTime) { mRotationTime = HostSwap16(aRotationTime); }
GetRotationTime(void) const992     uint16_t GetRotationTime(void) const { return HostSwap16(mRotationTime); }
GetFlagsLength(void) const993     uint8_t  GetFlagsLength(void) const { return GetLength() - sizeof(mRotationTime); }
994 
995     uint16_t mRotationTime;
996 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
997     uint8_t mFlags[kThread12FlagsLength];
998 #else
999     uint8_t mFlags[kThread11FlagsLength];
1000 #endif
1001 } OT_TOOL_PACKED_END;
1002 
1003 /**
1004  * This class implements Active Timestamp TLV generation and parsing.
1005  *
1006  */
1007 OT_TOOL_PACKED_BEGIN
1008 class ActiveTimestampTlv : public Tlv, public SimpleTlvInfo<Tlv::kActiveTimestamp, Timestamp>
1009 {
1010 public:
1011     /**
1012      * This method initializes the TLV.
1013      *
1014      */
Init(void)1015     void Init(void)
1016     {
1017         SetType(kActiveTimestamp);
1018         SetLength(sizeof(*this) - sizeof(Tlv));
1019         mTimestamp.Clear();
1020     }
1021 
1022     /**
1023      * This method indicates whether or not the TLV appears to be well-formed.
1024      *
1025      * @retval TRUE   If the TLV appears to be well-formed.
1026      * @retval FALSE  If the TLV does not appear to be well-formed.
1027      *
1028      */
IsValid(void) const1029     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1030 
1031     /**
1032      * This method gets the timestamp.
1033      *
1034      * @returns The timestamp.
1035      *
1036      */
GetTimestamp(void) const1037     const Timestamp &GetTimestamp(void) const { return mTimestamp; }
1038 
1039     /**
1040      * This method returns a reference to the timestamp.
1041      *
1042      * @returns A reference to the timestamp.
1043      *
1044      */
GetTimestamp(void)1045     Timestamp &GetTimestamp(void) { return mTimestamp; }
1046 
1047     /**
1048      * This method sets the timestamp.
1049      *
1050      * @param[in] aTimestamp   The new timestamp.
1051      *
1052      */
SetTimestamp(const Timestamp & aTimestamp)1053     void SetTimestamp(const Timestamp &aTimestamp) { mTimestamp = aTimestamp; }
1054 
1055 private:
1056     Timestamp mTimestamp;
1057 } OT_TOOL_PACKED_END;
1058 
1059 /**
1060  * This class implements State TLV generation and parsing.
1061  *
1062  */
1063 OT_TOOL_PACKED_BEGIN
1064 class StateTlv : public Tlv, public UintTlvInfo<Tlv::kState, uint8_t>
1065 {
1066 public:
1067     /**
1068      * This method initializes the TLV.
1069      *
1070      */
Init(void)1071     void Init(void)
1072     {
1073         SetType(kState);
1074         SetLength(sizeof(*this) - sizeof(Tlv));
1075     }
1076 
1077     /**
1078      * This method indicates whether or not the TLV appears to be well-formed.
1079      *
1080      * @retval TRUE   If the TLV appears to be well-formed.
1081      * @retval FALSE  If the TLV does not appear to be well-formed.
1082      *
1083      */
IsValid(void) const1084     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1085 
1086     /**
1087      * State values.
1088      *
1089      */
1090     enum State : uint8_t
1091     {
1092         kReject  = 0xff, ///< Reject (-1)
1093         kPending = 0,    ///< Pending
1094         kAccept  = 1,    ///< Accept
1095     };
1096 
1097     /**
1098      * This method returns the State value.
1099      *
1100      * @returns The State value.
1101      *
1102      */
GetState(void) const1103     State GetState(void) const { return static_cast<State>(mState); }
1104 
1105     /**
1106      * This method sets the State value.
1107      *
1108      * @param[in]  aState  The State value.
1109      *
1110      */
SetState(State aState)1111     void SetState(State aState) { mState = static_cast<uint8_t>(aState); }
1112 
1113 private:
1114     uint8_t mState;
1115 } OT_TOOL_PACKED_END;
1116 
1117 /**
1118  * This class implements Joiner UDP Port TLV generation and parsing.
1119  *
1120  */
1121 OT_TOOL_PACKED_BEGIN
1122 class JoinerUdpPortTlv : public Tlv, public UintTlvInfo<Tlv::kJoinerUdpPort, uint16_t>
1123 {
1124 public:
1125     /**
1126      * This method initializes the TLV.
1127      *
1128      */
Init(void)1129     void Init(void)
1130     {
1131         SetType(kJoinerUdpPort);
1132         SetLength(sizeof(*this) - sizeof(Tlv));
1133     }
1134 
1135     /**
1136      * This method indicates whether or not the TLV appears to be well-formed.
1137      *
1138      * @retval TRUE   If the TLV appears to be well-formed.
1139      * @retval FALSE  If the TLV does not appear to be well-formed.
1140      *
1141      */
IsValid(void) const1142     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1143 
1144     /**
1145      * This method returns the UDP Port value.
1146      *
1147      * @returns The UDP Port value.
1148      *
1149      */
GetUdpPort(void) const1150     uint16_t GetUdpPort(void) const { return HostSwap16(mUdpPort); }
1151 
1152     /**
1153      * This method sets the UDP Port value.
1154      *
1155      * @param[in]  aUdpPort  The UDP Port value.
1156      *
1157      */
SetUdpPort(uint16_t aUdpPort)1158     void SetUdpPort(uint16_t aUdpPort) { mUdpPort = HostSwap16(aUdpPort); }
1159 
1160 private:
1161     uint16_t mUdpPort;
1162 } OT_TOOL_PACKED_END;
1163 
1164 /**
1165  * This class implements Pending Timestamp TLV generation and parsing.
1166  *
1167  */
1168 OT_TOOL_PACKED_BEGIN
1169 class PendingTimestampTlv : public Tlv, public SimpleTlvInfo<Tlv::kPendingTimestamp, Timestamp>
1170 {
1171 public:
1172     /**
1173      * This method initializes the TLV.
1174      *
1175      */
Init(void)1176     void Init(void)
1177     {
1178         SetType(kPendingTimestamp);
1179         SetLength(sizeof(*this) - sizeof(Tlv));
1180         mTimestamp.Clear();
1181     }
1182 
1183     /**
1184      * This method indicates whether or not the TLV appears to be well-formed.
1185      *
1186      * @retval TRUE   If the TLV appears to be well-formed.
1187      * @retval FALSE  If the TLV does not appear to be well-formed.
1188      *
1189      */
IsValid(void) const1190     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1191 
1192     /**
1193      * This method gets the timestamp.
1194      *
1195      * @returns The timestamp.
1196      *
1197      */
GetTimestamp(void) const1198     const Timestamp &GetTimestamp(void) const { return mTimestamp; }
1199 
1200     /**
1201      * This method returns a reference to the timestamp.
1202      *
1203      * @returns A reference to the timestamp.
1204      *
1205      */
GetTimestamp(void)1206     Timestamp &GetTimestamp(void) { return mTimestamp; }
1207 
1208     /**
1209      * This method sets the timestamp.
1210      *
1211      * @param[in] aTimestamp   The new timestamp.
1212      *
1213      */
SetTimestamp(const Timestamp & aTimestamp)1214     void SetTimestamp(const Timestamp &aTimestamp) { mTimestamp = aTimestamp; }
1215 
1216 private:
1217     Timestamp mTimestamp;
1218 } OT_TOOL_PACKED_END;
1219 
1220 /**
1221  * This class implements Delay Timer TLV generation and parsing.
1222  *
1223  */
1224 OT_TOOL_PACKED_BEGIN
1225 class DelayTimerTlv : public Tlv, public UintTlvInfo<Tlv::kDelayTimer, uint32_t>
1226 {
1227 public:
1228     /**
1229      * This method initializes the TLV.
1230      *
1231      */
Init(void)1232     void Init(void)
1233     {
1234         SetType(kDelayTimer);
1235         SetLength(sizeof(*this) - sizeof(Tlv));
1236     }
1237 
1238     /**
1239      * This method indicates whether or not the TLV appears to be well-formed.
1240      *
1241      * @retval TRUE   If the TLV appears to be well-formed.
1242      * @retval FALSE  If the TLV does not appear to be well-formed.
1243      *
1244      */
IsValid(void) const1245     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1246 
1247     /**
1248      * This method returns the Delay Timer value.
1249      *
1250      * @returns The Delay Timer value.
1251      *
1252      */
GetDelayTimer(void) const1253     uint32_t GetDelayTimer(void) const { return HostSwap32(mDelayTimer); }
1254 
1255     /**
1256      * This method sets the Delay Timer value.
1257      *
1258      * @param[in]  aDelayTimer  The Delay Timer value.
1259      *
1260      */
SetDelayTimer(uint32_t aDelayTimer)1261     void SetDelayTimer(uint32_t aDelayTimer) { mDelayTimer = HostSwap32(aDelayTimer); }
1262 
1263     static constexpr uint32_t kMaxDelayTimer = 259200; ///< Maximum delay timer value for a Pending Dataset in seconds
1264 
1265     /**
1266      * Minimum Delay Timer value for a Pending Operational Dataset (ms)
1267      *
1268      */
1269     static constexpr uint32_t kDelayTimerMinimal = OPENTHREAD_CONFIG_TMF_PENDING_DATASET_MINIMUM_DELAY;
1270 
1271     /**
1272      * Default Delay Timer value for a Pending Operational Dataset (ms)
1273      *
1274      */
1275     static constexpr uint32_t kDelayTimerDefault = OPENTHREAD_CONFIG_TMF_PENDING_DATASET_DEFAULT_DELAY;
1276 
1277 private:
1278     uint32_t mDelayTimer;
1279 } OT_TOOL_PACKED_END;
1280 
1281 // forward declare ChannelMaskTlv
1282 class ChannelMaskTlv;
1283 
1284 /**
1285  * This class implements Channel Mask Entry generation and parsing.
1286  *
1287  */
1288 OT_TOOL_PACKED_BEGIN
1289 class ChannelMaskEntryBase
1290 {
1291 public:
1292     /**
1293      * This method gets the ChannelPage value.
1294      *
1295      * @returns The ChannelPage value.
1296      *
1297      */
GetChannelPage(void) const1298     uint8_t GetChannelPage(void) const { return mChannelPage; }
1299 
1300     /**
1301      * This method sets the ChannelPage value.
1302      *
1303      * @param[in]  aChannelPage  The ChannelPage value.
1304      *
1305      */
SetChannelPage(uint8_t aChannelPage)1306     void SetChannelPage(uint8_t aChannelPage) { mChannelPage = aChannelPage; }
1307 
1308     /**
1309      * This method gets the MaskLength value.
1310      *
1311      * @returns The MaskLength value.
1312      *
1313      */
GetMaskLength(void) const1314     uint8_t GetMaskLength(void) const { return mMaskLength; }
1315 
1316     /**
1317      * This method sets the MaskLength value.
1318      *
1319      * @param[in]  aMaskLength  The MaskLength value.
1320      *
1321      */
SetMaskLength(uint8_t aMaskLength)1322     void SetMaskLength(uint8_t aMaskLength) { mMaskLength = aMaskLength; }
1323 
1324     /**
1325      * This method returns the total size of this Channel Mask Entry including the mask.
1326      *
1327      * @returns The total size of this entry (number of bytes).
1328      *
1329      */
GetEntrySize(void) const1330     uint16_t GetEntrySize(void) const { return sizeof(ChannelMaskEntryBase) + mMaskLength; }
1331 
1332     /**
1333      * This method clears the bit corresponding to @p aChannel in ChannelMask.
1334      *
1335      * @param[in]  aChannel  The channel in ChannelMask to clear.
1336      *
1337      */
ClearChannel(uint8_t aChannel)1338     void ClearChannel(uint8_t aChannel)
1339     {
1340         uint8_t *mask = reinterpret_cast<uint8_t *>(this) + sizeof(*this);
1341         mask[aChannel / 8] &= ~(0x80 >> (aChannel % 8));
1342     }
1343 
1344     /**
1345      * This method sets the bit corresponding to @p aChannel in ChannelMask.
1346      *
1347      * @param[in]  aChannel  The channel in ChannelMask to set.
1348      *
1349      */
SetChannel(uint8_t aChannel)1350     void SetChannel(uint8_t aChannel)
1351     {
1352         uint8_t *mask = reinterpret_cast<uint8_t *>(this) + sizeof(*this);
1353         mask[aChannel / 8] |= 0x80 >> (aChannel % 8);
1354     }
1355 
1356     /**
1357      * This method indicates whether or not the bit corresponding to @p aChannel in ChannelMask is set.
1358      *
1359      * @param[in]  aChannel  The channel in ChannelMask to get.
1360      *
1361      */
IsChannelSet(uint8_t aChannel) const1362     bool IsChannelSet(uint8_t aChannel) const
1363     {
1364         const uint8_t *mask = reinterpret_cast<const uint8_t *>(this) + sizeof(*this);
1365         return (aChannel < (mMaskLength * 8)) ? ((mask[aChannel / 8] & (0x80 >> (aChannel % 8))) != 0) : false;
1366     }
1367 
1368     /**
1369      * This method gets the next Channel Mask Entry in a Channel Mask TLV.
1370      *
1371      * @returns A pointer to next Channel Mask Entry.
1372      *
1373      */
GetNext(void) const1374     const ChannelMaskEntryBase *GetNext(void) const
1375     {
1376         return reinterpret_cast<const ChannelMaskEntryBase *>(reinterpret_cast<const uint8_t *>(this) + GetEntrySize());
1377     }
1378 
1379     /**
1380      * This method gets the next Channel Mask Entry in a Channel Mask TLV.
1381      *
1382      * @returns A pointer to next Channel Mask Entry.
1383      *
1384      */
GetNext(void)1385     ChannelMaskEntryBase *GetNext(void) { return AsNonConst(AsConst(this)->GetNext()); }
1386 
1387 private:
1388     uint8_t mChannelPage;
1389     uint8_t mMaskLength;
1390 } OT_TOOL_PACKED_END;
1391 
1392 /**
1393  * This class implements Channel Mask Entry Page 0 generation and parsing.
1394  *
1395  */
1396 OT_TOOL_PACKED_BEGIN
1397 class ChannelMaskEntry : public ChannelMaskEntryBase
1398 {
1399 public:
1400     /**
1401      * This method initializes the entry.
1402      *
1403      */
Init(void)1404     void Init(void)
1405     {
1406         SetChannelPage(0);
1407         SetMaskLength(sizeof(mMask));
1408     }
1409 
1410     /**
1411      * This method indicates whether or not the entry appears to be well-formed.
1412      *
1413      * @retval TRUE   If the entry appears to be well-formed.
1414      * @retval FALSE  If the entry does not appear to be well-formed.
1415      *
1416      */
IsValid(void) const1417     bool IsValid(void) const { return GetMaskLength() == sizeof(mMask); }
1418 
1419     /**
1420      * This method returns the Channel Mask value as a `uint32_t` bit mask.
1421      *
1422      * @returns The Channel Mask value.
1423      *
1424      */
GetMask(void) const1425     uint32_t GetMask(void) const { return Encoding::Reverse32(HostSwap32(mMask)); }
1426 
1427     /**
1428      * This method sets the Channel Mask value.
1429      *
1430      * @param[in]  aMask  The Channel Mask value.
1431      *
1432      */
SetMask(uint32_t aMask)1433     void SetMask(uint32_t aMask) { mMask = HostSwap32(Encoding::Reverse32(aMask)); }
1434 
1435 private:
1436     uint32_t mMask;
1437 } OT_TOOL_PACKED_END;
1438 
1439 /**
1440  * This class implements Channel Mask TLV generation and parsing.
1441  *
1442  */
1443 OT_TOOL_PACKED_BEGIN
1444 class ChannelMaskBaseTlv : public Tlv, public TlvInfo<Tlv::kChannelMask>
1445 {
1446 public:
1447     /**
1448      * This method initializes the TLV.
1449      *
1450      */
Init(void)1451     void Init(void)
1452     {
1453         SetType(kChannelMask);
1454         SetLength(sizeof(*this) - sizeof(Tlv));
1455     }
1456 
1457     /**
1458      * This method indicates whether or not the TLV appears to be well-formed.
1459      *
1460      * @retval TRUE   If the TLV appears to be well-formed.
1461      * @retval FALSE  If the TLV does not appear to be well-formed.
1462      *
1463      */
1464     bool IsValid(void) const;
1465 
1466     /**
1467      * This method gets the first Channel Mask Entry in the Channel Mask TLV.
1468      *
1469      * @returns A pointer to first Channel Mask Entry or `nullptr` if not found.
1470      *
1471      */
1472     const ChannelMaskEntryBase *GetFirstEntry(void) const;
1473 
1474     /**
1475      * This method gets the first Channel Mask Entry in the Channel Mask TLV.
1476      *
1477      * @returns A pointer to first Channel Mask Entry or `nullptr` if not found.
1478      *
1479      */
1480     ChannelMaskEntryBase *GetFirstEntry(void);
1481 } OT_TOOL_PACKED_END;
1482 
1483 /**
1484  * This class implements Channel Mask TLV generation and parsing.
1485  *
1486  */
1487 OT_TOOL_PACKED_BEGIN
1488 class ChannelMaskTlv : public ChannelMaskBaseTlv
1489 {
1490 public:
1491     /**
1492      * This method initializes the TLV.
1493      *
1494      */
Init(void)1495     void Init(void)
1496     {
1497         SetType(kChannelMask);
1498         SetLength(sizeof(*this) - sizeof(Tlv));
1499         memset(mEntries, 0, sizeof(mEntries));
1500     }
1501 
1502     /**
1503      * This method sets the Channel Mask Entries.
1504      *
1505      * @param[in]  aChannelMask  The Channel Mask value.
1506      *
1507      */
1508     void SetChannelMask(uint32_t aChannelMask);
1509 
1510     /**
1511      * This method returns the Channel Mask value as a `uint32_t` bit mask.
1512      *
1513      * @returns The Channel Mask or 0 if not found.
1514      *
1515      */
1516     uint32_t GetChannelMask(void) const;
1517 
1518     /**
1519      * This method reads message and returns the Channel Mask value as a `uint32_t` bit mask.
1520      *
1521      * @param[in]   aMessage     A reference to the message.
1522      *
1523      * @returns The Channel Mask or 0 if not found.
1524      *
1525      */
1526     static uint32_t GetChannelMask(const Message &aMessage);
1527 
1528 private:
1529     static constexpr uint8_t kNumMaskEntries = Radio::kNumChannelPages;
1530 
1531     ChannelMaskEntry mEntries[kNumMaskEntries];
1532 } OT_TOOL_PACKED_END;
1533 
1534 /**
1535  * This class implements Energy List TLV generation and parsing.
1536  *
1537  */
1538 OT_TOOL_PACKED_BEGIN
1539 class EnergyListTlv : public Tlv, public TlvInfo<Tlv::kEnergyList>
1540 {
1541 public:
1542     /**
1543      * This method initializes the TLV.
1544      *
1545      */
Init(void)1546     void Init(void)
1547     {
1548         SetType(kEnergyList);
1549         SetLength(sizeof(*this) - sizeof(Tlv));
1550     }
1551 
1552     /**
1553      * This method indicates whether or not the TLV appears to be well-formed.
1554      *
1555      * @retval TRUE   If the TLV appears to be well-formed.
1556      * @retval FALSE  If the TLV does not appear to be well-formed.
1557      *
1558      */
IsValid(void) const1559     bool IsValid(void) const { return true; }
1560 } OT_TOOL_PACKED_END;
1561 
1562 /**
1563  * This class implements Provisioning URL TLV generation and parsing.
1564  *
1565  */
1566 OT_TOOL_PACKED_BEGIN
1567 class ProvisioningUrlTlv : public Tlv, public TlvInfo<Tlv::kProvisioningUrl>
1568 {
1569 public:
1570     /**
1571      * Maximum number of chars in the Provisioning URL string.
1572      *
1573      */
1574     static constexpr uint16_t kMaxLength = OT_PROVISIONING_URL_MAX_SIZE;
1575 
1576     /**
1577      * This method initializes the TLV.
1578      *
1579      */
Init(void)1580     void Init(void)
1581     {
1582         SetType(kProvisioningUrl);
1583         SetLength(0);
1584     }
1585 
1586     /*
1587      * This method returns the Provisioning URL length.
1588      *
1589      * @returns The Provisioning URL length.
1590      *
1591      */
GetProvisioningUrlLength(void) const1592     uint8_t GetProvisioningUrlLength(void) const
1593     {
1594         return GetLength() <= sizeof(mProvisioningUrl) ? GetLength() : sizeof(mProvisioningUrl);
1595     }
1596 
1597     /**
1598      * This method indicates whether or not the TLV appears to be well-formed.
1599      *
1600      * @retval TRUE   If the TLV appears to be well-formed.
1601      * @retval FALSE  If the TLV does not appear to be well-formed.
1602      *
1603      */
IsValid(void) const1604     bool IsValid(void) const
1605     {
1606         return GetType() == kProvisioningUrl && mProvisioningUrl[GetProvisioningUrlLength()] == '\0';
1607     }
1608 
1609     /**
1610      * This method returns the Provisioning URL value.
1611      *
1612      * @returns The Provisioning URL value.
1613      *
1614      */
GetProvisioningUrl(void) const1615     const char *GetProvisioningUrl(void) const { return mProvisioningUrl; }
1616 
1617     /**
1618      * This method sets the Provisioning URL value.
1619      *
1620      * @param[in]  aProvisioningUrl  A pointer to the Provisioning URL value.
1621      *
1622      */
SetProvisioningUrl(const char * aProvisioningUrl)1623     void SetProvisioningUrl(const char *aProvisioningUrl)
1624     {
1625         uint16_t len = aProvisioningUrl ? StringLength(aProvisioningUrl, kMaxLength) : 0;
1626 
1627         SetLength(static_cast<uint8_t>(len));
1628 
1629         if (len > 0)
1630         {
1631             memcpy(mProvisioningUrl, aProvisioningUrl, len);
1632         }
1633     }
1634 
1635 private:
1636     char mProvisioningUrl[kMaxLength];
1637 } OT_TOOL_PACKED_END;
1638 
1639 /**
1640  * This class implements Vendor Name TLV generation and parsing.
1641  *
1642  */
1643 OT_TOOL_PACKED_BEGIN
1644 class VendorNameTlv : public Tlv, public TlvInfo<Tlv::kVendorName>
1645 {
1646 public:
1647     /**
1648      * This method initializes the TLV.
1649      *
1650      */
Init(void)1651     void Init(void)
1652     {
1653         SetType(kVendorName);
1654         SetLength(0);
1655     }
1656 
1657     /**
1658      * This method returns the Vendor Name length.
1659      *
1660      * @returns The Vendor Name length.
1661      *
1662      */
GetVendorNameLength(void) const1663     uint8_t GetVendorNameLength(void) const
1664     {
1665         return GetLength() <= sizeof(mVendorName) ? GetLength() : sizeof(mVendorName);
1666     }
1667 
1668     /**
1669      * This method returns the Vendor Name value.
1670      *
1671      * @returns The Vendor Name value.
1672      *
1673      */
GetVendorName(void) const1674     const char *GetVendorName(void) const { return mVendorName; }
1675 
1676     /**
1677      * This method sets the Vendor Name value.
1678      *
1679      * @param[in]  aVendorName  A pointer to the Vendor Name value.
1680      *
1681      */
SetVendorName(const char * aVendorName)1682     void SetVendorName(const char *aVendorName)
1683     {
1684         uint16_t len = (aVendorName == nullptr) ? 0 : StringLength(aVendorName, sizeof(mVendorName));
1685 
1686         SetLength(static_cast<uint8_t>(len));
1687 
1688         if (len > 0)
1689         {
1690             memcpy(mVendorName, aVendorName, len);
1691         }
1692     }
1693 
1694 private:
1695     static constexpr uint8_t kMaxLength = 32;
1696 
1697     char mVendorName[kMaxLength];
1698 } OT_TOOL_PACKED_END;
1699 
1700 /**
1701  * This class implements Vendor Model TLV generation and parsing.
1702  *
1703  */
1704 OT_TOOL_PACKED_BEGIN
1705 class VendorModelTlv : public Tlv, public TlvInfo<Tlv::kVendorModel>
1706 {
1707 public:
1708     /**
1709      * This method initializes the TLV.
1710      *
1711      */
Init(void)1712     void Init(void)
1713     {
1714         SetType(kVendorModel);
1715         SetLength(0);
1716     }
1717 
1718     /**
1719      * This method returns the Vendor Model length.
1720      *
1721      * @returns The Vendor Model length.
1722      *
1723      */
GetVendorModelLength(void) const1724     uint8_t GetVendorModelLength(void) const
1725     {
1726         return GetLength() <= sizeof(mVendorModel) ? GetLength() : sizeof(mVendorModel);
1727     }
1728 
1729     /**
1730      * This method returns the Vendor Model value.
1731      *
1732      * @returns The Vendor Model value.
1733      *
1734      */
GetVendorModel(void) const1735     const char *GetVendorModel(void) const { return mVendorModel; }
1736 
1737     /**
1738      * This method sets the Vendor Model value.
1739      *
1740      * @param[in]  aVendorModel  A pointer to the Vendor Model value.
1741      *
1742      */
SetVendorModel(const char * aVendorModel)1743     void SetVendorModel(const char *aVendorModel)
1744     {
1745         uint16_t len = (aVendorModel == nullptr) ? 0 : StringLength(aVendorModel, sizeof(mVendorModel));
1746 
1747         SetLength(static_cast<uint8_t>(len));
1748 
1749         if (len > 0)
1750         {
1751             memcpy(mVendorModel, aVendorModel, len);
1752         }
1753     }
1754 
1755 private:
1756     static constexpr uint8_t kMaxLength = 32;
1757 
1758     char mVendorModel[kMaxLength];
1759 } OT_TOOL_PACKED_END;
1760 
1761 /**
1762  * This class implements Vendor SW Version TLV generation and parsing.
1763  *
1764  */
1765 OT_TOOL_PACKED_BEGIN
1766 class VendorSwVersionTlv : public Tlv, public TlvInfo<Tlv::kVendorSwVersion>
1767 {
1768 public:
1769     /**
1770      * This method initializes the TLV.
1771      *
1772      */
Init(void)1773     void Init(void)
1774     {
1775         SetType(kVendorSwVersion);
1776         SetLength(0);
1777     }
1778 
1779     /**
1780      * This method returns the Vendor SW Version length.
1781      *
1782      * @returns The Vendor SW Version length.
1783      *
1784      */
GetVendorSwVersionLength(void) const1785     uint8_t GetVendorSwVersionLength(void) const
1786     {
1787         return GetLength() <= sizeof(mVendorSwVersion) ? GetLength() : sizeof(mVendorSwVersion);
1788     }
1789 
1790     /**
1791      * This method returns the Vendor SW Version value.
1792      *
1793      * @returns The Vendor SW Version value.
1794      *
1795      */
GetVendorSwVersion(void) const1796     const char *GetVendorSwVersion(void) const { return mVendorSwVersion; }
1797 
1798     /**
1799      * This method sets the Vendor SW Version value.
1800      *
1801      * @param[in]  aVendorSwVersion  A pointer to the Vendor SW Version value.
1802      *
1803      */
SetVendorSwVersion(const char * aVendorSwVersion)1804     void SetVendorSwVersion(const char *aVendorSwVersion)
1805     {
1806         uint16_t len = (aVendorSwVersion == nullptr) ? 0 : StringLength(aVendorSwVersion, sizeof(mVendorSwVersion));
1807 
1808         SetLength(static_cast<uint8_t>(len));
1809 
1810         if (len > 0)
1811         {
1812             memcpy(mVendorSwVersion, aVendorSwVersion, len);
1813         }
1814     }
1815 
1816 private:
1817     static constexpr uint8_t kMaxLength = 16;
1818 
1819     char mVendorSwVersion[kMaxLength];
1820 } OT_TOOL_PACKED_END;
1821 
1822 /**
1823  * This class implements Vendor Data TLV generation and parsing.
1824  *
1825  */
1826 OT_TOOL_PACKED_BEGIN
1827 class VendorDataTlv : public Tlv, public TlvInfo<Tlv::kVendorData>
1828 {
1829 public:
1830     /**
1831      * This method initializes the TLV.
1832      *
1833      */
Init(void)1834     void Init(void)
1835     {
1836         SetType(kVendorData);
1837         SetLength(0);
1838     }
1839 
1840     /**
1841      * This method returns the Vendor Data length.
1842      *
1843      * @returns The Vendor Data length.
1844      *
1845      */
GetVendorDataLength(void) const1846     uint8_t GetVendorDataLength(void) const
1847     {
1848         return GetLength() <= sizeof(mVendorData) ? GetLength() : sizeof(mVendorData);
1849     }
1850 
1851     /**
1852      * This method returns the Vendor Data value.
1853      *
1854      * @returns The Vendor Data value.
1855      *
1856      */
GetVendorData(void) const1857     const char *GetVendorData(void) const { return mVendorData; }
1858 
1859     /**
1860      * This method sets the Vendor Data value.
1861      *
1862      * @param[in]  aVendorData  A pointer to the Vendor Data value.
1863      *
1864      */
SetVendorData(const char * aVendorData)1865     void SetVendorData(const char *aVendorData)
1866     {
1867         uint16_t len = (aVendorData == nullptr) ? 0 : StringLength(aVendorData, sizeof(mVendorData));
1868 
1869         SetLength(static_cast<uint8_t>(len));
1870 
1871         if (len > 0)
1872         {
1873             memcpy(mVendorData, aVendorData, len);
1874         }
1875     }
1876 
1877 private:
1878     static constexpr uint8_t kMaxLength = 64;
1879 
1880     char mVendorData[kMaxLength];
1881 } OT_TOOL_PACKED_END;
1882 
1883 /**
1884  * This class implements Vendor Stack Version TLV generation and parsing.
1885  *
1886  */
1887 OT_TOOL_PACKED_BEGIN
1888 class VendorStackVersionTlv : public Tlv, public TlvInfo<Tlv::kVendorStackVersion>
1889 {
1890 public:
1891     /**
1892      * Default constructor.
1893      *
1894      */
VendorStackVersionTlv(void)1895     VendorStackVersionTlv(void)
1896         : mBuildRevision(0)
1897         , mMinorMajor(0)
1898     {
1899     }
1900 
1901     /**
1902      * This method initializes the TLV.
1903      *
1904      */
Init(void)1905     void Init(void)
1906     {
1907         SetType(kVendorStackVersion);
1908         SetLength(sizeof(*this) - sizeof(Tlv));
1909     }
1910 
1911     /**
1912      * This method indicates whether or not the TLV appears to be well-formed.
1913      *
1914      * @retval TRUE   If the TLV appears to be well-formed.
1915      * @retval FALSE  If the TLV does not appear to be well-formed.
1916      *
1917      */
IsValid(void) const1918     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1919 
1920     /**
1921      * This method returns the Stack Vendor OUI value.
1922      *
1923      * @returns The Vendor Stack Vendor OUI value.
1924      *
1925      */
GetOui(void) const1926     uint32_t GetOui(void) const { return ReadUint24(mOui); }
1927 
1928     /**
1929      * This method returns the Stack Vendor OUI value.
1930      *
1931      * @param[in]  aOui  The Vendor Stack Vendor OUI value.
1932      *
1933      */
SetOui(uint32_t aOui)1934     void SetOui(uint32_t aOui) { WriteUint24(aOui, mOui); }
1935 
1936     /**
1937      * This method returns the Build value.
1938      *
1939      * @returns The Build value.
1940      *
1941      */
GetBuild(void) const1942     uint16_t GetBuild(void) const { return (HostSwap16(mBuildRevision) & kBuildMask) >> kBuildOffset; }
1943 
1944     /**
1945      * This method sets the Build value.
1946      *
1947      * @param[in]  aBuild  The Build value.
1948      *
1949      */
SetBuild(uint16_t aBuild)1950     void SetBuild(uint16_t aBuild)
1951     {
1952         mBuildRevision =
1953             HostSwap16((HostSwap16(mBuildRevision) & ~kBuildMask) | ((aBuild << kBuildOffset) & kBuildMask));
1954     }
1955 
1956     /**
1957      * This method returns the Revision value.
1958      *
1959      * @returns The Revision value.
1960      *
1961      */
GetRevision(void) const1962     uint8_t GetRevision(void) const { return (HostSwap16(mBuildRevision) & kRevMask) >> kRevOffset; }
1963 
1964     /**
1965      * This method sets the Revision value.
1966      *
1967      * @param[in]  aRevision  The Revision value.
1968      *
1969      */
SetRevision(uint8_t aRevision)1970     void SetRevision(uint8_t aRevision)
1971     {
1972         mBuildRevision = HostSwap16((HostSwap16(mBuildRevision) & ~kRevMask) | ((aRevision << kRevOffset) & kRevMask));
1973     }
1974 
1975     /**
1976      * This method returns the Minor value.
1977      *
1978      * @returns The Minor value.
1979      *
1980      */
GetMinor(void) const1981     uint8_t GetMinor(void) const { return (mMinorMajor & kMinorMask) >> kMinorOffset; }
1982 
1983     /**
1984      * This method sets the Minor value.
1985      *
1986      * @param[in]  aMinor  The Minor value.
1987      *
1988      */
SetMinor(uint8_t aMinor)1989     void SetMinor(uint8_t aMinor)
1990     {
1991         mMinorMajor = (mMinorMajor & ~kMinorMask) | ((aMinor << kMinorOffset) & kMinorMask);
1992     }
1993 
1994     /**
1995      * This method returns the Major value.
1996      *
1997      * @returns The Major value.
1998      *
1999      */
GetMajor(void) const2000     uint8_t GetMajor(void) const { return (mMinorMajor & kMajorMask) >> kMajorOffset; }
2001 
2002     /**
2003      * This method sets the Major value.
2004      *
2005      * @param[in] aMajor  The Major value.
2006      *
2007      */
SetMajor(uint8_t aMajor)2008     void SetMajor(uint8_t aMajor)
2009     {
2010         mMinorMajor = (mMinorMajor & ~kMajorMask) | ((aMajor << kMajorOffset) & kMajorMask);
2011     }
2012 
2013 private:
2014     // For `mBuildRevision`
2015     static constexpr uint8_t  kBuildOffset = 4;
2016     static constexpr uint16_t kBuildMask   = 0xfff << kBuildOffset;
2017     static constexpr uint8_t  kRevOffset   = 0;
2018     static constexpr uint16_t kRevMask     = 0xf << kBuildOffset;
2019 
2020     // For `mMinorMajor`
2021     static constexpr uint8_t kMinorOffset = 4;
2022     static constexpr uint8_t kMinorMask   = 0xf << kMinorOffset;
2023     static constexpr uint8_t kMajorOffset = 0;
2024     static constexpr uint8_t kMajorMask   = 0xf << kMajorOffset;
2025 
2026     uint8_t  mOui[3];
2027     uint16_t mBuildRevision;
2028     uint8_t  mMinorMajor;
2029 } OT_TOOL_PACKED_END;
2030 
2031 /**
2032  * This class implements UDP Encapsulation TLV generation and parsing.
2033  *
2034  */
2035 OT_TOOL_PACKED_BEGIN
2036 class UdpEncapsulationTlv : public ExtendedTlv, public TlvInfo<MeshCoP::Tlv::kUdpEncapsulation>
2037 {
2038 public:
2039     /**
2040      * This method initializes the TLV.
2041      *
2042      */
Init(void)2043     void Init(void)
2044     {
2045         SetType(MeshCoP::Tlv::kUdpEncapsulation);
2046         SetLength(sizeof(*this) - sizeof(ExtendedTlv));
2047     }
2048 
2049     /**
2050      * This method indicates whether or not the TLV appears to be well-formed.
2051      *
2052      * @retval TRUE   If the TLV appears to be well-formed.
2053      * @retval FALSE  If the TLV does not appear to be well-formed.
2054      *
2055      */
IsValid(void) const2056     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(ExtendedTlv); }
2057 
2058     /**
2059      * This method returns the source port.
2060      *
2061      * @returns The source port.
2062      *
2063      */
GetSourcePort(void) const2064     uint16_t GetSourcePort(void) const { return HostSwap16(mSourcePort); }
2065 
2066     /**
2067      * This method updates the source port.
2068      *
2069      * @param[in]   aSourcePort     The source port.
2070      *
2071      */
SetSourcePort(uint16_t aSourcePort)2072     void SetSourcePort(uint16_t aSourcePort) { mSourcePort = HostSwap16(aSourcePort); }
2073 
2074     /**
2075      * This method returns the destination port.
2076      *
2077      * @returns The destination port.
2078      *
2079      */
GetDestinationPort(void) const2080     uint16_t GetDestinationPort(void) const { return HostSwap16(mDestinationPort); }
2081 
2082     /**
2083      * This method updates the destination port.
2084      *
2085      * @param[in]   aDestinationPort    The destination port.
2086      *
2087      */
SetDestinationPort(uint16_t aDestinationPort)2088     void SetDestinationPort(uint16_t aDestinationPort) { mDestinationPort = HostSwap16(aDestinationPort); }
2089 
2090     /**
2091      * This method returns the calculated UDP length.
2092      *
2093      * @returns The calculated UDP length.
2094      *
2095      */
GetUdpLength(void) const2096     uint16_t GetUdpLength(void) const { return GetLength() - sizeof(mSourcePort) - sizeof(mDestinationPort); }
2097 
2098     /**
2099      * This method updates the UDP length.
2100      *
2101      * @param[in]   aLength     The length of UDP payload in bytes.
2102      *
2103      */
SetUdpLength(uint16_t aLength)2104     void SetUdpLength(uint16_t aLength) { SetLength(sizeof(mSourcePort) + sizeof(mDestinationPort) + aLength); }
2105 
2106 private:
2107     uint16_t mSourcePort;
2108     uint16_t mDestinationPort;
2109 } OT_TOOL_PACKED_END;
2110 
2111 /**
2112  * This class implements Discovery Request TLV generation and parsing.
2113  *
2114  */
2115 OT_TOOL_PACKED_BEGIN
2116 class DiscoveryRequestTlv : public Tlv, public TlvInfo<Tlv::kDiscoveryRequest>
2117 {
2118 public:
2119     /**
2120      * This method initializes the TLV.
2121      *
2122      */
Init(void)2123     void Init(void)
2124     {
2125         SetType(kDiscoveryRequest);
2126         SetLength(sizeof(*this) - sizeof(Tlv));
2127         mFlags    = 0;
2128         mReserved = 0;
2129     }
2130 
2131     /**
2132      * This method indicates whether or not the TLV appears to be well-formed.
2133      *
2134      * @retval TRUE   If the TLV appears to be well-formed.
2135      * @retval FALSE  If the TLV does not appear to be well-formed.
2136      *
2137      */
IsValid(void) const2138     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
2139 
2140     /**
2141      * This method returns the Version value.
2142      *
2143      * @returns The Version value.
2144      *
2145      */
GetVersion(void) const2146     uint8_t GetVersion(void) const { return mFlags >> kVersionOffset; }
2147 
2148     /**
2149      * This method sets the Version value.
2150      *
2151      * @param[in]  aVersion  The Version value.
2152      *
2153      */
SetVersion(uint8_t aVersion)2154     void SetVersion(uint8_t aVersion)
2155     {
2156         mFlags = (mFlags & ~kVersionMask) | ((aVersion << kVersionOffset) & kVersionMask);
2157     }
2158 
2159     /**
2160      * This method indicates whether or not the Joiner flag is set.
2161      *
2162      * @retval TRUE   If the Joiner flag is set.
2163      * @retval FALSE  If the Joiner flag is not set.
2164      *
2165      */
IsJoiner(void) const2166     bool IsJoiner(void) const { return (mFlags & kJoinerMask) != 0; }
2167 
2168     /**
2169      * This method sets the Joiner flag.
2170      *
2171      * @param[in]  aJoiner  TRUE if set, FALSE otherwise.
2172      *
2173      */
SetJoiner(bool aJoiner)2174     void SetJoiner(bool aJoiner)
2175     {
2176         if (aJoiner)
2177         {
2178             mFlags |= kJoinerMask;
2179         }
2180         else
2181         {
2182             mFlags &= ~kJoinerMask;
2183         }
2184     }
2185 
2186 private:
2187     static constexpr uint8_t kVersionOffset = 4;
2188     static constexpr uint8_t kVersionMask   = 0xf << kVersionOffset;
2189     static constexpr uint8_t kJoinerOffset  = 3;
2190     static constexpr uint8_t kJoinerMask    = 1 << kJoinerOffset;
2191 
2192     uint8_t mFlags;
2193     uint8_t mReserved;
2194 } OT_TOOL_PACKED_END;
2195 
2196 /**
2197  * This class implements Discovery Response TLV generation and parsing.
2198  *
2199  */
2200 OT_TOOL_PACKED_BEGIN
2201 class DiscoveryResponseTlv : public Tlv, public TlvInfo<Tlv::kDiscoveryResponse>
2202 {
2203 public:
2204     /**
2205      * This method initializes the TLV.
2206      *
2207      */
Init(void)2208     void Init(void)
2209     {
2210         SetType(kDiscoveryResponse);
2211         SetLength(sizeof(*this) - sizeof(Tlv));
2212         mFlags    = 0;
2213         mReserved = 0;
2214     }
2215 
2216     /**
2217      * This method indicates whether or not the TLV appears to be well-formed.
2218      *
2219      * @retval TRUE   If the TLV appears to be well-formed.
2220      * @retval FALSE  If the TLV does not appear to be well-formed.
2221      *
2222      */
IsValid(void) const2223     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
2224 
2225     /**
2226      * This method returns the Version value.
2227      *
2228      * @returns The Version value.
2229      *
2230      */
GetVersion(void) const2231     uint8_t GetVersion(void) const { return mFlags >> kVersionOffset; }
2232 
2233     /**
2234      * This method sets the Version value.
2235      *
2236      * @param[in]  aVersion  The Version value.
2237      *
2238      */
SetVersion(uint8_t aVersion)2239     void SetVersion(uint8_t aVersion)
2240     {
2241         mFlags = (mFlags & ~kVersionMask) | ((aVersion << kVersionOffset) & kVersionMask);
2242     }
2243 
2244     /**
2245      * This method indicates whether or not the Native Commissioner flag is set.
2246      *
2247      * @retval TRUE   If the Native Commissioner flag is set.
2248      * @retval FALSE  If the Native Commissioner flag is not set.
2249      *
2250      */
IsNativeCommissioner(void) const2251     bool IsNativeCommissioner(void) const { return (mFlags & kNativeMask) != 0; }
2252 
2253     /**
2254      * This method sets the Native Commissioner flag.
2255      *
2256      * @param[in]  aNativeCommissioner  TRUE if set, FALSE otherwise.
2257      *
2258      */
SetNativeCommissioner(bool aNativeCommissioner)2259     void SetNativeCommissioner(bool aNativeCommissioner)
2260     {
2261         if (aNativeCommissioner)
2262         {
2263             mFlags |= kNativeMask;
2264         }
2265         else
2266         {
2267             mFlags &= ~kNativeMask;
2268         }
2269     }
2270 
2271     /**
2272      * This method indicates whether or not the Commercial Commissioning Mode flag is set.
2273      *
2274      * @retval TRUE   If the Commercial Commissioning Mode flag is set.
2275      * @retval FALSE  If the Commercial Commissioning Mode flag is not set.
2276      *
2277      */
IsCommercialCommissioningMode(void) const2278     bool IsCommercialCommissioningMode(void) const { return (mFlags & kCCMMask) != 0; }
2279 
2280     /**
2281      * This method sets the Commercial Commissioning Mode flag.
2282      *
2283      * @param[in]  aCCM  TRUE if set, FALSE otherwise.
2284      *
2285      */
SetCommercialCommissioningMode(bool aCCM)2286     void SetCommercialCommissioningMode(bool aCCM)
2287     {
2288         if (aCCM)
2289         {
2290             mFlags |= kCCMMask;
2291         }
2292         else
2293         {
2294             mFlags &= ~kCCMMask;
2295         }
2296     }
2297 
2298 private:
2299     static constexpr uint8_t kVersionOffset = 4;
2300     static constexpr uint8_t kVersionMask   = 0xf << kVersionOffset;
2301     static constexpr uint8_t kNativeOffset  = 3;
2302     static constexpr uint8_t kNativeMask    = 1 << kNativeOffset;
2303     static constexpr uint8_t kCCMOffset     = 2;
2304     static constexpr uint8_t kCCMMask       = 1 << kCCMOffset;
2305 
2306     uint8_t mFlags;
2307     uint8_t mReserved;
2308 } OT_TOOL_PACKED_END;
2309 
2310 /**
2311  * This class implements Joiner Advertisement TLV generation and parsing.
2312  *
2313  */
2314 OT_TOOL_PACKED_BEGIN
2315 class JoinerAdvertisementTlv : public Tlv, public TlvInfo<Tlv::kJoinerAdvertisement>
2316 {
2317 public:
2318     static constexpr uint8_t kAdvDataMaxLength = OT_JOINER_ADVDATA_MAX_LENGTH; ///< The Max Length of AdvData
2319 
2320     /**
2321      * This method initializes the TLV.
2322      *
2323      */
Init(void)2324     void Init(void)
2325     {
2326         SetType(kJoinerAdvertisement);
2327         SetLength(sizeof(*this) - sizeof(Tlv));
2328     }
2329 
2330     /**
2331      * This method indicates whether or not the TLV appears to be well-formed.
2332      *
2333      * @retval TRUE   If the TLV appears to be well-formed.
2334      * @retval FALSE  If the TLV does not appear to be well-formed.
2335      *
2336      */
IsValid(void) const2337     bool IsValid(void) const { return GetLength() >= sizeof(mOui) && GetLength() <= sizeof(mOui) + sizeof(mAdvData); }
2338 
2339     /**
2340      * This method returns the Vendor OUI value.
2341      *
2342      * @returns The Vendor OUI value.
2343      *
2344      */
GetOui(void) const2345     uint32_t GetOui(void) const { return ReadUint24(mOui); }
2346 
2347     /**
2348      * This method sets the Vendor OUI value.
2349      *
2350      * @param[in]  aOui The Vendor OUI value.
2351      *
2352      */
SetOui(uint32_t aOui)2353     void SetOui(uint32_t aOui) { return WriteUint24(aOui, mOui); }
2354 
2355     /**
2356      * This method returns the Adv Data length.
2357      *
2358      * @returns The AdvData length.
2359      *
2360      */
GetAdvDataLength(void) const2361     uint8_t GetAdvDataLength(void) const { return GetLength() - sizeof(mOui); }
2362 
2363     /**
2364      * This method returns the Adv Data value.
2365      *
2366      * @returns A pointer to the Adv Data value.
2367      *
2368      */
GetAdvData(void) const2369     const uint8_t *GetAdvData(void) const { return mAdvData; }
2370 
2371     /**
2372      * This method sets the Adv Data value.
2373      *
2374      * @param[in]  aAdvData        A pointer to the AdvData value.
2375      * @param[in]  aAdvDataLength  The length of AdvData in bytes.
2376      *
2377      */
SetAdvData(const uint8_t * aAdvData,uint8_t aAdvDataLength)2378     void SetAdvData(const uint8_t *aAdvData, uint8_t aAdvDataLength)
2379     {
2380         OT_ASSERT((aAdvData != nullptr) && (aAdvDataLength > 0) && (aAdvDataLength <= kAdvDataMaxLength));
2381 
2382         SetLength(aAdvDataLength + sizeof(mOui));
2383         memcpy(mAdvData, aAdvData, aAdvDataLength);
2384     }
2385 
2386 private:
2387     uint8_t mOui[3];
2388     uint8_t mAdvData[kAdvDataMaxLength];
2389 } OT_TOOL_PACKED_END;
2390 
2391 } // namespace MeshCoP
2392 
2393 } // namespace ot
2394 
2395 #endif // MESHCOP_TLVS_HPP_
2396