From e9022846f6e9d2232b910fb5588097b64edbc08a Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Wed, 28 Aug 2019 19:25:47 +0200 Subject: [PATCH] wifi: (fixes #79) Block Ack manager uses the originator block ack window --- src/wifi/model/block-ack-manager.cc | 72 +++++++++++++---------------- src/wifi/model/block-ack-manager.h | 10 ++-- 2 files changed, 38 insertions(+), 44 deletions(-) diff --git a/src/wifi/model/block-ack-manager.cc b/src/wifi/model/block-ack-manager.cc index a9caac856..cfa2f4152 100644 --- a/src/wifi/model/block-ack-manager.cc +++ b/src/wifi/model/block-ack-manager.cc @@ -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 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 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 mpdu) it++; } agreementIt->second.second.insert (it, mpdu); + agreementIt->second.first.NotifyTransmittedMpdu (mpdu); } bool @@ -361,12 +362,7 @@ BlockAckManager::NotifyGotAck (Ptr 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 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 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 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 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 ())) diff --git a/src/wifi/model/block-ack-manager.h b/src/wifi/model/block-ack-manager.h index 5f6369a94..c11233d40 100644 --- a/src/wifi/model/block-ack-manager.h +++ b/src/wifi/model/block-ack-manager.h @@ -430,16 +430,16 @@ private: void InactivityTimeout (Mac48Address recipient, uint8_t tid); /** - * Set the starting sequence number for the agreement with recipient equal to - * recipient and TID equal to tid to the given startingSeq. - * 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 recipient and TID equal to tid + * to the given startingSeq. * * \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.