From 604bd34fa099deff4f16fe31c8f3e148f6007f9e Mon Sep 17 00:00:00 2001 From: Mirko Banchi Date: Sun, 22 Aug 2010 22:51:33 +0200 Subject: [PATCH] Packets that cannot be acknowledged in the block ack bitmap must not be transmitted --- src/devices/wifi/block-ack-agreement.cc | 1 + src/devices/wifi/block-ack-manager.cc | 32 ++++++++++++++++--- src/devices/wifi/block-ack-manager.h | 16 +++++++--- src/devices/wifi/edca-txop-n.cc | 4 ++- src/devices/wifi/mac-low.cc | 2 +- .../wifi/originator-block-ack-agreement.cc | 23 +++++++++---- .../wifi/originator-block-ack-agreement.h | 10 +++--- 7 files changed, 68 insertions(+), 20 deletions(-) diff --git a/src/devices/wifi/block-ack-agreement.cc b/src/devices/wifi/block-ack-agreement.cc index 2c2e408f9..7d27eea96 100644 --- a/src/devices/wifi/block-ack-agreement.cc +++ b/src/devices/wifi/block-ack-agreement.cc @@ -45,6 +45,7 @@ void BlockAckAgreement::SetBufferSize (uint16_t bufferSize) { NS_ASSERT (bufferSize <= 1024); + NS_ASSERT (bufferSize % 16 == 0); m_bufferSize = bufferSize; } void diff --git a/src/devices/wifi/block-ack-manager.cc b/src/devices/wifi/block-ack-manager.cc index 845d387ca..12f928331 100644 --- a/src/devices/wifi/block-ack-manager.cc +++ b/src/devices/wifi/block-ack-manager.cc @@ -1,6 +1,6 @@ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2009 MIRKO BANCHI + * Copyright (c) 2009, 2010 MIRKO BANCHI * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -414,7 +414,7 @@ BlockAckManager::ScheduleBlockAckReqIfNeeded (Mac48Address recipient, uint8_t ti AgreementsI it = m_agreements.find (std::make_pair (recipient, tid)); NS_ASSERT (it != m_agreements.end ()); - if ((*it).second.first.NeedBlockAckRequest () || + if ((*it).second.first.IsBlockAckRequestNeeded () || (GetNRetryNeededPackets (recipient, tid) == 0 && m_queue->GetNPacketsByTidAndAddress (tid, WifiMacHeader::ADDR1, recipient) == 0)) { @@ -473,13 +473,23 @@ BlockAckManager::NotifyAgreementUnsuccessful (Mac48Address recipient, uint8_t ti } void -BlockAckManager::NotifyMpduTransmission (Mac48Address recipient, uint8_t tid) +BlockAckManager::NotifyMpduTransmission (Mac48Address recipient, uint8_t tid, uint16_t nextSeqNumber) { NS_LOG_FUNCTION (this); Ptr bar = 0; AgreementsI it = m_agreements.find (std::make_pair (recipient, tid)); NS_ASSERT (it != m_agreements.end ()); - it->second.first.NotifyMpduTransmission (); + + uint16_t nextSeq; + if (GetNRetryNeededPackets (recipient, tid) > 0) + { + nextSeq = GetSeqNumOfNextRetryPacket (recipient, tid); + } + else + { + nextSeq = nextSeqNumber; + } + it->second.first.NotifyMpduTransmission (nextSeq); bar = ScheduleBlockAckReqIfNeeded (recipient, tid); if (bar != 0) { @@ -614,4 +624,18 @@ BlockAckManager::SetTxMiddle (MacTxMiddle* txMiddle) m_txMiddle = txMiddle; } +uint16_t +BlockAckManager::GetSeqNumOfNextRetryPacket (Mac48Address recipient, uint8_t tid) const +{ + std::list::const_iterator it = m_retryPackets.begin (); + while (it != m_retryPackets.end ()) + { + if ((*it)->hdr.GetAddr1 () == recipient && (*it)->hdr.GetQosTid () == tid) + { + return (*it)->hdr.GetSequenceNumber (); + } + } + return 4096; +} + } //namespace ns3 diff --git a/src/devices/wifi/block-ack-manager.h b/src/devices/wifi/block-ack-manager.h index 4cd739d63..9e83a69d6 100644 --- a/src/devices/wifi/block-ack-manager.h +++ b/src/devices/wifi/block-ack-manager.h @@ -1,6 +1,6 @@ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2009 MIRKO BANCHI + * Copyright (c) 2009, 2010 MIRKO BANCHI * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -151,7 +151,7 @@ public: * \param tid Traffic ID. * * Returns number of packets for a specific agreement that need retransmission. - * This methods doesn't return number of MPDUs that need retransmission but number MSDUs. + * This method doesn't return number of MPDUs that need retransmission but number of MSDUs. */ uint32_t GetNRetryNeededPackets (Mac48Address recipient, uint8_t tid) const; /** @@ -175,11 +175,13 @@ public: /** * \param recipient Address of peer station involved in block ack mechanism. * \param tid Traffic ID of transmitted packet. + * \param nextSeqNumber Sequence number of the next packet that would be trasmitted by EdcaTxopN. * - * This methods is typically invoked by ns3::EdcaTxopN object every time that a MPDU + * This method is typically invoked by ns3::EdcaTxopN object every time that a MPDU * with ack policy subfield in Qos Control field set to Block Ack is transmitted. + * The nextSeqNumber parameter is used to block transmission of packets that are out of bitmap. */ - void NotifyMpduTransmission (Mac48Address recipient, uint8_t tid); + void NotifyMpduTransmission (Mac48Address recipient, uint8_t tid, uint16_t nextSeqNumber); /** * \param nPackets Minimum number of packets for use of block ack. * @@ -237,6 +239,12 @@ public: * the value of BufferSize in the corresponding OriginatorBlockAckAgreement object. */ bool SwitchToBlockAckIfNeeded (Mac48Address recipient, uint8_t tid, uint16_t startingSeq); + /** + * Returns the sequence number of the next retry packet for a specific agreement. + * If there are no packets that need retransmission for the specified agreement or + * the agreement doesn't exist the function returns 4096; + */ + uint16_t GetSeqNumOfNextRetryPacket (Mac48Address recipient, uint8_t tid) const; private: /** * Checks if all packets, for which a block ack agreement was established or refreshed, diff --git a/src/devices/wifi/edca-txop-n.cc b/src/devices/wifi/edca-txop-n.cc index 5abc900bd..2a6e38d22 100644 --- a/src/devices/wifi/edca-txop-n.cc +++ b/src/devices/wifi/edca-txop-n.cc @@ -893,7 +893,9 @@ EdcaTxopN::CompleteTx (void) { m_baManager->StorePacket (m_currentPacket, m_currentHdr, m_currentPacketTimestamp); } - m_baManager->NotifyMpduTransmission (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid ()); + m_baManager->NotifyMpduTransmission (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid (), + m_txMiddle->GetNextSeqNumberByTidAndAddress (m_currentHdr.GetQosTid (), + m_currentHdr.GetAddr1 ())); //we are not waiting for an ack: transmission is completed m_currentPacket = 0; m_dcf->ResetCw (); diff --git a/src/devices/wifi/mac-low.cc b/src/devices/wifi/mac-low.cc index 9acd35567..36d2e4821 100644 --- a/src/devices/wifi/mac-low.cc +++ b/src/devices/wifi/mac-low.cc @@ -1524,7 +1524,7 @@ MacLow::CreateBlockAckAgreement (const MgtAddBaResponseHeader *respHdr, Mac48Add agreement.SetDelayedBlockAck (); } agreement.SetAmsduSupport (respHdr->IsAmsduSupported ()); - agreement.SetBufferSize (respHdr->GetBufferSize ()); + agreement.SetBufferSize (respHdr->GetBufferSize () + 1); agreement.SetTimeout (respHdr->GetTimeout ()); agreement.SetStartingSequence (startingSeq); diff --git a/src/devices/wifi/originator-block-ack-agreement.cc b/src/devices/wifi/originator-block-ack-agreement.cc index 934c41dda..5b2612c9b 100644 --- a/src/devices/wifi/originator-block-ack-agreement.cc +++ b/src/devices/wifi/originator-block-ack-agreement.cc @@ -1,6 +1,6 @@ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2009 MIRKO BANCHI + * Copyright (c) 2009, 2010 MIRKO BANCHI * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Mirko Banchi + * Author: Tommaso Pecorella */ #include "originator-block-ack-agreement.h" @@ -24,12 +25,14 @@ namespace ns3 { OriginatorBlockAckAgreement::OriginatorBlockAckAgreement () : BlockAckAgreement (), m_state (PENDING), - m_sentMpdus (0) + m_sentMpdus (0), + m_needBlockAckReq (false) {} OriginatorBlockAckAgreement::OriginatorBlockAckAgreement (Mac48Address recipient, uint8_t tid) : BlockAckAgreement (recipient, tid), m_state (PENDING), - m_sentMpdus (0) + m_sentMpdus (0), + m_needBlockAckReq (false) {} OriginatorBlockAckAgreement::~OriginatorBlockAckAgreement () {} @@ -39,6 +42,7 @@ OriginatorBlockAckAgreement::SetState (enum State state) m_state = state; if (state == INACTIVE) { + m_needBlockAckReq = false; m_sentMpdus = 0; } } @@ -63,19 +67,26 @@ OriginatorBlockAckAgreement::IsUnsuccessful (void) const return (m_state == UNSUCCESSFUL)?true:false; } void -OriginatorBlockAckAgreement::NotifyMpduTransmission (void) +OriginatorBlockAckAgreement::NotifyMpduTransmission (uint16_t nextSeqNumber) { NS_ASSERT (m_sentMpdus < m_bufferSize); m_sentMpdus++; + uint16_t delta = (nextSeqNumber - m_startingSeq + 4096) % 4096; + uint16_t min = m_bufferSize < 64 ? m_bufferSize : 64; + if (delta >= min || m_sentMpdus == m_bufferSize) + { + m_needBlockAckReq = true; + } } bool -OriginatorBlockAckAgreement::NeedBlockAckRequest (void) const +OriginatorBlockAckAgreement::IsBlockAckRequestNeeded (void) const { - return (m_sentMpdus == m_bufferSize/2)?true:false; + return m_needBlockAckReq; } void OriginatorBlockAckAgreement::CompleteExchange (void) { + m_needBlockAckReq = false; m_sentMpdus = 0; } diff --git a/src/devices/wifi/originator-block-ack-agreement.h b/src/devices/wifi/originator-block-ack-agreement.h index cf7b3b238..22799cc23 100644 --- a/src/devices/wifi/originator-block-ack-agreement.h +++ b/src/devices/wifi/originator-block-ack-agreement.h @@ -1,6 +1,6 @@ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2009 MIRKO BANCHI + * Copyright (c) 2009, 2010 MIRKO BANCHI * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Mirko Banchi + * Author: Tommaso Pecorella */ #ifndef ORIGINATOR_BLOCK_ACK_AGREEMENT_H #define ORIGINATOR_BLOCK_ACK_AGREEMENT_H @@ -97,17 +98,18 @@ public: /** * Notifies a packet's transmission with ack policy Block Ack. */ - void NotifyMpduTransmission (void); + void NotifyMpduTransmission (uint16_t nextSeqNumber); /** * Returns true if all packets for which a block ack was negotiated have been transmitted so * a block ack request is needed in order to acknowledge them. */ - bool NeedBlockAckRequest (void) const; + bool IsBlockAckRequestNeeded (void) const; void CompleteExchange (void); private: enum State m_state; - uint8_t m_sentMpdus; + uint16_t m_sentMpdus; + bool m_needBlockAckReq; }; } //namespace ns3