From 698abc5d5d4ada233d2e6770df008cf7fa0e26c5 Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Wed, 28 Aug 2019 19:00:55 +0200 Subject: [PATCH] wifi: OriginatorBlockAckAgreement uses a Block Ack window --- .../model/originator-block-ack-agreement.cc | 105 ++++++++++++++++++ .../model/originator-block-ack-agreement.h | 61 +++++++++- 2 files changed, 165 insertions(+), 1 deletion(-) diff --git a/src/wifi/model/originator-block-ack-agreement.cc b/src/wifi/model/originator-block-ack-agreement.cc index 6a510e35f..baadd2971 100644 --- a/src/wifi/model/originator-block-ack-agreement.cc +++ b/src/wifi/model/originator-block-ack-agreement.cc @@ -19,10 +19,15 @@ * Tommaso Pecorella */ +#include "ns3/log.h" #include "originator-block-ack-agreement.h" +#include "wifi-mac-queue-item.h" +#include "wifi-utils.h" namespace ns3 { +NS_LOG_COMPONENT_DEFINE ("OriginatorBlockAckAgreement"); + OriginatorBlockAckAgreement::OriginatorBlockAckAgreement (Mac48Address recipient, uint8_t tid) : BlockAckAgreement (recipient, tid), m_state (PENDING) @@ -69,4 +74,104 @@ OriginatorBlockAckAgreement::IsReset (void) const return (m_state == RESET) ? true : false; } +uint16_t +OriginatorBlockAckAgreement::GetStartingSequence (void) const +{ + if (m_txWindow.GetWinSize () == 0) + { + // the TX window has not been initialized yet + return m_startingSeq; + } + return m_txWindow.GetWinStart (); +} + +std::size_t +OriginatorBlockAckAgreement::GetDistance (uint16_t seqNumber) const +{ + NS_ASSERT (seqNumber < SEQNO_SPACE_SIZE); + return (seqNumber - GetStartingSequence () + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE; +} + +void +OriginatorBlockAckAgreement::InitTxWindow (void) +{ + m_txWindow.Init (m_startingSeq, m_bufferSize); +} + +void +OriginatorBlockAckAgreement::AdvanceTxWindow (void) +{ + while (m_txWindow.At (0)) + { + m_txWindow.Advance (1); // reset the current head -- ensures loop termination + } +} + +void +OriginatorBlockAckAgreement::NotifyTransmittedMpdu (Ptr mpdu) +{ + uint16_t mpduSeqNumber = mpdu->GetHeader ().GetSequenceNumber (); + uint16_t distance = GetDistance (mpduSeqNumber); + + if (distance >= SEQNO_SPACE_HALF_SIZE) + { + NS_LOG_DEBUG ("Transmitted an old MPDU, do nothing."); + return; + } + + // advance the transmit window if an MPDU beyond the current transmit window + // is transmitted (see Section 10.24.7.7 of 802.11-2016) + if (distance >= m_txWindow.GetWinSize ()) + { + std::size_t count = distance - m_txWindow.GetWinSize () + 1; + m_txWindow.Advance (count); + // transmit window may advance further + AdvanceTxWindow (); + NS_LOG_DEBUG ("Transmitted MPDU beyond current transmit window. New starting sequence number: " + << m_txWindow.GetWinStart ()); + } +} + +void +OriginatorBlockAckAgreement::NotifyAckedMpdu (Ptr mpdu) +{ + uint16_t mpduSeqNumber = mpdu->GetHeader ().GetSequenceNumber (); + uint16_t distance = GetDistance (mpduSeqNumber); + + if (distance >= SEQNO_SPACE_HALF_SIZE) + { + NS_LOG_DEBUG ("Acked an old MPDU, do nothing."); + return; + } + + // when an MPDU is transmitted, the transmit window is updated such that the + // transmitted MPDU is in the window, hence we cannot be notified of the + // acknowledgment of an MPDU which is beyond the transmit window + m_txWindow.At (distance) = true; + + // the starting sequence number can be advanced to the sequence number of + // the nearest unacknowledged MPDU + AdvanceTxWindow (); + NS_LOG_DEBUG ("Starting sequence number: " << m_txWindow.GetWinStart ()); +} + +void +OriginatorBlockAckAgreement::NotifyDiscardedMpdu (Ptr mpdu) +{ + uint16_t mpduSeqNumber = mpdu->GetHeader ().GetSequenceNumber (); + uint16_t distance = GetDistance (mpduSeqNumber); + + if (distance >= SEQNO_SPACE_HALF_SIZE) + { + NS_LOG_DEBUG ("Discarded an old MPDU, do nothing."); + return; + } + + m_txWindow.Advance (distance + 1); + // transmit window may advance further + AdvanceTxWindow (); + NS_LOG_DEBUG ("Discarded MPDU within current transmit window. New starting sequence number: " + << m_txWindow.GetWinStart ()); +} + } //namespace ns3 diff --git a/src/wifi/model/originator-block-ack-agreement.h b/src/wifi/model/originator-block-ack-agreement.h index d5666d880..5399d897a 100644 --- a/src/wifi/model/originator-block-ack-agreement.h +++ b/src/wifi/model/originator-block-ack-agreement.h @@ -22,9 +22,12 @@ #define ORIGINATOR_BLOCK_ACK_AGREEMENT_H #include "block-ack-agreement.h" +#include "block-ack-window.h" namespace ns3 { +class WifiMacQueueItem; + /** * \ingroup wifi * Maintains the state and information about transmitted MPDUs with ack policy block ack @@ -141,8 +144,64 @@ public: */ bool IsRejected (void) const; + /** + * Return the starting sequence number of the transmit window, if a transmit + * window has been initialized. Otherwise, return the starting sequence number + * stored by the BlockAckAgreement base class. + * + * \return the starting sequence number. + */ + uint16_t GetStartingSequence (void) const; + + /** + * Get the distance between the current starting sequence number and the + * given sequence number. + * + * \param seqNumber the given sequence number + * \return the distance of the given sequence number from the current winstart + */ + std::size_t GetDistance (uint16_t seqNumber) const; + + /** + * Initialize the originator's transmit window by setting its size and starting + * sequence number equal to the values stored by the BlockAckAgreement base class. + */ + void InitTxWindow (void); + + /** + * Advance the transmit window so as to include the transmitted MPDU, if the + * latter is not an old packet and is beyond the current transmit window. + * + * \param mpdu the transmitted MPDU + */ + void NotifyTransmittedMpdu (Ptr mpdu); + /** + * Record that the given MPDU has been acknowledged and advance the transmit + * window if possible. + * + * \param mpdu the acknowledged MPDU + */ + void NotifyAckedMpdu (Ptr mpdu); + /** + * Advance the transmit window beyond the MPDU that has been reported to + * be discarded. + * + * \param mpdu the discarded MPDU + */ + void NotifyDiscardedMpdu (Ptr mpdu); + + private: - State m_state; ///< state + /** + * Advance the transmit window so that the starting sequence number is the + * nearest unacknowledged MPDU. + * + * \param newStartingSeq the new starting sequence number + */ + void AdvanceTxWindow (void); + + State m_state; ///< state + BlockAckWindow m_txWindow; ///< originator's transmit window }; } //namespace ns3