wifi: Move TxPsdFlag to HePpdu

Enables to clean up WifiPhy and SpectrumWifiPhy signatures
This commit is contained in:
Rediet
2021-02-15 09:01:25 +01:00
parent 036e0d6acb
commit f913604e2c
14 changed files with 164 additions and 123 deletions

View File

@@ -307,18 +307,24 @@ Ptr<WifiPpdu>
HePhy::BuildPpdu (const WifiConstPsduMap & psdus, WifiTxVector txVector, Time ppduDuration)
{
NS_LOG_FUNCTION (this << psdus << txVector << ppduDuration);
HePpdu::TxPsdFlag flag = (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB) ?
HePpdu::PSD_HE_TB_NON_OFDMA_PORTION :
HePpdu::PSD_NON_HE_TB;
return Create<HePpdu> (psdus, txVector, ppduDuration, m_wifiPhy->GetPhyBand (),
ObtainNextUid (txVector));
ObtainNextUid (txVector), flag);
}
void
HePhy::StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxPowersW,
Time rxDuration, TxPsdFlag psdFlag)
Time rxDuration)
{
NS_LOG_FUNCTION (this << ppdu << rxDuration << psdFlag);
NS_LOG_FUNCTION (this << ppdu << rxDuration);
WifiTxVector txVector = ppdu->GetTxVector ();
auto hePpdu = DynamicCast<HePpdu> (ppdu);
NS_ASSERT (hePpdu);
HePpdu::TxPsdFlag psdFlag = hePpdu->GetTxPsdFlag ();
if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB
&& psdFlag == PSD_HE_TB_OFDMA_PORTION)
&& psdFlag == HePpdu::PSD_HE_TB_OFDMA_PORTION)
{
if (m_currentHeTbPpduUid == ppdu->GetUid ()
&& GetCurrentEvent () != 0)
@@ -344,7 +350,7 @@ HePhy::StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxPow
}
else
{
PhyEntity::StartReceivePreamble (ppdu, rxPowersW, rxDuration, psdFlag);
PhyEntity::StartReceivePreamble (ppdu, rxPowersW, rxDuration);
}
}

View File

@@ -74,7 +74,7 @@ public:
virtual Ptr<WifiPpdu> BuildPpdu (const WifiConstPsduMap & psdus, WifiTxVector txVector, Time ppduDuration) override;
Ptr<const WifiPsdu> GetAddressedPsduInPpdu (Ptr<const WifiPpdu> ppdu) const override;
void StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxPowersW,
Time rxDuration, TxPsdFlag psdFlag) override;
Time rxDuration) override;
void CancelAllEvents (void) override;
virtual uint16_t GetStaId (const Ptr<const WifiPpdu> ppdu) const override;
uint16_t GetMeasurementChannelWidth (const Ptr<const WifiPpdu> ppdu) const override;

View File

