diff --git a/etc/visual-studio/libopenthread.vcxproj b/etc/visual-studio/libopenthread.vcxproj
index 6c705b71a..5258d1fcc 100644
--- a/etc/visual-studio/libopenthread.vcxproj
+++ b/etc/visual-studio/libopenthread.vcxproj
@@ -82,6 +82,7 @@
+
diff --git a/etc/visual-studio/libopenthread.vcxproj.filters b/etc/visual-studio/libopenthread.vcxproj.filters
index d11a2c08f..2e4558714 100644
--- a/etc/visual-studio/libopenthread.vcxproj.filters
+++ b/etc/visual-studio/libopenthread.vcxproj.filters
@@ -144,6 +144,9 @@
Source Files\common
+
+ Source Files\common
+
Source Files\common
diff --git a/etc/visual-studio/libopenthread_k.vcxproj b/etc/visual-studio/libopenthread_k.vcxproj
index 633ab275a..68b2b8bbd 100644
--- a/etc/visual-studio/libopenthread_k.vcxproj
+++ b/etc/visual-studio/libopenthread_k.vcxproj
@@ -91,6 +91,7 @@
+
diff --git a/etc/visual-studio/libopenthread_k.vcxproj.filters b/etc/visual-studio/libopenthread_k.vcxproj.filters
index 9a8231810..36caed498 100644
--- a/etc/visual-studio/libopenthread_k.vcxproj.filters
+++ b/etc/visual-studio/libopenthread_k.vcxproj.filters
@@ -144,6 +144,9 @@
Source Files\common
+
+ Source Files\common
+
Source Files\common
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index 9db5c4404..06c55aa6d 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -123,6 +123,7 @@ SOURCES_COMMON = \
common/locator.cpp \
common/notifier.cpp \
common/message.cpp \
+ common/settings.cpp \
common/tasklet.cpp \
common/timer.cpp \
common/tlvs.cpp \
diff --git a/src/core/api/thread_api.cpp b/src/core/api/thread_api.cpp
index 99760a62b..ec87a4268 100644
--- a/src/core/api/thread_api.cpp
+++ b/src/core/api/thread_api.cpp
@@ -36,7 +36,6 @@
#include "openthread-core-config.h"
#include
-#include
#include "common/instance.hpp"
#include "common/logging.hpp"
@@ -497,10 +496,10 @@ exit:
bool otThreadGetAutoStart(otInstance *aInstance)
{
#if OPENTHREAD_CONFIG_ENABLE_AUTO_START_SUPPORT
- uint8_t autoStart = 0;
- uint16_t autoStartLength = sizeof(autoStart);
+ uint8_t autoStart = 0;
+ Instance &instance = *static_cast(aInstance);
- if (otPlatSettingsGet(aInstance, Settings::kKeyThreadAutoStart, 0, &autoStart, &autoStartLength) != OT_ERROR_NONE)
+ if (instance.GetSettings().ReadThreadAutoStart(autoStart) != OT_ERROR_NONE)
{
autoStart = 0;
}
@@ -515,8 +514,10 @@ bool otThreadGetAutoStart(otInstance *aInstance)
otError otThreadSetAutoStart(otInstance *aInstance, bool aStartAutomatically)
{
#if OPENTHREAD_CONFIG_ENABLE_AUTO_START_SUPPORT
- uint8_t autoStart = aStartAutomatically ? 1 : 0;
- return otPlatSettingsSet(aInstance, Settings::kKeyThreadAutoStart, &autoStart, sizeof(autoStart));
+ uint8_t autoStart = aStartAutomatically ? 1 : 0;
+ Instance &instance = *static_cast(aInstance);
+
+ return instance.GetSettings().SaveThreadAutoStart(autoStart);
#else
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aStartAutomatically);
diff --git a/src/core/common/instance.cpp b/src/core/common/instance.cpp
index d3acacd07..af950d2fe 100644
--- a/src/core/common/instance.cpp
+++ b/src/core/common/instance.cpp
@@ -36,7 +36,6 @@
#include "instance.hpp"
#include
-#include
#include "common/logging.hpp"
#include "common/new.hpp"
@@ -56,6 +55,7 @@ Instance::Instance(void)
, mEnergyScanCallback(NULL)
, mEnergyScanCallbackContext(NULL)
, mNotifier(*this)
+ , mSettings(*this)
, mTimerMilliScheduler(*this)
#if OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER
, mTimerMicroScheduler(*this)
@@ -134,7 +134,7 @@ void Instance::AfterInit(void)
// Restore datasets and network information
- otPlatSettingsInit(this);
+ GetSettings().Init();
mThreadNetif.GetMle().Restore();
#if OPENTHREAD_CONFIG_ENABLE_AUTO_START_SUPPORT
@@ -175,7 +175,7 @@ void Instance::Reset(void)
void Instance::FactoryReset(void)
{
- otPlatSettingsWipe(this);
+ GetSettings().Wipe();
otPlatReset(this);
}
@@ -184,7 +184,7 @@ otError Instance::ErasePersistentInfo(void)
otError error = OT_ERROR_NONE;
VerifyOrExit(mThreadNetif.GetMle().GetRole() == OT_DEVICE_ROLE_DISABLED, error = OT_ERROR_INVALID_STATE);
- otPlatSettingsWipe(this);
+ GetSettings().Wipe();
exit:
return error;
diff --git a/src/core/common/instance.hpp b/src/core/common/instance.hpp
index a38e0953a..c51b0b944 100644
--- a/src/core/common/instance.hpp
+++ b/src/core/common/instance.hpp
@@ -52,6 +52,7 @@
#include "crypto/mbedtls.hpp"
#endif
#include "common/notifier.hpp"
+#include "common/settings.hpp"
#include "net/ip6.hpp"
#include "thread/link_quality.hpp"
#include "thread/thread_netif.hpp"
@@ -234,6 +235,14 @@ public:
*/
Notifier &GetNotifier(void) { return mNotifier; }
+ /**
+ * This method returns a reference to the `Settings` object.
+ *
+ * @returns A reference to the `Settings` object.
+ *
+ */
+ Settings &GetSettings(void) { return mSettings; }
+
/**
* This method returns a reference to the tasklet scheduler object.
*
@@ -361,6 +370,7 @@ private:
void * mEnergyScanCallbackContext;
Notifier mNotifier;
+ Settings mSettings;
TaskletScheduler mTaskletScheduler;
TimerMilliScheduler mTimerMilliScheduler;
diff --git a/src/core/common/settings.cpp b/src/core/common/settings.cpp
new file mode 100644
index 000000000..7cee7f085
--- /dev/null
+++ b/src/core/common/settings.cpp
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 2018, The OpenThread Authors.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ * This file includes definitions for non-volatile storage of settings.
+ */
+
+#define WPP_NAME "settings.tmh"
+
+#include "settings.hpp"
+
+#include
+
+#include "common/code_utils.hpp"
+#include "common/instance.hpp"
+#include "common/logging.hpp"
+#include "meshcop/dataset.hpp"
+#include "thread/mle.hpp"
+
+namespace ot {
+
+#if (OPENTHREAD_CONFIG_LOG_UTIL != 0)
+#if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO)
+
+void SettingsBase::LogNetworkInfo(const char *aAction, const NetworkInfo &aNetworkInfo) const
+{
+ char string[Mac::Address::kAddressStringSize];
+
+ otLogInfoCore(GetInstance(),
+ "Non-volatile: %s NetworkInfo {rloc:0x%04x, extaddr:%s, role:%s, mode:0x%02x, keyseq:0x%x, ...",
+ aAction, aNetworkInfo.mRloc16, aNetworkInfo.mExtAddress.ToString(string, sizeof(string)),
+ Mle::Mle::RoleToString(static_cast(aNetworkInfo.mRole)), aNetworkInfo.mDeviceMode,
+ aNetworkInfo.mKeySequence);
+
+ otLogInfoCore(GetInstance(),
+ "Non-volatile: ... pid:0x%x, mlecntr:0x%x, maccntr:0x%x, mliid:%02x%02x%02x%02x%02x%02x%02x%02x}",
+ aNetworkInfo.mPreviousPartitionId, aNetworkInfo.mMleFrameCounter, aNetworkInfo.mMacFrameCounter,
+ aNetworkInfo.mMlIid[0], aNetworkInfo.mMlIid[1], aNetworkInfo.mMlIid[2], aNetworkInfo.mMlIid[3],
+ aNetworkInfo.mMlIid[4], aNetworkInfo.mMlIid[5], aNetworkInfo.mMlIid[6], aNetworkInfo.mMlIid[7]);
+}
+
+void SettingsBase::LogParentInfo(const char *aAction, const ParentInfo &aParentInfo) const
+{
+ char string[Mac::Address::kAddressStringSize];
+
+ otLogInfoCore(GetInstance(), "Non-volatile: %s ParentInfo {extaddr:%s}", aAction,
+ aParentInfo.mExtAddress.ToString(string, sizeof(string)));
+}
+
+void SettingsBase::LogChildInfo(const char *aAction, const ChildInfo &aChildInfo) const
+{
+ char string[Mac::Address::kAddressStringSize];
+
+ otLogInfoCore(GetInstance(), "Non-volatile: %s ChildInfo {rloc:0x%04x, extaddr:%s, timeout:%u, mode:0x%02x}",
+ aAction, aChildInfo.mRloc16, aChildInfo.mExtAddress.ToString(string, sizeof(string)),
+ aChildInfo.mTimeout, aChildInfo.mMode);
+}
+
+#endif // #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO)
+
+#if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_WARN)
+
+void SettingsBase::LogFailure(otError error, const char *aText) const
+{
+ if (error != OT_ERROR_NONE)
+ {
+ otLogWarnCore(GetInstance(), "Non-volatile: Error %s %s", otThreadErrorToString(error), aText);
+ }
+}
+
+#endif // #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_WARN)
+#endif // #if (OPENTHREAD_CONFIG_LOG_UTIL != 0)
+
+void Settings::Init(void)
+{
+ otPlatSettingsInit(&GetInstance());
+}
+
+void Settings::Wipe(void)
+{
+ otPlatSettingsWipe(&GetInstance());
+ otLogInfoCore(GetInstance(), "Non-volatile: Wiped all info");
+}
+
+otError Settings::SaveOperationalDataset(bool aIsActive, const MeshCoP::Dataset &aDataset)
+{
+ otError error = Save(aIsActive ? kKeyActiveDataset : kKeyPendingDataset, aDataset.GetBytes(), aDataset.GetSize());
+
+ LogFailure(error, "saving OperationalDataset");
+ return error;
+}
+
+otError Settings::ReadOperationalDataset(bool aIsActive, MeshCoP::Dataset &aDataset) const
+{
+ otError error = OT_ERROR_NONE;
+ uint16_t length;
+
+ SuccessOrExit(error = Read(aIsActive ? kKeyActiveDataset : kKeyPendingDataset, aDataset.GetBytes(),
+ MeshCoP::Dataset::kMaxSize, length));
+ aDataset.SetSize(length);
+
+exit:
+ return error;
+}
+
+otError Settings::DeleteOperationalDataset(bool aIsActive)
+{
+ otError error = Delete(aIsActive ? kKeyActiveDataset : kKeyPendingDataset);
+
+ LogFailure(error, "deleting OperationalDataset");
+ return error;
+}
+
+otError Settings::ReadNetworkInfo(NetworkInfo &aNetworkInfo) const
+{
+ otError error;
+
+ SuccessOrExit(error = ReadFixedSize(kKeyNetworkInfo, &aNetworkInfo, sizeof(NetworkInfo)));
+ LogNetworkInfo("Read", aNetworkInfo);
+
+exit:
+ return error;
+}
+
+otError Settings::SaveNetworkInfo(const NetworkInfo &aNetworkInfo)
+{
+ otError error;
+
+ SuccessOrExit(error = Save(kKeyNetworkInfo, &aNetworkInfo, sizeof(NetworkInfo)));
+ LogNetworkInfo("Saved", aNetworkInfo);
+
+exit:
+ LogFailure(error, "saving NetworkInfo");
+ return error;
+}
+
+otError Settings::DeleteNetworkInfo(void)
+{
+ otError error;
+
+ SuccessOrExit(error = Delete(kKeyNetworkInfo));
+ otLogInfoCore(GetInstance(), "Non-volatile: Deleted NetworkInfo");
+
+exit:
+ LogFailure(error, "deleting NetworkInfo");
+ return error;
+}
+
+otError Settings::ReadParentInfo(ParentInfo &aParentInfo) const
+{
+ otError error;
+
+ SuccessOrExit(error = ReadFixedSize(kKeyParentInfo, &aParentInfo, sizeof(ParentInfo)));
+ LogParentInfo("Read", aParentInfo);
+
+exit:
+ return error;
+}
+
+otError Settings::SaveParentInfo(const ParentInfo &aParentInfo)
+{
+ otError error;
+
+ SuccessOrExit(error = Save(kKeyParentInfo, &aParentInfo, sizeof(ParentInfo)));
+ LogParentInfo("Saved", aParentInfo);
+
+exit:
+ LogFailure(error, "saving ParentInfo");
+ return error;
+}
+
+otError Settings::DeleteParentInfo(void)
+{
+ otError error;
+
+ SuccessOrExit(error = Delete(kKeyParentInfo));
+ otLogInfoCore(GetInstance(), "Non-volatile: Deleted ParentInfo");
+
+exit:
+ LogFailure(error, "deleting ParentInfo");
+ return error;
+}
+
+otError Settings::AddChildInfo(const ChildInfo &aChildInfo)
+{
+ otError error;
+
+ SuccessOrExit(error = Add(kKeyChildInfo, &aChildInfo, sizeof(aChildInfo)));
+ LogChildInfo("Added", aChildInfo);
+
+exit:
+ LogFailure(error, "adding ChildInfo");
+ return error;
+}
+
+otError Settings::DeleteChildInfo(void)
+{
+ otError error;
+
+ SuccessOrExit(error = Delete(kKeyChildInfo));
+ otLogInfoCore(GetInstance(), "Non-volatile: Deleted all ChildInfo");
+
+exit:
+ LogFailure(error, "deleting all ChildInfo");
+ return error;
+}
+
+Settings::ChildInfoIterator::ChildInfoIterator(Instance &aInstance)
+ : SettingsBase(aInstance)
+ , mIndex(0)
+ , mIsDone(false)
+{
+ Reset();
+}
+
+void Settings::ChildInfoIterator::Reset(void)
+{
+ mIndex = 0;
+ mIsDone = false;
+ Read();
+}
+
+void Settings::ChildInfoIterator::Advance(void)
+{
+ if (!mIsDone)
+ {
+ mIndex++;
+ Read();
+ }
+}
+
+otError Settings::ChildInfoIterator::Delete(void)
+{
+ otError error = OT_ERROR_NONE;
+
+ VerifyOrExit(!mIsDone, error = OT_ERROR_INVALID_STATE);
+ SuccessOrExit(error = otPlatSettingsDelete(&GetInstance(), kKeyChildInfo, mIndex));
+ LogChildInfo("Removed", mChildInfo);
+
+exit:
+ LogFailure(error, "removing ChildInfo entry");
+ return error;
+}
+
+void Settings::ChildInfoIterator::Read(void)
+{
+ uint16_t size = sizeof(ChildInfo);
+ otError error;
+
+ SuccessOrExit(error = otPlatSettingsGet(&GetInstance(), kKeyChildInfo, mIndex,
+ reinterpret_cast(&mChildInfo), &size));
+ VerifyOrExit(size >= sizeof(ChildInfo), error = OT_ERROR_NOT_FOUND);
+ LogChildInfo("Read", mChildInfo);
+
+exit:
+ mIsDone = (error != OT_ERROR_NONE);
+}
+
+otError Settings::ReadFixedSize(Key aKey, void *aBuffer, uint16_t aExpectedSize) const
+{
+ uint16_t size = aExpectedSize;
+ otError error;
+
+ SuccessOrExit(error = otPlatSettingsGet(&GetInstance(), aKey, 0, reinterpret_cast(aBuffer), &size));
+ VerifyOrExit(size >= aExpectedSize, error = OT_ERROR_NOT_FOUND);
+
+exit:
+ return error;
+}
+
+otError Settings::Read(Key aKey, void *aBuffer, uint16_t aMaxBufferSize, uint16_t &aReadSize) const
+{
+ uint16_t size = aMaxBufferSize;
+ otError error;
+
+ SuccessOrExit(error = otPlatSettingsGet(&GetInstance(), aKey, 0, reinterpret_cast(aBuffer), &size));
+ aReadSize = (size <= aMaxBufferSize) ? size : aMaxBufferSize;
+
+exit:
+ return error;
+}
+
+otError Settings::Save(Key aKey, const void *aBuffer, uint16_t aSize)
+{
+ return otPlatSettingsSet(&GetInstance(), aKey, reinterpret_cast(aBuffer), aSize);
+}
+
+otError Settings::Add(Key aKey, const void *aBuffer, uint16_t aSize)
+{
+ return otPlatSettingsAdd(&GetInstance(), aKey, reinterpret_cast(aBuffer), aSize);
+}
+
+otError Settings::Delete(Key aKey)
+{
+ return otPlatSettingsDelete(&GetInstance(), aKey, -1);
+}
+
+} // namespace ot
diff --git a/src/core/common/settings.hpp b/src/core/common/settings.hpp
index c0b809e4b..c7d5ae621 100644
--- a/src/core/common/settings.hpp
+++ b/src/core/common/settings.hpp
@@ -28,7 +28,7 @@
/**
* @file
- * This file includes functions for debugging.
+ * This file includes definitions for non-volatile storage of settings.
*/
#ifndef SETTINGS_HPP_
@@ -36,86 +36,387 @@
#include "openthread-core-config.h"
+#include "common/locator.hpp"
+#include "mac/mac_frame.hpp"
#include "thread/mle.hpp"
namespace ot {
-namespace Settings {
+
+namespace MeshCoP {
+class Dataset;
+}
/**
- * Rules for updating existing value structures.
+ * This class defines the base class used by `Settings` and `Settings::ChildInfoIterator`.
*
- * 1. Modifying existing otPlatSettings* key value fields MUST only be
- * done by appending new fields. Existing fields MUST NOT be
- * deleted or modified in any way.
- *
- * 2. To support backward compatibility (rolling back to an older
- * software version), code reading and processing key values MUST
- * process key values that have longer length. Additionally, newer
- * versions MUST update/maintain values in existing key value
- * fields.
- *
- * 3. To support forward compatibility (rolling forward to a newer
- * software version), code reading and processing key values MUST
- * process key values that have shorter length.
- *
- * 4. New Key IDs may be defined in the future with the understanding
- * that such key values are not backward compatible.
+ * This class provides structure definitions for different settings keys.
*
*/
-
-/**
- * This enumeration defines the keys of settings
- *
- */
-enum
+class SettingsBase : public InstanceLocator
{
- kKeyActiveDataset = 0x0001, ///< Active Operational Dataset
- kKeyPendingDataset = 0x0002, ///< Pending Operational Dataset
- kKeyNetworkInfo = 0x0003, ///< Thread network information
- kKeyParentInfo = 0x0004, ///< Parent information
- kKeyChildInfo = 0x0005, ///< Child information
- kKeyThreadAutoStart = 0x0006, ///< Auto-start information
+public:
+ /**
+ * Rules for updating existing value structures.
+ *
+ * 1. Modifying existing key value fields in settings MUST only be
+ * done by appending new fields. Existing fields MUST NOT be
+ * deleted or modified in any way.
+ *
+ * 2. To support backward compatibility (rolling back to an older
+ * software version), code reading and processing key values MUST
+ * process key values that have longer length. Additionally, newer
+ * versions MUST update/maintain values in existing key value
+ * fields.
+ *
+ * 3. To support forward compatibility (rolling forward to a newer
+ * software version), code reading and processing key values MUST
+ * process key values that have shorter length.
+ *
+ * 4. New Key IDs may be defined in the future with the understanding
+ * that such key values are not backward compatible.
+ *
+ */
+
+ /**
+ * This structure represents the device's own network information for settings storage.
+ *
+ */
+ struct NetworkInfo
+ {
+ uint8_t mRole; ///< Current Thread role.
+ uint8_t mDeviceMode; ///< Device mode setting.
+ uint16_t mRloc16; ///< RLOC16
+ uint32_t mKeySequence; ///< Key Sequence
+ uint32_t mMleFrameCounter; ///< MLE Frame Counter
+ uint32_t mMacFrameCounter; ///< MAC Frame Counter
+ uint32_t mPreviousPartitionId; ///< PartitionId
+ Mac::ExtAddress mExtAddress; ///< Extended Address
+ uint8_t mMlIid[OT_IP6_IID_SIZE]; ///< IID from ML-EID
+ };
+
+ /**
+ * This structure represents the parent information for settings storage.
+ *
+ */
+ struct ParentInfo
+ {
+ Mac::ExtAddress mExtAddress; ///< Extended Address
+ };
+
+ /**
+ * This structure represents the child information for settings storage.
+ *
+ */
+ struct ChildInfo
+ {
+ Mac::ExtAddress mExtAddress; ///< Extended Address
+ uint32_t mTimeout; ///< Timeout
+ uint16_t mRloc16; ///< RLOC16
+ uint8_t mMode; ///< The MLE device mode
+ };
+
+protected:
+ /**
+ * This enumeration defines the keys of settings.
+ *
+ */
+ enum Key
+ {
+ kKeyActiveDataset = 0x0001, ///< Active Operational Dataset
+ kKeyPendingDataset = 0x0002, ///< Pending Operational Dataset
+ kKeyNetworkInfo = 0x0003, ///< Thread network information
+ kKeyParentInfo = 0x0004, ///< Parent information
+ kKeyChildInfo = 0x0005, ///< Child information
+ kKeyThreadAutoStart = 0x0006, ///< Auto-start information
+ };
+
+ explicit SettingsBase(Instance &aInstance)
+ : InstanceLocator(aInstance)
+ {
+ }
+
+#if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_UTIL != 0)
+ void LogNetworkInfo(const char *aAction, const NetworkInfo &aNetworkInfo) const;
+ void LogParentInfo(const char *aAction, const ParentInfo &aParentInfo) const;
+ void LogChildInfo(const char *aAction, const ChildInfo &aChildInfo) const;
+#else
+ void LogNetworkInfo(const char *, const NetworkInfo &) const {}
+ void LogParentInfo(const char *, const ParentInfo &) const {}
+ void LogChildInfo(const char *, const ChildInfo &) const {}
+#endif
+
+#if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_WARN) && (OPENTHREAD_CONFIG_LOG_UTIL != 0)
+ void LogFailure(otError aError, const char *aAction) const;
+#else
+ void LogFailure(otError, const char *) const {}
+#endif
};
/**
- * This structure represents the device's own network information for settings storage.
+ * This class defines methods related to non-volatile storage of settings.
*
*/
-struct NetworkInfo
+class Settings : public SettingsBase
{
- uint8_t mRole; ///< Current Thread role.
- uint8_t mDeviceMode; ///< Device mode setting.
- uint16_t mRloc16; ///< RLOC16
- uint32_t mKeySequence; ///< Key Sequence
- uint32_t mMleFrameCounter; ///< MLE Frame Counter
- uint32_t mMacFrameCounter; ///< MAC Frame Counter
- uint32_t mPreviousPartitionId; ///< PartitionId
- Mac::ExtAddress mExtAddress; ///< Extended Address
- uint8_t mMlIid[OT_IP6_IID_SIZE]; ///< IID from ML-EID
+public:
+ /**
+ * This constructor initializes a `Settings` object.
+ *
+ * @param[in] aInstance A reference to the OpenThread instance.
+ *
+ */
+ explicit Settings(Instance &aInstance)
+ : SettingsBase(aInstance)
+ {
+ }
+
+ /**
+ * This method initializes the platform settings (non-volatile) module.
+ *
+ * This should be called before any other method from this class.
+ *
+ */
+ void Init(void);
+
+ /**
+ * This method removes all settings from the non-volatile store.
+ *
+ */
+ void Wipe(void);
+
+ /**
+ * This method saves the Operational Dataset (active or pending).
+ *
+ * @param[in] aIsActive Indicates whether Dataset is active or pending.
+ * @param[in] aDataset A reference to a `Dataset` object to be saved.
+ *
+ * @retval OT_ERROR_NONE Successfully saved the Dataset.
+ * @retval OT_ERROR_NOT_IMPLEMENTED The platform does not implement settings functionality.
+ *
+ */
+ otError SaveOperationalDataset(bool aIsActive, const MeshCoP::Dataset &aDataset);
+
+ /**
+ * This method reads the Operational Dataset (active or pending).
+ *
+ * @param[in] aIsActive Indicates whether Dataset is active or pending.
+ * @param[out] aDataset A reference to a `Dataset` object to output the read content.
+ *
+ * @retval OT_ERROR_NONE Successfully read the Dataset.
+ * @retval OT_ERROR_NOT_FOUND No corresponding value in the setting store.
+ * @retval OT_ERROR_NOT_IMPLEMENTED The platform does not implement settings functionality.
+ *
+ */
+ otError ReadOperationalDataset(bool aIsActive, MeshCoP::Dataset &aDataset) const;
+
+ /**
+ * This method deletes the Operational Dataset (active/pending) from settings.
+ *
+ * @param[in] aIsActive Indicates whether Dataset is active or pending.
+ *
+ * @retval OT_ERROR_NONE Successfully deleted the Dataset.
+ * @retval OT_ERROR_NOT_IMPLEMENTED The platform does not implement settings functionality.
+ *
+ */
+ otError DeleteOperationalDataset(bool aIsActive);
+
+ /**
+ * This method saves Network Info.
+ *
+ * @param[in] aNetworkInfo A reference to a `NetworkInfo` structure to be saved.
+ *
+ * @retval OT_ERROR_NONE Successfully saved Network Info in settings.
+ * @retval OT_ERROR_NOT_IMPLEMENTED The platform does not implement settings functionality.
+ *
+ */
+ otError SaveNetworkInfo(const NetworkInfo &aNetworkInfo);
+
+ /**
+ * This method reads Network Info.
+ *
+ * @param[out] aNetworkInfo A reference to a `NetworkInfo` structure to output the read content.
+ *
+ * @retval OT_ERROR_NONE Successfully read the Network Info.
+ * @retval OT_ERROR_NOT_FOUND No corresponding value in the setting store.
+ * @retval OT_ERROR_NOT_IMPLEMENTED The platform does not implement settings functionality.
+ *
+ */
+ otError ReadNetworkInfo(NetworkInfo &aNetworkInfo) const;
+
+ /**
+ * This method deletes Network Info from settings.
+ *
+ * @retval OT_ERROR_NONE Successfully deleted the value.
+ * @retval OT_ERROR_NOT_IMPLEMENTED The platform does not implement settings functionality.
+ *
+ */
+ otError DeleteNetworkInfo(void);
+
+ /**
+ * This method saves Parent Info.
+ *
+ * @param[in] aParentInfo A reference to a `ParentInfo` structure to be saved.
+ *
+ * @retval OT_ERROR_NONE Successfully saved Parent Info in settings.
+ * @retval OT_ERROR_NOT_IMPLEMENTED The platform does not implement settings functionality.
+ *
+ */
+ otError SaveParentInfo(const ParentInfo &aParentInfo);
+
+ /**
+ * This method reads Parent Info.
+ *
+ * @param[out] aParentInfo A reference to a `ParentInfo` structure to output the read content.
+ *
+ * @retval OT_ERROR_NONE Successfully read the Parent Info.
+ * @retval OT_ERROR_NOT_FOUND No corresponding value in the setting store.
+ * @retval OT_ERROR_NOT_IMPLEMENTED The platform does not implement settings functionality.
+ *
+ */
+ otError ReadParentInfo(ParentInfo &aParentInfo) const;
+
+ /**
+ * This method deletes Parent Info from settings.
+ *
+ * @retval OT_ERROR_NONE Successfully deleted the value.
+ * @retval OT_ERROR_NOT_IMPLEMENTED The platform does not implement settings functionality.
+ *
+ */
+ otError DeleteParentInfo(void);
+
+ /**
+ * This method saves ThreadAutoStart.
+ *
+ * @param[in] aAutoStart A value to be saved (0 or 1).
+ *
+ * @retval OT_ERROR_NONE Successfully saved the value.
+ * @retval OT_ERROR_NOT_IMPLEMENTED The platform does not implement settings functionality.
+ *
+ */
+ otError SaveThreadAutoStart(uint8_t aAutoStart) { return Save(kKeyThreadAutoStart, &aAutoStart, sizeof(uint8_t)); }
+
+ /**
+ * This method reads ThreadAutoStart .
+ *
+ * @param[out] aAutoStart A reference to a `uint8_t` to output the read value
+ *
+ * @retval OT_ERROR_NONE Successfully read the value.
+ * @retval OT_ERROR_NOT_FOUND No corresponding value in the setting store.
+ * @retval OT_ERROR_NOT_IMPLEMENTED The platform does not implement settings functionality.
+ *
+ */
+ otError ReadThreadAutoStart(uint8_t &aAutoStart) const
+ {
+ return ReadFixedSize(kKeyThreadAutoStart, &aAutoStart, sizeof(uint8_t));
+ }
+
+ /**
+ * This method deletes ThreadAutoStart value from settings.
+ *
+ * @retval OT_ERROR_NONE Successfully deleted the value.
+ * @retval OT_ERROR_NOT_IMPLEMENTED The platform does not implement settings functionality.
+ *
+ */
+ otError DeleteThreadAutoStart(void) { return Delete(kKeyThreadAutoStart); }
+
+ /**
+ * This method adds a Child Info entry to settings.
+ *
+ * @note Child Info is a list-based settings property and can contain multiple entries.
+ *
+ * @param[in] aChildInfo A reference to a `ChildInfo` structure to be saved/added.
+ *
+ * @retval OT_ERROR_NONE Successfully saved the Child Info in settings.
+ * @retval OT_ERROR_NOT_IMPLEMENTED The platform does not implement settings functionality.
+ *
+ */
+ otError AddChildInfo(const ChildInfo &aChildInfo);
+
+ /**
+ * This method deletes all Child Info entries from the settings.
+ *
+ * @note Child Info is a list-based settings property and can contain multiple entries.
+ *
+ * @retval OT_ERROR_NONE Successfully deleted the value.
+ * @retval OT_ERROR_NOT_IMPLEMENTED The platform does not implement settings functionality.
+ *
+ */
+ otError DeleteChildInfo(void);
+
+ /**
+ * This class defines an iterator to access all Child Info entries in the settings.
+ *
+ */
+ class ChildInfoIterator : public SettingsBase
+ {
+ public:
+ /**
+ * This constructor initializes a `ChildInfoInterator` object.
+ *
+ * @param[in] aInstance A reference to the OpenThread instance.
+ *
+ */
+ ChildInfoIterator(Instance &aInstance);
+
+ /**
+ * This method resets the iterator to start from the first Child Info entry in the list.
+ *
+ */
+ void Reset(void);
+
+ /**
+ * This method indicates whether there are no more Child Info entries in the list (iterator has reached end of
+ * the list), or the current entry is valid.
+ *
+ * @retval TRUE There are no more entries in the list (reached end of the list).
+ * @retval FALSE The current entry is valid.
+ *
+ */
+ bool IsDone(void) { return mIsDone; }
+
+ /**
+ * This method advances the iterator to move to the next Child Info entry in the list (if any).
+ *
+ */
+ void Advance(void);
+
+ /**
+ * This method gets the Child Info corresponding to the current iterator entry in the list.
+ *
+ * @note This method should be used only if `IsDone()` is returning FALSE indicating that the iterator is
+ * pointing to a valid entry.
+ *
+ * @returns A reference to `ChildInfo` structure corresponding to current iterator entry.
+ *
+ */
+ const ChildInfo &GetChildInfo(void) const { return mChildInfo; }
+
+ /**
+ * This method deletes the current Child Info entry.
+ *
+ * @retval OT_ERROR_NONE The entry was deleted successfully.
+ * @retval OT_ERROR_INVALID_STATE The entry is not valid (iterator has reached end of list).
+ * @retval OT_ERROR_NOT_IMPLEMENTED The platform does not implement settings functionality.
+ *
+ */
+ otError Delete(void);
+
+ private:
+ void Read(void);
+
+ ChildInfo mChildInfo;
+ uint8_t mIndex;
+ bool mIsDone;
+ };
+
+private:
+ otError ReadFixedSize(Key aKey, void *aBuffer, uint16_t aExpectedLength) const;
+ otError Read(Key aKey, void *aBuffer, uint16_t aMaxBufferSize, uint16_t &aReadSize) const;
+ otError Save(Key aKey, const void *aValue, uint16_t aSize);
+ otError Add(Key aKey, const void *aValue, uint16_t aSize);
+ otError Delete(Key aKey);
};
-/**
- * This structure represents the parent information for settings storage.
- *
- */
-struct ParentInfo
-{
- Mac::ExtAddress mExtAddress; ///< Extended Address
-};
-
-/**
- * This structure represents the child information for settings storage.
- *
- */
-struct ChildInfo
-{
- Mac::ExtAddress mExtAddress; ///< Extended Address
- uint32_t mTimeout; ///< Timeout
- uint16_t mRloc16; ///< RLOC16
- uint8_t mMode; ///< The MLE device mode
-};
-
-} // namespace Settings
} // namespace ot
#endif // SETTINGS_HPP_
diff --git a/src/core/meshcop/dataset.cpp b/src/core/meshcop/dataset.cpp
index e64062158..5c7888de0 100644
--- a/src/core/meshcop/dataset.cpp
+++ b/src/core/meshcop/dataset.cpp
@@ -41,7 +41,6 @@
#include "common/code_utils.hpp"
#include "common/instance.hpp"
#include "common/logging.hpp"
-#include "common/settings.hpp"
#include "meshcop/meshcop_tlvs.hpp"
#include "thread/mle_tlvs.hpp"
@@ -509,22 +508,6 @@ exit:
return error;
}
-uint16_t Dataset::GetSettingsKey(void)
-{
- uint16_t rval;
-
- if (mType == Tlv::kActiveTimestamp)
- {
- rval = static_cast(Settings::kKeyActiveDataset);
- }
- else
- {
- rval = static_cast(Settings::kKeyPendingDataset);
- }
-
- return rval;
-}
-
void Dataset::Remove(uint8_t *aStart, uint8_t aLength)
{
memmove(aStart, aStart + aLength, mLength - (static_cast(aStart - mTlvs) + aLength));
diff --git a/src/core/meshcop/dataset.hpp b/src/core/meshcop/dataset.hpp
index 9c21620a2..7c937307c 100644
--- a/src/core/meshcop/dataset.hpp
+++ b/src/core/meshcop/dataset.hpp
@@ -85,6 +85,14 @@ public:
*/
const Tlv *Get(Tlv::Type aType) const;
+ /**
+ * This method returns a pointer to the byte representation of the Dataset.
+ *
+ * @returns A pointer to the byte representation of the Dataset.
+ *
+ */
+ uint8_t *GetBytes(void) { return mTlvs; }
+
/**
* This method returns a pointer to the byte representation of the Dataset.
*
@@ -107,6 +115,14 @@ public:
*/
uint16_t GetSize(void) const { return mLength; }
+ /**
+ * This method sets the Dataset size in bytes.
+ *
+ * @param[in] aSize The Dataset size in bytes.
+ *
+ */
+ void SetSize(uint16_t aSize) { mLength = aSize; }
+
/**
* This method returns the local time the dataset was last updated.
*
@@ -216,8 +232,6 @@ public:
otError ConvertToActive(void);
private:
- uint16_t GetSettingsKey(void);
-
void Remove(uint8_t *aStart, uint8_t aLength);
uint8_t mTlvs[kMaxSize]; ///< The Dataset buffer
diff --git a/src/core/meshcop/dataset_local.cpp b/src/core/meshcop/dataset_local.cpp
index 01107ab6b..d55a4b2b8 100644
--- a/src/core/meshcop/dataset_local.cpp
+++ b/src/core/meshcop/dataset_local.cpp
@@ -38,8 +38,6 @@
#include
-#include
-
#include "common/code_utils.hpp"
#include "common/instance.hpp"
#include "common/logging.hpp"
@@ -64,7 +62,7 @@ void DatasetLocal::Clear(void)
{
mTimestamp.Init();
mTimestampPresent = false;
- otPlatSettingsDelete(&GetInstance(), GetSettingsKey(), -1);
+ GetInstance().GetSettings().DeleteOperationalDataset(IsActive());
}
otError DatasetLocal::Restore(Dataset &aDataset)
@@ -97,8 +95,7 @@ otError DatasetLocal::Get(Dataset &aDataset) const
uint32_t elapsed;
otError error;
- aDataset.mLength = sizeof(aDataset.mTlvs);
- error = otPlatSettingsGet(&GetInstance(), GetSettingsKey(), 0, aDataset.mTlvs, &aDataset.mLength);
+ error = GetInstance().GetSettings().ReadOperationalDataset(IsActive(), aDataset);
VerifyOrExit(error == OT_ERROR_NONE, aDataset.mLength = 0);
if (mType == Tlv::kActiveTimestamp)
@@ -171,12 +168,12 @@ otError DatasetLocal::Set(const Dataset &aDataset)
if (aDataset.GetSize() == 0)
{
- error = otPlatSettingsDelete(&GetInstance(), GetSettingsKey(), 0);
+ error = GetInstance().GetSettings().DeleteOperationalDataset(IsActive());
otLogInfoMeshCoP(GetInstance(), "%s dataset deleted", mType == Tlv::kActiveTimestamp ? "Active" : "Pending");
}
else
{
- error = otPlatSettingsSet(&GetInstance(), GetSettingsKey(), aDataset.GetBytes(), aDataset.GetSize());
+ error = GetInstance().GetSettings().SaveOperationalDataset(IsActive(), aDataset);
otLogInfoMeshCoP(GetInstance(), "%s dataset set", mType == Tlv::kActiveTimestamp ? "Active" : "Pending");
}
@@ -200,22 +197,6 @@ exit:
return error;
}
-uint16_t DatasetLocal::GetSettingsKey(void) const
-{
- uint16_t rval;
-
- if (mType == Tlv::kActiveTimestamp)
- {
- rval = static_cast(Settings::kKeyActiveDataset);
- }
- else
- {
- rval = static_cast(Settings::kKeyPendingDataset);
- }
-
- return rval;
-}
-
int DatasetLocal::Compare(const Timestamp *aCompareTimestamp)
{
int rval = 1;
diff --git a/src/core/meshcop/dataset_local.hpp b/src/core/meshcop/dataset_local.hpp
index 16d9e37a2..81fd4c027 100644
--- a/src/core/meshcop/dataset_local.hpp
+++ b/src/core/meshcop/dataset_local.hpp
@@ -145,8 +145,8 @@ public:
int Compare(const Timestamp *aCompare);
private:
- uint16_t GetSettingsKey(void) const;
- void SetTimestamp(const Dataset &aDataset);
+ bool IsActive(void) const { return (mType == Tlv::kActiveTimestamp); }
+ void SetTimestamp(const Dataset &aDataset);
Timestamp mTimestamp; ///< Active or Pending Timestamp
uint32_t mUpdateTime; ///< Local time last updated
diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp
index d64a7c7d5..feb7cc500 100644
--- a/src/core/thread/mle.cpp
+++ b/src/core/thread/mle.cpp
@@ -36,7 +36,6 @@
#include "mle.hpp"
#include
-#include
#include "common/code_utils.hpp"
#include "common/debug.hpp"
@@ -293,19 +292,16 @@ otError Mle::Stop(bool aClearNetworkDatasets)
otError Mle::Restore(void)
{
- ThreadNetif & netif = GetNetif();
- otError error = OT_ERROR_NONE;
+ ThreadNetif & netif = GetNetif();
+ Settings & settings = GetInstance().GetSettings();
+ otError error = OT_ERROR_NONE;
Settings::NetworkInfo networkInfo;
Settings::ParentInfo parentInfo;
- uint16_t length;
netif.GetActiveDataset().Restore();
netif.GetPendingDataset().Restore();
- length = sizeof(networkInfo);
- SuccessOrExit(error = otPlatSettingsGet(&netif.GetInstance(), Settings::kKeyNetworkInfo, 0,
- reinterpret_cast(&networkInfo), &length));
- VerifyOrExit(length >= sizeof(networkInfo), error = OT_ERROR_NOT_FOUND);
+ SuccessOrExit(error = settings.ReadNetworkInfo(networkInfo));
netif.GetKeyManager().SetCurrentKeySequence(networkInfo.mKeySequence);
netif.GetKeyManager().SetMleFrameCounter(networkInfo.mMleFrameCounter);
@@ -328,10 +324,7 @@ otError Mle::Restore(void)
if (!IsActiveRouter(networkInfo.mRloc16))
{
- length = sizeof(parentInfo);
-
- error = otPlatSettingsGet(&netif.GetInstance(), Settings::kKeyParentInfo, 0,
- reinterpret_cast(&parentInfo), &length);
+ error = settings.ReadParentInfo(parentInfo);
if (error != OT_ERROR_NONE)
{
@@ -346,8 +339,6 @@ otError Mle::Restore(void)
ExitNow();
}
- VerifyOrExit(length >= sizeof(parentInfo), error = OT_ERROR_PARSE);
-
memset(&mParent, 0, sizeof(mParent));
mParent.SetExtAddress(*static_cast(&parentInfo.mExtAddress));
mParent.SetDeviceMode(ModeTlv::kModeFFD | ModeTlv::kModeRxOnWhenIdle | ModeTlv::kModeFullNetworkData |
@@ -372,8 +363,9 @@ exit:
otError Mle::Store(void)
{
- ThreadNetif & netif = GetNetif();
- otError error = OT_ERROR_NONE;
+ ThreadNetif & netif = GetNetif();
+ Settings & settings = GetInstance().GetSettings();
+ otError error = OT_ERROR_NONE;
Settings::NetworkInfo networkInfo;
memset(&networkInfo, 0, sizeof(networkInfo));
@@ -396,16 +388,13 @@ otError Mle::Store(void)
memset(&parentInfo, 0, sizeof(parentInfo));
parentInfo.mExtAddress = mParent.GetExtAddress();
- SuccessOrExit(error = otPlatSettingsSet(&netif.GetInstance(), Settings::kKeyParentInfo,
- reinterpret_cast(&parentInfo), sizeof(parentInfo)));
+ SuccessOrExit(error = settings.SaveParentInfo(parentInfo));
}
}
else
{
// when not attached, read out any existing values so that we do not change them
- uint16_t length = sizeof(networkInfo);
- IgnoreReturnValue(otPlatSettingsGet(&netif.GetInstance(), Settings::kKeyNetworkInfo, 0,
- reinterpret_cast(&networkInfo), &length));
+ IgnoreReturnValue(settings.ReadNetworkInfo(networkInfo));
}
// update MAC and MLE Frame Counters even when we are not attached MLE messages are sent before a device attached
@@ -415,8 +404,7 @@ otError Mle::Store(void)
networkInfo.mMacFrameCounter =
netif.GetKeyManager().GetMacFrameCounter() + OPENTHREAD_CONFIG_STORE_FRAME_COUNTER_AHEAD;
- SuccessOrExit(error = otPlatSettingsSet(&netif.GetInstance(), Settings::kKeyNetworkInfo,
- reinterpret_cast(&networkInfo), sizeof(networkInfo)));
+ SuccessOrExit(error = settings.SaveNetworkInfo(networkInfo));
netif.GetKeyManager().SetStoredMleFrameCounter(networkInfo.mMleFrameCounter);
netif.GetKeyManager().SetStoredMacFrameCounter(networkInfo.mMacFrameCounter);
@@ -3661,5 +3649,35 @@ void Mle::LogMleMessage(const char *aLogString, const Ip6::Address &aAddress, ui
OT_UNUSED_VARIABLE(aRloc);
}
+const char *Mle::RoleToString(otDeviceRole aRole)
+{
+ const char *roleString = "Unknown";
+
+ switch (aRole)
+ {
+ case OT_DEVICE_ROLE_DISABLED:
+ roleString = "Disabled";
+ break;
+
+ case OT_DEVICE_ROLE_DETACHED:
+ roleString = "Detached";
+ break;
+
+ case OT_DEVICE_ROLE_CHILD:
+ roleString = "Child";
+ break;
+
+ case OT_DEVICE_ROLE_ROUTER:
+ roleString = "Router";
+ break;
+
+ case OT_DEVICE_ROLE_LEADER:
+ roleString = "Leader";
+ break;
+ }
+
+ return roleString;
+}
+
} // namespace Mle
} // namespace ot
diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp
index 494ccd639..cc854d7b6 100644
--- a/src/core/thread/mle.hpp
+++ b/src/core/thread/mle.hpp
@@ -951,6 +951,12 @@ public:
*/
void RemoveDelayedDataResponseMessage(void);
+ /**
+ * This method converts a device role into a human-readable string.
+ *
+ */
+ static const char *RoleToString(otDeviceRole aRole);
+
protected:
enum
{
diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp
index 6945b8fa2..0e2a30f64 100644
--- a/src/core/thread/mle_router.cpp
+++ b/src/core/thread/mle_router.cpp
@@ -36,8 +36,6 @@
#include "mle_router.hpp"
-#include
-
#include "common/code_utils.hpp"
#include "common/debug.hpp"
#include "common/encoding.hpp"
@@ -3787,20 +3785,14 @@ void MleRouter::RestoreChildren(void)
{
otError error = OT_ERROR_NONE;
bool foundDuplicate = false;
- uint8_t index;
+ uint8_t numChildren = 0;
- for (index = 0;; index++)
+ for (Settings::ChildInfoIterator iter(GetInstance()); !iter.IsDone(); iter.Advance())
{
- Child * child;
- Settings::ChildInfo childInfo;
- uint16_t length;
+ Child * child;
+ const Settings::ChildInfo &childInfo = iter.GetChildInfo();
- length = sizeof(childInfo);
- SuccessOrExit(otPlatSettingsGet(&GetInstance(), Settings::kKeyChildInfo, index,
- reinterpret_cast(&childInfo), &length));
- VerifyOrExit(length >= sizeof(childInfo), error = OT_ERROR_PARSE);
-
- child = FindChild(*static_cast(&childInfo.mExtAddress));
+ child = FindChild(*static_cast(&childInfo.mExtAddress));
if (child == NULL)
{
@@ -3813,18 +3805,19 @@ void MleRouter::RestoreChildren(void)
memset(child, 0, sizeof(*child));
- child->SetExtAddress(*static_cast(&childInfo.mExtAddress));
+ child->SetExtAddress(*static_cast(&childInfo.mExtAddress));
child->SetRloc16(childInfo.mRloc16);
child->SetTimeout(childInfo.mTimeout);
child->SetDeviceMode(childInfo.mMode);
child->SetState(Neighbor::kStateRestored);
child->SetLastHeard(TimerMilli::GetNow());
GetNetif().GetMeshForwarder().GetSourceMatchController().SetSrcMatchAsShort(*child, true);
+ numChildren++;
}
exit:
- if (foundDuplicate || (index > kMaxChildren) || (error != OT_ERROR_NONE))
+ if (foundDuplicate || (numChildren > kMaxChildren) || (error != OT_ERROR_NONE))
{
// If there is any error, e.g., there are more saved children
// in non-volatile settings than could be restored or there are
@@ -3840,18 +3833,11 @@ otError MleRouter::RemoveStoredChild(uint16_t aChildRloc16)
{
otError error = OT_ERROR_NOT_FOUND;
- for (uint8_t i = 0; i < kMaxChildren; i++)
+ for (Settings::ChildInfoIterator iter(GetInstance()); !iter.IsDone(); iter.Advance())
{
- Settings::ChildInfo childInfo;
- uint16_t length = sizeof(childInfo);
-
- SuccessOrExit(error = otPlatSettingsGet(&GetInstance(), Settings::kKeyChildInfo, i,
- reinterpret_cast(&childInfo), &length));
- VerifyOrExit(length >= sizeof(childInfo), error = OT_ERROR_PARSE);
-
- if (childInfo.mRloc16 == aChildRloc16)
+ if (iter.GetChildInfo().mRloc16 == aChildRloc16)
{
- error = otPlatSettingsDelete(&GetInstance(), Settings::kKeyChildInfo, i);
+ error = iter.Delete();
ExitNow();
}
}
@@ -3876,8 +3862,7 @@ otError MleRouter::StoreChild(uint16_t aChildRloc16)
childInfo.mRloc16 = child->GetRloc16();
childInfo.mMode = child->GetDeviceMode();
- error = otPlatSettingsAdd(&GetInstance(), Settings::kKeyChildInfo, reinterpret_cast(&childInfo),
- sizeof(childInfo));
+ error = GetInstance().GetSettings().AddChildInfo(childInfo);
exit:
return error;
@@ -3887,7 +3872,7 @@ otError MleRouter::RefreshStoredChildren(void)
{
otError error = OT_ERROR_NONE;
- SuccessOrExit(error = otPlatSettingsDelete(&GetInstance(), Settings::kKeyChildInfo, -1));
+ SuccessOrExit(error = GetInstance().GetSettings().DeleteChildInfo());
for (uint8_t i = 0; i < kMaxChildren; i++)
{