mirror of
https://github.com/espressif/openthread.git
synced 2026-10-02 13:57:38 +00:00
[network-data] define and use a common Iterate method for all entry types (#4830)
This commit adds a common private `Iterate()` method which is used by other methods iterating over different types of entries: `GetNextOnMeshPrefix()`, `GetNextExternalRoute()`, `GetNextService()`, and `GetNextServer()`. It also adds methods to help advancing the iterator to next TLV or sub-TLV or entry index.
This commit is contained in:
+199
-200
@@ -104,67 +104,6 @@ exit:
|
|||||||
return tlv;
|
return tlv;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NetworkDataTlv *NetworkData::FindTlv(NetworkDataIterator &aIterator, NetworkDataTlv::Type aTlvType) const
|
|
||||||
{
|
|
||||||
const NetworkDataTlv *start = aIterator.GetTlv(mTlvs);
|
|
||||||
const NetworkDataTlv *tlv;
|
|
||||||
|
|
||||||
tlv = FindTlv(start, GetTlvsEnd(), aTlvType);
|
|
||||||
VerifyOrExit(tlv != NULL);
|
|
||||||
|
|
||||||
if (tlv != start)
|
|
||||||
{
|
|
||||||
aIterator.SaveTlvOffset(tlv, mTlvs);
|
|
||||||
aIterator.SetSubTlvOffset(0);
|
|
||||||
aIterator.SetEntryIndex(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit:
|
|
||||||
return tlv;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkData::IterateToNextTlv(NetworkDataIterator &aIterator) const
|
|
||||||
{
|
|
||||||
const NetworkDataTlv *tlv = aIterator.GetTlv(mTlvs);
|
|
||||||
|
|
||||||
tlv = tlv->GetNext();
|
|
||||||
|
|
||||||
aIterator.SaveTlvOffset(tlv, mTlvs);
|
|
||||||
aIterator.SetSubTlvOffset(0);
|
|
||||||
aIterator.SetEntryIndex(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
const NetworkDataTlv *NetworkData::FindSubTlv(NetworkDataIterator & aIterator,
|
|
||||||
NetworkDataTlv::Type aSubTlvType,
|
|
||||||
const NetworkDataTlv *aSubTlvs,
|
|
||||||
const NetworkDataTlv *aSubTlvsEnd) const
|
|
||||||
{
|
|
||||||
const NetworkDataTlv *subStart = aIterator.GetSubTlv(aSubTlvs);
|
|
||||||
const NetworkDataTlv *subTlv;
|
|
||||||
|
|
||||||
subTlv = FindTlv(subStart, aSubTlvsEnd, aSubTlvType);
|
|
||||||
VerifyOrExit(subTlv != NULL);
|
|
||||||
|
|
||||||
if (subTlv != subStart)
|
|
||||||
{
|
|
||||||
aIterator.SaveSubTlvOffset(subTlv, aSubTlvs);
|
|
||||||
aIterator.SetEntryIndex(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit:
|
|
||||||
return subTlv;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkData::IterateToNextSubTlv(NetworkDataIterator &aIterator, const NetworkDataTlv *aSubTlvs) const
|
|
||||||
{
|
|
||||||
const NetworkDataTlv *subTlv = aIterator.GetSubTlv(aSubTlvs);
|
|
||||||
|
|
||||||
subTlv = subTlv->GetNext();
|
|
||||||
|
|
||||||
aIterator.SaveSubTlvOffset(subTlv, aSubTlvs);
|
|
||||||
aIterator.SetEntryIndex(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
otError NetworkData::GetNetworkData(bool aStable, uint8_t *aData, uint8_t &aDataLength) const
|
otError NetworkData::GetNetworkData(bool aStable, uint8_t *aData, uint8_t &aDataLength) const
|
||||||
{
|
{
|
||||||
otError error = OT_ERROR_NONE;
|
otError error = OT_ERROR_NONE;
|
||||||
@@ -191,46 +130,13 @@ otError NetworkData::GetNextOnMeshPrefix(Iterator &aIterator, OnMeshPrefixConfig
|
|||||||
|
|
||||||
otError NetworkData::GetNextOnMeshPrefix(Iterator &aIterator, uint16_t aRloc16, OnMeshPrefixConfig &aConfig) const
|
otError NetworkData::GetNextOnMeshPrefix(Iterator &aIterator, uint16_t aRloc16, OnMeshPrefixConfig &aConfig) const
|
||||||
{
|
{
|
||||||
otError error = OT_ERROR_NOT_FOUND;
|
Config config;
|
||||||
NetworkDataIterator iterator(aIterator);
|
|
||||||
|
|
||||||
for (const PrefixTlv *prefix; (prefix = FindTlv<PrefixTlv>(iterator)) != NULL; IterateToNextTlv(iterator))
|
config.mOnMeshPrefix = &aConfig;
|
||||||
{
|
config.mExternalRoute = NULL;
|
||||||
for (const BorderRouterTlv *borderRouter;
|
config.mService = NULL;
|
||||||
(borderRouter = FindSubTlv<BorderRouterTlv>(iterator, prefix->GetSubTlvs(), prefix->GetNext())) != NULL;
|
|
||||||
IterateToNextSubTlv(iterator, prefix->GetSubTlvs()))
|
|
||||||
{
|
|
||||||
for (uint8_t index = iterator.GetEntryIndex(); index < borderRouter->GetNumEntries(); index++)
|
|
||||||
{
|
|
||||||
if (aRloc16 == Mac::kShortAddrBroadcast || borderRouter->GetEntry(index)->GetRloc() == aRloc16)
|
|
||||||
{
|
|
||||||
const BorderRouterEntry *borderRouterEntry = borderRouter->GetEntry(index);
|
|
||||||
|
|
||||||
memset(&aConfig, 0, sizeof(aConfig));
|
return Iterate(aIterator, aRloc16, config);
|
||||||
memcpy(&aConfig.mPrefix.mPrefix, prefix->GetPrefix(), BitVectorBytes(prefix->GetPrefixLength()));
|
|
||||||
aConfig.mPrefix.mLength = prefix->GetPrefixLength();
|
|
||||||
aConfig.mPreference = borderRouterEntry->GetPreference();
|
|
||||||
aConfig.mPreferred = borderRouterEntry->IsPreferred();
|
|
||||||
aConfig.mSlaac = borderRouterEntry->IsSlaac();
|
|
||||||
aConfig.mDhcp = borderRouterEntry->IsDhcp();
|
|
||||||
aConfig.mConfigure = borderRouterEntry->IsConfigure();
|
|
||||||
aConfig.mDefaultRoute = borderRouterEntry->IsDefaultRoute();
|
|
||||||
aConfig.mOnMesh = borderRouterEntry->IsOnMesh();
|
|
||||||
aConfig.mStable = borderRouter->IsStable();
|
|
||||||
aConfig.mRloc16 = borderRouterEntry->GetRloc();
|
|
||||||
aConfig.mNdDns = borderRouterEntry->IsNdDns();
|
|
||||||
aConfig.mDp = borderRouterEntry->IsDp();
|
|
||||||
|
|
||||||
iterator.SetEntryIndex(index + 1);
|
|
||||||
|
|
||||||
ExitNow(error = OT_ERROR_NONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exit:
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
otError NetworkData::GetNextExternalRoute(Iterator &aIterator, ExternalRouteConfig &aConfig) const
|
otError NetworkData::GetNextExternalRoute(Iterator &aIterator, ExternalRouteConfig &aConfig) const
|
||||||
@@ -240,39 +146,13 @@ otError NetworkData::GetNextExternalRoute(Iterator &aIterator, ExternalRouteConf
|
|||||||
|
|
||||||
otError NetworkData::GetNextExternalRoute(Iterator &aIterator, uint16_t aRloc16, ExternalRouteConfig &aConfig) const
|
otError NetworkData::GetNextExternalRoute(Iterator &aIterator, uint16_t aRloc16, ExternalRouteConfig &aConfig) const
|
||||||
{
|
{
|
||||||
otError error = OT_ERROR_NOT_FOUND;
|
Config config;
|
||||||
NetworkDataIterator iterator(aIterator);
|
|
||||||
|
|
||||||
for (const PrefixTlv *prefix; (prefix = FindTlv<PrefixTlv>(iterator)) != NULL; IterateToNextTlv(iterator))
|
config.mOnMeshPrefix = NULL;
|
||||||
{
|
config.mExternalRoute = &aConfig;
|
||||||
for (const HasRouteTlv *hasRoute;
|
config.mService = NULL;
|
||||||
(hasRoute = FindSubTlv<HasRouteTlv>(iterator, prefix->GetSubTlvs(), prefix->GetNext())) != NULL;
|
|
||||||
IterateToNextSubTlv(iterator, prefix->GetSubTlvs()))
|
|
||||||
{
|
|
||||||
for (uint8_t index = iterator.GetEntryIndex(); index < hasRoute->GetNumEntries(); index++)
|
|
||||||
{
|
|
||||||
if (aRloc16 == Mac::kShortAddrBroadcast || hasRoute->GetEntry(index)->GetRloc() == aRloc16)
|
|
||||||
{
|
|
||||||
const HasRouteEntry *hasRouteEntry = hasRoute->GetEntry(index);
|
|
||||||
|
|
||||||
memset(&aConfig, 0, sizeof(aConfig));
|
return Iterate(aIterator, aRloc16, config);
|
||||||
memcpy(&aConfig.mPrefix.mPrefix, prefix->GetPrefix(), BitVectorBytes(prefix->GetPrefixLength()));
|
|
||||||
aConfig.mPrefix.mLength = prefix->GetPrefixLength();
|
|
||||||
aConfig.mPreference = hasRouteEntry->GetPreference();
|
|
||||||
aConfig.mStable = hasRoute->IsStable();
|
|
||||||
aConfig.mRloc16 = hasRouteEntry->GetRloc();
|
|
||||||
aConfig.mNextHopIsThisDevice = (hasRouteEntry->GetRloc() == Get<Mle::MleRouter>().GetRloc16());
|
|
||||||
|
|
||||||
iterator.SetEntryIndex(index + 1);
|
|
||||||
|
|
||||||
ExitNow(error = OT_ERROR_NONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exit:
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
otError NetworkData::GetNextService(Iterator &aIterator, ServiceConfig &aConfig) const
|
otError NetworkData::GetNextService(Iterator &aIterator, ServiceConfig &aConfig) const
|
||||||
@@ -282,38 +162,183 @@ otError NetworkData::GetNextService(Iterator &aIterator, ServiceConfig &aConfig)
|
|||||||
|
|
||||||
otError NetworkData::GetNextService(Iterator &aIterator, uint16_t aRloc16, ServiceConfig &aConfig) const
|
otError NetworkData::GetNextService(Iterator &aIterator, uint16_t aRloc16, ServiceConfig &aConfig) const
|
||||||
{
|
{
|
||||||
|
Config config;
|
||||||
|
|
||||||
|
config.mOnMeshPrefix = NULL;
|
||||||
|
config.mExternalRoute = NULL;
|
||||||
|
config.mService = &aConfig;
|
||||||
|
|
||||||
|
return Iterate(aIterator, aRloc16, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
otError NetworkData::Iterate(Iterator &aIterator, uint16_t aRloc16, Config &aConfig) const
|
||||||
|
{
|
||||||
|
// Iterate to the next entry in Network Data matching `aRloc16`
|
||||||
|
// (can be set to `Mac::kShortAddrBroadcast` to allow any RLOC).
|
||||||
|
// The `aIterator` is used to track and save the current position.
|
||||||
|
// On input, the non-NULL pointer members in `aConfig` specify the
|
||||||
|
// Network Data entry types (`mOnMeshPrefix`, `mExternalRoute`,
|
||||||
|
// `mService`) to iterate over. On successful exit, the `aConfig`
|
||||||
|
// is updated such that only one member pointer is not NULL
|
||||||
|
// indicating the type of entry and the non-NULL config is updated
|
||||||
|
// with the entry info.
|
||||||
|
|
||||||
otError error = OT_ERROR_NOT_FOUND;
|
otError error = OT_ERROR_NOT_FOUND;
|
||||||
NetworkDataIterator iterator(aIterator);
|
NetworkDataIterator iterator(aIterator);
|
||||||
|
|
||||||
for (const ServiceTlv *service; (service = FindTlv<ServiceTlv>(iterator)) != NULL; IterateToNextTlv(iterator))
|
for (const NetworkDataTlv *cur; (cur = iterator.GetTlv(mTlvs)) < GetTlvsEnd(); iterator.AdvanceTlv(mTlvs))
|
||||||
{
|
{
|
||||||
for (const ServerTlv *server;
|
const NetworkDataTlv *subTlvs = NULL;
|
||||||
(server = FindSubTlv<ServerTlv>(iterator, service->GetSubTlvs(), service->GetNext())) != NULL;
|
|
||||||
IterateToNextSubTlv(iterator, service->GetSubTlvs()))
|
switch (cur->GetType())
|
||||||
{
|
{
|
||||||
if (!iterator.IsNewEntry())
|
case NetworkDataTlv::kTypePrefix:
|
||||||
|
if ((aConfig.mOnMeshPrefix != NULL) || (aConfig.mExternalRoute != NULL))
|
||||||
{
|
{
|
||||||
continue;
|
subTlvs = static_cast<const PrefixTlv *>(cur)->GetSubTlvs();
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
if ((aRloc16 == Mac::kShortAddrBroadcast) || (server->GetServer16() == aRloc16))
|
case NetworkDataTlv::kTypeService:
|
||||||
|
if (aConfig.mService != NULL)
|
||||||
{
|
{
|
||||||
memset(&aConfig, 0, sizeof(aConfig));
|
subTlvs = static_cast<const ServiceTlv *>(cur)->GetSubTlvs();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
aConfig.mServiceId = service->GetServiceId();
|
if (subTlvs == NULL)
|
||||||
aConfig.mEnterpriseNumber = service->GetEnterpriseNumber();
|
{
|
||||||
aConfig.mServiceDataLength = service->GetServiceDataLength();
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(&aConfig.mServiceData, service->GetServiceData(), service->GetServiceDataLength());
|
for (const NetworkDataTlv *subCur; (subCur = iterator.GetSubTlv(subTlvs)) < cur->GetNext();
|
||||||
|
iterator.AdvaceSubTlv(subTlvs))
|
||||||
|
{
|
||||||
|
if (cur->GetType() == NetworkDataTlv::kTypePrefix)
|
||||||
|
{
|
||||||
|
const PrefixTlv *prefix = static_cast<const PrefixTlv *>(cur);
|
||||||
|
|
||||||
aConfig.mServerConfig.mStable = server->IsStable();
|
switch (subCur->GetType())
|
||||||
aConfig.mServerConfig.mServerDataLength = server->GetServerDataLength();
|
{
|
||||||
memcpy(&aConfig.mServerConfig.mServerData, server->GetServerData(), server->GetServerDataLength());
|
case NetworkDataTlv::kTypeBorderRouter:
|
||||||
aConfig.mServerConfig.mRloc16 = server->GetServer16();
|
{
|
||||||
|
const BorderRouterTlv *borderRouter = static_cast<const BorderRouterTlv *>(subCur);
|
||||||
|
|
||||||
iterator.MarkEntryAsNotNew();
|
if (aConfig.mOnMeshPrefix == NULL)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ExitNow(error = OT_ERROR_NONE);
|
for (uint8_t index; (index = iterator.GetAndAdvanceIndex()) < borderRouter->GetNumEntries();)
|
||||||
|
{
|
||||||
|
if (aRloc16 == Mac::kShortAddrBroadcast || borderRouter->GetEntry(index)->GetRloc() == aRloc16)
|
||||||
|
{
|
||||||
|
const BorderRouterEntry *borderRouterEntry = borderRouter->GetEntry(index);
|
||||||
|
|
||||||
|
aConfig.mExternalRoute = NULL;
|
||||||
|
aConfig.mService = NULL;
|
||||||
|
memset(aConfig.mOnMeshPrefix, 0, sizeof(OnMeshPrefixConfig));
|
||||||
|
|
||||||
|
memcpy(&aConfig.mOnMeshPrefix->mPrefix.mPrefix, prefix->GetPrefix(),
|
||||||
|
BitVectorBytes(prefix->GetPrefixLength()));
|
||||||
|
aConfig.mOnMeshPrefix->mPrefix.mLength = prefix->GetPrefixLength();
|
||||||
|
aConfig.mOnMeshPrefix->mPreference = borderRouterEntry->GetPreference();
|
||||||
|
aConfig.mOnMeshPrefix->mPreferred = borderRouterEntry->IsPreferred();
|
||||||
|
aConfig.mOnMeshPrefix->mSlaac = borderRouterEntry->IsSlaac();
|
||||||
|
aConfig.mOnMeshPrefix->mDhcp = borderRouterEntry->IsDhcp();
|
||||||
|
aConfig.mOnMeshPrefix->mConfigure = borderRouterEntry->IsConfigure();
|
||||||
|
aConfig.mOnMeshPrefix->mDefaultRoute = borderRouterEntry->IsDefaultRoute();
|
||||||
|
aConfig.mOnMeshPrefix->mOnMesh = borderRouterEntry->IsOnMesh();
|
||||||
|
aConfig.mOnMeshPrefix->mStable = borderRouter->IsStable();
|
||||||
|
aConfig.mOnMeshPrefix->mRloc16 = borderRouterEntry->GetRloc();
|
||||||
|
aConfig.mOnMeshPrefix->mNdDns = borderRouterEntry->IsNdDns();
|
||||||
|
aConfig.mOnMeshPrefix->mDp = borderRouterEntry->IsDp();
|
||||||
|
|
||||||
|
ExitNow(error = OT_ERROR_NONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NetworkDataTlv::kTypeHasRoute:
|
||||||
|
{
|
||||||
|
const HasRouteTlv *hasRoute = static_cast<const HasRouteTlv *>(subCur);
|
||||||
|
|
||||||
|
if (aConfig.mExternalRoute == NULL)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t index; (index = iterator.GetAndAdvanceIndex()) < hasRoute->GetNumEntries();)
|
||||||
|
{
|
||||||
|
if (aRloc16 == Mac::kShortAddrBroadcast || hasRoute->GetEntry(index)->GetRloc() == aRloc16)
|
||||||
|
{
|
||||||
|
const HasRouteEntry *hasRouteEntry = hasRoute->GetEntry(index);
|
||||||
|
|
||||||
|
aConfig.mOnMeshPrefix = NULL;
|
||||||
|
aConfig.mService = NULL;
|
||||||
|
memset(aConfig.mExternalRoute, 0, sizeof(ExternalRouteConfig));
|
||||||
|
|
||||||
|
memcpy(&aConfig.mExternalRoute->mPrefix.mPrefix, prefix->GetPrefix(),
|
||||||
|
BitVectorBytes(prefix->GetPrefixLength()));
|
||||||
|
aConfig.mExternalRoute->mPrefix.mLength = prefix->GetPrefixLength();
|
||||||
|
aConfig.mExternalRoute->mPreference = hasRouteEntry->GetPreference();
|
||||||
|
aConfig.mExternalRoute->mStable = hasRoute->IsStable();
|
||||||
|
aConfig.mExternalRoute->mRloc16 = hasRouteEntry->GetRloc();
|
||||||
|
aConfig.mExternalRoute->mNextHopIsThisDevice =
|
||||||
|
(hasRouteEntry->GetRloc() == Get<Mle::MleRouter>().GetRloc16());
|
||||||
|
|
||||||
|
ExitNow(error = OT_ERROR_NONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // cur is `ServiceTLv`
|
||||||
|
{
|
||||||
|
const ServiceTlv *service = static_cast<const ServiceTlv *>(cur);
|
||||||
|
|
||||||
|
if (subCur->GetType() == NetworkDataTlv::kTypeServer)
|
||||||
|
{
|
||||||
|
const ServerTlv *server = static_cast<const ServerTlv *>(subCur);
|
||||||
|
|
||||||
|
if (!iterator.IsNewEntry())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((aRloc16 == Mac::kShortAddrBroadcast) || (server->GetServer16() == aRloc16))
|
||||||
|
{
|
||||||
|
aConfig.mOnMeshPrefix = NULL;
|
||||||
|
aConfig.mExternalRoute = NULL;
|
||||||
|
memset(aConfig.mService, 0, sizeof(ServiceConfig));
|
||||||
|
|
||||||
|
aConfig.mService->mServiceId = service->GetServiceId();
|
||||||
|
aConfig.mService->mEnterpriseNumber = service->GetEnterpriseNumber();
|
||||||
|
aConfig.mService->mServiceDataLength = service->GetServiceDataLength();
|
||||||
|
|
||||||
|
memcpy(&aConfig.mService->mServiceData, service->GetServiceData(),
|
||||||
|
service->GetServiceDataLength());
|
||||||
|
|
||||||
|
aConfig.mService->mServerConfig.mStable = server->IsStable();
|
||||||
|
aConfig.mService->mServerConfig.mServerDataLength = server->GetServerDataLength();
|
||||||
|
memcpy(&aConfig.mService->mServerConfig.mServerData, server->GetServerData(),
|
||||||
|
server->GetServerDataLength());
|
||||||
|
aConfig.mService->mServerConfig.mRloc16 = server->GetServer16();
|
||||||
|
|
||||||
|
iterator.MarkEntryAsNotNew();
|
||||||
|
|
||||||
|
ExitNow(error = OT_ERROR_NONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -804,59 +829,33 @@ exit:
|
|||||||
|
|
||||||
otError NetworkData::GetNextServer(Iterator &aIterator, uint16_t &aRloc16) const
|
otError NetworkData::GetNextServer(Iterator &aIterator, uint16_t &aRloc16) const
|
||||||
{
|
{
|
||||||
otError error = OT_ERROR_NONE;
|
otError error;
|
||||||
NetworkDataIterator iterator(aIterator);
|
OnMeshPrefixConfig prefixConfig;
|
||||||
|
ExternalRouteConfig routeConfig;
|
||||||
|
ServiceConfig serviceConfig;
|
||||||
|
Config config;
|
||||||
|
|
||||||
while (true)
|
config.mOnMeshPrefix = &prefixConfig;
|
||||||
|
config.mExternalRoute = &routeConfig;
|
||||||
|
config.mService = &serviceConfig;
|
||||||
|
|
||||||
|
SuccessOrExit(error = Iterate(aIterator, Mac::kShortAddrBroadcast, config));
|
||||||
|
|
||||||
|
if (config.mOnMeshPrefix != NULL)
|
||||||
{
|
{
|
||||||
switch (iterator.GetType())
|
aRloc16 = config.mOnMeshPrefix->mRloc16;
|
||||||
{
|
}
|
||||||
case NetworkDataIterator::kTypeOnMeshPrefix:
|
else if (config.mExternalRoute != NULL)
|
||||||
{
|
{
|
||||||
OnMeshPrefixConfig prefixConfig;
|
aRloc16 = config.mExternalRoute->mRloc16;
|
||||||
|
}
|
||||||
if (GetNextOnMeshPrefix(aIterator, prefixConfig) == OT_ERROR_NONE)
|
else if (config.mService != NULL)
|
||||||
{
|
{
|
||||||
aRloc16 = prefixConfig.mRloc16;
|
aRloc16 = config.mService->mServerConfig.mRloc16;
|
||||||
ExitNow();
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
iterator.SetType(NetworkDataIterator::kTypeExternalRoute);
|
OT_ASSERT(false);
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case NetworkDataIterator::kTypeExternalRoute:
|
|
||||||
{
|
|
||||||
ExternalRouteConfig routeConfig;
|
|
||||||
|
|
||||||
if (GetNextExternalRoute(aIterator, routeConfig) == OT_ERROR_NONE)
|
|
||||||
{
|
|
||||||
aRloc16 = routeConfig.mRloc16;
|
|
||||||
ExitNow();
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator.SetType(NetworkDataIterator::kTypeService);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case NetworkDataIterator::kTypeService:
|
|
||||||
{
|
|
||||||
ServiceConfig serviceConfig;
|
|
||||||
|
|
||||||
if (GetNextService(aIterator, serviceConfig) == OT_ERROR_NONE)
|
|
||||||
{
|
|
||||||
aRloc16 = serviceConfig.mServerConfig.mRloc16;
|
|
||||||
ExitNow();
|
|
||||||
}
|
|
||||||
|
|
||||||
ExitNow(error = OT_ERROR_NOT_FOUND);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset the iterator for next type.
|
|
||||||
iterator.SetTlvOffset(0);
|
|
||||||
iterator.SetSubTlvOffset(0);
|
|
||||||
iterator.SetEntryIndex(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
|||||||
@@ -830,41 +830,55 @@ private:
|
|||||||
class NetworkDataIterator
|
class NetworkDataIterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Type
|
|
||||||
{
|
|
||||||
kTypeOnMeshPrefix = 0,
|
|
||||||
kTypeExternalRoute = 1,
|
|
||||||
kTypeService = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit NetworkDataIterator(Iterator &aIterator)
|
explicit NetworkDataIterator(Iterator &aIterator)
|
||||||
: mIteratorBuffer(reinterpret_cast<uint8_t *>(&aIterator))
|
: mIteratorBuffer(reinterpret_cast<uint8_t *>(&aIterator))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t GetTlvOffset(void) const { return mIteratorBuffer[kTlvPosition]; }
|
|
||||||
uint8_t GetSubTlvOffset(void) const { return mIteratorBuffer[kSubTlvPosition]; }
|
|
||||||
uint8_t GetEntryIndex(void) const { return mIteratorBuffer[kEntryPosition]; }
|
|
||||||
Type GetType(void) const { return static_cast<Type>(mIteratorBuffer[kTypePosition]); }
|
|
||||||
void SetTlvOffset(uint8_t aOffset) { mIteratorBuffer[kTlvPosition] = aOffset; }
|
|
||||||
void SetSubTlvOffset(uint8_t aOffset) { mIteratorBuffer[kSubTlvPosition] = aOffset; }
|
|
||||||
void SetEntryIndex(uint8_t aIndex) { mIteratorBuffer[kEntryPosition] = aIndex; }
|
|
||||||
void SetType(Type aType) { mIteratorBuffer[kTypePosition] = static_cast<uint8_t>(aType); }
|
|
||||||
|
|
||||||
bool IsNewEntry(void) const { return GetEntryIndex() == 0; }
|
|
||||||
void MarkEntryAsNotNew(void) { SetEntryIndex(1); }
|
|
||||||
|
|
||||||
const NetworkDataTlv *GetTlv(const uint8_t *aTlvs) const
|
const NetworkDataTlv *GetTlv(const uint8_t *aTlvs) const
|
||||||
{
|
{
|
||||||
return reinterpret_cast<const NetworkDataTlv *>(aTlvs + GetTlvOffset());
|
return reinterpret_cast<const NetworkDataTlv *>(aTlvs + GetTlvOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AdvanceTlv(const uint8_t *aTlvs)
|
||||||
|
{
|
||||||
|
SaveTlvOffset(GetTlv(aTlvs)->GetNext(), aTlvs);
|
||||||
|
SetSubTlvOffset(0);
|
||||||
|
SetEntryIndex(0);
|
||||||
|
}
|
||||||
|
|
||||||
const NetworkDataTlv *GetSubTlv(const NetworkDataTlv *aSubTlvs) const
|
const NetworkDataTlv *GetSubTlv(const NetworkDataTlv *aSubTlvs) const
|
||||||
{
|
{
|
||||||
return reinterpret_cast<const NetworkDataTlv *>(reinterpret_cast<const uint8_t *>(aSubTlvs) +
|
return reinterpret_cast<const NetworkDataTlv *>(reinterpret_cast<const uint8_t *>(aSubTlvs) +
|
||||||
GetSubTlvOffset());
|
GetSubTlvOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AdvaceSubTlv(const NetworkDataTlv *aSubTlvs)
|
||||||
|
{
|
||||||
|
SaveSubTlvOffset(GetSubTlv(aSubTlvs)->GetNext(), aSubTlvs);
|
||||||
|
SetEntryIndex(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t GetAndAdvanceIndex(void) { return mIteratorBuffer[kEntryPosition]++; }
|
||||||
|
|
||||||
|
bool IsNewEntry(void) const { return GetEntryIndex() == 0; }
|
||||||
|
void MarkEntryAsNotNew(void) { SetEntryIndex(1); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
kTlvPosition = 0,
|
||||||
|
kSubTlvPosition = 1,
|
||||||
|
kEntryPosition = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t GetTlvOffset(void) const { return mIteratorBuffer[kTlvPosition]; }
|
||||||
|
uint8_t GetSubTlvOffset(void) const { return mIteratorBuffer[kSubTlvPosition]; }
|
||||||
|
void SetSubTlvOffset(uint8_t aOffset) { mIteratorBuffer[kSubTlvPosition] = aOffset; }
|
||||||
|
void SetTlvOffset(uint8_t aOffset) { mIteratorBuffer[kTlvPosition] = aOffset; }
|
||||||
|
uint8_t GetEntryIndex(void) const { return mIteratorBuffer[kEntryPosition]; }
|
||||||
|
void SetEntryIndex(uint8_t aIndex) { mIteratorBuffer[kEntryPosition] = aIndex; }
|
||||||
|
|
||||||
void SaveTlvOffset(const NetworkDataTlv *aTlv, const uint8_t *aTlvs)
|
void SaveTlvOffset(const NetworkDataTlv *aTlv, const uint8_t *aTlvs)
|
||||||
{
|
{
|
||||||
SetTlvOffset(static_cast<uint8_t>(reinterpret_cast<const uint8_t *>(aTlv) - aTlvs));
|
SetTlvOffset(static_cast<uint8_t>(reinterpret_cast<const uint8_t *>(aTlv) - aTlvs));
|
||||||
@@ -876,46 +890,24 @@ private:
|
|||||||
reinterpret_cast<const uint8_t *>(aSubTlvs)));
|
reinterpret_cast<const uint8_t *>(aSubTlvs)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
kTlvPosition = 0,
|
|
||||||
kSubTlvPosition = 1,
|
|
||||||
kEntryPosition = 2,
|
|
||||||
kTypePosition = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
uint8_t *mIteratorBuffer;
|
uint8_t *mIteratorBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Config
|
||||||
|
{
|
||||||
|
OnMeshPrefixConfig * mOnMeshPrefix;
|
||||||
|
ExternalRouteConfig *mExternalRoute;
|
||||||
|
ServiceConfig * mService;
|
||||||
|
};
|
||||||
|
|
||||||
|
otError Iterate(Iterator &aIterator, uint16_t aRloc16, Config &aConfig) const;
|
||||||
|
|
||||||
static void RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength, PrefixTlv &aPrefix);
|
static void RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength, PrefixTlv &aPrefix);
|
||||||
static void RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength, ServiceTlv &aService);
|
static void RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength, ServiceTlv &aService);
|
||||||
|
|
||||||
static void Remove(uint8_t *aData, uint8_t &aDataLength, uint8_t *aRemoveStart, uint8_t aRemoveLength);
|
static void Remove(uint8_t *aData, uint8_t &aDataLength, uint8_t *aRemoveStart, uint8_t aRemoveLength);
|
||||||
static void RemoveTlv(uint8_t *aData, uint8_t &aDataLength, NetworkDataTlv *aTlv);
|
static void RemoveTlv(uint8_t *aData, uint8_t &aDataLength, NetworkDataTlv *aTlv);
|
||||||
|
|
||||||
const NetworkDataTlv *FindTlv(NetworkDataIterator &aIterator, NetworkDataTlv::Type aTlvType) const;
|
|
||||||
void IterateToNextTlv(NetworkDataIterator &aIterator) const;
|
|
||||||
const NetworkDataTlv *FindSubTlv(NetworkDataIterator & aIterator,
|
|
||||||
NetworkDataTlv::Type aSubTlvType,
|
|
||||||
const NetworkDataTlv *aSubTlvs,
|
|
||||||
const NetworkDataTlv *aSubTlvsEnd) const;
|
|
||||||
void IterateToNextSubTlv(NetworkDataIterator &aIterator, const NetworkDataTlv *aSubTlvs) const;
|
|
||||||
|
|
||||||
template <typename TlvType> const TlvType *FindTlv(NetworkDataIterator &aIterator) const
|
|
||||||
{
|
|
||||||
return static_cast<const TlvType *>(FindTlv(aIterator, static_cast<NetworkDataTlv::Type>(TlvType::kType)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TlvType>
|
|
||||||
const TlvType *FindSubTlv(NetworkDataIterator & aIterator,
|
|
||||||
const NetworkDataTlv *aSubTlvs,
|
|
||||||
const NetworkDataTlv *aSubTlvsEnd) const
|
|
||||||
{
|
|
||||||
return static_cast<const TlvType *>(
|
|
||||||
FindSubTlv(aIterator, static_cast<NetworkDataTlv::Type>(TlvType::kType), aSubTlvs, aSubTlvsEnd));
|
|
||||||
}
|
|
||||||
|
|
||||||
const Type mType;
|
const Type mType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user