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/border_agent.h> 40 #include <openthread/platform/settings.h> 41 42 #include "common/clearable.hpp" 43 #include "common/encoding.hpp" 44 #include "common/equatable.hpp" 45 #include "common/locator.hpp" 46 #include "common/log.hpp" 47 #include "common/non_copyable.hpp" 48 #include "common/settings_driver.hpp" 49 #include "crypto/ecdsa.hpp" 50 #include "mac/mac_types.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 * This class defines the base class used by `Settings` and `Settings::ChildInfoIterator`. 63 * 64 * This class 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 * This enumeration 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 * This structure 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 * This method initializes the `NetworkInfo` object. 147 * 148 */ Init(void)149 void Init(void) 150 { 151 Clear(); 152 SetVersion(kThreadVersion1p1); 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 friend class Clearable<ParentInfo>; 348 349 public: 350 static constexpr Key kKey = kKeyParentInfo; ///< The associated key. 351 352 /** 353 * This method initializes the `ParentInfo` object. 354 * 355 */ Init(void)356 void Init(void) 357 { 358 Clear(); 359 SetVersion(kThreadVersion1p1); 360 } 361 362 /** 363 * This method 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 * This method 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 * This method returns the Thread version. 380 * 381 * @returns The Thread version. 382 * 383 */ GetVersion(void) const384 uint16_t GetVersion(void) const { return Encoding::LittleEndian::HostSwap16(mVersion); } 385 386 /** 387 * This method 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 = Encoding::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 * This structure 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 * This method clears the struct object (setting all the fields to zero). 416 * 417 */ Init(void)418 void Init(void) 419 { 420 memset(this, 0, sizeof(*this)); 421 SetVersion(kThreadVersion1p1); 422 } 423 424 /** 425 * This method 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 * This method 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 * This method returns the child timeout. 442 * 443 * @returns The child timeout. 444 * 445 */ GetTimeout(void) const446 uint32_t GetTimeout(void) const { return Encoding::LittleEndian::HostSwap32(mTimeout); } 447 448 /** 449 * This method 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 = Encoding::LittleEndian::HostSwap32(aTimeout); } 455 456 /** 457 * This method returns the RLOC16. 458 * 459 * @returns The RLOC16. 460 * 461 */ GetRloc16(void) const462 uint16_t GetRloc16(void) const { return Encoding::LittleEndian::HostSwap16(mRloc16); } 463 464 /** 465 * This method sets the RLOC16. 466 * 467 * @param[in] aRloc16 The RLOC16. 468 * 469 */ SetRloc16(uint16_t aRloc16)470 void SetRloc16(uint16_t aRloc16) { mRloc16 = Encoding::LittleEndian::HostSwap16(aRloc16); } 471 472 /** 473 * This method 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 * This method 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 * This method returns the Thread version. 490 * 491 * @returns The Thread version. 492 * 493 */ GetVersion(void) const494 uint16_t GetVersion(void) const { return Encoding::LittleEndian::HostSwap16(mVersion); } 495 496 /** 497 * This method 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 = Encoding::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 * This class 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 * This structure 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 * This method initializes the `DadInfo` object. 548 * 549 */ Init(void)550 void Init(void) { Clear(); } 551 552 /** 553 * This method 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 * This method 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 * This class 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 * This class 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 * This method initializes the `BrOnLinkPrefix` object. 605 * 606 */ Init(void)607 void Init(void) { Clear(); } 608 609 /** 610 * This method gets the prefix. 611 * 612 * @returns The prefix. 613 * 614 */ GetPrefix(void) const615 const Ip6::Prefix &GetPrefix(void) const { return mPrefix; } 616 617 /** 618 * This method 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 * This method 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 * This method 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 * This class 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 * This structure 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 * This method initializes the `SrpClientInfo` object. 682 * 683 */ Init(void)684 void Init(void) { Clear(); } 685 686 /** 687 * This method 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 * This method 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 * This method returns the server port number. 704 * 705 * @returns The server port number. 706 * 707 */ GetServerPort(void) const708 uint16_t GetServerPort(void) const { return Encoding::LittleEndian::HostSwap16(mServerPort); } 709 710 /** 711 * This method 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 = Encoding::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 * This structure 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 * This method initializes the `SrpServerInfo` object. 743 * 744 */ Init(void)745 void Init(void) { Clear(); } 746 747 /** 748 * This method returns the server port number. 749 * 750 * @returns The server port number. 751 * 752 */ GetPort(void) const753 uint16_t GetPort(void) const { return Encoding::LittleEndian::HostSwap16(mPort); } 754 755 /** 756 * This method 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 = Encoding::LittleEndian::HostSwap16(aPort); } 762 763 private: 764 void Log(Action aAction) const; 765 766 uint16_t mPort; // (in little-endian encoding) 767 } OT_TOOL_PACKED_END; 768 #endif // OPENTHREAD_CONFIG_SRP_SERVER_ENABLE && OPENTHREAD_CONFIG_SRP_SERVER_PORT_SWITCH_ENABLE 769 770 #if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE 771 /** 772 * This structure represents the Border Agent ID. 773 * 774 */ 775 OT_TOOL_PACKED_BEGIN 776 class BorderAgentId : private Clearable<BorderAgentId> 777 { 778 friend class Settings; 779 friend class Clearable<BorderAgentId>; 780 781 public: 782 static constexpr Key kKey = kKeyBorderAgentId; ///< The associated key. 783 static constexpr uint8_t kLength = OT_BORDER_AGENT_ID_LENGTH; 784 785 /** 786 * This method initializes the `BorderAgentId` object. 787 * 788 */ Init(void)789 void Init(void) { Clear(); } 790 791 /** 792 * This method returns the Border Agent ID. 793 * 794 * @returns The Border Agent ID. 795 * 796 */ GetId(void) const797 const uint8_t *GetId(void) const { return mId; } 798 799 /** 800 * This method returns the Border Agent ID. 801 * 802 * @returns The Border Agent ID. 803 * 804 */ GetId(void)805 uint8_t *GetId(void) { return mId; } 806 807 /** 808 * This method sets the Border Agent ID. 809 * 810 * @retval kErrorInvalidArgs If `aLength` doesn't equal to `OT_BORDER_AGENT_ID_LENGTH`. 811 * @retval kErrorNone If success. 812 * 813 */ 814 Error SetId(const uint8_t *aId, uint16_t aLength); 815 816 private: 817 void Log(Action aAction) const; 818 819 uint8_t mId[kLength]; 820 } OT_TOOL_PACKED_END; 821 #endif // OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE 822 823 protected: SettingsBase(Instance & aInstance)824 explicit SettingsBase(Instance &aInstance) 825 : InstanceLocator(aInstance) 826 { 827 } 828 829 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE 830 static void LogPrefix(Action aAction, Key aKey, const Ip6::Prefix &aPrefix); 831 #endif 832 833 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN) 834 static const char *KeyToString(Key aKey); 835 #endif 836 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO) 837 static const char *ActionToString(Action aAction); 838 #endif 839 }; 840 841 /** 842 * This class defines methods related to non-volatile storage of settings. 843 * 844 */ 845 class Settings : public SettingsBase, private NonCopyable 846 { 847 class ChildInfoIteratorBuilder; 848 849 public: 850 /** 851 * This constructor initializes a `Settings` object. 852 * 853 * @param[in] aInstance A reference to the OpenThread instance. 854 * 855 */ Settings(Instance & aInstance)856 explicit Settings(Instance &aInstance) 857 : SettingsBase(aInstance) 858 { 859 } 860 861 /** 862 * This method initializes the platform settings (non-volatile) module. 863 * 864 * This should be called before any other method from this class. 865 * 866 */ 867 void Init(void); 868 869 /** 870 * This method de-initializes the platform settings (non-volatile) module. 871 * 872 * This method should be called when OpenThread instance is no longer in use. 873 * 874 */ 875 void Deinit(void); 876 877 /** 878 * This method removes all settings from the non-volatile store. 879 * 880 */ 881 void Wipe(void); 882 883 /** 884 * This method saves the Operational Dataset (active or pending). 885 * 886 * @param[in] aType The Dataset type (active or pending) to save. 887 * @param[in] aDataset A reference to a `Dataset` object to be saved. 888 * 889 * @retval kErrorNone Successfully saved the Dataset. 890 * @retval kErrorNotImplemented The platform does not implement settings functionality. 891 * 892 */ 893 Error SaveOperationalDataset(MeshCoP::Dataset::Type aType, const MeshCoP::Dataset &aDataset); 894 895 /** 896 * This method reads the Operational Dataset (active or pending). 897 * 898 * @param[in] aType The Dataset type (active or pending) to read. 899 * @param[out] aDataset A reference to a `Dataset` object to output the read content. 900 * 901 * @retval kErrorNone Successfully read the Dataset. 902 * @retval kErrorNotFound No corresponding value in the setting store. 903 * @retval kErrorNotImplemented The platform does not implement settings functionality. 904 * 905 */ 906 Error ReadOperationalDataset(MeshCoP::Dataset::Type aType, MeshCoP::Dataset &aDataset) const; 907 908 /** 909 * This method deletes the Operational Dataset (active/pending) from settings. 910 * 911 * @param[in] aType The Dataset type (active or pending) to delete. 912 * 913 * @retval kErrorNone Successfully deleted the Dataset. 914 * @retval kErrorNotImplemented The platform does not implement settings functionality. 915 * 916 */ 917 Error DeleteOperationalDataset(MeshCoP::Dataset::Type aType); 918 919 /** 920 * This template method reads a specified settings entry. 921 * 922 * The template type `EntryType` specifies the entry's value data structure. It must provide the following: 923 * 924 * - It must provide a constant `EntryType::kKey` to specify the associated entry settings key. 925 * - It must provide method `Init()` to initialize the `aEntry` object. 926 * 927 * This version of `Read<EntryType>` is intended for use with entries that define a data structure which represents 928 * the entry's value, e.g., `NetworkInfo`, `ParentInfo`, `DadInfo`, etc. 929 * 930 * @tparam EntryType The settings entry type. 931 * 932 * @param[out] aEntry A reference to a entry data structure to output the read content. 933 * 934 * @retval kErrorNone Successfully read the entry. 935 * @retval kErrorNotFound No corresponding value in the setting store. 936 * @retval kErrorNotImplemented The platform does not implement settings functionality. 937 * 938 */ Read(EntryType & aEntry) const939 template <typename EntryType> Error Read(EntryType &aEntry) const 940 { 941 aEntry.Init(); 942 943 return ReadEntry(EntryType::kKey, &aEntry, sizeof(EntryType)); 944 } 945 946 /** 947 * This template method reads a specified settings entry. 948 * 949 * The template type `EntryType` provides information about the entry's value type. It must provide the following: 950 * 951 * - It must provide a constant `EntryType::kKey` to specify the associated entry settings key. 952 * - It must provide a nested type `EntryType::ValueType` to specify the associated entry value type. 953 * 954 * This version of `Read<EntryType>` is intended for use with entries that have a simple entry value type (which can 955 * be represented by an existing type), e.g., `OmrPrefix` (using `Ip6::Prefix` as the value type). 956 * 957 * @tparam EntryType The settings entry type. 958 * 959 * @param[out] aValue A reference to a value type object to output the read content. 960 * 961 * @retval kErrorNone Successfully read the value. 962 * @retval kErrorNotFound No corresponding value in the setting store. 963 * @retval kErrorNotImplemented The platform does not implement settings functionality. 964 * 965 */ Read(typename EntryType::ValueType & aValue) const966 template <typename EntryType> Error Read(typename EntryType::ValueType &aValue) const 967 { 968 return ReadEntry(EntryType::kKey, &aValue, sizeof(typename EntryType::ValueType)); 969 } 970 971 /** 972 * This template method saves a specified settings entry. 973 * 974 * The template type `EntryType` specifies the entry's value data structure. It must provide the following: 975 * 976 * - It must provide a constant `EntryType::kKey` to specify the associated entry settings key. 977 * 978 * This version of `Save<EntryType>` is intended for use with entries that define a data structure which represents 979 * the entry's value, e.g., `NetworkInfo`, `ParentInfo`, `DadInfo`, etc. 980 * 981 * @tparam EntryType The settings entry type. 982 * 983 * @param[in] aEntry The entry value to be saved. 984 * 985 * @retval kErrorNone Successfully saved Network Info in settings. 986 * @retval kErrorNotImplemented The platform does not implement settings functionality. 987 * 988 */ Save(const EntryType & aEntry)989 template <typename EntryType> Error Save(const EntryType &aEntry) 990 { 991 EntryType prev; 992 993 return SaveEntry(EntryType::kKey, &aEntry, &prev, sizeof(EntryType)); 994 } 995 996 /** 997 * This template method saves a specified settings entry. 998 * 999 * The template type `EntryType` provides information about the entry's value type. It must provide the following: 1000 * 1001 * - It must provide a constant `EntryType::kKey` to specify the associated entry settings key. 1002 * - It must provide a nested type `EntryType::ValueType` to specify the associated entry value type. 1003 * 1004 * This version of `Save<EntryType>` is intended for use with entries that have a simple entry value type (which can 1005 * be represented by an existing type), e.g., `OmrPrefix` (using `Ip6::Prefix` as the value type). 1006 * 1007 * @tparam EntryType The settings entry type. 1008 * 1009 * @param[in] aValue The entry value to be saved. 1010 * 1011 * @retval kErrorNone Successfully saved Network Info in settings. 1012 * @retval kErrorNotImplemented The platform does not implement settings functionality. 1013 * 1014 */ Save(const typename EntryType::ValueType & aValue)1015 template <typename EntryType> Error Save(const typename EntryType::ValueType &aValue) 1016 { 1017 typename EntryType::ValueType prev; 1018 1019 return SaveEntry(EntryType::kKey, &aValue, &prev, sizeof(typename EntryType::ValueType)); 1020 } 1021 1022 /** 1023 * This template method deletes a specified setting entry. 1024 * 1025 * The template type `EntryType` provides information about the entry's key. 1026 * 1027 * - It must provide a constant `EntryType::kKey` to specify the associated entry settings key. 1028 * 1029 * @tparam EntryType The settings entry type. 1030 * 1031 * @retval kErrorNone Successfully deleted the value. 1032 * @retval kErrorNotImplemented The platform does not implement settings functionality. 1033 * 1034 */ Delete(void)1035 template <typename EntryType> Error Delete(void) { return DeleteEntry(EntryType::kKey); } 1036 1037 #if OPENTHREAD_FTD 1038 /** 1039 * This method adds a Child Info entry to settings. 1040 * 1041 * @note Child Info is a list-based settings property and can contain multiple entries. 1042 * 1043 * @param[in] aChildInfo A reference to a `ChildInfo` structure to be saved/added. 1044 * 1045 * @retval kErrorNone Successfully saved the Child Info in settings. 1046 * @retval kErrorNotImplemented The platform does not implement settings functionality. 1047 * 1048 */ 1049 Error AddChildInfo(const ChildInfo &aChildInfo); 1050 1051 /** 1052 * This method deletes all Child Info entries from the settings. 1053 * 1054 * @note Child Info is a list-based settings property and can contain multiple entries. 1055 * 1056 * @retval kErrorNone Successfully deleted the value. 1057 * @retval kErrorNotImplemented The platform does not implement settings functionality. 1058 * 1059 */ 1060 Error DeleteAllChildInfo(void); 1061 1062 /** 1063 * This method enables range-based `for` loop iteration over all child info entries in the `Settings`. 1064 * 1065 * This method should be used as follows: 1066 * 1067 * for (const ChildInfo &childInfo : Get<Settings>().IterateChildInfo()) { ... } 1068 * 1069 * 1070 * @returns A ChildInfoIteratorBuilder instance. 1071 * 1072 */ IterateChildInfo(void)1073 ChildInfoIteratorBuilder IterateChildInfo(void) { return ChildInfoIteratorBuilder(GetInstance()); } 1074 1075 /** 1076 * This class defines an iterator to access all Child Info entries in the settings. 1077 * 1078 */ 1079 class ChildInfoIterator : public SettingsBase, public Unequatable<ChildInfoIterator> 1080 { 1081 friend class ChildInfoIteratorBuilder; 1082 1083 public: 1084 /** 1085 * This constructor initializes a `ChildInfoInterator` object. 1086 * 1087 * @param[in] aInstance A reference to the OpenThread instance. 1088 * 1089 */ 1090 explicit ChildInfoIterator(Instance &aInstance); 1091 1092 /** 1093 * This method indicates whether there are no more Child Info entries in the list (iterator has reached end of 1094 * the list), or the current entry is valid. 1095 * 1096 * @retval TRUE There are no more entries in the list (reached end of the list). 1097 * @retval FALSE The current entry is valid. 1098 * 1099 */ IsDone(void) const1100 bool IsDone(void) const { return mIsDone; } 1101 1102 /** 1103 * This method overloads operator `++` (pre-increment) to advance the iterator to move to the next Child Info 1104 * entry in the list (if any). 1105 * 1106 */ operator ++(void)1107 void operator++(void) { Advance(); } 1108 1109 /** 1110 * This method overloads operator `++` (post-increment) to advance the iterator to move to the next Child Info 1111 * entry in the list (if any). 1112 * 1113 */ operator ++(int)1114 void operator++(int) { Advance(); } 1115 1116 /** 1117 * This method gets the Child Info corresponding to the current iterator entry in the list. 1118 * 1119 * @note This method should be used only if `IsDone()` is returning FALSE indicating that the iterator is 1120 * pointing to a valid entry. 1121 * 1122 * @returns A reference to `ChildInfo` structure corresponding to current iterator entry. 1123 * 1124 */ GetChildInfo(void) const1125 const ChildInfo &GetChildInfo(void) const { return mChildInfo; } 1126 1127 /** 1128 * This method deletes the current Child Info entry. 1129 * 1130 * @retval kErrorNone The entry was deleted successfully. 1131 * @retval kErrorInvalidState The entry is not valid (iterator has reached end of list). 1132 * @retval kErrorNotImplemented The platform does not implement settings functionality. 1133 * 1134 */ 1135 Error Delete(void); 1136 1137 /** 1138 * This method overloads the `*` dereference operator and gets a reference to `ChildInfo` entry to which the 1139 * iterator is currently pointing. 1140 * 1141 * @note This method should be used only if `IsDone()` is returning FALSE indicating that the iterator is 1142 * pointing to a valid entry. 1143 * 1144 * 1145 * @returns A reference to the `ChildInfo` entry currently pointed by the iterator. 1146 * 1147 */ operator *(void) const1148 const ChildInfo &operator*(void) const { return mChildInfo; } 1149 1150 /** 1151 * This method overloads operator `==` to evaluate whether or not two iterator instances are equal. 1152 * 1153 * @param[in] aOther The other iterator to compare with. 1154 * 1155 * @retval TRUE If the two iterator objects are equal 1156 * @retval FALSE If the two iterator objects are not equal. 1157 * 1158 */ operator ==(const ChildInfoIterator & aOther) const1159 bool operator==(const ChildInfoIterator &aOther) const 1160 { 1161 return (mIsDone && aOther.mIsDone) || (!mIsDone && !aOther.mIsDone && (mIndex == aOther.mIndex)); 1162 } 1163 1164 private: 1165 enum IteratorType : uint8_t 1166 { 1167 kEndIterator, 1168 }; 1169 ChildInfoIterator(Instance & aInstance,IteratorType)1170 ChildInfoIterator(Instance &aInstance, IteratorType) 1171 : SettingsBase(aInstance) 1172 , mIndex(0) 1173 , mIsDone(true) 1174 { 1175 } 1176 1177 void Advance(void); 1178 void Read(void); 1179 1180 ChildInfo mChildInfo; 1181 uint16_t mIndex; 1182 bool mIsDone; 1183 }; 1184 #endif // OPENTHREAD_FTD 1185 1186 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE 1187 /** 1188 * This method adds or updates an on-link prefix. 1189 * 1190 * If there is no matching entry (matching the same `GetPrefix()`) saved in `Settings`, the new entry will be added. 1191 * If there is matching entry, it will be updated to the new @p aPrefix. 1192 * 1193 * @param[in] aBrOnLinkPrefix The on-link prefix to save (add or updated). 1194 * 1195 * @retval kErrorNone Successfully added or updated the entry in settings. 1196 * @retval kErrorNotImplemented The platform does not implement settings functionality. 1197 * 1198 */ 1199 Error AddOrUpdateBrOnLinkPrefix(const BrOnLinkPrefix &aBrOnLinkPrefix); 1200 1201 /** 1202 * This method removes an on-link prefix entry matching a given prefix. 1203 * 1204 * @param[in] aPrefix The prefix to remove 1205 * 1206 * @retval kErrorNone Successfully removed the matching entry in settings. 1207 * @retval kErrorNotImplemented The platform does not implement settings functionality. 1208 * 1209 */ 1210 Error RemoveBrOnLinkPrefix(const Ip6::Prefix &aPrefix); 1211 1212 /** 1213 * This method deletes all on-link prefix entries from the settings. 1214 * 1215 * @retval kErrorNone Successfully deleted the entries. 1216 * @retval kErrorNotImplemented The platform does not implement settings functionality. 1217 * 1218 */ 1219 Error DeleteAllBrOnLinkPrefixes(void); 1220 1221 /** 1222 * This method retrieves an entry from on-link prefixes list at a given index. 1223 * 1224 * @param[in] aIndex The index to read. 1225 * @param[out] aBrOnLinkPrefix A reference to `BrOnLinkPrefix` to output the read value. 1226 * 1227 * @retval kErrorNone Successfully read the value. 1228 * @retval kErrorNotFound No corresponding value in the setting store. 1229 * @retval kErrorNotImplemented The platform does not implement settings functionality. 1230 * 1231 */ 1232 Error ReadBrOnLinkPrefix(int aIndex, BrOnLinkPrefix &aBrOnLinkPrefix); 1233 1234 #endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE 1235 1236 private: 1237 #if OPENTHREAD_FTD 1238 class ChildInfoIteratorBuilder : public InstanceLocator 1239 { 1240 public: ChildInfoIteratorBuilder(Instance & aInstance)1241 explicit ChildInfoIteratorBuilder(Instance &aInstance) 1242 : InstanceLocator(aInstance) 1243 { 1244 } 1245 begin(void)1246 ChildInfoIterator begin(void) { return ChildInfoIterator(GetInstance()); } end(void)1247 ChildInfoIterator end(void) { return ChildInfoIterator(GetInstance(), ChildInfoIterator::kEndIterator); } 1248 }; 1249 #endif 1250 1251 static Key KeyForDatasetType(MeshCoP::Dataset::Type aType); 1252 1253 Error ReadEntry(Key aKey, void *aValue, uint16_t aMaxLength) const; 1254 Error SaveEntry(Key aKey, const void *aValue, void *aPrev, uint16_t aLength); 1255 Error DeleteEntry(Key aKey); 1256 1257 static void Log(Action aAction, Error aError, Key aKey, const void *aValue = nullptr); 1258 1259 static const uint16_t kSensitiveKeys[]; 1260 }; 1261 1262 } // namespace ot 1263 1264 #endif // SETTINGS_HPP_ 1265