diff --git a/src/wifi/model/he/he-frame-exchange-manager.cc b/src/wifi/model/he/he-frame-exchange-manager.cc index 9c19ac491..225548dc9 100644 --- a/src/wifi/model/he/he-frame-exchange-manager.cc +++ b/src/wifi/model/he/he-frame-exchange-manager.cc @@ -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 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 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 diff --git a/src/wifi/model/ht/ht-frame-exchange-manager.cc b/src/wifi/model/ht/ht-frame-exchange-manager.cc index 7501973a2..21cb484cd 100644 --- a/src/wifi/model/ht/ht-frame-exchange-manager.cc +++ b/src/wifi/model/ht/ht-frame-exchange-manager.cc @@ -1369,30 +1369,19 @@ HtFrameExchangeManager::BlockAckTimeout(Ptr 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 psdu, - const WifiTxVector& txVector, - bool& resetCw) +HtFrameExchangeManager::MissedBlockAck(Ptr 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 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 edca = m_mac->GetQosTxop(tid); @@ -1443,14 +1441,12 @@ HtFrameExchangeManager::MissedBlockAck(Ptr 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 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); } } diff --git a/src/wifi/model/ht/ht-frame-exchange-manager.h b/src/wifi/model/ht/ht-frame-exchange-manager.h index e79695614..ca4db622d 100644 --- a/src/wifi/model/ht/ht-frame-exchange-manager.h +++ b/src/wifi/model/ht/ht-frame-exchange-manager.h @@ -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 psdu, const WifiTxVector& txVector, bool& resetCw); + virtual void MissedBlockAck(Ptr psdu, const WifiTxVector& txVector); /// agreement key typedef (MAC address and TID) typedef std::pair AgreementKey; diff --git a/src/wifi/test/wifi-test.cc b/src/wifi/test/wifi-test.cc index c8386967a..483fa2b85 100644 --- a/src/wifi/test/wifi-test.cc +++ b/src/wifi/test/wifi-test.cc @@ -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(); }