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 
35 NS_OBJECT_ENSURE_REGISTERED (WifiMacQueue);
36 
37 TypeId
39 {
40  static TypeId tid = TypeId ("ns3::WifiMacQueue")
42  .SetGroupName ("Wifi")
43  .AddConstructor<WifiMacQueue> ()
44  .AddAttribute ("MaxDelay", "If a packet stays longer than this delay in the queue, it is dropped.",
45  TimeValue (MilliSeconds (500)),
47  MakeTimeChecker ())
48  .AddAttribute ("DropPolicy", "Upon enqueue with full queue, drop oldest (DropOldest) or newest (DropNewest) packet",
52  WifiMacQueue::DROP_NEWEST, "DropNewest"))
53  ;
54  return tid;
55 }
56 
58  : NS_LOG_TEMPLATE_DEFINE ("WifiMacQueue")
59 {
60 }
61 
63 {
65 }
66 
67 void
69 {
70  NS_LOG_FUNCTION (this << delay);
71 
72  m_maxDelay = delay;
73 }
74 
75 Time
77 {
78  NS_LOG_FUNCTION (this);
79 
80  return m_maxDelay;
81 }
82 
83 bool
84 WifiMacQueue::TtlExceeded (ConstIterator &it)
85 {
86  NS_LOG_FUNCTION (this);
87 
88  if (Simulator::Now () > (*it)->GetTimeStamp () + m_maxDelay)
89  {
90  NS_LOG_DEBUG ("Removing packet that stayed in the queue for too long (" <<
91  Simulator::Now () - (*it)->GetTimeStamp () << ")");
92  auto curr = it++;
93  DoRemove (curr);
94  return true;
95  }
96  return false;
97 }
98 
99 bool
101 {
102  NS_LOG_FUNCTION (this << item);
103 
104  NS_ASSERT_MSG (GetMode () == QueueBase::QUEUE_MODE_PACKETS, "WifiMacQueues must be in packet mode");
105 
106  // if the queue is full, remove the first stale packet (if any) encountered
107  // starting from the head of the queue, in order to make room for the new packet.
108  if (QueueBase::GetNPackets () == GetMaxPackets ())
109  {
110  auto it = Head ();
111  while (it != Tail () && !TtlExceeded (it))
112  {
113  it++;
114  }
115  }
116 
117  if (QueueBase::GetNPackets () == GetMaxPackets () && m_dropPolicy == DROP_OLDEST)
118  {
119  NS_LOG_DEBUG ("Remove the oldest item in the queue");
120  DoRemove (Head ());
121  }
122 
123  return DoEnqueue (Tail (), item);
124 }
125 
126 bool
128 {
129  NS_LOG_FUNCTION (this << item);
130 
131  NS_ASSERT_MSG (GetMode () == QueueBase::QUEUE_MODE_PACKETS, "WifiMacQueues must be in packet mode");
132 
133  // if the queue is full, remove the first stale packet (if any) encountered
134  // starting from the head of the queue, in order to make room for the new packet.
135  if (QueueBase::GetNPackets () == GetMaxPackets ())
136  {
137  auto it = Head ();
138  while (it != Tail () && !TtlExceeded (it))
139  {
140  it++;
141  }
142  }
143 
144  if (QueueBase::GetNPackets () == GetMaxPackets () && m_dropPolicy == DROP_OLDEST)
145  {
146  NS_LOG_DEBUG ("Remove the oldest item in the queue");
147  DoRemove (Head ());
148  }
149 
150  return DoEnqueue (Head (), item);
151 }
152 
155 {
156  NS_LOG_FUNCTION (this);
157 
158  for (auto it = Head (); it != Tail (); )
159  {
160  if (!TtlExceeded (it))
161  {
162  return DoDequeue (it);
163  }
164  }
165  NS_LOG_DEBUG ("The queue is empty");
166  return 0;
167 }
168 
172 {
173  NS_LOG_FUNCTION (this << dest);
174 
175  for (auto it = Head (); it != Tail (); )
176  {
177  if (!TtlExceeded (it))
178  {
179  if ((*it)->GetHeader ().IsQosData () && (*it)->GetAddress (type) == dest
180  && (*it)->GetHeader ().GetQosTid () == tid)
181  {
182  return DoDequeue (it);
183  }
184 
185  it++;
186  }
187  }
188  NS_LOG_DEBUG ("The queue is empty");
189  return 0;
190 }
191 
194 {
195  NS_LOG_FUNCTION (this);
196 
197  for (auto it = Head (); it != Tail (); )
198  {
199  if (!TtlExceeded (it))
200  {
201  if (!(*it)->GetHeader ().IsQosData ()
202  || !blockedPackets->IsBlocked ((*it)->GetHeader ().GetAddr1 (), (*it)->GetHeader ().GetQosTid ()))
203  {
204  return DoDequeue (it);
205  }
206 
207  it++;
208  }
209  }
210  NS_LOG_DEBUG ("The queue is empty");
211  return 0;
212 }
213 
215 WifiMacQueue::Peek (void) const
216 {
217  NS_LOG_FUNCTION (this);
218 
219  for (auto it = Head (); it != Tail (); it++)
220  {
221  // skip packets that stayed in the queue for too long. They will be
222  // actually removed from the queue by the next call to a non-const method
223  if (Simulator::Now () <= (*it)->GetTimeStamp () + m_maxDelay)
224  {
225  return DoPeek (it);
226  }
227  }
228  NS_LOG_DEBUG ("The queue is empty");
229  return 0;
230 }
231 
235 {
236  NS_LOG_FUNCTION (this << dest);
237 
238  for (auto it = Head (); it != Tail (); )
239  {
240  if (!TtlExceeded (it))
241  {
242  if ((*it)->GetHeader ().IsQosData () && (*it)->GetAddress (type) == dest
243  && (*it)->GetHeader ().GetQosTid () == tid)
244  {
245  return DoPeek (it);
246  }
247 
248  it++;
249  }
250  }
251  NS_LOG_DEBUG ("The queue is empty");
252  return 0;
253 }
254 
257 {
258  NS_LOG_FUNCTION (this);
259 
260  for (auto it = Head (); it != Tail (); )
261  {
262  if (!TtlExceeded (it))
263  {
264  if (!(*it)->GetHeader ().IsQosData ()
265  || !blockedPackets->IsBlocked ((*it)->GetHeader ().GetAddr1 (), (*it)->GetHeader ().GetQosTid ()))
266  {
267  return DoPeek (it);
268  }
269 
270  it++;
271  }
272  }
273  NS_LOG_DEBUG ("The queue is empty");
274  return 0;
275 }
276 
279 {
280  NS_LOG_FUNCTION (this);
281 
282  for (auto it = Head (); it != Tail (); )
283  {
284  if (!TtlExceeded (it))
285  {
286  return DoRemove (it);
287  }
288  }
289  NS_LOG_DEBUG ("The queue is empty");
290  return 0;
291 }
292 
293 bool
295 {
296  NS_LOG_FUNCTION (this << packet);
297 
298  for (auto it = Head (); it != Tail (); )
299  {
300  if (!TtlExceeded (it))
301  {
302  if ((*it)->GetPacket () == packet)
303  {
304  DoRemove (it);
305  return true;
306  }
307 
308  it++;
309  }
310  }
311  NS_LOG_DEBUG ("Packet " << packet << " not found in the queue");
312  return false;
313 }
314 
315 uint32_t
317  Mac48Address addr)
318 {
319  NS_LOG_FUNCTION (this << addr);
320 
321  uint32_t nPackets = 0;
322 
323  for (auto it = Head (); it != Tail (); )
324  {
325  if (!TtlExceeded (it))
326  {
327  if ((*it)->GetHeader ().IsQosData () && (*it)->GetAddress (type) == addr
328  && (*it)->GetHeader ().GetQosTid () == tid)
329  {
330  nPackets++;
331  }
332 
333  it++;
334  }
335  }
336  NS_LOG_DEBUG ("returns " << nPackets);
337  return nPackets;
338 }
339 
340 bool
342 {
343  NS_LOG_FUNCTION (this);
344 
345  for (auto it = Head (); it != Tail (); )
346  {
347  if (!TtlExceeded (it))
348  {
349  NS_LOG_DEBUG ("returns false");
350  return false;
351  }
352  }
353  NS_LOG_DEBUG ("returns true");
354  return true;
355 }
356 
357 uint32_t
359 {
360  NS_LOG_FUNCTION (this);
361 
362  // remove packets that stayed in the queue for too long
363  for (auto it = Head (); it != Tail (); )
364  {
365  if (!TtlExceeded (it))
366  {
367  it++;
368  }
369  }
370  return QueueBase::GetNPackets ();
371 }
372 
373 uint32_t
375 {
376  NS_LOG_FUNCTION (this);
377 
378  // remove packets that stayed in the queue for too long
379  for (auto it = Head (); it != Tail (); )
380  {
381  if (!TtlExceeded (it))
382  {
383  it++;
384  }
385  }
386  return QueueBase::GetNBytes ();
387 }
388 
389 } //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
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:201
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1015
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.
Ptr< WifiMacQueueItem > Dequeue(void)
Dequeue the packet in the front of the queue.
Use number of packets for maximum queue size.
Definition: queue.h:174
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:129
NS_ASSERT_MSG(false,"Ipv4AddressGenerator::MaskToIndex(): Impossible")
Hold variables of type enum.
Definition: enum.h:54
AddressType
Address types.
AttributeValue implementation for Time.
Definition: nstime.h:1069
#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.
static TypeId GetTypeId(void)
Get the type ID.
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.
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:1070
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.
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:121
Time GetMaxDelay(void) const
Return the maximum delay before the packet is discarded.
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