From 58d3bde8db95c62c6565862c28e4cc22a4efb92c Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Wed, 11 Oct 2023 18:02:15 +0200 Subject: [PATCH] wifi: CTS after ICF cannot be sent if main PHY is switching or operating on another link This situation may occur when an aux PHY is not TX capable. --- .../model/eht/eht-frame-exchange-manager.cc | 25 +++++++++++++++++++ .../model/eht/eht-frame-exchange-manager.h | 3 +++ src/wifi/model/eht/emlsr-manager.cc | 6 +++++ src/wifi/model/he/he-frame-exchange-manager.h | 6 ++--- 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/wifi/model/eht/eht-frame-exchange-manager.cc b/src/wifi/model/eht/eht-frame-exchange-manager.cc index e7182fe1a..631a8002a 100644 --- a/src/wifi/model/eht/eht-frame-exchange-manager.cc +++ b/src/wifi/model/eht/eht-frame-exchange-manager.cc @@ -576,6 +576,31 @@ EhtFrameExchangeManager::SendMuRts(const WifiTxParameters& txParams) HeFrameExchangeManager::SendMuRts(txParams); } +void +EhtFrameExchangeManager::SendCtsAfterMuRts(const WifiMacHeader& muRtsHdr, + const CtrlTriggerHeader& trigger, + double muRtsSnr) +{ + NS_LOG_FUNCTION(this << muRtsHdr << trigger << muRtsSnr); + + NS_ASSERT(m_staMac); + if (auto emlsrManager = m_staMac->GetEmlsrManager()) + { + auto mainPhy = m_staMac->GetDevice()->GetPhy(emlsrManager->GetMainPhyId()); + + // an aux PHY that is not TX capable may get a TXOP, release the channel and request + // the main PHY to switch channel. Shortly afterwards, the AP MLD may send an ICF, thus + // when the main PHY is scheduled to send the CTS, the main PHY may be switching channel + // or may be operating on another link + if (mainPhy->IsStateSwitching() || m_mac->GetLinkForPhy(mainPhy) != m_linkId) + { + NS_LOG_DEBUG("Main PHY is switching or operating on another link, abort sending CTS"); + return; + } + } + HeFrameExchangeManager::SendCtsAfterMuRts(muRtsHdr, trigger, muRtsSnr); +} + void EhtFrameExchangeManager::CtsAfterMuRtsTimeout(Ptr muRts, const WifiTxVector& txVector) { diff --git a/src/wifi/model/eht/eht-frame-exchange-manager.h b/src/wifi/model/eht/eht-frame-exchange-manager.h index bfb953610..cdd276c95 100644 --- a/src/wifi/model/eht/eht-frame-exchange-manager.h +++ b/src/wifi/model/eht/eht-frame-exchange-manager.h @@ -104,6 +104,9 @@ class EhtFrameExchangeManager : public HeFrameExchangeManager void ForwardPsduMapDown(WifiConstPsduMap psduMap, WifiTxVector& txVector) override; void SendMuRts(const WifiTxParameters& txParams) override; void CtsAfterMuRtsTimeout(Ptr muRts, const WifiTxVector& txVector) override; + void SendCtsAfterMuRts(const WifiMacHeader& muRtsHdr, + const CtrlTriggerHeader& trigger, + double muRtsSnr) override; void TransmissionSucceeded() override; void TransmissionFailed() override; void NotifyChannelReleased(Ptr txop) override; diff --git a/src/wifi/model/eht/emlsr-manager.cc b/src/wifi/model/eht/emlsr-manager.cc index 9ec3ed5f6..4b0ee2dc9 100644 --- a/src/wifi/model/eht/emlsr-manager.cc +++ b/src/wifi/model/eht/emlsr-manager.cc @@ -518,6 +518,12 @@ EmlsrManager::SwitchMainPhy(uint8_t linkId, NS_ASSERT_MSG(mainPhy != m_staMac->GetWifiPhy(linkId), "Main PHY is already operating on link " << +linkId); + if (mainPhy->IsStateSwitching()) + { + NS_LOG_DEBUG("Main PHY is already switching, ignore new switching request"); + return; + } + // find the link on which the main PHY is operating auto currMainPhyLinkId = m_staMac->GetLinkForPhy(mainPhy); NS_ASSERT_MSG(currMainPhyLinkId, "Current link ID for main PHY not found"); diff --git a/src/wifi/model/he/he-frame-exchange-manager.h b/src/wifi/model/he/he-frame-exchange-manager.h index 60e857ea6..a11e63c92 100644 --- a/src/wifi/model/he/he-frame-exchange-manager.h +++ b/src/wifi/model/he/he-frame-exchange-manager.h @@ -219,9 +219,9 @@ class HeFrameExchangeManager : public VhtFrameExchangeManager * \param trigger the MU-RTS Trigger Frame header * \param muRtsSnr the SNR of the MU-RTS in linear scale */ - void SendCtsAfterMuRts(const WifiMacHeader& muRtsHdr, - const CtrlTriggerHeader& trigger, - double muRtsSnr); + virtual void SendCtsAfterMuRts(const WifiMacHeader& muRtsHdr, + const CtrlTriggerHeader& trigger, + double muRtsSnr); /** * \return the mode used to transmit a CTS after an MU-RTS.