wifi: Add TX duration threshold to enable RTS/CTS protection

This commit is contained in:
Stefano Avallone
2024-04-11 19:04:36 +02:00
parent 10b048ddeb
commit 73751ccbde
5 changed files with 34 additions and 24 deletions

View File

@@ -23,6 +23,7 @@ Changes from ns-3.41 to ns-3-dev
redundant code in existing helpers and reducing the burden to add yet another helper when a new
application model is added.
* (wifi) Added a new **SingleRtsPerTxop** attribute to `WifiDefaultProtectionManager`, which, if set to true, prevents to use protection mechanisms (RTS or MU-RTS) more than once in a TXOP (unless required for specific purposes, such as transmitting an Initial Control Frame to an EMLSR client).
* (wifi) Added a new **RtsCtsTxDurationThresh** to `WifiRemoteStationManager` to enable RTS/CTS protection based on the TX duration of the data frame. Both the value of this attribute and the value of the existing **RtsCtsThreshold** attribute are evaluated: if either of the thresholds (or both) is exceeded, RTS/CTS is used.
### Changes to existing API

View File

@@ -121,7 +121,7 @@ WifiDefaultProtectionManager::TryAddMpdu(Ptr<const WifiMpdu> mpdu, const WifiTxP
NS_ASSERT(!txParams.m_protection || txParams.m_protection->method == WifiProtection::NONE);
std::unique_ptr<WifiProtection> protection;
protection = GetPsduProtection(hdr, txParams.GetSize(hdr.GetAddr1()), txParams.m_txVector);
protection = GetPsduProtection(hdr, txParams);
// return the newly computed method if none was set or it is not NONE
if (!txParams.m_protection || protection->method != WifiProtection::NONE)
@@ -158,9 +158,7 @@ WifiDefaultProtectionManager::TryAggregateMsdu(Ptr<const WifiMpdu> msdu,
}
std::unique_ptr<WifiProtection> protection;
protection = GetPsduProtection(msdu->GetHeader(),
txParams.GetSize(msdu->GetHeader().GetAddr1()),
txParams.m_txVector);
protection = GetPsduProtection(msdu->GetHeader(), txParams);
// the protection method may still be none
if (protection->method == WifiProtection::NONE)
@@ -174,10 +172,9 @@ WifiDefaultProtectionManager::TryAggregateMsdu(Ptr<const WifiMpdu> msdu,
std::unique_ptr<WifiProtection>
WifiDefaultProtectionManager::GetPsduProtection(const WifiMacHeader& hdr,
uint32_t size,
const WifiTxVector& txVector) const
const WifiTxParameters& txParams) const
{
NS_LOG_FUNCTION(this << hdr << size << txVector);
NS_LOG_FUNCTION(this << hdr << &txParams);
// a non-initial fragment does not need to be protected, unless it is being retransmitted
if (hdr.GetFragmentNumber() > 0 && !hdr.IsRetry())
@@ -207,12 +204,12 @@ WifiDefaultProtectionManager::GetPsduProtection(const WifiMacHeader& hdr,
}
// check if RTS/CTS is needed
if (emlsrNeedRts || GetWifiRemoteStationManager()->NeedRts(hdr, size))
if (emlsrNeedRts || GetWifiRemoteStationManager()->NeedRts(hdr, txParams))
{
auto protection = std::make_unique<WifiRtsCtsProtection>();
protection->rtsTxVector =
GetWifiRemoteStationManager()->GetRtsTxVector(hdr.GetAddr1(),
txVector.GetChannelWidth());
txParams.m_txVector.GetChannelWidth());
protection->ctsTxVector =
GetWifiRemoteStationManager()->GetCtsTxVector(hdr.GetAddr1(),
protection->rtsTxVector.GetMode());
@@ -221,7 +218,7 @@ WifiDefaultProtectionManager::GetPsduProtection(const WifiMacHeader& hdr,
// check if CTS-to-Self is needed
if (GetWifiRemoteStationManager()->GetUseNonErpProtection() &&
GetWifiRemoteStationManager()->NeedCtsToSelf(txVector))
GetWifiRemoteStationManager()->NeedCtsToSelf(txParams.m_txVector))
{
auto protection = std::make_unique<WifiCtsToSelfProtection>();
protection->ctsTxVector = GetWifiRemoteStationManager()->GetCtsToSelfTxVector();

View File

@@ -57,13 +57,12 @@ class WifiDefaultProtectionManager : public WifiProtectionManager
* Select the protection method for a single PSDU.
*
* \param hdr the MAC header of the PSDU
* \param size the size in bytes of the PSDU
* \param txVector the TxVector used to transmit the PSDU
* \param txParams the TX parameters describing the PSDU
* \return the selected protection method
*/
virtual std::unique_ptr<WifiProtection> GetPsduProtection(const WifiMacHeader& hdr,
uint32_t size,
const WifiTxVector& txVector) const;
virtual std::unique_ptr<WifiProtection> GetPsduProtection(
const WifiMacHeader& hdr,
const WifiTxParameters& txParams) const;
private:
/**

View File

@@ -26,6 +26,7 @@
#include "wifi-mpdu.h"
#include "wifi-net-device.h"
#include "wifi-phy.h"
#include "wifi-tx-parameters.h"
#include "ns3/boolean.h"
#include "ns3/eht-configuration.h"
@@ -74,6 +75,13 @@ WifiRemoteStationManager::GetTypeId()
UintegerValue(4692480),
MakeUintegerAccessor(&WifiRemoteStationManager::SetRtsCtsThreshold),
MakeUintegerChecker<uint32_t>(0, 4692480))
.AddAttribute("RtsCtsTxDurationThresh",
"If this threshold is a strictly positive value and the TX duration of "
"the PSDU is greater than or equal to this threshold, we use an RTS/CTS "
"handshake before sending the data frame.",
TimeValue(Time{0}),
MakeTimeAccessor(&WifiRemoteStationManager::m_rtsCtsTxDurationThresh),
MakeTimeChecker())
.AddAttribute(
"FragmentationThreshold",
"If the size of the PSDU is bigger than this value, we fragment it such that the "
@@ -1119,12 +1127,11 @@ WifiRemoteStationManager::ReportAmpduTxStatus(Mac48Address address,
}
bool
WifiRemoteStationManager::NeedRts(const WifiMacHeader& header, uint32_t size)
WifiRemoteStationManager::NeedRts(const WifiMacHeader& header, const WifiTxParameters& txParams)
{
NS_LOG_FUNCTION(this << header << size);
Mac48Address address = header.GetAddr1();
WifiTxVector txVector = GetDataTxVector(header, m_wifiPhy->GetChannelWidth());
const auto modulationClass = txVector.GetModulationClass();
NS_LOG_FUNCTION(this << header << &txParams);
auto address = header.GetAddr1();
const auto modulationClass = txParams.m_txVector.GetModulationClass();
if (address.IsGroup())
{
return false;
@@ -1146,7 +1153,11 @@ WifiRemoteStationManager::NeedRts(const WifiMacHeader& header, uint32_t size)
NS_LOG_DEBUG("WifiRemoteStationManager::NeedRTS returning true to protect non-HT stations");
return true;
}
bool normally = (size > m_rtsCtsThreshold);
NS_ASSERT(txParams.m_txDuration.has_value());
auto size = txParams.GetSize(header.GetAddr1());
bool normally =
(size > m_rtsCtsThreshold) || (m_rtsCtsTxDurationThresh.IsStrictlyPositive() &&
*txParams.m_txDuration >= m_rtsCtsTxDurationThresh);
return DoNeedRts(Lookup(address), size, normally);
}

View File

@@ -49,6 +49,7 @@ class WifiMacHeader;
class Packet;
class WifiMpdu;
class WifiTxVector;
class WifiTxParameters;
struct WifiRemoteStationState;
struct RxSignalInfo;
@@ -955,13 +956,13 @@ class WifiRemoteStationManager : public Object
void ReportRxOk(Mac48Address address, RxSignalInfo rxSignalInfo, WifiTxVector txVector);
/**
* \param header MAC header
* \param size the size of the frame to send in bytes
* \param header MAC header of the data frame to send
* \param txParams the TX parameters for the data frame to send
*
* \return true if we want to use an RTS/CTS handshake for this
* frame before sending it, false otherwise.
*/
bool NeedRts(const WifiMacHeader& header, uint32_t size);
bool NeedRts(const WifiMacHeader& header, const WifiTxParameters& txParams);
/**
* Return if we need to do CTS-to-self before sending a DATA.
*
@@ -1494,6 +1495,7 @@ class WifiRemoteStationManager : public Object
uint32_t m_maxSsrc; //!< Maximum STA short retry count (SSRC)
uint32_t m_maxSlrc; //!< Maximum STA long retry count (SLRC)
uint32_t m_rtsCtsThreshold; //!< Threshold for RTS/CTS
Time m_rtsCtsTxDurationThresh; //!< TX duration threshold for RTS/CTS
uint32_t m_fragmentationThreshold; //!< Current threshold for fragmentation
uint8_t m_defaultTxPowerLevel; //!< Default transmission power level
WifiMode m_nonUnicastMode; //!< Transmission mode for non-unicast Data frames