diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index bb6b822a3..c0f6b74ce 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -304,7 +304,23 @@ ThreadError Mle::Restore(void) { mNetif.GetMle().SetRouterId(GetRouterId(GetRloc16())); mNetif.GetMle().SetPreviousPartitionId(networkInfo.mPreviousPartitionId); - mNetif.GetMle().RestoreChildren(); + + switch (mNetif.GetMle().RestoreChildren()) + { + // If there are more saved children in non-volatile settings + // than could be restored or the values in the settings are + // invalid, erase all the children info in the settings and + // refresh the info to ensure that the non-volatile settings + // stay in sync with the child table. + + case kThreadError_Failed: + case kThreadError_NoBufs: + mNetif.GetMle().RefreshStoredChildren(); + break; + + default: + break; + } } exit: diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index bde3e1523..0f855eed9 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -3398,7 +3398,7 @@ ThreadError MleRouter::RestoreChildren(void) { ThreadError error = kThreadError_None; - for (uint8_t i = 0; i < kMaxChildren; i++) + for (uint8_t i = 0; ; i++) { Child *child; otChildInfo childInfo; @@ -3407,7 +3407,7 @@ ThreadError MleRouter::RestoreChildren(void) length = sizeof(childInfo); SuccessOrExit(otPlatSettingsGet(mNetif.GetInstance(), kKeyChildInfo, i, reinterpret_cast(&childInfo), &length)); - VerifyOrExit(length == sizeof(childInfo), ;); + VerifyOrExit(length == sizeof(childInfo), error = kThreadError_Failed); VerifyOrExit((child = NewChild()) != NULL, error = kThreadError_NoBufs); memset(child, 0, sizeof(*child)); @@ -3468,6 +3468,24 @@ exit: return error; } +ThreadError MleRouter::RefreshStoredChildren(void) +{ + ThreadError error = kThreadError_None; + + SuccessOrExit(error = otPlatSettingsDelete(mNetif.GetInstance(), kKeyChildInfo, -1)); + + for (uint8_t i = 0; i < kMaxChildren; i++) + { + if (mChildren[i].mState != Neighbor::kStateInvalid) + { + SuccessOrExit(error = StoreChild(mChildren[i].mValid.mRloc16)); + } + } + +exit: + return error; +} + ThreadError MleRouter::GetChildInfo(Child &aChild, otChildInfo &aChildInfo) { ThreadError error = kThreadError_None; diff --git a/src/core/thread/mle_router_ftd.hpp b/src/core/thread/mle_router_ftd.hpp index e71fb7f81..247e6b709 100644 --- a/src/core/thread/mle_router_ftd.hpp +++ b/src/core/thread/mle_router_ftd.hpp @@ -389,7 +389,7 @@ public: * * @param[in] aMaxChildren The max children allowed value. * - * @retval kThreadErrorNone Successfully set the max. + * @retval kThreadError_None Successfully set the max. * @retval kThreadError_InvalidArgs If @p aMaxChildren is not in the range [1, kMaxChildren]. * @retval kThreadError_InvalidState If MLE has already been started. * @@ -399,8 +399,9 @@ public: /** * This method restores children information from non-volatile memory. * - * @retval kThreadErrorNone Successfully restores children information. - * @retval kThreadError_NoBufs Insufficient available buffers to restore all children information. + * @retval kThreadError_None Successfully restored children information. + * @retval kThreadError_Failed The saved child info in non-volatile memory is invalid. + * @retval kThreadError_NoBufs More children in settings than max children. * */ ThreadError RestoreChildren(void); @@ -410,7 +411,7 @@ public: * * @param[in] aChildRloc16 The child RLOC16 to remove. * - * @retval kThreadErrorNone Successfully remove child. + * @retval kThreadError_None Successfully remove child. * @retval kThreadError_NotFound There is no specified child stored in non-volatile memory. * */ @@ -421,12 +422,22 @@ public: * * @param[in] aChildRloc16 The child RLOC16 to store. * - * @retval kThreadErrorNone Successfully store child. + * @retval kThreadError_None Successfully store child. * @retval kThreadError_NoBufs Insufficient available buffers to store child. * */ ThreadError StoreChild(uint16_t aChildRloc16); + /** + * This method refreshes all the saved children information in non-volatile memory by first erasing any saved + * child information in non-volatile memory and then saving all children info. + * + * @retval kThreadError_None Successfully refreshed all children info in non-volatile memory + * @retval kThreadError_NoBufs Insufficient available buffers to store child. + * + */ + ThreadError RefreshStoredChildren(void); + /** * This method returns a pointer to a Neighbor object. * diff --git a/src/core/thread/mle_router_mtd.hpp b/src/core/thread/mle_router_mtd.hpp index 20606fcab..8837368f7 100644 --- a/src/core/thread/mle_router_mtd.hpp +++ b/src/core/thread/mle_router_mtd.hpp @@ -113,6 +113,7 @@ public: ThreadError RestoreChildren(void) {return kThreadError_NotImplemented; } ThreadError RemoveStoredChild(uint16_t) {return kThreadError_NotImplemented; } ThreadError StoreChild(uint16_t) {return kThreadError_NotImplemented; } + ThreadError RefreshStoredChildren(void) { return kThreadError_NotImplemented; } Neighbor *GetNeighbor(uint16_t aAddress) { return Mle::GetNeighbor(aAddress); } Neighbor *GetNeighbor(const Mac::ExtAddress &aAddress) { return Mle::GetNeighbor(aAddress); }