diff --git a/src/wifi/model/block-ack-manager.cc b/src/wifi/model/block-ack-manager.cc index b4a6357b5..38f92e46c 100644 --- a/src/wifi/model/block-ack-manager.cc +++ b/src/wifi/model/block-ack-manager.cc @@ -456,12 +456,21 @@ BlockAckManager::NotifyMissedAck (Ptr mpdu) } void -BlockAckManager::NotifyGotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address recipient, double rxSnr, double dataSnr, WifiTxVector dataTxVector) +BlockAckManager::NotifyGotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address recipient, + const std::set& tids, double rxSnr, double dataSnr, + const WifiTxVector& dataTxVector, size_t index) { - NS_LOG_FUNCTION (this << blockAck << recipient << rxSnr << dataSnr << dataTxVector); + NS_LOG_FUNCTION (this << blockAck << recipient << rxSnr << dataSnr << dataTxVector << index); if (!blockAck->IsMultiTid ()) { - uint8_t tid = blockAck->GetTidInfo (); + uint8_t tid = blockAck->GetTidInfo (index); + // If this is a Multi-STA Block Ack with All-ack context (TID equal to 14), + // use the TID passed by the caller. + if (tid == 14) + { + NS_ASSERT (blockAck->GetAckType (index) && tids.size () == 1); + tid = *tids.begin (); + } if (ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED)) { bool foundFirstLost = false; @@ -515,12 +524,12 @@ BlockAckManager::NotifyGotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac4 RemoveOldPackets (recipient, tid, (currentSeq + 1) % SEQNO_SPACE_SIZE); } } - else if (blockAck->IsCompressed () || blockAck->IsExtendedCompressed ()) + else if (blockAck->IsCompressed () || blockAck->IsExtendedCompressed () || blockAck->IsMultiSta ()) { for (PacketQueueI queueIt = it->second.second.begin (); queueIt != queueEnd; ) { currentSeq = (*queueIt)->GetHeader ().GetSequenceNumber (); - if (blockAck->IsPacketReceived (currentSeq)) + if (blockAck->IsPacketReceived (currentSeq, index)) { it->second.first.NotifyAckedMpdu (*queueIt); nSuccessfulMpdus++; diff --git a/src/wifi/model/block-ack-manager.h b/src/wifi/model/block-ack-manager.h index 429439185..513cbcfed 100644 --- a/src/wifi/model/block-ack-manager.h +++ b/src/wifi/model/block-ack-manager.h @@ -194,17 +194,23 @@ public: /** * \param blockAck The received BlockAck frame. * \param recipient Sender of BlockAck frame. + * \param tids the set of TIDs the acknowledged MPDUs belong to * \param rxSnr received SNR of the BlockAck frame itself * \param dataSnr data SNR reported by remote station * \param dataTxVector the TXVECTOR used to send the Data + * \param index the index of the Per AID TID Info subfield, in case of Multi-STA + * Block Ack, or 0, otherwise * * Invoked upon receipt of a BlockAck frame. Typically, this function, is called * by ns3::QosTxop object. 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 + * using All-ack context. */ void NotifyGotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address recipient, - double rxSnr, double dataSnr, WifiTxVector dataTxVector); + const std::set& tids, double rxSnr, double dataSnr, + const WifiTxVector& dataTxVector, size_t index = 0); /** * \param recipient Sender of the expected BlockAck frame. * \param tid Traffic ID. diff --git a/src/wifi/model/he/he-frame-exchange-manager.cc b/src/wifi/model/he/he-frame-exchange-manager.cc index ae6aad1cc..c114e478d 100644 --- a/src/wifi/model/he/he-frame-exchange-manager.cc +++ b/src/wifi/model/he/he-frame-exchange-manager.cc @@ -905,7 +905,7 @@ HeFrameExchangeManager::ReceiveMpdu (Ptr mpdu, RxSignalInfo rx CtrlBAckResponseHeader blockAck; mpdu->GetPacket ()->PeekHeader (blockAck); uint8_t tid = blockAck.GetTidInfo (); - GetBaManager (tid)->NotifyGotBlockAck (&blockAck, hdr.GetAddr2 (), rxSignalInfo.snr, + GetBaManager (tid)->NotifyGotBlockAck (&blockAck, hdr.GetAddr2 (), {tid}, rxSignalInfo.snr, tag.Get (), m_txParams.m_txVector); // remove the sender from the set of stations that are expected to send a BlockAck diff --git a/src/wifi/model/ht/ht-frame-exchange-manager.cc b/src/wifi/model/ht/ht-frame-exchange-manager.cc index 778924dfe..e53398035 100644 --- a/src/wifi/model/ht/ht-frame-exchange-manager.cc +++ b/src/wifi/model/ht/ht-frame-exchange-manager.cc @@ -1338,7 +1338,7 @@ HtFrameExchangeManager::ReceiveMpdu (Ptr mpdu, RxSignalInfo rx CtrlBAckResponseHeader blockAck; mpdu->GetPacket ()->PeekHeader (blockAck); uint8_t tid = blockAck.GetTidInfo (); - GetBaManager (tid)->NotifyGotBlockAck (&blockAck, hdr.GetAddr2 (), rxSnr, + GetBaManager (tid)->NotifyGotBlockAck (&blockAck, hdr.GetAddr2 (), {tid}, rxSnr, tag.Get (), m_txParams.m_txVector); // cancel the timer diff --git a/src/wifi/model/recipient-block-ack-agreement.cc b/src/wifi/model/recipient-block-ack-agreement.cc index 0d864e853..339b65862 100644 --- a/src/wifi/model/recipient-block-ack-agreement.cc +++ b/src/wifi/model/recipient-block-ack-agreement.cc @@ -221,9 +221,9 @@ RecipientBlockAckAgreement::NotifyReceivedBar (uint16_t startingSequenceNumber) } void -RecipientBlockAckAgreement::FillBlockAckBitmap (CtrlBAckResponseHeader *blockAckHeader) const +RecipientBlockAckAgreement::FillBlockAckBitmap (CtrlBAckResponseHeader *blockAckHeader, std::size_t index) const { - NS_LOG_FUNCTION (this << blockAckHeader); + NS_LOG_FUNCTION (this << blockAckHeader << index); if (blockAckHeader->IsBasic ()) { NS_FATAL_ERROR ("Basic block ack is not supported."); @@ -232,7 +232,8 @@ RecipientBlockAckAgreement::FillBlockAckBitmap (CtrlBAckResponseHeader *blockAck { NS_FATAL_ERROR ("Multi-tid block ack is not supported."); } - else if (blockAckHeader->IsCompressed () || blockAckHeader->IsExtendedCompressed ()) + else if (blockAckHeader->IsCompressed () || blockAckHeader->IsExtendedCompressed () + || blockAckHeader->IsMultiSta ()) { // The Starting Sequence Number subfield of the Block Ack Starting Sequence // Control subfield of the BlockAck frame shall be set to any value in the @@ -240,14 +241,14 @@ RecipientBlockAckAgreement::FillBlockAckBitmap (CtrlBAckResponseHeader *blockAck // We set it to WinStartR uint16_t ssn = m_scoreboard.GetWinStart (); NS_LOG_DEBUG ("SSN=" << ssn); - blockAckHeader->SetStartingSequence (ssn); - blockAckHeader->ResetBitmap (); + blockAckHeader->SetStartingSequence (ssn, index); + blockAckHeader->ResetBitmap (index); for (std::size_t i = 0; i < m_scoreboard.GetWinSize (); i++) { if (m_scoreboard.At (i)) { - blockAckHeader->SetReceivedPacket ((ssn + i) % SEQNO_SPACE_SIZE); + blockAckHeader->SetReceivedPacket ((ssn + i) % SEQNO_SPACE_SIZE, index); } } } diff --git a/src/wifi/model/recipient-block-ack-agreement.h b/src/wifi/model/recipient-block-ack-agreement.h index 298d039d8..2b2995b94 100644 --- a/src/wifi/model/recipient-block-ack-agreement.h +++ b/src/wifi/model/recipient-block-ack-agreement.h @@ -80,10 +80,13 @@ public: /** * Set the Starting Sequence Number subfield of the Block Ack Starting Sequence * Control subfield of the Block Ack frame and fill the block ack bitmap. + * For Multi-STA Block Acks, index identifies the Per AID TID Info + * subfield whose bitmap has to be filled. * * \param blockAckHeader the block ack header + * \param index the index of the Per AID TID Info subfield (Multi-STA Block Ack only) */ - void FillBlockAckBitmap (CtrlBAckResponseHeader *blockAckHeader) const; + void FillBlockAckBitmap (CtrlBAckResponseHeader *blockAckHeader, std::size_t index = 0) const; /** * This is called when a Block Ack agreement is destroyed to flush the * received packets.