otError Local::AddOnMeshPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, int8_t aPrf, uint8_t aFlags, bool aStable) { otError error = OT_ERROR_NONE; uint8_t prefixLengthBytes = BitVectorBytes(aPrefixLength); uint8_t appendLength; PrefixTlv * prefixTlv; BorderRouterTlv *brTlv; VerifyOrExit(prefixLengthBytes <= sizeof(Ip6::Address), error = OT_ERROR_INVALID_ARGS); VerifyOrExit((aPrf == OT_ROUTE_PREFERENCE_LOW) || (aPrf == OT_ROUTE_PREFERENCE_MED) || (aPrf == OT_ROUTE_PREFERENCE_HIGH), error = OT_ERROR_INVALID_ARGS); VerifyOrExit(Ip6::Address::PrefixMatch(aPrefix, Get<Mle::MleRouter>().GetMeshLocalPrefix().m8, prefixLengthBytes) < Ip6::Address::kMeshLocalPrefixLength, error = OT_ERROR_INVALID_ARGS); RemoveOnMeshPrefix(aPrefix, aPrefixLength); appendLength = sizeof(PrefixTlv) + prefixLengthBytes + sizeof(BorderRouterTlv) + sizeof(BorderRouterEntry); VerifyOrExit(mLength + appendLength <= sizeof(mTlvs), error = OT_ERROR_NO_BUFS); prefixTlv = reinterpret_cast<PrefixTlv *>(mTlvs + mLength); Insert(reinterpret_cast<uint8_t *>(prefixTlv), appendLength); prefixTlv->Init(0, aPrefixLength, aPrefix); prefixTlv->SetSubTlvsLength(sizeof(BorderRouterTlv) + sizeof(BorderRouterEntry)); brTlv = static_cast<BorderRouterTlv *>(prefixTlv->GetSubTlvs()); brTlv->Init(); brTlv->SetLength(brTlv->GetLength() + sizeof(BorderRouterEntry)); brTlv->GetEntry(0)->Init(); brTlv->GetEntry(0)->SetPreference(aPrf); brTlv->GetEntry(0)->SetFlags(aFlags); if (aStable) { prefixTlv->SetStable(); brTlv->SetStable(); } ClearResubmitDelayTimer(); otDumpDebgNetData("add prefix done", mTlvs, mLength); exit: return error; }
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; } } }
void Local::UpdateRloc(BorderRouterTlv &aBorderRouter) { BorderRouterEntry *entry = aBorderRouter.GetEntry(0); entry->SetRloc(Get<Mle::MleRouter>().GetRloc16()); }
ThreadError Local::UpdateRloc(BorderRouterTlv &aBorderRouter) { BorderRouterEntry *entry = aBorderRouter.GetEntry(0); entry->SetRloc(mMle.GetRloc16()); return kThreadError_None; }