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 102e5c95b..78c4af0de 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 82aa2bcb5..b888f6266 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 d0db66434..ceeeda55c 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 1293f85dd..2937feb10 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 f037a57a8..1f8177e2d 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 b393dc17f..0609c8f43 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 d2793cb00..2b8544f2b 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 588cb4b6e..d699267d1 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 4af3e6a3b..79faeb675 100644 --- a/src/wifi/model/channel-access-manager.cc +++ b/src/wifi/model/channel-access-manager.cc @@ -25,6 +25,7 @@ #include "wifi-phy-listener.h" #include "wifi-phy.h" #include "mac-low.h" +#include "frame-exchange-manager.h" namespace ns3 { @@ -136,6 +137,7 @@ ChannelAccessManager::DoDispose (void) i = 0; } m_phy = 0; + m_feManager = 0; } void @@ -168,6 +170,14 @@ ChannelAccessManager::SetupLow (Ptr low) low->RegisterChannelAccessManager (this); } +void +ChannelAccessManager::SetupFrameExchangeManager (Ptr feManager) +{ + NS_LOG_FUNCTION (this << feManager); + m_feManager = feManager; + m_feManager->SetChannelAccessManager (this); +} + Time ChannelAccessManager::GetSlot (void) const { @@ -372,18 +382,37 @@ ChannelAccessManager::DoGrantDcfAccess (void) } /** - * Now, we notify all of these changes in one go. It is necessary to + * Now, we notify all of these changes in one go if the EDCAF winning + * the contention actually transmitted a frame. It is necessary to * perform first the calculations of which Txops are colliding and then * only apply the changes because applying the changes through notification * could change the global state of the manager, and, thus, could change * the result of the calculations. */ - txop->NotifyAccessGranted (); - for (auto collidingTxop : internalCollisionTxops) - { - collidingTxop->NotifyInternalCollision (); + bool transmitted = true; + if (m_feManager != 0) + { + transmitted = m_feManager->StartTransmission (txop); + } + else + { + txop->NotifyAccessGranted (); + } + if (transmitted) + { + for (auto& collidingTxop : internalCollisionTxops) + { + collidingTxop->NotifyInternalCollision (); + } + break; + } + else + { + // reset the current state to the EDCAF that won the contention + // but did not transmit anything + i--; + k = std::distance (m_txops.begin (), i); } - break; } i++; } diff --git a/src/wifi/model/channel-access-manager.h b/src/wifi/model/channel-access-manager.h index 3c58766eb..b006b2925 100644 --- a/src/wifi/model/channel-access-manager.h +++ b/src/wifi/model/channel-access-manager.h @@ -32,6 +32,7 @@ class WifiPhy; class PhyListener; class Txop; class MacLow; +class FrameExchangeManager; /** * \brief Manage a set of ns3::Txop @@ -72,6 +73,12 @@ public: * \param low the MacLow to listen to */ void SetupLow (Ptr low); + /** + * Set up the Frame Exchange Manager. + * + * \param feManager the Frame Exchange Manager + */ + void SetupFrameExchangeManager (Ptr feManager); /** * \param txop a new Txop. @@ -291,28 +298,29 @@ private: */ typedef std::vector> Txops; - Txops m_txops; //!< the vector of managed Txops - Time m_lastAckTimeoutEnd; //!< the last Ack timeout end time - Time m_lastCtsTimeoutEnd; //!< the last CTS timeout end time - Time m_lastNavStart; //!< the last NAV start time - Time m_lastNavDuration; //!< the last NAV duration time - Time m_lastRxStart; //!< the last receive start time - Time m_lastRxDuration; //!< the last receive duration time - bool m_lastRxReceivedOk; //!< the last receive OK - Time m_lastTxStart; //!< the last transmit start time - Time m_lastTxDuration; //!< the last transmit duration time - Time m_lastBusyStart; //!< the last busy start time - Time m_lastBusyDuration; //!< the last busy duration time - Time m_lastSwitchingStart; //!< the last switching start time - Time m_lastSwitchingDuration; //!< the last switching duration time - bool m_sleeping; //!< flag whether it is in sleeping state - bool m_off; //!< flag whether it is in off state - Time m_eifsNoDifs; //!< EIFS no DIFS time - EventId m_accessTimeout; //!< the access timeout ID - Time m_slot; //!< the slot time - Time m_sifs; //!< the SIFS time - PhyListener* m_phyListener; //!< the PHY listener - Ptr m_phy; //!< pointer to the PHY + Txops m_txops; //!< the vector of managed Txops + Time m_lastAckTimeoutEnd; //!< the last Ack timeout end time + Time m_lastCtsTimeoutEnd; //!< the last CTS timeout end time + Time m_lastNavStart; //!< the last NAV start time + Time m_lastNavDuration; //!< the last NAV duration time + Time m_lastRxStart; //!< the last receive start time + Time m_lastRxDuration; //!< the last receive duration time + bool m_lastRxReceivedOk; //!< the last receive OK + Time m_lastTxStart; //!< the last transmit start time + Time m_lastTxDuration; //!< the last transmit duration time + Time m_lastBusyStart; //!< the last busy start time + Time m_lastBusyDuration; //!< the last busy duration time + Time m_lastSwitchingStart; //!< the last switching start time + Time m_lastSwitchingDuration; //!< the last switching duration time + bool m_sleeping; //!< flag whether it is in sleeping state + bool m_off; //!< flag whether it is in off state + Time m_eifsNoDifs; //!< EIFS no DIFS time + EventId m_accessTimeout; //!< the access timeout ID + Time m_slot; //!< the slot time + Time m_sifs; //!< the SIFS time + PhyListener* m_phyListener; //!< the PHY listener + Ptr m_phy; //!< pointer to the PHY + Ptr m_feManager; //!< pointer to the Frame Exchange Manager }; } //namespace ns3 diff --git a/src/wifi/model/mac-low.cc b/src/wifi/model/mac-low.cc index 5470724d3..43d0dcc6c 100644 --- a/src/wifi/model/mac-low.cc +++ b/src/wifi/model/mac-low.cc @@ -254,7 +254,6 @@ MacLow::SetPhy (const Ptr phy) { m_phy = phy; m_phy->TraceConnectWithoutContext ("PhyRxPayloadBegin", MakeCallback (&MacLow::RxStartIndication, this)); - m_phy->SetReceiveOkCallback (MakeCallback (&MacLow::DeaggregateAmpduAndReceive, this)); m_phy->SetReceiveErrorCallback (MakeCallback (&MacLow::ReceiveError, this)); SetupPhyMacLowListener (phy); } diff --git a/src/wifi/model/regular-wifi-mac.cc b/src/wifi/model/regular-wifi-mac.cc index 448cd5fca..d53667f37 100644 --- a/src/wifi/model/regular-wifi-mac.cc +++ b/src/wifi/model/regular-wifi-mac.cc @@ -36,6 +36,7 @@ #include "he-configuration.h" #include #include +#include "frame-exchange-manager.h" namespace ns3 { @@ -108,6 +109,11 @@ RegularWifiMac::DoDispose () m_phy = 0; m_stationManager = 0; + if (m_feManager != 0) + { + m_feManager->Dispose (); + } + m_feManager = 0; m_txop->Dispose (); m_txop = 0; @@ -124,6 +130,49 @@ RegularWifiMac::DoDispose () WifiMac::DoDispose (); } +void +RegularWifiMac::SetupFrameExchangeManager (void) +{ + NS_LOG_FUNCTION (this); + + if (GetHeSupported ()) + { + // TODO create an HE Frame Exchange Manager + } + else if (GetVhtSupported ()) + { + // TODO create a VHT Frame Exchange Manager + } + else if (GetHtSupported ()) + { + // TODO create an HT Frame Exchange Manager + } + else if (GetQosSupported ()) + { + // TODO create a QoS Frame Exchange Manager + } + else + { + m_feManager = CreateObject (); + } + + if (m_feManager != 0) + { + m_feManager->SetWifiMac (this); + m_feManager->SetMacTxMiddle (m_txMiddle); + m_feManager->SetMacRxMiddle (m_rxMiddle); + m_feManager->SetAddress (GetAddress ()); + m_feManager->SetBssid (GetBssid ()); + m_channelAccessManager->SetupFrameExchangeManager (m_feManager); + } +} + +Ptr +RegularWifiMac::GetFrameExchangeManager (void) const +{ + return m_feManager; +} + void RegularWifiMac::SetWifiRemoteStationManager (const Ptr stationManager) { @@ -499,6 +548,14 @@ RegularWifiMac::SetWifiPhy (const Ptr phy) m_phy = phy; m_channelAccessManager->SetupPhyListener (phy); m_low->SetPhy (phy); + if (m_feManager != 0) + { + m_feManager->SetWifiPhy (phy); + } + else + { + m_phy->SetReceiveOkCallback (MakeCallback (&MacLow::DeaggregateAmpduAndReceive, m_low)); + } } Ptr @@ -649,6 +706,10 @@ RegularWifiMac::SetBssid (Mac48Address bssid) { NS_LOG_FUNCTION (this << bssid); m_low->SetBssid (bssid); + if (m_feManager) + { + m_feManager->SetBssid (bssid); + } } Mac48Address @@ -1091,6 +1152,7 @@ RegularWifiMac::ConfigureStandard (WifiStandard standard) NS_FATAL_ERROR ("Unsupported WifiPhyStandard in RegularWifiMac::FinishConfigureStandard ()"); } + SetupFrameExchangeManager (); ConfigureContentionWindow (cwmin, cwmax); } diff --git a/src/wifi/model/regular-wifi-mac.h b/src/wifi/model/regular-wifi-mac.h index b75a50b24..d10c3eebe 100644 --- a/src/wifi/model/regular-wifi-mac.h +++ b/src/wifi/model/regular-wifi-mac.h @@ -32,6 +32,7 @@ class MacRxMiddle; class MacTxMiddle; class ChannelAccessManager; class ExtendedCapabilities; +class FrameExchangeManager; /** * \brief base class for all MAC-level wifi objects. @@ -102,6 +103,13 @@ public: */ virtual void TxFailed (const WifiMacHeader &hdr); + /** + * Get the Frame Exchange Manager + * + * \return the Frame Exchange Manager + */ + Ptr GetFrameExchangeManager (void) const; + /** * Enable or disable CTS-to-self feature. * @@ -169,11 +177,12 @@ protected: virtual void DoInitialize (); virtual void DoDispose (); - Ptr m_rxMiddle; //!< RX middle (defragmentation etc.) - Ptr m_txMiddle; //!< TX middle (aggregation etc.) - Ptr m_low; //!< MacLow (RTS, CTS, Data, Ack etc.) + Ptr m_rxMiddle; //!< RX middle (defragmentation etc.) + Ptr m_txMiddle; //!< TX middle (aggregation etc.) + Ptr m_low; //!< MacLow (RTS, CTS, Data, Ack etc.) Ptr m_channelAccessManager; //!< channel access manager - Ptr m_phy; //!< Wifi PHY + Ptr m_phy; //!< Wifi PHY + Ptr m_feManager; //!< Frame Exchange Manager Ptr m_stationManager; //!< Remote station manager (rate control, RTS/CTS/fragmentation thresholds etc.) @@ -294,6 +303,12 @@ protected: */ bool GetQosSupported () const; + /** + * Create a Frame Exchange Manager depending on the supported version + * of the standard. + */ + void SetupFrameExchangeManager (void); + /** * Return whether the device supports HT. * diff --git a/src/wifi/test/channel-access-manager-test.cc b/src/wifi/test/channel-access-manager-test.cc index b1a3bccbe..019b23588 100644 --- a/src/wifi/test/channel-access-manager-test.cc +++ b/src/wifi/test/channel-access-manager-test.cc @@ -21,6 +21,7 @@ #include "ns3/test.h" #include "ns3/simulator.h" #include "ns3/channel-access-manager.h" +#include "ns3/frame-exchange-manager.h" #include "ns3/qos-txop.h" #include "ns3/mac-low.h" @@ -60,6 +61,7 @@ private: /// Inherited void DoDispose (void); + void NotifyChannelAccessed (void); typedef std::pair ExpectedGrant; //!< the expected grant typedef typedef std::list ExpectedGrants; //!< the collection of expected grants typedef @@ -75,19 +77,6 @@ private: ExpectedBackoffs m_expectedBackoff; //!< expected backoff (not due to an internal collision) ExpectedGrants m_expectedGrants; //!< expected grants - /** - * \returns true if access has been requested for this function and - * has not been granted already, false otherwise. - */ - bool IsAccessRequested (void) const; - /** - * Notify that access request has been received. - */ - void NotifyAccessRequested (void); - /** - * Notify the Txop that access has been granted. - */ - void NotifyAccessGranted (void); /** * Notify the Txop that internal collision has occurred. */ @@ -117,7 +106,6 @@ private: ChannelAccessManagerTest *m_test; //!< the test DCF/EDCA manager uint32_t m_i; //!< the index of the Txop - bool m_accessRequested; //!< true if access requested }; /** @@ -206,6 +194,32 @@ private: Time m_eifsNoDifs; // EIFS duration minus a DIFS }; +/** + * \ingroup wifi-test + * \ingroup tests + * + * \brief Frame Exchange Manager Stub + */ +class FrameExchangeManagerStub : public FrameExchangeManager +{ +public: + FrameExchangeManagerStub () + { + } + /** + * Request the FrameExchangeManager to start a frame exchange sequence. + * + * \param dcf the channel access function that gained channel access. It is + * the DCF on non-QoS stations and an EDCA on QoS stations. + * \return true if a frame exchange sequence was started, false otherwise + */ + bool StartTransmission (Ptr dcf) + { + dcf->NotifyChannelAccessed (); + return true; + } +}; + /** * \ingroup wifi-test * \ingroup tests @@ -387,6 +401,7 @@ private: typedef std::vector>> TxopTests; //!< the TXOP tests typedef Ptr m_low; //!< the MAC low stubbed + Ptr m_feManager; //!< the Frame Exchange Manager stubbed Ptr m_ChannelAccessManager; //!< the channel access manager TxopTests m_txop; //!< the vector of Txop test instances uint32_t m_ackTimeoutValue; //!< the Ack timeout value @@ -402,8 +417,7 @@ TxopTest::QueueTx (uint64_t txTime, uint64_t expectedGrantTime) template TxopTest::TxopTest (ChannelAccessManagerTest *test, uint32_t i) : m_test (test), - m_i (i), - m_accessRequested (false) + m_i (i) { } @@ -415,25 +429,11 @@ TxopTest::DoDispose (void) Txop::DoDispose (); } -template -bool -TxopTest::IsAccessRequested (void) const -{ - return m_accessRequested; -} - template void -TxopTest::NotifyAccessRequested (void) +TxopTest::NotifyChannelAccessed (void) { - m_accessRequested = true; -} - -template -void -TxopTest::NotifyAccessGranted (void) -{ - m_accessRequested = false; + Txop::m_access = Txop::NOT_REQUESTED; m_test->NotifyAccessGranted (m_i); } @@ -549,7 +549,7 @@ ChannelAccessManagerTest::NotifyChannelSwitching (uint32_t i) state->m_expectedGrants.pop_front (); NS_TEST_EXPECT_MSG_EQ (Simulator::Now (), MicroSeconds (expected.second), "Expected grant is now"); } - state->m_accessRequested = false; + state->Txop::m_access = Txop::NOT_REQUESTED; } template @@ -596,6 +596,8 @@ ChannelAccessManagerTest::StartTest (uint64_t slotTime, uint64_t sifs, m_ChannelAccessManager = CreateObject (); m_low = CreateObject (); m_ChannelAccessManager->SetupLow (m_low); + m_feManager = CreateObject (); + m_ChannelAccessManager->SetupFrameExchangeManager (m_feManager); m_ChannelAccessManager->SetSlot (MicroSeconds (slotTime)); m_ChannelAccessManager->SetSifs (MicroSeconds (sifs)); m_ChannelAccessManager->SetEifsNoDifs (MicroSeconds (eifsNoDifsNoSifs + sifs)); @@ -633,6 +635,7 @@ ChannelAccessManagerTest::EndTest (void) m_ChannelAccessManager = 0; m_low = 0; + m_feManager = 0; } template diff --git a/src/wifi/test/wifi-aggregation-test.cc b/src/wifi/test/wifi-aggregation-test.cc index 639803f6c..da63e7041 100644 --- a/src/wifi/test/wifi-aggregation-test.cc +++ b/src/wifi/test/wifi-aggregation-test.cc @@ -102,10 +102,10 @@ AmpduAggregationTest::DoRun (void) */ m_mac = CreateObject (); m_mac->SetDevice (m_device); - m_mac->SetWifiPhy (m_phy); m_mac->SetWifiRemoteStationManager (m_manager); m_mac->SetAddress (Mac48Address ("00:00:00:00:00:01")); m_mac->ConfigureStandard (WIFI_STANDARD_80211n_5GHZ); + m_mac->SetWifiPhy (m_phy); m_device->SetMac (m_mac); /* @@ -308,10 +308,10 @@ TwoLevelAggregationTest::DoRun (void) */ m_mac = CreateObject (); m_mac->SetDevice (m_device); - m_mac->SetWifiPhy (m_phy); m_mac->SetWifiRemoteStationManager (m_manager); m_mac->SetAddress (Mac48Address ("00:00:00:00:00:01")); m_mac->ConfigureStandard (WIFI_STANDARD_80211n_5GHZ); + m_mac->SetWifiPhy (m_phy); m_device->SetMac (m_mac); /* @@ -529,10 +529,10 @@ HeAggregationTest::DoRunSubTest (uint16_t bufferSize) */ m_mac = CreateObject (); m_mac->SetDevice (m_device); - m_mac->SetWifiPhy (m_phy); m_mac->SetWifiRemoteStationManager (m_manager); m_mac->SetAddress (Mac48Address ("00:00:00:00:00:01")); m_mac->ConfigureStandard (WIFI_STANDARD_80211ax_5GHZ); + m_mac->SetWifiPhy (m_phy); m_device->SetMac (m_mac); /* diff --git a/src/wifi/test/wifi-test.cc b/src/wifi/test/wifi-test.cc index 2f3a469bc..d35f79269 100644 --- a/src/wifi/test/wifi-test.cc +++ b/src/wifi/test/wifi-test.cc @@ -1580,10 +1580,10 @@ private: Ptr m_apPhy; ///< AP PHY Ptr m_staPhy; ///< STA PHY - uint8_t m_reassocReqCount; ///< count number of reassociation requests - uint8_t m_reassocRespCount; ///< count number of reassociation responses - uint8_t m_countOperationalChannelWidth20; ///< count number of beacon frames announcing a 20 MHz operating channel width - uint8_t m_countOperationalChannelWidth40; ///< count number of beacon frames announcing a 40 MHz operating channel width + uint16_t m_reassocReqCount; ///< count number of reassociation requests + uint16_t m_reassocRespCount; ///< count number of reassociation responses + uint16_t m_countOperationalChannelWidth20; ///< count number of beacon frames announcing a 20 MHz operating channel width + uint16_t m_countOperationalChannelWidth40; ///< count number of beacon frames announcing a 40 MHz operating channel width }; Bug2831TestCase::Bug2831TestCase () @@ -1658,6 +1658,7 @@ Bug2831TestCase::DoRun (void) mac.Set ("EnableBeaconJitter", BooleanValue (false)); Ptr apMac = mac.Create (); apMac->SetDevice (apDev); + apMac->SetAddress (Mac48Address::Allocate ()); apMac->ConfigureStandard (WIFI_STANDARD_80211ax_5GHZ); Ptr staNode = CreateObject (); @@ -1667,6 +1668,7 @@ Bug2831TestCase::DoRun (void) mac.SetTypeId ("ns3::StaWifiMac"); Ptr staMac = mac.Create (); staMac->SetDevice (staDev); + staMac->SetAddress (Mac48Address::Allocate ()); staMac->ConfigureStandard (WIFI_STANDARD_80211ax_5GHZ); Ptr apMobility = CreateObject (); @@ -1696,7 +1698,6 @@ Bug2831TestCase::DoRun (void) m_staPhy->SetChannelNumber (36); m_staPhy->SetChannelWidth (20); - apMac->SetAddress (Mac48Address::Allocate ()); apDev->SetMac (apMac); apDev->SetPhy (m_apPhy); ObjectFactory manager; @@ -1704,7 +1705,6 @@ Bug2831TestCase::DoRun (void) apDev->SetRemoteStationManager (manager.Create ()); apNode->AddDevice (apDev); - staMac->SetAddress (Mac48Address::Allocate ()); staDev->SetMac (staMac); staDev->SetPhy (m_staPhy); staDev->SetRemoteStationManager (manager.Create ());