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 ClearAllBytes(*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_ENABLE && 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) { ClearAllBytes(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_ENABLE && 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 */ 885 void SaveOperationalDataset(MeshCoP::Dataset::Type aType, const MeshCoP::Dataset &aDataset); 886 887 /** 888 * Reads the Operational Dataset (active or pending). 889 * 890 * @param[in] aType The Dataset type (active or pending) to read. 891 * @param[out] aDataset A reference to a `Dataset` object to output the read content. 892 * 893 * @retval kErrorNone Successfully read the Dataset. 894 * @retval kErrorNotFound No corresponding value in the setting store. 895 * 896 */ 897 Error ReadOperationalDataset(MeshCoP::Dataset::Type aType, MeshCoP::Dataset &aDataset) const; 898 899 /** 900 * Deletes the Operational Dataset (active/pending) from settings. 901 * 902 * @param[in] aType The Dataset type (active or pending) to delete. 903 * 904 */ 905 void DeleteOperationalDataset(MeshCoP::Dataset::Type aType); 906 907 /** 908 * Reads a specified settings entry. 909 * 910 * The template type `EntryType` specifies the entry's value data structure. 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 method `Init()` to initialize the `aEntry` object. 914 * 915 * This version of `Read<EntryType>` is intended for use with entries that define a data structure which represents 916 * the entry's value, e.g., `NetworkInfo`, `ParentInfo`, `DadInfo`, etc. 917 * 918 * @tparam EntryType The settings entry type. 919 * 920 * @param[out] aEntry A reference to a entry data structure to output the read content. 921 * 922 * @retval kErrorNone Successfully read the entry. 923 * @retval kErrorNotFound No corresponding value in the setting store. 924 * @retval kErrorNotImplemented The platform does not implement settings functionality. 925 * 926 */ Read(EntryType & aEntry) const927 template <typename EntryType> Error Read(EntryType &aEntry) const 928 { 929 aEntry.Init(); 930 931 return ReadEntry(EntryType::kKey, &aEntry, sizeof(EntryType)); 932 } 933 934 /** 935 * Reads a specified settings entry. 936 * 937 * The template type `EntryType` provides information about the entry's value type. It must provide the following: 938 * 939 * - It must provide a constant `EntryType::kKey` to specify the associated entry settings key. 940 * - It must provide a nested type `EntryType::ValueType` to specify the associated entry value type. 941 * 942 * This version of `Read<EntryType>` is intended for use with entries that have a simple entry value type (which can 943 * be represented by an existing type), e.g., `OmrPrefix` (using `Ip6::Prefix` as the value type). 944 * 945 * @tparam EntryType The settings entry type. 946 * 947 * @param[out] aValue A reference to a value type object to output the read content. 948 * 949 * @retval kErrorNone Successfully read the value. 950 * @retval kErrorNotFound No corresponding value in the setting store. 951 * @retval kErrorNotImplemented The platform does not implement settings functionality. 952 * 953 */ Read(typename EntryType::ValueType & aValue) const954 template <typename EntryType> Error Read(typename EntryType::ValueType &aValue) const 955 { 956 return ReadEntry(EntryType::kKey, &aValue, sizeof(typename EntryType::ValueType)); 957 } 958 959 /** 960 * Saves a specified settings entry. 961 * 962 * The template type `EntryType` specifies the entry's value data structure. It must provide the following: 963 * 964 * - It must provide a constant `EntryType::kKey` to specify the associated entry settings key. 965 * 966 * This version of `Save<EntryType>` is intended for use with entries that define a data structure which represents 967 * the entry's value, e.g., `NetworkInfo`, `ParentInfo`, `DadInfo`, etc. 968 * 969 * @tparam EntryType The settings entry type. 970 * 971 * @param[in] aEntry The entry value to be saved. 972 * 973 * @retval kErrorNone Successfully saved Network Info in settings. 974 * @retval kErrorNotImplemented The platform does not implement settings functionality. 975 * 976 */ Save(const EntryType & aEntry)977 template <typename EntryType> Error Save(const EntryType &aEntry) 978 { 979 EntryType prev; 980 981 return SaveEntry(EntryType::kKey, &aEntry, &prev, sizeof(EntryType)); 982 } 983 984 /** 985 * Saves a specified settings entry. 986 * 987 * The template type `EntryType` provides information about the entry's value type. It must provide the following: 988 * 989 * - It must provide a constant `EntryType::kKey` to specify the associated entry settings key. 990 * - It must provide a nested type `EntryType::ValueType` to specify the associated entry value type. 991 * 992 * This version of `Save<EntryType>` is intended for use with entries that have a simple entry value type (which can 993 * be represented by an existing type), e.g., `OmrPrefix` (using `Ip6::Prefix` as the value type). 994 * 995 * @tparam EntryType The settings entry type. 996 * 997 * @param[in] aValue The entry value to be saved. 998 * 999 * @retval kErrorNone Successfully saved Network Info in settings. 1000 * @retval kErrorNotImplemented The platform does not implement settings functionality. 1001 * 1002 */ Save(const typename EntryType::ValueType & aValue)1003 template <typename EntryType> Error Save(const typename EntryType::ValueType &aValue) 1004 { 1005 typename EntryType::ValueType prev; 1006 1007 return SaveEntry(EntryType::kKey, &aValue, &prev, sizeof(typename EntryType::ValueType)); 1008 } 1009 1010 /** 1011 * Deletes a specified setting entry. 1012 * 1013 * The template type `EntryType` provides information about the entry's key. 1014 * 1015 * - It must provide a constant `EntryType::kKey` to specify the associated entry settings key. 1016 * 1017 * @tparam EntryType The settings entry type. 1018 * 1019 * @retval kErrorNone Successfully deleted the value. 1020 * @retval kErrorNotImplemented The platform does not implement settings functionality. 1021 * 1022 */ Delete(void)1023 template <typename EntryType> Error Delete(void) { return DeleteEntry(EntryType::kKey); } 1024 1025 #if OPENTHREAD_FTD 1026 /** 1027 * Adds a Child Info entry to settings. 1028 * 1029 * @note Child Info is a list-based settings property and can contain multiple entries. 1030 * 1031 * @param[in] aChildInfo A reference to a `ChildInfo` structure to be saved/added. 1032 * 1033 * @retval kErrorNone Successfully saved the Child Info in settings. 1034 * @retval kErrorNotImplemented The platform does not implement settings functionality. 1035 * 1036 */ 1037 Error AddChildInfo(const ChildInfo &aChildInfo); 1038 1039 /** 1040 * Deletes all Child Info entries from the settings. 1041 * 1042 * @note Child Info is a list-based settings property and can contain multiple entries. 1043 * 1044 * @retval kErrorNone Successfully deleted the value. 1045 * @retval kErrorNotImplemented The platform does not implement settings functionality. 1046 * 1047 */ 1048 Error DeleteAllChildInfo(void); 1049 1050 /** 1051 * Enables range-based `for` loop iteration over all child info entries in the `Settings`. 1052 * 1053 * Should be used as follows: 1054 * 1055 * for (const ChildInfo &childInfo : Get<Settings>().IterateChildInfo()) { ... } 1056 * 1057 * 1058 * @returns A ChildInfoIteratorBuilder instance. 1059 * 1060 */ IterateChildInfo(void)1061 ChildInfoIteratorBuilder IterateChildInfo(void) { return ChildInfoIteratorBuilder(GetInstance()); } 1062 1063 /** 1064 * Defines an iterator to access all Child Info entries in the settings. 1065 * 1066 */ 1067 class ChildInfoIterator : public SettingsBase, public Unequatable<ChildInfoIterator> 1068 { 1069 friend class ChildInfoIteratorBuilder; 1070 1071 public: 1072 /** 1073 * Initializes a `ChildInfoInterator` object. 1074 * 1075 * @param[in] aInstance A reference to the OpenThread instance. 1076 * 1077 */ 1078 explicit ChildInfoIterator(Instance &aInstance); 1079 1080 /** 1081 * Indicates whether there are no more Child Info entries in the list (iterator has reached end of 1082 * the list), or the current entry is valid. 1083 * 1084 * @retval TRUE There are no more entries in the list (reached end of the list). 1085 * @retval FALSE The current entry is valid. 1086 * 1087 */ IsDone(void) const1088 bool IsDone(void) const { return mIsDone; } 1089 1090 /** 1091 * Overloads operator `++` (pre-increment) to advance the iterator to move to the next Child Info 1092 * entry in the list (if any). 1093 * 1094 */ operator ++(void)1095 void operator++(void) { Advance(); } 1096 1097 /** 1098 * Overloads operator `++` (post-increment) to advance the iterator to move to the next Child Info 1099 * entry in the list (if any). 1100 * 1101 */ operator ++(int)1102 void operator++(int) { Advance(); } 1103 1104 /** 1105 * Gets the Child Info corresponding to the current iterator entry in the list. 1106 * 1107 * @note This method should be used only if `IsDone()` is returning FALSE indicating that the iterator is 1108 * pointing to a valid entry. 1109 * 1110 * @returns A reference to `ChildInfo` structure corresponding to current iterator entry. 1111 * 1112 */ GetChildInfo(void) const1113 const ChildInfo &GetChildInfo(void) const { return mChildInfo; } 1114 1115 /** 1116 * Deletes the current Child Info entry. 1117 * 1118 * @retval kErrorNone The entry was deleted successfully. 1119 * @retval kErrorInvalidState The entry is not valid (iterator has reached end of list). 1120 * @retval kErrorNotImplemented The platform does not implement settings functionality. 1121 * 1122 */ 1123 Error Delete(void); 1124 1125 /** 1126 * Overloads the `*` dereference operator and gets a reference to `ChildInfo` entry to which the 1127 * iterator is currently pointing. 1128 * 1129 * @note This method should be used only if `IsDone()` is returning FALSE indicating that the iterator is 1130 * pointing to a valid entry. 1131 * 1132 * 1133 * @returns A reference to the `ChildInfo` entry currently pointed by the iterator. 1134 * 1135 */ operator *(void) const1136 const ChildInfo &operator*(void) const { return mChildInfo; } 1137 1138 /** 1139 * Overloads operator `==` to evaluate whether or not two iterator instances are equal. 1140 * 1141 * @param[in] aOther The other iterator to compare with. 1142 * 1143 * @retval TRUE If the two iterator objects are equal 1144 * @retval FALSE If the two iterator objects are not equal. 1145 * 1146 */ operator ==(const ChildInfoIterator & aOther) const1147 bool operator==(const ChildInfoIterator &aOther) const 1148 { 1149 return (mIsDone && aOther.mIsDone) || (!mIsDone && !aOther.mIsDone && (mIndex == aOther.mIndex)); 1150 } 1151 1152 private: 1153 enum IteratorType : uint8_t 1154 { 1155 kEndIterator, 1156 }; 1157 ChildInfoIterator(Instance & aInstance,IteratorType)1158 ChildInfoIterator(Instance &aInstance, IteratorType) 1159 : SettingsBase(aInstance) 1160 , mIndex(0) 1161 , mIsDone(true) 1162 { 1163 } 1164 1165 void Advance(void); 1166 void Read(void); 1167 1168 ChildInfo mChildInfo; 1169 uint16_t mIndex; 1170 bool mIsDone; 1171 }; 1172 #endif // OPENTHREAD_FTD 1173 1174 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE 1175 /** 1176 * Adds or updates an on-link prefix. 1177 * 1178 * If there is no matching entry (matching the same `GetPrefix()`) saved in `Settings`, the new entry will be added. 1179 * If there is matching entry, it will be updated to the new @p aPrefix. 1180 * 1181 * @param[in] aBrOnLinkPrefix The on-link prefix to save (add or updated). 1182 * 1183 * @retval kErrorNone Successfully added or updated the entry in settings. 1184 * @retval kErrorNotImplemented The platform does not implement settings functionality. 1185 * 1186 */ 1187 Error AddOrUpdateBrOnLinkPrefix(const BrOnLinkPrefix &aBrOnLinkPrefix); 1188 1189 /** 1190 * Removes an on-link prefix entry matching a given prefix. 1191 * 1192 * @param[in] aPrefix The prefix to remove 1193 * 1194 * @retval kErrorNone Successfully removed the matching entry in settings. 1195 * @retval kErrorNotImplemented The platform does not implement settings functionality. 1196 * 1197 */ 1198 Error RemoveBrOnLinkPrefix(const Ip6::Prefix &aPrefix); 1199 1200 /** 1201 * Deletes all on-link prefix entries from the settings. 1202 * 1203 * @retval kErrorNone Successfully deleted the entries. 1204 * @retval kErrorNotImplemented The platform does not implement settings functionality. 1205 * 1206 */ 1207 Error DeleteAllBrOnLinkPrefixes(void); 1208 1209 /** 1210 * Retrieves an entry from on-link prefixes list at a given index. 1211 * 1212 * @param[in] aIndex The index to read. 1213 * @param[out] aBrOnLinkPrefix A reference to `BrOnLinkPrefix` to output the read value. 1214 * 1215 * @retval kErrorNone Successfully read the value. 1216 * @retval kErrorNotFound No corresponding value in the setting store. 1217 * @retval kErrorNotImplemented The platform does not implement settings functionality. 1218 * 1219 */ 1220 Error ReadBrOnLinkPrefix(int aIndex, BrOnLinkPrefix &aBrOnLinkPrefix); 1221 1222 #endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE 1223 1224 private: 1225 #if OPENTHREAD_FTD 1226 class ChildInfoIteratorBuilder : public InstanceLocator 1227 { 1228 public: ChildInfoIteratorBuilder(Instance & aInstance)1229 explicit ChildInfoIteratorBuilder(Instance &aInstance) 1230 : InstanceLocator(aInstance) 1231 { 1232 } 1233 begin(void)1234 ChildInfoIterator begin(void) { return ChildInfoIterator(GetInstance()); } end(void)1235 ChildInfoIterator end(void) { return ChildInfoIterator(GetInstance(), ChildInfoIterator::kEndIterator); } 1236 }; 1237 #endif 1238 1239 static Key KeyForDatasetType(MeshCoP::Dataset::Type aType); 1240 1241 Error ReadEntry(Key aKey, void *aValue, uint16_t aMaxLength) const; 1242 Error SaveEntry(Key aKey, const void *aValue, void *aPrev, uint16_t aLength); 1243 Error DeleteEntry(Key aKey); 1244 1245 static void Log(Action aAction, Error aError, Key aKey, const void *aValue = nullptr); 1246 1247 static const uint16_t kSensitiveKeys[]; 1248 }; 1249 1250 } // namespace ot 1251 1252 #endif // SETTINGS_HPP_ 1253