diff --git a/src/wifi/model/eht/eht-frame-exchange-manager.cc b/src/wifi/model/eht/eht-frame-exchange-manager.cc index f9a918eea..a0c56f120 100644 --- a/src/wifi/model/eht/eht-frame-exchange-manager.cc +++ b/src/wifi/model/eht/eht-frame-exchange-manager.cc @@ -412,6 +412,40 @@ EhtFrameExchangeManager::ForwardPsduMapDown(WifiConstPsduMap psduMap, WifiTxVect if (m_apMac) { + // check if this is a BSRP TF used as ICF for some EMLSR client + if (IsTrigger(psduMap)) + { + CtrlTriggerHeader trigger; + psduMap.cbegin()->second->GetPayload(0)->PeekHeader(trigger); + + if (trigger.IsBsrp()) + { + auto recipients = GetTfRecipients(trigger); + for (const auto& client : recipients) + { + if (!GetWifiRemoteStationManager()->GetEmlsrEnabled(client)) + { + continue; + } + auto clientMld = GetWifiRemoteStationManager()->GetMldAddress(client); + NS_ASSERT(clientMld); + + // block transmissions on the other EMLSR links of the EMLSR clients + for (uint8_t linkId = 0; linkId < m_apMac->GetNLinks(); ++linkId) + { + if (linkId != m_linkId && + m_mac->GetWifiRemoteStationManager(linkId)->GetEmlsrEnabled(*clientMld)) + { + m_mac->BlockUnicastTxOnLinks( + WifiQueueBlockedReason::USING_OTHER_EMLSR_LINK, + *clientMld, + {linkId}); + } + } + } + } + } + // check if the EMLSR clients shall switch back to listening operation at the end of this // PPDU for (auto clientIt = m_protectedStas.begin(); clientIt != m_protectedStas.end();) diff --git a/src/wifi/model/he/rr-multi-user-scheduler.cc b/src/wifi/model/he/rr-multi-user-scheduler.cc index 392a3b0a6..2e58ca4ec 100644 --- a/src/wifi/model/he/rr-multi-user-scheduler.cc +++ b/src/wifi/model/he/rr-multi-user-scheduler.cc @@ -9,9 +9,9 @@ #include "rr-multi-user-scheduler.h" #include "he-configuration.h" -#include "he-frame-exchange-manager.h" #include "he-phy.h" +#include "ns3/eht-frame-exchange-manager.h" #include "ns3/log.h" #include "ns3/wifi-acknowledgment.h" #include "ns3/wifi-mac-queue.h" @@ -363,6 +363,21 @@ RrMultiUserScheduler::TrySendingBsrpTf() m_apMac->GetWifiRemoteStationManager(m_linkId)->GetRtsTxVector(m_triggerMacHdr.GetAddr1(), m_allowedWidth); + // If this BSRP TF is an ICF, we need to add padding and adjust the TXVECTOR + if (auto ehtFem = + DynamicCast(m_apMac->GetFrameExchangeManager(m_linkId))) + { + auto prevPaddingSize = m_trigger.GetPaddingSize(); + ehtFem->SetIcfPaddingAndTxVector(m_trigger, m_txParams.m_txVector); + // serialize again if padding has been added + if (m_trigger.GetPaddingSize() != prevPaddingSize) + { + auto packet = Create(); + packet->AddHeader(m_trigger); + item = Create(packet, item->GetHeader()); + } + } + if (!GetHeFem(m_linkId)->TryAddMpdu(item, m_txParams, m_availableTime)) { // sending the BSRP Trigger Frame is not possible, hence return NO_TX. In