[mle] save child info in settings on mode or timeout change (#3129)

This commit changes `MleRouter::HandleChildUpdateRequest()`:

- If the child entry is modified (i.e., timeout value or
  device mode changes) on an already attached child, the child
  info is updated and saved in the non-volatile settings.
  This ensures that after a parent reset the child can be
  recovered correctly.

- If the "Child Update Request" causes a mode change from rx-on
  to sleepy on a child in `kStateValid` (already attached), the
  source match controller is set to perform source address
  matching on the short address.

- This commit also adds a log to indicate mode change of a
  child.
This commit is contained in:
Abtin Keshavarzian
2018-10-10 12:43:13 -07:00
committed by Jonathan Hui
parent e3a82139e3
commit c5d611a366
+34 -2
View File
@@ -2243,6 +2243,7 @@ otError MleRouter::HandleChildUpdateRequest(const Message & aMessage,
uint8_t tlvs[kMaxResponseTlvs];
uint8_t tlvslength = 0;
uint16_t addressRegistrationOffset = 0;
bool childDidChange = false;
LogMleMessage("Receive Child Update Request from child", aMessageInfo.GetPeerAddr());
@@ -2270,7 +2271,25 @@ otError MleRouter::HandleChildUpdateRequest(const Message & aMessage,
ExitNow();
}
child->SetDeviceMode(mode.GetMode());
if (child->GetDeviceMode() != mode.GetMode())
{
otLogNoteMle(GetInstance(),
"Child 0x%04x mode change 0x%02x -> 0x%02x [rx-on:%s, sec-data-req:%s, ftd:%s, full-netdata:%s]",
child->GetRloc16(), child->GetDeviceMode(), mode.GetMode(),
(mode.GetMode() & ModeTlv::kModeRxOnWhenIdle) ? "yes" : " no",
(mode.GetMode() & ModeTlv::kModeSecureDataRequest) ? "yes" : " no",
(mode.GetMode() & ModeTlv::kModeFullThreadDevice) ? "yes" : "no",
(mode.GetMode() & ModeTlv::kModeFullNetworkData) ? "yes" : "no");
child->SetDeviceMode(mode.GetMode());
childDidChange = true;
if (!(mode.GetMode() & ModeTlv::kModeRxOnWhenIdle) && (child->GetState() == Neighbor::kStateValid))
{
GetNetif().GetMeshForwarder().GetSourceMatchController().SetSrcMatchAsShort(*child, true);
}
}
tlvs[tlvslength++] = Tlv::kMode;
// Parent MUST include Leader Data TLV in Child Update Response
@@ -2302,7 +2321,13 @@ otError MleRouter::HandleChildUpdateRequest(const Message & aMessage,
if (Tlv::GetTlv(aMessage, Tlv::kTimeout, sizeof(timeout), timeout) == OT_ERROR_NONE)
{
VerifyOrExit(timeout.IsValid(), error = OT_ERROR_PARSE);
child->SetTimeout(timeout.GetTimeout());
if (child->GetTimeout() != timeout.GetTimeout())
{
child->SetTimeout(timeout.GetTimeout());
childDidChange = true;
}
tlvs[tlvslength++] = Tlv::kTimeout;
}
@@ -2332,6 +2357,13 @@ otError MleRouter::HandleChildUpdateRequest(const Message & aMessage,
SetChildStateToValid(*child);
child->SetKeySequence(aKeySequence);
}
else if (child->GetState() == Neighbor::kStateValid)
{
if (childDidChange)
{
StoreChild(*child);
}
}
SendChildUpdateResponse(child, aMessageInfo, tlvs, tlvslength, &challenge);