wifi: Report RTS failed for all recipients of a failed MU-RTS

Also allows to remove duplicated code
This commit is contained in:
Stefano Avallone
2024-10-15 20:22:45 +02:00
parent 5650773b6d
commit 8fd6a07099
5 changed files with 32 additions and 76 deletions

View File

@@ -1089,38 +1089,46 @@ FrameExchangeManager::CtsTimeout(Ptr<WifiMpdu> rts, const WifiTxVector& txVector
{
NS_LOG_FUNCTION(this << *rts << txVector);
DoCtsTimeout(Create<WifiPsdu>(m_mpdu, true));
DoCtsTimeout(WifiPsduMap{{SU_STA_ID, Create<WifiPsdu>(m_mpdu, true)}});
m_mpdu = nullptr;
}
void
FrameExchangeManager::DoCtsTimeout(Ptr<WifiPsdu> psdu)
FrameExchangeManager::DoCtsTimeout(const WifiPsduMap& psduMap)
{
NS_LOG_FUNCTION(this << *psdu);
NS_LOG_FUNCTION(this << psduMap);
// GetUpdateCwOnCtsTimeout() needs to be called before resetting m_sentRtsTo
const auto updateCw = GetUpdateCwOnCtsTimeout();
m_sentRtsTo.clear();
for (const auto& mpdu : *PeekPointer(psdu))
for (const auto& [staId, psdu] : psduMap)
{
if (mpdu->IsQueued())
for (const auto& mpdu : *PeekPointer(psdu))
{
mpdu->ResetInFlight(m_linkId);
if (mpdu->IsQueued())
{
mpdu->ResetInFlight(m_linkId);
}
}
}
GetWifiRemoteStationManager()->ReportRtsFailed(psdu->GetHeader(0));
if (auto droppedMpdu = DropMpduIfRetryLimitReached(psdu))
{
GetWifiRemoteStationManager()->ReportFinalRtsFailed(droppedMpdu->GetHeader());
}
if (const auto& hdr = psdu->GetHeader(0);
!GetIndividuallyAddressedRecipient(m_mac, hdr).IsGroup())
{
GetWifiRemoteStationManager()->ReportRtsFailed(psdu->GetHeader(0));
// Make the sequence numbers of the MPDUs available again if the MPDUs have never
// been transmitted, both in case the MPDUs have been discarded and in case the
// MPDUs have to be transmitted (because a new sequence number is assigned to
// MPDUs that have never been transmitted and are selected for transmission)
ReleaseSequenceNumbers(psdu);
if (auto droppedMpdu = DropMpduIfRetryLimitReached(psdu))
{
GetWifiRemoteStationManager()->ReportFinalRtsFailed(droppedMpdu->GetHeader());
}
}
// Make the sequence numbers of the MPDUs available again if the MPDUs have never
// been transmitted, both in case the MPDUs have been discarded and in case the
// MPDUs have to be transmitted (because a new sequence number is assigned to
// MPDUs that have never been transmitted and are selected for transmission)
ReleaseSequenceNumbers(psdu);
}
TransmissionFailed(!updateCw);
}

View File

@@ -688,12 +688,12 @@ class FrameExchangeManager : public Object
*/
virtual void CtsTimeout(Ptr<WifiMpdu> rts, const WifiTxVector& txVector);
/**
* Take required actions when the CTS timer fired after sending an RTS to
* protect the given PSDU expires.
* Take required actions when the CTS timer fired after sending an (MU-)RTS to
* protect the given PSDU map expires.
*
* @param psdu the PSDU protected by the failed RTS
* @param psduMap the PSDU map protected by the failed (MU-)RTS
*/
void DoCtsTimeout(Ptr<WifiPsdu> psdu);
void DoCtsTimeout(const WifiPsduMap& psduMap);
/**
* @return whether CW shall be updated on CTS timeout

View File

@@ -421,55 +421,10 @@ HeFrameExchangeManager::CtsAfterMuRtsTimeout(Ptr<WifiMpdu> muRts, const WifiTxVe
return;
}
DoCtsAfterMuRtsTimeout(m_psduMap);
DoCtsTimeout(m_psduMap);
m_psduMap.clear();
}
void
HeFrameExchangeManager::DoCtsAfterMuRtsTimeout(const WifiPsduMap& psduMap)
{
NS_LOG_FUNCTION(this);
// GetUpdateCwOnCtsTimeout() needs to be called before resetting m_sentRtsTo
const auto updateCw = GetUpdateCwOnCtsTimeout();
m_sentRtsTo.clear();
for (const auto& psdu : psduMap)
{
for (const auto& mpdu : *PeekPointer(psdu.second))
{
if (mpdu->IsQueued())
{
mpdu->ResetInFlight(m_linkId);
}
}
}
if (const auto& hdr = psduMap.cbegin()->second->GetHeader(0); !hdr.GetAddr1().IsGroup())
{
GetWifiRemoteStationManager()->ReportRtsFailed(hdr);
}
for (const auto& [staId, psdu] : psduMap)
{
if (psdu->GetAddr1().IsGroup())
{
continue;
}
if (auto droppedMpdu = DropMpduIfRetryLimitReached(psdu))
{
GetWifiRemoteStationManager()->ReportFinalRtsFailed(droppedMpdu->GetHeader());
}
// Make the sequence numbers of the MPDUs available again if the MPDUs have never
// been transmitted, both in case the MPDUs have been discarded and in case the
// MPDUs have to be transmitted (because a new sequence number is assigned to
// MPDUs that have never been transmitted and are selected for transmission)
ReleaseSequenceNumbers(psdu);
}
TransmissionFailed(!updateCw);
}
Ptr<WifiPsdu>
HeFrameExchangeManager::GetPsduTo(Mac48Address to, const WifiPsduMap& psduMap)
{
@@ -498,7 +453,7 @@ HeFrameExchangeManager::CtsTimeout(Ptr<WifiMpdu> rts, const WifiTxVector& txVect
}
NS_ABORT_MSG_IF(m_psduMap.size() > 1, "RTS/CTS cannot be used to protect an MU PPDU");
DoCtsTimeout(m_psduMap.begin()->second);
DoCtsTimeout(m_psduMap);
m_psduMap.clear();
}

View File

@@ -191,13 +191,6 @@ class HeFrameExchangeManager : public VhtFrameExchangeManager
*/
virtual void CtsAfterMuRtsTimeout(Ptr<WifiMpdu> muRts, const WifiTxVector& txVector);
/**
* Called when no CTS frame is received after an MU-RTS.
*
* @param psduMap the PSDU map protected by the failed MU-RTS
*/
void DoCtsAfterMuRtsTimeout(const WifiPsduMap& psduMap);
/**
* Send CTS after receiving an MU-RTS.
*

View File

@@ -1123,7 +1123,7 @@ HtFrameExchangeManager::CtsTimeout(Ptr<WifiMpdu> rts, const WifiTxVector& txVect
return;
}
DoCtsTimeout(m_psdu);
DoCtsTimeout(WifiPsduMap{{SU_STA_ID, m_psdu}});
m_psdu = nullptr;
}