@@ -31,11 +31,27 @@ namespace ns3 {
NS_LOG_COMPONENT_DEFINE ("HePpdu");
std::ostream& operator<< (std::ostream& os, const HePpdu::TxPsdFlag &flag)
{
switch (flag)
{
case HePpdu::PSD_NON_HE_TB:
return (os << "PSD_NON_HE_TB");
case HePpdu::PSD_HE_TB_NON_OFDMA_PORTION:
return (os << "PSD_HE_TB_NON_OFDMA_PORTION");
case HePpdu::PSD_HE_TB_OFDMA_PORTION:
return (os << "PSD_HE_TB_OFDMA_PORTION");
default:
NS_FATAL_ERROR ("Invalid PSD flag");
return (os << "INVALID");
}
}
HePpdu::HePpdu (const WifiConstPsduMap & psdus, WifiTxVector txVector, Time ppduDuration,
WifiPhyBand band, uint64_t uid)
WifiPhyBand band, uint64_t uid, TxPsdFlag flag)
: OfdmPpdu (psdus.begin ()->second, txVector, band, uid, false) //don't instantiate LSigHeader of OfdmPpdu
{
NS_LOG_FUNCTION (this << psdus << txVector << ppduDuration << band << uid);
NS_LOG_FUNCTION (this << psdus << txVector << ppduDuration << band << uid << flag);
//overwrite with map (since only first element used by OfdmPpdu)
m_psdus.begin ()->second = 0;
@@ -47,6 +63,7 @@ HePpdu::HePpdu (const WifiConstPsduMap & psdus, WifiTxVector txVector, Time ppdu
}
SetPhyHeaders (txVector, ppduDuration);
SetTxPsdFlag (flag);
}
HePpdu::HePpdu (Ptr<const WifiPsdu> psdu, WifiTxVector txVector, Time ppduDuration,
@@ -56,6 +73,7 @@ HePpdu::HePpdu (Ptr<const WifiPsdu> psdu, WifiTxVector txVector, Time ppduDurati
NS_LOG_FUNCTION (this << psdu << txVector << ppduDuration << band << uid);
NS_ASSERT (!IsMu ());
SetPhyHeaders (txVector, ppduDuration);
SetTxPsdFlag (PSD_NON_HE_TB);
}
HePpdu::~HePpdu ()
@@ -141,7 +159,7 @@ HePpdu::GetTxDuration (void) const
Ptr<WifiPpdu>
HePpdu::Copy (void) const
{
return Create<HePpdu> (m_psdus, GetTxVector (), GetTxDuration (), m_band, m_uid);
return Create<HePpdu> (m_psdus, GetTxVector (), GetTxDuration (), m_band, m_uid, m_txPsdFlag);
}
WifiPpduType
@@ -213,6 +231,19 @@ HePpdu::GetStaId (void) const
return m_psdus.begin ()->first;
}
HePpdu::TxPsdFlag
HePpdu::GetTxPsdFlag (void) const
{
return m_txPsdFlag;
}
void
HePpdu::SetTxPsdFlag (TxPsdFlag flag)
{
NS_LOG_FUNCTION (this << flag);
NS_ASSERT ((IsUlMu () && flag > PSD_NON_HE_TB) || (!IsUlMu () && flag == PSD_NON_HE_TB));
m_txPsdFlag = flag;
}
std::string
HePpdu::PrintPayload (void) const
@@ -221,6 +252,7 @@ HePpdu::PrintPayload (void) const
if (IsMu ())
{
ss << m_psdus;
ss << ", " << m_txPsdFlag;
}
else
{

View File

@@ -151,6 +151,18 @@ public:
bool m_mu;
}; //class HeSigHeader
/**
* The transmit power spectral density flag, namely used
* to correctly build PSD for HE TB PPDU non-OFDMA and
* OFDMA portions.
*/
enum TxPsdFlag
{
PSD_NON_HE_TB = 0, //!< non-HE TB PPDU transmissions
PSD_HE_TB_NON_OFDMA_PORTION, //!< preamble of HE TB PPDU, which should only be sent on minimum subset of 20 MHz channels containing RU
PSD_HE_TB_OFDMA_PORTION //!< OFDMA portion of HE TB PPDU, which should only be sent on RU
};
/**
* Create an SU HE PPDU, storing a PSDU.
*
@@ -172,9 +184,10 @@ public:
* \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 HE TB PPDU
* \param flag the flag indicating the type of Tx PSD to build
*/
HePpdu (const WifiConstPsduMap & psdus, WifiTxVector txVector, Time ppduDuration,
WifiPhyBand band, uint64_t uid);
WifiPhyBand band, uint64_t uid, TxPsdFlag flag);
/**
* Destructor for HePpdu.
*/
@@ -195,6 +208,20 @@ public:
*/
Ptr<const WifiPsdu> GetPsdu (uint8_t bssColor, uint16_t staId = SU_STA_ID) const;
/**
* \return the transmit PSD flag set for this PPDU
*
* \see TxPsdFlag
*/
TxPsdFlag GetTxPsdFlag (void) const;
/**
* \param flag the transmit PSD flag set for this PPDU
*
* \see TxPsdFlag
*/
void SetTxPsdFlag (TxPsdFlag flag);
protected:
// Inherited
std::string PrintPayload (void) const override;
@@ -229,9 +256,19 @@ private:
*/
void SetPhyHeaders (WifiTxVector txVector, Time ppduDuration);
HeSigHeader m_heSig; //!< the HE-SIG PHY header
HeSigHeader m_heSig; //!< the HE-SIG PHY header
TxPsdFlag m_txPsdFlag; //!< the transmit power spectral density flag
}; //class HePpdu
/**
* \brief Stream insertion operator.
*
* \param os the stream
* \param flag the transmit power spectral density flag
* \returns a reference to the stream
*/
std::ostream& operator<< (std::ostream& os, const HePpdu::TxPsdFlag &flag);
} //namespace ns3
#endif /* HE_PPDU_H */

View File

