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(); }
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; } } }
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; } } }
ThreadError Local::Register(const Ip6::Address &aDestination) { ThreadError error = kThreadError_None; Coap::Header header; Message *message; Ip6::MessageInfo messageInfo; UpdateRloc(); mSocket.Open(&HandleUdpReceive, this); for (size_t i = 0; i < sizeof(mCoapToken); i++) { mCoapToken[i] = otPlatRandomGet(); } header.Init(); header.SetVersion(1); header.SetType(Coap::Header::kTypeConfirmable); header.SetCode(Coap::Header::kCodePost); header.SetMessageId(++mCoapMessageId); header.SetToken(mCoapToken, sizeof(mCoapToken)); header.AppendUriPathOptions(OPENTHREAD_URI_SERVER_DATA); header.AppendContentFormatOption(Coap::Header::kApplicationOctetStream); header.Finalize(); VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, error = kThreadError_NoBufs); SuccessOrExit(error = message->Append(header.GetBytes(), header.GetLength())); SuccessOrExit(error = message->Append(mTlvs, mLength)); memset(&messageInfo, 0, sizeof(messageInfo)); memcpy(&messageInfo.mPeerAddr, &aDestination, sizeof(messageInfo.mPeerAddr)); messageInfo.mPeerPort = kCoapUdpPort; SuccessOrExit(error = mSocket.SendTo(*message, messageInfo)); otLogInfoNetData("Sent network data registration\n"); exit: if (error != kThreadError_None && message != NULL) { Message::Free(*message); } return error; }
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; }
otError Local::SendServerDataNotification(void) { otError error = OT_ERROR_NONE; uint16_t rloc = Get<Mle::MleRouter>().GetRloc16(); #if OPENTHREAD_FTD // Don't send this Server Data Notification if the device is going to upgrade to Router if (Get<Mle::MleRouter>().IsFullThreadDevice() && Get<Mle::MleRouter>().IsRouterRoleEnabled() && (Get<Mle::MleRouter>().GetRole() < OT_DEVICE_ROLE_ROUTER) && (Get<RouterTable>().GetActiveRouterCount() < Get<Mle::MleRouter>().GetRouterUpgradeThreshold())) { ExitNow(error = OT_ERROR_INVALID_STATE); } #endif UpdateRloc(); #if OPENTHREAD_ENABLE_SERVICE VerifyOrExit(!IsOnMeshPrefixConsistent() || !IsExternalRouteConsistent() || !IsServiceConsistent(), ClearResubmitDelayTimer()); #else VerifyOrExit(!IsOnMeshPrefixConsistent() || !IsExternalRouteConsistent(), ClearResubmitDelayTimer()); #endif if (mOldRloc == rloc) { mOldRloc = Mac::kShortAddrInvalid; } SuccessOrExit(error = NetworkData::SendServerDataNotification(mOldRloc)); mOldRloc = rloc; exit: return error; }