wifi: OriginatorBlockAckAgreement uses a Block Ack window
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user