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/num_utils.hpp"
48 #include "common/string.hpp"
49 #include "common/tlvs.hpp"
50 #include "mac/mac_types.hpp"
51 #include "meshcop/extended_panid.hpp"
52 #include "meshcop/network_name.hpp"
53 #include "meshcop/timestamp.hpp"
54 #include "net/ip6_address.hpp"
55 #include "radio/radio.hpp"
56 #include "thread/key_manager.hpp"
57 #include "thread/mle_types.hpp"
58 
59 namespace ot {
60 namespace MeshCoP {
61 
62 using ot::Encoding::BigEndian::HostSwap16;
63 using ot::Encoding::BigEndian::HostSwap32;
64 using ot::Encoding::BigEndian::ReadUint24;
65 using ot::Encoding::BigEndian::WriteUint24;
66 
67 /**
68  * Implements MeshCoP TLV generation and parsing.
69  *
70  */
71 OT_TOOL_PACKED_BEGIN
72 class Tlv : public ot::Tlv
73 {
74 public:
75     /**
76      * MeshCoP TLV Types.
77      *
78      */
79     enum Type : uint8_t
80     {
81         kChannel                 = OT_MESHCOP_TLV_CHANNEL,                  ///< Channel TLV
82         kPanId                   = OT_MESHCOP_TLV_PANID,                    ///< PAN ID TLV
83         kExtendedPanId           = OT_MESHCOP_TLV_EXTPANID,                 ///< Extended PAN ID TLV
84         kNetworkName             = OT_MESHCOP_TLV_NETWORKNAME,              ///< Network Name TLV
85         kPskc                    = OT_MESHCOP_TLV_PSKC,                     ///< PSKc TLV
86         kNetworkKey              = OT_MESHCOP_TLV_NETWORKKEY,               ///< Network Network Key TLV
87         kNetworkKeySequence      = OT_MESHCOP_TLV_NETWORK_KEY_SEQUENCE,     ///< Network Key Sequence TLV
88         kMeshLocalPrefix         = OT_MESHCOP_TLV_MESHLOCALPREFIX,          ///< Mesh Local Prefix TLV
89         kSteeringData            = OT_MESHCOP_TLV_STEERING_DATA,            ///< Steering Data TLV
90         kBorderAgentLocator      = OT_MESHCOP_TLV_BORDER_AGENT_RLOC,        ///< Border Agent Locator TLV
91         kCommissionerId          = OT_MESHCOP_TLV_COMMISSIONER_ID,          ///< Commissioner ID TLV
92         kCommissionerSessionId   = OT_MESHCOP_TLV_COMM_SESSION_ID,          ///< Commissioner Session ID TLV
93         kSecurityPolicy          = OT_MESHCOP_TLV_SECURITYPOLICY,           ///< Security Policy TLV
94         kGet                     = OT_MESHCOP_TLV_GET,                      ///< Get TLV
95         kActiveTimestamp         = OT_MESHCOP_TLV_ACTIVETIMESTAMP,          ///< Active Timestamp TLV
96         kCommissionerUdpPort     = OT_MESHCOP_TLV_COMMISSIONER_UDP_PORT,    ///< Commissioner UDP Port TLV
97         kState                   = OT_MESHCOP_TLV_STATE,                    ///< State TLV
98         kJoinerDtlsEncapsulation = OT_MESHCOP_TLV_JOINER_DTLS,              ///< Joiner DTLS Encapsulation TLV
99         kJoinerUdpPort           = OT_MESHCOP_TLV_JOINER_UDP_PORT,          ///< Joiner UDP Port TLV
100         kJoinerIid               = OT_MESHCOP_TLV_JOINER_IID,               ///< Joiner IID TLV
101         kJoinerRouterLocator     = OT_MESHCOP_TLV_JOINER_RLOC,              ///< Joiner Router Locator TLV
102         kJoinerRouterKek         = OT_MESHCOP_TLV_JOINER_ROUTER_KEK,        ///< Joiner Router KEK TLV
103         kProvisioningUrl         = OT_MESHCOP_TLV_PROVISIONING_URL,         ///< Provisioning URL TLV
104         kVendorName              = OT_MESHCOP_TLV_VENDOR_NAME_TLV,          ///< meshcop Vendor Name TLV
105         kVendorModel             = OT_MESHCOP_TLV_VENDOR_MODEL_TLV,         ///< meshcop Vendor Model TLV
106         kVendorSwVersion         = OT_MESHCOP_TLV_VENDOR_SW_VERSION_TLV,    ///< meshcop Vendor SW Version TLV
107         kVendorData              = OT_MESHCOP_TLV_VENDOR_DATA_TLV,          ///< meshcop Vendor Data TLV
108         kVendorStackVersion      = OT_MESHCOP_TLV_VENDOR_STACK_VERSION_TLV, ///< meshcop Vendor Stack Version TLV
109         kUdpEncapsulation        = OT_MESHCOP_TLV_UDP_ENCAPSULATION_TLV,    ///< meshcop UDP encapsulation TLV
110         kIp6Address              = OT_MESHCOP_TLV_IPV6_ADDRESS_TLV,         ///< meshcop IPv6 address TLV
111         kPendingTimestamp        = OT_MESHCOP_TLV_PENDINGTIMESTAMP,         ///< Pending Timestamp TLV
112         kDelayTimer              = OT_MESHCOP_TLV_DELAYTIMER,               ///< Delay Timer TLV
113         kChannelMask             = OT_MESHCOP_TLV_CHANNELMASK,              ///< Channel Mask TLV
114         kCount                   = OT_MESHCOP_TLV_COUNT,                    ///< Count TLV
115         kPeriod                  = OT_MESHCOP_TLV_PERIOD,                   ///< Period TLV
116         kScanDuration            = OT_MESHCOP_TLV_SCAN_DURATION,            ///< Scan Duration TLV
117         kEnergyList              = OT_MESHCOP_TLV_ENERGY_LIST,              ///< Energy List TLV
118         kDiscoveryRequest        = OT_MESHCOP_TLV_DISCOVERYREQUEST,         ///< Discovery Request TLV
119         kDiscoveryResponse       = OT_MESHCOP_TLV_DISCOVERYRESPONSE,        ///< Discovery Response TLV
120         kJoinerAdvertisement     = OT_MESHCOP_TLV_JOINERADVERTISEMENT,      ///< Joiner Advertisement TLV
121     };
122 
123     /**
124      * Max length of Provisioning URL TLV.
125      *
126      */
127     static constexpr uint8_t kMaxProvisioningUrlLength = OT_PROVISIONING_URL_MAX_SIZE;
128 
129     static constexpr uint8_t kMaxVendorNameLength      = 32; ///< Max length of Vendor Name TLV.
130     static constexpr uint8_t kMaxVendorModelLength     = 32; ///< Max length of Vendor Model TLV.
131     static constexpr uint8_t kMaxVendorSwVersionLength = 16; ///< Max length of Vendor SW Version TLV.
132     static constexpr uint8_t kMaxVendorDataLength      = 64; ///< Max length of Vendor Data TLV.
133 
134     /**
135      * Returns the Type value.
136      *
137      * @returns The Type value.
138      *
139      */
GetType(void) const140     Type GetType(void) const { return static_cast<Type>(ot::Tlv::GetType()); }
141 
142     /**
143      * Sets the Type value.
144      *
145      * @param[in]  aType  The Type value.
146      *
147      */
SetType(Type aType)148     void SetType(Type aType) { ot::Tlv::SetType(static_cast<uint8_t>(aType)); }
149 
150     /**
151      * Returns a pointer to the next TLV.
152      *
153      * @returns A pointer to the next TLV.
154      *
155      */
GetNext(void)156     Tlv *GetNext(void) { return As<Tlv>(ot::Tlv::GetNext()); }
157 
158     /**
159      * Returns a pointer to the next TLV.
160      *
161      * @returns A pointer to the next TLV.
162      *
163      */
GetNext(void) const164     const Tlv *GetNext(void) const { return As<Tlv>(ot::Tlv::GetNext()); }
165 
166     /**
167      * Reads the requested TLV out of @p aMessage.
168      *
169      * @param[in]   aMessage    A reference to the message.
170      * @param[in]   aType       The Type value to search for.
171      * @param[in]   aMaxLength  Maximum number of bytes to read.
172      * @param[out]  aTlv        A reference to the TLV that will be copied to.
173      *
174      * @retval kErrorNone      Successfully copied the TLV.
175      * @retval kErrorNotFound  Could not find the TLV with Type @p aType.
176      *
177      */
FindTlv(const Message & aMessage,Type aType,uint16_t aMaxLength,Tlv & aTlv)178     static Error FindTlv(const Message &aMessage, Type aType, uint16_t aMaxLength, Tlv &aTlv)
179     {
180         return ot::Tlv::FindTlv(aMessage, static_cast<uint8_t>(aType), aMaxLength, aTlv);
181     }
182 
183     /**
184      * Reads the requested TLV out of @p aMessage.
185      *
186      * Can be used independent of whether the read TLV (from message) is an Extended TLV or not.
187      *
188      * @tparam      TlvType     The TlvType to search for (must be a sub-class of `Tlv`).
189      *
190      * @param[in]   aMessage    A reference to the message.
191      * @param[out]  aTlv        A reference to the TLV that will be copied to.
192      *
193      * @retval kErrorNone      Successfully copied the TLV.
194      * @retval kErrorNotFound  Could not find the TLV with Type @p aType.
195      *
196      */
197 
FindTlv(const Message & aMessage,TlvType & aTlv)198     template <typename TlvType> static Error FindTlv(const Message &aMessage, TlvType &aTlv)
199     {
200         return ot::Tlv::FindTlv(aMessage, aTlv);
201     }
202 
203     /**
204      * Indicates whether a TLV appears to be well-formed.
205      *
206      * @param[in]  aTlv  A reference to the TLV.
207      *
208      * @returns TRUE if the TLV appears to be well-formed, FALSE otherwise.
209      *
210      */
211     static bool IsValid(const Tlv &aTlv);
212 
213     /**
214      * Searches in a given sequence of TLVs to find the first TLV with a given template Type.
215      *
216      * @param[in]  aTlvsStart  A pointer to the start of the sequence of TLVs to search within.
217      * @param[in]  aTlvsLength The length (number of bytes) in TLV sequence.
218      * @param[in]  aType       The TLV Type to search for.
219      *
220      * @returns A pointer to the TLV if found, or `nullptr` if not found.
221      *
222      */
FindTlv(uint8_t * aTlvsStart,uint16_t aTlvsLength,Type aType)223     static Tlv *FindTlv(uint8_t *aTlvsStart, uint16_t aTlvsLength, Type aType)
224     {
225         return AsNonConst(FindTlv(AsConst(aTlvsStart), aTlvsLength, aType));
226     }
227 
228     /**
229      * Searches in a given sequence of TLVs to find the first TLV with a given template Type.
230      *
231      * @param[in]  aTlvsStart  A pointer to the start of the sequence of TLVs to search within.
232      * @param[in]  aTlvsLength The length (number of bytes) in TLV sequence.
233      * @param[in]  aType       The TLV Type to search for.
234      *
235      * @returns A pointer to the TLV if found, or `nullptr` if not found.
236      *
237      */
238     static const Tlv *FindTlv(const uint8_t *aTlvsStart, uint16_t aTlvsLength, Type aType);
239 
240     /**
241      * This static template method searches in a given sequence of TLVs to find the first TLV with a give template
242      * `TlvType`.
243      *
244      * @param[in]  aTlvsStart  A pointer to the start of the sequence of TLVs to search within.
245      * @param[in]  aTlvsLength The length (number of bytes) in TLV sequence.
246      *
247      * @returns A pointer to the TLV if found, or `nullptr` if not found.
248      *
249      */
FindTlv(uint8_t * aTlvsStart,uint16_t aTlvsLength)250     template <typename TlvType> static TlvType *FindTlv(uint8_t *aTlvsStart, uint16_t aTlvsLength)
251     {
252         return As<TlvType>(FindTlv(aTlvsStart, aTlvsLength, static_cast<Tlv::Type>(TlvType::kType)));
253     }
254 
255     /**
256      * This static template method searches in a given sequence of TLVs to find the first TLV with a give template
257      * `TlvType`.
258      *
259      * @param[in]  aTlvsStart  A pointer to the start of the sequence of TLVs to search within.
260      * @param[in]  aTlvsLength The length (number of bytes) in TLV sequence.
261      *
262      * @returns A pointer to the TLV if found, or `nullptr` if not found.
263      *
264      */
FindTlv(const uint8_t * aTlvsStart,uint16_t aTlvsLength)265     template <typename TlvType> static const TlvType *FindTlv(const uint8_t *aTlvsStart, uint16_t aTlvsLength)
266     {
267         return As<TlvType>(FindTlv(aTlvsStart, aTlvsLength, static_cast<Tlv::Type>(TlvType::kType)));
268     }
269 
270 } OT_TOOL_PACKED_END;
271 
272 /**
273  * Implements extended MeshCoP TLV generation and parsing.
274  *
275  */
276 OT_TOOL_PACKED_BEGIN
277 class ExtendedTlv : public ot::ExtendedTlv
278 {
279 public:
280     /**
281      * Returns the Type value.
282      *
283      * @returns The Type value.
284      *
285      */
GetType(void) const286     MeshCoP::Tlv::Type GetType(void) const { return static_cast<MeshCoP::Tlv::Type>(ot::ExtendedTlv::GetType()); }
287 
288     /**
289      * Sets the Type value.
290      *
291      * @param[in]  aType  The Type value.
292      *
293      */
SetType(MeshCoP::Tlv::Type aType)294     void SetType(MeshCoP::Tlv::Type aType) { ot::ExtendedTlv::SetType(static_cast<uint8_t>(aType)); }
295 } OT_TOOL_PACKED_END;
296 
297 /**
298  * Defines Commissioner UDP Port TLV constants and types.
299  *
300  */
301 typedef UintTlvInfo<Tlv::kCommissionerUdpPort, uint16_t> CommissionerUdpPortTlv;
302 
303 /**
304  * Defines IPv6 Address TLV constants and types.
305  *
306  */
307 typedef SimpleTlvInfo<Tlv::kIp6Address, Ip6::Address> Ip6AddressTlv;
308 
309 /**
310  * Defines Joiner IID TLV constants and types.
311  *
312  */
313 typedef SimpleTlvInfo<Tlv::kJoinerIid, Ip6::InterfaceIdentifier> JoinerIidTlv;
314 
315 /**
316  * Defines Joiner Router Locator TLV constants and types.
317  *
318  */
319 typedef UintTlvInfo<Tlv::kJoinerRouterLocator, uint16_t> JoinerRouterLocatorTlv;
320 
321 /**
322  * Defines Joiner Router KEK TLV constants and types.
323  *
324  */
325 typedef SimpleTlvInfo<Tlv::kJoinerRouterKek, Kek> JoinerRouterKekTlv;
326 
327 /**
328  * Defines Count TLV constants and types.
329  *
330  */
331 typedef UintTlvInfo<Tlv::kCount, uint8_t> CountTlv;
332 
333 /**
334  * Defines Period TLV constants and types.
335  *
336  */
337 typedef UintTlvInfo<Tlv::kPeriod, uint16_t> PeriodTlv;
338 
339 /**
340  * Defines Scan Duration TLV constants and types.
341  *
342  */
343 typedef UintTlvInfo<Tlv::kScanDuration, uint16_t> ScanDurationTlv;
344 
345 /**
346  * Implements Channel TLV generation and parsing.
347  *
348  */
349 OT_TOOL_PACKED_BEGIN
350 class ChannelTlv : public Tlv, public TlvInfo<Tlv::kChannel>
351 {
352 public:
353     /**
354      * Initializes the TLV.
355      *
356      */
Init(void)357     void Init(void)
358     {
359         SetType(kChannel);
360         SetLength(sizeof(*this) - sizeof(Tlv));
361     }
362 
363     /**
364      * Indicates whether or not the TLV appears to be well-formed.
365      *
366      * @retval TRUE   If the TLV appears to be well-formed.
367      * @retval FALSE  If the TLV does not appear to be well-formed.
368      *
369      */
370     bool IsValid(void) const;
371 
372     /**
373      * Returns the ChannelPage value.
374      *
375      * @returns The ChannelPage value.
376      *
377      */
GetChannelPage(void) const378     uint8_t GetChannelPage(void) const { return mChannelPage; }
379 
380     /**
381      * Sets the ChannelPage value.
382      *
383      * @param[in]  aChannelPage  The ChannelPage value.
384      *
385      */
SetChannelPage(uint8_t aChannelPage)386     void SetChannelPage(uint8_t aChannelPage) { mChannelPage = aChannelPage; }
387 
388     /**
389      * Returns the Channel value.
390      *
391      * @returns The Channel value.
392      *
393      */
GetChannel(void) const394     uint16_t GetChannel(void) const { return HostSwap16(mChannel); }
395 
396     /**
397      * Sets the Channel value.
398      * Note: This method also sets the channel page according to the channel value.
399      *
400      * @param[in]  aChannel  The Channel value.
401      *
402      */
403     void SetChannel(uint16_t aChannel);
404 
405 private:
406     uint8_t  mChannelPage;
407     uint16_t mChannel;
408 } OT_TOOL_PACKED_END;
409 
410 /**
411  * Implements PAN ID TLV generation and parsing.
412  *
413  */
414 OT_TOOL_PACKED_BEGIN
415 class PanIdTlv : public Tlv, public UintTlvInfo<Tlv::kPanId, uint16_t>
416 {
417 public:
418     /**
419      * Initializes the TLV.
420      *
421      */
Init(void)422     void Init(void)
423     {
424         SetType(kPanId);
425         SetLength(sizeof(*this) - sizeof(Tlv));
426     }
427 
428     /**
429      * 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(*this) - sizeof(Tlv); }
436 
437     /**
438      * Returns the PAN ID value.
439      *
440      * @returns The PAN ID value.
441      *
442      */
GetPanId(void) const443     uint16_t GetPanId(void) const { return HostSwap16(mPanId); }
444 
445     /**
446      * Sets the PAN ID value.
447      *
448      * @param[in]  aPanId  The PAN ID value.
449      *
450      */
SetPanId(uint16_t aPanId)451     void SetPanId(uint16_t aPanId) { mPanId = HostSwap16(aPanId); }
452 
453 private:
454     uint16_t mPanId;
455 } OT_TOOL_PACKED_END;
456 
457 /**
458  * Implements Extended PAN ID TLV generation and parsing.
459  *
460  */
461 OT_TOOL_PACKED_BEGIN
462 class ExtendedPanIdTlv : public Tlv, public SimpleTlvInfo<Tlv::kExtendedPanId, ExtendedPanId>
463 {
464 public:
465     /**
466      * Initializes the TLV.
467      *
468      */
Init(void)469     void Init(void)
470     {
471         SetType(kExtendedPanId);
472         SetLength(sizeof(*this) - sizeof(Tlv));
473     }
474 
475     /**
476      * Indicates whether or not the TLV appears to be well-formed.
477      *
478      * @retval TRUE   If the TLV appears to be well-formed.
479      * @retval FALSE  If the TLV does not appear to be well-formed.
480      *
481      */
IsValid(void) const482     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
483 
484     /**
485      * Returns the Extended PAN ID value.
486      *
487      * @returns The Extended PAN ID value.
488      *
489      */
GetExtendedPanId(void) const490     const ExtendedPanId &GetExtendedPanId(void) const { return mExtendedPanId; }
491 
492     /**
493      * Sets the Extended PAN ID value.
494      *
495      * @param[in]  aExtendedPanId  An Extended PAN ID value.
496      *
497      */
SetExtendedPanId(const ExtendedPanId & aExtendedPanId)498     void SetExtendedPanId(const ExtendedPanId &aExtendedPanId) { mExtendedPanId = aExtendedPanId; }
499 
500 private:
501     ExtendedPanId mExtendedPanId;
502 } OT_TOOL_PACKED_END;
503 
504 /**
505  * Implements Network Name TLV generation and parsing.
506  *
507  */
508 OT_TOOL_PACKED_BEGIN
509 class NetworkNameTlv : public Tlv, public TlvInfo<Tlv::kNetworkName>
510 {
511 public:
512     /**
513      * Initializes the TLV.
514      *
515      */
Init(void)516     void Init(void)
517     {
518         SetType(kNetworkName);
519         SetLength(sizeof(*this) - sizeof(Tlv));
520     }
521 
522     /**
523      * Indicates whether or not the TLV appears to be well-formed.
524      *
525      * @retval TRUE   If the TLV appears to be well-formed.
526      * @retval FALSE  If the TLV does not appear to be well-formed.
527      *
528      */
529     bool IsValid(void) const;
530 
531     /**
532      * Gets the Network Name value.
533      *
534      * @returns The Network Name value (as `NameData`).
535      *
536      */
537     NameData GetNetworkName(void) const;
538 
539     /**
540      * Sets the Network Name value.
541      *
542      * @param[in] aNameData   A Network Name value (as `NameData`).
543      *
544      */
545     void SetNetworkName(const NameData &aNameData);
546 
547 private:
548     char mNetworkName[NetworkName::kMaxSize];
549 } OT_TOOL_PACKED_END;
550 
551 /**
552  * Implements PSKc TLV generation and parsing.
553  *
554  */
555 OT_TOOL_PACKED_BEGIN
556 class PskcTlv : public Tlv, public SimpleTlvInfo<Tlv::kPskc, Pskc>
557 {
558 public:
559     /**
560      * Initializes the TLV.
561      *
562      */
Init(void)563     void Init(void)
564     {
565         SetType(kPskc);
566         SetLength(sizeof(*this) - sizeof(Tlv));
567     }
568 
569     /**
570      * Indicates whether or not the TLV appears to be well-formed.
571      *
572      * @retval TRUE   If the TLV appears to be well-formed.
573      * @retval FALSE  If the TLV does not appear to be well-formed.
574      *
575      */
IsValid(void) const576     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
577 
578     /**
579      * Returns the PSKc value.
580      *
581      * @returns The PSKc value.
582      *
583      */
GetPskc(void) const584     const Pskc &GetPskc(void) const { return mPskc; }
585 
586     /**
587      * Sets the PSKc value.
588      *
589      * @param[in]  aPskc  A pointer to the PSKc value.
590      *
591      */
SetPskc(const Pskc & aPskc)592     void SetPskc(const Pskc &aPskc) { mPskc = aPskc; }
593 
594 private:
595     Pskc mPskc;
596 } OT_TOOL_PACKED_END;
597 
598 /**
599  * Implements Network Network Key TLV generation and parsing.
600  *
601  */
602 OT_TOOL_PACKED_BEGIN
603 class NetworkKeyTlv : public Tlv, public SimpleTlvInfo<Tlv::kNetworkKey, NetworkKey>
604 {
605 public:
606     /**
607      * Initializes the TLV.
608      *
609      */
Init(void)610     void Init(void)
611     {
612         SetType(kNetworkKey);
613         SetLength(sizeof(*this) - sizeof(Tlv));
614     }
615 
616     /**
617      * Indicates whether or not the TLV appears to be well-formed.
618      *
619      * @retval TRUE   If the TLV appears to be well-formed.
620      * @retval FALSE  If the TLV does not appear to be well-formed.
621      *
622      */
IsValid(void) const623     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
624 
625     /**
626      * Returns the Network Network Key value.
627      *
628      * @returns The Network Network Key value.
629      *
630      */
GetNetworkKey(void) const631     const NetworkKey &GetNetworkKey(void) const { return mNetworkKey; }
632 
633     /**
634      * Sets the Network Network Key value.
635      *
636      * @param[in]  aNetworkKey  The Network Network Key.
637      *
638      */
SetNetworkKey(const NetworkKey & aNetworkKey)639     void SetNetworkKey(const NetworkKey &aNetworkKey) { mNetworkKey = aNetworkKey; }
640 
641 private:
642     NetworkKey mNetworkKey;
643 } OT_TOOL_PACKED_END;
644 
645 /**
646  * Implements Network Key Sequence TLV generation and parsing.
647  *
648  */
649 OT_TOOL_PACKED_BEGIN
650 class NetworkKeySequenceTlv : public Tlv, public UintTlvInfo<Tlv::kNetworkKeySequence, uint32_t>
651 {
652 public:
653     /**
654      * Initializes the TLV.
655      *
656      */
Init(void)657     void Init(void)
658     {
659         SetType(kNetworkKeySequence);
660         SetLength(sizeof(*this) - sizeof(Tlv));
661     }
662 
663     /**
664      * Indicates whether or not the TLV appears to be well-formed.
665      *
666      * @retval TRUE   If the TLV appears to be well-formed.
667      * @retval FALSE  If the TLV does not appear to be well-formed.
668      *
669      */
IsValid(void) const670     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
671 
672     /**
673      * Returns the Network Key Sequence value.
674      *
675      * @returns The Network Key Sequence value.
676      *
677      */
GetNetworkKeySequence(void) const678     uint32_t GetNetworkKeySequence(void) const { return HostSwap32(mNetworkKeySequence); }
679 
680     /**
681      * Sets the Network Key Sequence value.
682      *
683      * @param[in]  aNetworkKeySequence  The Network Key Sequence value.
684      *
685      */
SetNetworkKeySequence(uint32_t aNetworkKeySequence)686     void SetNetworkKeySequence(uint32_t aNetworkKeySequence) { mNetworkKeySequence = HostSwap32(aNetworkKeySequence); }
687 
688 private:
689     uint32_t mNetworkKeySequence;
690 } OT_TOOL_PACKED_END;
691 
692 /**
693  * Implements Mesh Local Prefix TLV generation and parsing.
694  *
695  */
696 OT_TOOL_PACKED_BEGIN
697 class MeshLocalPrefixTlv : public Tlv, public SimpleTlvInfo<Tlv::kMeshLocalPrefix, Ip6::NetworkPrefix>
698 {
699 public:
700     /**
701      * Initializes the TLV.
702      *
703      */
Init(void)704     void Init(void)
705     {
706         SetType(kMeshLocalPrefix);
707         SetLength(sizeof(*this) - sizeof(Tlv));
708     }
709 
710     /**
711      * Indicates whether or not the TLV appears to be well-formed.
712      *
713      * @retval TRUE   If the TLV appears to be well-formed.
714      * @retval FALSE  If the TLV does not appear to be well-formed.
715      *
716      */
IsValid(void) const717     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
718 
719     /**
720      * Returns the size (in bytes) of the Mesh Local Prefix field.
721      *
722      * @returns The size (in bytes) of the Mesh Local Prefix field (8 bytes).
723      *
724      */
GetMeshLocalPrefixLength(void) const725     uint8_t GetMeshLocalPrefixLength(void) const { return sizeof(mMeshLocalPrefix); }
726 
727     /**
728      * Returns the Mesh Local Prefix value.
729      *
730      * @returns The Mesh Local Prefix value.
731      *
732      */
GetMeshLocalPrefix(void) const733     const Ip6::NetworkPrefix &GetMeshLocalPrefix(void) const { return mMeshLocalPrefix; }
734 
735     /**
736      * Sets the Mesh Local Prefix value.
737      *
738      * @param[in]  aMeshLocalPrefix  A pointer to the Mesh Local Prefix value.
739      *
740      */
SetMeshLocalPrefix(const Ip6::NetworkPrefix & aMeshLocalPrefix)741     void SetMeshLocalPrefix(const Ip6::NetworkPrefix &aMeshLocalPrefix) { mMeshLocalPrefix = aMeshLocalPrefix; }
742 
743 private:
744     Ip6::NetworkPrefix mMeshLocalPrefix;
745 } OT_TOOL_PACKED_END;
746 
747 class SteeringData;
748 
749 /**
750  * Implements Steering Data TLV generation and parsing.
751  *
752  */
753 OT_TOOL_PACKED_BEGIN
754 class SteeringDataTlv : public Tlv, public TlvInfo<Tlv::kSteeringData>
755 {
756 public:
757     /**
758      * Initializes the TLV.
759      *
760      */
Init(void)761     void Init(void)
762     {
763         SetType(kSteeringData);
764         SetLength(sizeof(*this) - sizeof(Tlv));
765         Clear();
766     }
767 
768     /**
769      * Indicates whether or not the TLV appears to be well-formed.
770      *
771      * @retval TRUE   If the TLV appears to be well-formed.
772      * @retval FALSE  If the TLV does not appear to be well-formed.
773      *
774      */
IsValid(void) const775     bool IsValid(void) const { return GetLength() > 0; }
776 
777     /**
778      * Returns the Steering Data length.
779      *
780      * @returns The Steering Data length.
781      *
782      */
GetSteeringDataLength(void) const783     uint8_t GetSteeringDataLength(void) const
784     {
785         return GetLength() <= sizeof(mSteeringData) ? GetLength() : sizeof(mSteeringData);
786     }
787 
788     /**
789      * Sets all bits in the Bloom Filter to zero.
790      *
791      */
Clear(void)792     void Clear(void) { memset(mSteeringData, 0, GetSteeringDataLength()); }
793 
794     /**
795      * Copies the Steering Data from the TLV into a given `SteeringData` variable.
796      *
797      * @param[out]  aSteeringData   A reference to a `SteeringData` to copy into.
798      *
799      */
800     void CopyTo(SteeringData &aSteeringData) const;
801 
802 private:
803     uint8_t mSteeringData[OT_STEERING_DATA_MAX_LENGTH];
804 } OT_TOOL_PACKED_END;
805 
806 /**
807  * Implements Border Agent Locator TLV generation and parsing.
808  *
809  */
810 OT_TOOL_PACKED_BEGIN
811 class BorderAgentLocatorTlv : public Tlv, public UintTlvInfo<Tlv::kBorderAgentLocator, uint16_t>
812 {
813 public:
814     /**
815      * Initializes the TLV.
816      *
817      */
Init(void)818     void Init(void)
819     {
820         SetType(kBorderAgentLocator);
821         SetLength(sizeof(*this) - sizeof(Tlv));
822     }
823 
824     /**
825      * Indicates whether or not the TLV appears to be well-formed.
826      *
827      * @retval TRUE   If the TLV appears to be well-formed.
828      * @retval FALSE  If the TLV does not appear to be well-formed.
829      *
830      */
IsValid(void) const831     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
832 
833     /**
834      * Returns the Border Agent Locator value.
835      *
836      * @returns The Border Agent Locator value.
837      *
838      */
GetBorderAgentLocator(void) const839     uint16_t GetBorderAgentLocator(void) const { return HostSwap16(mLocator); }
840 
841     /**
842      * Sets the Border Agent Locator value.
843      *
844      * @param[in]  aLocator  The Border Agent Locator value.
845      *
846      */
SetBorderAgentLocator(uint16_t aLocator)847     void SetBorderAgentLocator(uint16_t aLocator) { mLocator = HostSwap16(aLocator); }
848 
849 private:
850     uint16_t mLocator;
851 } OT_TOOL_PACKED_END;
852 
853 /**
854  * Implements the Commissioner ID TLV generation and parsing.
855  *
856  */
857 OT_TOOL_PACKED_BEGIN
858 class CommissionerIdTlv : public Tlv, public TlvInfo<Tlv::kCommissionerId>
859 {
860 public:
861     static constexpr uint8_t kMaxLength = 64; ///< maximum length (bytes)
862 
863     /**
864      * Initializes the TLV.
865      *
866      */
Init(void)867     void Init(void)
868     {
869         SetType(kCommissionerId);
870         SetLength(sizeof(*this) - sizeof(Tlv));
871     }
872 
873     /**
874      * Returns the Commissioner ID length.
875      *
876      * @returns The Commissioner ID length.
877      *
878      */
GetCommissionerIdLength(void) const879     uint8_t GetCommissionerIdLength(void) const
880     {
881         return GetLength() <= sizeof(mCommissionerId) ? GetLength() : sizeof(mCommissionerId);
882     }
883 
884     /**
885      * Returns the Commissioner ID value.
886      *
887      * @returns The Commissioner ID value.
888      *
889      */
GetCommissionerId(void) const890     const char *GetCommissionerId(void) const { return mCommissionerId; }
891 
892     /**
893      * Sets the Commissioner ID value.
894      *
895      * @param[in]  aCommissionerId  A pointer to the Commissioner ID value.
896      *
897      */
SetCommissionerId(const char * aCommissionerId)898     void SetCommissionerId(const char *aCommissionerId)
899     {
900         uint16_t length = StringLength(aCommissionerId, sizeof(mCommissionerId));
901         memcpy(mCommissionerId, aCommissionerId, length);
902         SetLength(static_cast<uint8_t>(length));
903     }
904 
905 private:
906     char mCommissionerId[kMaxLength];
907 } OT_TOOL_PACKED_END;
908 
909 /**
910  * Implements Commissioner Session ID TLV generation and parsing.
911  *
912  */
913 OT_TOOL_PACKED_BEGIN
914 class CommissionerSessionIdTlv : public Tlv, public UintTlvInfo<Tlv::kCommissionerSessionId, uint16_t>
915 {
916 public:
917     /**
918      * Initializes the TLV.
919      *
920      */
Init(void)921     void Init(void)
922     {
923         SetType(kCommissionerSessionId);
924         SetLength(sizeof(*this) - sizeof(Tlv));
925     }
926 
927     /**
928      * Indicates whether or not the TLV appears to be well-formed.
929      *
930      * @retval TRUE   If the TLV appears to be well-formed.
931      * @retval FALSE  If the TLV does not appear to be well-formed.
932      *
933      */
IsValid(void) const934     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
935 
936     /**
937      * Returns the Commissioner Session ID value.
938      *
939      * @returns The Commissioner Session ID value.
940      *
941      */
GetCommissionerSessionId(void) const942     uint16_t GetCommissionerSessionId(void) const { return HostSwap16(mSessionId); }
943 
944     /**
945      * Sets the Commissioner Session ID value.
946      *
947      * @param[in]  aSessionId  The Commissioner Session ID value.
948      *
949      */
SetCommissionerSessionId(uint16_t aSessionId)950     void SetCommissionerSessionId(uint16_t aSessionId) { mSessionId = HostSwap16(aSessionId); }
951 
952 private:
953     uint16_t mSessionId;
954 } OT_TOOL_PACKED_END;
955 
956 /**
957  * Implements Security Policy TLV generation and parsing.
958  *
959  */
960 OT_TOOL_PACKED_BEGIN
961 class SecurityPolicyTlv : public Tlv, public TlvInfo<Tlv::kSecurityPolicy>
962 {
963 public:
964     /**
965      * Initializes the TLV.
966      *
967      */
Init(void)968     void Init(void)
969     {
970         SetType(kSecurityPolicy);
971         SetLength(sizeof(*this) - sizeof(Tlv));
972     }
973 
974     /**
975      * Indicates whether or not the TLV appears to be well-formed.
976      *
977      * @retval TRUE   If the TLV appears to be well-formed.
978      * @retval FALSE  If the TLV does not appear to be well-formed.
979      *
980      */
981     bool IsValid(void) const;
982 
983     /**
984      * Returns the Security Policy.
985      *
986      * @returns  The Security Policy.
987      *
988      */
989     SecurityPolicy GetSecurityPolicy(void) const;
990 
991     /**
992      * Sets the Security Policy.
993      *
994      * @param[in]  aSecurityPolicy  The Security Policy which will be set.
995      *
996      */
997     void SetSecurityPolicy(const SecurityPolicy &aSecurityPolicy);
998 
999 private:
1000     static constexpr uint8_t kThread11FlagsLength = 1; // The Thread 1.1 Security Policy Flags length.
1001     static constexpr uint8_t kThread12FlagsLength = 2; // The Thread 1.2 Security Policy Flags length.
1002 
SetRotationTime(uint16_t aRotationTime)1003     void     SetRotationTime(uint16_t aRotationTime) { mRotationTime = HostSwap16(aRotationTime); }
GetRotationTime(void) const1004     uint16_t GetRotationTime(void) const { return HostSwap16(mRotationTime); }
GetFlagsLength(void) const1005     uint8_t  GetFlagsLength(void) const { return GetLength() - sizeof(mRotationTime); }
1006 
1007     uint16_t mRotationTime;
1008 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
1009     uint8_t mFlags[kThread12FlagsLength];
1010 #else
1011     uint8_t mFlags[kThread11FlagsLength];
1012 #endif
1013 } OT_TOOL_PACKED_END;
1014 
1015 /**
1016  * Implements Active Timestamp TLV generation and parsing.
1017  *
1018  */
1019 OT_TOOL_PACKED_BEGIN
1020 class ActiveTimestampTlv : public Tlv, public SimpleTlvInfo<Tlv::kActiveTimestamp, Timestamp>
1021 {
1022 public:
1023     /**
1024      * Initializes the TLV.
1025      *
1026      */
Init(void)1027     void Init(void)
1028     {
1029         SetType(kActiveTimestamp);
1030         SetLength(sizeof(*this) - sizeof(Tlv));
1031         mTimestamp.Clear();
1032     }
1033 
1034     /**
1035      * Indicates whether or not the TLV appears to be well-formed.
1036      *
1037      * @retval TRUE   If the TLV appears to be well-formed.
1038      * @retval FALSE  If the TLV does not appear to be well-formed.
1039      *
1040      */
IsValid(void) const1041     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1042 
1043     /**
1044      * Gets the timestamp.
1045      *
1046      * @returns The timestamp.
1047      *
1048      */
GetTimestamp(void) const1049     const Timestamp &GetTimestamp(void) const { return mTimestamp; }
1050 
1051     /**
1052      * Returns a reference to the timestamp.
1053      *
1054      * @returns A reference to the timestamp.
1055      *
1056      */
GetTimestamp(void)1057     Timestamp &GetTimestamp(void) { return mTimestamp; }
1058 
1059     /**
1060      * Sets the timestamp.
1061      *
1062      * @param[in] aTimestamp   The new timestamp.
1063      *
1064      */
SetTimestamp(const Timestamp & aTimestamp)1065     void SetTimestamp(const Timestamp &aTimestamp) { mTimestamp = aTimestamp; }
1066 
1067 private:
1068     Timestamp mTimestamp;
1069 } OT_TOOL_PACKED_END;
1070 
1071 /**
1072  * Implements State TLV generation and parsing.
1073  *
1074  */
1075 class StateTlv : public UintTlvInfo<Tlv::kState, uint8_t>
1076 {
1077 public:
1078     StateTlv(void) = delete;
1079 
1080     /**
1081      * State values.
1082      *
1083      */
1084     enum State : uint8_t
1085     {
1086         kReject  = 0xff, ///< Reject (-1)
1087         kPending = 0,    ///< Pending
1088         kAccept  = 1,    ///< Accept
1089     };
1090 
1091     /**
1092      * Converts a `State` to a string.
1093      *
1094      * @param[in] aState  An item state.
1095      *
1096      * @returns A string representation of @p aState.
1097      *
1098      */
1099     static const char *StateToString(State aState);
1100 };
1101 
1102 /**
1103  * Implements Joiner UDP Port TLV generation and parsing.
1104  *
1105  */
1106 OT_TOOL_PACKED_BEGIN
1107 class JoinerUdpPortTlv : public Tlv, public UintTlvInfo<Tlv::kJoinerUdpPort, uint16_t>
1108 {
1109 public:
1110     /**
1111      * Initializes the TLV.
1112      *
1113      */
Init(void)1114     void Init(void)
1115     {
1116         SetType(kJoinerUdpPort);
1117         SetLength(sizeof(*this) - sizeof(Tlv));
1118     }
1119 
1120     /**
1121      * Indicates whether or not the TLV appears to be well-formed.
1122      *
1123      * @retval TRUE   If the TLV appears to be well-formed.
1124      * @retval FALSE  If the TLV does not appear to be well-formed.
1125      *
1126      */
IsValid(void) const1127     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1128 
1129     /**
1130      * Returns the UDP Port value.
1131      *
1132      * @returns The UDP Port value.
1133      *
1134      */
GetUdpPort(void) const1135     uint16_t GetUdpPort(void) const { return HostSwap16(mUdpPort); }
1136 
1137     /**
1138      * Sets the UDP Port value.
1139      *
1140      * @param[in]  aUdpPort  The UDP Port value.
1141      *
1142      */
SetUdpPort(uint16_t aUdpPort)1143     void SetUdpPort(uint16_t aUdpPort) { mUdpPort = HostSwap16(aUdpPort); }
1144 
1145 private:
1146     uint16_t mUdpPort;
1147 } OT_TOOL_PACKED_END;
1148 
1149 /**
1150  * Implements Pending Timestamp TLV generation and parsing.
1151  *
1152  */
1153 OT_TOOL_PACKED_BEGIN
1154 class PendingTimestampTlv : public Tlv, public SimpleTlvInfo<Tlv::kPendingTimestamp, Timestamp>
1155 {
1156 public:
1157     /**
1158      * Initializes the TLV.
1159      *
1160      */
Init(void)1161     void Init(void)
1162     {
1163         SetType(kPendingTimestamp);
1164         SetLength(sizeof(*this) - sizeof(Tlv));
1165         mTimestamp.Clear();
1166     }
1167 
1168     /**
1169      * Indicates whether or not the TLV appears to be well-formed.
1170      *
1171      * @retval TRUE   If the TLV appears to be well-formed.
1172      * @retval FALSE  If the TLV does not appear to be well-formed.
1173      *
1174      */
IsValid(void) const1175     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1176 
1177     /**
1178      * Gets the timestamp.
1179      *
1180      * @returns The timestamp.
1181      *
1182      */
GetTimestamp(void) const1183     const Timestamp &GetTimestamp(void) const { return mTimestamp; }
1184 
1185     /**
1186      * Returns a reference to the timestamp.
1187      *
1188      * @returns A reference to the timestamp.
1189      *
1190      */
GetTimestamp(void)1191     Timestamp &GetTimestamp(void) { return mTimestamp; }
1192 
1193     /**
1194      * Sets the timestamp.
1195      *
1196      * @param[in] aTimestamp   The new timestamp.
1197      *
1198      */
SetTimestamp(const Timestamp & aTimestamp)1199     void SetTimestamp(const Timestamp &aTimestamp) { mTimestamp = aTimestamp; }
1200 
1201 private:
1202     Timestamp mTimestamp;
1203 } OT_TOOL_PACKED_END;
1204 
1205 /**
1206  * Implements Delay Timer TLV generation and parsing.
1207  *
1208  */
1209 OT_TOOL_PACKED_BEGIN
1210 class DelayTimerTlv : public Tlv, public UintTlvInfo<Tlv::kDelayTimer, uint32_t>
1211 {
1212 public:
1213     /**
1214      * Initializes the TLV.
1215      *
1216      */
Init(void)1217     void Init(void)
1218     {
1219         SetType(kDelayTimer);
1220         SetLength(sizeof(*this) - sizeof(Tlv));
1221     }
1222 
1223     /**
1224      * Indicates whether or not the TLV appears to be well-formed.
1225      *
1226      * @retval TRUE   If the TLV appears to be well-formed.
1227      * @retval FALSE  If the TLV does not appear to be well-formed.
1228      *
1229      */
IsValid(void) const1230     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1231 
1232     /**
1233      * Returns the Delay Timer value.
1234      *
1235      * @returns The Delay Timer value.
1236      *
1237      */
GetDelayTimer(void) const1238     uint32_t GetDelayTimer(void) const { return HostSwap32(mDelayTimer); }
1239 
1240     /**
1241      * Sets the Delay Timer value.
1242      *
1243      * @param[in]  aDelayTimer  The Delay Timer value.
1244      *
1245      */
SetDelayTimer(uint32_t aDelayTimer)1246     void SetDelayTimer(uint32_t aDelayTimer) { mDelayTimer = HostSwap32(aDelayTimer); }
1247 
1248     static constexpr uint32_t kMaxDelayTimer = 259200; ///< Maximum delay timer value for a Pending Dataset in seconds
1249 
1250     /**
1251      * Minimum Delay Timer value for a Pending Operational Dataset (ms)
1252      *
1253      */
1254     static constexpr uint32_t kDelayTimerMinimal = OPENTHREAD_CONFIG_TMF_PENDING_DATASET_MINIMUM_DELAY;
1255 
1256     /**
1257      * Default Delay Timer value for a Pending Operational Dataset (ms)
1258      *
1259      */
1260     static constexpr uint32_t kDelayTimerDefault = OPENTHREAD_CONFIG_TMF_PENDING_DATASET_DEFAULT_DELAY;
1261 
1262 private:
1263     uint32_t mDelayTimer;
1264 } OT_TOOL_PACKED_END;
1265 
1266 // forward declare ChannelMaskTlv
1267 class ChannelMaskTlv;
1268 
1269 /**
1270  * Implements Channel Mask Entry generation and parsing.
1271  *
1272  */
1273 OT_TOOL_PACKED_BEGIN
1274 class ChannelMaskEntryBase
1275 {
1276 public:
1277     /**
1278      * Gets the ChannelPage value.
1279      *
1280      * @returns The ChannelPage value.
1281      *
1282      */
GetChannelPage(void) const1283     uint8_t GetChannelPage(void) const { return mChannelPage; }
1284 
1285     /**
1286      * Sets the ChannelPage value.
1287      *
1288      * @param[in]  aChannelPage  The ChannelPage value.
1289      *
1290      */
SetChannelPage(uint8_t aChannelPage)1291     void SetChannelPage(uint8_t aChannelPage) { mChannelPage = aChannelPage; }
1292 
1293     /**
1294      * Gets the MaskLength value.
1295      *
1296      * @returns The MaskLength value.
1297      *
1298      */
GetMaskLength(void) const1299     uint8_t GetMaskLength(void) const { return mMaskLength; }
1300 
1301     /**
1302      * Sets the MaskLength value.
1303      *
1304      * @param[in]  aMaskLength  The MaskLength value.
1305      *
1306      */
SetMaskLength(uint8_t aMaskLength)1307     void SetMaskLength(uint8_t aMaskLength) { mMaskLength = aMaskLength; }
1308 
1309     /**
1310      * Returns the total size of this Channel Mask Entry including the mask.
1311      *
1312      * @returns The total size of this entry (number of bytes).
1313      *
1314      */
GetEntrySize(void) const1315     uint16_t GetEntrySize(void) const { return sizeof(ChannelMaskEntryBase) + mMaskLength; }
1316 
1317     /**
1318      * Clears the bit corresponding to @p aChannel in ChannelMask.
1319      *
1320      * @param[in]  aChannel  The channel in ChannelMask to clear.
1321      *
1322      */
ClearChannel(uint8_t aChannel)1323     void ClearChannel(uint8_t aChannel)
1324     {
1325         uint8_t *mask = reinterpret_cast<uint8_t *>(this) + sizeof(*this);
1326         mask[aChannel / 8] &= ~(0x80 >> (aChannel % 8));
1327     }
1328 
1329     /**
1330      * Sets the bit corresponding to @p aChannel in ChannelMask.
1331      *
1332      * @param[in]  aChannel  The channel in ChannelMask to set.
1333      *
1334      */
SetChannel(uint8_t aChannel)1335     void SetChannel(uint8_t aChannel)
1336     {
1337         uint8_t *mask = reinterpret_cast<uint8_t *>(this) + sizeof(*this);
1338         mask[aChannel / 8] |= 0x80 >> (aChannel % 8);
1339     }
1340 
1341     /**
1342      * Indicates whether or not the bit corresponding to @p aChannel in ChannelMask is set.
1343      *
1344      * @param[in]  aChannel  The channel in ChannelMask to get.
1345      *
1346      */
IsChannelSet(uint8_t aChannel) const1347     bool IsChannelSet(uint8_t aChannel) const
1348     {
1349         const uint8_t *mask = reinterpret_cast<const uint8_t *>(this) + sizeof(*this);
1350         return (aChannel < (mMaskLength * 8)) ? ((mask[aChannel / 8] & (0x80 >> (aChannel % 8))) != 0) : false;
1351     }
1352 
1353     /**
1354      * Gets the next Channel Mask Entry in a Channel Mask TLV.
1355      *
1356      * @returns A pointer to next Channel Mask Entry.
1357      *
1358      */
GetNext(void) const1359     const ChannelMaskEntryBase *GetNext(void) const
1360     {
1361         return reinterpret_cast<const ChannelMaskEntryBase *>(reinterpret_cast<const uint8_t *>(this) + GetEntrySize());
1362     }
1363 
1364     /**
1365      * Gets the next Channel Mask Entry in a Channel Mask TLV.
1366      *
1367      * @returns A pointer to next Channel Mask Entry.
1368      *
1369      */
GetNext(void)1370     ChannelMaskEntryBase *GetNext(void) { return AsNonConst(AsConst(this)->GetNext()); }
1371 
1372 private:
1373     uint8_t mChannelPage;
1374     uint8_t mMaskLength;
1375 } OT_TOOL_PACKED_END;
1376 
1377 /**
1378  * Implements Channel Mask Entry Page 0 generation and parsing.
1379  *
1380  */
1381 OT_TOOL_PACKED_BEGIN
1382 class ChannelMaskEntry : public ChannelMaskEntryBase
1383 {
1384 public:
1385     /**
1386      * Initializes the entry.
1387      *
1388      */
Init(void)1389     void Init(void)
1390     {
1391         SetChannelPage(0);
1392         SetMaskLength(sizeof(mMask));
1393     }
1394 
1395     /**
1396      * Indicates whether or not the entry appears to be well-formed.
1397      *
1398      * @retval TRUE   If the entry appears to be well-formed.
1399      * @retval FALSE  If the entry does not appear to be well-formed.
1400      *
1401      */
IsValid(void) const1402     bool IsValid(void) const { return GetMaskLength() == sizeof(mMask); }
1403 
1404     /**
1405      * Returns the Channel Mask value as a `uint32_t` bit mask.
1406      *
1407      * @returns The Channel Mask value.
1408      *
1409      */
GetMask(void) const1410     uint32_t GetMask(void) const { return Encoding::Reverse32(HostSwap32(mMask)); }
1411 
1412     /**
1413      * Sets the Channel Mask value.
1414      *
1415      * @param[in]  aMask  The Channel Mask value.
1416      *
1417      */
SetMask(uint32_t aMask)1418     void SetMask(uint32_t aMask) { mMask = HostSwap32(Encoding::Reverse32(aMask)); }
1419 
1420 private:
1421     uint32_t mMask;
1422 } OT_TOOL_PACKED_END;
1423 
1424 /**
1425  * Implements Channel Mask TLV generation and parsing.
1426  *
1427  */
1428 OT_TOOL_PACKED_BEGIN
1429 class ChannelMaskBaseTlv : public Tlv, public TlvInfo<Tlv::kChannelMask>
1430 {
1431 public:
1432     /**
1433      * Initializes the TLV.
1434      *
1435      */
Init(void)1436     void Init(void)
1437     {
1438         SetType(kChannelMask);
1439         SetLength(sizeof(*this) - sizeof(Tlv));
1440     }
1441 
1442     /**
1443      * Indicates whether or not the TLV appears to be well-formed.
1444      *
1445      * @retval TRUE   If the TLV appears to be well-formed.
1446      * @retval FALSE  If the TLV does not appear to be well-formed.
1447      *
1448      */
1449     bool IsValid(void) const;
1450 
1451     /**
1452      * Gets the first Channel Mask Entry in the Channel Mask TLV.
1453      *
1454      * @returns A pointer to first Channel Mask Entry or `nullptr` if not found.
1455      *
1456      */
1457     const ChannelMaskEntryBase *GetFirstEntry(void) const;
1458 
1459     /**
1460      * Gets the first Channel Mask Entry in the Channel Mask TLV.
1461      *
1462      * @returns A pointer to first Channel Mask Entry or `nullptr` if not found.
1463      *
1464      */
1465     ChannelMaskEntryBase *GetFirstEntry(void);
1466 } OT_TOOL_PACKED_END;
1467 
1468 /**
1469  * Implements Channel Mask TLV generation and parsing.
1470  *
1471  */
1472 OT_TOOL_PACKED_BEGIN
1473 class ChannelMaskTlv : public ChannelMaskBaseTlv
1474 {
1475 public:
1476     /**
1477      * Initializes the TLV.
1478      *
1479      */
Init(void)1480     void Init(void)
1481     {
1482         SetType(kChannelMask);
1483         SetLength(sizeof(*this) - sizeof(Tlv));
1484         memset(mEntries, 0, sizeof(mEntries));
1485     }
1486 
1487     /**
1488      * Sets the Channel Mask Entries.
1489      *
1490      * @param[in]  aChannelMask  The Channel Mask value.
1491      *
1492      */
1493     void SetChannelMask(uint32_t aChannelMask);
1494 
1495     /**
1496      * Returns the Channel Mask value as a `uint32_t` bit mask.
1497      *
1498      * @returns The Channel Mask or 0 if not found.
1499      *
1500      */
1501     uint32_t GetChannelMask(void) const;
1502 
1503     /**
1504      * Reads message and returns the Channel Mask value as a `uint32_t` bit mask.
1505      *
1506      * @param[in]   aMessage     A reference to the message.
1507      *
1508      * @returns The Channel Mask or 0 if not found.
1509      *
1510      */
1511     static uint32_t GetChannelMask(const Message &aMessage);
1512 
1513 private:
1514     static constexpr uint8_t kNumMaskEntries = Radio::kNumChannelPages;
1515 
1516     ChannelMaskEntry mEntries[kNumMaskEntries];
1517 } OT_TOOL_PACKED_END;
1518 
1519 /**
1520  * Implements Energy List TLV generation and parsing.
1521  *
1522  */
1523 OT_TOOL_PACKED_BEGIN
1524 class EnergyListTlv : public Tlv, public TlvInfo<Tlv::kEnergyList>
1525 {
1526 public:
1527     /**
1528      * Initializes the TLV.
1529      *
1530      */
Init(void)1531     void Init(void)
1532     {
1533         SetType(kEnergyList);
1534         SetLength(sizeof(*this) - sizeof(Tlv));
1535     }
1536 
1537     /**
1538      * Indicates whether or not the TLV appears to be well-formed.
1539      *
1540      * @retval TRUE   If the TLV appears to be well-formed.
1541      * @retval FALSE  If the TLV does not appear to be well-formed.
1542      *
1543      */
IsValid(void) const1544     bool IsValid(void) const { return true; }
1545 
1546     /**
1547      * Returns a pointer to the start of energy measurement list.
1548      *
1549      * @returns A pointer to the start start of energy energy measurement list.
1550      *
1551      */
GetEnergyList(void) const1552     const uint8_t *GetEnergyList(void) const { return mEnergyList; }
1553 
1554     /**
1555      * Returns the length of energy measurement list.
1556      *
1557      * @returns The length of energy measurement list.
1558      *
1559      */
GetEnergyListLength(void) const1560     uint8_t GetEnergyListLength(void) const { return Min(kMaxListLength, GetLength()); }
1561 
1562 private:
1563     static constexpr uint8_t kMaxListLength = OPENTHREAD_CONFIG_TMF_ENERGY_SCAN_MAX_RESULTS;
1564 
1565     uint8_t mEnergyList[kMaxListLength];
1566 } OT_TOOL_PACKED_END;
1567 
1568 /**
1569  * Defines Provisioning TLV constants and types.
1570  *
1571  */
1572 typedef StringTlvInfo<Tlv::kProvisioningUrl, Tlv::kMaxProvisioningUrlLength> ProvisioningUrlTlv;
1573 
1574 /**
1575  * Defines Vendor Name TLV constants and types.
1576  *
1577  */
1578 typedef StringTlvInfo<Tlv::kVendorName, Tlv::kMaxVendorNameLength> VendorNameTlv;
1579 
1580 /**
1581  * Defines Vendor Model TLV constants and types.
1582  *
1583  */
1584 typedef StringTlvInfo<Tlv::kVendorModel, Tlv::kMaxVendorModelLength> VendorModelTlv;
1585 
1586 /**
1587  * Defines Vendor SW Version TLV constants and types.
1588  *
1589  */
1590 typedef StringTlvInfo<Tlv::kVendorSwVersion, Tlv::kMaxVendorSwVersionLength> VendorSwVersionTlv;
1591 
1592 /**
1593  * Defines Vendor Data TLV constants and types.
1594  *
1595  */
1596 typedef StringTlvInfo<Tlv::kVendorData, Tlv::kMaxVendorDataLength> VendorDataTlv;
1597 
1598 /**
1599  * Implements Vendor Stack Version TLV generation and parsing.
1600  *
1601  */
1602 OT_TOOL_PACKED_BEGIN
1603 class VendorStackVersionTlv : public Tlv, public TlvInfo<Tlv::kVendorStackVersion>
1604 {
1605 public:
1606     /**
1607      * Default constructor.
1608      *
1609      */
VendorStackVersionTlv(void)1610     VendorStackVersionTlv(void)
1611         : mBuildRevision(0)
1612         , mMinorMajor(0)
1613     {
1614     }
1615 
1616     /**
1617      * Initializes the TLV.
1618      *
1619      */
Init(void)1620     void Init(void)
1621     {
1622         SetType(kVendorStackVersion);
1623         SetLength(sizeof(*this) - sizeof(Tlv));
1624     }
1625 
1626     /**
1627      * Indicates whether or not the TLV appears to be well-formed.
1628      *
1629      * @retval TRUE   If the TLV appears to be well-formed.
1630      * @retval FALSE  If the TLV does not appear to be well-formed.
1631      *
1632      */
IsValid(void) const1633     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1634 
1635     /**
1636      * Returns the Stack Vendor OUI value.
1637      *
1638      * @returns The Vendor Stack Vendor OUI value.
1639      *
1640      */
GetOui(void) const1641     uint32_t GetOui(void) const { return ReadUint24(mOui); }
1642 
1643     /**
1644      * Returns the Stack Vendor OUI value.
1645      *
1646      * @param[in]  aOui  The Vendor Stack Vendor OUI value.
1647      *
1648      */
SetOui(uint32_t aOui)1649     void SetOui(uint32_t aOui) { WriteUint24(aOui, mOui); }
1650 
1651     /**
1652      * Returns the Build value.
1653      *
1654      * @returns The Build value.
1655      *
1656      */
GetBuild(void) const1657     uint16_t GetBuild(void) const { return (HostSwap16(mBuildRevision) & kBuildMask) >> kBuildOffset; }
1658 
1659     /**
1660      * Sets the Build value.
1661      *
1662      * @param[in]  aBuild  The Build value.
1663      *
1664      */
SetBuild(uint16_t aBuild)1665     void SetBuild(uint16_t aBuild)
1666     {
1667         mBuildRevision =
1668             HostSwap16((HostSwap16(mBuildRevision) & ~kBuildMask) | ((aBuild << kBuildOffset) & kBuildMask));
1669     }
1670 
1671     /**
1672      * Returns the Revision value.
1673      *
1674      * @returns The Revision value.
1675      *
1676      */
GetRevision(void) const1677     uint8_t GetRevision(void) const { return (HostSwap16(mBuildRevision) & kRevMask) >> kRevOffset; }
1678 
1679     /**
1680      * Sets the Revision value.
1681      *
1682      * @param[in]  aRevision  The Revision value.
1683      *
1684      */
SetRevision(uint8_t aRevision)1685     void SetRevision(uint8_t aRevision)
1686     {
1687         mBuildRevision = HostSwap16((HostSwap16(mBuildRevision) & ~kRevMask) | ((aRevision << kRevOffset) & kRevMask));
1688     }
1689 
1690     /**
1691      * Returns the Minor value.
1692      *
1693      * @returns The Minor value.
1694      *
1695      */
GetMinor(void) const1696     uint8_t GetMinor(void) const { return (mMinorMajor & kMinorMask) >> kMinorOffset; }
1697 
1698     /**
1699      * Sets the Minor value.
1700      *
1701      * @param[in]  aMinor  The Minor value.
1702      *
1703      */
SetMinor(uint8_t aMinor)1704     void SetMinor(uint8_t aMinor)
1705     {
1706         mMinorMajor = (mMinorMajor & ~kMinorMask) | ((aMinor << kMinorOffset) & kMinorMask);
1707     }
1708 
1709     /**
1710      * Returns the Major value.
1711      *
1712      * @returns The Major value.
1713      *
1714      */
GetMajor(void) const1715     uint8_t GetMajor(void) const { return (mMinorMajor & kMajorMask) >> kMajorOffset; }
1716 
1717     /**
1718      * Sets the Major value.
1719      *
1720      * @param[in] aMajor  The Major value.
1721      *
1722      */
SetMajor(uint8_t aMajor)1723     void SetMajor(uint8_t aMajor)
1724     {
1725         mMinorMajor = (mMinorMajor & ~kMajorMask) | ((aMajor << kMajorOffset) & kMajorMask);
1726     }
1727 
1728 private:
1729     // For `mBuildRevision`
1730     static constexpr uint8_t  kBuildOffset = 4;
1731     static constexpr uint16_t kBuildMask   = 0xfff << kBuildOffset;
1732     static constexpr uint8_t  kRevOffset   = 0;
1733     static constexpr uint16_t kRevMask     = 0xf << kBuildOffset;
1734 
1735     // For `mMinorMajor`
1736     static constexpr uint8_t kMinorOffset = 4;
1737     static constexpr uint8_t kMinorMask   = 0xf << kMinorOffset;
1738     static constexpr uint8_t kMajorOffset = 0;
1739     static constexpr uint8_t kMajorMask   = 0xf << kMajorOffset;
1740 
1741     uint8_t  mOui[3];
1742     uint16_t mBuildRevision;
1743     uint8_t  mMinorMajor;
1744 } OT_TOOL_PACKED_END;
1745 
1746 /**
1747  * Defines UDP Encapsulation TLV types and constants.
1748  *
1749  */
1750 typedef TlvInfo<MeshCoP::Tlv::kUdpEncapsulation> UdpEncapsulationTlv;
1751 
1752 /**
1753  * Represents UDP Encapsulation TLV value header (source and destination ports).
1754  *
1755  */
1756 OT_TOOL_PACKED_BEGIN
1757 class UdpEncapsulationTlvHeader
1758 {
1759 public:
1760     /**
1761      * Returns the source port.
1762      *
1763      * @returns The source port.
1764      *
1765      */
GetSourcePort(void) const1766     uint16_t GetSourcePort(void) const { return HostSwap16(mSourcePort); }
1767 
1768     /**
1769      * Updates the source port.
1770      *
1771      * @param[in]   aSourcePort     The source port.
1772      *
1773      */
SetSourcePort(uint16_t aSourcePort)1774     void SetSourcePort(uint16_t aSourcePort) { mSourcePort = HostSwap16(aSourcePort); }
1775 
1776     /**
1777      * Returns the destination port.
1778      *
1779      * @returns The destination port.
1780      *
1781      */
GetDestinationPort(void) const1782     uint16_t GetDestinationPort(void) const { return HostSwap16(mDestinationPort); }
1783 
1784     /**
1785      * Updates the destination port.
1786      *
1787      * @param[in]   aDestinationPort    The destination port.
1788      *
1789      */
SetDestinationPort(uint16_t aDestinationPort)1790     void SetDestinationPort(uint16_t aDestinationPort) { mDestinationPort = HostSwap16(aDestinationPort); }
1791 
1792 private:
1793     uint16_t mSourcePort;
1794     uint16_t mDestinationPort;
1795     // Followed by the UDP Payload.
1796 } OT_TOOL_PACKED_END;
1797 
1798 /**
1799  * Implements Discovery Request TLV generation and parsing.
1800  *
1801  */
1802 OT_TOOL_PACKED_BEGIN
1803 class DiscoveryRequestTlv : public Tlv, public TlvInfo<Tlv::kDiscoveryRequest>
1804 {
1805 public:
1806     /**
1807      * Initializes the TLV.
1808      *
1809      */
Init(void)1810     void Init(void)
1811     {
1812         SetType(kDiscoveryRequest);
1813         SetLength(sizeof(*this) - sizeof(Tlv));
1814         mFlags    = 0;
1815         mReserved = 0;
1816     }
1817 
1818     /**
1819      * Indicates whether or not the TLV appears to be well-formed.
1820      *
1821      * @retval TRUE   If the TLV appears to be well-formed.
1822      * @retval FALSE  If the TLV does not appear to be well-formed.
1823      *
1824      */
IsValid(void) const1825     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1826 
1827     /**
1828      * Returns the Version value.
1829      *
1830      * @returns The Version value.
1831      *
1832      */
GetVersion(void) const1833     uint8_t GetVersion(void) const { return mFlags >> kVersionOffset; }
1834 
1835     /**
1836      * Sets the Version value.
1837      *
1838      * @param[in]  aVersion  The Version value.
1839      *
1840      */
SetVersion(uint8_t aVersion)1841     void SetVersion(uint8_t aVersion)
1842     {
1843         mFlags = (mFlags & ~kVersionMask) | ((aVersion << kVersionOffset) & kVersionMask);
1844     }
1845 
1846     /**
1847      * Indicates whether or not the Joiner flag is set.
1848      *
1849      * @retval TRUE   If the Joiner flag is set.
1850      * @retval FALSE  If the Joiner flag is not set.
1851      *
1852      */
IsJoiner(void) const1853     bool IsJoiner(void) const { return (mFlags & kJoinerMask) != 0; }
1854 
1855     /**
1856      * Sets the Joiner flag.
1857      *
1858      * @param[in]  aJoiner  TRUE if set, FALSE otherwise.
1859      *
1860      */
SetJoiner(bool aJoiner)1861     void SetJoiner(bool aJoiner)
1862     {
1863         if (aJoiner)
1864         {
1865             mFlags |= kJoinerMask;
1866         }
1867         else
1868         {
1869             mFlags &= ~kJoinerMask;
1870         }
1871     }
1872 
1873 private:
1874     static constexpr uint8_t kVersionOffset = 4;
1875     static constexpr uint8_t kVersionMask   = 0xf << kVersionOffset;
1876     static constexpr uint8_t kJoinerOffset  = 3;
1877     static constexpr uint8_t kJoinerMask    = 1 << kJoinerOffset;
1878 
1879     uint8_t mFlags;
1880     uint8_t mReserved;
1881 } OT_TOOL_PACKED_END;
1882 
1883 /**
1884  * Implements Discovery Response TLV generation and parsing.
1885  *
1886  */
1887 OT_TOOL_PACKED_BEGIN
1888 class DiscoveryResponseTlv : public Tlv, public TlvInfo<Tlv::kDiscoveryResponse>
1889 {
1890 public:
1891     /**
1892      * Initializes the TLV.
1893      *
1894      */
Init(void)1895     void Init(void)
1896     {
1897         SetType(kDiscoveryResponse);
1898         SetLength(sizeof(*this) - sizeof(Tlv));
1899         mFlags    = 0;
1900         mReserved = 0;
1901     }
1902 
1903     /**
1904      * Indicates whether or not the TLV appears to be well-formed.
1905      *
1906      * @retval TRUE   If the TLV appears to be well-formed.
1907      * @retval FALSE  If the TLV does not appear to be well-formed.
1908      *
1909      */
IsValid(void) const1910     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1911 
1912     /**
1913      * Returns the Version value.
1914      *
1915      * @returns The Version value.
1916      *
1917      */
GetVersion(void) const1918     uint8_t GetVersion(void) const { return mFlags >> kVersionOffset; }
1919 
1920     /**
1921      * Sets the Version value.
1922      *
1923      * @param[in]  aVersion  The Version value.
1924      *
1925      */
SetVersion(uint8_t aVersion)1926     void SetVersion(uint8_t aVersion)
1927     {
1928         mFlags = (mFlags & ~kVersionMask) | ((aVersion << kVersionOffset) & kVersionMask);
1929     }
1930 
1931     /**
1932      * Indicates whether or not the Native Commissioner flag is set.
1933      *
1934      * @retval TRUE   If the Native Commissioner flag is set.
1935      * @retval FALSE  If the Native Commissioner flag is not set.
1936      *
1937      */
IsNativeCommissioner(void) const1938     bool IsNativeCommissioner(void) const { return (mFlags & kNativeMask) != 0; }
1939 
1940     /**
1941      * Sets the Native Commissioner flag.
1942      *
1943      * @param[in]  aNativeCommissioner  TRUE if set, FALSE otherwise.
1944      *
1945      */
SetNativeCommissioner(bool aNativeCommissioner)1946     void SetNativeCommissioner(bool aNativeCommissioner)
1947     {
1948         if (aNativeCommissioner)
1949         {
1950             mFlags |= kNativeMask;
1951         }
1952         else
1953         {
1954             mFlags &= ~kNativeMask;
1955         }
1956     }
1957 
1958     /**
1959      * Indicates whether or not the Commercial Commissioning Mode flag is set.
1960      *
1961      * @retval TRUE   If the Commercial Commissioning Mode flag is set.
1962      * @retval FALSE  If the Commercial Commissioning Mode flag is not set.
1963      *
1964      */
IsCommercialCommissioningMode(void) const1965     bool IsCommercialCommissioningMode(void) const { return (mFlags & kCCMMask) != 0; }
1966 
1967     /**
1968      * Sets the Commercial Commissioning Mode flag.
1969      *
1970      * @param[in]  aCCM  TRUE if set, FALSE otherwise.
1971      *
1972      */
SetCommercialCommissioningMode(bool aCCM)1973     void SetCommercialCommissioningMode(bool aCCM)
1974     {
1975         if (aCCM)
1976         {
1977             mFlags |= kCCMMask;
1978         }
1979         else
1980         {
1981             mFlags &= ~kCCMMask;
1982         }
1983     }
1984 
1985 private:
1986     static constexpr uint8_t kVersionOffset = 4;
1987     static constexpr uint8_t kVersionMask   = 0xf << kVersionOffset;
1988     static constexpr uint8_t kNativeOffset  = 3;
1989     static constexpr uint8_t kNativeMask    = 1 << kNativeOffset;
1990     static constexpr uint8_t kCCMOffset     = 2;
1991     static constexpr uint8_t kCCMMask       = 1 << kCCMOffset;
1992 
1993     uint8_t mFlags;
1994     uint8_t mReserved;
1995 } OT_TOOL_PACKED_END;
1996 
1997 /**
1998  * Implements Joiner Advertisement TLV generation and parsing.
1999  *
2000  */
2001 OT_TOOL_PACKED_BEGIN
2002 class JoinerAdvertisementTlv : public Tlv, public TlvInfo<Tlv::kJoinerAdvertisement>
2003 {
2004 public:
2005     static constexpr uint8_t kAdvDataMaxLength = OT_JOINER_ADVDATA_MAX_LENGTH; ///< The Max Length of AdvData
2006 
2007     /**
2008      * Initializes the TLV.
2009      *
2010      */
Init(void)2011     void Init(void)
2012     {
2013         SetType(kJoinerAdvertisement);
2014         SetLength(sizeof(*this) - sizeof(Tlv));
2015     }
2016 
2017     /**
2018      * Indicates whether or not the TLV appears to be well-formed.
2019      *
2020      * @retval TRUE   If the TLV appears to be well-formed.
2021      * @retval FALSE  If the TLV does not appear to be well-formed.
2022      *
2023      */
IsValid(void) const2024     bool IsValid(void) const { return GetLength() >= sizeof(mOui) && GetLength() <= sizeof(mOui) + sizeof(mAdvData); }
2025 
2026     /**
2027      * Returns the Vendor OUI value.
2028      *
2029      * @returns The Vendor OUI value.
2030      *
2031      */
GetOui(void) const2032     uint32_t GetOui(void) const { return ReadUint24(mOui); }
2033 
2034     /**
2035      * Sets the Vendor OUI value.
2036      *
2037      * @param[in]  aOui The Vendor OUI value.
2038      *
2039      */
SetOui(uint32_t aOui)2040     void SetOui(uint32_t aOui) { return WriteUint24(aOui, mOui); }
2041 
2042     /**
2043      * Returns the Adv Data length.
2044      *
2045      * @returns The AdvData length.
2046      *
2047      */
GetAdvDataLength(void) const2048     uint8_t GetAdvDataLength(void) const { return GetLength() - sizeof(mOui); }
2049 
2050     /**
2051      * Returns the Adv Data value.
2052      *
2053      * @returns A pointer to the Adv Data value.
2054      *
2055      */
GetAdvData(void) const2056     const uint8_t *GetAdvData(void) const { return mAdvData; }
2057 
2058     /**
2059      * Sets the Adv Data value.
2060      *
2061      * @param[in]  aAdvData        A pointer to the AdvData value.
2062      * @param[in]  aAdvDataLength  The length of AdvData in bytes.
2063      *
2064      */
SetAdvData(const uint8_t * aAdvData,uint8_t aAdvDataLength)2065     void SetAdvData(const uint8_t *aAdvData, uint8_t aAdvDataLength)
2066     {
2067         OT_ASSERT((aAdvData != nullptr) && (aAdvDataLength > 0) && (aAdvDataLength <= kAdvDataMaxLength));
2068 
2069         SetLength(aAdvDataLength + sizeof(mOui));
2070         memcpy(mAdvData, aAdvData, aAdvDataLength);
2071     }
2072 
2073 private:
2074     uint8_t mOui[3];
2075     uint8_t mAdvData[kAdvDataMaxLength];
2076 } OT_TOOL_PACKED_END;
2077 
2078 } // namespace MeshCoP
2079 
2080 } // namespace ot
2081 
2082 #endif // MESHCOP_TLVS_HPP_
2083