wifi: Rework a few functions to ease using BSRP TF as an ICF

This commit is contained in:
Stefano Avallone
2024-05-31 15:28:16 +02:00
parent 76344b05d4
commit 1f5e928167
5 changed files with 91 additions and 60 deletions

View File

@@ -331,6 +331,31 @@ EhtFrameExchangeManager::ForwardPsduDown(Ptr<const WifiPsdu> psdu, WifiTxVector&
auto txDuration = WifiPhy::CalculateTxDuration(psdu, txVector, m_phy->GetPhyBand());
if (m_apMac && psdu->GetHeader(0).IsTrigger())
{
for (const auto& client : m_sentRtsTo)
{
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});
}
}
}
}
HeFrameExchangeManager::ForwardPsduDown(psdu, txVector);
UpdateTxopEndOnTxStart(txDuration, psdu->GetDuration());
@@ -676,54 +701,51 @@ EhtFrameExchangeManager::GetMostRecentRssi(const Mac48Address& address) const
}
void
EhtFrameExchangeManager::SendMuRts(const WifiTxParameters& txParams)
EhtFrameExchangeManager::SetIcfPaddingAndTxVector(CtrlTriggerHeader& trigger,
WifiTxVector& txVector) const
{
NS_LOG_FUNCTION(this << &txParams);
NS_LOG_FUNCTION(this << trigger << txVector);
uint8_t maxPaddingDelay = 0;
// block transmissions on the other EMLSR links of the EMLSR clients
for (const auto& address : m_sentRtsTo)
if (!trigger.IsMuRts() && !trigger.IsBsrp())
{
if (!GetWifiRemoteStationManager()->GetEmlsrEnabled(address))
NS_LOG_INFO("Not an ICF");
return;
}
const auto recipients = GetTfRecipients(trigger);
uint8_t maxPaddingDelay = 0;
bool isUnprotectedEmlsrDst = false;
for (const auto& address : recipients)
{
if (!GetWifiRemoteStationManager()->GetEmlsrEnabled(address) ||
m_protectedStas.contains(address))
{
continue;
continue; // not an EMLSR client or EMLSR client already protected
}
isUnprotectedEmlsrDst = true;
auto emlCapabilities = GetWifiRemoteStationManager()->GetStationEmlCapabilities(address);
NS_ASSERT(emlCapabilities);
maxPaddingDelay = std::max(maxPaddingDelay, emlCapabilities->get().emlsrPaddingDelay);
}
auto mldAddress = GetWifiRemoteStationManager()->GetMldAddress(address);
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});
}
}
if (isUnprotectedEmlsrDst)
{
// The initial Control frame of frame exchanges shall be sent in the non-HT PPDU or
// non-HT duplicate PPDU format using a rate of 6 Mb/s, 12 Mb/s, or 24 Mb/s.
// (Sec. 35.3.17 of 802.11be D3.0)
GetWifiRemoteStationManager()->AdjustTxVectorForIcf(txVector);
}
// add padding (if needed)
if (maxPaddingDelay > 0)
{
NS_ASSERT(txParams.m_protection &&
txParams.m_protection->method == WifiProtection::MU_RTS_CTS);
auto protection = static_cast<WifiMuRtsCtsProtection*>(txParams.m_protection.get());
NS_ASSERT(protection->muRts.IsMuRts());
// see formula (35-1) in Sec. 35.5.2.2.3 of 802.11be D3.0
auto rate = protection->muRtsTxVector.GetMode().GetDataRate(protection->muRtsTxVector);
auto rate = txVector.GetMode().GetDataRate(txVector);
std::size_t nDbps = rate / 1e6 * 4; // see Table 17-4 of 802.11-2020
protection->muRts.SetPaddingSize((1 << (maxPaddingDelay + 2)) * nDbps / 8);
trigger.SetPaddingSize((1 << (maxPaddingDelay + 2)) * nDbps / 8);
}
HeFrameExchangeManager::SendMuRts(txParams);
}
void

View File

