wifi: Increment frame retry count on Block Ack timeout
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user