wifi: Rework MU transmission and reception procedures to apply to both OFDMA and MU-MIMO
This commit is contained in:
committed by
Sébastien Deronne
parent
e85f1621d5
commit
caac4e9636
@@ -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) +
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user