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:
@@ -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 {
|
||||
|
||||
|
||||
@@ -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> ();
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user