Only FTDs handle Discovery Requests and send Discovery Responses. (#998)

This commit is contained in:
Jonathan Hui
2016-11-21 19:04:37 +00:00
committed by GitHub
parent f37e413c7b
commit d8aae52899
5 changed files with 168 additions and 167 deletions
+1 -165
View File
@@ -1659,7 +1659,7 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn
switch (header.GetCommand())
{
case Header::kCommandDiscoveryRequest:
HandleDiscoveryRequest(aMessage, aMessageInfo);
mMleRouter.HandleDiscoveryRequest(aMessage, aMessageInfo);
break;
case Header::kCommandDiscoveryResponse:
@@ -2551,170 +2551,6 @@ exit:
return error;
}
ThreadError Mle::HandleDiscoveryRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
ThreadError error = kThreadError_None;
Tlv tlv;
MeshCoP::Tlv meshcopTlv;
MeshCoP::DiscoveryRequestTlv discoveryRequest;
MeshCoP::ExtendedPanIdTlv extPanId;
uint16_t offset;
uint16_t end;
otLogInfoMle("Received discovery request");
// only Routers and REEDs respond
VerifyOrExit((mDeviceMode & ModeTlv::kModeFFD) != 0, ;);
offset = aMessage.GetOffset();
end = aMessage.GetLength();
// find MLE Discovery TLV
while (offset < end)
{
aMessage.Read(offset, sizeof(tlv), &tlv);
if (tlv.GetType() == Tlv::kDiscovery)
{
break;
}
offset += sizeof(tlv) + tlv.GetLength();
}
VerifyOrExit(offset < end, error = kThreadError_Parse);
offset += sizeof(tlv);
end = offset + sizeof(tlv) + tlv.GetLength();
while (offset < end)
{
aMessage.Read(offset, sizeof(meshcopTlv), &meshcopTlv);
switch (meshcopTlv.GetType())
{
case MeshCoP::Tlv::kDiscoveryRequest:
aMessage.Read(offset, sizeof(discoveryRequest), &discoveryRequest);
VerifyOrExit(discoveryRequest.IsValid(), error = kThreadError_Parse);
break;
case MeshCoP::Tlv::kExtendedPanId:
aMessage.Read(offset, sizeof(extPanId), &extPanId);
VerifyOrExit(extPanId.IsValid(), error = kThreadError_Parse);
VerifyOrExit(memcmp(mMac.GetExtendedPanId(), extPanId.GetExtendedPanId(), OT_EXT_PAN_ID_SIZE),
error = kThreadError_Drop);
break;
default:
break;
}
offset += sizeof(meshcopTlv) + meshcopTlv.GetLength();
}
error = SendDiscoveryResponse(aMessageInfo.GetPeerAddr(), aMessage.GetPanId());
exit:
if (error != kThreadError_None)
{
otLogWarnMleErr(error, "Failed to process Discovery Request");
}
return error;
}
ThreadError Mle::SendDiscoveryResponse(const Ip6::Address &aDestination, uint16_t aPanId)
{
ThreadError error = kThreadError_None;
Message *message;
uint16_t startOffset;
Tlv tlv;
MeshCoP::DiscoveryResponseTlv discoveryResponse;
MeshCoP::ExtendedPanIdTlv extPanId;
MeshCoP::NetworkNameTlv networkName;
MeshCoP::JoinerUdpPortTlv joinerUdpPort;
uint8_t *cur;
uint8_t length;
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, ;);
message->SetLinkSecurityEnabled(false);
message->SetSubType(Message::kSubTypeMleDiscoverResponse);
message->SetPanId(aPanId);
SuccessOrExit(error = AppendHeader(*message, Header::kCommandDiscoveryResponse));
// Discovery TLV
tlv.SetType(Tlv::kDiscovery);
SuccessOrExit(error = message->Append(&tlv, sizeof(tlv)));
startOffset = message->GetLength();
// Discovery Response TLV
discoveryResponse.Init();
discoveryResponse.SetVersion(kVersion);
if (mNetif.GetKeyManager().GetSecurityPolicyFlags() & OT_SECURITY_POLICY_NATIVE_COMMISSIONING)
{
discoveryResponse.SetNativeCommissioner(true);
}
else
{
discoveryResponse.SetNativeCommissioner(false);
}
SuccessOrExit(error = message->Append(&discoveryResponse, sizeof(discoveryResponse)));
// Extended PAN ID TLV
extPanId.Init();
extPanId.SetExtendedPanId(mMac.GetExtendedPanId());
SuccessOrExit(error = message->Append(&extPanId, sizeof(extPanId)));
// Network Name TLV
networkName.Init();
networkName.SetNetworkName(mMac.GetNetworkName());
SuccessOrExit(error = message->Append(&networkName, sizeof(tlv) + networkName.GetLength()));
// Steering Data TLV
if ((cur = mNetif.GetNetworkDataLeader().GetCommissioningData(length)) != NULL)
{
uint8_t *end = cur + length;
while (cur < end)
{
MeshCoP::Tlv *meshcop = reinterpret_cast<MeshCoP::Tlv *>(cur);
if (meshcop->GetType() == MeshCoP::Tlv::kSteeringData)
{
SuccessOrExit(message->Append(meshcop, sizeof(*meshcop) + meshcop->GetLength()));
break;
}
cur += sizeof(*meshcop) + meshcop->GetLength();
}
}
// Joiner UDP Port TLV
joinerUdpPort.Init();
joinerUdpPort.SetUdpPort(mJoinerRouter.GetJoinerUdpPort());
SuccessOrExit(error = message->Append(&joinerUdpPort, sizeof(tlv) + joinerUdpPort.GetLength()));
tlv.SetLength(static_cast<uint8_t>(message->GetLength() - startOffset));
message->Write(startOffset - sizeof(tlv), sizeof(tlv), &tlv);
SuccessOrExit(error = SendMessage(*message, aDestination));
otLogInfoMle("Sent discovery response");
exit:
if (error != kThreadError_None && message != NULL)
{
message->Free();
}
return error;
}
ThreadError Mle::HandleDiscoveryResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
ThreadError error = kThreadError_None;