From 4586aee61e7cfa8d9ad299c256bc130348f3a9a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deronne?= Date: Tue, 24 Oct 2023 20:53:50 +0200 Subject: [PATCH] wifi: Handle GCR Block Ack agreement teardown --- src/wifi/model/block-ack-manager.cc | 63 ++++++++++++------- src/wifi/model/block-ack-manager.h | 37 ++++++++--- .../model/ht/ht-frame-exchange-manager.cc | 36 ++++++++--- src/wifi/model/ht/ht-frame-exchange-manager.h | 6 +- src/wifi/model/qos-txop.cc | 45 ++++++++----- src/wifi/model/qos-txop.h | 13 +++- 6 files changed, 141 insertions(+), 59 deletions(-) diff --git a/src/wifi/model/block-ack-manager.cc b/src/wifi/model/block-ack-manager.cc index d21192357..2b36209fb 100644 --- a/src/wifi/model/block-ack-manager.cc +++ b/src/wifi/model/block-ack-manager.cc @@ -215,10 +215,13 @@ BlockAckManager::CreateOriginatorAgreement(const MgtAddBaRequestHeader& reqHdr, } void -BlockAckManager::DestroyOriginatorAgreement(const Mac48Address& recipient, uint8_t tid) +BlockAckManager::DestroyOriginatorAgreement(const Mac48Address& recipient, + uint8_t tid, + std::optional gcrGroupAddr) { - NS_LOG_FUNCTION(this << recipient << tid); - if (auto it = GetOriginatorBaAgreement(recipient, tid); it != m_originatorAgreements.end()) + NS_LOG_FUNCTION(this << recipient << tid << gcrGroupAddr.has_value()); + if (auto it = GetOriginatorBaAgreement(recipient, tid, gcrGroupAddr); + it != m_originatorAgreements.end()) { m_originatorAgreements.erase(it); } @@ -267,7 +270,8 @@ BlockAckManager::UpdateOriginatorAgreement(const MgtAddBaResponseHeader& respHdr &BlockAckManager::InactivityTimeout, this, recipient, - tid); + tid, + respHdr.GetGcrGroupAddress()); } } m_unblockPackets(recipient, tid); @@ -327,10 +331,13 @@ BlockAckManager::CreateRecipientAgreement(const MgtAddBaResponseHeader& respHdr, } void -BlockAckManager::DestroyRecipientAgreement(const Mac48Address& originator, uint8_t tid) +BlockAckManager::DestroyRecipientAgreement(const Mac48Address& originator, + uint8_t tid, + std::optional gcrGroupAddr) { - NS_LOG_FUNCTION(this << originator << tid); - if (auto it = GetRecipientBaAgreement(originator, tid); it != m_recipientAgreements.end()) + NS_LOG_FUNCTION(this << originator << tid << gcrGroupAddr.has_value()); + if (auto it = GetRecipientBaAgreement(originator, tid, gcrGroupAddr); + it != m_recipientAgreements.end()) { // forward up the buffered MPDUs before destroying the agreement it->second.Flush(); @@ -558,7 +565,12 @@ BlockAckManager::NotifyGotBlockAck(uint8_t linkId, it->second.first.m_inactivityEvent.Cancel(); Time timeout = MicroSeconds(1024 * it->second.first.GetTimeout()); it->second.first.m_inactivityEvent = - Simulator::Schedule(timeout, &BlockAckManager::InactivityTimeout, this, recipient, tid); + Simulator::Schedule(timeout, + &BlockAckManager::InactivityTimeout, + this, + recipient, + tid, + std::nullopt); } NS_ASSERT(blockAck.IsCompressed() || blockAck.IsExtendedCompressed() || blockAck.IsMultiSta()); @@ -818,17 +830,21 @@ BlockAckManager::RemoveFromSendBarIfDataQueuedList(const Mac48Address& recipient } void -BlockAckManager::InactivityTimeout(const Mac48Address& recipient, uint8_t tid) +BlockAckManager::InactivityTimeout(const Mac48Address& recipient, + uint8_t tid, + std::optional gcrGroupAddr) { - NS_LOG_FUNCTION(this << recipient << tid); - m_blockAckInactivityTimeout(recipient, tid, true); + NS_LOG_FUNCTION(this << recipient << tid << gcrGroupAddr.has_value()); + m_blockAckInactivityTimeout(recipient, tid, true, gcrGroupAddr); } void -BlockAckManager::NotifyOriginatorAgreementRejected(const Mac48Address& recipient, uint8_t tid) +BlockAckManager::NotifyOriginatorAgreementRejected(const Mac48Address& recipient, + uint8_t tid, + std::optional gcrGroupAddr) { - NS_LOG_FUNCTION(this << recipient << tid); - auto it = GetOriginatorBaAgreement(recipient, tid); + NS_LOG_FUNCTION(this << recipient << tid << gcrGroupAddr.has_value()); + auto it = GetOriginatorBaAgreement(recipient, tid, gcrGroupAddr); NS_ASSERT(it != m_originatorAgreements.end()); if (!it->second.first.IsRejected()) { @@ -842,10 +858,12 @@ BlockAckManager::NotifyOriginatorAgreementRejected(const Mac48Address& recipient } void -BlockAckManager::NotifyOriginatorAgreementNoReply(const Mac48Address& recipient, uint8_t tid) +BlockAckManager::NotifyOriginatorAgreementNoReply(const Mac48Address& recipient, + uint8_t tid, + std::optional gcrGroupAddr) { - NS_LOG_FUNCTION(this << recipient << tid); - auto it = GetOriginatorBaAgreement(recipient, tid); + NS_LOG_FUNCTION(this << recipient << tid << gcrGroupAddr.has_value()); + auto it = GetOriginatorBaAgreement(recipient, tid, gcrGroupAddr); NS_ASSERT(it != m_originatorAgreements.end()); if (!it->second.first.IsNoReply()) { @@ -859,10 +877,12 @@ BlockAckManager::NotifyOriginatorAgreementNoReply(const Mac48Address& recipient, } void -BlockAckManager::NotifyOriginatorAgreementReset(const Mac48Address& recipient, uint8_t tid) +BlockAckManager::NotifyOriginatorAgreementReset(const Mac48Address& recipient, + uint8_t tid, + std::optional gcrGroupAddr) { - NS_LOG_FUNCTION(this << recipient << tid); - auto it = GetOriginatorBaAgreement(recipient, tid); + NS_LOG_FUNCTION(this << recipient << tid << gcrGroupAddr.has_value()); + auto it = GetOriginatorBaAgreement(recipient, tid, gcrGroupAddr); NS_ASSERT(it != m_originatorAgreements.end()); if (!it->second.first.IsReset()) { @@ -911,7 +931,8 @@ BlockAckManager::NeedBarRetransmission(uint8_t tid, const Mac48Address& recipien } void -BlockAckManager::SetBlockAckInactivityCallback(Callback callback) +BlockAckManager::SetBlockAckInactivityCallback( + Callback> callback) { NS_LOG_FUNCTION(this << &callback); m_blockAckInactivityTimeout = callback; diff --git a/src/wifi/model/block-ack-manager.h b/src/wifi/model/block-ack-manager.h index 04f063474..483226aeb 100644 --- a/src/wifi/model/block-ack-manager.h +++ b/src/wifi/model/block-ack-manager.h @@ -111,11 +111,14 @@ class BlockAckManager : public Object /** * @param recipient Address of peer station involved in block ack mechanism. * @param tid traffic ID of transmitted packet. + * @param gcrGroupAddr the GCR Group Address (only if it a GCR Block Ack agreement) * * Invoked when a recipient reject a block ack agreement or when a DELBA frame * is Received/Transmitted. */ - void DestroyOriginatorAgreement(const Mac48Address& recipient, uint8_t tid); + void DestroyOriginatorAgreement(const Mac48Address& recipient, + uint8_t tid, + std::optional gcrGroupAddr); /** * @param respHdr Relative Add block ack response (action frame). * @param recipient Address of peer station involved in block ack mechanism. @@ -152,8 +155,11 @@ class BlockAckManager : public Object * * @param originator the originator MAC address * @param tid the TID associated with the Block Ack agreement + * @param gcrGroupAddr the GCR Group Address (only if it a GCR Block Ack agreement) */ - void DestroyRecipientAgreement(const Mac48Address& originator, uint8_t tid); + void DestroyRecipientAgreement(const Mac48Address& originator, + uint8_t tid, + std::optional gcrGroupAddr); /** * @param mpdu MPDU to store. @@ -246,29 +252,38 @@ class BlockAckManager : public Object /** * @param recipient Address of peer station involved in block ack mechanism. * @param tid Traffic ID of transmitted packet. + * @param gcrGroupAddr the GCR Group Address (only if it a GCR Block Ack agreement) * * Marks an originator agreement as rejected. This happens if recipient station reject * block ack setup by an ADDBA Response frame with a failure status code. For now we assume * that every QoS station accepts a block ack setup. */ - void NotifyOriginatorAgreementRejected(const Mac48Address& recipient, uint8_t tid); + void NotifyOriginatorAgreementRejected(const Mac48Address& recipient, + uint8_t tid, + std::optional gcrGroupAddr); /** * @param recipient Address of peer station involved in block ack mechanism. * @param tid Traffic ID of transmitted packet. + * @param gcrGroupAddr the GCR Group Address (only if it a GCR Block Ack agreement) * * Marks an originator agreement after not receiving response to ADDBA request. During this * state any packets in queue will be transmitted using normal MPDU. This also unblocks * recipient address. */ - void NotifyOriginatorAgreementNoReply(const Mac48Address& recipient, uint8_t tid); + void NotifyOriginatorAgreementNoReply(const Mac48Address& recipient, + uint8_t tid, + std::optional gcrGroupAddr); /** * @param recipient Address of peer station involved in block ack mechanism. * @param tid Traffic ID of transmitted packet. + * @param gcrGroupAddr the GCR Group Address (only if it a GCR Block Ack agreement) * * Set Originator BA agreement to a transitory state to reset it after not receiving response * to ADDBA request. */ - void NotifyOriginatorAgreementReset(const Mac48Address& recipient, uint8_t tid); + void NotifyOriginatorAgreementReset(const Mac48Address& recipient, + uint8_t tid, + std::optional gcrGroupAddr); /** * @param nPackets Minimum number of packets for use of block ack. * @@ -287,7 +302,8 @@ class BlockAckManager : public Object * Set block ack inactivity callback * @param callback the block ack inactivity callback function */ - void SetBlockAckInactivityCallback(Callback callback); + void SetBlockAckInactivityCallback( + Callback> callback); /** * Set block destination callback * @param callback the block destination callback @@ -456,11 +472,14 @@ class BlockAckManager : public Object private: /** - * Inactivity timeout function + * Inactivity timeout function for a Block Ack agreement * @param recipient the recipient MAC address * @param tid Traffic ID + * @param gcrGroupAddr the GCR Group Address (only if it a GCR Block Ack agreement) */ - void InactivityTimeout(const Mac48Address& recipient, uint8_t tid); + void InactivityTimeout(const Mac48Address& recipient, + uint8_t tid, + std::optional gcrGroupAddr); /** * typedef for a list of WifiMpdu. @@ -569,7 +588,7 @@ class BlockAckManager : public Object uint8_t m_blockAckThreshold; ///< block ack threshold Ptr m_queue; ///< queue - Callback + Callback> m_blockAckInactivityTimeout; ///< BlockAck inactivity timeout callback Callback m_blockPackets; ///< block packets callback Callback m_unblockPackets; ///< unblock packets callback diff --git a/src/wifi/model/ht/ht-frame-exchange-manager.cc b/src/wifi/model/ht/ht-frame-exchange-manager.cc index d2518898c..ddedbbe79 100644 --- a/src/wifi/model/ht/ht-frame-exchange-manager.cc +++ b/src/wifi/model/ht/ht-frame-exchange-manager.cc @@ -286,7 +286,8 @@ HtFrameExchangeManager::SendAddBaResponse(const MgtAddBaRequestHeader& reqHdr, this, originator, tid, - false); + false, + reqHdr.GetGcrGroupAddress()); } auto mpdu = Create(packet, hdr); @@ -320,9 +321,12 @@ HtFrameExchangeManager::SendAddBaResponse(const MgtAddBaRequestHeader& reqHdr, } void -HtFrameExchangeManager::SendDelbaFrame(Mac48Address addr, uint8_t tid, bool byOriginator) +HtFrameExchangeManager::SendDelbaFrame(Mac48Address addr, + uint8_t tid, + bool byOriginator, + std::optional gcrGroupAddr) { - NS_LOG_FUNCTION(this << addr << +tid << byOriginator); + NS_LOG_FUNCTION(this << addr << +tid << byOriginator << gcrGroupAddr.has_value()); WifiMacHeader hdr; hdr.SetType(WIFI_MAC_MGT_ACTION); // use the remote link address if addr is an MLD address @@ -335,6 +339,10 @@ HtFrameExchangeManager::SendDelbaFrame(Mac48Address addr, uint8_t tid, bool byOr MgtDelBaHeader delbaHdr; delbaHdr.SetTid(tid); byOriginator ? delbaHdr.SetByOriginator() : delbaHdr.SetByRecipient(); + if (gcrGroupAddr.has_value()) + { + delbaHdr.SetGcrGroupAddress(gcrGroupAddr.value()); + } WifiActionHeader actionHdr; WifiActionHeader::ActionValue action; @@ -725,11 +733,15 @@ HtFrameExchangeManager::NotifyReceivedNormalAck(Ptr mpdu) auto tid = delBa.GetTid(); if (delBa.IsByOriginator()) { - GetBaManager(tid)->DestroyOriginatorAgreement(address, tid); + GetBaManager(tid)->DestroyOriginatorAgreement(address, + tid, + delBa.GetGcrGroupAddress()); } else { - GetBaManager(tid)->DestroyRecipientAgreement(address, tid); + GetBaManager(tid)->DestroyRecipientAgreement(address, + tid, + delBa.GetGcrGroupAddress()); } } else if (actionHdr.GetAction().blockAck == WifiActionHeader::BLOCK_ACK_ADDBA_REQUEST) @@ -742,7 +754,8 @@ HtFrameExchangeManager::NotifyReceivedNormalAck(Ptr mpdu) &QosTxop::AddBaResponseTimeout, edca, address, - addBa.GetTid()); + addBa.GetTid(), + addBa.GetGcrGroupAddress()); } else if (actionHdr.GetAction().blockAck == WifiActionHeader::BLOCK_ACK_ADDBA_RESPONSE) { @@ -828,12 +841,15 @@ HtFrameExchangeManager::NotifyPacketDiscarded(Ptr mpdu) { NS_LOG_DEBUG("No ACK after ADDBA request"); Ptr qosTxop = m_mac->GetQosTxop(tid); - qosTxop->NotifyOriginatorAgreementNoReply(recipient, tid); + qosTxop->NotifyOriginatorAgreementNoReply(recipient, + tid, + addBa.GetGcrGroupAddress()); Simulator::Schedule(qosTxop->GetFailedAddBaTimeout(), &QosTxop::ResetBa, qosTxop, recipient, - tid); + tid, + addBa.GetGcrGroupAddress()); } } } @@ -1769,7 +1785,9 @@ HtFrameExchangeManager::ReceiveMgtAction(Ptr mpdu, const WifiTxV // agreement exists in BlockAckManager and we need to // destroy it. GetBaManager(delBaHdr.GetTid()) - ->DestroyRecipientAgreement(recipient, delBaHdr.GetTid()); + ->DestroyRecipientAgreement(recipient, + delBaHdr.GetTid(), + delBaHdr.GetGcrGroupAddress()); } else { diff --git a/src/wifi/model/ht/ht-frame-exchange-manager.h b/src/wifi/model/ht/ht-frame-exchange-manager.h index e0c30b2f2..2e6f0a949 100644 --- a/src/wifi/model/ht/ht-frame-exchange-manager.h +++ b/src/wifi/model/ht/ht-frame-exchange-manager.h @@ -138,8 +138,12 @@ class HtFrameExchangeManager : public QosFrameExchangeManager * @param addr address of the recipient. * @param tid traffic ID. * @param byOriginator flag to indicate whether this is set by the originator. + * @param gcrGroupAddr the GCR Group Address (only if it a GCR Block Ack agreement) */ - void SendDelbaFrame(Mac48Address addr, uint8_t tid, bool byOriginator); + void SendDelbaFrame(Mac48Address addr, + uint8_t tid, + bool byOriginator, + std::optional gcrGroupAddr); /** * Get the next BlockAckRequest or MU-BAR Trigger Frame to send, if any. If TID and recipient diff --git a/src/wifi/model/qos-txop.cc b/src/wifi/model/qos-txop.cc index 35823dd6c..7c2b646a9 100644 --- a/src/wifi/model/qos-txop.cc +++ b/src/wifi/model/qos-txop.cc @@ -680,7 +680,9 @@ QosTxop::GotAddBaResponse(const MgtAddBaResponseHeader& respHdr, Mac48Address re else { NS_LOG_DEBUG("discard ADDBA response" << recipient); - m_baManager->NotifyOriginatorAgreementRejected(recipient, tid); + m_baManager->NotifyOriginatorAgreementRejected(recipient, + tid, + respHdr.GetGcrGroupAddress()); } } @@ -689,14 +691,18 @@ QosTxop::GotDelBaFrame(const MgtDelBaHeader* delBaHdr, Mac48Address recipient) { NS_LOG_FUNCTION(this << delBaHdr << recipient); NS_LOG_DEBUG("received DELBA frame from=" << recipient); - m_baManager->DestroyOriginatorAgreement(recipient, delBaHdr->GetTid()); + m_baManager->DestroyOriginatorAgreement(recipient, + delBaHdr->GetTid(), + delBaHdr->GetGcrGroupAddress()); } void -QosTxop::NotifyOriginatorAgreementNoReply(const Mac48Address& recipient, uint8_t tid) +QosTxop::NotifyOriginatorAgreementNoReply(const Mac48Address& recipient, + uint8_t tid, + std::optional gcrGroupAddr) { - NS_LOG_FUNCTION(this << recipient << tid); - m_baManager->NotifyOriginatorAgreementNoReply(recipient, tid); + NS_LOG_FUNCTION(this << recipient << tid << gcrGroupAddr.has_value()); + m_baManager->NotifyOriginatorAgreementNoReply(recipient, tid, gcrGroupAddr); } void @@ -742,30 +748,37 @@ QosTxop::GetBlockAckInactivityTimeout() const } void -QosTxop::AddBaResponseTimeout(Mac48Address recipient, uint8_t tid) +QosTxop::AddBaResponseTimeout(Mac48Address recipient, + uint8_t tid, + std::optional gcrGroupAddr) { - NS_LOG_FUNCTION(this << recipient << +tid); + NS_LOG_FUNCTION(this << recipient << +tid << gcrGroupAddr.has_value()); // If agreement is still pending, ADDBA response is not received - if (auto agreement = m_baManager->GetAgreementAsOriginator(recipient, tid); - agreement && agreement->get().IsPending()) + auto agreement = m_baManager->GetAgreementAsOriginator(recipient, tid, gcrGroupAddr); + if (agreement && agreement->get().IsPending()) { - NotifyOriginatorAgreementNoReply(recipient, tid); - Simulator::Schedule(m_failedAddBaTimeout, &QosTxop::ResetBa, this, recipient, tid); + NotifyOriginatorAgreementNoReply(recipient, tid, gcrGroupAddr); + Simulator::Schedule(m_failedAddBaTimeout, + &QosTxop::ResetBa, + this, + recipient, + tid, + gcrGroupAddr); } } void -QosTxop::ResetBa(Mac48Address recipient, uint8_t tid) +QosTxop::ResetBa(Mac48Address recipient, uint8_t tid, std::optional gcrGroupAddr) { - NS_LOG_FUNCTION(this << recipient << +tid); + NS_LOG_FUNCTION(this << recipient << +tid << gcrGroupAddr.has_value()); // This function is scheduled when waiting for an ADDBA response. However, // before this function is called, a DELBA request may arrive, which causes // the agreement to be deleted. Hence, check if an agreement exists before // notifying that the agreement has to be reset. - if (auto agreement = m_baManager->GetAgreementAsOriginator(recipient, tid); - agreement && !agreement->get().IsEstablished()) + auto agreement = m_baManager->GetAgreementAsOriginator(recipient, tid, gcrGroupAddr); + if (agreement && !agreement->get().IsEstablished()) { - m_baManager->NotifyOriginatorAgreementReset(recipient, tid); + m_baManager->NotifyOriginatorAgreementReset(recipient, tid, gcrGroupAddr); } } diff --git a/src/wifi/model/qos-txop.h b/src/wifi/model/qos-txop.h index 96a4cc372..b6d9bc179 100644 --- a/src/wifi/model/qos-txop.h +++ b/src/wifi/model/qos-txop.h @@ -143,22 +143,29 @@ class QosTxop : public Txop * * @param recipient the intended recipient of the ADDBA_REQUEST frame * @param tid the TID + * @param gcrGroupAddr the GCR Group Address (only if it a GCR Block Ack agreement) */ - void NotifyOriginatorAgreementNoReply(const Mac48Address& recipient, uint8_t tid); + void NotifyOriginatorAgreementNoReply(const Mac48Address& recipient, + uint8_t tid, + std::optional gcrGroupAddr); /** * Callback when ADDBA response is not received after timeout. * * @param recipient MAC address of recipient * @param tid traffic ID + * @param gcrGroupAddr the GCR Group Address (only if it a GCR Block Ack agreement) */ - void AddBaResponseTimeout(Mac48Address recipient, uint8_t tid); + void AddBaResponseTimeout(Mac48Address recipient, + uint8_t tid, + std::optional gcrGroupAddr); /** * Reset BA agreement after BA negotiation failed. * * @param recipient MAC address of recipient * @param tid traffic ID + * @param gcrGroupAddr the GCR Group Address (only if it a GCR Block Ack agreement) */ - void ResetBa(Mac48Address recipient, uint8_t tid); + void ResetBa(Mac48Address recipient, uint8_t tid, std::optional gcrGroupAddr); /** * Set threshold for block ack mechanism. If number of packets in the