--- a/src/wifi/test/wifi-test.cc Fri Dec 07 10:12:40 2012 -0800
+++ b/src/wifi/test/wifi-test.cc Fri Dec 07 14:36:01 2012 -0500
@@ -37,6 +37,7 @@
#include "ns3/dca-txop.h"
#include "ns3/mac-rx-middle.h"
#include "ns3/pointer.h"
+#include "ns3/rng-seed-manager.h"
namespace ns3 {
@@ -285,6 +286,148 @@
}
//-----------------------------------------------------------------------------
+/**
+ * Make sure that when multiple broadcast packets are queued on the same
+ * device in a short succession no virtual collision occurs
+ *
+ * The observed behavior is that the first frame will be sent immediately,
+ * and the frames are spaced by (backoff + SIFS + AIFS) time intervals
+ * (where backoff is a random number of slot sizes up to maximum CW)
+ *
+ * The following test case should _not_ generate virtual collision for the second frame.
+ * The seed and run numbers were pick such that the second frame gets backoff = 0.
+ *
+ * frame 1, frame 2
+ * arrive SIFS + AIFS
+ * V <----------->
+ * time |--------------|-------------------|-------------|----------->
+ * 0 1s 1.001408s 1.001442s
+ * ^ ^ ^
+ * start TX finish TX start TX
+ * frame 1 frame 1 frame 2
+ * ^
+ * frame 2
+ * backoff = 0
+ *
+ * The buggy behavior was that frame 2 experiences a virtual collision and re-selects the
+ * backoff again. As a result, the _actual_ backoff experience by frame 2 is less likely to be 0
+ * since that would require two successions of 0 backoff (one that generates the virtual collision and
+ * one after the virtual collision).
+ */
+
+class Bug555TestCase : public TestCase
+{
+public:
+
+ Bug555TestCase ();
+
+ virtual void DoRun (void);
+
+private:
+
+ void SendOnePacket (Ptr<WifiNetDevice> dev);
+
+ ObjectFactory m_manager;
+ ObjectFactory m_mac;
+ ObjectFactory m_propDelay;
+
+ Time m_firstTransmissionTime;
+ Time m_secondTransmissionTime;
+ unsigned int m_numSentPackets;
+
+ void NotifyPhyTxBegin (Ptr<const Packet> p);
+};
+
+Bug555TestCase::Bug555TestCase ()
+ : TestCase ("Test case for Bug 555")
+{
+}
+
+void
+Bug555TestCase::NotifyPhyTxBegin (Ptr<const Packet> p)
+{
+ if (m_numSentPackets == 0)
+ {
+ NS_ASSERT_MSG (Simulator::Now() == Time (Seconds (1)), "Packet 0 not transmitted at 1 second");
+ m_numSentPackets++;
+ m_firstTransmissionTime = Simulator::Now ();
+ }
+ else if (m_numSentPackets == 1)
+ {
+ m_secondTransmissionTime = Simulator::Now ();
+ }
+}
+
+void
+Bug555TestCase::SendOnePacket (Ptr<WifiNetDevice> dev)
+{
+ Ptr<Packet> p = Create<Packet> (1000);
+ dev->Send (p, dev->GetBroadcast (), 1);
+}
+
+void
+Bug555TestCase::DoRun (void)
+{
+ m_mac.SetTypeId ("ns3::AdhocWifiMac");
+ m_propDelay.SetTypeId ("ns3::ConstantSpeedPropagationDelayModel");
+ m_manager.SetTypeId ("ns3::ConstantRateWifiManager");
+
+ //The simulation with the following seed and run numbers expe
+ RngSeedManager::SetSeed (1);
+ RngSeedManager::SetRun (17);
+
+ Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel> ();
+ Ptr<PropagationDelayModel> propDelay = m_propDelay.Create<PropagationDelayModel> ();
+ Ptr<PropagationLossModel> propLoss = CreateObject<RandomPropagationLossModel> ();
+ channel->SetPropagationDelayModel (propDelay);
+ channel->SetPropagationLossModel (propLoss);
+
+ Ptr<Node> txNode = CreateObject<Node> ();
+ Ptr<WifiNetDevice> txDev = CreateObject<WifiNetDevice> ();
+ Ptr<WifiMac> txMac = m_mac.Create<WifiMac> ();
+ txMac->ConfigureStandard (WIFI_PHY_STANDARD_80211a);
+
+ Ptr<ConstantPositionMobilityModel> txMobility = CreateObject<ConstantPositionMobilityModel> ();
+ Ptr<YansWifiPhy> txPhy = CreateObject<YansWifiPhy> ();
+ Ptr<ErrorRateModel> txError = CreateObject<YansErrorRateModel> ();
+ txPhy->SetErrorRateModel (txError);
+ txPhy->SetChannel (channel);
+ txPhy->SetDevice (txDev);
+ txPhy->SetMobility (txNode);
+ txPhy->ConfigureStandard (WIFI_PHY_STANDARD_80211a);
+
+ txPhy->TraceConnectWithoutContext ("PhyTxBegin", MakeCallback (&Bug555TestCase::NotifyPhyTxBegin, this));
+
+ txMobility->SetPosition (Vector (0.0, 0.0, 0.0));
+ txNode->AggregateObject (txMobility);
+ txMac->SetAddress (Mac48Address::Allocate ());
+ txDev->SetMac (txMac);
+ txDev->SetPhy (txPhy);
+ txDev->SetRemoteStationManager (m_manager.Create<WifiRemoteStationManager> ());
+ txNode->AddDevice (txDev);
+
+ m_firstTransmissionTime = Seconds (0.0);
+ m_secondTransmissionTime = Seconds (0.0);
+ m_numSentPackets = 0;
+
+ Simulator::Schedule (Seconds (1.0), &Bug555TestCase::SendOnePacket, this, txDev);
+ Simulator::Schedule (Seconds (1.0), &Bug555TestCase::SendOnePacket, this, txDev);
+
+ Simulator::Stop (Seconds (2.0));
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ // First packet has 1408 us of transmit time. Slot time is 9 us.
+ // Backoff is 0 slots. SIFS is 16 us. AIFS is 2 slots = 18 us.
+ // Should send next packet at 1408 us + (0 * 9 us) + 16 us + 18 us
+ // 1442 us after the first one.
+ uint32_t expectedWait1 = 1408 + (0 * 9) + 16 + 18;
+ Time expectedSecondTransmissionTime = MicroSeconds (expectedWait1) + Seconds (1.0);
+
+ NS_TEST_ASSERT_MSG_EQ (m_secondTransmissionTime, expectedSecondTransmissionTime, "The second transmission time not correct!");
+}
+
+//-----------------------------------------------------------------------------
class WifiTestSuite : public TestSuite
{
@@ -298,6 +441,7 @@
AddTestCase (new WifiTest);
AddTestCase (new QosUtilsIsOldPacketTest);
AddTestCase (new InterferenceHelperSequenceTest); // Bug 991
+ AddTestCase (new Bug555TestCase); // Bug 555
}
static WifiTestSuite g_wifiTestSuite;