mirror of
https://github.com/espressif/openthread.git
synced 2026-09-04 08:10:11 +00:00
[settings] adding Settings class (#2606)
This commit is contained in:
committed by
Jonathan Hui
parent
130b88f71c
commit
ad4b597262
@@ -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>
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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_
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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++)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user