wifi: Decouple protection and TX plus acknowledgment
...to make it possible, e.g., to use MU-RTS to protect a SU transmission
This commit is contained in:
@@ -414,20 +414,7 @@ FrameExchangeManager::SendMpduWithProtection(Ptr<WifiMpdu> mpdu, WifiTxParameter
|
||||
m_mpdu->SetInFlight(m_linkId);
|
||||
}
|
||||
|
||||
switch (m_txParams.m_protection->method)
|
||||
{
|
||||
case WifiProtection::RTS_CTS:
|
||||
SendRts(m_txParams);
|
||||
break;
|
||||
case WifiProtection::CTS_TO_SELF:
|
||||
SendCtsToSelf(m_txParams);
|
||||
break;
|
||||
case WifiProtection::NONE:
|
||||
SendMpdu();
|
||||
break;
|
||||
default:
|
||||
NS_ABORT_MSG("Unknown protection type");
|
||||
}
|
||||
StartProtection(m_txParams);
|
||||
|
||||
if (m_txParams.m_acknowledgment->method == WifiAcknowledgment::NONE)
|
||||
{
|
||||
@@ -436,6 +423,35 @@ FrameExchangeManager::SendMpduWithProtection(Ptr<WifiMpdu> mpdu, WifiTxParameter
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FrameExchangeManager::StartProtection(const WifiTxParameters& txParams)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << &txParams);
|
||||
|
||||
switch (txParams.m_protection->method)
|
||||
{
|
||||
case WifiProtection::RTS_CTS:
|
||||
SendRts(txParams);
|
||||
break;
|
||||
case WifiProtection::CTS_TO_SELF:
|
||||
SendCtsToSelf(txParams);
|
||||
break;
|
||||
case WifiProtection::NONE:
|
||||
ProtectionCompleted();
|
||||
break;
|
||||
default:
|
||||
NS_ABORT_MSG("Unknown protection type: " << txParams.m_protection.get());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FrameExchangeManager::ProtectionCompleted()
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
NS_ASSERT(m_mpdu);
|
||||
SendMpdu();
|
||||
}
|
||||
|
||||
void
|
||||
FrameExchangeManager::SendMpdu()
|
||||
{
|
||||
@@ -794,7 +810,9 @@ FrameExchangeManager::SendCtsToSelf(const WifiTxParameters& txParams)
|
||||
Time ctsDuration = m_phy->CalculateTxDuration(GetCtsSize(),
|
||||
ctsToSelfProtection->ctsTxVector,
|
||||
m_phy->GetPhyBand());
|
||||
Simulator::Schedule(ctsDuration + m_phy->GetSifs(), &FrameExchangeManager::SendMpdu, this);
|
||||
Simulator::Schedule(ctsDuration + m_phy->GetSifs(),
|
||||
&FrameExchangeManager::ProtectionCompleted,
|
||||
this);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1269,7 +1287,7 @@ FrameExchangeManager::ReceiveMpdu(Ptr<const WifiMpdu> mpdu,
|
||||
|
||||
m_txTimer.Cancel();
|
||||
m_channelAccessManager->NotifyCtsTimeoutResetNow();
|
||||
Simulator::Schedule(m_phy->GetSifs(), &FrameExchangeManager::SendMpdu, this);
|
||||
Simulator::Schedule(m_phy->GetSifs(), &FrameExchangeManager::ProtectionCompleted, this);
|
||||
}
|
||||
else if (hdr.IsAck() && m_mpdu && m_txTimer.IsRunning() &&
|
||||
m_txTimer.GetReason() == WifiTxTimer::WAIT_NORMAL_ACK)
|
||||
|
||||
@@ -299,6 +299,18 @@ class FrameExchangeManager : public Object
|
||||
*/
|
||||
void SendMpduWithProtection(Ptr<WifiMpdu> mpdu, WifiTxParameters& txParams);
|
||||
|
||||
/**
|
||||
* Start the protection mechanism indicated by the given TX parameters
|
||||
*
|
||||
* \param txParams the TX parameters
|
||||
*/
|
||||
virtual void StartProtection(const WifiTxParameters& txParams);
|
||||
|
||||
/**
|
||||
* Transmit prepared frame upon successful protection mechanism.
|
||||
*/
|
||||
virtual void ProtectionCompleted();
|
||||
|
||||
/**
|
||||
* Update the NAV, if needed, based on the Duration/ID of the given <i>psdu</i>.
|
||||
*
|
||||
|
||||
@@ -282,25 +282,39 @@ HeFrameExchangeManager::SendPsduMapWithProtection(WifiPsduMap psduMap, WifiTxPar
|
||||
}
|
||||
}
|
||||
|
||||
if (m_txParams.m_protection->method == WifiProtection::RTS_CTS)
|
||||
StartProtection(m_txParams);
|
||||
}
|
||||
|
||||
void
|
||||
HeFrameExchangeManager::StartProtection(const WifiTxParameters& txParams)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << &txParams);
|
||||
|
||||
NS_ABORT_MSG_IF(m_psduMap.size() > 1 &&
|
||||
txParams.m_protection->method == WifiProtection::RTS_CTS,
|
||||
"Cannot use RTS/CTS with MU PPDUs");
|
||||
if (txParams.m_protection->method == WifiProtection::MU_RTS_CTS)
|
||||
{
|
||||
NS_ABORT_MSG_IF(m_psduMap.size() > 1, "Cannot use RTS/CTS with MU PPDUs");
|
||||
SendRts(m_txParams);
|
||||
}
|
||||
else if (m_txParams.m_protection->method == WifiProtection::MU_RTS_CTS)
|
||||
{
|
||||
SendMuRts(m_txParams);
|
||||
}
|
||||
else if (m_txParams.m_protection->method == WifiProtection::NONE)
|
||||
{
|
||||
SendPsduMap();
|
||||
SendMuRts(txParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ABORT_MSG("Unknown or prohibited protection type: " << m_txParams.m_protection.get());
|
||||
VhtFrameExchangeManager::StartProtection(txParams);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HeFrameExchangeManager::ProtectionCompleted()
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
if (!m_psduMap.empty())
|
||||
{
|
||||
SendPsduMap();
|
||||
return;
|
||||
}
|
||||
VhtFrameExchangeManager::ProtectionCompleted();
|
||||
}
|
||||
|
||||
Time
|
||||
HeFrameExchangeManager::GetMuRtsDurationId(uint32_t muRtsSize,
|
||||
const WifiTxVector& muRtsTxVector,
|
||||
@@ -387,7 +401,13 @@ HeFrameExchangeManager::CtsAfterMuRtsTimeout(Ptr<WifiMpdu> muRts, const WifiTxVe
|
||||
{
|
||||
NS_LOG_FUNCTION(this << *muRts << txVector);
|
||||
|
||||
NS_ASSERT(!m_psduMap.empty());
|
||||
if (m_psduMap.empty())
|
||||
{
|
||||
// A CTS Timeout occurred when protecting a single PSDU that is not included
|
||||
// in a DL MU PPDU is handled by the parent classes
|
||||
VhtFrameExchangeManager::CtsTimeout(muRts, txVector);
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& psdu : m_psduMap)
|
||||
{
|
||||
@@ -2295,9 +2315,11 @@ HeFrameExchangeManager::ReceiveMpdu(Ptr<const WifiMpdu> mpdu,
|
||||
|
||||
m_txTimer.Cancel();
|
||||
m_channelAccessManager->NotifyCtsTimeoutResetNow();
|
||||
Simulator::Schedule(m_phy->GetSifs(), &HeFrameExchangeManager::SendPsduMap, this);
|
||||
Simulator::Schedule(m_phy->GetSifs(),
|
||||
&HeFrameExchangeManager::ProtectionCompleted,
|
||||
this);
|
||||
}
|
||||
else if (hdr.IsCts() && !m_psduMap.empty() && m_txTimer.IsRunning() &&
|
||||
else if (hdr.IsCts() && m_txTimer.IsRunning() &&
|
||||
m_txTimer.GetReason() == WifiTxTimer::WAIT_CTS_AFTER_MU_RTS)
|
||||
{
|
||||
NS_ABORT_MSG_IF(inAmpdu, "Received CTS as part of an A-MPDU");
|
||||
@@ -2307,7 +2329,9 @@ HeFrameExchangeManager::ReceiveMpdu(Ptr<const WifiMpdu> mpdu,
|
||||
|
||||
m_txTimer.Cancel();
|
||||
m_channelAccessManager->NotifyCtsTimeoutResetNow();
|
||||
Simulator::Schedule(m_phy->GetSifs(), &HeFrameExchangeManager::SendPsduMap, this);
|
||||
Simulator::Schedule(m_phy->GetSifs(),
|
||||
&HeFrameExchangeManager::ProtectionCompleted,
|
||||
this);
|
||||
}
|
||||
else if (hdr.IsAck() && m_txTimer.IsRunning() &&
|
||||
m_txTimer.GetReason() == WifiTxTimer::WAIT_NORMAL_ACK_AFTER_DL_MU_PPDU)
|
||||
|
||||
@@ -156,6 +156,8 @@ class HeFrameExchangeManager : public VhtFrameExchangeManager
|
||||
void CtsTimeout(Ptr<WifiMpdu> rts, const WifiTxVector& txVector) override;
|
||||
void UpdateNav(Ptr<const WifiPsdu> psdu, const WifiTxVector& txVector) override;
|
||||
void NavResetTimeout() override;
|
||||
void StartProtection(const WifiTxParameters& txParams) override;
|
||||
void ProtectionCompleted() override;
|
||||
|
||||
/**
|
||||
* Clear the TXOP holder if the intra-BSS NAV counted down to zero (includes the case
|
||||
|
||||
@@ -954,22 +954,19 @@ HtFrameExchangeManager::SendPsduWithProtection(Ptr<WifiPsdu> psdu, WifiTxParamet
|
||||
}
|
||||
}
|
||||
|
||||
if (m_txParams.m_protection->method == WifiProtection::RTS_CTS)
|
||||
{
|
||||
SendRts(m_txParams);
|
||||
}
|
||||
else if (m_txParams.m_protection->method == WifiProtection::CTS_TO_SELF)
|
||||
{
|
||||
SendCtsToSelf(m_txParams);
|
||||
}
|
||||
else if (m_txParams.m_protection->method == WifiProtection::NONE)
|
||||
StartProtection(m_txParams);
|
||||
}
|
||||
|
||||
void
|
||||
HtFrameExchangeManager::ProtectionCompleted()
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
if (m_psdu)
|
||||
{
|
||||
SendPsdu();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ABORT_MSG("Unknown protection type");
|
||||
}
|
||||
QosFrameExchangeManager::ProtectionCompleted();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1552,7 +1549,9 @@ HtFrameExchangeManager::ReceiveMpdu(Ptr<const WifiMpdu> mpdu,
|
||||
|
||||
m_txTimer.Cancel();
|
||||
m_channelAccessManager->NotifyCtsTimeoutResetNow();
|
||||
Simulator::Schedule(m_phy->GetSifs(), &HtFrameExchangeManager::SendPsdu, this);
|
||||
Simulator::Schedule(m_phy->GetSifs(),
|
||||
&HtFrameExchangeManager::ProtectionCompleted,
|
||||
this);
|
||||
}
|
||||
else if (hdr.IsBlockAck() && m_txTimer.IsRunning() &&
|
||||
m_txTimer.GetReason() == WifiTxTimer::WAIT_BLOCK_ACK && hdr.GetAddr1() == m_self)
|
||||
|
||||
@@ -200,6 +200,7 @@ class HtFrameExchangeManager : public QosFrameExchangeManager
|
||||
void FinalizeMacHeader(Ptr<const WifiPsdu> psdu) override;
|
||||
void CtsTimeout(Ptr<WifiMpdu> rts, const WifiTxVector& txVector) override;
|
||||
void TransmissionSucceeded() override;
|
||||
void ProtectionCompleted() override;
|
||||
|
||||
/**
|
||||
* Get a PSDU containing the given MPDU
|
||||
|
||||
Reference in New Issue
Block a user