diff --git a/src/lr-wpan/test/lr-wpan-ack-test.cc b/src/lr-wpan/test/lr-wpan-ack-test.cc index 79bebbad8..bf6c930de 100644 --- a/src/lr-wpan/test/lr-wpan-ack-test.cc +++ b/src/lr-wpan/test/lr-wpan-ack-test.cc @@ -17,6 +17,8 @@ * * Author: * Sascha Alexander Jopen + * Modifications: + * Tommaso Pecorella */ #include @@ -31,6 +33,9 @@ #include "ns3/rng-seed-manager.h" #include +#include +#include +#include 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 dev, McpsDataIndicationParams params, Ptr p); + void DataIndicationDev0 (McpsDataIndicationParams params, Ptr 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 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 dev, McpsDataIndicationParams params, Ptr p); + void DataIndicationDev1 (McpsDataIndicationParams params, Ptr 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 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 m_dev0; //!< 1st LrWpanNetDevice. + Ptr 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 dev, McpsDataIndicationParams params, Ptr p) +LrWpanAckTestCase::DataIndicationDev0 (McpsDataIndicationParams params, Ptr p) { - if (dev->GetMac ()->GetShortAddress () == Mac16Address ("00:02")) - { - Ptr p = Create (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 dev, McpsDataConfirmParams params) +LrWpanAckTestCase::DataIndicationDev1 (McpsDataIndicationParams params, Ptr p) { - if (dev->GetMac ()->GetShortAddress () == Mac16Address ("00:01")) + Ptr pkt = Create (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 dev, McpsDataIndicationParams params, Ptr p) +LrWpanAckTestCase::DataConfirmDev0 (McpsDataConfirmParams params) { - if (dev->GetMac ()->GetExtendedAddress () == Mac64Address ("00:00:00:00:00:00:00:02")) - { - Ptr p = Create (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 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 n0 = CreateObject (); Ptr n1 = CreateObject (); - Ptr dev0 = CreateObject (); - Ptr dev1 = CreateObject (); + m_dev0 = CreateObject (); + m_dev1 = CreateObject (); // 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 channel = CreateObject (); @@ -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 sender0Mobility = CreateObject (); sender0Mobility->SetPosition (Vector (0,0,0)); - dev0->GetPhy ()->SetMobility (sender0Mobility); + m_dev0->GetPhy ()->SetMobility (sender0Mobility); Ptr sender1Mobility = CreateObject (); // 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 p0 = Create (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 p1 = Create (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