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