wifi: Rework MU transmission and reception procedures to apply to both OFDMA and MU-MIMO

This commit is contained in:
Sebastien Deronne
2022-05-08 14:59:41 +02:00
committed by Sébastien Deronne
parent e85f1621d5
commit caac4e9636
9 changed files with 127 additions and 131 deletions

View File

@@ -146,7 +146,7 @@ EhtPhy::GetSigBSize(const WifiTxVector& txVector) const
}
Time
EhtPhy::CalculateNonOfdmaDurationForHeTb(const WifiTxVector& txVector) const
EhtPhy::CalculateNonHeDurationForHeTb(const WifiTxVector& txVector) const
{
Time duration = GetDuration(WIFI_PPDU_FIELD_PREAMBLE, txVector) +
GetDuration(WIFI_PPDU_FIELD_NON_HT_HEADER, txVector) +
@@ -155,7 +155,7 @@ EhtPhy::CalculateNonOfdmaDurationForHeTb(const WifiTxVector& txVector) const
}
Time
EhtPhy::CalculateNonOfdmaDurationForHeMu(const WifiTxVector& txVector) const
EhtPhy::CalculateNonHeDurationForHeMu(const WifiTxVector& txVector) const
{
Time duration = GetDuration(WIFI_PPDU_FIELD_PREAMBLE, txVector) +
GetDuration(WIFI_PPDU_FIELD_NON_HT_HEADER, txVector) +

View File

@@ -260,8 +260,8 @@ class EhtPhy : public HePhy
PhyFieldRxStatus status,
WifiPpduField field) override;
WifiPhyRxfailureReason GetFailureReason(WifiPpduField field) const override;
Time CalculateNonOfdmaDurationForHeTb(const WifiTxVector& txVector) const override;
Time CalculateNonOfdmaDurationForHeMu(const WifiTxVector& txVector) const override;
Time CalculateNonHeDurationForHeTb(const WifiTxVector& txVector) const override;
Time CalculateNonHeDurationForHeMu(const WifiTxVector& txVector) const override;
uint32_t GetSigBSize(const WifiTxVector& txVector) const override;
/**

View File

@@ -299,7 +299,7 @@ HePhy::ConvertLSigLengthToHeTbPpduDuration(uint16_t length,
}
Time
HePhy::CalculateNonOfdmaDurationForHeTb(const WifiTxVector& txVector) const
HePhy::CalculateNonHeDurationForHeTb(const WifiTxVector& txVector) const
{
Time duration = GetDuration(WIFI_PPDU_FIELD_PREAMBLE, txVector) +
GetDuration(WIFI_PPDU_FIELD_NON_HT_HEADER, txVector) +
@@ -308,7 +308,7 @@ HePhy::CalculateNonOfdmaDurationForHeTb(const WifiTxVector& txVector) const
}
Time
HePhy::CalculateNonOfdmaDurationForHeMu(const WifiTxVector& txVector) const
HePhy::CalculateNonHeDurationForHeMu(const WifiTxVector& txVector) const
{
Time duration = GetDuration(WIFI_PPDU_FIELD_PREAMBLE, txVector) +
GetDuration(WIFI_PPDU_FIELD_NON_HT_HEADER, txVector) +
@@ -373,29 +373,29 @@ HePhy::StartReceivePreamble(Ptr<const WifiPpdu> ppdu,
NS_ASSERT(txVector.GetModulationClass() >= WIFI_MOD_CLASS_HE);
if (m_currentMuPpduUid == ppdu->GetUid() && GetCurrentEvent())
{
// AP or STA has already received non-OFDMA part, switch to OFDMA part, and schedule
// AP or STA has already received non-HE portion, switch to HE portion, and schedule
// reception of payload (will be canceled for STAs by StartPayload)
bool ofdmaStarted = !m_beginOfdmaPayloadRxEvents.empty();
NS_LOG_INFO("Switch to OFDMA part (already started? "
<< (ofdmaStarted ? "Y" : "N") << ") "
<< "and schedule OFDMA payload reception in "
bool hePortionStarted = !m_beginMuPayloadRxEvents.empty();
NS_LOG_INFO("Switch to HE portion (already started? "
<< (hePortionStarted ? "Y" : "N") << ") "
<< "and schedule payload reception in "
<< GetDuration(WIFI_PPDU_FIELD_TRAINING, txVector).As(Time::NS));
auto event = CreateInterferenceEvent(ppdu, rxDuration, rxPowersW, !ofdmaStarted);
auto event = CreateInterferenceEvent(ppdu, rxDuration, rxPowersW, !hePortionStarted);
uint16_t staId = GetStaId(ppdu);
NS_ASSERT(m_beginOfdmaPayloadRxEvents.find(staId) == m_beginOfdmaPayloadRxEvents.end());
m_beginOfdmaPayloadRxEvents[staId] =
NS_ASSERT(m_beginMuPayloadRxEvents.find(staId) == m_beginMuPayloadRxEvents.end());
m_beginMuPayloadRxEvents[staId] =
Simulator::Schedule(GetDuration(WIFI_PPDU_FIELD_TRAINING, txVector),
&HePhy::StartReceiveOfdmaPayload,
&HePhy::StartReceiveMuPayload,
this,
event);
}
else
{
// PHY receives the OFDMA payload while having dropped the preamble
NS_LOG_INFO("Consider OFDMA part of the PPDU as interference since device dropped the "
// PHY receives the HE portion while having dropped the preamble
NS_LOG_INFO("Consider HE portion of the PPDU as interference since device dropped the "
"preamble");
CreateInterferenceEvent(ppdu, rxDuration, rxPowersW);
// the OFDMA part of the PPDU will be noise _after_ the completion of the current event
// the HE portion of the PPDU will be noise _after_ the completion of the current event
ErasePreambleEvent(ppdu, rxDuration);
}
}
@@ -412,11 +412,11 @@ void
HePhy::CancelAllEvents()
{
NS_LOG_FUNCTION(this);
for (auto& beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
for (auto& beginMuPayloadRxEvent : m_beginMuPayloadRxEvents)
{
beginOfdmaPayloadRxEvent.second.Cancel();
beginMuPayloadRxEvent.second.Cancel();
}
m_beginOfdmaPayloadRxEvents.clear();
m_beginMuPayloadRxEvents.clear();
PhyEntity::CancelAllEvents();
}
@@ -446,11 +446,11 @@ HePhy::DoResetReceive(Ptr<Event> event)
{
NS_ASSERT(event->GetEndTime() == Simulator::Now());
}
for (auto& beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
for (auto& beginMuPayloadRxEvent : m_beginMuPayloadRxEvents)
{
beginOfdmaPayloadRxEvent.second.Cancel();
beginMuPayloadRxEvent.second.Cancel();
}
m_beginOfdmaPayloadRxEvents.clear();
m_beginMuPayloadRxEvents.clear();
}
Ptr<Event>
@@ -470,8 +470,8 @@ HePhy::DoGetEvent(Ptr<const WifiPpdu> ppdu, RxPowerWattPerChannelBand& rxPowersW
const auto& txVector = ppdu->GetTxVector();
const auto rxDuration =
(ppdu->GetType() == WIFI_PPDU_TYPE_UL_MU)
? CalculateNonOfdmaDurationForHeTb(
txVector) // the OFDMA part of the transmission will be added later on
? CalculateNonHeDurationForHeTb(
txVector) // the HE portion of the transmission will be added later on
: ppdu->GetTxDuration();
if (it != currentPreambleEvents.cend())
{
@@ -535,8 +535,8 @@ HePhy::DoGetEvent(Ptr<const WifiPpdu> ppdu, RxPowerWattPerChannelBand& rxPowersW
else if (ppdu->GetType() == WIFI_PPDU_TYPE_DL_MU)
{
const auto& txVector = ppdu->GetTxVector();
Time rxDuration = CalculateNonOfdmaDurationForHeMu(
txVector); // the OFDMA part of the transmission will be added later on
Time rxDuration = CalculateNonHeDurationForHeMu(
txVector); // the HE portion of the transmission will be added later on
event = CreateInterferenceEvent(ppdu, rxDuration, rxPowersW);
AddPreambleEvent(event);
}
@@ -687,7 +687,7 @@ HePhy::ProcessSigA(Ptr<Event> event, PhyFieldRxStatus status)
NS_ASSERT(txVector.GetHeMuUserInfo(staId) == m_trigVector->GetHeMuUserInfo(staId));
m_currentMuPpduUid =
ppdu->GetUid(); // to be able to correctly schedule start of OFDMA payload
ppdu->GetUid(); // to be able to correctly schedule start of MU payload
}
if (ppdu->GetType() != WIFI_PPDU_TYPE_DL_MU &&
@@ -747,10 +747,10 @@ HePhy::ProcessSigB(Ptr<Event> event, PhyFieldRxStatus status)
// included in HE MU PPDUs, but it is necessary for EHT to avoid that a non-AP
// STA receiving a Trigger Frame sent as an EHT SU transmission (which carries
// the EHT-SIG field) stores the PPDU UID and uses it later to schedule the
// reception of the OFDMA payload of the TB PPDU (see HePhy::StartReceivePreamble())
// reception of the payload of the TB PPDU (see HePhy::StartReceivePreamble())
// despite it lacks the TRIGVECTOR.
m_currentMuPpduUid =
event->GetPpdu()->GetUid(); // to be able to correctly schedule start of OFDMA payload
event->GetPpdu()->GetUid(); // to be able to correctly schedule start of MU payload
}
return status;
}
@@ -821,13 +821,13 @@ HePhy::DoStartReceivePayload(Ptr<Event> event)
txVector,
m_wifiPhy->GetPhyBand()) -
CalculatePhyPreambleAndHeaderDuration(txVector);
// This method is called when we start receiving the first OFDMA payload. To
// This method is called when we start receiving the first MU payload. To
// compute the time to the reception end of the last TB PPDU, we need to add the
// offset of the last TB PPDU to the payload duration (same for all TB PPDUs)
Time maxOffset{0};
for (const auto& beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
for (const auto& beginMuPayloadRxEvent : m_beginMuPayloadRxEvents)
{
maxOffset = Max(maxOffset, Simulator::GetDelayLeft(beginOfdmaPayloadRxEvent.second));
maxOffset = Max(maxOffset, Simulator::GetDelayLeft(beginMuPayloadRxEvent.second));
}
Time timeToEndRx = payloadDuration + maxOffset;
@@ -837,14 +837,14 @@ HePhy::DoStartReceivePayload(Ptr<Event> event)
NotifyPayloadBegin(txVector, timeToEndRx);
m_endRxPayloadEvents.push_back(
Simulator::Schedule(timeToEndRx, &PhyEntity::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)
// Cancel all scheduled events for MU payload reception
NS_ASSERT(!m_beginMuPayloadRxEvents.empty() &&
m_beginMuPayloadRxEvents.begin()->second.IsRunning());
for (auto& beginMuPayloadRxEvent : m_beginMuPayloadRxEvents)
{
beginOfdmaPayloadRxEvent.second.Cancel();
beginMuPayloadRxEvent.second.Cancel();
}
m_beginOfdmaPayloadRxEvents.clear();
m_beginMuPayloadRxEvents.clear();
}
else
{
@@ -853,11 +853,11 @@ HePhy::DoStartReceivePayload(Ptr<Event> event)
m_signalNoiseMap.insert({std::make_pair(ppdu->GetUid(), staId), SignalNoiseDbm()});
m_statusPerMpduMap.insert({std::make_pair(ppdu->GetUid(), staId), std::vector<bool>()});
// for HE TB PPDUs, ScheduleEndOfMpdus and EndReceive are scheduled by
// StartReceiveOfdmaPayload
NS_ASSERT(!m_beginOfdmaPayloadRxEvents.empty());
for (auto& beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
// StartReceiveMuPayload
NS_ASSERT(!m_beginMuPayloadRxEvents.empty());
for (auto& beginMuPayloadRxEvent : m_beginMuPayloadRxEvents)
{
NS_ASSERT(beginOfdmaPayloadRxEvent.second.IsRunning());
NS_ASSERT(beginMuPayloadRxEvent.second.IsRunning());
}
}
@@ -913,7 +913,7 @@ HePhy::DoEndReceivePayload(Ptr<const WifiPpdu> ppdu)
}
if (m_endRxPayloadEvents.empty())
{
// We've got the last PPDU of the UL-OFDMA transmission.
// We've got the last PPDU of the UL-MU transmission.
// Indicate a successful reception is terminated if at least one HE TB PPDU
// has been successfully received, otherwise indicate a unsuccessful reception is
// terminated.
@@ -937,7 +937,7 @@ HePhy::DoEndReceivePayload(Ptr<const WifiPpdu> ppdu)
}
void
HePhy::StartReceiveOfdmaPayload(Ptr<Event> event)
HePhy::StartReceiveMuPayload(Ptr<Event> event)
{
NS_LOG_FUNCTION(this << event);
Ptr<const WifiPpdu> ppdu = event->GetPpdu();
@@ -954,15 +954,15 @@ HePhy::StartReceiveOfdmaPayload(Ptr<Event> event)
NS_LOG_FUNCTION(this << *event << it->second);
NS_ASSERT(GetCurrentEvent());
NS_ASSERT(m_rxHeTbPpdus == 0);
auto itEvent = m_beginOfdmaPayloadRxEvents.find(GetStaId(ppdu));
auto itEvent = m_beginMuPayloadRxEvents.find(GetStaId(ppdu));
/**
* m_beginOfdmaPayloadRxEvents should still be running only for APs, since canceled in
* m_beginMuPayloadRxEvents 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);
NS_ASSERT(itEvent != m_beginMuPayloadRxEvents.end() && itEvent->second.IsExpired());
m_beginMuPayloadRxEvents.erase(itEvent);
Time payloadDuration =
ppdu->GetTxDuration() - CalculatePhyPreambleAndHeaderDuration(ppdu->GetTxVector());
@@ -1309,10 +1309,10 @@ HePhy::GetMaxDelayPpduSameUid(const WifiTxVector& txVector)
auto heConfiguration = m_wifiPhy->GetDevice()->GetHeConfiguration();
NS_ASSERT(heConfiguration);
// DoStartReceivePayload(), which is called when we start receiving the Data field,
// computes the max offset among TB PPDUs based on the begin OFDMA payload RX events,
// computes the max offset among TB PPDUs based on the begin MU payload RX events,
// which are scheduled by StartReceivePreamble() when starting the reception of the
// OFDMA portion. Therefore, the maximum delay cannot exceed the duration of the
// training fields that are between the start of the OFDMA portion and the start
// HE portion. Therefore, the maximum delay cannot exceed the duration of the
// training fields that are between the start of the HE portion and the start
// of the Data field.
auto maxDelay = GetDuration(WIFI_PPDU_FIELD_TRAINING, txVector);
if (heConfiguration->GetMaxTbPpduDelay().IsStrictlyPositive())
@@ -1356,9 +1356,9 @@ HePhy::GetTxPowerSpectralDensity(double txPowerW,
case WIFI_PPDU_TYPE_UL_MU: {
if (flag == HePpdu::PSD_NON_HE_PORTION)
{
// non-OFDMA portion is sent only on the 20 MHz channels covering the RU
// non-HE portion is sent only on the 20 MHz channels covering the RU
const uint16_t staId = GetStaId(ppdu);
centerFrequency = GetCenterFrequencyForNonOfdmaPart(txVector, staId);
centerFrequency = GetCenterFrequencyForNonHePart(txVector, staId);
const uint16_t ruWidth = HeRu::GetBandwidth(txVector.GetRu(staId).GetRuType());
channelWidth = (ruWidth < 20) ? 20 : ruWidth;
return WifiSpectrumValueHelper::CreateDuplicated20MhzTxPowerSpectralDensity(
@@ -1424,7 +1424,7 @@ HePhy::GetTxPowerSpectralDensity(double txPowerW,
}
uint16_t
HePhy::GetCenterFrequencyForNonOfdmaPart(const WifiTxVector& txVector, uint16_t staId) const
HePhy::GetCenterFrequencyForNonHePart(const WifiTxVector& txVector, uint16_t staId) const
{
NS_LOG_FUNCTION(this << txVector << staId);
NS_ASSERT(txVector.IsUlMu() && (txVector.GetModulationClass() >= WIFI_MOD_CLASS_HE));
@@ -1462,40 +1462,39 @@ HePhy::StartTx(Ptr<const WifiPpdu> ppdu)
}
if (ppdu->GetType() == WIFI_PPDU_TYPE_UL_MU || ppdu->GetType() == WIFI_PPDU_TYPE_DL_MU)
{
auto nonOfdmaTxPowerDbm =
m_wifiPhy->GetTxPowerForTransmission(ppdu) + m_wifiPhy->GetTxGain();
auto nonHeTxPowerDbm = m_wifiPhy->GetTxPowerForTransmission(ppdu) + m_wifiPhy->GetTxGain();
// temporarily set WifiPpdu flag to PSD_HE_PORTION for correct calculation of the OFDMA TX
// power
// temporarily set WifiPpdu flag to PSD_HE_PORTION for correct calculation of TX power for
// the HE portion
auto hePpdu = DynamicCast<const HePpdu>(ppdu);
NS_ASSERT(hePpdu);
hePpdu->SetTxPsdFlag(HePpdu::PSD_HE_PORTION);
auto ofdmaTxPowerDbm = m_wifiPhy->GetTxPowerForTransmission(ppdu) + m_wifiPhy->GetTxGain();
auto heTxPowerDbm = m_wifiPhy->GetTxPowerForTransmission(ppdu) + m_wifiPhy->GetTxGain();
hePpdu->SetTxPsdFlag(HePpdu::PSD_NON_HE_PORTION);
// non-OFDMA part
auto nonOfdmaDuration = ppdu->GetType() == WIFI_PPDU_TYPE_UL_MU
? CalculateNonOfdmaDurationForHeTb(txVector)
: CalculateNonOfdmaDurationForHeMu(txVector);
auto nonOfdmaTxPowerSpectrum =
GetTxPowerSpectralDensity(DbmToW(nonOfdmaTxPowerDbm), ppdu, HePpdu::PSD_NON_HE_PORTION);
Transmit(nonOfdmaDuration,
// non-HE portion
auto nonHePortionDuration = ppdu->GetType() == WIFI_PPDU_TYPE_UL_MU
? CalculateNonHeDurationForHeTb(txVector)
: CalculateNonHeDurationForHeMu(txVector);
auto nonHeTxPowerSpectrum =
GetTxPowerSpectralDensity(DbmToW(nonHeTxPowerDbm), ppdu, HePpdu::PSD_NON_HE_PORTION);
Transmit(nonHePortionDuration,
ppdu,
nonOfdmaTxPowerDbm,
nonOfdmaTxPowerSpectrum,
"non-OFDMA transmission");
nonHeTxPowerDbm,
nonHeTxPowerSpectrum,
"non-HE portion transmission");
// OFDMA part
auto ofdmaDuration = ppdu->GetTxDuration() - nonOfdmaDuration;
auto ofdmaTxPowerSpectrum =
GetTxPowerSpectralDensity(DbmToW(ofdmaTxPowerDbm), ppdu, HePpdu::PSD_HE_PORTION);
Simulator::Schedule(nonOfdmaDuration,
&HePhy::StartTxOfdma,
// HE portion
auto hePortionDuration = ppdu->GetTxDuration() - nonHePortionDuration;
auto heTxPowerSpectrum =
GetTxPowerSpectralDensity(DbmToW(heTxPowerDbm), ppdu, HePpdu::PSD_HE_PORTION);
Simulator::Schedule(nonHePortionDuration,
&HePhy::StartTxHePortion,
this,
ppdu,
ofdmaTxPowerDbm,
ofdmaTxPowerSpectrum,
ofdmaDuration);
heTxPowerDbm,
heTxPowerSpectrum,
hePortionDuration);
}
else
{
@@ -1504,16 +1503,16 @@ HePhy::StartTx(Ptr<const WifiPpdu> ppdu)
}
void
HePhy::StartTxOfdma(Ptr<const WifiPpdu> ppdu,
double txPowerDbm,
Ptr<SpectrumValue> txPowerSpectrum,
Time ofdmaDuration)
HePhy::StartTxHePortion(Ptr<const WifiPpdu> ppdu,
double txPowerDbm,
Ptr<SpectrumValue> txPowerSpectrum,
Time hePortionDuration)
{
NS_LOG_FUNCTION(this << ppdu << txPowerDbm << ofdmaDuration);
NS_LOG_FUNCTION(this << ppdu << txPowerDbm << hePortionDuration);
auto hePpdu = DynamicCast<const HePpdu>(ppdu);
NS_ASSERT(hePpdu);
hePpdu->SetTxPsdFlag(HePpdu::PSD_HE_PORTION);
Transmit(ofdmaDuration, ppdu, txPowerDbm, txPowerSpectrum, "OFDMA transmission");
Transmit(hePortionDuration, ppdu, txPowerDbm, txPowerSpectrum, "HE portion transmission");
}
Time

View File

@@ -152,16 +152,16 @@ class HePhy : public VhtPhy
/**
* \param txVector the transmission parameters used for the HE TB PPDU
*
* \return the duration of the non-OFDMA portion of the HE TB PPDU.
* \return the duration of the non-HE portion of the HE TB PPDU.
*/
virtual Time CalculateNonOfdmaDurationForHeTb(const WifiTxVector& txVector) const;
virtual Time CalculateNonHeDurationForHeTb(const WifiTxVector& txVector) const;
/**
* \param txVector the transmission parameters used for the HE MU PPDU
*
* \return the duration of the non-OFDMA portion of the HE MU PPDU.
* \return the duration of the non-HE portion of the HE MU PPDU.
*/
virtual Time CalculateNonOfdmaDurationForHeMu(const WifiTxVector& txVector) const;
virtual Time CalculateNonHeDurationForHeMu(const WifiTxVector& txVector) const;
/**
* Get the band in the TX spectrum associated with the RU used by the PSDU
@@ -215,15 +215,15 @@ class HePhy : public VhtPhy
void SetTrigVector(const WifiTxVector& trigVector, Time validity);
/**
* Get the center frequency of the non-OFDMA part of the current TxVector for the
* Get the center frequency of the non-HE portion of the current TxVector for the
* given STA-ID.
* Note this method is only to be used for UL MU.
*
* \param txVector the TXVECTOR that has the RU allocation
* \param staId the STA-ID of the station taking part of the UL MU
* \return the center frequency in MHz corresponding to the non-OFDMA part of the HE TB PPDU
* \return the center frequency in MHz corresponding to the non-HE portion of the HE TB PPDU
*/
uint16_t GetCenterFrequencyForNonOfdmaPart(const WifiTxVector& txVector, uint16_t staId) const;
uint16_t GetCenterFrequencyForNonHePart(const WifiTxVector& txVector, uint16_t staId) const;
/**
* Sets the OBSS-PD algorithm.
@@ -523,13 +523,13 @@ class HePhy : public VhtPhy
virtual uint32_t GetSigBSize(const WifiTxVector& txVector) const;
/**
* Start receiving the PSDU (i.e. the first symbol of the PSDU has arrived) of an OFDMA
* transmission. This function is called upon the RX event corresponding to the OFDMA part of
* Start receiving the PSDU (i.e. the first symbol of the PSDU has arrived) of an MU
* transmission. This function is called upon the RX event corresponding to the HE portion of
* the MU PPDU.
*
* \param event the event holding incoming OFDMA part of the PPDU's information
* \param event the event holding incoming HE portion of the PPDU's information
*/
void StartReceiveOfdmaPayload(Ptr<Event> event);
void StartReceiveMuPayload(Ptr<Event> event);
/**
* Return the rate (in bps) of the non-HT Reference Rate
@@ -563,8 +563,8 @@ class HePhy : public VhtPhy
uint64_t m_currentMuPpduUid; //!< UID of the HE MU or HE TB PPDU being received
std::map<uint16_t /* STA-ID */, EventId>
m_beginOfdmaPayloadRxEvents; //!< the beginning of the OFDMA payload reception events
//!< (indexed by STA-ID)
m_beginMuPayloadRxEvents; //!< the beginning of the MU payload reception events (indexed by
//!< STA-ID)
EndOfHeSigACallback m_endOfHeSigACallback; //!< end of HE-SIG-A callback
std::optional<WifiTxVector> m_trigVector; //!< the TRIGVECTOR
@@ -590,17 +590,17 @@ class HePhy : public VhtPhy
HePpdu::TxPsdFlag flag) const;
/**
* Start the transmission of the OFDMA part of the MU PPDU.
* Start the transmission of the HE portion of the MU PPDU.
*
* \param ppdu the PPDU
* \param txPowerDbm the total TX power in dBm
* \param txPowerSpectrum the TX PSD
* \param ofdmaDuration the duration of the OFDMA part
* \param hePortionDuration the duration of the HE portion
*/
void StartTxOfdma(Ptr<const WifiPpdu> ppdu,
double txPowerDbm,
Ptr<SpectrumValue> txPowerSpectrum,
Time ofdmaDuration);
void StartTxHePortion(Ptr<const WifiPpdu> ppdu,
double txPowerDbm,
Ptr<SpectrumValue> txPowerSpectrum,
Time hePortionDuration);
/**
* Notify PHY state helper to switch to CCA busy state,

View File

@@ -222,10 +222,10 @@ InterferenceHelper::Add(Ptr<const WifiPpdu> ppdu,
const WifiTxVector& txVector,
Time duration,
RxPowerWattPerChannelBand& rxPowerW,
bool isStartOfdmaRxing)
bool isStartHePortionRxing)
{
Ptr<Event> event = Create<Event>(ppdu, txVector, duration, std::move(rxPowerW));
AppendEvent(event, isStartOfdmaRxing);
AppendEvent(event, isStartHePortionRxing);
return event;
}
@@ -354,9 +354,9 @@ InterferenceHelper::GetEnergyDuration(double energyW, const WifiSpectrumBandInfo
}
void
InterferenceHelper::AppendEvent(Ptr<Event> event, bool isStartOfdmaRxing)
InterferenceHelper::AppendEvent(Ptr<Event> event, bool isStartHePortionRxing)
{
NS_LOG_FUNCTION(this << event << isStartOfdmaRxing);
NS_LOG_FUNCTION(this << event << isStartHePortionRxing);
for (const auto& [band, power] : event->GetRxPowerWPerBand())
{
auto niIt = m_niChanges.find(band);
@@ -372,11 +372,11 @@ InterferenceHelper::AppendEvent(Ptr<Event> event, bool isStartOfdmaRxing)
// Always leave the first zero power noise event in the list
niIt->second.erase(++(niIt->second.begin()), ++previousPowerPosition);
}
else if (isStartOfdmaRxing)
else if (isStartHePortionRxing)
{
// When the first UL-OFDMA payload is received, we need to set m_firstPowers
// When the first HE portion is received, we need to set m_firstPowerPerBand
// so that it takes into account interferences that arrived between the start of the
// UL MU transmission and the start of UL-OFDMA payload.
// HE TB PPDU transmission and the start of HE TB payload.
m_firstPowers.find(band)->second = previousPowerStart;
}
auto first =
@@ -535,7 +535,7 @@ InterferenceHelper::CalculatePayloadPer(Ptr<const Event> event,
Time phyPayloadStart = j->first;
if (event->GetPpdu()->GetType() != WIFI_PPDU_TYPE_UL_MU &&
event->GetPpdu()->GetType() !=
WIFI_PPDU_TYPE_DL_MU) // j->first corresponds to the start of the OFDMA payload
WIFI_PPDU_TYPE_DL_MU) // j->first corresponds to the start of the MU payload
{
phyPayloadStart =
j->first + WifiPhy::CalculatePhyPreambleAndHeaderDuration(event->GetTxVector());

View File

@@ -212,9 +212,8 @@ class InterferenceHelper : public Object
* \param txVector the TXVECTOR
* \param duration the PPDU duration
* \param rxPower received power per band (W)
* \param isStartOfdmaRxing flag whether the event corresponds to the start of the OFDMA payload
* reception (only used for UL-OFDMA) //TODO simplify this once WifiPpdu is subclassed by adding
* an attribute
* \param isStartHePortionRxing flag whether the event corresponds to the start of the HE
* portion reception (only used for MU)
*
* \return Event
*/
@@ -222,7 +221,7 @@ class InterferenceHelper : public Object
const WifiTxVector& txVector,
Time duration,
RxPowerWattPerChannelBand& rxPower,
bool isStartOfdmaRxing = false);
bool isStartHePortionRxing = false);
/**
* Add a non-Wifi signal to interference helper.
@@ -428,10 +427,10 @@ class InterferenceHelper : public Object
* Append the given Event.
*
* \param event the event to be appended
* \param isStartOfdmaRxing flag whether event corresponds to the start of the OFDMA payload
* reception (only used for UL-OFDMA)
* \param isStartHePortionRxing flag whether event corresponds to the start of the HE portion
* reception (only used for MU)
*/
void AppendEvent(Ptr<Event> event, bool isStartOfdmaRxing);
void AppendEvent(Ptr<Event> event, bool isStartHePortionRxing);
/**
* Calculate noise and interference power in W.

View File

@@ -887,13 +887,13 @@ Ptr<Event>
PhyEntity::CreateInterferenceEvent(Ptr<const WifiPpdu> ppdu,
Time duration,
RxPowerWattPerChannelBand& rxPower,
bool isStartOfdmaRxing /* = false */)
bool isStartHePortionRxing /* = false */)
{
return m_wifiPhy->m_interference->Add(ppdu,
ppdu->GetTxVector(),
duration,
rxPower,
isStartOfdmaRxing);
isStartHePortionRxing);
}
void

