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