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 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; }