wifi: Rework a few functions to ease using BSRP TF as an ICF
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user