From 908be8467d84d186d1519c4e2c9213f930b15095 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deronne?= Date: Mon, 25 Sep 2023 20:20:07 +0200 Subject: [PATCH] wifi: BA manager stores groupcast MPDUs if GCR Block Ack service is used --- src/wifi/model/block-ack-manager.cc | 29 +++++++++++++++++++++++------ src/wifi/model/block-ack-manager.h | 28 +++++++++++++++++++++++++--- src/wifi/model/qos-txop.cc | 20 ++++++++++++++++++-- 3 files changed, 66 insertions(+), 11 deletions(-) diff --git a/src/wifi/model/block-ack-manager.cc b/src/wifi/model/block-ack-manager.cc index 7c7c79d98..14e8b1bb1 100644 --- a/src/wifi/model/block-ack-manager.cc +++ b/src/wifi/model/block-ack-manager.cc @@ -368,15 +368,32 @@ void BlockAckManager::StorePacket(Ptr mpdu) { NS_LOG_FUNCTION(this << *mpdu); + DoStorePacket(mpdu, mpdu->GetHeader().GetAddr1()); +} + +void +BlockAckManager::StoreGcrPacket(Ptr 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 mpdu, + const Mac48Address& recipient, + std::optional 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 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) diff --git a/src/wifi/model/block-ack-manager.h b/src/wifi/model/block-ack-manager.h index 9915ff00e..24499c185 100644 --- a/src/wifi/model/block-ack-manager.h +++ b/src/wifi/model/block-ack-manager.h @@ -166,9 +166,19 @@ class BlockAckManager : public Object * @param mpdu MPDU to store. * * Stores mpdu 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 mpdu); + + /** + * @param mpdu groupcast MPDU to store. + * @param members intended recipients for the groupcast MPDU. + * + * Stores mpdu 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 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 tids is only used if blockAck is a Multi-STA Block Ack @@ -211,6 +221,7 @@ class BlockAckManager : public Object const Mac48Address& recipient, const std::set& 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 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 mpdu for a possible future retransmission. + */ + void DoStorePacket(Ptr mpdu, + const Mac48Address& recipient, + std::optional gcrGroupAddr = std::nullopt); + /** * typedef for a list of WifiMpdu. */ diff --git a/src/wifi/model/qos-txop.cc b/src/wifi/model/qos-txop.cc index 429d5b4d1..13c94d90f 100644 --- a/src/wifi/model/qos-txop.cc +++ b/src/wifi/model/qos-txop.cc @@ -732,10 +732,26 @@ QosTxop::NotifyOriginatorAgreementNoReply(const Mac48Address& recipient, void QosTxop::CompleteMpduTx(Ptr 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(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());