diff --git a/src/wifi/model/wifi-phy-state-helper.cc b/src/wifi/model/wifi-phy-state-helper.cc index 9d5943a60..74343d1c8 100644 --- a/src/wifi/model/wifi-phy-state-helper.cc +++ b/src/wifi/model/wifi-phy-state-helper.cc @@ -593,7 +593,7 @@ void WifiPhyStateHelper::SwitchFromRxAbort (void) { NS_LOG_FUNCTION (this); - NS_ASSERT (IsStateRx ()); + NS_ASSERT (IsStateRx () || IsStateCcaBusy ()); //because abort can happen before RX is set by payload start NotifyRxEndOk (); DoSwitchFromRx (); m_endCcaBusy = Simulator::Now (); diff --git a/src/wifi/model/wifi-phy.cc b/src/wifi/model/wifi-phy.cc index da47cba65..fc0d54baf 100644 --- a/src/wifi/model/wifi-phy.cc +++ b/src/wifi/model/wifi-phy.cc @@ -3004,7 +3004,7 @@ WifiPhy::StartReceiveHeader (Ptr event) m_currentEvent = event; double snr = m_interference.CalculateSnr (m_currentEvent, measurementChannelWidth, 1, measurementBand); - NS_LOG_DEBUG ("SNR(dB)=" << RatioToDb (snr) << " at start of legacy PHY header"); + NS_LOG_DEBUG ("SNR(dB)=" << RatioToDb (snr) << " at start of non-HT preamble"); Time headerPayloadDuration = m_currentEvent->GetStartTime () + m_currentEvent->GetPpdu ()->GetTxDuration () - Simulator::Now (); @@ -3052,10 +3052,10 @@ WifiPhy::StartReceiveHeader (Ptr event) if (txVector.GetPreambleType () == WIFI_PREAMBLE_HT_GF) { - //No non-HT PHY header for HT GF - Time remainingPreambleHeaderDuration = CalculatePhyPreambleAndHeaderDuration (txVector) - (Simulator::Now () - m_currentEvent->GetStartTime ()); + //No non-HT PHY header for HT GF, in addition, remaining HT-LTFs follow after HT-SIG + Time remainingPreambleHeaderDuration = GetPhyPreambleDuration (txVector) + GetPhyHtSigHeaderDuration (WIFI_PREAMBLE_HT_GF) - (Simulator::Now () - m_currentEvent->GetStartTime ()); m_state->SwitchMaybeToCcaBusy (remainingPreambleHeaderDuration); - m_endPhyRxEvent = Simulator::Schedule (remainingPreambleHeaderDuration, &WifiPhy::StartReceivePayload, this, m_currentEvent); + m_endPhyRxEvent = Simulator::Schedule (remainingPreambleHeaderDuration, &WifiPhy::EndReceiveCommonHeader, this, m_currentEvent); } else { @@ -3089,15 +3089,16 @@ WifiPhy::ContinueReceiveHeader (Ptr event) 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); + NS_LOG_DEBUG ("L-SIG/RL-SIG: SNR(dB)=" << RatioToDb (snrPer.snr) << ", PER=" << snrPer.per); if (m_random->GetValue () > snrPer.per) //non-HT PHY header reception succeeded { NS_LOG_DEBUG ("Received non-HT PHY header"); WifiTxVector txVector = event->GetTxVector (); Time remainingRxDuration = event->GetEndTime () - Simulator::Now (); m_state->SwitchMaybeToCcaBusy (remainingRxDuration); - Time remainingPreambleHeaderDuration = CalculatePhyPreambleAndHeaderDuration (txVector) - GetPhyPreambleDuration (txVector) - GetPhyHeaderDuration (txVector); - m_endPhyRxEvent = Simulator::Schedule (remainingPreambleHeaderDuration, &WifiPhy::StartReceivePayload, this, event); + WifiPreamble preamble = txVector.GetPreambleType (); + Time headerDuration = GetPhyHtSigHeaderDuration (preamble) + GetPhySigA1Duration (preamble) + GetPhySigA2Duration (preamble); + m_endPhyRxEvent = Simulator::Schedule (headerDuration, &WifiPhy::EndReceiveCommonHeader, this, event); } else //non-HT PHY header reception failed { @@ -3328,138 +3329,247 @@ WifiPhy::StartReceiveOfdmaPayload (Ptr ppdu, RxPowerWattPerChannelBand } else { - //Don't do anything special for STAs since ResetReceive has already been scheduled by StartReceivePayload + NS_LOG_INFO ("Ignore reception of OFDMA payload since device is non-AP STA"); NS_ASSERT (m_endRxEvents.size () == 1 && m_endRxEvents.front ().IsRunning ()); } } +void +WifiPhy::EndReceiveCommonHeader (Ptr event) +{ + NS_LOG_FUNCTION (this << *event); + NS_ASSERT (m_endPhyRxEvent.IsExpired ()); + Ptr ppdu = event->GetPpdu (); + WifiModulationClass modulation = ppdu->GetModulation (); + //calculate PER on the measurement channel for PHY headers + uint16_t measurementChannelWidth = GetMeasurementChannelWidth (ppdu); + auto measurementBand = GetBand (measurementChannelWidth); + bool commonHeaderReceived = true; //If we are here, this means non-HT PHY header was already successfully received + if (modulation >= WIFI_MOD_CLASS_HT) + { + InterferenceHelper::SnrPer snrPer = m_interference.CalculateHtPhyHeaderSnrPer (event, measurementChannelWidth, measurementBand); + NS_LOG_DEBUG ("SIG-A/HT-SIG: SNR(dB)=" << RatioToDb (snrPer.snr) << ", PER=" << snrPer.per); + commonHeaderReceived = (m_random->GetValue () > snrPer.per); + } + WifiTxVector txVector = event->GetTxVector (); + bool success = false; + bool filteredOut = false; + if (commonHeaderReceived) //PHY reception succeeded + { + Ptr psdu = GetAddressedPsduInPpdu (ppdu); + if ((txVector.GetChannelWidth () >= 40) && (txVector.GetChannelWidth () > GetChannelWidth ())) + { + NS_LOG_DEBUG ("Packet reception could not be started because not enough channel width"); + NotifyRxDrop (psdu, UNSUPPORTED_SETTINGS); + } + + if (ppdu->IsDlMu ()) //Final decision on content of DL MU is reported to end of SIG-B (unless the PPDU is filtered) + { + if (psdu) //a valid pointer is returned only if BSS colors match + { + NS_LOG_INFO ("The BSS color of this DL MU PPDU matches device's. Schedule SIG-B reception."); + Time timeBetweenSigAAndSigB = (ppdu->GetModulation () == WIFI_MOD_CLASS_VHT) ? //SIG-B just before payload for VHT whereas before training for HE + GetPhyTrainingSymbolDuration (txVector) : + NanoSeconds (0); + m_endPhyRxEvent = Simulator::Schedule (timeBetweenSigAAndSigB + GetPhySigBDuration (txVector), + &WifiPhy::EndReceiveSigB, this, event); + success = true; + } + else + { + NS_LOG_DEBUG ("The BSS color of this DL MU PPDU does not match the device's. The PPDU is filtered."); + filteredOut = true; + m_phyRxPayloadBeginTrace (txVector, NanoSeconds (0)); //this callback (equivalent to PHY-RXSTART primitive) is also triggered for filtered PPDUs + } + } + else if (psdu) + { + success = ScheduleStartReceivePayload (event, GetPhyTrainingSymbolDuration (txVector)); + } + else + { + NS_ASSERT (ppdu->IsUlMu ()); + NS_LOG_DEBUG ("No PSDU addressed to that PHY in the received MU PPDU. The PPDU is filtered."); + filteredOut = true; + m_phyRxPayloadBeginTrace (txVector, NanoSeconds (0)); //this callback (equivalent to PHY-RXSTART primitive) is also triggered for filtered PPDUs + } + if (modulation == WIFI_MOD_CLASS_HE) + { + HePreambleParameters params; + params.rssiW = event->GetRxPowerW (measurementBand); + params.bssColor = event->GetTxVector ().GetBssColor (); + Simulator::Schedule (GetPhyTrainingSymbolDuration (txVector) + GetPhySigBDuration (txVector), + &WifiPhy::NotifyEndOfHePreamble, this, params); //TODO change this to immediate call since HE-SIG-A has been decoded + } + } + else //PHY reception failed + { + NS_LOG_DEBUG ("Drop packet because SIG-A or HT-SIG reception failed"); + NotifyRxDrop (GetAddressedPsduInPpdu (ppdu), SIG_A_FAILURE); + } + if (!success) + { + if (filteredOut) + { + AbortCurrentReception (FILTERED); //PHY-RXSTART is immediately followed by PHY-RXEND (Filtered) + if (event->GetEndTime () > (Simulator::Now () + m_state->GetDelayUntilIdle ())) + { + MaybeCcaBusyDuration (GetMeasurementChannelWidth (ppdu)); + } + } + else + { + Time remainingDuration = ppdu->GetTxDuration () - CalculatePhyPreambleAndHeaderDuration (txVector) + + GetPhyTrainingSymbolDuration (txVector) + GetPhySigBDuration (txVector); + m_endRxEvents.push_back (Simulator::Schedule (remainingDuration, + &WifiPhy::ResetReceive, this, event)); + } + } +} + +void +WifiPhy::EndReceiveSigB (Ptr event) +{ + NS_LOG_FUNCTION (this << *event); + NS_ASSERT (m_endPhyRxEvent.IsExpired ()); + Ptr ppdu = event->GetPpdu (); + WifiTxVector txVector = event->GetTxVector (); + NS_ASSERT (ppdu->IsDlMu ()); + + Time timeBetweenSigBAndPayload = (ppdu->GetModulation () == WIFI_MOD_CLASS_VHT) ? //SIG-B just before payload for VHT whereas before training for HE + NanoSeconds (0) : + GetPhyTrainingSymbolDuration (txVector); + + //calculate PER of SIG-B on measurement channel + uint16_t measurementChannelWidth = GetMeasurementChannelWidth (ppdu); + InterferenceHelper::SnrPer snrPer = m_interference.CalculateHtPhyHeaderSnrPer (event, measurementChannelWidth, GetBand (measurementChannelWidth)); + NS_LOG_DEBUG ("SIG-B: SNR(dB)=" << RatioToDb (snrPer.snr) << ", PER=" << snrPer.per); + + bool success = false; + bool filteredOut = false; + if (m_random->GetValue () > snrPer.per) //SIG-B decoding succeeded + { + Ptr psdu = GetAddressedPsduInPpdu (ppdu); + if (psdu) + { + success = ScheduleStartReceivePayload (event, timeBetweenSigBAndPayload); + } + else + { + NS_LOG_DEBUG ("No PSDU addressed to that PHY in the received MU PPDU. The PPDU is filtered."); + filteredOut = true; + m_phyRxPayloadBeginTrace (txVector, NanoSeconds (0)); //this callback (equivalent to PHY-RXSTART primitive) is also triggered for filtered PPDUs + } + } + else //PHY reception failed + { + NS_LOG_DEBUG ("Drop packet because SIG-B reception failed"); + NotifyRxDrop (GetAddressedPsduInPpdu (ppdu), SIG_B_FAILURE); + } + if (!success) + { + if (filteredOut) + { + AbortCurrentReception (FILTERED); //PHY-RXSTART is immediately followed by PHY-RXEND (Filtered) + if (event->GetEndTime () > (Simulator::Now () + m_state->GetDelayUntilIdle ())) + { + MaybeCcaBusyDuration (GetMeasurementChannelWidth (ppdu)); + } + } + else + { + Time remainingDuration = ppdu->GetTxDuration () - CalculatePhyPreambleAndHeaderDuration (txVector) + + timeBetweenSigBAndPayload; + m_endRxEvents.push_back (Simulator::Schedule (remainingDuration, + &WifiPhy::ResetReceive, this, event)); + } + } +} + +bool +WifiPhy::ScheduleStartReceivePayload (Ptr event, Time timeToPayloadStart) +{ + Ptr ppdu = event->GetPpdu (); + Ptr psdu = GetAddressedPsduInPpdu (ppdu); + NS_ASSERT (psdu); + WifiTxVector txVector = event->GetTxVector (); + uint16_t staId = GetStaId (ppdu); + WifiMode txMode = txVector.GetMode (staId); + uint8_t nss = txVector.GetNssMax(); + if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_MU) + { + for (auto info : txVector.GetHeMuUserInfoMap ()) + { + if (info.first == staId) + { + nss = info.second.nss; //no need to look at other PSDUs + break; + } + } + } + + bool success = false; + if (nss > GetMaxSupportedRxSpatialStreams ()) + { + NS_LOG_DEBUG ("Packet reception could not be started because not enough RX antennas"); + NotifyRxDrop (psdu, UNSUPPORTED_SETTINGS); + } + else if (IsModeSupported (txMode) || IsMcsSupported (txMode)) + { + NS_LOG_INFO ("SIG correctly decoded and with supported settings. Schedule start of payload."); + m_endPhyRxEvent = Simulator::Schedule (timeToPayloadStart, + &WifiPhy::StartReceivePayload, this, event); + + Ptr device = DynamicCast (GetDevice ()); + bool isAp = device != 0 && (DynamicCast (device->GetMac ()) != 0); + if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB && isAp) + { + m_currentHeTbPpduUid = ppdu->GetUid (); //to be able to correctly schedule start of OFDMA payload + } + success = true; + } + else //mode is not allowed + { + NS_LOG_DEBUG ("Drop packet because it was sent using an unsupported mode (" << txMode << ")"); + NotifyRxDrop (psdu, UNSUPPORTED_SETTINGS); + } + return success; +} + void WifiPhy::StartReceivePayload (Ptr event) { NS_LOG_FUNCTION (this << *event); NS_ASSERT (m_endPhyRxEvent.IsExpired ()); - bool canReceivePayload = false; Ptr ppdu = event->GetPpdu (); - WifiModulationClass modulation = ppdu->GetModulation (); - //calculate PER on the measurement channel for PHY headers - uint16_t measurementChannelWidth = GetMeasurementChannelWidth (ppdu); - auto measurementBand = GetBand (measurementChannelWidth); - - if (modulation >= WIFI_MOD_CLASS_HT) + 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 device = DynamicCast (GetDevice ()); + bool isAp = device != 0 && (DynamicCast (device->GetMac ()) != 0); + if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB && !isAp) { - 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); + 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)); } else { - //If we are here, this means non-HT PHY header was already successfully received - canReceivePayload = true; - } - WifiTxVector txVector = event->GetTxVector (); - Time payloadDuration = ppdu->GetTxDuration () - CalculatePhyPreambleAndHeaderDuration (txVector); - bool success = false; - if (canReceivePayload) //PHY reception succeeded - { - Ptr psdu = GetAddressedPsduInPpdu (ppdu); - if (psdu) + 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 ()}); + if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB) { - uint16_t staId = GetStaId (ppdu); - WifiMode txMode = txVector.GetMode (staId); - uint8_t nss = txVector.GetNssMax(); - if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_MU) - { - for (const auto & info : txVector.GetHeMuUserInfoMap ()) - { - if (info.first == staId) - { - nss = info.second.nss; //no need to look at other PSDUs - break; - } - } - } - - if (nss > GetMaxSupportedRxSpatialStreams ()) - { - NS_LOG_DEBUG ("Packet reception could not be started because not enough RX antennas"); - NotifyRxDrop (psdu, UNSUPPORTED_SETTINGS); - } - else if ((txVector.GetChannelWidth () >= 40) && (txVector.GetChannelWidth () > GetChannelWidth ())) - { - NS_LOG_DEBUG ("Packet reception could not be started because not enough channel width"); - NotifyRxDrop (psdu, UNSUPPORTED_SETTINGS); - } - else if (IsModeSupported (txMode) || IsMcsSupported (txMode)) - { - 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 device = DynamicCast (GetDevice ()); - bool isAp = device != 0 && (DynamicCast (device->GetMac ()) != 0); - if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB && !isAp) - { - NS_LOG_DEBUG ("Ignore UL-OFDMA (OFDMA part of HE TB PPDU) received by STA but keep state in Rx"); - m_currentHeTbPpduUid = ppdu->GetUid (); - //ResetReceive is scheduled below at end of PSDU - } - else - { - success = true; - NS_LOG_DEBUG ("Receiving PSDU"); - m_signalNoiseMap.insert ({std::make_pair (ppdu->GetUid (), staId), SignalNoiseDbm ()}); - m_statusPerMpduMap.insert ({std::make_pair (ppdu->GetUid (), staId), std::vector ()}); - if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB) - { - //for HE TB PPDUs, ScheduleEndOfMpdus and EndReceive are scheduled by StartReceiveOfdmaPayload - NS_ASSERT (isAp); - m_currentHeTbPpduUid = ppdu->GetUid (); - } - else - { - ScheduleEndOfMpdus (event); - m_endRxEvents.push_back (Simulator::Schedule (payloadDuration, &WifiPhy::EndReceive, this, event)); - } - } - } - else //mode is not allowed - { - NS_LOG_DEBUG ("Drop packet because it was sent using an unsupported mode (" << txMode << ")"); - NotifyRxDrop (GetAddressedPsduInPpdu (event->GetPpdu ()), UNSUPPORTED_SETTINGS); - } + //for HE TB PPDUs, ScheduleEndOfMpdus and EndReceive are scheduled by StartReceiveOfdmaPayload + NS_ASSERT (isAp); } else { - NS_ASSERT (ppdu->IsMu ()); - NS_LOG_DEBUG ("No PSDU addressed to that PHY in the received MU PPDU. The PPDU is filtered."); - payloadDuration = NanoSeconds (0); //so as to call AbortCurrentReception below - m_phyRxPayloadBeginTrace (txVector, payloadDuration); //this callback (equivalent to PHY-RXSTART primitive) is also triggered for filtered PPDUs - } - if (modulation == WIFI_MOD_CLASS_HE) - { - HePreambleParameters params; - params.rssiW = event->GetRxPowerW (measurementBand); - params.bssColor = event->GetTxVector ().GetBssColor (); - NotifyEndOfHePreamble (params); - } - } - else //PHY reception failed - { - NS_LOG_DEBUG ("Drop packet because HT PHY header reception failed"); - NotifyRxDrop (GetAddressedPsduInPpdu (ppdu), SIG_A_FAILURE); - } - if (!success) - { - if (payloadDuration.IsStrictlyPositive ()) - { - m_endRxEvents.push_back (Simulator::Schedule (payloadDuration, &WifiPhy::ResetReceive, this, event)); - } - else - { - AbortCurrentReception (FILTERED); //immediately followed by PHY-RXEND (Filtered) - if (event->GetEndTime () > (Simulator::Now () + m_state->GetDelayUntilIdle ())) - { - MaybeCcaBusyDuration (GetMeasurementChannelWidth (ppdu)); - } + ScheduleEndOfMpdus (event); + m_endRxEvents.push_back (Simulator::Schedule (payloadDuration, &WifiPhy::EndReceive, this, event)); } } } @@ -3498,7 +3608,10 @@ WifiPhy::ScheduleEndOfMpdus (Ptr event) } endOfMpduDuration += mpduDuration; - Simulator::Schedule (endOfMpduDuration, &WifiPhy::EndOfMpdu, this, event, Create (*mpdu, false), i, relativeStart, 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 (*mpdu, false), i, relativeStart, mpduDuration)); //Prepare next iteration ++i; @@ -5004,47 +5117,54 @@ void WifiPhy::AbortCurrentReception (WifiPhyRxfailureReason reason) { NS_LOG_FUNCTION (this << reason); - for (auto & endPreambleDetectionEvent : m_endPreambleDetectionEvents) + if (reason != OBSS_PD_CCA_RESET || m_currentEvent) //Otherwise abort has already been called just before with FILTERED reason { - if (endPreambleDetectionEvent.IsRunning ()) + for (auto & endPreambleDetectionEvent : m_endPreambleDetectionEvents) { - endPreambleDetectionEvent.Cancel (); + if (endPreambleDetectionEvent.IsRunning ()) + { + endPreambleDetectionEvent.Cancel (); + } } + 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 (); + m_interference.NotifyRxEnd (Simulator::Now ()); + if (!m_currentEvent) + { + return; + } + NotifyRxDrop (GetAddressedPsduInPpdu (m_currentEvent->GetPpdu ()), reason); + if (reason == OBSS_PD_CCA_RESET) + { + m_state->SwitchFromRxAbort (); + } + for (auto it = m_currentPreambleEvents.begin (); it != m_currentPreambleEvents.end (); ++it) + { + if (it->second == m_currentEvent) + { + it = m_currentPreambleEvents.erase (it); + break; + } + } + m_currentEvent = 0; } - 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 (); - m_interference.NotifyRxEnd (Simulator::Now ()); - if (!m_currentEvent) - { - return; - } - NotifyRxDrop (GetAddressedPsduInPpdu (m_currentEvent->GetPpdu ()), reason); - if (reason == OBSS_PD_CCA_RESET) + else if (reason == OBSS_PD_CCA_RESET) { m_state->SwitchFromRxAbort (); } - for (auto it = m_currentPreambleEvents.begin (); it != m_currentPreambleEvents.end (); ++it) - { - if (it->second == m_currentEvent) - { - it = m_currentPreambleEvents.erase (it); - break; - } - } - m_currentEvent = 0; } void diff --git a/src/wifi/model/wifi-phy.h b/src/wifi/model/wifi-phy.h index 19dde397b..3217ef77a 100644 --- a/src/wifi/model/wifi-phy.h +++ b/src/wifi/model/wifi-phy.h @@ -62,6 +62,7 @@ enum WifiPhyRxfailureReason RECEPTION_ABORTED_BY_TX, L_SIG_FAILURE, SIG_A_FAILURE, + SIG_B_FAILURE, PREAMBLE_DETECTION_PACKET_SWITCH, FRAME_CAPTURE_PACKET_SWITCH, OBSS_PD_CCA_RESET, @@ -229,6 +230,24 @@ public: */ void ContinueReceiveHeader (Ptr event); + /** + * The last common PHY header of the current PPDU has been received. + * + * The last common PHY header is: + * - the non-HT header if the PPDU is non-HT + * - the HT or SIG-A header otherwise + * + * \param event the event holding incoming PPDU's information + */ + void EndReceiveCommonHeader (Ptr event); + + /** + * The SIG-B of the current MU PPDU has been received. + * + * \param event the event holding incoming PPDU's information + */ + void EndReceiveSigB (Ptr event); + /** * Start receiving the PSDU (i.e. the first symbol of the PSDU has arrived). * @@ -2070,6 +2089,17 @@ private: */ void DropPreambleEvent (Ptr ppdu, WifiPhyRxfailureReason reason, Time endRx, uint16_t measurementChannelWidth); + /** + * Schedule StartReceivePayload if the mode in the SIG and the number of + * spatial streams are supported. + * + * \param event the event holding the incoming PPDU's information + * \param timeToPayloadStart the time left till payload start + * \return \c true if the reception of the payload has been scheduled, + * \c false otherwise + */ + bool ScheduleStartReceivePayload (Ptr event, Time timeToPayloadStart); + /** * The trace source fired when a packet begins the transmission process on * the medium. diff --git a/src/wifi/test/examples-to-run.py b/src/wifi/test/examples-to-run.py index 77e52cf51..4cf723186 100644 --- a/src/wifi/test/examples-to-run.py +++ b/src/wifi/test/examples-to-run.py @@ -309,7 +309,7 @@ cpp_examples = [ ("wifi-test-interference-helper --enableCapture=0 --txPowerA=5 --txPowerB=15 --delay=10 --txModeA=OfdmRate6Mbps --txModeB=OfdmRate6Mbps --checkResults=1 --expectRxASuccessfull=0 --expectRxBSuccessfull=0", "True", "True"), ("wifi-test-interference-helper --enableCapture=0 --txPowerA=5 --txPowerB=15 --delay=17 --standard=WIFI_PHY_STANDARD_80211ac --preamble=WIFI_PREAMBLE_VHT_SU --txModeA=VhtMcs0 --txModeB=VhtMcs0 --checkResults=1 --expectRxASuccessfull=0 --expectRxBSuccessfull=0", "True", "True"), ("wifi-test-interference-helper --enableCapture=0 --txPowerA=5 --txPowerB=15 --delay=20 --standard=WIFI_PHY_STANDARD_80211ac --preamble=WIFI_PREAMBLE_VHT_SU --txModeA=VhtMcs0 --txModeB=VhtMcs0 --checkResults=1 --expectRxASuccessfull=0 --expectRxBSuccessfull=0", "True", "True"), - ("wifi-test-interference-helper --enableCapture=0 --txPowerA=5 --txPowerB=15 --delay=30 --standard=WIFI_PHY_STANDARD_80211ac --preamble=WIFI_PREAMBLE_VHT_SU --txModeA=VhtMcs0 --txModeB=VhtMcs0 --checkResults=1 --expectRxASuccessfull=0 --expectRxBSuccessfull=0", "True", "True"), + ("wifi-test-interference-helper --enableCapture=0 --txPowerA=5 --txPowerB=15 --delay=27 --standard=WIFI_PHY_STANDARD_80211ac --preamble=WIFI_PREAMBLE_VHT_SU --txModeA=VhtMcs0 --txModeB=VhtMcs0 --checkResults=1 --expectRxASuccessfull=0 --expectRxBSuccessfull=0", "True", "True"), ("wifi-test-interference-helper --enableCapture=1 --txPowerA=5 --txPowerB=15 --delay=10 --txModeA=OfdmRate6Mbps --txModeB=OfdmRate6Mbps --checkResults=1 --expectRxASuccessfull=0 --expectRxBSuccessfull=1", "True", "False"), ("wifi-bianchi --validate --phyRate=54 --nMinStas=5 --nMaxStas=10 --duration=5", "False", "False"), # TODO: run from N=5 to N=50 for 100s (TAKES_FOREVER) when issue #170 is fixed ("wifi-bianchi --validate --phyRate=6 --nMinStas=5 --nMaxStas=10 --duration=15", "True", "False"), # TODO: run from N=5 to N=50 for 400s (TAKES_FOREVER) when issue #170 is fixed