mirror of
https://github.com/espressif/openthread.git
synced 2026-09-07 01:30:11 +00:00
Only FTDs handle Discovery Requests and send Discovery Responses. (#998)
This commit is contained in:
+1
-165
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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; }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user