• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 non-volatile storage of settings.
32  */
33 
34 #ifndef SETTINGS_HPP_
35 #define SETTINGS_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include <openthread/platform/settings.h>
40 
41 #include "common/clearable.hpp"
42 #include "common/encoding.hpp"
43 #include "common/equatable.hpp"
44 #include "common/locator.hpp"
45 #include "common/log.hpp"
46 #include "common/non_copyable.hpp"
47 #include "common/settings_driver.hpp"
48 #include "crypto/ecdsa.hpp"
49 #include "mac/mac_types.hpp"
50 #include "meshcop/dataset.hpp"
51 #include "net/ip6_address.hpp"
52 #include "utils/flash.hpp"
53 #include "utils/slaac_address.hpp"
54 
55 namespace ot {
56 
57 class Settings;
58 
59 /**
60  * This class defines the base class used by `Settings` and `Settings::ChildInfoIterator`.
61  *
62  * This class provides structure definitions for different settings keys.
63  *
64  */
65 class SettingsBase : public InstanceLocator
66 {
67 protected:
68     enum Action : uint8_t
69     {
70         kActionRead,
71         kActionSave,
72         kActionResave,
73         kActionDelete,
74 #if OPENTHREAD_FTD
75         kActionAdd,
76         kActionRemove,
77         kActionDeleteAll,
78 #endif
79     };
80 
81 public:
82     /**
83      * Rules for updating existing value structures.
84      *
85      * 1. Modifying existing key value fields in settings MUST only be
86      *    done by appending new fields.  Existing fields MUST NOT be
87      *    deleted or modified in any way.
88      *
89      * 2. To support backward compatibility (rolling back to an older
90      *    software version), code reading and processing key values MUST
91      *    process key values that have longer length.  Additionally, newer
92      *    versions MUST update/maintain values in existing key value
93      *    fields.
94      *
95      * 3. To support forward compatibility (rolling forward to a newer
96      *    software version), code reading and processing key values MUST
97      *    process key values that have shorter length.
98      *
99      * 4. New Key IDs may be defined in the future with the understanding
100      *    that such key values are not backward compatible.
101      *
102      */
103 
104     /**
105      * This enumeration defines the keys of settings.
106      *
107      */
108     enum Key : uint16_t
109     {
110         kKeyActiveDataset     = OT_SETTINGS_KEY_ACTIVE_DATASET,
111         kKeyPendingDataset    = OT_SETTINGS_KEY_PENDING_DATASET,
112         kKeyNetworkInfo       = OT_SETTINGS_KEY_NETWORK_INFO,
113         kKeyParentInfo        = OT_SETTINGS_KEY_PARENT_INFO,
114         kKeyChildInfo         = OT_SETTINGS_KEY_CHILD_INFO,
115         kKeySlaacIidSecretKey = OT_SETTINGS_KEY_SLAAC_IID_SECRET_KEY,
116         kKeyDadInfo           = OT_SETTINGS_KEY_DAD_INFO,
117         kKeySrpEcdsaKey       = OT_SETTINGS_KEY_SRP_ECDSA_KEY,
118         kKeySrpClientInfo     = OT_SETTINGS_KEY_SRP_CLIENT_INFO,
119         kKeySrpServerInfo     = OT_SETTINGS_KEY_SRP_SERVER_INFO,
120         kKeyBrUlaPrefix       = OT_SETTINGS_KEY_BR_ULA_PREFIX,
121     };
122 
123     static constexpr Key kLastKey = kKeyBrUlaPrefix; ///< The last (numerically) enumerator value in `Key`.
124     static_assert(static_cast<uint16_t>(kLastKey) < static_cast<uint16_t>(OT_SETTINGS_KEY_VENDOR_RESERVED_MIN),
125                   "Core settings keys overlap with vendor reserved keys");
126 
127     /**
128      * This structure represents the device's own network information for settings storage.
129      *
130      */
131     OT_TOOL_PACKED_BEGIN
132     class NetworkInfo : private Clearable<NetworkInfo>
133     {
134         friend class Settings;
135 
136     public:
137         static constexpr Key kKey = kKeyNetworkInfo; ///< The associated key.
138 
139         /**
140          * This method initializes the `NetworkInfo` object.
141          *
142          */
Init(void)143         void Init(void)
144         {
145             Clear();
146             SetVersion(OT_THREAD_VERSION_1_1);
147         }
148 
149         /**
150          * This method returns the Thread role.
151          *
152          * @returns The Thread role.
153          *
154          */
GetRole(void) const155         uint8_t GetRole(void) const { return mRole; }
156 
157         /**
158          * This method sets the Thread role.
159          *
160          * @param[in] aRole  The Thread Role.
161          *
162          */
SetRole(uint8_t aRole)163         void SetRole(uint8_t aRole) { mRole = aRole; }
164 
165         /**
166          * This method returns the Thread device mode.
167          *
168          * @returns the Thread device mode.
169          *
170          */
GetDeviceMode(void) const171         uint8_t GetDeviceMode(void) const { return mDeviceMode; }
172 
173         /**
174          * This method sets the Thread device mode.
175          *
176          * @param[in] aDeviceMode  The Thread device mode.
177          *
178          */
SetDeviceMode(uint8_t aDeviceMode)179         void SetDeviceMode(uint8_t aDeviceMode) { mDeviceMode = aDeviceMode; }
180 
181         /**
182          * This method returns the RLOC16.
183          *
184          * @returns The RLOC16.
185          *
186          */
GetRloc16(void) const187         uint16_t GetRloc16(void) const { return Encoding::LittleEndian::HostSwap16(mRloc16); }
188 
189         /**
190          * This method sets the RLOC16.
191          *
192          * @param[in] aRloc16  The RLOC16.
193          *
194          */
SetRloc16(uint16_t aRloc16)195         void SetRloc16(uint16_t aRloc16) { mRloc16 = Encoding::LittleEndian::HostSwap16(aRloc16); }
196 
197         /**
198          * This method returns the key sequence.
199          *
200          * @returns The key sequence.
201          *
202          */
GetKeySequence(void) const203         uint32_t GetKeySequence(void) const { return Encoding::LittleEndian::HostSwap32(mKeySequence); }
204 
205         /**
206          * This method sets the key sequence.
207          *
208          * @param[in] aKeySequence  The key sequence.
209          *
210          */
SetKeySequence(uint32_t aKeySequence)211         void SetKeySequence(uint32_t aKeySequence) { mKeySequence = Encoding::LittleEndian::HostSwap32(aKeySequence); }
212 
213         /**
214          * This method returns the MLE frame counter.
215          *
216          * @returns The MLE frame counter.
217          *
218          */
GetMleFrameCounter(void) const219         uint32_t GetMleFrameCounter(void) const { return Encoding::LittleEndian::HostSwap32(mMleFrameCounter); }
220 
221         /**
222          * This method sets the MLE frame counter.
223          *
224          * @param[in] aMleFrameCounter  The MLE frame counter.
225          *
226          */
SetMleFrameCounter(uint32_t aMleFrameCounter)227         void SetMleFrameCounter(uint32_t aMleFrameCounter)
228         {
229             mMleFrameCounter = Encoding::LittleEndian::HostSwap32(aMleFrameCounter);
230         }
231 
232         /**
233          * This method returns the MAC frame counter.
234          *
235          * @returns The MAC frame counter.
236          *
237          */
GetMacFrameCounter(void) const238         uint32_t GetMacFrameCounter(void) const { return Encoding::LittleEndian::HostSwap32(mMacFrameCounter); }
239 
240         /**
241          * This method sets the MAC frame counter.
242          *
243          * @param[in] aMacFrameCounter  The MAC frame counter.
244          *
245          */
SetMacFrameCounter(uint32_t aMacFrameCounter)246         void SetMacFrameCounter(uint32_t aMacFrameCounter)
247         {
248             mMacFrameCounter = Encoding::LittleEndian::HostSwap32(aMacFrameCounter);
249         }
250 
251         /**
252          * This method returns the previous partition ID.
253          *
254          * @returns The previous partition ID.
255          *
256          */
GetPreviousPartitionId(void) const257         uint32_t GetPreviousPartitionId(void) const { return Encoding::LittleEndian::HostSwap32(mPreviousPartitionId); }
258 
259         /**
260          * This method sets the previous partition id.
261          *
262          * @param[in] aPreviousPartitionId  The previous partition ID.
263          *
264          */
SetPreviousPartitionId(uint32_t aPreviousPartitionId)265         void SetPreviousPartitionId(uint32_t aPreviousPartitionId)
266         {
267             mPreviousPartitionId = Encoding::LittleEndian::HostSwap32(aPreviousPartitionId);
268         }
269 
270         /**
271          * This method returns the extended address.
272          *
273          * @returns The extended address.
274          *
275          */
GetExtAddress(void) const276         const Mac::ExtAddress &GetExtAddress(void) const { return mExtAddress; }
277 
278         /**
279          * This method sets the extended address.
280          *
281          * @param[in] aExtAddress  The extended address.
282          *
283          */
SetExtAddress(const Mac::ExtAddress & aExtAddress)284         void SetExtAddress(const Mac::ExtAddress &aExtAddress) { mExtAddress = aExtAddress; }
285 
286         /**
287          * This method returns the Mesh Local Interface Identifier.
288          *
289          * @returns The Mesh Local Interface Identifier.
290          *
291          */
GetMeshLocalIid(void) const292         const Ip6::InterfaceIdentifier &GetMeshLocalIid(void) const { return mMlIid; }
293 
294         /**
295          * This method sets the Mesh Local Interface Identifier.
296          *
297          * @param[in] aMeshLocalIid  The Mesh Local Interface Identifier.
298          *
299          */
SetMeshLocalIid(const Ip6::InterfaceIdentifier & aMeshLocalIid)300         void SetMeshLocalIid(const Ip6::InterfaceIdentifier &aMeshLocalIid) { mMlIid = aMeshLocalIid; }
301 
302         /**
303          * This method returns the Thread version.
304          *
305          * @returns The Thread version.
306          *
307          */
GetVersion(void) const308         uint16_t GetVersion(void) const { return Encoding::LittleEndian::HostSwap16(mVersion); }
309 
310         /**
311          * This method sets the Thread version.
312          *
313          * @param[in] aVersion  The Thread version.
314          *
315          */
SetVersion(uint16_t aVersion)316         void SetVersion(uint16_t aVersion) { mVersion = Encoding::LittleEndian::HostSwap16(aVersion); }
317 
318     private:
319         void Log(Action aAction) const;
320 
321         uint8_t                  mRole;                ///< Current Thread role.
322         uint8_t                  mDeviceMode;          ///< Device mode setting.
323         uint16_t                 mRloc16;              ///< RLOC16
324         uint32_t                 mKeySequence;         ///< Key Sequence
325         uint32_t                 mMleFrameCounter;     ///< MLE Frame Counter
326         uint32_t                 mMacFrameCounter;     ///< MAC Frame Counter
327         uint32_t                 mPreviousPartitionId; ///< PartitionId
328         Mac::ExtAddress          mExtAddress;          ///< Extended Address
329         Ip6::InterfaceIdentifier mMlIid;               ///< IID from ML-EID
330         uint16_t                 mVersion;             ///< Version
331     } OT_TOOL_PACKED_END;
332 
333     /**
334      * This structure represents the parent information for settings storage.
335      *
336      */
337     OT_TOOL_PACKED_BEGIN
338     class ParentInfo : private Clearable<ParentInfo>
339     {
340         friend class Settings;
341 
342     public:
343         static constexpr Key kKey = kKeyParentInfo; ///< The associated key.
344 
345         /**
346          * This method initializes the `ParentInfo` object.
347          *
348          */
Init(void)349         void Init(void)
350         {
351             Clear();
352             SetVersion(OT_THREAD_VERSION_1_1);
353         }
354 
355         /**
356          * This method returns the extended address.
357          *
358          * @returns The extended address.
359          *
360          */
GetExtAddress(void) const361         const Mac::ExtAddress &GetExtAddress(void) const { return mExtAddress; }
362 
363         /**
364          * This method sets the extended address.
365          *
366          * @param[in] aExtAddress  The extended address.
367          *
368          */
SetExtAddress(const Mac::ExtAddress & aExtAddress)369         void SetExtAddress(const Mac::ExtAddress &aExtAddress) { mExtAddress = aExtAddress; }
370 
371         /**
372          * This method returns the Thread version.
373          *
374          * @returns The Thread version.
375          *
376          */
GetVersion(void) const377         uint16_t GetVersion(void) const { return Encoding::LittleEndian::HostSwap16(mVersion); }
378 
379         /**
380          * This method sets the Thread version.
381          *
382          * @param[in] aVersion  The Thread version.
383          *
384          */
SetVersion(uint16_t aVersion)385         void SetVersion(uint16_t aVersion) { mVersion = Encoding::LittleEndian::HostSwap16(aVersion); }
386 
387     private:
388         void Log(Action aAction) const;
389 
390         Mac::ExtAddress mExtAddress; ///< Extended Address
391         uint16_t        mVersion;    ///< Version
392     } OT_TOOL_PACKED_END;
393 
394 #if OPENTHREAD_FTD
395     /**
396      * This structure represents the child information for settings storage.
397      *
398      */
399     OT_TOOL_PACKED_BEGIN
400     class ChildInfo
401     {
402         friend class Settings;
403 
404     public:
405         static constexpr Key kKey = kKeyChildInfo; ///< The associated key.
406 
407         /**
408          * This method clears the struct object (setting all the fields to zero).
409          *
410          */
Init(void)411         void Init(void)
412         {
413             memset(this, 0, sizeof(*this));
414             SetVersion(OT_THREAD_VERSION_1_1);
415         }
416 
417         /**
418          * This method returns the extended address.
419          *
420          * @returns The extended address.
421          *
422          */
GetExtAddress(void) const423         const Mac::ExtAddress &GetExtAddress(void) const { return mExtAddress; }
424 
425         /**
426          * This method sets the extended address.
427          *
428          * @param[in] aExtAddress  The extended address.
429          *
430          */
SetExtAddress(const Mac::ExtAddress & aExtAddress)431         void SetExtAddress(const Mac::ExtAddress &aExtAddress) { mExtAddress = aExtAddress; }
432 
433         /**
434          * This method returns the child timeout.
435          *
436          * @returns The child timeout.
437          *
438          */
GetTimeout(void) const439         uint32_t GetTimeout(void) const { return Encoding::LittleEndian::HostSwap32(mTimeout); }
440 
441         /**
442          * This method sets the child timeout.
443          *
444          * @param[in] aTimeout  The child timeout.
445          *
446          */
SetTimeout(uint32_t aTimeout)447         void SetTimeout(uint32_t aTimeout) { mTimeout = Encoding::LittleEndian::HostSwap32(aTimeout); }
448 
449         /**
450          * This method returns the RLOC16.
451          *
452          * @returns The RLOC16.
453          *
454          */
GetRloc16(void) const455         uint16_t GetRloc16(void) const { return Encoding::LittleEndian::HostSwap16(mRloc16); }
456 
457         /**
458          * This method sets the RLOC16.
459          *
460          * @param[in] aRloc16  The RLOC16.
461          *
462          */
SetRloc16(uint16_t aRloc16)463         void SetRloc16(uint16_t aRloc16) { mRloc16 = Encoding::LittleEndian::HostSwap16(aRloc16); }
464 
465         /**
466          * This method returns the Thread device mode.
467          *
468          * @returns The Thread device mode.
469          *
470          */
GetMode(void) const471         uint8_t GetMode(void) const { return mMode; }
472 
473         /**
474          * This method sets the Thread device mode.
475          *
476          * @param[in] aMode  The Thread device mode.
477          *
478          */
SetMode(uint8_t aMode)479         void SetMode(uint8_t aMode) { mMode = aMode; }
480 
481         /**
482          * This method returns the Thread version.
483          *
484          * @returns The Thread version.
485          *
486          */
GetVersion(void) const487         uint16_t GetVersion(void) const { return Encoding::LittleEndian::HostSwap16(mVersion); }
488 
489         /**
490          * This method sets the Thread version.
491          *
492          * @param[in] aVersion  The Thread version.
493          *
494          */
SetVersion(uint16_t aVersion)495         void SetVersion(uint16_t aVersion) { mVersion = Encoding::LittleEndian::HostSwap16(aVersion); }
496 
497     private:
498         void Log(Action aAction) const;
499 
500         Mac::ExtAddress mExtAddress; ///< Extended Address
501         uint32_t        mTimeout;    ///< Timeout
502         uint16_t        mRloc16;     ///< RLOC16
503         uint8_t         mMode;       ///< The MLE device mode
504         uint16_t        mVersion;    ///< Version
505     } OT_TOOL_PACKED_END;
506 #endif // OPENTHREAD_FTD
507 
508 #if OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
509     /**
510      * This class defines constants and types for SLAAC IID Secret key settings.
511      *
512      */
513     class SlaacIidSecretKey
514     {
515     public:
516         static constexpr Key kKey = kKeySlaacIidSecretKey; ///< The associated key.
517 
518         typedef Utils::Slaac::IidSecretKey ValueType; ///< The associated value type.
519 
520     private:
521         SlaacIidSecretKey(void) = default;
522     };
523 #endif
524 
525 #if OPENTHREAD_CONFIG_DUA_ENABLE
526     /**
527      * This structure represents the duplicate address detection information for settings storage.
528      *
529      */
530     OT_TOOL_PACKED_BEGIN
531     class DadInfo : private Clearable<DadInfo>
532     {
533         friend class Settings;
534 
535     public:
536         static constexpr Key kKey = kKeyDadInfo; ///< The associated key.
537 
538         /**
539          * This method initializes the `DadInfo` object.
540          *
541          */
Init(void)542         void Init(void) { Clear(); }
543 
544         /**
545          * This method returns the Dad Counter.
546          *
547          * @returns The Dad Counter value.
548          *
549          */
GetDadCounter(void) const550         uint8_t GetDadCounter(void) const { return mDadCounter; }
551 
552         /**
553          * This method sets the Dad Counter.
554          *
555          * @param[in] aDadCounter The Dad Counter value.
556          *
557          */
SetDadCounter(uint8_t aDadCounter)558         void SetDadCounter(uint8_t aDadCounter) { mDadCounter = aDadCounter; }
559 
560     private:
561         void Log(Action aAction) const;
562 
563         uint8_t mDadCounter; ///< Dad Counter used to resolve address conflict in Thread 1.2 DUA feature.
564     } OT_TOOL_PACKED_END;
565 #endif // OPENTHREAD_CONFIG_DUA_ENABLE
566 
567 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
568     /**
569      * This class defines constants and types for BR ULA prefix settings.
570      *
571      */
572     class BrUlaPrefix
573     {
574     public:
575         static constexpr Key kKey = kKeyBrUlaPrefix; ///< The associated key.
576 
577         typedef Ip6::Prefix ValueType; ///< The associated value type.
578 
579     private:
580         BrUlaPrefix(void) = default;
581     };
582 #endif
583 
584 #if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
585     /**
586      * This class defines constants and types for SRP ECDSA key settings.
587      *
588      */
589     class SrpEcdsaKey
590     {
591     public:
592         static constexpr Key kKey = kKeySrpEcdsaKey; ///< The associated key.
593 
594         typedef Crypto::Ecdsa::P256::KeyPair ValueType; ///< The associated value type.
595 
596     private:
597         SrpEcdsaKey(void) = default;
598     };
599 
600 #if OPENTHREAD_CONFIG_SRP_CLIENT_SAVE_SELECTED_SERVER_ENABLE
601     /**
602      * This structure represents the SRP client info (selected server address).
603      *
604      */
605     OT_TOOL_PACKED_BEGIN
606     class SrpClientInfo : private Clearable<SrpClientInfo>
607     {
608         friend class Settings;
609 
610     public:
611         static constexpr Key kKey = kKeySrpClientInfo; ///< The associated key.
612 
613         /**
614          * This method initializes the `SrpClientInfo` object.
615          *
616          */
Init(void)617         void Init(void) { Clear(); }
618 
619         /**
620          * This method returns the server IPv6 address.
621          *
622          * @returns The server IPv6 address.
623          *
624          */
GetServerAddress(void) const625         const Ip6::Address &GetServerAddress(void) const { return mServerAddress; }
626 
627         /**
628          * This method sets the server IPv6 address.
629          *
630          * @param[in] aAddress  The server IPv6 address.
631          *
632          */
SetServerAddress(const Ip6::Address & aAddress)633         void SetServerAddress(const Ip6::Address &aAddress) { mServerAddress = aAddress; }
634 
635         /**
636          * This method returns the server port number.
637          *
638          * @returns The server port number.
639          *
640          */
GetServerPort(void) const641         uint16_t GetServerPort(void) const { return Encoding::LittleEndian::HostSwap16(mServerPort); }
642 
643         /**
644          * This method sets the server port number.
645          *
646          * @param[in] aPort  The server port number.
647          *
648          */
SetServerPort(uint16_t aPort)649         void SetServerPort(uint16_t aPort) { mServerPort = Encoding::LittleEndian::HostSwap16(aPort); }
650 
651     private:
652         void Log(Action aAction) const;
653 
654         Ip6::Address mServerAddress;
655         uint16_t     mServerPort; // (in little-endian encoding)
656     } OT_TOOL_PACKED_END;
657 #endif // OPENTHREAD_CONFIG_SRP_CLIENT_SAVE_SELECTED_SERVER_ENABLE
658 #endif // OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
659 
660 #if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE && OPENTHREAD_CONFIG_SRP_SERVER_PORT_SWITCH_ENABLE
661     /**
662      * This structure represents the SRP server info.
663      *
664      */
665     OT_TOOL_PACKED_BEGIN
666     class SrpServerInfo : private Clearable<SrpServerInfo>
667     {
668         friend class Settings;
669 
670     public:
671         static constexpr Key kKey = kKeySrpServerInfo; ///< The associated key.
672 
673         /**
674          * This method initializes the `SrpServerInfo` object.
675          *
676          */
Init(void)677         void Init(void) { Clear(); }
678 
679         /**
680          * This method returns the server port number.
681          *
682          * @returns The server port number.
683          *
684          */
GetPort(void) const685         uint16_t GetPort(void) const { return Encoding::LittleEndian::HostSwap16(mPort); }
686 
687         /**
688          * This method sets the server port number.
689          *
690          * @param[in] aPort  The server port number.
691          *
692          */
SetPort(uint16_t aPort)693         void SetPort(uint16_t aPort) { mPort = Encoding::LittleEndian::HostSwap16(aPort); }
694 
695     private:
696         void Log(Action aAction) const;
697 
698         uint16_t mPort; // (in little-endian encoding)
699     } OT_TOOL_PACKED_END;
700 #endif // OPENTHREAD_CONFIG_SRP_SERVER_ENABLE && OPENTHREAD_CONFIG_SRP_SERVER_PORT_SWITCH_ENABLE
701 
702 protected:
SettingsBase(Instance & aInstance)703     explicit SettingsBase(Instance &aInstance)
704         : InstanceLocator(aInstance)
705     {
706     }
707 
708 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
709     static void LogPrefix(Action aAction, Key aKey, const Ip6::Prefix &aPrefix);
710 #endif
711 
712 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN)
713     static const char *KeyToString(Key aKey);
714 #endif
715 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
716     static const char *ActionToString(Action aAction);
717 #endif
718 };
719 
720 /**
721  * This class defines methods related to non-volatile storage of settings.
722  *
723  */
724 class Settings : public SettingsBase, private NonCopyable
725 {
726     class ChildInfoIteratorBuilder;
727 
728 public:
729     /**
730      * This constructor initializes a `Settings` object.
731      *
732      * @param[in]  aInstance     A reference to the OpenThread instance.
733      *
734      */
Settings(Instance & aInstance)735     explicit Settings(Instance &aInstance)
736         : SettingsBase(aInstance)
737     {
738     }
739 
740     /**
741      * This method initializes the platform settings (non-volatile) module.
742      *
743      * This should be called before any other method from this class.
744      *
745      */
746     void Init(void);
747 
748     /**
749      * This method de-initializes the platform settings (non-volatile) module.
750      *
751      * This method should be called when OpenThread instance is no longer in use.
752      *
753      */
754     void Deinit(void);
755 
756     /**
757      * This method removes all settings from the non-volatile store.
758      *
759      */
760     void Wipe(void);
761 
762     /**
763      * This method saves the Operational Dataset (active or pending).
764      *
765      * @param[in]   aType       The Dataset type (active or pending) to save.
766      * @param[in]   aDataset    A reference to a `Dataset` object to be saved.
767      *
768      * @retval kErrorNone             Successfully saved the Dataset.
769      * @retval kErrorNotImplemented   The platform does not implement settings functionality.
770      *
771      */
772     Error SaveOperationalDataset(MeshCoP::Dataset::Type aType, const MeshCoP::Dataset &aDataset);
773 
774     /**
775      * This method reads the Operational Dataset (active or pending).
776      *
777      * @param[in]   aType            The Dataset type (active or pending) to read.
778      * @param[out]  aDataset         A reference to a `Dataset` object to output the read content.
779      *
780      * @retval kErrorNone             Successfully read the Dataset.
781      * @retval kErrorNotFound         No corresponding value in the setting store.
782      * @retval kErrorNotImplemented   The platform does not implement settings functionality.
783      *
784      */
785     Error ReadOperationalDataset(MeshCoP::Dataset::Type aType, MeshCoP::Dataset &aDataset) const;
786 
787     /**
788      * This method deletes the Operational Dataset (active/pending) from settings.
789      *
790      * @param[in]   aType            The Dataset type (active or pending) to delete.
791      *
792      * @retval kErrorNone            Successfully deleted the Dataset.
793      * @retval kErrorNotImplemented  The platform does not implement settings functionality.
794      *
795      */
796     Error DeleteOperationalDataset(MeshCoP::Dataset::Type aType);
797 
798     /**
799      * This template method reads a specified settings entry.
800      *
801      * The template type `EntryType` specifies the entry's value data structure. It must provide the following:
802      *
803      *  - It must provide a constant `EntryType::kKey` to specify the associated entry settings key.
804      *  - It must provide method `Init()` to initialize the `aEntry` object.
805      *
806      * This version of `Read<EntryType>` is intended for use with entries that define a data structure which represents
807      * the entry's value, e.g., `NetworkInfo`, `ParentInfo`, `DadInfo`, etc.
808      *
809      * @tparam EntryType              The settings entry type.
810      *
811      * @param[out] aEntry             A reference to a entry data structure to output the read content.
812      *
813      * @retval kErrorNone             Successfully read the entry.
814      * @retval kErrorNotFound         No corresponding value in the setting store.
815      * @retval kErrorNotImplemented   The platform does not implement settings functionality.
816      *
817      */
Read(EntryType & aEntry) const818     template <typename EntryType> Error Read(EntryType &aEntry) const
819     {
820         aEntry.Init();
821 
822         return ReadEntry(EntryType::kKey, &aEntry, sizeof(EntryType));
823     }
824 
825     /**
826      * This template method reads a specified settings entry.
827      *
828      * The template type `EntryType` provides information about the entry's value type. It must provide the following:
829      *
830      *  - It must provide a constant `EntryType::kKey` to specify the associated entry settings key.
831      *  - It must provide a nested type `EntryType::ValueType` to specify the associated entry value type.
832      *
833      * This version of `Read<EntryType>` is intended for use with entries that have a simple entry value type (which can
834      * be represented by an existing type), e.g., `OmrPrefix` (using `Ip6::Prefix` as the value type).
835      *
836      * @tparam EntryType              The settings entry type.
837      *
838      * @param[out] aValue             A reference to a value type object to output the read content.
839      *
840      * @retval kErrorNone             Successfully read the value.
841      * @retval kErrorNotFound         No corresponding value in the setting store.
842      * @retval kErrorNotImplemented   The platform does not implement settings functionality.
843      *
844      */
Read(typename EntryType::ValueType & aValue) const845     template <typename EntryType> Error Read(typename EntryType::ValueType &aValue) const
846     {
847         return ReadEntry(EntryType::kKey, &aValue, sizeof(typename EntryType::ValueType));
848     }
849 
850     /**
851      * This template method saves a specified settings entry.
852      *
853      * The template type `EntryType` specifies the entry's value data structure. It must provide the following:
854      *
855      *  - It must provide a constant `EntryType::kKey` to specify the associated entry settings key.
856      *
857      * This version of `Save<EntryType>` is intended for use with entries that define a data structure which represents
858      * the entry's value, e.g., `NetworkInfo`, `ParentInfo`, `DadInfo`, etc.
859      *
860      * @tparam EntryType              The settings entry type.
861      *
862      * @param[in] aEntry              The entry value to be saved.
863      *
864      * @retval kErrorNone             Successfully saved Network Info in settings.
865      * @retval kErrorNotImplemented   The platform does not implement settings functionality.
866      *
867      */
Save(const EntryType & aEntry)868     template <typename EntryType> Error Save(const EntryType &aEntry)
869     {
870         EntryType prev;
871 
872         return SaveEntry(EntryType::kKey, &aEntry, &prev, sizeof(EntryType));
873     }
874 
875     /**
876      * This template method saves a specified settings entry.
877      *
878      * The template type `EntryType` provides information about the entry's value type. It must provide the following:
879      *
880      *  - It must provide a constant `EntryType::kKey` to specify the associated entry settings key.
881      *  - It must provide a nested type `EntryType::ValueType` to specify the associated entry value type.
882      *
883      * This version of `Save<EntryType>` is intended for use with entries that have a simple entry value type (which can
884      * be represented by an existing type), e.g., `OmrPrefix` (using `Ip6::Prefix` as the value type).
885      *
886      * @tparam EntryType              The settings entry type.
887      *
888      * @param[in] aValue              The entry value to be saved.
889      *
890      * @retval kErrorNone             Successfully saved Network Info in settings.
891      * @retval kErrorNotImplemented   The platform does not implement settings functionality.
892      *
893      */
Save(const typename EntryType::ValueType & aValue)894     template <typename EntryType> Error Save(const typename EntryType::ValueType &aValue)
895     {
896         typename EntryType::ValueType prev;
897 
898         return SaveEntry(EntryType::kKey, &aValue, &prev, sizeof(typename EntryType::ValueType));
899     }
900 
901     /**
902      * This template method deletes a specified setting entry.
903      *
904      * The template type `EntryType` provides information about the entry's key.
905      *
906      *  - It must provide a constant `EntryType::kKey` to specify the associated entry settings key.
907      *
908      * @tparam EntryType             The settings entry type.
909      *
910      * @retval kErrorNone            Successfully deleted the value.
911      * @retval kErrorNotImplemented  The platform does not implement settings functionality.
912      *
913      */
Delete(void)914     template <typename EntryType> Error Delete(void) { return DeleteEntry(EntryType::kKey); }
915 
916 #if OPENTHREAD_FTD
917     /**
918      * This method adds a Child Info entry to settings.
919      *
920      * @note Child Info is a list-based settings property and can contain multiple entries.
921      *
922      * @param[in]   aChildInfo            A reference to a `ChildInfo` structure to be saved/added.
923      *
924      * @retval kErrorNone             Successfully saved the Child Info in settings.
925      * @retval kErrorNotImplemented   The platform does not implement settings functionality.
926      *
927      */
928     Error AddChildInfo(const ChildInfo &aChildInfo);
929 
930     /**
931      * This method deletes all Child Info entries from the settings.
932      *
933      * @note Child Info is a list-based settings property and can contain multiple entries.
934      *
935      * @retval kErrorNone            Successfully deleted the value.
936      * @retval kErrorNotImplemented  The platform does not implement settings functionality.
937      *
938      */
939     Error DeleteAllChildInfo(void);
940 
941     /**
942      * This method enables range-based `for` loop iteration over all child info entries in the `Settings`.
943      *
944      * This method should be used as follows:
945      *
946      *     for (const ChildInfo &childInfo : Get<Settings>().IterateChildInfo()) { ... }
947      *
948      *
949      * @returns A ChildInfoIteratorBuilder instance.
950      *
951      */
IterateChildInfo(void)952     ChildInfoIteratorBuilder IterateChildInfo(void) { return ChildInfoIteratorBuilder(GetInstance()); }
953 
954     /**
955      * This class defines an iterator to access all Child Info entries in the settings.
956      *
957      */
958     class ChildInfoIterator : public SettingsBase, public Unequatable<ChildInfoIterator>
959     {
960         friend class ChildInfoIteratorBuilder;
961 
962     public:
963         /**
964          * This constructor initializes a `ChildInfoInterator` object.
965          *
966          * @param[in]  aInstance  A reference to the OpenThread instance.
967          *
968          */
969         explicit ChildInfoIterator(Instance &aInstance);
970 
971         /**
972          * This method indicates whether there are no more Child Info entries in the list (iterator has reached end of
973          * the list), or the current entry is valid.
974          *
975          * @retval TRUE   There are no more entries in the list (reached end of the list).
976          * @retval FALSE  The current entry is valid.
977          *
978          */
IsDone(void) const979         bool IsDone(void) const { return mIsDone; }
980 
981         /**
982          * This method overloads operator `++` (pre-increment) to advance the iterator to move to the next Child Info
983          * entry in the list (if any).
984          *
985          */
operator ++(void)986         void operator++(void) { Advance(); }
987 
988         /**
989          * This method overloads operator `++` (post-increment) to advance the iterator to move to the next Child Info
990          * entry in the list (if any).
991          *
992          */
operator ++(int)993         void operator++(int) { Advance(); }
994 
995         /**
996          * This method gets the Child Info corresponding to the current iterator entry in the list.
997          *
998          * @note This method should be used only if `IsDone()` is returning FALSE indicating that the iterator is
999          * pointing to a valid entry.
1000          *
1001          * @returns A reference to `ChildInfo` structure corresponding to current iterator entry.
1002          *
1003          */
GetChildInfo(void) const1004         const ChildInfo &GetChildInfo(void) const { return mChildInfo; }
1005 
1006         /**
1007          * This method deletes the current Child Info entry.
1008          *
1009          * @retval kErrorNone            The entry was deleted successfully.
1010          * @retval kErrorInvalidState    The entry is not valid (iterator has reached end of list).
1011          * @retval kErrorNotImplemented  The platform does not implement settings functionality.
1012          *
1013          */
1014         Error Delete(void);
1015 
1016         /**
1017          * This method overloads the `*` dereference operator and gets a reference to `ChildInfo` entry to which the
1018          * iterator is currently pointing.
1019          *
1020          * @note This method should be used only if `IsDone()` is returning FALSE indicating that the iterator is
1021          * pointing to a valid entry.
1022          *
1023          *
1024          * @returns A reference to the `ChildInfo` entry currently pointed by the iterator.
1025          *
1026          */
operator *(void) const1027         const ChildInfo &operator*(void)const { return mChildInfo; }
1028 
1029         /**
1030          * This method overloads operator `==` to evaluate whether or not two iterator instances are equal.
1031          *
1032          * @param[in]  aOther  The other iterator to compare with.
1033          *
1034          * @retval TRUE   If the two iterator objects are equal
1035          * @retval FALSE  If the two iterator objects are not equal.
1036          *
1037          */
operator ==(const ChildInfoIterator & aOther) const1038         bool operator==(const ChildInfoIterator &aOther) const
1039         {
1040             return (mIsDone && aOther.mIsDone) || (!mIsDone && !aOther.mIsDone && (mIndex == aOther.mIndex));
1041         }
1042 
1043     private:
1044         enum IteratorType : uint8_t
1045         {
1046             kEndIterator,
1047         };
1048 
ChildInfoIterator(Instance & aInstance,IteratorType)1049         ChildInfoIterator(Instance &aInstance, IteratorType)
1050             : SettingsBase(aInstance)
1051             , mIndex(0)
1052             , mIsDone(true)
1053         {
1054         }
1055 
1056         void Advance(void);
1057         void Read(void);
1058 
1059         ChildInfo mChildInfo;
1060         uint16_t  mIndex;
1061         bool      mIsDone;
1062     };
1063 #endif // OPENTHREAD_FTD
1064 
1065 private:
1066 #if OPENTHREAD_FTD
1067     class ChildInfoIteratorBuilder : public InstanceLocator
1068     {
1069     public:
ChildInfoIteratorBuilder(Instance & aInstance)1070         explicit ChildInfoIteratorBuilder(Instance &aInstance)
1071             : InstanceLocator(aInstance)
1072         {
1073         }
1074 
begin(void)1075         ChildInfoIterator begin(void) { return ChildInfoIterator(GetInstance()); }
end(void)1076         ChildInfoIterator end(void) { return ChildInfoIterator(GetInstance(), ChildInfoIterator::kEndIterator); }
1077     };
1078 #endif
1079 
1080     static Key KeyForDatasetType(MeshCoP::Dataset::Type aType);
1081 
1082     Error ReadEntry(Key aKey, void *aValue, uint16_t aMaxLength) const;
1083     Error SaveEntry(Key aKey, const void *aValue, void *aPrev, uint16_t aLength);
1084     Error DeleteEntry(Key aKey);
1085 
1086     static void Log(Action aAction, Error aError, Key aKey, const void *aValue = nullptr);
1087 
1088     static const uint16_t kSensitiveKeys[];
1089 };
1090 
1091 } // namespace ot
1092 
1093 #endif // SETTINGS_HPP_
1094