wifi: Consider correct measurement channel width for solicited HE TB PPDUs
This commit is contained in:
@@ -461,11 +461,11 @@ InterferenceHelper::CalculatePayloadPer (Ptr<const Event> event, uint16_t channe
|
||||
}
|
||||
|
||||
double
|
||||
InterferenceHelper::CalculateNonHtPhyHeaderPer (Ptr<const Event> event, NiChangesPerBand *nis, WifiSpectrumBand band) const
|
||||
InterferenceHelper::CalculateNonHtPhyHeaderPer (Ptr<const Event> event, NiChangesPerBand *nis,
|
||||
uint16_t channelWidth, WifiSpectrumBand band) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << band.first << band.second);
|
||||
const WifiTxVector txVector = event->GetTxVector ();
|
||||
uint16_t channelWidth = txVector.GetChannelWidth () >= 40 ? 20 : txVector.GetChannelWidth (); //calculate PER on the 20 MHz primary channel for L-SIG
|
||||
double psr = 1.0; /* Packet Success Rate */
|
||||
auto ni_it = nis->find (band)->second;
|
||||
auto j = ni_it.begin ();
|
||||
@@ -576,11 +576,11 @@ InterferenceHelper::CalculateNonHtPhyHeaderPer (Ptr<const Event> event, NiChange
|
||||
}
|
||||
|
||||
double
|
||||
InterferenceHelper::CalculateHtPhyHeaderPer (Ptr<const Event> event, NiChangesPerBand *nis, WifiSpectrumBand band) const
|
||||
InterferenceHelper::CalculateHtPhyHeaderPer (Ptr<const Event> event, NiChangesPerBand *nis,
|
||||
uint16_t channelWidth, WifiSpectrumBand band) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << band.first << band.second);
|
||||
const WifiTxVector txVector = event->GetTxVector ();
|
||||
uint16_t channelWidth = txVector.GetChannelWidth () >= 40 ? 20 : txVector.GetChannelWidth (); //calculate PER on the 20 MHz primary channel for PHY headers
|
||||
double psr = 1.0; /* Packet Success Rate */
|
||||
auto ni_it = nis->find (band)->second;
|
||||
auto j = ni_it.begin ();
|
||||
@@ -879,19 +879,10 @@ InterferenceHelper::CalculateSnr (Ptr<Event> event, uint16_t channelWidth, uint8
|
||||
}
|
||||
|
||||
struct InterferenceHelper::SnrPer
|
||||
InterferenceHelper::CalculateNonHtPhyHeaderSnrPer (Ptr<Event> event, WifiSpectrumBand band) const
|
||||
InterferenceHelper::CalculateNonHtPhyHeaderSnrPer (Ptr<Event> event, uint16_t channelWidth, WifiSpectrumBand band) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << band.first << band.second);
|
||||
NS_LOG_FUNCTION (this << channelWidth << band.first << band.second);
|
||||
NiChangesPerBand ni;
|
||||
uint16_t channelWidth;
|
||||
if (event->GetTxVector ().GetChannelWidth () >= 40)
|
||||
{
|
||||
channelWidth = 20; //calculate PER on the 20 MHz primary channel for L-SIG
|
||||
}
|
||||
else
|
||||
{
|
||||
channelWidth = event->GetTxVector ().GetChannelWidth ();
|
||||
}
|
||||
double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni, band);
|
||||
double snr = CalculateSnr (event->GetRxPowerW (band),
|
||||
noiseInterferenceW,
|
||||
@@ -901,7 +892,7 @@ InterferenceHelper::CalculateNonHtPhyHeaderSnrPer (Ptr<Event> event, WifiSpectru
|
||||
/* calculate the SNIR at the start of the PHY header and accumulate
|
||||
* all SNIR changes in the SNIR vector.
|
||||
*/
|
||||
double per = CalculateNonHtPhyHeaderPer (event, &ni, band);
|
||||
double per = CalculateNonHtPhyHeaderPer (event, &ni, channelWidth, band);
|
||||
|
||||
struct SnrPer snrPer;
|
||||
snrPer.snr = snr;
|
||||
@@ -910,19 +901,10 @@ InterferenceHelper::CalculateNonHtPhyHeaderSnrPer (Ptr<Event> event, WifiSpectru
|
||||
}
|
||||
|
||||
struct InterferenceHelper::SnrPer
|
||||
InterferenceHelper::CalculateHtPhyHeaderSnrPer (Ptr<Event> event, WifiSpectrumBand band) const
|
||||
InterferenceHelper::CalculateHtPhyHeaderSnrPer (Ptr<Event> event, uint16_t channelWidth, WifiSpectrumBand band) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << band.first << band.second);
|
||||
NiChangesPerBand ni;
|
||||
uint16_t channelWidth;
|
||||
if (event->GetTxVector ().GetChannelWidth () >= 40)
|
||||
{
|
||||
channelWidth = 20; //calculate PER on the 20 MHz primary channel for PHY headers
|
||||
}
|
||||
else
|
||||
{
|
||||
channelWidth = event->GetTxVector ().GetChannelWidth ();
|
||||
}
|
||||
double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni, band);
|
||||
double snr = CalculateSnr (event->GetRxPowerW (band),
|
||||
noiseInterferenceW,
|
||||
@@ -932,7 +914,7 @@ InterferenceHelper::CalculateHtPhyHeaderSnrPer (Ptr<Event> event, WifiSpectrumBa
|
||||
/* calculate the SNIR at the start of the PHY header and accumulate
|
||||
* all SNIR changes in the SNIR vector.
|
||||
*/
|
||||
double per = CalculateHtPhyHeaderPer (event, &ni, band);
|
||||
double per = CalculateHtPhyHeaderPer (event, &ni, channelWidth, band);
|
||||
|
||||
struct SnrPer snrPer;
|
||||
snrPer.snr = snr;
|
||||
|
||||
@@ -256,21 +256,23 @@ public:
|
||||
* all SNIR changes in the SNIR vector.
|
||||
*
|
||||
* \param event the event corresponding to the first time the corresponding PPDU arrives
|
||||
* \param channelWidth the channel width (in MHz) for header measurement
|
||||
* \param band identify the band used by the PSDU
|
||||
*
|
||||
* \return struct of SNR and PER
|
||||
*/
|
||||
struct InterferenceHelper::SnrPer CalculateNonHtPhyHeaderSnrPer (Ptr<Event> event, WifiSpectrumBand band) const;
|
||||
struct InterferenceHelper::SnrPer CalculateNonHtPhyHeaderSnrPer (Ptr<Event> event, uint16_t channelWidth, WifiSpectrumBand band) const;
|
||||
/**
|
||||
* Calculate the SNIR at the start of the HT PHY header and accumulate
|
||||
* all SNIR changes in the SNIR vector.
|
||||
*
|
||||
* \param event the event corresponding to the first time the corresponding PPDU arrives
|
||||
* \param channelWidth the channel width (in MHz) for header measurement
|
||||
* \param band identify the band used by the PSDU
|
||||
*
|
||||
* \return struct of SNR and PER
|
||||
*/
|
||||
struct InterferenceHelper::SnrPer CalculateHtPhyHeaderSnrPer (Ptr<Event> event, WifiSpectrumBand band) const;
|
||||
struct InterferenceHelper::SnrPer CalculateHtPhyHeaderSnrPer (Ptr<Event> event, uint16_t channelWidth, WifiSpectrumBand band) const;
|
||||
|
||||
/**
|
||||
* Notify that RX has started.
|
||||
@@ -423,22 +425,26 @@ private:
|
||||
*
|
||||
* \param event the event
|
||||
* \param nis the NiChanges
|
||||
* \param channelWidth the channel width (in MHz) for header measurement
|
||||
* \param band the band
|
||||
*
|
||||
* \return the error rate of the non-HT PHY header
|
||||
*/
|
||||
double CalculateNonHtPhyHeaderPer (Ptr<const Event> event, NiChangesPerBand *nis, WifiSpectrumBand band) const;
|
||||
double CalculateNonHtPhyHeaderPer (Ptr<const Event> event, NiChangesPerBand *nis,
|
||||
uint16_t channelWidth, WifiSpectrumBand band) const;
|
||||
/**
|
||||
* Calculate the error rate of the HT PHY header. TheHT PHY header
|
||||
* can be divided into multiple chunks (e.g. due to interference from other transmissions).
|
||||
*
|
||||
* \param event the event
|
||||
* \param nis the NiChanges
|
||||
* \param channelWidth the channel width (in MHz) for header measurement
|
||||
* \param band the band
|
||||
*
|
||||
* \return the error rate of the HT PHY header
|
||||
*/
|
||||
double CalculateHtPhyHeaderPer (Ptr<const Event> event, NiChangesPerBand *nis, WifiSpectrumBand band) const;
|
||||
double CalculateHtPhyHeaderPer (Ptr<const Event> event, NiChangesPerBand *nis,
|
||||
uint16_t channelWidth, WifiSpectrumBand band) const;
|
||||
|
||||
double m_noiseFigure; //!< noise figure (linear)
|
||||
Ptr<ErrorRateModel> m_errorRateModel; //!< error rate model
|
||||
|
||||
@@ -344,14 +344,14 @@ SpectrumWifiPhy::StartRx (Ptr<SpectrumSignalParameters> rxParams)
|
||||
{
|
||||
NS_LOG_INFO ("Received non Wi-Fi signal");
|
||||
m_interference.AddForeignSignal (rxDuration, rxPowerW);
|
||||
SwitchMaybeToCcaBusy ();
|
||||
SwitchMaybeToCcaBusy (GetMeasurementChannelWidth (nullptr));
|
||||
return;
|
||||
}
|
||||
if (wifiRxParams && m_disableWifiReception)
|
||||
{
|
||||
NS_LOG_INFO ("Received Wi-Fi signal but blocked from syncing");
|
||||
m_interference.AddForeignSignal (rxDuration, rxPowerW);
|
||||
SwitchMaybeToCcaBusy ();
|
||||
SwitchMaybeToCcaBusy (GetMeasurementChannelWidth (nullptr));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -383,7 +383,7 @@ SpectrumWifiPhy::StartRx (Ptr<SpectrumSignalParameters> rxParams)
|
||||
if (rxDuration > m_state->GetDelayUntilIdle ())
|
||||
{
|
||||
//that packet will be noise _after_ the completion of the OFDMA part of the HE TB PPDUs
|
||||
SwitchMaybeToCcaBusy ();
|
||||
SwitchMaybeToCcaBusy (GetMeasurementChannelWidth (ppdu));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +140,18 @@ public:
|
||||
* to the current channel bandwidth (which can be different from devices max
|
||||
* channel width).
|
||||
*/
|
||||
uint16_t GetGuardBandwidth (uint16_t currentChannelWidth) const;
|
||||
virtual uint16_t GetGuardBandwidth (uint16_t currentChannelWidth) const;
|
||||
|
||||
/**
|
||||
* Get the center frequency of the non-OFDMA part 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
|
||||
*/
|
||||
uint16_t GetCenterFrequencyForNonOfdmaPart (WifiTxVector txVector, uint16_t staId) const;
|
||||
|
||||
/**
|
||||
* Callback invoked when the PHY model starts to process a signal
|
||||
@@ -176,17 +187,6 @@ protected:
|
||||
*/
|
||||
WifiSpectrumBand GetBand (uint16_t bandWidth, uint8_t bandIndex = 0);
|
||||
|
||||
/**
|
||||
* Get the center frequency of the non-OFDMA part 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
|
||||
*/
|
||||
uint16_t GetCenterFrequencyForNonOfdmaPart (WifiTxVector txVector, uint16_t staId) const;
|
||||
|
||||
|
||||
private:
|
||||
/**
|
||||
|
||||
@@ -513,6 +513,7 @@ WifiPhy::WifiPhy ()
|
||||
m_endTxEvent (),
|
||||
m_currentEvent (0),
|
||||
m_previouslyRxPpduUid (UINT64_MAX),
|
||||
m_previouslyTxPpduUid (UINT64_MAX),
|
||||
m_currentHeTbPpduUid (UINT64_MAX),
|
||||
m_standard (WIFI_PHY_STANDARD_UNSPECIFIED),
|
||||
m_band (WIFI_PHY_BAND_UNSPECIFIED),
|
||||
@@ -1908,8 +1909,7 @@ WifiPhy::ResumeFromSleep (void)
|
||||
case WifiPhyState::SLEEP:
|
||||
{
|
||||
NS_LOG_DEBUG ("resuming from sleep mode");
|
||||
uint16_t primaryChannelWidth = GetChannelWidth () >= 40 ? 20 : GetChannelWidth ();
|
||||
Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaEdThresholdW, GetBand (primaryChannelWidth));
|
||||
Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaEdThresholdW, GetBand (GetMeasurementChannelWidth (nullptr)));
|
||||
m_state->SwitchFromSleep (delayUntilCcaEnd);
|
||||
break;
|
||||
}
|
||||
@@ -1940,8 +1940,7 @@ WifiPhy::ResumeFromOff (void)
|
||||
case WifiPhyState::OFF:
|
||||
{
|
||||
NS_LOG_DEBUG ("resuming from off mode");
|
||||
uint16_t primaryChannelWidth = GetChannelWidth () >= 40 ? 20 : GetChannelWidth ();
|
||||
Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaEdThresholdW, GetBand (primaryChannelWidth));
|
||||
Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaEdThresholdW, GetBand (GetMeasurementChannelWidth (nullptr)));
|
||||
m_state->SwitchFromOff (delayUntilCcaEnd);
|
||||
break;
|
||||
}
|
||||
@@ -2890,7 +2889,7 @@ WifiPhy::Send (WifiConstPsduMap psdus, WifiTxVector txVector)
|
||||
{
|
||||
AbortCurrentReception (RECEPTION_ABORTED_BY_TX);
|
||||
//that packet will be noise _after_ the transmission.
|
||||
MaybeCcaBusyDuration ();
|
||||
MaybeCcaBusyDuration (GetMeasurementChannelWidth (m_currentEvent != 0 ? m_currentEvent->GetPpdu () : nullptr));
|
||||
}
|
||||
|
||||
for (auto & endPreambleDetectionEvent : m_endPreambleDetectionEvents)
|
||||
@@ -2938,6 +2937,7 @@ WifiPhy::Send (WifiConstPsduMap psdus, WifiTxVector txVector)
|
||||
uid = m_globalPpduUid++;
|
||||
}
|
||||
m_previouslyRxPpduUid = UINT64_MAX; //reset to use it only once
|
||||
m_previouslyTxPpduUid = uid; //to be able to identify solicited HE TB PPDUs
|
||||
Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdus, txVector, txDuration, GetPhyBand (), uid);
|
||||
|
||||
if (m_wifiRadioEnergyModel != 0 && m_wifiRadioEnergyModel->GetMaximumTimeInState (WifiPhyState::TX) < txDuration)
|
||||
@@ -2971,15 +2971,15 @@ WifiPhy::StartReceiveHeader (Ptr<Event> event)
|
||||
NS_ASSERT (!IsStateRx ());
|
||||
NS_ASSERT (m_endPhyRxEvent.IsExpired ());
|
||||
|
||||
//calculate PER on the 20 MHz primary channel for PHY headers
|
||||
uint16_t primaryChannelWidth = GetChannelWidth () >= 40 ? 20 : GetChannelWidth ();
|
||||
auto primaryBand = GetBand (primaryChannelWidth);
|
||||
double maxRxPowerW = 0;
|
||||
//calculate PER on the measurement channel for PHY headers
|
||||
uint16_t measurementChannelWidth = GetMeasurementChannelWidth (event->GetPpdu ());
|
||||
auto measurementBand = GetBand (measurementChannelWidth);
|
||||
double maxRxPowerW = -1; //in case current event may not be sent on measurement channel (rxPowerW would be equal to 0)
|
||||
Ptr<Event> maxEvent;
|
||||
NS_ASSERT (!m_currentPreambleEvents.empty ());
|
||||
for (auto preambleEvent : m_currentPreambleEvents)
|
||||
{
|
||||
double rxPowerW = preambleEvent.second->GetRxPowerW (primaryBand);
|
||||
double rxPowerW = preambleEvent.second->GetRxPowerW (measurementBand);
|
||||
if (rxPowerW > maxRxPowerW)
|
||||
{
|
||||
maxRxPowerW = rxPowerW;
|
||||
@@ -3003,12 +3003,13 @@ WifiPhy::StartReceiveHeader (Ptr<Event> event)
|
||||
|
||||
m_currentEvent = event;
|
||||
|
||||
double snr = m_interference.CalculateSnr (m_currentEvent, primaryChannelWidth, 1, primaryBand);
|
||||
double snr = m_interference.CalculateSnr (m_currentEvent, measurementChannelWidth, 1, measurementBand);
|
||||
NS_LOG_DEBUG ("SNR(dB)=" << RatioToDb (snr) << " at start of legacy PHY header");
|
||||
|
||||
Time headerPayloadDuration = m_currentEvent->GetStartTime () + m_currentEvent->GetPpdu ()->GetTxDuration () - Simulator::Now ();
|
||||
|
||||
if (!m_preambleDetectionModel || (m_preambleDetectionModel->IsPreambleDetected (m_currentEvent->GetRxPowerW (primaryBand), snr, primaryChannelWidth)))
|
||||
if ((!m_preambleDetectionModel && maxRxPowerW > 0.0)
|
||||
|| (m_preambleDetectionModel && m_preambleDetectionModel->IsPreambleDetected (m_currentEvent->GetRxPowerW (measurementBand), snr, measurementChannelWidth)))
|
||||
{
|
||||
for (auto & endPreambleDetectionEvent : m_endPreambleDetectionEvents)
|
||||
{
|
||||
@@ -3069,7 +3070,7 @@ WifiPhy::StartReceiveHeader (Ptr<Event> event)
|
||||
NS_LOG_DEBUG ("Drop packet because PHY preamble detection failed");
|
||||
// Like CCA-SD, CCA-ED is governed by the 4 us CCA window to flag CCA-BUSY
|
||||
// for any received signal greater than the CCA-ED threshold.
|
||||
DropPreambleEvent (m_currentEvent->GetPpdu (), PREAMBLE_DETECT_FAILURE, m_currentEvent->GetEndTime ());
|
||||
DropPreambleEvent (m_currentEvent->GetPpdu (), PREAMBLE_DETECT_FAILURE, m_currentEvent->GetEndTime (), GetMeasurementChannelWidth (m_currentEvent->GetPpdu ()));
|
||||
if (m_currentPreambleEvents.empty())
|
||||
{
|
||||
//Do not erase events if there are still pending preamble events to be processed
|
||||
@@ -3085,16 +3086,8 @@ WifiPhy::ContinueReceiveHeader (Ptr<Event> event)
|
||||
NS_LOG_FUNCTION (this << *event);
|
||||
NS_ASSERT (m_endPhyRxEvent.IsExpired ());
|
||||
|
||||
uint16_t channelWidth;
|
||||
if (event->GetTxVector ().GetChannelWidth () >= 40)
|
||||
{
|
||||
channelWidth = 20; //calculate PER on the 20 MHz primary channel for PHY headers
|
||||
}
|
||||
else
|
||||
{
|
||||
channelWidth = event->GetTxVector ().GetChannelWidth ();
|
||||
}
|
||||
InterferenceHelper::SnrPer snrPer = m_interference.CalculateNonHtPhyHeaderSnrPer (event, GetBand (channelWidth));
|
||||
uint16_t measurementChannelWidth = GetMeasurementChannelWidth (event->GetPpdu ());
|
||||
InterferenceHelper::SnrPer snrPer = m_interference.CalculateNonHtPhyHeaderSnrPer (event, measurementChannelWidth, GetBand (measurementChannelWidth));
|
||||
|
||||
NS_LOG_DEBUG ("SNR(dB)=" << RatioToDb (snrPer.snr) << ", PER=" << snrPer.per);
|
||||
if (m_random->GetValue () > snrPer.per) //non-HT PHY header reception succeeded
|
||||
@@ -3112,7 +3105,7 @@ WifiPhy::ContinueReceiveHeader (Ptr<Event> event)
|
||||
AbortCurrentReception (L_SIG_FAILURE);
|
||||
if (event->GetEndTime () > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
|
||||
{
|
||||
MaybeCcaBusyDuration ();
|
||||
MaybeCcaBusyDuration (GetMeasurementChannelWidth (event->GetPpdu ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3185,7 +3178,7 @@ WifiPhy::StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxP
|
||||
NS_LOG_DEBUG ("Cannot start RX because device is OFF");
|
||||
if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
|
||||
{
|
||||
MaybeCcaBusyDuration ();
|
||||
MaybeCcaBusyDuration (GetMeasurementChannelWidth (nullptr));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -3195,7 +3188,7 @@ WifiPhy::StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxP
|
||||
NS_LOG_DEBUG ("Packet reception stopped because transmitter has been switched off");
|
||||
if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
|
||||
{
|
||||
MaybeCcaBusyDuration ();
|
||||
MaybeCcaBusyDuration (GetMeasurementChannelWidth (ppdu));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -3212,7 +3205,7 @@ WifiPhy::StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxP
|
||||
* busy due to other devices' transmissions started before the end of
|
||||
* the switching.
|
||||
*/
|
||||
DropPreambleEvent (ppdu, CHANNEL_SWITCHING, endRx);
|
||||
DropPreambleEvent (ppdu, CHANNEL_SWITCHING, endRx, GetMeasurementChannelWidth (ppdu));
|
||||
break;
|
||||
case WifiPhyState::RX:
|
||||
if (m_frameCaptureModel != 0
|
||||
@@ -3226,7 +3219,7 @@ WifiPhy::StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxP
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("Drop packet because already in Rx");
|
||||
DropPreambleEvent (ppdu, RXING, endRx);
|
||||
DropPreambleEvent (ppdu, RXING, endRx, GetMeasurementChannelWidth (ppdu));
|
||||
if (m_currentEvent == 0)
|
||||
{
|
||||
/*
|
||||
@@ -3241,7 +3234,7 @@ WifiPhy::StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxP
|
||||
break;
|
||||
case WifiPhyState::TX:
|
||||
NS_LOG_DEBUG ("Drop packet because already in Tx");
|
||||
DropPreambleEvent (ppdu, TXING, endRx);
|
||||
DropPreambleEvent (ppdu, TXING, endRx, GetMeasurementChannelWidth (ppdu));
|
||||
break;
|
||||
case WifiPhyState::CCA_BUSY:
|
||||
if (m_currentEvent != 0)
|
||||
@@ -3257,7 +3250,7 @@ WifiPhy::StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxP
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("Drop packet because already decoding preamble");
|
||||
DropPreambleEvent (ppdu, BUSY_DECODING_PREAMBLE, endRx);
|
||||
DropPreambleEvent (ppdu, BUSY_DECODING_PREAMBLE, endRx, GetMeasurementChannelWidth (ppdu));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -3271,7 +3264,7 @@ WifiPhy::StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxP
|
||||
break;
|
||||
case WifiPhyState::SLEEP:
|
||||
NS_LOG_DEBUG ("Drop packet because in sleep mode");
|
||||
DropPreambleEvent (ppdu, SLEEPING, endRx);
|
||||
DropPreambleEvent (ppdu, SLEEPING, endRx, GetMeasurementChannelWidth (nullptr));
|
||||
break;
|
||||
default:
|
||||
NS_FATAL_ERROR ("Invalid WifiPhy state.");
|
||||
@@ -3280,9 +3273,9 @@ WifiPhy::StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxP
|
||||
}
|
||||
|
||||
void
|
||||
WifiPhy::DropPreambleEvent (Ptr<const WifiPpdu> ppdu, WifiPhyRxfailureReason reason, Time endRx)
|
||||
WifiPhy::DropPreambleEvent (Ptr<const WifiPpdu> ppdu, WifiPhyRxfailureReason reason, Time endRx, uint16_t measurementChannelWidth)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << *ppdu << reason << endRx);
|
||||
NS_LOG_FUNCTION (this << *ppdu << reason << endRx << measurementChannelWidth);
|
||||
NotifyRxDrop (GetAddressedPsduInPpdu (ppdu), reason);
|
||||
auto it = m_currentPreambleEvents.find (std::make_pair (ppdu->GetUid (), ppdu->GetPreamble ()));
|
||||
if (it != m_currentPreambleEvents.end ())
|
||||
@@ -3292,19 +3285,18 @@ WifiPhy::DropPreambleEvent (Ptr<const WifiPpdu> ppdu, WifiPhyRxfailureReason rea
|
||||
if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
|
||||
{
|
||||
//that PPDU will be noise _after_ the end of the current event.
|
||||
MaybeCcaBusyDuration ();
|
||||
MaybeCcaBusyDuration (measurementChannelWidth);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WifiPhy::MaybeCcaBusyDuration ()
|
||||
WifiPhy::MaybeCcaBusyDuration (uint16_t channelWidth)
|
||||
{
|
||||
//We are here because we have received the first bit of a packet and we are
|
||||
//not going to be able to synchronize on it
|
||||
//In this model, CCA becomes busy when the aggregation of all signals as
|
||||
//tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
|
||||
uint16_t primaryChannelWidth = GetChannelWidth () >= 40 ? 20 : GetChannelWidth ();
|
||||
Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaEdThresholdW, GetBand (primaryChannelWidth));
|
||||
Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaEdThresholdW, GetBand (channelWidth));
|
||||
if (!delayUntilCcaEnd.IsZero ())
|
||||
{
|
||||
m_state->SwitchMaybeToCcaBusy (delayUntilCcaEnd);
|
||||
@@ -3352,13 +3344,13 @@ WifiPhy::StartReceivePayload (Ptr<Event> event)
|
||||
bool canReceivePayload = false;
|
||||
Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
|
||||
WifiModulationClass modulation = ppdu->GetModulation ();
|
||||
//calculate PER on the primary 20 MHz channel for PHY headers
|
||||
uint16_t primaryChannelWidth = std::min (event->GetTxVector ().GetChannelWidth (), static_cast<uint16_t> (20));
|
||||
auto primaryBand = GetBand (primaryChannelWidth);
|
||||
//calculate PER on the measurement channel for PHY headers
|
||||
uint16_t measurementChannelWidth = GetMeasurementChannelWidth (ppdu);
|
||||
auto measurementBand = GetBand (measurementChannelWidth);
|
||||
|
||||
if (modulation >= WIFI_MOD_CLASS_HT)
|
||||
{
|
||||
InterferenceHelper::SnrPer snrPer = m_interference.CalculateHtPhyHeaderSnrPer (event, primaryBand);
|
||||
InterferenceHelper::SnrPer snrPer = m_interference.CalculateHtPhyHeaderSnrPer (event, measurementChannelWidth, measurementBand);
|
||||
NS_LOG_DEBUG ("SNR(dB)=" << RatioToDb (snrPer.snr) << ", PER=" << snrPer.per);
|
||||
canReceivePayload = (m_random->GetValue () > snrPer.per);
|
||||
}
|
||||
@@ -3451,7 +3443,7 @@ WifiPhy::StartReceivePayload (Ptr<Event> event)
|
||||
if (modulation == WIFI_MOD_CLASS_HE)
|
||||
{
|
||||
HePreambleParameters params;
|
||||
params.rssiW = event->GetRxPowerW (primaryBand);
|
||||
params.rssiW = event->GetRxPowerW (measurementBand);
|
||||
params.bssColor = event->GetTxVector ().GetBssColor ();
|
||||
NotifyEndOfHePreamble (params);
|
||||
}
|
||||
@@ -3472,7 +3464,7 @@ WifiPhy::StartReceivePayload (Ptr<Event> event)
|
||||
AbortCurrentReception (FILTERED); //immediately followed by PHY-RXEND (Filtered)
|
||||
if (event->GetEndTime () > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
|
||||
{
|
||||
MaybeCcaBusyDuration ();
|
||||
MaybeCcaBusyDuration (GetMeasurementChannelWidth (ppdu));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3641,7 +3633,7 @@ WifiPhy::EndReceive (Ptr<Event> event)
|
||||
else
|
||||
{
|
||||
m_interference.NotifyRxEnd (Simulator::Now ());
|
||||
MaybeCcaBusyDuration ();
|
||||
MaybeCcaBusyDuration (GetMeasurementChannelWidth (ppdu));
|
||||
m_currentEvent = 0;
|
||||
m_currentPreambleEvents.clear ();
|
||||
m_endRxEvents.clear ();
|
||||
@@ -3653,7 +3645,7 @@ WifiPhy::EndReceive (Ptr<Event> event)
|
||||
}
|
||||
m_endOfMpduEvents.clear ();
|
||||
}
|
||||
MaybeCcaBusyDuration ();
|
||||
MaybeCcaBusyDuration (GetMeasurementChannelWidth (ppdu));
|
||||
}
|
||||
|
||||
std::pair<bool, SignalNoiseDbm>
|
||||
@@ -3766,7 +3758,7 @@ WifiPhy::ResetReceive (Ptr<Event> event)
|
||||
m_interference.NotifyRxEnd (Simulator::Now ());
|
||||
m_currentEvent = 0;
|
||||
m_currentPreambleEvents.clear ();
|
||||
MaybeCcaBusyDuration ();
|
||||
MaybeCcaBusyDuration (GetMeasurementChannelWidth (ppdu));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -5002,16 +4994,14 @@ WifiPhy::GetLastRxEndTime (void) const
|
||||
}
|
||||
|
||||
void
|
||||
WifiPhy::SwitchMaybeToCcaBusy (void)
|
||||
WifiPhy::SwitchMaybeToCcaBusy (uint16_t channelWidth)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_LOG_FUNCTION (this << channelWidth);
|
||||
//We are here because we have received the first bit of a packet and we are
|
||||
//not going to be able to synchronize on it
|
||||
//In this model, CCA becomes busy when the aggregation of all signals as
|
||||
//tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
|
||||
|
||||
uint16_t primaryChannelWidth = GetChannelWidth () >= 40 ? 20 : GetChannelWidth ();
|
||||
Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaEdThresholdW, GetBand (primaryChannelWidth));
|
||||
Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaEdThresholdW, GetBand (channelWidth));
|
||||
if (!delayUntilCcaEnd.IsZero ())
|
||||
{
|
||||
NS_LOG_DEBUG ("Calling SwitchMaybeToCcaBusy for " << delayUntilCcaEnd.As (Time::S));
|
||||
@@ -5098,8 +5088,7 @@ void
|
||||
WifiPhy::StartRx (Ptr<Event> event)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << *event);
|
||||
uint16_t primaryChannelWidth = GetChannelWidth () >= 40 ? 20 : GetChannelWidth ();
|
||||
NS_LOG_DEBUG ("sync to signal (power=" << event->GetRxPowerW (GetBand (primaryChannelWidth)) << "W)");
|
||||
NS_LOG_DEBUG ("sync to signal (power=" << event->GetRxPowerW (GetBand (GetMeasurementChannelWidth (event->GetPpdu ()))) << "W)");
|
||||
m_interference.NotifyRxStart (); //We need to notify it now so that it starts recording events
|
||||
m_endPreambleDetectionEvents.push_back (Simulator::Schedule (GetPreambleDetectionDuration (), &WifiPhy::StartReceiveHeader, this, event));
|
||||
}
|
||||
@@ -5170,6 +5159,32 @@ WifiPhy::GetStaId (const Ptr<const WifiPpdu> ppdu) const
|
||||
return staId;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
WifiPhy::GetMeasurementChannelWidth (const Ptr<const WifiPpdu> ppdu) const
|
||||
{
|
||||
uint16_t channelWidth = GetChannelWidth ();
|
||||
if (ppdu == nullptr)
|
||||
{
|
||||
// Here because PHY was not receiving anything (e.g. resuming from OFF) nor expecting anything (e.g. sleep)
|
||||
// nor processing a Wi-Fi signal.
|
||||
return channelWidth >= 40 ? 20 : channelWidth;
|
||||
}
|
||||
|
||||
channelWidth = std::min (channelWidth, ppdu->GetTxVector ().GetChannelWidth ());
|
||||
/**
|
||||
* The PHY shall not issue a PHY-RXSTART.indication primitive in response to a PPDU that does not overlap
|
||||
* the primary channel unless the PHY at an AP receives the HE TB PPDU solicited by the AP. For the HE
|
||||
* TB PPDU solicited by the AP, the PHY shall issue a PHY-RXSTART.indication primitive for a PPDU
|
||||
* received in the primary or at the secondary 20 MHz channel, the secondary 40 MHz channel, or the secondary
|
||||
* 80 MHz channel.
|
||||
*/
|
||||
if (channelWidth >= 40 && ppdu->GetUid () != m_previouslyTxPpduUid)
|
||||
{
|
||||
channelWidth = 20;
|
||||
}
|
||||
return channelWidth;
|
||||
}
|
||||
|
||||
WifiSpectrumBand
|
||||
WifiPhy::GetBand (uint16_t /*bandWidth*/, uint8_t /*bandIndex*/)
|
||||
{
|
||||
|
||||
@@ -1816,8 +1816,10 @@ protected:
|
||||
* state of interference tracker. In this model, CCA becomes busy when
|
||||
* the aggregation of all signals as tracked by the InterferenceHelper
|
||||
* class is higher than the CcaEdThreshold
|
||||
*
|
||||
* \param channelWidth the channel width in MHz used for RSSI measurement
|
||||
*/
|
||||
void SwitchMaybeToCcaBusy (void);
|
||||
void SwitchMaybeToCcaBusy (uint16_t channelWidth);
|
||||
|
||||
/**
|
||||
* Return the STA ID that has been assigned to the station this PHY belongs to.
|
||||
@@ -1828,6 +1830,16 @@ protected:
|
||||
*/
|
||||
virtual uint16_t GetStaId (const Ptr<const WifiPpdu> ppdu) const;
|
||||
|
||||
/**
|
||||
* Return the channel width used to measure the RSSI.
|
||||
* This corresponds to the primary channel unless it corresponds to the
|
||||
* HE TB PPDU solicited by the AP.
|
||||
*
|
||||
* \param ppdu the PPDU that is being received
|
||||
* \param the channel width (in MHz) used for RSSI measurement
|
||||
*/
|
||||
uint16_t GetMeasurementChannelWidth (const Ptr<const WifiPpdu> ppdu) const;
|
||||
|
||||
/**
|
||||
* Get the start band index and the stop band index for a given band
|
||||
*
|
||||
@@ -1883,6 +1895,7 @@ protected:
|
||||
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
|
||||
|
||||
uint64_t m_previouslyRxPpduUid; //!< UID of the previously received PPDU (reused by HE TB PPDUs), reset to UINT64_MAX upon transmission
|
||||
uint64_t m_previouslyTxPpduUid; //!< UID of the previously sent PPDU, used by AP to recognize response HE TB PPDUs
|
||||
|
||||
uint64_t m_currentHeTbPpduUid; //!< UID of the HE TB PPDU being received
|
||||
|
||||
@@ -1995,8 +2008,9 @@ private:
|
||||
|
||||
/**
|
||||
* Eventually switch to CCA busy
|
||||
* \param channelWidth the channel width in MHz used for RSSI measurement
|
||||
*/
|
||||
void MaybeCcaBusyDuration (void);
|
||||
void MaybeCcaBusyDuration (uint16_t channelWidth);
|
||||
|
||||
/**
|
||||
* Starting receiving the PPDU after having detected the medium is idle or after a reception switch.
|
||||
@@ -2052,8 +2066,9 @@ private:
|
||||
* \param ppdu the incoming PPDU
|
||||
* \param reason the reason the PPDU is dropped
|
||||
* \param endRx the end of the incoming PPDU's reception
|
||||
* \param measurementChannelWidth the measurement width (in MHz) to consider for the PPDU
|
||||
*/
|
||||
void DropPreambleEvent (Ptr<const WifiPpdu> ppdu, WifiPhyRxfailureReason reason, Time endRx);
|
||||
void DropPreambleEvent (Ptr<const WifiPpdu> ppdu, WifiPhyRxfailureReason reason, Time endRx, uint16_t measurementChannelWidth);
|
||||
|
||||
/**
|
||||
* The trace source fired when a packet begins the transmission process on
|
||||
|
||||
@@ -46,7 +46,6 @@ 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
|
||||
{
|
||||
@@ -77,6 +76,11 @@ public:
|
||||
* \param ppdu the PPDU to send
|
||||
*/
|
||||
void StartTx (Ptr<WifiPpdu> ppdu) override;
|
||||
/**
|
||||
* \param currentChannelWidth channel width of the current transmission (MHz)
|
||||
* \return the width of the guard band (MHz) set to 2
|
||||
*/
|
||||
uint16_t GetGuardBandwidth (uint16_t currentChannelWidth) const override;
|
||||
|
||||
/**
|
||||
* Set the global PPDU UID counter.
|
||||
@@ -153,6 +157,14 @@ OfdmaSpectrumWifiPhy::GetCurrentPreambleEvents (void)
|
||||
return m_currentPreambleEvents;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
OfdmaSpectrumWifiPhy::GetGuardBandwidth (uint16_t currentChannelWidth) const
|
||||
{
|
||||
// return a small enough value to avoid having too much out of band transmission
|
||||
// knowing that slopes are not configurable yet.
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup wifi-test
|
||||
* \ingroup tests
|
||||
@@ -1293,7 +1305,10 @@ 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);
|
||||
|
||||
Ptr<SpectrumValue> rxPsd = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (DEFAULT_FREQUENCY, DEFAULT_CHANNEL_WIDTH, txPowerWatts, DEFAULT_GUARD_WIDTH);
|
||||
uint32_t centerFrequency = m_phy->GetCenterFrequencyForNonOfdmaPart (txVector, staId);
|
||||
uint16_t ruWidth = HeRu::GetBandwidth (txVector.GetRu (staId).ruType);
|
||||
uint16_t channelWidth = ruWidth < 20 ? 20 : ruWidth;
|
||||
Ptr<SpectrumValue> rxPsd = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerWatts, m_phy->GetGuardBandwidth (channelWidth));
|
||||
Ptr<WifiSpectrumSignalParameters> rxParams = Create<WifiSpectrumSignalParameters> ();
|
||||
rxParams->psd = rxPsd;
|
||||
rxParams->txPhy = 0;
|
||||
|
||||
Reference in New Issue
Block a user