wifi: Add TX duration threshold to enable RTS/CTS protection
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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:
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user