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 
34 TypeId
36 {
37  static TypeId tid = TypeId ("ns3::WifiMacQueue")
39  .SetGroupName ("Wifi")
40  .AddConstructor<WifiMacQueue> ()
41  .AddAttribute ("MaxDelay", "If a packet stays longer than this delay in the queue, it is dropped.",
42  TimeValue (MilliSeconds (500)),
44  MakeTimeChecker ())
45  .AddAttribute ("DropPolicy", "Upon enqueue with full queue, drop oldest (DropOldest) or newest (DropNewest) packet",
49  WifiMacQueue::DROP_NEWEST, "DropNewest"))
50  ;
51  return tid;
52 }
53 
55  : NS_LOG_TEMPLATE_DEFINE ("WifiMacQueue")
56 {
57 }
58 
60 {
62 }
63 
64 void
66 {
67  NS_LOG_FUNCTION (this << delay);
68  m_maxDelay = delay;
69 }
70 
71 Time
73 {
74  return m_maxDelay;
75 }
76 
77 bool
78 WifiMacQueue::TtlExceeded (ConstIterator &it)
79 {
80  NS_LOG_FUNCTION (this);
81 
82  if (Simulator::Now () > (*it)->GetTimeStamp () + m_maxDelay)
83  {
84  NS_LOG_DEBUG ("Removing packet that stayed in the queue for too long (" <<
85  Simulator::Now () - (*it)->GetTimeStamp () << ")");
86  auto curr = it++;
87  DoRemove (curr);
88  return true;
89  }
90  return false;
91 }
92 
93 bool
95 {
96  NS_LOG_FUNCTION (this << item);
97  NS_ASSERT_MSG (GetMaxSize ().GetUnit () == QueueSizeUnit::PACKETS,
98  "WifiMacQueues must be in packet mode");
99 
100  // if the queue is full, remove the first stale packet (if any) encountered
101  // starting from the head of the queue, in order to make room for the new packet.
102  if (QueueBase::GetNPackets () == GetMaxSize ().GetValue ())
103  {
104  auto it = Head ();
105  while (it != Tail () && !TtlExceeded (it))
106  {
107  it++;
108  }
109  }
110 
111  if (QueueBase::GetNPackets () == GetMaxSize ().GetValue () && m_dropPolicy == DROP_OLDEST)
112  {
113  NS_LOG_DEBUG ("Remove the oldest item in the queue");
114  DoRemove (Head ());
115  }
116 
117  return DoEnqueue (Tail (), item);
118 }
119 
120 bool
122 {
123  NS_LOG_FUNCTION (this << item);
124  NS_ASSERT_MSG (GetMaxSize ().GetUnit () == QueueSizeUnit::PACKETS,
125  "WifiMacQueues must be in packet mode");
126 
127  // if the queue is full, remove the first stale packet (if any) encountered
128  // starting from the head of the queue, in order to make room for the new packet.
129  if (QueueBase::GetNPackets () == GetMaxSize ().GetValue ())
130  {
131  auto it = Head ();
132  while (it != Tail () && !TtlExceeded (it))
133  {
134  it++;
135  }
136  }
137 
138  if (QueueBase::GetNPackets () == GetMaxSize ().GetValue () && m_dropPolicy == DROP_OLDEST)
139  {
140  NS_LOG_DEBUG ("Remove the oldest item in the queue");
141  DoRemove (Head ());
142  }
143 
144  return DoEnqueue (Head (), item);
145 }
146 
149 {
150  NS_LOG_FUNCTION (this);
151  for (auto it = Head (); it != Tail (); )
152  {
153  if (!TtlExceeded (it))
154  {
155  return DoDequeue (it);
156  }
157  }
158  NS_LOG_DEBUG ("The queue is empty");
159  return 0;
160 }
161 
164 {
165  NS_LOG_FUNCTION (this << dest);
166 
167  for (auto it = Head (); it != Tail (); )
168  {
169  if (!TtlExceeded (it))
170  {
171  if ((*it)->GetHeader ().IsData () && (*it)->GetDestinationAddress () == dest)
172  {
173  return DoDequeue (it);
174  }
175 
176  it++;
177  }
178  }
179  NS_LOG_DEBUG ("The queue is empty");
180  return 0;
181 }
182 
185 {
186  NS_LOG_FUNCTION (this << dest);
187  for (auto it = Head (); it != Tail (); )
188  {
189  if (!TtlExceeded (it))
190  {
191  if ((*it)->GetHeader ().IsQosData () && (*it)->GetDestinationAddress () == dest
192  && (*it)->GetHeader ().GetQosTid () == tid)
193  {
194  return DoDequeue (it);
195  }
196 
197  it++;
198  }
199  }
200  NS_LOG_DEBUG ("The queue is empty");
201  return 0;
202 }
203 
206 {
207  NS_LOG_FUNCTION (this);
208  for (auto it = Head (); it != Tail (); )
209  {
210  if (!TtlExceeded (it))
211  {
212  if (!(*it)->GetHeader ().IsQosData ()
213  || !blockedPackets->IsBlocked ((*it)->GetHeader ().GetAddr1 (), (*it)->GetHeader ().GetQosTid ()))
214  {
215  return DoDequeue (it);
216  }
217 
218  it++;
219  }
220  }
221  NS_LOG_DEBUG ("The queue is empty");
222  return 0;
223 }
224 
226 WifiMacQueue::Peek (void) const
227 {
228  NS_LOG_FUNCTION (this);
229  for (auto it = Head (); it != Tail (); it++)
230  {
231  // skip packets that stayed in the queue for too long. They will be
232  // actually removed from the queue by the next call to a non-const method
233  if (Simulator::Now () <= (*it)->GetTimeStamp () + m_maxDelay)
234  {
235  return DoPeek (it);
236  }
237  }
238  NS_LOG_DEBUG ("The queue is empty");
239  return 0;
240 }
241 
244 {
245  NS_LOG_FUNCTION (this << dest);
246  for (auto it = Head (); it != Tail (); )
247  {
248  if (!TtlExceeded (it))
249  {
250  if ((*it)->GetHeader ().IsQosData () && (*it)->GetDestinationAddress () == dest
251  && (*it)->GetHeader ().GetQosTid () == tid)
252  {
253  return DoPeek (it);
254  }
255 
256  it++;
257  }
258  }
259  NS_LOG_DEBUG ("The queue is empty");
260  return 0;
261 }
262 
265 {
266  NS_LOG_FUNCTION (this);
267  for (auto it = Head (); it != Tail (); )
268  {
269  if (!TtlExceeded (it))
270  {
271  if (!(*it)->GetHeader ().IsQosData ()
272  || !blockedPackets->IsBlocked ((*it)->GetHeader ().GetAddr1 (), (*it)->GetHeader ().GetQosTid ()))
273  {
274  return DoPeek (it);
275  }
276 
277  it++;
278  }
279  }
280  NS_LOG_DEBUG ("The queue is empty");
281  return 0;
282 }
283 
286 {
287  NS_LOG_FUNCTION (this);
288 
289  for (auto it = Head (); it != Tail (); )
290  {
291  if (!TtlExceeded (it))
292  {
293  return DoRemove (it);
294  }
295  }
296  NS_LOG_DEBUG ("The queue is empty");
297  return 0;
298 }
299 
300 bool
302 {
303  NS_LOG_FUNCTION (this << packet);
304  for (auto it = Head (); it != Tail (); )
305  {
306  if (!TtlExceeded (it))
307  {
308  if ((*it)->GetPacket () == packet)
309  {
310  DoRemove (it);
311  return true;
312  }
313 
314  it++;
315  }
316  }
317  NS_LOG_DEBUG ("Packet " << packet << " not found in the queue");
318  return false;
319 }
320 
321 uint32_t
323 {
324  NS_LOG_FUNCTION (this << dest);
325 
326  uint32_t nPackets = 0;
327 
328  for (auto it = Head (); it != Tail (); )
329  {
330  if (!TtlExceeded (it))
331  {
332  if ((*it)->GetHeader ().IsData () && (*it)->GetDestinationAddress () == dest)
333  {
334  nPackets++;
335  }
336 
337  it++;
338  }
339  }
340  NS_LOG_DEBUG ("returns " << nPackets);
341  return nPackets;
342 }
343 
344 uint32_t
346 {
347  NS_LOG_FUNCTION (this << dest);
348  uint32_t nPackets = 0;
349  for (auto it = Head (); it != Tail (); )
350  {
351  if (!TtlExceeded (it))
352  {
353  if ((*it)->GetHeader ().IsQosData () && (*it)->GetDestinationAddress () == dest
354  && (*it)->GetHeader ().GetQosTid () == tid)
355  {
356  nPackets++;
357  }
358 
359  it++;
360  }
361  }
362  NS_LOG_DEBUG ("returns " << nPackets);
363  return nPackets;
364 }
365 
366 bool
368 {
369  NS_LOG_FUNCTION (this);
370  for (auto it = Head (); it != Tail (); )
371  {
372  if (!TtlExceeded (it))
373  {
374  NS_LOG_DEBUG ("returns false");
375  return false;
376  }
377  }
378  NS_LOG_DEBUG ("returns true");
379  return true;
380 }
381 
382 uint32_t
384 {
385  NS_LOG_FUNCTION (this);
386  // remove packets that stayed in the queue for too long
387  for (auto it = Head (); it != Tail (); )
388  {
389  if (!TtlExceeded (it))
390  {
391  it++;
392  }
393  }
394  return QueueBase::GetNPackets ();
395 }
396 
397 uint32_t
399 {
400  NS_LOG_FUNCTION (this);
401  // remove packets that stayed in the queue for too long
402  for (auto it = Head (); it != Tail (); )
403  {
404  if (!TtlExceeded (it))
405  {
406  it++;
407  }
408  }
409  return QueueBase::GetNBytes ();
410 }
411 
412 } //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.
#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 WifiMacQueueItem > PeekByTidAndAddress(uint8_t tid, Mac48Address dest)
Search and return, if present in the queue, the first packet having the address indicated by type equ...
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
Ptr< const WifiMacQueueItem > PeekFirstAvailable(const Ptr< QosBlockedDestinations > blockedPackets)
Return first available packet for transmission.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1022
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 AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
uint32_t GetNBytes(void) const
Definition: queue.cc:102
Hold variables of type enum.
Definition: enum.h:54
AttributeValue implementation for Time.
Definition: nstime.h:1076
#define NS_LOG_TEMPLATE_DEFINE(name)
Initialize a reference to a Log component.
Definition: log.h:236
Ptr< WifiMacQueueItem > DequeueByAddress(Mac48Address dest)
Search and return, if present in the queue, the first packet having the address indicated by type equ...
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< WifiMacQueueItem > DequeueFirstAvailable(const Ptr< QosBlockedDestinations > blockedPackets)
Return first available packet for transmission.
DropPolicy m_dropPolicy
Drop behavior of queue.
uint32_t GetNPacketsByAddress(Mac48Address dest)
Return the number of packets having destination address specified by dest.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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:1077
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:249
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...
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.
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:270
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...
uint32_t GetNPackets(void)
uint32_t GetNPackets(void) const
Definition: queue.cc:94
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:915