wifi: Move HE-STF and HE-LTF of HE TB PPDUs to OFDMA portion

This commit is contained in:
Rediet
2020-09-14 09:22:51 +02:00
committed by Sebastien Deronne
parent 00354337b3
commit 35d8fc7ee9
5 changed files with 175 additions and 55 deletions

View File

@@ -357,19 +357,27 @@ SpectrumWifiPhy::StartRx (Ptr<SpectrumSignalParameters> rxParams)
NS_LOG_INFO ("Received Wi-Fi signal");
Ptr<WifiPpdu> ppdu = Copy (wifiRxParams->ppdu);
if (ppdu->GetTxVector ().GetPreambleType () == WIFI_PREAMBLE_HE_TB
WifiTxVector txVector = ppdu->GetTxVector ();
if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB
&& wifiRxParams->txPsdFlag == PSD_HE_TB_OFDMA_PORTION)
{
if (m_currentHeTbPpduUid == ppdu->GetUid () && m_currentEvent != 0)
{
//AP and STA already received non-OFDMA part, handle OFDMA payload reception
StartReceiveOfdmaPayload (ppdu, rxPowerW);
//AP or STA has already received non-OFDMA part, switch to OFDMA part, and schedule reception of payload (will be canceled for STAs by StartPayloadStart)
bool ofdmaStarted = !m_beginOfdmaPayloadRxEvents.empty ();
NS_LOG_INFO ("Switch to OFDMA part (already started? " << (ofdmaStarted ? "Y" : "N") << ") "
<< "and schedule OFDMA payload reception in " << GetPhyTrainingSymbolDuration (txVector).As (Time::NS));
Ptr<Event> event = m_interference.Add (ppdu, txVector, rxDuration, rxPowerW, !ofdmaStarted);
uint16_t staId = GetStaId (ppdu);
NS_ASSERT (m_beginOfdmaPayloadRxEvents.find (staId) == m_beginOfdmaPayloadRxEvents.end ());
m_beginOfdmaPayloadRxEvents[staId] = Simulator::Schedule (GetPhyTrainingSymbolDuration (txVector),
&WifiPhy::StartReceiveOfdmaPayload, this, event);
}
else
{
//PHY receives the OFDMA payload while having dropped the preamble
NS_LOG_INFO ("Consider UL-OFDMA part of the HE TB PPDU as interference since device dropped the preamble");
m_interference.Add (ppdu, ppdu->GetTxVector (), rxDuration, rxPowerW);
NS_LOG_INFO ("Consider OFDMA part of the HE TB PPDU as interference since device dropped the preamble");
m_interference.Add (ppdu, txVector, rxDuration, rxPowerW);
auto it = m_currentPreambleEvents.find (std::make_pair(ppdu->GetUid (), ppdu->GetPreamble ()));
if (it != m_currentPreambleEvents.end ())
{
@@ -516,7 +524,7 @@ SpectrumWifiPhy::StartTx (Ptr<WifiPpdu> ppdu)
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
Time nonOfdmaDuration = CalculateNonOfdmaDurationForHeTb (txVector);
Ptr<SpectrumValue> txPowerSpectrum = GetTxPowerSpectralDensity (txPowerWatts, ppdu, PSD_HE_TB_NON_OFDMA_PORTION);
Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
txParams->duration = nonOfdmaDuration;
@@ -555,7 +563,7 @@ SpectrumWifiPhy::StartOfdmaTx (Ptr<WifiPpdu> ppdu, double txPowerWatts)
Ptr<SpectrumValue> txPowerSpectrum = GetTxPowerSpectralDensity (txPowerWatts, ppdu, PSD_HE_TB_OFDMA_PORTION);
Ptr<WifiSpectrumSignalParameters> txParams = Create<WifiSpectrumSignalParameters> ();
WifiTxVector txVector = ppdu->GetTxVector ();
txParams->duration = ppdu->GetTxDuration () - CalculatePhyPreambleAndHeaderDuration (txVector);
txParams->duration = ppdu->GetTxDuration () - CalculateNonOfdmaDurationForHeTb (txVector);
txParams->psd = txPowerSpectrum;
txParams->txPhy = m_wifiSpectrumPhyInterface->GetObject<SpectrumPhy> ();
txParams->txAntenna = m_antenna;

View File

@@ -534,8 +534,7 @@ WifiPhy::WifiPhy ()
m_channelNumber (0),
m_initialChannelNumber (0),
m_wifiRadioEnergyModel (0),
m_timeLastPreambleDetected (Seconds (0)),
m_ofdmaStarted (false)
m_timeLastPreambleDetected (Seconds (0))
{
NS_LOG_FUNCTION (this);
m_random = CreateObject<UniformRandomVariable> ();
@@ -563,6 +562,11 @@ WifiPhy::DoDispose (void)
endPreambleDetectionEvent.Cancel ();
}
m_endPreambleDetectionEvents.clear ();
for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
{
beginOfdmaPayloadRxEvent.second.Cancel ();
}
m_beginOfdmaPayloadRxEvents.clear ();
m_device = 0;
m_mobility = 0;
m_state = 0;
@@ -1713,6 +1717,11 @@ WifiPhy::DoChannelSwitch (uint8_t nch)
endPreambleDetectionEvent.Cancel ();
}
m_endPreambleDetectionEvents.clear ();
for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
{
beginOfdmaPayloadRxEvent.second.Cancel ();
}
m_beginOfdmaPayloadRxEvents.clear ();
goto switchChannel;
break;
case WifiPhyState::TX:
@@ -1732,6 +1741,11 @@ WifiPhy::DoChannelSwitch (uint8_t nch)
endRxEvent.Cancel ();
}
m_endRxEvents.clear ();
for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
{
beginOfdmaPayloadRxEvent.second.Cancel ();
}
m_beginOfdmaPayloadRxEvents.clear ();
}
goto switchChannel;
break;
@@ -1790,6 +1804,11 @@ WifiPhy::DoFrequencySwitch (uint16_t frequency)
endPreambleDetectionEvent.Cancel ();
}
m_endPreambleDetectionEvents.clear ();
for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
{
beginOfdmaPayloadRxEvent.second.Cancel ();
}
m_beginOfdmaPayloadRxEvents.clear ();
goto switchFrequency;
break;
case WifiPhyState::TX:
@@ -1809,6 +1828,11 @@ WifiPhy::DoFrequencySwitch (uint16_t frequency)
}
m_endRxEvents.clear ();
goto switchFrequency;
for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
{
beginOfdmaPayloadRxEvent.second.Cancel ();
}
m_beginOfdmaPayloadRxEvents.clear ();
break;
case WifiPhyState::SLEEP:
NS_LOG_DEBUG ("frequency switching ignored in sleep mode");
@@ -1887,6 +1911,11 @@ WifiPhy::SetOffMode (void)
endPreambleDetectionEvent.Cancel ();
}
m_endPreambleDetectionEvents.clear ();
for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
{
beginOfdmaPayloadRxEvent.second.Cancel ();
}
m_beginOfdmaPayloadRxEvents.clear ();
m_state->SwitchToOff ();
}
@@ -2671,6 +2700,17 @@ WifiPhy::CalculatePhyPreambleAndHeaderDuration (WifiTxVector txVector)
return duration;
}
Time
WifiPhy::CalculateNonOfdmaDurationForHeTb (WifiTxVector txVector)
{
NS_ASSERT (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB);
Time duration = GetPhyPreambleDuration (txVector)
+ GetPhyHeaderDuration (txVector)
+ GetPhySigA1Duration (WIFI_PREAMBLE_HE_TB)
+ GetPhySigA2Duration (WIFI_PREAMBLE_HE_TB);
return duration;
}
Time
WifiPhy::CalculateTxDuration (uint32_t size, WifiTxVector txVector, WifiPhyBand band, uint16_t staId)
{
@@ -2961,7 +3001,11 @@ WifiPhy::Reset (void)
NS_LOG_FUNCTION (this);
m_currentPreambleEvents.clear ();
m_currentEvent = 0;
m_ofdmaStarted = false;
for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
{
beginOfdmaPayloadRxEvent.second.Cancel ();
}
m_beginOfdmaPayloadRxEvents.clear ();
}
void
@@ -3130,6 +3174,7 @@ WifiPhy::StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxP
auto uidPreamblePair = std::make_pair (ppdu->GetUid (), ppdu->GetPreamble ());
if (ppdu->IsUlMu ())
{
rxDuration = CalculateNonOfdmaDurationForHeTb (txVector); //the OFDMA part of the transmission will be added later on
auto it = m_currentPreambleEvents.find (uidPreamblePair);
if (it != m_currentPreambleEvents.end ())
{
@@ -3162,7 +3207,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, CalculatePhyPreambleAndHeaderDuration (txVector), rxPowersW); //the OFDMA part of the transmission will be added later on
event = m_interference.Add (ppdu, txVector, rxDuration, rxPowersW);
m_currentPreambleEvents.insert ({std::make_pair (ppdu->GetUid (), ppdu->GetPreamble ()), event});
}
}
@@ -3305,33 +3350,32 @@ WifiPhy::MaybeCcaBusyDuration (uint16_t channelWidth)
}
void
WifiPhy::StartReceiveOfdmaPayload (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxPowersW)
WifiPhy::StartReceiveOfdmaPayload (Ptr<Event> event)
{
Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
RxPowerWattPerChannelBand rxPowersW = event->GetRxPowerWPerBand ();
//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, !m_ofdmaStarted);
m_ofdmaStarted = true;
Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (GetDevice ());
bool isAp = (DynamicCast<ApWifiMac> (device->GetMac ()) != 0);
if (isAp)
{
Ptr<const WifiPsdu> psdu = GetAddressedPsduInPpdu (ppdu);
ScheduleEndOfMpdus (event);
m_endRxEvents.push_back (Simulator::Schedule (payloadDuration, &WifiPhy::EndReceive, this, event));
m_signalNoiseMap.insert ({std::make_pair (ppdu->GetUid (), ppdu->GetStaId ()), SignalNoiseDbm ()});
m_statusPerMpduMap.insert ({std::make_pair (ppdu->GetUid (), ppdu->GetStaId ()), std::vector<bool> ()});
}
else
{
NS_LOG_INFO ("Ignore reception of OFDMA payload since device is non-AP STA");
NS_ASSERT (m_endRxEvents.size () == 1 && m_endRxEvents.front ().IsRunning ());
}
NS_LOG_FUNCTION (this << event << *ppdu << it->second);
NS_ASSERT (m_currentEvent != 0);
auto itEvent = m_beginOfdmaPayloadRxEvents.find (GetStaId (ppdu));
/**
* m_beginOfdmaPayloadRxEvents should still be running only for APs, since canceled in StartReceivePayload for STAs.
* This is because SpectrumWifiPhy does not have access to the device type and thus blindly schedules things, letting
* the parent WifiPhy class take into account device type.
*/
NS_ASSERT (itEvent != m_beginOfdmaPayloadRxEvents.end () && itEvent->second.IsExpired ());
m_beginOfdmaPayloadRxEvents.erase (itEvent);
Time payloadDuration = ppdu->GetTxDuration () - CalculatePhyPreambleAndHeaderDuration (ppdu->GetTxVector ());
Ptr<const WifiPsdu> psdu = GetAddressedPsduInPpdu (ppdu);
ScheduleEndOfMpdus (event);
m_endRxEvents.push_back (Simulator::Schedule (payloadDuration, &WifiPhy::EndReceive, this, event));
m_signalNoiseMap.insert ({std::make_pair (ppdu->GetUid (), ppdu->GetStaId ()), SignalNoiseDbm ()});
m_statusPerMpduMap.insert ({std::make_pair (ppdu->GetUid (), ppdu->GetStaId ()), std::vector<bool> ()});
}
void
@@ -3517,12 +3561,9 @@ WifiPhy::ScheduleStartReceivePayload (Ptr<Event> event, Time timeToPayloadStart)
else if (IsModeSupported (txMode) || IsMcsSupported (txMode))
{
NS_LOG_INFO ("SIG correctly decoded and with supported settings. Schedule start of payload.");
m_endPhyRxEvent = Simulator::Schedule (timeToPayloadStart,
&WifiPhy::StartReceivePayload, this, event);
Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (GetDevice ());
bool isAp = device != 0 && (DynamicCast<ApWifiMac> (device->GetMac ()) != 0);
if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB && isAp)
m_state->SwitchMaybeToCcaBusy (timeToPayloadStart);
m_endPhyRxEvent = Simulator::Schedule (timeToPayloadStart, &WifiPhy::StartReceivePayload, this, event);
if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB)
{
m_currentHeTbPpduUid = ppdu->GetUid (); //to be able to correctly schedule start of OFDMA payload
}
@@ -3554,6 +3595,13 @@ WifiPhy::StartReceivePayload (Ptr<Event> event)
NS_LOG_DEBUG ("Ignore HE TB PPDU payload received by STA but keep state in Rx");
m_endRxEvents.push_back (Simulator::Schedule (payloadDuration,
&WifiPhy::ResetReceive, this, event));
//Cancel all scheduled events for OFDMA payload reception
NS_ASSERT (!m_beginOfdmaPayloadRxEvents.empty () && m_beginOfdmaPayloadRxEvents.begin ()->second.IsRunning ());
for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
{
beginOfdmaPayloadRxEvent.second.Cancel ();
}
m_beginOfdmaPayloadRxEvents.clear ();
}
else
{
@@ -3565,6 +3613,11 @@ WifiPhy::StartReceivePayload (Ptr<Event> event)
{
//for HE TB PPDUs, ScheduleEndOfMpdus and EndReceive are scheduled by StartReceiveOfdmaPayload
NS_ASSERT (isAp);
NS_ASSERT (!m_beginOfdmaPayloadRxEvents.empty ());
for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
{
NS_ASSERT (beginOfdmaPayloadRxEvent.second.IsRunning ());
}
}
else
{
@@ -3862,6 +3915,11 @@ WifiPhy::ResetReceive (Ptr<Event> event)
m_interference.NotifyRxEnd (Simulator::Now ());
m_currentEvent = 0;
m_currentPreambleEvents.clear ();
for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
{
beginOfdmaPayloadRxEvent.second.Cancel ();
}
m_beginOfdmaPayloadRxEvents.clear ();
MaybeCcaBusyDuration (GetMeasurementChannelWidth (ppdu));
}
@@ -5141,6 +5199,11 @@ WifiPhy::AbortCurrentReception (WifiPhyRxfailureReason reason)
endRxEvent.Cancel ();
}
m_endRxEvents.clear ();
for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
{
beginOfdmaPayloadRxEvent.second.Cancel ();
}
m_beginOfdmaPayloadRxEvents.clear ();
m_interference.NotifyRxEnd (Simulator::Now ());
if (!m_currentEvent)
{

View File

@@ -259,10 +259,9 @@ public:
* 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
* \param event the event holding incoming OFDMA part of the PPDU's information
*/
void StartReceiveOfdmaPayload (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxPowersW);
void StartReceiveOfdmaPayload (Ptr<Event> event);
/**
* The last symbol of the PPDU has arrived.
@@ -413,6 +412,12 @@ public:
* \return the total amount of time this PHY will stay busy for the transmission of the PHY preamble and PHY header.
*/
static Time CalculatePhyPreambleAndHeaderDuration (WifiTxVector txVector);
/**
* \param txVector the transmission parameters used for the HE TB PPDU
*
* \return the duration of the non-OFDMA portion of the HE TB PPDU.
*/
static Time CalculateNonOfdmaDurationForHeTb (WifiTxVector txVector);
/**
*
* \return the preamble detection duration, which is the time correlation needs to detect the start of an incoming frame.
@@ -1798,6 +1803,16 @@ public:
*/
void NotifyChannelAccessRequested (void);
/**
* Get the RU band used to transmit a PSDU to a given STA in a HE MU PPDU
*
* \param txVector the TXVECTOR used for the transmission
* \param staId the STA-ID of the recipient
*
* \return the RU band used to transmit a PSDU to a given STA in a HE MU PPDU
*/
WifiSpectrumBand GetRuBand (WifiTxVector txVector, uint16_t staId);
protected:
// Inherited
@@ -1878,16 +1893,6 @@ protected:
*/
virtual WifiSpectrumBand ConvertHeRuSubcarriers (uint16_t channelWidth, HeRu::SubcarrierRange range) const;
/**
* Get the RU band used to transmit a PSDU to a given STA in a HE MU PPDU
*
* \param txVector the TXVECTOR used for the transmission
* \param staId the STA-ID of the recipient
*
* \return the RU band used to transmit a PSDU to a given STA in a HE MU PPDU
*/
WifiSpectrumBand GetRuBand (WifiTxVector txVector, uint16_t staId);
/**
* Get the band used to transmit the non-OFDMA part of an HE TB PPDU.
*
@@ -1910,6 +1915,9 @@ protected:
std::vector <EventId> m_endRxEvents; //!< the end of receive events (only one unless UL MU reception)
std::vector <EventId> m_endPreambleDetectionEvents; //!< the end of preamble detection events
std::map <uint16_t /* STA-ID */, EventId> m_beginOfdmaPayloadRxEvents; //!< the beginning of the OFDMA payload reception events (indexed by STA-ID)
Ptr<Event> m_currentEvent; //!< Hold the current event
std::map <std::pair<uint64_t /* UID*/, WifiPreamble>, Ptr<Event> > m_currentPreambleEvents; //!< store event associated to a PPDU (that has a unique ID and preamble combination) whose preamble is being received
@@ -2308,8 +2316,6 @@ private:
std::map<UidStaIdPair, std::vector<bool> > m_statusPerMpduMap; //!< Map of the current reception status per MPDU that is filled in as long as MPDUs are being processed by the PHY in case of an A-MPDU
std::map<UidStaIdPair, SignalNoiseDbm> m_signalNoiseMap; //!< Map of the latest signal power and noise power in dBm (noise power includes the noise figure)
bool m_ofdmaStarted; //!< Flag whether the reception of the OFDMA part has started (only used for UL-OFDMA)
Callback<void> m_capabilitiesChangedCallback; //!< Callback when PHY capabilities changed
};

