diff --git a/src/wifi/helper/wifi-helper.cc b/src/wifi/helper/wifi-helper.cc index 453145bdc..49b54bfbd 100644 --- a/src/wifi/helper/wifi-helper.cc +++ b/src/wifi/helper/wifi-helper.cc @@ -941,11 +941,15 @@ WifiHelper::EnableLogComponents (void) LogComponentEnable ("ConstantRateWifiManager", LOG_LEVEL_ALL); LogComponentEnable ("ChannelAccessManager", LOG_LEVEL_ALL); LogComponentEnable ("DsssErrorRateModel", LOG_LEVEL_ALL); + LogComponentEnable ("DsssPhy", LOG_LEVEL_ALL); + LogComponentEnable ("ErpOfdmPhy", LOG_LEVEL_ALL); LogComponentEnable ("FrameExchangeManager", LOG_LEVEL_ALL); LogComponentEnable ("HeConfiguration", LOG_LEVEL_ALL); LogComponentEnable ("HeFrameExchangeManager", LOG_LEVEL_ALL); + LogComponentEnable ("HePhy", LOG_LEVEL_ALL); LogComponentEnable ("HtConfiguration", LOG_LEVEL_ALL); LogComponentEnable ("HtFrameExchangeManager", LOG_LEVEL_ALL); + LogComponentEnable ("HtPhy", LOG_LEVEL_ALL); LogComponentEnable ("IdealWifiManager", LOG_LEVEL_ALL); LogComponentEnable ("InfrastructureWifiMac", LOG_LEVEL_ALL); LogComponentEnable ("InterferenceHelper", LOG_LEVEL_ALL); @@ -957,9 +961,11 @@ WifiHelper::EnableLogComponents (void) LogComponentEnable ("MsduAggregator", LOG_LEVEL_ALL); LogComponentEnable ("NistErrorRateModel", LOG_LEVEL_ALL); LogComponentEnable ("ObssPdAlgorithm", LOG_LEVEL_ALL); + LogComponentEnable ("OfdmPhy", LOG_LEVEL_ALL); LogComponentEnable ("OnoeWifiManager", LOG_LEVEL_ALL); LogComponentEnable ("OriginatorBlockAckAgreement", LOG_LEVEL_ALL); LogComponentEnable ("ParfWifiManager", LOG_LEVEL_ALL); + LogComponentEnable ("PhyEntity", LOG_LEVEL_ALL); LogComponentEnable ("QosFrameExchangeManager", LOG_LEVEL_ALL); LogComponentEnable ("QosTxop", LOG_LEVEL_ALL); LogComponentEnable ("RegularWifiMac", LOG_LEVEL_ALL); @@ -974,6 +980,7 @@ WifiHelper::EnableLogComponents (void) LogComponentEnable ("Txop", LOG_LEVEL_ALL); LogComponentEnable ("VhtConfiguration", LOG_LEVEL_ALL); LogComponentEnable ("VhtFrameExchangeManager", LOG_LEVEL_ALL); + LogComponentEnable ("VhtPhy", LOG_LEVEL_ALL); LogComponentEnable ("WifiAckManager", LOG_LEVEL_ALL); LogComponentEnable ("WifiDefaultAckManager", LOG_LEVEL_ALL); LogComponentEnable ("WifiDefaultProtectionManager", LOG_LEVEL_ALL); diff --git a/src/wifi/model/dsss-phy.cc b/src/wifi/model/dsss-phy.cc new file mode 100644 index 000000000..9bcc6a145 --- /dev/null +++ b/src/wifi/model/dsss-phy.cc @@ -0,0 +1,187 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2020 Orange Labs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Rediet + * Sébastien Deronne (for logic ported from wifi-phy) + * Mathieu Lacage (for logic ported from wifi-phy) + */ + +#include "dsss-phy.h" +#include "ns3/log.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("DsssPhy"); + +/******************************************************* + * HR/DSSS PHY (IEEE 802.11-2016, clause 16) + *******************************************************/ + +/* *NS_CHECK_STYLE_OFF* */ +const PhyEntity::PpduFormats DsssPhy::m_dsssPpduFormats { + { WIFI_PREAMBLE_LONG, { WIFI_PPDU_FIELD_PREAMBLE, //PHY preamble + WIFI_PPDU_FIELD_NON_HT_HEADER, //PHY header + WIFI_PPDU_FIELD_DATA } }, + { WIFI_PREAMBLE_SHORT, { WIFI_PPDU_FIELD_PREAMBLE, //Short PHY preamble + WIFI_PPDU_FIELD_NON_HT_HEADER, //Short PHY header + WIFI_PPDU_FIELD_DATA } } +}; +/* *NS_CHECK_STYLE_ON* */ + +DsssPhy::DsssPhy () +{ + NS_LOG_FUNCTION (this); + for (const auto & rate : GetDsssRatesBpsList ()) + { + WifiMode mode = GetDsssRate (rate); + NS_LOG_LOGIC ("Add " << mode << " to list"); + m_modeList.emplace_back (mode); + } +} + +DsssPhy::~DsssPhy () +{ + NS_LOG_FUNCTION (this); +} + +WifiMode +DsssPhy::GetSigMode (WifiPpduField field, WifiTxVector txVector) const +{ + switch (field) + { + case WIFI_PPDU_FIELD_NON_HT_HEADER: + return GetHeaderMode (txVector); + default: + return PhyEntity::GetSigMode (field, txVector); + } +} + +WifiMode +DsssPhy::GetHeaderMode (WifiTxVector txVector) const +{ + if (txVector.GetPreambleType () == WIFI_PREAMBLE_LONG + || txVector.GetMode () == GetDsssRate1Mbps ()) + { + //Section 16.2.3 "PPDU field definitions" and Section 16.2.2.2 "Long PPDU format"; IEEE Std 802.11-2016 + return GetDsssRate1Mbps (); + } + else + { + //Section 16.2.2.3 "Short PPDU format"; IEEE Std 802.11-2016 + return GetDsssRate2Mbps (); + } +} + +const PhyEntity::PpduFormats & +DsssPhy::GetPpduFormats (void) const +{ + return m_dsssPpduFormats; +} + +void +DsssPhy::InitializeModes (void) +{ + for (const auto & rate : GetDsssRatesBpsList ()) + { + GetDsssRate (rate); + } +} + +WifiMode +DsssPhy::GetDsssRate (uint64_t rate) +{ + switch (rate) + { + case 1000000: + return GetDsssRate1Mbps (); + case 2000000: + return GetDsssRate2Mbps (); + case 5500000: + return GetDsssRate5_5Mbps (); + case 11000000: + return GetDsssRate11Mbps (); + default: + NS_ABORT_MSG ("Inexistent rate (" << rate << " bps) requested for HR/DSSS"); + return WifiMode (); + } +} + +std::vector +DsssPhy::GetDsssRatesBpsList (void) +{ + /* *NS_CHECK_STYLE_OFF* */ + return { + 1000000, 2000000, + 5500000, 11000000 + }; + /* *NS_CHECK_STYLE_ON* */ +} + +// Clause 15 rates (DSSS) + +WifiMode +DsssPhy::GetDsssRate1Mbps (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("DsssRate1Mbps", + WIFI_MOD_CLASS_DSSS, + true, + WIFI_CODE_RATE_UNDEFINED, + 2); + return mode; +} + +WifiMode +DsssPhy::GetDsssRate2Mbps (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("DsssRate2Mbps", + WIFI_MOD_CLASS_DSSS, + true, + WIFI_CODE_RATE_UNDEFINED, + 4); + return mode; +} + + +// Clause 16 rates (HR/DSSS) + +WifiMode +DsssPhy::GetDsssRate5_5Mbps (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("DsssRate5_5Mbps", + WIFI_MOD_CLASS_HR_DSSS, + true, + WIFI_CODE_RATE_UNDEFINED, + 16); + return mode; +} + +WifiMode +DsssPhy::GetDsssRate11Mbps (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("DsssRate11Mbps", + WIFI_MOD_CLASS_HR_DSSS, + true, + WIFI_CODE_RATE_UNDEFINED, + 256); + return mode; +} + +} //namespace ns3 diff --git a/src/wifi/model/dsss-phy.h b/src/wifi/model/dsss-phy.h new file mode 100644 index 000000000..70a6ec20c --- /dev/null +++ b/src/wifi/model/dsss-phy.h @@ -0,0 +1,118 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2020 Orange Labs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Rediet + * Sébastien Deronne (for logic ported from wifi-phy) + * Mathieu Lacage (for logic ported from wifi-phy) + */ + +#ifndef DSSS_PHY_H +#define DSSS_PHY_H + +#include "phy-entity.h" +#include + +/** + * \file + * \ingroup wifi + * Declaration of ns3::DsssPhy class. + */ + +namespace ns3 { + +/** + * \brief PHY entity for HR/DSSS (11b) + * \ingroup wifi + * + * Refer to IEEE 802.11-2016, clause 16 (HR/DSSS). + * Note that DSSS rates (clause 15) are a subset + * of HR/DSSS rates. + */ +class DsssPhy : public PhyEntity +{ +public: + /** + * Constructor for HR/DSSS PHY + */ + DsssPhy (); + /** + * Destructor for HR/DSSS PHY + */ + virtual ~DsssPhy (); + + // Inherited + WifiMode GetSigMode (WifiPpduField field, WifiTxVector txVector) const override; + const PpduFormats & GetPpduFormats (void) const override; + + /** + * Initialize all HR/DSSS modes. + */ + static void InitializeModes (void); + /** + * Return a WifiMode for HR/DSSS + * corresponding to the provided rate. + * + * \param rate the rate in bps + * \return a WifiMode for HR/DSSS + */ + static WifiMode GetDsssRate (uint64_t rate); + /** + * Return the list of rates (in bps) achievable with + * HR/DSSS. + * + * \return a vector containing the achievable rates in bps + */ + static std::vector GetDsssRatesBpsList (void); + + /** + * Return a WifiMode for DSSS at 1 Mbps. + * + * \return a WifiMode for DSSS at 1 Mbps + */ + static WifiMode GetDsssRate1Mbps (void); + /** + * Return a WifiMode for DSSS at 2 Mbps. + * + * \return a WifiMode for DSSS at 2 Mbps + */ + static WifiMode GetDsssRate2Mbps (void); + /** + * Return a WifiMode for HR/DSSS at 5.5 Mbps. + * + * \return a WifiMode for HR/DSSS at 5.5 Mbps + */ + static WifiMode GetDsssRate5_5Mbps (void); + /** + * Return a WifiMode for HR/DSSS at 11 Mbps. + * + * \return a WifiMode for HR/DSSS at 11 Mbps + */ + static WifiMode GetDsssRate11Mbps (void); + +private: + /** + * \param txVector the transmission parameters + * \return the WifiMode used for the PHY header field + */ + WifiMode GetHeaderMode (WifiTxVector txVector) const; + + static const PpduFormats m_dsssPpduFormats; //!< DSSS and HR/DSSS PPDU formats +}; //class DsssPhy + +} //namespace ns3 + +#endif /* DSSS_PHY_H */ diff --git a/src/wifi/model/erp-ofdm-phy.cc b/src/wifi/model/erp-ofdm-phy.cc new file mode 100644 index 000000000..aa73666c1 --- /dev/null +++ b/src/wifi/model/erp-ofdm-phy.cc @@ -0,0 +1,197 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2020 Orange Labs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Rediet + * Sébastien Deronne (for logic ported from wifi-phy) + * Mathieu Lacage (for logic ported from wifi-phy) + */ + +#include "erp-ofdm-phy.h" +#include "ns3/log.h" +#include "ns3/assert.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("ErpOfdmPhy"); + +/******************************************************* + * ERP-OFDM PHY (IEEE 802.11-2016, clause 18) + *******************************************************/ + +ErpOfdmPhy::ErpOfdmPhy () + : OfdmPhy (OFDM_PHY_DEFAULT, false) //don't add OFDM modes to list +{ + NS_LOG_FUNCTION (this); + for (const auto & rate : GetErpOfdmRatesBpsList ()) + { + WifiMode mode = GetErpOfdmRate (rate); + NS_LOG_LOGIC ("Add " << mode << " to list"); + m_modeList.emplace_back (mode); + } +} + +ErpOfdmPhy::~ErpOfdmPhy () +{ + NS_LOG_FUNCTION (this); +} + +WifiMode +ErpOfdmPhy::GetHeaderMode (WifiTxVector txVector) const +{ + NS_ASSERT (txVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM); + return GetErpOfdmRate6Mbps (); +} + +void +ErpOfdmPhy::InitializeModes (void) +{ + for (const auto & rate : GetErpOfdmRatesBpsList ()) + { + GetErpOfdmRate (rate); + } +} + +WifiMode +ErpOfdmPhy::GetErpOfdmRate (uint64_t rate) +{ + switch (rate) + { + case 6000000: + return GetErpOfdmRate6Mbps (); + case 9000000: + return GetErpOfdmRate9Mbps (); + case 12000000: + return GetErpOfdmRate12Mbps (); + case 18000000: + return GetErpOfdmRate18Mbps (); + case 24000000: + return GetErpOfdmRate24Mbps (); + case 36000000: + return GetErpOfdmRate36Mbps (); + case 48000000: + return GetErpOfdmRate48Mbps (); + case 54000000: + return GetErpOfdmRate54Mbps (); + default: + NS_ABORT_MSG ("Inexistent rate (" << rate << " bps) requested for ERP-OFDM"); + return WifiMode (); + } +} + +std::vector +ErpOfdmPhy::GetErpOfdmRatesBpsList (void) +{ + return OfdmPhy::GetOfdmRatesBpsList ().at (20); +} + +WifiMode +ErpOfdmPhy::GetErpOfdmRate6Mbps (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("ErpOfdmRate6Mbps", + WIFI_MOD_CLASS_ERP_OFDM, + true, + WIFI_CODE_RATE_1_2, + 2); + return mode; +} + +WifiMode +ErpOfdmPhy::GetErpOfdmRate9Mbps (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("ErpOfdmRate9Mbps", + WIFI_MOD_CLASS_ERP_OFDM, + false, + WIFI_CODE_RATE_3_4, + 2); + return mode; +} + +WifiMode +ErpOfdmPhy::GetErpOfdmRate12Mbps (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("ErpOfdmRate12Mbps", + WIFI_MOD_CLASS_ERP_OFDM, + true, + WIFI_CODE_RATE_1_2, + 4); + return mode; +} + +WifiMode +ErpOfdmPhy::GetErpOfdmRate18Mbps (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("ErpOfdmRate18Mbps", + WIFI_MOD_CLASS_ERP_OFDM, + false, + WIFI_CODE_RATE_3_4, + 4); + return mode; +} + +WifiMode +ErpOfdmPhy::GetErpOfdmRate24Mbps (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("ErpOfdmRate24Mbps", + WIFI_MOD_CLASS_ERP_OFDM, + true, + WIFI_CODE_RATE_1_2, + 16); + return mode; +} + +WifiMode +ErpOfdmPhy::GetErpOfdmRate36Mbps (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("ErpOfdmRate36Mbps", + WIFI_MOD_CLASS_ERP_OFDM, + false, + WIFI_CODE_RATE_3_4, + 16); + return mode; +} + +WifiMode +ErpOfdmPhy::GetErpOfdmRate48Mbps (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("ErpOfdmRate48Mbps", + WIFI_MOD_CLASS_ERP_OFDM, + false, + WIFI_CODE_RATE_2_3, + 64); + return mode; +} + +WifiMode +ErpOfdmPhy::GetErpOfdmRate54Mbps (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("ErpOfdmRate54Mbps", + WIFI_MOD_CLASS_ERP_OFDM, + false, + WIFI_CODE_RATE_3_4, + 64); + return mode; +} + +} //namespace ns3 diff --git a/src/wifi/model/erp-ofdm-phy.h b/src/wifi/model/erp-ofdm-phy.h new file mode 100644 index 000000000..d4b66563a --- /dev/null +++ b/src/wifi/model/erp-ofdm-phy.h @@ -0,0 +1,133 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2020 Orange Labs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Rediet + * Sébastien Deronne (for logic ported from wifi-phy) + * Mathieu Lacage (for logic ported from wifi-phy) + */ + +#ifndef ERP_OFDM_PHY_H +#define ERP_OFDM_PHY_H + +#include "ofdm-phy.h" + +/** + * \file + * \ingroup wifi + * Declaration of ns3::ErpOfdmPhy class. + */ + +namespace ns3 { + +/** + * \brief PHY entity for ERP-OFDM (11g) + * \ingroup wifi + * + * ERP-OFDM PHY is based on OFDM PHY. + * ERP-DSSS/CCK mode is not supported. + * + * Refer to IEEE 802.11-2016, clause 18. + */ +class ErpOfdmPhy : public OfdmPhy +{ +public: + /** + * Constructor for ERP-OFDM PHY + */ + ErpOfdmPhy (); + /** + * Destructor for ERP-OFDM PHY + */ + virtual ~ErpOfdmPhy (); + + /** + * Initialize all ERP-OFDM modes. + */ + static void InitializeModes (void); + /** + * Return a WifiMode for ERP-OFDM + * corresponding to the provided rate. + * + * \param rate the rate in bps + * \return a WifiMode for ERP-OFDM + */ + static WifiMode GetErpOfdmRate (uint64_t rate); + /** + * Return the list of rates (in bps) achievable with + * ERP-OFDM. + * + * \return a vector containing the achievable rates in bps + */ + static std::vector GetErpOfdmRatesBpsList (void); + + /** + * Return a WifiMode for ERP-OFDM at 6 Mbps. + * + * \return a WifiMode for ERP-OFDM at 6 Mbps + */ + static WifiMode GetErpOfdmRate6Mbps (void); + /** + * Return a WifiMode for ERP-OFDM at 9 Mbps. + * + * \return a WifiMode for ERP-OFDM at 9 Mbps + */ + static WifiMode GetErpOfdmRate9Mbps (void); + /** + * Return a WifiMode for ERP-OFDM at 12 Mbps. + * + * \return a WifiMode for ERP-OFDM at 12 Mbps + */ + static WifiMode GetErpOfdmRate12Mbps (void); + /** + * Return a WifiMode for ERP-OFDM at 18 Mbps. + * + * \return a WifiMode for ERP-OFDM at 18 Mbps + */ + static WifiMode GetErpOfdmRate18Mbps (void); + /** + * Return a WifiMode for ERP-OFDM at 24 Mbps. + * + * \return a WifiMode for ERP-OFDM at 24 Mbps + */ + static WifiMode GetErpOfdmRate24Mbps (void); + /** + * Return a WifiMode for ERP-OFDM at 36 Mbps. + * + * \return a WifiMode for ERP-OFDM at 36 Mbps + */ + static WifiMode GetErpOfdmRate36Mbps (void); + /** + * Return a WifiMode for ERP-OFDM at 48 Mbps. + * + * \return a WifiMode for ERP-OFDM at 48 Mbps + */ + static WifiMode GetErpOfdmRate48Mbps (void); + /** + * Return a WifiMode for ERP-OFDM at 54 Mbps. + * + * \return a WifiMode for ERP-OFDM at 54 Mbps + */ + static WifiMode GetErpOfdmRate54Mbps (void); + +private: + // Inherited + WifiMode GetHeaderMode (WifiTxVector txVector) const override; +}; //class ErpOfdmPhy + +} //namespace ns3 + +#endif /* ERP_OFDM_PHY_H */ diff --git a/src/wifi/model/he-phy.cc b/src/wifi/model/he-phy.cc new file mode 100644 index 000000000..bc8f64c66 --- /dev/null +++ b/src/wifi/model/he-phy.cc @@ -0,0 +1,276 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2020 Orange Labs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Rediet + * Sébastien Deronne (for logic ported from wifi-phy) + */ + +#include "he-phy.h" +#include "ns3/log.h" +#include "ns3/assert.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("HePhy"); + +/******************************************************* + * HE PHY (P802.11ax/D4.0, clause 27) + *******************************************************/ + +/* *NS_CHECK_STYLE_OFF* */ +const PhyEntity::PpduFormats HePhy::m_hePpduFormats { //Ignoring PE (Packet Extension) + { WIFI_PREAMBLE_HE_SU, { WIFI_PPDU_FIELD_PREAMBLE, //L-STF + L-LTF + WIFI_PPDU_FIELD_NON_HT_HEADER, //L-SIG + RL-SIG + WIFI_PPDU_FIELD_SIG_A, //HE-SIG-A + WIFI_PPDU_FIELD_TRAINING, //HE-STF + HE-LTFs + WIFI_PPDU_FIELD_DATA } }, + { WIFI_PREAMBLE_HE_MU, { WIFI_PPDU_FIELD_PREAMBLE, //L-STF + L-LTF + WIFI_PPDU_FIELD_NON_HT_HEADER, //L-SIG + RL-SIG + WIFI_PPDU_FIELD_SIG_A, //HE-SIG-A + WIFI_PPDU_FIELD_SIG_B, //HE-SIG-B + WIFI_PPDU_FIELD_TRAINING, //HE-STF + HE-LTFs + WIFI_PPDU_FIELD_DATA } }, + { WIFI_PREAMBLE_HE_TB, { WIFI_PPDU_FIELD_PREAMBLE, //L-STF + L-LTF + WIFI_PPDU_FIELD_NON_HT_HEADER, //L-SIG + RL-SIG + WIFI_PPDU_FIELD_SIG_A, //HE-SIG-A + WIFI_PPDU_FIELD_TRAINING, //HE-STF + HE-LTFs + WIFI_PPDU_FIELD_DATA } }, + { WIFI_PREAMBLE_HE_ER_SU, { WIFI_PPDU_FIELD_PREAMBLE, //L-STF + L-LTF + WIFI_PPDU_FIELD_NON_HT_HEADER, //L-SIG + RL-SIG + WIFI_PPDU_FIELD_SIG_A, //HE-SIG-A + WIFI_PPDU_FIELD_TRAINING, //HE-STF + HE-LTFs + WIFI_PPDU_FIELD_DATA } } +}; +/* *NS_CHECK_STYLE_ON* */ + +HePhy::HePhy (bool buildModeList /* = true */) + : VhtPhy (false) //don't add VHT modes to list +{ + NS_LOG_FUNCTION (this << buildModeList); + m_bssMembershipSelector = HE_PHY; + m_maxMcsIndexPerSs = 11; + m_maxSupportedMcsIndexPerSs = m_maxMcsIndexPerSs; + if (buildModeList) + { + BuildModeList (); + } +} + +HePhy::~HePhy () +{ + NS_LOG_FUNCTION (this); +} + +void +HePhy::BuildModeList (void) +{ + NS_LOG_FUNCTION (this); + NS_ASSERT (m_modeList.empty ()); + NS_ASSERT (m_bssMembershipSelector == HE_PHY); + for (uint8_t index = 0; index <= m_maxSupportedMcsIndexPerSs; ++index) + { + NS_LOG_LOGIC ("Add HeMcs" << +index << " to list"); + m_modeList.emplace_back (GetHeMcs (index)); + } +} + +WifiMode +HePhy::GetSigAMode (void) const +{ + return GetVhtMcs0 (); //same number of data tones as VHT for 20 MHz (i.e. 52) +} + +WifiMode +HePhy::GetSigBMode (WifiTxVector txVector) const +{ + NS_ABORT_MSG_IF (txVector.GetPreambleType () != WIFI_PREAMBLE_HE_MU, "HE-SIG-B only available for HE MU"); + /** + * Get smallest HE MCS index among station's allocations and use the + * VHT version of the index. This enables to have 800 ns GI, 52 data + * tones, and 312.5 kHz spacing while ensuring that MCS will be decoded + * by all stations. + */ + uint8_t smallestMcs = 5; //maximum MCS for HE-SIG-B + for (auto & info : txVector.GetHeMuUserInfoMap ()) + { + smallestMcs = std::min (smallestMcs, info.second.mcs.GetMcsValue ()); + } + switch (smallestMcs) //GetVhtMcs (mcs) is not static + { + case 0: + return GetVhtMcs0 (); + case 1: + return GetVhtMcs1 (); + case 2: + return GetVhtMcs2 (); + case 3: + return GetVhtMcs3 (); + case 4: + return GetVhtMcs4 (); + case 5: + default: + return GetVhtMcs5 (); + } +} + +const PhyEntity::PpduFormats & +HePhy::GetPpduFormats (void) const +{ + return m_hePpduFormats; +} + +void +HePhy::InitializeModes (void) +{ + for (uint8_t i = 0; i < 12; ++i) + { + GetHeMcs (i); + } +} + +WifiMode +HePhy::GetHeMcs (uint8_t index) +{ + switch (index) + { + case 0: + return GetHeMcs0 (); + case 1: + return GetHeMcs1 (); + case 2: + return GetHeMcs2 (); + case 3: + return GetHeMcs3 (); + case 4: + return GetHeMcs4 (); + case 5: + return GetHeMcs5 (); + case 6: + return GetHeMcs6 (); + case 7: + return GetHeMcs7 (); + case 8: + return GetHeMcs8 (); + case 9: + return GetHeMcs9 (); + case 10: + return GetHeMcs10 (); + case 11: + return GetHeMcs11 (); + default: + NS_ABORT_MSG ("Inexistent index (" << +index << ") requested for HE"); + return WifiMode (); + } +} + +WifiMode +HePhy::GetHeMcs0 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HeMcs0", 0, WIFI_MOD_CLASS_HE); + return mcs; +} + +WifiMode +HePhy::GetHeMcs1 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HeMcs1", 1, WIFI_MOD_CLASS_HE); + return mcs; +} + +WifiMode +HePhy::GetHeMcs2 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HeMcs2", 2, WIFI_MOD_CLASS_HE); + return mcs; +} + +WifiMode +HePhy::GetHeMcs3 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HeMcs3", 3, WIFI_MOD_CLASS_HE); + return mcs; +} + +WifiMode +HePhy::GetHeMcs4 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HeMcs4", 4, WIFI_MOD_CLASS_HE); + return mcs; +} + +WifiMode +HePhy::GetHeMcs5 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HeMcs5", 5, WIFI_MOD_CLASS_HE); + return mcs; +} + +WifiMode +HePhy::GetHeMcs6 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HeMcs6", 6, WIFI_MOD_CLASS_HE); + return mcs; +} + +WifiMode +HePhy::GetHeMcs7 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HeMcs7", 7, WIFI_MOD_CLASS_HE); + return mcs; +} + +WifiMode +HePhy::GetHeMcs8 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HeMcs8", 8, WIFI_MOD_CLASS_HE); + return mcs; +} + +WifiMode +HePhy::GetHeMcs9 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HeMcs9", 9, WIFI_MOD_CLASS_HE); + return mcs; +} + +WifiMode +HePhy::GetHeMcs10 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HeMcs10", 10, WIFI_MOD_CLASS_HE); + return mcs; +} + +WifiMode +HePhy::GetHeMcs11 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HeMcs11", 11, WIFI_MOD_CLASS_HE); + return mcs; +} + +} //namespace ns3 diff --git a/src/wifi/model/he-phy.h b/src/wifi/model/he-phy.h new file mode 100644 index 000000000..addfab986 --- /dev/null +++ b/src/wifi/model/he-phy.h @@ -0,0 +1,163 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2020 Orange Labs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Rediet + * Sébastien Deronne (for logic ported from wifi-phy) + */ + +#ifndef HE_PHY_H +#define HE_PHY_H + +#include "vht-phy.h" + +/** + * \file + * \ingroup wifi + * Declaration of ns3::HePhy class. + */ + +namespace ns3 { + +/** + * This defines the BSS membership value for HE PHY. + */ +#define HE_PHY 125 + +/** + * \brief PHY entity for HE (11ax) + * \ingroup wifi + * + * HE PHY is based on VHT PHY. + * + * Refer to P802.11ax/D4.0, clause 27. + */ +class HePhy : public VhtPhy +{ +public: + /** + * Constructor for HE PHY + * + * \param buildModeList flag used to add HE modes to list (disabled + * by child classes to only add child classes' modes) + */ + HePhy (bool buildModeList = true); + /** + * Destructor for HE PHY + */ + virtual ~HePhy (); + + // Inherited + WifiMode GetSigAMode (void) const override; + WifiMode GetSigBMode (WifiTxVector txVector) const override; + virtual const PpduFormats & GetPpduFormats (void) const override; + + /** + * Initialize all HE modes. + */ + static void InitializeModes (void); + /** + * Return the HE MCS corresponding to + * the provided index. + * + * \param index the index of the MCS + * \return an HE MCS + */ + static WifiMode GetHeMcs (uint8_t index); + + /** + * Return MCS 0 from HE MCS values. + * + * \return MCS 0 from HE MCS values + */ + static WifiMode GetHeMcs0 (void); + /** + * Return MCS 1 from HE MCS values. + * + * \return MCS 1 from HE MCS values + */ + static WifiMode GetHeMcs1 (void); + /** + * Return MCS 2 from HE MCS values. + * + * \return MCS 2 from HE MCS values + */ + static WifiMode GetHeMcs2 (void); + /** + * Return MCS 3 from HE MCS values. + * + * \return MCS 3 from HE MCS values + */ + static WifiMode GetHeMcs3 (void); + /** + * Return MCS 4 from HE MCS values. + * + * \return MCS 4 from HE MCS values + */ + static WifiMode GetHeMcs4 (void); + /** + * Return MCS 5 from HE MCS values. + * + * \return MCS 5 from HE MCS values + */ + static WifiMode GetHeMcs5 (void); + /** + * Return MCS 6 from HE MCS values. + * + * \return MCS 6 from HE MCS values + */ + static WifiMode GetHeMcs6 (void); + /** + * Return MCS 7 from HE MCS values. + * + * \return MCS 7 from HE MCS values + */ + static WifiMode GetHeMcs7 (void); + /** + * Return MCS 8 from HE MCS values. + * + * \return MCS 8 from HE MCS values + */ + static WifiMode GetHeMcs8 (void); + /** + * Return MCS 9 from HE MCS values. + * + * \return MCS 9 from HE MCS values + */ + static WifiMode GetHeMcs9 (void); + /** + * Return MCS 10 from HE MCS values. + * + * \return MCS 10 from HE MCS values + */ + static WifiMode GetHeMcs10 (void); + /** + * Return MCS 11 from HE MCS values. + * + * \return MCS 11 from HE MCS values + */ + static WifiMode GetHeMcs11 (void); + +private: + // Inherited + virtual void BuildModeList (void) override; + + static const PpduFormats m_hePpduFormats; //!< HE PPDU formats +}; //class HePhy + +} //namespace ns3 + +#endif /* HE_PHY_H */ diff --git a/src/wifi/model/ht-phy.cc b/src/wifi/model/ht-phy.cc new file mode 100644 index 000000000..336f1497c --- /dev/null +++ b/src/wifi/model/ht-phy.cc @@ -0,0 +1,536 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2020 Orange Labs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Rediet + * Sébastien Deronne (for logic ported from wifi-phy) + */ + +#include "ht-phy.h" +#include "ns3/log.h" +#include "ns3/assert.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("HtPhy"); + +/******************************************************* + * HT PHY (IEEE 802.11-2016, clause 19) + *******************************************************/ + +/* *NS_CHECK_STYLE_OFF* */ +const PhyEntity::PpduFormats HtPhy::m_htPpduFormats { + { WIFI_PREAMBLE_HT_MF, { WIFI_PPDU_FIELD_PREAMBLE, //L-STF + L-LTF + WIFI_PPDU_FIELD_NON_HT_HEADER, //L-SIG + WIFI_PPDU_FIELD_HT_SIG, //HT-SIG + WIFI_PPDU_FIELD_TRAINING, //HT-STF + HT-LTFs + WIFI_PPDU_FIELD_DATA } }, + { WIFI_PREAMBLE_HT_GF, { WIFI_PPDU_FIELD_PREAMBLE, //HT-GF-STF + HT-LTF1 + WIFI_PPDU_FIELD_HT_SIG, //HT-SIG + WIFI_PPDU_FIELD_TRAINING, //Additional HT-LTFs + WIFI_PPDU_FIELD_DATA } } +}; +/* *NS_CHECK_STYLE_ON* */ + +HtPhy::HtPhy (uint8_t maxNss /* = 1 */, bool buildModeList /* = true */) + : OfdmPhy (OFDM_PHY_DEFAULT, false) //don't add OFDM modes to list +{ + NS_LOG_FUNCTION (this << +maxNss << buildModeList); + m_maxSupportedNss = maxNss; + m_bssMembershipSelector = HT_PHY; + m_maxMcsIndexPerSs = 7; + m_maxSupportedMcsIndexPerSs = m_maxMcsIndexPerSs; + if (buildModeList) + { + NS_ABORT_MSG_IF (maxNss == 0 || maxNss > 4, "Unsupported max Nss " << +maxNss << " for HT PHY"); + BuildModeList (); + } +} + +HtPhy::~HtPhy () +{ + NS_LOG_FUNCTION (this); +} + +void +HtPhy::BuildModeList (void) +{ + NS_LOG_FUNCTION (this); + NS_ASSERT (m_modeList.empty ()); + NS_ASSERT (m_bssMembershipSelector == HT_PHY); + + uint8_t index = 0; + for (uint8_t nss = 1; nss <= m_maxSupportedNss; ++nss) + { + for (uint8_t i = 0; i <= m_maxSupportedMcsIndexPerSs; ++i) + { + NS_LOG_LOGIC ("Add HtMcs" << +index << " to list"); + m_modeList.emplace_back (GetHtMcs (index)); + ++index; + } + index = 8 * nss; + } +} + +WifiMode +HtPhy::GetMcs (uint8_t index) const +{ + for (const auto & mcs : m_modeList) + { + if (mcs.GetMcsValue () == index) + { + return mcs; + } + } + + // Should have returned if MCS found + NS_ABORT_MSG ("Unsupported MCS index " << +index << " for this PHY entity"); + return WifiMode (); +} + +bool +HtPhy::IsMcsSupported (uint8_t index) const +{ + for (const auto & mcs : m_modeList) + { + if (mcs.GetMcsValue () == index) + { + return true; + } + } + return false; +} + +bool +HtPhy::HandlesMcsModes (void) const +{ + return true; +} + +const PhyEntity::PpduFormats & +HtPhy::GetPpduFormats (void) const +{ + return m_htPpduFormats; +} + +WifiMode +HtPhy::GetSigMode (WifiPpduField field, WifiTxVector txVector) const +{ + switch (field) + { + case WIFI_PPDU_FIELD_NON_HT_HEADER: + return GetLSigMode (); + case WIFI_PPDU_FIELD_HT_SIG: + return GetHtSigMode (); + default: + return PhyEntity::GetSigMode (field, txVector); + } +} + +WifiMode +HtPhy::GetLSigMode (void) +{ + return GetOfdmRate6Mbps (); +} + +WifiMode +HtPhy::GetHtSigMode (void) const +{ + return GetLSigMode (); //same number of data tones as OFDM (i.e. 48) +} + +uint8_t +HtPhy::GetBssMembershipSelector (void) const +{ + return m_bssMembershipSelector; +} + +void +HtPhy::SetMaxSupportedMcsIndexPerSs (uint8_t maxIndex) +{ + NS_LOG_FUNCTION (this << +maxIndex); + NS_ABORT_MSG_IF (maxIndex > m_maxMcsIndexPerSs, "Provided max MCS index " << +maxIndex << " per SS greater than max standard-defined value " << +m_maxMcsIndexPerSs); + if (maxIndex != m_maxSupportedMcsIndexPerSs) + { + NS_LOG_LOGIC ("Rebuild mode list since max MCS index per spatial stream has changed"); + m_maxSupportedMcsIndexPerSs = maxIndex; + m_modeList.clear (); + BuildModeList (); + } +} + +uint8_t +HtPhy::GetMaxSupportedMcsIndexPerSs (void) const +{ + return m_maxSupportedMcsIndexPerSs; +} + +void +HtPhy::SetMaxSupportedNss (uint8_t maxNss) +{ + NS_LOG_FUNCTION (this << +maxNss); + NS_ASSERT (m_bssMembershipSelector == HT_PHY); + NS_ABORT_MSG_IF (maxNss == 0 || maxNss > 4, "Unsupported max Nss " << +maxNss << " for HT PHY"); + if (maxNss != m_maxSupportedNss) + { + NS_LOG_LOGIC ("Rebuild mode list since max number of spatial streams has changed"); + m_maxSupportedNss = maxNss; + m_modeList.clear (); + BuildModeList (); + } +} + +void +HtPhy::InitializeModes (void) +{ + for (uint8_t i = 0; i < 32; ++i) + { + GetHtMcs (i); + } +} + +WifiMode +HtPhy::GetHtMcs (uint8_t index) +{ + switch (index) + { + case 0: + return GetHtMcs0 (); + case 1: + return GetHtMcs1 (); + case 2: + return GetHtMcs2 (); + case 3: + return GetHtMcs3 (); + case 4: + return GetHtMcs4 (); + case 5: + return GetHtMcs5 (); + case 6: + return GetHtMcs6 (); + case 7: + return GetHtMcs7 (); + case 8: + return GetHtMcs8 (); + case 9: + return GetHtMcs9 (); + case 10: + return GetHtMcs10 (); + case 11: + return GetHtMcs11 (); + case 12: + return GetHtMcs12 (); + case 13: + return GetHtMcs13 (); + case 14: + return GetHtMcs14 (); + case 15: + return GetHtMcs15 (); + case 16: + return GetHtMcs16 (); + case 17: + return GetHtMcs17 (); + case 18: + return GetHtMcs18 (); + case 19: + return GetHtMcs19 (); + case 20: + return GetHtMcs20 (); + case 21: + return GetHtMcs21 (); + case 22: + return GetHtMcs22 (); + case 23: + return GetHtMcs23 (); + case 24: + return GetHtMcs24 (); + case 25: + return GetHtMcs25 (); + case 26: + return GetHtMcs26 (); + case 27: + return GetHtMcs27 (); + case 28: + return GetHtMcs28 (); + case 29: + return GetHtMcs29 (); + case 30: + return GetHtMcs30 (); + case 31: + return GetHtMcs31 (); + default: + NS_ABORT_MSG ("Inexistent (or not supported) index (" << +index << ") requested for HT"); + return WifiMode (); + } +} + +WifiMode +HtPhy::GetHtMcs0 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs0", 0, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs1 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs1", 1, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs2 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs2", 2, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs3 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs3", 3, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs4 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs4", 4, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs5 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs5", 5, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs6 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs6", 6, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs7 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs7", 7, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs8 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs8", 8, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs9 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs9", 9, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs10 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs10", 10, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs11 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs11", 11, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs12 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs12", 12, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs13 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs13", 13, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs14 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs14", 14, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs15 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs15", 15, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs16 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs16", 16, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs17 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs17", 17, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs18 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs18", 18, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs19 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs19", 19, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs20 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs20", 20, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs21 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs21", 21, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs22 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs22", 22, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs23 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs23", 23, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs24 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs24", 24, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs25 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs25", 25, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs26 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs26", 26, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs27 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs27", 27, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs28 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs28", 28, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs29 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs29", 29, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs30 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs30", 30, WIFI_MOD_CLASS_HT); + return mcs; +} + +WifiMode +HtPhy::GetHtMcs31 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("HtMcs31", 31, WIFI_MOD_CLASS_HT); + return mcs; +} + +} //namespace ns3 diff --git a/src/wifi/model/ht-phy.h b/src/wifi/model/ht-phy.h new file mode 100644 index 000000000..cd9d96506 --- /dev/null +++ b/src/wifi/model/ht-phy.h @@ -0,0 +1,338 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2020 Orange Labs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Rediet + * Sébastien Deronne (for logic ported from wifi-phy) + */ + +#ifndef HT_PHY_H +#define HT_PHY_H + +#include "ofdm-phy.h" + +/** + * \file + * \ingroup wifi + * Declaration of ns3::HtPhy class. + */ + +namespace ns3 { + +/** + * This defines the BSS membership value for HT PHY. + */ +#define HT_PHY 127 + +/** + * \brief PHY entity for HT (11n) + * \ingroup wifi + * + * HT PHY is based on OFDM PHY. + * HT-Mixed and HT-Greenfield PPDU formats are + * supported. Only HT MCSs up to 31 are supported. + * + * Refer to IEEE 802.11-2016, clause 19. + */ +class HtPhy : public OfdmPhy +{ +public: + /** + * Constructor for HT PHY + * + * \param maxNss the maximum number of spatial streams + * \param buildModeList flag used to add HT modes to list (disabled + * by child classes to only add child classes' modes) + */ + HtPhy (uint8_t maxNss = 1, bool buildModeList = true); + /** + * Destructor for HT PHY + */ + virtual ~HtPhy (); + + // Inherited + WifiMode GetMcs (uint8_t index) const override; + bool IsMcsSupported (uint8_t index) const override; + bool HandlesMcsModes (void) const override; + virtual WifiMode GetSigMode (WifiPpduField field, WifiTxVector txVector) const override; + virtual const PpduFormats & GetPpduFormats (void) const override; + + /** + * \return the WifiMode used for the L-SIG (non-HT header) field + */ + static WifiMode GetLSigMode (void); + /** + * \return the WifiMode used for the HT-SIG field + */ + virtual WifiMode GetHtSigMode (void) const; + + /** + * \return the BSS membership selector for this PHY entity + */ + uint8_t GetBssMembershipSelector (void) const; + + /** + * Set the maximum supported MCS index __per spatial stream__. + * For HT, this results in non-continuous indices for supported MCSs. + * + * \return the maximum MCS index per spatial stream supported by this entity + */ + uint8_t GetMaxSupportedMcsIndexPerSs (void) const; + /** + * Set the maximum supported MCS index __per spatial stream__. + * For HT, this results in non-continuous indices for supported MCSs. + * + * \param maxIndex the maximum MCS index per spatial stream supported by this entity + * + * The provided value should not be greater than maximum standard-defined value. + */ + void SetMaxSupportedMcsIndexPerSs (uint8_t maxIndex); + /** + * Configure the maximum number of spatial streams supported + * by this HT PHY. + * + * \param maxNss the maximum number of spatial streams + */ + void SetMaxSupportedNss (uint8_t maxNss); + + /** + * Initialize all HT modes. + */ + static void InitializeModes (void); + /** + * Return the HT MCS corresponding to + * the provided index. + * + * \param index the index of the MCS + * \return an HT MCS + */ + static WifiMode GetHtMcs (uint8_t index); + + /** + * Return MCS 0 from HT MCS values. + * + * \return MCS 0 from HT MCS values + */ + static WifiMode GetHtMcs0 (void); + /** + * Return MCS 1 from HT MCS values. + * + * \return MCS 1 from HT MCS values + */ + static WifiMode GetHtMcs1 (void); + /** + * Return MCS 2 from HT MCS values. + * + * \return MCS 2 from HT MCS values + */ + static WifiMode GetHtMcs2 (void); + /** + * Return MCS 3 from HT MCS values. + * + * \return MCS 3 from HT MCS values + */ + static WifiMode GetHtMcs3 (void); + /** + * Return MCS 4 from HT MCS values. + * + * \return MCS 4 from HT MCS values + */ + static WifiMode GetHtMcs4 (void); + /** + * Return MCS 5 from HT MCS values. + * + * \return MCS 5 from HT MCS values + */ + static WifiMode GetHtMcs5 (void); + /** + * Return MCS 6 from HT MCS values. + * + * \return MCS 6 from HT MCS values + */ + static WifiMode GetHtMcs6 (void); + /** + * Return MCS 7 from HT MCS values. + * + * \return MCS 7 from HT MCS values + */ + static WifiMode GetHtMcs7 (void); + /** + * Return MCS 8 from HT MCS values. + * + * \return MCS 8 from HT MCS values + */ + static WifiMode GetHtMcs8 (void); + /** + * Return MCS 9 from HT MCS values. + * + * \return MCS 9 from HT MCS values + */ + static WifiMode GetHtMcs9 (void); + /** + * Return MCS 10 from HT MCS values. + * + * \return MCS 10 from HT MCS values + */ + static WifiMode GetHtMcs10 (void); + /** + * Return MCS 11 from HT MCS values. + * + * \return MCS 11 from HT MCS values + */ + static WifiMode GetHtMcs11 (void); + /** + * Return MCS 12 from HT MCS values. + * + * \return MCS 12 from HT MCS values + */ + static WifiMode GetHtMcs12 (void); + /** + * Return MCS 13 from HT MCS values. + * + * \return MCS 13 from HT MCS values + */ + static WifiMode GetHtMcs13 (void); + /** + * Return MCS 14 from HT MCS values. + * + * \return MCS 14 from HT MCS values + */ + static WifiMode GetHtMcs14 (void); + /** + * Return MCS 15 from HT MCS values. + * + * \return MCS 15 from HT MCS values + */ + static WifiMode GetHtMcs15 (void); + /** + * Return MCS 16 from HT MCS values. + * + * \return MCS 16 from HT MCS values + */ + static WifiMode GetHtMcs16 (void); + /** + * Return MCS 17 from HT MCS values. + * + * \return MCS 17 from HT MCS values + */ + static WifiMode GetHtMcs17 (void); + /** + * Return MCS 18 from HT MCS values. + * + * \return MCS 18 from HT MCS values + */ + static WifiMode GetHtMcs18 (void); + /** + * Return MCS 19 from HT MCS values. + * + * \return MCS 19 from HT MCS values + */ + static WifiMode GetHtMcs19 (void); + /** + * Return MCS 20 from HT MCS values. + * + * \return MCS 20 from HT MCS values + */ + static WifiMode GetHtMcs20 (void); + /** + * Return MCS 21 from HT MCS values. + * + * \return MCS 21 from HT MCS values + */ + static WifiMode GetHtMcs21 (void); + /** + * Return MCS 22 from HT MCS values. + * + * \return MCS 22 from HT MCS values + */ + static WifiMode GetHtMcs22 (void); + /** + * Return MCS 23 from HT MCS values. + * + * \return MCS 23 from HT MCS values + */ + static WifiMode GetHtMcs23 (void); + /** + * Return MCS 24 from HT MCS values. + * + * \return MCS 24 from HT MCS values + */ + static WifiMode GetHtMcs24 (void); + /** + * Return MCS 25 from HT MCS values. + * + * \return MCS 25 from HT MCS values + */ + static WifiMode GetHtMcs25 (void); + /** + * Return MCS 26 from HT MCS values. + * + * \return MCS 26 from HT MCS values + */ + static WifiMode GetHtMcs26 (void); + /** + * Return MCS 27 from HT MCS values. + * + * \return MCS 27 from HT MCS values + */ + static WifiMode GetHtMcs27 (void); + /** + * Return MCS 28 from HT MCS values. + * + * \return MCS 28 from HT MCS values + */ + static WifiMode GetHtMcs28 (void); + /** + * Return MCS 29 from HT MCS values. + * + * \return MCS 29 from HT MCS values + */ + static WifiMode GetHtMcs29 (void); + /** + * Return MCS 30 from HT MCS values. + * + * \return MCS 30 from HT MCS values + */ + static WifiMode GetHtMcs30 (void); + /** + * Return MCS 31 from HT MCS values. + * + * \return MCS 31 from HT MCS values + */ + static WifiMode GetHtMcs31 (void); + +protected: + /** + * Build mode list. + * Should be redone whenever the maximum MCS index per spatial stream + * ,or any other important parameter having an impact on the MCS index + * (e.g. number of spatial streams for HT), changes. + */ + virtual void BuildModeList (void); + + uint8_t m_maxMcsIndexPerSs; //!< the maximum MCS index per spatial stream as defined by the standard + uint8_t m_maxSupportedMcsIndexPerSs; //!< the maximum supported MCS index per spatial stream + uint8_t m_bssMembershipSelector; //!< the BSS membership selector + +private: + uint8_t m_maxSupportedNss; //!< Maximum supported number of spatial streams (used to build HT MCS indices) + + static const PpduFormats m_htPpduFormats; //!< HT PPDU formats +}; //class HtPhy + +} //namespace ns3 + +#endif /* HT_PHY_H */ diff --git a/src/wifi/model/ofdm-phy.cc b/src/wifi/model/ofdm-phy.cc new file mode 100644 index 000000000..24af5c83f --- /dev/null +++ b/src/wifi/model/ofdm-phy.cc @@ -0,0 +1,548 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2020 Orange Labs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Rediet + * Sébastien Deronne (for logic ported from wifi-phy) + * Mathieu Lacage (for logic ported from wifi-phy) + */ + +#include "ofdm-phy.h" +#include "ns3/log.h" +#include "ns3/assert.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("OfdmPhy"); + +/******************************************************* + * OFDM PHY (IEEE 802.11-2016, clause 17) + *******************************************************/ + +/* *NS_CHECK_STYLE_OFF* */ +const PhyEntity::PpduFormats OfdmPhy::m_ofdmPpduFormats { + { WIFI_PREAMBLE_LONG, { WIFI_PPDU_FIELD_PREAMBLE, //STF + LTF + WIFI_PPDU_FIELD_NON_HT_HEADER, //SIG + WIFI_PPDU_FIELD_DATA } } +}; +/* *NS_CHECK_STYLE_ON* */ + +OfdmPhy::OfdmPhy (OfdmPhyVariant variant /* = OFDM_PHY_DEFAULT */, bool buildModeList /* = true */) +{ + NS_LOG_FUNCTION (this << variant << buildModeList); + + if (buildModeList) + { + auto bwRatesMap = GetOfdmRatesBpsList (); + + switch (variant) + { + case OFDM_PHY_DEFAULT: + for (const auto & rate : bwRatesMap.at (20)) + { + WifiMode mode = GetOfdmRate (rate, 20); + NS_LOG_LOGIC ("Add " << mode << " to list"); + m_modeList.emplace_back (mode); + } + break; + case OFDM_PHY_HOLLAND: + NS_LOG_LOGIC ("Use Holland configuration"); + NS_LOG_LOGIC ("Add OfdmRate6Mbps to list"); + m_modeList.emplace_back (GetOfdmRate6Mbps ()); + NS_LOG_LOGIC ("Add OfdmRate12Mbps to list"); + m_modeList.emplace_back (GetOfdmRate12Mbps ()); + NS_LOG_LOGIC ("Add OfdmRate18Mbps to list"); + m_modeList.emplace_back (GetOfdmRate18Mbps ()); + NS_LOG_LOGIC ("Add OfdmRate36Mbps to list"); + m_modeList.emplace_back (GetOfdmRate36Mbps ()); + NS_LOG_LOGIC ("Add OfdmRate54Mbps to list"); + m_modeList.emplace_back (GetOfdmRate54Mbps ()); + break; + case OFDM_PHY_10_MHZ: + for (const auto & rate : bwRatesMap.at (10)) + { + WifiMode mode = GetOfdmRate (rate, 10); + NS_LOG_LOGIC ("Add " << mode << " to list"); + m_modeList.emplace_back (mode); + } + break; + case OFDM_PHY_5_MHZ: + for (const auto & rate : bwRatesMap.at (5)) + { + WifiMode mode = GetOfdmRate (rate, 5); + NS_LOG_LOGIC ("Add " << mode << " to list"); + m_modeList.emplace_back (mode); + } + break; + default: + NS_ABORT_MSG ("Unsupported 11a OFDM variant"); + } + } +} + +OfdmPhy::~OfdmPhy () +{ + NS_LOG_FUNCTION (this); +} + +WifiMode +OfdmPhy::GetSigMode (WifiPpduField field, WifiTxVector txVector) const +{ + switch (field) + { + case WIFI_PPDU_FIELD_NON_HT_HEADER: + return GetHeaderMode (txVector); + default: + return PhyEntity::GetSigMode (field, txVector); + } +} + +WifiMode +OfdmPhy::GetHeaderMode (WifiTxVector txVector) const +{ + switch (txVector.GetChannelWidth ()) + { + case 5: + return GetOfdmRate1_5MbpsBW5MHz (); + case 10: + return GetOfdmRate3MbpsBW10MHz (); + case 20: + default: + //Section 17.3.2 "PPDU frame format"; IEEE Std 802.11-2016. + //Actually this is only the first part of the PhyHeader, + //because the last 16 bits of the PhyHeader are using the + //same mode of the payload + return GetOfdmRate6Mbps (); + } +} + +const PhyEntity::PpduFormats & +OfdmPhy::GetPpduFormats (void) const +{ + return m_ofdmPpduFormats; +} + +void +OfdmPhy::InitializeModes (void) +{ + for (const auto & ratesPerBw : GetOfdmRatesBpsList ()) + { + for (const auto & rate : ratesPerBw.second) + { + GetOfdmRate (rate, ratesPerBw.first); + } + } +} + +WifiMode +OfdmPhy::GetOfdmRate (uint64_t rate, uint16_t bw) +{ + switch (bw) + { + case 20: + switch (rate) + { + case 6000000: + return GetOfdmRate6Mbps (); + case 9000000: + return GetOfdmRate9Mbps (); + case 12000000: + return GetOfdmRate12Mbps (); + case 18000000: + return GetOfdmRate18Mbps (); + case 24000000: + return GetOfdmRate24Mbps (); + case 36000000: + return GetOfdmRate36Mbps (); + case 48000000: + return GetOfdmRate48Mbps (); + case 54000000: + return GetOfdmRate54Mbps (); + default: + NS_ABORT_MSG ("Inexistent rate (" << rate << " bps) requested for 11a OFDM (default)"); + return WifiMode (); + } + break; + case 10: + switch (rate) + { + case 3000000: + return GetOfdmRate3MbpsBW10MHz (); + case 4500000: + return GetOfdmRate4_5MbpsBW10MHz (); + case 6000000: + return GetOfdmRate6MbpsBW10MHz (); + case 9000000: + return GetOfdmRate9MbpsBW10MHz (); + case 12000000: + return GetOfdmRate12MbpsBW10MHz (); + case 18000000: + return GetOfdmRate18MbpsBW10MHz (); + case 24000000: + return GetOfdmRate24MbpsBW10MHz (); + case 27000000: + return GetOfdmRate27MbpsBW10MHz (); + default: + NS_ABORT_MSG ("Inexistent rate (" << rate << " bps) requested for 11a OFDM (10 MHz)"); + return WifiMode (); + } + break; + case 5: + switch (rate) + { + case 1500000: + return GetOfdmRate1_5MbpsBW5MHz (); + case 2250000: + return GetOfdmRate2_25MbpsBW5MHz (); + case 3000000: + return GetOfdmRate3MbpsBW5MHz (); + case 4500000: + return GetOfdmRate4_5MbpsBW5MHz (); + case 6000000: + return GetOfdmRate6MbpsBW5MHz (); + case 9000000: + return GetOfdmRate9MbpsBW5MHz (); + case 12000000: + return GetOfdmRate12MbpsBW5MHz (); + case 13500000: + return GetOfdmRate13_5MbpsBW5MHz (); + default: + NS_ABORT_MSG ("Inexistent rate (" << rate << " bps) requested for 11a OFDM (5 MHz)"); + return WifiMode (); + } + break; + default: + NS_ABORT_MSG ("Inexistent bandwidth (" << +bw << " MHz) requested for 11a OFDM"); + return WifiMode (); + } +} + +std::map > +OfdmPhy::GetOfdmRatesBpsList (void) +{ + /* *NS_CHECK_STYLE_OFF* */ + return { + { 20, // MHz + { 6000000, 9000000, 12000000, 18000000, + 24000000, 36000000, 48000000, 54000000 }}, + { 10, // MHz + { 3000000, 4500000, 6000000, 9000000, + 12000000, 18000000, 24000000, 27000000 }}, + { 5, // MHz + { 1500000, 2250000, 3000000, 4500000, + 6000000, 9000000, 12000000, 13500000 }} + }; + /* *NS_CHECK_STYLE_ON* */ +} + + +// 20 MHz channel rates (default) + +WifiMode +OfdmPhy::GetOfdmRate6Mbps (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate6Mbps", + WIFI_MOD_CLASS_OFDM, + true, + WIFI_CODE_RATE_1_2, + 2); + return mode; +} + +WifiMode +OfdmPhy::GetOfdmRate9Mbps (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate9Mbps", + WIFI_MOD_CLASS_OFDM, + false, + WIFI_CODE_RATE_3_4, + 2); + return mode; +} + +WifiMode +OfdmPhy::GetOfdmRate12Mbps (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate12Mbps", + WIFI_MOD_CLASS_OFDM, + true, + WIFI_CODE_RATE_1_2, + 4); + return mode; +} + +WifiMode +OfdmPhy::GetOfdmRate18Mbps (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate18Mbps", + WIFI_MOD_CLASS_OFDM, + false, + WIFI_CODE_RATE_3_4, + 4); + return mode; +} + +WifiMode +OfdmPhy::GetOfdmRate24Mbps (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate24Mbps", + WIFI_MOD_CLASS_OFDM, + true, + WIFI_CODE_RATE_1_2, + 16); + return mode; +} + +WifiMode +OfdmPhy::GetOfdmRate36Mbps (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate36Mbps", + WIFI_MOD_CLASS_OFDM, + false, + WIFI_CODE_RATE_3_4, + 16); + return mode; +} + +WifiMode +OfdmPhy::GetOfdmRate48Mbps (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate48Mbps", + WIFI_MOD_CLASS_OFDM, + false, + WIFI_CODE_RATE_2_3, + 64); + return mode; +} + +WifiMode +OfdmPhy::GetOfdmRate54Mbps (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate54Mbps", + WIFI_MOD_CLASS_OFDM, + false, + WIFI_CODE_RATE_3_4, + 64); + return mode; +} + + +// 10 MHz channel rates + +WifiMode +OfdmPhy::GetOfdmRate3MbpsBW10MHz (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate3MbpsBW10MHz", + WIFI_MOD_CLASS_OFDM, + true, + WIFI_CODE_RATE_1_2, + 2); + return mode; +} + +WifiMode +OfdmPhy::GetOfdmRate4_5MbpsBW10MHz (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate4_5MbpsBW10MHz", + WIFI_MOD_CLASS_OFDM, + false, + WIFI_CODE_RATE_3_4, + 2); + return mode; +} + +WifiMode +OfdmPhy::GetOfdmRate6MbpsBW10MHz (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate6MbpsBW10MHz", + WIFI_MOD_CLASS_OFDM, + true, + WIFI_CODE_RATE_1_2, + 4); + return mode; +} + +WifiMode +OfdmPhy::GetOfdmRate9MbpsBW10MHz (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate9MbpsBW10MHz", + WIFI_MOD_CLASS_OFDM, + false, + WIFI_CODE_RATE_3_4, + 4); + return mode; +} + +WifiMode +OfdmPhy::GetOfdmRate12MbpsBW10MHz (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate12MbpsBW10MHz", + WIFI_MOD_CLASS_OFDM, + true, + WIFI_CODE_RATE_1_2, + 16); + return mode; +} + +WifiMode +OfdmPhy::GetOfdmRate18MbpsBW10MHz (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate18MbpsBW10MHz", + WIFI_MOD_CLASS_OFDM, + false, + WIFI_CODE_RATE_3_4, + 16); + return mode; +} + +WifiMode +OfdmPhy::GetOfdmRate24MbpsBW10MHz (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate24MbpsBW10MHz", + WIFI_MOD_CLASS_OFDM, + false, + WIFI_CODE_RATE_2_3, + 64); + return mode; +} + +WifiMode +OfdmPhy::GetOfdmRate27MbpsBW10MHz (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate27MbpsBW10MHz", + WIFI_MOD_CLASS_OFDM, + false, + WIFI_CODE_RATE_3_4, + 64); + return mode; +} + + +// 5 MHz channel rates + +WifiMode +OfdmPhy::GetOfdmRate1_5MbpsBW5MHz (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate1_5MbpsBW5MHz", + WIFI_MOD_CLASS_OFDM, + true, + WIFI_CODE_RATE_1_2, + 2); + return mode; +} + +WifiMode +OfdmPhy::GetOfdmRate2_25MbpsBW5MHz (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate2_25MbpsBW5MHz", + WIFI_MOD_CLASS_OFDM, + false, + WIFI_CODE_RATE_3_4, + 2); + return mode; +} + +WifiMode +OfdmPhy::GetOfdmRate3MbpsBW5MHz (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate3MbpsBW5MHz", + WIFI_MOD_CLASS_OFDM, + true, + WIFI_CODE_RATE_1_2, + 4); + return mode; +} + +WifiMode +OfdmPhy::GetOfdmRate4_5MbpsBW5MHz (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate4_5MbpsBW5MHz", + WIFI_MOD_CLASS_OFDM, + false, + WIFI_CODE_RATE_3_4, + 4); + return mode; +} + +WifiMode +OfdmPhy::GetOfdmRate6MbpsBW5MHz (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate6MbpsBW5MHz", + WIFI_MOD_CLASS_OFDM, + true, + WIFI_CODE_RATE_1_2, + 16); + return mode; +} + +WifiMode +OfdmPhy::GetOfdmRate9MbpsBW5MHz (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate9MbpsBW5MHz", + WIFI_MOD_CLASS_OFDM, + false, + WIFI_CODE_RATE_3_4, + 16); + return mode; +} + +WifiMode +OfdmPhy::GetOfdmRate12MbpsBW5MHz (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate12MbpsBW5MHz", + WIFI_MOD_CLASS_OFDM, + false, + WIFI_CODE_RATE_2_3, + 64); + return mode; +} + +WifiMode +OfdmPhy::GetOfdmRate13_5MbpsBW5MHz (void) +{ + static WifiMode mode = + WifiModeFactory::CreateWifiMode ("OfdmRate13_5MbpsBW5MHz", + WIFI_MOD_CLASS_OFDM, + false, + WIFI_CODE_RATE_3_4, + 64); + return mode; +} + +} //namespace ns3 diff --git a/src/wifi/model/ofdm-phy.h b/src/wifi/model/ofdm-phy.h new file mode 100644 index 000000000..6ccb7a200 --- /dev/null +++ b/src/wifi/model/ofdm-phy.h @@ -0,0 +1,268 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2020 Orange Labs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Rediet + * Sébastien Deronne (for logic ported from wifi-phy) + * Mathieu Lacage (for logic ported from wifi-phy) + */ + +#ifndef OFDM_PHY_H +#define OFDM_PHY_H + +#include "phy-entity.h" +#include +#include + +/** + * \file + * \ingroup wifi + * Declaration of ns3::OfdmPhy class + * and ns3::OfdmPhyVariant enum. + */ + +namespace ns3 { + +/** + * \ingroup wifi + * The OFDM (11a) PHY variants. + * + * \see OfdmPhy + */ +enum OfdmPhyVariant +{ + OFDM_PHY_DEFAULT, + OFDM_PHY_HOLLAND, + OFDM_PHY_10_MHZ, + OFDM_PHY_5_MHZ +}; + +/** + * \brief PHY entity for OFDM (11a) + * \ingroup wifi + * + * This class is also used for the 10 MHz and 5 MHz bandwidth + * variants addressing vehicular communications (default is 20 MHz + * bandwidth). + * It is also used for the Holland configuration detailed in this paper: + * Gavin Holland, Nitin Vaidya and Paramvir Bahl, "A Rate-Adaptive + * MAC Protocol for Multi-Hop Wireless Networks", in Proc. of + * ACM MOBICOM, 2001. + * + * Refer to IEEE 802.11-2016, clause 17. + */ +class OfdmPhy : public PhyEntity +{ +public: + /** + * Constructor for OFDM PHY + * + * \param variant the OFDM PHY variant + * \param buildModeList flag used to add OFDM modes to list (disabled + * by child classes to only add child classes' modes) + */ + OfdmPhy (OfdmPhyVariant variant = OFDM_PHY_DEFAULT, bool buildModeList = true); + /** + * Destructor for OFDM PHY + */ + virtual ~OfdmPhy (); + + // Inherited + virtual WifiMode GetSigMode (WifiPpduField field, WifiTxVector txVector) const override; + virtual const PpduFormats & GetPpduFormats (void) const override; + + /** + * Initialize all OFDM modes (for all variants). + */ + static void InitializeModes (void); + /** + * Return a WifiMode for OFDM + * corresponding to the provided rate and + * the channel bandwidth (20, 10, or 5 MHz). + * + * \param rate the rate in bps + * \param bw the bandwidth in MHz + * \return a WifiMode for OFDM + */ + static WifiMode GetOfdmRate (uint64_t rate, uint16_t bw = 20); + /** + * Return the list of rates (in bps) achievable with + * OFDM along with the supported bandwidth. + * + * \return a map containing a vector of achievable rates in bps + * for each supported bandwidth in Mbps + */ + static std::map > GetOfdmRatesBpsList (void); + + /** + * Return a WifiMode for OFDM at 6 Mbps. + * + * \return a WifiMode for OFDM at 6 Mbps + */ + static WifiMode GetOfdmRate6Mbps (void); + /** + * Return a WifiMode for OFDM at 9 Mbps. + * + * \return a WifiMode for OFDM at 9 Mbps + */ + static WifiMode GetOfdmRate9Mbps (void); + /** + * Return a WifiMode for OFDM at 12Mbps. + * + * \return a WifiMode for OFDM at 12 Mbps + */ + static WifiMode GetOfdmRate12Mbps (void); + /** + * Return a WifiMode for OFDM at 18 Mbps. + * + * \return a WifiMode for OFDM at 18 Mbps + */ + static WifiMode GetOfdmRate18Mbps (void); + /** + * Return a WifiMode for OFDM at 24 Mbps. + * + * \return a WifiMode for OFDM at 24 Mbps + */ + static WifiMode GetOfdmRate24Mbps (void); + /** + * Return a WifiMode for OFDM at 36 Mbps. + * + * \return a WifiMode for OFDM at 36 Mbps + */ + static WifiMode GetOfdmRate36Mbps (void); + /** + * Return a WifiMode for OFDM at 48 Mbps. + * + * \return a WifiMode for OFDM at 48 Mbps + */ + static WifiMode GetOfdmRate48Mbps (void); + /** + * Return a WifiMode for OFDM at 54 Mbps. + * + * \return a WifiMode for OFDM at 54 Mbps + */ + static WifiMode GetOfdmRate54Mbps (void); + /** + * Return a WifiMode for OFDM at 3 Mbps with 10 MHz channel spacing. + * + * \return a WifiMode for OFDM at 3 Mbps with 10 MHz channel spacing + */ + static WifiMode GetOfdmRate3MbpsBW10MHz (void); + /** + * Return a WifiMode for OFDM at 4.5 Mbps with 10 MHz channel spacing. + * + * \return a WifiMode for OFDM at 4.5 Mbps with 10 MHz channel spacing + */ + static WifiMode GetOfdmRate4_5MbpsBW10MHz (void); + /** + * Return a WifiMode for OFDM at 6 Mbps with 10 MHz channel spacing. + * + * \return a WifiMode for OFDM at 6 Mbps with 10 MHz channel spacing + */ + static WifiMode GetOfdmRate6MbpsBW10MHz (void); + /** + * Return a WifiMode for OFDM at 9 Mbps with 10 MHz channel spacing. + * + * \return a WifiMode for OFDM at 9 Mbps with 10 MHz channel spacing + */ + static WifiMode GetOfdmRate9MbpsBW10MHz (void); + /** + * Return a WifiMode for OFDM at 12 Mbps with 10 MHz channel spacing. + * + * \return a WifiMode for OFDM at 12 Mbps with 10 MHz channel spacing + */ + static WifiMode GetOfdmRate12MbpsBW10MHz (void); + /** + * Return a WifiMode for OFDM at 18 Mbps with 10 MHz channel spacing. + * + * \return a WifiMode for OFDM at 18 Mbps with 10 MHz channel spacing + */ + static WifiMode GetOfdmRate18MbpsBW10MHz (void); + /** + * Return a WifiMode for OFDM at 24 Mbps with 10 MHz channel spacing. + * + * \return a WifiMode for OFDM at 24 Mbps with 10 MHz channel spacing + */ + static WifiMode GetOfdmRate24MbpsBW10MHz (void); + /** + * Return a WifiMode for OFDM at 27 Mbps with 10 MHz channel spacing. + * + * \return a WifiMode for OFDM at 27 Mbps with 10 MHz channel spacing + */ + static WifiMode GetOfdmRate27MbpsBW10MHz (void); + /** + * Return a WifiMode for OFDM at 1.5 Mbps with 5 MHz channel spacing. + * + * \return a WifiMode for OFDM at 1.5 Mbps with 5 MHz channel spacing + */ + static WifiMode GetOfdmRate1_5MbpsBW5MHz (void); + /** + * Return a WifiMode for OFDM at 2.25 Mbps with 5 MHz channel spacing. + * + * \return a WifiMode for OFDM at 2.25 Mbps with 5 MHz channel spacing + */ + static WifiMode GetOfdmRate2_25MbpsBW5MHz (void); + /** + * Return a WifiMode for OFDM at 3 Mbps with 5 MHz channel spacing. + * + * \return a WifiMode for OFDM at 3 Mbps with 5 MHz channel spacing + */ + static WifiMode GetOfdmRate3MbpsBW5MHz (void); + /** + * Return a WifiMode for OFDM at 4.5 Mbps with 5 MHz channel spacing. + * + * \return a WifiMode for OFDM at 4.5 Mbps with 5 MHz channel spacing + */ + static WifiMode GetOfdmRate4_5MbpsBW5MHz (void); + /** + * Return a WifiMode for OFDM at 6 Mbps with 5 MHz channel spacing. + * + * \return a WifiMode for OFDM at 6 Mbps with 5 MHz channel spacing + */ + static WifiMode GetOfdmRate6MbpsBW5MHz (void); + /** + * Return a WifiMode for OFDM at 9 Mbps with 5 MHz channel spacing. + * + * \return a WifiMode for OFDM at 9 Mbps with 5 MHz channel spacing + */ + static WifiMode GetOfdmRate9MbpsBW5MHz (void); + /** + * Return a WifiMode for OFDM at 12 Mbps with 5 MHz channel spacing. + * + * \return a WifiMode for OFDM at 12 Mbps with 5 MHz channel spacing + */ + static WifiMode GetOfdmRate12MbpsBW5MHz (void); + /** + * Return a WifiMode for OFDM at 13.5 Mbps with 5 MHz channel spacing. + * + * \return a WifiMode for OFDM at 13.5 Mbps with 5 MHz channel spacing + */ + static WifiMode GetOfdmRate13_5MbpsBW5MHz (void); + +protected: + /** + * \param txVector the transmission parameters + * \return the WifiMode used for the SIGNAL field + */ + virtual WifiMode GetHeaderMode (WifiTxVector txVector) const; + +private: + static const PpduFormats m_ofdmPpduFormats; //!< OFDM PPDU formats +}; //class OfdmPhy + +} //namespace ns3 + +#endif /* OFDM_PHY_H */ diff --git a/src/wifi/model/phy-entity.cc b/src/wifi/model/phy-entity.cc new file mode 100644 index 000000000..c6b9f9a6d --- /dev/null +++ b/src/wifi/model/phy-entity.cc @@ -0,0 +1,127 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2020 Orange Labs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Rediet + * Sébastien Deronne (for logic ported from wifi-phy) + * Mathieu Lacage (for logic ported from wifi-phy) + */ + +#include "phy-entity.h" +#include "ns3/log.h" +#include "ns3/assert.h" +#include + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("PhyEntity"); + +/******************************************************* + * Abstract base class for PHY entities + *******************************************************/ + +PhyEntity::~PhyEntity () +{ + m_modeList.clear (); +} + +bool +PhyEntity::IsModeSupported (WifiMode mode) const +{ + for (const auto & m : m_modeList) + { + if (m == mode) + { + return true; + } + } + return false; +} + +uint8_t +PhyEntity::GetNumModes (void) const +{ + return m_modeList.size (); +} + +WifiMode +PhyEntity::GetMcs (uint8_t /* index */) const +{ + NS_ABORT_MSG ("This method should be used only for HtPhy and child classes. Use GetMode instead."); + return WifiMode (); +} + +bool +PhyEntity::IsMcsSupported (uint8_t /* index */) const +{ + NS_ABORT_MSG ("This method should be used only for HtPhy and child classes. Use IsModeSupported instead."); + return false; +} + +bool +PhyEntity::HandlesMcsModes (void) const +{ + return false; +} + +std::list::const_iterator +PhyEntity::begin (void) const +{ + return m_modeList.begin (); +} + +std::list::const_iterator +PhyEntity::end (void) const +{ + return m_modeList.end (); +} + +WifiMode +PhyEntity::GetSigMode (WifiPpduField field, WifiTxVector txVector) const +{ + NS_FATAL_ERROR ("PPDU field is not a SIG field (no sense in retrieving the signaled mode) or is unsupported: " << field); + return WifiMode (); //should be overloaded +} + +WifiPpduField +PhyEntity::GetNextField (WifiPpduField currentField, WifiPreamble preamble) const +{ + auto ppduFormats = GetPpduFormats (); + const auto itPpdu = ppduFormats.find (preamble); + if (itPpdu != ppduFormats.end ()) + { + const auto itField = std::find (itPpdu->second.begin (), itPpdu->second.end (), currentField); + if (itField != itPpdu->second.end ()) + { + const auto itNextField = std::next (itField, 1); + if (itNextField != itPpdu->second.end ()) + { + return *(itNextField); + } + NS_FATAL_ERROR ("No field after " << currentField << " for " << preamble << " for the provided PPDU formats"); + } + else + { + NS_FATAL_ERROR ("Unsupported PPDU field " << currentField << " for " << preamble << " for the provided PPDU formats"); + } + } + else + { + NS_FATAL_ERROR ("Unsupported preamble " << preamble << " for the provided PPDU formats"); + } +} + +} //namespace ns3 diff --git a/src/wifi/model/phy-entity.h b/src/wifi/model/phy-entity.h new file mode 100644 index 000000000..d6f295bc6 --- /dev/null +++ b/src/wifi/model/phy-entity.h @@ -0,0 +1,151 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2020 Orange Labs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Rediet + * Sébastien Deronne (for logic ported from wifi-phy) + * Mathieu Lacage (for logic ported from wifi-phy) + */ + +#ifndef PHY_ENTITY_H +#define PHY_ENTITY_H + +#include "wifi-tx-vector.h" +#include "ns3/simple-ref-count.h" +#include "ns3/nstime.h" +#include + +/** + * \file + * \ingroup wifi + * Declaration of ns3::PhyEntity class. + */ + +namespace ns3 { + +/** + * \brief Abstract class for PHY entities + * \ingroup wifi + * + * This class enables to have a unique set of APIs + * to be used by each PHY entity, corresponding to + * the different amendments of the IEEE 802.11 standard. + */ +class PhyEntity : public SimpleRefCount +{ +public: + /** + * Destructor for PHY entity + */ + virtual ~PhyEntity (); + + /** + * Check if the WifiMode is supported. + * + * \param mode the WifiMode to check + * \return true if the WifiMode is supported, + * false otherwise + */ + virtual bool IsModeSupported (WifiMode mode) const; + /** + * \return the number of WifiModes supported by this entity + */ + virtual uint8_t GetNumModes (void) const; + + /** + * Get the WifiMode corresponding to the given MCS index. + * + * \param index the index of the MCS + * \return the WifiMode corresponding to the MCS index + * + * This method should be used only for HtPhy and child classes. + */ + virtual WifiMode GetMcs (uint8_t index) const; + /** + * Check if the WifiMode corresponding to the given MCS index is supported. + * + * \param index the index of the MCS + * \return true if the WifiMode corresponding to the MCS index is supported, + * false otherwise + * + * Will return false for non-MCS modes. + */ + virtual bool IsMcsSupported (uint8_t index) const; + /** + * Check if the WifiModes handled by this PHY are MCSs. + * + * \return true if the handled WifiModes are MCSs, + * false if they are non-MCS modes + */ + virtual bool HandlesMcsModes (void) const; + + /** + * Get the WifiMode for the SIG field specified by the PPDU field. + * + * \param field the PPDU field + * \param txVector the transmission parameters + * + * \return the WifiMode used for the SIG field + * + * This method is overridden by child classes. + */ + virtual WifiMode GetSigMode (WifiPpduField field, WifiTxVector txVector) const; + + /** + * \brief Return a const iterator to the first WifiMode + * + * \return a const iterator to the first WifiMode. + */ + std::list::const_iterator begin (void) const; + /** + * \brief Return a const iterator to past-the-last WifiMode + * + * \return a const iterator to past-the-last WifiMode. + */ + std::list::const_iterator end (void) const; + + /** + * Return the field following the provided one. + * + * \param currentField the considered PPDU field + * \param preamble the preamble indicating the PPDU format + * \return the PPDU field following the reference one + */ + WifiPpduField GetNextField (WifiPpduField currentField, WifiPreamble preamble) const; + +protected: + /** + * A map of PPDU field elements per preamble type. + * This corresponds to the different PPDU formats introduced by each amendment. + */ + typedef std::map > PpduFormats; + + /** + * Return the PPDU formats of the PHY. + * + * This method should be implemented (overridden) by each child + * class introducing new formats. + * + * \return the PPDU formats of the PHY + */ + virtual const PpduFormats & GetPpduFormats (void) const = 0; + + std::list m_modeList; //!< the list of supported modes +}; //class PhyEntity + +} //namespace ns3 + +#endif /* PHY_ENTITY_H */ diff --git a/src/wifi/model/vht-phy.cc b/src/wifi/model/vht-phy.cc new file mode 100644 index 000000000..641bd8532 --- /dev/null +++ b/src/wifi/model/vht-phy.cc @@ -0,0 +1,242 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2020 Orange Labs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Rediet + * Sébastien Deronne (for logic ported from wifi-phy) + */ + +#include "vht-phy.h" +#include "ns3/log.h" +#include "ns3/assert.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("VhtPhy"); + +/******************************************************* + * VHT PHY (IEEE 802.11-2016, clause 21) + *******************************************************/ + +/* *NS_CHECK_STYLE_OFF* */ +const PhyEntity::PpduFormats VhtPhy::m_vhtPpduFormats { + { WIFI_PREAMBLE_VHT_SU, { WIFI_PPDU_FIELD_PREAMBLE, //L-STF + L-LTF + WIFI_PPDU_FIELD_NON_HT_HEADER, //L-SIG + WIFI_PPDU_FIELD_SIG_A, //VHT-SIG-A + WIFI_PPDU_FIELD_TRAINING, //VHT-STF + VHT-LTFs + WIFI_PPDU_FIELD_DATA } }, + { WIFI_PREAMBLE_VHT_MU, { WIFI_PPDU_FIELD_PREAMBLE, //L-STF + L-LTF + WIFI_PPDU_FIELD_NON_HT_HEADER, //L-SIG + WIFI_PPDU_FIELD_SIG_A, //VHT-SIG-A + WIFI_PPDU_FIELD_TRAINING, //VHT-STF + VHT-LTFs + WIFI_PPDU_FIELD_SIG_B, //VHT-SIG-B + WIFI_PPDU_FIELD_DATA } } +}; +/* *NS_CHECK_STYLE_ON* */ + +VhtPhy::VhtPhy (bool buildModeList /* = true */) + : HtPhy (1, false) //don't add HT modes to list +{ + NS_LOG_FUNCTION (this << buildModeList); + m_bssMembershipSelector = VHT_PHY; + m_maxMcsIndexPerSs = 9; + m_maxSupportedMcsIndexPerSs = m_maxMcsIndexPerSs; + if (buildModeList) + { + BuildModeList (); + } +} + +VhtPhy::~VhtPhy () +{ + NS_LOG_FUNCTION (this); +} + +void +VhtPhy::BuildModeList (void) +{ + NS_LOG_FUNCTION (this); + NS_ASSERT (m_modeList.empty ()); + NS_ASSERT (m_bssMembershipSelector == VHT_PHY); + for (uint8_t index = 0; index <= m_maxSupportedMcsIndexPerSs; ++index) + { + NS_LOG_LOGIC ("Add VhtMcs" << +index << " to list"); + m_modeList.emplace_back (GetVhtMcs (index)); + } +} + +const PhyEntity::PpduFormats & +VhtPhy::GetPpduFormats (void) const +{ + return m_vhtPpduFormats; +} + +WifiMode +VhtPhy::GetSigMode (WifiPpduField field, WifiTxVector txVector) const +{ + switch (field) + { + case WIFI_PPDU_FIELD_SIG_A: + return GetSigAMode (); + case WIFI_PPDU_FIELD_SIG_B: + return GetSigBMode (txVector); + default: + return HtPhy::GetSigMode (field, txVector); + } +} + +WifiMode +VhtPhy::GetHtSigMode (void) const +{ + NS_ASSERT (m_bssMembershipSelector != HT_PHY); + NS_FATAL_ERROR ("No HT-SIG"); + return WifiMode (); +} + +WifiMode +VhtPhy::GetSigAMode (void) const +{ + return GetLSigMode (); //same number of data tones as OFDM (i.e. 48) +} + +WifiMode +VhtPhy::GetSigBMode (WifiTxVector txVector) const +{ + NS_ABORT_MSG_IF (txVector.GetPreambleType () != WIFI_PREAMBLE_VHT_MU, "VHT-SIG-B only available for VHT MU"); + return GetVhtMcs0 (); +} + +void +VhtPhy::InitializeModes (void) +{ + for (uint8_t i = 0; i < 10; ++i) + { + GetVhtMcs (i); + } +} + +WifiMode +VhtPhy::GetVhtMcs (uint8_t index) +{ + switch (index) + { + case 0: + return GetVhtMcs0 (); + case 1: + return GetVhtMcs1 (); + case 2: + return GetVhtMcs2 (); + case 3: + return GetVhtMcs3 (); + case 4: + return GetVhtMcs4 (); + case 5: + return GetVhtMcs5 (); + case 6: + return GetVhtMcs6 (); + case 7: + return GetVhtMcs7 (); + case 8: + return GetVhtMcs8 (); + case 9: + return GetVhtMcs9 (); + default: + NS_ABORT_MSG ("Inexistent index (" << +index << ") requested for VHT"); + return WifiMode (); + } +} + +WifiMode +VhtPhy::GetVhtMcs0 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("VhtMcs0", 0, WIFI_MOD_CLASS_VHT); + return mcs; +} + +WifiMode +VhtPhy::GetVhtMcs1 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("VhtMcs1", 1, WIFI_MOD_CLASS_VHT); + return mcs; +} + +WifiMode +VhtPhy::GetVhtMcs2 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("VhtMcs2", 2, WIFI_MOD_CLASS_VHT); + return mcs; +} + +WifiMode +VhtPhy::GetVhtMcs3 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("VhtMcs3", 3, WIFI_MOD_CLASS_VHT); + return mcs; +} + +WifiMode +VhtPhy::GetVhtMcs4 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("VhtMcs4", 4, WIFI_MOD_CLASS_VHT); + return mcs; +} + +WifiMode +VhtPhy::GetVhtMcs5 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("VhtMcs5", 5, WIFI_MOD_CLASS_VHT); + return mcs; +} + +WifiMode +VhtPhy::GetVhtMcs6 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("VhtMcs6", 6, WIFI_MOD_CLASS_VHT); + return mcs; +} + +WifiMode +VhtPhy::GetVhtMcs7 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("VhtMcs7", 7, WIFI_MOD_CLASS_VHT); + return mcs; +} + +WifiMode +VhtPhy::GetVhtMcs8 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("VhtMcs8", 8, WIFI_MOD_CLASS_VHT); + return mcs; +} + +WifiMode +VhtPhy::GetVhtMcs9 (void) +{ + static WifiMode mcs = + WifiModeFactory::CreateWifiMcs ("VhtMcs9", 9, WIFI_MOD_CLASS_VHT); + return mcs; +} + +} //namespace ns3 diff --git a/src/wifi/model/vht-phy.h b/src/wifi/model/vht-phy.h new file mode 100644 index 000000000..8c8d1c383 --- /dev/null +++ b/src/wifi/model/vht-phy.h @@ -0,0 +1,164 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2020 Orange Labs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Rediet + * Sébastien Deronne (for logic ported from wifi-phy) + */ + +#ifndef VHT_PHY_H +#define VHT_PHY_H + +#include "ht-phy.h" + +/** + * \file + * \ingroup wifi + * Declaration of ns3::VhtPhy class. + */ + +namespace ns3 { + +/** + * This defines the BSS membership value for VHT PHY. + */ +#define VHT_PHY 126 + +/** + * \brief PHY entity for VHT (11ac) + * \ingroup wifi + * + * VHT PHY is based on HT PHY. + * + * Refer to IEEE 802.11-2016, clause 21. + */ +class VhtPhy : public HtPhy +{ +public: + /** + * Constructor for VHT PHY + * + * \param buildModeList flag used to add VHT modes to list (disabled + * by child classes to only add child classes' modes) + */ + VhtPhy (bool buildModeList = true); + /** + * Destructor for VHT PHY + */ + virtual ~VhtPhy (); + + // Inherited + virtual WifiMode GetSigMode (WifiPpduField field, WifiTxVector txVector) const override; + virtual const PpduFormats & GetPpduFormats (void) const override; + + /** + * \return the WifiMode used for the SIG-A field + */ + virtual WifiMode GetSigAMode (void) const; + /** + * \param txVector the transmission parameters + * \return the WifiMode used for the SIG-B field + */ + virtual WifiMode GetSigBMode (WifiTxVector txVector) const; + + /** + * Initialize all VHT modes. + */ + static void InitializeModes (void); + /** + * Return the VHT MCS corresponding to + * the provided index. + * + * \param index the index of the MCS + * \return an VHT MCS + */ + static WifiMode GetVhtMcs (uint8_t index); + + /** + * Return MCS 0 from VHT MCS values. + * + * \return MCS 0 from VHT MCS values + */ + static WifiMode GetVhtMcs0 (void); + /** + * Return MCS 1 from VHT MCS values. + * + * \return MCS 1 from VHT MCS values + */ + static WifiMode GetVhtMcs1 (void); + /** + * Return MCS 2 from VHT MCS values. + * + * \return MCS 2 from VHT MCS values + */ + static WifiMode GetVhtMcs2 (void); + /** + * Return MCS 3 from VHT MCS values. + * + * \return MCS 3 from VHT MCS values + */ + static WifiMode GetVhtMcs3 (void); + /** + * Return MCS 4 from VHT MCS values. + * + * \return MCS 4 from VHT MCS values + */ + static WifiMode GetVhtMcs4 (void); + /** + * Return MCS 5 from VHT MCS values. + * + * \return MCS 5 from VHT MCS values + */ + static WifiMode GetVhtMcs5 (void); + /** + * Return MCS 6 from VHT MCS values. + * + * \return MCS 6 from VHT MCS values + */ + static WifiMode GetVhtMcs6 (void); + /** + * Return MCS 7 from VHT MCS values. + * + * \return MCS 7 from VHT MCS values + */ + static WifiMode GetVhtMcs7 (void); + /** + * Return MCS 8 from VHT MCS values. + * + * \return MCS 8 from VHT MCS values + */ + static WifiMode GetVhtMcs8 (void); + /** + * Return MCS 9 from VHT MCS values. + * + * \return MCS 9 from VHT MCS values + */ + static WifiMode GetVhtMcs9 (void); + +protected: + // Inherited + WifiMode GetHtSigMode (void) const override; + +private: + // Inherited + virtual void BuildModeList (void) override; + + static const PpduFormats m_vhtPpduFormats; //!< VHT PPDU formats +}; //class VhtPhy + +} //namespace ns3 + +#endif /* VHT_PHY_H */ diff --git a/src/wifi/model/wifi-phy-common.h b/src/wifi/model/wifi-phy-common.h index 0f415aa2e..4cf8c037b 100644 --- a/src/wifi/model/wifi-phy-common.h +++ b/src/wifi/model/wifi-phy-common.h @@ -1,6 +1,7 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2005,2006,2007 INRIA + * Copyright (c) 2020 Orange Labs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -15,7 +16,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * Author: Mathieu Lacage + * Authors: Mathieu Lacage + * Rediet */ #ifndef WIFI_PHY_COMMON_H @@ -29,6 +31,7 @@ * Declaration of the following enums: * - ns3::WifiPreamble * - ns3::WifiModulationClass + * - ns3::WifiPpduField */ namespace ns3 { @@ -139,6 +142,64 @@ inline std::ostream& operator<< (std::ostream &os, const WifiModulationClass &mo } } +/** + * \ingroup wifi + * The type of PPDU field (grouped for convenience) + */ +enum WifiPpduField +{ + /** + * SYNC + SFD fields for DSSS or ERP, + * shortSYNC + shortSFD fields for HR/DSSS or ERP, + * HT-GF-STF + HT-GF-LTF1 fields for HT-GF, + * L-STF + L-LTF fields otherwise. + */ + WIFI_PPDU_FIELD_PREAMBLE = 0, + /** + * PHY header field for DSSS or ERP, + * short PHY header field for HR/DSSS or ERP, + * field not present for HT-GF, + * L-SIG field or L-SIG + RL-SIG fields otherwise. + */ + WIFI_PPDU_FIELD_NON_HT_HEADER, + WIFI_PPDU_FIELD_HT_SIG, //!< HT-SIG field + WIFI_PPDU_FIELD_TRAINING, //!< STF + LTF fields (excluding those in preamble for HT-GF) + WIFI_PPDU_FIELD_SIG_A, //!< SIG-A field + WIFI_PPDU_FIELD_SIG_B, //!< SIG-B field + WIFI_PPDU_FIELD_DATA //!< data field +}; + +/** + * \brief Stream insertion operator. + * + * \param os the stream + * \param field the PPDU field + * \returns a reference to the stream + */ +inline std::ostream& operator<< (std::ostream &os, const WifiPpduField &field) +{ + switch (field) + { + case WIFI_PPDU_FIELD_PREAMBLE: + return (os << "preamble"); + case WIFI_PPDU_FIELD_NON_HT_HEADER: + return (os << "non-HT header"); + case WIFI_PPDU_FIELD_HT_SIG: + return (os << "HT-SIG"); + case WIFI_PPDU_FIELD_TRAINING: + return (os << "training"); + case WIFI_PPDU_FIELD_SIG_A: + return (os << "SIG-A"); + case WIFI_PPDU_FIELD_SIG_B: + return (os << "SIG-B"); + case WIFI_PPDU_FIELD_DATA: + return (os << "data"); + default: + NS_FATAL_ERROR ("Unknown field"); + return (os << "unknown"); + } +} + } //namespace ns3 #endif /* WIFI_PHY_COMMON_H */ diff --git a/src/wifi/model/wifi-phy.cc b/src/wifi/model/wifi-phy.cc index aa11d97bc..bd1276d98 100644 --- a/src/wifi/model/wifi-phy.cc +++ b/src/wifi/model/wifi-phy.cc @@ -40,6 +40,7 @@ #include "mpdu-aggregator.h" #include "wifi-psdu.h" #include "ap-wifi-mac.h" +#include "he-phy.h" //includes OFDM, HT, and VHT namespace ns3 { diff --git a/src/wifi/model/wifi-phy.h b/src/wifi/model/wifi-phy.h index 237d423e4..6be9c5dba 100644 --- a/src/wifi/model/wifi-phy.h +++ b/src/wifi/model/wifi-phy.h @@ -33,10 +33,6 @@ namespace ns3 { -#define HE_PHY 125 -#define VHT_PHY 126 -#define HT_PHY 127 - class Channel; class NetDevice; class MobilityModel; diff --git a/src/wifi/wscript b/src/wifi/wscript index 6a507881d..9117376a2 100644 --- a/src/wifi/wscript +++ b/src/wifi/wscript @@ -112,6 +112,13 @@ def build(bld): 'model/obss-pd-algorithm.cc', 'model/constant-obss-pd-algorithm.cc', 'model/he-ru.cc', + 'model/phy-entity.cc', + 'model/dsss-phy.cc', + 'model/ofdm-phy.cc', + 'model/erp-ofdm-phy.cc', + 'model/ht-phy.cc', + 'model/vht-phy.cc', + 'model/he-phy.cc', 'helper/wifi-radio-energy-model-helper.cc', 'helper/athstats-helper.cc', 'helper/wifi-helper.cc', @@ -264,6 +271,13 @@ def build(bld): 'model/constant-obss-pd-algorithm.h', 'model/he-ru.h', 'model/reference/error-rate-tables.h', + 'model/phy-entity.h', + 'model/dsss-phy.h', + 'model/ofdm-phy.h', + 'model/erp-ofdm-phy.h', + 'model/ht-phy.h', + 'model/vht-phy.h', + 'model/he-phy.h', 'helper/wifi-radio-energy-model-helper.h', 'helper/athstats-helper.h', 'helper/wifi-helper.h',