diff --git a/src/aodv/test/aodv-chain-regression-test-0-0.pcap b/src/aodv/test/aodv-chain-regression-test-0-0.pcap index 9c8c80047..3108090ba 100644 Binary files a/src/aodv/test/aodv-chain-regression-test-0-0.pcap and b/src/aodv/test/aodv-chain-regression-test-0-0.pcap differ diff --git a/src/aodv/test/aodv-chain-regression-test-1-0.pcap b/src/aodv/test/aodv-chain-regression-test-1-0.pcap index 4d6410f9d..bcd1f00f4 100644 Binary files a/src/aodv/test/aodv-chain-regression-test-1-0.pcap and b/src/aodv/test/aodv-chain-regression-test-1-0.pcap differ diff --git a/src/aodv/test/aodv-chain-regression-test-2-0.pcap b/src/aodv/test/aodv-chain-regression-test-2-0.pcap index 0ee28de79..9d233047f 100644 Binary files a/src/aodv/test/aodv-chain-regression-test-2-0.pcap and b/src/aodv/test/aodv-chain-regression-test-2-0.pcap differ diff --git a/src/aodv/test/aodv-chain-regression-test-3-0.pcap b/src/aodv/test/aodv-chain-regression-test-3-0.pcap index 30c4ea28a..ad5ae327f 100644 Binary files a/src/aodv/test/aodv-chain-regression-test-3-0.pcap and b/src/aodv/test/aodv-chain-regression-test-3-0.pcap differ diff --git a/src/aodv/test/aodv-chain-regression-test-4-0.pcap b/src/aodv/test/aodv-chain-regression-test-4-0.pcap index ab9bb4adf..977c4acce 100644 Binary files a/src/aodv/test/aodv-chain-regression-test-4-0.pcap and b/src/aodv/test/aodv-chain-regression-test-4-0.pcap differ diff --git a/src/aodv/test/bug-606-test-0-0.pcap b/src/aodv/test/bug-606-test-0-0.pcap index cf91f88e8..97e12d641 100644 Binary files a/src/aodv/test/bug-606-test-0-0.pcap and b/src/aodv/test/bug-606-test-0-0.pcap differ diff --git a/src/aodv/test/bug-606-test-1-0.pcap b/src/aodv/test/bug-606-test-1-0.pcap index e44c9bf1b..6b4c7e3b4 100644 Binary files a/src/aodv/test/bug-606-test-1-0.pcap and b/src/aodv/test/bug-606-test-1-0.pcap differ diff --git a/src/aodv/test/bug-606-test-2-0.pcap b/src/aodv/test/bug-606-test-2-0.pcap index d364a162f..73a18bacc 100644 Binary files a/src/aodv/test/bug-606-test-2-0.pcap and b/src/aodv/test/bug-606-test-2-0.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 c8fe30e0f..16e37045d 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 53a6e6093..3bb49f0d7 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/flame/flame-regression-test-2-1.pcap b/src/mesh/test/flame/flame-regression-test-2-1.pcap index cc5204dbe..588cb4b6e 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/model/channel-access-manager.cc b/src/wifi/model/channel-access-manager.cc index bcdeae75e..ee64cb5a3 100644 --- a/src/wifi/model/channel-access-manager.cc +++ b/src/wifi/model/channel-access-manager.cc @@ -242,6 +242,56 @@ ChannelAccessManager::IsBusy (void) const return false; } +bool +ChannelAccessManager::NeedBackoffUponAccess (Ptr txop) +{ + NS_LOG_FUNCTION (this << txop); + + // the Txop might have a stale value of remaining backoff slots + UpdateBackoff (); + + /* + * From section 10.3.4.2 "Basic access" of IEEE 802.11-2016: + * + * A STA may transmit an MPDU when it is operating under the DCF access + * method, either in the absence of a PC, or in the CP of the PCF 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. + * + * From section 10.22.2.2 "EDCA backoff procedure" of IEEE 802.11-2016: + * + * The backoff procedure shall be invoked by an EDCAF when any of the following + * events occurs: + * a) An MA-UNITDATA.request primitive is received that causes a frame with that AC + * to be 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 + */ + if (!txop->HasFramesToTransmit () && !txop->GetLow ()->IsCfPeriod () && txop->GetBackoffSlots () == 0) + { + if (!IsBusy ()) + { + // medium idle. If this is a DCF, use immediate access (we can transmit + // 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 = (txop->IsQosTxop () ? Seconds (0) + : m_sifs + txop->GetAifsn () * m_slot); + txop->UpdateBackoffSlotsNow (0, Simulator::Now () + delay); + } + else + { + // medium busy, backoff is neeeded + return true; + } + } + return false; +} + void ChannelAccessManager::RequestAccess (Ptr state, bool isCfPeriod) { diff --git a/src/wifi/model/channel-access-manager.h b/src/wifi/model/channel-access-manager.h index ad0dbd56c..7d68376f9 100644 --- a/src/wifi/model/channel-access-manager.h +++ b/src/wifi/model/channel-access-manager.h @@ -112,6 +112,15 @@ public: */ void Add (Ptr dcf); + /** + * Determine if a new backoff needs to be generated when a packet is queued + * for transmission. + * + * \param txop the Txop requesting to generate a backoff + * \return true if backoff needs to be generated, false otherwise + */ + bool NeedBackoffUponAccess (Ptr txop); + /** * \param state a Txop * \param isCfPeriod flag whether it is called during the CF period diff --git a/src/wifi/model/txop.cc b/src/wifi/model/txop.cc index dc387659b..7b15b7bd0 100644 --- a/src/wifi/model/txop.cc +++ b/src/wifi/model/txop.cc @@ -312,50 +312,6 @@ Txop::HasFramesToTransmit (void) return ret; } -void -Txop::GenerateBackoffUponAccessIfNeeded (void) -{ - NS_LOG_FUNCTION (this); - /* - * From section 10.3.4.2 "Basic access" of IEEE 802.11-2016: - * - * A STA may transmit an MPDU when it is operating under the DCF access - * method, either in the absence of a PC, or in the CP of the PCF 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. - * - * From section 10.22.2.2 "EDCA backoff procedure" of IEEE 802.11-2016: - * - * The backoff procedure shall be invoked by an EDCAF when any of the following - * events occurs: - * a) An MA-UNITDATA.request primitive is received that causes a frame with that AC - * to be 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 - */ - if (!HasFramesToTransmit () && !m_low->IsCfPeriod () && m_backoffSlots == 0) - { - 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). 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); - } - else - { - // medium busy, generate backoff - GenerateBackoff (); - } - } -} - void Txop::Queue (Ptr packet, const WifiMacHeader &hdr) { @@ -365,7 +321,10 @@ Txop::Queue (Ptr packet, const WifiMacHeader &hdr) SocketPriorityTag priorityTag; packetCopy->RemovePacketTag (priorityTag); m_stationManager->PrepareForQueue (hdr.GetAddr1 (), &hdr, packetCopy); - GenerateBackoffUponAccessIfNeeded (); + if (m_channelAccessManager->NeedBackoffUponAccess (this)) + { + GenerateBackoff (); + } m_queue->Enqueue (Create (packetCopy, hdr)); StartAccessIfNeeded (); } diff --git a/src/wifi/model/txop.h b/src/wifi/model/txop.h index 606f8078c..0fb0c6dec 100644 --- a/src/wifi/model/txop.h +++ b/src/wifi/model/txop.h @@ -376,10 +376,6 @@ protected: * \return true if the DCF has frames to transmit. */ virtual bool HasFramesToTransmit (void); - /** - * Generate a new backoff, if needed, when a packet is queued for transmission. - */ - virtual void GenerateBackoffUponAccessIfNeeded (void); /** * Generate a new backoff now. */ diff --git a/src/wifi/test/channel-access-manager-test.cc b/src/wifi/test/channel-access-manager-test.cc index a6126a557..758c567a3 100644 --- a/src/wifi/test/channel-access-manager-test.cc +++ b/src/wifi/test/channel-access-manager-test.cc @@ -679,7 +679,10 @@ void ChannelAccessManagerTest::DoAccessRequest (uint64_t txTime, uint64_t expectedGrantTime, Ptr> state) { - state->GenerateBackoffUponAccessIfNeeded (); + if (m_ChannelAccessManager->NeedBackoffUponAccess (state)) + { + state->GenerateBackoff (); + } state->QueueTx (txTime, expectedGrantTime); m_ChannelAccessManager->RequestAccess (state); } diff --git a/src/wifi/test/wifi-test.cc b/src/wifi/test/wifi-test.cc index 0be76272b..97533ddc9 100644 --- a/src/wifi/test/wifi-test.cc +++ b/src/wifi/test/wifi-test.cc @@ -460,7 +460,6 @@ DcfImmediateAccessBroadcastTestCase::NotifyPhyTxBegin (Ptr p, doub { 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 (); } @@ -536,13 +535,17 @@ DcfImmediateAccessBroadcastTestCase::DoRun (void) Simulator::Run (); Simulator::Destroy (); + // First packet is transmitted a DIFS after the packet is queued. A DIFS + // is 2 slots (2 * 9 = 18 us) plus a SIFS (16 us), i.e., 34 us + Time expectedFirstTransmissionTime = Seconds (1.0) + MicroSeconds (34); + //First packet has 1408 us of transmit time. Slot time is 9 us. //Backoff is 1 slots. SIFS is 16 us. DIFS is 2 slots = 18 us. //Should send next packet at 1408 us + (1 * 9 us) + 16 us + (2 * 9) us //1451 us after the first one. uint32_t expectedWait1 = 1408 + (1 * 9) + 16 + (2 * 9); - Time expectedSecondTransmissionTime = MicroSeconds (expectedWait1) + MilliSeconds (1000); - NS_TEST_ASSERT_MSG_EQ (m_firstTransmissionTime, MilliSeconds (1000), "The first transmission time not correct!"); + Time expectedSecondTransmissionTime = expectedFirstTransmissionTime + MicroSeconds (expectedWait1); + NS_TEST_ASSERT_MSG_EQ (m_firstTransmissionTime, expectedFirstTransmissionTime, "The first transmission time not correct!"); NS_TEST_ASSERT_MSG_EQ (m_secondTransmissionTime, expectedSecondTransmissionTime, "The second transmission time not correct!"); }