View File

@@ -310,7 +310,7 @@ SpectrumWifiPhyListenerTest::DoRun (void)
Simulator::Run ();
NS_TEST_ASSERT_MSG_EQ (m_count, 1, "Didn't receive right number of packets");
NS_TEST_ASSERT_MSG_EQ (m_listener->m_notifyMaybeCcaBusyStart, 2, "Didn't receive NotifyMaybeCcaBusyStart (preamble deteted + L-SIG received)");
NS_TEST_ASSERT_MSG_EQ (m_listener->m_notifyMaybeCcaBusyStart, 3, "Didn't receive NotifyMaybeCcaBusyStart (preamble deteted + L-SIG received + common PHY header(s) received)");
NS_TEST_ASSERT_MSG_EQ (m_listener->m_notifyRxStart, 1, "Didn't receive NotifyRxStart");
NS_TEST_ASSERT_MSG_EQ (m_listener->m_notifyRxEndOk, 1, "Didn't receive NotifyRxEnd");

View File

@@ -48,6 +48,7 @@ NS_LOG_COMPONENT_DEFINE ("WifiPhyOfdmaTest");
static const uint8_t DEFAULT_CHANNEL_NUMBER = 36;
static const uint32_t DEFAULT_FREQUENCY = 5180; // MHz
static const uint16_t DEFAULT_CHANNEL_WIDTH = 20; // MHz
static const uint16_t DEFAULT_GUARD_WIDTH = DEFAULT_CHANNEL_WIDTH; // MHz (expanded to channel width to model spectrum mask)
class OfdmaSpectrumWifiPhy : public SpectrumWifiPhy
{
@@ -1224,6 +1225,21 @@ private:
*/
void RxHeTbPpdu (uint64_t uid, uint16_t staId, double txPowerWatts, size_t payloadSize);
/**
* Receive OFDMA part of HE TB PPDU function.
* Immediately schedules DoRxHeTbPpduOfdmaPart.
*
* \param rxParamsOfdma the spectrum signal parameters to send for OFDMA part
*/
void RxHeTbPpduOfdmaPart (Ptr<WifiSpectrumSignalParameters> rxParamsOfdma);
/**
* Receive OFDMA part of HE TB PPDU function.
* Actual reception call.
*
* \param rxParamsOfdma the spectrum signal parameters to send for OFDMA part
*/
void DoRxHeTbPpduOfdmaPart (Ptr<WifiSpectrumSignalParameters> rxParamsOfdma);
/**
* RX dropped function
* \param p the packet
@@ -1327,6 +1343,8 @@ TestMultipleHeTbPreambles::RxHeTbPpdu (uint64_t uid, uint16_t staId, double txPo
Time ppduDuration = m_phy->CalculateTxDuration (psdu->GetSize (), txVector, m_phy->GetPhyBand (), staId);
Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdus, txVector, ppduDuration, WIFI_PHY_BAND_5GHZ, uid);
//Send non-OFDMA part
Time nonOfdmaDuration = WifiPhy::CalculateNonOfdmaDurationForHeTb (txVector);
uint32_t centerFrequency = m_phy->GetCenterFrequencyForNonOfdmaPart (txVector, staId);
uint16_t ruWidth = HeRu::GetBandwidth (txVector.GetRu (staId).ruType);
uint16_t channelWidth = ruWidth < 20 ? 20 : ruWidth;
@@ -1334,11 +1352,36 @@ TestMultipleHeTbPreambles::RxHeTbPpdu (uint64_t uid, uint16_t staId, double txPo
Ptr<WifiSpectrumSignalParameters> rxParams = Create<WifiSpectrumSignalParameters> ();
rxParams->psd = rxPsd;
rxParams->txPhy = 0;
rxParams->duration = ppduDuration;
rxParams->duration = nonOfdmaDuration;
rxParams->ppdu = ppdu;
rxParams->txPsdFlag = PSD_HE_TB_NON_OFDMA_PORTION;
m_phy->StartRx (rxParams);
//Schedule OFDMA part
WifiSpectrumBand band = m_phy->GetRuBand (txVector, staId);
Ptr<SpectrumValue> rxPsdOfdma = WifiSpectrumValueHelper::CreateHeMuOfdmTxPowerSpectralDensity (DEFAULT_FREQUENCY, DEFAULT_CHANNEL_WIDTH, txPowerWatts, DEFAULT_GUARD_WIDTH, band);
Ptr<WifiSpectrumSignalParameters> rxParamsOfdma = Create<WifiSpectrumSignalParameters> ();
rxParamsOfdma->psd = rxPsd;
rxParamsOfdma->txPhy = 0;
rxParamsOfdma->duration = ppduDuration - nonOfdmaDuration;
rxParamsOfdma->ppdu = ppdu;
rxParamsOfdma->txPsdFlag = PSD_HE_TB_OFDMA_PORTION;
Simulator::Schedule (nonOfdmaDuration, &TestMultipleHeTbPreambles::RxHeTbPpduOfdmaPart, this, rxParamsOfdma);
}
void
TestMultipleHeTbPreambles::RxHeTbPpduOfdmaPart (Ptr<WifiSpectrumSignalParameters> rxParamsOfdma)
{
Simulator::ScheduleNow (&TestMultipleHeTbPreambles::DoRxHeTbPpduOfdmaPart, this, rxParamsOfdma);
}
void
TestMultipleHeTbPreambles::DoRxHeTbPpduOfdmaPart (Ptr<WifiSpectrumSignalParameters> rxParamsOfdma)
{
//This is needed to make sure the OFDMA part is started as the last event since HE-SIG-A should end at the exact same time as the start
//For normal WifiNetDevices, this the reception of the OFDMA part is scheduled after end of HE-SIG-A decoding.
m_phy->StartRx (rxParamsOfdma);
}
void