From a3c69b62ea7a7e48ca9aa312f25015884c6cbba9 Mon Sep 17 00:00:00 2001 From: Rediet Date: Tue, 19 Jan 2021 10:47:14 +0100 Subject: [PATCH] wifi: Add static and supported PhyEntity maps in WifiPhy Map of static PHY entities is invoked by static methods Prepares subsequent commit where mode handling will be moved from WifiPhy to PhyEntity --- src/wifi/model/dsss-phy.cc | 4 ++ src/wifi/model/erp-ofdm-phy.cc | 2 + src/wifi/model/he-phy.cc | 2 + src/wifi/model/ht-phy.cc | 2 + src/wifi/model/ofdm-phy.cc | 2 + src/wifi/model/vht-phy.cc | 2 + src/wifi/model/wifi-phy.cc | 85 ++++++++++++++++++++++++++++++-- src/wifi/model/wifi-phy.h | 70 +++++++++++++++++++++++++- src/wifi/model/wifi-tx-vector.cc | 5 +- 9 files changed, 166 insertions(+), 8 deletions(-) diff --git a/src/wifi/model/dsss-phy.cc b/src/wifi/model/dsss-phy.cc index 560791280..da43e1031 100644 --- a/src/wifi/model/dsss-phy.cc +++ b/src/wifi/model/dsss-phy.cc @@ -21,6 +21,7 @@ */ #include "dsss-phy.h" +#include "wifi-phy.h" //only used for static mode constructor #include "ns3/log.h" namespace ns3 { @@ -197,6 +198,9 @@ public: ConstructorDsss () { ns3::DsssPhy::InitializeModes (); + ns3::Ptr phyEntity = ns3::Create (); + ns3::WifiPhy::AddStaticPhyEntity (ns3::WIFI_MOD_CLASS_HR_DSSS, phyEntity); + ns3::WifiPhy::AddStaticPhyEntity (ns3::WIFI_MOD_CLASS_DSSS, phyEntity); //use same entity when plain DSSS modes are used } } g_constructor_dsss; ///< the constructor for DSSS modes diff --git a/src/wifi/model/erp-ofdm-phy.cc b/src/wifi/model/erp-ofdm-phy.cc index 51244002b..558f188a6 100644 --- a/src/wifi/model/erp-ofdm-phy.cc +++ b/src/wifi/model/erp-ofdm-phy.cc @@ -21,6 +21,7 @@ */ #include "erp-ofdm-phy.h" +#include "wifi-phy.h" //only used for static mode constructor #include "ns3/log.h" #include "ns3/assert.h" @@ -207,6 +208,7 @@ public: ConstructorErpOfdm () { ns3::ErpOfdmPhy::InitializeModes (); + ns3::WifiPhy::AddStaticPhyEntity (ns3::WIFI_MOD_CLASS_ERP_OFDM, ns3::Create ()); } } g_constructor_erp_ofdm; ///< the constructor for ERP-OFDM modes diff --git a/src/wifi/model/he-phy.cc b/src/wifi/model/he-phy.cc index 51c8945d9..3840117df 100644 --- a/src/wifi/model/he-phy.cc +++ b/src/wifi/model/he-phy.cc @@ -20,6 +20,7 @@ */ #include "he-phy.h" +#include "wifi-phy.h" //only used for static mode constructor #include "ns3/log.h" #include "ns3/assert.h" @@ -286,6 +287,7 @@ public: ConstructorHe () { ns3::HePhy::InitializeModes (); + ns3::WifiPhy::AddStaticPhyEntity (ns3::WIFI_MOD_CLASS_HE, ns3::Create ()); } } g_constructor_he; ///< the constructor for HE modes diff --git a/src/wifi/model/ht-phy.cc b/src/wifi/model/ht-phy.cc index 22786516b..56aeaaa6c 100644 --- a/src/wifi/model/ht-phy.cc +++ b/src/wifi/model/ht-phy.cc @@ -20,6 +20,7 @@ */ #include "ht-phy.h" +#include "wifi-phy.h" //only used for static mode constructor #include "ns3/log.h" #include "ns3/assert.h" @@ -546,6 +547,7 @@ public: ConstructorHt () { ns3::HtPhy::InitializeModes (); + ns3::WifiPhy::AddStaticPhyEntity (ns3::WIFI_MOD_CLASS_HT, ns3::Create ()); //dummy Nss } } g_constructor_ht; ///< the constructor for HT modes diff --git a/src/wifi/model/ofdm-phy.cc b/src/wifi/model/ofdm-phy.cc index 9fad0df1c..0aa85af7d 100644 --- a/src/wifi/model/ofdm-phy.cc +++ b/src/wifi/model/ofdm-phy.cc @@ -21,6 +21,7 @@ */ #include "ofdm-phy.h" +#include "wifi-phy.h" //only used for static mode constructor #include "ns3/log.h" #include "ns3/assert.h" @@ -558,6 +559,7 @@ public: ConstructorOfdm () { ns3::OfdmPhy::InitializeModes (); + ns3::WifiPhy::AddStaticPhyEntity (ns3::WIFI_MOD_CLASS_OFDM, ns3::Create ()); //default variant will do } } g_constructor_ofdm; ///< the constructor for OFDM modes diff --git a/src/wifi/model/vht-phy.cc b/src/wifi/model/vht-phy.cc index e35482592..946a1a492 100644 --- a/src/wifi/model/vht-phy.cc +++ b/src/wifi/model/vht-phy.cc @@ -20,6 +20,7 @@ */ #include "vht-phy.h" +#include "wifi-phy.h" //only used for static mode constructor #include "ns3/log.h" #include "ns3/assert.h" @@ -252,6 +253,7 @@ public: ConstructorVht () { ns3::VhtPhy::InitializeModes (); + ns3::WifiPhy::AddStaticPhyEntity (ns3::WIFI_MOD_CLASS_VHT, ns3::Create ()); } } g_constructor_vht; ///< the constructor for VHT modes diff --git a/src/wifi/model/wifi-phy.cc b/src/wifi/model/wifi-phy.cc index 12b6d90bb..9186c1ba5 100644 --- a/src/wifi/model/wifi-phy.cc +++ b/src/wifi/model/wifi-phy.cc @@ -40,6 +40,8 @@ #include "mpdu-aggregator.h" #include "wifi-psdu.h" #include "ap-wifi-mac.h" +#include "dsss-phy.h" +#include "erp-ofdm-phy.h" #include "he-phy.h" //includes OFDM, HT, and VHT namespace ns3 { @@ -288,6 +290,8 @@ WifiPhy::ChannelToFrequencyWidthMap WifiPhy::m_channelToFrequencyWidth = { { {207, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6975, 160} } }; +std::map > WifiPhy::m_staticPhyEntities; //will be filled by g_constructor_XXX + TypeId WifiPhy::GetTypeId (void) { @@ -583,6 +587,12 @@ WifiPhy::DoDispose (void) m_deviceMcsSet.clear (); m_mcsIndexMap.clear (); m_currentPreambleEvents.clear (); + + for (auto & phyEntity : m_phyEntities) + { + phyEntity.second = 0; + } + m_phyEntities.clear (); } void @@ -965,6 +975,48 @@ WifiPhy::ConfigureDefaultsForStandard (void) } } +const Ptr +WifiPhy::GetStaticPhyEntity (WifiModulationClass modulation) +{ + const auto it = m_staticPhyEntities.find (modulation); + NS_ABORT_MSG_IF (it == m_staticPhyEntities.end (), "Unimplemented Wi-Fi modulation class"); + return it->second; +} + +const Ptr +WifiPhy::GetPhyEntity (WifiModulationClass modulation) const +{ + const auto it = m_phyEntities.find (modulation); + NS_ABORT_MSG_IF (it == m_phyEntities.end (), "Unsupported Wi-Fi modulation class"); + return it->second; +} + +Ptr +WifiPhy::GetPhyEntity (WifiModulationClass modulation) +{ + //This method returns a non-const pointer to be used by child classes + const auto it = m_phyEntities.find (modulation); + NS_ABORT_MSG_IF (it == m_phyEntities.end (), "Unsupported Wi-Fi modulation class"); + return it->second; +} + +void +WifiPhy::AddStaticPhyEntity (WifiModulationClass modulation, Ptr phyEntity) +{ + NS_LOG_FUNCTION (modulation); + NS_ASSERT_MSG (m_staticPhyEntities.find (modulation) == m_staticPhyEntities.end (), "The PHY entity has already been added. The setting should only be done once per modulation class"); + m_staticPhyEntities[modulation] = phyEntity; +} + +void +WifiPhy::AddPhyEntity (WifiModulationClass modulation, Ptr phyEntity) +{ + NS_LOG_FUNCTION (this << modulation); + NS_ABORT_MSG_IF (m_staticPhyEntities.find (modulation) == m_staticPhyEntities.end (), "Cannot add an unimplemented PHY to supported list. Update the former first."); + NS_ASSERT_MSG (m_phyEntities.find (modulation) == m_phyEntities.end (), "The PHY entity has already been added. The setting should only be done once per modulation class"); + m_phyEntities[modulation] = phyEntity; +} + void WifiPhy::SetSifs (Time sifs) { @@ -1017,6 +1069,7 @@ void WifiPhy::Configure80211a (void) { NS_LOG_FUNCTION (this); + AddPhyEntity (WIFI_MOD_CLASS_OFDM, Create ()); // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016 SetSifs (MicroSeconds (16)); @@ -1040,6 +1093,9 @@ void WifiPhy::Configure80211b (void) { NS_LOG_FUNCTION (this); + Ptr phyEntity = Create (); + AddPhyEntity (WIFI_MOD_CLASS_HR_DSSS, phyEntity); + AddPhyEntity (WIFI_MOD_CLASS_DSSS, phyEntity); //when plain DSSS modes are used // See Table 16-4 "HR/DSSS PHY characteristics" of 802.11-2016 SetSifs (MicroSeconds (10)); @@ -1065,6 +1121,7 @@ WifiPhy::Configure80211g (void) // if the user sets the ShortSlotTimeSupported flag to true and when the BSS // consists of only ERP STAs capable of supporting this option. Configure80211b (); + AddPhyEntity (WIFI_MOD_CLASS_ERP_OFDM, Create ()); m_deviceRateSet.push_back (WifiPhy::GetErpOfdmRate6Mbps ()); m_deviceRateSet.push_back (WifiPhy::GetErpOfdmRate9Mbps ()); @@ -1082,6 +1139,8 @@ WifiPhy::Configure80211p (void) NS_LOG_FUNCTION (this); if (GetChannelWidth () == 10) { + AddPhyEntity (WIFI_MOD_CLASS_OFDM, Create (OFDM_PHY_10_MHZ)); + // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016 SetSifs (MicroSeconds (32)); SetSlot (MicroSeconds (13)); @@ -1099,6 +1158,8 @@ WifiPhy::Configure80211p (void) } else if (GetChannelWidth () == 5) { + AddPhyEntity (WIFI_MOD_CLASS_OFDM, Create (OFDM_PHY_5_MHZ)); + // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016 SetSifs (MicroSeconds (64)); SetSlot (MicroSeconds (21)); @@ -1124,6 +1185,7 @@ void WifiPhy::ConfigureHolland (void) { NS_LOG_FUNCTION (this); + AddPhyEntity (WIFI_MOD_CLASS_OFDM, Create (OFDM_PHY_HOLLAND)); SetSifs (MicroSeconds (16)); SetSlot (MicroSeconds (9)); @@ -1243,6 +1305,8 @@ WifiPhy::Configure80211n (void) { Configure80211a (); } + AddPhyEntity (WIFI_MOD_CLASS_HT, Create (m_txSpatialStreams)); + // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties // of the PPDU causing the EIFS" of 802.11-2016 m_blockAckTxTime = MicroSeconds (68); @@ -1255,6 +1319,7 @@ WifiPhy::Configure80211ac (void) { NS_LOG_FUNCTION (this); Configure80211n (); + AddPhyEntity (WIFI_MOD_CLASS_VHT, Create ()); PushMcs (WifiPhy::GetVhtMcs0 ()); PushMcs (WifiPhy::GetVhtMcs1 ()); @@ -1282,6 +1347,7 @@ WifiPhy::Configure80211ax (void) { Configure80211ac (); } + AddPhyEntity (WIFI_MOD_CLASS_HE, Create ()); PushMcs (WifiPhy::GetHeMcs0 ()); PushMcs (WifiPhy::GetHeMcs1 ()); @@ -1442,7 +1508,7 @@ WifiPhy::ConfigureStandardAndBand (WifiPhyStandard standard, WifiPhyBand band) break; case WIFI_PHY_STANDARD_UNSPECIFIED: default: - NS_ASSERT (false); + NS_ASSERT_MSG (false, "Unsupported standard"); break; } } @@ -1564,9 +1630,22 @@ WifiPhy::SetMaxSupportedTxSpatialStreams (uint8_t streams) bool changed = (m_txSpatialStreams != streams); m_txSpatialStreams = streams; ConfigureHtDeviceMcsSet (); - if (changed && !m_capabilitiesChangedCallback.IsNull ()) + if (changed) { - m_capabilitiesChangedCallback (); + auto phyEntity = m_phyEntities.find (WIFI_MOD_CLASS_HT); + if (phyEntity != m_phyEntities.end ()) + { + Ptr htPhy = DynamicCast (phyEntity->second); + if (htPhy) + { + htPhy->SetMaxSupportedNss (m_txSpatialStreams); //this is essential to have the right MCSs configured + } + + if (!m_capabilitiesChangedCallback.IsNull ()) + { + m_capabilitiesChangedCallback (); + } + } } } diff --git a/src/wifi/model/wifi-phy.h b/src/wifi/model/wifi-phy.h index 6be9c5dba..2475ecb64 100644 --- a/src/wifi/model/wifi-phy.h +++ b/src/wifi/model/wifi-phy.h @@ -41,7 +41,7 @@ class FrameCaptureModel; class PreambleDetectionModel; class WifiRadioEnergyModel; class UniformRandomVariable; -class WifiPsdu; +class PhyEntity; /** * Enumeration of the possible reception failure reasons. @@ -1835,6 +1835,36 @@ public: */ WifiSpectrumBand GetNonOfdmaBand (WifiTxVector txVector, uint16_t staId) const; + /** + * Add the PHY entity to the map of __implemented__ PHY entities for the + * given modulation class. + * Through this method, child classes can add their own PHY entities in + * a static manner. + * + * \param modulation the modulation class + * \param phyEntity the PHY entity + */ + static void AddStaticPhyEntity (WifiModulationClass modulation, Ptr phyEntity); + + /** + * Get the __implemented__ PHY entity corresponding to the modulation class. + * This is used to compute the different amendment-specific parameters within + * calling static methods. + * + * \param modulation the modulation class + * \return the pointer to the static implemented PHY entity + */ + static const Ptr GetStaticPhyEntity (WifiModulationClass modulation); + + /** + * Get the supported PHY entity corresponding to the modulation class, for + * the WifiPhy instance. + * + * \param modulation the modulation class + * \return the const pointer to the supported PHY entity + */ + const Ptr GetPhyEntity (WifiModulationClass modulation) const; + protected: // Inherited @@ -1915,6 +1945,29 @@ protected: */ virtual WifiSpectrumBand ConvertHeRuSubcarriers (uint16_t channelWidth, HeRu::SubcarrierRange range) const; + /** + * Add the PHY entity to the map of supported PHY entities for the + * given modulation class for the WifiPhy instance. + * This is a wrapper method used to check that the PHY entity is + * in the static map of implemented PHY entities (\see m_staticPhyEntities). + * In addition, child classes can add their own PHY entities. + * + * \param modulation the modulation class + * \param phyEntity the PHY entity + */ + void AddPhyEntity (WifiModulationClass modulation, Ptr phyEntity); + /** + * Get the supported PHY entity corresponding to the modulation class, for + * the WifiPhy instance. + * + * This method enables child classes to retrieve the non-const pointer to + * the supported PHY entity. + * + * \param modulation the modulation class + * \return the non-const pointer to the supported PHY entity + */ + Ptr GetPhyEntity (WifiModulationClass modulation); + InterferenceHelper m_interference; //!< Pointer to InterferenceHelper Ptr m_random; //!< Provides uniform random variables. Ptr m_state; //!< Pointer to WifiPhyStateHelper @@ -1940,6 +1993,14 @@ protected: static uint64_t m_globalPpduUid; //!< Global counter of the PPDU UID + /** + * This map holds the supported PHY entities. + * + * The set of parameters (e.g. mode) that this WifiPhy(-derived class) can + * support can be obtained through it. + */ + std::map > m_phyEntities; + private: /** @@ -2225,6 +2286,13 @@ private: */ TracedCallback m_phyEndOfHeSigATrace; + /** + * Map of __implemented__ PHY entities. This is used to compute the different + * amendment-specific parameters in a static manner. + * For PHY entities supported by a given WifiPhy instance, + * \see m_phyEntities. + */ + static std::map > m_staticPhyEntities; /** * This vector holds the set of transmission modes that this * WifiPhy(-derived class) can support. In conversation we call this diff --git a/src/wifi/model/wifi-tx-vector.cc b/src/wifi/model/wifi-tx-vector.cc index 9899887a1..a0a4360af 100644 --- a/src/wifi/model/wifi-tx-vector.cc +++ b/src/wifi/model/wifi-tx-vector.cc @@ -128,10 +128,7 @@ WifiTxVector::GetModulationClass (void) const { NS_ABORT_MSG_IF (!m_modeInitialized, "WifiTxVector mode must be set before using"); - // TODO Replace the following with IsMu when available - if (m_preamble == WIFI_PREAMBLE_VHT_MU - || m_preamble == WIFI_PREAMBLE_HE_MU - || m_preamble == WIFI_PREAMBLE_HE_TB) + if (IsMu ()) { NS_ASSERT (!m_muUserInfos.empty ()); // all the modes belong to the same modulation class