diff --git a/src/wifi/model/block-ack-manager.h b/src/wifi/model/block-ack-manager.h index f3287ae01..383e28584 100644 --- a/src/wifi/model/block-ack-manager.h +++ b/src/wifi/model/block-ack-manager.h @@ -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 { diff --git a/src/wifi/model/msdu-aggregator.cc b/src/wifi/model/msdu-aggregator.cc index 7995c2d54..d597dc174 100644 --- a/src/wifi/model/msdu-aggregator.cc +++ b/src/wifi/model/msdu-aggregator.cc @@ -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 aggregatedPacket) { NS_LOG_FUNCTION_NOARGS (); - DeaggregatedMsdus set; + WifiMacQueueItem::DeaggregatedMsdus set; AmsduSubframeHeader hdr; Ptr extractedMsdu = Create (); diff --git a/src/wifi/model/msdu-aggregator.h b/src/wifi/model/msdu-aggregator.h index b6d9ed870..23dadf86c 100644 --- a/src/wifi/model/msdu-aggregator.h +++ b/src/wifi/model/msdu-aggregator.h @@ -25,14 +25,13 @@ #include "ns3/nstime.h" #include "wifi-mode.h" #include "qos-utils.h" +#include "wifi-mac-queue-item.h" #include 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, AmsduSubframeHeader> > DeaggregatedMsdus; - /// DeaggregatedMsdusCI typedef - typedef std::list, AmsduSubframeHeader> >::const_iterator DeaggregatedMsdusCI; /// EDCA queues typedef typedef std::map > EdcaQueues; @@ -119,7 +114,7 @@ public: * \param aggregatedPacket the aggregated packet. * \returns DeaggregatedMsdus. */ - static DeaggregatedMsdus Deaggregate (Ptr aggregatedPacket); + static WifiMacQueueItem::DeaggregatedMsdus Deaggregate (Ptr aggregatedPacket); /** * Set the map of EDCA queues. diff --git a/src/wifi/model/wifi-mac-queue-item.cc b/src/wifi/model/wifi-mac-queue-item.cc index 3d8cd6cfa..95f2a8932 100644 --- a/src/wifi/model/wifi-mac-queue-item.cc +++ b/src/wifi/model/wifi-mac-queue-item.cc @@ -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 @@ -110,6 +123,7 @@ WifiMacQueueItem::Aggregate (Ptr msdu) // An MSDU is going to be aggregated to this MPDU, hence this has to be an A-MSDU now Ptr firstMsdu = Create (*this); m_packet = Create (); + m_queueIts.clear (); DoAggregate (firstMsdu); m_header.SetQosAmsdu (); @@ -156,6 +170,7 @@ WifiMacQueueItem::DoAggregate (Ptr msdu) hdr.SetLength (static_cast (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 msdu) m_tstamp = Max (m_tstamp, msdu->GetTimeStamp ()); } +bool +WifiMacQueueItem::IsQueued (void) const +{ + return !m_queueIts.empty (); +} -MsduAggregator::DeaggregatedMsdusCI +const std::list& +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) diff --git a/src/wifi/model/wifi-mac-queue-item.h b/src/wifi/model/wifi-mac-queue-item.h index a3a1c4fca..e93dd0695 100644 --- a/src/wifi/model/wifi-mac-queue-item.h +++ b/src/wifi/model/wifi-mac-queue-item.h @@ -26,13 +26,14 @@ #include "ns3/nstime.h" #include "wifi-mac-header.h" -#include "msdu-aggregator.h" #include "amsdu-subframe-header.h" +#include 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 msdu); + /// DeaggregatedMsdus typedef + typedef std::list, AmsduSubframeHeader> > DeaggregatedMsdus; + /// DeaggregatedMsdusCI typedef + typedef std::list, 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>::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& GetQueueIteratorPairs (void) const; /** * \brief Get the MAC protocol data unit (MPDU) corresponding to this item @@ -142,10 +187,13 @@ private: */ void DoAggregate (Ptr msdu); + friend class WifiMacQueue; // to set QueueIteratorPair information + Ptr 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 m_queueIts; //!< Queue iterators pointing to this MSDU(s), if queued }; /** diff --git a/src/wifi/model/wifi-mac-queue.cc b/src/wifi/model/wifi-mac-queue.cc index 8f67650c0..d5623f8cb 100644 --- a/src/wifi/model/wifi-mac-queue.cc +++ b/src/wifi/model/wifi-mac-queue.cc @@ -567,4 +567,45 @@ WifiMacQueue::GetNBytes (void) return QueueBase::GetNBytes (); } +bool +WifiMacQueue::DoEnqueue (ConstIterator pos, Ptr item) +{ + Iterator ret; + if (Queue::DoEnqueue (pos, item, ret)) + { + // set item's information about its position in the queue + item->m_queueIts = {{this, ret}}; + return true; + } + return false; +} + +Ptr +WifiMacQueue::DoDequeue (ConstIterator pos) +{ + Ptr item = Queue::DoDequeue (pos); + + if (item != 0) + { + NS_ASSERT (item->m_queueIts.size () == 1); + item->m_queueIts.clear (); + } + + return item; +} + +Ptr +WifiMacQueue::DoRemove (ConstIterator pos) +{ + Ptr item = Queue::DoRemove (pos); + + if (item != 0) + { + NS_ASSERT (item->m_queueIts.size () == 1); + item->m_queueIts.clear (); + } + + return item; +} + } //namespace ns3 diff --git a/src/wifi/model/wifi-mac-queue.h b/src/wifi/model/wifi-mac-queue.h index 11178dcd3..5ab584120 100644 --- a/src/wifi/model/wifi-mac-queue.h +++ b/src/wifi/model/wifi-mac-queue.h @@ -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 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 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 DoRemove (ConstIterator pos); Time m_maxDelay; //!< Time to live for packets in the queue DropPolicy m_dropPolicy; //!< Drop behavior of queue