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  * This class 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      * This method 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      * This method 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      * This method 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      * This method 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      * This static method 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      * This static method reads the requested TLV out of @p aMessage.
185      *
186      * This method 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      * This static method 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      * This static method 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      * This static method 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  * This class 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      * This method 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      * This method 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  * This class defines Commissioner UDP Port TLV constants and types.
299  *
300  */
301 typedef UintTlvInfo<Tlv::kCommissionerUdpPort, uint16_t> CommissionerUdpPortTlv;
302 
303 /**
304  * This class defines IPv6 Address TLV constants and types.
305  *
306  */
307 typedef SimpleTlvInfo<Tlv::kIp6Address, Ip6::Address> Ip6AddressTlv;
308 
309 /**
310  * This class defines Joiner IID TLV constants and types.
311  *
312  */
313 typedef SimpleTlvInfo<Tlv::kJoinerIid, Ip6::InterfaceIdentifier> JoinerIidTlv;
314 
315 /**
316  * This class defines Joiner Router Locator TLV constants and types.
317  *
318  */
319 typedef UintTlvInfo<Tlv::kJoinerRouterLocator, uint16_t> JoinerRouterLocatorTlv;
320 
321 /**
322  * This class defines Joiner Router KEK TLV constants and types.
323  *
324  */
325 typedef SimpleTlvInfo<Tlv::kJoinerRouterKek, Kek> JoinerRouterKekTlv;
326 
327 /**
328  * This class defines Count TLV constants and types.
329  *
330  */
331 typedef UintTlvInfo<Tlv::kCount, uint8_t> CountTlv;
332 
333 /**
334  * This class defines Period TLV constants and types.
335  *
336  */
337 typedef UintTlvInfo<Tlv::kPeriod, uint16_t> PeriodTlv;
338 
339 /**
340  * This class defines Scan Duration TLV constants and types.
341  *
342  */
343 typedef UintTlvInfo<Tlv::kScanDuration, uint16_t> ScanDurationTlv;
344 
345 /**
346  * This class 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      * This method 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      * This method 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      * This method 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      * This method 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      * This method 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      * This method 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  * This class 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      * This method 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      * This method indicates whether or not the TLV appears to be well-formed.
430      *
431      * @retval TRUE   If the TLV appears to be well-formed.
432      * @retval FALSE  If the TLV does not appear to be well-formed.
433      *
434      */
IsValid(void) const435     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
436 
437     /**
438      * This method 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      * This method 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  * This class 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      * This method 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      * This method 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      * This method 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      * This method 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  * This class 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      * This method 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      * This method 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      * This method gets the Network Name value.
533      *
534      * @returns The Network Name value (as `NameData`).
535      *
536      */
537     NameData GetNetworkName(void) const;
538 
539     /**
540      * This method 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  * This class 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      * This method 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      * This method 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      * This method 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      * This method 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  * This class 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      * This method 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      * This method 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      * This method 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      * This method 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  * This class 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      * This method 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      * This method 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      * This method 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      * This method 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  * This class 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      * This method 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      * This method 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      * This method 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      * This method 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      * This method 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  * This class 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      * This method 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      * This method 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      * This method 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      * This method sets all bits in the Bloom Filter to zero.
790      *
791      */
Clear(void)792     void Clear(void) { memset(mSteeringData, 0, GetSteeringDataLength()); }
793 
794     /**
795      * This method 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  * This class 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      * This method 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      * This method 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      * This method 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      * This method 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  * This class 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      * This method 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      * This method 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      * This method 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      * This method 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  * This class 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      * This method 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      * This method 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      * This method 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      * This method 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  * This class 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      * This method 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      * This method 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      * This method returns the Security Policy.
985      *
986      * @returns  The Security Policy.
987      *
988      */
989     SecurityPolicy GetSecurityPolicy(void) const;
990 
991     /**
992      * This method 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  * This class 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      * This method 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      * This method 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      * This method gets the timestamp.
1045      *
1046      * @returns The timestamp.
1047      *
1048      */
GetTimestamp(void) const1049     const Timestamp &GetTimestamp(void) const { return mTimestamp; }
1050 
1051     /**
1052      * This method 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      * This method 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  * This class 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 /**
1093  * This class implements Joiner UDP Port TLV generation and parsing.
1094  *
1095  */
1096 OT_TOOL_PACKED_BEGIN
1097 class JoinerUdpPortTlv : public Tlv, public UintTlvInfo<Tlv::kJoinerUdpPort, uint16_t>
1098 {
1099 public:
1100     /**
1101      * This method initializes the TLV.
1102      *
1103      */
Init(void)1104     void Init(void)
1105     {
1106         SetType(kJoinerUdpPort);
1107         SetLength(sizeof(*this) - sizeof(Tlv));
1108     }
1109 
1110     /**
1111      * This method indicates whether or not the TLV appears to be well-formed.
1112      *
1113      * @retval TRUE   If the TLV appears to be well-formed.
1114      * @retval FALSE  If the TLV does not appear to be well-formed.
1115      *
1116      */
IsValid(void) const1117     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1118 
1119     /**
1120      * This method returns the UDP Port value.
1121      *
1122      * @returns The UDP Port value.
1123      *
1124      */
GetUdpPort(void) const1125     uint16_t GetUdpPort(void) const { return HostSwap16(mUdpPort); }
1126 
1127     /**
1128      * This method sets the UDP Port value.
1129      *
1130      * @param[in]  aUdpPort  The UDP Port value.
1131      *
1132      */
SetUdpPort(uint16_t aUdpPort)1133     void SetUdpPort(uint16_t aUdpPort) { mUdpPort = HostSwap16(aUdpPort); }
1134 
1135 private:
1136     uint16_t mUdpPort;
1137 } OT_TOOL_PACKED_END;
1138 
1139 /**
1140  * This class implements Pending Timestamp TLV generation and parsing.
1141  *
1142  */
1143 OT_TOOL_PACKED_BEGIN
1144 class PendingTimestampTlv : public Tlv, public SimpleTlvInfo<Tlv::kPendingTimestamp, Timestamp>
1145 {
1146 public:
1147     /**
1148      * This method initializes the TLV.
1149      *
1150      */
Init(void)1151     void Init(void)
1152     {
1153         SetType(kPendingTimestamp);
1154         SetLength(sizeof(*this) - sizeof(Tlv));
1155         mTimestamp.Clear();
1156     }
1157 
1158     /**
1159      * This method indicates whether or not the TLV appears to be well-formed.
1160      *
1161      * @retval TRUE   If the TLV appears to be well-formed.
1162      * @retval FALSE  If the TLV does not appear to be well-formed.
1163      *
1164      */
IsValid(void) const1165     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1166 
1167     /**
1168      * This method gets the timestamp.
1169      *
1170      * @returns The timestamp.
1171      *
1172      */
GetTimestamp(void) const1173     const Timestamp &GetTimestamp(void) const { return mTimestamp; }
1174 
1175     /**
1176      * This method returns a reference to the timestamp.
1177      *
1178      * @returns A reference to the timestamp.
1179      *
1180      */
GetTimestamp(void)1181     Timestamp &GetTimestamp(void) { return mTimestamp; }
1182 
1183     /**
1184      * This method sets the timestamp.
1185      *
1186      * @param[in] aTimestamp   The new timestamp.
1187      *
1188      */
SetTimestamp(const Timestamp & aTimestamp)1189     void SetTimestamp(const Timestamp &aTimestamp) { mTimestamp = aTimestamp; }
1190 
1191 private:
1192     Timestamp mTimestamp;
1193 } OT_TOOL_PACKED_END;
1194 
1195 /**
1196  * This class implements Delay Timer TLV generation and parsing.
1197  *
1198  */
1199 OT_TOOL_PACKED_BEGIN
1200 class DelayTimerTlv : public Tlv, public UintTlvInfo<Tlv::kDelayTimer, uint32_t>
1201 {
1202 public:
1203     /**
1204      * This method initializes the TLV.
1205      *
1206      */
Init(void)1207     void Init(void)
1208     {
1209         SetType(kDelayTimer);
1210         SetLength(sizeof(*this) - sizeof(Tlv));
1211     }
1212 
1213     /**
1214      * This method indicates whether or not the TLV appears to be well-formed.
1215      *
1216      * @retval TRUE   If the TLV appears to be well-formed.
1217      * @retval FALSE  If the TLV does not appear to be well-formed.
1218      *
1219      */
IsValid(void) const1220     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1221 
1222     /**
1223      * This method returns the Delay Timer value.
1224      *
1225      * @returns The Delay Timer value.
1226      *
1227      */
GetDelayTimer(void) const1228     uint32_t GetDelayTimer(void) const { return HostSwap32(mDelayTimer); }
1229 
1230     /**
1231      * This method sets the Delay Timer value.
1232      *
1233      * @param[in]  aDelayTimer  The Delay Timer value.
1234      *
1235      */
SetDelayTimer(uint32_t aDelayTimer)1236     void SetDelayTimer(uint32_t aDelayTimer) { mDelayTimer = HostSwap32(aDelayTimer); }
1237 
1238     static constexpr uint32_t kMaxDelayTimer = 259200; ///< Maximum delay timer value for a Pending Dataset in seconds
1239 
1240     /**
1241      * Minimum Delay Timer value for a Pending Operational Dataset (ms)
1242      *
1243      */
1244     static constexpr uint32_t kDelayTimerMinimal = OPENTHREAD_CONFIG_TMF_PENDING_DATASET_MINIMUM_DELAY;
1245 
1246     /**
1247      * Default Delay Timer value for a Pending Operational Dataset (ms)
1248      *
1249      */
1250     static constexpr uint32_t kDelayTimerDefault = OPENTHREAD_CONFIG_TMF_PENDING_DATASET_DEFAULT_DELAY;
1251 
1252 private:
1253     uint32_t mDelayTimer;
1254 } OT_TOOL_PACKED_END;
1255 
1256 // forward declare ChannelMaskTlv
1257 class ChannelMaskTlv;
1258 
1259 /**
1260  * This class implements Channel Mask Entry generation and parsing.
1261  *
1262  */
1263 OT_TOOL_PACKED_BEGIN
1264 class ChannelMaskEntryBase
1265 {
1266 public:
1267     /**
1268      * This method gets the ChannelPage value.
1269      *
1270      * @returns The ChannelPage value.
1271      *
1272      */
GetChannelPage(void) const1273     uint8_t GetChannelPage(void) const { return mChannelPage; }
1274 
1275     /**
1276      * This method sets the ChannelPage value.
1277      *
1278      * @param[in]  aChannelPage  The ChannelPage value.
1279      *
1280      */
SetChannelPage(uint8_t aChannelPage)1281     void SetChannelPage(uint8_t aChannelPage) { mChannelPage = aChannelPage; }
1282 
1283     /**
1284      * This method gets the MaskLength value.
1285      *
1286      * @returns The MaskLength value.
1287      *
1288      */
GetMaskLength(void) const1289     uint8_t GetMaskLength(void) const { return mMaskLength; }
1290 
1291     /**
1292      * This method sets the MaskLength value.
1293      *
1294      * @param[in]  aMaskLength  The MaskLength value.
1295      *
1296      */
SetMaskLength(uint8_t aMaskLength)1297     void SetMaskLength(uint8_t aMaskLength) { mMaskLength = aMaskLength; }
1298 
1299     /**
1300      * This method returns the total size of this Channel Mask Entry including the mask.
1301      *
1302      * @returns The total size of this entry (number of bytes).
1303      *
1304      */
GetEntrySize(void) const1305     uint16_t GetEntrySize(void) const { return sizeof(ChannelMaskEntryBase) + mMaskLength; }
1306 
1307     /**
1308      * This method clears the bit corresponding to @p aChannel in ChannelMask.
1309      *
1310      * @param[in]  aChannel  The channel in ChannelMask to clear.
1311      *
1312      */
ClearChannel(uint8_t aChannel)1313     void ClearChannel(uint8_t aChannel)
1314     {
1315         uint8_t *mask = reinterpret_cast<uint8_t *>(this) + sizeof(*this);
1316         mask[aChannel / 8] &= ~(0x80 >> (aChannel % 8));
1317     }
1318 
1319     /**
1320      * This method sets the bit corresponding to @p aChannel in ChannelMask.
1321      *
1322      * @param[in]  aChannel  The channel in ChannelMask to set.
1323      *
1324      */
SetChannel(uint8_t aChannel)1325     void SetChannel(uint8_t aChannel)
1326     {
1327         uint8_t *mask = reinterpret_cast<uint8_t *>(this) + sizeof(*this);
1328         mask[aChannel / 8] |= 0x80 >> (aChannel % 8);
1329     }
1330 
1331     /**
1332      * This method indicates whether or not the bit corresponding to @p aChannel in ChannelMask is set.
1333      *
1334      * @param[in]  aChannel  The channel in ChannelMask to get.
1335      *
1336      */
IsChannelSet(uint8_t aChannel) const1337     bool IsChannelSet(uint8_t aChannel) const
1338     {
1339         const uint8_t *mask = reinterpret_cast<const uint8_t *>(this) + sizeof(*this);
1340         return (aChannel < (mMaskLength * 8)) ? ((mask[aChannel / 8] & (0x80 >> (aChannel % 8))) != 0) : false;
1341     }
1342 
1343     /**
1344      * This method gets the next Channel Mask Entry in a Channel Mask TLV.
1345      *
1346      * @returns A pointer to next Channel Mask Entry.
1347      *
1348      */
GetNext(void) const1349     const ChannelMaskEntryBase *GetNext(void) const
1350     {
1351         return reinterpret_cast<const ChannelMaskEntryBase *>(reinterpret_cast<const uint8_t *>(this) + GetEntrySize());
1352     }
1353 
1354     /**
1355      * This method gets the next Channel Mask Entry in a Channel Mask TLV.
1356      *
1357      * @returns A pointer to next Channel Mask Entry.
1358      *
1359      */
GetNext(void)1360     ChannelMaskEntryBase *GetNext(void) { return AsNonConst(AsConst(this)->GetNext()); }
1361 
1362 private:
1363     uint8_t mChannelPage;
1364     uint8_t mMaskLength;
1365 } OT_TOOL_PACKED_END;
1366 
1367 /**
1368  * This class implements Channel Mask Entry Page 0 generation and parsing.
1369  *
1370  */
1371 OT_TOOL_PACKED_BEGIN
1372 class ChannelMaskEntry : public ChannelMaskEntryBase
1373 {
1374 public:
1375     /**
1376      * This method initializes the entry.
1377      *
1378      */
Init(void)1379     void Init(void)
1380     {
1381         SetChannelPage(0);
1382         SetMaskLength(sizeof(mMask));
1383     }
1384 
1385     /**
1386      * This method indicates whether or not the entry appears to be well-formed.
1387      *
1388      * @retval TRUE   If the entry appears to be well-formed.
1389      * @retval FALSE  If the entry does not appear to be well-formed.
1390      *
1391      */
IsValid(void) const1392     bool IsValid(void) const { return GetMaskLength() == sizeof(mMask); }
1393 
1394     /**
1395      * This method returns the Channel Mask value as a `uint32_t` bit mask.
1396      *
1397      * @returns The Channel Mask value.
1398      *
1399      */
GetMask(void) const1400     uint32_t GetMask(void) const { return Encoding::Reverse32(HostSwap32(mMask)); }
1401 
1402     /**
1403      * This method sets the Channel Mask value.
1404      *
1405      * @param[in]  aMask  The Channel Mask value.
1406      *
1407      */
SetMask(uint32_t aMask)1408     void SetMask(uint32_t aMask) { mMask = HostSwap32(Encoding::Reverse32(aMask)); }
1409 
1410 private:
1411     uint32_t mMask;
1412 } OT_TOOL_PACKED_END;
1413 
1414 /**
1415  * This class implements Channel Mask TLV generation and parsing.
1416  *
1417  */
1418 OT_TOOL_PACKED_BEGIN
1419 class ChannelMaskBaseTlv : public Tlv, public TlvInfo<Tlv::kChannelMask>
1420 {
1421 public:
1422     /**
1423      * This method initializes the TLV.
1424      *
1425      */
Init(void)1426     void Init(void)
1427     {
1428         SetType(kChannelMask);
1429         SetLength(sizeof(*this) - sizeof(Tlv));
1430     }
1431 
1432     /**
1433      * This method indicates whether or not the TLV appears to be well-formed.
1434      *
1435      * @retval TRUE   If the TLV appears to be well-formed.
1436      * @retval FALSE  If the TLV does not appear to be well-formed.
1437      *
1438      */
1439     bool IsValid(void) const;
1440 
1441     /**
1442      * This method gets the first Channel Mask Entry in the Channel Mask TLV.
1443      *
1444      * @returns A pointer to first Channel Mask Entry or `nullptr` if not found.
1445      *
1446      */
1447     const ChannelMaskEntryBase *GetFirstEntry(void) const;
1448 
1449     /**
1450      * This method gets the first Channel Mask Entry in the Channel Mask TLV.
1451      *
1452      * @returns A pointer to first Channel Mask Entry or `nullptr` if not found.
1453      *
1454      */
1455     ChannelMaskEntryBase *GetFirstEntry(void);
1456 } OT_TOOL_PACKED_END;
1457 
1458 /**
1459  * This class implements Channel Mask TLV generation and parsing.
1460  *
1461  */
1462 OT_TOOL_PACKED_BEGIN
1463 class ChannelMaskTlv : public ChannelMaskBaseTlv
1464 {
1465 public:
1466     /**
1467      * This method initializes the TLV.
1468      *
1469      */
Init(void)1470     void Init(void)
1471     {
1472         SetType(kChannelMask);
1473         SetLength(sizeof(*this) - sizeof(Tlv));
1474         memset(mEntries, 0, sizeof(mEntries));
1475     }
1476 
1477     /**
1478      * This method sets the Channel Mask Entries.
1479      *
1480      * @param[in]  aChannelMask  The Channel Mask value.
1481      *
1482      */
1483     void SetChannelMask(uint32_t aChannelMask);
1484 
1485     /**
1486      * This method returns the Channel Mask value as a `uint32_t` bit mask.
1487      *
1488      * @returns The Channel Mask or 0 if not found.
1489      *
1490      */
1491     uint32_t GetChannelMask(void) const;
1492 
1493     /**
1494      * This method reads message and returns the Channel Mask value as a `uint32_t` bit mask.
1495      *
1496      * @param[in]   aMessage     A reference to the message.
1497      *
1498      * @returns The Channel Mask or 0 if not found.
1499      *
1500      */
1501     static uint32_t GetChannelMask(const Message &aMessage);
1502 
1503 private:
1504     static constexpr uint8_t kNumMaskEntries = Radio::kNumChannelPages;
1505 
1506     ChannelMaskEntry mEntries[kNumMaskEntries];
1507 } OT_TOOL_PACKED_END;
1508 
1509 /**
1510  * This class implements Energy List TLV generation and parsing.
1511  *
1512  */
1513 OT_TOOL_PACKED_BEGIN
1514 class EnergyListTlv : public Tlv, public TlvInfo<Tlv::kEnergyList>
1515 {
1516 public:
1517     /**
1518      * This method initializes the TLV.
1519      *
1520      */
Init(void)1521     void Init(void)
1522     {
1523         SetType(kEnergyList);
1524         SetLength(sizeof(*this) - sizeof(Tlv));
1525     }
1526 
1527     /**
1528      * This method indicates whether or not the TLV appears to be well-formed.
1529      *
1530      * @retval TRUE   If the TLV appears to be well-formed.
1531      * @retval FALSE  If the TLV does not appear to be well-formed.
1532      *
1533      */
IsValid(void) const1534     bool IsValid(void) const { return true; }
1535 
1536     /**
1537      * This method returns a pointer to the start of energy measurement list.
1538      *
1539      * @returns A pointer to the start start of energy energy measurement list.
1540      *
1541      */
GetEnergyList(void) const1542     const uint8_t *GetEnergyList(void) const { return mEnergyList; }
1543 
1544     /**
1545      * This method returns the length of energy measurement list.
1546      *
1547      * @returns The length of energy measurement list.
1548      *
1549      */
GetEnergyListLength(void) const1550     uint8_t GetEnergyListLength(void) const { return Min(kMaxListLength, GetLength()); }
1551 
1552 private:
1553     static constexpr uint8_t kMaxListLength = OPENTHREAD_CONFIG_TMF_ENERGY_SCAN_MAX_RESULTS;
1554 
1555     uint8_t mEnergyList[kMaxListLength];
1556 } OT_TOOL_PACKED_END;
1557 
1558 /**
1559  * This class defines Provisioning TLV constants and types.
1560  *
1561  */
1562 typedef StringTlvInfo<Tlv::kProvisioningUrl, Tlv::kMaxProvisioningUrlLength> ProvisioningUrlTlv;
1563 
1564 /**
1565  * This class defines Vendor Name TLV constants and types.
1566  *
1567  */
1568 typedef StringTlvInfo<Tlv::kVendorName, Tlv::kMaxVendorNameLength> VendorNameTlv;
1569 
1570 /**
1571  * This class defines Vendor Model TLV constants and types.
1572  *
1573  */
1574 typedef StringTlvInfo<Tlv::kVendorModel, Tlv::kMaxVendorModelLength> VendorModelTlv;
1575 
1576 /**
1577  * This class defines Vendor SW Version TLV constants and types.
1578  *
1579  */
1580 typedef StringTlvInfo<Tlv::kVendorSwVersion, Tlv::kMaxVendorSwVersionLength> VendorSwVersionTlv;
1581 
1582 /**
1583  * This class defines Vendor Data TLV constants and types.
1584  *
1585  */
1586 typedef StringTlvInfo<Tlv::kVendorData, Tlv::kMaxVendorDataLength> VendorDataTlv;
1587 
1588 /**
1589  * This class implements Vendor Stack Version TLV generation and parsing.
1590  *
1591  */
1592 OT_TOOL_PACKED_BEGIN
1593 class VendorStackVersionTlv : public Tlv, public TlvInfo<Tlv::kVendorStackVersion>
1594 {
1595 public:
1596     /**
1597      * Default constructor.
1598      *
1599      */
VendorStackVersionTlv(void)1600     VendorStackVersionTlv(void)
1601         : mBuildRevision(0)
1602         , mMinorMajor(0)
1603     {
1604     }
1605 
1606     /**
1607      * This method initializes the TLV.
1608      *
1609      */
Init(void)1610     void Init(void)
1611     {
1612         SetType(kVendorStackVersion);
1613         SetLength(sizeof(*this) - sizeof(Tlv));
1614     }
1615 
1616     /**
1617      * This method indicates whether or not the TLV appears to be well-formed.
1618      *
1619      * @retval TRUE   If the TLV appears to be well-formed.
1620      * @retval FALSE  If the TLV does not appear to be well-formed.
1621      *
1622      */
IsValid(void) const1623     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1624 
1625     /**
1626      * This method returns the Stack Vendor OUI value.
1627      *
1628      * @returns The Vendor Stack Vendor OUI value.
1629      *
1630      */
GetOui(void) const1631     uint32_t GetOui(void) const { return ReadUint24(mOui); }
1632 
1633     /**
1634      * This method returns the Stack Vendor OUI value.
1635      *
1636      * @param[in]  aOui  The Vendor Stack Vendor OUI value.
1637      *
1638      */
SetOui(uint32_t aOui)1639     void SetOui(uint32_t aOui) { WriteUint24(aOui, mOui); }
1640 
1641     /**
1642      * This method returns the Build value.
1643      *
1644      * @returns The Build value.
1645      *
1646      */
GetBuild(void) const1647     uint16_t GetBuild(void) const { return (HostSwap16(mBuildRevision) & kBuildMask) >> kBuildOffset; }
1648 
1649     /**
1650      * This method sets the Build value.
1651      *
1652      * @param[in]  aBuild  The Build value.
1653      *
1654      */
SetBuild(uint16_t aBuild)1655     void SetBuild(uint16_t aBuild)
1656     {
1657         mBuildRevision =
1658             HostSwap16((HostSwap16(mBuildRevision) & ~kBuildMask) | ((aBuild << kBuildOffset) & kBuildMask));
1659     }
1660 
1661     /**
1662      * This method returns the Revision value.
1663      *
1664      * @returns The Revision value.
1665      *
1666      */
GetRevision(void) const1667     uint8_t GetRevision(void) const { return (HostSwap16(mBuildRevision) & kRevMask) >> kRevOffset; }
1668 
1669     /**
1670      * This method sets the Revision value.
1671      *
1672      * @param[in]  aRevision  The Revision value.
1673      *
1674      */
SetRevision(uint8_t aRevision)1675     void SetRevision(uint8_t aRevision)
1676     {
1677         mBuildRevision = HostSwap16((HostSwap16(mBuildRevision) & ~kRevMask) | ((aRevision << kRevOffset) & kRevMask));
1678     }
1679 
1680     /**
1681      * This method returns the Minor value.
1682      *
1683      * @returns The Minor value.
1684      *
1685      */
GetMinor(void) const1686     uint8_t GetMinor(void) const { return (mMinorMajor & kMinorMask) >> kMinorOffset; }
1687 
1688     /**
1689      * This method sets the Minor value.
1690      *
1691      * @param[in]  aMinor  The Minor value.
1692      *
1693      */
SetMinor(uint8_t aMinor)1694     void SetMinor(uint8_t aMinor)
1695     {
1696         mMinorMajor = (mMinorMajor & ~kMinorMask) | ((aMinor << kMinorOffset) & kMinorMask);
1697     }
1698 
1699     /**
1700      * This method returns the Major value.
1701      *
1702      * @returns The Major value.
1703      *
1704      */
GetMajor(void) const1705     uint8_t GetMajor(void) const { return (mMinorMajor & kMajorMask) >> kMajorOffset; }
1706 
1707     /**
1708      * This method sets the Major value.
1709      *
1710      * @param[in] aMajor  The Major value.
1711      *
1712      */
SetMajor(uint8_t aMajor)1713     void SetMajor(uint8_t aMajor)
1714     {
1715         mMinorMajor = (mMinorMajor & ~kMajorMask) | ((aMajor << kMajorOffset) & kMajorMask);
1716     }
1717 
1718 private:
1719     // For `mBuildRevision`
1720     static constexpr uint8_t  kBuildOffset = 4;
1721     static constexpr uint16_t kBuildMask   = 0xfff << kBuildOffset;
1722     static constexpr uint8_t  kRevOffset   = 0;
1723     static constexpr uint16_t kRevMask     = 0xf << kBuildOffset;
1724 
1725     // For `mMinorMajor`
1726     static constexpr uint8_t kMinorOffset = 4;
1727     static constexpr uint8_t kMinorMask   = 0xf << kMinorOffset;
1728     static constexpr uint8_t kMajorOffset = 0;
1729     static constexpr uint8_t kMajorMask   = 0xf << kMajorOffset;
1730 
1731     uint8_t  mOui[3];
1732     uint16_t mBuildRevision;
1733     uint8_t  mMinorMajor;
1734 } OT_TOOL_PACKED_END;
1735 
1736 /**
1737  * This class defines UDP Encapsulation TLV types and constants.
1738  *
1739  */
1740 typedef TlvInfo<MeshCoP::Tlv::kUdpEncapsulation> UdpEncapsulationTlv;
1741 
1742 /**
1743  * This class represents UDP Encapsulation TLV value header (source and destination ports).
1744  *
1745  */
1746 OT_TOOL_PACKED_BEGIN
1747 class UdpEncapsulationTlvHeader
1748 {
1749 public:
1750     /**
1751      * This method returns the source port.
1752      *
1753      * @returns The source port.
1754      *
1755      */
GetSourcePort(void) const1756     uint16_t GetSourcePort(void) const { return HostSwap16(mSourcePort); }
1757 
1758     /**
1759      * This method updates the source port.
1760      *
1761      * @param[in]   aSourcePort     The source port.
1762      *
1763      */
SetSourcePort(uint16_t aSourcePort)1764     void SetSourcePort(uint16_t aSourcePort) { mSourcePort = HostSwap16(aSourcePort); }
1765 
1766     /**
1767      * This method returns the destination port.
1768      *
1769      * @returns The destination port.
1770      *
1771      */
GetDestinationPort(void) const1772     uint16_t GetDestinationPort(void) const { return HostSwap16(mDestinationPort); }
1773 
1774     /**
1775      * This method updates the destination port.
1776      *
1777      * @param[in]   aDestinationPort    The destination port.
1778      *
1779      */
SetDestinationPort(uint16_t aDestinationPort)1780     void SetDestinationPort(uint16_t aDestinationPort) { mDestinationPort = HostSwap16(aDestinationPort); }
1781 
1782 private:
1783     uint16_t mSourcePort;
1784     uint16_t mDestinationPort;
1785     // Followed by the UDP Payload.
1786 } OT_TOOL_PACKED_END;
1787 
1788 /**
1789  * This class implements Discovery Request TLV generation and parsing.
1790  *
1791  */
1792 OT_TOOL_PACKED_BEGIN
1793 class DiscoveryRequestTlv : public Tlv, public TlvInfo<Tlv::kDiscoveryRequest>
1794 {
1795 public:
1796     /**
1797      * This method initializes the TLV.
1798      *
1799      */
Init(void)1800     void Init(void)
1801     {
1802         SetType(kDiscoveryRequest);
1803         SetLength(sizeof(*this) - sizeof(Tlv));
1804         mFlags    = 0;
1805         mReserved = 0;
1806     }
1807 
1808     /**
1809      * This method indicates whether or not the TLV appears to be well-formed.
1810      *
1811      * @retval TRUE   If the TLV appears to be well-formed.
1812      * @retval FALSE  If the TLV does not appear to be well-formed.
1813      *
1814      */
IsValid(void) const1815     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1816 
1817     /**
1818      * This method returns the Version value.
1819      *
1820      * @returns The Version value.
1821      *
1822      */
GetVersion(void) const1823     uint8_t GetVersion(void) const { return mFlags >> kVersionOffset; }
1824 
1825     /**
1826      * This method sets the Version value.
1827      *
1828      * @param[in]  aVersion  The Version value.
1829      *
1830      */
SetVersion(uint8_t aVersion)1831     void SetVersion(uint8_t aVersion)
1832     {
1833         mFlags = (mFlags & ~kVersionMask) | ((aVersion << kVersionOffset) & kVersionMask);
1834     }
1835 
1836     /**
1837      * This method indicates whether or not the Joiner flag is set.
1838      *
1839      * @retval TRUE   If the Joiner flag is set.
1840      * @retval FALSE  If the Joiner flag is not set.
1841      *
1842      */
IsJoiner(void) const1843     bool IsJoiner(void) const { return (mFlags & kJoinerMask) != 0; }
1844 
1845     /**
1846      * This method sets the Joiner flag.
1847      *
1848      * @param[in]  aJoiner  TRUE if set, FALSE otherwise.
1849      *
1850      */
SetJoiner(bool aJoiner)1851     void SetJoiner(bool aJoiner)
1852     {
1853         if (aJoiner)
1854         {
1855             mFlags |= kJoinerMask;
1856         }
1857         else
1858         {
1859             mFlags &= ~kJoinerMask;
1860         }
1861     }
1862 
1863 private:
1864     static constexpr uint8_t kVersionOffset = 4;
1865     static constexpr uint8_t kVersionMask   = 0xf << kVersionOffset;
1866     static constexpr uint8_t kJoinerOffset  = 3;
1867     static constexpr uint8_t kJoinerMask    = 1 << kJoinerOffset;
1868 
1869     uint8_t mFlags;
1870     uint8_t mReserved;
1871 } OT_TOOL_PACKED_END;
1872 
1873 /**
1874  * This class implements Discovery Response TLV generation and parsing.
1875  *
1876  */
1877 OT_TOOL_PACKED_BEGIN
1878 class DiscoveryResponseTlv : public Tlv, public TlvInfo<Tlv::kDiscoveryResponse>
1879 {
1880 public:
1881     /**
1882      * This method initializes the TLV.
1883      *
1884      */
Init(void)1885     void Init(void)
1886     {
1887         SetType(kDiscoveryResponse);
1888         SetLength(sizeof(*this) - sizeof(Tlv));
1889         mFlags    = 0;
1890         mReserved = 0;
1891     }
1892 
1893     /**
1894      * This method indicates whether or not the TLV appears to be well-formed.
1895      *
1896      * @retval TRUE   If the TLV appears to be well-formed.
1897      * @retval FALSE  If the TLV does not appear to be well-formed.
1898      *
1899      */
IsValid(void) const1900     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1901 
1902     /**
1903      * This method returns the Version value.
1904      *
1905      * @returns The Version value.
1906      *
1907      */
GetVersion(void) const1908     uint8_t GetVersion(void) const { return mFlags >> kVersionOffset; }
1909 
1910     /**
1911      * This method sets the Version value.
1912      *
1913      * @param[in]  aVersion  The Version value.
1914      *
1915      */
SetVersion(uint8_t aVersion)1916     void SetVersion(uint8_t aVersion)
1917     {
1918         mFlags = (mFlags & ~kVersionMask) | ((aVersion << kVersionOffset) & kVersionMask);
1919     }
1920 
1921     /**
1922      * This method indicates whether or not the Native Commissioner flag is set.
1923      *
1924      * @retval TRUE   If the Native Commissioner flag is set.
1925      * @retval FALSE  If the Native Commissioner flag is not set.
1926      *
1927      */
IsNativeCommissioner(void) const1928     bool IsNativeCommissioner(void) const { return (mFlags & kNativeMask) != 0; }
1929 
1930     /**
1931      * This method sets the Native Commissioner flag.
1932      *
1933      * @param[in]  aNativeCommissioner  TRUE if set, FALSE otherwise.
1934      *
1935      */
SetNativeCommissioner(bool aNativeCommissioner)1936     void SetNativeCommissioner(bool aNativeCommissioner)
1937     {
1938         if (aNativeCommissioner)
1939         {
1940             mFlags |= kNativeMask;
1941         }
1942         else
1943         {
1944             mFlags &= ~kNativeMask;
1945         }
1946     }
1947 
1948     /**
1949      * This method indicates whether or not the Commercial Commissioning Mode flag is set.
1950      *
1951      * @retval TRUE   If the Commercial Commissioning Mode flag is set.
1952      * @retval FALSE  If the Commercial Commissioning Mode flag is not set.
1953      *
1954      */
IsCommercialCommissioningMode(void) const1955     bool IsCommercialCommissioningMode(void) const { return (mFlags & kCCMMask) != 0; }
1956 
1957     /**
1958      * This method sets the Commercial Commissioning Mode flag.
1959      *
1960      * @param[in]  aCCM  TRUE if set, FALSE otherwise.
1961      *
1962      */
SetCommercialCommissioningMode(bool aCCM)1963     void SetCommercialCommissioningMode(bool aCCM)
1964     {
1965         if (aCCM)
1966         {
1967             mFlags |= kCCMMask;
1968         }
1969         else
1970         {
1971             mFlags &= ~kCCMMask;
1972         }
1973     }
1974 
1975 private:
1976     static constexpr uint8_t kVersionOffset = 4;
1977     static constexpr uint8_t kVersionMask   = 0xf << kVersionOffset;
1978     static constexpr uint8_t kNativeOffset  = 3;
1979     static constexpr uint8_t kNativeMask    = 1 << kNativeOffset;
1980     static constexpr uint8_t kCCMOffset     = 2;
1981     static constexpr uint8_t kCCMMask       = 1 << kCCMOffset;
1982 
1983     uint8_t mFlags;
1984     uint8_t mReserved;
1985 } OT_TOOL_PACKED_END;
1986 
1987 /**
1988  * This class implements Joiner Advertisement TLV generation and parsing.
1989  *
1990  */
1991 OT_TOOL_PACKED_BEGIN
1992 class JoinerAdvertisementTlv : public Tlv, public TlvInfo<Tlv::kJoinerAdvertisement>
1993 {
1994 public:
1995     static constexpr uint8_t kAdvDataMaxLength = OT_JOINER_ADVDATA_MAX_LENGTH; ///< The Max Length of AdvData
1996 
1997     /**
1998      * This method initializes the TLV.
1999      *
2000      */
Init(void)2001     void Init(void)
2002     {
2003         SetType(kJoinerAdvertisement);
2004         SetLength(sizeof(*this) - sizeof(Tlv));
2005     }
2006 
2007     /**
2008      * This method indicates whether or not the TLV appears to be well-formed.
2009      *
2010      * @retval TRUE   If the TLV appears to be well-formed.
2011      * @retval FALSE  If the TLV does not appear to be well-formed.
2012      *
2013      */
IsValid(void) const2014     bool IsValid(void) const { return GetLength() >= sizeof(mOui) && GetLength() <= sizeof(mOui) + sizeof(mAdvData); }
2015 
2016     /**
2017      * This method returns the Vendor OUI value.
2018      *
2019      * @returns The Vendor OUI value.
2020      *
2021      */
GetOui(void) const2022     uint32_t GetOui(void) const { return ReadUint24(mOui); }
2023 
2024     /**
2025      * This method sets the Vendor OUI value.
2026      *
2027      * @param[in]  aOui The Vendor OUI value.
2028      *
2029      */
SetOui(uint32_t aOui)2030     void SetOui(uint32_t aOui) { return WriteUint24(aOui, mOui); }
2031 
2032     /**
2033      * This method returns the Adv Data length.
2034      *
2035      * @returns The AdvData length.
2036      *
2037      */
GetAdvDataLength(void) const2038     uint8_t GetAdvDataLength(void) const { return GetLength() - sizeof(mOui); }
2039 
2040     /**
2041      * This method returns the Adv Data value.
2042      *
2043      * @returns A pointer to the Adv Data value.
2044      *
2045      */
GetAdvData(void) const2046     const uint8_t *GetAdvData(void) const { return mAdvData; }
2047 
2048     /**
2049      * This method sets the Adv Data value.
2050      *
2051      * @param[in]  aAdvData        A pointer to the AdvData value.
2052      * @param[in]  aAdvDataLength  The length of AdvData in bytes.
2053      *
2054      */
SetAdvData(const uint8_t * aAdvData,uint8_t aAdvDataLength)2055     void SetAdvData(const uint8_t *aAdvData, uint8_t aAdvDataLength)
2056     {
2057         OT_ASSERT((aAdvData != nullptr) && (aAdvDataLength > 0) && (aAdvDataLength <= kAdvDataMaxLength));
2058 
2059         SetLength(aAdvDataLength + sizeof(mOui));
2060         memcpy(mAdvData, aAdvData, aAdvDataLength);
2061     }
2062 
2063 private:
2064     uint8_t mOui[3];
2065     uint8_t mAdvData[kAdvDataMaxLength];
2066 } OT_TOOL_PACKED_END;
2067 
2068 } // namespace MeshCoP
2069 
2070 } // namespace ot
2071 
2072 #endif // MESHCOP_TLVS_HPP_
2073