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