wifi: A queued WifiMacQueueItem stores an iterator to itself

This allows us to dequeue packets only when they are actually
transmitted. For instance, a packet protected by RTS is dequeued
only if the CTS is received. This saves us from reinserting the
packets in the queue if CTS is missed (think of A-MPDUs, multi-TID
A-MPDUs, MU PPDUs, ...)
This commit is contained in:
Stefano Avallone
2020-11-18 12:53:23 +01:00
parent 999b2ac02f
commit 2bcf750347
7 changed files with 156 additions and 18 deletions

View File

@@ -28,6 +28,7 @@
#include "originator-block-ack-agreement.h"
#include "block-ack-type.h"
#include "wifi-mac-queue-item.h"
#include "wifi-tx-vector.h"
namespace ns3 {

View File

@@ -22,7 +22,6 @@
#include "ns3/log.h"
#include "ns3/packet.h"
#include "msdu-aggregator.h"
#include "amsdu-subframe-header.h"
#include "qos-txop.h"
#include "mpdu-aggregator.h"
#include "wifi-remote-station-manager.h"
@@ -271,11 +270,11 @@ MsduAggregator::GetMaxAmsduSize (Mac48Address recipient, uint8_t tid,
return maxAmsduSize;
}
MsduAggregator::DeaggregatedMsdus
WifiMacQueueItem::DeaggregatedMsdus
MsduAggregator::Deaggregate (Ptr<Packet> aggregatedPacket)
{
NS_LOG_FUNCTION_NOARGS ();
DeaggregatedMsdus set;
WifiMacQueueItem::DeaggregatedMsdus set;
AmsduSubframeHeader hdr;
Ptr<Packet> extractedMsdu = Create<Packet> ();

View File

@@ -25,14 +25,13 @@
#include "ns3/nstime.h"
#include "wifi-mode.h"
#include "qos-utils.h"
#include "wifi-mac-queue-item.h"
#include <map>
namespace ns3 {
class AmsduSubframeHeader;
class Packet;
class QosTxop;
class WifiMacQueueItem;
class WifiTxVector;
/**
@@ -42,10 +41,6 @@ class WifiTxVector;
class MsduAggregator : public Object
{
public:
/// DeaggregatedMsdus typedef
typedef std::list<std::pair<Ptr<const Packet>, AmsduSubframeHeader> > DeaggregatedMsdus;
/// DeaggregatedMsdusCI typedef
typedef std::list<std::pair<Ptr<const Packet>, AmsduSubframeHeader> >::const_iterator DeaggregatedMsdusCI;
/// EDCA queues typedef
typedef std::map<AcIndex, Ptr<QosTxop> > EdcaQueues;
@@ -119,7 +114,7 @@ public:
* \param aggregatedPacket the aggregated packet.
* \returns DeaggregatedMsdus.
*/
static DeaggregatedMsdus Deaggregate (Ptr<Packet> aggregatedPacket);
static WifiMacQueueItem::DeaggregatedMsdus Deaggregate (Ptr<Packet> aggregatedPacket);
/**
* Set the map of EDCA queues.

View File

@@ -27,6 +27,7 @@
#include "wifi-mac-queue-item.h"
#include "wifi-mac-trailer.h"
#include "wifi-utils.h"
#include "msdu-aggregator.h"
namespace ns3 {
@@ -82,10 +83,22 @@ WifiMacQueueItem::GetTimeStamp (void) const
return m_tstamp;
}
uint32_t
WifiMacQueueItem::GetPacketSize (void) const
{
return m_packet->GetSize ();
}
uint32_t
WifiMacQueueItem::GetSize (void) const
{
return m_packet->GetSize () + m_header.GetSerializedSize () + WIFI_MAC_FCS_LENGTH;
return GetPacketSize () + m_header.GetSerializedSize () + WIFI_MAC_FCS_LENGTH;
}
bool
WifiMacQueueItem::IsFragment (void) const
{
return m_header.IsMoreFragments () || m_header.GetFragmentNumber () > 0;
}
Ptr<Packet>
@@ -110,6 +123,7 @@ WifiMacQueueItem::Aggregate (Ptr<const WifiMacQueueItem> msdu)
// An MSDU is going to be aggregated to this MPDU, hence this has to be an A-MSDU now
Ptr<const WifiMacQueueItem> firstMsdu = Create<const WifiMacQueueItem> (*this);
m_packet = Create<Packet> ();
m_queueIts.clear ();
DoAggregate (firstMsdu);
m_header.SetQosAmsdu ();
@@ -156,6 +170,7 @@ WifiMacQueueItem::DoAggregate (Ptr<const WifiMacQueueItem> msdu)
hdr.SetLength (static_cast<uint16_t> (msdu->GetPacket ()->GetSize ()));
m_msduList.push_back ({msdu->GetPacket (), hdr});
m_queueIts.insert (m_queueIts.end (), msdu->m_queueIts.begin (), msdu->m_queueIts.end ());
// build the A-MSDU
NS_ASSERT (m_packet);
@@ -186,14 +201,25 @@ WifiMacQueueItem::DoAggregate (Ptr<const WifiMacQueueItem> msdu)
m_tstamp = Max (m_tstamp, msdu->GetTimeStamp ());
}
bool
WifiMacQueueItem::IsQueued (void) const
{
return !m_queueIts.empty ();
}
MsduAggregator::DeaggregatedMsdusCI
const std::list<WifiMacQueueItem::QueueIteratorPair>&
WifiMacQueueItem::GetQueueIteratorPairs (void) const
{
return m_queueIts;
}
WifiMacQueueItem::DeaggregatedMsdusCI
WifiMacQueueItem::begin (void)
{
return m_msduList.begin ();
}
MsduAggregator::DeaggregatedMsdusCI
WifiMacQueueItem::DeaggregatedMsdusCI
WifiMacQueueItem::end (void)
{
return m_msduList.end ();
@@ -202,9 +228,11 @@ WifiMacQueueItem::end (void)
void
WifiMacQueueItem::Print (std::ostream& os) const
{
os << "size=" << m_packet->GetSize ()
os << m_header.GetTypeString ()
<< ", payloadSize=" << GetPacketSize ()
<< ", to=" << m_header.GetAddr1 ()
<< ", seqN=" << m_header.GetSequenceNumber ()
<< ", duration/ID=" << m_header.GetDuration ()
<< ", lifetime=" << (Simulator::Now () - m_tstamp).As (Time::US);
if (m_header.IsQosData ())
{
@@ -222,6 +250,7 @@ WifiMacQueueItem::Print (std::ostream& os) const
os << ", ack=BlockAck";
}
}
os << ", packet=" << m_packet;
}
std::ostream & operator << (std::ostream &os, const WifiMacQueueItem &item)

View File

@@ -26,13 +26,14 @@
#include "ns3/nstime.h"
#include "wifi-mac-header.h"
#include "msdu-aggregator.h"
#include "amsdu-subframe-header.h"
#include <list>
namespace ns3 {
class QosBlockedDestinations;
class Packet;
class WifiMacQueue;
/**
* \ingroup wifi
@@ -98,6 +99,21 @@ public:
*/
uint32_t GetSize (void) const;
/**
* \brief Return the size in bytes of the packet or control header or management
* header stored by this item.
*
* \return the size in bytes of the packet or control header or management header
* stored by this item
*/
uint32_t GetPacketSize (void) const;
/**
* Return true if this item contains an MSDU fragment, false otherwise
* \return true if this item contains an MSDU fragment, false otherwise
*/
bool IsFragment (void) const;
/**
* \brief Aggregate the MSDU contained in the given MPDU to this MPDU (thus
* constituting an A-MSDU). Note that the given MPDU cannot contain
@@ -106,18 +122,47 @@ public:
*/
void Aggregate (Ptr<const WifiMacQueueItem> msdu);
/// DeaggregatedMsdus typedef
typedef std::list<std::pair<Ptr<const Packet>, AmsduSubframeHeader> > DeaggregatedMsdus;
/// DeaggregatedMsdusCI typedef
typedef std::list<std::pair<Ptr<const Packet>, AmsduSubframeHeader> >::const_iterator DeaggregatedMsdusCI;
/**
* \brief Get a constant iterator pointing to the first MSDU in the list of aggregated MSDUs.
*
* \return a constant iterator pointing to the first MSDU in the list of aggregated MSDUs
*/
MsduAggregator::DeaggregatedMsdusCI begin (void);
DeaggregatedMsdusCI begin (void);
/**
* \brief Get a constant iterator indicating past-the-last MSDU in the list of aggregated MSDUs.
*
* \return a constant iterator indicating past-the-last MSDU in the list of aggregated MSDUs
*/
MsduAggregator::DeaggregatedMsdusCI end (void);
DeaggregatedMsdusCI end (void);
/// Const iterator typedef
typedef std::list<Ptr<WifiMacQueueItem>>::const_iterator ConstIterator;
/// Information needed to remove an MSDU from the queue
struct QueueIteratorPair
{
WifiMacQueue* queue; //!< pointer to the queue where the MSDU is enqueued
ConstIterator it; //!< iterator pointing to the MSDU in the queue
};
/**
* Return true if this item is stored in some queue, false otherwise.
*
* \return true if this item is stored in some queue, false otherwise
*/
bool IsQueued (void) const;
/**
* Get a const reference to the list of iterators pointing to the positions
* of the items in the queue. The list is empty if the item is not stored in
* a queue. The list contains multiple iterators in case of A-MSDU that is not
* stored in the Block Ack Manager retransmit queue.
*/
const std::list<QueueIteratorPair>& GetQueueIteratorPairs (void) const;
/**
* \brief Get the MAC protocol data unit (MPDU) corresponding to this item
@@ -142,10 +187,13 @@ private:
*/
void DoAggregate (Ptr<const WifiMacQueueItem> msdu);
friend class WifiMacQueue; // to set QueueIteratorPair information
Ptr<const Packet> m_packet; //!< The packet (MSDU or A-MSDU) contained in this queue item
WifiMacHeader m_header; //!< Wifi MAC header associated with the packet
Time m_tstamp; //!< timestamp when the packet arrived at the queue
MsduAggregator::DeaggregatedMsdus m_msduList; //!< The list of aggregated MSDUs included in this MPDU
DeaggregatedMsdus m_msduList; //!< The list of aggregated MSDUs included in this MPDU
std::list<QueueIteratorPair> m_queueIts; //!< Queue iterators pointing to this MSDU(s), if queued
};
/**

View File

@@ -567,4 +567,45 @@ WifiMacQueue::GetNBytes (void)
return QueueBase::GetNBytes ();
}
bool
WifiMacQueue::DoEnqueue (ConstIterator pos, Ptr<WifiMacQueueItem> item)
{
Iterator ret;
if (Queue<WifiMacQueueItem>::DoEnqueue (pos, item, ret))
{
// set item's information about its position in the queue
item->m_queueIts = {{this, ret}};
return true;
}
return false;
}
Ptr<WifiMacQueueItem>
WifiMacQueue::DoDequeue (ConstIterator pos)
{
Ptr<WifiMacQueueItem> item = Queue<WifiMacQueueItem>::DoDequeue (pos);
if (item != 0)
{
NS_ASSERT (item->m_queueIts.size () == 1);
item->m_queueIts.clear ();
}
return item;
}
Ptr<WifiMacQueueItem>
WifiMacQueue::DoRemove (ConstIterator pos)
{
Ptr<WifiMacQueueItem> item = Queue<WifiMacQueueItem>::DoRemove (pos);
if (item != 0)
{
NS_ASSERT (item->m_queueIts.size () == 1);
item->m_queueIts.clear ();
}
return item;
}
} //namespace ns3

View File

@@ -312,6 +312,31 @@ private:
* \return true if the item is removed, false otherwise
*/
bool TtlExceeded (ConstIterator &it);
/**
* Wrapper for the DoEnqueue method provided by the base class that additionally
* sets the iterator field of the item, if insertion succeeded.
*
* \param pos the position before where the item will be inserted
* \param item the item to enqueue
* \return true if success, false if the packet has been dropped.
*/
bool DoEnqueue (ConstIterator pos, Ptr<WifiMacQueueItem> item);
/**
* Wrapper for the DoDequeue method provided by the base class that additionally
* resets the iterator field of the item, if an item was dequeued.
*
* \param pos the position of the item to dequeue
* \return the item.
*/
Ptr<WifiMacQueueItem> DoDequeue (ConstIterator pos);
/**
* Wrapper for the DoRemove method provided by the base class that additionally
* resets the iterator field of the item, if an item was dropped.
*
* \param pos the position of the item to drop
* \return the item.
*/
Ptr<WifiMacQueueItem> DoRemove (ConstIterator pos);
Time m_maxDelay; //!< Time to live for packets in the queue
DropPolicy m_dropPolicy; //!< Drop behavior of queue