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