wifi: (fixes #79) Block Ack manager uses the originator block ack window

This commit is contained in:
Stefano Avallone
2019-08-28 19:25:47 +02:00
parent f9089161e1
commit e9022846f6
2 changed files with 38 additions and 44 deletions

View File

@@ -198,6 +198,7 @@ BlockAckManager::UpdateAgreement (const MgtAddBaResponseHeader *respHdr, Mac48Ad
// update the starting sequence number because some frames may have been sent
// under Normal Ack policy after the transmission of the ADDBA Request frame
agreement.SetStartingSequence (m_txMiddle->GetNextSeqNumberByTidAndAddress (tid, recipient));
agreement.InitTxWindow ();
if (respHdr->IsImmediateBlockAck ())
{
agreement.SetImmediateBlockAck ();
@@ -241,8 +242,7 @@ BlockAckManager::StorePacket (Ptr<WifiMacQueueItem> mpdu)
AgreementsI agreementIt = m_agreements.find (std::make_pair (recipient, tid));
NS_ASSERT (agreementIt != m_agreements.end ());
uint16_t startingSeq = agreementIt->second.first.GetStartingSequence ();
uint16_t mpduDist = (mpdu->GetHeader ().GetSequenceNumber () - startingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE;
uint16_t mpduDist = agreementIt->second.first.GetDistance (mpdu->GetHeader ().GetSequenceNumber ());
if (mpduDist >= SEQNO_SPACE_HALF_SIZE)
{
@@ -261,7 +261,7 @@ BlockAckManager::StorePacket (Ptr<WifiMacQueueItem> mpdu)
return;
}
uint16_t dist = ((*it)->GetHeader ().GetSequenceNumber () - startingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE;
uint16_t dist = agreementIt->second.first.GetDistance ((*it)->GetHeader ().GetSequenceNumber ());
if (mpduDist < dist ||
(mpduDist == dist && mpdu->GetHeader ().GetFragmentNumber () < (*it)->GetHeader ().GetFragmentNumber ()))
@@ -272,6 +272,7 @@ BlockAckManager::StorePacket (Ptr<WifiMacQueueItem> mpdu)
it++;
}
agreementIt->second.second.insert (it, mpdu);
agreementIt->second.first.NotifyTransmittedMpdu (mpdu);
}
bool
@@ -361,12 +362,7 @@ BlockAckManager::NotifyGotAck (Ptr<const WifiMacQueueItem> mpdu)
}
}
uint16_t startingSeq = it->second.first.GetStartingSequence ();
if (mpdu->GetHeader ().GetSequenceNumber () == startingSeq)
{
// make the transmit window advance
it->second.first.SetStartingSequence ((startingSeq + 1) % SEQNO_SPACE_SIZE);
}
it->second.first.NotifyAckedMpdu (mpdu);
}
void
@@ -447,7 +443,7 @@ BlockAckManager::NotifyGotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac4
if (!foundFirstLost)
{
foundFirstLost = true;
SetStartingSequence (recipient, tid, currentSeq);
RemoveOldPackets (recipient, tid, currentSeq);
}
nFailedMpdus++;
InsertInRetryQueue (*queueIt);
@@ -458,7 +454,7 @@ BlockAckManager::NotifyGotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac4
// If all frames were acknowledged, move the transmit window past the last one
if (!foundFirstLost && currentSeq != SEQNO_SPACE_SIZE)
{
SetStartingSequence (recipient, tid, (currentSeq + 1) % SEQNO_SPACE_SIZE);
RemoveOldPackets (recipient, tid, (currentSeq + 1) % SEQNO_SPACE_SIZE);
}
}
else if (blockAck->IsCompressed () || blockAck->IsExtendedCompressed ())
@@ -468,6 +464,7 @@ BlockAckManager::NotifyGotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac4
currentSeq = (*queueIt)->GetHeader ().GetSequenceNumber ();
if (blockAck->IsPacketReceived (currentSeq))
{
it->second.first.NotifyAckedMpdu (*queueIt);
nSuccessfulMpdus++;
if (!m_txOkCallback.IsNull ())
{
@@ -476,11 +473,6 @@ BlockAckManager::NotifyGotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac4
}
else if (!QosUtilsIsOldPacket (currentStartingSeq, currentSeq))
{
if (!foundFirstLost)
{
foundFirstLost = true;
SetStartingSequence (recipient, tid, currentSeq);
}
nFailedMpdus++;
if (!m_txFailedCallback.IsNull ())
{
@@ -491,11 +483,6 @@ BlockAckManager::NotifyGotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac4
// in any case, this packet is no longer outstanding
queueIt = it->second.second.erase (queueIt);
}
// If all frames were acknowledged, move the transmit window past the last one
if (!foundFirstLost && currentSeq != SEQNO_SPACE_SIZE)
{
SetStartingSequence (recipient, tid, (currentSeq + 1) % SEQNO_SPACE_SIZE);
}
}
m_stationManager->ReportAmpduTxStatus (recipient, tid, nSuccessfulMpdus, nFailedMpdus, rxSnr, dataSnr);
}
@@ -532,7 +519,19 @@ BlockAckManager::DiscardOutstandingMpdus (Mac48Address recipient, uint8_t tid)
if (ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED))
{
AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
it->second.second.clear ();
while (!it->second.second.empty ())
{
Ptr<WifiMacQueueItem> mpdu = it->second.second.front ();
if (it->second.first.GetDistance (mpdu->GetHeader ().GetSequenceNumber ()) >= SEQNO_SPACE_HALF_SIZE)
{
// old packet
it->second.second.pop_front ();
}
else
{
NotifyDiscardedMpdu (mpdu);
}
}
}
}
@@ -570,8 +569,11 @@ BlockAckManager::NotifyDiscardedMpdu (Ptr<const WifiMacQueueItem> mpdu)
return;
}
// advance the transmit window past the discarded mpdu
SetStartingSequence (recipient, tid, (mpdu->GetHeader ().GetSequenceNumber () + 1) % SEQNO_SPACE_SIZE);
// remove outstanding frames and frames in the retransmit queue with a sequence
// number less than or equal to the discarded MPDU
RemoveOldPackets (recipient, tid, (mpdu->GetHeader ().GetSequenceNumber () + 1) % SEQNO_SPACE_SIZE);
// actually advance the transmit window
it->second.first.NotifyDiscardedMpdu (mpdu);
// schedule a block ack request
NS_LOG_DEBUG ("Schedule a Block Ack Request for agreement (" << recipient << ", " << +tid << ")");
@@ -749,7 +751,6 @@ BlockAckManager::RemoveFromRetryQueue (Mac48Address address, uint8_t tid, uint16
AgreementsI agreementIt = m_agreements.find (std::make_pair (address, tid));
NS_ASSERT (agreementIt != m_agreements.end ());
uint16_t startingSeq = agreementIt->second.first.GetStartingSequence ();
/* remove retry packet iterators if they are present in retry queue */
WifiMacQueue::ConstIterator it = m_retryPackets->PeekByTidAndAddress (tid, address);
@@ -758,10 +759,8 @@ BlockAckManager::RemoveFromRetryQueue (Mac48Address address, uint8_t tid, uint16
{
uint16_t itSeq = (*it)->GetHeader ().GetSequenceNumber ();
if ((itSeq - startingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE
>= (startSeq - startingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE
&& (itSeq - startingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE
<= (endSeq - startingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE)
if (agreementIt->second.first.GetDistance (itSeq) >= agreementIt->second.first.GetDistance (startSeq)
&& agreementIt->second.first.GetDistance (itSeq) <= agreementIt->second.first.GetDistance (endSeq))
{
NS_LOG_DEBUG ("Removing frame with seqnum = " << itSeq);
it = m_retryPackets->Remove (it);
@@ -775,7 +774,7 @@ BlockAckManager::RemoveFromRetryQueue (Mac48Address address, uint8_t tid, uint16
}
void
BlockAckManager::SetStartingSequence (Mac48Address recipient, uint8_t tid, uint16_t startingSeq)
BlockAckManager::RemoveOldPackets (Mac48Address recipient, uint8_t tid, uint16_t startingSeq)
{
NS_LOG_FUNCTION (this << recipient << +tid << startingSeq);
@@ -783,7 +782,7 @@ BlockAckManager::SetStartingSequence (Mac48Address recipient, uint8_t tid, uint1
NS_ASSERT (agreementIt != m_agreements.end ());
uint16_t currStartingSeq = agreementIt->second.first.GetStartingSequence ();
NS_ABORT_MSG_IF ((startingSeq - currStartingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE >= SEQNO_SPACE_HALF_SIZE,
NS_ABORT_MSG_IF (agreementIt->second.first.GetDistance (startingSeq) >= SEQNO_SPACE_HALF_SIZE,
"The new starting sequence number is an old sequence number");
if (startingSeq == currStartingSeq)
@@ -801,8 +800,7 @@ BlockAckManager::SetStartingSequence (Mac48Address recipient, uint8_t tid, uint1
{
uint16_t itSeq = (*it)->GetHeader ().GetSequenceNumber ();
if ((itSeq - currStartingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE
<= (lastRemovedSeq - currStartingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE)
if (agreementIt->second.first.GetDistance (itSeq) <= agreementIt->second.first.GetDistance (lastRemovedSeq))
{
NS_LOG_DEBUG ("Removing frame with seqnum = " << itSeq);
it = agreementIt->second.second.erase (it);
@@ -812,9 +810,6 @@ BlockAckManager::SetStartingSequence (Mac48Address recipient, uint8_t tid, uint1
it++;
}
}
// update the starting sequence number
agreementIt->second.first.SetStartingSequence (startingSeq);
}
void
@@ -869,8 +864,7 @@ BlockAckManager::InsertInRetryQueue (Ptr<WifiMacQueueItem> mpdu)
AgreementsI agreementIt = m_agreements.find (std::make_pair (recipient, tid));
NS_ASSERT (agreementIt != m_agreements.end ());
uint16_t startingSeq = agreementIt->second.first.GetStartingSequence ();
uint16_t mpduDist = (mpdu->GetHeader ().GetSequenceNumber () - startingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE;
uint16_t mpduDist = agreementIt->second.first.GetDistance (mpdu->GetHeader ().GetSequenceNumber ());
if (mpduDist >= SEQNO_SPACE_HALF_SIZE)
{
@@ -888,7 +882,7 @@ BlockAckManager::InsertInRetryQueue (Ptr<WifiMacQueueItem> mpdu)
return;
}
uint16_t dist = ((*it)->GetHeader ().GetSequenceNumber () - startingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE;
uint16_t dist = agreementIt->second.first.GetDistance ((*it)->GetHeader ().GetSequenceNumber ());
if (mpduDist < dist ||
(mpduDist == dist && mpdu->GetHeader ().GetFragmentNumber () < (*it)->GetHeader ().GetFragmentNumber ()))

View File

@@ -430,16 +430,16 @@ private:
void InactivityTimeout (Mac48Address recipient, uint8_t tid);
/**
* Set the starting sequence number for the agreement with recipient equal to
* <i>recipient</i> and TID equal to <i>tid</i> to the given <i>startingSeq</i>.
* Also, remove packets that became old from the retransmit queue and from the
* queue of outstanding packets.
* Remove packets from the retransmit queue and from the queue of outstanding
* packets that become old after setting the starting sequence number for the
* agreement with recipient equal to <i>recipient</i> and TID equal to <i>tid</i>
* to the given <i>startingSeq</i>.
*
* \param recipient the recipient MAC address
* \param tid Traffic ID
* \param startingSeq the new starting sequence number
*/
void SetStartingSequence (Mac48Address recipient, uint8_t tid, uint16_t startingSeq);
void RemoveOldPackets (Mac48Address recipient, uint8_t tid, uint16_t startingSeq);
/**
* typedef for a list of WifiMacQueueItem.