@@ -353,7 +353,7 @@ PhyEntity::DoEndReceiveField (WifiPpduField field, Ptr<Event> event)
void
PhyEntity::StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxPowersW,
Time /* rxDuration */, TxPsdFlag /* psdFlag */)
Time /* rxDuration */)
{
//The total RX power corresponds to the maximum over all the bands
auto it = std::max_element (rxPowersW.begin (), rxPowersW.end (),

View File

@@ -27,7 +27,6 @@
#include "wifi-tx-vector.h"
#include "wifi-phy-band.h"
#include "wifi-ppdu.h"
#include "wifi-spectrum-signal-parameters.h"
#include "wifi-mpdu-type.h"
#include "wifi-ppdu.h"
#include "ns3/event-id.h"
@@ -346,10 +345,9 @@ public:
* \param ppdu the arriving PPDU
* \param rxPowersW the receive power in W per band
* \param rxDuration the duration of the PPDU
* \param psdFlag the flag indicating the type of Tx PSD to build
*/
virtual void StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxPowersW,
Time rxDuration, TxPsdFlag psdFlag);
Time rxDuration);
/**
* Start receiving a given field.
*

View File

@@ -31,6 +31,7 @@
#include "ns3/simulator.h"
#include "spectrum-wifi-phy.h"
#include "wifi-spectrum-phy-interface.h"
#include "wifi-spectrum-signal-parameters.h"
#include "wifi-utils.h"
#include "he-ppdu.h" //TODO: remove this once code ported to HePhy
#include "wifi-psdu.h"
@@ -360,7 +361,7 @@ SpectrumWifiPhy::StartRx (Ptr<SpectrumSignalParameters> rxParams)
NS_LOG_INFO ("Received Wi-Fi signal");
Ptr<WifiPpdu> ppdu = wifiRxParams->ppdu->Copy ();
StartReceivePreamble (ppdu, rxPowerW, rxDuration, wifiRxParams->txPsdFlag);
StartReceivePreamble (ppdu, rxPowerW, rxDuration);
}
Ptr<AntennaModel>
@@ -386,12 +387,12 @@ SpectrumWifiPhy::CreateWifiSpectrumPhyInterface (Ptr<NetDevice> device)
}
Ptr<SpectrumValue>
SpectrumWifiPhy::GetTxPowerSpectralDensity (double txPowerW, Ptr<WifiPpdu> ppdu, TxPsdFlag flag /* = PSD_NON_HE_TB */)
SpectrumWifiPhy::GetTxPowerSpectralDensity (double txPowerW, Ptr<WifiPpdu> ppdu)
{
WifiTxVector txVector = ppdu->GetTxVector ();
uint16_t centerFrequency = GetCenterFrequencyForChannelWidth (txVector);
uint16_t channelWidth = txVector.GetChannelWidth ();
NS_LOG_FUNCTION (centerFrequency << channelWidth << txPowerW << flag);
NS_LOG_FUNCTION (centerFrequency << channelWidth << txPowerW);
Ptr<SpectrumValue> v;
switch (ppdu->GetModulation ())
{
@@ -411,26 +412,31 @@ SpectrumWifiPhy::GetTxPowerSpectralDensity (double txPowerW, Ptr<WifiPpdu> ppdu,
m_txMaskInnerBandMinimumRejection, m_txMaskOuterBandMinimumRejection, m_txMaskOuterBandMaximumRejection);
break;
case WIFI_MOD_CLASS_HE:
if (flag == PSD_HE_TB_OFDMA_PORTION)
{
//TODO Move this to HePhy
const auto hePhy = DynamicCast<HePhy> (GetPhyEntity (WIFI_MOD_CLASS_HE));
WifiSpectrumBand band = hePhy->GetRuBand (txVector, hePhy->GetStaId (ppdu));
v = WifiSpectrumValueHelper::CreateHeMuOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerW, GetGuardBandwidth (channelWidth), band);
}
else
{
if (flag == PSD_HE_TB_NON_OFDMA_PORTION)
{
//non-OFDMA portion is sent only on the 20 MHz channels covering the RU
uint16_t staId = GetPhyEntity (WIFI_MOD_CLASS_HE)->GetStaId (ppdu);
centerFrequency = GetCenterFrequencyForNonOfdmaPart (txVector, staId);
uint16_t ruWidth = HeRu::GetBandwidth (txVector.GetRu (staId).ruType);
channelWidth = ruWidth < 20 ? 20 : ruWidth;
}
v = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerW, GetGuardBandwidth (channelWidth),
m_txMaskInnerBandMinimumRejection, m_txMaskOuterBandMinimumRejection, m_txMaskOuterBandMaximumRejection);
}
{
//TODO: Move this to HePhy
auto hePpdu = DynamicCast<HePpdu> (ppdu);
NS_ASSERT (hePpdu);
HePpdu::TxPsdFlag flag = hePpdu->GetTxPsdFlag ();
if (flag == HePpdu::PSD_HE_TB_OFDMA_PORTION)
{
const auto hePhy = DynamicCast<HePhy> (GetPhyEntity (WIFI_MOD_CLASS_HE));
WifiSpectrumBand band = hePhy->GetRuBand (txVector, hePhy->GetStaId (ppdu));
v = WifiSpectrumValueHelper::CreateHeMuOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerW, GetGuardBandwidth (channelWidth), band);
}
else
{
if (flag == HePpdu::PSD_HE_TB_NON_OFDMA_PORTION)
{
//non-OFDMA portion is sent only on the 20 MHz channels covering the RU
uint16_t staId = GetPhyEntity (WIFI_MOD_CLASS_HE)->GetStaId (ppdu);
centerFrequency = GetCenterFrequencyForNonOfdmaPart (txVector, staId);
uint16_t ruWidth = HeRu::GetBandwidth (txVector.GetRu (staId).ruType);
channelWidth = ruWidth < 20 ? 20 : ruWidth;
}
v = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerW, GetGuardBandwidth (channelWidth),
m_txMaskInnerBandMinimumRejection, m_txMaskOuterBandMinimumRejection, m_txMaskOuterBandMaximumRejection);
}
}
break;
default:
NS_FATAL_ERROR ("modulation class unknown");
@@ -458,6 +464,7 @@ uint16_t
SpectrumWifiPhy::GetCenterFrequencyForNonOfdmaPart (WifiTxVector txVector, uint16_t staId) const
{
NS_LOG_FUNCTION (this << txVector << staId);
//TODO Move this to HePhy
NS_ASSERT (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB);
uint16_t centerFrequency = GetCenterFrequencyForChannelWidth (txVector);
uint16_t currentWidth = txVector.GetChannelWidth ();
@@ -485,32 +492,32 @@ SpectrumWifiPhy::StartTx (Ptr<WifiPpdu> ppdu, uint8_t txPowerLevel)
NS_ASSERT_MSG (m_wifiSpectrumPhyInterface, "SpectrumPhy() is not set; maybe forgot to call CreateWifiSpectrumPhyInterface?");
if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB)
{
double txPowerWatts = DbmToW (GetTxPowerForTransmission (txVector, ppdu->GetStaId (), PSD_HE_TB_NON_OFDMA_PORTION) + GetTxGain ()); //enforce power density limit on non-OFDMA part
//TODO Move this to HePhy
double txPowerWatts = DbmToW (GetTxPowerForTransmission (ppdu) + GetTxGain ()); //enforce power density limit on non-OFDMA part
NS_LOG_DEBUG ("Start transmission: signal power before antenna gain=" << WToDbm (txPowerWatts) << "dBm");
//non-OFDMA part
//TODO Move this to HePhy
auto hePhy = DynamicCast<const HePhy> (GetPhyEntity (txVector.GetModulationClass ()));
Time nonOfdmaDuration = hePhy->CalculateNonOfdmaDurationForHeTb (txVector);
Ptr<SpectrumValue> txPowerSpectrum = GetTxPowerSpectralDensity (txPowerWatts, ppdu, PSD_HE_TB_NON_OFDMA_PORTION);
Ptr<SpectrumValue> txPowerSpectrum = GetTxPowerSpectralDensity (txPowerWatts, ppdu);
Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
txParams->duration = nonOfdmaDuration;
txParams->psd = txPowerSpectrum;
txParams->txPhy = m_wifiSpectrumPhyInterface->GetObject<SpectrumPhy> ();
txParams->txAntenna = m_antenna;
txParams->ppdu = ppdu;
txParams->txPsdFlag = PSD_HE_TB_NON_OFDMA_PORTION;
NS_LOG_DEBUG ("Starting non-OFDMA transmission with power " << WToDbm (txPowerWatts) << " dBm on channel " << +GetChannelNumber () << " for " << txParams->duration.GetMicroSeconds () << " us");
NS_LOG_DEBUG ("Starting non-OFDMA transmission with integrated spectrum power " << WToDbm (Integral (*txPowerSpectrum)) << " dBm; spectrum model Uid: " << txPowerSpectrum->GetSpectrumModel ()->GetUid ());
Transmit (txParams);
//OFDMA part
txPowerWatts = DbmToW (GetTxPowerForTransmission (txVector, ppdu->GetStaId (), PSD_HE_TB_OFDMA_PORTION) + GetTxGain ()); //enforce power density limit since transmission bandwidth of RU is potentially narrower than total PPDU bandwidth
Simulator::Schedule (nonOfdmaDuration, &SpectrumWifiPhy::StartOfdmaTx, this, ppdu, txPowerWatts);
auto hePpdu = DynamicCast<HePpdu> (ppdu);
NS_ASSERT (hePpdu);
Simulator::Schedule (nonOfdmaDuration, &SpectrumWifiPhy::StartOfdmaTx, this, hePpdu);
}
else
{
double txPowerWatts = DbmToW (GetTxPowerForTransmission (txVector) + GetTxGain ());
double txPowerWatts = DbmToW (GetTxPowerForTransmission (ppdu) + GetTxGain ());
NS_LOG_DEBUG ("Start transmission: signal power before antenna gain=" << WToDbm (txPowerWatts) << "dBm");
Ptr<SpectrumValue> txPowerSpectrum = GetTxPowerSpectralDensity (txPowerWatts, ppdu);
Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
@@ -526,22 +533,23 @@ SpectrumWifiPhy::StartTx (Ptr<WifiPpdu> ppdu, uint8_t txPowerLevel)
}
void
SpectrumWifiPhy::StartOfdmaTx (Ptr<WifiPpdu> ppdu, double txPowerWatts)
SpectrumWifiPhy::StartOfdmaTx (Ptr<HePpdu> ppdu)
{
NS_LOG_FUNCTION (this << ppdu << txPowerWatts);
NS_LOG_FUNCTION (this << ppdu);
//TODO: Move this to HePhy
NS_ASSERT (DynamicCast<HePpdu> (ppdu)->GetType () == WIFI_PPDU_TYPE_UL_MU);
Ptr<SpectrumValue> txPowerSpectrum = GetTxPowerSpectralDensity (txPowerWatts, ppdu, PSD_HE_TB_OFDMA_PORTION);
NS_ASSERT (ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU);
ppdu->SetTxPsdFlag (HePpdu::PSD_HE_TB_OFDMA_PORTION);
double txPowerWatts = DbmToW (GetTxPowerForTransmission (ppdu) + GetTxGain ()); //enforce power density limit since transmission bandwidth of RU is potentially narrower than total PPDU bandwidth
Ptr<SpectrumValue> txPowerSpectrum = GetTxPowerSpectralDensity (txPowerWatts, ppdu);
Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
WifiTxVector txVector = ppdu->GetTxVector ();
//TODO Move this to HePhy
auto hePhy = DynamicCast<const HePhy> (GetPhyEntity (txVector.GetModulationClass ()));
txParams->duration = ppdu->GetTxDuration () - hePhy->CalculateNonOfdmaDurationForHeTb (txVector);
txParams->psd = txPowerSpectrum;
txParams->txPhy = m_wifiSpectrumPhyInterface->GetObject<SpectrumPhy> ();
txParams->txAntenna = m_antenna;
txParams->ppdu = ppdu;
txParams->txPsdFlag = PSD_HE_TB_OFDMA_PORTION;
NS_LOG_DEBUG ("Starting OFDMA transmission with power " << WToDbm (txPowerWatts) << " dBm on channel " << +GetChannelNumber () << " for " << txParams->duration.GetMicroSeconds () << " us");
NS_LOG_DEBUG ("Starting OFDMA transmission with integrated spectrum power " << WToDbm (Integral (*txPowerSpectrum)) << " dBm; spectrum model Uid: " << txPowerSpectrum->GetSpectrumModel ()->GetUid ());
Transmit (txParams);

View File

@@ -35,7 +35,8 @@
namespace ns3 {
class WifiSpectrumPhyInterface;
class WifiPpdu;
struct WifiSpectrumSignalParameters;
class HePpdu; //TODO revert to WifiPpdu once Tx refactoring is finished
/**
* \brief 802.11 PHY layer model
@@ -191,13 +192,12 @@ private:
/**
* \param txPowerW power in W to spread across the bands
* \param ppdu the PPDU that will be transmitted
* \param flag flag indicating the type of Tx PSD to build
* \return Pointer to SpectrumValue
*
* This is a helper function to create the right TX PSD corresponding
* to the standard in use.
*/
Ptr<SpectrumValue> GetTxPowerSpectralDensity (double txPowerW, Ptr<WifiPpdu> ppdu, TxPsdFlag flag = PSD_NON_HE_TB);
Ptr<SpectrumValue> GetTxPowerSpectralDensity (double txPowerW, Ptr<WifiPpdu> ppdu);
/**
* \param channelWidth the total channel width (MHz) used for the OFDMA transmission
@@ -211,10 +211,9 @@ private:
/**
* This function is called to send the OFDMA part of a PPDU.
*
* \param ppdu the PPDU to send
* \param txPowerWatts the transmit power in watts
* \param ppdu the HE PPDU to send
*/
void StartOfdmaTx (Ptr<WifiPpdu> ppdu, double txPowerWatts);
void StartOfdmaTx (Ptr<HePpdu> ppdu);
/**
* This function is sending the signal to the Spectrum channel

View File

@@ -44,6 +44,7 @@
#include "dsss-phy.h"
#include "erp-ofdm-phy.h"
#include "he-phy.h" //includes OFDM, HT, and VHT
#include "he-ppdu.h" //TODO: remove this once code ported to HePhy
namespace ns3 {
@@ -2105,7 +2106,10 @@ WifiPhy::Send (WifiConstPsduMap psdus, WifiTxVector txVector)
return;
}
double txPowerW = DbmToW (GetTxPowerForTransmission (txVector) + GetTxGain ());
Ptr<WifiPpdu> ppdu = GetPhyEntity (txVector.GetModulationClass ())->BuildPpdu (psdus, txVector, txDuration);
m_previouslyRxPpduUid = UINT64_MAX; //reset (after creation of PPDU) to use it only once
double txPowerW = DbmToW (GetTxPowerForTransmission (ppdu) + GetTxGain ());
NotifyTxBegin (psdus, txPowerW);
m_phyTxPsduBeginTrace (psdus, txVector, txPowerW);
for (auto const& psdu : psdus)
@@ -2114,9 +2118,6 @@ WifiPhy::Send (WifiConstPsduMap psdus, WifiTxVector txVector)
}
m_state->SwitchToTx (txDuration, psdus, GetPowerDbm (txVector.GetTxPowerLevel ()), txVector);
Ptr<WifiPpdu> ppdu = GetPhyEntity (txVector.GetModulationClass ())->BuildPpdu (psdus, txVector, txDuration);
m_previouslyRxPpduUid = UINT64_MAX; //reset (after creation of PPDU) to use it only once
if (m_wifiRadioEnergyModel != 0 && m_wifiRadioEnergyModel->GetMaximumTimeInState (WifiPhyState::TX) < txDuration)
{
ppdu->SetTruncatedTx ();
@@ -2151,14 +2152,13 @@ WifiPhy::Reset (void)
}
void
WifiPhy::StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxPowersW,
Time rxDuration, TxPsdFlag psdFlag /* = PSD_NON_HE_TB */)
WifiPhy::StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxPowersW, Time rxDuration)
{
WifiModulationClass modulation = ppdu->GetTxVector ().GetModulationClass ();
auto it = m_phyEntities.find (modulation);
if (it != m_phyEntities.end ())
{
it->second->StartReceivePreamble (ppdu, rxPowersW, rxDuration, psdFlag);
it->second->StartReceivePreamble (ppdu, rxPowersW, rxDuration);
}
else
{
@@ -2480,9 +2480,10 @@ WifiPhy::ResetCca (bool powerRestricted, double txPowerMaxSiso, double txPowerMa
}
double
WifiPhy::GetTxPowerForTransmission (WifiTxVector txVector, uint16_t staId /* = SU_STA_ID */, TxPsdFlag flag /* = PSD_NON_HE_TB */) const
WifiPhy::GetTxPowerForTransmission (Ptr<const WifiPpdu> ppdu) const
{
NS_LOG_FUNCTION (this << m_powerRestricted << txVector << staId << flag);
NS_LOG_FUNCTION (this << m_powerRestricted << ppdu);
WifiTxVector txVector = ppdu->GetTxVector ();
// Get transmit power before antenna gain
double txPowerDbm;
if (!m_powerRestricted)
@@ -2503,17 +2504,21 @@ WifiPhy::GetTxPowerForTransmission (WifiTxVector txVector, uint16_t staId /* = S
//Apply power density constraint on EIRP
uint16_t channelWidth = txVector.GetChannelWidth ();
if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB && staId != SU_STA_ID)
//TODO: Move to HePhy
if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB && ppdu->GetStaId () != SU_STA_ID)
{
NS_ASSERT (flag > PSD_NON_HE_TB);
uint16_t ruWidth = HeRu::GetBandwidth (txVector.GetRu (staId).ruType);
channelWidth = (flag == PSD_HE_TB_NON_OFDMA_PORTION && ruWidth < 20) ? 20 : ruWidth;
NS_LOG_INFO ("Use channelWidth=" << channelWidth << " MHz for HE TB from " << staId << " for " << flag);
auto hePpdu = DynamicCast<const HePpdu> (ppdu);
NS_ASSERT (hePpdu);
HePpdu::TxPsdFlag flag = hePpdu->GetTxPsdFlag ();
NS_ASSERT (flag > HePpdu::PSD_NON_HE_TB);
uint16_t ruWidth = HeRu::GetBandwidth (txVector.GetRu (ppdu->GetStaId ()).ruType);
channelWidth = (flag == HePpdu::PSD_HE_TB_NON_OFDMA_PORTION && ruWidth < 20) ? 20 : ruWidth;
NS_LOG_INFO ("Use channelWidth=" << channelWidth << " MHz for HE TB from " << ppdu->GetStaId () << " for " << flag);
}
double txPowerDbmPerMhz = (txPowerDbm + GetTxGain ()) - RatioToDb (channelWidth); //account for antenna gain since EIRP
NS_LOG_INFO ("txPowerDbm=" << txPowerDbm << " with txPowerDbmPerMhz=" << txPowerDbmPerMhz << " over " << channelWidth << " MHz");
txPowerDbm = std::min (txPowerDbmPerMhz, m_powerDensityLimit) + RatioToDb (channelWidth);
txPowerDbm -= GetTxGain(); //remove antenna gain since will be added right afterwards
txPowerDbm -= GetTxGain (); //remove antenna gain since will be added right afterwards
NS_LOG_INFO ("txPowerDbm=" << txPowerDbm << " after applying m_powerDensityLimit=" << m_powerDensityLimit);
return txPowerDbm;
}

View File

@@ -121,10 +121,8 @@ public:
* \param ppdu the arriving PPDU
* \param rxPowersW the receive power in W per band
* \param rxDuration the duration of the PPDU
* \param psdFlag the flag indicating the type of Tx PSD to build
*/
void StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxPowersW,
Time rxDuration, TxPsdFlag psdFlag = PSD_NON_HE_TB);
void StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxPowersW, Time rxDuration);
/**
* Reset PHY at the end of the packet under reception after it has failed the PHY header.
@@ -969,12 +967,10 @@ public:
* The returned power will satisfy the power density constraints
* after addition of antenna gain.
*
* \param txVector the TXVECTOR
* \param staId the STA-ID of the transmitting station, only applicable for HE TB PPDU
* \param flag flag indicating the type of Tx PSD to build
* \param ppdu the PPDU to transmit
* \return the transmit power in dBm for the next transmission
*/
double GetTxPowerForTransmission (WifiTxVector txVector, uint16_t staId = SU_STA_ID, TxPsdFlag flag = PSD_NON_HE_TB) const;
double GetTxPowerForTransmission (Ptr<const WifiPpdu> ppdu) const;
/**
* Notify the PHY that an access to the channel was requested.
* This is typically called by the channel access manager to

View File

@@ -37,7 +37,6 @@ WifiSpectrumSignalParameters::WifiSpectrumSignalParameters (const WifiSpectrumSi
{
NS_LOG_FUNCTION (this << &p);
ppdu = p.ppdu;
txPsdFlag = p.txPsdFlag;
}
Ptr<SpectrumSignalParameters>

View File

@@ -28,44 +28,6 @@ namespace ns3 {
class WifiPpdu;
/**
* \ingroup wifi
*
* The transmit power spectral density flag, namely used
* to correctly build PSD for HE TB PPDU non-OFDMA and
* OFDMA portions.
*/
enum TxPsdFlag
{
PSD_NON_HE_TB = 0, //!< non-HE TB PPDU transmissions
PSD_HE_TB_NON_OFDMA_PORTION, //!< preamble of HE TB PPDU, which should only be sent on minimum subset of 20 MHz channels containing RU
PSD_HE_TB_OFDMA_PORTION //!< OFDMA portion of HE TB PPDU, which should only be sent on RU
};
/**
* \brief Stream insertion operator.
*
* \param os the stream
* \param flag the transmit power spectral density flag
* \returns a reference to the stream
*/
inline std::ostream& operator<< (std::ostream& os, TxPsdFlag flag)
{
switch (flag)
{
case PSD_NON_HE_TB:
return (os << "PSD_NON_HE_TB");
case PSD_HE_TB_NON_OFDMA_PORTION:
return (os << "PSD_HE_TB_NON_OFDMA_PORTION");
case PSD_HE_TB_OFDMA_PORTION:
return (os << "PSD_HE_TB_OFDMA_PORTION");
default:
NS_FATAL_ERROR ("Invalid PSD flag");
return (os << "INVALID");
}
}
/**
* \ingroup wifi
*
@@ -90,7 +52,6 @@ struct WifiSpectrumSignalParameters : public SpectrumSignalParameters
WifiSpectrumSignalParameters (const WifiSpectrumSignalParameters& p);
Ptr<WifiPpdu> ppdu; ///< The PPDU being transmitted
TxPsdFlag txPsdFlag {PSD_NON_HE_TB}; ///< The transmit power spectral density flag
};
} // namespace ns3

View File

@@ -86,7 +86,7 @@ YansWifiPhy::StartTx (Ptr<WifiPpdu> ppdu, uint8_t txPowerLevel)
WifiTxVector txVector = ppdu->GetTxVector ();
txVector.SetTxPowerLevel (txPowerLevel);
NS_LOG_DEBUG ("Start transmission: signal power before antenna gain=" << GetPowerDbm (txVector.GetTxPowerLevel ()) << "dBm");
m_channel->Send (this, ppdu, GetTxPowerForTransmission (txVector) + GetTxGain ());
m_channel->Send (this, ppdu, GetTxPowerForTransmission (ppdu) + GetTxGain ());
}
} //namespace ns3

View File

@@ -1447,7 +1447,8 @@ TestMultipleHeTbPreambles::RxHeTbPpdu (uint64_t uid, uint16_t staId, double txPo
psdus.insert (std::make_pair (staId, psdu));
Time ppduDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand (), staId);
Ptr<WifiPpdu> ppdu = Create<HePpdu> (psdus, txVector, ppduDuration, WIFI_PHY_BAND_5GHZ, uid);
Ptr<HePpdu> ppdu = Create<HePpdu> (psdus, txVector, ppduDuration, WIFI_PHY_BAND_5GHZ, uid,
HePpdu::PSD_HE_TB_NON_OFDMA_PORTION);
//Send non-OFDMA part
Time nonOfdmaDuration = m_phy->GetHePhy ()->CalculateNonOfdmaDurationForHeTb (txVector);
@@ -1460,11 +1461,11 @@ TestMultipleHeTbPreambles::RxHeTbPpdu (uint64_t uid, uint16_t staId, double txPo
rxParams->txPhy = 0;
rxParams->duration = nonOfdmaDuration;
rxParams->ppdu = ppdu;
rxParams->txPsdFlag = PSD_HE_TB_NON_OFDMA_PORTION;
m_phy->StartRx (rxParams);
//Schedule OFDMA part
ppdu->SetTxPsdFlag (HePpdu::PSD_HE_TB_OFDMA_PORTION);
WifiSpectrumBand band = m_phy->GetHePhy ()->GetRuBand (txVector, staId);
Ptr<SpectrumValue> rxPsdOfdma = WifiSpectrumValueHelper::CreateHeMuOfdmTxPowerSpectralDensity (DEFAULT_FREQUENCY, DEFAULT_CHANNEL_WIDTH, txPowerWatts, DEFAULT_GUARD_WIDTH, band);
Ptr<WifiSpectrumSignalParameters> rxParamsOfdma = Create<WifiSpectrumSignalParameters> ();
@@ -1472,7 +1473,6 @@ TestMultipleHeTbPreambles::RxHeTbPpdu (uint64_t uid, uint16_t staId, double txPo
rxParamsOfdma->txPhy = 0;
rxParamsOfdma->duration = ppduDuration - nonOfdmaDuration;
rxParamsOfdma->ppdu = ppdu;
rxParamsOfdma->txPsdFlag = PSD_HE_TB_OFDMA_PORTION;
Simulator::Schedule (nonOfdmaDuration, &TestMultipleHeTbPreambles::RxHeTbPpduOfdmaPart, this, rxParamsOfdma);
}