void AnnounceBeginServer::HandleRequest(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { MeshCoP::ChannelMask0Tlv channelMask; MeshCoP::CountTlv count; MeshCoP::PeriodTlv period; Ip6::MessageInfo responseInfo(aMessageInfo); VerifyOrExit(aHeader.GetCode() == OT_COAP_CODE_POST); SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kChannelMask, sizeof(channelMask), channelMask)); VerifyOrExit(channelMask.IsValid()); SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kCount, sizeof(count), count)); VerifyOrExit(count.IsValid()); SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kPeriod, sizeof(period), period)); VerifyOrExit(period.IsValid()); SendAnnounce(channelMask.GetMask(), count.GetCount(), period.GetPeriod()); if (aHeader.IsConfirmable() && !aMessageInfo.GetSockAddr().IsMulticast()) { SuccessOrExit(GetNetif().GetCoap().SendEmptyAck(aHeader, responseInfo)); otLogInfoMeshCoP(GetInstance(), "sent announce begin response"); } exit: return; }
void PanIdQueryClient::HandleConflict(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { ThreadNetif &netif = GetNetif(); MeshCoP::PanIdTlv panId; MeshCoP::ChannelMask0Tlv channelMask; Ip6::MessageInfo responseInfo(aMessageInfo); VerifyOrExit(aHeader.GetType() == OT_COAP_TYPE_CONFIRMABLE && aHeader.GetCode() == OT_COAP_CODE_POST); otLogInfoMeshCoP(GetInstance(), "received panid conflict"); SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kPanId, sizeof(panId), panId)); VerifyOrExit(panId.IsValid()); SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kChannelMask, sizeof(channelMask), channelMask)); VerifyOrExit(channelMask.IsValid()); if (mCallback != NULL) { mCallback(panId.GetPanId(), channelMask.GetMask(), mContext); } SuccessOrExit(netif.GetCoap().SendEmptyAck(aHeader, responseInfo)); otLogInfoMeshCoP(GetInstance(), "sent panid query conflict response"); exit: return; }
otError AnnounceBeginClient::SendRequest(uint32_t aChannelMask, uint8_t aCount, uint16_t aPeriod, const Ip6::Address &aAddress) { otError error = OT_ERROR_NONE; Coap::Header header; MeshCoP::CommissionerSessionIdTlv sessionId; MeshCoP::ChannelMask0Tlv channelMask; MeshCoP::CountTlv count; MeshCoP::PeriodTlv period; Ip6::MessageInfo messageInfo; Message *message = NULL; VerifyOrExit(GetNetif().GetCommissioner().IsActive(), error = OT_ERROR_INVALID_STATE); header.Init(aAddress.IsMulticast() ? OT_COAP_TYPE_NON_CONFIRMABLE : OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST); header.SetToken(Coap::Header::kDefaultTokenLength); header.AppendUriPathOptions(OT_URI_PATH_ANNOUNCE_BEGIN); header.SetPayloadMarker(); VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(GetNetif().GetCoap(), header)) != NULL, error = OT_ERROR_NO_BUFS); sessionId.Init(); sessionId.SetCommissionerSessionId(GetNetif().GetCommissioner().GetSessionId()); SuccessOrExit(error = message->Append(&sessionId, sizeof(sessionId))); channelMask.Init(); channelMask.SetMask(aChannelMask); SuccessOrExit(error = message->Append(&channelMask, sizeof(channelMask))); count.Init(); count.SetCount(aCount); SuccessOrExit(error = message->Append(&count, sizeof(count))); period.Init(); period.SetPeriod(aPeriod); SuccessOrExit(error = message->Append(&period, sizeof(period))); messageInfo.SetSockAddr(GetNetif().GetMle().GetMeshLocal16()); messageInfo.SetPeerAddr(aAddress); messageInfo.SetPeerPort(kCoapUdpPort); messageInfo.SetInterfaceId(GetNetif().GetInterfaceId()); SuccessOrExit(error = GetNetif().GetCoap().SendMessage(*message, messageInfo)); otLogInfoMeshCoP(GetInstance(), "sent announce begin query"); exit: if (error != OT_ERROR_NONE && message != NULL) { message->Free(); } return error; }
otError PanIdQueryClient::SendQuery(uint16_t aPanId, uint32_t aChannelMask, const Ip6::Address &aAddress, otCommissionerPanIdConflictCallback aCallback, void *aContext) { ThreadNetif &netif = GetNetif(); otError error = OT_ERROR_NONE; Coap::Header header; MeshCoP::CommissionerSessionIdTlv sessionId; MeshCoP::ChannelMask0Tlv channelMask; MeshCoP::PanIdTlv panId; Ip6::MessageInfo messageInfo; Message *message = NULL; VerifyOrExit(netif.GetCommissioner().IsActive(), error = OT_ERROR_INVALID_STATE); header.Init(aAddress.IsMulticast() ? OT_COAP_TYPE_NON_CONFIRMABLE : OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST); header.SetToken(Coap::Header::kDefaultTokenLength); header.AppendUriPathOptions(OT_URI_PATH_PANID_QUERY); header.SetPayloadMarker(); VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(netif.GetCoap(), header)) != NULL, error = OT_ERROR_NO_BUFS); sessionId.Init(); sessionId.SetCommissionerSessionId(netif.GetCommissioner().GetSessionId()); SuccessOrExit(error = message->Append(&sessionId, sizeof(sessionId))); channelMask.Init(); channelMask.SetMask(aChannelMask); SuccessOrExit(error = message->Append(&channelMask, sizeof(channelMask))); panId.Init(); panId.SetPanId(aPanId); SuccessOrExit(error = message->Append(&panId, sizeof(panId))); messageInfo.SetSockAddr(netif.GetMle().GetMeshLocal16()); messageInfo.SetPeerAddr(aAddress); messageInfo.SetPeerPort(kCoapUdpPort); messageInfo.SetInterfaceId(netif.GetInterfaceId()); SuccessOrExit(error = netif.GetCoap().SendMessage(*message, messageInfo)); otLogInfoMeshCoP(GetInstance(), "sent panid query"); mCallback = aCallback; mContext = aContext; exit: if (error != OT_ERROR_NONE && message != NULL) { message->Free(); } return error; }
otError EnergyScanServer::SendReport(void) { otError error = OT_ERROR_NONE; Coap::Header header; MeshCoP::ChannelMask0Tlv channelMask; MeshCoP::EnergyListTlv energyList; Ip6::MessageInfo messageInfo; Message * message; header.Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST); header.SetToken(Coap::Header::kDefaultTokenLength); header.AppendUriPathOptions(OT_URI_PATH_ENERGY_REPORT); header.SetPayloadMarker(); VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(GetNetif().GetCoap(), header)) != NULL, error = OT_ERROR_NO_BUFS); channelMask.Init(); channelMask.SetMask(mChannelMask); SuccessOrExit(error = message->Append(&channelMask, sizeof(channelMask))); energyList.Init(); energyList.SetLength(mScanResultsLength); SuccessOrExit(error = message->Append(&energyList, sizeof(energyList))); SuccessOrExit(error = message->Append(mScanResults, mScanResultsLength)); messageInfo.SetSockAddr(GetNetif().GetMle().GetMeshLocal16()); messageInfo.SetPeerAddr(mCommissioner); messageInfo.SetPeerPort(kCoapUdpPort); SuccessOrExit(error = GetNetif().GetCoap().SendMessage(*message, messageInfo)); otLogInfoMeshCoP(GetInstance(), "sent scan results"); exit: if (error != OT_ERROR_NONE && message != NULL) { message->Free(); } mActive = false; return error; }
void EnergyScanServer::HandleRequest(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { MeshCoP::CountTlv count; MeshCoP::PeriodTlv period; MeshCoP::ScanDurationTlv scanDuration; MeshCoP::ChannelMask0Tlv channelMask; Ip6::MessageInfo responseInfo(aMessageInfo); VerifyOrExit(aHeader.GetCode() == OT_COAP_CODE_POST); SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kCount, sizeof(count), count)); VerifyOrExit(count.IsValid()); SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kPeriod, sizeof(period), period)); VerifyOrExit(period.IsValid()); SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kScanDuration, sizeof(scanDuration), scanDuration)); VerifyOrExit(scanDuration.IsValid()); SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kChannelMask, sizeof(channelMask), channelMask)); VerifyOrExit(channelMask.IsValid()); mChannelMask = channelMask.GetMask(); mChannelMaskCurrent = mChannelMask; mCount = count.GetCount(); mPeriod = period.GetPeriod(); mScanDuration = scanDuration.GetScanDuration(); mScanResultsLength = 0; mActive = true; mTimer.Start(kScanDelay); mCommissioner = aMessageInfo.GetPeerAddr(); if (aHeader.IsConfirmable() && !aMessageInfo.GetSockAddr().IsMulticast()) { SuccessOrExit(GetNetif().GetCoap().SendEmptyAck(aHeader, responseInfo)); otLogInfoMeshCoP(GetInstance(), "sent energy scan query response"); } exit: return; }
void EnergyScanClient::HandleReport(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { ThreadNetif &netif = GetNetif(); MeshCoP::ChannelMask0Tlv channelMask; Ip6::MessageInfo responseInfo(aMessageInfo); OT_TOOL_PACKED_BEGIN struct { MeshCoP::EnergyListTlv tlv; uint8_t list[OPENTHREAD_CONFIG_MAX_ENERGY_RESULTS]; } OT_TOOL_PACKED_END energyList; VerifyOrExit(aHeader.GetType() == OT_COAP_TYPE_CONFIRMABLE && aHeader.GetCode() == OT_COAP_CODE_POST); otLogInfoMeshCoP(GetInstance(), "received energy scan report"); SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kChannelMask, sizeof(channelMask), channelMask)); VerifyOrExit(channelMask.IsValid()); SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kEnergyList, sizeof(energyList), energyList.tlv)); VerifyOrExit(energyList.tlv.IsValid()); if (mCallback != NULL) { mCallback(channelMask.GetMask(), energyList.list, energyList.tlv.GetLength(), mContext); } SuccessOrExit(netif.GetCoap().SendEmptyAck(aHeader, responseInfo)); otLogInfoMeshCoP(GetInstance(), "sent energy scan report response"); exit: return; }
ThreadError Dataset::Set(const otOperationalDataset &aDataset) { ThreadError error = kThreadError_None; MeshCoP::ActiveTimestampTlv activeTimestampTlv; VerifyOrExit(aDataset.mIsActiveTimestampSet, error = kThreadError_InvalidArgs); activeTimestampTlv.Init(); activeTimestampTlv.SetSeconds(aDataset.mActiveTimestamp); activeTimestampTlv.SetTicks(0); Set(activeTimestampTlv); if (mType == Tlv::kPendingTimestamp) { MeshCoP::PendingTimestampTlv pendingTimestampTlv; VerifyOrExit(aDataset.mIsPendingTimestampSet, error = kThreadError_InvalidArgs); pendingTimestampTlv.Init(); pendingTimestampTlv.SetSeconds(aDataset.mPendingTimestamp); pendingTimestampTlv.SetTicks(0); Set(pendingTimestampTlv); if (aDataset.mIsDelaySet) { MeshCoP::DelayTimerTlv tlv; tlv.Init(); tlv.SetDelayTimer(aDataset.mDelay); Set(tlv); } } if (aDataset.mIsChannelSet) { MeshCoP::ChannelTlv tlv; tlv.Init(); tlv.SetChannelPage(0); tlv.SetChannel(aDataset.mChannel); Set(tlv); } if (aDataset.mIsChannelMaskPage0Set) { MeshCoP::ChannelMask0Tlv tlv; tlv.Init(); tlv.SetMask(aDataset.mChannelMaskPage0); Set(tlv); } if (aDataset.mIsExtendedPanIdSet) { MeshCoP::ExtendedPanIdTlv tlv; tlv.Init(); tlv.SetExtendedPanId(aDataset.mExtendedPanId.m8); Set(tlv); } if (aDataset.mIsMeshLocalPrefixSet) { MeshCoP::MeshLocalPrefixTlv tlv; tlv.Init(); tlv.SetMeshLocalPrefix(aDataset.mMeshLocalPrefix.m8); Set(tlv); } if (aDataset.mIsMasterKeySet) { MeshCoP::NetworkMasterKeyTlv tlv; tlv.Init(); tlv.SetNetworkMasterKey(aDataset.mMasterKey.m8); Set(tlv); } if (aDataset.mIsNetworkNameSet) { MeshCoP::NetworkNameTlv tlv; tlv.Init(); tlv.SetNetworkName(aDataset.mNetworkName.m8); Set(tlv); } if (aDataset.mIsPanIdSet) { MeshCoP::PanIdTlv tlv; tlv.Init(); tlv.SetPanId(aDataset.mPanId); Set(tlv); } if (aDataset.mIsPSKcSet) { MeshCoP::PSKcTlv tlv; tlv.Init(); tlv.SetPSKc(aDataset.mPSKc.m8); Set(tlv); } if (aDataset.mIsSecurityPolicySet) { MeshCoP::SecurityPolicyTlv tlv; tlv.Init(); tlv.SetRotationTime(aDataset.mSecurityPolicy.mRotationTime); tlv.SetFlags(aDataset.mSecurityPolicy.mFlags); Set(tlv); } exit: return error; }
otError Dataset::Set(const otOperationalDataset &aDataset) { otError error = OT_ERROR_NONE; MeshCoP::ActiveTimestampTlv activeTimestampTlv; VerifyOrExit(aDataset.mComponents.mIsActiveTimestampPresent, error = OT_ERROR_INVALID_ARGS); activeTimestampTlv.Init(); activeTimestampTlv.SetSeconds(aDataset.mActiveTimestamp); activeTimestampTlv.SetTicks(0); Set(activeTimestampTlv); if (mType == Tlv::kPendingTimestamp) { MeshCoP::PendingTimestampTlv pendingTimestampTlv; VerifyOrExit(aDataset.mComponents.mIsPendingTimestampPresent, error = OT_ERROR_INVALID_ARGS); pendingTimestampTlv.Init(); pendingTimestampTlv.SetSeconds(aDataset.mPendingTimestamp); pendingTimestampTlv.SetTicks(0); Set(pendingTimestampTlv); if (aDataset.mComponents.mIsDelayPresent) { MeshCoP::DelayTimerTlv tlv; tlv.Init(); tlv.SetDelayTimer(aDataset.mDelay); Set(tlv); } } if (aDataset.mComponents.mIsChannelPresent) { MeshCoP::ChannelTlv tlv; tlv.Init(); tlv.SetChannelPage(0); tlv.SetChannel(aDataset.mChannel); Set(tlv); } if (aDataset.mComponents.mIsChannelMaskPage0Present) { MeshCoP::ChannelMask0Tlv tlv; tlv.Init(); tlv.SetMask(aDataset.mChannelMaskPage0); Set(tlv); } if (aDataset.mComponents.mIsExtendedPanIdPresent) { MeshCoP::ExtendedPanIdTlv tlv; tlv.Init(); tlv.SetExtendedPanId(aDataset.mExtendedPanId); Set(tlv); } if (aDataset.mComponents.mIsMeshLocalPrefixPresent) { MeshCoP::MeshLocalPrefixTlv tlv; tlv.Init(); tlv.SetMeshLocalPrefix(aDataset.mMeshLocalPrefix.m8); Set(tlv); } if (aDataset.mComponents.mIsMasterKeyPresent) { MeshCoP::NetworkMasterKeyTlv tlv; tlv.Init(); tlv.SetNetworkMasterKey(aDataset.mMasterKey); Set(tlv); } if (aDataset.mComponents.mIsNetworkNamePresent) { MeshCoP::NetworkNameTlv tlv; tlv.Init(); tlv.SetNetworkName(aDataset.mNetworkName.m8); Set(tlv); } if (aDataset.mComponents.mIsPanIdPresent) { MeshCoP::PanIdTlv tlv; tlv.Init(); tlv.SetPanId(aDataset.mPanId); Set(tlv); } if (aDataset.mComponents.mIsPSKcPresent) { MeshCoP::PSKcTlv tlv; tlv.Init(); tlv.SetPSKc(aDataset.mPSKc.m8); Set(tlv); } if (aDataset.mComponents.mIsSecurityPolicyPresent) { MeshCoP::SecurityPolicyTlv tlv; tlv.Init(); tlv.SetRotationTime(aDataset.mSecurityPolicy.mRotationTime); tlv.SetFlags(aDataset.mSecurityPolicy.mFlags); Set(tlv); } mUpdateTime = TimerMilli::GetNow(); exit: return error; }