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