From d3cd6bc879b8a3aa1a2042a554d2028f81ea7414 Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Mon, 21 Aug 2023 23:20:49 +0200 Subject: [PATCH] wifi: (fixes #942) Trace expired MPDUs before removing them from the queue Otherwise, expired MPDUs may be classified as frames that have never been transmitted, a BlockAckReq to advance the recipient window is not sent and the throughput goes down to zero. --- src/wifi/model/wifi-mac-queue.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/wifi/model/wifi-mac-queue.cc b/src/wifi/model/wifi-mac-queue.cc index 7fee2442c..ee2e743f2 100644 --- a/src/wifi/model/wifi-mac-queue.cc +++ b/src/wifi/model/wifi-mac-queue.cc @@ -191,7 +191,17 @@ WifiMacQueue::TtlExceeded(Ptr item, const Time& now) { NS_LOG_DEBUG("Removing packet that stayed in the queue for too long (queuing time=" << now - it->expiryTime + m_maxDelay << ")"); - m_traceExpired(DoRemove(it)); + // Trace the expired MPDU first and then remove it from the queue (if still in the queue). + // Indeed, the Expired traced source is connected to BlockAckManager::NotifyDiscardedMpdu, + // which checks if the expired MPDU is in-flight or is a retransmission to determine + // whether a BlockAckReq frame must be sent to advance the recipient window. If the + // expired MPDU is removed from the queue before tracing the expiration, it is no longer + // in-flight and NotifyDiscardedMpdu wrongfully assumes that a BlockAckReq is not needed. + m_traceExpired(item); + if (item->IsQueued()) + { + DoRemove(it); + } return true; } return false;