wifi: Split non-OFDMA and OFDMA in two TX events for HE TB PPDUs
This commit is contained in:
@@ -28,11 +28,14 @@
|
||||
#include "ns3/boolean.h"
|
||||
#include "ns3/net-device.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "spectrum-wifi-phy.h"
|
||||
#include "wifi-spectrum-phy-interface.h"
|
||||
#include "wifi-utils.h"
|
||||
#include "wifi-ppdu.h"
|
||||
#include "wifi-psdu.h"
|
||||
#include "ap-wifi-mac.h"
|
||||
#include "wifi-net-device.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -356,7 +359,26 @@ SpectrumWifiPhy::StartRx (Ptr<SpectrumSignalParameters> rxParams)
|
||||
|
||||
NS_LOG_INFO ("Received Wi-Fi signal");
|
||||
Ptr<WifiPpdu> ppdu = Copy (wifiRxParams->ppdu);
|
||||
StartReceivePreamble (ppdu, rxPowerW);
|
||||
if (ppdu->GetTxVector ().GetPreambleType () == WIFI_PREAMBLE_HE_TB
|
||||
&& wifiRxParams->txPsdFlag == PSD_HE_TB_OFDMA_PORTION
|
||||
&& m_currentHeTbPpduUid == ppdu->GetUid ())
|
||||
{
|
||||
Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (GetDevice ());
|
||||
bool isAp = (DynamicCast<ApWifiMac> (device->GetMac ()) != 0);
|
||||
if (isAp)
|
||||
{
|
||||
StartReceiveOfdmaPayload (ppdu, rxPowerW);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_INFO ("Ignore UL-OFDMA since device is not AP");
|
||||
m_currentPreambleEvents.clear ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
StartReceivePreamble (ppdu, rxPowerW);
|
||||
}
|
||||
}
|
||||
|
||||
Ptr<AntennaModel>
|
||||
@@ -382,7 +404,7 @@ SpectrumWifiPhy::CreateWifiSpectrumPhyInterface (Ptr<NetDevice> device)
|
||||
}
|
||||
|
||||
Ptr<SpectrumValue>
|
||||
SpectrumWifiPhy::GetTxPowerSpectralDensity (double txPowerW, Ptr<WifiPpdu> ppdu)
|
||||
SpectrumWifiPhy::GetTxPowerSpectralDensity (double txPowerW, Ptr<WifiPpdu> ppdu, bool isOfdma)
|
||||
{
|
||||
WifiTxVector txVector = ppdu->GetTxVector ();
|
||||
uint16_t centerFrequency = GetCenterFrequencyForChannelWidth (txVector);
|
||||
@@ -407,7 +429,7 @@ SpectrumWifiPhy::GetTxPowerSpectralDensity (double txPowerW, Ptr<WifiPpdu> ppdu)
|
||||
m_txMaskInnerBandMinimumRejection, m_txMaskOuterBandMinimumRejection, m_txMaskOuterBandMaximumRejection);
|
||||
break;
|
||||
case WIFI_MOD_CLASS_HE:
|
||||
if (ppdu->IsUlMu ())
|
||||
if (isOfdma)
|
||||
{
|
||||
WifiSpectrumBand band = GetRuBand (txVector, GetStaId (ppdu));
|
||||
v = WifiSpectrumValueHelper::CreateHeMuOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerW, GetGuardBandwidth (channelWidth), band);
|
||||
@@ -448,16 +470,64 @@ SpectrumWifiPhy::StartTx (Ptr<WifiPpdu> ppdu)
|
||||
double txPowerDbm = GetTxPowerForTransmission (txVector) + GetTxGain ();
|
||||
NS_LOG_DEBUG ("Start transmission: signal power before antenna gain=" << txPowerDbm << "dBm");
|
||||
double txPowerWatts = DbmToW (txPowerDbm);
|
||||
Ptr<SpectrumValue> txPowerSpectrum = GetTxPowerSpectralDensity (txPowerWatts, ppdu);
|
||||
Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
|
||||
txParams->duration = ppdu->GetTxDuration ();
|
||||
txParams->psd = txPowerSpectrum;
|
||||
NS_ASSERT_MSG (m_wifiSpectrumPhyInterface, "SpectrumPhy() is not set; maybe forgot to call CreateWifiSpectrumPhyInterface?");
|
||||
if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB)
|
||||
{
|
||||
//non-OFDMA part
|
||||
Time nonOfdmaDuration = CalculatePhyPreambleAndHeaderDuration (txVector); //consider that HE-STF and HE-LTFs are also part of the non-OFDMA part
|
||||
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
|
||||
Simulator::Schedule (nonOfdmaDuration, &SpectrumWifiPhy::StartOfdmaTx, this, ppdu, txPowerWatts);
|
||||
}
|
||||
else
|
||||
{
|
||||
Ptr<SpectrumValue> txPowerSpectrum = GetTxPowerSpectralDensity (txPowerWatts, ppdu);
|
||||
Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
|
||||
txParams->duration = ppdu->GetTxDuration ();
|
||||
txParams->psd = txPowerSpectrum;
|
||||
txParams->txPhy = m_wifiSpectrumPhyInterface->GetObject<SpectrumPhy> ();
|
||||
txParams->txAntenna = m_antenna;
|
||||
txParams->ppdu = ppdu;
|
||||
NS_LOG_DEBUG ("Starting transmission with power " << WToDbm (txPowerWatts) << " dBm on channel " << +GetChannelNumber () << " for " << txParams->duration.GetMicroSeconds () << " us");
|
||||
NS_LOG_DEBUG ("Starting transmission with integrated spectrum power " << WToDbm (Integral (*txPowerSpectrum)) << " dBm; spectrum model Uid: " << txPowerSpectrum->GetSpectrumModel ()->GetUid ());
|
||||
Transmit (txParams);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SpectrumWifiPhy::StartOfdmaTx (Ptr<WifiPpdu> ppdu, double txPowerWatts)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << ppdu << txPowerWatts);
|
||||
NS_ASSERT (ppdu->IsUlMu ());
|
||||
Ptr<SpectrumValue> txPowerSpectrum = GetTxPowerSpectralDensity (txPowerWatts, ppdu, true);
|
||||
Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
|
||||
WifiTxVector txVector = ppdu->GetTxVector ();
|
||||
txParams->duration = ppdu->GetTxDuration () - CalculatePhyPreambleAndHeaderDuration (txVector);
|
||||
txParams->psd = txPowerSpectrum;
|
||||
txParams->txPhy = m_wifiSpectrumPhyInterface->GetObject<SpectrumPhy> ();
|
||||
txParams->txAntenna = m_antenna;
|
||||
txParams->ppdu = ppdu;
|
||||
NS_LOG_DEBUG ("Starting transmission with power " << WToDbm (txPowerWatts) << " dBm on channel " << +GetChannelNumber ());
|
||||
NS_LOG_DEBUG ("Starting transmission with integrated spectrum power " << WToDbm (Integral (*txPowerSpectrum)) << " dBm; spectrum model Uid: " << txPowerSpectrum->GetSpectrumModel ()->GetUid ());
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
SpectrumWifiPhy::Transmit (Ptr<WifiSpectrumSignalParameters> txParams)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << txParams);
|
||||
m_channel->StartTx (txParams);
|
||||
}
|
||||
|
||||
|
||||
@@ -181,12 +181,13 @@ private:
|
||||
/**
|
||||
* \param txPowerW power in W to spread across the bands
|
||||
* \param ppdu the PPDU that will be transmitted
|
||||
* \param isOfdma flag whether the constructed Tx PSD is for the OFDMA part of an HE TB PPDU
|
||||
* \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);
|
||||
Ptr<SpectrumValue> GetTxPowerSpectralDensity (double txPowerW, Ptr<WifiPpdu> ppdu, bool isOfdma = false);
|
||||
|
||||
/**
|
||||
* \param channelWidth the total channel width (MHz) used for the OFDMA transmission
|
||||
@@ -197,6 +198,21 @@ private:
|
||||
*/
|
||||
WifiSpectrumBand ConvertHeRuSubcarriers (uint16_t channelWidth, HeRu::SubcarrierRange range) const;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
void StartOfdmaTx (Ptr<WifiPpdu> ppdu, double txPowerWatts);
|
||||
|
||||
/**
|
||||
* This function is sending the signal to the Spectrum channel
|
||||
*
|
||||
* \param txParams the parameters to be provided to the Spectrum channel
|
||||
*/
|
||||
void Transmit (Ptr<WifiSpectrumSignalParameters> txParams);
|
||||
|
||||
/**
|
||||
* Perform run-time spectrum model change
|
||||
*/
|
||||
|
||||
@@ -512,6 +512,7 @@ WifiPhy::WifiPhy ()
|
||||
m_endPhyRxEvent (),
|
||||
m_endTxEvent (),
|
||||
m_previouslyRxPpduUid (UINT64_MAX),
|
||||
m_currentHeTbPpduUid (UINT64_MAX),
|
||||
m_standard (WIFI_PHY_STANDARD_UNSPECIFIED),
|
||||
m_band (WIFI_PHY_BAND_UNSPECIFIED),
|
||||
m_isConstructed (false),
|
||||
@@ -2988,7 +2989,7 @@ WifiPhy::StartReceiveHeader (Ptr<Event> event)
|
||||
double snr = snrPer.snr;
|
||||
NS_LOG_DEBUG ("snr(dB)=" << RatioToDb (snrPer.snr));
|
||||
|
||||
Time headerPayloadDuration = m_currentEvent->GetDuration () - (Simulator::Now () - m_currentEvent->GetStartTime ()); //startOfPreambleDuration;
|
||||
Time headerPayloadDuration = m_currentEvent->GetStartTime () + m_currentEvent->GetPpdu ()->GetTxDuration () - Simulator::Now ();
|
||||
|
||||
if (!m_preambleDetectionModel || (m_preambleDetectionModel->IsPreambleDetected (m_currentEvent->GetRxPowerW (band), snr, m_channelWidth)))
|
||||
{
|
||||
@@ -3150,7 +3151,7 @@ WifiPhy::StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxP
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("Received a new HE TB PPDU for UID " << ppdu->GetUid () << " from STA-ID " << ppdu->GetStaId () << " and BSS color " << +txVector.GetBssColor ());
|
||||
event = m_interference.Add (ppdu, txVector, rxDuration, rxPowersW);
|
||||
event = m_interference.Add (ppdu, txVector, CalculatePhyPreambleAndHeaderDuration (txVector), rxPowersW); //the OFDMA part of the transmission will be added later on
|
||||
m_currentPreambleEvents.insert ({std::make_pair (ppdu->GetUid (), ppdu->GetPreamble ()), event});
|
||||
}
|
||||
}
|
||||
@@ -3293,6 +3294,24 @@ WifiPhy::MaybeCcaBusyDuration ()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WifiPhy::StartReceiveOfdmaPayload (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxPowersW)
|
||||
{
|
||||
//The total RX power corresponds to the maximum over all the bands
|
||||
auto it = std::max_element (rxPowersW.begin (), rxPowersW.end (),
|
||||
[] (const std::pair<WifiSpectrumBand, double>& p1, const std::pair<WifiSpectrumBand, double>& p2) {
|
||||
return p1.second < p2.second;
|
||||
});
|
||||
NS_LOG_FUNCTION (this << *ppdu << it->second);
|
||||
|
||||
WifiTxVector txVector = ppdu->GetTxVector ();
|
||||
Time payloadDuration = ppdu->GetTxDuration () - CalculatePhyPreambleAndHeaderDuration (txVector);
|
||||
Ptr<Event> event = m_interference.Add (ppdu, txVector, payloadDuration, rxPowersW);
|
||||
|
||||
NS_ASSERT (m_endRxEvent.IsExpired ());
|
||||
m_endRxEvent = Simulator::Schedule (payloadDuration, &WifiPhy::EndReceive, this, event);
|
||||
}
|
||||
|
||||
void
|
||||
WifiPhy::StartReceivePayload (Ptr<Event> event)
|
||||
{
|
||||
@@ -3317,7 +3336,7 @@ WifiPhy::StartReceivePayload (Ptr<Event> event)
|
||||
canReceivePayload = true;
|
||||
}
|
||||
WifiTxVector txVector = event->GetTxVector ();
|
||||
Time payloadDuration = event->GetEndTime () - event->GetStartTime () - CalculatePhyPreambleAndHeaderDuration (txVector);
|
||||
Time payloadDuration = ppdu->GetTxDuration () - CalculatePhyPreambleAndHeaderDuration (txVector);
|
||||
bool success = false;
|
||||
if (canReceivePayload) //PHY reception succeeded
|
||||
{
|
||||
@@ -3357,9 +3376,17 @@ WifiPhy::StartReceivePayload (Ptr<Event> event)
|
||||
}
|
||||
m_state->SwitchToRx (payloadDuration);
|
||||
m_phyRxPayloadBeginTrace (txVector, payloadDuration); //this callback (equivalent to PHY-RXSTART primitive) is triggered only if headers have been correctly decoded and that the mode within is supported
|
||||
m_endRxEvent = Simulator::Schedule (payloadDuration, &WifiPhy::EndReceive, this, event);
|
||||
success = true;
|
||||
NS_LOG_DEBUG ("Receiving PSDU");
|
||||
if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB)
|
||||
{
|
||||
m_currentHeTbPpduUid = ppdu->GetUid ();
|
||||
//EndReceive is scheduled by StartReceiveOfdmaPayload
|
||||
}
|
||||
else
|
||||
{
|
||||
m_endRxEvent = Simulator::Schedule (payloadDuration, &WifiPhy::EndReceive, this, event);
|
||||
}
|
||||
}
|
||||
else //mode is not allowed
|
||||
{
|
||||
|
||||
@@ -211,7 +211,7 @@ public:
|
||||
* Start receiving the PHY preamble of a PPDU (i.e. the first bit of the preamble has arrived).
|
||||
*
|
||||
* \param ppdu the arriving PPDU
|
||||
* \param rxPowersW the receive power in W per 20 MHz channel band
|
||||
* \param rxPowersW the receive power in W per band
|
||||
*/
|
||||
void StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxPowersW);
|
||||
|
||||
@@ -236,6 +236,15 @@ public:
|
||||
*/
|
||||
void StartReceivePayload (Ptr<Event> event);
|
||||
|
||||
/**
|
||||
* Start receiving the PSDU (i.e. the first symbol of the PSDU has arrived) of an UL-OFDMA transmission.
|
||||
* This function is called upon the RX event corresponding to the OFDMA part of the UL MU PPDU.
|
||||
*
|
||||
* \param ppdu the arriving PPDU
|
||||
* \param rxPowersW the receive power in W per band
|
||||
*/
|
||||
void StartReceiveOfdmaPayload (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxPowersW);
|
||||
|
||||
/**
|
||||
* The last symbol of the PPDU has arrived.
|
||||
*
|
||||
@@ -1864,6 +1873,8 @@ protected:
|
||||
|
||||
uint64_t m_previouslyRxPpduUid; //!< UID of the previously received PPDU (reused by HE TB PPDUs), reset to UINT64_MAX upon transmission
|
||||
|
||||
uint64_t m_currentHeTbPpduUid; //!< UID of the HE TB PPDU being received
|
||||
|
||||
static uint64_t m_globalPpduUid; //!< Global counter of the PPDU UID
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user