wifi: BA manager stores groupcast MPDUs if GCR Block Ack service is used

This commit is contained in:
Sébastien Deronne
2023-09-25 20:20:07 +02:00
parent 56a6441d9c
commit 908be8467d
3 changed files with 66 additions and 11 deletions

View File

@@ -368,15 +368,32 @@ void
BlockAckManager::StorePacket(Ptr<WifiMpdu> mpdu)
{
NS_LOG_FUNCTION(this << *mpdu);
DoStorePacket(mpdu, mpdu->GetHeader().GetAddr1());
}
void
BlockAckManager::StoreGcrPacket(Ptr<WifiMpdu> mpdu, const GcrManager::GcrMembers& members)
{
NS_LOG_FUNCTION(this << *mpdu << members.size());
for (const auto& member : members)
{
DoStorePacket(mpdu, member, mpdu->begin()->second.GetDestinationAddr());
}
}
void
BlockAckManager::DoStorePacket(Ptr<WifiMpdu> mpdu,
const Mac48Address& recipient,
std::optional<Mac48Address> gcrGroupAddr)
{
NS_LOG_FUNCTION(this << *mpdu << recipient << gcrGroupAddr.has_value());
NS_ASSERT(mpdu->GetHeader().IsQosData());
const auto tid = mpdu->GetHeader().GetQosTid();
const auto recipient = mpdu->GetHeader().GetAddr1();
auto agreementIt = GetOriginatorBaAgreement(recipient, tid);
auto agreementIt = GetOriginatorBaAgreement(recipient, tid, gcrGroupAddr);
NS_ASSERT(agreementIt != m_originatorAgreements.end());
uint16_t mpduDist =
const auto mpduDist =
agreementIt->second.first.GetDistance(mpdu->GetHeader().GetSequenceNumber());
if (mpduDist >= SEQNO_SPACE_HALF_SIZE)
@@ -396,7 +413,7 @@ BlockAckManager::StorePacket(Ptr<WifiMpdu> mpdu)
return;
}
uint16_t dist =
const auto dist =
agreementIt->second.first.GetDistance((*it)->GetHeader().GetSequenceNumber());
if (mpduDist > dist || (mpduDist == dist && mpdu->GetHeader().GetFragmentNumber() >
@@ -450,7 +467,7 @@ BlockAckManager::HandleInFlightMpdu(uint8_t linkId,
const WifiMacHeader& hdr = (*mpduIt)->GetHeader();
NS_ASSERT(hdr.GetAddr1() == it->first.first);
NS_ASSERT((hdr.GetAddr1() == it->first.first) || hdr.GetAddr1().IsGroup());
NS_ASSERT(hdr.IsQosData() && hdr.GetQosTid() == it->first.second);
if (it->second.first.GetDistance(hdr.GetSequenceNumber()) >= SEQNO_SPACE_HALF_SIZE)

View File

@@ -166,9 +166,19 @@ class BlockAckManager : public Object
* @param mpdu MPDU to store.
*
* Stores <i>mpdu</i> for a possible future retransmission. Retransmission occurs
* if the packet, in a BlockAck frame, is indicated by recipient as not received.
* if the packet, in a Block Ack frame, is indicated by recipient as not received.
*/
void StorePacket(Ptr<WifiMpdu> mpdu);
/**
* @param mpdu groupcast MPDU to store.
* @param members intended recipients for the groupcast MPDU.
*
* Stores <i>mpdu</i> for a possible future retransmission. Retransmission occurs
* if the packet, in a GCR Block Ack frame, is indicated by recipient as not received.
*/
void StoreGcrPacket(Ptr<WifiMpdu> mpdu, const GcrManager::GcrMembers& members);
/**
* Invoked upon receipt of an Ack frame on the given link after the transmission of a
* QoS data frame sent under an established block ack agreement. Remove the acknowledged
@@ -199,8 +209,8 @@ class BlockAckManager : public Object
* @return a pair of values indicating the number of successfully received MPDUs
* and the number of failed MPDUs
*
* Invoked upon receipt of a BlockAck frame on the given link. Typically, this function
* is called by ns3::QosTxop object. Performs a check on which MPDUs, previously sent
* Invoked upon receipt of a Block Ack frame on the given link. Typically, this function
* is called by the frame exchange manager. Performs a check on which MPDUs, previously sent
* with Ack Policy set to Block Ack, were correctly received by the recipient.
* An acknowledged MPDU is removed from the buffer, retransmitted otherwise.
* Note that <i>tids</i> is only used if <i>blockAck</i> is a Multi-STA Block Ack
@@ -211,6 +221,7 @@ class BlockAckManager : public Object
const Mac48Address& recipient,
const std::set<uint8_t>& tids,
size_t index = 0);
/**
* @param linkId the ID of the given link
* @param recipient Sender of the expected BlockAck frame.
@@ -506,6 +517,17 @@ class BlockAckManager : public Object
uint8_t tid,
std::optional<Mac48Address> gcrGroupAddr);
/**
* @param mpdu MPDU to store.
* @param recipient intended recipient for the stored MPDU.
* @param gcrGroupAddr the GCR Group Address (only if MPDU is transmitted using the GCR service)
*
* Stores <i>mpdu</i> for a possible future retransmission.
*/
void DoStorePacket(Ptr<WifiMpdu> mpdu,
const Mac48Address& recipient,
std::optional<Mac48Address> gcrGroupAddr = std::nullopt);
/**
* typedef for a list of WifiMpdu.
*/

View File

@@ -732,10 +732,26 @@ QosTxop::NotifyOriginatorAgreementNoReply(const Mac48Address& recipient,
void
QosTxop::CompleteMpduTx(Ptr<WifiMpdu> mpdu)
{
NS_LOG_FUNCTION(this << *mpdu);
NS_ASSERT(mpdu->GetHeader().IsQosData());
// If there is an established BA agreement, store the packet in the queue of outstanding packets
if (m_mac->GetBaAgreementEstablishedAsOriginator(mpdu->GetHeader().GetAddr1(),
mpdu->GetHeader().GetQosTid()))
if (auto apMac = DynamicCast<ApWifiMac>(m_mac);
IsGcr(m_mac, mpdu->GetHeader()) &&
(apMac->GetGcrManager()->GetRetransmissionPolicyFor(mpdu->GetHeader()) ==
GroupAddressRetransmissionPolicy::GCR_BLOCK_ACK))
{
NS_ASSERT(mpdu->IsQueued());
NS_ASSERT(m_queue->GetAc() == mpdu->GetQueueAc());
const auto recipient = mpdu->begin()->second.GetDestinationAddr();
m_baManager->StoreGcrPacket(
m_queue->GetOriginal(mpdu),
apMac->GetGcrManager()->GetMemberStasForGroupAddress(recipient));
return;
}
if (const auto recipient = mpdu->GetHeader().GetAddr1();
m_mac->GetBaAgreementEstablishedAsOriginator(recipient, mpdu->GetHeader().GetQosTid()))
{
NS_ASSERT(mpdu->IsQueued());
NS_ASSERT(m_queue->GetAc() == mpdu->GetQueueAc());