Implement Network Data TLV in Child Update messages. (#659)

This commit is contained in:
Jonathan Hui
2016-09-23 10:19:55 -07:00
committed by GitHub
parent 9b97c1c7d0
commit 4742419be6
2 changed files with 51 additions and 7 deletions
+28 -6
View File
@@ -2026,6 +2026,7 @@ ThreadError Mle::HandleChildUpdateResponse(const Message &aMessage, const Ip6::M
LeaderDataTlv leaderData;
SourceAddressTlv sourceAddress;
TimeoutTlv timeout;
NetworkDataTlv networkData;
uint8_t tlvs[] = {Tlv::kNetworkData};
otLogInfoMle("Received Child Update Response\n");
@@ -2061,11 +2062,6 @@ ThreadError Mle::HandleChildUpdateResponse(const Message &aMessage, const Ip6::M
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kLeaderData, sizeof(leaderData), leaderData));
VerifyOrExit(leaderData.IsValid(), error = kThreadError_Parse);
if (static_cast<int8_t>(leaderData.GetDataVersion() - mNetworkData.GetVersion()) > 0)
{
SendDataRequest(aMessageInfo.GetPeerAddr(), tlvs, sizeof(tlvs));
}
// Source Address
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kSourceAddress, sizeof(sourceAddress), sourceAddress));
VerifyOrExit(sourceAddress.IsValid(), error = kThreadError_Parse);
@@ -2083,7 +2079,16 @@ ThreadError Mle::HandleChildUpdateResponse(const Message &aMessage, const Ip6::M
mTimeout = timeout.GetTimeout();
}
if ((mode.GetMode() & ModeTlv::kModeRxOnWhenIdle) == 0)
// Network Data optional
if (Tlv::GetTlv(aMessage, Tlv::kNetworkData, sizeof(networkData), networkData) == kThreadError_None)
{
VerifyOrExit(networkData.IsValid(), error = kThreadError_Parse);
mNetworkData.SetNetworkData(leaderData.GetDataVersion(), leaderData.GetStableDataVersion(),
(mDeviceMode & ModeTlv::kModeFullNetworkData) == 0,
networkData.GetNetworkData(), networkData.GetLength());
}
if ((mDeviceMode & ModeTlv::kModeRxOnWhenIdle) == 0)
{
mMesh.SetPollPeriod(Timer::SecToMsec(mTimeout / kMaxChildKeepAliveAttempts));
mMesh.SetRxOnWhenIdle(false);
@@ -2093,6 +2098,23 @@ ThreadError Mle::HandleChildUpdateResponse(const Message &aMessage, const Ip6::M
mMesh.SetRxOnWhenIdle(true);
}
if (mDeviceMode & ModeTlv::kModeFullNetworkData)
{
// full network data
if (leaderData.GetDataVersion() != mNetworkData.GetVersion())
{
SendDataRequest(aMessageInfo.GetPeerAddr(), tlvs, sizeof(tlvs));
}
}
else
{
// stable network data
if (leaderData.GetStableDataVersion() != mNetworkData.GetStableVersion())
{
SendDataRequest(aMessageInfo.GetPeerAddr(), tlvs, sizeof(tlvs));
}
}
break;
default:
+23 -1
View File
@@ -1982,6 +1982,8 @@ exit:
ThreadError MleRouter::HandleChildUpdateRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
static const uint8_t kMaxResponseTlvs = 8;
ThreadError error = kThreadError_None;
Mac::ExtAddress macAddr;
ModeTlv mode;
@@ -1990,7 +1992,7 @@ ThreadError MleRouter::HandleChildUpdateRequest(const Message &aMessage, const I
LeaderDataTlv leaderData;
TimeoutTlv timeout;
Child *child;
uint8_t tlvs[7];
uint8_t tlvs[kMaxResponseTlvs];
uint8_t tlvslength = 0;
otLogInfoMle("Received Child Update Request\n");
@@ -2038,13 +2040,29 @@ ThreadError MleRouter::HandleChildUpdateRequest(const Message &aMessage, const I
if (child->mMode & ModeTlv::kModeFullNetworkData)
{
// full network data
child->mNetworkDataVersion = leaderData.GetDataVersion();
if (leaderData.GetDataVersion() != mNetworkData.GetVersion())
{
tlvs[tlvslength++] = Tlv::kNetworkData;
}
}
else
{
// stable network data
child->mNetworkDataVersion = leaderData.GetStableDataVersion();
if (leaderData.GetStableDataVersion() != mNetworkData.GetStableVersion())
{
tlvs[tlvslength++] = Tlv::kNetworkData;
}
}
}
else
{
tlvs[tlvslength++] = Tlv::kNetworkData;
}
// Timeout
if (Tlv::GetTlv(aMessage, Tlv::kTimeout, sizeof(timeout), timeout) == kThreadError_None)
@@ -2241,6 +2259,10 @@ ThreadError MleRouter::SendChildUpdateResponse(Child *aChild, const Ip6::Message
SuccessOrExit(error = AppendMode(*message, aChild->mMode));
break;
case Tlv::kNetworkData:
SuccessOrExit(error = AppendNetworkData(*message, (aChild->mMode & ModeTlv::kModeFullNetworkData) == 0));
break;
case Tlv::kResponse:
SuccessOrExit(error = AppendResponse(*message, aChallenge->GetChallenge(), aChallenge->GetLength()));
break;