wifi: Increment frame retry count on Block Ack timeout

This commit is contained in:
Stefano Avallone
2024-07-24 12:26:50 +02:00
parent 00929c5766
commit e37b16e674
4 changed files with 23 additions and 70 deletions

View File

@@ -1413,19 +1413,10 @@ HeFrameExchangeManager::BlockAcksInTbPpduTimeout(WifiPsduMap* psduMap,
const auto& staMissedBlockAckFrom = m_txTimer.GetStasExpectedToRespond();
NS_ASSERT(!staMissedBlockAckFrom.empty());
bool resetCw;
if (staMissedBlockAckFrom.size() == nSolicitedStations)
{
// no station replied, the transmission failed
// call ReportDataFailed to increase SRC/LRC
GetWifiRemoteStationManager()->ReportDataFailed(*psduMap->begin()->second->begin());
resetCw = false;
}
else
{
// the transmission succeeded
resetCw = true;
}
if (m_triggerFrame)
@@ -1436,35 +1427,22 @@ HeFrameExchangeManager::BlockAcksInTbPpduTimeout(WifiPsduMap* psduMap,
for (const auto& sta : staMissedBlockAckFrom)
{
Ptr<WifiPsdu> psdu = GetPsduTo(sta, *psduMap);
auto psdu = GetPsduTo(sta, *psduMap);
NS_ASSERT(psdu);
// If the QSRC[AC] or the QLRC[AC] has reached dot11ShortRetryLimit or dot11LongRetryLimit
// respectively, CW[AC] shall be reset to CWmin[AC] (sec. 10.22.2.2 of 802.11-2016).
// We should get that psduResetCw is the same for all PSDUs, but the handling of QSRC/QLRC
// needs to be aligned to the specifications.
bool psduResetCw;
MissedBlockAck(psdu, m_txParams.m_txVector, psduResetCw);
resetCw = resetCw || psduResetCw;
MissedBlockAck(psdu, m_txParams.m_txVector);
}
NS_ASSERT(m_edca);
if (resetCw)
{
m_edca->ResetCw(m_linkId);
}
else
{
m_edca->UpdateFailedCw(m_linkId);
}
if (staMissedBlockAckFrom.size() == nSolicitedStations)
{
// no station replied, the transmission failed
m_edca->UpdateFailedCw(m_linkId);
TransmissionFailed();
}
else
{
m_edca->ResetCw(m_linkId);
TransmissionSucceeded();
}
m_psduMap.clear();
@@ -1475,12 +1453,9 @@ HeFrameExchangeManager::BlockAckAfterTbPpduTimeout(Ptr<WifiPsdu> psdu, const Wif
{
NS_LOG_FUNCTION(this << *psdu << txVector);
bool resetCw;
// call ReportDataFailed to increase SRC/LRC
GetWifiRemoteStationManager()->ReportDataFailed(*psdu->begin());
MissedBlockAck(psdu, m_txParams.m_txVector, resetCw);
MissedBlockAck(psdu, m_txParams.m_txVector);
// This is a PSDU sent in a TB PPDU. An HE STA resumes the EDCA backoff procedure
// without modifying CW or the backoff counter for the associated EDCAF, after

View File

@@ -1369,30 +1369,19 @@ HtFrameExchangeManager::BlockAckTimeout(Ptr<WifiPsdu> psdu, const WifiTxVector&
GetWifiRemoteStationManager()->ReportDataFailed(*psdu->begin());
bool resetCw;
MissedBlockAck(psdu, txVector, resetCw);
MissedBlockAck(psdu, txVector);
NS_ASSERT(m_edca);
if (resetCw)
{
m_edca->ResetCw(m_linkId);
}
else
{
m_edca->UpdateFailedCw(m_linkId);
}
m_edca->UpdateFailedCw(m_linkId);
m_psdu = nullptr;
TransmissionFailed();
}
void
HtFrameExchangeManager::MissedBlockAck(Ptr<WifiPsdu> psdu,
const WifiTxVector& txVector,
bool& resetCw)
HtFrameExchangeManager::MissedBlockAck(Ptr<WifiPsdu> psdu, const WifiTxVector& txVector)
{
NS_LOG_FUNCTION(this << psdu << txVector << resetCw);
NS_LOG_FUNCTION(this << psdu << txVector);
auto recipient = psdu->GetAddr1();
auto recipientMld = GetWifiRemoteStationManager()->GetMldAddress(recipient).value_or(recipient);
@@ -1413,6 +1402,15 @@ HtFrameExchangeManager::MissedBlockAck(Ptr<WifiPsdu> psdu,
NS_ABORT_MSG_IF(tids.size() > 1, "Multi-TID A-MPDUs not handled here");
NS_ASSERT(!tids.empty());
tid = *tids.begin();
GetWifiRemoteStationManager()
->ReportAmpduTxStatus(recipient, 0, psdu->GetNMpdus(), 0, 0, txVector);
if (auto droppedMpdu = DropMpduIfRetryLimitReached(psdu))
{
// notify remote station manager if at least an MPDU was dropped
GetWifiRemoteStationManager()->ReportFinalDataFailed(droppedMpdu);
}
}
Ptr<QosTxop> edca = m_mac->GetQosTxop(tid);
@@ -1443,14 +1441,12 @@ HtFrameExchangeManager::MissedBlockAck(Ptr<WifiPsdu> psdu,
auto [reqHdr, hdr] = edca->PrepareBlockAckRequest(recipient, tid);
GetBaManager(tid)->ScheduleBar(reqHdr, hdr);
}
resetCw = false;
}
else
{
NS_LOG_DEBUG("Missed Block Ack, do not transmit a BlockAckReq");
// if a BA agreement exists, we can get here if there is no outstanding
// MPDU whose lifetime has not expired yet.
GetWifiRemoteStationManager()->ReportFinalDataFailed(*psdu->begin());
if (isBar)
{
DequeuePsdu(psdu);
@@ -1461,31 +1457,12 @@ HtFrameExchangeManager::MissedBlockAck(Ptr<WifiPsdu> psdu,
// for this recipient
GetBaManager(tid)->AddToSendBarIfDataQueuedList(recipientMld, tid);
}
resetCw = true;
}
}
else
{
// we have to retransmit the data frames, if needed
GetWifiRemoteStationManager()
->ReportAmpduTxStatus(recipient, 0, psdu->GetNMpdus(), 0, 0, txVector);
if (!GetWifiRemoteStationManager()->NeedRetransmission(*psdu->begin()))
{
NS_LOG_DEBUG("Missed Block Ack, do not retransmit the data frames");
GetWifiRemoteStationManager()->ReportFinalDataFailed(*psdu->begin());
for (const auto& mpdu : *PeekPointer(psdu))
{
NotifyPacketDiscarded(mpdu);
DequeueMpdu(mpdu);
}
resetCw = true;
}
else
{
NS_LOG_DEBUG("Missed Block Ack, retransmit data frames");
GetBaManager(tid)->NotifyMissedBlockAck(m_linkId, recipientMld, tid);
resetCw = false;
}
GetBaManager(tid)->NotifyMissedBlockAck(m_linkId, recipientMld, tid);
}
}

View File

@@ -339,9 +339,8 @@ class HtFrameExchangeManager : public QosFrameExchangeManager
*
* @param psdu the PSDU (BlockAckReq or A-MPDU) that solicited a BlockAck response
* @param txVector the TXVECTOR used to send the PSDU that solicited a BlockAck response
* \param[out] resetCw true if we shall stop retransmitting the PSDU
*/
virtual void MissedBlockAck(Ptr<WifiPsdu> psdu, const WifiTxVector& txVector, bool& resetCw);
virtual void MissedBlockAck(Ptr<WifiPsdu> psdu, const WifiTxVector& txVector);
/// agreement key typedef (MAC address and TID)
typedef std::pair<Mac48Address, uint8_t> AgreementKey;

View File

@@ -2769,7 +2769,9 @@ Issue40TestCase::RunOne(bool useAmpdu)
NS_TEST_ASSERT_MSG_EQ(m_rxCount,
(useAmpdu ? 12 : 6),
"Incorrect number of successfully received packets");
NS_TEST_ASSERT_MSG_EQ(m_txMacFinalDataFailedCount, 1, "Incorrect number of dropped TX packets");
NS_TEST_ASSERT_MSG_EQ(m_txMacFinalDataFailedCount,
(useAmpdu ? 2 : 1),
"Incorrect number of dropped TX packets");
Simulator::Destroy();
}