void Local::UpdateRloc(void) { for (NetworkDataTlv *cur = reinterpret_cast<NetworkDataTlv *>(mTlvs); cur < reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength); cur = cur->GetNext()) { switch (cur->GetType()) { case NetworkDataTlv::kTypePrefix: UpdateRloc(*static_cast<PrefixTlv *>(cur)); break; #if OPENTHREAD_ENABLE_SERVICE case NetworkDataTlv::kTypeService: UpdateRloc(*static_cast<ServiceTlv *>(cur)); break; #endif default: assert(false); break; } } ClearResubmitDelayTimer(); }
ContextTlv *NetworkData::FindContext(PrefixTlv &aPrefix) { ContextTlv *rval = NULL; NetworkDataTlv *cur = reinterpret_cast<NetworkDataTlv *>(aPrefix.GetSubTlvs()); NetworkDataTlv *end = reinterpret_cast<NetworkDataTlv *>(aPrefix.GetSubTlvs() + aPrefix.GetSubTlvsLength()); while (cur < end) { if (cur->GetType() == NetworkDataTlv::kTypeContext) { ExitNow(rval = reinterpret_cast<ContextTlv *>(cur)); } cur = cur->GetNext(); } exit: return rval; }
void Local::UpdateRloc(PrefixTlv &aPrefix) { for (NetworkDataTlv *cur = aPrefix.GetSubTlvs(); cur < aPrefix.GetNext(); cur = cur->GetNext()) { switch (cur->GetType()) { case NetworkDataTlv::kTypeHasRoute: UpdateRloc(*static_cast<HasRouteTlv *>(cur)); break; case NetworkDataTlv::kTypeBorderRouter: UpdateRloc(*static_cast<BorderRouterTlv *>(cur)); break; default: assert(false); break; } } }
HasRouteTlv *NetworkData::FindHasRoute(PrefixTlv &aPrefix, bool aStable) { HasRouteTlv *rval = NULL; NetworkDataTlv *cur = reinterpret_cast<NetworkDataTlv *>(aPrefix.GetSubTlvs()); NetworkDataTlv *end = reinterpret_cast<NetworkDataTlv *>(aPrefix.GetSubTlvs() + aPrefix.GetSubTlvsLength()); while (cur < end) { if (cur->GetType() == NetworkDataTlv::kTypeHasRoute && cur->IsStable() == aStable) { ExitNow(rval = reinterpret_cast<HasRouteTlv *>(cur)); } cur = cur->GetNext(); } exit: return rval; }
ThreadError Local::UpdateRloc(void) { for (NetworkDataTlv *cur = reinterpret_cast<NetworkDataTlv *>(mTlvs); cur < reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength); cur = cur->GetNext()) { switch (cur->GetType()) { case NetworkDataTlv::kTypePrefix: UpdateRloc(*reinterpret_cast<PrefixTlv *>(cur)); break; default: assert(false); break; } } return kThreadError_None; }
PrefixTlv *NetworkData::FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, uint8_t *aTlvs, uint8_t aTlvsLength) { NetworkDataTlv *cur = reinterpret_cast<NetworkDataTlv *>(aTlvs); NetworkDataTlv *end = reinterpret_cast<NetworkDataTlv *>(aTlvs + aTlvsLength); PrefixTlv *compare; while (cur < end) { if (cur->GetType() == NetworkDataTlv::kTypePrefix) { compare = reinterpret_cast<PrefixTlv *>(cur); if (compare->GetPrefixLength() == aPrefixLength && PrefixMatch(compare->GetPrefix(), aPrefix, aPrefixLength) >= aPrefixLength) { return compare; } } cur = cur->GetNext(); } return NULL; }
ThreadError Local::UpdateRloc(PrefixTlv &aPrefix) { for (NetworkDataTlv *cur = reinterpret_cast<NetworkDataTlv *>(aPrefix.GetSubTlvs()); cur < reinterpret_cast<NetworkDataTlv *>(aPrefix.GetSubTlvs() + aPrefix.GetSubTlvsLength()); cur = cur->GetNext()) { switch (cur->GetType()) { case NetworkDataTlv::kTypeHasRoute: UpdateRloc(*reinterpret_cast<HasRouteTlv *>(cur)); break; case NetworkDataTlv::kTypeBorderRouter: UpdateRloc(*reinterpret_cast<BorderRouterTlv *>(cur)); break; default: assert(false); break; } } return kThreadError_None; }
void Local::UpdateRloc(ServiceTlv &aService) { for (NetworkDataTlv *cur = aService.GetSubTlvs(); cur < aService.GetNext(); cur = cur->GetNext()) { switch (cur->GetType()) { case NetworkDataTlv::kTypeServer: UpdateRloc(*static_cast<ServerTlv *>(cur)); break; default: assert(false); break; } } }
void NetworkData::RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength) { NetworkDataTlv *cur = reinterpret_cast<NetworkDataTlv *>(aData); NetworkDataTlv *end; PrefixTlv *prefix; uint8_t length; uint8_t *dst; uint8_t *src; while (1) { end = reinterpret_cast<NetworkDataTlv *>(aData + aDataLength); if (cur >= end) { break; } switch (cur->GetType()) { case NetworkDataTlv::kTypePrefix: { prefix = reinterpret_cast<PrefixTlv *>(cur); RemoveTemporaryData(aData, aDataLength, *prefix); if (prefix->GetSubTlvsLength() == 0) { length = sizeof(NetworkDataTlv) + cur->GetLength(); dst = reinterpret_cast<uint8_t *>(cur); src = reinterpret_cast<uint8_t *>(cur->GetNext()); memmove(dst, src, aDataLength - (src - aData)); aDataLength -= length; continue; } otDumpDebgNetData("remove prefix done", mTlvs, mLength); break; } default: { // remove temporary tlv if (!cur->IsStable()) { length = sizeof(NetworkDataTlv) + cur->GetLength(); dst = reinterpret_cast<uint8_t *>(cur); src = reinterpret_cast<uint8_t *>(cur->GetNext()); memmove(dst, src, aDataLength - (src - aData)); aDataLength -= length; continue; } break; } } cur = cur->GetNext(); } otDumpDebgNetData("remove done", aData, aDataLength); }
void NetworkData::RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength, PrefixTlv &aPrefix) { NetworkDataTlv *cur = reinterpret_cast<NetworkDataTlv *>(aPrefix.GetSubTlvs()); NetworkDataTlv *end; BorderRouterTlv *borderRouter; HasRouteTlv *hasRoute; ContextTlv *context; BorderRouterEntry *borderRouterEntry; HasRouteEntry *hasRouteEntry; uint8_t length; uint8_t contextId; uint8_t *dst; uint8_t *src; while (1) { end = reinterpret_cast<NetworkDataTlv *>(aPrefix.GetSubTlvs() + aPrefix.GetSubTlvsLength()); if (cur >= end) { break; } if (cur->IsStable()) { switch (cur->GetType()) { case NetworkDataTlv::kTypeBorderRouter: { borderRouter = FindBorderRouter(aPrefix); if ((context = FindContext(aPrefix)) == NULL) { break; } contextId = context->GetContextId(); // replace p_border_router_16 for (int i = 0; i < borderRouter->GetNumEntries(); i++) { borderRouterEntry = borderRouter->GetEntry(i); if (borderRouterEntry->IsDhcp() || borderRouterEntry->IsConfigure()) { borderRouterEntry->SetRloc(0xfc00 | contextId); } else { borderRouterEntry->SetRloc(0xfffe); } } break; } case NetworkDataTlv::kTypeHasRoute: { hasRoute = FindHasRoute(aPrefix); // replace r_border_router_16 for (int j = 0; j < hasRoute->GetNumEntries(); j++) { hasRouteEntry = hasRoute->GetEntry(j); hasRouteEntry->SetRloc(0xfffe); } break; } default: { break; } } // keep stable tlv cur = cur->GetNext(); } else { // remove temporary tlv length = sizeof(NetworkDataTlv) + cur->GetLength(); dst = reinterpret_cast<uint8_t *>(cur); src = reinterpret_cast<uint8_t *>(cur->GetNext()); memmove(dst, src, aDataLength - (src - aData)); aPrefix.SetSubTlvsLength(aPrefix.GetSubTlvsLength() - length); aDataLength -= length; } } }