diff --git a/Android.bp b/Android.bp index 09d422c39..6a55ad15e 100644 --- a/Android.bp +++ b/Android.bp @@ -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", diff --git a/Android.mk b/Android.mk index 45112db09..ce7f0f3f5 100644 --- a/Android.mk +++ b/Android.mk @@ -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 \ diff --git a/include/openthread/dataset_updater.h b/include/openthread/dataset_updater.h index e183cb04b..627ddb390 100644 --- a/include/openthread/dataset_updater.h +++ b/include/openthread/dataset_updater.h @@ -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. diff --git a/include/openthread/instance.h b/include/openthread/instance.h index 7b477b762..b0297f6d9 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -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 diff --git a/src/core/BUILD.gn b/src/core/BUILD.gn index 616bb9417..860cf8148 100644 --- a/src/core/BUILD.gn +++ b/src/core/BUILD.gn @@ -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", diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 5120eb3e3..f4cfad7f3 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -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 diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 96387d50f..323ea6c78 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -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 \ diff --git a/src/core/api/dataset_updater_api.cpp b/src/core/api/dataset_updater_api.cpp index 63a61d018..fd9b8626f 100644 --- a/src/core/api/dataset_updater_api.cpp +++ b/src/core/api/dataset_updater_api.cpp @@ -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(aInstance); - return instance.Get().RequestUpdate(*static_cast(aDataset), - aCallback, aContext, aReryWaitInterval); + return instance.Get().RequestUpdate(*static_cast(aDataset), + aCallback, aContext); } void otDatasetUpdaterCancelUpdate(otInstance *aInstance) { Instance &instance = *static_cast(aInstance); - instance.Get().CancelUpdate(); + instance.Get().CancelUpdate(); } bool otDatasetUpdaterIsUpdateOngoing(otInstance *aInstance) { Instance &instance = *static_cast(aInstance); - return instance.Get().IsUpdateOngoing(); + return instance.Get().IsUpdateOngoing(); } #endif // OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE && OPENTHREAD_FTD diff --git a/src/core/common/instance.hpp b/src/core/common/instance.hpp index bb7e391ee..8b7e8ccb2 100644 --- a/src/core/common/instance.hpp +++ b/src/core/common/instance.hpp @@ -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; } diff --git a/src/core/common/notifier.cpp b/src/core/common/notifier.cpp index 6f970f4ba..573f0e2b2 100644 --- a/src/core/common/notifier.cpp +++ b/src/core/common/notifier.cpp @@ -147,7 +147,7 @@ void Notifier::EmitEvents(void) Get().HandleNotifierEvents(events); #endif #if OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE || OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE - Get().HandleNotifierEvents(events); + Get().HandleNotifierEvents(events); #endif #endif // OPENTHREAD_FTD #if OPENTHREAD_FTD || OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE diff --git a/src/core/config/dataset_updater.h b/src/core/config/dataset_updater.h index 1cff726a5..40557485a 100644 --- a/src/core/config/dataset_updater.h +++ b/src/core/config/dataset_updater.h @@ -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 /** diff --git a/src/core/meshcop/dataset_manager.cpp b/src/core/meshcop/dataset_manager.cpp index 1d7e20d30..47c161ab1 100644 --- a/src/core/meshcop/dataset_manager.cpp +++ b/src/core/meshcop/dataset_manager.cpp @@ -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().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; diff --git a/src/core/meshcop/dataset_manager.hpp b/src/core/meshcop/dataset_manager.hpp index 98d08a7e2..50a7cb391 100644 --- a/src/core/meshcop/dataset_manager.hpp +++ b/src/core/meshcop/dataset_manager.hpp @@ -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. diff --git a/src/core/utils/dataset_updater.cpp b/src/core/meshcop/dataset_updater.cpp similarity index 55% rename from src/core/utils/dataset_updater.cpp rename to src/core/meshcop/dataset_updater.cpp index fde10dce3..c816e0bdc 100644 --- a/src/core/utils/dataset_updater.cpp +++ b/src/core/meshcop/dataset_updater.cpp @@ -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().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().IsDisabled(), error = OT_ERROR_INVALID_STATE); - VerifyOrExit(!Get().IsDisabled(), Finish(OT_ERROR_INVALID_STATE)); + IgnoreError(mDataset->Read(0, requestedDataset)); - error = Get().Read(curDataset); + error = Get().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().Read(curDataset) == OT_ERROR_NONE) + if (Get().GetTimestamp() != nullptr) { - newDataset.SetPendingTimestamp(curDataset.GetPendingTimestamp() + timestampIncrease); - } - else - { - newDataset.SetPendingTimestamp(timestampIncrease); + timestamp = *Get().GetTimestamp(); } - mDataset->Write(0, newDataset); + timestamp.AdvanceRandomTicks(); + dataset.SetTimestamp(timestamp); } - error = Get().SendSetRequest(newDataset, nullptr, 0); + { + ActiveTimestampTlv *tlv = dataset.GetTlv(); + tlv->AdvanceRandomTicks(); + } - if (error == OT_ERROR_NONE) - { - mState = kStateSentMgmtPendingDataset; - mTimer.Start(newDataset.GetDelay() + mWaitInterval); - } - else - { - mTimer.Start(kRetryInterval); - } + SuccessOrExit(error = Get().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().Read(dataset) == OT_ERROR_NONE) { - MeshCoP::Dataset::Info requestedDataset; - MeshCoP::Dataset::Info activeDataset; - - SuccessOrExit(Get().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().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 diff --git a/src/core/utils/dataset_updater.hpp b/src/core/meshcop/dataset_updater.hpp similarity index 83% rename from src/core/utils/dataset_updater.hpp rename to src/core/meshcop/dataset_updater.hpp index 63f13d3e5..6ba76d271 100644 --- a/src/core/utils/dataset_updater.hpp +++ b/src/core/meshcop/dataset_updater.hpp @@ -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_ diff --git a/src/core/meshcop/timestamp.cpp b/src/core/meshcop/timestamp.cpp index 47eef7537..9a523d1c5 100644 --- a/src/core/meshcop/timestamp.cpp +++ b/src/core/meshcop/timestamp.cpp @@ -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 diff --git a/src/core/meshcop/timestamp.hpp b/src/core/meshcop/timestamp.hpp index 4149cd63f..b8888b910 100644 --- a/src/core/meshcop/timestamp.hpp +++ b/src/core/meshcop/timestamp.hpp @@ -42,6 +42,7 @@ #include #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, }; diff --git a/src/core/utils/channel_manager.cpp b/src/core/utils/channel_manager.cpp index 555e217e2..db2252bc5 100644 --- a/src/core/utils/channel_manager.cpp +++ b/src/core/utils/channel_manager.cpp @@ -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().CancelUpdate(); } mState = kStateChangeRequested; @@ -106,7 +105,7 @@ void ChannelManager::StartDatasetUpdate(void) dataset.SetChannel(mChannel); dataset.SetDelay(Time::SecToMsec(mDelay)); - switch (Get().RequestUpdate(dataset, HandleDatasetUpdateDone, this, kChangeCheckWaitInterval)) + switch (Get().RequestUpdate(dataset, HandleDatasetUpdateDone, this)) { case OT_ERROR_NONE: mState = kStateChangeInProgress; diff --git a/src/core/utils/channel_manager.hpp b/src/core/utils/channel_manager.hpp index a74b0eb25..3d8f1dba8 100644 --- a/src/core/utils/channel_manager.hpp +++ b/src/core/utils/channel_manager.hpp @@ -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,