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