A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
wimax-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) 2007,2008 INRIA, UDcast
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Jahanzeb Farooq <jahanzeb.farooq@sophia.inria.fr>
19  * Mohamed Amine Ismail <Amine.Ismail@sophia.inria.fr>
20  * <Amine.Ismail@UDcast.com>
21  */
22 
23 #include "wimax-mac-queue.h"
24 #include "ns3/packet.h"
25 #include "ns3/trace-source-accessor.h"
26 #include "ns3/uinteger.h"
27 #include "ns3/simulator.h"
28 #include "ns3/log.h"
29 
30 NS_LOG_COMPONENT_DEFINE ("WimaxMacQueue");
31 
32 namespace ns3 {
33 
34 NS_OBJECT_ENSURE_REGISTERED (WimaxMacQueue)
35  ;
36 
38  : m_packet (Create<Packet> ()),
39  m_hdrType (MacHeaderType ()),
40  m_hdr (
41  GenericMacHeader ()),
42  m_timeStamp (Seconds (0)),
43  m_fragmentation (false),
44  m_fragmentNumber (0),
45  m_fragmentOffset (0)
46 {
47 }
48 
50  const MacHeaderType &hdrType,
51  const GenericMacHeader &hdr, Time timeStamp)
52  : m_packet (packet),
53  m_hdrType (hdrType),
54  m_hdr (hdr),
55  m_timeStamp (timeStamp),
56  m_fragmentation (false),
57  m_fragmentNumber (0),
58  m_fragmentOffset (0)
59 {
60 }
61 
62 uint32_t
64 {
65  uint32_t size = m_packet->GetSize () + m_hdrType.GetSerializedSize ();
66 
67  /*check because may be it is a bandwidth request packet (in which case a Bandwidth Request Header
68  has already been added to the packet) in which case Generic MAC Header will not be added to it.
69  this will only happen in the case of SS as only SS sends the bandwidth request packet. */
70  if (m_hdrType.GetType () == MacHeaderType::HEADER_TYPE_GENERIC)
71  {
72  size += m_hdr.GetSerializedSize ();
73  }
74 
75  return size;
76 }
77 
78 TypeId
80 {
81  static TypeId tid = TypeId ("ns3::WimaxMacQueue")
82  .SetParent<Object> ()
83  .AddAttribute (
84  "MaxSize",
85  "Maximum size",
86  UintegerValue (1024),
87  MakeUintegerAccessor (&WimaxMacQueue::GetMaxSize,
89  MakeUintegerChecker<uint32_t> ())
90  .AddTraceSource ("Enqueue",
91  "Enqueue trace",
93  .AddTraceSource ("Dequeue",
94  "Dequeue trace",
96  .AddTraceSource ("Drop",
97  "Drop trace",
99  ;
100  return tid;
101 }
102 
104  : m_maxSize (0),
105  m_bytes (0),
106  m_nrDataPackets (0),
108 {
109 }
110 
112  : m_maxSize (maxSize),
113  m_bytes (0),
114  m_nrDataPackets (0),
115  m_nrRequestPackets (0)
116 {
117 }
118 
120 {
121 }
122 
123 void
124 WimaxMacQueue::SetMaxSize (uint32_t maxSize)
125 {
126  m_maxSize = maxSize;
127 }
128 
129 uint32_t
131 {
132  return m_maxSize;
133 }
134 
135 bool
137  const GenericMacHeader &hdr)
138 {
139 
140  if (m_queue.size () == m_maxSize)
141  {
142 
143  m_traceDrop (packet);
144  return false;
145  }
146 
147  m_traceEnqueue (packet);
148  QueueElement element (packet, hdrType, hdr, Simulator::Now ());
149  m_queue.push_back (element);
150 
152  {
153  m_nrDataPackets++;
154  }
155  else
156  {
158  }
159 
160  m_bytes += element.GetSize ();
161  return true;
162 }
163 
166 {
167  if (!IsEmpty ())
168  {
169  QueueElement element = Front (packetType);
170  Pop (packetType);
171 
173  {
174  NS_LOG_INFO ("Enqueued Packet IS A data packet");
176  "Can not enqueue more packets: no space left in the queue");
177  m_nrDataPackets--;
178  }
179  else
180  {
181  NS_LOG_INFO ("Enqueued Packet IS A Request BW packet");
183  "Can not enqueue more packets: no space left in the queue");
185  }
186 
187  Ptr<Packet> packet = element.m_packet;
188 
189  if (!element.m_fragmentation)
190  {
191  NS_LOG_INFO ("FRAG_DEBUG: Enqueued Packet IS NOT a fragment" << std::endl);
192  /*check because may be it is a bandwidth request packet (in which case a Bandwidth Request Header
193  has already been added to the packet) in which case Generic MAC Header will not be added to it.
194  this will only happen in the case of SS as only SS sends the bandwidth request packet. */
195  m_bytes -= element.GetSize ();
197  {
198  packet->AddHeader (element.m_hdr);
199  }
200  packet->AddHeader (element.m_hdrType);
201 
202  m_traceDequeue (packet);
203  return packet;
204  }
205  else
206  {
207  /*
208  The enqueued packet is a fragment (the latest fragment)
209  We must modify type field of the m_hdr and add a fragmentation Subhdr
210  */
211  NS_LOG_INFO ("\t Enqueued Packet IS a fragment, add subhdr" << std::endl);
212 
213  // Create a fragment
214  uint32_t fragmentOffset = element.m_fragmentOffset;
215  uint32_t fragmentSize = element.m_packet->GetSize () - fragmentOffset;
216 
217  NS_LOG_INFO ("\t Create a fragment"
218  "\n\t\t fragmentOffset=" << fragmentOffset <<
219  "\n\t\t packetSize=" << element.m_packet->GetSize () <<
220  "\n\t\t fragmentSize=" << fragmentSize << std::endl);
221 
222  Ptr<Packet> fragment = packet->CreateFragment (fragmentOffset,fragmentSize);
223 
224  FragmentationSubheader fragmentSubhdr;
225  NS_LOG_INFO ("\t Latest Fragment" << std::endl);
226  fragmentSubhdr.SetFc (2); // This is the latest fragment
227  fragmentSubhdr.SetFsn (element.m_fragmentNumber);
228 
229  NS_LOG_INFO ("\t FragmentSize=" << fragment->GetSize () << std::endl);
230  fragment->AddHeader (fragmentSubhdr);
231 
232  /*check because may be it is a bandwidth request packet (in which case a Bandwidth Request Header
233  has already been added to the packet) in which case Generic MAC Header will not be added to it.
234  this will only happen in the case of SS as only SS sends the bandwidth request packet. */
236  {
237  uint8_t tmpType = element.m_hdr.GetType ();
238  tmpType |= 4;
239  element.m_hdr.SetType (tmpType);
240 
241  uint32_t length = fragmentSize + element.m_hdr.GetSerializedSize ()
242  + fragmentSubhdr.GetSerializedSize ();
243  element.m_hdr.SetLen ((uint16_t)length);
244 
245  fragment->AddHeader (element.m_hdr);
246  }
247  fragment->AddHeader (element.m_hdrType);
248  m_bytes -= fragmentSize;
249 
250  m_traceDequeue (fragment);
251  return fragment;
252  }
253  }
254  return 0;
255 }
256 
258 WimaxMacQueue::Dequeue (MacHeaderType::HeaderType packetType, uint32_t availableByte)
259 {
260  if (!IsEmpty ())
261  {
262  NS_LOG_INFO ("FRAG_DEBUG: Dequeue function" << std::endl);
263  QueueElement element = Front (packetType);
264 
265  uint32_t headerSize = 2 + element.m_hdr.GetSerializedSize () +
266  element.m_hdrType.GetSerializedSize ();
267 
268  // Create a fragment
269  uint32_t maxFragmentSize = availableByte - headerSize;
270  uint32_t fragmentOffset = element.m_fragmentOffset; // It is the latest byte sent.
271 
272  Ptr<Packet> packet = element.m_packet->Copy ();
273  NS_LOG_INFO ("\t Create a fragment"
274  "\n\t\t availableByte=" << availableByte <<
275  "\n\t\t headerSize=" << headerSize <<
276  "\n\t\t maxFragmentSize=" << maxFragmentSize << ""
277  "\n\t\t fragmentOffset=" << fragmentOffset <<
278  "\n\t\t payloadSize=" << packet->GetSize ()
279  << std::endl);
280  Ptr<Packet> fragment = packet->CreateFragment (fragmentOffset,
281  maxFragmentSize);
282  m_bytes -= maxFragmentSize;
283 
284  FragmentationSubheader fragmentSubhdr;
285  if (!element.m_fragmentation)
286  {
287  NS_LOG_INFO ("\t First Fragment" << std::endl);
288  SetFragmentation (packetType);
289  fragmentSubhdr.SetFc (1);
290  }
291  else
292  {
293  NS_LOG_INFO ("\t Middle Fragment" << std::endl);
294  fragmentSubhdr.SetFc (3);
295  }
296  fragmentSubhdr.SetFsn (element.m_fragmentNumber);
297  NS_LOG_INFO ("\t FragmentSize=" << fragment->GetSize () << std::endl);
298  fragment->AddHeader (fragmentSubhdr);
299 
300  SetFragmentNumber (packetType);
301  SetFragmentOffset (packetType, maxFragmentSize);
302 
303  /*check because may be it is a bandwidth request packet (in which case a Bandwidth Request Header
304  has already been added to the packet) in which case Generic MAC Header will not be added to it.
305  this will only happen in the case of SS as only SS sends the bandwidth request packet. */
307  {
308  uint8_t tmpType = element.m_hdr.GetType ();
309  tmpType |= 4;
310  element.m_hdr.SetType (tmpType);
311 
312  uint32_t length = maxFragmentSize + element.m_hdr.GetSerializedSize ()
313  + fragmentSubhdr.GetSerializedSize ();
314  element.m_hdr.SetLen ((uint16_t)length);
315 
316  fragment->AddHeader (element.m_hdr);
317  }
318  fragment->AddHeader (element.m_hdrType);
319 
320  m_traceDequeue (fragment);
321  return fragment;
322  }
323  return 0;
324 }
325 
328 {
329  if (!IsEmpty ())
330  {
331  QueueElement element = m_queue.front ();
332  hdr = element.m_hdr;
333  Ptr<Packet> packet = element.m_packet->Copy ();
334 
335  // this function must not be used by SS as it may be then a bandwidth request header
336  packet->AddHeader (element.m_hdr);
337  return packet;
338  }
339 
340  return 0;
341 }
342 
344 WimaxMacQueue::Peek (GenericMacHeader &hdr, Time &timeStamp) const
345 {
346  if (!IsEmpty ())
347  {
348  QueueElement element = m_queue.front ();
349  hdr = element.m_hdr;
350  timeStamp = element.m_timeStamp;
351  Ptr<Packet> packet = element.m_packet->Copy ();
352 
353  // this function must not be used for by SS as it may be then a bandwidth request header
354  packet->AddHeader (element.m_hdr);
355  return packet;
356  }
357 
358  return 0;
359 }
360 
363 {
364  if (!IsEmpty ())
365  {
366  QueueElement element = Front (packetType);
367  Ptr<Packet> packet = element.m_packet->Copy ();
368 
369  /*check because may be it is a bandwidth request packet (in which case a Bandwidth Request Header
370  has already been added to the packet) in which case Generic MAC Header will not be added to it.
371  this will only happen in the case of SS as only SS sends the bandwidth request packet. */
373  {
374  packet->AddHeader (element.m_hdr);
375  }
376  return packet;
377  }
378 
379  return 0;
380 }
381 
384  Time &timeStamp) const
385 {
386  if (!IsEmpty ())
387  {
388  QueueElement element = Front (packetType);
389  timeStamp = element.m_timeStamp;
390  Ptr<Packet> packet = element.m_packet->Copy ();
391 
392  /*check because may be it is a bandwidth request packet (in which case a Bandwidth Request Header
393  has already been added to the packet) in which case Generic MAC Header will not be added to it.
394  this will only happen in the case of SS as only SS sends the bandwidth request packet. */
396  {
397  packet->AddHeader (element.m_hdr);
398  }
399  return packet;
400  }
401 
402  return 0;
403 }
404 
405 uint32_t
407 {
408  return m_queue.size ();
409 }
410 
411 uint32_t
413 {
414  return m_bytes;
415 }
416 
418 {
419  uint32_t queueSize = GetNBytes ();
420  // Add MAC Overhead
421  queueSize += GetSize () * 6;
423  if (CheckForFragmentation (packetType))
424  {
425  queueSize += 2;
426  }
427  return queueSize;
428 }
429 
432 {
433  QueueElement element;
434 
435  for (std::deque<QueueElement>::const_iterator iter = m_queue.begin (); iter
436  != m_queue.end (); ++iter)
437  {
438  element = *iter;
439  if (element.m_hdrType.GetType () == packetType)
440  {
441  break;
442  }
443  }
444 
445  return element;
446 }
447 
448 void
450 {
451  QueueElement element;
452 
453  for (std::deque<QueueElement>::iterator iter = m_queue.begin (); iter
454  != m_queue.end (); ++iter)
455  {
456  element = *iter;
457  if (element.m_hdrType.GetType () == packetType)
458  {
459  m_queue.erase (iter);
460  break;
461  }
462  }
463 }
464 
465 bool
467 {
468  return m_queue.empty ();
469 }
470 
471 bool
473 {
474  if (packetType == MacHeaderType::HEADER_TYPE_GENERIC)
475  {
476  return m_nrDataPackets == 0;
477  }
478  else
479  {
480  return m_nrRequestPackets == 0;
481  }
482 
483  return true;
484 }
485 
488 {
489  return m_queue;
490 }
491 
492 bool
494 {
495  QueueElement element;
496  for (std::deque<QueueElement>::const_iterator iter = m_queue.begin (); iter
497  != m_queue.end (); ++iter)
498  {
499  element = *iter;
500  if (element.m_hdrType.GetType () == packetType)
501  {
502  break;
503  }
504  }
505 
506  if (element.m_fragmentation)
507  {
508  NS_LOG_INFO ("FRAG_DEBUG: CheckForFragmentation"
509  "\n\t\t m_fragmentation is true " << std::endl);
510  }
511 
512  return element.m_fragmentation;
513 }
514 
515 uint32_t
517 {
518  QueueElement element;
519  for (std::deque<QueueElement>::const_iterator iter = m_queue.begin (); iter
520  != m_queue.end (); ++iter)
521  {
522  element = *iter;
523  if (element.m_hdrType.GetType () == packetType)
524  {
525  break;
526  }
527  }
528 
529  NS_LOG_INFO ("\t\t GetFirstPacketHdrSize ()");
530 
531  uint32_t hdrSize = 0;
533  {
534  hdrSize += element.m_hdr.GetSerializedSize ();
535  NS_LOG_INFO ("\t\t\t m_hdr.GetSerializedSize=" <<
536  element.m_hdr.GetSerializedSize ());
537  }
538 
539  hdrSize += element.m_hdrType.GetSerializedSize ();
540  NS_LOG_INFO ("\t\t\t m_hdrType.GetSerializedSize=" <<
541  element.m_hdrType.GetSerializedSize ());
542 
543  if (CheckForFragmentation (packetType))
544  {
545  NS_LOG_INFO ("\t\t\t fragSubhdrSize=2");
546  hdrSize += 2;
547  }
548 
549  NS_LOG_INFO ("\t\t hdrSize=" << hdrSize);
550 
551  return hdrSize;
552 }
553 
554 uint32_t
556 {
557  QueueElement element;
558  for (std::deque<QueueElement>::const_iterator iter = m_queue.begin (); iter
559  != m_queue.end (); ++iter)
560  {
561  element = *iter;
562  if (element.m_hdrType.GetType () == packetType)
563  {
564  break;
565  }
566  }
567 
568  NS_LOG_INFO ("\t\t GetFirstPacketPayloadSize ()");
569 
570  if (CheckForFragmentation (packetType))
571  {
572  NS_LOG_INFO ("\t\t\t fullPayloadSize=" << element.m_packet->GetSize ()
573  << "\n\t\t\t fragmentOffset=" << element.m_fragmentOffset
574  << "\n\t\t\t (fragment)payloadSize=" <<
575  element.m_packet->GetSize () - element.m_fragmentOffset);
576 
577  return element.m_packet->GetSize () - element.m_fragmentOffset;
578  }
579  NS_LOG_INFO ("\t\t payloadSize=" <<
580  element.m_packet->GetSize ());
581 
582  return element.m_packet->GetSize ();
583 }
584 
585 uint32_t
587 {
588  NS_LOG_INFO ("\t GetFirstPacketRequiredByte ()");
589 
590  uint32_t requiredByte = GetFirstPacketPayloadSize (packetType) +
591  GetFirstPacketHdrSize (packetType);
592 
593  NS_LOG_INFO ("\t Required Bytes = " << requiredByte << std::endl);
594 
595  return requiredByte;
596 }
597 
598 void
600 {
601  for (std::deque<QueueElement>::iterator iter = m_queue.begin (); iter
602  != m_queue.end (); ++iter)
603  {
604  if (iter->m_hdrType.GetType () == packetType)
605  {
606  iter->SetFragmentation ();
607  break;
608  }
609  }
610 }
611 
612 void
614 {
615  for (std::deque<QueueElement>::iterator iter = m_queue.begin (); iter
616  != m_queue.end (); ++iter)
617  {
618  if (iter->m_hdrType.GetType () == packetType)
619  {
620  iter->SetFragmentNumber ();
621  break;
622  }
623  }
624 }
625 
626 void
628 {
629  for (std::deque<QueueElement>::iterator iter = m_queue.begin (); iter
630  != m_queue.end (); ++iter)
631  {
632  if (iter->m_hdrType.GetType () == packetType)
633  {
634  iter->SetFragmentOffset (offset);
635  break;
636  }
637  }
638 }
639 
640 void
642 {
643  m_fragmentation = true;
644 }
645 
646 void
648 {
649  m_fragmentNumber++;
650 }
651 
652 void
654 {
655  m_fragmentOffset += offset;
656 }
657 } // namespace ns3
HeaderType
this class implements the mac header type field.
uint32_t GetFirstPacketHdrSize(MacHeaderType::HeaderType packetType)
void SetFragmentOffset(MacHeaderType::HeaderType packetType, uint32_t offset)
keep track of time values and allow control of global simulation resolution
Definition: nstime.h:81
TracedCallback< Ptr< const Packet > > m_traceDrop
std::deque< QueueElement > PacketQueue
void SetType(uint8_t type)
TracedCallback< Ptr< const Packet > > m_traceDequeue
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
uint32_t GetNBytes(void) const
uint32_t GetSize(void) const
Definition: packet.h:650
Ptr< Packet > Peek(GenericMacHeader &hdr) const
Same as Dequeue but does not pop from queue.
NS_LOG_COMPONENT_DEFINE("WimaxMacQueue")
#define NS_LOG_INFO(msg)
Definition: log.h:298
network packets
Definition: packet.h:203
void SetFragmentOffset(uint32_t offset)
this class implements the Generic mac Header as described by IEEE Standard for Local and metropolitan...
uint8_t GetType(void) const
uint32_t GetSerializedSize(void) const
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
Definition: packet.cc:228
uint32_t GetSize(void) const
uint32_t GetSerializedSize(void) const
Ptr< T > Create(void)
Definition: ptr.h:231
Hold an unsigned integer type.
Definition: uinteger.h:46
TracedCallback< Ptr< const Packet > > m_traceEnqueue
uint32_t GetQueueLengthWithMACOverhead(void)
bool CheckForFragmentation(MacHeaderType::HeaderType packetType)
Fragmentation utilities.
bool Enqueue(Ptr< Packet > packet, const MacHeaderType &hdrType, const GenericMacHeader &hdr)
Enqueue a packet.
uint32_t GetFirstPacketRequiredByte(MacHeaderType::HeaderType packetType)
Represents the HT (Header Type) field of generic MAC and bandwidth request headers.
Ptr< Packet > Copy(void) const
Definition: packet.cc:122
bool IsEmpty(void) const
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
WimaxMacQueue::QueueElement Front(MacHeaderType::HeaderType packetType) const
void SetFragmentation(MacHeaderType::HeaderType packetType)
uint32_t GetSerializedSize(void) const
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
uint32_t GetMaxSize(void) const
this class implements the fragmentation sub-header as described by IEEE Standard for Local and metrop...
void SetMaxSize(uint32_t maxSize)
set the maximum queue size
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
const WimaxMacQueue::PacketQueue & GetPacketQueue(void) const
uint8_t GetType(void) const
static TypeId GetTypeId(void)
void Pop(MacHeaderType::HeaderType packetType)
void SetFragmentNumber(MacHeaderType::HeaderType packetType)
a base class which provides memory management and object aggregation
Definition: object.h:63
Ptr< Packet > Dequeue(MacHeaderType::HeaderType packetType)
Dequeue a packet of type packetType from the queue.
uint32_t GetFirstPacketPayloadSize(MacHeaderType::HeaderType packetType)
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:253
void SetLen(uint16_t len)