wifi: Move preamble and payload reception logic from WifiPhy to PhyEntity
This commit is contained in:
@@ -190,7 +190,7 @@ public:
|
||||
* \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)
|
||||
* \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
|
||||
*
|
||||
* \return Event
|
||||
*/
|
||||
|
||||
@@ -360,49 +360,7 @@ SpectrumWifiPhy::StartRx (Ptr<SpectrumSignalParameters> rxParams)
|
||||
|
||||
NS_LOG_INFO ("Received Wi-Fi signal");
|
||||
Ptr<WifiPpdu> ppdu = wifiRxParams->ppdu->Copy ();
|
||||
WifiTxVector txVector = ppdu->GetTxVector ();
|
||||
if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB
|
||||
&& wifiRxParams->txPsdFlag == PSD_HE_TB_OFDMA_PORTION)
|
||||
{
|
||||
if (DynamicCast<const HePhy> (GetPhyEntity (WIFI_MOD_CLASS_HE))->GetCurrentHeTbPpduUid () == ppdu->GetUid ()
|
||||
&& m_currentEvent != 0)
|
||||
{
|
||||
//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 " << GetPpduFieldDuration (WIFI_PPDU_FIELD_TRAINING, 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 (GetPpduFieldDuration (WIFI_PPDU_FIELD_TRAINING, txVector),
|
||||
&WifiPhy::StartReceiveOfdmaPayload, this, event);
|
||||
}
|
||||
else
|
||||
{
|
||||
//PHY receives the OFDMA payload while having dropped the preamble
|
||||
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 ())
|
||||
{
|
||||
m_currentPreambleEvents.erase (it);
|
||||
}
|
||||
if (m_currentPreambleEvents.empty ())
|
||||
{
|
||||
Reset ();
|
||||
}
|
||||
|
||||
if (rxDuration > m_state->GetDelayUntilIdle ())
|
||||
{
|
||||
//that packet will be noise _after_ the completion of the OFDMA part of the HE TB PPDUs
|
||||
SwitchMaybeToCcaBusy (GetMeasurementChannelWidth (ppdu));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
StartReceivePreamble (ppdu, rxPowerW);
|
||||
}
|
||||
StartReceivePreamble (ppdu, rxPowerW, rxDuration, wifiRxParams->txPsdFlag);
|
||||
}
|
||||
|
||||
Ptr<AntennaModel>
|
||||
@@ -455,7 +413,9 @@ SpectrumWifiPhy::GetTxPowerSpectralDensity (double txPowerW, Ptr<WifiPpdu> ppdu,
|
||||
case WIFI_MOD_CLASS_HE:
|
||||
if (flag == PSD_HE_TB_OFDMA_PORTION)
|
||||
{
|
||||
WifiSpectrumBand band = GetRuBand (txVector, GetStaId (ppdu));
|
||||
//TODO Move this to HePhy
|
||||
const auto hePhy = DynamicCast<HePhy> (GetPhyEntity (WIFI_MOD_CLASS_HE));
|
||||
WifiSpectrumBand band = hePhy->GetRuBand (txVector, GetStaId (ppdu));
|
||||
v = WifiSpectrumValueHelper::CreateHeMuOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerW, GetGuardBandwidth (channelWidth), band);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -563,21 +563,10 @@ WifiPhy::DoDispose (void)
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_endTxEvent.Cancel ();
|
||||
m_endPhyRxEvent.Cancel ();
|
||||
for (auto & endRxEvent : m_endRxEvents)
|
||||
for (auto & phyEntity : m_phyEntities)
|
||||
{
|
||||
endRxEvent.Cancel ();
|
||||
phyEntity.second->CancelAllEvents ();
|
||||
}
|
||||
m_endRxEvents.clear ();
|
||||
for (auto & endPreambleDetectionEvent : m_endPreambleDetectionEvents)
|
||||
{
|
||||
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;
|
||||
@@ -1621,21 +1610,10 @@ WifiPhy::DoChannelSwitch (uint8_t nch)
|
||||
case WifiPhyState::RX:
|
||||
NS_LOG_DEBUG ("drop packet because of channel switching while reception");
|
||||
m_endPhyRxEvent.Cancel ();
|
||||
for (auto & endRxEvent : m_endRxEvents)
|
||||
for (auto & phyEntity : m_phyEntities)
|
||||
{
|
||||
endRxEvent.Cancel ();
|
||||
phyEntity.second->CancelAllEvents ();
|
||||
}
|
||||
m_endRxEvents.clear ();
|
||||
for (auto & endPreambleDetectionEvent : m_endPreambleDetectionEvents)
|
||||
{
|
||||
endPreambleDetectionEvent.Cancel ();
|
||||
}
|
||||
m_endPreambleDetectionEvents.clear ();
|
||||
for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
|
||||
{
|
||||
beginOfdmaPayloadRxEvent.second.Cancel ();
|
||||
}
|
||||
m_beginOfdmaPayloadRxEvents.clear ();
|
||||
goto switchChannel;
|
||||
break;
|
||||
case WifiPhyState::TX:
|
||||
@@ -1644,22 +1622,9 @@ WifiPhy::DoChannelSwitch (uint8_t nch)
|
||||
break;
|
||||
case WifiPhyState::CCA_BUSY:
|
||||
case WifiPhyState::IDLE:
|
||||
for (auto & phyEntity : m_phyEntities)
|
||||
{
|
||||
for (auto & endPreambleDetectionEvent : m_endPreambleDetectionEvents)
|
||||
{
|
||||
endPreambleDetectionEvent.Cancel ();
|
||||
}
|
||||
m_endPreambleDetectionEvents.clear ();
|
||||
for (auto & endRxEvent : m_endRxEvents)
|
||||
{
|
||||
endRxEvent.Cancel ();
|
||||
}
|
||||
m_endRxEvents.clear ();
|
||||
for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
|
||||
{
|
||||
beginOfdmaPayloadRxEvent.second.Cancel ();
|
||||
}
|
||||
m_beginOfdmaPayloadRxEvents.clear ();
|
||||
phyEntity.second->CancelAllEvents ();
|
||||
}
|
||||
goto switchChannel;
|
||||
break;
|
||||
@@ -1708,21 +1673,10 @@ WifiPhy::DoFrequencySwitch (uint16_t frequency)
|
||||
case WifiPhyState::RX:
|
||||
NS_LOG_DEBUG ("drop packet because of channel/frequency switching while reception");
|
||||
m_endPhyRxEvent.Cancel ();
|
||||
for (auto & endRxEvent : m_endRxEvents)
|
||||
for (auto & phyEntity : m_phyEntities)
|
||||
{
|
||||
endRxEvent.Cancel ();
|
||||
phyEntity.second->CancelAllEvents ();
|
||||
}
|
||||
m_endRxEvents.clear ();
|
||||
for (auto & endPreambleDetectionEvent : m_endPreambleDetectionEvents)
|
||||
{
|
||||
endPreambleDetectionEvent.Cancel ();
|
||||
}
|
||||
m_endPreambleDetectionEvents.clear ();
|
||||
for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
|
||||
{
|
||||
beginOfdmaPayloadRxEvent.second.Cancel ();
|
||||
}
|
||||
m_beginOfdmaPayloadRxEvents.clear ();
|
||||
goto switchFrequency;
|
||||
break;
|
||||
case WifiPhyState::TX:
|
||||
@@ -1731,22 +1685,11 @@ WifiPhy::DoFrequencySwitch (uint16_t frequency)
|
||||
break;
|
||||
case WifiPhyState::CCA_BUSY:
|
||||
case WifiPhyState::IDLE:
|
||||
for (auto & endPreambleDetectionEvent : m_endPreambleDetectionEvents)
|
||||
for (auto & phyEntity : m_phyEntities)
|
||||
{
|
||||
endPreambleDetectionEvent.Cancel ();
|
||||
phyEntity.second->CancelAllEvents ();
|
||||
}
|
||||
m_endPreambleDetectionEvents.clear ();
|
||||
for (auto & endRxEvent : m_endRxEvents)
|
||||
{
|
||||
endRxEvent.Cancel ();
|
||||
}
|
||||
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");
|
||||
@@ -1815,21 +1758,10 @@ WifiPhy::SetOffMode (void)
|
||||
m_channelAccessRequested = false;
|
||||
m_endPhyRxEvent.Cancel ();
|
||||
m_endTxEvent.Cancel ();
|
||||
for (auto & endRxEvent : m_endRxEvents)
|
||||
for (auto & phyEntity : m_phyEntities)
|
||||
{
|
||||
endRxEvent.Cancel ();
|
||||
phyEntity.second->CancelAllEvents ();
|
||||
}
|
||||
m_endRxEvents.clear ();
|
||||
for (auto & endPreambleDetectionEvent : m_endPreambleDetectionEvents)
|
||||
{
|
||||
endPreambleDetectionEvent.Cancel ();
|
||||
}
|
||||
m_endPreambleDetectionEvents.clear ();
|
||||
for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
|
||||
{
|
||||
beginOfdmaPayloadRxEvent.second.Cancel ();
|
||||
}
|
||||
m_beginOfdmaPayloadRxEvents.clear ();
|
||||
m_state->SwitchToOff ();
|
||||
}
|
||||
|
||||
@@ -1975,7 +1907,7 @@ WifiPhy::CalculateTxDuration (WifiConstPsduMap psduMap, WifiTxVector txVector, W
|
||||
//TODO: Move this logic to HePhy
|
||||
if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB)
|
||||
{
|
||||
return ConvertLSigLengthToHeTbPpduDuration (txVector.GetLength (), txVector, band);
|
||||
return HePhy::ConvertLSigLengthToHeTbPpduDuration (txVector.GetLength (), txVector, band);
|
||||
}
|
||||
|
||||
Time maxDuration = Seconds (0);
|
||||
@@ -2164,30 +2096,23 @@ WifiPhy::Send (WifiConstPsduMap psdus, WifiTxVector txVector)
|
||||
return;
|
||||
}
|
||||
|
||||
Time txDuration;
|
||||
if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB)
|
||||
{
|
||||
NS_ASSERT (txVector.GetLength () > 0);
|
||||
txDuration = ConvertLSigLengthToHeTbPpduDuration (txVector.GetLength (), txVector, GetPhyBand ());
|
||||
}
|
||||
else
|
||||
{
|
||||
txDuration = CalculateTxDuration (psdus, txVector, GetPhyBand ());
|
||||
}
|
||||
Time txDuration = CalculateTxDuration (psdus, txVector, GetPhyBand ());
|
||||
|
||||
if (!m_endPreambleDetectionEvents.empty () || ((m_currentEvent != 0) && (m_currentEvent->GetEndTime () > (Simulator::Now () + m_state->GetDelayUntilIdle ()))))
|
||||
bool noEndPreambleDetectionEvent = true;
|
||||
for (const auto & it : m_phyEntities)
|
||||
{
|
||||
noEndPreambleDetectionEvent &= it.second->NoEndPreambleDetectionEvents ();
|
||||
}
|
||||
if (!noEndPreambleDetectionEvent || ((m_currentEvent != 0) && (m_currentEvent->GetEndTime () > (Simulator::Now () + m_state->GetDelayUntilIdle ()))))
|
||||
{
|
||||
AbortCurrentReception (RECEPTION_ABORTED_BY_TX);
|
||||
//that packet will be noise _after_ the transmission.
|
||||
MaybeCcaBusyDuration (GetMeasurementChannelWidth (m_currentEvent != 0 ? m_currentEvent->GetPpdu () : nullptr));
|
||||
}
|
||||
|
||||
for (auto & endPreambleDetectionEvent : m_endPreambleDetectionEvents)
|
||||
for (auto & it : m_phyEntities)
|
||||
{
|
||||
if (endPreambleDetectionEvent.IsRunning ())
|
||||
{
|
||||
endPreambleDetectionEvent.Cancel ();
|
||||
}
|
||||
it.second->CancelRunningEndPreambleDetectionEvents ();
|
||||
}
|
||||
m_currentPreambleEvents.clear ();
|
||||
|
||||
@@ -2252,190 +2177,30 @@ WifiPhy::Reset (void)
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_currentPreambleEvents.clear ();
|
||||
m_currentEvent = 0;
|
||||
for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
|
||||
for (auto & phyEntity : m_phyEntities)
|
||||
{
|
||||
beginOfdmaPayloadRxEvent.second.Cancel ();
|
||||
phyEntity.second->CancelAllEvents ();
|
||||
}
|
||||
m_beginOfdmaPayloadRxEvents.clear ();
|
||||
}
|
||||
|
||||
void
|
||||
WifiPhy::StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxPowersW)
|
||||
WifiPhy::StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxPowersW,
|
||||
Time rxDuration, TxPsdFlag psdFlag /* = PSD_NON_HE_TB */)
|
||||
{
|
||||
//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 rxDuration = ppdu->GetTxDuration ();
|
||||
|
||||
Ptr<Event> event;
|
||||
//We store all incoming preamble events, and a decision is made at the end of the preamble detection window.
|
||||
//If a preamble is received after the preamble detection window, it is stored anyway because this is needed for HE TB PPDUs in
|
||||
//order to properly update the received power in InterferenceHelper. The map is cleaned anyway at the end of the current reception.
|
||||
auto uidPreamblePair = std::make_pair (ppdu->GetUid (), ppdu->GetPreamble ());
|
||||
if (ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU)
|
||||
WifiModulationClass modulation = ppdu->GetTxVector ().GetModulationClass ();
|
||||
auto it = m_phyEntities.find (modulation);
|
||||
if (it != m_phyEntities.end ())
|
||||
{
|
||||
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 ())
|
||||
{
|
||||
NS_LOG_DEBUG ("Received another HE TB PPDU for UID " << ppdu->GetUid () << " from STA-ID " << ppdu->GetStaId () << " and BSS color " << +txVector.GetBssColor ());
|
||||
event = it->second;
|
||||
if (Simulator::Now () - event->GetStartTime () > NanoSeconds (400))
|
||||
{
|
||||
//Section 27.3.14.3 from 802.11ax Draft 4.0: Pre-correction accuracy requirements.
|
||||
//A STA that transmits an HE TB PPDU, non-HT PPDU, or non-HT duplicate PPDU in response to a triggering PPDU
|
||||
//shall ensure that the transmission start time of the HE TB PPDU, non-HT PPDU, or non-HT duplicate PPDU is
|
||||
//within ±0.4 µs + 16 µs from the end, at the STA’s antenna connector, of the last OFDM symbol of the triggering
|
||||
//PPDU (if it contains no PE field) or of the PE field of the triggering PPDU (if the PE field is present).
|
||||
//As a result, if an HE TB PPDU arrives later than 0.4 µs, it is added as an interference but PPDU is dropped.
|
||||
event = m_interference.Add (ppdu, txVector, rxDuration, rxPowersW);
|
||||
NS_LOG_DEBUG ("Drop packet because not received within the 400ns window");
|
||||
NotifyRxDrop (GetAddressedPsduInPpdu (ppdu), HE_TB_PPDU_TOO_LATE);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Update received power of the event associated to that UL MU transmission
|
||||
m_interference.UpdateEvent (event, rxPowersW);
|
||||
}
|
||||
if ((m_currentEvent != 0) && (m_currentEvent->GetPpdu ()->GetUid () != ppdu->GetUid ()))
|
||||
{
|
||||
NS_LOG_DEBUG ("Drop packet because already receiving another HE TB PPDU");
|
||||
NotifyRxDrop (GetAddressedPsduInPpdu (ppdu), RXING);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("Received a new HE TB PPDU for UID " << ppdu->GetUid () << " from STA-ID " << ppdu->GetStaId () << " and BSS color " << +txVector.GetBssColor ());
|
||||
event = m_interference.Add (ppdu, txVector, rxDuration, rxPowersW);
|
||||
m_currentPreambleEvents.insert ({std::make_pair (ppdu->GetUid (), ppdu->GetPreamble ()), event});
|
||||
}
|
||||
it->second->StartReceivePreamble (ppdu, rxPowersW, rxDuration, psdFlag);
|
||||
}
|
||||
else
|
||||
{
|
||||
event = m_interference.Add (ppdu, txVector, rxDuration, rxPowersW);
|
||||
NS_ASSERT (m_currentPreambleEvents.find (uidPreamblePair) == m_currentPreambleEvents.end ());
|
||||
m_currentPreambleEvents.insert ({uidPreamblePair, event});
|
||||
}
|
||||
|
||||
Time endRx = Simulator::Now () + rxDuration;
|
||||
if (m_state->GetState () == WifiPhyState::OFF)
|
||||
{
|
||||
NS_LOG_DEBUG ("Cannot start RX because device is OFF");
|
||||
if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
|
||||
//TODO find a fallback PHY for receiving the PPDU (e.g. 11a for 11ax due to preamble structure)
|
||||
NS_LOG_DEBUG ("Unsupported modulation received (" << modulation << "), consider as noise");
|
||||
if (ppdu->GetTxDuration () > m_state->GetDelayUntilIdle ())
|
||||
{
|
||||
MaybeCcaBusyDuration (GetMeasurementChannelWidth (nullptr));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (ppdu->IsTruncatedTx ())
|
||||
{
|
||||
NS_LOG_DEBUG ("Packet reception stopped because transmitter has been switched off");
|
||||
if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
|
||||
{
|
||||
MaybeCcaBusyDuration (GetMeasurementChannelWidth (ppdu));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch (m_state->GetState ())
|
||||
{
|
||||
case WifiPhyState::SWITCHING:
|
||||
NS_LOG_DEBUG ("Drop packet because of channel switching");
|
||||
/*
|
||||
* Packets received on the upcoming channel are added to the event list
|
||||
* during the switching state. This way the medium can be correctly sensed
|
||||
* when the device listens to the channel for the first time after the
|
||||
* switching e.g. after channel switching, the channel may be sensed as
|
||||
* busy due to other devices' transmissions started before the end of
|
||||
* the switching.
|
||||
*/
|
||||
DropPreambleEvent (ppdu, CHANNEL_SWITCHING, endRx, GetMeasurementChannelWidth (ppdu));
|
||||
break;
|
||||
case WifiPhyState::RX:
|
||||
if (m_frameCaptureModel != 0
|
||||
&& m_frameCaptureModel->IsInCaptureWindow (m_timeLastPreambleDetected)
|
||||
&& m_frameCaptureModel->CaptureNewFrame (m_currentEvent, event))
|
||||
{
|
||||
AbortCurrentReception (FRAME_CAPTURE_PACKET_SWITCH);
|
||||
NS_LOG_DEBUG ("Switch to new packet");
|
||||
StartRx (event);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("Drop packet because already in Rx");
|
||||
DropPreambleEvent (ppdu, RXING, endRx, GetMeasurementChannelWidth (ppdu));
|
||||
if (m_currentEvent == 0)
|
||||
{
|
||||
/*
|
||||
* We are here because the non-legacy PHY header has not been successfully received.
|
||||
* The PHY is kept in RX state for the duration of the PPDU, but EndReceive function is
|
||||
* not called when the reception of the PPDU is finished, which is responsible to clear
|
||||
* m_currentPreambleEvents. As a result, m_currentPreambleEvents should be cleared here.
|
||||
*/
|
||||
m_currentPreambleEvents.clear ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WifiPhyState::TX:
|
||||
NS_LOG_DEBUG ("Drop packet because already in Tx");
|
||||
DropPreambleEvent (ppdu, TXING, endRx, GetMeasurementChannelWidth (ppdu));
|
||||
break;
|
||||
case WifiPhyState::CCA_BUSY:
|
||||
if (m_currentEvent != 0)
|
||||
{
|
||||
if (m_frameCaptureModel != 0
|
||||
&& m_frameCaptureModel->IsInCaptureWindow (m_timeLastPreambleDetected)
|
||||
&& m_frameCaptureModel->CaptureNewFrame (m_currentEvent, event))
|
||||
{
|
||||
AbortCurrentReception (FRAME_CAPTURE_PACKET_SWITCH);
|
||||
NS_LOG_DEBUG ("Switch to new packet");
|
||||
StartRx (event);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("Drop packet because already decoding preamble");
|
||||
DropPreambleEvent (ppdu, BUSY_DECODING_PREAMBLE, endRx, GetMeasurementChannelWidth (ppdu));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
StartRx (event);
|
||||
}
|
||||
break;
|
||||
case WifiPhyState::IDLE:
|
||||
NS_ASSERT (m_currentEvent == 0);
|
||||
StartRx (event);
|
||||
break;
|
||||
case WifiPhyState::SLEEP:
|
||||
NS_LOG_DEBUG ("Drop packet because in sleep mode");
|
||||
DropPreambleEvent (ppdu, SLEEPING, endRx, GetMeasurementChannelWidth (nullptr));
|
||||
break;
|
||||
default:
|
||||
NS_FATAL_ERROR ("Invalid WifiPhy state.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WifiPhy::DropPreambleEvent (Ptr<const WifiPpdu> ppdu, WifiPhyRxfailureReason reason, Time endRx, uint16_t measurementChannelWidth)
|
||||
{
|
||||
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 ())
|
||||
{
|
||||
m_currentPreambleEvents.erase (it);
|
||||
}
|
||||
if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
|
||||
{
|
||||
//that PPDU will be noise _after_ the end of the current event.
|
||||
MaybeCcaBusyDuration (measurementChannelWidth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2453,347 +2218,6 @@ WifiPhy::MaybeCcaBusyDuration (uint16_t channelWidth)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
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 << 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
|
||||
WifiPhy::StartReceivePayload (Ptr<Event> event)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << *event);
|
||||
NS_ASSERT (m_endPhyRxEvent.IsExpired ());
|
||||
Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
|
||||
WifiTxVector txVector = event->GetTxVector ();
|
||||
Time payloadDuration = ppdu->GetTxDuration () - CalculatePhyPreambleAndHeaderDuration (txVector);
|
||||
m_state->SwitchToRx (payloadDuration);
|
||||
m_phyRxPayloadBeginTrace (txVector, payloadDuration); //this callback (equivalent to PHY-RXSTART primitive) is triggered only if headers have been correctly decoded and that the mode within is supported
|
||||
|
||||
Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (GetDevice ());
|
||||
bool isAp = device != 0 && (DynamicCast<ApWifiMac> (device->GetMac ()) != 0);
|
||||
if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB && !isAp)
|
||||
{
|
||||
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
|
||||
{
|
||||
NS_LOG_DEBUG ("Receiving PSDU");
|
||||
uint16_t staId = GetStaId (ppdu);
|
||||
m_signalNoiseMap.insert ({std::make_pair (ppdu->GetUid (), staId), SignalNoiseDbm ()});
|
||||
m_statusPerMpduMap.insert ({std::make_pair (ppdu->GetUid (), staId), std::vector<bool> ()});
|
||||
if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB)
|
||||
{
|
||||
//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
|
||||
{
|
||||
ScheduleEndOfMpdus (event);
|
||||
m_endRxEvents.push_back (Simulator::Schedule (payloadDuration, &WifiPhy::EndReceive, this, event));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WifiPhy::ScheduleEndOfMpdus (Ptr<Event> event)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << *event);
|
||||
Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
|
||||
Ptr<const WifiPsdu> psdu = GetAddressedPsduInPpdu (ppdu);
|
||||
WifiTxVector txVector = event->GetTxVector ();
|
||||
uint16_t staId = GetStaId (ppdu);
|
||||
Time endOfMpduDuration = NanoSeconds (0);
|
||||
Time relativeStart = NanoSeconds (0);
|
||||
Time psduDuration = ppdu->GetTxDuration () - CalculatePhyPreambleAndHeaderDuration (txVector);
|
||||
Time remainingAmpduDuration = psduDuration;
|
||||
size_t nMpdus = psdu->GetNMpdus ();
|
||||
MpduType mpduType = (nMpdus > 1) ? FIRST_MPDU_IN_AGGREGATE : (psdu->IsSingle () ? SINGLE_MPDU : NORMAL_MPDU);
|
||||
uint32_t totalAmpduSize = 0;
|
||||
double totalAmpduNumSymbols = 0.0;
|
||||
auto mpdu = psdu->begin ();
|
||||
for (size_t i = 0; i < nMpdus && mpdu != psdu->end (); ++mpdu)
|
||||
{
|
||||
uint32_t size = (mpduType == NORMAL_MPDU) ? psdu->GetSize () : psdu->GetAmpduSubframeSize (i);
|
||||
Time mpduDuration = GetPayloadDuration (size, txVector,
|
||||
GetPhyBand (), mpduType, true, totalAmpduSize,
|
||||
totalAmpduNumSymbols, staId);
|
||||
|
||||
remainingAmpduDuration -= mpduDuration;
|
||||
if (i == (nMpdus - 1) && !remainingAmpduDuration.IsZero ()) //no more MPDUs coming
|
||||
{
|
||||
if (remainingAmpduDuration < NanoSeconds (txVector.GetGuardInterval ())) //enables to ignore padding
|
||||
{
|
||||
mpduDuration += remainingAmpduDuration; //apply a correction just in case rounding had induced slight shift
|
||||
}
|
||||
}
|
||||
|
||||
endOfMpduDuration += mpduDuration;
|
||||
NS_LOG_INFO ("Schedule end of MPDU #" << i << " in " << endOfMpduDuration.As (Time::NS)
|
||||
<< " (relativeStart=" << relativeStart.As (Time::NS) << ", mpduDuration=" << mpduDuration.As (Time::NS)
|
||||
<< ", remainingAmdpuDuration=" << remainingAmpduDuration.As (Time::NS) << ")");
|
||||
m_endOfMpduEvents.push_back (Simulator::Schedule (endOfMpduDuration, &WifiPhy::EndOfMpdu, this, event, Create<WifiPsdu> (*mpdu, false), i, relativeStart, mpduDuration));
|
||||
|
||||
//Prepare next iteration
|
||||
++i;
|
||||
relativeStart += mpduDuration;
|
||||
mpduType = (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WifiPhy::EndOfMpdu (Ptr<Event> event, Ptr<const WifiPsdu> psdu, size_t mpduIndex, Time relativeStart, Time mpduDuration)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << *event << mpduIndex << relativeStart << mpduDuration);
|
||||
Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
|
||||
WifiTxVector txVector = event->GetTxVector ();
|
||||
uint16_t staId = GetStaId (ppdu);
|
||||
|
||||
uint16_t channelWidth = std::min (GetChannelWidth (), event->GetTxVector ().GetChannelWidth ());
|
||||
WifiSpectrumBand band;
|
||||
if (txVector.IsMu ())
|
||||
{
|
||||
band = GetRuBand (txVector, staId);
|
||||
channelWidth = HeRu::GetBandwidth (txVector.GetRu (staId).ruType);
|
||||
}
|
||||
else
|
||||
{
|
||||
band = GetBand (channelWidth);
|
||||
}
|
||||
double snr = m_interference.CalculateSnr (event, channelWidth, txVector.GetNss (staId), band);
|
||||
|
||||
std::pair<bool, SignalNoiseDbm> rxInfo = GetReceptionStatus (psdu, event, staId, relativeStart, mpduDuration);
|
||||
NS_LOG_DEBUG ("Extracted MPDU #" << mpduIndex << ": duration: " << mpduDuration.GetNanoSeconds () << "ns" <<
|
||||
", correct reception: " << rxInfo.first << ", Signal/Noise: " << rxInfo.second.signal << "/" << rxInfo.second.noise << "dBm");
|
||||
|
||||
auto signalNoiseIt = m_signalNoiseMap.find (std::make_pair (ppdu->GetUid (), staId));
|
||||
NS_ASSERT (signalNoiseIt != m_signalNoiseMap.end ());
|
||||
signalNoiseIt->second = rxInfo.second;
|
||||
|
||||
RxSignalInfo rxSignalInfo;
|
||||
rxSignalInfo.snr = snr;
|
||||
rxSignalInfo.rssi = rxInfo.second.signal;
|
||||
|
||||
auto statusPerMpduIt = m_statusPerMpduMap.find (std::make_pair (ppdu->GetUid (), staId));
|
||||
NS_ASSERT (statusPerMpduIt != m_statusPerMpduMap.end ());
|
||||
statusPerMpduIt->second.push_back (rxInfo.first);
|
||||
|
||||
if (rxInfo.first && GetAddressedPsduInPpdu (ppdu)->GetNMpdus () > 1)
|
||||
{
|
||||
//only done for correct MPDU that is part of an A-MPDU
|
||||
m_state->ContinueRxNextMpdu (Copy (psdu), rxSignalInfo, txVector);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WifiPhy::EndReceive (Ptr<Event> event)
|
||||
{
|
||||
Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
|
||||
WifiTxVector txVector = event->GetTxVector ();
|
||||
Time psduDuration = ppdu->GetTxDuration () - CalculatePhyPreambleAndHeaderDuration (txVector);
|
||||
NS_LOG_FUNCTION (this << *event << psduDuration);
|
||||
if (ppdu->GetType () != WIFI_PPDU_TYPE_UL_MU)
|
||||
{
|
||||
NS_ASSERT (GetLastRxEndTime () == Simulator::Now ());
|
||||
}
|
||||
NS_ASSERT (event->GetEndTime () == Simulator::Now ());
|
||||
|
||||
uint16_t staId = GetStaId (ppdu);
|
||||
WifiSpectrumBand band;
|
||||
uint16_t channelWidth = std::min (GetChannelWidth (), txVector.GetChannelWidth ());
|
||||
if (txVector.IsMu ())
|
||||
{
|
||||
band = GetRuBand (txVector, staId);
|
||||
channelWidth = HeRu::GetBandwidth (txVector.GetRu (staId).ruType);
|
||||
}
|
||||
else
|
||||
{
|
||||
band = GetBand (channelWidth);
|
||||
}
|
||||
double snr = m_interference.CalculateSnr (event, channelWidth, txVector.GetNss (staId), band);
|
||||
|
||||
Ptr<const WifiPsdu> psdu = GetAddressedPsduInPpdu (ppdu);
|
||||
NotifyRxEnd (psdu);
|
||||
|
||||
auto signalNoiseIt = m_signalNoiseMap.find (std::make_pair (ppdu->GetUid (), staId));
|
||||
NS_ASSERT (signalNoiseIt != m_signalNoiseMap.end ());
|
||||
auto statusPerMpduIt = m_statusPerMpduMap.find (std::make_pair (ppdu->GetUid (), staId));
|
||||
NS_ASSERT (statusPerMpduIt != m_statusPerMpduMap.end ());
|
||||
|
||||
if (std::count (statusPerMpduIt->second.begin (), statusPerMpduIt->second.end (), true))
|
||||
{
|
||||
//At least one MPDU has been successfully received
|
||||
NotifyMonitorSniffRx (psdu, GetFrequency (), txVector, signalNoiseIt->second, statusPerMpduIt->second, staId);
|
||||
RxSignalInfo rxSignalInfo;
|
||||
rxSignalInfo.snr = snr;
|
||||
rxSignalInfo.rssi = signalNoiseIt->second.signal; //same information for all MPDUs
|
||||
m_state->SwitchFromRxEndOk (Copy (psdu), rxSignalInfo, txVector, staId, statusPerMpduIt->second);
|
||||
m_previouslyRxPpduUid = event->GetPpdu ()->GetUid (); //store UID only if reception is successful (because otherwise trigger won't be read by MAC layer)
|
||||
}
|
||||
else
|
||||
{
|
||||
m_state->SwitchFromRxEndError (Copy (psdu), snr);
|
||||
}
|
||||
|
||||
if (ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU)
|
||||
{
|
||||
for (auto it = m_endRxEvents.begin (); it != m_endRxEvents.end (); )
|
||||
{
|
||||
if (it->IsExpired ())
|
||||
{
|
||||
it = m_endRxEvents.erase (it);
|
||||
}
|
||||
else
|
||||
{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
if (m_endRxEvents.empty ())
|
||||
{
|
||||
//We got the last PPDU of the UL-OFDMA transmission
|
||||
m_interference.NotifyRxEnd (Simulator::Now ());
|
||||
m_signalNoiseMap.clear ();
|
||||
m_statusPerMpduMap.clear ();
|
||||
for (const auto & endOfMpduEvent : m_endOfMpduEvents)
|
||||
{
|
||||
NS_ASSERT (endOfMpduEvent.IsExpired ());
|
||||
}
|
||||
m_endOfMpduEvents.clear ();
|
||||
Reset ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_interference.NotifyRxEnd (Simulator::Now ());
|
||||
MaybeCcaBusyDuration (GetMeasurementChannelWidth (ppdu));
|
||||
m_currentEvent = 0;
|
||||
m_currentPreambleEvents.clear ();
|
||||
m_endRxEvents.clear ();
|
||||
m_signalNoiseMap.clear ();
|
||||
m_statusPerMpduMap.clear ();
|
||||
for (const auto & endOfMpduEvent : m_endOfMpduEvents)
|
||||
{
|
||||
NS_ASSERT (endOfMpduEvent.IsExpired ());
|
||||
}
|
||||
m_endOfMpduEvents.clear ();
|
||||
}
|
||||
MaybeCcaBusyDuration (GetMeasurementChannelWidth (ppdu));
|
||||
}
|
||||
|
||||
std::pair<bool, SignalNoiseDbm>
|
||||
WifiPhy::GetReceptionStatus (Ptr<const WifiPsdu> psdu, Ptr<Event> event, uint16_t staId,
|
||||
Time relativeMpduStart, Time mpduDuration)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << *psdu << *event << staId << relativeMpduStart << mpduDuration);
|
||||
uint16_t channelWidth = std::min (GetChannelWidth (), event->GetTxVector ().GetChannelWidth ());
|
||||
WifiTxVector txVector = event->GetTxVector ();
|
||||
WifiSpectrumBand band;
|
||||
if (txVector.IsMu ())
|
||||
{
|
||||
band = GetRuBand (txVector, staId);
|
||||
channelWidth = HeRu::GetBandwidth (txVector.GetRu (staId).ruType);
|
||||
}
|
||||
else
|
||||
{
|
||||
band = GetBand (channelWidth);
|
||||
}
|
||||
PhyEntity::SnrPer snrPer = m_interference.CalculatePayloadSnrPer (event, channelWidth, band, staId, std::make_pair (relativeMpduStart, relativeMpduStart + mpduDuration));
|
||||
|
||||
WifiMode mode = event->GetTxVector ().GetMode (staId);
|
||||
NS_LOG_DEBUG ("rate=" << (mode.GetDataRate (event->GetTxVector (), staId)) <<
|
||||
", SNR(dB)=" << RatioToDb (snrPer.snr) << ", PER=" << snrPer.per << ", size=" << psdu->GetSize () <<
|
||||
", relativeStart = " << relativeMpduStart.As (Time::NS) << ", duration = " << mpduDuration.As (Time::NS));
|
||||
|
||||
// There are two error checks: PER and receive error model check.
|
||||
// PER check models is typical for Wi-Fi and is based on signal modulation;
|
||||
// Receive error model is optional, if we have an error model and
|
||||
// it indicates that the packet is corrupt, drop the packet.
|
||||
SignalNoiseDbm signalNoise;
|
||||
signalNoise.signal = WToDbm (event->GetRxPowerW (band));
|
||||
signalNoise.noise = WToDbm (event->GetRxPowerW (band) / snrPer.snr);
|
||||
if (m_random->GetValue () > snrPer.per &&
|
||||
!(m_postReceptionErrorModel && m_postReceptionErrorModel->IsCorrupt (psdu->GetPacket ()->Copy ())))
|
||||
{
|
||||
NS_LOG_DEBUG ("Reception succeeded: " << psdu);
|
||||
return std::make_pair (true, signalNoise);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("Reception failed: " << psdu);
|
||||
return std::make_pair (false, signalNoise);
|
||||
}
|
||||
}
|
||||
|
||||
WifiSpectrumBand
|
||||
WifiPhy::GetRuBand (WifiTxVector txVector, uint16_t staId) const
|
||||
{
|
||||
NS_ASSERT (txVector.IsMu ());
|
||||
WifiSpectrumBand band;
|
||||
HeRu::RuSpec ru = txVector.GetRu (staId);
|
||||
uint16_t channelWidth = txVector.GetChannelWidth ();
|
||||
NS_ASSERT (channelWidth <= GetChannelWidth ());
|
||||
HeRu::SubcarrierGroup group = HeRu::GetSubcarrierGroup (channelWidth, ru.ruType, ru.index);
|
||||
HeRu::SubcarrierRange range = std::make_pair (group.front ().first, group.back ().second);
|
||||
band = ConvertHeRuSubcarriers (channelWidth, range);
|
||||
return band;
|
||||
}
|
||||
|
||||
WifiSpectrumBand
|
||||
WifiPhy::GetNonOfdmaBand (WifiTxVector txVector, uint16_t staId) const
|
||||
{
|
||||
NS_ASSERT (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB);
|
||||
uint16_t channelWidth = txVector.GetChannelWidth ();
|
||||
NS_ASSERT (channelWidth <= GetChannelWidth ());
|
||||
|
||||
HeRu::RuSpec ru = txVector.GetRu (staId);
|
||||
uint16_t ruWidth = HeRu::GetBandwidth (ru.ruType);
|
||||
uint16_t nonOfdmaWidth = ruWidth < 20 ? 20 : ruWidth;
|
||||
|
||||
// Find the RU that encompasses the non-OFDMA part of the HE TB PPDU for the STA-ID
|
||||
HeRu::RuSpec nonOfdmaRu = HeRu::FindOverlappingRu (channelWidth, ru, HeRu::GetRuType (nonOfdmaWidth));
|
||||
|
||||
HeRu::SubcarrierGroup groupPreamble = HeRu::GetSubcarrierGroup (channelWidth, nonOfdmaRu.ruType, nonOfdmaRu.index);
|
||||
HeRu::SubcarrierRange range = std::make_pair (groupPreamble.front ().first, groupPreamble.back ().second);
|
||||
return ConvertHeRuSubcarriers (channelWidth, range);
|
||||
}
|
||||
|
||||
WifiSpectrumBand
|
||||
WifiPhy::ConvertHeRuSubcarriers (uint16_t channelWidth, HeRu::SubcarrierRange range) const
|
||||
{
|
||||
@@ -2816,23 +2240,11 @@ void
|
||||
WifiPhy::ResetReceive (Ptr<Event> event)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << *event);
|
||||
Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
|
||||
if (ppdu->GetType () != WIFI_PPDU_TYPE_UL_MU)
|
||||
{
|
||||
NS_ASSERT (event->GetEndTime () == Simulator::Now ());
|
||||
}
|
||||
NS_ASSERT (!IsStateRx ());
|
||||
NS_ASSERT (m_endRxEvents.size () == 1 && m_endRxEvents.front ().IsExpired ());
|
||||
m_endRxEvents.clear ();
|
||||
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));
|
||||
MaybeCcaBusyDuration (GetMeasurementChannelWidth (event->GetPpdu ()));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -3054,33 +2466,14 @@ WifiPhy::AbortCurrentReception (WifiPhyRxfailureReason reason)
|
||||
NS_LOG_FUNCTION (this << reason);
|
||||
if (reason != OBSS_PD_CCA_RESET || m_currentEvent) //Otherwise abort has already been called just before with FILTERED reason
|
||||
{
|
||||
for (auto & endPreambleDetectionEvent : m_endPreambleDetectionEvents)
|
||||
for (auto & phyEntity : m_phyEntities)
|
||||
{
|
||||
if (endPreambleDetectionEvent.IsRunning ())
|
||||
{
|
||||
endPreambleDetectionEvent.Cancel ();
|
||||
}
|
||||
phyEntity.second->CancelAllEvents ();
|
||||
}
|
||||
m_endPreambleDetectionEvents.clear ();
|
||||
if (m_endPhyRxEvent.IsRunning ())
|
||||
{
|
||||
m_endPhyRxEvent.Cancel ();
|
||||
}
|
||||
for (auto & endMpduEvent : m_endOfMpduEvents)
|
||||
{
|
||||
endMpduEvent.Cancel ();
|
||||
}
|
||||
m_endOfMpduEvents.clear ();
|
||||
for (auto & endRxEvent : m_endRxEvents)
|
||||
{
|
||||
endRxEvent.Cancel ();
|
||||
}
|
||||
m_endRxEvents.clear ();
|
||||
for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
|
||||
{
|
||||
beginOfdmaPayloadRxEvent.second.Cancel ();
|
||||
}
|
||||
m_beginOfdmaPayloadRxEvents.clear ();
|
||||
m_interference.NotifyRxEnd (Simulator::Now ());
|
||||
if (!m_currentEvent)
|
||||
{
|
||||
@@ -3158,26 +2551,6 @@ WifiPhy::GetTxPowerForTransmission (WifiTxVector txVector, uint16_t staId /* = S
|
||||
return txPowerDbm;
|
||||
}
|
||||
|
||||
void
|
||||
WifiPhy::StartRx (Ptr<Event> event)
|
||||
{
|
||||
//TODO: To move to StartReceivePreamble (and include the logic therein)
|
||||
WifiModulationClass modulation = event->GetTxVector ().GetModulationClass ();
|
||||
auto it = m_phyEntities.find (modulation);
|
||||
if (it != m_phyEntities.end ())
|
||||
{
|
||||
it->second->StartReceiveField (WIFI_PPDU_FIELD_PREAMBLE, event);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("Unsupported modulation received (" << modulation << "), consider as noise");
|
||||
if (event->GetEndTime () > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
|
||||
{
|
||||
MaybeCcaBusyDuration (GetMeasurementChannelWidth (nullptr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ptr<const WifiPsdu>
|
||||
WifiPhy::GetAddressedPsduInPpdu (Ptr<const WifiPpdu> ppdu) const
|
||||
{
|
||||
@@ -3188,24 +2561,8 @@ WifiPhy::GetAddressedPsduInPpdu (Ptr<const WifiPpdu> ppdu) const
|
||||
uint16_t
|
||||
WifiPhy::GetStaId (const Ptr<const WifiPpdu> ppdu) const
|
||||
{
|
||||
uint16_t staId = SU_STA_ID;
|
||||
if (ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU)
|
||||
{
|
||||
staId = ppdu->GetStaId ();
|
||||
}
|
||||
else if (ppdu->GetType () == WIFI_PPDU_TYPE_DL_MU)
|
||||
{
|
||||
Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (GetDevice ());
|
||||
if (device)
|
||||
{
|
||||
Ptr<StaWifiMac> mac = DynamicCast<StaWifiMac> (device->GetMac ());
|
||||
if (mac && mac->IsAssociated ())
|
||||
{
|
||||
return mac->GetAssociationId ();
|
||||
}
|
||||
}
|
||||
}
|
||||
return staId;
|
||||
//TODO: wrapper. See if still needed
|
||||
return GetPhyEntity (ppdu->GetModulation ())->GetStaId (ppdu);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
@@ -3243,20 +2600,6 @@ WifiPhy::GetBand (uint16_t /*bandWidth*/, uint8_t /*bandIndex*/)
|
||||
return band;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
WifiPhy::ConvertHeTbPpduDurationToLSigLength (Time ppduDuration, WifiPhyBand band)
|
||||
{
|
||||
return DynamicCast<const HePhy> (GetStaticPhyEntity (WIFI_MOD_CLASS_HE))->ConvertHeTbPpduDurationToLSigLength (ppduDuration, band);
|
||||
}
|
||||
|
||||
Time
|
||||
WifiPhy::ConvertLSigLengthToHeTbPpduDuration (uint16_t length, WifiTxVector txVector, WifiPhyBand band)
|
||||
{
|
||||
NS_ASSERT (txVector.GetModulationClass () == WIFI_MOD_CLASS_HE);
|
||||
auto hePhy = DynamicCast<const HePhy> (GetStaticPhyEntity (txVector.GetModulationClass ()));
|
||||
return (hePhy ? hePhy->ConvertLSigLengthToHeTbPpduDuration (length, txVector, band) : NanoSeconds (0));
|
||||
}
|
||||
|
||||
int64_t
|
||||
WifiPhy::AssignStreams (int64_t stream)
|
||||
{
|
||||
|
||||
@@ -121,30 +121,11 @@ public:
|
||||
*
|
||||
* \param ppdu the arriving PPDU
|
||||
* \param rxPowersW the receive power in W per band
|
||||
* \param rxDuration the duration of the PPDU
|
||||
* \param psdFlag the flag indicating the type of Tx PSD to build
|
||||
*/
|
||||
void StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxPowersW);
|
||||
|
||||
/**
|
||||
* Start receiving the PSDU (i.e. the first symbol of the PSDU has arrived).
|
||||
*
|
||||
* \param event the event holding incoming PPDU's information
|
||||
*/
|
||||
void StartReceivePayload (Ptr<Event> event);
|
||||
|
||||
/**
|
||||
* Start receiving the PSDU (i.e. the first symbol of the PSDU has arrived) of an UL-OFDMA transmission.
|
||||
* This function is called upon the RX event corresponding to the OFDMA part of the UL MU PPDU.
|
||||
*
|
||||
* \param event the event holding incoming OFDMA part of the PPDU's information
|
||||
*/
|
||||
void StartReceiveOfdmaPayload (Ptr<Event> event);
|
||||
|
||||
/**
|
||||
* The last symbol of the PPDU has arrived.
|
||||
*
|
||||
* \param event the event holding incoming PPDU's information
|
||||
*/
|
||||
void EndReceive (Ptr<Event> event);
|
||||
void StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxPowersW,
|
||||
Time rxDuration, TxPsdFlag psdFlag = PSD_NON_HE_TB);
|
||||
|
||||
/**
|
||||
* Reset PHY at the end of the packet under reception after it has failed the PHY header.
|
||||
@@ -251,23 +232,6 @@ public:
|
||||
*/
|
||||
Time GetLastRxEndTime (void) const;
|
||||
|
||||
/**
|
||||
* \param ppduDuration the duration of the HE TB PPDU
|
||||
* \param band the frequency band being used
|
||||
*
|
||||
* \return the L-SIG length value corresponding to that HE TB PPDU duration.
|
||||
*/
|
||||
static uint16_t ConvertHeTbPpduDurationToLSigLength (Time ppduDuration, WifiPhyBand band);
|
||||
|
||||
/**
|
||||
* \param length the L-SIG length value
|
||||
* \param txVector the TXVECTOR used for the transmission of this HE TB PPDU
|
||||
* \param band the frequency band being used
|
||||
*
|
||||
* \return the duration of the HE TB PPDU corresponding to that L-SIG length value.
|
||||
*/
|
||||
static Time ConvertLSigLengthToHeTbPpduDuration (uint16_t length, WifiTxVector txVector, WifiPhyBand band);
|
||||
|
||||
/**
|
||||
* \param size the number of bytes in the packet to send
|
||||
* \param txVector the TXVECTOR used for the transmission of this packet
|
||||
@@ -1042,24 +1006,6 @@ 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) const;
|
||||
/**
|
||||
* Get the band used to transmit the non-OFDMA part of an HE TB PPDU.
|
||||
*
|
||||
* \param txVector the TXVECTOR used for the transmission
|
||||
* \param staId the STA-ID of the station taking part of the UL MU
|
||||
*
|
||||
* \return the spectrum band used to transmit the non-OFDMA part of an HE TB PPDU
|
||||
*/
|
||||
WifiSpectrumBand GetNonOfdmaBand (WifiTxVector txVector, uint16_t staId) const;
|
||||
|
||||
/**
|
||||
* \param channelWidth the total channel width (MHz) used for the OFDMA transmission
|
||||
@@ -1141,6 +1087,7 @@ protected:
|
||||
* \param channelWidth the channel width in MHz used for RSSI measurement
|
||||
*/
|
||||
void SwitchMaybeToCcaBusy (uint16_t channelWidth);
|
||||
|
||||
/**
|
||||
* Return the STA ID that has been assigned to the station this PHY belongs to.
|
||||
* This is typically called for MU PPDUs, in order to pick the correct PSDU.
|
||||
@@ -1149,6 +1096,7 @@ protected:
|
||||
* \return the STA ID
|
||||
*/
|
||||
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
|
||||
@@ -1202,11 +1150,6 @@ protected:
|
||||
EventId m_endPhyRxEvent; //!< the end of PHY receive event
|
||||
EventId m_endTxEvent; //!< the end of transmit event
|
||||
|
||||
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
|
||||
|
||||
@@ -1345,45 +1288,6 @@ private:
|
||||
*/
|
||||
void MaybeCcaBusyDuration (uint16_t channelWidth);
|
||||
|
||||
/**
|
||||
* Starting receiving the PPDU after having detected the medium is idle or after a reception switch.
|
||||
*
|
||||
* \param event the event holding incoming PPDU's information
|
||||
*/
|
||||
void StartRx (Ptr<Event> event);
|
||||
/**
|
||||
* Get the reception status for the provided MPDU and notify.
|
||||
*
|
||||
* \param psdu the arriving MPDU formatted as a PSDU
|
||||
* \param event the event holding incoming PPDU's information
|
||||
* \param staId the station ID of the PSDU (only used for MU)
|
||||
* \param relativeMpduStart the relative start time of the MPDU within the A-MPDU. 0 for normal MPDUs
|
||||
* \param mpduDuration the duration of the MPDU
|
||||
*
|
||||
* \return information on MPDU reception: status, signal power (dBm), and noise power (in dBm)
|
||||
*/
|
||||
std::pair<bool, SignalNoiseDbm> GetReceptionStatus (Ptr<const WifiPsdu> psdu,
|
||||
Ptr<Event> event, uint16_t staId,
|
||||
Time relativeMpduStart,
|
||||
Time mpduDuration);
|
||||
/**
|
||||
* The last symbol of an MPDU in an A-MPDU has arrived.
|
||||
*
|
||||
* \param event the event holding incoming PPDU's information
|
||||
* \param psdu the arriving MPDU formatted as a PSDU containing a normal MPDU
|
||||
* \param mpduIndex the index of the MPDU within the A-MPDU
|
||||
* \param relativeMpduStart the relative start time of the MPDU within the A-MPDU.
|
||||
* \param mpduDuration the duration of the MPDU
|
||||
*/
|
||||
void EndOfMpdu (Ptr<Event> event, Ptr<const WifiPsdu> psdu, size_t mpduIndex, Time relativeStart, Time mpduDuration);
|
||||
|
||||
/**
|
||||
* Schedule end of MPDUs events.
|
||||
*
|
||||
* \param event the event holding incoming PPDU's information
|
||||
*/
|
||||
void ScheduleEndOfMpdus (Ptr<Event> event);
|
||||
|
||||
/**
|
||||
* Get the PSDU addressed to that PHY in a PPDU (useful for MU PPDU).
|
||||
*
|
||||
@@ -1392,17 +1296,6 @@ private:
|
||||
*/
|
||||
Ptr<const WifiPsdu> GetAddressedPsduInPpdu (Ptr<const WifiPpdu> ppdu) const;
|
||||
|
||||
/**
|
||||
* Drop the PPDU and the corresponding preamble detection event, but keep CCA busy
|
||||
* state after the completion of the currently processed event.
|
||||
*
|
||||
* \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, uint16_t measurementChannelWidth);
|
||||
|
||||
/**
|
||||
* The trace source fired when a packet begins the transmission process on
|
||||
* the medium.
|
||||
@@ -1567,16 +1460,6 @@ private:
|
||||
Ptr<ErrorModel> m_postReceptionErrorModel; //!< Error model for receive packet events
|
||||
Time m_timeLastPreambleDetected; //!< Record the time the last preamble was detected
|
||||
|
||||
std::vector <EventId> m_endOfMpduEvents; //!< the end of MPDU events (only used for A-MPDUs)
|
||||
|
||||
/**
|
||||
* A pair of a UID and STA_ID
|
||||
*/
|
||||
typedef std::pair <uint64_t /* uid */, uint16_t /* staId */> UidStaIdPair;
|
||||
|
||||
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)
|
||||
|
||||
Callback<void> m_capabilitiesChangedCallback; //!< Callback when PHY capabilities changed
|
||||
};
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ YansWifiChannel::Receive (Ptr<YansWifiPhy> phy, Ptr<WifiPpdu> ppdu, double rxPow
|
||||
}
|
||||
RxPowerWattPerChannelBand rxPowerW;
|
||||
rxPowerW.insert ({std::make_pair (0, 0), (DbmToW (rxPowerDbm + phy->GetRxGain ()))}); //dummy band for YANS
|
||||
phy->StartReceivePreamble (ppdu, rxPowerW);
|
||||
phy->StartReceivePreamble (ppdu, rxPowerW, ppdu->GetTxDuration ());
|
||||
}
|
||||
|
||||
std::size_t
|
||||
|
||||
@@ -56,6 +56,58 @@ 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)
|
||||
|
||||
/**
|
||||
* HE PHY slightly modified so as to return a given
|
||||
* STA-ID in case of DL MU for OfdmaSpectrumWifiPhy.
|
||||
*/
|
||||
class OfdmaTestHePhy : public HePhy
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param staId the ID of the STA to which this PHY belongs to
|
||||
*/
|
||||
OfdmaTestHePhy (uint16_t staId);
|
||||
virtual ~OfdmaTestHePhy ();
|
||||
|
||||
/**
|
||||
* Return the STA ID that has been assigned to the station this PHY belongs to.
|
||||
* This is typically called for MU PPDUs, in order to pick the correct PSDU.
|
||||
*
|
||||
* \param ppdu the PPDU for which the STA ID is requested
|
||||
* \return the STA ID
|
||||
*/
|
||||
uint16_t GetStaId (const Ptr<const WifiPpdu> ppdu) const override;
|
||||
|
||||
|
||||
private:
|
||||
uint16_t m_staId; ///< ID of the STA to which this PHY belongs to
|
||||
}; //class OfdmaTestHePhy
|
||||
|
||||
OfdmaTestHePhy::OfdmaTestHePhy (uint16_t staId)
|
||||
: HePhy (),
|
||||
m_staId (staId)
|
||||
{
|
||||
}
|
||||
|
||||
OfdmaTestHePhy::~OfdmaTestHePhy ()
|
||||
{
|
||||
}
|
||||
|
||||
uint16_t
|
||||
OfdmaTestHePhy::GetStaId (const Ptr<const WifiPpdu> ppdu) const
|
||||
{
|
||||
if (ppdu->GetType () == WIFI_PPDU_TYPE_DL_MU)
|
||||
{
|
||||
return m_staId;
|
||||
}
|
||||
return HePhy::GetStaId (ppdu);
|
||||
}
|
||||
|
||||
/**
|
||||
* SpectrumWifiPhy used for testing OFDMA.
|
||||
*/
|
||||
class OfdmaSpectrumWifiPhy : public SpectrumWifiPhy
|
||||
{
|
||||
public:
|
||||
@@ -72,6 +124,9 @@ public:
|
||||
OfdmaSpectrumWifiPhy (uint16_t staId);
|
||||
virtual ~OfdmaSpectrumWifiPhy ();
|
||||
|
||||
// Inherited
|
||||
virtual void DoInitialize (void) override;
|
||||
|
||||
using WifiPhy::Reset;
|
||||
|
||||
/**
|
||||
@@ -125,13 +180,15 @@ public:
|
||||
*/
|
||||
Time GetEnergyDuration (double energyW, WifiSpectrumBand band);
|
||||
|
||||
private:
|
||||
// Inherited
|
||||
uint16_t GetStaId (const Ptr<const WifiPpdu> ppdu) const override;
|
||||
/**
|
||||
* \return a const pointer to the HE PHY instance
|
||||
*/
|
||||
Ptr<const HePhy> GetHePhy (void) const;
|
||||
|
||||
private:
|
||||
uint16_t m_staId; ///< ID of the STA to which this PHY belongs to
|
||||
TracedCallback<uint64_t> m_phyTxPpduUidTrace; //!< Callback providing UID of the PPDU that is about to be transmitted
|
||||
};
|
||||
}; //class OfdmaSpectrumWifiPhy
|
||||
|
||||
TypeId
|
||||
OfdmaSpectrumWifiPhy::GetTypeId (void)
|
||||
@@ -157,14 +214,14 @@ OfdmaSpectrumWifiPhy::~OfdmaSpectrumWifiPhy()
|
||||
{
|
||||
}
|
||||
|
||||
uint16_t
|
||||
OfdmaSpectrumWifiPhy::GetStaId (const Ptr<const WifiPpdu> ppdu) const
|
||||
void
|
||||
OfdmaSpectrumWifiPhy::DoInitialize (void)
|
||||
{
|
||||
if (ppdu->GetType () == WIFI_PPDU_TYPE_DL_MU)
|
||||
{
|
||||
return m_staId;
|
||||
}
|
||||
return SpectrumWifiPhy::GetStaId (ppdu);
|
||||
//Replace HE PHY instance with test instance
|
||||
Ptr<OfdmaTestHePhy> hePhy = Create<OfdmaTestHePhy> (m_staId);
|
||||
hePhy->SetOwner (this);
|
||||
m_phyEntities[WIFI_MOD_CLASS_HE] = hePhy;
|
||||
SpectrumWifiPhy::DoInitialize ();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -213,6 +270,12 @@ OfdmaSpectrumWifiPhy::GetEnergyDuration (double energyW, WifiSpectrumBand band)
|
||||
return m_interference.GetEnergyDuration (energyW, band);
|
||||
}
|
||||
|
||||
Ptr<const HePhy>
|
||||
OfdmaSpectrumWifiPhy::GetHePhy (void) const
|
||||
{
|
||||
return DynamicCast<const HePhy> (GetPhyEntity (WIFI_MOD_CLASS_HE));
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup wifi-test
|
||||
* \ingroup tests
|
||||
@@ -1152,8 +1215,8 @@ TestUlOfdmaPpduUid::SendTbPpdu (void)
|
||||
m_phySta1->GetPhyBand (), rxStaId2);
|
||||
Time txDuration = std::max (txDuration1, txDuration2);
|
||||
|
||||
txVector1.SetLength (m_phySta1->ConvertHeTbPpduDurationToLSigLength (txDuration, m_phySta1->GetPhyBand ()));
|
||||
txVector2.SetLength (m_phySta2->ConvertHeTbPpduDurationToLSigLength (txDuration, m_phySta2->GetPhyBand ()));
|
||||
txVector1.SetLength (HePhy::ConvertHeTbPpduDurationToLSigLength (txDuration, m_phySta1->GetPhyBand ()));
|
||||
txVector2.SetLength (HePhy::ConvertHeTbPpduDurationToLSigLength (txDuration, m_phySta2->GetPhyBand ()));
|
||||
|
||||
m_phySta1->Send (psdus1, txVector1);
|
||||
m_phySta2->Send (psdus2, txVector2);
|
||||
@@ -1390,7 +1453,7 @@ TestMultipleHeTbPreambles::RxHeTbPpdu (uint64_t uid, uint16_t staId, double txPo
|
||||
m_phy->StartRx (rxParams);
|
||||
|
||||
//Schedule OFDMA part
|
||||
WifiSpectrumBand band = m_phy->GetRuBand (txVector, staId);
|
||||
WifiSpectrumBand band = m_phy->GetHePhy ()->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;
|
||||
@@ -1861,7 +1924,7 @@ TestUlOfdmaPhyTransmission::SendHeTbPpdu (uint16_t txStaId, std::size_t index, s
|
||||
}
|
||||
|
||||
Time txDuration = phy->CalculateTxDuration (psdu->GetSize (), txVector, phy->GetPhyBand (), txStaId);
|
||||
txVector.SetLength (phy->ConvertHeTbPpduDurationToLSigLength (txDuration, phy->GetPhyBand ()));
|
||||
txVector.SetLength (HePhy::ConvertHeTbPpduDurationToLSigLength (txDuration, phy->GetPhyBand ()));
|
||||
|
||||
phy->SetPpduUid (uid);
|
||||
phy->Send (psdus, txVector);
|
||||
@@ -2182,10 +2245,12 @@ TestUlOfdmaPhyTransmission::SchedulePowerMeasurementChecks (Time delay, double r
|
||||
Time nonOfdmaDuration = m_phyAp->CalculateNonOfdmaDurationForHeTb (txVectorSta2);
|
||||
NS_ASSERT (nonOfdmaDuration == m_phyAp->CalculateNonOfdmaDurationForHeTb (txVectorSta1));
|
||||
|
||||
Ptr<const HePhy> hePhy = m_phyAp->GetHePhy ();
|
||||
|
||||
std::vector<double> rxPowerNonOfdma { rxPowerNonOfdmaRu1, rxPowerNonOfdmaRu2 };
|
||||
std::vector<WifiSpectrumBand> nonOfdmaBand { m_phyAp->GetNonOfdmaBand (txVectorSta1, 1), m_phyAp->GetNonOfdmaBand (txVectorSta2, 2) };
|
||||
std::vector<WifiSpectrumBand> nonOfdmaBand { hePhy->GetNonOfdmaBand (txVectorSta1, 1), hePhy->GetNonOfdmaBand (txVectorSta2, 2) };
|
||||
std::vector<double> rxPowerOfdma { rxPowerOfdmaRu1, rxPowerOfdmaRu2 };
|
||||
std::vector<WifiSpectrumBand> ofdmaBand { m_phyAp->GetRuBand (txVectorSta1, 1), m_phyAp->GetRuBand (txVectorSta2, 2) };
|
||||
std::vector<WifiSpectrumBand> ofdmaBand { hePhy->GetRuBand (txVectorSta1, 1), hePhy->GetRuBand (txVectorSta2, 2) };
|
||||
|
||||
for (uint8_t i = 0; i < 2; ++i)
|
||||
{
|
||||
@@ -2824,7 +2889,7 @@ TestPhyPaddingExclusion::SendHeTbPpdu (uint16_t txStaId, std::size_t index, std:
|
||||
phy = m_phySta2;
|
||||
}
|
||||
|
||||
txVector.SetLength (phy->ConvertHeTbPpduDurationToLSigLength (txDuration, phy->GetPhyBand ()));
|
||||
txVector.SetLength (HePhy::ConvertHeTbPpduDurationToLSigLength (txDuration, phy->GetPhyBand ()));
|
||||
|
||||
phy->SetPpduUid (0);
|
||||
phy->Send (psdus, txVector);
|
||||
@@ -3200,7 +3265,7 @@ TestUlOfdmaPowerControl::SendMuBar (std::vector <uint16_t> staIds)
|
||||
//Build MU-BAR trigger frame
|
||||
CtrlTriggerHeader muBar;
|
||||
muBar.SetType (MU_BAR_TRIGGER);
|
||||
muBar.SetUlLength (WifiPhy::ConvertHeTbPpduDurationToLSigLength (MicroSeconds (120), WIFI_PHY_BAND_5GHZ));
|
||||
muBar.SetUlLength (HePhy::ConvertHeTbPpduDurationToLSigLength (MicroSeconds (128), WIFI_PHY_BAND_5GHZ));
|
||||
muBar.SetMoreTF (true);
|
||||
muBar.SetCsRequired (true);
|
||||
muBar.SetUlBandwidth (DEFAULT_CHANNEL_WIDTH);
|
||||
|
||||
Reference in New Issue
Block a user