diff --git a/src/lr-wpan/model/lr-wpan-mac.h b/src/lr-wpan/model/lr-wpan-mac.h index a6ed7f07a..584e7f178 100644 --- a/src/lr-wpan/model/lr-wpan-mac.h +++ b/src/lr-wpan/model/lr-wpan-mac.h @@ -46,6 +46,7 @@ class LrWpanCsmaCa; */ typedef enum { + TX_OPTION_NONE = 0, TX_OPTION_ACK = 1, TX_OPTION_GTS = 2, TX_OPTION_INDIRECT = 4 diff --git a/src/lr-wpan/test/examples-to-run.py b/src/lr-wpan/test/examples-to-run.py index 8f60206bc..0b3425959 100644 --- a/src/lr-wpan/test/examples-to-run.py +++ b/src/lr-wpan/test/examples-to-run.py @@ -8,10 +8,11 @@ # # See test.py for more information. cpp_examples = [ - ("lr-wpan-packet-print", "True", "True"), - ("lr-wpan-phy-test", "True", "True"), ("lr-wpan-data", "True", "True"), + ("lr-wpan-error-distance-plot", "True", "True"), ("lr-wpan-error-model-plot", "True", "True"), + ("lr-wpan-packet-print", "True", "True"), + ("lr-wpan-phy-test", "True", "True"), ] # A list of Python examples to run in order to ensure that they remain diff --git a/src/lr-wpan/test/lr-wpan-ack-test.cc b/src/lr-wpan/test/lr-wpan-ack-test.cc new file mode 100644 index 000000000..099298312 --- /dev/null +++ b/src/lr-wpan/test/lr-wpan-ack-test.cc @@ -0,0 +1,198 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2014 Fraunhofer FKIE + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: + * Sascha Alexander Jopen + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("lr-wpan-ack-test"); + +using namespace ns3; + +class LrWpanAckTestCase : public TestCase +{ +public: + LrWpanAckTestCase (); + + static void DataIndication (LrWpanAckTestCase *testCase, Ptr dev, McpsDataIndicationParams params, Ptr p); + static void DataConfirm (LrWpanAckTestCase *testCase, Ptr dev, McpsDataConfirmParams params); + +private: + virtual void DoRun (void); + + Time m_requestTime; + Time m_requestAckTime; + Time m_replyTime; + Time m_replyAckTime; + Time m_replyArrivalTime; +}; + +LrWpanAckTestCase::LrWpanAckTestCase () + : TestCase ("Test the 802.15.4 ACK handling") +{ + m_requestTime = Seconds (0); + m_requestAckTime = Seconds (0); + m_replyTime = Seconds (0); + m_replyAckTime = Seconds (0); + m_replyArrivalTime = Seconds (0); +} + +void +LrWpanAckTestCase::DataIndication (LrWpanAckTestCase *testCase, Ptr dev, McpsDataIndicationParams params, Ptr p) +{ + if (dev->GetAddress () == 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 (); + } +} + +void +LrWpanAckTestCase::DataConfirm (LrWpanAckTestCase *testCase, Ptr dev, McpsDataConfirmParams params) +{ + if (dev->GetAddress () == Mac16Address ("00:01")) + { + testCase->m_requestAckTime = Simulator::Now (); + } + else + { + testCase->m_replyAckTime = Simulator::Now (); + } +} + +void +LrWpanAckTestCase::DoRun (void) +{ + // Test setup: + // Two nodes well in communication range. + // Node 1 sends a request packet to node 2 with ACK request bit set. Node 2 + // immediately answers with a reply packet on receiption 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. + + // Enable calculation of FCS in the trailers. Only necessary when interacting with real devices or wireshark. + // GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true)); + + // Create 2 nodes, and a NetDevice for each one + Ptr n0 = CreateObject (); + Ptr n1 = CreateObject (); + + Ptr dev0 = CreateObject (); + Ptr dev1 = CreateObject (); + + dev0->SetAddress (Mac16Address ("00:01")); + dev1->SetAddress (Mac16Address ("00:02")); + + // Each device must be attached to the same channel + Ptr channel = CreateObject (); + Ptr propModel = CreateObject (); + Ptr delayModel = CreateObject (); + channel->AddPropagationLossModel (propModel); + channel->SetPropagationDelayModel (delayModel); + + dev0->SetChannel (channel); + dev1->SetChannel (channel); + + // To complete configuration, a LrWpanNetDevice must be added to a node + n0->AddDevice (dev0); + n1->AddDevice (dev1); + + Ptr sender0Mobility = CreateObject (); + sender0Mobility->SetPosition (Vector (0,0,0)); + dev0->GetPhy ()->SetMobility (sender0Mobility); + Ptr sender1Mobility = CreateObject (); + // Configure position 10 m distance + sender1Mobility->SetPosition (Vector (0,10,0)); + dev1->GetPhy ()->SetMobility (sender1Mobility); + + McpsDataConfirmCallback cb0; + cb0 = MakeBoundCallback (&LrWpanAckTestCase::DataConfirm, this, dev0); + dev0->GetMac ()->SetMcpsDataConfirmCallback (cb0); + + McpsDataIndicationCallback cb1; + cb1 = MakeBoundCallback (&LrWpanAckTestCase::DataIndication, this, dev0); + dev0->GetMac ()->SetMcpsDataIndicationCallback (cb1); + + McpsDataConfirmCallback cb2; + cb2 = MakeBoundCallback (&LrWpanAckTestCase::DataConfirm, this, dev1); + dev1->GetMac ()->SetMcpsDataConfirmCallback (cb2); + + McpsDataIndicationCallback cb3; + cb3 = MakeBoundCallback (&LrWpanAckTestCase::DataIndication, this, dev1); + 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; + 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::Run (); + + 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)"); + + Simulator::Destroy (); +} + +class LrWpanAckTestSuite : public TestSuite +{ +public: + LrWpanAckTestSuite (); +}; + +LrWpanAckTestSuite::LrWpanAckTestSuite () + : TestSuite ("lr-wpan-ack", UNIT) +{ + AddTestCase (new LrWpanAckTestCase, TestCase::QUICK); +} + +static LrWpanAckTestSuite g_lrWpanAckTestSuite; diff --git a/src/lr-wpan/wscript b/src/lr-wpan/wscript index bf60150af..7c5a9539f 100644 --- a/src/lr-wpan/wscript +++ b/src/lr-wpan/wscript @@ -19,9 +19,11 @@ def build(bld): module_test = bld.create_ns3_module_test_library('lr-wpan') module_test.source = [ - 'test/lr-wpan-pd-plme-sap-test.cc', - 'test/lr-wpan-packet-test.cc', + 'test/lr-wpan-ack-test.cc', + 'test/lr-wpan-collision-test.cc', 'test/lr-wpan-error-model-test.cc', + 'test/lr-wpan-packet-test.cc', + 'test/lr-wpan-pd-plme-sap-test.cc', 'test/lr-wpan-spectrum-value-helper-test.cc', 'test/lr-wpan-collision-test.cc', ]