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_tlvs.hpp"
58 #include "thread/mle_types.hpp"
59 
60 namespace ot {
61 namespace MeshCoP {
62 
63 /**
64  * 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      * Max length of Provisioning URL TLV.
121      *
122      */
123     static constexpr uint8_t kMaxProvisioningUrlLength = OT_PROVISIONING_URL_MAX_SIZE;
124 
125     static constexpr uint8_t kMaxCommissionerIdLength  = 64; ///< Max length of Commissioner ID TLV.
126     static constexpr uint8_t kMaxVendorNameLength      = 32; ///< Max length of Vendor Name TLV.
127     static constexpr uint8_t kMaxVendorModelLength     = 32; ///< Max length of Vendor Model TLV.
128     static constexpr uint8_t kMaxVendorSwVersionLength = 16; ///< Max length of Vendor SW Version TLV.
129     static constexpr uint8_t kMaxVendorDataLength      = 64; ///< Max length of Vendor Data TLV.
130 
131     /**
132      * Returns the Type value.
133      *
134      * @returns The Type value.
135      *
136      */
GetType(void) const137     Type GetType(void) const { return static_cast<Type>(ot::Tlv::GetType()); }
138 
139     /**
140      * Sets the Type value.
141      *
142      * @param[in]  aType  The Type value.
143      *
144      */
SetType(Type aType)145     void SetType(Type aType) { ot::Tlv::SetType(static_cast<uint8_t>(aType)); }
146 
147     /**
148      * Returns a pointer to the next TLV.
149      *
150      * @returns A pointer to the next TLV.
151      *
152      */
GetNext(void)153     Tlv *GetNext(void) { return As<Tlv>(ot::Tlv::GetNext()); }
154 
155     /**
156      * Returns a pointer to the next TLV.
157      *
158      * @returns A pointer to the next TLV.
159      *
160      */
GetNext(void) const161     const Tlv *GetNext(void) const { return As<Tlv>(ot::Tlv::GetNext()); }
162 
163 } OT_TOOL_PACKED_END;
164 
165 /**
166  * Implements extended MeshCoP TLV generation and parsing.
167  *
168  */
169 OT_TOOL_PACKED_BEGIN
170 class ExtendedTlv : public ot::ExtendedTlv
171 {
172 public:
173     /**
174      * Returns the Type value.
175      *
176      * @returns The Type value.
177      *
178      */
GetType(void) const179     MeshCoP::Tlv::Type GetType(void) const { return static_cast<MeshCoP::Tlv::Type>(ot::ExtendedTlv::GetType()); }
180 
181     /**
182      * Sets the Type value.
183      *
184      * @param[in]  aType  The Type value.
185      *
186      */
SetType(MeshCoP::Tlv::Type aType)187     void SetType(MeshCoP::Tlv::Type aType) { ot::ExtendedTlv::SetType(static_cast<uint8_t>(aType)); }
188 } OT_TOOL_PACKED_END;
189 
190 /**
191  * Defines Commissioner UDP Port TLV constants and types.
192  *
193  */
194 typedef UintTlvInfo<Tlv::kCommissionerUdpPort, uint16_t> CommissionerUdpPortTlv;
195 
196 /**
197  * Defines IPv6 Address TLV constants and types.
198  *
199  */
200 typedef SimpleTlvInfo<Tlv::kIp6Address, Ip6::Address> Ip6AddressTlv;
201 
202 /**
203  * Defines Joiner IID TLV constants and types.
204  *
205  */
206 typedef SimpleTlvInfo<Tlv::kJoinerIid, Ip6::InterfaceIdentifier> JoinerIidTlv;
207 
208 /**
209  * Defines Joiner Router Locator TLV constants and types.
210  *
211  */
212 typedef UintTlvInfo<Tlv::kJoinerRouterLocator, uint16_t> JoinerRouterLocatorTlv;
213 
214 /**
215  * Defines Joiner Router KEK TLV constants and types.
216  *
217  */
218 typedef SimpleTlvInfo<Tlv::kJoinerRouterKek, Kek> JoinerRouterKekTlv;
219 
220 /**
221  * Defines Count TLV constants and types.
222  *
223  */
224 typedef UintTlvInfo<Tlv::kCount, uint8_t> CountTlv;
225 
226 /**
227  * Defines Period TLV constants and types.
228  *
229  */
230 typedef UintTlvInfo<Tlv::kPeriod, uint16_t> PeriodTlv;
231 
232 /**
233  * Defines Scan Duration TLV constants and types.
234  *
235  */
236 typedef UintTlvInfo<Tlv::kScanDuration, uint16_t> ScanDurationTlv;
237 
238 /**
239  * Defines Commissioner ID TLV constants and types.
240  *
241  */
242 typedef StringTlvInfo<Tlv::kCommissionerId, Tlv::kMaxCommissionerIdLength> CommissionerIdTlv;
243 
244 /**
245  * Implements Channel TLV value format.
246  *
247  */
248 typedef Mle::ChannelTlvValue ChannelTlvValue;
249 
250 /**
251  * Defines Channel TLV constants and types.
252  *
253  */
254 typedef SimpleTlvInfo<Tlv::kChannel, ChannelTlvValue> ChannelTlv;
255 
256 /**
257  * Defines PAN ID TLV constants and types.
258  *
259  */
260 typedef UintTlvInfo<Tlv::kPanId, uint16_t> PanIdTlv;
261 
262 /**
263  * Defines Extended PAN ID TLV constants and types.
264  *
265  */
266 typedef SimpleTlvInfo<Tlv::kExtendedPanId, ExtendedPanId> ExtendedPanIdTlv;
267 
268 /**
269  * Implements Network Name TLV generation and parsing.
270  *
271  */
272 OT_TOOL_PACKED_BEGIN
273 class NetworkNameTlv : public Tlv, public TlvInfo<Tlv::kNetworkName>
274 {
275 public:
276     /**
277      * Initializes the TLV.
278      *
279      */
Init(void)280     void Init(void)
281     {
282         SetType(kNetworkName);
283         SetLength(sizeof(*this) - sizeof(Tlv));
284     }
285 
286     /**
287      * Indicates whether or not the TLV appears to be well-formed.
288      *
289      * @retval TRUE   If the TLV appears to be well-formed.
290      * @retval FALSE  If the TLV does not appear to be well-formed.
291      *
292      */
293     bool IsValid(void) const;
294 
295     /**
296      * Gets the Network Name value.
297      *
298      * @returns The Network Name value (as `NameData`).
299      *
300      */
301     NameData GetNetworkName(void) const;
302 
303     /**
304      * Sets the Network Name value.
305      *
306      * @param[in] aNameData   A Network Name value (as `NameData`).
307      *
308      */
309     void SetNetworkName(const NameData &aNameData);
310 
311 private:
312     char mNetworkName[NetworkName::kMaxSize];
313 } OT_TOOL_PACKED_END;
314 
315 /**
316  * Defines PSKc TLV constants and types.
317  *
318  */
319 typedef SimpleTlvInfo<Tlv::kPskc, Pskc> PskcTlv;
320 
321 /**
322  * Defines Network Key TLV constants and types.
323  *
324  */
325 typedef SimpleTlvInfo<Tlv::kNetworkKey, NetworkKey> NetworkKeyTlv;
326 
327 /**
328  * Defines Network Key Sequence TLV constants and types.
329  *
330  */
331 typedef UintTlvInfo<Tlv::kNetworkKeySequence, uint32_t> NetworkKeySequenceTlv;
332 
333 /**
334  * Defines Mesh Local Prefix TLV constants and types.
335  *
336  */
337 typedef SimpleTlvInfo<Tlv::kMeshLocalPrefix, Ip6::NetworkPrefix> MeshLocalPrefixTlv;
338 
339 class SteeringData;
340 
341 /**
342  * Implements Steering Data TLV generation and parsing.
343  *
344  */
345 OT_TOOL_PACKED_BEGIN
346 class SteeringDataTlv : public Tlv, public TlvInfo<Tlv::kSteeringData>
347 {
348 public:
349     /**
350      * Initializes the TLV.
351      *
352      */
Init(void)353     void Init(void)
354     {
355         SetType(kSteeringData);
356         SetLength(sizeof(*this) - sizeof(Tlv));
357         Clear();
358     }
359 
360     /**
361      * Indicates whether or not the TLV appears to be well-formed.
362      *
363      * @retval TRUE   If the TLV appears to be well-formed.
364      * @retval FALSE  If the TLV does not appear to be well-formed.
365      *
366      */
IsValid(void) const367     bool IsValid(void) const { return GetLength() > 0; }
368 
369     /**
370      * Returns the Steering Data length.
371      *
372      * @returns The Steering Data length.
373      *
374      */
GetSteeringDataLength(void) const375     uint8_t GetSteeringDataLength(void) const
376     {
377         return GetLength() <= sizeof(mSteeringData) ? GetLength() : sizeof(mSteeringData);
378     }
379 
380     /**
381      * Sets all bits in the Bloom Filter to zero.
382      *
383      */
Clear(void)384     void Clear(void) { memset(mSteeringData, 0, GetSteeringDataLength()); }
385 
386     /**
387      * Copies the Steering Data from the TLV into a given `SteeringData` variable.
388      *
389      * @param[out]  aSteeringData   A reference to a `SteeringData` to copy into.
390      *
391      */
392     void CopyTo(SteeringData &aSteeringData) const;
393 
394 private:
395     uint8_t mSteeringData[OT_STEERING_DATA_MAX_LENGTH];
396 } OT_TOOL_PACKED_END;
397 
398 /**
399  * Implements Border Agent Locator TLV generation and parsing.
400  *
401  */
402 OT_TOOL_PACKED_BEGIN
403 class BorderAgentLocatorTlv : public Tlv, public UintTlvInfo<Tlv::kBorderAgentLocator, uint16_t>
404 {
405 public:
406     /**
407      * Initializes the TLV.
408      *
409      */
Init(void)410     void Init(void)
411     {
412         SetType(kBorderAgentLocator);
413         SetLength(sizeof(*this) - sizeof(Tlv));
414     }
415 
416     /**
417      * Indicates whether or not the TLV appears to be well-formed.
418      *
419      * @retval TRUE   If the TLV appears to be well-formed.
420      * @retval FALSE  If the TLV does not appear to be well-formed.
421      *
422      */
IsValid(void) const423     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
424 
425     /**
426      * Returns the Border Agent Locator value.
427      *
428      * @returns The Border Agent Locator value.
429      *
430      */
GetBorderAgentLocator(void) const431     uint16_t GetBorderAgentLocator(void) const { return BigEndian::HostSwap16(mLocator); }
432 
433     /**
434      * Sets the Border Agent Locator value.
435      *
436      * @param[in]  aLocator  The Border Agent Locator value.
437      *
438      */
SetBorderAgentLocator(uint16_t aLocator)439     void SetBorderAgentLocator(uint16_t aLocator) { mLocator = BigEndian::HostSwap16(aLocator); }
440 
441 private:
442     uint16_t mLocator;
443 } OT_TOOL_PACKED_END;
444 
445 /**
446  * Implements Commissioner Session ID TLV generation and parsing.
447  *
448  */
449 OT_TOOL_PACKED_BEGIN
450 class CommissionerSessionIdTlv : public Tlv, public UintTlvInfo<Tlv::kCommissionerSessionId, uint16_t>
451 {
452 public:
453     /**
454      * Initializes the TLV.
455      *
456      */
Init(void)457     void Init(void)
458     {
459         SetType(kCommissionerSessionId);
460         SetLength(sizeof(*this) - sizeof(Tlv));
461     }
462 
463     /**
464      * Indicates whether or not the TLV appears to be well-formed.
465      *
466      * @retval TRUE   If the TLV appears to be well-formed.
467      * @retval FALSE  If the TLV does not appear to be well-formed.
468      *
469      */
IsValid(void) const470     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
471 
472     /**
473      * Returns the Commissioner Session ID value.
474      *
475      * @returns The Commissioner Session ID value.
476      *
477      */
GetCommissionerSessionId(void) const478     uint16_t GetCommissionerSessionId(void) const { return BigEndian::HostSwap16(mSessionId); }
479 
480     /**
481      * Sets the Commissioner Session ID value.
482      *
483      * @param[in]  aSessionId  The Commissioner Session ID value.
484      *
485      */
SetCommissionerSessionId(uint16_t aSessionId)486     void SetCommissionerSessionId(uint16_t aSessionId) { mSessionId = BigEndian::HostSwap16(aSessionId); }
487 
488 private:
489     uint16_t mSessionId;
490 } OT_TOOL_PACKED_END;
491 
492 /**
493  * Implements Security Policy TLV generation and parsing.
494  *
495  */
496 OT_TOOL_PACKED_BEGIN
497 class SecurityPolicyTlv : public Tlv, public TlvInfo<Tlv::kSecurityPolicy>
498 {
499 public:
500     /**
501      * Initializes the TLV.
502      *
503      */
Init(void)504     void Init(void)
505     {
506         SetType(kSecurityPolicy);
507         SetLength(sizeof(*this) - sizeof(Tlv));
508     }
509 
510     /**
511      * Indicates whether or not the TLV appears to be well-formed.
512      *
513      * @retval TRUE   If the TLV appears to be well-formed.
514      * @retval FALSE  If the TLV does not appear to be well-formed.
515      *
516      */
517     bool IsValid(void) const;
518 
519     /**
520      * Returns the Security Policy.
521      *
522      * @returns  The Security Policy.
523      *
524      */
525     SecurityPolicy GetSecurityPolicy(void) const;
526 
527     /**
528      * Sets the Security Policy.
529      *
530      * @param[in]  aSecurityPolicy  The Security Policy which will be set.
531      *
532      */
533     void SetSecurityPolicy(const SecurityPolicy &aSecurityPolicy);
534 
535 private:
536     static constexpr uint8_t kThread11FlagsLength = 1; // The Thread 1.1 Security Policy Flags length.
537     static constexpr uint8_t kThread12FlagsLength = 2; // The Thread 1.2 Security Policy Flags length.
538 
SetRotationTime(uint16_t aRotationTime)539     void     SetRotationTime(uint16_t aRotationTime) { mRotationTime = BigEndian::HostSwap16(aRotationTime); }
GetRotationTime(void) const540     uint16_t GetRotationTime(void) const { return BigEndian::HostSwap16(mRotationTime); }
GetFlagsLength(void) const541     uint8_t  GetFlagsLength(void) const { return GetLength() - sizeof(mRotationTime); }
542 
543     uint16_t mRotationTime;
544 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
545     uint8_t mFlags[kThread12FlagsLength];
546 #else
547     uint8_t mFlags[kThread11FlagsLength];
548 #endif
549 } OT_TOOL_PACKED_END;
550 
551 /**
552  * Defines Active Timestamp TLV constants and types.
553  *
554  */
555 typedef SimpleTlvInfo<Tlv::kActiveTimestamp, Timestamp> ActiveTimestampTlv;
556 
557 /**
558  * Implements State TLV generation and parsing.
559  *
560  */
561 class StateTlv : public UintTlvInfo<Tlv::kState, uint8_t>
562 {
563 public:
564     StateTlv(void) = delete;
565 
566     /**
567      * State values.
568      *
569      */
570     enum State : uint8_t
571     {
572         kReject  = 0xff, ///< Reject (-1)
573         kPending = 0,    ///< Pending
574         kAccept  = 1,    ///< Accept
575     };
576 
577     /**
578      * Converts a `State` to a string.
579      *
580      * @param[in] aState  An item state.
581      *
582      * @returns A string representation of @p aState.
583      *
584      */
585     static const char *StateToString(State aState);
586 };
587 
588 /**
589  * Defines Joiner UDP Port TLV constants and types.
590  *
591  */
592 typedef UintTlvInfo<Tlv::kJoinerUdpPort, uint16_t> JoinerUdpPortTlv;
593 
594 /**
595  * Defines Pending Timestamp TLV constants and types.
596  *
597  */
598 typedef SimpleTlvInfo<Tlv::kPendingTimestamp, Timestamp> PendingTimestampTlv;
599 
600 /**
601  * Defines Delay Timer TLV constants and types.
602  *
603  */
604 class DelayTimerTlv : public UintTlvInfo<Tlv::kDelayTimer, uint32_t>
605 {
606 public:
607     /**
608      * Minimum Delay Timer value (in msec).
609      *
610      */
611     static constexpr uint32_t kMinDelay = OPENTHREAD_CONFIG_TMF_PENDING_DATASET_MINIMUM_DELAY;
612 
613     /**
614      * Maximum Delay Timer value (in msec).
615      *
616      */
617     static constexpr uint32_t kMaxDelay = (72 * Time::kOneHourInMsec);
618 
619     /**
620      * Default Delay Timer value (in msec).
621      *
622      */
623     static constexpr uint32_t kDefaultDelay = OPENTHREAD_CONFIG_TMF_PENDING_DATASET_DEFAULT_DELAY;
624 
625     /**
626      * Calculates the remaining delay in milliseconds, based on the value read from a Delay Timer TLV and the specified
627      * update time.
628      *
629      * Ensures that the calculated delay does not exceed `kMaxDelay`. Also accounts for time already elapsed since
630      * @p aUpdateTime.
631      *
632      * Caller MUST ensure that @p aDelayTimerTlv is a Delay Timer TLV, otherwise behavior is undefined.
633      *
634      * @param[in] aDelayTimerTlv   The delay timer TLV to read delay from.
635      * @param[in] aUpdateTimer     The update time of the Dataset.
636      *
637      * @return The remaining delay (in msec).
638      *
639      */
640     static uint32_t CalculateRemainingDelay(const Tlv &aDelayTimerTlv, TimeMilli aUpdateTime);
641 
642     static_assert(kMinDelay <= kMaxDelay, "TMF_PENDING_DATASET_MINIMUM_DELAY is larger than max allowed");
643     static_assert(kDefaultDelay <= kMaxDelay, "TMF_PENDING_DATASET_DEFAULT_DELAY is larger than max allowed");
644     static_assert(kDefaultDelay >= kMinDelay, "TMF_PENDING_DATASET_DEFAULT_DELAY is smaller than min allowed");
645 };
646 
647 /**
648  * Implements Channel Mask TLV generation and parsing.
649  *
650  */
651 OT_TOOL_PACKED_BEGIN
652 class ChannelMaskTlv : public Tlv, public TlvInfo<Tlv::kChannelMask>
653 {
654     static constexpr uint8_t kEntryHeaderSize = 2; // Two bytes: mChannelPage and mMaskLength
655     static constexpr uint8_t kEntrySize       = kEntryHeaderSize + sizeof(uint32_t);
656 
657 public:
658     /**
659      * Represents Channel Mask TLV value to append.
660      *
661      */
662     struct Value
663     {
664         static constexpr uint16_t kMaxLength = (kEntrySize * Radio::kNumChannelPages); ///< Max value length.
665 
666         uint8_t mData[kMaxLength]; ///< Array to store TLV value (encoded as one or more Channel Mask TLV Entry)
667         uint8_t mLength;           ///< Value length in bytes.
668     };
669 
670     ChannelMaskTlv(void) = delete;
671 
672     /**
673      * Parses the Channel Mask TLV value and validates that all the included entries are well-formed.
674      *
675      * @returns TRUE if the TLV is well-formed, FALSE otherwise.
676      *
677      */
678     bool IsValid(void) const;
679 
680     /**
681      * Parses and retrieves the combined channel mask for all supported channel pages from entries in the TLV.
682      *
683      * @param[out] aChannelMask  A reference to return the channel mask.
684      *
685      * @retval kErrorNone   Successfully parsed the TLV value, @p aChannelMask is updated.
686      * @retval kErrorParse  TLV value is not well-formed.
687      *
688      */
689     Error ReadChannelMask(uint32_t &aChannelMask) const;
690 
691     /**
692      * Searches within a given message for Channel Mask TLV, parses and validates the TLV value and returns the
693      * combined channel mask for all supported channel pages included in the TLV.
694      *
695      * @param[in]  aMessage      The message to search in.
696      * @param[out] aChannelMask  A reference to return the channel mask.
697      *
698      * @retval kErrorNone       Found the TLV, successfully parsed its value, @p aChannelMask is updated.
699      * @retval kErrorNotFound   No Channel Mask TLV found in the @p aMessage.
700      * @retval kErrorParse      Found the TLV, but failed to parse it.
701      *
702      */
703     static Error FindIn(const Message &aMessage, uint32_t &aChannelMask);
704 
705     /**
706      * Prepares Channel Mask TLV value for appending/writing.
707      *
708      * @param[out] aValue        A reference to `Value` structure to populate.
709      * @param[in]  aChannelMask  The combined channel mask for all supported channel pages.
710      *
711      */
712     static void PrepareValue(Value &aValue, uint32_t aChannelMask);
713 
714     /**
715      * Prepares a Channel Mask TLV value and appends the TLV to a given message.
716      *
717      * @param[in] aMessage       The message to append to.
718      * @param[in] aChannelMask   The combined channel mask for all supported channel pages.
719      *
720      * @retval kErrorNone    Successfully prepared the Channel Mask TLV and appended it to @p aMessage.
721      * @retval kErrorNoBufs  Insufficient available buffers to grow the message.
722      *
723      */
724     static Error AppendTo(Message &aMessage, uint32_t aChannelMask);
725 
726 private:
727     static constexpr uint8_t kMaskLength = sizeof(uint32_t);
728 
729     OT_TOOL_PACKED_BEGIN
730     class Entry
731     {
732     public:
GetChannelPage(void) const733         uint8_t  GetChannelPage(void) const { return mChannelPage; }
SetChannelPage(uint8_t aChannelPage)734         void     SetChannelPage(uint8_t aChannelPage) { mChannelPage = aChannelPage; }
GetMaskLength(void) const735         uint8_t  GetMaskLength(void) const { return mMaskLength; }
SetMaskLength(uint8_t aMaskLength)736         void     SetMaskLength(uint8_t aMaskLength) { mMaskLength = aMaskLength; }
GetMask(void) const737         uint32_t GetMask(void) const { return Reverse32(BigEndian::HostSwap32(mMask)); }
SetMask(uint32_t aMask)738         void     SetMask(uint32_t aMask) { mMask = BigEndian::HostSwap32(Reverse32(aMask)); }
739 
740     private:
741         uint8_t  mChannelPage;
742         uint8_t  mMaskLength;
743         uint32_t mMask;
744     } OT_TOOL_PACKED_END;
745 
746     struct EntriesData : public Clearable<EntriesData>
747     {
748         // Represents received Channel Mask TLV Entries data which
749         // is either contained in `mData` buffer, or in `mMessage`
750         // at `mOffset`.
751 
752         Error Parse(uint32_t &aChannelMask);
753 
754         const uint8_t *mData;
755         const Message *mMessage;
756         uint16_t       mOffset;
757         uint16_t       mLength;
758     };
759 
760     uint8_t mEntriesStart;
761 } OT_TOOL_PACKED_BEGIN;
762 
763 /**
764  * Implements Energy List TLV generation and parsing.
765  *
766  */
767 OT_TOOL_PACKED_BEGIN
768 class EnergyListTlv : public Tlv, public TlvInfo<Tlv::kEnergyList>
769 {
770 public:
771     /**
772      * Initializes the TLV.
773      *
774      */
Init(void)775     void Init(void)
776     {
777         SetType(kEnergyList);
778         SetLength(sizeof(*this) - sizeof(Tlv));
779     }
780 
781     /**
782      * Indicates whether or not the TLV appears to be well-formed.
783      *
784      * @retval TRUE   If the TLV appears to be well-formed.
785      * @retval FALSE  If the TLV does not appear to be well-formed.
786      *
787      */
IsValid(void) const788     bool IsValid(void) const { return true; }
789 
790     /**
791      * Returns a pointer to the start of energy measurement list.
792      *
793      * @returns A pointer to the start start of energy energy measurement list.
794      *
795      */
GetEnergyList(void) const796     const uint8_t *GetEnergyList(void) const { return mEnergyList; }
797 
798     /**
799      * Returns the length of energy measurement list.
800      *
801      * @returns The length of energy measurement list.
802      *
803      */
GetEnergyListLength(void) const804     uint8_t GetEnergyListLength(void) const { return Min(kMaxListLength, GetLength()); }
805 
806 private:
807     static constexpr uint8_t kMaxListLength = OPENTHREAD_CONFIG_TMF_ENERGY_SCAN_MAX_RESULTS;
808 
809     uint8_t mEnergyList[kMaxListLength];
810 } OT_TOOL_PACKED_END;
811 
812 /**
813  * Defines Provisioning TLV constants and types.
814  *
815  */
816 typedef StringTlvInfo<Tlv::kProvisioningUrl, Tlv::kMaxProvisioningUrlLength> ProvisioningUrlTlv;
817 
818 /**
819  * Defines Vendor Name TLV constants and types.
820  *
821  */
822 typedef StringTlvInfo<Tlv::kVendorName, Tlv::kMaxVendorNameLength> VendorNameTlv;
823 
824 /**
825  * Defines Vendor Model TLV constants and types.
826  *
827  */
828 typedef StringTlvInfo<Tlv::kVendorModel, Tlv::kMaxVendorModelLength> VendorModelTlv;
829 
830 /**
831  * Defines Vendor SW Version TLV constants and types.
832  *
833  */
834 typedef StringTlvInfo<Tlv::kVendorSwVersion, Tlv::kMaxVendorSwVersionLength> VendorSwVersionTlv;
835 
836 /**
837  * Defines Vendor Data TLV constants and types.
838  *
839  */
840 typedef StringTlvInfo<Tlv::kVendorData, Tlv::kMaxVendorDataLength> VendorDataTlv;
841 
842 /**
843  * Implements Vendor Stack Version TLV generation and parsing.
844  *
845  */
846 OT_TOOL_PACKED_BEGIN
847 class VendorStackVersionTlv : public Tlv, public TlvInfo<Tlv::kVendorStackVersion>
848 {
849 public:
850     /**
851      * Default constructor.
852      *
853      */
VendorStackVersionTlv(void)854     VendorStackVersionTlv(void)
855         : mBuildRevision(0)
856         , mMinorMajor(0)
857     {
858     }
859 
860     /**
861      * Initializes the TLV.
862      *
863      */
Init(void)864     void Init(void)
865     {
866         SetType(kVendorStackVersion);
867         SetLength(sizeof(*this) - sizeof(Tlv));
868     }
869 
870     /**
871      * Indicates whether or not the TLV appears to be well-formed.
872      *
873      * @retval TRUE   If the TLV appears to be well-formed.
874      * @retval FALSE  If the TLV does not appear to be well-formed.
875      *
876      */
IsValid(void) const877     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
878 
879     /**
880      * Returns the Stack Vendor OUI value.
881      *
882      * @returns The Vendor Stack Vendor OUI value.
883      *
884      */
GetOui(void) const885     uint32_t GetOui(void) const { return BigEndian::ReadUint24(mOui); }
886 
887     /**
888      * Returns the Stack Vendor OUI value.
889      *
890      * @param[in]  aOui  The Vendor Stack Vendor OUI value.
891      *
892      */
SetOui(uint32_t aOui)893     void SetOui(uint32_t aOui) { BigEndian::WriteUint24(aOui, mOui); }
894 
895     /**
896      * Returns the Build value.
897      *
898      * @returns The Build value.
899      *
900      */
GetBuild(void) const901     uint16_t GetBuild(void) const { return (BigEndian::HostSwap16(mBuildRevision) & kBuildMask) >> kBuildOffset; }
902 
903     /**
904      * Sets the Build value.
905      *
906      * @param[in]  aBuild  The Build value.
907      *
908      */
SetBuild(uint16_t aBuild)909     void SetBuild(uint16_t aBuild)
910     {
911         mBuildRevision = BigEndian::HostSwap16((BigEndian::HostSwap16(mBuildRevision) & ~kBuildMask) |
912                                                ((aBuild << kBuildOffset) & kBuildMask));
913     }
914 
915     /**
916      * Returns the Revision value.
917      *
918      * @returns The Revision value.
919      *
920      */
GetRevision(void) const921     uint8_t GetRevision(void) const { return (BigEndian::HostSwap16(mBuildRevision) & kRevMask) >> kRevOffset; }
922 
923     /**
924      * Sets the Revision value.
925      *
926      * @param[in]  aRevision  The Revision value.
927      *
928      */
SetRevision(uint8_t aRevision)929     void SetRevision(uint8_t aRevision)
930     {
931         mBuildRevision = BigEndian::HostSwap16((BigEndian::HostSwap16(mBuildRevision) & ~kRevMask) |
932                                                ((aRevision << kRevOffset) & kRevMask));
933     }
934 
935     /**
936      * Returns the Minor value.
937      *
938      * @returns The Minor value.
939      *
940      */
GetMinor(void) const941     uint8_t GetMinor(void) const { return (mMinorMajor & kMinorMask) >> kMinorOffset; }
942 
943     /**
944      * Sets the Minor value.
945      *
946      * @param[in]  aMinor  The Minor value.
947      *
948      */
SetMinor(uint8_t aMinor)949     void SetMinor(uint8_t aMinor)
950     {
951         mMinorMajor = (mMinorMajor & ~kMinorMask) | ((aMinor << kMinorOffset) & kMinorMask);
952     }
953 
954     /**
955      * Returns the Major value.
956      *
957      * @returns The Major value.
958      *
959      */
GetMajor(void) const960     uint8_t GetMajor(void) const { return (mMinorMajor & kMajorMask) >> kMajorOffset; }
961 
962     /**
963      * Sets the Major value.
964      *
965      * @param[in] aMajor  The Major value.
966      *
967      */
SetMajor(uint8_t aMajor)968     void SetMajor(uint8_t aMajor)
969     {
970         mMinorMajor = (mMinorMajor & ~kMajorMask) | ((aMajor << kMajorOffset) & kMajorMask);
971     }
972 
973 private:
974     // For `mBuildRevision`
975     static constexpr uint8_t  kBuildOffset = 4;
976     static constexpr uint16_t kBuildMask   = 0xfff << kBuildOffset;
977     static constexpr uint8_t  kRevOffset   = 0;
978     static constexpr uint16_t kRevMask     = 0xf << kBuildOffset;
979 
980     // For `mMinorMajor`
981     static constexpr uint8_t kMinorOffset = 4;
982     static constexpr uint8_t kMinorMask   = 0xf << kMinorOffset;
983     static constexpr uint8_t kMajorOffset = 0;
984     static constexpr uint8_t kMajorMask   = 0xf << kMajorOffset;
985 
986     uint8_t  mOui[3];
987     uint16_t mBuildRevision;
988     uint8_t  mMinorMajor;
989 } OT_TOOL_PACKED_END;
990 
991 /**
992  * Defines UDP Encapsulation TLV types and constants.
993  *
994  */
995 typedef TlvInfo<MeshCoP::Tlv::kUdpEncapsulation> UdpEncapsulationTlv;
996 
997 /**
998  * Represents UDP Encapsulation TLV value header (source and destination ports).
999  *
1000  */
1001 OT_TOOL_PACKED_BEGIN
1002 class UdpEncapsulationTlvHeader
1003 {
1004 public:
1005     /**
1006      * Returns the source port.
1007      *
1008      * @returns The source port.
1009      *
1010      */
GetSourcePort(void) const1011     uint16_t GetSourcePort(void) const { return BigEndian::HostSwap16(mSourcePort); }
1012 
1013     /**
1014      * Updates the source port.
1015      *
1016      * @param[in]   aSourcePort     The source port.
1017      *
1018      */
SetSourcePort(uint16_t aSourcePort)1019     void SetSourcePort(uint16_t aSourcePort) { mSourcePort = BigEndian::HostSwap16(aSourcePort); }
1020 
1021     /**
1022      * Returns the destination port.
1023      *
1024      * @returns The destination port.
1025      *
1026      */
GetDestinationPort(void) const1027     uint16_t GetDestinationPort(void) const { return BigEndian::HostSwap16(mDestinationPort); }
1028 
1029     /**
1030      * Updates the destination port.
1031      *
1032      * @param[in]   aDestinationPort    The destination port.
1033      *
1034      */
SetDestinationPort(uint16_t aDestinationPort)1035     void SetDestinationPort(uint16_t aDestinationPort) { mDestinationPort = BigEndian::HostSwap16(aDestinationPort); }
1036 
1037 private:
1038     uint16_t mSourcePort;
1039     uint16_t mDestinationPort;
1040     // Followed by the UDP Payload.
1041 } OT_TOOL_PACKED_END;
1042 
1043 /**
1044  * Implements Discovery Request TLV generation and parsing.
1045  *
1046  */
1047 OT_TOOL_PACKED_BEGIN
1048 class DiscoveryRequestTlv : public Tlv, public TlvInfo<Tlv::kDiscoveryRequest>
1049 {
1050 public:
1051     /**
1052      * Initializes the TLV.
1053      *
1054      */
Init(void)1055     void Init(void)
1056     {
1057         SetType(kDiscoveryRequest);
1058         SetLength(sizeof(*this) - sizeof(Tlv));
1059         mFlags    = 0;
1060         mReserved = 0;
1061     }
1062 
1063     /**
1064      * Indicates whether or not the TLV appears to be well-formed.
1065      *
1066      * @retval TRUE   If the TLV appears to be well-formed.
1067      * @retval FALSE  If the TLV does not appear to be well-formed.
1068      *
1069      */
IsValid(void) const1070     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1071 
1072     /**
1073      * Returns the Version value.
1074      *
1075      * @returns The Version value.
1076      *
1077      */
GetVersion(void) const1078     uint8_t GetVersion(void) const { return mFlags >> kVersionOffset; }
1079 
1080     /**
1081      * Sets the Version value.
1082      *
1083      * @param[in]  aVersion  The Version value.
1084      *
1085      */
SetVersion(uint8_t aVersion)1086     void SetVersion(uint8_t aVersion)
1087     {
1088         mFlags = (mFlags & ~kVersionMask) | ((aVersion << kVersionOffset) & kVersionMask);
1089     }
1090 
1091     /**
1092      * Indicates whether or not the Joiner flag is set.
1093      *
1094      * @retval TRUE   If the Joiner flag is set.
1095      * @retval FALSE  If the Joiner flag is not set.
1096      *
1097      */
IsJoiner(void) const1098     bool IsJoiner(void) const { return (mFlags & kJoinerMask) != 0; }
1099 
1100     /**
1101      * Sets the Joiner flag.
1102      *
1103      * @param[in]  aJoiner  TRUE if set, FALSE otherwise.
1104      *
1105      */
SetJoiner(bool aJoiner)1106     void SetJoiner(bool aJoiner)
1107     {
1108         if (aJoiner)
1109         {
1110             mFlags |= kJoinerMask;
1111         }
1112         else
1113         {
1114             mFlags &= ~kJoinerMask;
1115         }
1116     }
1117 
1118 private:
1119     static constexpr uint8_t kVersionOffset = 4;
1120     static constexpr uint8_t kVersionMask   = 0xf << kVersionOffset;
1121     static constexpr uint8_t kJoinerOffset  = 3;
1122     static constexpr uint8_t kJoinerMask    = 1 << kJoinerOffset;
1123 
1124     uint8_t mFlags;
1125     uint8_t mReserved;
1126 } OT_TOOL_PACKED_END;
1127 
1128 /**
1129  * Implements Discovery Response TLV generation and parsing.
1130  *
1131  */
1132 OT_TOOL_PACKED_BEGIN
1133 class DiscoveryResponseTlv : public Tlv, public TlvInfo<Tlv::kDiscoveryResponse>
1134 {
1135 public:
1136     /**
1137      * Initializes the TLV.
1138      *
1139      */
Init(void)1140     void Init(void)
1141     {
1142         SetType(kDiscoveryResponse);
1143         SetLength(sizeof(*this) - sizeof(Tlv));
1144         mFlags    = 0;
1145         mReserved = 0;
1146     }
1147 
1148     /**
1149      * Indicates whether or not the TLV appears to be well-formed.
1150      *
1151      * @retval TRUE   If the TLV appears to be well-formed.
1152      * @retval FALSE  If the TLV does not appear to be well-formed.
1153      *
1154      */
IsValid(void) const1155     bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
1156 
1157     /**
1158      * Returns the Version value.
1159      *
1160      * @returns The Version value.
1161      *
1162      */
GetVersion(void) const1163     uint8_t GetVersion(void) const { return mFlags >> kVersionOffset; }
1164 
1165     /**
1166      * Sets the Version value.
1167      *
1168      * @param[in]  aVersion  The Version value.
1169      *
1170      */
SetVersion(uint8_t aVersion)1171     void SetVersion(uint8_t aVersion)
1172     {
1173         mFlags = (mFlags & ~kVersionMask) | ((aVersion << kVersionOffset) & kVersionMask);
1174     }
1175 
1176     /**
1177      * Indicates whether or not the Native Commissioner flag is set.
1178      *
1179      * @retval TRUE   If the Native Commissioner flag is set.
1180      * @retval FALSE  If the Native Commissioner flag is not set.
1181      *
1182      */
IsNativeCommissioner(void) const1183     bool IsNativeCommissioner(void) const { return (mFlags & kNativeMask) != 0; }
1184 
1185     /**
1186      * Sets the Native Commissioner flag.
1187      *
1188      * @param[in]  aNativeCommissioner  TRUE if set, FALSE otherwise.
1189      *
1190      */
SetNativeCommissioner(bool aNativeCommissioner)1191     void SetNativeCommissioner(bool aNativeCommissioner)
1192     {
1193         if (aNativeCommissioner)
1194         {
1195             mFlags |= kNativeMask;
1196         }
1197         else
1198         {
1199             mFlags &= ~kNativeMask;
1200         }
1201     }
1202 
1203     /**
1204      * Indicates whether or not the Commercial Commissioning Mode flag is set.
1205      *
1206      * @retval TRUE   If the Commercial Commissioning Mode flag is set.
1207      * @retval FALSE  If the Commercial Commissioning Mode flag is not set.
1208      *
1209      */
IsCommercialCommissioningMode(void) const1210     bool IsCommercialCommissioningMode(void) const { return (mFlags & kCcmMask) != 0; }
1211 
1212     /**
1213      * Sets the Commercial Commissioning Mode flag.
1214      *
1215      * @param[in]  aCcm  TRUE if set, FALSE otherwise.
1216      *
1217      */
SetCommercialCommissioningMode(bool aCcm)1218     void SetCommercialCommissioningMode(bool aCcm)
1219     {
1220         if (aCcm)
1221         {
1222             mFlags |= kCcmMask;
1223         }
1224         else
1225         {
1226             mFlags &= ~kCcmMask;
1227         }
1228     }
1229 
1230 private:
1231     static constexpr uint8_t kVersionOffset = 4;
1232     static constexpr uint8_t kVersionMask   = 0xf << kVersionOffset;
1233     static constexpr uint8_t kNativeOffset  = 3;
1234     static constexpr uint8_t kNativeMask    = 1 << kNativeOffset;
1235     static constexpr uint8_t kCcmOffset     = 2;
1236     static constexpr uint8_t kCcmMask       = 1 << kCcmOffset;
1237 
1238     uint8_t mFlags;
1239     uint8_t mReserved;
1240 } OT_TOOL_PACKED_END;
1241 
1242 /**
1243  * Implements Joiner Advertisement TLV generation and parsing.
1244  *
1245  */
1246 OT_TOOL_PACKED_BEGIN
1247 class JoinerAdvertisementTlv : public Tlv, public TlvInfo<Tlv::kJoinerAdvertisement>
1248 {
1249 public:
1250     static constexpr uint8_t kAdvDataMaxLength = OT_JOINER_ADVDATA_MAX_LENGTH; ///< The Max Length of AdvData
1251 
1252     /**
1253      * Initializes the TLV.
1254      *
1255      */
Init(void)1256     void Init(void)
1257     {
1258         SetType(kJoinerAdvertisement);
1259         SetLength(sizeof(*this) - sizeof(Tlv));
1260     }
1261 
1262     /**
1263      * Indicates whether or not the TLV appears to be well-formed.
1264      *
1265      * @retval TRUE   If the TLV appears to be well-formed.
1266      * @retval FALSE  If the TLV does not appear to be well-formed.
1267      *
1268      */
IsValid(void) const1269     bool IsValid(void) const { return GetLength() >= sizeof(mOui) && GetLength() <= sizeof(mOui) + sizeof(mAdvData); }
1270 
1271     /**
1272      * Returns the Vendor OUI value.
1273      *
1274      * @returns The Vendor OUI value.
1275      *
1276      */
GetOui(void) const1277     uint32_t GetOui(void) const { return BigEndian::ReadUint24(mOui); }
1278 
1279     /**
1280      * Sets the Vendor OUI value.
1281      *
1282      * @param[in]  aOui The Vendor OUI value.
1283      *
1284      */
SetOui(uint32_t aOui)1285     void SetOui(uint32_t aOui) { return BigEndian::WriteUint24(aOui, mOui); }
1286 
1287     /**
1288      * Returns the Adv Data length.
1289      *
1290      * @returns The AdvData length.
1291      *
1292      */
GetAdvDataLength(void) const1293     uint8_t GetAdvDataLength(void) const { return GetLength() - sizeof(mOui); }
1294 
1295     /**
1296      * Returns the Adv Data value.
1297      *
1298      * @returns A pointer to the Adv Data value.
1299      *
1300      */
GetAdvData(void) const1301     const uint8_t *GetAdvData(void) const { return mAdvData; }
1302 
1303     /**
1304      * Sets the Adv Data value.
1305      *
1306      * @param[in]  aAdvData        A pointer to the AdvData value.
1307      * @param[in]  aAdvDataLength  The length of AdvData in bytes.
1308      *
1309      */
SetAdvData(const uint8_t * aAdvData,uint8_t aAdvDataLength)1310     void SetAdvData(const uint8_t *aAdvData, uint8_t aAdvDataLength)
1311     {
1312         OT_ASSERT((aAdvData != nullptr) && (aAdvDataLength > 0) && (aAdvDataLength <= kAdvDataMaxLength));
1313 
1314         SetLength(aAdvDataLength + sizeof(mOui));
1315         memcpy(mAdvData, aAdvData, aAdvDataLength);
1316     }
1317 
1318 private:
1319     uint8_t mOui[3];
1320     uint8_t mAdvData[kAdvDataMaxLength];
1321 } OT_TOOL_PACKED_END;
1322 
1323 } // namespace MeshCoP
1324 
1325 } // namespace ot
1326 
1327 #endif // MESHCOP_TLVS_HPP_
1328