lr-wpan: Modify test to check for ACK correctness

This commit is contained in:
Tommaso Pecorella
2020-12-29 00:50:17 +01:00
parent e444d145ac
commit bcfe223809

View File

@@ -17,6 +17,8 @@
*
* Author:
* Sascha Alexander Jopen <jopen@cs.uni-bonn.de>
* Modifications:
* Tommaso Pecorella <tommaso.pecorella@unifi.it>
*/
#include <ns3/log.h>
@@ -31,6 +33,9 @@
#include "ns3/rng-seed-manager.h"
#include <iostream>
#include <string>
#include <fstream>
#include <streambuf>
using namespace ns3;
@@ -50,129 +55,117 @@ NS_LOG_COMPONENT_DEFINE ("lr-wpan-ack-test");
class LrWpanAckTestCase : public TestCase
{
public:
LrWpanAckTestCase ();
typedef enum
{
EXTENDED_ADDRESS_UNICAST,
SHORT_ADDRESS_UNICAST,
SHORT_ADDRESS_MULTICAST,
SHORT_ADDRESS_BROADCAST,
} TestMode_e;
/**
* \brief Function called when DataIndication is hit.
* Create test case
*
* \param prefix Unique file names prefix
* \param mode Test mode
*/
LrWpanAckTestCase (const char * const prefix, TestMode_e mode);
/**
* \brief Function called when DataIndication is hit on dev0.
* \param testCase The TestCase.
* \param dev The LrWpanNetDevice.
* \param params The MCPS params.
* \param p the packet.
*/
static void DataIndication (LrWpanAckTestCase *testCase, Ptr<LrWpanNetDevice> dev, McpsDataIndicationParams params, Ptr<Packet> p);
void DataIndicationDev0 (McpsDataIndicationParams params, Ptr<Packet> p);
/**
* \brief Function called when DataConfirm is hit.
* \brief Function called when DataIndication is hit on dev1.
* \param testCase The TestCase.
* \param dev The LrWpanNetDevice.
* \param params The MCPS params.
*/
static void DataConfirm (LrWpanAckTestCase *testCase, Ptr<LrWpanNetDevice> dev, McpsDataConfirmParams params);
/**
* \brief Function called when DataIndication is hit in extended addressing test.
* \param testCase The TestCase.
* \param dev The LrWpanNetDevice.
* \param params The MCPS params.
* \param p the packet.
*/
static void ExtendedAddressingDataIndication (LrWpanAckTestCase *testCase, Ptr<LrWpanNetDevice> dev, McpsDataIndicationParams params, Ptr<Packet> p);
void DataIndicationDev1 (McpsDataIndicationParams params, Ptr<Packet> p);
/**
* \brief Function called when DataConfirm is hit in extended addressing test.
* \brief Function called when DataConfirm is hit on dev0.
* \param testCase The TestCase.
* \param dev The LrWpanNetDevice.
* \param params The MCPS params.
*/
static void ExtendedAddressingDataConfirm (LrWpanAckTestCase *testCase, Ptr<LrWpanNetDevice> dev, McpsDataConfirmParams params);
void DataConfirmDev0 (McpsDataConfirmParams params);
/**
* \brief Function called when DataConfirm is hit on dev1.
* \param testCase The TestCase.
* \param params The MCPS params.
*/
void DataConfirmDev1 (McpsDataConfirmParams params);
private:
virtual void DoRun (void);
std::string m_prefix; //!< Filename prefix
Time m_requestTime; //!< Request time.
Time m_requestAckTime; //!< Request ack time.
Time m_requestSentTime; //!< Request successfully sent time.
Time m_replyTime; //!< Reply time.
Time m_replyAckTime; //!< Reply ack time.
Time m_replySentTime; //!< Reply successfully sent time.
Time m_replyArrivalTime; //!< Reply arrival time.
TestMode_e m_mode; //!< Test mode.
Ptr<LrWpanNetDevice> m_dev0; //!< 1st LrWpanNetDevice.
Ptr<LrWpanNetDevice> m_dev1; //!< 2nd LrWpanNetDevice.
};
LrWpanAckTestCase::LrWpanAckTestCase ()
LrWpanAckTestCase::LrWpanAckTestCase (const char * const prefix, TestMode_e mode)
: TestCase ("Test the 802.15.4 ACK handling")
{
m_prefix = prefix;
m_requestTime = Seconds (0);
m_requestAckTime = Seconds (0);
m_requestSentTime = Seconds (0);
m_replyTime = Seconds (0);
m_replyAckTime = Seconds (0);
m_replySentTime = Seconds (0);
m_replyArrivalTime = Seconds (0);
m_mode = mode;
}
void
LrWpanAckTestCase::DataIndication (LrWpanAckTestCase *testCase, Ptr<LrWpanNetDevice> dev, McpsDataIndicationParams params, Ptr<Packet> p)
LrWpanAckTestCase::DataIndicationDev0 (McpsDataIndicationParams params, Ptr<Packet> p)
{
if (dev->GetMac ()->GetShortAddress () == Mac16Address ("00:02"))
{
Ptr<Packet> p = Create<Packet> (10); // 10 bytes of dummy data
McpsDataRequestParams params;
params.m_srcAddrMode = SHORT_ADDR;
params.m_dstAddrMode = SHORT_ADDR;
params.m_dstPanId = 0;
params.m_dstAddr = Mac16Address ("00:01");
params.m_msduHandle = 0;
params.m_txOptions = TX_OPTION_NONE;
testCase->m_replyTime = Simulator::Now ();
dev->GetMac ()->McpsDataRequest (params, p);
}
else
{
testCase->m_replyArrivalTime = Simulator::Now ();
}
m_replyArrivalTime = Simulator::Now ();
}
void
LrWpanAckTestCase::DataConfirm (LrWpanAckTestCase *testCase, Ptr<LrWpanNetDevice> dev, McpsDataConfirmParams params)
LrWpanAckTestCase::DataIndicationDev1 (McpsDataIndicationParams params, Ptr<Packet> p)
{
if (dev->GetMac ()->GetShortAddress () == Mac16Address ("00:01"))
Ptr<Packet> pkt = Create<Packet> (10); // 10 bytes of dummy data
McpsDataRequestParams replyParams;
replyParams.m_dstPanId = 0;
replyParams.m_msduHandle = 0;
replyParams.m_txOptions = TX_OPTION_NONE;
if (m_mode == EXTENDED_ADDRESS_UNICAST)
{
testCase->m_requestAckTime = Simulator::Now ();
}
replyParams.m_srcAddrMode = EXT_ADDR;
replyParams.m_dstAddrMode = EXT_ADDR;
replyParams.m_dstExtAddr = Mac64Address ("00:00:00:00:00:00:00:01");
}
else
{
testCase->m_replyAckTime = Simulator::Now ();
replyParams.m_srcAddrMode = SHORT_ADDR;
replyParams.m_dstAddrMode = SHORT_ADDR;
replyParams.m_dstAddr = Mac16Address ("00:01");
}
m_replyTime = Simulator::Now ();
m_dev1->GetMac ()->McpsDataRequest (replyParams, pkt);
}
void
LrWpanAckTestCase::ExtendedAddressingDataIndication (LrWpanAckTestCase *testCase, Ptr<LrWpanNetDevice> dev, McpsDataIndicationParams params, Ptr<Packet> p)
LrWpanAckTestCase::DataConfirmDev0 (McpsDataConfirmParams params)
{
if (dev->GetMac ()->GetExtendedAddress () == Mac64Address ("00:00:00:00:00:00:00:02"))
{
Ptr<Packet> p = Create<Packet> (10); // 10 bytes of dummy data
McpsDataRequestParams params;
params.m_srcAddrMode = EXT_ADDR;
params.m_dstAddrMode = EXT_ADDR;
params.m_dstPanId = 0;
params.m_dstExtAddr = Mac64Address ("00:00:00:00:00:00:00:01");
params.m_msduHandle = 0;
params.m_txOptions = TX_OPTION_NONE;
testCase->m_replyTime = Simulator::Now ();
dev->GetMac ()->McpsDataRequest (params, p);
}
else
{
testCase->m_replyArrivalTime = Simulator::Now ();
}
m_requestSentTime = Simulator::Now ();
}
void
LrWpanAckTestCase::ExtendedAddressingDataConfirm (LrWpanAckTestCase *testCase, Ptr<LrWpanNetDevice> dev, McpsDataConfirmParams params)
LrWpanAckTestCase::DataConfirmDev1 (McpsDataConfirmParams params)
{
if (dev->GetMac ()->GetExtendedAddress () == Mac64Address ("00:00:00:00:00:00:00:01"))
{
testCase->m_requestAckTime = Simulator::Now ();
}
else
{
testCase->m_replyAckTime = Simulator::Now ();
}
m_replySentTime = Simulator::Now ();
}
void
@@ -184,7 +177,8 @@ LrWpanAckTestCase::DoRun (void)
// immediately answers with a reply packet on reception of the request.
// We expect the ACK of the request packet to always arrive at node 1 before
// the reply packet sent by node 2.
// The same is repeated for extended addressing mode.
// This, of course, unelss the packet is sent to a broadcast or multicast address
// in this case we don't expect any ACK.
// Enable calculation of FCS in the trailers. Only necessary when interacting with real devices or wireshark.
// GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true));
@@ -193,19 +187,27 @@ LrWpanAckTestCase::DoRun (void)
RngSeedManager::SetSeed (1);
RngSeedManager::SetRun (6);
// Helper - used to create traces
LrWpanHelper helper;
std::string asciiPrefix;
// Create 2 nodes, and a NetDevice for each one
Ptr<Node> n0 = CreateObject <Node> ();
Ptr<Node> n1 = CreateObject <Node> ();
Ptr<LrWpanNetDevice> dev0 = CreateObject<LrWpanNetDevice> ();
Ptr<LrWpanNetDevice> dev1 = CreateObject<LrWpanNetDevice> ();
m_dev0 = CreateObject<LrWpanNetDevice> ();
m_dev1 = CreateObject<LrWpanNetDevice> ();
// Make random variable stream assignment deterministic
dev0->AssignStreams (0);
dev1->AssignStreams (10);
m_dev0->AssignStreams (0);
m_dev1->AssignStreams (10);
dev0->SetAddress (Mac16Address ("00:01"));
dev1->SetAddress (Mac16Address ("00:02"));
// Add short addresses.
m_dev0->SetAddress (Mac16Address ("00:01"));
m_dev1->SetAddress (Mac16Address ("00:02"));
// Add extended addresses.
m_dev0->GetMac()->SetExtendedAddress (Mac64Address ("00:00:00:00:00:00:00:01"));
m_dev1->GetMac()->SetExtendedAddress (Mac64Address ("00:00:00:00:00:00:00:02"));
// Each device must be attached to the same channel
Ptr<SingleModelSpectrumChannel> channel = CreateObject<SingleModelSpectrumChannel> ();
@@ -214,101 +216,102 @@ LrWpanAckTestCase::DoRun (void)
channel->AddPropagationLossModel (propModel);
channel->SetPropagationDelayModel (delayModel);
dev0->SetChannel (channel);
dev1->SetChannel (channel);
m_dev0->SetChannel (channel);
m_dev1->SetChannel (channel);
// To complete configuration, a LrWpanNetDevice must be added to a node
n0->AddDevice (dev0);
n1->AddDevice (dev1);
n0->AddDevice (m_dev0);
n1->AddDevice (m_dev1);
Ptr<ConstantPositionMobilityModel> sender0Mobility = CreateObject<ConstantPositionMobilityModel> ();
sender0Mobility->SetPosition (Vector (0,0,0));
dev0->GetPhy ()->SetMobility (sender0Mobility);
m_dev0->GetPhy ()->SetMobility (sender0Mobility);
Ptr<ConstantPositionMobilityModel> sender1Mobility = CreateObject<ConstantPositionMobilityModel> ();
// Configure position 10 m distance
sender1Mobility->SetPosition (Vector (0,10,0));
dev1->GetPhy ()->SetMobility (sender1Mobility);
m_dev1->GetPhy ()->SetMobility (sender1Mobility);
McpsDataConfirmCallback cb0;
cb0 = MakeBoundCallback (&LrWpanAckTestCase::DataConfirm, this, dev0);
dev0->GetMac ()->SetMcpsDataConfirmCallback (cb0);
cb0 = MakeCallback (&LrWpanAckTestCase::DataConfirmDev0, this);
m_dev0->GetMac ()->SetMcpsDataConfirmCallback (cb0);
McpsDataIndicationCallback cb1;
cb1 = MakeBoundCallback (&LrWpanAckTestCase::DataIndication, this, dev0);
dev0->GetMac ()->SetMcpsDataIndicationCallback (cb1);
cb1 = MakeCallback (&LrWpanAckTestCase::DataIndicationDev0, this);
m_dev0->GetMac ()->SetMcpsDataIndicationCallback (cb1);
McpsDataConfirmCallback cb2;
cb2 = MakeBoundCallback (&LrWpanAckTestCase::DataConfirm, this, dev1);
dev1->GetMac ()->SetMcpsDataConfirmCallback (cb2);
cb2 = MakeCallback (&LrWpanAckTestCase::DataConfirmDev1, this);
m_dev1->GetMac ()->SetMcpsDataConfirmCallback (cb2);
McpsDataIndicationCallback cb3;
cb3 = MakeBoundCallback (&LrWpanAckTestCase::DataIndication, this, dev1);
dev1->GetMac ()->SetMcpsDataIndicationCallback (cb3);
cb3 = MakeCallback (&LrWpanAckTestCase::DataIndicationDev1, this);
m_dev1->GetMac ()->SetMcpsDataIndicationCallback (cb3);
Ptr<Packet> p0 = Create<Packet> (50); // 50 bytes of dummy data
McpsDataRequestParams params;
params.m_srcAddrMode = SHORT_ADDR;
params.m_dstAddrMode = SHORT_ADDR;
uint8_t expectedAckCount = 0;
switch (m_mode)
{
case SHORT_ADDRESS_UNICAST:
params.m_srcAddrMode = SHORT_ADDR;
params.m_dstAddrMode = SHORT_ADDR;
params.m_dstAddr = Mac16Address ("00:02");
expectedAckCount = 1;
break;
case SHORT_ADDRESS_MULTICAST:
params.m_srcAddrMode = SHORT_ADDR;
params.m_dstAddrMode = SHORT_ADDR;
params.m_dstAddr = Mac16Address::GetMulticast (Ipv6Address::GetAllNodesMulticast ());
expectedAckCount = 0;
break;
case SHORT_ADDRESS_BROADCAST:
params.m_srcAddrMode = SHORT_ADDR;
params.m_dstAddrMode = SHORT_ADDR;
params.m_dstAddr = Mac16Address::GetBroadcast ();
expectedAckCount = 0;
break;
case EXTENDED_ADDRESS_UNICAST:
params.m_srcAddrMode = EXT_ADDR;
params.m_dstAddrMode = EXT_ADDR;
params.m_dstExtAddr = Mac64Address ("00:00:00:00:00:00:00:02");
expectedAckCount = 1;
break;
}
params.m_dstPanId = 0;
params.m_dstAddr = Mac16Address ("00:02");
params.m_msduHandle = 0;
params.m_txOptions = TX_OPTION_ACK;
m_requestTime = Simulator::Now ();
Simulator::ScheduleNow (&LrWpanMac::McpsDataRequest, dev0->GetMac (), params, p0);
Simulator::ScheduleNow (&LrWpanMac::McpsDataRequest, m_dev0->GetMac (), params, p0);
helper.EnableAscii (CreateTempDirFilename (m_prefix), m_dev0);
Simulator::Run ();
std::ifstream traceFile (CreateTempDirFilename (m_prefix)+"-0-0.tr");
uint8_t ackCounter = 0;
std::string sub ("Frame Type = 2");
for( std::string line; getline ( traceFile, line ); )
{
if (line.find(sub, 0) != std::string::npos)
{
ackCounter++;
}
}
traceFile.close ();
// Note: the packet being correctly sent includes receiving an ACK in case of for unicact packets.
NS_TEST_EXPECT_MSG_LT (m_requestTime, m_replyTime, "Sent the request before the reply (as expected)");
NS_TEST_EXPECT_MSG_LT (m_requestAckTime, m_replyArrivalTime, "The request was ACKed before the reply arrived (as expected)");
NS_TEST_EXPECT_MSG_LT (m_replyAckTime, m_replyArrivalTime, "The reply was ACKed before the reply arrived (as expected)");
NS_TEST_EXPECT_MSG_GT (m_requestSentTime, Time (0), "The request was sent (as expected)");
NS_TEST_EXPECT_MSG_LT (m_requestSentTime, m_replyArrivalTime, "The request was sent before the reply arrived (as expected)");
NS_TEST_EXPECT_MSG_LT (m_replySentTime, m_replyArrivalTime, "The reply was sent before the reply arrived (as expected)");
NS_TEST_EXPECT_MSG_EQ (ackCounter, expectedAckCount, "The right amount of ACKs have been seen on the channel (as expected)");
// Test extended addressing.
// Resetting the timers.
m_requestTime = Seconds (0);
m_requestAckTime = Seconds (0);
m_replyTime = Seconds (0);
m_replyAckTime = Seconds (0);
m_replyArrivalTime = Seconds (0);
// Adding exteneded addresses.
dev0->GetMac()->SetExtendedAddress (Mac64Address ("00:00:00:00:00:00:00:01"));
dev1->GetMac()->SetExtendedAddress (Mac64Address ("00:00:00:00:00:00:00:02"));
// Changing callbacks for those with exteneded addressing.
cb0 = MakeBoundCallback (&LrWpanAckTestCase::ExtendedAddressingDataConfirm, this, dev0);
dev0->GetMac ()->SetMcpsDataConfirmCallback (cb0);
cb1 = MakeBoundCallback (&LrWpanAckTestCase::ExtendedAddressingDataIndication, this, dev0);
dev0->GetMac ()->SetMcpsDataIndicationCallback (cb1);
cb2 = MakeBoundCallback (&LrWpanAckTestCase::ExtendedAddressingDataConfirm, this, dev1);
dev1->GetMac ()->SetMcpsDataConfirmCallback (cb2);
cb3 = MakeBoundCallback (&LrWpanAckTestCase::ExtendedAddressingDataIndication, this, dev1);
dev1->GetMac ()->SetMcpsDataIndicationCallback (cb3);
Ptr<Packet> p1 = Create<Packet> (50); // 50 bytes of dummy data
params.m_srcAddrMode = EXT_ADDR;
params.m_dstAddrMode = EXT_ADDR;
params.m_dstPanId = 0;
params.m_dstExtAddr = Mac64Address ("00:00:00:00:00:00:00:02");
params.m_msduHandle = 0;
params.m_txOptions = TX_OPTION_ACK;
m_requestTime = Simulator::Now ();
Simulator::ScheduleNow (&LrWpanMac::McpsDataRequest, dev0->GetMac (), params, p0);
Simulator::Run ();
NS_TEST_EXPECT_MSG_LT (m_requestTime, m_replyTime, "ExtendedAddressing: Sent the request before the reply (as expected)");
NS_TEST_EXPECT_MSG_LT (m_requestAckTime, m_replyArrivalTime, "ExtendedAddressing: The request was ACKed before the reply arrived (as expected)");
NS_TEST_EXPECT_MSG_LT (m_replyAckTime, m_replyArrivalTime, "ExtendedAddressing: The reply was ACKed before the reply arrived (as expected)");
m_dev0 = 0;
m_dev1 = 0;
Simulator::Destroy ();
}
/**
* \ingroup lr-wpan-test
* \ingroup tests
@@ -324,7 +327,10 @@ public:
LrWpanAckTestSuite::LrWpanAckTestSuite ()
: TestSuite ("lr-wpan-ack", UNIT)
{
AddTestCase (new LrWpanAckTestCase, TestCase::QUICK);
AddTestCase (new LrWpanAckTestCase ("short-unicast", LrWpanAckTestCase::SHORT_ADDRESS_UNICAST), TestCase::QUICK);
AddTestCase (new LrWpanAckTestCase ("short-multicast", LrWpanAckTestCase::SHORT_ADDRESS_MULTICAST), TestCase::QUICK);
AddTestCase (new LrWpanAckTestCase ("short-broadcast", LrWpanAckTestCase::SHORT_ADDRESS_BROADCAST), TestCase::QUICK);
AddTestCase (new LrWpanAckTestCase ("extended-unicast", LrWpanAckTestCase::EXTENDED_ADDRESS_UNICAST), TestCase::QUICK);
}
static LrWpanAckTestSuite g_lrWpanAckTestSuite; //!< Static variable for test initialization