[dataset] change updater to use DatasetManager (#6227)

This commit changes the dataset updater implementation to leverage
MeshCoP::DatasetManager, which already provides a mechanism to
communicate Pending Dataset updates with the Leader. The
DatasetManager implementation ensures that only one CoAP transaction
is outstanding at a time.

This commit also ensures that any unspecified values are copied from
the Active Dataset.
This commit is contained in:
Jonathan Hui
2021-03-02 11:30:37 -08:00
parent 93b6fea3aa
commit 38ae36271c
19 changed files with 155 additions and 148 deletions
+1 -1
View File
@@ -287,6 +287,7 @@ cc_library_static {
"src/core/meshcop/dataset_local.cpp",
"src/core/meshcop/dataset_manager.cpp",
"src/core/meshcop/dataset_manager_ftd.cpp",
"src/core/meshcop/dataset_updater.cpp",
"src/core/meshcop/dtls.cpp",
"src/core/meshcop/energy_scan_client.cpp",
"src/core/meshcop/joiner.cpp",
@@ -360,7 +361,6 @@ cc_library_static {
"src/core/utils/channel_manager.cpp",
"src/core/utils/channel_monitor.cpp",
"src/core/utils/child_supervision.cpp",
"src/core/utils/dataset_updater.cpp",
"src/core/utils/flash.cpp",
"src/core/utils/heap.cpp",
"src/core/utils/jam_detector.cpp",
+1 -1
View File
@@ -250,6 +250,7 @@ LOCAL_SRC_FILES := \
src/core/meshcop/dataset_local.cpp \
src/core/meshcop/dataset_manager.cpp \
src/core/meshcop/dataset_manager_ftd.cpp \
src/core/meshcop/dataset_updater.cpp \
src/core/meshcop/dtls.cpp \
src/core/meshcop/energy_scan_client.cpp \
src/core/meshcop/joiner.cpp \
@@ -323,7 +324,6 @@ LOCAL_SRC_FILES := \
src/core/utils/channel_manager.cpp \
src/core/utils/channel_monitor.cpp \
src/core/utils/child_supervision.cpp \
src/core/utils/dataset_updater.cpp \
src/core/utils/flash.cpp \
src/core/utils/heap.cpp \
src/core/utils/jam_detector.cpp \
+1 -3
View File
@@ -80,7 +80,6 @@ typedef void (*otDatasetUpdaterCallback)(otError aError, void *aContext);
* @param[in] aDataset A pointer to the Dataset containing the fields to change.
* @param[in] aCallback A callback to indicate when Dataset update request finishes.
* @param[in] aContext An arbitrary context passed to callback.
* @param[in] aRetryWaitInterval The wait time after sending Pending dataset before retrying (interval in ms).
*
* @retval OT_ERROR_NONE Dataset update started successfully (@p aCallback will be invoked on completion).
* @retval OT_ERROR_INVALID_STATE Device is disabled (MLE is disabled).
@@ -92,8 +91,7 @@ typedef void (*otDatasetUpdaterCallback)(otError aError, void *aContext);
otError otDatasetUpdaterRequestUpdate(otInstance * aInstance,
const otOperationalDataset *aDataset,
otDatasetUpdaterCallback aCallback,
void * aContext,
uint32_t aReryWaitInterval);
void * aContext);
/**
* This function cancels an ongoing (if any) Operational Dataset update request.
+1 -1
View File
@@ -53,7 +53,7 @@ extern "C" {
* @note This number versions both OpenThread platform and user APIs.
*
*/
#define OPENTHREAD_API_VERSION (81)
#define OPENTHREAD_API_VERSION (82)
/**
* @addtogroup api-instance
+2 -2
View File
@@ -445,6 +445,8 @@ openthread_core_files = [
"meshcop/dataset_manager.cpp",
"meshcop/dataset_manager.hpp",
"meshcop/dataset_manager_ftd.cpp",
"meshcop/dataset_updater.cpp",
"meshcop/dataset_updater.hpp",
"meshcop/dtls.cpp",
"meshcop/dtls.hpp",
"meshcop/energy_scan_client.cpp",
@@ -598,8 +600,6 @@ openthread_core_files = [
"utils/channel_monitor.hpp",
"utils/child_supervision.cpp",
"utils/child_supervision.hpp",
"utils/dataset_updater.cpp",
"utils/dataset_updater.hpp",
"utils/flash.cpp",
"utils/flash.hpp",
"utils/heap.cpp",
+1 -1
View File
@@ -125,6 +125,7 @@ set(COMMON_SOURCES
meshcop/dataset_local.cpp
meshcop/dataset_manager.cpp
meshcop/dataset_manager_ftd.cpp
meshcop/dataset_updater.cpp
meshcop/dtls.cpp
meshcop/energy_scan_client.cpp
meshcop/joiner.cpp
@@ -198,7 +199,6 @@ set(COMMON_SOURCES
utils/channel_manager.cpp
utils/channel_monitor.cpp
utils/child_supervision.cpp
utils/dataset_updater.cpp
utils/flash.cpp
utils/heap.cpp
utils/jam_detector.cpp
+2 -2
View File
@@ -202,6 +202,7 @@ SOURCES_COMMON = \
meshcop/dataset_local.cpp \
meshcop/dataset_manager.cpp \
meshcop/dataset_manager_ftd.cpp \
meshcop/dataset_updater.cpp \
meshcop/dtls.cpp \
meshcop/energy_scan_client.cpp \
meshcop/joiner.cpp \
@@ -275,7 +276,6 @@ SOURCES_COMMON = \
utils/channel_manager.cpp \
utils/channel_monitor.cpp \
utils/child_supervision.cpp \
utils/dataset_updater.cpp \
utils/flash.cpp \
utils/heap.cpp \
utils/jam_detector.cpp \
@@ -450,6 +450,7 @@ HEADERS_COMMON = \
meshcop/dataset.hpp \
meshcop/dataset_local.hpp \
meshcop/dataset_manager.hpp \
meshcop/dataset_updater.hpp \
meshcop/dtls.hpp \
meshcop/energy_scan_client.hpp \
meshcop/joiner.hpp \
@@ -531,7 +532,6 @@ HEADERS_COMMON = \
utils/channel_manager.hpp \
utils/channel_monitor.hpp \
utils/child_supervision.hpp \
utils/dataset_updater.hpp \
utils/flash.hpp \
utils/heap.hpp \
utils/jam_detector.hpp \
+6 -7
View File
@@ -37,7 +37,7 @@
#include "common/instance.hpp"
#include "common/locator-getters.hpp"
#include "utils/dataset_updater.hpp"
#include "meshcop/dataset_updater.hpp"
using namespace ot;
@@ -46,27 +46,26 @@ using namespace ot;
otError otDatasetUpdaterRequestUpdate(otInstance * aInstance,
const otOperationalDataset *aDataset,
otDatasetUpdaterCallback aCallback,
void * aContext,
uint32_t aReryWaitInterval)
void * aContext)
{
Instance &instance = *static_cast<Instance *>(aInstance);
return instance.Get<Utils::DatasetUpdater>().RequestUpdate(*static_cast<const MeshCoP::Dataset::Info *>(aDataset),
aCallback, aContext, aReryWaitInterval);
return instance.Get<MeshCoP::DatasetUpdater>().RequestUpdate(*static_cast<const MeshCoP::Dataset::Info *>(aDataset),
aCallback, aContext);
}
void otDatasetUpdaterCancelUpdate(otInstance *aInstance)
{
Instance &instance = *static_cast<Instance *>(aInstance);
instance.Get<Utils::DatasetUpdater>().CancelUpdate();
instance.Get<MeshCoP::DatasetUpdater>().CancelUpdate();
}
bool otDatasetUpdaterIsUpdateOngoing(otInstance *aInstance)
{
Instance &instance = *static_cast<Instance *>(aInstance);
return instance.Get<Utils::DatasetUpdater>().IsUpdateOngoing();
return instance.Get<MeshCoP::DatasetUpdater>().IsUpdateOngoing();
}
#endif // OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE && OPENTHREAD_FTD
+5 -5
View File
@@ -64,6 +64,9 @@
#include "common/settings.hpp"
#include "crypto/mbedtls.hpp"
#include "meshcop/border_agent.hpp"
#if (OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE || OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE) && OPENTHREAD_FTD
#include "meshcop/dataset_updater.hpp"
#endif
#include "net/ip6.hpp"
#include "thread/announce_sender.hpp"
#include "thread/link_quality.hpp"
@@ -76,9 +79,6 @@
#if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
#include "utils/channel_monitor.hpp"
#endif
#if (OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE || OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE) && OPENTHREAD_FTD
#include "utils/dataset_updater.hpp"
#endif
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
#include "backbone_router/bbr_leader.hpp"
@@ -359,7 +359,7 @@ private:
#endif
#if (OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE || OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE) && OPENTHREAD_FTD
Utils::DatasetUpdater mDatasetUpdater;
MeshCoP::DatasetUpdater mDatasetUpdater;
#endif
#if OPENTHREAD_CONFIG_ANNOUNCE_SENDER_ENABLE
@@ -757,7 +757,7 @@ template <> inline Utils::ChannelManager &Instance::Get(void)
#endif
#if (OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE || OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE) && OPENTHREAD_FTD
template <> inline Utils::DatasetUpdater &Instance::Get(void)
template <> inline MeshCoP::DatasetUpdater &Instance::Get(void)
{
return mDatasetUpdater;
}
+1 -1
View File
@@ -147,7 +147,7 @@ void Notifier::EmitEvents(void)
Get<Utils::ChildSupervisor>().HandleNotifierEvents(events);
#endif
#if OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE || OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE
Get<Utils::DatasetUpdater>().HandleNotifierEvents(events);
Get<MeshCoP::DatasetUpdater>().HandleNotifierEvents(events);
#endif
#endif // OPENTHREAD_FTD
#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
+1 -1
View File
@@ -52,7 +52,7 @@
*
*/
#ifndef OPENTHREAD_CONFIG_DATASET_UPDATER_DEFAULT_DELAY
#define OPENTHREAD_CONFIG_DATASET_UPDATER_DEFAULT_DELAY 1000
#define OPENTHREAD_CONFIG_DATASET_UPDATER_DEFAULT_DELAY 30000
#endif
/**
+22
View File
@@ -199,6 +199,17 @@ exit:
return error;
}
otError DatasetManager::SaveLocal(const Dataset &aDataset)
{
otError error;
SuccessOrExit(error = mLocal.Save(aDataset));
HandleDatasetUpdated();
exit:
return error;
}
void DatasetManager::HandleDatasetUpdated(void)
{
switch (Get<Mle::MleRouter>().GetRole())
@@ -745,6 +756,17 @@ exit:
return error;
}
otError PendingDataset::Save(const Dataset &aDataset)
{
otError error;
SuccessOrExit(error = DatasetManager::SaveLocal(aDataset));
StartDelayTimer();
exit:
return error;
}
otError PendingDataset::Save(const Timestamp &aTimestamp, const Message &aMessage, uint16_t aOffset, uint8_t aLength)
{
otError error = OT_ERROR_NONE;
+22
View File
@@ -285,6 +285,17 @@ protected:
*/
otError Save(const Timestamp &aTimestamp, const Message &aMessage, uint16_t aOffset, uint8_t aLength);
/**
* This method saves the Operational Dataset in non-volatile memory.
*
* @param[in] aDataset The Operational Dataset.
*
* @retval OT_ERROR_NONE Successfully applied configuration.
* @retval OT_ERROR_PARSE The dataset has at least one TLV with invalid format.
*
*/
otError SaveLocal(const Dataset &aDataset);
/**
* This method handles a MGMT_GET request message.
*
@@ -566,6 +577,17 @@ public:
*/
otError Save(const Timestamp &aTimestamp, const Message &aMessage, uint16_t aOffset, uint8_t aLength);
/**
* This method saves the Operational Dataset in non-volatile memory.
*
* @param[in] aDataset The Operational Dataset.
*
* @retval OT_ERROR_NONE Successfully applied configuration.
* @retval OT_ERROR_PARSE The dataset has at least one TLV with invalid format.
*
*/
otError Save(const Dataset &aDataset);
#if OPENTHREAD_FTD
/**
* This method starts the Leader functions for maintaining the Active Operational Dataset.
@@ -43,12 +43,10 @@
#if (OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE || OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE) && OPENTHREAD_FTD
namespace ot {
namespace Utils {
namespace MeshCoP {
DatasetUpdater::DatasetUpdater(Instance &aInstance)
: InstanceLocator(aInstance)
, mState(kStateIdle)
, mWaitInterval(kWaitInterval)
, mCallback(nullptr)
, mCallbackContext(nullptr)
, mTimer(aInstance, DatasetUpdater::HandleTimer)
@@ -56,16 +54,13 @@ DatasetUpdater::DatasetUpdater(Instance &aInstance)
{
}
otError DatasetUpdater::RequestUpdate(const MeshCoP::Dataset::Info &aDataset,
Callback aCallback,
void * aContext,
uint32_t aReryWaitInterval)
otError DatasetUpdater::RequestUpdate(const MeshCoP::Dataset::Info &aDataset, Callback aCallback, void *aContext)
{
otError error = OT_ERROR_NONE;
Message *message = nullptr;
VerifyOrExit(!Get<Mle::Mle>().IsDisabled(), error = OT_ERROR_INVALID_STATE);
VerifyOrExit(mState == kStateIdle, error = OT_ERROR_BUSY);
VerifyOrExit(mDataset == nullptr, error = OT_ERROR_BUSY);
VerifyOrExit(!aDataset.IsActiveTimestampPresent() && !aDataset.IsPendingTimestampPresent(),
error = OT_ERROR_INVALID_ARGS);
@@ -77,11 +72,9 @@ otError DatasetUpdater::RequestUpdate(const MeshCoP::Dataset::Info &aDataset,
mCallback = aCallback;
mCallbackContext = aContext;
mWaitInterval = aReryWaitInterval;
mDataset = message;
mState = kStateUpdateRequested;
PreparePendingDataset();
mTimer.Start(1);
exit:
FreeMessageOnError(message, error);
@@ -90,12 +83,13 @@ exit:
void DatasetUpdater::CancelUpdate(void)
{
if (mState != kStateIdle)
{
FreeMessage(mDataset);
mState = kStateIdle;
mTimer.Stop();
}
VerifyOrExit(mDataset != nullptr);
FreeMessage(mDataset);
mTimer.Stop();
exit:
return;
}
void DatasetUpdater::HandleTimer(Timer &aTimer)
@@ -105,28 +99,20 @@ void DatasetUpdater::HandleTimer(Timer &aTimer)
void DatasetUpdater::HandleTimer(void)
{
switch (mState)
{
case kStateIdle:
break;
case kStateUpdateRequested:
case kStateSentMgmtPendingDataset:
PreparePendingDataset();
break;
}
PreparePendingDataset();
}
void DatasetUpdater::PreparePendingDataset(void)
{
Dataset dataset(Dataset::kPending);
MeshCoP::Dataset::Info requestedDataset;
otError error;
MeshCoP::Dataset::Info newDataset;
MeshCoP::Dataset::Info curDataset;
VerifyOrExit(mState != kStateIdle);
VerifyOrExit(!Get<Mle::Mle>().IsDisabled(), error = OT_ERROR_INVALID_STATE);
VerifyOrExit(!Get<Mle::Mle>().IsDisabled(), Finish(OT_ERROR_INVALID_STATE));
IgnoreError(mDataset->Read(0, requestedDataset));
error = Get<MeshCoP::ActiveDataset>().Read(curDataset);
error = Get<ActiveDataset>().Read(dataset);
if (error != OT_ERROR_NONE)
{
@@ -136,80 +122,51 @@ void DatasetUpdater::PreparePendingDataset(void)
// right after the network is formed but before the active
// dataset is created.
mState = kStateUpdateRequested;
mTimer.Start(kRetryInterval);
ExitNow();
ExitNow(error = OT_ERROR_NONE);
}
IgnoreError(mDataset->Read(0, newDataset));
IgnoreError(dataset.SetFrom(requestedDataset));
if (newDataset.IsSubsetOf(curDataset))
if (!requestedDataset.IsDelayPresent())
{
// If new requested Dataset is already contained in the current
// Active Dataset, no change is required, and we can report the
// update to be successful.
uint32_t delay = kDefaultDelay;
Finish(OT_ERROR_NONE);
ExitNow();
SuccessOrExit(error = dataset.SetTlv(Tlv::kDelayTimer, delay));
}
if (newDataset.IsActiveTimestampPresent())
{
// Presence of the active timestamp in the new Dataset
// indicates that it is a retry. In this case, we ensure
// that the timestamp is ahead of current active dataset.
// This covers the case where another device in network
// requested a Dataset update after this device.
Timestamp timestamp;
VerifyOrExit(newDataset.GetActiveTimestamp() > curDataset.GetActiveTimestamp(), Finish(OT_ERROR_ALREADY));
}
else
{
newDataset.SetActiveTimestamp(curDataset.GetActiveTimestamp() +
Random::NonCrypto::GetUint32InRange(1, kMaxTimestampIncrease));
}
if (!newDataset.IsDelayPresent())
{
newDataset.SetDelay(kDefaultDelay);
}
if (!newDataset.IsPendingTimestampPresent())
{
uint32_t timestampIncrease = Random::NonCrypto::GetUint32InRange(1, kMaxTimestampIncrease);
if (Get<MeshCoP::PendingDataset>().Read(curDataset) == OT_ERROR_NONE)
if (Get<PendingDataset>().GetTimestamp() != nullptr)
{
newDataset.SetPendingTimestamp(curDataset.GetPendingTimestamp() + timestampIncrease);
}
else
{
newDataset.SetPendingTimestamp(timestampIncrease);
timestamp = *Get<PendingDataset>().GetTimestamp();
}
mDataset->Write(0, newDataset);
timestamp.AdvanceRandomTicks();
dataset.SetTimestamp(timestamp);
}
error = Get<MeshCoP::PendingDataset>().SendSetRequest(newDataset, nullptr, 0);
{
ActiveTimestampTlv *tlv = dataset.GetTlv<ActiveTimestampTlv>();
tlv->AdvanceRandomTicks();
}
if (error == OT_ERROR_NONE)
{
mState = kStateSentMgmtPendingDataset;
mTimer.Start(newDataset.GetDelay() + mWaitInterval);
}
else
{
mTimer.Start(kRetryInterval);
}
SuccessOrExit(error = Get<PendingDataset>().Save(dataset));
exit:
return;
if (error != OT_ERROR_NONE)
{
Finish(error);
}
}
void DatasetUpdater::Finish(otError aError)
{
OT_ASSERT(mDataset != nullptr);
FreeMessage(mDataset);
mState = kStateIdle;
mDataset = nullptr;
if (mCallback != nullptr)
{
@@ -219,21 +176,30 @@ void DatasetUpdater::Finish(otError aError)
void DatasetUpdater::HandleNotifierEvents(Events aEvents)
{
VerifyOrExit(mState == kStateSentMgmtPendingDataset);
MeshCoP::Dataset::Info requestedDataset;
MeshCoP::Dataset::Info dataset;
if (aEvents.Contains(kEventActiveDatasetChanged))
VerifyOrExit(mDataset != nullptr);
VerifyOrExit(aEvents.ContainsAny(kEventActiveDatasetChanged | kEventPendingDatasetChanged));
IgnoreError(mDataset->Read(0, requestedDataset));
if (aEvents.Contains(kEventActiveDatasetChanged) && Get<MeshCoP::ActiveDataset>().Read(dataset) == OT_ERROR_NONE)
{
MeshCoP::Dataset::Info requestedDataset;
MeshCoP::Dataset::Info activeDataset;
SuccessOrExit(Get<MeshCoP::ActiveDataset>().Read(activeDataset));
IgnoreError(mDataset->Read(0, requestedDataset));
if (requestedDataset.IsSubsetOf(activeDataset))
if (requestedDataset.IsSubsetOf(dataset))
{
Finish(OT_ERROR_NONE);
}
else if (requestedDataset.GetActiveTimestamp() <= activeDataset.GetActiveTimestamp())
else if (requestedDataset.GetActiveTimestamp() <= dataset.GetActiveTimestamp())
{
Finish(OT_ERROR_ALREADY);
}
}
if (aEvents.Contains(kEventPendingDatasetChanged) && Get<MeshCoP::PendingDataset>().Read(dataset) == OT_ERROR_NONE)
{
if (!requestedDataset.IsSubsetOf(dataset))
{
Finish(OT_ERROR_ALREADY);
}
@@ -243,7 +209,7 @@ exit:
return;
}
} // namespace Utils
} // namespace MeshCoP
} // namespace ot
#endif // #if (OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE || OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE) && OPENTHREAD_FTD
@@ -47,7 +47,7 @@
#include "meshcop/meshcop_tlvs.hpp"
namespace ot {
namespace Utils {
namespace MeshCoP {
#if (OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE || OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE) && OPENTHREAD_FTD
@@ -93,7 +93,6 @@ public:
* @param[in] aDataset Dataset info containing fields to change.
* @param[in] aCallback A callback to indicate when Dataset update request finishes.
* @param[in] aContext An arbitrary context passed to callback.
* @param[in] aRetryWaitInterval The wait time after sending Pending dataset before retrying (interval in ms).
*
* @retval OT_ERROR_NONE Dataset update started successfully (@p aCallback will be invoked on completion).
* @retval OT_ERROR_INVALID_STATE Device is disabled (MLE is disabled).
@@ -102,10 +101,7 @@ public:
* @retval OT_ERROR_NO_BUFS Could not allocated buffer to save Dataset.
*
*/
otError RequestUpdate(const MeshCoP::Dataset::Info &aDataset,
Callback aCallback,
void * aContext,
uint32_t aReryWaitInterval = kWaitInterval);
otError RequestUpdate(const MeshCoP::Dataset::Info &aDataset, Callback aCallback, void *aContext);
/**
* This method cancels an ongoing (if any) Operational Dataset update request.
@@ -120,26 +116,14 @@ public:
* @retval FALSE There is no ongoing update.
*
*/
bool IsUpdateOngoing(void) const { return (mState != kStateIdle); }
bool IsUpdateOngoing(void) const { return mDataset != nullptr; }
private:
enum State : uint8_t
{
kStateIdle,
kStateUpdateRequested,
kStateSentMgmtPendingDataset,
};
enum : uint32_t
{
// Default delay (in ms) in Pending Dataset.
kDefaultDelay = OPENTHREAD_CONFIG_DATASET_UPDATER_DEFAULT_DELAY,
kDefaultDelay = OPENTHREAD_CONFIG_DATASET_UPDATER_DEFAULT_DELAY, // Default delay (in ms) in Pending Dataset.
// Default wait interval (in ms) after sending Pending Dataset to retry (in addition Dataset Delay)
kWaitInterval = OPENTHREAD_CONFIG_DATASET_UPDATER_DEFAULT_RETRY_WAIT_INTERVAL,
kRetryInterval = 1000, // In ms. Retry interval when preparing and/or sending Pending Dataset fails.
kMaxTimestampIncrease = 128, // Maximum increase of Pending/Active Timestamp during Dataset Update.
kRetryInterval = 1000, // In ms. Retry interval when preparing and/or sending Pending Dataset fails.
};
static void HandleTimer(Timer &aTimer);
@@ -148,8 +132,6 @@ private:
void Finish(otError aError);
void HandleNotifierEvents(Events aEvents);
State mState;
uint32_t mWaitInterval;
Callback mCallback;
void * mCallbackContext;
TimerMilli mTimer;
@@ -158,7 +140,7 @@ private:
#endif // (OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE || OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE) && OPENTHREAD_FTD
} // namespace Utils
} // namespace MeshCoP
} // namespace ot
#endif // DATASET_UPDATER_HPP_
+14
View File
@@ -68,5 +68,19 @@ int Timestamp::Compare(const Timestamp &aCompare) const
return rval;
}
void Timestamp::AdvanceRandomTicks(void)
{
uint16_t ticks = GetTicks();
ticks += Random::NonCrypto::GetUint32InRange(1, kMaxRandomTicks);
if (ticks & (kTicksMask >> kTicksOffset))
{
SetSeconds(GetSeconds() + 1);
}
SetTicks(ticks);
}
} // namespace MeshCoP
} // namespace ot
+8
View File
@@ -42,6 +42,7 @@
#include <openthread/platform/toolchain.h>
#include "common/encoding.hpp"
#include "common/random.hpp"
namespace ot {
namespace MeshCoP {
@@ -137,11 +138,18 @@ public:
((aAuthoritative << kAuthoritativeOffset) & kAuthoritativeMask));
}
/**
* This method increments the timestamp by a random number of ticks [0, 32767].
*
*/
void AdvanceRandomTicks(void);
private:
enum
{
kTicksOffset = 1,
kTicksMask = 0x7fff << kTicksOffset,
kMaxRandomTicks = 0x7fff,
kAuthoritativeOffset = 0,
kAuthoritativeMask = 1 << kAuthoritativeOffset,
};
+2 -3
View File
@@ -39,8 +39,8 @@
#include "common/locator-getters.hpp"
#include "common/logging.hpp"
#include "common/random.hpp"
#include "meshcop/dataset_updater.hpp"
#include "radio/radio.hpp"
#include "utils/dataset_updater.hpp"
#if OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE && OPENTHREAD_FTD
@@ -73,7 +73,6 @@ void ChannelManager::RequestChannelChange(uint8_t aChannel)
if (mState == kStateChangeInProgress)
{
VerifyOrExit(mChannel != aChannel);
Get<DatasetUpdater>().CancelUpdate();
}
mState = kStateChangeRequested;
@@ -106,7 +105,7 @@ void ChannelManager::StartDatasetUpdate(void)
dataset.SetChannel(mChannel);
dataset.SetDelay(Time::SecToMsec(mDelay));
switch (Get<DatasetUpdater>().RequestUpdate(dataset, HandleDatasetUpdateDone, this, kChangeCheckWaitInterval))
switch (Get<MeshCoP::DatasetUpdater>().RequestUpdate(dataset, HandleDatasetUpdateDone, this))
{
case OT_ERROR_NONE:
mState = kStateChangeInProgress;
-3
View File
@@ -233,9 +233,6 @@ private:
// Retry interval to resend Pending Dataset in case of tx failure (in ms).
kPendingDatasetTxRetryInterval = 20000,
// Wait time after sending Pending Dataset to check whether the channel was changed (in ms).
kChangeCheckWaitInterval = 30000,
// Maximum jitter/wait time to start a requested channel change (in ms).
kRequestStartJitterInterval = 10000,