From fc4df268bddb00c137b0340d3614870741b2e752 Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Wed, 17 Jan 2024 13:30:44 +0100 Subject: [PATCH] wifi: Move actions AP takes when an EMLSR client starts a TXOP to a separate method --- .../model/eht/eht-frame-exchange-manager.cc | 97 +++++++++++++------ .../model/eht/eht-frame-exchange-manager.h | 13 +++ 2 files changed, 79 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 25aebbd0a..e1f577657 100644 --- a/src/wifi/model/eht/eht-frame-exchange-manager.cc +++ b/src/wifi/model/eht/eht-frame-exchange-manager.cc @@ -858,6 +858,68 @@ EhtFrameExchangeManager::PostProcessFrame(Ptr psdu, const WifiTx } } +bool +EhtFrameExchangeManager::CheckEmlsrClientStartingTxop(const WifiMacHeader& hdr, + const WifiTxVector& txVector) +{ + NS_LOG_FUNCTION(this); + + auto sender = hdr.GetAddr2(); + + if (m_ongoingTxopEnd.IsRunning()) + { + NS_LOG_DEBUG("A TXOP is already ongoing"); + return false; + } + + if (auto holder = FindTxopHolder(hdr, txVector); holder != sender) + { + NS_LOG_DEBUG("Sender (" << sender << ") differs from the TXOP holder (" + << (holder ? Address(*holder) : Address()) << ")"); + return false; + } + + if (!GetWifiRemoteStationManager()->GetEmlsrEnabled(sender)) + { + NS_LOG_DEBUG("Sender (" << sender << ") is not an EMLSR client"); + return false; + } + + NS_LOG_DEBUG("EMLSR client " << sender << " is starting a TXOP"); + + // Block transmissions for this EMLSR client on other links + auto mldAddress = GetWifiRemoteStationManager()->GetMldAddress(sender); + NS_ASSERT(mldAddress); + + for (uint8_t linkId = 0; linkId < m_apMac->GetNLinks(); ++linkId) + { + if (linkId != m_linkId && + m_mac->GetWifiRemoteStationManager(linkId)->GetEmlsrEnabled(*mldAddress)) + { + m_mac->BlockUnicastTxOnLinks(WifiQueueBlockedReason::USING_OTHER_EMLSR_LINK, + *mldAddress, + {linkId}); + } + } + + // Make sure that transmissions for this EMLSR client are not blocked on this link + // (the AP MLD may have sent an ICF on another link right before receiving this MPDU, + // thus transmissions on this link may have been blocked) + m_mac->UnblockUnicastTxOnLinks(WifiQueueBlockedReason::USING_OTHER_EMLSR_LINK, + *mldAddress, + {m_linkId}); + + // Stop the transition delay timer for this EMLSR client, if any is running + if (auto it = m_transDelayTimer.find(*mldAddress); + it != m_transDelayTimer.end() && it->second.IsRunning()) + { + it->second.PeekEventImpl()->Invoke(); + it->second.Cancel(); + } + + return true; +} + void EhtFrameExchangeManager::ReceiveMpdu(Ptr mpdu, RxSignalInfo rxSignalInfo, @@ -869,38 +931,11 @@ EhtFrameExchangeManager::ReceiveMpdu(Ptr mpdu, const auto& hdr = mpdu->GetHeader(); - if (m_apMac && GetWifiRemoteStationManager()->GetEmlsrEnabled(hdr.GetAddr2())) + if (m_apMac) { - // the AP MLD received an MPDU from an EMLSR client, which is now involved in an UL TXOP, - // hence block transmissions for this EMLSR client on other links - auto mldAddress = GetWifiRemoteStationManager()->GetMldAddress(hdr.GetAddr2()); - NS_ASSERT(mldAddress); - - for (uint8_t linkId = 0; linkId < m_apMac->GetNLinks(); linkId++) - { - if (linkId != m_linkId && - m_mac->GetWifiRemoteStationManager(linkId)->GetEmlsrEnabled(*mldAddress)) - { - m_mac->BlockUnicastTxOnLinks(WifiQueueBlockedReason::USING_OTHER_EMLSR_LINK, - *mldAddress, - {linkId}); - } - } - - // Make sure that transmissions for this EMLSR client are not blocked on this link - // (the AP MLD may have sent an ICF on another link right before receiving this MPDU, - // thus transmissions on this link may have been blocked) - m_mac->UnblockUnicastTxOnLinks(WifiQueueBlockedReason::USING_OTHER_EMLSR_LINK, - *mldAddress, - {m_linkId}); - - // Stop the transition delay timer for this EMLSR client, if any is running - if (auto it = m_transDelayTimer.find(*mldAddress); - it != m_transDelayTimer.end() && it->second.IsRunning()) - { - it->second.PeekEventImpl()->Invoke(); - it->second.Cancel(); - } + // 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); } bool icfReceived = false; diff --git a/src/wifi/model/eht/eht-frame-exchange-manager.h b/src/wifi/model/eht/eht-frame-exchange-manager.h index 8f87a68e0..bcdae3b70 100644 --- a/src/wifi/model/eht/eht-frame-exchange-manager.h +++ b/src/wifi/model/eht/eht-frame-exchange-manager.h @@ -132,6 +132,19 @@ class EhtFrameExchangeManager : public HeFrameExchangeManager void EmlsrSwitchToListening(const Mac48Address& address, const Time& delay); private: + /** + * Check if the frame received (or being received) is sent by an EMLSR client to start an + * UL TXOP. If so, take the appropriate actions (e.g., block transmission to the EMLSR client + * on the other links). This method is intended to be called when an MPDU (possibly within + * an A-MPDU) is received or when the reception of the MAC header in an MPDU is notified. + * + * \param hdr the MAC header of the received (or being received) MPDU + * \param txVector the TXVECTOR used to transmit the frame received (or being received) + * \return whether the frame received (or being received) is sent by an EMLSR client to start + * an UL TXOP + */ + bool CheckEmlsrClientStartingTxop(const WifiMacHeader& hdr, const WifiTxVector& txVector); + /** * Update the TXOP end timer when starting a frame transmission. *