Handle RestoreChildren() failures and ensure to refresh the non-volatile settings. (#1543)

This commit makes the following changes:

- It updates `RestoreChildren()` to detect error cases where the
  saved children info is invalid or if there are more children
  stored in non-volatile settings than can be restored.

- In case of such errors, it is ensured that the content in
  non-volatile memory is refreshed (through newly introduced method
  `MleRouter::RefreshStoredChildren()`) so that it stays in sync
  with the child table.
This commit is contained in:
Abtin Keshavarzian
2017-03-31 08:48:56 -07:00
committed by Jonathan Hui
parent 75172aabc7
commit c05830179b
4 changed files with 54 additions and 8 deletions
+17 -1
View File
@@ -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:
+20 -2
View File
@@ -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<uint8_t *>(&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;
+16 -5
View File
@@ -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.
*
+1
View File
@@ -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); }