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