void EnergyScanClient::HandleReport(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { ThreadNetif & netif = GetNetif(); MeshCoP::ChannelMaskTlv 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(aMessage.GetType() == OT_COAP_TYPE_CONFIRMABLE && aMessage.GetCode() == OT_COAP_CODE_POST); otLogInfoMeshCoP("received energy scan report"); SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kChannelMask, sizeof(channelMask), channelMask)); VerifyOrExit(channelMask.IsValid() && channelMask.GetChannelPage() == OT_RADIO_CHANNEL_PAGE); 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(aMessage, responseInfo)); otLogInfoMeshCoP("sent energy scan report response"); exit: return; }
void Joiner::HandleJoinerFinalizeResponse(Coap::Message & aMessage, const Ip6::MessageInfo *aMessageInfo, otError aResult) { OT_UNUSED_VARIABLE(aMessageInfo); StateTlv state; VerifyOrExit(mState == OT_JOINER_STATE_CONNECTED && aResult == OT_ERROR_NONE && aMessage.GetType() == OT_COAP_TYPE_ACKNOWLEDGMENT && aMessage.GetCode() == OT_COAP_CODE_CHANGED); SuccessOrExit(Tlv::GetTlv(aMessage, Tlv::kState, sizeof(state), state)); VerifyOrExit(state.IsValid()); mState = OT_JOINER_STATE_ENTRUST; mTimer.Start(kTimeout); otLogInfoMeshCoP("received joiner finalize response %d", static_cast<uint8_t>(state.GetState())); #if OPENTHREAD_ENABLE_CERT_LOG uint8_t buf[OPENTHREAD_CONFIG_MESSAGE_BUFFER_SIZE]; VerifyOrExit(aMessage.GetLength() <= sizeof(buf)); aMessage.Read(aMessage.GetOffset(), aMessage.GetLength() - aMessage.GetOffset(), buf); otDumpCertMeshCoP("[THCI] direction=recv | type=JOIN_FIN.rsp |", buf, aMessage.GetLength() - aMessage.GetOffset()); #endif exit: Close(); }
void EnergyScanClient::HandleReport(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { uint32_t mask; OT_TOOL_PACKED_BEGIN struct { MeshCoP::EnergyListTlv tlv; uint8_t list[OPENTHREAD_CONFIG_MAX_ENERGY_RESULTS]; } OT_TOOL_PACKED_END energyList; VerifyOrExit(aMessage.GetType() == OT_COAP_TYPE_CONFIRMABLE && aMessage.GetCode() == OT_COAP_CODE_POST); otLogInfoMeshCoP("received energy scan report"); VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0); SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kEnergyList, sizeof(energyList), energyList.tlv)); VerifyOrExit(energyList.tlv.IsValid()); if (mCallback != NULL) { mCallback(mask, energyList.list, energyList.tlv.GetLength(), mContext); } SuccessOrExit(Get<Coap::Coap>().SendEmptyAck(aMessage, aMessageInfo)); otLogInfoMeshCoP("sent energy scan report response"); exit: return; }
void JoinerRouter::HandleRelayTransmit(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { OT_UNUSED_VARIABLE(aMessageInfo); otError error; JoinerUdpPortTlv joinerPort; JoinerIidTlv joinerIid; JoinerRouterKekTlv kek; uint16_t offset; uint16_t length; Message * message = NULL; otMessageSettings settings = {false, static_cast<otMessagePriority>(kMeshCoPMessagePriority)}; Ip6::MessageInfo messageInfo; VerifyOrExit(aMessage.GetType() == OT_COAP_TYPE_NON_CONFIRMABLE && aMessage.GetCode() == OT_COAP_CODE_POST, error = OT_ERROR_DROP); otLogInfoMeshCoP("Received relay transmit"); SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kJoinerUdpPort, sizeof(joinerPort), joinerPort)); VerifyOrExit(joinerPort.IsValid(), error = OT_ERROR_PARSE); SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kJoinerIid, sizeof(joinerIid), joinerIid)); VerifyOrExit(joinerIid.IsValid(), error = OT_ERROR_PARSE); SuccessOrExit(error = Tlv::GetValueOffset(aMessage, Tlv::kJoinerDtlsEncapsulation, offset, length)); VerifyOrExit((message = mSocket.NewMessage(0, &settings)) != NULL, error = OT_ERROR_NO_BUFS); while (length) { uint16_t copyLength = length; uint8_t tmp[16]; if (copyLength >= sizeof(tmp)) { copyLength = sizeof(tmp); } aMessage.Read(offset, copyLength, tmp); SuccessOrExit(error = message->Append(tmp, copyLength)); offset += copyLength; length -= copyLength; } aMessage.CopyTo(offset, 0, length, *message); messageInfo.mPeerAddr.mFields.m16[0] = HostSwap16(0xfe80); memcpy(messageInfo.mPeerAddr.mFields.m8 + 8, joinerIid.GetIid(), 8); messageInfo.SetPeerPort(joinerPort.GetUdpPort()); messageInfo.SetInterfaceId(GetNetif().GetInterfaceId()); SuccessOrExit(error = mSocket.SendTo(*message, messageInfo)); if (Tlv::GetTlv(aMessage, Tlv::kJoinerRouterKek, sizeof(kek), kek) == OT_ERROR_NONE) { otLogInfoMeshCoP("Received kek"); DelaySendingJoinerEntrust(messageInfo, kek); } exit: if (error != OT_ERROR_NONE && message != NULL) { message->Free(); } }
void Joiner::HandleJoinerEntrust(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { ThreadNetif & netif = GetNetif(); otError error; NetworkMasterKeyTlv masterKey; MeshLocalPrefixTlv meshLocalPrefix; ExtendedPanIdTlv extendedPanId; NetworkNameTlv networkName; ActiveTimestampTlv activeTimestamp; NetworkKeySequenceTlv networkKeySeq; VerifyOrExit(mState == OT_JOINER_STATE_ENTRUST && aMessage.GetType() == OT_COAP_TYPE_CONFIRMABLE && aMessage.GetCode() == OT_COAP_CODE_POST, error = OT_ERROR_DROP); otLogInfoMeshCoP("Received joiner entrust"); otLogCertMeshCoP("[THCI] direction=recv | type=JOIN_ENT.ntf"); SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kNetworkMasterKey, sizeof(masterKey), masterKey)); VerifyOrExit(masterKey.IsValid(), error = OT_ERROR_PARSE); SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kMeshLocalPrefix, sizeof(meshLocalPrefix), meshLocalPrefix)); VerifyOrExit(meshLocalPrefix.IsValid(), error = OT_ERROR_PARSE); SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kExtendedPanId, sizeof(extendedPanId), extendedPanId)); VerifyOrExit(extendedPanId.IsValid(), error = OT_ERROR_PARSE); SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kNetworkName, sizeof(networkName), networkName)); VerifyOrExit(networkName.IsValid(), error = OT_ERROR_PARSE); SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kActiveTimestamp, sizeof(activeTimestamp), activeTimestamp)); VerifyOrExit(activeTimestamp.IsValid(), error = OT_ERROR_PARSE); SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kNetworkKeySequence, sizeof(networkKeySeq), networkKeySeq)); VerifyOrExit(networkKeySeq.IsValid(), error = OT_ERROR_PARSE); netif.GetKeyManager().SetMasterKey(masterKey.GetNetworkMasterKey()); netif.GetKeyManager().SetCurrentKeySequence(networkKeySeq.GetNetworkKeySequence()); netif.GetMle().SetMeshLocalPrefix(meshLocalPrefix.GetMeshLocalPrefix()); netif.GetMac().SetExtendedPanId(extendedPanId.GetExtendedPanId()); { otNetworkName name; memcpy(name.m8, networkName.GetNetworkName(), networkName.GetLength()); name.m8[networkName.GetLength()] = '\0'; netif.GetMac().SetNetworkName(name.m8); } otLogInfoMeshCoP("join success!"); // Send dummy response. SendJoinerEntrustResponse(aMessage, aMessageInfo); // Delay extended address configuration to allow DTLS wrap up. mTimer.Start(kConfigExtAddressDelay); exit: if (error != OT_ERROR_NONE) { otLogWarnMeshCoP("Error while processing joiner entrust: %s", otThreadErrorToString(error)); } }