wifi: Add support for Multi-STA BlockAck

This commit is contained in:
Stefano Avallone
2021-01-09 12:24:01 +01:00
parent e5629b2748
commit e164766c9b
6 changed files with 34 additions and 15 deletions

View File

@@ -456,12 +456,21 @@ BlockAckManager::NotifyMissedAck (Ptr<WifiMacQueueItem> 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<uint8_t>& 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++;

View File

@@ -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 <i>tids</i> is only used if <i>blockAck</i> 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<uint8_t>& tids, double rxSnr, double dataSnr,
const WifiTxVector& dataTxVector, size_t index = 0);
/**
* \param recipient Sender of the expected BlockAck frame.
* \param tid Traffic ID.

View File

@@ -905,7 +905,7 @@ HeFrameExchangeManager::ReceiveMpdu (Ptr<WifiMacQueueItem> 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

View File

@@ -1338,7 +1338,7 @@ HtFrameExchangeManager::ReceiveMpdu (Ptr<WifiMacQueueItem> 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

View File

@@ -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);
}
}
}

View File

@@ -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, <i>index</i> 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.