[settings] adding Settings class (#2606)

This commit is contained in:
Abtin Keshavarzian
2018-03-19 22:45:04 +00:00
committed by Jonathan Hui
parent 130b88f71c
commit ad4b597262
17 changed files with 801 additions and 169 deletions
+1
View File
@@ -82,6 +82,7 @@
<ClCompile Include="..\..\src\core\common\logging.cpp" />
<ClCompile Include="..\..\src\core\common\message.cpp" />
<ClCompile Include="..\..\src\core\common\notifier.cpp" />
<ClCompile Include="..\..\src\core\common\settings.cpp" />
<ClCompile Include="..\..\src\core\common\tasklet.cpp" />
<ClCompile Include="..\..\src\core\common\timer.cpp" />
<ClCompile Include="..\..\src\core\common\tlvs.cpp" />
@@ -144,6 +144,9 @@
<ClCompile Include="..\..\src\core\common\notifier.cpp">
<Filter>Source Files\common</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\common\settings.cpp">
<Filter>Source Files\common</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\common\tasklet.cpp">
<Filter>Source Files\common</Filter>
</ClCompile>
@@ -91,6 +91,7 @@
<ClCompile Include="..\..\src\core\common\logging.cpp" />
<ClCompile Include="..\..\src\core\common\message.cpp" />
<ClCompile Include="..\..\src\core\common\notifier.cpp" />
<ClCompile Include="..\..\src\core\common\settings.cpp" />
<ClCompile Include="..\..\src\core\common\tasklet.cpp" />
<ClCompile Include="..\..\src\core\common\timer.cpp" />
<ClCompile Include="..\..\src\core\common\tlvs.cpp" />
@@ -144,6 +144,9 @@
<ClCompile Include="..\..\src\core\common\notifier.cpp">
<Filter>Source Files\common</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\common\settings.cpp">
<Filter>Source Files\common</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\common\tasklet.cpp">
<Filter>Source Files\common</Filter>
</ClCompile>
+1
View File
@@ -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 \
+7 -6
View File
@@ -36,7 +36,6 @@
#include "openthread-core-config.h"
#include <openthread/thread.h>
#include <openthread/platform/settings.h>
#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<Instance *>(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<Instance *>(aInstance);
return instance.GetSettings().SaveThreadAutoStart(autoStart);
#else
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aStartAutomatically);
+4 -4
View File
@@ -36,7 +36,6 @@
#include "instance.hpp"
#include <openthread/platform/misc.h>
#include <openthread/platform/settings.h>
#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;
+10
View File
@@ -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;
+324
View File
@@ -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 <openthread/platform/settings.h>
#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<otDeviceRole>(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<uint8_t *>(&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<uint8_t *>(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<uint8_t *>(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<const uint8_t *>(aBuffer), aSize);
}
otError Settings::Add(Key aKey, const void *aBuffer, uint16_t aSize)
{
return otPlatSettingsAdd(&GetInstance(), aKey, reinterpret_cast<const uint8_t *>(aBuffer), aSize);
}
otError Settings::Delete(Key aKey)
{
return otPlatSettingsDelete(&GetInstance(), aKey, -1);
}
} // namespace ot
+365 -64
View File
@@ -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_
-17
View File
@@ -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<uint16_t>(Settings::kKeyActiveDataset);
}
else
{
rval = static_cast<uint16_t>(Settings::kKeyPendingDataset);
}
return rval;
}
void Dataset::Remove(uint8_t *aStart, uint8_t aLength)
{
memmove(aStart, aStart + aLength, mLength - (static_cast<uint8_t>(aStart - mTlvs) + aLength));
+16 -2
View File
@@ -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
+4 -23
View File
@@ -38,8 +38,6 @@
#include <stdio.h>
#include <openthread/platform/settings.h>
#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<uint16_t>(Settings::kKeyActiveDataset);
}
else
{
rval = static_cast<uint16_t>(Settings::kKeyPendingDataset);
}
return rval;
}
int DatasetLocal::Compare(const Timestamp *aCompareTimestamp)
{
int rval = 1;
+2 -2
View File
@@ -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
+41 -23
View File
@@ -36,7 +36,6 @@
#include "mle.hpp"
#include <openthread/platform/radio.h>
#include <openthread/platform/settings.h>
#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<uint8_t *>(&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<uint8_t *>(&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<Mac::ExtAddress *>(&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<uint8_t *>(&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<uint8_t *>(&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<uint8_t *>(&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
+6
View File
@@ -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
{
+13 -28
View File
@@ -36,8 +36,6 @@
#include "mle_router.hpp"
#include <openthread/platform/settings.h>
#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<uint8_t *>(&childInfo), &length));
VerifyOrExit(length >= sizeof(childInfo), error = OT_ERROR_PARSE);
child = FindChild(*static_cast<Mac::ExtAddress *>(&childInfo.mExtAddress));
child = FindChild(*static_cast<const Mac::ExtAddress *>(&childInfo.mExtAddress));
if (child == NULL)
{
@@ -3813,18 +3805,19 @@ void MleRouter::RestoreChildren(void)
memset(child, 0, sizeof(*child));
child->SetExtAddress(*static_cast<Mac::ExtAddress *>(&childInfo.mExtAddress));
child->SetExtAddress(*static_cast<const Mac::ExtAddress *>(&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<uint8_t *>(&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<uint8_t *>(&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++)
{