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 "ns3/uinteger.h"
26 #include "ns3/enum.h"
27 #include "ns3/assert.h"
28 #include "wifi-mac-queue.h"
30 
31 namespace ns3 {
32 
33 NS_LOG_COMPONENT_DEFINE ("WifiMacQueue");
34 
36  : m_packet (p),
37  m_header (header),
38  m_tstamp (Simulator::Now ())
39 {
40 }
41 
43 {
44 }
45 
48 {
49  return m_packet;
50 }
51 
52 const WifiMacHeader&
54 {
55  return m_header;
56 }
57 
60 {
61  if (type == WifiMacHeader::ADDR1)
62  {
63  return m_header.GetAddr1 ();
64  }
65  if (type == WifiMacHeader::ADDR2)
66  {
67  return m_header.GetAddr2 ();
68  }
69  if (type == WifiMacHeader::ADDR3)
70  {
71  return m_header.GetAddr3 ();
72  }
73  return 0;
74 }
75 
76 Time
78 {
79  return m_tstamp;
80 }
81 
82 uint32_t
84 {
86 }
87 
88 
91 
92 TypeId
94 {
95  static TypeId tid = TypeId ("ns3::WifiMacQueue")
97  .SetGroupName ("Wifi")
98  .AddConstructor<WifiMacQueue> ()
99  .AddAttribute ("MaxDelay", "If a packet stays longer than this delay in the queue, it is dropped.",
100  TimeValue (MilliSeconds (500.0)),
102  MakeTimeChecker ())
103  .AddAttribute ("DropPolicy", "Upon enqueue with full queue, drop oldest (DropOldest) or newest (DropNewest) packet",
107  WifiMacQueue::DROP_NEWEST, "DropNewest"))
108  ;
109  return tid;
110 }
111 
113  : NS_LOG_TEMPLATE_DEFINE ("WifiMacQueue")
114 {
115 }
116 
118 {
120 }
121 
122 void
124 {
125  NS_LOG_FUNCTION (this << delay);
126 
127  m_maxDelay = delay;
128 }
129 
130 Time
132 {
133  NS_LOG_FUNCTION (this);
134 
135  return m_maxDelay;
136 }
137 
138 bool
139 WifiMacQueue::TtlExceeded (ConstIterator &it)
140 {
141  NS_LOG_FUNCTION (this);
142 
143  if (Simulator::Now () > (*it)->GetTimeStamp () + m_maxDelay)
144  {
145  NS_LOG_DEBUG ("Removing packet that stayed in the queue for too long (" <<
146  Simulator::Now () - (*it)->GetTimeStamp () << ")");
147  auto curr = it++;
148  DoRemove (curr);
149  return true;
150  }
151  return false;
152 }
153 
154 bool
156 {
157  NS_LOG_FUNCTION (this << item);
158 
159  NS_ASSERT_MSG (GetMode () == QueueBase::QUEUE_MODE_PACKETS, "WifiMacQueues must be in packet mode");
160 
161  // if the queue is full, remove the first stale packet (if any) encountered
162  // starting from the head of the queue, in order to make room for the new packet.
163  if (QueueBase::GetNPackets () == GetMaxPackets ())
164  {
165  auto it = Head ();
166  while (it != Tail () && !TtlExceeded (it))
167  {
168  it++;
169  }
170  }
171 
172  if (QueueBase::GetNPackets () == GetMaxPackets () && m_dropPolicy == DROP_OLDEST)
173  {
174  NS_LOG_DEBUG ("Remove the oldest item in the queue");
175  DoRemove (Head ());
176  }
177 
178  return DoEnqueue (Tail (), item);
179 }
180 
181 bool
183 {
184  NS_LOG_FUNCTION (this << item);
185 
186  NS_ASSERT_MSG (GetMode () == QueueBase::QUEUE_MODE_PACKETS, "WifiMacQueues must be in packet mode");
187 
188  // if the queue is full, remove the first stale packet (if any) encountered
189  // starting from the head of the queue, in order to make room for the new packet.
190  if (QueueBase::GetNPackets () == GetMaxPackets ())
191  {
192  auto it = Head ();
193  while (it != Tail () && !TtlExceeded (it))
194  {
195  it++;
196  }
197  }
198 
199  if (QueueBase::GetNPackets () == GetMaxPackets () && m_dropPolicy == DROP_OLDEST)
200  {
201  NS_LOG_DEBUG ("Remove the oldest item in the queue");
202  DoRemove (Head ());
203  }
204 
205  return DoEnqueue (Head (), item);
206 }
207 
210 {
211  NS_LOG_FUNCTION (this);
212 
213  for (auto it = Head (); it != Tail (); )
214  {
215  if (!TtlExceeded (it))
216  {
217  return DoDequeue (it);
218  }
219  }
220  NS_LOG_DEBUG ("The queue is empty");
221  return 0;
222 }
223 
227 {
228  NS_LOG_FUNCTION (this << dest);
229 
230  for (auto it = Head (); it != Tail (); )
231  {
232  if (!TtlExceeded (it))
233  {
234  if ((*it)->GetHeader ().IsQosData () && (*it)->GetAddress (type) == dest &&
235  (*it)->GetHeader ().GetQosTid () == tid)
236  {
237  return DoDequeue (it);
238  }
239 
240  it++;
241  }
242  }
243  NS_LOG_DEBUG ("The queue is empty");
244  return 0;
245 }
246 
249 {
250  NS_LOG_FUNCTION (this);
251 
252  for (auto it = Head (); it != Tail (); )
253  {
254  if (!TtlExceeded (it))
255  {
256  if (!(*it)->GetHeader ().IsQosData ()
257  || !blockedPackets->IsBlocked ((*it)->GetHeader ().GetAddr1 (), (*it)->GetHeader ().GetQosTid ()))
258  {
259  return DoDequeue (it);
260  }
261 
262  it++;
263  }
264  }
265  NS_LOG_DEBUG ("The queue is empty");
266  return 0;
267 }
268 
270 WifiMacQueue::Peek (void) const
271 {
272  NS_LOG_FUNCTION (this);
273 
274  for (auto it = Head (); it != Tail (); it++)
275  {
276  // skip packets that stayed in the queue for too long. They will be
277  // actually removed from the queue by the next call to a non-const method
278  if (Simulator::Now () <= (*it)->GetTimeStamp () + m_maxDelay)
279  {
280  return DoPeek (it);
281  }
282  }
283  NS_LOG_DEBUG ("The queue is empty");
284  return 0;
285 }
286 
290 {
291  NS_LOG_FUNCTION (this << dest);
292 
293  for (auto it = Head (); it != Tail (); )
294  {
295  if (!TtlExceeded (it))
296  {
297  if ((*it)->GetHeader ().IsQosData () && (*it)->GetAddress (type) == dest &&
298  (*it)->GetHeader ().GetQosTid () == tid)
299  {
300  return DoPeek (it);
301  }
302 
303  it++;
304  }
305  }
306  NS_LOG_DEBUG ("The queue is empty");
307  return 0;
308 }
309 
312 {
313  NS_LOG_FUNCTION (this);
314 
315  for (auto it = Head (); it != Tail (); )
316  {
317  if (!TtlExceeded (it))
318  {
319  if (!(*it)->GetHeader ().IsQosData ()
320  || !blockedPackets->IsBlocked ((*it)->GetHeader ().GetAddr1 (), (*it)->GetHeader ().GetQosTid ()))
321  {
322  return DoPeek (it);
323  }
324 
325  it++;
326  }
327  }
328  NS_LOG_DEBUG ("The queue is empty");
329  return 0;
330 }
331 
334 {
335  NS_LOG_FUNCTION (this);
336 
337  for (auto it = Head (); it != Tail (); )
338  {
339  if (!TtlExceeded (it))
340  {
341  return DoRemove (it);
342  }
343  }
344  NS_LOG_DEBUG ("The queue is empty");
345  return 0;
346 }
347 
348 bool
350 {
351  NS_LOG_FUNCTION (this << packet);
352 
353  for (auto it = Head (); it != Tail (); )
354  {
355  if (!TtlExceeded (it))
356  {
357  if ((*it)->GetPacket () == packet)
358  {
359  DoRemove (it);
360  return true;
361  }
362 
363  it++;
364  }
365  }
366  NS_LOG_DEBUG ("Packet " << packet << " not found in the queue");
367  return false;
368 }
369 
370 uint32_t
372  Mac48Address addr)
373 {
374  NS_LOG_FUNCTION (this << addr);
375 
376  uint32_t nPackets = 0;
377 
378  for (auto it = Head (); it != Tail (); )
379  {
380  if (!TtlExceeded (it))
381  {
382  if ((*it)->GetHeader ().IsQosData () && (*it)->GetAddress (type) == addr &&
383  (*it)->GetHeader ().GetQosTid () == tid)
384  {
385  nPackets++;
386  }
387 
388  it++;
389  }
390  }
391  NS_LOG_DEBUG ("returns " << nPackets);
392  return nPackets;
393 }
394 
395 bool
397 {
398  NS_LOG_FUNCTION (this);
399 
400  for (auto it = Head (); it != Tail (); )
401  {
402  if (!TtlExceeded (it))
403  {
404  NS_LOG_DEBUG ("returns false");
405  return false;
406  }
407  }
408  NS_LOG_DEBUG ("returns true");
409  return true;
410 }
411 
412 uint32_t
414 {
415  NS_LOG_FUNCTION (this);
416 
417  // remove packets that stayed in the queue for too long
418  for (auto it = Head (); it != Tail (); )
419  {
420  if (!TtlExceeded (it))
421  {
422  it++;
423  }
424  }
425  return QueueBase::GetNPackets ();
426 }
427 
428 uint32_t
430 {
431  NS_LOG_FUNCTION (this);
432 
433  // remove packets that stayed in the queue for too long
434  for (auto it = Head (); it != Tail (); )
435  {
436  if (!TtlExceeded (it))
437  {
438  it++;
439  }
440  }
441  return QueueBase::GetNBytes ();
442 }
443 
444 } //namespace ns3
Time m_maxDelay
Time to live for packets in the queue.
Ptr< const Packet > GetPacket(void) const
Get the packet stored in this item.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Control the scheduling of simulation events.
Definition: simulator.h:68
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
Mac48Address GetAddress(enum WifiMacHeader::AddressType type) const
Return the requested address present in the header.
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.
Mac48Address GetAddr3(void) const
Return the address in the Address 3 field.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1001
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:796
uint32_t GetNPacketsByTidAndAddress(uint8_t tid, WifiMacHeader::AddressType type, Mac48Address addr)
Return the number of QoS packets having tid equal to tid and address specified by type equal to addr...
uint32_t GetNBytes(void)
Introspection did not find any typical Config paths.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Time GetTimeStamp(void) const
Get the timestamp included in this item.
Ptr< WifiMacQueueItem > Dequeue(void)
Dequeue the packet in the front of the queue.
Use number of packets for maximum queue size.
Definition: queue.h:166
Template class for packet Queues.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
Ptr< const Packet > m_packet
The packet contained in this queue item.
uint32_t GetNBytes(void) const
Definition: queue.cc:116
uint32_t GetSerializedSize(void) const
WifiMacQueueItem stores (const) packets along with their Wifi MAC headers and the time when they were...
Hold variables of type enum.
Definition: enum.h:54
Time m_tstamp
timestamp when the packet arrived at the queue
AddressType
Address types.
AttributeValue implementation for Time.
Definition: nstime.h:1055
#define NS_LOG_TEMPLATE_DEFINE(name)
Initialize a reference to a Log component.
Definition: log.h:235
Ptr< WifiMacQueueItem > DequeueByTidAndAddress(uint8_t tid, WifiMacHeader::AddressType type, Mac48Address addr)
Search and return, if present in the queue, the first packet having the address indicated by type equ...
Ptr< const WifiMacQueueItem > Peek(void) const
Peek the packet in the front of the queue.
WifiMacQueueItem()
Default constructor.
static TypeId GetTypeId(void)
Get the type ID.
WifiMacHeader m_header
Wifi MAC header associated with the packet.
Ptr< WifiMacQueueItem > DequeueFirstAvailable(const Ptr< QosBlockedDestinations > blockedPackets)
Return first available packet for transmission.
DropPolicy m_dropPolicy
Drop behavior of queue.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
const WifiMacHeader & GetHeader(void) const
Get the header stored in this item.
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:1056
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...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:90
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.
Ptr< const WifiMacQueueItem > PeekByTidAndAddress(uint8_t tid, WifiMacHeader::AddressType type, Mac48Address addr)
Search and return, if present in the queue, the first packet having the address indicated by type equ...
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:269
bool TtlExceeded(ConstIterator &it)
Remove the item pointed to by the iterator it if it has been in the queue for too long...
uint32_t GetNPackets(void) const
Definition: queue.cc:108
#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
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:365
Time GetMaxDelay(void) const
Return the maximum delay before the packet is discarded.
Mac48Address GetAddr1(void) const
Return the address in the Address 1 field.
uint32_t GetSize(void) const
Return the size of the packet included in this item.
uint32_t GetNPackets(void)
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:914
Implements the IEEE 802.11 MAC header.
Mac48Address GetAddr2(void) const
Return the address in the Address 2 field.