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 ();