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 managing MeshCoP Datasets.
32 *
33 */
34
35 #ifndef MESHCOP_DATASET_HPP_
36 #define MESHCOP_DATASET_HPP_
37
38 #include "openthread-core-config.h"
39
40 #include <openthread/dataset.h>
41
42 #include "common/clearable.hpp"
43 #include "common/locator.hpp"
44 #include "common/message.hpp"
45 #include "common/timer.hpp"
46 #include "common/type_traits.hpp"
47 #include "meshcop/meshcop_tlvs.hpp"
48 #include "thread/mle_types.hpp"
49
50 namespace ot {
51 namespace MeshCoP {
52
53 /**
54 * This class represents MeshCop Dataset.
55 *
56 */
57 class Dataset
58 {
59 friend class DatasetLocal;
60
61 public:
62 static constexpr uint8_t kMaxSize = OT_OPERATIONAL_DATASET_MAX_LENGTH; ///< Max size of MeshCoP Dataset (bytes)
63 static constexpr uint8_t kMaxValueSize = 16; ///< Max size of a TLV value (bytes)
64 static constexpr uint8_t kMaxGetTypes = 64; ///< Max number of types in MGMT_GET.req
65
66 /**
67 * This enumeration represents the Dataset type (active or pending).
68 *
69 */
70 enum Type : uint8_t
71 {
72 kActive, ///< Active Dataset
73 kPending, ///< Pending Dataset
74 };
75
76 /**
77 * This class represents presence of different components in Active or Pending Operational Dataset.
78 *
79 */
80 class Components : public otOperationalDatasetComponents, public Clearable<Components>
81 {
82 public:
83 /**
84 * This method indicates whether or not the Active Timestamp is present in the Dataset.
85 *
86 * @returns TRUE if Active Timestamp is present, FALSE otherwise.
87 *
88 */
IsActiveTimestampPresent(void) const89 bool IsActiveTimestampPresent(void) const { return mIsActiveTimestampPresent; }
90
91 /**
92 * This method indicates whether or not the Pending Timestamp is present in the Dataset.
93 *
94 * @returns TRUE if Pending Timestamp is present, FALSE otherwise.
95 *
96 */
IsPendingTimestampPresent(void) const97 bool IsPendingTimestampPresent(void) const { return mIsPendingTimestampPresent; }
98
99 /**
100 * This method indicates whether or not the Network Key is present in the Dataset.
101 *
102 * @returns TRUE if Network Key is present, FALSE otherwise.
103 *
104 */
IsNetworkKeyPresent(void) const105 bool IsNetworkKeyPresent(void) const { return mIsNetworkKeyPresent; }
106
107 /**
108 * This method indicates whether or not the Network Name is present in the Dataset.
109 *
110 * @returns TRUE if Network Name is present, FALSE otherwise.
111 *
112 */
IsNetworkNamePresent(void) const113 bool IsNetworkNamePresent(void) const { return mIsNetworkNamePresent; }
114
115 /**
116 * This method indicates whether or not the Extended PAN ID is present in the Dataset.
117 *
118 * @returns TRUE if Extended PAN ID is present, FALSE otherwise.
119 *
120 */
IsExtendedPanIdPresent(void) const121 bool IsExtendedPanIdPresent(void) const { return mIsExtendedPanIdPresent; }
122
123 /**
124 * This method indicates whether or not the Mesh Local Prefix is present in the Dataset.
125 *
126 * @returns TRUE if Mesh Local Prefix is present, FALSE otherwise.
127 *
128 */
IsMeshLocalPrefixPresent(void) const129 bool IsMeshLocalPrefixPresent(void) const { return mIsMeshLocalPrefixPresent; }
130
131 /**
132 * This method indicates whether or not the Delay Timer is present in the Dataset.
133 *
134 * @returns TRUE if Delay Timer is present, FALSE otherwise.
135 *
136 */
IsDelayPresent(void) const137 bool IsDelayPresent(void) const { return mIsDelayPresent; }
138
139 /**
140 * This method indicates whether or not the PAN ID is present in the Dataset.
141 *
142 * @returns TRUE if PAN ID is present, FALSE otherwise.
143 *
144 */
IsPanIdPresent(void) const145 bool IsPanIdPresent(void) const { return mIsPanIdPresent; }
146
147 /**
148 * This method indicates whether or not the Channel is present in the Dataset.
149 *
150 * @returns TRUE if Channel is present, FALSE otherwise.
151 *
152 */
IsChannelPresent(void) const153 bool IsChannelPresent(void) const { return mIsChannelPresent; }
154
155 /**
156 * This method indicates whether or not the PSKc is present in the Dataset.
157 *
158 * @returns TRUE if PSKc is present, FALSE otherwise.
159 *
160 */
IsPskcPresent(void) const161 bool IsPskcPresent(void) const { return mIsPskcPresent; }
162
163 /**
164 * This method indicates whether or not the Security Policy is present in the Dataset.
165 *
166 * @returns TRUE if Security Policy is present, FALSE otherwise.
167 *
168 */
IsSecurityPolicyPresent(void) const169 bool IsSecurityPolicyPresent(void) const { return mIsSecurityPolicyPresent; }
170
171 /**
172 * This method indicates whether or not the Channel Mask is present in the Dataset.
173 *
174 * @returns TRUE if Channel Mask is present, FALSE otherwise.
175 *
176 */
IsChannelMaskPresent(void) const177 bool IsChannelMaskPresent(void) const { return mIsChannelMaskPresent; }
178 };
179
180 /**
181 * This type represents the information about the fields contained an Active or Pending Operational Dataset.
182 *
183 */
184 class Info : public otOperationalDataset, public Clearable<Info>
185 {
186 public:
187 /**
188 * This method indicates whether or not the Active Timestamp is present in the Dataset.
189 *
190 * @returns TRUE if Active Timestamp is present, FALSE otherwise.
191 *
192 */
IsActiveTimestampPresent(void) const193 bool IsActiveTimestampPresent(void) const { return mComponents.mIsActiveTimestampPresent; }
194
195 /**
196 * This method gets the Active Timestamp in the Dataset.
197 *
198 * This method MUST be used when Active Timestamp component is present in the Dataset, otherwise its behavior is
199 * undefined.
200 *
201 * @returns The Active Timestamp in the Dataset.
202 *
203 */
GetActiveTimestamp(void) const204 uint64_t GetActiveTimestamp(void) const { return mActiveTimestamp; }
205
206 /**
207 * This method sets the Active Timestamp in the Dataset.
208 *
209 * @param[in] aTimestamp A Timestamp value.
210 *
211 */
SetActiveTimestamp(uint64_t aTimestamp)212 void SetActiveTimestamp(uint64_t aTimestamp)
213 {
214 mActiveTimestamp = aTimestamp;
215 mComponents.mIsActiveTimestampPresent = true;
216 }
217
218 /**
219 * This method indicates whether or not the Pending Timestamp is present in the Dataset.
220 *
221 * @returns TRUE if Pending Timestamp is present, FALSE otherwise.
222 *
223 */
IsPendingTimestampPresent(void) const224 bool IsPendingTimestampPresent(void) const { return mComponents.mIsPendingTimestampPresent; }
225
226 /**
227 * This method gets the Pending Timestamp in the Dataset.
228 *
229 * This method MUST be used when Pending Timestamp component is present in the Dataset, otherwise its behavior
230 * is undefined.
231 *
232 * @returns The Pending Timestamp in the Dataset.
233 *
234 */
GetPendingTimestamp(void) const235 uint64_t GetPendingTimestamp(void) const { return mPendingTimestamp; }
236
237 /**
238 * This method sets the Pending Timestamp in the Dataset.
239 *
240 * @param[in] aTimestamp A Timestamp value.
241 *
242 */
SetPendingTimestamp(uint64_t aTimestamp)243 void SetPendingTimestamp(uint64_t aTimestamp)
244 {
245 mPendingTimestamp = aTimestamp;
246 mComponents.mIsPendingTimestampPresent = true;
247 }
248
249 /**
250 * This method indicates whether or not the Network Key is present in the Dataset.
251 *
252 * @returns TRUE if Network Key is present, FALSE otherwise.
253 *
254 */
IsNetworkKeyPresent(void) const255 bool IsNetworkKeyPresent(void) const { return mComponents.mIsNetworkKeyPresent; }
256
257 /**
258 * This method gets the Network Key in the Dataset.
259 *
260 * This method MUST be used when Network Key component is present in the Dataset, otherwise its behavior
261 * is undefined.
262 *
263 * @returns The Network Key in the Dataset.
264 *
265 */
GetNetworkKey(void) const266 const NetworkKey &GetNetworkKey(void) const { return static_cast<const NetworkKey &>(mNetworkKey); }
267
268 /**
269 * This method sets the Network Key in the Dataset.
270 *
271 * @param[in] aNetworkKey A Network Key.
272 *
273 */
SetNetworkKey(const NetworkKey & aNetworkKey)274 void SetNetworkKey(const NetworkKey &aNetworkKey)
275 {
276 mNetworkKey = aNetworkKey;
277 mComponents.mIsNetworkKeyPresent = true;
278 }
279
280 /**
281 * This method returns a reference to the Network Key in the Dataset to be updated by caller.
282 *
283 * @returns A reference to the Network Key in the Dataset.
284 *
285 */
UpdateNetworkKey(void)286 NetworkKey &UpdateNetworkKey(void)
287 {
288 mComponents.mIsNetworkKeyPresent = true;
289 return static_cast<NetworkKey &>(mNetworkKey);
290 }
291
292 /**
293 * This method indicates whether or not the Network Name is present in the Dataset.
294 *
295 * @returns TRUE if Network Name is present, FALSE otherwise.
296 *
297 */
IsNetworkNamePresent(void) const298 bool IsNetworkNamePresent(void) const { return mComponents.mIsNetworkNamePresent; }
299
300 /**
301 * This method gets the Network Name in the Dataset.
302 *
303 * This method MUST be used when Network Name component is present in the Dataset, otherwise its behavior is
304 * undefined.
305 *
306 * @returns The Network Name in the Dataset.
307 *
308 */
GetNetworkName(void) const309 const Mac::NetworkName &GetNetworkName(void) const
310 {
311 return static_cast<const Mac::NetworkName &>(mNetworkName);
312 }
313
314 /**
315 * This method sets the Network Name in the Dataset.
316 *
317 * @param[in] aNetworkNameData A Network Name Data.
318 *
319 */
SetNetworkName(const Mac::NameData & aNetworkNameData)320 void SetNetworkName(const Mac::NameData &aNetworkNameData)
321 {
322 IgnoreError(static_cast<Mac::NetworkName &>(mNetworkName).Set(aNetworkNameData));
323 mComponents.mIsNetworkNamePresent = true;
324 }
325
326 /**
327 * This method indicates whether or not the Extended PAN ID is present in the Dataset.
328 *
329 * @returns TRUE if Extended PAN ID is present, FALSE otherwise.
330 *
331 */
IsExtendedPanIdPresent(void) const332 bool IsExtendedPanIdPresent(void) const { return mComponents.mIsExtendedPanIdPresent; }
333
334 /**
335 * This method gets the Extended PAN ID in the Dataset.
336 *
337 * This method MUST be used when Extended PAN ID component is present in the Dataset, otherwise its behavior is
338 * undefined.
339 *
340 * @returns The Extended PAN ID in the Dataset.
341 *
342 */
GetExtendedPanId(void) const343 const Mac::ExtendedPanId &GetExtendedPanId(void) const
344 {
345 return static_cast<const Mac::ExtendedPanId &>(mExtendedPanId);
346 }
347
348 /**
349 * This method sets the Extended PAN ID in the Dataset.
350 *
351 * @param[in] aExtendedPanId An Extended PAN ID.
352 *
353 */
SetExtendedPanId(const Mac::ExtendedPanId & aExtendedPanId)354 void SetExtendedPanId(const Mac::ExtendedPanId &aExtendedPanId)
355 {
356 mExtendedPanId = aExtendedPanId;
357 mComponents.mIsExtendedPanIdPresent = true;
358 }
359
360 /**
361 * This method indicates whether or not the Mesh Local Prefix is present in the Dataset.
362 *
363 * @returns TRUE if Mesh Local Prefix is present, FALSE otherwise.
364 *
365 */
IsMeshLocalPrefixPresent(void) const366 bool IsMeshLocalPrefixPresent(void) const { return mComponents.mIsMeshLocalPrefixPresent; }
367
368 /**
369 * This method gets the Mesh Local Prefix in the Dataset.
370 *
371 * This method MUST be used when Mesh Local Prefix component is present in the Dataset, otherwise its behavior
372 * is undefined.
373 *
374 * @returns The Mesh Local Prefix in the Dataset.
375 *
376 */
GetMeshLocalPrefix(void) const377 const Mle::MeshLocalPrefix &GetMeshLocalPrefix(void) const
378 {
379 return static_cast<const Mle::MeshLocalPrefix &>(mMeshLocalPrefix);
380 }
381
382 /**
383 * This method sets the Mesh Local Prefix in the Dataset.
384 *
385 * @param[in] aMeshLocalPrefix A Mesh Local Prefix.
386 *
387 */
SetMeshLocalPrefix(const Mle::MeshLocalPrefix & aMeshLocalPrefix)388 void SetMeshLocalPrefix(const Mle::MeshLocalPrefix &aMeshLocalPrefix)
389 {
390 mMeshLocalPrefix = aMeshLocalPrefix;
391 mComponents.mIsMeshLocalPrefixPresent = true;
392 }
393
394 /**
395 * This method indicates whether or not the Delay Timer is present in the Dataset.
396 *
397 * @returns TRUE if Delay Timer is present, FALSE otherwise.
398 *
399 */
IsDelayPresent(void) const400 bool IsDelayPresent(void) const { return mComponents.mIsDelayPresent; }
401
402 /**
403 * This method gets the Delay Timer in the Dataset.
404 *
405 * This method MUST be used when Delay Timer component is present in the Dataset, otherwise its behavior is
406 * undefined.
407 *
408 * @returns The Delay Timer in the Dataset.
409 *
410 */
GetDelay(void) const411 uint32_t GetDelay(void) const { return mDelay; }
412
413 /**
414 * This method sets the Delay Timer in the Dataset.
415 *
416 * @param[in] aDely A Delay value.
417 *
418 */
SetDelay(uint32_t aDelay)419 void SetDelay(uint32_t aDelay)
420 {
421 mDelay = aDelay;
422 mComponents.mIsDelayPresent = true;
423 }
424
425 /**
426 * This method indicates whether or not the PAN ID is present in the Dataset.
427 *
428 * @returns TRUE if PAN ID is present, FALSE otherwise.
429 *
430 */
IsPanIdPresent(void) const431 bool IsPanIdPresent(void) const { return mComponents.mIsPanIdPresent; }
432
433 /**
434 * This method gets the PAN ID in the Dataset.
435 *
436 * This method MUST be used when PAN ID component is present in the Dataset, otherwise its behavior is
437 * undefined.
438 *
439 * @returns The PAN ID in the Dataset.
440 *
441 */
GetPanId(void) const442 Mac::PanId GetPanId(void) const { return mPanId; }
443
444 /**
445 * This method sets the PAN ID in the Dataset.
446 *
447 * @param[in] aPanId A PAN ID.
448 *
449 */
SetPanId(Mac::PanId aPanId)450 void SetPanId(Mac::PanId aPanId)
451 {
452 mPanId = aPanId;
453 mComponents.mIsPanIdPresent = true;
454 }
455
456 /**
457 * This method indicates whether or not the Channel is present in the Dataset.
458 *
459 * @returns TRUE if Channel is present, FALSE otherwise.
460 *
461 */
IsChannelPresent(void) const462 bool IsChannelPresent(void) const { return mComponents.mIsChannelPresent; }
463
464 /**
465 * This method gets the Channel in the Dataset.
466 *
467 * This method MUST be used when Channel component is present in the Dataset, otherwise its behavior is
468 * undefined.
469 *
470 * @returns The Channel in the Dataset.
471 *
472 */
GetChannel(void) const473 uint16_t GetChannel(void) const { return mChannel; }
474
475 /**
476 * This method sets the Channel in the Dataset.
477 *
478 * @param[in] aChannel A Channel.
479 *
480 */
SetChannel(uint16_t aChannel)481 void SetChannel(uint16_t aChannel)
482 {
483 mChannel = aChannel;
484 mComponents.mIsChannelPresent = true;
485 }
486
487 /**
488 * This method indicates whether or not the PSKc is present in the Dataset.
489 *
490 * @returns TRUE if PSKc is present, FALSE otherwise.
491 *
492 */
IsPskcPresent(void) const493 bool IsPskcPresent(void) const { return mComponents.mIsPskcPresent; }
494
495 /**
496 * This method gets the PSKc in the Dataset.
497 *
498 * This method MUST be used when PSKc component is present in the Dataset, otherwise its behavior is undefined.
499 *
500 * @returns The PSKc in the Dataset.
501 *
502 */
GetPskc(void) const503 const Pskc &GetPskc(void) const { return static_cast<const Pskc &>(mPskc); }
504
505 /**
506 * This method set the PSKc in the Dataset.
507 *
508 * @param[in] aPskc A PSKc value.
509 *
510 */
SetPskc(const Pskc & aPskc)511 void SetPskc(const Pskc &aPskc)
512 {
513 mPskc = aPskc;
514 mComponents.mIsPskcPresent = true;
515 }
516
517 /**
518 * This method indicates whether or not the Security Policy is present in the Dataset.
519 *
520 * @returns TRUE if Security Policy is present, FALSE otherwise.
521 *
522 */
IsSecurityPolicyPresent(void) const523 bool IsSecurityPolicyPresent(void) const { return mComponents.mIsSecurityPolicyPresent; }
524
525 /**
526 * This method gets the Security Policy in the Dataset.
527 *
528 * This method MUST be used when Security Policy component is present in the Dataset, otherwise its behavior is
529 * undefined.
530 *
531 * @returns The Security Policy in the Dataset.
532 *
533 */
GetSecurityPolicy(void) const534 const SecurityPolicy &GetSecurityPolicy(void) const
535 {
536 return static_cast<const SecurityPolicy &>(mSecurityPolicy);
537 }
538
539 /**
540 * This method sets the Security Policy in the Dataset.
541 *
542 * @param[in] aSecurityPolicy A Security Policy to set in Dataset.
543 *
544 */
SetSecurityPolicy(const SecurityPolicy & aSecurityPolicy)545 void SetSecurityPolicy(const SecurityPolicy &aSecurityPolicy)
546 {
547 mSecurityPolicy = aSecurityPolicy;
548 mComponents.mIsSecurityPolicyPresent = true;
549 }
550
551 /**
552 * This method indicates whether or not the Channel Mask is present in the Dataset.
553 *
554 * @returns TRUE if Channel Mask is present, FALSE otherwise.
555 *
556 */
IsChannelMaskPresent(void) const557 bool IsChannelMaskPresent(void) const { return mComponents.mIsChannelMaskPresent; }
558
559 /**
560 * This method gets the Channel Mask in the Dataset.
561 *
562 * This method MUST be used when Channel Mask component is present in the Dataset, otherwise its behavior is
563 * undefined.
564 *
565 * @returns The Channel Mask in the Dataset.
566 *
567 */
GetChannelMask(void) const568 otChannelMask GetChannelMask(void) const { return mChannelMask; }
569
570 /**
571 * This method sets the Channel Mask in the Dataset.
572 *
573 * @param[in] aChannelMask A Channel Mask value.
574 *
575 */
SetChannelMask(otChannelMask aChannelMask)576 void SetChannelMask(otChannelMask aChannelMask)
577 {
578 mChannelMask = aChannelMask;
579 mComponents.mIsChannelMaskPresent = true;
580 }
581
582 /**
583 * This method populates the Dataset with random fields.
584 *
585 * The Network Key, PSKc, Mesh Local Prefix, PAN ID, and Extended PAN ID are generated randomly (crypto-secure)
586 * with Network Name set to "OpenThread-%04x" with PAN ID appended as hex. The Channel is chosen randomly from
587 * radio's preferred channel mask, Channel Mask is set from radio's supported mask, and Security Policy Flags
588 * from current `KeyManager` value.
589 *
590 * @param[in] aInstance The OpenThread instance.
591 *
592 * @retval kErrorNone If the Dataset was generated successfully.
593 *
594 */
595 Error GenerateRandom(Instance &aInstance);
596
597 /**
598 * This method checks whether the Dataset is a subset of another one, i.e., all the components in the current
599 * Dataset are also present in the @p aOther and the component values fully match.
600 *
601 * The matching of components in the two Datasets excludes Active/Pending Timestamp and Delay components.
602 *
603 * @param[in] aOther The other Dataset to check against.
604 *
605 * @retval TRUE The current dataset is a subset of @p aOther.
606 * @retval FALSE The current Dataset is not a subset of @p aOther.
607 *
608 */
609 bool IsSubsetOf(const Info &aOther) const;
610 };
611
612 /**
613 * This constructor initializes the object.
614 *
615 */
616 Dataset(void);
617
618 /**
619 * This method clears the Dataset.
620 *
621 */
622 void Clear(void);
623
624 /**
625 * This method indicates whether or not the dataset appears to be well-formed.
626 *
627 * @returns TRUE if the dataset appears to be well-formed, FALSE otherwise.
628 *
629 */
630 bool IsValid(void) const;
631
632 /**
633 * This method returns a pointer to the TLV with a given type.
634 *
635 * @param[in] aType A TLV type.
636 *
637 * @returns A pointer to the TLV or nullptr if none is found.
638 *
639 */
GetTlv(Tlv::Type aType)640 Tlv *GetTlv(Tlv::Type aType) { return const_cast<Tlv *>(const_cast<const Dataset *>(this)->GetTlv(aType)); }
641
642 /**
643 * This method returns a pointer to the TLV with a given type.
644 *
645 * @param[in] aType The TLV type.
646 *
647 * @returns A pointer to the TLV or nullptr if none is found.
648 *
649 */
650 const Tlv *GetTlv(Tlv::Type aType) const;
651
652 /**
653 * This template method returns a pointer to the TLV with a given template type `TlvType`
654 *
655 * @returns A pointer to the TLV or nullptr if none is found.
656 *
657 */
GetTlv(void)658 template <typename TlvType> TlvType *GetTlv(void)
659 {
660 return static_cast<TlvType *>(GetTlv(static_cast<Tlv::Type>(TlvType::kType)));
661 }
662
663 /**
664 * This template method returns a pointer to the TLV with a given template type `TlvType`
665 *
666 * @returns A pointer to the TLV or nullptr if none is found.
667 *
668 */
GetTlv(void) const669 template <typename TlvType> const TlvType *GetTlv(void) const
670 {
671 return static_cast<const TlvType *>(GetTlv(static_cast<Tlv::Type>(TlvType::kType)));
672 }
673
674 /**
675 * This method returns a pointer to the byte representation of the Dataset.
676 *
677 * @returns A pointer to the byte representation of the Dataset.
678 *
679 */
GetBytes(void)680 uint8_t *GetBytes(void) { return mTlvs; }
681
682 /**
683 * This method returns a pointer to the byte representation of the Dataset.
684 *
685 * @returns A pointer to the byte representation of the Dataset.
686 *
687 */
GetBytes(void) const688 const uint8_t *GetBytes(void) const { return mTlvs; }
689
690 /**
691 * This method converts the TLV representation to structure representation.
692 *
693 * @param[out] aDatasetInfo A reference to `Info` object to output the Dataset.
694 *
695 */
696 void ConvertTo(Info &aDatasetInfo) const;
697
698 /**
699 * This method converts the TLV representation to structure representation.
700 *
701 * @param[out] aDataset A reference to `otOperationalDatasetTlvs` to output the Dataset.
702 *
703 */
704 void ConvertTo(otOperationalDatasetTlvs &aDataset) const;
705
706 /**
707 * This method returns the Dataset size in bytes.
708 *
709 * @returns The Dataset size in bytes.
710 *
711 */
GetSize(void) const712 uint16_t GetSize(void) const { return mLength; }
713
714 /**
715 * This method sets the Dataset size in bytes.
716 *
717 * @param[in] aSize The Dataset size in bytes.
718 *
719 */
SetSize(uint16_t aSize)720 void SetSize(uint16_t aSize) { mLength = aSize; }
721
722 /**
723 * This method returns the local time the dataset was last updated.
724 *
725 * @returns The local time the dataset was last updated.
726 *
727 */
GetUpdateTime(void) const728 TimeMilli GetUpdateTime(void) const { return mUpdateTime; }
729
730 /**
731 * This method returns a reference to the Timestamp.
732 *
733 * @param[in] aType The type of the dataset, active or pending.
734 *
735 * @returns A pointer to the Timestamp.
736 *
737 */
738 const Timestamp *GetTimestamp(Type aType) const;
739
740 /**
741 * This method sets the Timestamp value.
742 *
743 * @param[in] aType The type of the dataset, active or pending.
744 * @param[in] aTimestamp A Timestamp.
745 *
746 */
747 void SetTimestamp(Type aType, const Timestamp &aTimestamp);
748
749 /**
750 * This method sets a TLV in the Dataset.
751 *
752 * @param[in] aTlv A reference to the TLV.
753 *
754 * @retval kErrorNone Successfully set the TLV.
755 * @retval kErrorNoBufs Could not set the TLV due to insufficient buffer space.
756 *
757 */
758 Error SetTlv(const Tlv &aTlv);
759
760 /**
761 * This method sets a TLV with a given TLV Type and Value.
762 *
763 * @param[in] aType The TLV Type.
764 * @param[in] aValue A pointer to TLV Value.
765 * @param[in] aLength The TLV Length in bytes (length of @p aValue).
766 *
767 * @retval kErrorNone Successfully set the TLV.
768 * @retval kErrorNoBufs Could not set the TLV due to insufficient buffer space.
769 *
770 */
771 Error SetTlv(Tlv::Type aType, const void *aValue, uint8_t aLength);
772
773 /**
774 * This template method sets a TLV with a given TLV Type and Value.
775 *
776 * @tparam ValueType The type of TLV's Value.
777 *
778 * @param[in] aType The TLV Type.
779 * @param[in] aValue The TLV Value (of type `ValueType`).
780 *
781 * @retval kErrorNone Successfully set the TLV.
782 * @retval kErrorNoBufs Could not set the TLV due to insufficient buffer space.
783 *
784 */
SetTlv(Tlv::Type aType,const ValueType & aValue)785 template <typename ValueType> Error SetTlv(Tlv::Type aType, const ValueType &aValue)
786 {
787 static_assert(!TypeTraits::IsPointer<ValueType>::kValue, "ValueType must not be a pointer");
788
789 return SetTlv(aType, &aValue, sizeof(ValueType));
790 }
791
792 /**
793 * This method sets the Dataset using TLVs stored in a message buffer.
794 *
795 * @param[in] aMessage The message buffer.
796 * @param[in] aOffset The message buffer offset where the dataset starts.
797 * @param[in] aLength The TLVs length in the message buffer in bytes.
798 *
799 * @retval kErrorNone Successfully set the Dataset.
800 * @retval kErrorInvalidArgs The values of @p aOffset and @p aLength are not valid for @p aMessage.
801 *
802 */
803 Error Set(const Message &aMessage, uint16_t aOffset, uint8_t aLength);
804
805 /**
806 * This method sets the Dataset using an existing Dataset.
807 *
808 * If this Dataset is an Active Dataset, any Pending Timestamp and Delay Timer TLVs will be omitted in the copy
809 * from @p aDataset.
810 *
811 * @param[in] aType The type of the dataset, active or pending.
812 * @param[in] aDataset The input Dataset.
813 *
814 */
815 void Set(Type aType, const Dataset &aDataset);
816
817 /**
818 * This method sets the Dataset from a given structure representation.
819 *
820 * @param[in] aDatasetInfo The input Dataset as `Dataset::Info`.
821 *
822 * @retval kErrorNone Successfully set the Dataset.
823 * @retval kErrorInvalidArgs Dataset is missing Active and/or Pending Timestamp.
824 *
825 */
826 Error SetFrom(const Info &aDatasetInfo);
827
828 /**
829 * This method sets the Dataset using @p aDataset.
830 *
831 * @param[in] aDataset The input Dataset as otOperationalDatasetTlvs.
832 *
833 */
834 void SetFrom(const otOperationalDatasetTlvs &aDataset);
835
836 /**
837 * This method removes a TLV from the Dataset.
838 *
839 * @param[in] aType The type of a specific TLV.
840 *
841 */
842 void RemoveTlv(Tlv::Type aType);
843
844 /**
845 * This method appends the MLE Dataset TLV but excluding MeshCoP Sub Timestamp TLV.
846 *
847 * @param[in] aType The type of the dataset, active or pending.
848 * @param[in] aMessage A message to append to.
849 *
850 * @retval kErrorNone Successfully append MLE Dataset TLV without MeshCoP Sub Timestamp TLV.
851 * @retval kErrorNoBufs Insufficient available buffers to append the message with MLE Dataset TLV.
852 *
853 */
854 Error AppendMleDatasetTlv(Type aType, Message &aMessage) const;
855
856 /**
857 * This method applies the Active or Pending Dataset to the Thread interface.
858 *
859 * @param[in] aInstance A reference to the OpenThread instance.
860 * @param[out] aIsNetworkKeyUpdated A pointer to where to place whether network key was updated.
861 *
862 * @retval kErrorNone Successfully applied configuration.
863 * @retval kErrorParse The dataset has at least one TLV with invalid format.
864 *
865 */
866 Error ApplyConfiguration(Instance &aInstance, bool *aIsNetworkKeyUpdated = nullptr) const;
867
868 /**
869 * This method converts a Pending Dataset to an Active Dataset.
870 *
871 * This method removes the Delay Timer and Pending Timestamp TLVs
872 *
873 */
874 void ConvertToActive(void);
875
876 /**
877 * This method returns a pointer to the start of Dataset TLVs sequence.
878 *
879 * @return A pointer to the start of Dataset TLVs sequence.
880 *
881 */
GetTlvsStart(void)882 Tlv *GetTlvsStart(void) { return reinterpret_cast<Tlv *>(mTlvs); }
883
884 /**
885 * This method returns a pointer to the start of Dataset TLVs sequence.
886 *
887 * @return A pointer to start of Dataset TLVs sequence.
888 *
889 */
GetTlvsStart(void) const890 const Tlv *GetTlvsStart(void) const { return reinterpret_cast<const Tlv *>(mTlvs); }
891
892 /**
893 * This method returns a pointer to the past-the-end of Dataset TLVs sequence.
894 *
895 * Note that past-the-end points to the byte after the end of the last TLV in Dataset TLVs sequence.
896 *
897 * @return A pointer to past-the-end of Dataset TLVs sequence.
898 *
899 */
GetTlvsEnd(void)900 Tlv *GetTlvsEnd(void) { return reinterpret_cast<Tlv *>(mTlvs + mLength); }
901
902 /**
903 * This method returns a pointer to the past-the-end of Dataset TLVs sequence.
904 *
905 * Note that past-the-end points to the byte after the end of the last TLV in Dataset TLVs sequence.
906 *
907 * @return A pointer to past-the-end of Dataset TLVs sequence.
908 *
909 */
GetTlvsEnd(void) const910 const Tlv *GetTlvsEnd(void) const { return reinterpret_cast<const Tlv *>(mTlvs + mLength); }
911
912 /**
913 * This static method converts a Dataset Type to a string.
914 *
915 * @param[in] aType A Dataset type.
916 *
917 */
918 static const char *TypeToString(Type aType);
919
920 private:
921 void RemoveTlv(Tlv *aTlv);
922
923 uint8_t mTlvs[kMaxSize]; ///< The Dataset buffer
924 TimeMilli mUpdateTime; ///< Local time last updated
925 uint16_t mLength; ///< The number of valid bytes in @var mTlvs
926 };
927
928 /**
929 * This is a template specialization of `SetTlv<ValueType>` with a `uint16_t` value type.
930 *
931 * @param[in] aType The TLV Type.
932 * @param[in] aValue The TLV value (as `uint16_t`).
933 *
934 * @retval kErrorNone Successfully set the TLV.
935 * @retval kErrorNoBufs Could not set the TLV due to insufficient buffer space.
936 *
937 */
SetTlv(Tlv::Type aType,const uint16_t & aValue)938 template <> inline Error Dataset::SetTlv(Tlv::Type aType, const uint16_t &aValue)
939 {
940 uint16_t value = Encoding::BigEndian::HostSwap16(aValue);
941
942 return SetTlv(aType, &value, sizeof(uint16_t));
943 }
944
945 /**
946 * This is a template specialization of `SetTlv<ValueType>` with a `uint32_t` value type
947 *
948 * @param[in] aType The TLV Type.
949 * @param[in] aValue The TLV value (as `uint32_t`).
950 *
951 * @retval kErrorNone Successfully set the TLV.
952 * @retval kErrorNoBufs Could not set the TLV due to insufficient buffer space.
953 *
954 */
SetTlv(Tlv::Type aType,const uint32_t & aValue)955 template <> inline Error Dataset::SetTlv(Tlv::Type aType, const uint32_t &aValue)
956 {
957 uint32_t value = Encoding::BigEndian::HostSwap32(aValue);
958
959 return SetTlv(aType, &value, sizeof(uint32_t));
960 }
961
962 } // namespace MeshCoP
963 } // namespace ot
964
965 #endif // MESHCOP_DATASET_HPP_
966