[mle] fix issue with saving child info to non-volatile (#2935)
This commit addresses an bug where the child info was not being
saved in non-volatile settings. It fixes the following cases in
the code where a child id was used to search for a child (using
`FindChild()`) instead of the RLOC16 address:
- `StoreChild()` is changed to accept a `const Child &` as input
parameter avoiding the need to look up the child by ID or RLOC16.
- `SendChildIdResponse()` and `GetChildInfoById()` are updated to
perform the search for a child using its RLOC16.
diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp
index 1d13ffc..cc7e9ac 100644
--- a/src/core/thread/mle_router.cpp
+++ b/src/core/thread/mle_router.cpp
@@ -2773,6 +2773,8 @@
if (aChild.GetRloc16() == 0)
{
+ uint16_t rloc16;
+
// pick next Child ID that is not being used
do
{
@@ -2782,10 +2784,13 @@
{
mNextChildId = kMinChildId;
}
- } while (GetChildTable().FindChild(mNextChildId, ChildTable::kInStateAnyExceptInvalid) != NULL);
+
+ rloc16 = netif.GetMac().GetShortAddress() | mNextChildId;
+
+ } while (GetChildTable().FindChild(rloc16, ChildTable::kInStateAnyExceptInvalid) != NULL);
// allocate Child ID
- aChild.SetRloc16(netif.GetMac().GetShortAddress() | mNextChildId);
+ aChild.SetRloc16(rloc16);
}
SuccessOrExit(error = AppendAddress16(*message, aChild.GetRloc16()));
@@ -3423,15 +3428,17 @@
otError MleRouter::GetChildInfoById(uint16_t aChildId, otChildInfo &aChildInfo)
{
- otError error = OT_ERROR_NONE;
- Child * child;
+ otError error = OT_ERROR_NONE;
+ Child * child;
+ uint16_t rloc16;
if ((aChildId & ~kMaxChildId) != 0)
{
aChildId = GetChildId(aChildId);
}
- child = GetChildTable().FindChild(aChildId, ChildTable::kInStateAnyExceptInvalid);
+ rloc16 = GetNetif().GetMac().GetShortAddress() | aChildId;
+ child = GetChildTable().FindChild(rloc16, ChildTable::kInStateAnyExceptInvalid);
VerifyOrExit(child != NULL, error = OT_ERROR_NOT_FOUND);
error = GetChildInfo(*child, aChildInfo);
@@ -3537,27 +3544,19 @@
return error;
}
-otError MleRouter::StoreChild(uint16_t aChildRloc16)
+otError MleRouter::StoreChild(const Child &aChild)
{
- otError error = OT_ERROR_NONE;
- Child * child;
Settings::ChildInfo childInfo;
- child = GetChildTable().FindChild(GetChildId(aChildRloc16), ChildTable::kInStateAnyExceptInvalid);
- VerifyOrExit(child != NULL, error = OT_ERROR_NOT_FOUND);
-
- IgnoreReturnValue(RemoveStoredChild(aChildRloc16));
+ IgnoreReturnValue(RemoveStoredChild(aChild.GetRloc16()));
memset(&childInfo, 0, sizeof(childInfo));
- childInfo.mExtAddress = child->GetExtAddress();
- childInfo.mTimeout = child->GetTimeout();
- childInfo.mRloc16 = child->GetRloc16();
- childInfo.mMode = child->GetDeviceMode();
+ childInfo.mExtAddress = aChild.GetExtAddress();
+ childInfo.mTimeout = aChild.GetTimeout();
+ childInfo.mRloc16 = aChild.GetRloc16();
+ childInfo.mMode = aChild.GetDeviceMode();
- error = GetInstance().GetSettings().AddChildInfo(childInfo);
-
-exit:
- return error;
+ return GetInstance().GetSettings().AddChildInfo(childInfo);
}
otError MleRouter::RefreshStoredChildren(void)
@@ -3568,7 +3567,7 @@
for (ChildTable::Iterator iter(GetInstance(), ChildTable::kInStateAnyExceptInvalid); !iter.IsDone(); iter++)
{
- SuccessOrExit(error = StoreChild(iter.GetChild()->GetRloc16()));
+ SuccessOrExit(error = StoreChild(*iter.GetChild()));
}
exit:
@@ -4535,7 +4534,7 @@
VerifyOrExit(aChild.GetState() != Neighbor::kStateValid);
aChild.SetState(Neighbor::kStateValid);
- StoreChild(aChild.GetRloc16());
+ StoreChild(aChild);
SignalChildUpdated(OT_THREAD_CHILD_TABLE_EVENT_CHILD_ADDED, aChild);
exit:
diff --git a/src/core/thread/mle_router_ftd.hpp b/src/core/thread/mle_router_ftd.hpp
index d4dfcfd..3b0bd34 100644
--- a/src/core/thread/mle_router_ftd.hpp
+++ b/src/core/thread/mle_router_ftd.hpp
@@ -364,13 +364,13 @@
/**
* This method store a child information into non-volatile memory.
*
- * @param[in] aChildRloc16 The child RLOC16 to store.
+ * @param[in] aChild A reference to the child to store.
*
* @retval OT_ERROR_NONE Successfully store child.
* @retval OT_ERROR_NO_BUFS Insufficient available buffers to store child.
*
*/
- otError StoreChild(uint16_t aChildRloc16);
+ otError StoreChild(const Child &aChild);
/**
* 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 42fd340..fc53e60 100644
--- a/src/core/thread/mle_router_mtd.hpp
+++ b/src/core/thread/mle_router_mtd.hpp
@@ -90,7 +90,7 @@
void RestoreChildren(void) {}
otError RemoveStoredChild(uint16_t) { return OT_ERROR_NOT_IMPLEMENTED; }
- otError StoreChild(uint16_t) { return OT_ERROR_NOT_IMPLEMENTED; }
+ otError StoreChild(const Child &) { return OT_ERROR_NOT_IMPLEMENTED; }
Neighbor *GetNeighbor(uint16_t aAddress) { return Mle::GetNeighbor(aAddress); }
Neighbor *GetNeighbor(const Mac::ExtAddress &aAddress) { return Mle::GetNeighbor(aAddress); }