A Discrete-Event Network Simulator
API
wifi-mac-queue.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005, 2009 INRIA
4  * Copyright (c) 2009 MIRKO BANCHI
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
20  * Mirko Banchi <mk.banchi@gmail.com>
21  * Stefano Avallone <stavallo@unina.it>
22  */
23 
24 #include "ns3/simulator.h"
25 #include "wifi-mac-queue.h"
27 
28 namespace ns3 {
29 
30 NS_LOG_COMPONENT_DEFINE ("WifiMacQueue");
31 
32 NS_OBJECT_ENSURE_REGISTERED (WifiMacQueue);
33 NS_OBJECT_TEMPLATE_CLASS_DEFINE (Queue, WifiMacQueueItem);
34 
35 TypeId
37 {
38  static TypeId tid = TypeId ("ns3::WifiMacQueue")
40  .SetGroupName ("Wifi")
41  .AddConstructor<WifiMacQueue> ()
42  .AddAttribute ("MaxQueueSize",
43  "The max queue size",
44  QueueSizeValue (QueueSize ("500p")),
47  .AddAttribute ("MaxDelay", "If a packet stays longer than this delay in the queue, it is dropped.",
48  TimeValue (MilliSeconds (500)),
50  MakeTimeChecker ())
51  .AddAttribute ("DropPolicy", "Upon enqueue with full queue, drop oldest (DropOldest) or newest (DropNewest) packet",
55  WifiMacQueue::DROP_NEWEST, "DropNewest"))
56  .AddTraceSource ("Expired", "MPDU dropped because its lifetime expired.",
58  "ns3::WifiMacQueueItem::TracedCallback")
59  ;
60  return tid;
61 }
62 
64  : m_expiredPacketsPresent (false),
65  NS_LOG_TEMPLATE_DEFINE ("WifiMacQueue")
66 {
67 }
68 
70 {
72 }
73 
74 const WifiMacQueue::ConstIterator WifiMacQueue::EMPTY = std::list<Ptr<WifiMacQueueItem>> ().end ();
75 
76 void
78 {
79  NS_LOG_FUNCTION (this << size);
80  m_maxSize = size;
81 }
82 
85 {
86  return m_maxSize;
87 }
88 
89 void
91 {
92  NS_LOG_FUNCTION (this << delay);
93  m_maxDelay = delay;
94 }
95 
96 Time
98 {
99  return m_maxDelay;
100 }
101 
102 bool
103 WifiMacQueue::TtlExceeded (ConstIterator &it)
104 {
105  NS_LOG_FUNCTION (this);
106 
107  if (Simulator::Now () > (*it)->GetTimeStamp () + m_maxDelay)
108  {
109  NS_LOG_DEBUG ("Removing packet that stayed in the queue for too long (" <<
110  Simulator::Now () - (*it)->GetTimeStamp () << ")");
111  m_traceExpired (*it);
112  auto curr = it++;
113  DoRemove (curr);
114  return true;
115  }
116  return false;
117 }
118 
119 bool
121 {
122  NS_LOG_FUNCTION (this << *item);
123 
124  return Insert (end (), item);
125 }
126 
127 bool
129 {
130  NS_LOG_FUNCTION (this << *item);
131 
132  return Insert (begin (), item);
133 }
134 
135 bool
137 {
138  NS_LOG_FUNCTION (this << *item);
139  NS_ASSERT_MSG (GetMaxSize ().GetUnit () == QueueSizeUnit::PACKETS,
140  "WifiMacQueues must be in packet mode");
141 
142  QueueBase::SetMaxSize (GetMaxQueueSize ()); //Make sure QueueBase has the same maximum queue size
143 
144  // insert the item if the queue is not full
145  if (QueueBase::GetNPackets () < GetMaxSize ().GetValue ())
146  {
147  return DoEnqueue (pos, item);
148  }
149 
150  // the queue is full; scan the list in the attempt to remove stale packets
151  ConstIterator it = begin ();
152  while (it != end ())
153  {
154  if (it == pos && TtlExceeded (it))
155  {
156  return DoEnqueue (it, item);
157  }
158  if (TtlExceeded (it))
159  {
160  return DoEnqueue (pos, item);
161  }
162  it++;
163  }
164 
165  // the queue is still full, remove the oldest item if the policy is drop oldest
166  if (m_dropPolicy == DROP_OLDEST)
167  {
168  NS_LOG_DEBUG ("Remove the oldest item in the queue");
169  DoRemove (begin ());
170  }
171 
172  return DoEnqueue (pos, item);
173 }
174 
177 {
178  NS_LOG_FUNCTION (this);
179  for (ConstIterator it = begin (); it != end (); )
180  {
181  if (!TtlExceeded (it))
182  {
183  return DoDequeue (it);
184  }
185  }
186  NS_LOG_DEBUG ("The queue is empty");
187  return 0;
188 }
189 
192 {
193  NS_LOG_FUNCTION (this << dest);
194  ConstIterator it = PeekByAddress (dest);
195 
196  if (it == end ())
197  {
198  return 0;
199  }
200  return Dequeue (it);
201 }
202 
205 {
206  NS_LOG_FUNCTION (this << +tid);
207  ConstIterator it = PeekByTid (tid);
208 
209  if (it == end ())
210  {
211  return 0;
212  }
213  return Dequeue (it);
214 }
215 
218 {
219  NS_LOG_FUNCTION (this << +tid << dest);
220  ConstIterator it = PeekByTidAndAddress (tid, dest);
221 
222  if (it == end ())
223  {
224  return 0;
225  }
226  return Dequeue (it);
227 }
228 
231 {
232  NS_LOG_FUNCTION (this);
233  ConstIterator it = PeekFirstAvailable (blockedPackets);
234 
235  if (it == end ())
236  {
237  return 0;
238  }
239  return Dequeue (it);
240 }
241 
243 WifiMacQueue::Dequeue (ConstIterator pos)
244 {
245  NS_LOG_FUNCTION (this);
246 
248  {
249  if (TtlExceeded (pos))
250  {
251  NS_LOG_DEBUG ("Packet lifetime expired");
252  return 0;
253  }
254  return DoDequeue (pos);
255  }
256 
257  // remove stale items queued before the given position
258  ConstIterator it = begin ();
259  while (it != end ())
260  {
261  if (it == pos)
262  {
263  // reset the flag signaling the presence of expired packets before returning
264  m_expiredPacketsPresent = false;
265 
266  if (TtlExceeded (it))
267  {
268  return 0;
269  }
270  return DoDequeue (it);
271  }
272  else if (!TtlExceeded (it))
273  {
274  it++;
275  }
276  }
277  NS_LOG_DEBUG ("Invalid iterator");
278  return 0;
279 }
280 
281 Ptr<const WifiMacQueueItem>
282 WifiMacQueue::Peek (void) const
283 {
284  NS_LOG_FUNCTION (this);
285  for (auto it = begin (); it != end (); it++)
286  {
287  // skip packets that stayed in the queue for too long. They will be
288  // actually removed from the queue by the next call to a non-const method
289  if (Simulator::Now () <= (*it)->GetTimeStamp () + m_maxDelay)
290  {
291  return DoPeek (it);
292  }
293  // signal the presence of expired packets
295  }
296  NS_LOG_DEBUG ("The queue is empty");
297  return 0;
298 }
299 
300 WifiMacQueue::ConstIterator
301 WifiMacQueue::PeekByAddress (Mac48Address dest, ConstIterator pos) const
302 {
303  NS_LOG_FUNCTION (this << dest);
304  ConstIterator it = (pos != EMPTY ? pos : begin ());
305  while (it != end ())
306  {
307  // skip packets that stayed in the queue for too long. They will be
308  // actually removed from the queue by the next call to a non-const method
309  if (Simulator::Now () <= (*it)->GetTimeStamp () + m_maxDelay)
310  {
311  if (((*it)->GetHeader ().IsData () || (*it)->GetHeader ().IsQosData ())
312  && (*it)->GetDestinationAddress () == dest)
313  {
314  return it;
315  }
316  }
317  else
318  {
319  // signal the presence of expired packets
321  }
322  it++;
323  }
324  NS_LOG_DEBUG ("The queue is empty");
325  return end ();
326 }
327 
328 WifiMacQueue::ConstIterator
329 WifiMacQueue::PeekByTid (uint8_t tid, ConstIterator pos) const
330 {
331  NS_LOG_FUNCTION (this << +tid);
332  ConstIterator it = (pos != EMPTY ? pos : begin ());
333  while (it != end ())
334  {
335  // skip packets that stayed in the queue for too long. They will be
336  // actually removed from the queue by the next call to a non-const method
337  if (Simulator::Now () <= (*it)->GetTimeStamp () + m_maxDelay)
338  {
339  if ((*it)->GetHeader ().IsQosData () && (*it)->GetHeader ().GetQosTid () == tid)
340  {
341  return it;
342  }
343  }
344  else
345  {
346  // signal the presence of expired packets
348  }
349  it++;
350  }
351  NS_LOG_DEBUG ("The queue is empty");
352  return end ();
353 }
354 
355 WifiMacQueue::ConstIterator
356 WifiMacQueue::PeekByTidAndAddress (uint8_t tid, Mac48Address dest, ConstIterator pos) const
357 {
358  NS_LOG_FUNCTION (this << +tid << dest);
359  ConstIterator it = (pos != EMPTY ? pos : begin ());
360  while (it != end ())
361  {
362  // skip packets that stayed in the queue for too long. They will be
363  // actually removed from the queue by the next call to a non-const method
364  if (Simulator::Now () <= (*it)->GetTimeStamp () + m_maxDelay)
365  {
366  if ((*it)->GetHeader ().IsQosData () && (*it)->GetDestinationAddress () == dest
367  && (*it)->GetHeader ().GetQosTid () == tid)
368  {
369  return it;
370  }
371  }
372  else
373  {
374  // signal the presence of expired packets
376  }
377  it++;
378  }
379  NS_LOG_DEBUG ("The queue is empty");
380  return end ();
381 }
382 
383 WifiMacQueue::ConstIterator
384 WifiMacQueue::PeekFirstAvailable (const Ptr<QosBlockedDestinations> blockedPackets, ConstIterator pos) const
385 {
386  NS_LOG_FUNCTION (this);
387  ConstIterator it = (pos != EMPTY ? pos : begin ());
388  while (it != end ())
389  {
390  // skip packets that stayed in the queue for too long. They will be
391  // actually removed from the queue by the next call to a non-const method
392  if (Simulator::Now () <= (*it)->GetTimeStamp () + m_maxDelay)
393  {
394  if (!(*it)->GetHeader ().IsQosData () || !blockedPackets
395  || !blockedPackets->IsBlocked ((*it)->GetHeader ().GetAddr1 (), (*it)->GetHeader ().GetQosTid ()))
396  {
397  return it;
398  }
399  }
400  else
401  {
402  // signal the presence of expired packets
404  }
405  it++;
406  }
407  NS_LOG_DEBUG ("The queue is empty");
408  return end ();
409 }
410 
413 {
414  NS_LOG_FUNCTION (this);
415 
416  for (ConstIterator it = begin (); it != end (); )
417  {
418  if (!TtlExceeded (it))
419  {
420  return DoRemove (it);
421  }
422  }
423  NS_LOG_DEBUG ("The queue is empty");
424  return 0;
425 }
426 
427 bool
429 {
430  NS_LOG_FUNCTION (this << packet);
431  for (ConstIterator it = begin (); it != end (); )
432  {
433  if (!TtlExceeded (it))
434  {
435  if ((*it)->GetPacket () == packet)
436  {
437  DoRemove (it);
438  return true;
439  }
440 
441  it++;
442  }
443  }
444  NS_LOG_DEBUG ("Packet " << packet << " not found in the queue");
445  return false;
446 }
447 
448 WifiMacQueue::ConstIterator
449 WifiMacQueue::Remove (ConstIterator pos, bool removeExpired)
450 {
451  NS_LOG_FUNCTION (this);
452 
453  if (!removeExpired)
454  {
455  ConstIterator curr = pos++;
456  DoRemove (curr);
457  return pos;
458  }
459 
460  // remove stale items queued before the given position
461  ConstIterator it = begin ();
462  while (it != end ())
463  {
464  if (it == pos)
465  {
466  // reset the flag signaling the presence of expired packets before returning
467  m_expiredPacketsPresent = false;
468 
469  ConstIterator curr = pos++;
470  DoRemove (curr);
471  return pos;
472  }
473  else if (!TtlExceeded (it))
474  {
475  it++;
476  }
477  }
478  NS_LOG_DEBUG ("Invalid iterator");
479  return end ();
480 }
481 
482 uint32_t
484 {
485  NS_LOG_FUNCTION (this << dest);
486 
487  uint32_t nPackets = 0;
488 
489  for (ConstIterator it = begin (); it != end (); )
490  {
491  if (!TtlExceeded (it))
492  {
493  if ((*it)->GetHeader ().IsData () && (*it)->GetDestinationAddress () == dest)
494  {
495  nPackets++;
496  }
497 
498  it++;
499  }
500  }
501  NS_LOG_DEBUG ("returns " << nPackets);
502  return nPackets;
503 }
504 
505 uint32_t
507 {
508  NS_LOG_FUNCTION (this << dest);
509  uint32_t nPackets = 0;
510  for (ConstIterator it = begin (); it != end (); )
511  {
512  if (!TtlExceeded (it))
513  {
514  if ((*it)->GetHeader ().IsQosData () && (*it)->GetDestinationAddress () == dest
515  && (*it)->GetHeader ().GetQosTid () == tid)
516  {
517  nPackets++;
518  }
519 
520  it++;
521  }
522  }
523  NS_LOG_DEBUG ("returns " << nPackets);
524  return nPackets;
525 }
526 
527 bool
529 {
530  NS_LOG_FUNCTION (this);
531  for (ConstIterator it = begin (); it != end (); )
532  {
533  if (!TtlExceeded (it))
534  {
535  NS_LOG_DEBUG ("returns false");
536  return false;
537  }
538  }
539  NS_LOG_DEBUG ("returns true");
540  return true;
541 }
542 
543 uint32_t
545 {
546  NS_LOG_FUNCTION (this);
547  // remove packets that stayed in the queue for too long
548  for (ConstIterator it = begin (); it != end (); )
549  {
550  if (!TtlExceeded (it))
551  {
552  it++;
553  }
554  }
555  return QueueBase::GetNPackets ();
556 }
557 
558 uint32_t
560 {
561  NS_LOG_FUNCTION (this);
562  // remove packets that stayed in the queue for too long
563  for (ConstIterator it = begin (); it != end (); )
564  {
565  if (!TtlExceeded (it))
566  {
567  it++;
568  }
569  }
570  return QueueBase::GetNBytes ();
571 }
572 
573 } //namespace ns3
Time m_maxDelay
Time to live for packets in the queue.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void SetMaxDelay(Time delay)
Set the maximum delay before the packet is discarded.
Class for representing queue sizes.
Definition: queue-size.h:94
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
NS_ASSERT_MSG(false, "Ipv4AddressGenerator::MaskToIndex(): Impossible")
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: enum.h:209
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:204
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1070
uint32_t GetNBytes(void)
Introspection did not find any typical Config paths.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
uint32_t GetNPacketsByTidAndAddress(uint8_t tid, Mac48Address dest)
Return the number of QoS packets having tid equal to tid and destination address equal to dest...
Ptr< WifiMacQueueItem > Dequeue(void)
Dequeue the packet in the front of the queue.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
ConstIterator PeekByTidAndAddress(uint8_t tid, Mac48Address dest, ConstIterator pos=EMPTY) const
Search and return, if present in the queue, the first packet having the receiver address equal to des...
uint32_t GetNBytes(void) const
Definition: queue.cc:103
Hold variables of type enum.
Definition: enum.h:54
ConstIterator PeekByAddress(Mac48Address dest, ConstIterator pos=EMPTY) const
Search and return, if present in the queue, the first packet (either Data frame or QoS Data frame) ha...
void SetMaxQueueSize(QueueSize size)
Set the maximum size of this queue.
AttributeValue implementation for Time.
Definition: nstime.h:1124
#define NS_LOG_TEMPLATE_DEFINE(name)
Initialize a reference to a Log component.
Definition: log.h:238
Ptr< WifiMacQueueItem > DequeueByAddress(Mac48Address dest)
Search and return, if present in the queue, the first packet (either Data frame or QoS Data frame) ha...
Use number of packets for queue size.
Definition: queue-size.h:44
Ptr< const WifiMacQueueItem > Peek(void) const
Peek the packet in the front of the queue.
static TypeId GetTypeId(void)
Get the type ID.
Time GetMaxDelay(void) const
Return the maximum delay before the packet is discarded.
Ptr< const AttributeAccessor > MakeQueueSizeAccessor(T1 a1)
Definition: queue-size.h:221
static const ConstIterator EMPTY
Invalid iterator to signal an empty queue.
DropPolicy m_dropPolicy
Drop behavior of queue.
uint32_t GetNPacketsByAddress(Mac48Address dest)
Return the number of packets having destination address specified by dest.
Ptr< const AttributeChecker > MakeQueueSizeChecker(void)
Definition: queue-size.cc:29
Every class exported by the ns3 library is enclosed in the ns3 namespace.
TracedCallback< Ptr< const WifiMacQueueItem > > m_traceExpired
True if expired packets are in the queue
an EUI-48 address
Definition: mac48-address.h:43
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: nstime.h:1125
Ptr< WifiMacQueueItem > DequeueFirstAvailable(const Ptr< QosBlockedDestinations > blockedPackets=nullptr)
Return first available packet for transmission.
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:193
QueueSize GetMaxQueueSize(void) const
bool Enqueue(Ptr< WifiMacQueueItem > item)
Enqueue the given Wifi MAC queue item at the end of the queue.
This queue implements the timeout procedure described in (Section 9.19.2.6 "Retransmit procedures" pa...
bool Insert(ConstIterator pos, Ptr< WifiMacQueueItem > item)
Enqueue the given Wifi MAC queue item before the given position.
Ptr< const AttributeChecker > MakeEnumChecker(int v1, std::string n1, int v2, std::string n2, int v3, std::string n3, int v4, std::string n4, int v5, std::string n5, int v6, std::string n6, int v7, std::string n7, int v8, std::string n8, int v9, std::string n9, int v10, std::string n10, int v11, std::string n11, int v12, std::string n12, int v13, std::string n13, int v14, std::string n14, int v15, std::string n15, int v16, std::string n16, int v17, std::string n17, int v18, std::string n18, int v19, std::string n19, int v20, std::string n20, int v21, std::string n21, int v22, std::string n22)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.cc:184
Ptr< WifiMacQueueItem > Remove(void)
Remove the packet in the front of the queue.
QueueSize m_maxSize
max queue size
bool PushFront(Ptr< WifiMacQueueItem > item)
Enqueue the given Wifi MAC queue item at the front of the queue.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:272
bool TtlExceeded(ConstIterator &it)
Remove the item pointed to by the iterator it if it has been in the queue for too long...
Ptr< WifiMacQueueItem > DequeueByTidAndAddress(uint8_t tid, Mac48Address dest)
Search and return, if present in the queue, the first packet having the address indicated by type equ...
#define NS_OBJECT_TEMPLATE_CLASS_DEFINE(type, param)
Explicitly instantiate a template class and register the resulting instance with the TypeId system...
Definition: object-base.h:67
ConstIterator PeekFirstAvailable(const Ptr< QosBlockedDestinations > blockedPackets=nullptr, ConstIterator pos=EMPTY) const
Return first available packet for transmission.
void SetMaxSize(QueueSize size)
Set the maximum size of this queue.
Definition: queue.cc:205
uint32_t GetNPackets(void)
uint32_t GetNPackets(void) const
Definition: queue.cc:95
a unique identifier for an interface.
Definition: type-id.h:58
ConstIterator PeekByTid(uint8_t tid, ConstIterator pos=EMPTY) const
Search and return, if present in the queue, the first packet having the tid equal to tid...
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:915
Ptr< WifiMacQueueItem > DequeueByTid(uint8_t tid)
Search and return, if present in the queue, the first packet having the tid equal to tid...