wifi: (fixes #79) Block Ack manager uses the originator block ack window
This commit is contained in:
@@ -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 ()))
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user