From bc9745584b044197c10fac29a0cb504b74cddfed Mon Sep 17 00:00:00 2001 From: Rongli Sun Date: Wed, 10 Jun 2020 03:39:22 +0800 Subject: [PATCH] [dua] save dad counter into non volatile memory (#4904) --- src/core/common/settings.cpp | 55 +++++++++++++++++++++++ src/core/common/settings.hpp | 79 ++++++++++++++++++++++++++++++++- src/core/thread/dua_manager.cpp | 29 +++++++++++- src/core/thread/dua_manager.hpp | 7 +++ src/core/thread/mle.cpp | 4 ++ 5 files changed, 172 insertions(+), 2 deletions(-) diff --git a/src/core/common/settings.cpp b/src/core/common/settings.cpp index fda8d6b6d..26934cf86 100644 --- a/src/core/common/settings.cpp +++ b/src/core/common/settings.cpp @@ -78,6 +78,13 @@ void SettingsBase::LogChildInfo(const char *aAction, const ChildInfo &aChildInfo aChildInfo.GetMode(), aChildInfo.GetVersion()); } +#if OPENTHREAD_CONFIG_DUA_ENABLE +void SettingsBase::LogDadInfo(const char *aAction, const DadInfo &aDadInfo) const +{ + otLogInfoCore("Non-volatile: %s DadInfo {DadCounter:%2d}", aAction, aDadInfo.mDadCounter); +} +#endif + #endif // #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_WARN) @@ -395,6 +402,54 @@ exit: mIsDone = (error != OT_ERROR_NONE); } +#if OPENTHREAD_CONFIG_DUA_ENABLE +otError Settings::ReadDadInfo(DadInfo &aDadInfo) const +{ + otError error; + uint16_t length = sizeof(DadInfo); + + aDadInfo.Init(); + SuccessOrExit(error = Read(kKeyDadInfo, &aDadInfo, length)); + LogDadInfo("Read", aDadInfo); + +exit: + return error; +} + +otError Settings::SaveDadInfo(const DadInfo &aDadInfo) +{ + otError error = OT_ERROR_NONE; + DadInfo prevDadInfo; + uint16_t length = sizeof(DadInfo); + + if ((Read(kKeyDadInfo, &prevDadInfo, length) == OT_ERROR_NONE) && (length == sizeof(DadInfo)) && + (memcmp(&prevDadInfo, &aDadInfo, sizeof(DadInfo)) == 0)) + { + LogDadInfo("Re-saved", aDadInfo); + ExitNow(); + } + + SuccessOrExit(error = Save(kKeyDadInfo, &aDadInfo, sizeof(DadInfo))); + LogDadInfo("Saved", aDadInfo); + +exit: + LogFailure(error, "saving DadInfo", false); + return error; +} + +otError Settings::DeleteDadInfo(void) +{ + otError error; + + SuccessOrExit(error = Delete(kKeyDadInfo)); + otLogInfoCore("Non-volatile: Deleted DadInfo"); + +exit: + LogFailure(error, "deleting DadInfo", true); + return error; +} +#endif // OPENTHREAD_CONFIG_DUA_ENABLE + otError Settings::Read(Key aKey, void *aBuffer, uint16_t &aSize) const { return Get().Get(aKey, 0, reinterpret_cast(aBuffer), &aSize); diff --git a/src/core/common/settings.hpp b/src/core/common/settings.hpp index 5f7c1bd29..9ae472a58 100644 --- a/src/core/common/settings.hpp +++ b/src/core/common/settings.hpp @@ -538,6 +538,40 @@ public: uint16_t mVersion; ///< Version } OT_TOOL_PACKED_END; + /** + * This structure represents the duplicate address detection information for settings storage. + * + */ + OT_TOOL_PACKED_BEGIN + class DadInfo + { + public: + /** + * This method clears the struct object (setting all the fields to zero). + * + */ + void Init(void) { memset(this, 0, sizeof(*this)); } + + /** + * This method returns the Dad Counter. + * + * @returns The Dad Counter value. + * + */ + uint8_t GetDadCounter(void) const { return mDadCounter; } + + /** + * This method sets the Dad Counter. + * + * @param[in] aDadCounter The Dad Counter value. + * + */ + void SetDadCounter(uint8_t aDadCounter) { mDadCounter = aDadCounter; } + + private: + uint8_t mDadCounter; ///< Dad Counter used to resolve address conflict in Thread 1.2 DUA feature. + } OT_TOOL_PACKED_END; + /** * This enumeration defines the keys of settings. * @@ -551,6 +585,7 @@ public: kKeyChildInfo = 0x0005, ///< Child information kKeyReserved = 0x0006, ///< Reserved (previously auto-start) kKeySlaacIidSecretKey = 0x0007, ///< Secret key used by SLAAC module for generating semantically opaque IID + kKeyDadInfo = 0x0008, ///< Duplicate Address Detection (DAD) information. }; protected: @@ -563,11 +598,17 @@ protected: 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 +#if OPENTHREAD_CONFIG_DUA_ENABLE + void LogDadInfo(const char *aAction, const DadInfo &aDadInfo) const; +#endif +#else // (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_UTIL != 0) void LogNetworkInfo(const char *, const NetworkInfo &) const {} void LogParentInfo(const char *, const ParentInfo &) const {} void LogChildInfo(const char *, const ChildInfo &) const {} +#if OPENTHREAD_CONFIG_DUA_ENABLE + void LogDadInfo(const char *, const DadInfo &) const {} #endif +#endif // (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_UTIL != 0) #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_WARN) && (OPENTHREAD_CONFIG_LOG_UTIL != 0) void LogFailure(otError aError, const char *aAction, bool aIsDelete) const; @@ -864,6 +905,42 @@ public: bool mIsDone; }; +#if OPENTHREAD_CONFIG_DUA_ENABLE + + /** + * This method saves duplicate address detection information. + * + * @param[in] aDadInfo A reference to a `DadInfo` structure to be saved. + * + * @retval OT_ERROR_NONE Successfully saved duplicate address detection information in settings. + * @retval OT_ERROR_NOT_IMPLEMENTED The platform does not implement settings functionality. + * + */ + otError SaveDadInfo(const DadInfo &aDadInfo); + + /** + * This method reads duplicate address detection information. + * + * @param[out] aDadInfo A reference to a `DadInfo` structure to output the read content. + * + * @retval OT_ERROR_NONE Successfully read the duplicate address detection information. + * @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 ReadDadInfo(DadInfo &aDadInfo) const; + + /** + * This method deletes duplicate address detection information from settings. + * + * @retval OT_ERROR_NONE Successfully deleted the value. + * @retval OT_ERROR_NOT_IMPLEMENTED The platform does not implement settings functionality. + * + */ + otError DeleteDadInfo(void); + +#endif // OPENTHREAD_CONFIG_DUA_ENABLE + private: otError Read(Key aKey, void *aBuffer, uint16_t &aSize) const; otError Save(Key aKey, const void *aValue, uint16_t aSize); diff --git a/src/core/thread/dua_manager.cpp b/src/core/thread/dua_manager.cpp index d2b304227..1e73ad6be 100644 --- a/src/core/thread/dua_manager.cpp +++ b/src/core/thread/dua_manager.cpp @@ -39,6 +39,7 @@ #include "common/instance.hpp" #include "common/locator-getters.hpp" #include "common/logging.hpp" +#include "common/settings.hpp" #include "net/ip6_address.hpp" #include "thread/thread_netif.hpp" #include "utils/slaac_address.hpp" @@ -99,9 +100,16 @@ exit: otError DuaManager::GenerateDomainUnicastAddressIid(void) { otError error; + uint8_t dadCounter = mDadCounter; - if ((error = Get().GenerateIid(mDomainUnicastAddress, NULL, 0, &mDadCounter)) == OT_ERROR_NONE) + if ((error = Get().GenerateIid(mDomainUnicastAddress, NULL, 0, &dadCounter)) == OT_ERROR_NONE) { + if (dadCounter != mDadCounter) + { + mDadCounter = dadCounter; + IgnoreError(Store()); + } + otLogInfoIp6("Generated DUA: %s", mDomainUnicastAddress.GetAddress().ToString().AsCString()); } else @@ -156,6 +164,25 @@ exit: return; } +void DuaManager::Restore(void) +{ + Settings::DadInfo dadInfo; + + SuccessOrExit(Get().ReadDadInfo(dadInfo)); + mDadCounter = dadInfo.GetDadCounter(); + +exit: + return; +} + +otError DuaManager::Store(void) +{ + Settings::DadInfo dadInfo; + + dadInfo.SetDadCounter(mDadCounter); + return Get().SaveDadInfo(dadInfo); +} + } // namespace ot #endif // (OPENTHREAD_FTD || OPENTHREAD_MTD) && OPENTHREAD_CONFIG_DUA_ENABLE diff --git a/src/core/thread/dua_manager.hpp b/src/core/thread/dua_manager.hpp index 6855e35c1..69702529e 100644 --- a/src/core/thread/dua_manager.hpp +++ b/src/core/thread/dua_manager.hpp @@ -124,8 +124,15 @@ public: */ const Ip6::InterfaceIdentifier &GetFixedDuaInterfaceIdentifier(void) const { return mFixedDuaInterfaceIdentifier; } + /* + * This method restores duplicate address detection information from non-volatile memory. + * + */ + void Restore(void); + private: otError GenerateDomainUnicastAddressIid(void); + otError Store(void); Ip6::InterfaceIdentifier mFixedDuaInterfaceIdentifier; Ip6::NetifUnicastAddress mDomainUnicastAddress; diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 0f4bb70a3..4b0ee48e8 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -366,6 +366,10 @@ otError Mle::Restore(void) IgnoreError(Get().Restore()); IgnoreError(Get().Restore()); +#if OPENTHREAD_CONFIG_DUA_ENABLE + Get().Restore(); +#endif + SuccessOrExit(error = Get().ReadNetworkInfo(networkInfo)); Get().SetCurrentKeySequence(networkInfo.GetKeySequence());