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