mirror of
https://github.com/espressif/openthread.git
synced 2026-09-01 23:09:53 +00:00
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:
committed by
Jonathan Hui
parent
75172aabc7
commit
c05830179b
+17
-1
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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); }
|
||||
|
||||
Reference in New Issue
Block a user