From 3a5923afa0b051ab7da508ae5dad2104e8b5947c Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Mon, 16 Sep 2024 15:51:56 +0200 Subject: [PATCH] wifi: AP MLD does not block links if it does not reply to an RTS sent by an EMLSR client --- .../model/eht/eht-frame-exchange-manager.cc | 26 ++++++++++++------- src/wifi/model/frame-exchange-manager.cc | 18 ++++++------- src/wifi/model/frame-exchange-manager.h | 1 + .../model/he/he-frame-exchange-manager.cc | 12 ++++----- src/wifi/model/qos-frame-exchange-manager.cc | 12 ++++----- 5 files changed, 38 insertions(+), 31 deletions(-) diff --git a/src/wifi/model/eht/eht-frame-exchange-manager.cc b/src/wifi/model/eht/eht-frame-exchange-manager.cc index 3c5a96c80..cf2efeab0 100644 --- a/src/wifi/model/eht/eht-frame-exchange-manager.cc +++ b/src/wifi/model/eht/eht-frame-exchange-manager.cc @@ -1412,13 +1412,7 @@ EhtFrameExchangeManager::ReceiveMpdu(Ptr mpdu, NS_ASSERT(mpdu->GetHeader().GetAddr1().IsGroup() || mpdu->GetHeader().GetAddr1() == m_self); const auto& hdr = mpdu->GetHeader(); - - if (m_apMac) - { - // if the AP MLD received an MPDU from an EMLSR client that is starting an UL TXOP, - // block transmissions to the EMLSR client on other links - CheckEmlsrClientStartingTxop(hdr, txVector); - } + const auto sender = hdr.GetAddr2(); if (hdr.IsTrigger()) { @@ -1432,7 +1426,7 @@ EhtFrameExchangeManager::ReceiveMpdu(Ptr mpdu, if (hdr.GetAddr1() != m_self && (!hdr.GetAddr1().IsBroadcast() || !m_staMac->IsAssociated() || - hdr.GetAddr2() != m_bssid // not sent by the AP this STA is associated with + sender != m_bssid // not sent by the AP this STA is associated with || trigger.FindUserInfoWithAid(m_staMac->GetAssociationId()) == trigger.end())) { return; // not addressed to us @@ -1459,7 +1453,7 @@ EhtFrameExchangeManager::ReceiveMpdu(Ptr mpdu, m_ongoingTxopEnd = Simulator::Schedule(m_phy->GetSifs() + NanoSeconds(1), &EhtFrameExchangeManager::TxopEnd, this, - hdr.GetAddr2()); + sender); } } @@ -1470,6 +1464,20 @@ EhtFrameExchangeManager::ReceiveMpdu(Ptr mpdu, } HeFrameExchangeManager::ReceiveMpdu(mpdu, rxSignalInfo, txVector, inAmpdu); + + if (m_apMac && GetWifiRemoteStationManager()->GetEmlsrEnabled(sender)) + { + if (hdr.IsRts() && !m_sendCtsEvent.IsPending()) + { + // received RTS but did not send CTS (e.g., NAV busy), start transition delay + EmlsrSwitchToListening(sender, Time{0}); + return; + } + + // if the AP MLD received an MPDU from an EMLSR client that is starting an UL TXOP, + // block transmissions to the EMLSR client on other links + CheckEmlsrClientStartingTxop(hdr, txVector); + } } void diff --git a/src/wifi/model/frame-exchange-manager.cc b/src/wifi/model/frame-exchange-manager.cc index 2dc2d479a..d1b2af393 100644 --- a/src/wifi/model/frame-exchange-manager.cc +++ b/src/wifi/model/frame-exchange-manager.cc @@ -73,10 +73,8 @@ FrameExchangeManager::Reset() { NS_LOG_FUNCTION(this); m_txTimer.Cancel(); - if (m_navResetEvent.IsPending()) - { - m_navResetEvent.Cancel(); - } + m_navResetEvent.Cancel(); + m_sendCtsEvent.Cancel(); m_navEnd = Simulator::Now(); m_mpdu = nullptr; m_txParams.Clear(); @@ -1344,12 +1342,12 @@ FrameExchangeManager::ReceiveMpdu(Ptr mpdu, if (VirtualCsMediumIdle()) { NS_LOG_DEBUG("Received RTS from=" << hdr.GetAddr2() << ", schedule CTS"); - Simulator::Schedule(m_phy->GetSifs(), - &FrameExchangeManager::SendCtsAfterRts, - this, - hdr, - txVector.GetMode(), - rxSnr); + m_sendCtsEvent = Simulator::Schedule(m_phy->GetSifs(), + &FrameExchangeManager::SendCtsAfterRts, + this, + hdr, + txVector.GetMode(), + rxSnr); } else { diff --git a/src/wifi/model/frame-exchange-manager.h b/src/wifi/model/frame-exchange-manager.h index 1256fc3e4..3862a3682 100644 --- a/src/wifi/model/frame-exchange-manager.h +++ b/src/wifi/model/frame-exchange-manager.h @@ -508,6 +508,7 @@ class FrameExchangeManager : public Object Ptr m_dcf; //!< the DCF/EDCAF that gained channel access WifiTxTimer m_txTimer; //!< the timer set upon frame transmission EventId m_navResetEvent; //!< the event to reset the NAV after an RTS + EventId m_sendCtsEvent; //!< the event to send a CTS after an (MU-)RTS Ptr m_mac; //!< the MAC layer on this station Ptr m_apMac; //!< AP MAC layer pointer (null if not an AP) Ptr m_staMac; //!< STA MAC layer pointer (null if not a STA) diff --git a/src/wifi/model/he/he-frame-exchange-manager.cc b/src/wifi/model/he/he-frame-exchange-manager.cc index d1c640d1a..0124fe08b 100644 --- a/src/wifi/model/he/he-frame-exchange-manager.cc +++ b/src/wifi/model/he/he-frame-exchange-manager.cc @@ -2640,12 +2640,12 @@ HeFrameExchangeManager::ReceiveMpdu(Ptr mpdu, // - The UL MU CS condition indicates that the medium is idle // (Sec. 26.2.6.3 of 802.11ax-2021) NS_LOG_DEBUG("Schedule CTS"); - Simulator::Schedule(m_phy->GetSifs(), - &HeFrameExchangeManager::SendCtsAfterMuRts, - this, - hdr, - trigger, - rxSignalInfo.snr); + m_sendCtsEvent = Simulator::Schedule(m_phy->GetSifs(), + &HeFrameExchangeManager::SendCtsAfterMuRts, + this, + hdr, + trigger, + rxSignalInfo.snr); } else if (trigger.IsMuBar()) { diff --git a/src/wifi/model/qos-frame-exchange-manager.cc b/src/wifi/model/qos-frame-exchange-manager.cc index 29b615411..13f9ea9c2 100644 --- a/src/wifi/model/qos-frame-exchange-manager.cc +++ b/src/wifi/model/qos-frame-exchange-manager.cc @@ -806,12 +806,12 @@ QosFrameExchangeManager::ReceiveMpdu(Ptr mpdu, if (hdr.GetAddr2() == m_txopHolder || VirtualCsMediumIdle()) { NS_LOG_DEBUG("Received RTS from=" << hdr.GetAddr2() << ", schedule CTS"); - Simulator::Schedule(m_phy->GetSifs(), - &QosFrameExchangeManager::SendCtsAfterRts, - this, - hdr, - txVector.GetMode(), - rxSnr); + m_sendCtsEvent = Simulator::Schedule(m_phy->GetSifs(), + &QosFrameExchangeManager::SendCtsAfterRts, + this, + hdr, + txVector.GetMode(), + rxSnr); } else {