diff --git a/CHANGES.html b/CHANGES.html
index 91a7b1e5e..7eb92a9cc 100644
--- a/CHANGES.html
+++ b/CHANGES.html
@@ -88,6 +88,12 @@ and BuildingsHelper classes, a building aware pathloss models, e.g.,
HybridBuildingsPropagationLossModel is now able to accurately compute
the pathloss for a node moving in and out of buildings in a simulation. See issue 80
for discussion.
+
The implementation of the wifi channel access functions has been improved
+to make them more adherent to the IEEE 802.11-2016 standard. Concerning the DCF,
+the backoff procedure is no longer invoked when a packet is queued for transmission
+and the medium has not been idle for a DIFS, but it is invoked if the medium is busy
+or does not remain idle for a DIFS after the packet has been queued. Concerning the
+EDCAF, tranmissions are now correctly aligned at slot boundaries.
diff --git a/RELEASE_NOTES b/RELEASE_NOTES
index f735249c8..83da0fbda 100644
--- a/RELEASE_NOTES
+++ b/RELEASE_NOTES
@@ -29,6 +29,8 @@ Bugs fixed
----------
- Issue #119 - Waf --lcov-report option was broken
- Issue #84 - Wi-Fi removing wrong header due to copy-paste error
+- wifi: a zero value for the backoff timer might be discarded and a new value
+ might be generated by an erroneous call to NotifyCollision().
Known issues
------------
diff --git a/src/mesh/test/dot11s/hwmp-proactive-regression-test-2-1.pcap b/src/mesh/test/dot11s/hwmp-proactive-regression-test-2-1.pcap
index 6f08daddd..bb0e88a55 100644
Binary files a/src/mesh/test/dot11s/hwmp-proactive-regression-test-2-1.pcap and b/src/mesh/test/dot11s/hwmp-proactive-regression-test-2-1.pcap differ
diff --git a/src/mesh/test/dot11s/hwmp-proactive-regression-test-4-1.pcap b/src/mesh/test/dot11s/hwmp-proactive-regression-test-4-1.pcap
index b9f4ac7c8..102e5c95b 100644
Binary files a/src/mesh/test/dot11s/hwmp-proactive-regression-test-4-1.pcap and b/src/mesh/test/dot11s/hwmp-proactive-regression-test-4-1.pcap differ
diff --git a/src/mesh/test/dot11s/hwmp-reactive-regression-test-5-1.pcap b/src/mesh/test/dot11s/hwmp-reactive-regression-test-5-1.pcap
index 5614e77ed..82aa2bcb5 100644
Binary files a/src/mesh/test/dot11s/hwmp-reactive-regression-test-5-1.pcap and b/src/mesh/test/dot11s/hwmp-reactive-regression-test-5-1.pcap differ
diff --git a/src/mesh/test/dot11s/hwmp-simplest-regression-test-0-1.pcap b/src/mesh/test/dot11s/hwmp-simplest-regression-test-0-1.pcap
index 515d4b65f..c8fe30e0f 100644
Binary files a/src/mesh/test/dot11s/hwmp-simplest-regression-test-0-1.pcap and b/src/mesh/test/dot11s/hwmp-simplest-regression-test-0-1.pcap differ
diff --git a/src/mesh/test/dot11s/hwmp-simplest-regression-test-1-1.pcap b/src/mesh/test/dot11s/hwmp-simplest-regression-test-1-1.pcap
index f18b9e0b6..53a6e6093 100644
Binary files a/src/mesh/test/dot11s/hwmp-simplest-regression-test-1-1.pcap and b/src/mesh/test/dot11s/hwmp-simplest-regression-test-1-1.pcap differ
diff --git a/src/mesh/test/dot11s/hwmp-target-flags-regression-test-0-1.pcap b/src/mesh/test/dot11s/hwmp-target-flags-regression-test-0-1.pcap
index bf5f463cd..f037a57a8 100644
Binary files a/src/mesh/test/dot11s/hwmp-target-flags-regression-test-0-1.pcap and b/src/mesh/test/dot11s/hwmp-target-flags-regression-test-0-1.pcap differ
diff --git a/src/mesh/test/dot11s/hwmp-target-flags-regression-test-1-1.pcap b/src/mesh/test/dot11s/hwmp-target-flags-regression-test-1-1.pcap
index 6b8b0492a..b393dc17f 100644
Binary files a/src/mesh/test/dot11s/hwmp-target-flags-regression-test-1-1.pcap and b/src/mesh/test/dot11s/hwmp-target-flags-regression-test-1-1.pcap differ
diff --git a/src/mesh/test/dot11s/hwmp-target-flags-regression-test-2-1.pcap b/src/mesh/test/dot11s/hwmp-target-flags-regression-test-2-1.pcap
index f20aa1c2a..d2793cb00 100644
Binary files a/src/mesh/test/dot11s/hwmp-target-flags-regression-test-2-1.pcap and b/src/mesh/test/dot11s/hwmp-target-flags-regression-test-2-1.pcap differ
diff --git a/src/mesh/test/flame/flame-regression-test-2-1.pcap b/src/mesh/test/flame/flame-regression-test-2-1.pcap
index 7c09bb44c..cc5204dbe 100644
Binary files a/src/mesh/test/flame/flame-regression-test-2-1.pcap and b/src/mesh/test/flame/flame-regression-test-2-1.pcap differ
diff --git a/src/wifi/doc/source/wifi-design.rst b/src/wifi/doc/source/wifi-design.rst
index 2d9f3872a..fcf9e6a7d 100644
--- a/src/wifi/doc/source/wifi-design.rst
+++ b/src/wifi/doc/source/wifi-design.rst
@@ -578,9 +578,28 @@ where the backoff timer duration is lazily calculated whenever needed since it
is claimed to have much better performance than the simpler recurring timer
solution.
-The backoff procedure of DCF is described in section 9.2.5.2 of [ieee80211]_.
+The DCF basic access is described in section 10.3.4.2 of [ieee80211-2016]_.
-* “The backoff procedure shall be invoked for a STA to transfer a frame
+* “A STA may transmit an MPDU when it is operating under the DCF access method
+ [..] when the STA determines that the medium is idle when a frame is queued
+ for transmission, and remains idle for a period of a DIFS, or an EIFS
+ (10.3.2.3.7) from the end of the immediately preceding medium-busy event,
+ whichever is the greater, and the backoff timer is zero. Otherwise the random
+ backoff procedure described in 10.3.4.3 shall be followed."
+
+Thus, a station is allowed not to invoke the backoff procedure if all of the
+following conditions are met:
+
+* the medium is idle when a frame is queued for transmission
+* the medium remains idle until the most recent of these two events: a DIFS
+ from the time when the frame is queued for transmission; an EIFS from the
+ end of the immediately preceding medium-busy event (associated with the
+ reception of an erroneous frame)
+* the backoff timer is zero
+
+The backoff procedure of DCF is described in section 10.3.4.3 of [ieee80211-2016]_.
+
+* “A STA shall invoke the backoff procedure to transfer a frame
when finding the medium busy as indicated by either the physical or
virtual CS mechanism.”
* “A backoff procedure shall be performed immediately after the end of
@@ -588,19 +607,43 @@ The backoff procedure of DCF is described in section 9.2.5.2 of [ieee80211]_.
type Data, Management, or Control with subtype PS-Poll, even if no
additional transmissions are currently queued.”
-Thus, if the queue is empty, a newly arrived packet should be transmitted
-immediately after channel is sensed idle for DIFS. If queue is not empty
-and after a successful MPDU that has no more fragments, a node should
-also start the backoff timer.
+The EDCA backoff procedure is slightly different than the DCF backoff procedure
+and is described in section 10.22.2.2 of [ieee80211-2016]_. The backoff procedure
+shall be invoked by an EDCAF when any of the following events occur:
-Some users have observed that the 802.11 MAC with an empty queue on an
-idle channel will transmit the first frame arriving to the model
-immediately without waiting for DIFS or backoff, and wonder whether this
-is compliant. According to the standard, “The backoff procedure shall
-be invoked for a STA to transfer a frame when finding the medium busy
-as indicated by either the physical or virtual CS mechanism.” So in
-this case, the medium is not found to be busy in recent past and the
-station can transmit immediately.
+* a frame is "queued for transmission such that one of the transmit queues
+ associated with that AC has now become non-empty and any other transmit queues
+ associated with that AC are empty; the medium is busy on the primary channel"
+* "The transmission of the MPDU in the final PPDU transmitted by the TXOP holder
+ during the TXOP for that AC has completed and the TXNAV timer has expired, and
+ the AC was a primary AC"
+* "The transmission of an MPDU in the initial PPDU of a TXOP fails [..] and the
+ AC was a primary AC"
+* "The transmission attempt collides internally with another EDCAF of an AC that
+ has higher priority"
+* (optionally) "The transmission by the TXOP holder of an MPDU in a non-initial
+ PPDU of a TXOP fails"
+
+Additionally, section 10.22.2.4 of [ieee80211-2016]_ introduces the notion of
+slot boundary, which basically occurs following SIFS + AIFSN * slotTime of idle
+medium after the last busy medium that was the result of a reception of a frame
+with a correct FCS or following EIFS - DIFS + AIFSN * slotTime + SIFS of idle
+medium after the last indicated busy medium that was the result of a frame reception
+that has resulted in FCS error, or following a slotTime of idle medium occurring
+immediately after any of these conditions.
+
+On these specific slot boundaries, each EDCAF shall make a determination to perform
+one and only one of the following functions:
+
+* Decrement the backoff timer.
+* Initiate the transmission of a frame exchange sequence.
+* Invoke the backoff procedure due to an internal collision.
+* Do nothing.
+
+Thus, if an EDCAF decrements its backoff timer on a given slot boundary and, as
+a result, the backoff timer has a zero value, the EDCAF cannot immediately
+transmit, but it has to wait for another slotTime of idle medium before transmission
+can start.
The higher-level MAC functions are implemented in a set of other C++ classes and
deal with:
diff --git a/src/wifi/doc/source/wifi-references.rst b/src/wifi/doc/source/wifi-references.rst
index d26357906..5e00cff7f 100644
--- a/src/wifi/doc/source/wifi-references.rst
+++ b/src/wifi/doc/source/wifi-references.rst
@@ -7,6 +7,8 @@ References
.. [ieee80211] IEEE Std 802.11-2012, *Part 11: Wireless LAN Medium Access Control (MAC) and Physical Layer (PHY) Specifications*
+.. [ieee80211-2016] IEEE Std 802.11-2016, *Part 11: Wireless LAN Medium Access Control (MAC) and Physical Layer (PHY) Specifications*
+
.. [pei80211b] \G. Pei and Tom Henderson, `Validation of ns-3 802.11b PHY model `__
.. [pei80211ofdm] \G. Pei and Tom Henderson, `Validation of OFDM error rate model in ns-3 `__
diff --git a/src/wifi/model/channel-access-manager.cc b/src/wifi/model/channel-access-manager.cc
index f1ff74006..bcdeae75e 100644
--- a/src/wifi/model/channel-access-manager.cc
+++ b/src/wifi/model/channel-access-manager.cc
@@ -262,6 +262,21 @@ ChannelAccessManager::RequestAccess (Ptr state, bool isCfPeriod)
m_accessTimeout = Simulator::Schedule (delay, &ChannelAccessManager::DoGrantPcfAccess, this, state);
return;
}
+ /*
+ * EDCAF operations shall be performed at slot boundaries (Sec. 10.22.2.4 of 802.11-2016)
+ */
+ Time accessGrantStart = GetAccessGrantStart () + (state->GetAifsn () * m_slot);
+
+ if (state->IsQosTxop () && state->GetBackoffStart () > accessGrantStart)
+ {
+ // The backoff start time reported by the EDCAF is more recent than the last
+ // time the medium was busy plus an AIFS, hence we need to align it to the
+ // next slot boundary.
+ Time diff = state->GetBackoffStart () - accessGrantStart;
+ uint32_t nIntSlots = (diff / m_slot).GetHigh () + 1;
+ state->UpdateBackoffSlotsNow (0, accessGrantStart + (nIntSlots * m_slot));
+ }
+
UpdateBackoff ();
NS_ASSERT (!state->IsAccessRequested ());
state->NotifyAccessRequested ();
diff --git a/src/wifi/model/txop.cc b/src/wifi/model/txop.cc
index 3fe5616aa..dc387659b 100644
--- a/src/wifi/model/txop.cc
+++ b/src/wifi/model/txop.cc
@@ -341,7 +341,10 @@ Txop::GenerateBackoffUponAccessIfNeeded (void)
if (!m_channelAccessManager->IsBusy ())
{
// medium idle. If this is a DCF, use immediate access (we can transmit
- // in a DIFS if the medium remains idle).
+ // in a DIFS if the medium remains idle). If this is an EDCAF, update
+ // the backoff start time kept by the EDCAF to the current time in order
+ // to correctly align the backoff start time at the next slot boundary
+ // (performed by the next call to ChannelAccessManager::RequestAccess())
Time delay = (IsQosTxop () ? Seconds (0) : m_low->GetSifs () + GetAifsn () * m_low->GetSlotTime ());
UpdateBackoffSlotsNow (0, Simulator::Now () + delay);
}
diff --git a/src/wifi/test/block-ack-test-suite.cc b/src/wifi/test/block-ack-test-suite.cc
index ae9cca68e..7521d61dc 100644
--- a/src/wifi/test/block-ack-test-suite.cc
+++ b/src/wifi/test/block-ack-test-suite.cc
@@ -868,14 +868,29 @@ BlockAckAggregationDisabledTest::DoRun (void)
packetSocket.Install (wifiStaNode);
packetSocket.Install (wifiApNode);
- Ptr client = CreateObject ();
- client->SetAttribute ("PacketSize", UintegerValue (1400));
- client->SetAttribute ("MaxPackets", UintegerValue (14));
- client->SetAttribute ("Interval", TimeValue (MicroSeconds (0)));
- client->SetRemote (socket);
- wifiStaNode.Get (0)->AddApplication (client);
- client->SetStartTime (Seconds (1));
- client->SetStopTime (Seconds (3.0));
+ // the first client application generates a single packet, which is sent
+ // with the normal ack policy because there are no other packets queued
+ Ptr client1 = CreateObject ();
+ client1->SetAttribute ("PacketSize", UintegerValue (1400));
+ client1->SetAttribute ("MaxPackets", UintegerValue (1));
+ client1->SetAttribute ("Interval", TimeValue (MicroSeconds (0)));
+ client1->SetRemote (socket);
+ wifiStaNode.Get (0)->AddApplication (client1);
+ client1->SetStartTime (Seconds (1));
+ client1->SetStopTime (Seconds (3.0));
+
+ // the second client application generates 13 packets. Even if when the first
+ // packet is queued the queue is empty, the first packet is not transmitted
+ // immediately, but the EDCAF waits for the next slot boundary. At that time,
+ // other packets have been queued, hence a BA agreement is established first.
+ Ptr client2 = CreateObject ();
+ client2->SetAttribute ("PacketSize", UintegerValue (1400));
+ client2->SetAttribute ("MaxPackets", UintegerValue (13));
+ client2->SetAttribute ("Interval", TimeValue (MicroSeconds (0)));
+ client2->SetRemote (socket);
+ wifiStaNode.Get (0)->AddApplication (client2);
+ client2->SetStartTime (Seconds (1.5));
+ client2->SetStopTime (Seconds (3.0));
Ptr server = CreateObject ();
server->SetLocal (socket);
@@ -892,7 +907,7 @@ BlockAckAggregationDisabledTest::DoRun (void)
Simulator::Destroy ();
- // The client application generates 14 packets, so we expect that the wifi PHY
+ // The client applications generate 14 packets, so we expect that the wifi PHY
// layer transmits 14 MPDUs, the server application receives 14 packets, and
// two BARs are transmitted.
NS_TEST_EXPECT_MSG_EQ (m_txTotal, 14, "Unexpected number of transmitted packets");
diff --git a/src/wifi/test/inter-bss-test-suite.cc b/src/wifi/test/inter-bss-test-suite.cc
index ef01a4ab9..5793ea562 100644
--- a/src/wifi/test/inter-bss-test-suite.cc
+++ b/src/wifi/test/inter-bss-test-suite.cc
@@ -231,11 +231,11 @@ TestInterBssConstantObssPdAlgo::SetupSimulation ()
// AP2 sends a packet 0.5s later.
Simulator::Schedule (Seconds (2.0), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, ap_device2, sta_device2, m_payloadSize2);
- Simulator::Schedule (Seconds (2.0) + MicroSeconds (1), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, ap_device2, WifiPhyState::TX);
+ Simulator::Schedule (Seconds (2.0) + MicroSeconds (5), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, ap_device2, WifiPhyState::TX);
// All other PHYs should have stay idle until 4us (preamble detection time).
- Simulator::Schedule (Seconds (2.0) + MicroSeconds (2), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, sta_device1, WifiPhyState::IDLE);
- Simulator::Schedule (Seconds (2.0) + MicroSeconds (2), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, sta_device2, WifiPhyState::IDLE);
- Simulator::Schedule (Seconds (2.0) + MicroSeconds (2), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, ap_device1, WifiPhyState::IDLE);
+ Simulator::Schedule (Seconds (2.0) + MicroSeconds (6), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, sta_device1, WifiPhyState::IDLE);
+ Simulator::Schedule (Seconds (2.0) + MicroSeconds (6), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, sta_device2, WifiPhyState::IDLE);
+ Simulator::Schedule (Seconds (2.0) + MicroSeconds (6), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, ap_device1, WifiPhyState::IDLE);
// All PHYs should be receiving the PHY header if preamble has been detected (always the case in this test).
Simulator::Schedule (Seconds (2.0) + MicroSeconds (10), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, sta_device1, WifiPhyState::RX);
Simulator::Schedule (Seconds (2.0) + MicroSeconds (10), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, sta_device2, WifiPhyState::RX);
@@ -251,18 +251,18 @@ TestInterBssConstantObssPdAlgo::SetupSimulation ()
// AP2 sends another packet 0.1s later.
Simulator::Schedule (Seconds (2.1), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, ap_device2, sta_device2, m_payloadSize2);
// STA1 sends a packet 100us later. Even though AP2 is still transmitting, STA1 can transmit simultaneously if it's PHY was reset by OBSS_PD SR.
- Simulator::Schedule (Seconds (2.1) + MicroSeconds (100), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, sta_device1, ap_device1, m_payloadSize1);
+ Simulator::Schedule (Seconds (2.1) + MicroSeconds (90), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, sta_device1, ap_device1, m_payloadSize1);
if (expectPhyReset)
{
// In this case, we check the TX power is restricted (and set the expected value slightly before transmission should occur)
double expectedTxPower = std::min (m_txPowerDbm, 21 - (m_obssPdLevelDbm + 82));
- Simulator::Schedule (Seconds (2.1) + MicroSeconds (99), &TestInterBssConstantObssPdAlgo::SetExpectedTxPower, this, expectedTxPower);
+ Simulator::Schedule (Seconds (2.1) + MicroSeconds (89), &TestInterBssConstantObssPdAlgo::SetExpectedTxPower, this, expectedTxPower);
}
// Check simultaneous transmissions
- Simulator::Schedule (Seconds (2.1) + MicroSeconds (105), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, sta_device1, expectPhyReset ? WifiPhyState::TX : WifiPhyState::RX);
- Simulator::Schedule (Seconds (2.1) + MicroSeconds (105), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, ap_device1, WifiPhyState::RX);
- Simulator::Schedule (Seconds (2.1) + MicroSeconds (105), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, sta_device2, WifiPhyState::RX);
- Simulator::Schedule (Seconds (2.1) + MicroSeconds (105), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, ap_device2, WifiPhyState::TX);
+ Simulator::Schedule (Seconds (2.1) + MicroSeconds (100), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, sta_device1, expectPhyReset ? WifiPhyState::TX : WifiPhyState::RX);
+ Simulator::Schedule (Seconds (2.1) + MicroSeconds (100), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, ap_device1, WifiPhyState::RX);
+ Simulator::Schedule (Seconds (2.1) + MicroSeconds (100), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, sta_device2, WifiPhyState::RX);
+ Simulator::Schedule (Seconds (2.1) + MicroSeconds (100), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, ap_device2, WifiPhyState::TX);
// Verify transmit power restrictions are not applied if access to the channel is requested after ignored OBSS transmissions.
@@ -280,14 +280,14 @@ TestInterBssConstantObssPdAlgo::SetupSimulation ()
// This test checks whether this sequence preserves transmit power restrictions if CCA resets occurred, since STA 1 has been deferring during ignored OBSS transmissions.
Simulator::Schedule (Seconds (2.4), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, sta_device2, ap_device2, m_payloadSize2 / 10);
- Simulator::Schedule (Seconds (2.4) + MicroSeconds (5), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, ap_device2, sta_device2, m_payloadSize2 / 10);
- Simulator::Schedule (Seconds (2.4) + MicroSeconds (65), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, ap_device1, sta_device1, m_payloadSize1 / 10);
- Simulator::Schedule (Seconds (2.4) + MicroSeconds (105), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, ap_device3, sta_device3, m_payloadSize3 / 10);
+ Simulator::Schedule (Seconds (2.4) + MicroSeconds (15), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, ap_device2, sta_device2, m_payloadSize2 / 10);
+ Simulator::Schedule (Seconds (2.4) + MicroSeconds (270), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, ap_device1, sta_device1, m_payloadSize1 / 10);
+ Simulator::Schedule (Seconds (2.4) + MicroSeconds (300), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, ap_device3, sta_device3, m_payloadSize3 / 10);
if (expectPhyReset)
{
// In this case, we check the TX power is restricted (and set the expected value slightly before transmission should occur)
double expectedTxPower = std::min (m_txPowerDbm, 21 - (m_obssPdLevelDbm + 82));
- Simulator::Schedule (Seconds (2.4) + MicroSeconds (450), &TestInterBssConstantObssPdAlgo::SetExpectedTxPower, this, expectedTxPower);
+ Simulator::Schedule (Seconds (2.4) + MicroSeconds (400), &TestInterBssConstantObssPdAlgo::SetExpectedTxPower, this, expectedTxPower);
}
Simulator::Stop (Seconds (2.5));
diff --git a/src/wifi/test/wifi-test.cc b/src/wifi/test/wifi-test.cc
index 1ca004537..649334970 100644
--- a/src/wifi/test/wifi-test.cc
+++ b/src/wifi/test/wifi-test.cc
@@ -1954,14 +1954,14 @@ private:
*/
void RunSubtest (PointerValue apErrorModel, PointerValue staErrorModel);
- uint8_t m_receivedNormalMpduCount; ///< Count received normal MPDU packets on STA
- uint8_t m_receivedAmpduCount; ///< Count received A-MPDU packets on STA
- uint8_t m_droppedActionCount; ///< Count dropped ADDBA request/response
- uint8_t m_addbaEstablishedCount; ///< Count number of times ADDBA state machine is in established state
- uint8_t m_addbaPendingCount; ///< Count number of times ADDBA state machine is in pending state
- uint8_t m_addbaRejectedCount; ///< Count number of times ADDBA state machine is in rejected state
- uint8_t m_addbaNoReplyCount; ///< Count number of times ADDBA state machine is in no_reply state
- uint8_t m_addbaResetCount; ///< Count number of times ADDBA state machine is in reset state
+ uint16_t m_receivedNormalMpduCount; ///< Count received normal MPDU packets on STA
+ uint16_t m_receivedAmpduCount; ///< Count received A-MPDU packets on STA
+ uint16_t m_droppedActionCount; ///< Count dropped ADDBA request/response
+ uint16_t m_addbaEstablishedCount; ///< Count number of times ADDBA state machine is in established state
+ uint16_t m_addbaPendingCount; ///< Count number of times ADDBA state machine is in pending state
+ uint16_t m_addbaRejectedCount; ///< Count number of times ADDBA state machine is in rejected state
+ uint16_t m_addbaNoReplyCount; ///< Count number of times ADDBA state machine is in no_reply state
+ uint16_t m_addbaResetCount; ///< Count number of times ADDBA state machine is in reset state
};
Bug2470TestCase::Bug2470TestCase ()
@@ -2096,8 +2096,10 @@ Bug2470TestCase::RunSubtest (PointerValue apErrorModel, PointerValue staErrorMod
Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxDrop", MakeCallback (&Bug2470TestCase::RxDropCallback, this));
Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::RegularWifiMac/BE_Txop/BlockAckManager/AgreementState", MakeCallback (&Bug2470TestCase::AddbaStateChangedCallback, this));
- Simulator::Schedule (Seconds (0.5), &Bug2470TestCase::SendPacketBurst, this, 5, apDevice.Get (0), staDevice.Get (0)->GetAddress ());
- Simulator::Schedule (Seconds (0.8), &Bug2470TestCase::SendPacketBurst, this, 5, apDevice.Get (0), staDevice.Get (0)->GetAddress ());
+ Simulator::Schedule (Seconds (0.5), &Bug2470TestCase::SendPacketBurst, this, 1, apDevice.Get (0), staDevice.Get (0)->GetAddress ());
+ Simulator::Schedule (Seconds (0.5) + MicroSeconds (5), &Bug2470TestCase::SendPacketBurst, this, 4, apDevice.Get (0), staDevice.Get (0)->GetAddress ());
+ Simulator::Schedule (Seconds (0.8), &Bug2470TestCase::SendPacketBurst, this, 1, apDevice.Get (0), staDevice.Get (0)->GetAddress ());
+ Simulator::Schedule (Seconds (0.8) + MicroSeconds (5), &Bug2470TestCase::SendPacketBurst, this, 4, apDevice.Get (0), staDevice.Get (0)->GetAddress ());
Simulator::Stop (Seconds (1.0));
Simulator::Run ();