View File

@@ -839,14 +839,13 @@ class PhyEntity : public SimpleRefCount<PhyEntity>
* \param ppdu the PPDU
* \param duration the PPDU duration
* \param rxPower received power per band (W)
* \param isStartOfdmaRxing flag whether the event corresponds to the start of the OFDMA payload
* reception (only used for UL-OFDMA)
* \return the created event
* \param isStartHePortionRxing flag whether the event corresponds to the start of the OFDMA
* payload reception (only used for UL-OFDMA) \return the created event
*/
Ptr<Event> CreateInterferenceEvent(Ptr<const WifiPpdu> ppdu,
Time duration,
RxPowerWattPerChannelBand& rxPower,
bool isStartOfdmaRxing = false);
bool isStartHePortionRxing = false);
/**
* Update an event in WifiPhy's InterferenceHelper class.
* Wrapper used by child classes.

View File

@@ -2430,9 +2430,8 @@ TestMultipleHeTbPreambles::RxHeTbPpdu(uint64_t uid,
HePpdu::PSD_NON_HE_PORTION);
// Send non-OFDMA part
Time nonOfdmaDuration = m_phy->GetHePhy()->CalculateNonOfdmaDurationForHeTb(txVector);
uint32_t centerFrequency =
m_phy->GetHePhy()->GetCenterFrequencyForNonOfdmaPart(txVector, staId);
Time nonOfdmaDuration = m_phy->GetHePhy()->CalculateNonHeDurationForHeTb(txVector);
uint32_t centerFrequency = m_phy->GetHePhy()->GetCenterFrequencyForNonHePart(txVector, staId);
uint16_t ruWidth = HeRu::GetBandwidth(txVector.GetRu(staId).GetRuType());
uint16_t channelWidth = ruWidth < 20 ? 20 : ruWidth;
Ptr<SpectrumValue> rxPsd = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity(
@@ -3982,8 +3981,8 @@ TestUlOfdmaPhyTransmission::SchedulePowerMeasurementChecks(Time delay,
WifiTxVector txVectorSta1 = GetTxVectorForHeTbPpdu(1, 1, 0);
WifiTxVector txVectorSta2 = GetTxVectorForHeTbPpdu(2, 2, 0);
Ptr<const HePhy> hePhy = m_phyAp->GetHePhy();
Time nonOfdmaDuration = hePhy->CalculateNonOfdmaDurationForHeTb(txVectorSta2);
NS_ASSERT(nonOfdmaDuration == hePhy->CalculateNonOfdmaDurationForHeTb(txVectorSta1));
Time nonOfdmaDuration = hePhy->CalculateNonHeDurationForHeTb(txVectorSta2);
NS_ASSERT(nonOfdmaDuration == hePhy->CalculateNonHeDurationForHeTb(txVectorSta1));
std::vector<double> rxPowerNonOfdma{rxPowerNonOfdmaRu1, rxPowerNonOfdmaRu2};
std::vector<WifiSpectrumBandInfo> nonOfdmaBand{hePhy->GetNonOfdmaBand(txVectorSta1, 1),