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:
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user