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/border_agent.hpp"
51 #include "meshcop/dataset.hpp"
52 #include "net/ip6_address.hpp"
53 #include "thread/version.hpp"
54 #include "utils/flash.hpp"
55 #include "utils/slaac_address.hpp"
56 
57 namespace ot {
58 
59 class Settings;
60 
61 /**
62  * Defines the base class used by `Settings` and `Settings::ChildInfoIterator`.
63  *
64  * Provides structure definitions for different settings keys.
65  *
66  */
67 class SettingsBase : public InstanceLocator
68 {
69 protected:
70     enum Action : uint8_t
71     {
72         kActionRead,
73         kActionSave,
74         kActionResave,
75         kActionDelete,
76 #if OPENTHREAD_FTD
77         kActionAdd,
78         kActionRemove,
79         kActionDeleteAll,
80 #endif
81     };
82 
83 public:
84     /**
85      * Rules for updating existing value structures.
86      *
87      * 1. Modifying existing key value fields in settings MUST only be
88      *    done by appending new fields.  Existing fields MUST NOT be
89      *    deleted or modified in any way.
90      *
91      * 2. To support backward compatibility (rolling back to an older
92      *    software version), code reading and processing key values MUST
93      *    process key values that have longer length.  Additionally, newer
94      *    versions MUST update/maintain values in existing key value
95      *    fields.
96      *
97      * 3. To support forward compatibility (rolling forward to a newer
98      *    software version), code reading and processing key values MUST
99      *    process key values that have shorter length.
100      *
101      * 4. New Key IDs may be defined in the future with the understanding
102      *    that such key values are not backward compatible.
103      *
104      */
105 
106     /**
107      * Defines the keys of settings.
108      *
109      */
110     enum Key : uint16_t
111     {
112         kKeyActiveDataset     = OT_SETTINGS_KEY_ACTIVE_DATASET,
113         kKeyPendingDataset    = OT_SETTINGS_KEY_PENDING_DATASET,
114         kKeyNetworkInfo       = OT_SETTINGS_KEY_NETWORK_INFO,
115         kKeyParentInfo        = OT_SETTINGS_KEY_PARENT_INFO,
116         kKeyChildInfo         = OT_SETTINGS_KEY_CHILD_INFO,
117         kKeySlaacIidSecretKey = OT_SETTINGS_KEY_SLAAC_IID_SECRET_KEY,
118         kKeyDadInfo           = OT_SETTINGS_KEY_DAD_INFO,
119         kKeySrpEcdsaKey       = OT_SETTINGS_KEY_SRP_ECDSA_KEY,
120         kKeySrpClientInfo     = OT_SETTINGS_KEY_SRP_CLIENT_INFO,
121         kKeySrpServerInfo     = OT_SETTINGS_KEY_SRP_SERVER_INFO,
122         kKeyBrUlaPrefix       = OT_SETTINGS_KEY_BR_ULA_PREFIX,
123         kKeyBrOnLinkPrefixes  = OT_SETTINGS_KEY_BR_ON_LINK_PREFIXES,
124         kKeyBorderAgentId     = OT_SETTINGS_KEY_BORDER_AGENT_ID,
125     };
126 
127     static constexpr Key kLastKey = kKeyBorderAgentId; ///< The last (numerically) enumerator value in `Key`.
128 
129     static_assert(static_cast<uint16_t>(kLastKey) < static_cast<uint16_t>(OT_SETTINGS_KEY_VENDOR_RESERVED_MIN),
130                   "Core settings keys overlap with vendor reserved keys");
131 
132     /**
133      * Represents the device's own network information for settings storage.
134      *
135      */
136     OT_TOOL_PACKED_BEGIN
137     class NetworkInfo : private Clearable<NetworkInfo>
138     {
139         friend class Settings;
140         friend class Clearable<NetworkInfo>;
141 
142     public:
143         static constexpr Key kKey = kKeyNetworkInfo; ///< The associated key.
144 
145         /**
146          * Initializes the `NetworkInfo` object.
147          *
148          */
Init(void)149         void Init(void)
150         {
151             Clear();
152             SetVersion(kThreadVersion1p1);
153         }
154 
155         /**
156          * Returns the Thread role.
157          *
158          * @returns The Thread role.
159          *
160          */
GetRole(void) const161         uint8_t GetRole(void) const { return mRole; }
162 
163         /**
164          * Sets the Thread role.
165          *
166          * @param[in] aRole  The Thread Role.
167          *
168          */
SetRole(uint8_t aRole)169         void SetRole(uint8_t aRole) { mRole = aRole; }
170 
171         /**
172          * Returns the Thread device mode.
173          *
174          * @returns the Thread device mode.
175          *
176          */
GetDeviceMode(void) const177         uint8_t GetDeviceMode(void) const { return mDeviceMode; }
178 
179         /**
180          * Sets the Thread device mode.
181          *
182          * @param[in] aDeviceMode  The Thread device mode.
183          *
184          */
SetDeviceMode(uint8_t aDeviceMode)185         void SetDeviceMode(uint8_t aDeviceMode) { mDeviceMode = aDeviceMode; }
186 
187         /**
188          * Returns the RLOC16.
189          *
190          * @returns The RLOC16.
191          *
192          */
GetRloc16(void) const193         uint16_t GetRloc16(void) const { return LittleEndian::HostSwap16(mRloc16); }
194 
195         /**
196          * Sets the RLOC16.
197          *
198          * @param[in] aRloc16  The RLOC16.
199          *
200          */
SetRloc16(uint16_t aRloc16)201         void SetRloc16(uint16_t aRloc16) { mRloc16 = LittleEndian::HostSwap16(aRloc16); }
202 
203         /**
204          * Returns the key sequence.
205          *
206          * @returns The key sequence.
207          *
208          */
GetKeySequence(void) const209         uint32_t GetKeySequence(void) const { return LittleEndian::HostSwap32(mKeySequence); }
210 
211         /**
212          * Sets the key sequence.
213          *
214          * @param[in] aKeySequence  The key sequence.
215          *
216          */
SetKeySequence(uint32_t aKeySequence)217         void SetKeySequence(uint32_t aKeySequence) { mKeySequence = LittleEndian::HostSwap32(aKeySequence); }
218 
219         /**
220          * Returns the MLE frame counter.
221          *
222          * @returns The MLE frame counter.
223          *
224          */
GetMleFrameCounter(void) const225         uint32_t GetMleFrameCounter(void) const { return LittleEndian::HostSwap32(mMleFrameCounter); }
226 
227         /**
228          * Sets the MLE frame counter.
229          *
230          * @param[in] aMleFrameCounter  The MLE frame counter.
231          *
232          */
SetMleFrameCounter(uint32_t aMleFrameCounter)233         void SetMleFrameCounter(uint32_t aMleFrameCounter)
234         {
235             mMleFrameCounter = LittleEndian::HostSwap32(aMleFrameCounter);
236         }
237 
238         /**
239          * Returns the MAC frame counter.
240          *
241          * @returns The MAC frame counter.
242          *
243          */
GetMacFrameCounter(void) const244         uint32_t GetMacFrameCounter(void) const { return LittleEndian::HostSwap32(mMacFrameCounter); }
245 
246         /**
247          * Sets the MAC frame counter.
248          *
249          * @param[in] aMacFrameCounter  The MAC frame counter.
250          *
251          */
SetMacFrameCounter(uint32_t aMacFrameCounter)252         void SetMacFrameCounter(uint32_t aMacFrameCounter)
253         {
254             mMacFrameCounter = LittleEndian::HostSwap32(aMacFrameCounter);
255         }
256 
257         /**
258          * Returns the previous partition ID.
259          *
260          * @returns The previous partition ID.
261          *
262          */
GetPreviousPartitionId(void) const263         uint32_t GetPreviousPartitionId(void) const { return LittleEndian::HostSwap32(mPreviousPartitionId); }
264 
265         /**
266          * Sets the previous partition id.
267          *
268          * @param[in] aPreviousPartitionId  The previous partition ID.
269          *
270          */
SetPreviousPartitionId(uint32_t aPreviousPartitionId)271         void SetPreviousPartitionId(uint32_t aPreviousPartitionId)
272         {
273             mPreviousPartitionId = LittleEndian::HostSwap32(aPreviousPartitionId);
274         }
275 
276         /**
277          * Returns the extended address.
278          *
279          * @returns The extended address.
280          *
281          */
GetExtAddress(void) const282         const Mac::ExtAddress &GetExtAddress(void) const { return mExtAddress; }
283 
284         /**
285          * Sets the extended address.
286          *
287          * @param[in] aExtAddress  The extended address.
288          *
289          */
SetExtAddress(const Mac::ExtAddress & aExtAddress)290         void SetExtAddress(const Mac::ExtAddress &aExtAddress) { mExtAddress = aExtAddress; }
291 
292         /**
293          * Returns the Mesh Local Interface Identifier.
294          *
295          * @returns The Mesh Local Interface Identifier.
296          *
297          */
GetMeshLocalIid(void) const298         const Ip6::InterfaceIdentifier &GetMeshLocalIid(void) const { return mMlIid; }
299 
300         /**
301          * Sets the Mesh Local Interface Identifier.
302          *
303          * @param[in] aMeshLocalIid  The Mesh Local Interface Identifier.
304          *
305          */
SetMeshLocalIid(const Ip6::InterfaceIdentifier & aMeshLocalIid)306         void SetMeshLocalIid(const Ip6::InterfaceIdentifier &aMeshLocalIid) { mMlIid = aMeshLocalIid; }
307 
308         /**
309          * Returns the Thread version.
310          *
311          * @returns The Thread version.
312          *
313          */
GetVersion(void) const314         uint16_t GetVersion(void) const { return LittleEndian::HostSwap16(mVersion); }
315 
316         /**
317          * Sets the Thread version.
318          *
319          * @param[in] aVersion  The Thread version.
320          *
321          */
SetVersion(uint16_t aVersion)322         void SetVersion(uint16_t aVersion) { mVersion = LittleEndian::HostSwap16(aVersion); }
323 
324     private:
325         void Log(Action aAction) const;
326 
327         uint8_t                  mRole;                ///< Current Thread role.
328         uint8_t                  mDeviceMode;          ///< Device mode setting.
329         uint16_t                 mRloc16;              ///< RLOC16
330         uint32_t                 mKeySequence;         ///< Key Sequence
331         uint32_t                 mMleFrameCounter;     ///< MLE Frame Counter
332         uint32_t                 mMacFrameCounter;     ///< MAC Frame Counter
333         uint32_t                 mPreviousPartitionId; ///< PartitionId
334         Mac::ExtAddress          mExtAddress;          ///< Extended Address
335         Ip6::InterfaceIdentifier mMlIid;               ///< IID from ML-EID
336         uint16_t                 mVersion;             ///< Version
337     } OT_TOOL_PACKED_END;
338 
339     /**
340      * Represents the parent information for settings storage.
341      *
342      */
343     OT_TOOL_PACKED_BEGIN
344     class ParentInfo : private Clearable<ParentInfo>
345     {
346         friend class Settings;
347         friend class Clearable<ParentInfo>;
348 
349     public:
350         static constexpr Key kKey = kKeyParentInfo; ///< The associated key.
351 
352         /**
353          * Initializes the `ParentInfo` object.
354          *
355          */
Init(void)356         void Init(void)
357         {
358             Clear();
359             SetVersion(kThreadVersion1p1);
360         }
361 
362         /**
363          * Returns the extended address.
364          *
365          * @returns The extended address.
366          *
367          */
GetExtAddress(void) const368         const Mac::ExtAddress &GetExtAddress(void) const { return mExtAddress; }
369 
370         /**
371          * Sets the extended address.
372          *
373          * @param[in] aExtAddress  The extended address.
374          *
375          */
SetExtAddress(const Mac::ExtAddress & aExtAddress)376         void SetExtAddress(const Mac::ExtAddress &aExtAddress) { mExtAddress = aExtAddress; }
377 
378         /**
379          * Returns the Thread version.
380          *
381          * @returns The Thread version.
382          *
383          */
GetVersion(void) const384         uint16_t GetVersion(void) const { return LittleEndian::HostSwap16(mVersion); }
385 
386         /**
387          * Sets the Thread version.
388          *
389          * @param[in] aVersion  The Thread version.
390          *
391          */
SetVersion(uint16_t aVersion)392         void SetVersion(uint16_t aVersion) { mVersion = LittleEndian::HostSwap16(aVersion); }
393 
394     private:
395         void Log(Action aAction) const;
396 
397         Mac::ExtAddress mExtAddress; ///< Extended Address
398         uint16_t        mVersion;    ///< Version
399     } OT_TOOL_PACKED_END;
400 
401 #if OPENTHREAD_FTD
402     /**
403      * Represents the child information for settings storage.
404      *
405      */
406     OT_TOOL_PACKED_BEGIN
407     class ChildInfo
408     {
409         friend class Settings;
410 
411     public:
412         static constexpr Key kKey = kKeyChildInfo; ///< The associated key.
413 
414         /**
415          * Clears the struct object (setting all the fields to zero).
416          *
417          */
Init(void)418         void Init(void)
419         {
420             memset(this, 0, sizeof(*this));
421             SetVersion(kThreadVersion1p1);
422         }
423 
424         /**
425          * Returns the extended address.
426          *
427          * @returns The extended address.
428          *
429          */
GetExtAddress(void) const430         const Mac::ExtAddress &GetExtAddress(void) const { return mExtAddress; }
431 
432         /**
433          * Sets the extended address.
434          *
435          * @param[in] aExtAddress  The extended address.
436          *
437          */
SetExtAddress(const Mac::ExtAddress & aExtAddress)438         void SetExtAddress(const Mac::ExtAddress &aExtAddress) { mExtAddress = aExtAddress; }
439 
440         /**
441          * Returns the child timeout.
442          *
443          * @returns The child timeout.
444          *
445          */
GetTimeout(void) const446         uint32_t GetTimeout(void) const { return LittleEndian::HostSwap32(mTimeout); }
447 
448         /**
449          * Sets the child timeout.
450          *
451          * @param[in] aTimeout  The child timeout.
452          *
453          */
SetTimeout(uint32_t aTimeout)454         void SetTimeout(uint32_t aTimeout) { mTimeout = LittleEndian::HostSwap32(aTimeout); }
455 
456         /**
457          * Returns the RLOC16.
458          *
459          * @returns The RLOC16.
460          *
461          */
GetRloc16(void) const462         uint16_t GetRloc16(void) const { return LittleEndian::HostSwap16(mRloc16); }
463 
464         /**
465          * Sets the RLOC16.
466          *
467          * @param[in] aRloc16  The RLOC16.
468          *
469          */
SetRloc16(uint16_t aRloc16)470         void SetRloc16(uint16_t aRloc16) { mRloc16 = LittleEndian::HostSwap16(aRloc16); }
471 
472         /**
473          * Returns the Thread device mode.
474          *
475          * @returns The Thread device mode.
476          *
477          */
GetMode(void) const478         uint8_t GetMode(void) const { return mMode; }
479 
480         /**
481          * Sets the Thread device mode.
482          *
483          * @param[in] aMode  The Thread device mode.
484          *
485          */
SetMode(uint8_t aMode)486         void SetMode(uint8_t aMode) { mMode = aMode; }
487 
488         /**
489          * Returns the Thread version.
490          *
491          * @returns The Thread version.
492          *
493          */
GetVersion(void) const494         uint16_t GetVersion(void) const { return LittleEndian::HostSwap16(mVersion); }
495 
496         /**
497          * Sets the Thread version.
498          *
499          * @param[in] aVersion  The Thread version.
500          *
501          */
SetVersion(uint16_t aVersion)502         void SetVersion(uint16_t aVersion) { mVersion = LittleEndian::HostSwap16(aVersion); }
503 
504     private:
505         void Log(Action aAction) const;
506 
507         Mac::ExtAddress mExtAddress; ///< Extended Address
508         uint32_t        mTimeout;    ///< Timeout
509         uint16_t        mRloc16;     ///< RLOC16
510         uint8_t         mMode;       ///< The MLE device mode
511         uint16_t        mVersion;    ///< Version
512     } OT_TOOL_PACKED_END;
513 #endif // OPENTHREAD_FTD
514 
515 #if OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
516     /**
517      * Defines constants and types for SLAAC IID Secret key settings.
518      *
519      */
520     class SlaacIidSecretKey
521     {
522     public:
523         static constexpr Key kKey = kKeySlaacIidSecretKey; ///< The associated key.
524 
525         typedef Utils::Slaac::IidSecretKey ValueType; ///< The associated value type.
526 
527     private:
528         SlaacIidSecretKey(void) = default;
529     };
530 #endif
531 
532 #if OPENTHREAD_CONFIG_DUA_ENABLE
533     /**
534      * Represents the duplicate address detection information for settings storage.
535      *
536      */
537     OT_TOOL_PACKED_BEGIN
538     class DadInfo : private Clearable<DadInfo>
539     {
540         friend class Settings;
541         friend class Clearable<DadInfo>;
542 
543     public:
544         static constexpr Key kKey = kKeyDadInfo; ///< The associated key.
545 
546         /**
547          * Initializes the `DadInfo` object.
548          *
549          */
Init(void)550         void Init(void) { Clear(); }
551 
552         /**
553          * Returns the Dad Counter.
554          *
555          * @returns The Dad Counter value.
556          *
557          */
GetDadCounter(void) const558         uint8_t GetDadCounter(void) const { return mDadCounter; }
559 
560         /**
561          * Sets the Dad Counter.
562          *
563          * @param[in] aDadCounter The Dad Counter value.
564          *
565          */
SetDadCounter(uint8_t aDadCounter)566         void SetDadCounter(uint8_t aDadCounter) { mDadCounter = aDadCounter; }
567 
568     private:
569         void Log(Action aAction) const;
570 
571         uint8_t mDadCounter; ///< Dad Counter used to resolve address conflict in Thread 1.2 DUA feature.
572     } OT_TOOL_PACKED_END;
573 #endif // OPENTHREAD_CONFIG_DUA_ENABLE
574 
575 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
576     /**
577      * Defines constants and types for BR ULA prefix settings.
578      *
579      */
580     class BrUlaPrefix
581     {
582     public:
583         static constexpr Key kKey = kKeyBrUlaPrefix; ///< The associated key.
584 
585         typedef Ip6::Prefix ValueType; ///< The associated value type.
586 
587     private:
588         BrUlaPrefix(void) = default;
589     };
590 
591     /**
592      * Represents a BR on-link prefix entry for settings storage.
593      *
594      */
595     OT_TOOL_PACKED_BEGIN
596     class BrOnLinkPrefix : public Clearable<BrOnLinkPrefix>
597     {
598         friend class Settings;
599 
600     public:
601         static constexpr Key kKey = kKeyBrOnLinkPrefixes; ///< The associated key.
602 
603         /**
604          * Initializes the `BrOnLinkPrefix` object.
605          *
606          */
Init(void)607         void Init(void) { Clear(); }
608 
609         /**
610          * Gets the prefix.
611          *
612          * @returns The prefix.
613          *
614          */
GetPrefix(void) const615         const Ip6::Prefix &GetPrefix(void) const { return mPrefix; }
616 
617         /**
618          * Set the prefix.
619          *
620          * @param[in] aPrefix   The prefix.
621          *
622          */
SetPrefix(const Ip6::Prefix & aPrefix)623         void SetPrefix(const Ip6::Prefix &aPrefix) { mPrefix = aPrefix; }
624 
625         /**
626          * Gets the remaining prefix lifetime in seconds.
627          *
628          * @returns The prefix lifetime in seconds.
629          *
630          */
GetLifetime(void) const631         uint32_t GetLifetime(void) const { return mLifetime; }
632 
633         /**
634          * Sets the the prefix lifetime.
635          *
636          * @param[in] aLifetime  The prefix lifetime in seconds.
637          *
638          */
SetLifetime(uint32_t aLifetime)639         void SetLifetime(uint32_t aLifetime) { mLifetime = aLifetime; }
640 
641     private:
642         void Log(const char *aActionText) const;
643 
644         Ip6::Prefix mPrefix;
645         uint32_t    mLifetime;
646     } OT_TOOL_PACKED_END;
647 
648 #endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
649 
650 #if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
651     /**
652      * Defines constants and types for SRP ECDSA key settings.
653      *
654      */
655     class SrpEcdsaKey
656     {
657     public:
658         static constexpr Key kKey = kKeySrpEcdsaKey; ///< The associated key.
659 
660         typedef Crypto::Ecdsa::P256::KeyPair ValueType; ///< The associated value type.
661 
662     private:
663         SrpEcdsaKey(void) = default;
664     };
665 
666 #if OPENTHREAD_CONFIG_SRP_CLIENT_SAVE_SELECTED_SERVER_ENABLE
667     /**
668      * Represents the SRP client info (selected server address).
669      *
670      */
671     OT_TOOL_PACKED_BEGIN
672     class SrpClientInfo : private Clearable<SrpClientInfo>
673     {
674         friend class Settings;
675         friend class Clearable<SrpClientInfo>;
676 
677     public:
678         static constexpr Key kKey = kKeySrpClientInfo; ///< The associated key.
679 
680         /**
681          * Initializes the `SrpClientInfo` object.
682          *
683          */
Init(void)684         void Init(void) { Clear(); }
685 
686         /**
687          * Returns the server IPv6 address.
688          *
689          * @returns The server IPv6 address.
690          *
691          */
GetServerAddress(void) const692         const Ip6::Address &GetServerAddress(void) const { return mServerAddress; }
693 
694         /**
695          * Sets the server IPv6 address.
696          *
697          * @param[in] aAddress  The server IPv6 address.
698          *
699          */
SetServerAddress(const Ip6::Address & aAddress)700         void SetServerAddress(const Ip6::Address &aAddress) { mServerAddress = aAddress; }
701 
702         /**
703          * Returns the server port number.
704          *
705          * @returns The server port number.
706          *
707          */
GetServerPort(void) const708         uint16_t GetServerPort(void) const { return LittleEndian::HostSwap16(mServerPort); }
709 
710         /**
711          * Sets the server port number.
712          *
713          * @param[in] aPort  The server port number.
714          *
715          */
SetServerPort(uint16_t aPort)716         void SetServerPort(uint16_t aPort) { mServerPort = LittleEndian::HostSwap16(aPort); }
717 
718     private:
719         void Log(Action aAction) const;
720 
721         Ip6::Address mServerAddress;
722         uint16_t     mServerPort; // (in little-endian encoding)
723     } OT_TOOL_PACKED_END;
724 #endif // OPENTHREAD_CONFIG_SRP_CLIENT_SAVE_SELECTED_SERVER_ENABLE
725 #endif // OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
726 
727 #if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE && OPENTHREAD_CONFIG_SRP_SERVER_PORT_SWITCH_ENABLE
728     /**
729      * Represents the SRP server info.
730      *
731      */
732     OT_TOOL_PACKED_BEGIN
733     class SrpServerInfo : private Clearable<SrpServerInfo>
734     {
735         friend class Settings;
736         friend class Clearable<SrpServerInfo>;
737 
738     public:
739         static constexpr Key kKey = kKeySrpServerInfo; ///< The associated key.
740 
741         /**
742          * Initializes the `SrpServerInfo` object.
743          *
744          */
Init(void)745         void Init(void) { Clear(); }
746 
747         /**
748          * Returns the server port number.
749          *
750          * @returns The server port number.
751          *
752          */
GetPort(void) const753         uint16_t GetPort(void) const { return LittleEndian::HostSwap16(mPort); }
754 
755         /**
756          * Sets the server port number.
757          *
758          * @param[in] aPort  The server port number.
759          *
760          */
SetPort(uint16_t aPort)761         void SetPort(uint16_t aPort) { mPort = LittleEndian::HostSwap16(aPort); }
762 
763     private:
764         void Log(Action aAction) const;
765 
766         uint16_t mPort; // (in little-endian encoding)
767     } OT_TOOL_PACKED_END;
768 #endif // OPENTHREAD_CONFIG_SRP_SERVER_ENABLE && OPENTHREAD_CONFIG_SRP_SERVER_PORT_SWITCH_ENABLE
769 
770 #if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
771     /**
772      * Represents the Border Agent ID.
773      *
774      */
775     OT_TOOL_PACKED_BEGIN
776     class BorderAgentId
777     {
778         friend class Settings;
779 
780     public:
781         static constexpr Key kKey = kKeyBorderAgentId; ///< The associated key.
782 
783         /**
784          * Initializes the `BorderAgentId` object.
785          *
786          */
Init(void)787         void Init(void) { mId = {}; }
788 
789         /**
790          * Returns the Border Agent ID.
791          *
792          * @returns The Border Agent ID.
793          *
794          */
GetId(void) const795         const MeshCoP::BorderAgent::Id &GetId(void) const { return mId; }
796 
797         /**
798          * Returns the Border Agent ID.
799          *
800          * @returns The Border Agent ID.
801          *
802          */
GetId(void)803         MeshCoP::BorderAgent::Id &GetId(void) { return mId; }
804 
805         /**
806          * Sets the Border Agent ID.
807          *
808          */
SetId(const MeshCoP::BorderAgent::Id & aId)809         void SetId(const MeshCoP::BorderAgent::Id &aId) { mId = aId; }
810 
811     private:
812         void Log(Action aAction) const;
813 
814         MeshCoP::BorderAgent::Id mId;
815     } OT_TOOL_PACKED_END;
816 #endif // OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
817 
818 protected:
SettingsBase(Instance & aInstance)819     explicit SettingsBase(Instance &aInstance)
820         : InstanceLocator(aInstance)
821     {
822     }
823 
824 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
825     static void LogPrefix(Action aAction, Key aKey, const Ip6::Prefix &aPrefix);
826 #endif
827 
828 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN)
829     static const char *KeyToString(Key aKey);
830 #endif
831 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
832     static const char *ActionToString(Action aAction);
833 #endif
834 };
835 
836 /**
837  * Defines methods related to non-volatile storage of settings.
838  *
839  */
840 class Settings : public SettingsBase, private NonCopyable
841 {
842     class ChildInfoIteratorBuilder;
843 
844 public:
845     /**
846      * Initializes a `Settings` object.
847      *
848      * @param[in]  aInstance     A reference to the OpenThread instance.
849      *
850      */
Settings(Instance & aInstance)851     explicit Settings(Instance &aInstance)
852         : SettingsBase(aInstance)
853     {
854     }
855 
856     /**
857      * Initializes the platform settings (non-volatile) module.
858      *
859      * This should be called before any other method from this class.
860      *
861      */
862     void Init(void);
863 
864     /**
865      * De-initializes the platform settings (non-volatile) module.
866      *
867      * Should be called when OpenThread instance is no longer in use.
868      *
869      */
870     void Deinit(void);
871 
872     /**
873      * Removes all settings from the non-volatile store.
874      *
875      */
876     void Wipe(void);
877 
878     /**
879      * Saves the Operational Dataset (active or pending).
880      *
881      * @param[in]   aType       The Dataset type (active or pending) to save.
882      * @param[in]   aDataset    A reference to a `Dataset` object to be saved.
883      *
884      * @retval kErrorNone             Successfully saved the Dataset.
885      * @retval kErrorNotImplemented   The platform does not implement settings functionality.
886      *
887      */
888     Error SaveOperationalDataset(MeshCoP::Dataset::Type aType, const MeshCoP::Dataset &aDataset);
889 
890     /**
891      * Reads the Operational Dataset (active or pending).
892      *
893      * @param[in]   aType            The Dataset type (active or pending) to read.
894      * @param[out]  aDataset         A reference to a `Dataset` object to output the read content.
895      *
896      * @retval kErrorNone             Successfully read the Dataset.
897      * @retval kErrorNotFound         No corresponding value in the setting store.
898      * @retval kErrorNotImplemented   The platform does not implement settings functionality.
899      *
900      */
901     Error ReadOperationalDataset(MeshCoP::Dataset::Type aType, MeshCoP::Dataset &aDataset) const;
902 
903     /**
904      * Deletes the Operational Dataset (active/pending) from settings.
905      *
906      * @param[in]   aType            The Dataset type (active or pending) to delete.
907      *
908      * @retval kErrorNone            Successfully deleted the Dataset.
909      * @retval kErrorNotImplemented  The platform does not implement settings functionality.
910      *
911      */
912     Error DeleteOperationalDataset(MeshCoP::Dataset::Type aType);
913 
914     /**
915      * Reads a specified settings entry.
916      *
917      * The template type `EntryType` specifies the entry's value data structure. It must provide the following:
918      *
919      *  - It must provide a constant `EntryType::kKey` to specify the associated entry settings key.
920      *  - It must provide method `Init()` to initialize the `aEntry` object.
921      *
922      * This version of `Read<EntryType>` is intended for use with entries that define a data structure which represents
923      * the entry's value, e.g., `NetworkInfo`, `ParentInfo`, `DadInfo`, etc.
924      *
925      * @tparam EntryType              The settings entry type.
926      *
927      * @param[out] aEntry             A reference to a entry data structure to output the read content.
928      *
929      * @retval kErrorNone             Successfully read the entry.
930      * @retval kErrorNotFound         No corresponding value in the setting store.
931      * @retval kErrorNotImplemented   The platform does not implement settings functionality.
932      *
933      */
Read(EntryType & aEntry) const934     template <typename EntryType> Error Read(EntryType &aEntry) const
935     {
936         aEntry.Init();
937 
938         return ReadEntry(EntryType::kKey, &aEntry, sizeof(EntryType));
939     }
940 
941     /**
942      * Reads a specified settings entry.
943      *
944      * The template type `EntryType` provides information about the entry's value type. It must provide the following:
945      *
946      *  - It must provide a constant `EntryType::kKey` to specify the associated entry settings key.
947      *  - It must provide a nested type `EntryType::ValueType` to specify the associated entry value type.
948      *
949      * This version of `Read<EntryType>` is intended for use with entries that have a simple entry value type (which can
950      * be represented by an existing type), e.g., `OmrPrefix` (using `Ip6::Prefix` as the value type).
951      *
952      * @tparam EntryType              The settings entry type.
953      *
954      * @param[out] aValue             A reference to a value type object to output the read content.
955      *
956      * @retval kErrorNone             Successfully read the value.
957      * @retval kErrorNotFound         No corresponding value in the setting store.
958      * @retval kErrorNotImplemented   The platform does not implement settings functionality.
959      *
960      */
Read(typename EntryType::ValueType & aValue) const961     template <typename EntryType> Error Read(typename EntryType::ValueType &aValue) const
962     {
963         return ReadEntry(EntryType::kKey, &aValue, sizeof(typename EntryType::ValueType));
964     }
965 
966     /**
967      * Saves a specified settings entry.
968      *
969      * The template type `EntryType` specifies the entry's value data structure. It must provide the following:
970      *
971      *  - It must provide a constant `EntryType::kKey` to specify the associated entry settings key.
972      *
973      * This version of `Save<EntryType>` is intended for use with entries that define a data structure which represents
974      * the entry's value, e.g., `NetworkInfo`, `ParentInfo`, `DadInfo`, etc.
975      *
976      * @tparam EntryType              The settings entry type.
977      *
978      * @param[in] aEntry              The entry value to be saved.
979      *
980      * @retval kErrorNone             Successfully saved Network Info in settings.
981      * @retval kErrorNotImplemented   The platform does not implement settings functionality.
982      *
983      */
Save(const EntryType & aEntry)984     template <typename EntryType> Error Save(const EntryType &aEntry)
985     {
986         EntryType prev;
987 
988         return SaveEntry(EntryType::kKey, &aEntry, &prev, sizeof(EntryType));
989     }
990 
991     /**
992      * Saves a specified settings entry.
993      *
994      * The template type `EntryType` provides information about the entry's value type. It must provide the following:
995      *
996      *  - It must provide a constant `EntryType::kKey` to specify the associated entry settings key.
997      *  - It must provide a nested type `EntryType::ValueType` to specify the associated entry value type.
998      *
999      * This version of `Save<EntryType>` is intended for use with entries that have a simple entry value type (which can
1000      * be represented by an existing type), e.g., `OmrPrefix` (using `Ip6::Prefix` as the value type).
1001      *
1002      * @tparam EntryType              The settings entry type.
1003      *
1004      * @param[in] aValue              The entry value to be saved.
1005      *
1006      * @retval kErrorNone             Successfully saved Network Info in settings.
1007      * @retval kErrorNotImplemented   The platform does not implement settings functionality.
1008      *
1009      */
Save(const typename EntryType::ValueType & aValue)1010     template <typename EntryType> Error Save(const typename EntryType::ValueType &aValue)
1011     {
1012         typename EntryType::ValueType prev;
1013 
1014         return SaveEntry(EntryType::kKey, &aValue, &prev, sizeof(typename EntryType::ValueType));
1015     }
1016 
1017     /**
1018      * Deletes a specified setting entry.
1019      *
1020      * The template type `EntryType` provides information about the entry's key.
1021      *
1022      *  - It must provide a constant `EntryType::kKey` to specify the associated entry settings key.
1023      *
1024      * @tparam EntryType             The settings entry type.
1025      *
1026      * @retval kErrorNone            Successfully deleted the value.
1027      * @retval kErrorNotImplemented  The platform does not implement settings functionality.
1028      *
1029      */
Delete(void)1030     template <typename EntryType> Error Delete(void) { return DeleteEntry(EntryType::kKey); }
1031 
1032 #if OPENTHREAD_FTD
1033     /**
1034      * Adds a Child Info entry to settings.
1035      *
1036      * @note Child Info is a list-based settings property and can contain multiple entries.
1037      *
1038      * @param[in]   aChildInfo            A reference to a `ChildInfo` structure to be saved/added.
1039      *
1040      * @retval kErrorNone             Successfully saved the Child Info in settings.
1041      * @retval kErrorNotImplemented   The platform does not implement settings functionality.
1042      *
1043      */
1044     Error AddChildInfo(const ChildInfo &aChildInfo);
1045 
1046     /**
1047      * Deletes all Child Info entries from the settings.
1048      *
1049      * @note Child Info is a list-based settings property and can contain multiple entries.
1050      *
1051      * @retval kErrorNone            Successfully deleted the value.
1052      * @retval kErrorNotImplemented  The platform does not implement settings functionality.
1053      *
1054      */
1055     Error DeleteAllChildInfo(void);
1056 
1057     /**
1058      * Enables range-based `for` loop iteration over all child info entries in the `Settings`.
1059      *
1060      * Should be used as follows:
1061      *
1062      *     for (const ChildInfo &childInfo : Get<Settings>().IterateChildInfo()) { ... }
1063      *
1064      *
1065      * @returns A ChildInfoIteratorBuilder instance.
1066      *
1067      */
IterateChildInfo(void)1068     ChildInfoIteratorBuilder IterateChildInfo(void) { return ChildInfoIteratorBuilder(GetInstance()); }
1069 
1070     /**
1071      * Defines an iterator to access all Child Info entries in the settings.
1072      *
1073      */
1074     class ChildInfoIterator : public SettingsBase, public Unequatable<ChildInfoIterator>
1075     {
1076         friend class ChildInfoIteratorBuilder;
1077 
1078     public:
1079         /**
1080          * Initializes a `ChildInfoInterator` object.
1081          *
1082          * @param[in]  aInstance  A reference to the OpenThread instance.
1083          *
1084          */
1085         explicit ChildInfoIterator(Instance &aInstance);
1086 
1087         /**
1088          * Indicates whether there are no more Child Info entries in the list (iterator has reached end of
1089          * the list), or the current entry is valid.
1090          *
1091          * @retval TRUE   There are no more entries in the list (reached end of the list).
1092          * @retval FALSE  The current entry is valid.
1093          *
1094          */
IsDone(void) const1095         bool IsDone(void) const { return mIsDone; }
1096 
1097         /**
1098          * Overloads operator `++` (pre-increment) to advance the iterator to move to the next Child Info
1099          * entry in the list (if any).
1100          *
1101          */
operator ++(void)1102         void operator++(void) { Advance(); }
1103 
1104         /**
1105          * Overloads operator `++` (post-increment) to advance the iterator to move to the next Child Info
1106          * entry in the list (if any).
1107          *
1108          */
operator ++(int)1109         void operator++(int) { Advance(); }
1110 
1111         /**
1112          * Gets the Child Info corresponding to the current iterator entry in the list.
1113          *
1114          * @note This method should be used only if `IsDone()` is returning FALSE indicating that the iterator is
1115          * pointing to a valid entry.
1116          *
1117          * @returns A reference to `ChildInfo` structure corresponding to current iterator entry.
1118          *
1119          */
GetChildInfo(void) const1120         const ChildInfo &GetChildInfo(void) const { return mChildInfo; }
1121 
1122         /**
1123          * Deletes the current Child Info entry.
1124          *
1125          * @retval kErrorNone            The entry was deleted successfully.
1126          * @retval kErrorInvalidState    The entry is not valid (iterator has reached end of list).
1127          * @retval kErrorNotImplemented  The platform does not implement settings functionality.
1128          *
1129          */
1130         Error Delete(void);
1131 
1132         /**
1133          * Overloads the `*` dereference operator and gets a reference to `ChildInfo` entry to which the
1134          * iterator is currently pointing.
1135          *
1136          * @note This method should be used only if `IsDone()` is returning FALSE indicating that the iterator is
1137          * pointing to a valid entry.
1138          *
1139          *
1140          * @returns A reference to the `ChildInfo` entry currently pointed by the iterator.
1141          *
1142          */
operator *(void) const1143         const ChildInfo &operator*(void) const { return mChildInfo; }
1144 
1145         /**
1146          * Overloads operator `==` to evaluate whether or not two iterator instances are equal.
1147          *
1148          * @param[in]  aOther  The other iterator to compare with.
1149          *
1150          * @retval TRUE   If the two iterator objects are equal
1151          * @retval FALSE  If the two iterator objects are not equal.
1152          *
1153          */
operator ==(const ChildInfoIterator & aOther) const1154         bool operator==(const ChildInfoIterator &aOther) const
1155         {
1156             return (mIsDone && aOther.mIsDone) || (!mIsDone && !aOther.mIsDone && (mIndex == aOther.mIndex));
1157         }
1158 
1159     private:
1160         enum IteratorType : uint8_t
1161         {
1162             kEndIterator,
1163         };
1164 
ChildInfoIterator(Instance & aInstance,IteratorType)1165         ChildInfoIterator(Instance &aInstance, IteratorType)
1166             : SettingsBase(aInstance)
1167             , mIndex(0)
1168             , mIsDone(true)
1169         {
1170         }
1171 
1172         void Advance(void);
1173         void Read(void);
1174 
1175         ChildInfo mChildInfo;
1176         uint16_t  mIndex;
1177         bool      mIsDone;
1178     };
1179 #endif // OPENTHREAD_FTD
1180 
1181 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
1182     /**
1183      * Adds or updates an on-link prefix.
1184      *
1185      * If there is no matching entry (matching the same `GetPrefix()`) saved in `Settings`, the new entry will be added.
1186      * If there is matching entry, it will be updated to the new @p aPrefix.
1187      *
1188      * @param[in] aBrOnLinkPrefix    The on-link prefix to save (add or updated).
1189      *
1190      * @retval kErrorNone             Successfully added or updated the entry in settings.
1191      * @retval kErrorNotImplemented   The platform does not implement settings functionality.
1192      *
1193      */
1194     Error AddOrUpdateBrOnLinkPrefix(const BrOnLinkPrefix &aBrOnLinkPrefix);
1195 
1196     /**
1197      * Removes an on-link prefix entry matching a given prefix.
1198      *
1199      * @param[in] aPrefix            The prefix to remove
1200      *
1201      * @retval kErrorNone            Successfully removed the matching entry in settings.
1202      * @retval kErrorNotImplemented  The platform does not implement settings functionality.
1203      *
1204      */
1205     Error RemoveBrOnLinkPrefix(const Ip6::Prefix &aPrefix);
1206 
1207     /**
1208      * Deletes all on-link prefix entries from the settings.
1209      *
1210      * @retval kErrorNone            Successfully deleted the entries.
1211      * @retval kErrorNotImplemented  The platform does not implement settings functionality.
1212      *
1213      */
1214     Error DeleteAllBrOnLinkPrefixes(void);
1215 
1216     /**
1217      * Retrieves an entry from on-link prefixes list at a given index.
1218      *
1219      * @param[in]  aIndex            The index to read.
1220      * @param[out] aBrOnLinkPrefix   A reference to `BrOnLinkPrefix` to output the read value.
1221      *
1222      * @retval kErrorNone             Successfully read the value.
1223      * @retval kErrorNotFound         No corresponding value in the setting store.
1224      * @retval kErrorNotImplemented   The platform does not implement settings functionality.
1225      *
1226      */
1227     Error ReadBrOnLinkPrefix(int aIndex, BrOnLinkPrefix &aBrOnLinkPrefix);
1228 
1229 #endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
1230 
1231 private:
1232 #if OPENTHREAD_FTD
1233     class ChildInfoIteratorBuilder : public InstanceLocator
1234     {
1235     public:
ChildInfoIteratorBuilder(Instance & aInstance)1236         explicit ChildInfoIteratorBuilder(Instance &aInstance)
1237             : InstanceLocator(aInstance)
1238         {
1239         }
1240 
begin(void)1241         ChildInfoIterator begin(void) { return ChildInfoIterator(GetInstance()); }
end(void)1242         ChildInfoIterator end(void) { return ChildInfoIterator(GetInstance(), ChildInfoIterator::kEndIterator); }
1243     };
1244 #endif
1245 
1246     static Key KeyForDatasetType(MeshCoP::Dataset::Type aType);
1247 
1248     Error ReadEntry(Key aKey, void *aValue, uint16_t aMaxLength) const;
1249     Error SaveEntry(Key aKey, const void *aValue, void *aPrev, uint16_t aLength);
1250     Error DeleteEntry(Key aKey);
1251 
1252     static void Log(Action aAction, Error aError, Key aKey, const void *aValue = nullptr);
1253 
1254     static const uint16_t kSensitiveKeys[];
1255 };
1256 
1257 } // namespace ot
1258 
1259 #endif // SETTINGS_HPP_
1260