diff --git a/src/core/api/dataset_api.cpp b/src/core/api/dataset_api.cpp index 33b5f3d68..fe08d2057 100644 --- a/src/core/api/dataset_api.cpp +++ b/src/core/api/dataset_api.cpp @@ -61,14 +61,14 @@ otError otDatasetGetActiveTlvs(otInstance *aInstance, otOperationalDatasetTlvs * otError otDatasetSetActive(otInstance *aInstance, const otOperationalDataset *aDataset) { - return AsCoreType(aInstance).Get().Save(AsCoreType(aDataset)); + return AsCoreType(aInstance).Get().SaveLocal(AsCoreType(aDataset)); } otError otDatasetSetActiveTlvs(otInstance *aInstance, const otOperationalDatasetTlvs *aDataset) { AssertPointerIsNotNull(aDataset); - return AsCoreType(aInstance).Get().Save(*aDataset); + return AsCoreType(aInstance).Get().SaveLocal(*aDataset); } otError otDatasetGetPending(otInstance *aInstance, otOperationalDataset *aDataset) @@ -85,14 +85,14 @@ otError otDatasetGetPendingTlvs(otInstance *aInstance, otOperationalDatasetTlvs otError otDatasetSetPending(otInstance *aInstance, const otOperationalDataset *aDataset) { - return AsCoreType(aInstance).Get().Save(AsCoreType(aDataset)); + return AsCoreType(aInstance).Get().SaveLocal(AsCoreType(aDataset)); } otError otDatasetSetPendingTlvs(otInstance *aInstance, const otOperationalDatasetTlvs *aDataset) { AssertPointerIsNotNull(aDataset); - return AsCoreType(aInstance).Get().Save(*aDataset); + return AsCoreType(aInstance).Get().SaveLocal(*aDataset); } otError otDatasetSendMgmtActiveGet(otInstance *aInstance, diff --git a/src/core/meshcop/dataset_local.cpp b/src/core/meshcop/dataset_local.cpp index 848f6188a..e93e9b704 100644 --- a/src/core/meshcop/dataset_local.cpp +++ b/src/core/meshcop/dataset_local.cpp @@ -146,30 +146,6 @@ exit: return error; } -Error DatasetLocal::Save(const Dataset::Info &aDatasetInfo) -{ - Error error; - Dataset dataset; - - dataset.SetFrom(aDatasetInfo); - SuccessOrExit(error = Save(dataset)); - -exit: - return error; -} - -Error DatasetLocal::Save(const Dataset::Tlvs &aDatasetTlvs) -{ - Error error = kErrorNone; - Dataset dataset; - - SuccessOrExit(error = dataset.SetFrom(aDatasetTlvs)); - error = Save(dataset); - -exit: - return error; -} - Error DatasetLocal::Save(const Dataset &aDataset) { Error error = kErrorNone; diff --git a/src/core/meshcop/dataset_local.hpp b/src/core/meshcop/dataset_local.hpp index 85ceb3d16..36f492f3c 100644 --- a/src/core/meshcop/dataset_local.hpp +++ b/src/core/meshcop/dataset_local.hpp @@ -150,29 +150,6 @@ public: */ TimeMilli GetUpdateTime(void) const { return mUpdateTime; } - /** - * Stores the dataset into non-volatile memory. - * - * @param[in] aDatasetInfo The Dataset to save as `Dataset::Info`. - * - * @retval kErrorNone Successfully saved the dataset. - * @retval kErrorNotImplemented The platform does not implement settings functionality. - * - */ - Error Save(const Dataset::Info &aDatasetInfo); - - /** - * Stores the dataset into non-volatile memory. - * - * @param[in] aDatasetTlvs The Dataset to save as `Dataset::Tlvs`. - * - * @retval kErrorNone Successfully saved the dataset. - * @retval kErrorInvalidArgs The dataset TLVs is invalid, its length is longer than `Dataset::kMaxLength`. - * @retval kErrorNotImplemented The platform does not implement settings functionality. - * - */ - Error Save(const Dataset::Tlvs &aDatasetTlvs); - /** * Stores the dataset into non-volatile memory. * diff --git a/src/core/meshcop/dataset_manager.cpp b/src/core/meshcop/dataset_manager.cpp index ebe3d6b57..ee32b8fae 100644 --- a/src/core/meshcop/dataset_manager.cpp +++ b/src/core/meshcop/dataset_manager.cpp @@ -115,6 +115,34 @@ void DatasetManager::Clear(void) void DatasetManager::HandleDetach(void) { IgnoreError(Restore()); } +Error DatasetManager::Save(const Timestamp &aTimestamp, const Message &aMessage, uint16_t aOffset, uint16_t aLength) +{ + Error error = kErrorNone; + Dataset dataset; + + SuccessOrExit(error = dataset.SetFrom(aMessage, aOffset, aLength)); + SuccessOrExit(error = dataset.ValidateTlvs()); + + if (IsActiveDataset()) + { + SuccessOrExit(error = dataset.Write(aTimestamp)); + } + else + { + SuccessOrExit(error = dataset.Write(aTimestamp)); + } + + SuccessOrExit(error = Save(dataset)); + + if (IsPendingDataset()) + { + Get().StartDelayTimer(dataset); + } + +exit: + return error; +} + Error DatasetManager::Save(const Dataset &aDataset) { Error error = kErrorNone; @@ -152,23 +180,22 @@ exit: return error; } -Error DatasetManager::Save(const Dataset::Info &aDatasetInfo) +Error DatasetManager::SaveLocal(const Dataset::Info &aDatasetInfo) { - Error error; + Dataset dataset; - SuccessOrExit(error = mLocal.Save(aDatasetInfo)); - HandleDatasetUpdated(); + dataset.SetFrom(aDatasetInfo); -exit: - return error; + return SaveLocal(dataset); } -Error DatasetManager::Save(const Dataset::Tlvs &aDatasetTlvs) +Error DatasetManager::SaveLocal(const Dataset::Tlvs &aDatasetTlvs) { - Error error; + Error error; + Dataset dataset; - SuccessOrExit(error = mLocal.Save(aDatasetTlvs)); - HandleDatasetUpdated(); + SuccessOrExit(error = dataset.SetFrom(aDatasetTlvs)); + error = SaveLocal(dataset); exit: return error; @@ -179,14 +206,12 @@ Error DatasetManager::SaveLocal(const Dataset &aDataset) Error error; SuccessOrExit(error = mLocal.Save(aDataset)); - HandleDatasetUpdated(); -exit: - return error; -} + if (IsPendingDataset()) + { + Get().StartDelayTimer(aDataset); + } -void DatasetManager::HandleDatasetUpdated(void) -{ switch (Get().GetRole()) { case Mle::kRoleDisabled: @@ -194,11 +219,11 @@ void DatasetManager::HandleDatasetUpdated(void) break; case Mle::kRoleChild: - SendSet(); + SyncLocalWithLeader(aDataset); break; #if OPENTHREAD_FTD case Mle::kRoleRouter: - SendSet(); + SyncLocalWithLeader(aDataset); break; case Mle::kRoleLeader: @@ -212,6 +237,9 @@ void DatasetManager::HandleDatasetUpdated(void) } SignalDatasetChange(); + +exit: + return error; } void DatasetManager::SignalDatasetChange(void) const @@ -240,13 +268,25 @@ exit: return error; } -void DatasetManager::HandleTimer(void) { SendSet(); } - -void DatasetManager::SendSet(void) +void DatasetManager::HandleTimer(void) { - Error error = kErrorNone; Dataset dataset; + SuccessOrExit(Read(dataset)); + SyncLocalWithLeader(dataset); + +exit: + return; +} + +void DatasetManager::SyncLocalWithLeader(const Dataset &aDataset) +{ + // Attempts to synchronize the local Dataset with the leader by + // sending `MGMT_SET` command if the local Dataset's timestamp is + // newer. + + Error error = kErrorNone; + VerifyOrExit(!mMgmtPending, error = kErrorBusy); VerifyOrExit(Get().IsChild() || Get().IsRouter(), error = kErrorInvalidState); @@ -267,9 +307,7 @@ void DatasetManager::SendSet(void) } } - IgnoreError(Read(dataset)); - - error = SendSetRequest(dataset); + error = SendSetRequest(aDataset); exit: if (error == kErrorNoBufs) @@ -572,23 +610,6 @@ exit: return isValid; } -Error ActiveDatasetManager::Save(const Timestamp &aTimestamp, - const Message &aMessage, - uint16_t aOffset, - uint16_t aLength) -{ - Error error = kErrorNone; - Dataset dataset; - - SuccessOrExit(error = dataset.SetFrom(aMessage, aOffset, aLength)); - SuccessOrExit(error = dataset.ValidateTlvs()); - SuccessOrExit(error = dataset.Write(aTimestamp)); - error = DatasetManager::Save(dataset); - -exit: - return error; -} - template <> void ActiveDatasetManager::HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { @@ -621,73 +642,28 @@ void PendingDatasetManager::ClearNetwork(void) IgnoreError(DatasetManager::Save(dataset)); } -Error PendingDatasetManager::Save(const Dataset::Info &aDatasetInfo) -{ - Error error; - - SuccessOrExit(error = DatasetManager::Save(aDatasetInfo)); - StartDelayTimer(); - -exit: - return error; -} - -Error PendingDatasetManager::Save(const Dataset::Tlvs &aDatasetTlvs) -{ - Error error; - - SuccessOrExit(error = DatasetManager::Save(aDatasetTlvs)); - StartDelayTimer(); - -exit: - return error; -} - -Error PendingDatasetManager::Save(const Dataset &aDataset) -{ - Error error; - - SuccessOrExit(error = DatasetManager::SaveLocal(aDataset)); - StartDelayTimer(); - -exit: - return error; -} - -Error PendingDatasetManager::Save(const Timestamp &aTimestamp, - const Message &aMessage, - uint16_t aOffset, - uint16_t aLength) -{ - Error error = kErrorNone; - Dataset dataset; - - SuccessOrExit(error = dataset.SetFrom(aMessage, aOffset, aLength)); - SuccessOrExit(error = dataset.ValidateTlvs()); - SuccessOrExit(dataset.Write(aTimestamp)); - SuccessOrExit(error = DatasetManager::Save(dataset)); - StartDelayTimer(); - -exit: - return error; -} - void PendingDatasetManager::StartDelayTimer(void) { - Tlv *tlv; - uint32_t delay; - Dataset dataset; + Dataset dataset; - IgnoreError(Read(dataset)); + SuccessOrExit(Read(dataset)); + StartDelayTimer(dataset); + +exit: + return; +} + +void PendingDatasetManager::StartDelayTimer(const Dataset &aDataset) +{ + uint32_t delay; mDelayTimer.Stop(); - tlv = dataset.FindTlv(Tlv::kDelayTimer); - VerifyOrExit(tlv != nullptr); + SuccessOrExit(aDataset.Read(delay)); - delay = Min(tlv->ReadValueAs(), DelayTimerTlv::kMaxDelay); + delay = Min(delay, DelayTimerTlv::kMaxDelay); - mDelayTimer.StartAt(dataset.GetUpdateTime(), delay); + mDelayTimer.StartAt(aDataset.GetUpdateTime(), delay); LogInfo("delay timer started %lu", ToUlong(delay)); exit: @@ -703,7 +679,7 @@ void PendingDatasetManager::HandleDelayTimer(void) dataset.ConvertToActive(); - Get().Save(dataset); + IgnoreError(Get().Save(dataset)); Clear(); } diff --git a/src/core/meshcop/dataset_manager.hpp b/src/core/meshcop/dataset_manager.hpp index 0cf12f92b..f909a61ef 100644 --- a/src/core/meshcop/dataset_manager.hpp +++ b/src/core/meshcop/dataset_manager.hpp @@ -110,6 +110,70 @@ public: */ Error Read(Dataset::Tlvs &aDatasetTlvs) const { return mLocal.Read(aDatasetTlvs); } + /** + * Saves the Operational Dataset in non-volatile memory. + * + * @param[in] aDataset The Operational Dataset. + * + * @retval kErrorNone Successfully applied configuration. + * @retval kErrorParse The dataset has at least one TLV with invalid format. + * + */ + Error SaveLocal(const Dataset &aDataset); + + /** + * Saves the Operational Dataset in non-volatile memory. + * + * @param[in] aDatasetInfo The Operational Dataset as `Dataset::Info`. + * + * @retval kErrorNone Successfully saved the dataset. + * @retval kErrorNotImplemented The platform does not implement settings functionality. + * + */ + Error SaveLocal(const Dataset::Info &aDatasetInfo); + + /** + * Saves the Operational Dataset in non-volatile memory. + * + * @param[in] aDatasetTlvs The Operational Dataset as `Dataset::Tlvs`. + * + * @retval kErrorNone Successfully saved the dataset. + * @retval kErrorNotImplemented The platform does not implement settings functionality. + * + */ + Error SaveLocal(const Dataset::Tlvs &aDatasetTlvs); + + /** + * Sets the Operational Dataset for the partition. + * + * Also updates the non-volatile local version if the partition's Operational Dataset is newer. If Active + * Operational Dataset is changed, applies the configuration to to Thread interface. + * + * @param[in] aDataset The Operational Dataset. + * + * @retval kErrorNone Successfully applied configuration. + * @retval kErrorParse The dataset has at least one TLV with invalid format. + * + */ + Error Save(const Dataset &aDataset); + + /** + * Sets the Operational Dataset for the partition read from a given message. + * + * Also updates the non-volatile local version if the partition's Operational Dataset is newer. If Active + * Operational Dataset is changed, applies the configuration to to Thread interface. + * + * @param[in] aTimestamp The timestamp for the Operational Dataset. + * @param[in] aMessage The message to read from. + * @param[in] aOffset The offset where the Operational Dataset begins. + * @param[in] aLength The length of the Operational Dataset. + * + * @retval kErrorNone Successfully parsed the Dataset from the @p aMessage and saved it. + * @retval kErrorParse Could not parse the Dataset from @p aMessage. + * + */ + Error Save(const Timestamp &aTimestamp, const Message &aMessage, uint16_t aOffset, uint16_t aLength); + /** * Retrieves the channel mask from local dataset. * @@ -212,66 +276,6 @@ protected: */ void Clear(void); - /** - * Saves the Operational Dataset in non-volatile memory. - * - * @param[in] aDataset The Operational Dataset. - * - * @retval kErrorNone Successfully applied configuration. - * @retval kErrorParse The dataset has at least one TLV with invalid format. - * - */ - Error Save(const Dataset &aDataset); - - /** - * Saves the Operational Dataset in non-volatile memory. - * - * @param[in] aDatasetInfo The Operational Dataset as `Dataset::Info`. - * - * @retval kErrorNone Successfully saved the dataset. - * @retval kErrorNotImplemented The platform does not implement settings functionality. - * - */ - Error Save(const Dataset::Info &aDatasetInfo); - - /** - * Saves the Operational Dataset in non-volatile memory. - * - * @param[in] aDatasetTlvs The Operational Dataset as `Dataset::Tlvs`. - * - * @retval kErrorNone Successfully saved the dataset. - * @retval kErrorNotImplemented The platform does not implement settings functionality. - * - */ - Error Save(const Dataset::Tlvs &aDatasetTlvs); - - /** - * Sets the Operational Dataset for the partition. - * - * Also updates the non-volatile version if the partition's Operational Dataset is newer. - * - * @param[in] aTimestamp The timestamp for the Operational Dataset. - * @param[in] aMessage The message buffer. - * @param[in] aOffset The offset where the Operational Dataset begins. - * @param[in] aLength The length of the Operational Dataset. - * - * @retval kErrorNone Successfully parsed the Dataset from the @p aMessage and saved it. - * @retval kErrorParse Could not parse the Dataset from @p aMessage. - * - */ - Error Save(const Timestamp &aTimestamp, const Message &aMessage, uint16_t aOffset, uint8_t aLength); - - /** - * Saves the Operational Dataset in non-volatile memory. - * - * @param[in] aDataset The Operational Dataset. - * - * @retval kErrorNone Successfully applied configuration. - * @retval kErrorParse The dataset has at least one TLV with invalid format. - * - */ - Error SaveLocal(const Dataset &aDataset); - /** * Handles a MGMT_GET request message. * @@ -341,7 +345,6 @@ private: bool mAffectsNetworkKey; }; #endif - static void HandleMgmtSetResponse(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo, @@ -351,8 +354,7 @@ private: bool IsActiveDataset(void) const { return GetType() == Dataset::kActive; } bool IsPendingDataset(void) const { return GetType() == Dataset::kPending; } void SignalDatasetChange(void) const; - void HandleDatasetUpdated(void); - void SendSet(void); + void SyncLocalWithLeader(const Dataset &aDataset); Error SendSetRequest(const Dataset &aDataset); void SendGetResponse(const Coap::Message &aRequest, const Ip6::MessageInfo &aMessageInfo, @@ -423,55 +425,6 @@ public: */ void Clear(void) { DatasetManager::Clear(); } - /** - * Saves the Operational Dataset in non-volatile memory. - * - * Also reconfigures the Thread interface. - * - * @param[in] aDataset The Operational Dataset. - * - */ - void Save(const Dataset &aDataset) { IgnoreError(DatasetManager::Save(aDataset)); } - - /** - * Sets the Operational Dataset for the partition. - * - * Also reconfigures the Thread interface. - * Also updates the non-volatile version if the partition's Operational Dataset is newer. - * - * @param[in] aTimestamp The timestamp for the Operational Dataset. - * @param[in] aMessage The message buffer. - * @param[in] aOffset The offset where the Operational Dataset begins. - * @param[in] aLength The length of the Operational Dataset. - * - * @retval kErrorNone Successfully parsed the Dataset from the @p aMessage and saved it. - * @retval kErrorParse Could not parse the Dataset from @p aMessage. - * - */ - Error Save(const Timestamp &aTimestamp, const Message &aMessage, uint16_t aOffset, uint16_t aLength); - - /** - * Sets the Operational Dataset in non-volatile memory. - * - * @param[in] aDatasetInfo The Operational Dataset as `Dataset::Info`. - * - * @retval kErrorNone Successfully saved the dataset. - * @retval kErrorNotImplemented The platform does not implement settings functionality. - * - */ - Error Save(const Dataset::Info &aDatasetInfo) { return DatasetManager::Save(aDatasetInfo); } - - /** - * Sets the Operational Dataset in non-volatile memory. - * - * @param[in] aDatasetTlvs The Operational Dataset as `Dataset::Tlvs`. - * - * @retval kErrorNone Successfully saved the dataset. - * @retval kErrorNotImplemented The platform does not implement settings functionality. - * - */ - Error Save(const Dataset::Tlvs &aDatasetTlvs) { return DatasetManager::Save(aDatasetTlvs); } - #if OPENTHREAD_FTD /** @@ -547,58 +500,6 @@ public: */ void ClearNetwork(void); - /** - * Saves the Operational Dataset in non-volatile memory. - * - * Also starts the Delay Timer. - * - * @param[in] aDatasetInfo The Operational Dataset as `Dataset::Info`. - * - * @retval kErrorNone Successfully saved the dataset. - * @retval kErrorNotImplemented The platform does not implement settings functionality. - * - */ - Error Save(const Dataset::Info &aDatasetInfo); - - /** - * Saves the Operational Dataset in non-volatile memory. - * - * Also starts the Delay Timer. - * - * @param[in] aDatasetTlvs The Operational Dataset as a sequence of TLVs. - * - * @retval kErrorNone Successfully saved the dataset. - * @retval kErrorNotImplemented The platform does not implement settings functionality. - * - */ - Error Save(const Dataset::Tlvs &aDatasetTlvs); - - /** - * Sets the Operational Dataset for the partition. - * - * Also updates the non-volatile version if the partition's Operational Dataset is newer. - * - * Also starts the Delay Timer. - * - * @param[in] aTimestamp The timestamp for the Operational Dataset. - * @param[in] aMessage The message buffer. - * @param[in] aOffset The offset where the Operational Dataset begins. - * @param[in] aLength The length of the Operational Dataset. - * - */ - Error Save(const Timestamp &aTimestamp, const Message &aMessage, uint16_t aOffset, uint16_t aLength); - - /** - * Saves the Operational Dataset in non-volatile memory. - * - * @param[in] aDataset The Operational Dataset. - * - * @retval kErrorNone Successfully applied configuration. - * @retval kErrorParse The dataset has at least one TLV with invalid format. - * - */ - Error Save(const Dataset &aDataset); - #if OPENTHREAD_FTD /** * Starts the Leader functions for maintaining the Active Operational Dataset. @@ -613,6 +514,7 @@ private: #endif void StartDelayTimer(void); + void StartDelayTimer(const Dataset &aDataset); static void HandleTimer(Timer &aTimer); void HandleTimer(void) { DatasetManager::HandleTimer(); } diff --git a/src/core/meshcop/dataset_manager_ftd.cpp b/src/core/meshcop/dataset_manager_ftd.cpp index 9c2c20edc..72a5dbc10 100644 --- a/src/core/meshcop/dataset_manager_ftd.cpp +++ b/src/core/meshcop/dataset_manager_ftd.cpp @@ -433,7 +433,7 @@ void PendingDatasetManager::ApplyActiveDataset(Dataset &aDataset) SuccessOrExit(aDataset.Write(Get().GetDelayTimerMinimal())); IgnoreError(DatasetManager::Save(aDataset)); - StartDelayTimer(); + StartDelayTimer(aDataset); exit: return; diff --git a/src/core/meshcop/dataset_updater.cpp b/src/core/meshcop/dataset_updater.cpp index 4aadbaff4..36fd28a17 100644 --- a/src/core/meshcop/dataset_updater.cpp +++ b/src/core/meshcop/dataset_updater.cpp @@ -149,7 +149,7 @@ void DatasetUpdater::PreparePendingDataset(void) IgnoreError(dataset.Write(timestamp)); } - SuccessOrExit(error = Get().Save(dataset)); + SuccessOrExit(error = Get().SaveLocal(dataset)); exit: if (error != kErrorNone) diff --git a/src/core/meshcop/joiner.cpp b/src/core/meshcop/joiner.cpp index f8fb30e0c..ce0b6a167 100644 --- a/src/core/meshcop/joiner.cpp +++ b/src/core/meshcop/joiner.cpp @@ -533,7 +533,7 @@ template <> void Joiner::HandleTmf(Coap::Message &aMessage, c datasetInfo.Set(Get().GetPanChannel()); datasetInfo.Set(Get().GetPanId()); - IgnoreError(Get().Save(datasetInfo)); + IgnoreError(Get().SaveLocal(datasetInfo)); LogInfo("Joiner successful!"); diff --git a/src/core/meshcop/tcat_agent.cpp b/src/core/meshcop/tcat_agent.cpp index b90163210..1221a5549 100644 --- a/src/core/meshcop/tcat_agent.cpp +++ b/src/core/meshcop/tcat_agent.cpp @@ -476,7 +476,7 @@ Error TcatAgent::HandleSetActiveOperationalDataset(const Message &aIncommingMess } dataset.ConvertTo(datasetTlvs); - error = Get().Save(datasetTlvs); + error = Get().SaveLocal(datasetTlvs); exit: return error;