otError Leader::SendDatasetChanged(const Ip6::Address &aAddress) { ThreadNetif &netif = GetNetif(); otError error = OT_ERROR_NONE; Coap::Header header; 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_DATASET_CHANGED); VerifyOrExit((message = NewMeshCoPMessage(netif.GetCoap(), header)) != NULL, error = OT_ERROR_NO_BUFS); messageInfo.SetSockAddr(netif.GetMle().GetMeshLocal16()); messageInfo.SetPeerAddr(aAddress); messageInfo.SetPeerPort(kCoapUdpPort); SuccessOrExit(error = netif.GetCoap().SendMessage(*message, messageInfo)); otLogInfoMeshCoP(GetInstance(), "sent dataset changed"); exit: if (error != OT_ERROR_NONE && message != NULL) { message->Free(); } return error; }
void JoinerRouter::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { ThreadNetif & netif = GetNetif(); otError error; Coap::Message * message = NULL; Ip6::MessageInfo messageInfo; JoinerUdpPortTlv udpPort; JoinerIidTlv iid; JoinerRouterLocatorTlv rloc; ExtendedTlv tlv; uint16_t borderAgentRloc; uint16_t offset; otLogInfoMeshCoP("JoinerRouter::HandleUdpReceive"); SuccessOrExit(error = GetBorderAgentRloc(GetNetif(), borderAgentRloc)); VerifyOrExit((message = NewMeshCoPMessage(netif.GetCoap())) != NULL, error = OT_ERROR_NO_BUFS); message->Init(OT_COAP_TYPE_NON_CONFIRMABLE, OT_COAP_CODE_POST); message->SetToken(Coap::Message::kDefaultTokenLength); message->AppendUriPathOptions(OT_URI_PATH_RELAY_RX); message->SetPayloadMarker(); udpPort.Init(); udpPort.SetUdpPort(aMessageInfo.GetPeerPort()); SuccessOrExit(error = message->Append(&udpPort, sizeof(udpPort))); iid.Init(); iid.SetIid(aMessageInfo.GetPeerAddr().mFields.m8 + 8); SuccessOrExit(error = message->Append(&iid, sizeof(iid))); rloc.Init(); rloc.SetJoinerRouterLocator(netif.GetMle().GetRloc16()); SuccessOrExit(error = message->Append(&rloc, sizeof(rloc))); tlv.SetType(Tlv::kJoinerDtlsEncapsulation); tlv.SetLength(aMessage.GetLength() - aMessage.GetOffset()); SuccessOrExit(error = message->Append(&tlv, sizeof(tlv))); offset = message->GetLength(); SuccessOrExit(error = message->SetLength(offset + tlv.GetLength())); aMessage.CopyTo(aMessage.GetOffset(), offset, tlv.GetLength(), *message); messageInfo.SetSockAddr(netif.GetMle().GetMeshLocal16()); messageInfo.SetPeerAddr(netif.GetMle().GetMeshLocal16()); messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(borderAgentRloc); messageInfo.SetPeerPort(kCoapUdpPort); SuccessOrExit(error = netif.GetCoap().SendMessage(*message, messageInfo)); otLogInfoMeshCoP("Sent relay rx"); exit: if (error != OT_ERROR_NONE && message != NULL) { message->Free(); } }
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 otUdpProxyReceive(otInstance * aInstance, otMessage * aMessage, uint16_t aPeerPort, const otIp6Address *aPeerAddr, uint16_t aSockPort) { Ip6::MessageInfo messageInfo; Instance & instance = *static_cast<Instance *>(aInstance); Ip6::Ip6 & ip6 = instance.Get<Ip6::Ip6>(); assert(aMessage != NULL && aPeerAddr != NULL); messageInfo.SetSockAddr(instance.GetThreadNetif().GetMle().GetMeshLocal16()); messageInfo.SetSockPort(aSockPort); messageInfo.SetPeerAddr(*static_cast<const ot::Ip6::Address *>(aPeerAddr)); messageInfo.SetPeerPort(aPeerPort); messageInfo.SetInterfaceId(OT_NETIF_INTERFACE_ID_HOST); ip6.GetUdp().HandlePayload(*static_cast<ot::Message *>(aMessage), messageInfo); static_cast<ot::Message *>(aMessage)->Free(); }
otError EnergyScanClient::SendQuery(uint32_t aChannelMask, uint8_t aCount, uint16_t aPeriod, uint16_t aScanDuration, const Ip6::Address & aAddress, otCommissionerEnergyReportCallback aCallback, void * aContext) { ThreadNetif & netif = GetNetif(); otError error = OT_ERROR_NONE; MeshCoP::CommissionerSessionIdTlv sessionId; MeshCoP::ChannelMaskTlv channelMask; MeshCoP::CountTlv count; MeshCoP::PeriodTlv period; MeshCoP::ScanDurationTlv scanDuration; Ip6::MessageInfo messageInfo; Coap::Message * message = NULL; VerifyOrExit(netif.GetCommissioner().IsActive(), error = OT_ERROR_INVALID_STATE); VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(netif.GetCoap())) != NULL, error = OT_ERROR_NO_BUFS); message->Init(aAddress.IsMulticast() ? OT_COAP_TYPE_NON_CONFIRMABLE : OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST); message->SetToken(Coap::Message::kDefaultTokenLength); message->AppendUriPathOptions(OT_URI_PATH_ENERGY_SCAN); message->SetPayloadMarker(); sessionId.Init(); sessionId.SetCommissionerSessionId(netif.GetCommissioner().GetSessionId()); SuccessOrExit(error = message->Append(&sessionId, sizeof(sessionId))); channelMask.Init(); channelMask.SetChannelPage(OT_RADIO_CHANNEL_PAGE); 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))); scanDuration.Init(); scanDuration.SetScanDuration(aScanDuration); SuccessOrExit(error = message->Append(&scanDuration, sizeof(scanDuration))); messageInfo.SetSockAddr(netif.GetMle().GetMeshLocal16()); messageInfo.SetPeerAddr(aAddress); messageInfo.SetPeerPort(kCoapUdpPort); messageInfo.SetInterfaceId(netif.GetInterfaceId()); SuccessOrExit(error = netif.GetCoap().SendMessage(*message, messageInfo)); otLogInfoMeshCoP("sent energy scan query"); mCallback = aCallback; mContext = aContext; exit: if (error != OT_ERROR_NONE && message != NULL) { message->Free(); } return error; }
void Client::HandleRetransmissionTimer(void) { uint32_t now = otPlatAlarmGetNow(); uint32_t nextDelta = 0xffffffff; RequestMetadata requestMetadata; Message *message = mPendingRequests.GetHead(); Message *nextMessage = NULL; Ip6::MessageInfo messageInfo; while (message != NULL) { nextMessage = message->GetNext(); requestMetadata.ReadFrom(*message); if (requestMetadata.IsLater(now)) { // Calculate the next delay and choose the lowest. if (requestMetadata.mNextTimerShot - now < nextDelta) { nextDelta = requestMetadata.mNextTimerShot - now; } } else if ((requestMetadata.mConfirmable) && (requestMetadata.mRetransmissionCount < kMaxRetransmit)) { // Increment retransmission counter and timer. requestMetadata.mRetransmissionCount++; requestMetadata.mRetransmissionTimeout *= 2; requestMetadata.mNextTimerShot = now + requestMetadata.mRetransmissionTimeout; requestMetadata.UpdateIn(*message); // Check if retransmission time is lower than current lowest. if (requestMetadata.mRetransmissionTimeout < nextDelta) { nextDelta = requestMetadata.mRetransmissionTimeout; } // Retransmit if (!requestMetadata.mAcknowledged) { messageInfo.SetPeerAddr(requestMetadata.mDestinationAddress); messageInfo.SetPeerPort(requestMetadata.mDestinationPort); messageInfo.SetSockAddr(requestMetadata.mSourceAddress); SendCopy(*message, messageInfo); } } else { // No expected response or acknowledgment. FinalizeCoapTransaction(*message, requestMetadata, NULL, NULL, NULL, kThreadError_ResponseTimeout); } message = nextMessage; } if (nextDelta != 0xffffffff) { mRetransmissionTimer.Start(nextDelta); } }