From 728f46518ec9eba9ab7b1274944a59b3db2d6eb2 Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Thu, 2 Nov 2023 10:17:57 +0100 Subject: [PATCH] wifi: PHY notifies MAC as the last action when RX ends Because the MAC may request a PHY state change (channel switch, sleep) when notified of an RX end, which may conflict with the actions taken by the PHY when an RX ends. --- src/wifi/model/he/he-phy.cc | 2 -- src/wifi/model/phy-entity.cc | 23 +++++++++++++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/wifi/model/he/he-phy.cc b/src/wifi/model/he/he-phy.cc index bff4c7fe1..b42b31771 100644 --- a/src/wifi/model/he/he-phy.cc +++ b/src/wifi/model/he/he-phy.cc @@ -863,7 +863,6 @@ HePhy::RxPayloadSucceeded(Ptr psdu, const std::vector& statusPerMpdu) { NS_LOG_FUNCTION(this << *psdu << txVector); - m_state->NotifyRxPsduSucceeded(psdu, rxSignalInfo, txVector, staId, statusPerMpdu); if (!IsUlMu(txVector.GetPreambleType())) { m_state->SwitchFromRxEndOk(); @@ -878,7 +877,6 @@ void HePhy::RxPayloadFailed(Ptr psdu, double snr, const WifiTxVector& txVector) { NS_LOG_FUNCTION(this << *psdu << txVector << snr); - m_state->NotifyRxPsduFailed(psdu, snr); if (!txVector.IsUlMu()) { m_state->SwitchFromRxEndError(); diff --git a/src/wifi/model/phy-entity.cc b/src/wifi/model/phy-entity.cc index e30af9345..f33adb409 100644 --- a/src/wifi/model/phy-entity.cc +++ b/src/wifi/model/phy-entity.cc @@ -709,31 +709,44 @@ PhyEntity::EndReceivePayload(Ptr event) NS_ASSERT(signalNoiseIt != m_signalNoiseMap.end()); auto statusPerMpduIt = m_statusPerMpduMap.find({ppdu->GetUid(), staId}); NS_ASSERT(statusPerMpduIt != m_statusPerMpduMap.end()); + // store per-MPDU status, which is cleared by the call to DoEndReceivePayload below + auto statusPerMpdu = statusPerMpduIt->second; - if (std::count(statusPerMpduIt->second.begin(), statusPerMpduIt->second.end(), true)) + RxSignalInfo rxSignalInfo; + bool success; + + if (std::count(statusPerMpdu.cbegin(), statusPerMpdu.cend(), true)) { // At least one MPDU has been successfully received m_wifiPhy->NotifyMonitorSniffRx(psdu, m_wifiPhy->GetFrequency(), txVector, signalNoiseIt->second, - statusPerMpduIt->second, + statusPerMpdu, staId); - RxSignalInfo rxSignalInfo; rxSignalInfo.snr = snr; rxSignalInfo.rssi = signalNoiseIt->second.signal; // same information for all MPDUs - RxPayloadSucceeded(psdu, rxSignalInfo, txVector, staId, statusPerMpduIt->second); + RxPayloadSucceeded(psdu, rxSignalInfo, txVector, staId, statusPerMpdu); m_wifiPhy->m_previouslyRxPpduUid = ppdu->GetUid(); // store UID only if reception is successful (because otherwise trigger // won't be read by MAC layer) + success = true; } else { RxPayloadFailed(psdu, snr, txVector); + success = false; } DoEndReceivePayload(ppdu); m_wifiPhy->SwitchMaybeToCcaBusy(ppdu); + + // notify the MAC through the PHY state helper as the last action. Indeed, the notification + // of the RX end may lead the MAC to request a PHY state change (e.g., channel switch, sleep). + // Hence, all actions the PHY has to perform when RX ends should be completed before + // notifying the MAC. + success ? m_state->NotifyRxPsduSucceeded(psdu, rxSignalInfo, txVector, staId, statusPerMpdu) + : m_state->NotifyRxPsduFailed(psdu, snr); } void @@ -744,7 +757,6 @@ PhyEntity::RxPayloadSucceeded(Ptr psdu, const std::vector& statusPerMpdu) { NS_LOG_FUNCTION(this << *psdu << txVector); - m_state->NotifyRxPsduSucceeded(psdu, rxSignalInfo, txVector, staId, statusPerMpdu); m_state->SwitchFromRxEndOk(); } @@ -752,7 +764,6 @@ void PhyEntity::RxPayloadFailed(Ptr psdu, double snr, const WifiTxVector& txVector) { NS_LOG_FUNCTION(this << *psdu << txVector << snr); - m_state->NotifyRxPsduFailed(psdu, snr); m_state->SwitchFromRxEndError(); }