[mle] enable retransmission of network data to SEDs (#2107)

The Thread Specification requires the router to repeatedly transmit
new Thread Network Data to the SED until it receive an explicit
acknolwedgment from the SED.  Prior to this commit, when network data
changes, a router attempts to update the SED by sending a single MLE
Data Response message.  If the message is lost for any reason (e.g. no
available message buffers, link-layer delivery failure, etc.), the
router will not attempt to send the MLE Data Response again to update
the SED's network data.

This commit makes the following changes:

- The router communicates updated network data in an MLE Child Update
  Request message, requiring the SED to send an MLE Child Update
  Response message with the Leader Data TLV.

- The router repeatedly attempts to transmit new network data to the
  SED until it receives a Leader Data TLV with the updated version.
This commit is contained in:
Jonathan Hui
2017-08-16 09:59:58 -07:00
committed by GitHub
parent ff270a1233
commit 9d66542ed8
2 changed files with 26 additions and 14 deletions
+25 -14
View File
@@ -1888,6 +1888,8 @@ void MleRouter::HandleStateUpdateTimer(void)
}
}
SynchronizeChildNetworkData();
mStateUpdateTimer.Start(kStateUpdatePeriod);
exit:
@@ -2461,7 +2463,6 @@ exit:
otError MleRouter::HandleNetworkDataUpdateRouter(void)
{
static const uint8_t tlvs[] = {Tlv::kNetworkData};
ThreadNetif &netif = GetNetif();
Ip6::Address destination;
uint16_t delay;
@@ -2474,37 +2475,47 @@ otError MleRouter::HandleNetworkDataUpdateRouter(void)
delay = (mRole == OT_DEVICE_ROLE_LEADER) ? 0 : (otPlatRandomGet() % kUnsolicitedDataResponseJitter);
SendDataResponse(destination, tlvs, sizeof(tlvs), delay);
SynchronizeChildNetworkData();
exit:
return OT_ERROR_NONE;
}
void MleRouter::SynchronizeChildNetworkData(void)
{
ThreadNetif &netif = GetNetif();
VerifyOrExit(mRole == OT_DEVICE_ROLE_ROUTER || mRole == OT_DEVICE_ROLE_LEADER);
for (uint8_t i = 0; i < mMaxChildrenAllowed; i++)
{
Child *child = &mChildren[i];
uint8_t version;
if (child->GetState() != Neighbor::kStateValid || child->IsRxOnWhenIdle())
{
continue;
}
memset(&destination, 0, sizeof(destination));
destination.mFields.m16[0] = HostSwap16(0xfe80);
destination.SetIid(child->GetExtAddress());
if (child->IsFullNetworkData())
{
if (child->GetNetworkDataVersion() != netif.GetNetworkDataLeader().GetVersion())
{
SendDataResponse(destination, tlvs, sizeof(tlvs), 0);
}
version = netif.GetNetworkDataLeader().GetVersion();
}
else
{
if (child->GetNetworkDataVersion() != netif.GetNetworkDataLeader().GetStableVersion())
{
SendDataResponse(destination, tlvs, sizeof(tlvs), 0);
}
version = netif.GetNetworkDataLeader().GetStableVersion();
}
if (child->GetNetworkDataVersion() == version)
{
continue;
}
SuccessOrExit(SendChildUpdateRequest(child));
}
exit:
return OT_ERROR_NONE;
return;
}
#if OPENTHREAD_CONFIG_ENABLE_STEERING_DATA_SET_OOB
+1
View File
@@ -753,6 +753,7 @@ private:
otError SetStateRouter(uint16_t aRloc16);
otError SetStateLeader(uint16_t aRloc16);
void StopLeader(void);
void SynchronizeChildNetworkData(void);
otError UpdateChildAddresses(const AddressRegistrationTlv &aTlv, Child &aChild);
void UpdateRoutes(const RouteTlv &aTlv, uint8_t aRouterId);