wifi: Handle lifetime expiry for groupcast MPDUs stored by Block Ack manager

This commit is contained in:
Sébastien Deronne
2023-10-20 11:19:46 +02:00
parent 911220a0c1
commit 123b04a8e3
2 changed files with 60 additions and 22 deletions

View File

@@ -676,7 +676,6 @@ void
BlockAckManager::NotifyDiscardedMpdu(Ptr<const WifiMpdu> mpdu)
{
NS_LOG_FUNCTION(this << *mpdu);
if (!mpdu->GetHeader().IsQosData())
{
NS_LOG_DEBUG("Not a QoS Data frame");
@@ -691,14 +690,37 @@ BlockAckManager::NotifyDiscardedMpdu(Ptr<const WifiMpdu> mpdu)
const auto recipient = mpdu->GetOriginal()->GetHeader().GetAddr1();
const auto tid = mpdu->GetHeader().GetQosTid();
auto it = GetOriginatorBaAgreement(recipient, tid);
if (it == m_originatorAgreements.end() || !it->second.first.IsEstablished())
if (!recipient.IsGroup())
{
auto it = GetOriginatorBaAgreement(recipient, tid);
HandleDiscardedMpdu(mpdu, it);
}
else
{
const auto groupAddress = mpdu->GetOriginal()->GetHeader().GetAddr1();
for (auto it = m_originatorAgreements.begin(); it != m_originatorAgreements.end(); ++it)
{
if (it->first.second != tid || !it->second.first.GetGcrGroupAddress().has_value() ||
it->second.first.GetGcrGroupAddress().value() != groupAddress)
{
continue;
}
HandleDiscardedMpdu(mpdu, it);
}
}
}
void
BlockAckManager::HandleDiscardedMpdu(Ptr<const WifiMpdu> mpdu, OriginatorAgreementsI iter)
{
if (iter == m_originatorAgreements.end() || !iter->second.first.IsEstablished())
{
NS_LOG_DEBUG("No established Block Ack agreement");
return;
}
if (const auto currStartingSeq = it->second.first.GetStartingSequence();
auto& [baAgreement, packetQueue] = iter->second;
if (const auto currStartingSeq = baAgreement.GetStartingSequence();
QosUtilsIsOldPacket(currStartingSeq, mpdu->GetHeader().GetSequenceNumber()))
{
NS_LOG_DEBUG("Discarded an old frame");
@@ -706,13 +728,13 @@ BlockAckManager::NotifyDiscardedMpdu(Ptr<const WifiMpdu> mpdu)
}
// actually advance the transmit window
it->second.first.NotifyDiscardedMpdu(mpdu);
baAgreement.NotifyDiscardedMpdu(mpdu);
// remove old MPDUs from the EDCA queue and from the in flight queue
// (including the given MPDU which became old after advancing the transmit window)
for (auto mpduIt = it->second.second.begin(); mpduIt != it->second.second.end();)
for (auto mpduIt = iter->second.second.begin(); mpduIt != iter->second.second.end();)
{
if (it->second.first.GetDistance((*mpduIt)->GetHeader().GetSequenceNumber()) >=
if (baAgreement.GetDistance((*mpduIt)->GetHeader().GetSequenceNumber()) >=
SEQNO_SPACE_HALF_SIZE)
{
NS_LOG_DEBUG("Dropping old MPDU: " << **mpduIt);
@@ -721,7 +743,7 @@ BlockAckManager::NotifyDiscardedMpdu(Ptr<const WifiMpdu> mpdu)
{
m_droppedOldMpduCallback(*mpduIt);
}
mpduIt = it->second.second.erase(mpduIt);
mpduIt = packetQueue.erase(mpduIt);
}
else
{
@@ -729,20 +751,25 @@ BlockAckManager::NotifyDiscardedMpdu(Ptr<const WifiMpdu> mpdu)
}
}
// schedule a BlockAckRequest
NS_LOG_DEBUG("Schedule a Block Ack Request for agreement (" << recipient << ", " << +tid
<< ")");
// TODO: GCR-BA not supported yet
if (!baAgreement.GetGcrGroupAddress())
{
// schedule a BlockAckRequest
const auto [recipient, tid] = iter->first;
NS_LOG_DEBUG("Schedule a Block Ack Request for agreement (" << recipient << ", " << +tid
<< ")");
WifiMacHeader hdr;
hdr.SetType(WIFI_MAC_CTL_BACKREQ);
hdr.SetAddr1(recipient);
hdr.SetAddr2(mpdu->GetOriginal()->GetHeader().GetAddr2());
hdr.SetDsNotTo();
hdr.SetDsNotFrom();
hdr.SetNoRetry();
hdr.SetNoMoreFragments();
WifiMacHeader hdr;
hdr.SetType(WIFI_MAC_CTL_BACKREQ);
hdr.SetAddr1(recipient);
hdr.SetAddr2(mpdu->GetOriginal()->GetHeader().GetAddr2());
hdr.SetDsNotTo();
hdr.SetDsNotFrom();
hdr.SetNoRetry();
hdr.SetNoMoreFragments();
ScheduleBar(GetBlockAckReqHeader(recipient, tid), hdr);
ScheduleBar(GetBlockAckReqHeader(recipient, tid), hdr);
}
}
void

View File

@@ -484,11 +484,11 @@ class BlockAckManager : public Object
/**
* typedef for a list of WifiMpdu.
*/
typedef std::list<Ptr<WifiMpdu>> PacketQueue;
using PacketQueue = std::list<Ptr<WifiMpdu>>;
/**
* typedef for an iterator for PacketQueue.
*/
typedef std::list<Ptr<WifiMpdu>>::iterator PacketQueueI;
using PacketQueueI = std::list<Ptr<WifiMpdu>>::iterator;
/// AgreementKey-indexed map of originator block ack agreements
using OriginatorAgreements =
@@ -574,6 +574,17 @@ class BlockAckManager : public Object
const OriginatorAgreementsI& it,
const Time& now);
/**
* Handle discarded MPDU by making the transmit window advance beyond the discarded frame.
* This also involves (i) the removal of frames that consequently become old from the
* retransmit queue and from the queue of the block ack agreement, and (ii) the
* scheduling of a BlockAckRequest.
*
* @param mpdu the discarded MPDU
* @param iter an iterator to the corresponding agreement
*/
void HandleDiscardedMpdu(Ptr<const WifiMpdu> mpdu, OriginatorAgreementsI iter);
/**
* This data structure contains, for each originator block ack agreement (recipient, TID),
* a set of packets for which an ack by block ack is requested.