From 7f271f896eb4eda63cf13cadbdeee9f06c879c2d Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Wed, 2 Oct 2019 18:56:05 +0200 Subject: [PATCH] wifi: Update Block Ack Requests before sending them --- src/wifi/model/block-ack-manager.cc | 47 +++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/src/wifi/model/block-ack-manager.cc b/src/wifi/model/block-ack-manager.cc index 6080080ee..b1ae1b31d 100644 --- a/src/wifi/model/block-ack-manager.cc +++ b/src/wifi/model/block-ack-manager.cc @@ -289,13 +289,56 @@ Ptr BlockAckManager::GetBar (bool remove) { Ptr bar; - if (m_bars.size () > 0) + // remove all expired MPDUs in the retransmission queue, so that Block Ack Requests + // (if needed) are scheduled + m_retryPackets->Remove (WifiMacQueue::EMPTY, true); + + while (!m_bars.empty ()) { - bar = m_bars.front ().bar; + auto nextBar = m_bars.front (); + + if (nextBar.bar->GetHeader ().IsBlockAckReq ()) + { + Mac48Address recipient = nextBar.bar->GetHeader ().GetAddr1 (); + AgreementsI it = m_agreements.find (std::make_pair (recipient, nextBar.tid)); + if (it == m_agreements.end ()) + { + // BA agreement was torn down; remove this BAR and continue + m_bars.pop_front (); + continue; + } + // remove expired outstanding MPDUs and update the starting sequence number + for (auto mpduIt = it->second.second.begin (); mpduIt != it->second.second.end (); ) + { + if ((*mpduIt)->GetTimeStamp () + m_queue->GetMaxDelay () <= Simulator::Now ()) + { + // MPDU expired + it->second.first.NotifyDiscardedMpdu (*mpduIt); + mpduIt = it->second.second.erase (mpduIt); + } + else + { + mpduIt++; + } + } + // update BAR if the starting sequence number changed + CtrlBAckRequestHeader reqHdr; + nextBar.bar->GetPacket ()->PeekHeader (reqHdr); + if (reqHdr.GetStartingSequence () != it->second.first.GetStartingSequence ()) + { + reqHdr.SetStartingSequence (it->second.first.GetStartingSequence ()); + Ptr packet = Create (); + packet->AddHeader (reqHdr); + nextBar.bar = Create (packet, nextBar.bar->GetHeader ()); + } + } + + bar = nextBar.bar; if (remove) { m_bars.pop_front (); } + break; } return bar; }