diff --git a/src/wifi/model/block-ack-manager.cc b/src/wifi/model/block-ack-manager.cc index ef3326701..62c213648 100644 --- a/src/wifi/model/block-ack-manager.cc +++ b/src/wifi/model/block-ack-manager.cc @@ -600,8 +600,6 @@ BlockAckManager::NotifyDiscardedMpdu(Ptr mpdu) // schedule a BlockAckRequest NS_LOG_DEBUG("Schedule a Block Ack Request for agreement (" << recipient << ", " << +tid << ")"); - Ptr bar = Create(); - bar->AddHeader(GetBlockAckReqHeader(recipient, tid)); WifiMacHeader hdr; hdr.SetType(WIFI_MAC_CTL_BACKREQ); @@ -612,7 +610,7 @@ BlockAckManager::NotifyDiscardedMpdu(Ptr mpdu) hdr.SetNoRetry(); hdr.SetNoMoreFragments(); - ScheduleBar(Create(bar, hdr)); + ScheduleBar(GetBlockAckReqHeader(recipient, tid), hdr); } void @@ -660,31 +658,27 @@ BlockAckManager::GetBlockAckReqHeader(const Mac48Address& recipient, uint8_t tid } void -BlockAckManager::ScheduleBar(Ptr bar) +BlockAckManager::ScheduleBar(const CtrlBAckRequestHeader& reqHdr, const WifiMacHeader& hdr) { - NS_LOG_FUNCTION(this << *bar); - NS_ASSERT(bar->GetHeader().IsBlockAckReq()); + NS_LOG_FUNCTION(this << reqHdr << hdr); - CtrlBAckRequestHeader reqHdr; - bar->GetPacket()->PeekHeader(reqHdr); uint8_t tid = reqHdr.GetTidInfo(); - WifiContainerQueueId queueId(WIFI_CTL_QUEUE, - WIFI_UNICAST, - bar->GetHeader().GetAddr1(), - std::nullopt); + WifiContainerQueueId queueId(WIFI_CTL_QUEUE, WIFI_UNICAST, hdr.GetAddr1(), std::nullopt); + auto pkt = Create(); + pkt->AddHeader(reqHdr); Ptr item = nullptr; // if a BAR for the given agreement is present, replace it with the new one while ((item = m_queue->PeekByQueueId(queueId, item))) { - if (item->GetHeader().IsBlockAckReq() && - item->GetHeader().GetAddr1() == bar->GetHeader().GetAddr1()) + if (item->GetHeader().IsBlockAckReq() && item->GetHeader().GetAddr1() == hdr.GetAddr1()) { CtrlBAckRequestHeader otherHdr; item->GetPacket()->PeekHeader(otherHdr); if (otherHdr.GetTidInfo() == tid) { + auto bar = Create(pkt, hdr, item->GetTimestamp()); // replace item with bar m_queue->Replace(item, bar); return; @@ -692,7 +686,7 @@ BlockAckManager::ScheduleBar(Ptr bar) } } - m_queue->Enqueue(bar); + m_queue->Enqueue(Create(pkt, hdr)); } void diff --git a/src/wifi/model/block-ack-manager.h b/src/wifi/model/block-ack-manager.h index 05aa5ec8c..ce608e9a3 100644 --- a/src/wifi/model/block-ack-manager.h +++ b/src/wifi/model/block-ack-manager.h @@ -408,18 +408,19 @@ class BlockAckManager : public Object CtrlBAckRequestHeader GetBlockAckReqHeader(const Mac48Address& recipient, uint8_t tid) const; /** - * \param bar the BlockAckRequest to enqueue + * \param reqHdr the BlockAckRequest header + * \param hdr the 802.11 MAC header * - * Enqueue the given BlockAckRequest into the queue storing the next (MU-)BAR + * Enqueue the given BlockAckRequest into the queue storing the next BAR * frames to transmit. If a BAR for the same recipient and TID is already present * in the queue, it is replaced by the new one. If the given BAR is retransmitted, * it is placed at the head of the queue, otherwise at the tail. */ - void ScheduleBar(Ptr bar); + void ScheduleBar(const CtrlBAckRequestHeader& reqHdr, const WifiMacHeader& hdr); /** * \param muBar the MU-BAR Trigger Frame to enqueue * - * Enqueue the given MU-BAR Trigger Frame into the queue storing the next (MU-)BAR + * Enqueue the given MU-BAR Trigger Frame into the queue storing the next MU-BAR * frames to transmit. If the given MU-BAR Trigger Frame is retransmitted, * it is placed at the head of the queue, otherwise at the tail. */ diff --git a/src/wifi/model/he/he-frame-exchange-manager.cc b/src/wifi/model/he/he-frame-exchange-manager.cc index daa03a7ce..98cdf45ff 100644 --- a/src/wifi/model/he/he-frame-exchange-manager.cc +++ b/src/wifi/model/he/he-frame-exchange-manager.cc @@ -509,8 +509,9 @@ HeFrameExchangeManager::SendPsduMap() uint8_t tid = *tids.begin(); NS_ASSERT(m_edca); - m_edca->GetBaManager()->ScheduleBar( - m_mac->GetQosTxop(tid)->PrepareBlockAckRequest(psdu.second->GetAddr1(), tid)); + auto [reqHdr, hdr] = + m_mac->GetQosTxop(tid)->PrepareBlockAckRequest(psdu.second->GetAddr1(), tid); + m_edca->GetBaManager()->ScheduleBar(reqHdr, hdr); } } diff --git a/src/wifi/model/ht/ht-frame-exchange-manager.cc b/src/wifi/model/ht/ht-frame-exchange-manager.cc index c0ad4e7a8..b85606bec 100644 --- a/src/wifi/model/ht/ht-frame-exchange-manager.cc +++ b/src/wifi/model/ht/ht-frame-exchange-manager.cc @@ -520,7 +520,10 @@ HtFrameExchangeManager::GetBar(AcIndex ac, { if (queue->PeekByTidAndAddress(tid, recipient)) { - selectedBar = m_mac->GetQosTxop(ac)->PrepareBlockAckRequest(recipient, tid); + auto [reqHdr, hdr] = m_mac->GetQosTxop(ac)->PrepareBlockAckRequest(recipient, tid); + auto pkt = Create(); + pkt->AddHeader(reqHdr); + selectedBar = Create(pkt, hdr); baManager->RemoveFromSendBarIfDataQueuedList(recipient, tid); queue->Enqueue(selectedBar); break; @@ -1041,7 +1044,8 @@ HtFrameExchangeManager::SendPsdu() uint8_t tid = *tids.begin(); Ptr edca = m_mac->GetQosTxop(tid); - GetBaManager(tid)->ScheduleBar(edca->PrepareBlockAckRequest(m_psdu->GetAddr1(), tid)); + auto [reqHdr, hdr] = edca->PrepareBlockAckRequest(m_psdu->GetAddr1(), tid); + GetBaManager(tid)->ScheduleBar(reqHdr, hdr); Simulator::Schedule(txDuration, &HtFrameExchangeManager::TransmissionSucceeded, this); } @@ -1401,7 +1405,8 @@ HtFrameExchangeManager::MissedBlockAck(Ptr psdu, else { // missed block ack after data frame with Implicit BAR Ack policy - GetBaManager(tid)->ScheduleBar(edca->PrepareBlockAckRequest(recipient, tid)); + auto [reqHdr, hdr] = edca->PrepareBlockAckRequest(recipient, tid); + GetBaManager(tid)->ScheduleBar(reqHdr, hdr); } resetCw = false; } diff --git a/src/wifi/model/qos-txop.cc b/src/wifi/model/qos-txop.cc index 32ed8fdb2..5bc6e8951 100644 --- a/src/wifi/model/qos-txop.cc +++ b/src/wifi/model/qos-txop.cc @@ -287,7 +287,7 @@ QosTxop::GetBaStartingSequence(Mac48Address address, uint8_t tid) const return m_baManager->GetOriginatorStartingSequence(address, tid); } -Ptr +std::pair QosTxop::PrepareBlockAckRequest(Mac48Address recipient, uint8_t tid) const { NS_LOG_FUNCTION(this << recipient << +tid); @@ -297,8 +297,6 @@ QosTxop::PrepareBlockAckRequest(Mac48Address recipient, uint8_t tid) const CtrlBAckRequestHeader reqHdr = m_baManager->GetBlockAckReqHeader(recipientMld.value_or(recipient), tid); - Ptr bar = Create(); - bar->AddHeader(reqHdr); WifiMacHeader hdr; hdr.SetType(WIFI_MAC_CTL_BACKREQ); @@ -309,7 +307,7 @@ QosTxop::PrepareBlockAckRequest(Mac48Address recipient, uint8_t tid) const hdr.SetNoRetry(); hdr.SetNoMoreFragments(); - return Create(bar, hdr); + return {reqHdr, hdr}; } bool diff --git a/src/wifi/model/qos-txop.h b/src/wifi/model/qos-txop.h index 53e2a33ae..894dce5c7 100644 --- a/src/wifi/model/qos-txop.h +++ b/src/wifi/model/qos-txop.h @@ -136,14 +136,15 @@ class QosTxop : public Txop /** * \param recipient Address of recipient. * \param tid traffic ID. - * \return the BlockAckRequest to send + * \return the BlockAckRequest header and the MAC header for the BlockAckReq * * Prepare a BlockAckRequest to be sent to recipient for Traffic ID * tid. The header for the BlockAckRequest is requested to the QosTxop * corresponding to the given TID. A block ack agreement with the given recipient * for the given TID must have been established by such QosTxop. */ - Ptr PrepareBlockAckRequest(Mac48Address recipient, uint8_t tid) const; + std::pair PrepareBlockAckRequest(Mac48Address recipient, + uint8_t tid) const; /* Event handlers */ /**