wifi: Ensure at most one ADDBA_RESPONSE frame per agreement is in the MAC queue

This commit is contained in:
Stefano Avallone
2022-09-01 23:15:31 +02:00
committed by Stefano Avallone
parent fa51183362
commit 2f3039eb6b
2 changed files with 30 additions and 0 deletions

View File

@@ -68,6 +68,7 @@ HtFrameExchangeManager::DoDispose (void)
NS_LOG_FUNCTION (this);
m_agreements.clear ();
m_pendingAgreements.clear ();
m_pendingAddBaResp.clear ();
m_msduAggregator = 0;
m_mpduAggregator = 0;
m_psdu = 0;
@@ -241,6 +242,31 @@ HtFrameExchangeManager::SendAddBaResponse (const MgtAddBaRequestHeader *reqHdr,
auto mpdu = Create<WifiMacQueueItem> (packet, hdr);
/*
* It is possible (though, unlikely) that at this point there are other ADDBA_RESPONSE frame(s)
* in the MAC queue. This may happen if the recipient receives an ADDBA_REQUEST frame, enqueues
* an ADDBA_RESPONSE frame, but is not able to successfully transmit it before the timer to
* wait for ADDBA_RESPONSE expires at the originator. The latter may then send another
* ADDBA_REQUEST frame, which triggers the creation of another ADDBA_RESPONSE frame.
* The first ADDBA_RESPONSE frame that is acknowledged causes the Block Ack agreement to be
* moved from the queue of pending agreements to the queue of establish agreements; the next
* one will find no pending agreement, thus causing the simulation to abort.
* As a solution, we keep track of the previously enqueued ADDBA_RESPONSE frame (if any), dequeue
* it and replace it with the new ADDBA_RESPONSE frame.
*/
// remove any pending ADDBA_RESPONSE frame
AgreementKey key (originator, reqHdr->GetTid ());
if (auto it = m_pendingAddBaResp.find (key);
it != m_pendingAddBaResp.end ())
{
NS_ASSERT_MSG (it->second, "The pointer to the pending ADDBA_RESPONSE cannot be null");
DequeueMpdu (it->second);
m_pendingAddBaResp.erase (it);
}
// store the new ADDBA_RESPONSE frame
m_pendingAddBaResp[key] = mpdu;
//It is unclear which queue this frame should go into. For now we
//bung it into the queue corresponding to the TID for which we are
//establishing an agreement, and push it to the head.
@@ -589,6 +615,7 @@ HtFrameExchangeManager::NotifyReceivedNormalAck (Ptr<WifiMacQueueItem> mpdu)
<< ", " << +key.second << "} not found");
m_agreements.erase (nh.key ());
m_agreements.insert (std::move (nh));
m_pendingAddBaResp.erase (key);
}
}
}

View File

@@ -385,6 +385,9 @@ protected:
Ptr<MsduAggregator> m_msduAggregator; //!< A-MSDU aggregator
Ptr<MpduAggregator> m_mpduAggregator; //!< A-MPDU aggregator
/// pending ADDBA_RESPONSE frames indexed by agreement key
std::map<AgreementKey, Ptr<WifiMacQueueItem>> m_pendingAddBaResp;
private:
/**
* Send the current PSDU, which can be acknowledged by a BlockAck frame or