A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
20  * Author: Mirko Banchi <mk.banchi@gmail.com>
21  */
22 #include "ns3/simulator.h"
23 #include "ns3/packet.h"
24 #include "ns3/uinteger.h"
25 
26 #include "wifi-mac-queue.h"
28 
29 using namespace std;
30 
31 namespace ns3 {
32 
33 NS_OBJECT_ENSURE_REGISTERED (WifiMacQueue);
34 
35 WifiMacQueue::Item::Item (Ptr<const Packet> packet,
36  const WifiMacHeader &hdr,
37  Time tstamp)
38  : packet (packet),
39  hdr (hdr),
40  tstamp (tstamp)
41 {
42 }
43 
44 TypeId
46 {
47  static TypeId tid = TypeId ("ns3::WifiMacQueue")
48  .SetParent<Object> ()
49  .AddConstructor<WifiMacQueue> ()
50  .AddAttribute ("MaxPacketNumber", "If a packet arrives when there are already this number of packets, it is dropped.",
51  UintegerValue (400),
52  MakeUintegerAccessor (&WifiMacQueue::m_maxSize),
53  MakeUintegerChecker<uint32_t> ())
54  .AddAttribute ("MaxDelay", "If a packet stays longer than this delay in the queue, it is dropped.",
55  TimeValue (Seconds (10.0)),
56  MakeTimeAccessor (&WifiMacQueue::m_maxDelay),
57  MakeTimeChecker ())
58  ;
59  return tid;
60 }
61 
63  : m_size (0)
64 {
65 }
66 
68 {
69  Flush ();
70 }
71 
72 void
73 WifiMacQueue::SetMaxSize (uint32_t maxSize)
74 {
75  m_maxSize = maxSize;
76 }
77 
78 void
80 {
81  m_maxDelay = delay;
82 }
83 
84 uint32_t
86 {
87  return m_maxSize;
88 }
89 
90 Time
92 {
93  return m_maxDelay;
94 }
95 
96 void
98 {
99  Cleanup ();
100  if (m_size == m_maxSize)
101  {
102  return;
103  }
104  Time now = Simulator::Now ();
105  m_queue.push_back (Item (packet, hdr, now));
106  m_size++;
107 }
108 
109 void
111 {
112  if (m_queue.empty ())
113  {
114  return;
115  }
116 
117  Time now = Simulator::Now ();
118  uint32_t n = 0;
119  for (PacketQueueI i = m_queue.begin (); i != m_queue.end ();)
120  {
121  if (i->tstamp + m_maxDelay > now)
122  {
123  i++;
124  }
125  else
126  {
127  i = m_queue.erase (i);
128  n++;
129  }
130  }
131  m_size -= n;
132 }
133 
136 {
137  Cleanup ();
138  if (!m_queue.empty ())
139  {
140  Item i = m_queue.front ();
141  m_queue.pop_front ();
142  m_size--;
143  *hdr = i.hdr;
144  return i.packet;
145  }
146  return 0;
147 }
148 
151 {
152  Cleanup ();
153  if (!m_queue.empty ())
154  {
155  Item i = m_queue.front ();
156  *hdr = i.hdr;
157  return i.packet;
158  }
159  return 0;
160 }
161 
165 {
166  Cleanup ();
167  Ptr<const Packet> packet = 0;
168  if (!m_queue.empty ())
169  {
170  PacketQueueI it;
171  NS_ASSERT (type <= 4);
172  for (it = m_queue.begin (); it != m_queue.end (); ++it)
173  {
174  if (it->hdr.IsQosData ())
175  {
176  if (GetAddressForPacket (type, it) == dest
177  && it->hdr.GetQosTid () == tid)
178  {
179  packet = it->packet;
180  *hdr = it->hdr;
181  m_queue.erase (it);
182  m_size--;
183  break;
184  }
185  }
186  }
187  }
188  return packet;
189 }
190 
194 {
195  Cleanup ();
196  if (!m_queue.empty ())
197  {
198  PacketQueueI it;
199  NS_ASSERT (type <= 4);
200  for (it = m_queue.begin (); it != m_queue.end (); ++it)
201  {
202  if (it->hdr.IsQosData ())
203  {
204  if (GetAddressForPacket (type, it) == dest
205  && it->hdr.GetQosTid () == tid)
206  {
207  *hdr = it->hdr;
208  return it->packet;
209  }
210  }
211  }
212  }
213  return 0;
214 }
215 
216 bool
218 {
219  Cleanup ();
220  return m_queue.empty ();
221 }
222 
223 uint32_t
225 {
226  return m_size;
227 }
228 
229 void
231 {
232  m_queue.erase (m_queue.begin (), m_queue.end ());
233  m_size = 0;
234 }
235 
238 {
239  if (type == WifiMacHeader::ADDR1)
240  {
241  return it->hdr.GetAddr1 ();
242  }
243  if (type == WifiMacHeader::ADDR2)
244  {
245  return it->hdr.GetAddr2 ();
246  }
247  if (type == WifiMacHeader::ADDR3)
248  {
249  return it->hdr.GetAddr3 ();
250  }
251  return 0;
252 }
253 
254 bool
256 {
257  PacketQueueI it = m_queue.begin ();
258  for (; it != m_queue.end (); it++)
259  {
260  if (it->packet == packet)
261  {
262  m_queue.erase (it);
263  m_size--;
264  return true;
265  }
266  }
267  return false;
268 }
269 
270 void
272 {
273  Cleanup ();
274  if (m_size == m_maxSize)
275  {
276  return;
277  }
278  Time now = Simulator::Now ();
279  m_queue.push_front (Item (packet, hdr, now));
280  m_size++;
281 }
282 
283 uint32_t
285  Mac48Address addr)
286 {
287  Cleanup ();
288  uint32_t nPackets = 0;
289  if (!m_queue.empty ())
290  {
291  PacketQueueI it;
292  NS_ASSERT (type <= 4);
293  for (it = m_queue.begin (); it != m_queue.end (); it++)
294  {
295  if (GetAddressForPacket (type, it) == addr)
296  {
297  if (it->hdr.IsQosData () && it->hdr.GetQosTid () == tid)
298  {
299  nPackets++;
300  }
301  }
302  }
303  }
304  return nPackets;
305 }
306 
309  const QosBlockedDestinations *blockedPackets)
310 {
311  Cleanup ();
312  Ptr<const Packet> packet = 0;
313  for (PacketQueueI it = m_queue.begin (); it != m_queue.end (); it++)
314  {
315  if (!it->hdr.IsQosData ()
316  || !blockedPackets->IsBlocked (it->hdr.GetAddr1 (), it->hdr.GetQosTid ()))
317  {
318  *hdr = it->hdr;
319  timestamp = it->tstamp;
320  packet = it->packet;
321  m_queue.erase (it);
322  m_size--;
323  return packet;
324  }
325  }
326  return packet;
327 }
328 
331  const QosBlockedDestinations *blockedPackets)
332 {
333  Cleanup ();
334  for (PacketQueueI it = m_queue.begin (); it != m_queue.end (); it++)
335  {
336  if (!it->hdr.IsQosData ()
337  || !blockedPackets->IsBlocked (it->hdr.GetAddr1 (), it->hdr.GetQosTid ()))
338  {
339  *hdr = it->hdr;
340  timestamp = it->tstamp;
341  return it->packet;
342  }
343  }
344  return 0;
345 }
346 
347 } // namespace ns3