wifi: Add initial EhtPhy and EhtPpdu classes for 802.11be

This commit is contained in:
Sébastien Deronne
2021-03-06 15:50:59 +01:00
committed by Sebastien Deronne
parent 53adc7ef39
commit 9faa0b6079
7 changed files with 844 additions and 3 deletions

View File

@@ -27,6 +27,8 @@ set(source_files
model/edca-parameter-set.cc
model/eht/eht-capabilities.cc
model/eht/eht-configuration.cc
model/eht/eht-phy.cc
model/eht/eht-ppdu.cc
model/error-rate-model.cc
model/extended-capabilities.cc
model/frame-capture-model.cc
@@ -163,6 +165,8 @@ set(header_files
model/edca-parameter-set.h
model/eht/eht-capabilities.h
model/eht/eht-configuration.h
model/eht/eht-phy.h
model/eht/eht-ppdu.h
model/error-rate-model.h
model/extended-capabilities.h
model/frame-capture-model.h

View File

@@ -852,6 +852,8 @@ WifiHelper::EnableLogComponents (void)
LogComponentEnable ("DsssPpdu", LOG_LEVEL_ALL);
LogComponentEnable ("ErpOfdmPhy", LOG_LEVEL_ALL);
LogComponentEnable ("ErpOfdmPpdu", LOG_LEVEL_ALL);
LogComponentEnable ("EhtPhy", LOG_LEVEL_ALL);
LogComponentEnable ("EhtPpdu", LOG_LEVEL_ALL);
LogComponentEnable ("FrameExchangeManager", LOG_LEVEL_ALL);
LogComponentEnable ("HeConfiguration", LOG_LEVEL_ALL);
LogComponentEnable ("HeFrameExchangeManager", LOG_LEVEL_ALL);

View File

@@ -0,0 +1,381 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2021 DERONNE SOFTWARE ENGINEERING
*
* 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
*
* Author: Sébastien Deronne <sebastien.deronne@gmail.com>
*/
#include "ns3/wifi-phy.h"
#include "ns3/wifi-psdu.h"
#include "ns3/wifi-utils.h"
#include "ns3/interference-helper.h"
#include "eht-phy.h"
#include "eht-ppdu.h"
namespace ns3 {
NS_LOG_COMPONENT_DEFINE ("EhtPhy");
/*******************************************************
* EHT PHY (P802.11be/D1.5)
*******************************************************/
/* *NS_CHECK_STYLE_OFF* */
const PhyEntity::PpduFormats EhtPhy::m_ehtPpduFormats {
{ WIFI_PREAMBLE_EHT_MU, { WIFI_PPDU_FIELD_PREAMBLE, //L-STF + L-LTF
WIFI_PPDU_FIELD_NON_HT_HEADER, //L-SIG + RL-SIG
WIFI_PPDU_FIELD_U_SIG, //U-SIG
WIFI_PPDU_FIELD_EHT_SIG, //EHT-SIG
WIFI_PPDU_FIELD_TRAINING, //EHT-STF + EHT-LTFs
WIFI_PPDU_FIELD_DATA } },
{ WIFI_PREAMBLE_EHT_TB, { WIFI_PPDU_FIELD_PREAMBLE, //L-STF + L-LTF
WIFI_PPDU_FIELD_NON_HT_HEADER, //L-SIG + RL-SIG
WIFI_PPDU_FIELD_U_SIG, //U-SIG
WIFI_PPDU_FIELD_TRAINING, //EHT-STF + EHT-LTFs
WIFI_PPDU_FIELD_DATA } }
};
/* *NS_CHECK_STYLE_ON* */
EhtPhy::EhtPhy (bool buildModeList /* = true */)
: HePhy (false) //don't add HE modes to list
{
NS_LOG_FUNCTION (this << buildModeList);
m_bssMembershipSelector = EHT_PHY;
m_maxMcsIndexPerSs = 13;
m_maxSupportedMcsIndexPerSs = m_maxMcsIndexPerSs;
if (buildModeList)
{
BuildModeList ();
}
}
EhtPhy::~EhtPhy ()
{
NS_LOG_FUNCTION (this);
}
void
EhtPhy::BuildModeList (void)
{
NS_LOG_FUNCTION (this);
NS_ASSERT (m_modeList.empty ());
NS_ASSERT (m_bssMembershipSelector == EHT_PHY);
for (uint8_t index = 0; index <= m_maxSupportedMcsIndexPerSs; ++index)
{
NS_LOG_LOGIC ("Add EhtMcs" << +index << " to list");
m_modeList.emplace_back (CreateEhtMcs (index));
}
}
WifiMode
EhtPhy::GetSigMode (WifiPpduField field, const WifiTxVector& txVector) const
{
switch (field)
{
case WIFI_PPDU_FIELD_U_SIG:
return GetSigAMode (); //U-SIG is similar to SIG-A
case WIFI_PPDU_FIELD_EHT_SIG:
return GetSigBMode (txVector); //EHT-SIG is similar to SIG-B
default:
return HePhy::GetSigMode (field, txVector);
}
}
Time
EhtPhy::GetDuration (WifiPpduField field, const WifiTxVector& txVector) const
{
switch (field)
{
case WIFI_PPDU_FIELD_U_SIG:
return GetSigADuration (txVector.GetPreambleType ()); //U-SIG is similar to SIG-A
case WIFI_PPDU_FIELD_EHT_SIG:
return GetSigBDuration (txVector); //EHT-SIG is similar to SIG-B
case WIFI_PPDU_FIELD_SIG_A:
[[fallthrough]];
case WIFI_PPDU_FIELD_SIG_B:
return NanoSeconds (0);
default:
return HePhy::GetDuration (field, txVector);
}
}
const PhyEntity::PpduFormats &
EhtPhy::GetPpduFormats (void) const
{
return m_ehtPpduFormats;
}
Ptr<WifiPpdu>
EhtPhy::BuildPpdu (const WifiConstPsduMap & psdus, const WifiTxVector& txVector, Time ppduDuration)
{
NS_LOG_FUNCTION (this << psdus << txVector << ppduDuration);
HePpdu::TxPsdFlag flag = (IsUlMu (txVector.GetPreambleType ())) ?
HePpdu::PSD_HE_TB_NON_OFDMA_PORTION :
HePpdu::PSD_NON_HE_TB;
return Create<EhtPpdu> (psdus, txVector,
m_wifiPhy->GetOperatingChannel ().GetPrimaryChannelCenterFrequency (txVector.GetChannelWidth ()),
ppduDuration, m_wifiPhy->GetPhyBand (),
ObtainNextUid (txVector), flag,
m_wifiPhy->GetOperatingChannel ().GetPrimaryChannelIndex (20));
}
PhyEntity::PhyFieldRxStatus
EhtPhy::DoEndReceiveField (WifiPpduField field, Ptr<Event> event)
{
NS_LOG_FUNCTION (this << field << *event);
switch (field)
{
case WIFI_PPDU_FIELD_U_SIG:
[[fallthrough]];
case WIFI_PPDU_FIELD_EHT_SIG:
return EndReceiveSig (event, field);
default:
return HePhy::DoEndReceiveField (field, event);
}
}
PhyEntity::PhyFieldRxStatus
EhtPhy::ProcessSig (Ptr<Event> event, PhyFieldRxStatus status, WifiPpduField field)
{
NS_LOG_FUNCTION (this << *event << status << field);
switch (field)
{
case WIFI_PPDU_FIELD_U_SIG:
return ProcessSigA (event, status); //U-SIG is similar to SIG-A
case WIFI_PPDU_FIELD_EHT_SIG:
return ProcessSigB (event, status); //EHT-SIG is similar to SIG-B
default:
return HePhy::ProcessSig (event, status, field);
}
return status;
}
WifiPhyRxfailureReason
EhtPhy::GetFailureReason (WifiPpduField field) const
{
switch (field)
{
case WIFI_PPDU_FIELD_U_SIG:
return U_SIG_FAILURE;
case WIFI_PPDU_FIELD_EHT_SIG:
return EHT_SIG_FAILURE;
default:
return HePhy::GetFailureReason (field);
}
}
void
EhtPhy::InitializeModes (void)
{
for (uint8_t i = 0; i <= 13; ++i)
{
GetEhtMcs (i);
}
}
WifiMode
EhtPhy::GetEhtMcs (uint8_t index)
{
#define CASE(x) \
case x: \
return GetEhtMcs ## x (); \
switch (index)
{
CASE ( 0)
CASE ( 1)
CASE ( 2)
CASE ( 3)
CASE ( 4)
CASE ( 5)
CASE ( 6)
CASE ( 7)
CASE ( 8)
CASE ( 9)
CASE (10)
CASE (11)
CASE (12)
CASE (13)
default:
NS_ABORT_MSG ("Inexistent index (" << +index << ") requested for EHT");
return WifiMode ();
}
#undef CASE
}
#define GET_EHT_MCS(x) \
WifiMode \
EhtPhy::GetEhtMcs ## x (void) \
{ \
static WifiMode mcs = CreateEhtMcs (x); \
return mcs; \
}; \
GET_EHT_MCS (0)
GET_EHT_MCS (1)
GET_EHT_MCS (2)
GET_EHT_MCS (3)
GET_EHT_MCS (4)
GET_EHT_MCS (5)
GET_EHT_MCS (6)
GET_EHT_MCS (7)
GET_EHT_MCS (8)
GET_EHT_MCS (9)
GET_EHT_MCS (10)
GET_EHT_MCS (11)
GET_EHT_MCS (12)
GET_EHT_MCS (13)
#undef GET_EHT_MCS
WifiMode
EhtPhy::CreateEhtMcs (uint8_t index)
{
NS_ASSERT_MSG (index <= 13, "EhtMcs index must be <= 13!");
return WifiModeFactory::CreateWifiMcs ("EhtMcs" + std::to_string (index),
index,
WIFI_MOD_CLASS_EHT,
false,
MakeBoundCallback (&GetCodeRate, index),
MakeBoundCallback (&GetConstellationSize, index),
MakeCallback (&GetPhyRateFromTxVector),
MakeCallback (&GetDataRateFromTxVector),
MakeBoundCallback (&GetNonHtReferenceRate, index),
MakeCallback (&IsAllowed));
}
WifiCodeRate
EhtPhy::GetCodeRate (uint8_t mcsValue)
{
switch (mcsValue)
{
case 12:
return WIFI_CODE_RATE_3_4;
case 13:
return WIFI_CODE_RATE_5_6;
default:
return HePhy::GetCodeRate (mcsValue);
}
}
uint16_t
EhtPhy::GetConstellationSize (uint8_t mcsValue)
{
switch (mcsValue)
{
case 12:
[[fallthrough]];
case 13:
return 4096;
default:
return HePhy::GetConstellationSize (mcsValue);
}
}
uint64_t
EhtPhy::GetPhyRate (uint8_t mcsValue, uint16_t channelWidth, uint16_t guardInterval, uint8_t nss)
{
WifiCodeRate codeRate = GetCodeRate (mcsValue);
uint64_t dataRate = GetDataRate (mcsValue, channelWidth, guardInterval, nss);
return HtPhy::CalculatePhyRate (codeRate, dataRate);
}
uint64_t
EhtPhy::GetPhyRateFromTxVector (const WifiTxVector& txVector, uint16_t staId /* = SU_STA_ID */)
{
uint16_t bw = txVector.GetChannelWidth ();
if (txVector.IsMu ())
{
bw = HeRu::GetBandwidth (txVector.GetRu (staId).GetRuType ());
}
return EhtPhy::GetPhyRate (txVector.GetMode (staId).GetMcsValue (),
bw,
txVector.GetGuardInterval (),
txVector.GetNss (staId));
}
uint64_t
EhtPhy::GetDataRateFromTxVector (const WifiTxVector& txVector, uint16_t staId /* = SU_STA_ID */)
{
uint16_t bw = txVector.GetChannelWidth ();
if (txVector.IsMu ())
{
bw = HeRu::GetBandwidth (txVector.GetRu (staId).GetRuType ());
}
return EhtPhy::GetDataRate (txVector.GetMode (staId).GetMcsValue (),
bw,
txVector.GetGuardInterval (),
txVector.GetNss (staId));
}
uint64_t
EhtPhy::GetDataRate (uint8_t mcsValue, uint16_t channelWidth, uint16_t guardInterval, uint8_t nss)
{
NS_ASSERT (guardInterval == 800 || guardInterval == 1600 || guardInterval == 3200);
NS_ASSERT (nss <= 8);
return HtPhy::CalculateDataRate (GetSymbolDuration (NanoSeconds (guardInterval)),
GetUsableSubcarriers (channelWidth),
static_cast<uint16_t> (log2 (GetConstellationSize (mcsValue))),
HtPhy::GetCodeRatio (GetCodeRate (mcsValue)), nss);
}
uint64_t
EhtPhy::GetNonHtReferenceRate (uint8_t mcsValue)
{
WifiCodeRate codeRate = GetCodeRate (mcsValue);
uint16_t constellationSize = GetConstellationSize (mcsValue);
return CalculateNonHtReferenceRate (codeRate, constellationSize);
}
uint64_t
EhtPhy::CalculateNonHtReferenceRate (WifiCodeRate codeRate, uint16_t constellationSize)
{
uint64_t dataRate;
switch (constellationSize)
{
case 4096:
if (codeRate == WIFI_CODE_RATE_3_4 || codeRate == WIFI_CODE_RATE_5_6)
{
dataRate = 54000000;
}
else
{
NS_FATAL_ERROR ("Trying to get reference rate for a MCS with wrong combination of coding rate and modulation");
}
break;
default:
dataRate = HePhy::CalculateNonHtReferenceRate (codeRate, constellationSize);
}
return dataRate;
}
} //namespace ns3
namespace {
/**
* Constructor class for EHT modes
*/
static class ConstructorEht
{
public:
ConstructorEht ()
{
ns3::EhtPhy::InitializeModes ();
ns3::WifiPhy::AddStaticPhyEntity (ns3::WIFI_MOD_CLASS_EHT, ns3::Create<ns3::EhtPhy> ());
}
} g_constructor_eht; ///< the constructor for EHT modes
}

View File

@@ -0,0 +1,280 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2021 DERONNE SOFTWARE ENGINEERING
*
* 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
*
* Author: Sébastien Deronne <sebastien.deronne@gmail.com>
*/
#ifndef EHT_PHY_H
#define EHT_PHY_H
#include "ns3/he-phy.h"
/**
* \file
* \ingroup wifi
* Declaration of ns3::EhtPhy class.
*/
namespace ns3 {
/**
* This defines the BSS membership value for EHT PHY.
*/
#define EHT_PHY 121 // FIXME: not defined yet as of 802.11be D1.5
/**
* \brief PHY entity for EHT (11be)
* \ingroup wifi
*
* EHT PHY is based on HE PHY.
*
* Refer to P802.11be/D1.5.
*/
class EhtPhy : public HePhy
{
public:
/**
* Constructor for EHT PHY
*
* \param buildModeList flag used to add EHT modes to list (disabled
* by child classes to only add child classes' modes)
*/
EhtPhy (bool buildModeList = true);
/**
* Destructor for EHT PHY
*/
virtual ~EhtPhy ();
const PpduFormats& GetPpduFormats (void) const override;
Time GetDuration (WifiPpduField field, const WifiTxVector& txVector) const override;
Ptr<WifiPpdu> BuildPpdu (const WifiConstPsduMap & psdus, const WifiTxVector& txVector, Time ppduDuration) override;
/**
* Initialize all EHT modes.
*/
static void InitializeModes (void);
/**
* Return the EHT MCS corresponding to
* the provided index.
*
* \param index the index of the MCS
* \return an EHT MCS
*/
static WifiMode GetEhtMcs (uint8_t index);
/**
* Return MCS 0 from EHT MCS values.
*
* \return MCS 0 from EHT MCS values
*/
static WifiMode GetEhtMcs0 (void);
/**
* Return MCS 1 from EHT MCS values.
*
* \return MCS 1 from EHT MCS values
*/
static WifiMode GetEhtMcs1 (void);
/**
* Return MCS 2 from EHT MCS values.
*
* \return MCS 2 from EHT MCS values
*/
static WifiMode GetEhtMcs2 (void);
/**
* Return MCS 3 from EHT MCS values.
*
* \return MCS 3 from EHT MCS values
*/
static WifiMode GetEhtMcs3 (void);
/**
* Return MCS 4 from EHT MCS values.
*
* \return MCS 4 from EHT MCS values
*/
static WifiMode GetEhtMcs4 (void);
/**
* Return MCS 5 from EHT MCS values.
*
* \return MCS 5 from EHT MCS values
*/
static WifiMode GetEhtMcs5 (void);
/**
* Return MCS 6 from EHT MCS values.
*
* \return MCS 6 from EHT MCS values
*/
static WifiMode GetEhtMcs6 (void);
/**
* Return MCS 7 from EHT MCS values.
*
* \return MCS 7 from EHT MCS values
*/
static WifiMode GetEhtMcs7 (void);
/**
* Return MCS 8 from EHT MCS values.
*
* \return MCS 8 from EHT MCS values
*/
static WifiMode GetEhtMcs8 (void);
/**
* Return MCS 9 from EHT MCS values.
*
* \return MCS 9 from EHT MCS values
*/
static WifiMode GetEhtMcs9 (void);
/**
* Return MCS 10 from EHT MCS values.
*
* \return MCS 10 from EHT MCS values
*/
static WifiMode GetEhtMcs10 (void);
/**
* Return MCS 11 from EHT MCS values.
*
* \return MCS 11 from EHT MCS values
*/
static WifiMode GetEhtMcs11 (void);
/**
* Return MCS 12 from EHT MCS values.
*
* \return MCS 12 from EHT MCS values
*/
static WifiMode GetEhtMcs12 (void);
/**
* Return MCS 13 from EHT MCS values.
*
* \return MCS 13 from EHT MCS values
*/
static WifiMode GetEhtMcs13 (void);
/**
* Return the coding rate corresponding to
* the supplied EHT MCS index. This function is used
* as a callback for WifiMode operation.
*
* \param mcsValue the MCS index
* \return the coding rate.
*/
static WifiCodeRate GetCodeRate (uint8_t mcsValue);
/**
* Return the constellation size corresponding
* to the supplied EHT MCS index. This function is used
* as a callback for WifiMode operation.
*
* \param mcsValue the MCS index
* \return the size of modulation constellation.
*/
static uint16_t GetConstellationSize (uint8_t mcsValue);
/**
* Return the PHY rate corresponding to the supplied EHT MCS
* index, channel width, guard interval, and number of
* spatial stream. This function calls HtPhy::CalculatePhyRate
* and is mainly used as a callback for WifiMode operation.
*
* \param mcsValue the EHT MCS index
* \param channelWidth the considered channel width in MHz
* \param guardInterval the considered guard interval duration in nanoseconds
* \param nss the considered number of stream
*
* \return the physical bit rate of this signal in bps.
*/
static uint64_t GetPhyRate (uint8_t mcsValue, uint16_t channelWidth, uint16_t guardInterval, uint8_t nss);
/**
* Return the PHY rate corresponding to
* the supplied TXVECTOR for the STA-ID.
*
* \param txVector the TXVECTOR used for the transmission
* \param staId the station ID for MU (unused if SU)
* \return the physical bit rate of this signal in bps.
*/
static uint64_t GetPhyRateFromTxVector (const WifiTxVector& txVector, uint16_t staId = SU_STA_ID);
/**
* Return the data rate corresponding to
* the supplied TXVECTOR for the STA-ID.
*
* \param txVector the TXVECTOR used for the transmission
* \param staId the station ID for MU (unused if SU)
* \return the data bit rate in bps.
*/
static uint64_t GetDataRateFromTxVector (const WifiTxVector& txVector, uint16_t staId = SU_STA_ID);
/**
* Return the data rate corresponding to
* the supplied EHT MCS index, channel width,
* guard interval, and number of spatial
* streams.
*
* \param mcsValue the EHT MCS index
* \param channelWidth the channel width in MHz
* \param guardInterval the guard interval duration in nanoseconds
* \param nss the number of spatial streams
* \return the data bit rate in bps.
*/
static uint64_t GetDataRate (uint8_t mcsValue, uint16_t channelWidth, uint16_t guardInterval, uint8_t nss);
/**
* Calculate the rate in bps of the non-HT Reference Rate corresponding
* to the supplied HE MCS index. This function calls CalculateNonHtReferenceRate
* and is used as a callback for WifiMode operation.
*
* \param mcsValue the HE MCS index
* \return the rate in bps of the non-HT Reference Rate.
*/
static uint64_t GetNonHtReferenceRate (uint8_t mcsValue);
protected:
void BuildModeList (void) override;
WifiMode GetSigMode (WifiPpduField field, const WifiTxVector& txVector) const override;
PhyFieldRxStatus DoEndReceiveField (WifiPpduField field, Ptr<Event> event) override;
PhyFieldRxStatus ProcessSig (Ptr<Event> event, PhyFieldRxStatus status, WifiPpduField field) override;
WifiPhyRxfailureReason GetFailureReason (WifiPpduField field) const override;
/**
* Create and return the EHT MCS corresponding to
* the provided index.
* This method binds all the callbacks used by WifiMode.
*
* \param index the index of the MCS
* \return an EHT MCS
*/
static WifiMode CreateEhtMcs (uint8_t index);
/**
* Return the rate (in bps) of the non-HT Reference Rate
* which corresponds to the supplied code rate and
* constellation size.
*
* \param codeRate the convolutional coding rate
* \param constellationSize the size of modulation constellation
* \returns the rate in bps.
*
* To convert an HE MCS to its corresponding non-HT Reference Rate
* use the modulation and coding rate of the HT MCS
* and lookup in Table 10-10 of IEEE P802.11ax/D6.0.
*/
static uint64_t CalculateNonHtReferenceRate (WifiCodeRate codeRate, uint16_t constellationSize);
static const PpduFormats m_ehtPpduFormats; //!< EHT PPDU formats
}; //class EhtPhy
} //namespace ns3
#endif /* EHT_PHY_H */

View File

@@ -0,0 +1,99 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2021 DERONNE SOFTWARE ENGINEERING
*
* 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
*
* Author: Sébastien Deronne <sebastien.deronne@gmail.com>
*/
#include "ns3/log.h"
#include "ns3/wifi-psdu.h"
#include "eht-phy.h"
#include "eht-ppdu.h"
namespace ns3 {
NS_LOG_COMPONENT_DEFINE ("EhtPpdu");
EhtPpdu::EhtPpdu (const WifiConstPsduMap & psdus, const WifiTxVector& txVector, uint16_t txCenterFreq,
Time ppduDuration, WifiPhyBand band, uint64_t uid, TxPsdFlag flag, uint8_t p20Index)
: HePpdu (psdus, txVector, txCenterFreq, ppduDuration, band, uid, flag, p20Index)
{
NS_LOG_FUNCTION (this << psdus << txVector << txCenterFreq << ppduDuration << band << uid << flag << p20Index);
}
EhtPpdu::~EhtPpdu ()
{
NS_LOG_FUNCTION (this);
}
WifiPpduType
EhtPpdu::GetType (void) const
{
if (m_muUserInfos.empty ())
{
return WIFI_PPDU_TYPE_SU;
}
switch (m_preamble)
{
case WIFI_PREAMBLE_EHT_MU:
return WIFI_PPDU_TYPE_DL_MU;
case WIFI_PREAMBLE_EHT_TB:
return WIFI_PPDU_TYPE_UL_MU;
default:
NS_ASSERT_MSG (false, "invalid preamble " << m_preamble);
return WIFI_PPDU_TYPE_SU;
}
}
bool
EhtPpdu::IsDlMu (void) const
{
return (m_preamble == WIFI_PREAMBLE_EHT_MU) && !m_muUserInfos.empty ();
}
bool
EhtPpdu::IsUlMu (void) const
{
return (m_preamble == WIFI_PREAMBLE_EHT_TB) && !m_muUserInfos.empty ();
}
WifiTxVector
EhtPpdu::DoGetTxVector (void) const
{
// FIXME: define EHT PHY headers
WifiTxVector txVector;
txVector.SetPreambleType (m_preamble);
txVector.SetMode (EhtPhy::GetEhtMcs (m_heSig.GetMcs ()));
txVector.SetChannelWidth (m_heSig.GetChannelWidth ());
txVector.SetNss (m_heSig.GetNStreams ());
txVector.SetGuardInterval (m_heSig.GetGuardInterval ());
txVector.SetBssColor (m_heSig.GetBssColor ());
txVector.SetLength (m_lSig.GetLength ());
txVector.SetAggregation (m_psdus.size () > 1 || m_psdus.begin ()->second->IsAggregate ());
for (auto const& muUserInfo : m_muUserInfos)
{
txVector.SetHeMuUserInfo (muUserInfo.first, muUserInfo.second);
}
return txVector;
}
Ptr<WifiPpdu>
EhtPpdu::Copy (void) const
{
return ns3::Copy (Ptr (this));
}
} //namespace ns3

View File

@@ -0,0 +1,75 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2021 DERONNE SOFTWARE ENGINEERING
*
* 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
*
* Author: Sébastien Deronne <sebastien.deronne@gmail.com>
*/
#ifndef EHT_PPDU_H
#define EHT_PPDU_H
#include "ns3/he-ppdu.h"
/**
* \file
* \ingroup wifi
* Declaration of ns3::EhtPpdu class.
*/
namespace ns3 {
/**
* \brief EHT PPDU (11be)
* \ingroup wifi
*
* EhtPpdu is currently identical to HePpdu
*/
class EhtPpdu : public HePpdu
{
public:
/**
* Create an EHT PPDU, storing a map of PSDUs.
*
* This PPDU can either be UL or DL.
*
* \param psdus the PHY payloads (PSDUs)
* \param txVector the TXVECTOR that was used for this PPDU
* \param txCenterFreq the center frequency (MHz) that was used for this PPDU
* \param ppduDuration the transmission duration of this PPDU
* \param band the WifiPhyBand used for the transmission of this PPDU
* \param uid the unique ID of this PPDU or of the triggering PPDU if this is an EHT TB PPDU
* \param flag the flag indicating the type of Tx PSD to build
* \param p20Index the index of the primary 20 MHz channel
*/
EhtPpdu (const WifiConstPsduMap & psdus, const WifiTxVector& txVector, uint16_t txCenterFreq,
Time ppduDuration, WifiPhyBand band, uint64_t uid, TxPsdFlag flag, uint8_t p20Index);
/**
* Destructor for EhtPpdu.
*/
virtual ~EhtPpdu ();
WifiPpduType GetType (void) const override;
Ptr<WifiPpdu> Copy (void) const override;
protected:
bool IsDlMu (void) const override;
bool IsUlMu (void) const override;
WifiTxVector DoGetTxVector (void) const override;
}; //class EhtPpdu
} //namespace ns3
#endif /* EHT_PPDU_H */

View File

@@ -233,17 +233,17 @@ protected:
* Return true if the PPDU is a MU PPDU
* \return true if the PPDU is a MU PPDU
*/
bool IsMu (void) const;
virtual bool IsMu (void) const;
/**
* Return true if the PPDU is a DL MU PPDU
* \return true if the PPDU is a DL MU PPDU
*/
bool IsDlMu (void) const;
virtual bool IsDlMu (void) const;
/**
* Return true if the PPDU is an UL MU PPDU
* \return true if the PPDU is an UL MU PPDU
*/
bool IsUlMu (void) const;
virtual bool IsUlMu (void) const;
/**
* Fill in the HE PHY headers.