void Joiner::SendJoinerEntrustResponse(const Coap::Message &aRequest, const Ip6::MessageInfo &aRequestInfo) { ThreadNetif & netif = GetNetif(); otError error = OT_ERROR_NONE; Coap::Message * message; Ip6::MessageInfo responseInfo(aRequestInfo); VerifyOrExit((message = NewMeshCoPMessage(netif.GetCoap())) != NULL, error = OT_ERROR_NO_BUFS); message->SetDefaultResponseHeader(aRequest); message->SetSubType(Message::kSubTypeJoinerEntrust); memset(&responseInfo.mSockAddr, 0, sizeof(responseInfo.mSockAddr)); SuccessOrExit(error = netif.GetCoap().SendMessage(*message, responseInfo)); mState = OT_JOINER_STATE_JOINED; otLogInfoArp("Sent Joiner Entrust response"); otLogInfoMeshCoP("Sent joiner entrust response length = %d", message->GetLength()); otLogCertMeshCoP("[THCI] direction=send | type=JOIN_ENT.rsp"); exit: if (error != OT_ERROR_NONE && message != NULL) { message->Free(); } }
otError JoinerRouter::DelaySendingJoinerEntrust(const Ip6::MessageInfo &aMessageInfo, const JoinerRouterKekTlv &aKek) { ThreadNetif & netif = GetNetif(); otError error; Coap::Message * message = NULL; Ip6::MessageInfo messageInfo; Dataset dataset(MeshCoP::Tlv::kActiveTimestamp); NetworkMasterKeyTlv masterKey; MeshLocalPrefixTlv meshLocalPrefix; ExtendedPanIdTlv extendedPanId; NetworkNameTlv networkName; NetworkKeySequenceTlv networkKeySequence; const Tlv * tlv; DelayedJoinEntHeader delayedMessage; VerifyOrExit((message = NewMeshCoPMessage(netif.GetCoap())) != NULL, error = OT_ERROR_NO_BUFS); message->Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST); message->AppendUriPathOptions(OT_URI_PATH_JOINER_ENTRUST); message->SetPayloadMarker(); message->SetSubType(Message::kSubTypeJoinerEntrust); masterKey.Init(); masterKey.SetNetworkMasterKey(netif.GetKeyManager().GetMasterKey()); SuccessOrExit(error = message->Append(&masterKey, sizeof(masterKey))); meshLocalPrefix.Init(); meshLocalPrefix.SetMeshLocalPrefix(netif.GetMle().GetMeshLocalPrefix()); SuccessOrExit(error = message->Append(&meshLocalPrefix, sizeof(meshLocalPrefix))); extendedPanId.Init(); extendedPanId.SetExtendedPanId(netif.GetMac().GetExtendedPanId()); SuccessOrExit(error = message->Append(&extendedPanId, sizeof(extendedPanId))); networkName.Init(); networkName.SetNetworkName(netif.GetMac().GetNetworkName()); SuccessOrExit(error = message->Append(&networkName, sizeof(Tlv) + networkName.GetLength())); netif.GetActiveDataset().Get(dataset); if ((tlv = dataset.Get(Tlv::kActiveTimestamp)) != NULL) { SuccessOrExit(error = message->Append(tlv, sizeof(Tlv) + tlv->GetLength())); } else { ActiveTimestampTlv activeTimestamp; activeTimestamp.Init(); SuccessOrExit(error = message->Append(&activeTimestamp, sizeof(activeTimestamp))); } if ((tlv = dataset.Get(Tlv::kChannelMask)) != NULL) { SuccessOrExit(error = message->Append(tlv, sizeof(Tlv) + tlv->GetLength())); } else { ChannelMaskBaseTlv channelMask; channelMask.Init(); SuccessOrExit(error = message->Append(&channelMask, sizeof(channelMask))); } if ((tlv = dataset.Get(Tlv::kPSKc)) != NULL) { SuccessOrExit(error = message->Append(tlv, sizeof(Tlv) + tlv->GetLength())); } else { PSKcTlv pskc; pskc.Init(); SuccessOrExit(error = message->Append(&pskc, sizeof(pskc))); } if ((tlv = dataset.Get(Tlv::kSecurityPolicy)) != NULL) { SuccessOrExit(error = message->Append(tlv, sizeof(Tlv) + tlv->GetLength())); } else { SecurityPolicyTlv securityPolicy; securityPolicy.Init(); SuccessOrExit(error = message->Append(&securityPolicy, sizeof(securityPolicy))); } networkKeySequence.Init(); networkKeySequence.SetNetworkKeySequence(netif.GetKeyManager().GetCurrentKeySequence()); SuccessOrExit(error = message->Append(&networkKeySequence, networkKeySequence.GetSize())); messageInfo = aMessageInfo; messageInfo.SetPeerPort(kCoapUdpPort); delayedMessage = DelayedJoinEntHeader(TimerMilli::GetNow() + kDelayJoinEnt, messageInfo, aKek.GetKek()); SuccessOrExit(delayedMessage.AppendTo(*message)); mDelayedJoinEnts.Enqueue(*message); if (!mTimer.IsRunning()) { mTimer.Start(kDelayJoinEnt); } exit: if (error != OT_ERROR_NONE && message != NULL) { message->Free(); } return error; }