wifi: Mark MPDUs as inflight as soon as the PSDU has been prepared
In this way, MPDUs are already marked as inflight when the (MU-)RTS is sent, thus they are not included in the PSDU prepared for transmission on a second link.
This commit is contained in:
@@ -409,6 +409,11 @@ FrameExchangeManager::SendMpduWithProtection(Ptr<WifiMpdu> mpdu, WifiTxParameter
|
||||
// Set QoS Ack policy if this is a QoS data frame
|
||||
WifiAckManager::SetQosAckPolicy(m_mpdu, m_txParams.m_acknowledgment.get());
|
||||
|
||||
if (m_mpdu->IsQueued())
|
||||
{
|
||||
m_mpdu->SetInFlight(m_linkId);
|
||||
}
|
||||
|
||||
switch (m_txParams.m_protection->method)
|
||||
{
|
||||
case WifiProtection::RTS_CTS:
|
||||
@@ -423,6 +428,12 @@ FrameExchangeManager::SendMpduWithProtection(Ptr<WifiMpdu> mpdu, WifiTxParameter
|
||||
default:
|
||||
NS_ABORT_MSG("Unknown protection type");
|
||||
}
|
||||
|
||||
if (m_txParams.m_acknowledgment->method == WifiAcknowledgment::NONE)
|
||||
{
|
||||
// we are done with frames that do not require acknowledgment
|
||||
m_mpdu = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -481,12 +492,6 @@ FrameExchangeManager::SendMpdu()
|
||||
|
||||
// transmit the MPDU
|
||||
ForwardMpduDown(m_mpdu, m_txParams.m_txVector);
|
||||
|
||||
if (m_txParams.m_acknowledgment->method == WifiAcknowledgment::NONE)
|
||||
{
|
||||
// we are done with frames that do not require acknowledgment
|
||||
m_mpdu = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -494,11 +499,6 @@ FrameExchangeManager::ForwardMpduDown(Ptr<WifiMpdu> mpdu, WifiTxVector& txVector
|
||||
{
|
||||
NS_LOG_FUNCTION(this << *mpdu << txVector);
|
||||
|
||||
if (mpdu->IsQueued())
|
||||
{
|
||||
mpdu->SetInFlight(m_linkId);
|
||||
}
|
||||
|
||||
m_phy->Send(Create<WifiPsdu>(mpdu, false), txVector);
|
||||
}
|
||||
|
||||
@@ -913,6 +913,14 @@ FrameExchangeManager::DoCtsTimeout(Ptr<WifiPsdu> psdu)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << *psdu);
|
||||
|
||||
for (const auto& mpdu : *PeekPointer(psdu))
|
||||
{
|
||||
if (mpdu->IsQueued())
|
||||
{
|
||||
mpdu->ResetInFlight(m_linkId);
|
||||
}
|
||||
}
|
||||
|
||||
GetWifiRemoteStationManager()->ReportRtsFailed(psdu->GetHeader(0));
|
||||
|
||||
if (!GetWifiRemoteStationManager()->NeedRetransmission(*psdu->begin()))
|
||||
@@ -949,12 +957,12 @@ FrameExchangeManager::ReleaseSequenceNumber(Ptr<WifiMpdu> mpdu) const
|
||||
NS_LOG_FUNCTION(this << *mpdu);
|
||||
|
||||
// the MPDU should be still in the DCF queue, unless it expired.
|
||||
// If the MPDU has never been transmitted, it will be assigned a sequence
|
||||
// number again the next time we try to transmit it. Therefore, we need to
|
||||
// If the MPDU has never been transmitted and is not in-flight, it will be assigned
|
||||
// a sequence number again the next time we try to transmit it. Therefore, we need to
|
||||
// make its sequence number available again
|
||||
if (!mpdu->GetHeader().IsRetry())
|
||||
if (!mpdu->GetHeader().IsRetry() && !mpdu->IsInFlight())
|
||||
{
|
||||
m_txMiddle->SetSequenceNumberFor(&mpdu->GetHeader());
|
||||
m_txMiddle->SetSequenceNumberFor(&mpdu->GetOriginal()->GetHeader());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -271,6 +271,17 @@ HeFrameExchangeManager::SendPsduMapWithProtection(WifiPsduMap psduMap, WifiTxPar
|
||||
WifiAckManager::SetQosAckPolicy(psdu.second, m_txParams.m_acknowledgment.get());
|
||||
}
|
||||
|
||||
for (const auto& psdu : m_psduMap)
|
||||
{
|
||||
for (const auto& mpdu : *PeekPointer(psdu.second))
|
||||
{
|
||||
if (mpdu->IsQueued())
|
||||
{
|
||||
mpdu->SetInFlight(m_linkId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_txParams.m_protection->method == WifiProtection::RTS_CTS)
|
||||
{
|
||||
NS_ABORT_MSG_IF(m_psduMap.size() > 1, "Cannot use RTS/CTS with MU PPDUs");
|
||||
@@ -377,6 +388,18 @@ HeFrameExchangeManager::CtsAfterMuRtsTimeout(Ptr<WifiMpdu> muRts, const WifiTxVe
|
||||
NS_LOG_FUNCTION(this << *muRts << txVector);
|
||||
|
||||
NS_ASSERT(!m_psduMap.empty());
|
||||
|
||||
for (const auto& psdu : m_psduMap)
|
||||
{
|
||||
for (const auto& mpdu : *PeekPointer(psdu.second))
|
||||
{
|
||||
if (mpdu->IsQueued())
|
||||
{
|
||||
mpdu->ResetInFlight(m_linkId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE Implementation of QSRC[AC] and QLRC[AC] should be improved...
|
||||
const auto& hdr = m_psduMap.cbegin()->second->GetHeader(0);
|
||||
if (!hdr.GetAddr1().IsGroup())
|
||||
|
||||
@@ -862,7 +862,8 @@ HtFrameExchangeManager::ReleaseSequenceNumber(Ptr<WifiMpdu> mpdu) const
|
||||
uint8_t tid = hdr.GetQosTid();
|
||||
Ptr<QosTxop> edca = m_mac->GetQosTxop(tid);
|
||||
|
||||
if (m_mac->GetBaAgreementEstablishedAsOriginator(hdr.GetAddr1(), tid) && !hdr.IsRetry())
|
||||
if (m_mac->GetBaAgreementEstablishedAsOriginator(hdr.GetAddr1(), tid) && !hdr.IsRetry() &&
|
||||
!mpdu->IsInFlight())
|
||||
{
|
||||
// The MPDU has never been transmitted, so we can make its sequence
|
||||
// number available again if it is lower than the sequence number
|
||||
@@ -935,6 +936,14 @@ HtFrameExchangeManager::SendPsduWithProtection(Ptr<WifiPsdu> psdu, WifiTxParamet
|
||||
// Set QoS Ack policy
|
||||
WifiAckManager::SetQosAckPolicy(m_psdu, m_txParams.m_acknowledgment.get());
|
||||
|
||||
for (const auto& mpdu : *PeekPointer(m_psdu))
|
||||
{
|
||||
if (mpdu->IsQueued())
|
||||
{
|
||||
mpdu->SetInFlight(m_linkId);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_txParams.m_protection->method == WifiProtection::RTS_CTS)
|
||||
{
|
||||
SendRts(m_txParams);
|
||||
@@ -1087,11 +1096,6 @@ HtFrameExchangeManager::NotifyTxToEdca(Ptr<const WifiPsdu> psdu) const
|
||||
edca->CompleteMpduTx(mpdu);
|
||||
}
|
||||
}
|
||||
|
||||
if (mpdu->IsQueued())
|
||||
{
|
||||
mpdu->SetInFlight(m_linkId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user