wifi: Add more methods to WifiMacQueue
- Insert/Dequeue/Remove from specific positions in the queue - Peek methods are const and return a ConstIterator - Added a trace for expired MPDUs
This commit is contained in:
@@ -120,9 +120,9 @@ MsduAggregator::GetNextAmsdu (Mac48Address recipient, uint8_t tid,
|
||||
|
||||
Ptr<QosTxop> qosTxop = m_edca.find (QosUtilsMapTidToAc (tid))->second;
|
||||
Ptr<WifiMacQueue> queue = qosTxop->GetWifiMacQueue ();
|
||||
Ptr<const WifiMacQueueItem> peekedItem = queue->PeekByTidAndAddress (tid, recipient);
|
||||
WifiMacQueue::ConstIterator peekedIt = queue->PeekByTidAndAddress (tid, recipient);
|
||||
|
||||
if (!peekedItem)
|
||||
if (peekedIt == queue->end ())
|
||||
{
|
||||
NS_LOG_DEBUG ("No packet with the given TID and address in the queue");
|
||||
return 0;
|
||||
@@ -147,19 +147,19 @@ MsduAggregator::GetNextAmsdu (Mac48Address recipient, uint8_t tid,
|
||||
|
||||
Ptr<Packet> amsdu = Create<Packet> ();
|
||||
uint8_t nMsdu = 0;
|
||||
WifiMacHeader header = peekedItem->GetHeader ();
|
||||
Time tstamp = peekedItem->GetTimeStamp ();
|
||||
// We need to keep track of the first MSDU. If it is dequeued but aggregation
|
||||
// fails, we need to re-insert it in the queue
|
||||
Ptr<const WifiMacQueueItem> first = peekedItem;
|
||||
WifiMacHeader header = (*peekedIt)->GetHeader ();
|
||||
Time tstamp = (*peekedIt)->GetTimeStamp ();
|
||||
// We need to keep track of the first MSDU. When it is processed, it is not known
|
||||
// if aggregation will succeed or not.
|
||||
WifiMacQueue::ConstIterator first = peekedIt;
|
||||
|
||||
// TODO Add support for the Max Number Of MSDUs In A-MSDU field in the Extended
|
||||
// Capabilities element sent by the recipient
|
||||
|
||||
while (peekedItem != 0) // && nMsdu < maxNMsdus
|
||||
while (peekedIt != queue->end ())
|
||||
{
|
||||
// check if aggregating the peeked MSDU violates the A-MSDU size limit
|
||||
uint16_t newAmsduSize = GetSizeIfAggregated (peekedItem->GetPacket ()->GetSize (),
|
||||
uint16_t newAmsduSize = GetSizeIfAggregated ((*peekedIt)->GetPacket ()->GetSize (),
|
||||
amsdu->GetSize ());
|
||||
|
||||
if (newAmsduSize > maxAmsduSize)
|
||||
@@ -177,36 +177,43 @@ MsduAggregator::GetNextAmsdu (Mac48Address recipient, uint8_t tid,
|
||||
break;
|
||||
}
|
||||
|
||||
// We can now safely aggregate the MSDU to the A-MSDU and remove it from the queue
|
||||
Aggregate (peekedItem->GetPacket (), amsdu,
|
||||
// We can now safely aggregate the MSDU to the A-MSDU
|
||||
Aggregate ((*peekedIt)->GetPacket (), amsdu,
|
||||
qosTxop->MapSrcAddressForAggregation (header),
|
||||
qosTxop->MapDestAddressForAggregation (header));
|
||||
queue->Remove (peekedItem->GetPacket ());
|
||||
|
||||
nMsdu++;
|
||||
|
||||
/* "The expiration of the A-MSDU lifetime timer occurs only when the lifetime
|
||||
* timer of all of the constituent MSDUs of the A-MSDU have expired" (Section
|
||||
* 10.12 of 802.11-2016)
|
||||
*/
|
||||
// The timestamp of the A-MSDU is the most recent among those of the MSDUs
|
||||
tstamp = Max (tstamp, peekedItem->GetTimeStamp ());
|
||||
tstamp = Max (tstamp, (*peekedIt)->GetTimeStamp ());
|
||||
|
||||
peekedItem = queue->PeekByTidAndAddress (tid, recipient);
|
||||
// If it is the first MSDU, move to the next one
|
||||
if (nMsdu == 0)
|
||||
{
|
||||
peekedIt++;
|
||||
}
|
||||
// otherwise, remove it from the queue
|
||||
else
|
||||
{
|
||||
peekedIt = queue->Remove (peekedIt);
|
||||
}
|
||||
|
||||
nMsdu++;
|
||||
|
||||
peekedIt = queue->PeekByTidAndAddress (tid, recipient, peekedIt);
|
||||
}
|
||||
|
||||
if (nMsdu < 2)
|
||||
{
|
||||
NS_LOG_DEBUG ("Aggregation failed (could not aggregate at least two MSDUs)");
|
||||
|
||||
// re-insert the first MSDU in the queue if it was removed
|
||||
if (nMsdu == 1)
|
||||
{
|
||||
queue->PushFront (Create<WifiMacQueueItem> (*first));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Aggregation succeeded, we have to remove the first MSDU
|
||||
queue->Remove (first);
|
||||
|
||||
header.SetQosAmsdu ();
|
||||
header.SetAddr3 (qosTxop->GetLow ()->GetBssid ());
|
||||
|
||||
|
||||
@@ -190,15 +190,17 @@ QosTxop::PeekNextFrame (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
Ptr<const WifiMacQueueItem> item;
|
||||
WifiMacQueue::ConstIterator it;
|
||||
|
||||
// check if there is a packet in the MacLow aggregation queue
|
||||
for (uint8_t tid = 0; tid < 8; tid++)
|
||||
{
|
||||
if (QosUtilsMapTidToAc (tid) == m_ac)
|
||||
{
|
||||
item = m_low->GetAggregateQueue ()->PeekByTid (tid);
|
||||
if (item != 0)
|
||||
it = m_low->GetAggregateQueue ()->PeekByTid (tid);
|
||||
if (it != m_low->GetAggregateQueue ()->end ())
|
||||
{
|
||||
item = *it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -220,10 +222,11 @@ QosTxop::PeekNextFrame (void)
|
||||
}
|
||||
|
||||
// otherwise, check if there is a packet in the EDCA queue
|
||||
item = m_queue->PeekFirstAvailable (m_qosBlockedDestinations);
|
||||
it = m_queue->PeekFirstAvailable (m_qosBlockedDestinations);
|
||||
|
||||
if (item != 0)
|
||||
if (it != m_queue->end ())
|
||||
{
|
||||
item = *it;
|
||||
// set the sequence number by just peeking the next value
|
||||
uint16_t sequence = m_txMiddle->PeekNextSequenceNumberFor (&item->GetHeader ());
|
||||
WifiMacHeader hdr = item->GetHeader ();
|
||||
@@ -245,10 +248,11 @@ QosTxop::PeekNextFrameByTidAndAddress (uint8_t tid, Mac48Address recipient)
|
||||
Ptr<const WifiMacQueueItem> item;
|
||||
|
||||
// check if there is a packet in the MacLow aggregation queue
|
||||
item = m_low->GetAggregateQueue ()->PeekByTidAndAddress (tid, recipient);
|
||||
WifiMacQueue::ConstIterator it = m_low->GetAggregateQueue ()->PeekByTidAndAddress (tid, recipient);
|
||||
|
||||
if (item != 0)
|
||||
if (it != m_low->GetAggregateQueue ()->end ())
|
||||
{
|
||||
item = *it;
|
||||
NS_LOG_DEBUG ("packet peeked from MacLow aggregation queue, " << *item);
|
||||
return item;
|
||||
}
|
||||
@@ -263,10 +267,11 @@ QosTxop::PeekNextFrameByTidAndAddress (uint8_t tid, Mac48Address recipient)
|
||||
}
|
||||
|
||||
// otherwise, check if there is a packet in the EDCA queue
|
||||
item = m_queue->PeekByTidAndAddress (tid, recipient);
|
||||
it = m_queue->PeekByTidAndAddress (tid, recipient);
|
||||
|
||||
if (item != 0)
|
||||
if (it != m_queue->end ())
|
||||
{
|
||||
item = *it;
|
||||
// set the sequence number by just peeking the next value
|
||||
uint16_t sequence = m_txMiddle->PeekNextSequenceNumberFor (&item->GetHeader ());
|
||||
WifiMacHeader hdr = item->GetHeader ();
|
||||
@@ -367,10 +372,11 @@ QosTxop::DequeuePeekedFrame (Ptr<const WifiMacQueueItem> peekedItem, WifiTxVecto
|
||||
&& GetBaAgreementEstablished (recipient, peekedItem->GetHeader ().GetQosTid ()))
|
||||
{
|
||||
uint8_t tid = peekedItem->GetHeader ().GetQosTid ();
|
||||
testItem = m_low->GetAggregateQueue ()->PeekByTidAndAddress (tid, recipient);
|
||||
WifiMacQueue::ConstIterator testIt = m_low->GetAggregateQueue ()->PeekByTidAndAddress (tid, recipient);
|
||||
|
||||
if (testItem)
|
||||
if (testIt != m_low->GetAggregateQueue ()->end ())
|
||||
{
|
||||
testItem = *testIt;
|
||||
// if not null, the test packet must equal the peeked packet
|
||||
NS_ASSERT (testItem->GetPacket () == peekedItem->GetPacket ());
|
||||
item = m_low->GetAggregateQueue ()->DequeueByTidAndAddress (tid, recipient);
|
||||
@@ -399,9 +405,9 @@ QosTxop::DequeuePeekedFrame (Ptr<const WifiMacQueueItem> peekedItem, WifiTxVecto
|
||||
if (peekedItem->GetHeader ().IsQosData ())
|
||||
{
|
||||
uint8_t tid = peekedItem->GetHeader ().GetQosTid ();
|
||||
testItem = m_queue->PeekByTidAndAddress (tid, recipient);
|
||||
WifiMacQueue::ConstIterator testIt = m_queue->PeekByTidAndAddress (tid, recipient);
|
||||
|
||||
NS_ASSERT (testItem != 0 && testItem->GetPacket () == peekedItem->GetPacket ());
|
||||
NS_ASSERT (testIt != m_queue->end () && (*testIt)->GetPacket () == peekedItem->GetPacket ());
|
||||
|
||||
// try A-MSDU aggregation
|
||||
if (m_low->GetMsduAggregator () != 0 && !recipient.IsBroadcast () && aggregate)
|
||||
|
||||
@@ -53,12 +53,16 @@ WifiMacQueue::GetTypeId (void)
|
||||
MakeEnumAccessor (&WifiMacQueue::m_dropPolicy),
|
||||
MakeEnumChecker (WifiMacQueue::DROP_OLDEST, "DropOldest",
|
||||
WifiMacQueue::DROP_NEWEST, "DropNewest"))
|
||||
.AddTraceSource ("Expired", "MPDU dropped because its lifetime expired.",
|
||||
MakeTraceSourceAccessor (&WifiMacQueue::m_traceExpired),
|
||||
"ns3::WifiMacQueueItem::TracedCallback")
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
WifiMacQueue::WifiMacQueue ()
|
||||
: NS_LOG_TEMPLATE_DEFINE ("WifiMacQueue")
|
||||
: m_expiredPacketsPresent (false),
|
||||
NS_LOG_TEMPLATE_DEFINE ("WifiMacQueue")
|
||||
{
|
||||
}
|
||||
|
||||
@@ -67,6 +71,8 @@ WifiMacQueue::~WifiMacQueue ()
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
}
|
||||
|
||||
const WifiMacQueue::ConstIterator WifiMacQueue::EMPTY = std::list<Ptr<WifiMacQueueItem>> ().end ();
|
||||
|
||||
void
|
||||
WifiMacQueue::SetMaxQueueSize (QueueSize size)
|
||||
{
|
||||
@@ -102,6 +108,7 @@ WifiMacQueue::TtlExceeded (ConstIterator &it)
|
||||
{
|
||||
NS_LOG_DEBUG ("Removing packet that stayed in the queue for too long (" <<
|
||||
Simulator::Now () - (*it)->GetTimeStamp () << ")");
|
||||
m_traceExpired (*it);
|
||||
auto curr = it++;
|
||||
DoRemove (curr);
|
||||
return true;
|
||||
@@ -112,59 +119,57 @@ WifiMacQueue::TtlExceeded (ConstIterator &it)
|
||||
bool
|
||||
WifiMacQueue::Enqueue (Ptr<WifiMacQueueItem> item)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << item);
|
||||
NS_ASSERT_MSG (GetMaxSize ().GetUnit () == QueueSizeUnit::PACKETS,
|
||||
"WifiMacQueues must be in packet mode");
|
||||
NS_LOG_FUNCTION (this << *item);
|
||||
|
||||
QueueBase::SetMaxSize (GetMaxQueueSize ()); //Make sure QueueBase has the same maximum queue size
|
||||
|
||||
// if the queue is full, remove the first stale packet (if any) encountered
|
||||
// starting from the head of the queue, in order to make room for the new packet.
|
||||
if (QueueBase::GetNPackets () == GetMaxSize ().GetValue ())
|
||||
{
|
||||
ConstIterator it = begin ();
|
||||
while (it != end () && !TtlExceeded (it))
|
||||
{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
if (QueueBase::GetNPackets () == GetMaxSize ().GetValue () && m_dropPolicy == DROP_OLDEST)
|
||||
{
|
||||
NS_LOG_DEBUG ("Remove the oldest item in the queue");
|
||||
DoRemove (begin ());
|
||||
}
|
||||
|
||||
return DoEnqueue (end (), item);
|
||||
return Insert (end (), item);
|
||||
}
|
||||
|
||||
bool
|
||||
WifiMacQueue::PushFront (Ptr<WifiMacQueueItem> item)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << item);
|
||||
NS_LOG_FUNCTION (this << *item);
|
||||
|
||||
return Insert (begin (), item);
|
||||
}
|
||||
|
||||
bool
|
||||
WifiMacQueue::Insert (ConstIterator pos, Ptr<WifiMacQueueItem> item)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << *item);
|
||||
NS_ASSERT_MSG (GetMaxSize ().GetUnit () == QueueSizeUnit::PACKETS,
|
||||
"WifiMacQueues must be in packet mode");
|
||||
|
||||
QueueBase::SetMaxSize (GetMaxQueueSize ()); //Make sure QueueBase has the same maximum queue size
|
||||
|
||||
// if the queue is full, remove the first stale packet (if any) encountered
|
||||
// starting from the head of the queue, in order to make room for the new packet.
|
||||
if (QueueBase::GetNPackets () == GetMaxSize ().GetValue ())
|
||||
// insert the item if the queue is not full
|
||||
if (QueueBase::GetNPackets () < GetMaxSize ().GetValue ())
|
||||
{
|
||||
ConstIterator it = begin ();
|
||||
while (it != end () && !TtlExceeded (it))
|
||||
{
|
||||
it++;
|
||||
}
|
||||
return DoEnqueue (pos, item);
|
||||
}
|
||||
|
||||
if (QueueBase::GetNPackets () == GetMaxSize ().GetValue () && m_dropPolicy == DROP_OLDEST)
|
||||
// the queue is full; scan the list in the attempt to remove stale packets
|
||||
ConstIterator it = begin ();
|
||||
while (it != end ())
|
||||
{
|
||||
if (it == pos && TtlExceeded (it))
|
||||
{
|
||||
return DoEnqueue (it, item);
|
||||
}
|
||||
if (TtlExceeded (it))
|
||||
{
|
||||
return DoEnqueue (pos, item);
|
||||
}
|
||||
it++;
|
||||
}
|
||||
|
||||
// the queue is still full, remove the oldest item if the policy is drop oldest
|
||||
if (m_dropPolicy == DROP_OLDEST)
|
||||
{
|
||||
NS_LOG_DEBUG ("Remove the oldest item in the queue");
|
||||
DoRemove (begin ());
|
||||
}
|
||||
|
||||
return DoEnqueue (begin (), item);
|
||||
return DoEnqueue (pos, item);
|
||||
}
|
||||
|
||||
Ptr<WifiMacQueueItem>
|
||||
@@ -186,82 +191,90 @@ Ptr<WifiMacQueueItem>
|
||||
WifiMacQueue::DequeueByAddress (Mac48Address dest)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << dest);
|
||||
ConstIterator it = PeekByAddress (dest);
|
||||
|
||||
for (ConstIterator it = begin (); it != end (); )
|
||||
if (it == end ())
|
||||
{
|
||||
if (!TtlExceeded (it))
|
||||
{
|
||||
if ((*it)->GetHeader ().IsData () && (*it)->GetDestinationAddress () == dest)
|
||||
{
|
||||
return DoDequeue (it);
|
||||
}
|
||||
|
||||
it++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
NS_LOG_DEBUG ("The queue is empty");
|
||||
return 0;
|
||||
return Dequeue (it);
|
||||
}
|
||||
|
||||
Ptr<WifiMacQueueItem>
|
||||
WifiMacQueue::DequeueByTid (uint8_t tid)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << +tid);
|
||||
for (ConstIterator it = begin (); it != end (); )
|
||||
{
|
||||
if (!TtlExceeded (it))
|
||||
{
|
||||
if ((*it)->GetHeader ().IsQosData () && (*it)->GetHeader ().GetQosTid () == tid)
|
||||
{
|
||||
return DoDequeue (it);
|
||||
}
|
||||
ConstIterator it = PeekByTid (tid);
|
||||
|
||||
it++;
|
||||
}
|
||||
if (it == end ())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
NS_LOG_DEBUG ("The queue is empty");
|
||||
return 0;
|
||||
return Dequeue (it);
|
||||
}
|
||||
|
||||
Ptr<WifiMacQueueItem>
|
||||
WifiMacQueue::DequeueByTidAndAddress (uint8_t tid, Mac48Address dest)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << dest);
|
||||
for (ConstIterator it = begin (); it != end (); )
|
||||
{
|
||||
if (!TtlExceeded (it))
|
||||
{
|
||||
if ((*it)->GetHeader ().IsQosData () && (*it)->GetDestinationAddress () == dest
|
||||
&& (*it)->GetHeader ().GetQosTid () == tid)
|
||||
{
|
||||
return DoDequeue (it);
|
||||
}
|
||||
NS_LOG_FUNCTION (this << +tid << dest);
|
||||
ConstIterator it = PeekByTidAndAddress (tid, dest);
|
||||
|
||||
it++;
|
||||
}
|
||||
if (it == end ())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
NS_LOG_DEBUG ("The queue is empty");
|
||||
return 0;
|
||||
return Dequeue (it);
|
||||
}
|
||||
|
||||
Ptr<WifiMacQueueItem>
|
||||
WifiMacQueue::DequeueFirstAvailable (const Ptr<QosBlockedDestinations> blockedPackets)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
for (ConstIterator it = begin (); it != end (); )
|
||||
{
|
||||
if (!TtlExceeded (it))
|
||||
{
|
||||
if (!(*it)->GetHeader ().IsQosData ()
|
||||
|| !blockedPackets->IsBlocked ((*it)->GetHeader ().GetAddr1 (), (*it)->GetHeader ().GetQosTid ()))
|
||||
{
|
||||
return DoDequeue (it);
|
||||
}
|
||||
ConstIterator it = PeekFirstAvailable (blockedPackets);
|
||||
|
||||
if (it == end ())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return Dequeue (it);
|
||||
}
|
||||
|
||||
Ptr<WifiMacQueueItem>
|
||||
WifiMacQueue::Dequeue (ConstIterator pos)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
if (!m_expiredPacketsPresent)
|
||||
{
|
||||
if (TtlExceeded (pos))
|
||||
{
|
||||
NS_LOG_DEBUG ("Packet lifetime expired");
|
||||
return 0;
|
||||
}
|
||||
return DoDequeue (pos);
|
||||
}
|
||||
|
||||
// remove stale items queued before the given position
|
||||
ConstIterator it = begin ();
|
||||
while (it != end ())
|
||||
{
|
||||
if (it == pos)
|
||||
{
|
||||
// reset the flag signaling the presence of expired packets before returning
|
||||
m_expiredPacketsPresent = false;
|
||||
|
||||
if (TtlExceeded (it))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return DoDequeue (it);
|
||||
}
|
||||
else if (!TtlExceeded (it))
|
||||
{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
NS_LOG_DEBUG ("The queue is empty");
|
||||
NS_LOG_DEBUG ("Invalid iterator");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -277,71 +290,122 @@ WifiMacQueue::Peek (void) const
|
||||
{
|
||||
return DoPeek (it);
|
||||
}
|
||||
// signal the presence of expired packets
|
||||
m_expiredPacketsPresent = true;
|
||||
}
|
||||
NS_LOG_DEBUG ("The queue is empty");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Ptr<const WifiMacQueueItem>
|
||||
WifiMacQueue::PeekByTid (uint8_t tid)
|
||||
WifiMacQueue::ConstIterator
|
||||
WifiMacQueue::PeekByAddress (Mac48Address dest, ConstIterator pos) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << dest);
|
||||
ConstIterator it = (pos != EMPTY ? pos : begin ());
|
||||
while (it != end ())
|
||||
{
|
||||
// skip packets that stayed in the queue for too long. They will be
|
||||
// actually removed from the queue by the next call to a non-const method
|
||||
if (Simulator::Now () <= (*it)->GetTimeStamp () + m_maxDelay)
|
||||
{
|
||||
if (((*it)->GetHeader ().IsData () || (*it)->GetHeader ().IsQosData ())
|
||||
&& (*it)->GetDestinationAddress () == dest)
|
||||
{
|
||||
return it;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// signal the presence of expired packets
|
||||
m_expiredPacketsPresent = true;
|
||||
}
|
||||
it++;
|
||||
}
|
||||
NS_LOG_DEBUG ("The queue is empty");
|
||||
return end ();
|
||||
}
|
||||
|
||||
WifiMacQueue::ConstIterator
|
||||
WifiMacQueue::PeekByTid (uint8_t tid, ConstIterator pos) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << +tid);
|
||||
for (ConstIterator it = begin (); it != end (); )
|
||||
ConstIterator it = (pos != EMPTY ? pos : begin ());
|
||||
while (it != end ())
|
||||
{
|
||||
if (!TtlExceeded (it))
|
||||
// skip packets that stayed in the queue for too long. They will be
|
||||
// actually removed from the queue by the next call to a non-const method
|
||||
if (Simulator::Now () <= (*it)->GetTimeStamp () + m_maxDelay)
|
||||
{
|
||||
if ((*it)->GetHeader ().IsQosData () && (*it)->GetHeader ().GetQosTid () == tid)
|
||||
{
|
||||
return DoPeek (it);
|
||||
return it;
|
||||
}
|
||||
|
||||
it++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// signal the presence of expired packets
|
||||
m_expiredPacketsPresent = true;
|
||||
}
|
||||
it++;
|
||||
}
|
||||
NS_LOG_DEBUG ("The queue is empty");
|
||||
return 0;
|
||||
return end ();
|
||||
}
|
||||
|
||||
Ptr<const WifiMacQueueItem>
|
||||
WifiMacQueue::PeekByTidAndAddress (uint8_t tid, Mac48Address dest)
|
||||
WifiMacQueue::ConstIterator
|
||||
WifiMacQueue::PeekByTidAndAddress (uint8_t tid, Mac48Address dest, ConstIterator pos) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << dest);
|
||||
for (ConstIterator it = begin (); it != end (); )
|
||||
NS_LOG_FUNCTION (this << +tid << dest);
|
||||
ConstIterator it = (pos != EMPTY ? pos : begin ());
|
||||
while (it != end ())
|
||||
{
|
||||
if (!TtlExceeded (it))
|
||||
// skip packets that stayed in the queue for too long. They will be
|
||||
// actually removed from the queue by the next call to a non-const method
|
||||
if (Simulator::Now () <= (*it)->GetTimeStamp () + m_maxDelay)
|
||||
{
|
||||
if ((*it)->GetHeader ().IsQosData () && (*it)->GetDestinationAddress () == dest
|
||||
&& (*it)->GetHeader ().GetQosTid () == tid)
|
||||
{
|
||||
return DoPeek (it);
|
||||
return it;
|
||||
}
|
||||
|
||||
it++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// signal the presence of expired packets
|
||||
m_expiredPacketsPresent = true;
|
||||
}
|
||||
it++;
|
||||
}
|
||||
NS_LOG_DEBUG ("The queue is empty");
|
||||
return 0;
|
||||
return end ();
|
||||
}
|
||||
|
||||
Ptr<const WifiMacQueueItem>
|
||||
WifiMacQueue::PeekFirstAvailable (const Ptr<QosBlockedDestinations> blockedPackets)
|
||||
WifiMacQueue::ConstIterator
|
||||
WifiMacQueue::PeekFirstAvailable (const Ptr<QosBlockedDestinations> blockedPackets, ConstIterator pos) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
for (ConstIterator it = begin (); it != end (); )
|
||||
ConstIterator it = (pos != EMPTY ? pos : begin ());
|
||||
while (it != end ())
|
||||
{
|
||||
if (!TtlExceeded (it))
|
||||
// skip packets that stayed in the queue for too long. They will be
|
||||
// actually removed from the queue by the next call to a non-const method
|
||||
if (Simulator::Now () <= (*it)->GetTimeStamp () + m_maxDelay)
|
||||
{
|
||||
if (!(*it)->GetHeader ().IsQosData ()
|
||||
if (!(*it)->GetHeader ().IsQosData () || !blockedPackets
|
||||
|| !blockedPackets->IsBlocked ((*it)->GetHeader ().GetAddr1 (), (*it)->GetHeader ().GetQosTid ()))
|
||||
{
|
||||
return DoPeek (it);
|
||||
return it;
|
||||
}
|
||||
|
||||
it++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// signal the presence of expired packets
|
||||
m_expiredPacketsPresent = true;
|
||||
}
|
||||
it++;
|
||||
}
|
||||
NS_LOG_DEBUG ("The queue is empty");
|
||||
return 0;
|
||||
return end ();
|
||||
}
|
||||
|
||||
Ptr<WifiMacQueueItem>
|
||||
@@ -381,6 +445,40 @@ WifiMacQueue::Remove (Ptr<const Packet> packet)
|
||||
return false;
|
||||
}
|
||||
|
||||
WifiMacQueue::ConstIterator
|
||||
WifiMacQueue::Remove (ConstIterator pos, bool removeExpired)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
if (!removeExpired)
|
||||
{
|
||||
ConstIterator curr = pos++;
|
||||
DoRemove (curr);
|
||||
return pos;
|
||||
}
|
||||
|
||||
// remove stale items queued before the given position
|
||||
ConstIterator it = begin ();
|
||||
while (it != end ())
|
||||
{
|
||||
if (it == pos)
|
||||
{
|
||||
// reset the flag signaling the presence of expired packets before returning
|
||||
m_expiredPacketsPresent = false;
|
||||
|
||||
ConstIterator curr = pos++;
|
||||
DoRemove (curr);
|
||||
return pos;
|
||||
}
|
||||
else if (!TtlExceeded (it))
|
||||
{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
NS_LOG_DEBUG ("Invalid iterator");
|
||||
return end ();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
WifiMacQueue::GetNPacketsByAddress (Mac48Address dest)
|
||||
{
|
||||
|
||||
@@ -72,6 +72,12 @@ public:
|
||||
DROP_OLDEST
|
||||
};
|
||||
|
||||
/// allow the usage of iterators and const iterators
|
||||
using Queue<WifiMacQueueItem>::ConstIterator;
|
||||
using Queue<WifiMacQueueItem>::Iterator;
|
||||
using Queue<WifiMacQueueItem>::begin;
|
||||
using Queue<WifiMacQueueItem>::end;
|
||||
|
||||
/**
|
||||
* \brief Set the maximum size of this queue
|
||||
*
|
||||
@@ -111,6 +117,14 @@ public:
|
||||
* \return true if success, false if the packet has been dropped
|
||||
*/
|
||||
bool PushFront (Ptr<WifiMacQueueItem> item);
|
||||
/**
|
||||
* Enqueue the given Wifi MAC queue item before the given position.
|
||||
*
|
||||
* \param pos the position before which the item is to be inserted
|
||||
* \param item the Wifi MAC queue item to be enqueued
|
||||
* \return true if success, false if the packet has been dropped
|
||||
*/
|
||||
bool Insert (ConstIterator pos, Ptr<WifiMacQueueItem> item);
|
||||
/**
|
||||
* Dequeue the packet in the front of the queue.
|
||||
*
|
||||
@@ -118,8 +132,8 @@ public:
|
||||
*/
|
||||
Ptr<WifiMacQueueItem> Dequeue (void);
|
||||
/**
|
||||
* Search and return, if present in the queue, the first packet having the
|
||||
* address indicated by <i>type</i> equal to <i>addr</i>.
|
||||
* Search and return, if present in the queue, the first packet (either Data
|
||||
* frame or QoS Data frame) having the receiver address equal to <i>addr</i>.
|
||||
* This method removes the packet from the queue.
|
||||
* It is typically used by ns3::Txop during the CF period.
|
||||
*
|
||||
@@ -163,7 +177,16 @@ public:
|
||||
*
|
||||
* \return packet
|
||||
*/
|
||||
Ptr<WifiMacQueueItem> DequeueFirstAvailable (const Ptr<QosBlockedDestinations> blockedPackets);
|
||||
Ptr<WifiMacQueueItem> DequeueFirstAvailable (const Ptr<QosBlockedDestinations> blockedPackets = nullptr);
|
||||
/**
|
||||
* Dequeue the item at position <i>pos</i> in the queue. Return a null
|
||||
* pointer if the given iterator is invalid, the queue is empty or the
|
||||
* lifetime of the item pointed to by the given iterator is expired.
|
||||
*
|
||||
* \param pos the position of the item to be dequeued
|
||||
* \return the dequeued item, if any
|
||||
*/
|
||||
Ptr<WifiMacQueueItem> Dequeue (WifiMacQueue::ConstIterator pos);
|
||||
/**
|
||||
* Peek the packet in the front of the queue. The packet is not removed.
|
||||
*
|
||||
@@ -171,36 +194,55 @@ public:
|
||||
*/
|
||||
Ptr<const WifiMacQueueItem> Peek (void) const;
|
||||
/**
|
||||
* Search and return, if present in the queue, the first packet having the
|
||||
* tid equal to <i>tid</i>. This method does not remove the packet from the queue.
|
||||
* Search and return, if present in the queue, the first packet (either Data
|
||||
* frame or QoS Data frame) having the receiver address equal to <i>addr</i>.
|
||||
* If <i>pos</i> is a valid iterator, the search starts from the packet pointed
|
||||
* to by the given iterator.
|
||||
* This method does not remove the packet from the queue.
|
||||
*
|
||||
* \param tid the given TID
|
||||
* \param dest the given destination
|
||||
* \param pos the iterator pointing to the packet the search starts from
|
||||
*
|
||||
* \return packet
|
||||
* \return an iterator pointing to the peeked packet
|
||||
*/
|
||||
Ptr<const WifiMacQueueItem> PeekByTid (uint8_t tid);
|
||||
ConstIterator PeekByAddress (Mac48Address dest, ConstIterator pos = EMPTY) const;
|
||||
/**
|
||||
* Search and return, if present in the queue, the first packet having the
|
||||
* address indicated by <i>type</i> equal to <i>addr</i>, and tid
|
||||
* equal to <i>tid</i>. This method does not remove the packet from the queue.
|
||||
* It is typically used by ns3::QosTxop in order to perform correct MSDU
|
||||
* aggregation (A-MSDU).
|
||||
* tid equal to <i>tid</i>. If <i>pos</i> is a valid iterator, the search starts
|
||||
* from the packet pointed to by the given iterator.
|
||||
* This method does not remove the packet from the queue.
|
||||
*
|
||||
* \param tid the given TID
|
||||
* \param pos the iterator pointing to the packet the search starts from
|
||||
*
|
||||
* \return an iterator pointing to the peeked packet
|
||||
*/
|
||||
ConstIterator PeekByTid (uint8_t tid, ConstIterator pos = EMPTY) const;
|
||||
/**
|
||||
* Search and return, if present in the queue, the first packet having the
|
||||
* receiver address equal to <i>dest</i>, and tid equal to <i>tid</i>.
|
||||
* If <i>pos</i> is a valid iterator, the search starts from the packet pointed
|
||||
* to by the given iterator. This method does not remove the packet from the queue.
|
||||
* It is typically used by ns3::QosTxop in order to perform correct MSDU aggregation
|
||||
* (A-MSDU).
|
||||
*
|
||||
* \param tid the given TID
|
||||
* \param dest the given destination
|
||||
* \param pos the iterator pointing to the packet the search starts from
|
||||
*
|
||||
* \return packet
|
||||
* \return an iterator pointing to the peeked packet
|
||||
*/
|
||||
Ptr<const WifiMacQueueItem> PeekByTidAndAddress (uint8_t tid,
|
||||
Mac48Address dest);
|
||||
ConstIterator PeekByTidAndAddress (uint8_t tid, Mac48Address dest, ConstIterator pos = EMPTY) const;
|
||||
/**
|
||||
* Return first available packet for transmission. The packet is not removed from queue.
|
||||
*
|
||||
* \param blockedPackets
|
||||
* \param pos the iterator pointing to the packet the search starts from
|
||||
*
|
||||
* \return packet
|
||||
* \return an iterator pointing to the peeked packet
|
||||
*/
|
||||
Ptr<const WifiMacQueueItem> PeekFirstAvailable (const Ptr<QosBlockedDestinations> blockedPackets);
|
||||
ConstIterator PeekFirstAvailable (const Ptr<QosBlockedDestinations> blockedPackets = nullptr,
|
||||
ConstIterator pos = EMPTY) const;
|
||||
/**
|
||||
* Remove the packet in the front of the queue.
|
||||
*
|
||||
@@ -217,6 +259,17 @@ public:
|
||||
* \return true if the packet was removed, false otherwise
|
||||
*/
|
||||
bool Remove (Ptr<const Packet> packet);
|
||||
/**
|
||||
* Remove the item at position <i>pos</i> in the queue and return an iterator
|
||||
* pointing to the item following the removed one. If <i>removeExpired</i> is
|
||||
* true, all the items in the queue from the head to the given position are
|
||||
* removed if their lifetime expired.
|
||||
*
|
||||
* \param pos the position of the item to be removed
|
||||
* \param removeExpired true to remove expired items
|
||||
* \return an iterator pointing to the item following the removed one
|
||||
*/
|
||||
ConstIterator Remove (ConstIterator pos, bool removeExpired = false);
|
||||
/**
|
||||
* Return the number of packets having destination address specified by
|
||||
* <i>dest</i>.
|
||||
@@ -272,6 +325,11 @@ private:
|
||||
QueueSize m_maxSize; //!< max queue size
|
||||
Time m_maxDelay; //!< Time to live for packets in the queue
|
||||
DropPolicy m_dropPolicy; //!< Drop behavior of queue
|
||||
mutable bool m_expiredPacketsPresent; //!> True if expired packets are in the queue
|
||||
static const ConstIterator EMPTY; //!< Invalid iterator to signal an empty queue
|
||||
|
||||
/// Traced callback: fired when a packet is dropped due to lifetime expiration
|
||||
TracedCallback<Ptr<const WifiMacQueueItem> > m_traceExpired;
|
||||
|
||||
NS_LOG_TEMPLATE_DECLARE; //!< redefinition of the log component
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user