mirror of
https://github.com/espressif/openthread.git
synced 2026-08-04 01:47:47 +00:00
[nexus] add helpers for sending and validating ICMPv6 echo exchange (#12408)
This commit adds helper methods in Nexus to simplify ICMPv6 echo exchanges: - `Node::SendEchoRequest()`: sends an ICMPv6 Echo Request with configurable parameters such as payload size and hop limit. - `Core::SendAndVerifyEchoRequest()`: sends an Echo Request and validates the matching Echo Reply within a timeout. This commit also update various certification tests to use these helpers, removing duplicate local utility functions.
This commit is contained in:
@@ -51,6 +51,8 @@ Message *Icmp::NewMessage(void) { return Get<Ip6>().NewMessage(sizeof(Header));
|
||||
|
||||
Error Icmp::RegisterHandler(Handler &aHandler) { return mHandlers.Add(aHandler); }
|
||||
|
||||
Error Icmp::UnregisterHandler(Handler &aHandler) { return mHandlers.Remove(aHandler); }
|
||||
|
||||
Error Icmp::SendEchoRequest(Message &aMessage, const MessageInfo &aMessageInfo, uint16_t aIdentifier)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
@@ -236,6 +236,16 @@ public:
|
||||
*/
|
||||
Error RegisterHandler(Handler &aHandler);
|
||||
|
||||
/**
|
||||
* Unregisters an ICMPv6 handler.
|
||||
*
|
||||
* @param[in] aHandler The ICMPv6 handler.
|
||||
*
|
||||
* @retval kErrorNone The handler was successfully removed from the list.
|
||||
* @retval kErrorNotFound Could not find the handler in the list.
|
||||
*/
|
||||
Error UnregisterHandler(Handler &aHandler);
|
||||
|
||||
/**
|
||||
* Sends an ICMPv6 Echo Request message.
|
||||
*
|
||||
|
||||
@@ -415,5 +415,58 @@ void Core::ProcessTrel(Node &aNode)
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Core::IcmpEchoResponseContext::IcmpEchoResponseContext(Node &aNode, uint16_t aIdentifier)
|
||||
: mNode(aNode)
|
||||
, mIdentifier(aIdentifier)
|
||||
, mResponseReceived(false)
|
||||
{
|
||||
}
|
||||
|
||||
void Core::HandleIcmpResponse(void *aContext,
|
||||
otMessage *aMessage,
|
||||
const otMessageInfo *aMessageInfo,
|
||||
const otIcmp6Header *aIcmpHeader)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aMessage);
|
||||
|
||||
IcmpEchoResponseContext *context = static_cast<IcmpEchoResponseContext *>(aContext);
|
||||
const Ip6::Icmp::Header *header = AsCoreTypePtr(aIcmpHeader);
|
||||
const Ip6::MessageInfo *messageInfo = AsCoreTypePtr(aMessageInfo);
|
||||
|
||||
VerifyOrQuit(context != nullptr);
|
||||
VerifyOrQuit(header != nullptr);
|
||||
VerifyOrQuit(messageInfo != nullptr);
|
||||
|
||||
if ((header->GetType() == Ip6::Icmp::Header::kTypeEchoReply) && (header->GetId() == context->mIdentifier))
|
||||
{
|
||||
context->mResponseReceived = true;
|
||||
|
||||
Log("Received Echo Reply on Node %u (%s) from %s", context->mNode.GetId(), context->mNode.GetName(),
|
||||
messageInfo->GetPeerAddr().ToString().AsCString());
|
||||
}
|
||||
}
|
||||
|
||||
void Core::SendAndVerifyEchoRequest(Node &aSender,
|
||||
const Ip6::Address &aDestination,
|
||||
uint16_t aPayloadSize,
|
||||
uint8_t aHopLimit,
|
||||
uint32_t aResponseTimeout)
|
||||
{
|
||||
static constexpr uint16_t kIdentifier = 0x1234;
|
||||
|
||||
IcmpEchoResponseContext icmpContext(aSender, kIdentifier);
|
||||
Ip6::Icmp::Handler icmpHandler(HandleIcmpResponse, &icmpContext);
|
||||
|
||||
SuccessOrQuit(aSender.Get<Ip6::Icmp>().RegisterHandler(icmpHandler));
|
||||
|
||||
aSender.SendEchoRequest(aDestination, kIdentifier, aPayloadSize, aHopLimit);
|
||||
AdvanceTime(aResponseTimeout);
|
||||
VerifyOrQuit(icmpContext.mResponseReceived);
|
||||
|
||||
SuccessOrQuit(aSender.Get<Ip6::Icmp>().UnregisterHandler(icmpHandler));
|
||||
}
|
||||
|
||||
} // namespace Nexus
|
||||
} // namespace ot
|
||||
|
||||
@@ -56,7 +56,15 @@ public:
|
||||
TimeMilli GetNow(void) { return mNow; }
|
||||
void AdvanceTime(uint32_t aDuration);
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Test specific helper methods
|
||||
|
||||
void SaveTestInfo(const char *aFilename);
|
||||
void SendAndVerifyEchoRequest(Node &aSender,
|
||||
const Ip6::Address &aDestination,
|
||||
uint16_t aPayloadSize = 0,
|
||||
uint8_t aHopLimit = 64,
|
||||
uint32_t aResponseTimeout = 1000);
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Used by platform implementation
|
||||
@@ -77,6 +85,15 @@ private:
|
||||
kSendAckFramePending,
|
||||
};
|
||||
|
||||
struct IcmpEchoResponseContext
|
||||
{
|
||||
IcmpEchoResponseContext(Node &aNode, uint16_t aIdentifier);
|
||||
|
||||
Node &mNode;
|
||||
uint16_t mIdentifier;
|
||||
bool mResponseReceived;
|
||||
};
|
||||
|
||||
void Process(Node &aNode);
|
||||
void ProcessRadio(Node &aNode);
|
||||
void ProcessMdns(Node &aNode);
|
||||
@@ -84,6 +101,11 @@ private:
|
||||
void ProcessTrel(Node &aNode);
|
||||
#endif
|
||||
|
||||
static void HandleIcmpResponse(void *aContext,
|
||||
otMessage *aMessage,
|
||||
const otMessageInfo *aMessageInfo,
|
||||
const otIcmp6Header *aIcmpHeader);
|
||||
|
||||
static Core *sCore;
|
||||
static bool sInUse;
|
||||
|
||||
|
||||
@@ -103,6 +103,28 @@ void Node::AllowList(Node &aNode)
|
||||
|
||||
void Node::UnallowList(Node &aNode) { Get<Mac::Filter>().RemoveAddress(aNode.Get<Mac::Mac>().GetExtAddress()); }
|
||||
|
||||
void Node::SendEchoRequest(const Ip6::Address &aDestination,
|
||||
uint16_t aIdentifier,
|
||||
uint16_t aPayloadSize,
|
||||
uint8_t aHopLimit)
|
||||
{
|
||||
Message *message;
|
||||
Ip6::MessageInfo messageInfo;
|
||||
|
||||
message = Get<Ip6::Icmp>().NewMessage();
|
||||
VerifyOrQuit(message != nullptr);
|
||||
|
||||
SuccessOrQuit(message->SetLength(aPayloadSize));
|
||||
|
||||
messageInfo.SetPeerAddr(aDestination);
|
||||
messageInfo.SetHopLimit(aHopLimit);
|
||||
|
||||
Log("Sending Echo Request from Node %lu (%s) to %s (payload-size:%u)", ToUlong(GetId()), GetName(),
|
||||
aDestination.ToString().AsCString(), aPayloadSize);
|
||||
|
||||
SuccessOrQuit(Get<Ip6::Icmp>().SendEchoRequest(*message, messageInfo, aIdentifier));
|
||||
}
|
||||
|
||||
void Node::SetName(const char *aPrefix, uint16_t aIndex) { mName.Clear().Append("%s %u", aPrefix, aIndex); }
|
||||
|
||||
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
|
||||
|
||||
@@ -79,6 +79,10 @@ public:
|
||||
void Join(Node &aNode, JoinMode aJoinMode = kAsFtd);
|
||||
void AllowList(Node &aNode);
|
||||
void UnallowList(Node &aNode);
|
||||
void SendEchoRequest(const Ip6::Address &aDestination,
|
||||
uint16_t aIdentifier,
|
||||
uint16_t aPayloadSize = 0,
|
||||
uint8_t aHopLimit = 64);
|
||||
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
|
||||
void GetTrelSockAddr(Ip6::SockAddr &aSockAddr) const;
|
||||
#endif
|
||||
|
||||
@@ -46,42 +46,6 @@ static constexpr uint32_t kFormNetworkTime = 13 * 1000;
|
||||
*/
|
||||
static constexpr uint32_t kAttachToRouterTime = 200 * 1000;
|
||||
|
||||
/**
|
||||
* Time to wait for ICMPv6 Echo Reply.
|
||||
*/
|
||||
static constexpr uint32_t kEchoResponseTime = 1000;
|
||||
|
||||
static void HandleEchoReply(void *aContext,
|
||||
otMessage *aMessage,
|
||||
const otMessageInfo *aMessageInfo,
|
||||
const otIcmp6Header *aIcmpHeader)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aMessage);
|
||||
OT_UNUSED_VARIABLE(aMessageInfo);
|
||||
|
||||
if (aIcmpHeader->mType == OT_ICMP6_TYPE_ECHO_REPLY)
|
||||
{
|
||||
*static_cast<bool *>(aContext) = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void SendAndVerifyEchoRequest(Core &aNexus, Node &aSender, Node &aReceiver, bool &aReceivedEchoReply)
|
||||
{
|
||||
Message *message = aSender.Get<Ip6::Icmp>().NewMessage();
|
||||
Ip6::MessageInfo messageInfo;
|
||||
|
||||
VerifyOrQuit(message != nullptr);
|
||||
|
||||
messageInfo.SetPeerAddr(aReceiver.Get<Mle::Mle>().GetLinkLocalAddress());
|
||||
messageInfo.SetHopLimit(64);
|
||||
|
||||
aReceivedEchoReply = false;
|
||||
SuccessOrQuit(aSender.Get<Ip6::Icmp>().SendEchoRequest(*message, messageInfo, 0x1234));
|
||||
|
||||
aNexus.AdvanceTime(kEchoResponseTime);
|
||||
VerifyOrQuit(aReceivedEchoReply, "Echo Reply not received");
|
||||
}
|
||||
|
||||
void Test5_1_1(void)
|
||||
{
|
||||
/**
|
||||
@@ -177,26 +141,16 @@ void Test5_1_1(void)
|
||||
* - Pass Criteria:
|
||||
* - The DUT MUST respond with ICMPv6 Echo Reply
|
||||
*/
|
||||
bool routerReceivedEchoReply = false;
|
||||
Ip6::Icmp::Handler routerIcmpHandler(HandleEchoReply, &routerReceivedEchoReply);
|
||||
bool leaderReceivedEchoReply = false;
|
||||
Ip6::Icmp::Handler leaderIcmpHandler(HandleEchoReply, &leaderReceivedEchoReply);
|
||||
|
||||
// 1. Verify Leader as DUT: Router (Reference) sends Echo Request to Leader (DUT) Link-Local address
|
||||
SuccessOrQuit(router.Get<Ip6::Icmp>().RegisterHandler(routerIcmpHandler));
|
||||
|
||||
Log("Step 11.1: Sending Echo Request from Router to Leader Link-Local: %s",
|
||||
leader.Get<Mle::Mle>().GetLinkLocalAddress().ToString().AsCString());
|
||||
SendAndVerifyEchoRequest(nexus, router, leader, routerReceivedEchoReply);
|
||||
Log("Leader (as DUT) responded with Echo Reply successfully");
|
||||
Log("Step 11.1: Sending Echo Request from Router to Leader Link-Local");
|
||||
nexus.SendAndVerifyEchoRequest(router, leader.Get<Mle::Mle>().GetLinkLocalAddress());
|
||||
|
||||
// 2. Verify Router as DUT: Leader (Reference) sends Echo Request to Router (DUT) Link-Local address
|
||||
SuccessOrQuit(leader.Get<Ip6::Icmp>().RegisterHandler(leaderIcmpHandler));
|
||||
|
||||
Log("Step 11.2: Sending Echo Request from Leader to Router Link-Local: %s",
|
||||
router.Get<Mle::Mle>().GetLinkLocalAddress().ToString().AsCString());
|
||||
SendAndVerifyEchoRequest(nexus, leader, router, leaderReceivedEchoReply);
|
||||
Log("Router (as DUT) responded with Echo Reply successfully");
|
||||
Log("Step 11.2: Sending Echo Request from Leader to Router Link-Local");
|
||||
nexus.SendAndVerifyEchoRequest(leader, router.Get<Mle::Mle>().GetLinkLocalAddress());
|
||||
|
||||
nexus.SaveTestInfo("test_5_1_1.json");
|
||||
}
|
||||
|
||||
@@ -64,17 +64,6 @@ static constexpr uint32_t kChildTimeoutWaitTime = (kChildTimeout + 2) * 1000;
|
||||
*/
|
||||
static constexpr uint32_t kEchoRequestWaitTime = 5 * 1000;
|
||||
|
||||
static void SendEchoRequest(Node &aSender, const Ip6::Address &aPeerAddr, uint16_t aIdentifier)
|
||||
{
|
||||
Message *message = aSender.Get<Ip6::Icmp>().NewMessage();
|
||||
Ip6::MessageInfo messageInfo;
|
||||
|
||||
VerifyOrQuit(message != nullptr);
|
||||
messageInfo.SetPeerAddr(aPeerAddr);
|
||||
messageInfo.SetHopLimit(64);
|
||||
SuccessOrQuit(aSender.Get<Ip6::Icmp>().SendEchoRequest(*message, messageInfo, aIdentifier));
|
||||
}
|
||||
|
||||
void Test5_1_2(void)
|
||||
{
|
||||
/**
|
||||
@@ -167,7 +156,7 @@ void Test5_1_2(void)
|
||||
* Leader automatically attempts to perform address resolution by sending an Address Query Request
|
||||
* - Pass Criteria: N/A
|
||||
*/
|
||||
SendEchoRequest(leader, med.Get<Mle::Mle>().GetMeshLocalEid(), 0x1234);
|
||||
leader.SendEchoRequest(med.Get<Mle::Mle>().GetMeshLocalEid(), 0x1234);
|
||||
|
||||
Log("---------------------------------------------------------------------------------------");
|
||||
Log("Step 4: Router_1 (DUT)");
|
||||
@@ -188,7 +177,7 @@ void Test5_1_2(void)
|
||||
* Leader automatically attempts to perform address resolution by sending an Address Query Request
|
||||
* - Pass Criteria: N/A
|
||||
*/
|
||||
SendEchoRequest(leader, sed.Get<Mle::Mle>().GetMeshLocalEid(), 0x5678);
|
||||
leader.SendEchoRequest(sed.Get<Mle::Mle>().GetMeshLocalEid(), 0x5678);
|
||||
|
||||
Log("---------------------------------------------------------------------------------------");
|
||||
Log("Step 7: Router_1 (DUT)");
|
||||
|
||||
@@ -46,52 +46,6 @@ static constexpr uint32_t kFormNetworkTime = 13 * 1000;
|
||||
*/
|
||||
static constexpr uint32_t kAttachToRouterTime = 200 * 1000;
|
||||
|
||||
/**
|
||||
* Time to wait for ICMPv6 Echo Response.
|
||||
*/
|
||||
static constexpr uint32_t kEchoResponseTime = 1000;
|
||||
|
||||
/**
|
||||
* ICMPv6 Echo Request identifier.
|
||||
*/
|
||||
static constexpr uint16_t kEchoIdentifier = 0x1234;
|
||||
|
||||
/**
|
||||
* ICMPv6 Hop Limit.
|
||||
*/
|
||||
static constexpr uint8_t kHopLimit = 64;
|
||||
|
||||
static void HandleEchoReply(void *aContext,
|
||||
otMessage *aMessage,
|
||||
const otMessageInfo *aMessageInfo,
|
||||
const otIcmp6Header *aIcmpHeader)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aMessage);
|
||||
OT_UNUSED_VARIABLE(aMessageInfo);
|
||||
|
||||
if (aIcmpHeader->mType == OT_ICMP6_TYPE_ECHO_REPLY)
|
||||
{
|
||||
*static_cast<bool *>(aContext) = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void SendAndVerifyEchoRequest(Core &aNexus, Node &aSender, Node &aReceiver, bool &aReceivedEchoReply)
|
||||
{
|
||||
Message *message = aSender.Get<Ip6::Icmp>().NewMessage();
|
||||
Ip6::MessageInfo messageInfo;
|
||||
|
||||
VerifyOrQuit(message != nullptr);
|
||||
|
||||
messageInfo.SetPeerAddr(aReceiver.Get<Mle::Mle>().GetLinkLocalAddress());
|
||||
messageInfo.SetHopLimit(kHopLimit);
|
||||
|
||||
aReceivedEchoReply = false;
|
||||
SuccessOrQuit(aSender.Get<Ip6::Icmp>().SendEchoRequest(*message, messageInfo, kEchoIdentifier));
|
||||
|
||||
aNexus.AdvanceTime(kEchoResponseTime);
|
||||
VerifyOrQuit(aReceivedEchoReply, "Echo Reply not received");
|
||||
}
|
||||
|
||||
void Test5_1_6(void)
|
||||
{
|
||||
/**
|
||||
@@ -151,11 +105,7 @@ void Test5_1_6(void)
|
||||
* - Pass Criteria:
|
||||
* - The DUT MUST respond with an ICMPv6 Echo Reply
|
||||
*/
|
||||
bool leaderReceivedEchoReply = false;
|
||||
Ip6::Icmp::Handler leaderIcmpHandler(HandleEchoReply, &leaderReceivedEchoReply);
|
||||
SuccessOrQuit(leader.Get<Ip6::Icmp>().RegisterHandler(leaderIcmpHandler));
|
||||
|
||||
SendAndVerifyEchoRequest(nexus, leader, router, leaderReceivedEchoReply);
|
||||
nexus.SendAndVerifyEchoRequest(leader, router.Get<Mle::Mle>().GetLinkLocalAddress());
|
||||
|
||||
Log("---------------------------------------------------------------------------------------");
|
||||
Log("Step 2: Harness instructs the Leader to remove the Router ID of Router_1 (the DUT)");
|
||||
@@ -191,7 +141,7 @@ void Test5_1_6(void)
|
||||
* - Pass Criteria:
|
||||
* - The DUT MUST respond with an ICMPv6 Echo Reply
|
||||
*/
|
||||
SendAndVerifyEchoRequest(nexus, leader, router, leaderReceivedEchoReply);
|
||||
nexus.SendAndVerifyEchoRequest(leader, router.Get<Mle::Mle>().GetLinkLocalAddress());
|
||||
|
||||
nexus.SaveTestInfo("test_5_1_6.json");
|
||||
}
|
||||
|
||||
@@ -73,14 +73,14 @@ static constexpr uint16_t kIp6HeaderSize = 40;
|
||||
static constexpr uint16_t kIcmp6HeaderSize = 8;
|
||||
|
||||
/**
|
||||
* Small ICMPv6 Echo Request datagram size in octets.
|
||||
* Small ICMPv6 Echo Request payload size in octets.
|
||||
*/
|
||||
static constexpr uint16_t kSmallDatagramSize = 106;
|
||||
static constexpr uint16_t kSmallIcmpEchoPayloadSize = 106 - kIp6HeaderSize - kIcmp6HeaderSize;
|
||||
|
||||
/**
|
||||
* Large ICMPv6 Echo Request datagram size in octets.
|
||||
*/
|
||||
static constexpr uint16_t kLargeDatagramSize = 1280;
|
||||
static constexpr uint16_t kLargeIcmpEchoPayloadSize = 1280 - kIp6HeaderSize - kIcmp6HeaderSize;
|
||||
|
||||
/**
|
||||
* Time to wait for ICMPv6 Echo replies.
|
||||
@@ -97,38 +97,6 @@ static constexpr uint16_t kMedEchoId = 1001;
|
||||
*/
|
||||
static constexpr uint16_t kSedEchoId = 2001;
|
||||
|
||||
static void SendEchoRequest(Node &aSender, const Ip6::Address &aPeerAddr, uint16_t aDatagramSize, uint16_t aIdentifier)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Message *message = aSender.Get<Ip6::Icmp>().NewMessage();
|
||||
Ip6::MessageInfo messageInfo;
|
||||
uint16_t payloadLength;
|
||||
|
||||
VerifyOrQuit(message != nullptr);
|
||||
|
||||
VerifyOrExit(aDatagramSize >= kIp6HeaderSize + kIcmp6HeaderSize, error = kErrorInvalidArgs);
|
||||
payloadLength = aDatagramSize - kIp6HeaderSize - kIcmp6HeaderSize;
|
||||
|
||||
error = message->SetLength(payloadLength);
|
||||
SuccessOrExit(error);
|
||||
|
||||
messageInfo.SetPeerAddr(aPeerAddr);
|
||||
messageInfo.SetHopLimit(64);
|
||||
|
||||
error = aSender.Get<Ip6::Icmp>().SendEchoRequest(*message, messageInfo, aIdentifier);
|
||||
SuccessOrExit(error);
|
||||
|
||||
message = nullptr;
|
||||
|
||||
exit:
|
||||
if (message != nullptr)
|
||||
{
|
||||
message->Free();
|
||||
}
|
||||
|
||||
SuccessOrQuit(error);
|
||||
}
|
||||
|
||||
static void CreateNodes(Core &aNexus, Node *aNodes[], uint16_t aCount, const char *aNamePrefix)
|
||||
{
|
||||
for (uint16_t i = 0; i < aCount; i++)
|
||||
@@ -249,8 +217,9 @@ void Test5_1_7(void)
|
||||
*/
|
||||
for (uint16_t i = 0; i < kNumMeds; i++)
|
||||
{
|
||||
SendEchoRequest(leader, meds[i]->Get<Mle::Mle>().GetMeshLocalEid(), kSmallDatagramSize, kMedEchoId + i);
|
||||
leader.SendEchoRequest(meds[i]->Get<Mle::Mle>().GetMeshLocalEid(), kMedEchoId + i, kSmallIcmpEchoPayloadSize);
|
||||
}
|
||||
|
||||
nexus.AdvanceTime(kEchoResponseWaitTime);
|
||||
|
||||
Log("---------------------------------------------------------------------------------------");
|
||||
@@ -266,11 +235,13 @@ void Test5_1_7(void)
|
||||
* - The DUT MUST properly forward ICMPv6 Echo Requests to all SED children.
|
||||
* - The DUT MUST properly forward ICMPv6 Echo Replies to the Leader.
|
||||
*/
|
||||
SendEchoRequest(leader, seds[0]->Get<Mle::Mle>().GetMeshLocalEid(), kLargeDatagramSize, kSedEchoId);
|
||||
leader.SendEchoRequest(seds[0]->Get<Mle::Mle>().GetMeshLocalEid(), kSedEchoId, kLargeIcmpEchoPayloadSize);
|
||||
|
||||
for (uint16_t i = 1; i < kNumSeds; i++)
|
||||
{
|
||||
SendEchoRequest(leader, seds[i]->Get<Mle::Mle>().GetMeshLocalEid(), kSmallDatagramSize, kSedEchoId + i);
|
||||
leader.SendEchoRequest(seds[i]->Get<Mle::Mle>().GetMeshLocalEid(), kSedEchoId + i, kSmallIcmpEchoPayloadSize);
|
||||
}
|
||||
|
||||
nexus.AdvanceTime(kEchoResponseWaitTime);
|
||||
|
||||
nexus.SaveTestInfo("test_5_1_7.json");
|
||||
|
||||
@@ -51,52 +51,6 @@ static constexpr uint32_t kAttachToRouterTime = 200 * 1000;
|
||||
*/
|
||||
static constexpr uint32_t kAttachToChildTime = 10 * 1000;
|
||||
|
||||
/**
|
||||
* Time to wait for ICMPv6 Echo Reply.
|
||||
*/
|
||||
static constexpr uint32_t kEchoResponseTime = 1000;
|
||||
|
||||
static void HandleEchoReply(void *aContext,
|
||||
otMessage *aMessage,
|
||||
const otMessageInfo *aMessageInfo,
|
||||
const otIcmp6Header *aIcmpHeader)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aMessage);
|
||||
OT_UNUSED_VARIABLE(aMessageInfo);
|
||||
|
||||
if (aIcmpHeader->mType == OT_ICMP6_TYPE_ECHO_REPLY)
|
||||
{
|
||||
*static_cast<bool *>(aContext) = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void SendAndVerifyEchoRequest(Core &aNexus,
|
||||
Node &aSender,
|
||||
const Ip6::Address &aReceiverAddr,
|
||||
bool &aReceivedEchoReply)
|
||||
{
|
||||
Message *message = aSender.Get<Ip6::Icmp>().NewMessage();
|
||||
Ip6::MessageInfo messageInfo;
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrQuit(message != nullptr);
|
||||
|
||||
messageInfo.SetPeerAddr(aReceiverAddr);
|
||||
messageInfo.SetHopLimit(64);
|
||||
|
||||
aReceivedEchoReply = false;
|
||||
|
||||
error = aSender.Get<Ip6::Icmp>().SendEchoRequest(*message, messageInfo, 0x1234);
|
||||
if (error != kErrorNone)
|
||||
{
|
||||
message->Free();
|
||||
SuccessOrQuit(error);
|
||||
}
|
||||
|
||||
aNexus.AdvanceTime(kEchoResponseTime);
|
||||
VerifyOrQuit(aReceivedEchoReply, "Echo Reply not received");
|
||||
}
|
||||
|
||||
void Test5_2_1(void)
|
||||
{
|
||||
/**
|
||||
@@ -256,11 +210,7 @@ void Test5_2_1(void)
|
||||
* - Pass Criteria:
|
||||
* - REED_1 responds with ICMPv6 Echo Reply.
|
||||
*/
|
||||
bool reed1ReceivedEchoReply = false;
|
||||
Ip6::Icmp::Handler leaderIcmpHandler(HandleEchoReply, &reed1ReceivedEchoReply);
|
||||
leader.Get<Ip6::Icmp>().RegisterHandler(leaderIcmpHandler);
|
||||
|
||||
SendAndVerifyEchoRequest(nexus, leader, reed1.Get<Mle::Mle>().GetMeshLocalEid(), reed1ReceivedEchoReply);
|
||||
nexus.SendAndVerifyEchoRequest(leader, reed1.Get<Mle::Mle>().GetMeshLocalEid());
|
||||
|
||||
nexus.SaveTestInfo("test_5_2_1.json");
|
||||
}
|
||||
|
||||
@@ -60,26 +60,11 @@ static constexpr uint32_t kReedAdvertisementMaxJitter = 60 * 1000;
|
||||
*/
|
||||
static constexpr uint32_t kWaitTime = kReedAdvertisementInterval + kReedAdvertisementMaxJitter;
|
||||
|
||||
/**
|
||||
* Time to wait for ICMPv6 Echo Response.
|
||||
*/
|
||||
static constexpr uint32_t kEchoResponseTime = 1000;
|
||||
|
||||
/**
|
||||
* Number of routers in the topology besides the leader.
|
||||
*/
|
||||
static constexpr uint16_t kNumRouters = 15;
|
||||
|
||||
/**
|
||||
* Hop limit for ICMPv6 Echo Request.
|
||||
*/
|
||||
static constexpr uint8_t kEchoHopLimit = 64;
|
||||
|
||||
/**
|
||||
* Echo Request Identifier.
|
||||
*/
|
||||
static constexpr uint16_t kEchoIdentifier = 0x1234;
|
||||
|
||||
void Test5_2_4(void)
|
||||
{
|
||||
/**
|
||||
@@ -281,18 +266,7 @@ void Test5_2_4(void)
|
||||
* Leader.
|
||||
* - Pass Criteria: The Leader MUST respond with an ICMPv6 Echo Reply.
|
||||
*/
|
||||
{
|
||||
Message *message = med1.Get<Ip6::Icmp>().NewMessage();
|
||||
Ip6::MessageInfo messageInfo;
|
||||
|
||||
VerifyOrQuit(message != nullptr);
|
||||
messageInfo.SetPeerAddr(leader.Get<Mle::Mle>().GetMeshLocalEid());
|
||||
messageInfo.SetHopLimit(kEchoHopLimit);
|
||||
|
||||
SuccessOrQuit(med1.Get<Ip6::Icmp>().SendEchoRequest(*message, messageInfo, kEchoIdentifier));
|
||||
}
|
||||
|
||||
nexus.AdvanceTime(kEchoResponseTime);
|
||||
nexus.SendAndVerifyEchoRequest(med1, leader.Get<Mle::Mle>().GetMeshLocalEid());
|
||||
|
||||
nexus.SaveTestInfo("test_5_2_4.json");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user