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()) switch (header.GetCommand())
{ {
case Header::kCommandDiscoveryRequest: case Header::kCommandDiscoveryRequest:
HandleDiscoveryRequest(aMessage, aMessageInfo); mMleRouter.HandleDiscoveryRequest(aMessage, aMessageInfo);
break; break;
case Header::kCommandDiscoveryResponse: case Header::kCommandDiscoveryResponse:
@@ -2551,170 +2551,6 @@ exit:
return error; 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 Mle::HandleDiscoveryResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{ {
ThreadError error = kThreadError_None; ThreadError error = kThreadError_None;
-2
View File
@@ -1210,12 +1210,10 @@ private:
ThreadError HandleParentResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, ThreadError HandleParentResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo,
uint32_t aKeySequence); uint32_t aKeySequence);
ThreadError HandleAnnounce(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo); ThreadError HandleAnnounce(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
ThreadError HandleDiscoveryRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
ThreadError HandleDiscoveryResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo); ThreadError HandleDiscoveryResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
ThreadError SendParentRequest(void); ThreadError SendParentRequest(void);
ThreadError SendChildIdRequest(void); ThreadError SendChildIdRequest(void);
ThreadError SendDiscoveryResponse(const Ip6::Address &aDestination, uint16_t aPanId);
void SendOrphanAnnounce(void); void SendOrphanAnnounce(void);
bool IsBetterParent(uint16_t aRloc16, uint8_t aLinkQuality, ConnectivityTlv &aConnectivityTlv) const; bool IsBetterParent(uint16_t aRloc16, uint8_t aLinkQuality, ConnectivityTlv &aConnectivityTlv) const;
+164
View File
@@ -2303,6 +2303,170 @@ exit:
return kThreadError_None; return kThreadError_None;
} }
ThreadError MleRouter::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 MleRouter::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 = NewMessage()) != 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 MleRouter::SendChildIdResponse(Child *aChild) ThreadError MleRouter::SendChildIdResponse(Child *aChild)
{ {
ThreadError error = kThreadError_None; ThreadError error = kThreadError_None;
+2
View File
@@ -680,6 +680,7 @@ private:
ThreadError HandleChildUpdateRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo); ThreadError HandleChildUpdateRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
ThreadError HandleDataRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo); ThreadError HandleDataRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
ThreadError HandleNetworkDataUpdateRouter(void); ThreadError HandleNetworkDataUpdateRouter(void);
ThreadError HandleDiscoveryRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
ThreadError ProcessRouteTlv(const RouteTlv &aRoute); ThreadError ProcessRouteTlv(const RouteTlv &aRoute);
void ResetAdvertiseInterval(void); void ResetAdvertiseInterval(void);
@@ -697,6 +698,7 @@ private:
ThreadError SendChildUpdateResponse(Child *aChild, const Ip6::MessageInfo &aMessageInfo, ThreadError SendChildUpdateResponse(Child *aChild, const Ip6::MessageInfo &aMessageInfo,
const uint8_t *aTlvs, uint8_t aTlvsLength, const ChallengeTlv *challenge); const uint8_t *aTlvs, uint8_t aTlvsLength, const ChallengeTlv *challenge);
ThreadError SendDataResponse(const Ip6::Address &aDestination, const uint8_t *aTlvs, uint8_t aTlvsLength); ThreadError SendDataResponse(const Ip6::Address &aDestination, const uint8_t *aTlvs, uint8_t aTlvsLength);
ThreadError SendDiscoveryResponse(const Ip6::Address &aDestination, uint16_t aPanId);
ThreadError SetStateRouter(uint16_t aRloc16); ThreadError SetStateRouter(uint16_t aRloc16);
ThreadError SetStateLeader(uint16_t aRloc16); ThreadError SetStateLeader(uint16_t aRloc16);
+1
View File
@@ -152,6 +152,7 @@ private:
ThreadError HandleChildUpdateRequest(const Message &, const Ip6::MessageInfo &) { return kThreadError_Drop; } ThreadError HandleChildUpdateRequest(const Message &, const Ip6::MessageInfo &) { return kThreadError_Drop; }
ThreadError HandleDataRequest(const Message &, const Ip6::MessageInfo &) { return kThreadError_Drop; } ThreadError HandleDataRequest(const Message &, const Ip6::MessageInfo &) { return kThreadError_Drop; }
ThreadError HandleNetworkDataUpdateRouter(void) { return kThreadError_None; } ThreadError HandleNetworkDataUpdateRouter(void) { return kThreadError_None; }
ThreadError HandleDiscoveryRequest(const Message &, const Ip6::MessageInfo &) { return kThreadError_Drop; }
ThreadError ProcessRouteTlv(const RouteTlv &aRoute) { (void)aRoute; return kThreadError_None; } ThreadError ProcessRouteTlv(const RouteTlv &aRoute) { (void)aRoute; return kThreadError_None; }