From fb82040208ee2323ec4abd769ee116887e095610 Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Sun, 14 Apr 2019 11:42:12 +0200 Subject: [PATCH] wifi: Do not store packets if they are old or already present --- src/wifi/model/block-ack-manager.cc | 138 ++++++++++++++-------------- src/wifi/model/block-ack-manager.h | 15 +-- 2 files changed, 71 insertions(+), 82 deletions(-) diff --git a/src/wifi/model/block-ack-manager.cc b/src/wifi/model/block-ack-manager.cc index 0cad3cb06..6be5d1027 100644 --- a/src/wifi/model/block-ack-manager.cc +++ b/src/wifi/model/block-ack-manager.cc @@ -231,31 +231,46 @@ BlockAckManager::GetRetransmitQueue (void) void BlockAckManager::StorePacket (Ptr mpdu) { - NS_LOG_FUNCTION (this << mpdu); + NS_LOG_FUNCTION (this << *mpdu); NS_ASSERT (mpdu->GetHeader ().IsQosData ()); uint8_t tid = mpdu->GetHeader ().GetQosTid (); Mac48Address recipient = mpdu->GetHeader ().GetAddr1 (); - AgreementsI it = m_agreements.find (std::make_pair (recipient, tid)); - NS_ASSERT (it != m_agreements.end ()); - PacketQueueI queueIt = it->second.second.begin (); - for (; queueIt != it->second.second.end (); ) + 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 + 4096) % 4096; + + if (mpduDist >= 2048) { - if (((mpdu->GetHeader ().GetSequenceNumber () - (*queueIt)->GetHeader ().GetSequenceNumber () + 4096) % 4096) > 2047) + NS_LOG_DEBUG ("Got an old packet. Do nothing"); + return; + } + + // store the packet and keep the list sorted in increasing order of sequence number + // with respect to the starting sequence number + PacketQueueI it = agreementIt->second.second.begin (); + while (it != agreementIt->second.second.end ()) + { + if (mpdu->GetHeader ().GetSequenceControl () == (*it)->GetHeader ().GetSequenceControl ()) + { + NS_LOG_DEBUG ("Packet already in the queue of the BA agreement"); + return; + } + + uint16_t dist = ((*it)->GetHeader ().GetSequenceNumber () - startingSeq + 4096) % 4096; + + if (mpduDist < dist || + (mpduDist == dist && mpdu->GetHeader ().GetFragmentNumber () < (*it)->GetHeader ().GetFragmentNumber ())) { - queueIt = it->second.second.insert (queueIt, mpdu); break; } - else - { - queueIt++; - } - } - if (queueIt == it->second.second.end ()) - { - it->second.second.push_back (mpdu); + + it++; } + agreementIt->second.second.insert (it, mpdu); } bool @@ -319,26 +334,6 @@ BlockAckManager::SetWifiRemoteStationManager (const Ptrbegin (); - while (it != m_retryPackets->end ()) - { - if (!(*it)->GetHeader ().IsQosData ()) - { - NS_FATAL_ERROR ("Packet in blockAck manager retry queue is not Qos Data"); - } - if ((*it)->GetHeader ().GetAddr1 () == recipient && (*it)->GetHeader ().GetQosTid () == tid - && currentSeq == (*it)->GetHeader ().GetSequenceNumber ()) - { - return true; - } - it++; - } - return false; -} - void BlockAckManager::NotifyGotAck (Ptr mpdu) { @@ -403,10 +398,7 @@ BlockAckManager::NotifyMissedAck (Ptr mpdu) } // insert in the retransmission queue - if (!AlreadyExists (mpdu->GetHeader ().GetSequenceNumber (), recipient, tid)) - { - InsertInRetryQueue (mpdu); - } + InsertInRetryQueue (mpdu); } void @@ -458,10 +450,7 @@ BlockAckManager::NotifyGotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac4 SetStartingSequence (recipient, tid, currentSeq); } nFailedMpdus++; - if (!AlreadyExists (currentSeq, recipient, tid)) - { - InsertInRetryQueue (*queueIt); - } + InsertInRetryQueue (*queueIt); } // in any case, this packet is no longer outstanding queueIt = it->second.second.erase (queueIt); @@ -497,10 +486,7 @@ BlockAckManager::NotifyGotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac4 { m_txFailedCallback ((*queueIt)->GetHeader ()); } - if (!AlreadyExists (currentSeq, recipient, tid)) - { - InsertInRetryQueue (*queueIt); - } + InsertInRetryQueue (*queueIt); } // in any case, this packet is no longer outstanding queueIt = it->second.second.erase (queueIt); @@ -531,10 +517,7 @@ BlockAckManager::NotifyMissedBlockAck (Mac48Address recipient, uint8_t tid) for (auto& item : it->second.second) { // Queue previously transmitted packets that do not already exist in the retry queue. - if (!AlreadyExists (item->GetHeader ().GetSequenceNumber (), recipient, tid)) - { - InsertInRetryQueue (item); - } + InsertInRetryQueue (item); } // remove all packets from the queue of outstanding packets (they will be // re-inserted if retransmitted) @@ -917,32 +900,47 @@ BlockAckManager::SetTxFailedCallback (TxFailed callback) } void -BlockAckManager::InsertInRetryQueue (Ptr item) +BlockAckManager::InsertInRetryQueue (Ptr mpdu) { - NS_LOG_INFO ("Adding to retry queue " << *item); - if (m_retryPackets->GetNPackets () == 0) + NS_LOG_INFO ("Adding to retry queue " << *mpdu); + NS_ASSERT (mpdu->GetHeader ().IsQosData ()); + + uint8_t tid = mpdu->GetHeader ().GetQosTid (); + Mac48Address recipient = mpdu->GetHeader ().GetAddr1 (); + + 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 + 4096) % 4096; + + if (mpduDist >= 2048) { - m_retryPackets->Enqueue (item); + NS_LOG_DEBUG ("Got an old packet. Do nothing"); + return; } - else + + WifiMacQueue::ConstIterator it = m_retryPackets->PeekByTidAndAddress (tid, recipient); + + while (it != m_retryPackets->end ()) { - for (WifiMacQueue::ConstIterator it = m_retryPackets->begin (); it != m_retryPackets->end (); ) + if (mpdu->GetHeader ().GetSequenceControl () == (*it)->GetHeader ().GetSequenceControl ()) { - if (((item->GetHeader ().GetSequenceNumber () - (*it)->GetHeader ().GetSequenceNumber () + 4096) % 4096) > 2047) - { - m_retryPackets->Insert (it, item); - break; - } - else - { - it++; - if (it == m_retryPackets->end ()) - { - m_retryPackets->Enqueue (item); - } - } + NS_LOG_DEBUG ("Packet already in the retransmit queue"); + return; } + + uint16_t dist = ((*it)->GetHeader ().GetSequenceNumber () - startingSeq + 4096) % 4096; + + if (mpduDist < dist || + (mpduDist == dist && mpdu->GetHeader ().GetFragmentNumber () < (*it)->GetHeader ().GetFragmentNumber ())) + { + break; + } + + it = m_retryPackets->PeekByTidAndAddress (tid, recipient, ++it); } + m_retryPackets->Insert (it, mpdu); } uint16_t diff --git a/src/wifi/model/block-ack-manager.h b/src/wifi/model/block-ack-manager.h index a68ededb5..409a6e977 100644 --- a/src/wifi/model/block-ack-manager.h +++ b/src/wifi/model/block-ack-manager.h @@ -342,15 +342,6 @@ public: * the value of BufferSize in the corresponding OriginatorBlockAckAgreement object. */ bool SwitchToBlockAckIfNeeded (Mac48Address recipient, uint8_t tid, uint16_t startingSeq); - /** - * Checks if the packet already exists in the retransmit queue or not if it does then it doesn't add it again - * - * \param currentSeq the current sequence - * \param recipient the destination address - * \param tid the Traffic ID - * \returns true if the packet already exists - */ - bool AlreadyExists (uint16_t currentSeq, Mac48Address recipient, uint8_t tid) const; /** * This function returns true if the lifetime of the packets a BAR refers to didn't * expire yet otherwise it returns false. @@ -490,12 +481,12 @@ private: std::pair >::const_iterator AgreementsCI; /** - * \param item the packet to insert in the retransmission queue + * \param mpdu the packet to insert in the retransmission queue * - * Insert item in retransmission queue. + * Insert mpdu in retransmission queue. * This method ensures packets are retransmitted in the correct order. */ - void InsertInRetryQueue (Ptr item); + void InsertInRetryQueue (Ptr mpdu); /** * Remove an item from retransmission queue.