mirror of
https://github.com/espressif/openthread.git
synced 2026-08-07 11:17:46 +00:00
[network-data] deregister for invalid child on new network data (#4485)
This commit is contained in:
@@ -2606,6 +2606,24 @@ void MleRouter::HandleNetworkDataUpdateRouter(void)
|
||||
|
||||
SynchronizeChildNetworkData();
|
||||
|
||||
// Detect if any server entry with invalid child RLOC16
|
||||
{
|
||||
NetworkData::Iterator iterator = NetworkData::kIteratorInit;
|
||||
uint16_t rloc16 = Mac::kShortAddrInvalid;
|
||||
|
||||
while (Get<NetworkData::Leader>().GetNextServer(iterator, rloc16) == OT_ERROR_NONE)
|
||||
{
|
||||
if (!IsActiveRouter(rloc16) && RouterIdMatch(GetRloc16(), rloc16) &&
|
||||
mChildTable.FindChild(rloc16, Child::kInStateValid) == NULL)
|
||||
{
|
||||
Get<NetworkData::Leader>().SendServerDataNotification(rloc16);
|
||||
// In Thread 1.1 Specification 5.15.6.1, only one RLOC16 TLV entry may appear in SRV_DATA.ntf.
|
||||
// So break here.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1036,6 +1036,110 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError NetworkData::GetNextServer(Iterator &aIterator, uint16_t &aRloc16)
|
||||
{
|
||||
otError error = OT_ERROR_NOT_FOUND;
|
||||
NetworkDataIterator iterator(aIterator);
|
||||
NetworkDataTlv * cur = reinterpret_cast<NetworkDataTlv *>(mTlvs + iterator.GetTlvOffset());
|
||||
NetworkDataTlv * end = reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength);
|
||||
|
||||
for (; cur < end; cur = cur->GetNext(), iterator.SetSubTlvOffset(0), iterator.SetEntryIndex(0))
|
||||
{
|
||||
NetworkDataTlv *subCur;
|
||||
NetworkDataTlv *subEnd;
|
||||
|
||||
VerifyOrExit((cur + 1) <= end && cur->GetNext() <= end, error = OT_ERROR_PARSE);
|
||||
|
||||
switch (cur->GetType())
|
||||
{
|
||||
case NetworkDataTlv::kTypePrefix:
|
||||
{
|
||||
PrefixTlv *prefix = static_cast<PrefixTlv *>(cur);
|
||||
subCur = reinterpret_cast<NetworkDataTlv *>(reinterpret_cast<uint8_t *>(prefix->GetSubTlvs()) +
|
||||
iterator.GetSubTlvOffset());
|
||||
subEnd = cur->GetNext();
|
||||
|
||||
for (; subCur < subEnd; subCur = subCur->GetNext(), iterator.SetEntryIndex(0))
|
||||
{
|
||||
VerifyOrExit((subCur + 1) <= subEnd && subCur->GetNext() <= subEnd, error = OT_ERROR_PARSE);
|
||||
|
||||
if (subCur->GetType() == NetworkDataTlv::kTypeBorderRouter)
|
||||
{
|
||||
BorderRouterTlv *borderRouter = static_cast<BorderRouterTlv *>(subCur);
|
||||
uint8_t index = iterator.GetEntryIndex();
|
||||
|
||||
if (index < borderRouter->GetNumEntries())
|
||||
{
|
||||
aRloc16 = borderRouter->GetEntry(index)->GetRloc();
|
||||
|
||||
iterator.SaveTlvOffset(cur, mTlvs);
|
||||
iterator.SaveSubTlvOffset(subCur, prefix->GetSubTlvs());
|
||||
iterator.SetEntryIndex(index + 1);
|
||||
|
||||
ExitNow(error = OT_ERROR_NONE);
|
||||
}
|
||||
}
|
||||
else if (subCur->GetType() == NetworkDataTlv::kTypeHasRoute)
|
||||
{
|
||||
HasRouteTlv *hasRoute = static_cast<HasRouteTlv *>(subCur);
|
||||
uint8_t index = iterator.GetEntryIndex();
|
||||
|
||||
if (index < hasRoute->GetNumEntries())
|
||||
{
|
||||
aRloc16 = hasRoute->GetEntry(index)->GetRloc();
|
||||
|
||||
iterator.SaveTlvOffset(cur, mTlvs);
|
||||
iterator.SaveSubTlvOffset(subCur, prefix->GetSubTlvs());
|
||||
iterator.SetEntryIndex(index + 1);
|
||||
|
||||
ExitNow(error = OT_ERROR_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case NetworkDataTlv::kTypeService:
|
||||
{
|
||||
ServiceTlv *service = static_cast<ServiceTlv *>(cur);
|
||||
subCur = reinterpret_cast<NetworkDataTlv *>(reinterpret_cast<uint8_t *>(service->GetSubTlvs()) +
|
||||
iterator.GetSubTlvOffset());
|
||||
subEnd = cur->GetNext();
|
||||
|
||||
for (; subCur < subEnd; subCur = subCur->GetNext())
|
||||
{
|
||||
VerifyOrExit((subCur + 1) <= subEnd && subCur->GetNext() <= subEnd, error = OT_ERROR_PARSE);
|
||||
|
||||
if (subCur->GetType() == NetworkDataTlv::kTypeServer)
|
||||
{
|
||||
ServerTlv *server = static_cast<ServerTlv *>(subCur);
|
||||
aRloc16 = server->GetServer16();
|
||||
|
||||
if (subCur->GetNext() >= cur->GetNext())
|
||||
{
|
||||
iterator.SaveTlvOffset(cur->GetNext(), mTlvs);
|
||||
iterator.SetSubTlvOffset(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
iterator.SaveTlvOffset(cur, mTlvs);
|
||||
iterator.SaveSubTlvOffset(subCur->GetNext(), service->GetSubTlvs());
|
||||
}
|
||||
|
||||
ExitNow(error = OT_ERROR_NONE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void NetworkData::ClearResubmitDelayTimer(void)
|
||||
{
|
||||
mLastAttempt.SetValue(0);
|
||||
|
||||
@@ -304,6 +304,18 @@ public:
|
||||
*/
|
||||
bool ContainsService(uint8_t aServiceId, uint16_t aRloc16);
|
||||
|
||||
/**
|
||||
* This method provides the next server RLOC16 in the Thread Network Data.
|
||||
*
|
||||
* @param[inout] aIterator A reference to the Network Data iterator.
|
||||
* @param[out] aRloc16 The RLOC16 value.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully found the next server.
|
||||
* @retval OT_ERROR_NOT_FOUND No subsequent server exists in the Thread Network Data.
|
||||
*
|
||||
*/
|
||||
otError GetNextServer(Iterator &aIterator, uint16_t &aRloc16);
|
||||
|
||||
/**
|
||||
* This method cancels the data resubmit delay timer.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user