wifi: Add ability to select whether the NAV protection should cover the entire TXOP or only the current frame exchange

This commit is contained in:
Sébastien Deronne
2024-08-24 13:14:16 +02:00
parent 500cf9acac
commit 46cda10f70
5 changed files with 99 additions and 34 deletions

View File

@@ -34,6 +34,7 @@ The required Doxygen version for documentation generation is now version 1.13.
- (dsr) !2403 - Reformatted documentation and added a new concept figure.
- (flow-monitor) !2387 - Reformatted documentation and added a new concept figure.
- (wifi) Added the `ProtectSingleExchange` attribute to the `QosFrameExchangeManager` to choose whether the NAV protection should cover the entire TXOP or only the current frame exchange when the TXOP limit is non-zero. In that case, the Duration/ID field in frames establishing the protection is set to the time remaining until the end of the current frame exchange.
### Bugs fixed

View File

@@ -334,20 +334,31 @@ HeFrameExchangeManager::GetMuRtsDurationId(uint32_t muRtsSize,
{
NS_LOG_FUNCTION(this << muRtsSize << muRtsTxVector << txDuration << response);
WifiTxVector txVector;
txVector.SetMode(GetCtsModeAfterMuRts());
const auto singleDurationId =
VhtFrameExchangeManager::GetRtsDurationId(txVector, txDuration, response);
if (m_edca->GetTxopLimit(m_linkId).IsZero())
{
WifiTxVector txVector;
txVector.SetMode(GetCtsModeAfterMuRts());
return VhtFrameExchangeManager::GetRtsDurationId(txVector, txDuration, response);
return singleDurationId;
}
// under multiple protection settings, if the TXOP limit is not null, Duration/ID
// is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016).
// The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8
// of 802.11-2016)
return std::max(m_edca->GetRemainingTxop(m_linkId) -
WifiPhy::CalculateTxDuration(muRtsSize, muRtsTxVector, m_phy->GetPhyBand()),
Seconds(0));
auto duration =
std::max(m_edca->GetRemainingTxop(m_linkId) -
WifiPhy::CalculateTxDuration(muRtsSize, muRtsTxVector, m_phy->GetPhyBand()),
Seconds(0));
if (m_protectSingleExchange)
{
duration = std::min(duration, singleDurationId);
}
return duration;
}
void
@@ -1724,15 +1735,19 @@ HeFrameExchangeManager::SendMultiStaBlockAck(const WifiTxParameters& txParams, T
* settings defined in 9.2.5.2. (Sec. 9.2.5.7 of 802.11ax-2021)
*/
NS_ASSERT(m_edca);
if (m_edca->GetTxopLimit(m_linkId).IsZero())
const auto singleDurationId = Max(durationId - m_phy->GetSifs() - txDuration, Seconds(0));
if (m_edca->GetTxopLimit(m_linkId).IsZero()) // single protection settings
{
// single protection settings
psdu->SetDuration(Max(durationId - m_phy->GetSifs() - txDuration, Seconds(0)));
psdu->SetDuration(singleDurationId);
}
else
else // multiple protection settings
{
// multiple protection settings
psdu->SetDuration(Max(m_edca->GetRemainingTxop(m_linkId) - txDuration, Seconds(0)));
auto duration = Max(m_edca->GetRemainingTxop(m_linkId) - txDuration, Seconds(0));
if (m_protectSingleExchange)
{
duration = std::min(duration, singleDurationId);
}
psdu->SetDuration(duration);
}
psdu->GetPayload(0)->AddPacketTag(m_muSnrTag);

View File

@@ -1034,19 +1034,28 @@ HtFrameExchangeManager::GetPsduDurationId(Time txDuration, const WifiTxParameter
NS_LOG_FUNCTION(this << txDuration << &txParams);
NS_ASSERT(m_edca);
NS_ASSERT(txParams.m_acknowledgment &&
txParams.m_acknowledgment->acknowledgmentTime.has_value());
const auto singleDurationId = *txParams.m_acknowledgment->acknowledgmentTime;
if (m_edca->GetTxopLimit(m_linkId).IsZero())
{
NS_ASSERT(txParams.m_acknowledgment &&
txParams.m_acknowledgment->acknowledgmentTime.has_value());
return *txParams.m_acknowledgment->acknowledgmentTime;
return singleDurationId;
}
// under multiple protection settings, if the TXOP limit is not null, Duration/ID
// is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016).
// The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8
// of 802.11-2016)
return std::max(m_edca->GetRemainingTxop(m_linkId) - txDuration, Seconds(0));
auto duration = std::max(m_edca->GetRemainingTxop(m_linkId) - txDuration, Seconds(0));
if (m_protectSingleExchange)
{
duration = std::min(duration, singleDurationId);
}
return duration;
}
void

View File

@@ -44,6 +44,13 @@ QosFrameExchangeManager::GetTypeId()
"of QoS data frames sent by non-AP stations",
BooleanValue(false),
MakeBooleanAccessor(&QosFrameExchangeManager::m_setQosQueueSize),
MakeBooleanChecker())
.AddAttribute("ProtectSingleExchange",
"Whether the Duration/ID field in frames establishing protection only "
"covers the immediate frame exchange instead of rest of the TXOP limit "
"when the latter is non-zero",
BooleanValue(false),
MakeBooleanAccessor(&QosFrameExchangeManager::m_protectSingleExchange),
MakeBooleanChecker());
return tid;
}
@@ -471,15 +478,18 @@ QosFrameExchangeManager::GetFrameDurationId(const WifiMacHeader& header,
{
NS_LOG_FUNCTION(this << header << size << &txParams << fragmentedPacket);
const auto singleDurationId =
FrameExchangeManager::GetFrameDurationId(header, size, txParams, fragmentedPacket);
// TODO This will be removed once no Txop is installed on a QoS station
if (!m_edca)
{
return FrameExchangeManager::GetFrameDurationId(header, size, txParams, fragmentedPacket);
return singleDurationId;
}
if (m_edca->GetTxopLimit(m_linkId).IsZero())
{
return FrameExchangeManager::GetFrameDurationId(header, size, txParams, fragmentedPacket);
return singleDurationId;
}
NS_ASSERT(txParams.m_acknowledgment &&
@@ -489,10 +499,17 @@ QosFrameExchangeManager::GetFrameDurationId(const WifiMacHeader& header,
// is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016).
// The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8
// of 802.11-2016)
return std::max(
m_edca->GetRemainingTxop(m_linkId) -
WifiPhy::CalculateTxDuration(size, txParams.m_txVector, m_phy->GetPhyBand()),
*txParams.m_acknowledgment->acknowledgmentTime);
auto duration =
std::max(m_edca->GetRemainingTxop(m_linkId) -
WifiPhy::CalculateTxDuration(size, txParams.m_txVector, m_phy->GetPhyBand()),
*txParams.m_acknowledgment->acknowledgmentTime);
if (m_protectSingleExchange)
{
duration = std::min(duration, singleDurationId);
}
return duration;
}
Time
@@ -502,25 +519,35 @@ QosFrameExchangeManager::GetRtsDurationId(const WifiTxVector& rtsTxVector,
{
NS_LOG_FUNCTION(this << rtsTxVector << txDuration << response);
const auto singleDurationId =
FrameExchangeManager::GetRtsDurationId(rtsTxVector, txDuration, response);
// TODO This will be removed once no Txop is installed on a QoS station
if (!m_edca)
{
return FrameExchangeManager::GetRtsDurationId(rtsTxVector, txDuration, response);
return singleDurationId;
}
if (m_edca->GetTxopLimit(m_linkId).IsZero())
{
return FrameExchangeManager::GetRtsDurationId(rtsTxVector, txDuration, response);
return singleDurationId;
}
// under multiple protection settings, if the TXOP limit is not null, Duration/ID
// is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016).
// The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8
// of 802.11-2016)
return std::max(
m_edca->GetRemainingTxop(m_linkId) -
WifiPhy::CalculateTxDuration(GetRtsSize(), rtsTxVector, m_phy->GetPhyBand()),
Seconds(0));
auto duration =
std::max(m_edca->GetRemainingTxop(m_linkId) -
WifiPhy::CalculateTxDuration(GetRtsSize(), rtsTxVector, m_phy->GetPhyBand()),
Seconds(0));
if (m_protectSingleExchange)
{
duration = std::min(duration, singleDurationId);
}
return duration;
}
Time
@@ -530,25 +557,35 @@ QosFrameExchangeManager::GetCtsToSelfDurationId(const WifiTxVector& ctsTxVector,
{
NS_LOG_FUNCTION(this << ctsTxVector << txDuration << response);
const auto singleDurationId =
FrameExchangeManager::GetCtsToSelfDurationId(ctsTxVector, txDuration, response);
// TODO This will be removed once no Txop is installed on a QoS station
if (!m_edca)
{
return FrameExchangeManager::GetCtsToSelfDurationId(ctsTxVector, txDuration, response);
return singleDurationId;
}
if (m_edca->GetTxopLimit(m_linkId).IsZero())
{
return FrameExchangeManager::GetCtsToSelfDurationId(ctsTxVector, txDuration, response);
return singleDurationId;
}
// under multiple protection settings, if the TXOP limit is not null, Duration/ID
// is set to cover the remaining TXOP time (Sec. 9.2.5.2 of 802.11-2016).
// The TXOP holder may exceed the TXOP limit in some situations (Sec. 10.22.2.8
// of 802.11-2016)
return std::max(
m_edca->GetRemainingTxop(m_linkId) -
WifiPhy::CalculateTxDuration(GetCtsSize(), ctsTxVector, m_phy->GetPhyBand()),
Seconds(0));
auto duration =
std::max(m_edca->GetRemainingTxop(m_linkId) -
WifiPhy::CalculateTxDuration(GetCtsSize(), ctsTxVector, m_phy->GetPhyBand()),
Seconds(0));
if (m_protectSingleExchange)
{
duration = std::min(duration, singleDurationId);
}
return duration;
}
void

View File

@@ -191,6 +191,9 @@ class QosFrameExchangeManager : public FrameExchangeManager
std::optional<Mac48Address> m_txopHolder; //!< MAC address of the TXOP holder
bool m_setQosQueueSize; /**< whether to set the Queue Size subfield of the
QoS Control field of QoS data frames */
bool m_protectSingleExchange; /**< true if the Duration/ID field in frames establishing
protection only covers the immediate frame exchange instead of
rest of the TXOP limit when the latter is non-zero */
private:
/**