--- a/RELEASE_NOTES Fri Dec 07 10:12:40 2012 -0800
+++ b/RELEASE_NOTES Fri Dec 07 14:36:01 2012 -0500
@@ -42,6 +42,7 @@
- bug 1532 - unimplemented LTE Scheduler methods
- bug 1524 - Fragmentation Threshold equals to Packet Size at MAC Layer (Data + IP + UDP) crash the reception
- bug 1525 - Linker error with mpi on Mac 10.8
+ - bug 555 - DCF immediate access
Known issues
------------
Binary file src/aodv/test/tcp-chain-test-0-0.pcap has changed
Binary file src/aodv/test/tcp-chain-test-9-0.pcap has changed
--- a/src/wifi/bindings/modulegen__gcc_ILP32.py Fri Dec 07 10:12:40 2012 -0800
+++ b/src/wifi/bindings/modulegen__gcc_ILP32.py Fri Dec 07 14:36:01 2012 -0500
@@ -2553,6 +2553,11 @@
'void',
[],
is_pure_virtual=True, is_virtual=True)
+ ## mac-low.h (module 'wifi'): void ns3::MacLowTransmissionListener::EndTxNoAck() [member function]
+ cls.add_method('EndTxNoAck',
+ 'void',
+ [],
+ is_pure_virtual=True, is_virtual=True)
## mac-low.h (module 'wifi'): void ns3::MacLowTransmissionListener::GotAck(double snr, ns3::WifiMode txMode) [member function]
cls.add_method('GotAck',
'void',
@@ -4095,6 +4100,7 @@
def register_Ns3Int64x64_t_methods(root_module, cls):
cls.add_inplace_numeric_operator('+=', param('ns3::int64x64_t const &', 'right'))
+ cls.add_binary_comparison_operator('<=')
cls.add_binary_comparison_operator('!=')
cls.add_binary_numeric_operator('*', root_module['ns3::int64x64_t'], root_module['ns3::int64x64_t'], param('long long unsigned int const', 'right'))
cls.add_binary_numeric_operator('*', root_module['ns3::int64x64_t'], root_module['ns3::int64x64_t'], param('long unsigned int const', 'right'))
@@ -4151,7 +4157,6 @@
cls.add_inplace_numeric_operator('-=', param('ns3::int64x64_t const &', 'right'))
cls.add_inplace_numeric_operator('/=', param('ns3::int64x64_t const &', 'right'))
cls.add_output_stream_operator()
- cls.add_binary_comparison_operator('<=')
cls.add_binary_comparison_operator('==')
cls.add_binary_comparison_operator('>=')
## int64x64-double.h (module 'core'): ns3::int64x64_t::int64x64_t() [constructor]
@@ -5354,6 +5359,7 @@
def register_Ns3Time_methods(root_module, cls):
cls.add_inplace_numeric_operator('+=', param('ns3::Time const &', 'right'))
+ cls.add_binary_comparison_operator('<=')
cls.add_binary_comparison_operator('!=')
cls.add_binary_numeric_operator('+', root_module['ns3::Time'], root_module['ns3::Time'], param('ns3::Time const &', 'right'))
cls.add_binary_numeric_operator('-', root_module['ns3::Time'], root_module['ns3::Time'], param('ns3::Time const &', 'right'))
@@ -5361,7 +5367,6 @@
cls.add_binary_comparison_operator('>')
cls.add_inplace_numeric_operator('-=', param('ns3::Time const &', 'right'))
cls.add_output_stream_operator()
- cls.add_binary_comparison_operator('<=')
cls.add_binary_comparison_operator('==')
cls.add_binary_comparison_operator('>=')
## nstime.h (module 'core'): ns3::Time::Time() [constructor]
@@ -8918,6 +8923,10 @@
cls.add_method('Cancel',
'void',
[])
+ ## edca-txop-n.h (module 'wifi'): void ns3::EdcaTxopN::EndTxNoAck() [member function]
+ cls.add_method('EndTxNoAck',
+ 'void',
+ [])
## edca-txop-n.h (module 'wifi'): void ns3::EdcaTxopN::RestartAccessIfNeeded() [member function]
cls.add_method('RestartAccessIfNeeded',
'void',
--- a/src/wifi/bindings/modulegen__gcc_LP64.py Fri Dec 07 10:12:40 2012 -0800
+++ b/src/wifi/bindings/modulegen__gcc_LP64.py Fri Dec 07 14:36:01 2012 -0500
@@ -2553,6 +2553,11 @@
'void',
[],
is_pure_virtual=True, is_virtual=True)
+ ## mac-low.h (module 'wifi'): void ns3::MacLowTransmissionListener::EndTxNoAck() [member function]
+ cls.add_method('EndTxNoAck',
+ 'void',
+ [],
+ is_pure_virtual=True, is_virtual=True)
## mac-low.h (module 'wifi'): void ns3::MacLowTransmissionListener::GotAck(double snr, ns3::WifiMode txMode) [member function]
cls.add_method('GotAck',
'void',
@@ -4095,6 +4100,7 @@
def register_Ns3Int64x64_t_methods(root_module, cls):
cls.add_inplace_numeric_operator('+=', param('ns3::int64x64_t const &', 'right'))
+ cls.add_binary_comparison_operator('<=')
cls.add_binary_comparison_operator('!=')
cls.add_binary_numeric_operator('*', root_module['ns3::int64x64_t'], root_module['ns3::int64x64_t'], param('long long unsigned int const', 'right'))
cls.add_binary_numeric_operator('*', root_module['ns3::int64x64_t'], root_module['ns3::int64x64_t'], param('long unsigned int const', 'right'))
@@ -4151,7 +4157,6 @@
cls.add_inplace_numeric_operator('-=', param('ns3::int64x64_t const &', 'right'))
cls.add_inplace_numeric_operator('/=', param('ns3::int64x64_t const &', 'right'))
cls.add_output_stream_operator()
- cls.add_binary_comparison_operator('<=')
cls.add_binary_comparison_operator('==')
cls.add_binary_comparison_operator('>=')
## int64x64-double.h (module 'core'): ns3::int64x64_t::int64x64_t() [constructor]
@@ -5354,6 +5359,7 @@
def register_Ns3Time_methods(root_module, cls):
cls.add_inplace_numeric_operator('+=', param('ns3::Time const &', 'right'))
+ cls.add_binary_comparison_operator('<=')
cls.add_binary_comparison_operator('!=')
cls.add_binary_numeric_operator('+', root_module['ns3::Time'], root_module['ns3::Time'], param('ns3::Time const &', 'right'))
cls.add_binary_numeric_operator('-', root_module['ns3::Time'], root_module['ns3::Time'], param('ns3::Time const &', 'right'))
@@ -5361,7 +5367,6 @@
cls.add_binary_comparison_operator('>')
cls.add_inplace_numeric_operator('-=', param('ns3::Time const &', 'right'))
cls.add_output_stream_operator()
- cls.add_binary_comparison_operator('<=')
cls.add_binary_comparison_operator('==')
cls.add_binary_comparison_operator('>=')
## nstime.h (module 'core'): ns3::Time::Time() [constructor]
@@ -8918,6 +8923,10 @@
cls.add_method('Cancel',
'void',
[])
+ ## edca-txop-n.h (module 'wifi'): void ns3::EdcaTxopN::EndTxNoAck() [member function]
+ cls.add_method('EndTxNoAck',
+ 'void',
+ [])
## edca-txop-n.h (module 'wifi'): void ns3::EdcaTxopN::RestartAccessIfNeeded() [member function]
cls.add_method('RestartAccessIfNeeded',
'void',
--- a/src/wifi/model/dca-txop.cc Fri Dec 07 10:12:40 2012 -0800
+++ b/src/wifi/model/dca-txop.cc Fri Dec 07 14:36:01 2012 -0500
@@ -103,6 +103,10 @@
{
m_txop->Cancel ();
}
+ virtual void EndTxNoAck (void)
+ {
+ m_txop->EndTxNoAck ();
+ }
private:
DcaTxop *m_txop;
@@ -407,10 +411,6 @@
&m_currentHdr,
params,
m_transmissionListener);
- m_currentPacket = 0;
- m_dcf->ResetCw ();
- m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
- StartAccessIfNeeded ();
NS_LOG_DEBUG ("tx broadcast");
}
else
@@ -621,4 +621,15 @@
*/
}
+void
+DcaTxop::EndTxNoAck (void)
+{
+ NS_LOG_FUNCTION (this);
+ NS_LOG_DEBUG ("a transmission that did not require an ACK just finished");
+ m_currentPacket = 0;
+ m_dcf->ResetCw ();
+ m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
+ StartAccessIfNeeded ();
+}
+
} // namespace ns3
--- a/src/wifi/model/dca-txop.h Fri Dec 07 10:12:40 2012 -0800
+++ b/src/wifi/model/dca-txop.h Fri Dec 07 14:36:01 2012 -0500
@@ -147,6 +147,7 @@
void MissedAck (void);
void StartNext (void);
void Cancel (void);
+ void EndTxNoAck (void);
void RestartAccessIfNeeded (void);
void StartAccessIfNeeded (void);
--- a/src/wifi/model/edca-txop-n.cc Fri Dec 07 10:12:40 2012 -0800
+++ b/src/wifi/model/edca-txop-n.cc Fri Dec 07 14:36:01 2012 -0500
@@ -111,6 +111,10 @@
{
m_txop->Cancel ();
}
+ virtual void EndTxNoAck (void)
+ {
+ m_txop->EndTxNoAck ();
+ }
private:
EdcaTxopN *m_txop;
@@ -384,10 +388,6 @@
params,
m_transmissionListener);
- m_currentPacket = 0;
- m_dcf->ResetCw ();
- m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
- StartAccessIfNeeded ();
NS_LOG_DEBUG ("tx broadcast");
}
else if (m_currentHdr.GetType () == WIFI_MAC_CTL_BACKREQ)
@@ -730,6 +730,17 @@
NS_LOG_DEBUG ("transmission cancelled");
}
+void
+EdcaTxopN::EndTxNoAck (void)
+{
+ NS_LOG_FUNCTION (this);
+ NS_LOG_DEBUG ("a transmission that did not require an ACK just finished");
+ m_currentPacket = 0;
+ m_dcf->ResetCw ();
+ m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
+ StartAccessIfNeeded ();
+}
+
bool
EdcaTxopN::NeedFragmentation (void) const
{
--- a/src/wifi/model/edca-txop-n.h Fri Dec 07 10:12:40 2012 -0800
+++ b/src/wifi/model/edca-txop-n.h Fri Dec 07 14:36:01 2012 -0500
@@ -126,6 +126,7 @@
void MissedAck (void);
void StartNext (void);
void Cancel (void);
+ void EndTxNoAck (void);
void RestartAccessIfNeeded (void);
void StartAccessIfNeeded (void);
--- a/src/wifi/model/mac-low.cc Fri Dec 07 10:12:40 2012 -0800
+++ b/src/wifi/model/mac-low.cc Fri Dec 07 14:36:01 2012 -0500
@@ -360,6 +360,7 @@
m_sendAckEvent (),
m_sendDataEvent (),
m_waitSifsEvent (),
+ m_endTxNoAckEvent (),
m_currentPacket (0),
m_listener (0)
{
@@ -396,6 +397,7 @@
m_sendAckEvent.Cancel ();
m_sendDataEvent.Cancel ();
m_waitSifsEvent.Cancel ();
+ m_endTxNoAckEvent.Cancel ();
m_phy = 0;
m_stationManager = 0;
delete m_phyMacLowListener;
@@ -457,6 +459,11 @@
m_waitSifsEvent.Cancel ();
oneRunning = true;
}
+ if (m_endTxNoAckEvent.IsRunning ())
+ {
+ m_endTxNoAckEvent.Cancel ();
+ oneRunning = true;
+ }
if (oneRunning && m_listener != 0)
{
m_listener->Cancel ();
@@ -1352,7 +1359,7 @@
else
{
// since we do not expect any timer to be triggered.
- m_listener = 0;
+ Simulator::Schedule(txDuration, &MacLow::EndTxNoAck, this);
}
}
@@ -1490,6 +1497,14 @@
m_listener->StartNext ();
}
+void
+MacLow::EndTxNoAck (void)
+{
+ MacLowTransmissionListener *listener = m_listener;
+ m_listener = 0;
+ listener->EndTxNoAck ();
+}
+
void
MacLow::FastAckFailedTimeout (void)
{
--- a/src/wifi/model/mac-low.h Fri Dec 07 10:12:40 2012 -0800
+++ b/src/wifi/model/mac-low.h Fri Dec 07 14:36:01 2012 -0500
@@ -123,7 +123,15 @@
* you can assume that the packet has not been passed
* down the stack to the PHY.
*/
- virtual void Cancel (void) = 0;
+ virtual void Cancel (void) = 0;
+
+ /**
+ * Invoked upon the end of the transmission of a frame that does not
+ * require an ACK (e.g., broadcast and multicast frames).
+ *
+ */
+ virtual void EndTxNoAck (void) = 0;
+
};
@@ -541,6 +549,7 @@
void SendAckAfterData (Mac48Address source, Time duration, WifiMode txMode, double rtsSnr);
void SendDataAfterCts (Mac48Address source, Time duration, WifiMode txMode);
void WaitSifsAfterEndTx (void);
+ void EndTxNoAck (void);
void SendRtsForPacket (void);
void SendDataPacket (void);
@@ -614,6 +623,7 @@
EventId m_sendAckEvent;
EventId m_sendDataEvent;
EventId m_waitSifsEvent;
+ EventId m_endTxNoAckEvent;
EventId m_navCounterResetCtsMissed;
Ptr<Packet> m_currentPacket;
--- 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;