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