wifi: OriginatorBlockAckAgreement uses a Block Ack window

This commit is contained in:
Stefano Avallone
2019-08-28 19:00:55 +02:00
parent 333c58765a
commit 698abc5d5d
2 changed files with 165 additions and 1 deletions

View File

@@ -19,10 +19,15 @@
* Tommaso Pecorella <tommaso.pecorella@unifi.it>
*/
#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<const WifiMacQueueItem> 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<const WifiMacQueueItem> 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<const WifiMacQueueItem> 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

View File

@@ -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<const WifiMacQueueItem> mpdu);
/**
* Record that the given MPDU has been acknowledged and advance the transmit
* window if possible.
*
* \param mpdu the acknowledged MPDU
*/
void NotifyAckedMpdu (Ptr<const WifiMacQueueItem> mpdu);
/**
* Advance the transmit window beyond the MPDU that has been reported to
* be discarded.
*
* \param mpdu the discarded MPDU
*/
void NotifyDiscardedMpdu (Ptr<const WifiMacQueueItem> 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