@@ -161,6 +161,15 @@ class EhtFrameExchangeManager : public HeFrameExchangeManager
*/
EventId& GetOngoingTxopEndEvent();
/**
* Set the padding and the TXVECTOR of the given Trigger Frame, in case it is an Initial
* Control Frame for some EMLSR client(s).
*
* \param trigger the given Trigger Frame
* \param txVector the TXVECTOR used to transmit the Trigger Frame
*/
void SetIcfPaddingAndTxVector(CtrlTriggerHeader& trigger, WifiTxVector& txVector) const;
/// ICF drop reason traced callback (WifiMac exposes this trace source)
TracedCallback<WifiIcfDrop, uint8_t> m_icfDropCallback;
@@ -169,7 +178,6 @@ class EhtFrameExchangeManager : public HeFrameExchangeManager
void RxStartIndication(WifiTxVector txVector, Time psduDuration) override;
void ForwardPsduDown(Ptr<const WifiPsdu> psdu, WifiTxVector& txVector) override;
void ForwardPsduMapDown(WifiConstPsduMap psduMap, WifiTxVector& txVector) override;
void SendMuRts(const WifiTxParameters& txParams) override;
void CtsAfterMuRtsTimeout(Ptr<WifiMpdu> muRts, const WifiTxVector& txVector) override;
void SendCtsAfterMuRts(const WifiMacHeader& muRtsHdr,
const CtrlTriggerHeader& trigger,

View File

@@ -265,7 +265,12 @@ HeFrameExchangeManager::StartProtection(const WifiTxParameters& txParams)
"Cannot use RTS/CTS with MU PPDUs");
if (txParams.m_protection->method == WifiProtection::MU_RTS_CTS)
{
RecordSentMuRtsTo(txParams);
auto protection = static_cast<WifiMuRtsCtsProtection*>(txParams.m_protection.get());
NS_ASSERT(protection->muRts.IsMuRts());
NS_ASSERT(m_sentRtsTo.empty());
m_sentRtsTo = GetTfRecipients(protection->muRts);
SendMuRts(txParams);
}
else
@@ -274,25 +279,21 @@ HeFrameExchangeManager::StartProtection(const WifiTxParameters& txParams)
}
}
void
HeFrameExchangeManager::RecordSentMuRtsTo(const WifiTxParameters& txParams)
std::set<Mac48Address>
HeFrameExchangeManager::GetTfRecipients(const CtrlTriggerHeader& trigger) const
{
NS_LOG_FUNCTION(this << &txParams);
NS_ASSERT(txParams.m_protection && txParams.m_protection->method == WifiProtection::MU_RTS_CTS);
auto protection = static_cast<WifiMuRtsCtsProtection*>(txParams.m_protection.get());
NS_ASSERT(protection->muRts.IsMuRts());
NS_ASSERT_MSG(m_apMac, "APs only can send MU-RTS TF");
std::set<Mac48Address> recipients;
NS_ASSERT_MSG(m_apMac, "APs only can send Trigger Frames");
const auto& aidAddrMap = m_apMac->GetStaList(m_linkId);
NS_ASSERT(m_sentRtsTo.empty());
for (const auto& userInfo : protection->muRts)
for (const auto& userInfo : trigger)
{
const auto addressIt = aidAddrMap.find(userInfo.GetAid12());
NS_ASSERT_MSG(addressIt != aidAddrMap.end(), "AID not found");
m_sentRtsTo.insert(addressIt->second);
recipients.insert(addressIt->second);
}
return recipients;
}
void

View File

@@ -129,6 +129,14 @@ class HeFrameExchangeManager : public VhtFrameExchangeManager
*/
bool UlMuCsMediumIdle(const CtrlTriggerHeader& trigger) const;
/**
* Get the (link) address of the non-AP stations solicited by the given Trigger Frame.
*
* \param trigger the given Trigger Frame
* \return the (link) address of the non-AP stations solicited by the given Trigger Frame
*/
std::set<Mac48Address> GetTfRecipients(const CtrlTriggerHeader& trigger) const;
protected:
void DoDispose() override;
void Reset() override;
@@ -180,13 +188,6 @@ class HeFrameExchangeManager : public VhtFrameExchangeManager
Time txDuration,
Time response) const;
/**
* Record the stations being solicited by an MU-RTS TF.
*
* \param txParams the TX parameters for the data frame protected by the MU-RTS TF.
*/
void RecordSentMuRtsTo(const WifiTxParameters& txParams);
/**
* Send an MU-RTS to begin an MU-RTS/CTS frame exchange protecting an MU PPDU.
*

View File

@@ -9,12 +9,12 @@
#include "wifi-default-protection-manager.h"
#include "ap-wifi-mac.h"
#include "frame-exchange-manager.h"
#include "sta-wifi-mac.h"
#include "wifi-mpdu.h"
#include "wifi-tx-parameters.h"
#include "ns3/boolean.h"
#include "ns3/eht-frame-exchange-manager.h"
#include "ns3/emlsr-manager.h"
#include "ns3/erp-ofdm-phy.h"
#include "ns3/log.h"
@@ -310,12 +310,12 @@ WifiDefaultProtectionManager::TryAddMpduToMuPpdu(Ptr<const WifiMpdu> mpdu,
}
}
// The initial Control frame of frame exchanges shall be sent in the non-HT PPDU or
// non-HT duplicate PPDU format using a rate of 6 Mb/s, 12 Mb/s, or 24 Mb/s.
// (Sec. 35.3.17 of 802.11be D3.0)
if (isEmlsrDestination && !isProtected)
{
GetWifiRemoteStationManager()->AdjustTxVectorForIcf(protection->muRtsTxVector);
// This MU-RTS is an ICF for some EMLSR client
auto ehtFem =
StaticCast<EhtFrameExchangeManager>(m_mac->GetFrameExchangeManager(m_linkId));
ehtFem->SetIcfPaddingAndTxVector(protection->muRts, protection->muRtsTxVector);
}
return std::unique_ptr<WifiMuRtsCtsProtection>(protection);
@@ -395,12 +395,11 @@ WifiDefaultProtectionManager::TryUlMuTransmission(Ptr<const WifiMpdu> mpdu,
{
protection->muRtsTxVector.SetMode(ErpOfdmPhy::GetErpOfdmRate6Mbps());
}
// The initial Control frame of frame exchanges shall be sent in the non-HT PPDU or
// non-HT duplicate PPDU format using a rate of 6 Mb/s, 12 Mb/s, or 24 Mb/s.
// (Sec. 35.3.17 of 802.11be D3.0)
if (isUnprotectedEmlsrDst)
{
GetWifiRemoteStationManager()->AdjustTxVectorForIcf(protection->muRtsTxVector);
// This MU-RTS is an ICF for some EMLSR client
auto ehtFem = StaticCast<EhtFrameExchangeManager>(m_mac->GetFrameExchangeManager(m_linkId));
ehtFem->SetIcfPaddingAndTxVector(protection->muRts, protection->muRtsTxVector);
}
return protection;