wifi: Add support for Multi-STA BlockAck
This commit is contained in:
@@ -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++;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user