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 
37  : m_packet (Create<Packet> ()),
38  m_hdrType (MacHeaderType ()),
39  m_hdr (
40  GenericMacHeader ()),
41  m_timeStamp (Seconds (0)),
42  m_fragmentation (false),
43  m_fragmentNumber (0),
44  m_fragmentOffset (0)
45 {
46 }
47 
49  const MacHeaderType &hdrType,
50  const GenericMacHeader &hdr, Time timeStamp)
51  : m_packet (packet),
52  m_hdrType (hdrType),
53  m_hdr (hdr),
54  m_timeStamp (timeStamp),
55  m_fragmentation (false),
56  m_fragmentNumber (0),
57  m_fragmentOffset (0)
58 {
59 }
60 
61 uint32_t
63 {
64  uint32_t size = m_packet->GetSize () + m_hdrType.GetSerializedSize ();
65 
66  /*check because may be it is a bandwidth request packet (in which case a Bandwidth Request Header
67  has already been added to the packet) in which case Generic MAC Header will not be added to it.
68  this will only happen in the case of SS as only SS sends the bandwidth request packet. */
69  if (m_hdrType.GetType () == MacHeaderType::HEADER_TYPE_GENERIC)
70  {
71  size += m_hdr.GetSerializedSize ();
72  }
73 
74  return size;
75 }
76 
77 TypeId
79 {
80  static TypeId tid = TypeId ("ns3::WimaxMacQueue")
81  .SetParent<Object> ()
82  .AddAttribute (
83  "MaxSize",
84  "Maximum size",
85  UintegerValue (1024),
86  MakeUintegerAccessor (&WimaxMacQueue::GetMaxSize,
88  MakeUintegerChecker<uint32_t> ())
89  .AddTraceSource ("Enqueue",
90  "Enqueue trace",
92  .AddTraceSource ("Dequeue",
93  "Dequeue trace",
95  .AddTraceSource ("Drop",
96  "Drop trace",
98  ;
99  return tid;
100 }
101 
103  : m_maxSize (0),
104  m_bytes (0),
105  m_nrDataPackets (0),
107 {
108 }
109 
111  : m_maxSize (maxSize),
112  m_bytes (0),
113  m_nrDataPackets (0),
114  m_nrRequestPackets (0)
115 {
116 }
117 
119 {
120 }
121 
122 void
123 WimaxMacQueue::SetMaxSize (uint32_t maxSize)
124 {
125  m_maxSize = maxSize;
126 }
127 
128 uint32_t
130 {
131  return m_maxSize;
132 }
133 
134 bool
136  const GenericMacHeader &hdr)
137 {
138 
139  if (m_queue.size () == m_maxSize)
140  {
141 
142  m_traceDrop (packet);
143  return false;
144  }
145 
146  m_traceEnqueue (packet);
147  QueueElement element (packet, hdrType, hdr, Simulator::Now ());
148  m_queue.push_back (element);
149 
151  {
152  m_nrDataPackets++;
153  }
154  else
155  {
157  }
158 
159  m_bytes += element.GetSize ();
160  return true;
161 }
162 
165 {
166  if (!IsEmpty ())
167  {
168  QueueElement element = Front (packetType);
169  Pop (packetType);
170 
172  {
173  NS_LOG_INFO ("Enqueued Packet IS A data packet");
175  "Can not enqueue more packets: no space left in the queue");
176  m_nrDataPackets--;
177  }
178  else
179  {
180  NS_LOG_INFO ("Enqueued Packet IS A Request BW packet");
182  "Can not enqueue more packets: no space left in the queue");
184  }
185 
186  Ptr<Packet> packet = element.m_packet;
187 
188  if (!element.m_fragmentation)
189  {
190  NS_LOG_INFO ("FRAG_DEBUG: Enqueued Packet IS NOT a fragment" << std::endl);
191  /*check because may be it is a bandwidth request packet (in which case a Bandwidth Request Header
192  has already been added to the packet) in which case Generic MAC Header will not be added to it.
193  this will only happen in the case of SS as only SS sends the bandwidth request packet. */
194  m_bytes -= element.GetSize ();
196  {
197  packet->AddHeader (element.m_hdr);
198  }
199  packet->AddHeader (element.m_hdrType);
200 
201  m_traceDequeue (packet);
202  return packet;
203  }
204  else
205  {
206  /*
207  The enqueued packet is a fragment (the latest fragment)
208  We must modify type field of the m_hdr and add a fragmentation Subhdr
209  */
210  NS_LOG_INFO ("\t Enqueued Packet IS a fragment, add subhdr" << std::endl);
211 
212  // Create a fragment
213  uint32_t fragmentOffset = element.m_fragmentOffset;
214  uint32_t fragmentSize = element.m_packet->GetSize () - fragmentOffset;
215 
216  NS_LOG_INFO ("\t Create a fragment"
217  "\n\t\t fragmentOffset=" << fragmentOffset <<
218  "\n\t\t packetSize=" << element.m_packet->GetSize () <<
219  "\n\t\t fragmentSize=" << fragmentSize << std::endl);
220 
221  Ptr<Packet> fragment = packet->CreateFragment (fragmentOffset,fragmentSize);
222 
223  FragmentationSubheader fragmentSubhdr;
224  NS_LOG_INFO ("\t Latest Fragment" << std::endl);
225  fragmentSubhdr.SetFc (2); // This is the latest fragment
226  fragmentSubhdr.SetFsn (element.m_fragmentNumber);
227 
228  NS_LOG_INFO ("\t FragmentSize=" << fragment->GetSize () << std::endl);
229  fragment->AddHeader (fragmentSubhdr);
230 
231  /*check because may be it is a bandwidth request packet (in which case a Bandwidth Request Header
232  has already been added to the packet) in which case Generic MAC Header will not be added to it.
233  this will only happen in the case of SS as only SS sends the bandwidth request packet. */
235  {
236  uint8_t tmpType = element.m_hdr.GetType ();
237  tmpType |= 4;
238  element.m_hdr.SetType (tmpType);
239 
240  uint32_t length = fragmentSize + element.m_hdr.GetSerializedSize ()
241  + fragmentSubhdr.GetSerializedSize ();
242  element.m_hdr.SetLen ((uint16_t)length);
243 
244  fragment->AddHeader (element.m_hdr);
245  }
246  fragment->AddHeader (element.m_hdrType);
247  m_bytes -= fragmentSize;
248 
249  m_traceDequeue (fragment);
250  return fragment;
251  }
252  }
253  return 0;
254 }
255 
257 WimaxMacQueue::Dequeue (MacHeaderType::HeaderType packetType, uint32_t availableByte)
258 {
259  if (!IsEmpty ())
260  {
261  NS_LOG_INFO ("FRAG_DEBUG: Dequeue function" << std::endl);
262  QueueElement element = Front (packetType);
263 
264  uint32_t headerSize = 2 + element.m_hdr.GetSerializedSize () +
265  element.m_hdrType.GetSerializedSize ();
266 
267  // Create a fragment
268  uint32_t maxFragmentSize = availableByte - headerSize;
269  uint32_t fragmentOffset = element.m_fragmentOffset; // It is the latest byte sent.
270 
271  Ptr<Packet> packet = element.m_packet->Copy ();
272  NS_LOG_INFO ("\t Create a fragment"
273  "\n\t\t availableByte=" << availableByte <<
274  "\n\t\t headerSize=" << headerSize <<
275  "\n\t\t maxFragmentSize=" << maxFragmentSize << ""
276  "\n\t\t fragmentOffset=" << fragmentOffset <<
277  "\n\t\t payloadSize=" << packet->GetSize ()
278  << std::endl);
279  Ptr<Packet> fragment = packet->CreateFragment (fragmentOffset,
280  maxFragmentSize);
281  m_bytes -= maxFragmentSize;
282 
283  FragmentationSubheader fragmentSubhdr;
284  if (!element.m_fragmentation)
285  {
286  NS_LOG_INFO ("\t First Fragment" << std::endl);
287  SetFragmentation (packetType);
288  fragmentSubhdr.SetFc (1);
289  }
290  else
291  {
292  NS_LOG_INFO ("\t Middle Fragment" << std::endl);
293  fragmentSubhdr.SetFc (3);
294  }
295  fragmentSubhdr.SetFsn (element.m_fragmentNumber);
296  NS_LOG_INFO ("\t FragmentSize=" << fragment->GetSize () << std::endl);
297  fragment->AddHeader (fragmentSubhdr);
298 
299  SetFragmentNumber (packetType);
300  SetFragmentOffset (packetType, maxFragmentSize);
301 
302  /*check because may be it is a bandwidth request packet (in which case a Bandwidth Request Header
303  has already been added to the packet) in which case Generic MAC Header will not be added to it.
304  this will only happen in the case of SS as only SS sends the bandwidth request packet. */
306  {
307  uint8_t tmpType = element.m_hdr.GetType ();
308  tmpType |= 4;
309  element.m_hdr.SetType (tmpType);
310 
311  uint32_t length = maxFragmentSize + element.m_hdr.GetSerializedSize ()
312  + fragmentSubhdr.GetSerializedSize ();
313  element.m_hdr.SetLen ((uint16_t)length);
314 
315  fragment->AddHeader (element.m_hdr);
316  }
317  fragment->AddHeader (element.m_hdrType);
318 
319  m_traceDequeue (fragment);
320  return fragment;
321  }
322  return 0;
323 }
324 
327 {
328  if (!IsEmpty ())
329  {
330  QueueElement element = m_queue.front ();
331  hdr = element.m_hdr;
332  Ptr<Packet> packet = element.m_packet->Copy ();
333 
334  // this function must not be used by SS as it may be then a bandwidth request header
335  packet->AddHeader (element.m_hdr);
336  return packet;
337  }
338 
339  return 0;
340 }
341 
343 WimaxMacQueue::Peek (GenericMacHeader &hdr, Time &timeStamp) const
344 {
345  if (!IsEmpty ())
346  {
347  QueueElement element = m_queue.front ();
348  hdr = element.m_hdr;
349  timeStamp = element.m_timeStamp;
350  Ptr<Packet> packet = element.m_packet->Copy ();
351 
352  // this function must not be used for by SS as it may be then a bandwidth request header
353  packet->AddHeader (element.m_hdr);
354  return packet;
355  }
356 
357  return 0;
358 }
359 
362 {
363  if (!IsEmpty ())
364  {
365  QueueElement element = Front (packetType);
366  Ptr<Packet> packet = element.m_packet->Copy ();
367 
368  /*check because may be it is a bandwidth request packet (in which case a Bandwidth Request Header
369  has already been added to the packet) in which case Generic MAC Header will not be added to it.
370  this will only happen in the case of SS as only SS sends the bandwidth request packet. */
372  {
373  packet->AddHeader (element.m_hdr);
374  }
375  return packet;
376  }
377 
378  return 0;
379 }
380 
383  Time &timeStamp) const
384 {
385  if (!IsEmpty ())
386  {
387  QueueElement element = Front (packetType);
388  timeStamp = element.m_timeStamp;
389  Ptr<Packet> packet = element.m_packet->Copy ();
390 
391  /*check because may be it is a bandwidth request packet (in which case a Bandwidth Request Header
392  has already been added to the packet) in which case Generic MAC Header will not be added to it.
393  this will only happen in the case of SS as only SS sends the bandwidth request packet. */
395  {
396  packet->AddHeader (element.m_hdr);
397  }
398  return packet;
399  }
400 
401  return 0;
402 }
403 
404 uint32_t
406 {
407  return m_queue.size ();
408 }
409 
410 uint32_t
412 {
413  return m_bytes;
414 }
415 
417 {
418  uint32_t queueSize = GetNBytes ();
419  // Add MAC Overhead
420  queueSize += GetSize () * 6;
422  if (CheckForFragmentation (packetType))
423  {
424  queueSize += 2;
425  }
426  return queueSize;
427 }
428 
431 {
432  QueueElement element;
433 
434  for (std::deque<QueueElement>::const_iterator iter = m_queue.begin (); iter
435  != m_queue.end (); ++iter)
436  {
437  element = *iter;
438  if (element.m_hdrType.GetType () == packetType)
439  {
440  break;
441  }
442  }
443 
444  return element;
445 }
446 
447 void
449 {
450  QueueElement element;
451 
452  for (std::deque<QueueElement>::iterator iter = m_queue.begin (); iter
453  != m_queue.end (); ++iter)
454  {
455  element = *iter;
456  if (element.m_hdrType.GetType () == packetType)
457  {
458  m_queue.erase (iter);
459  break;
460  }
461  }
462 }
463 
464 bool
466 {
467  return m_queue.empty ();
468 }
469 
470 bool
472 {
473  if (packetType == MacHeaderType::HEADER_TYPE_GENERIC)
474  {
475  return m_nrDataPackets == 0;
476  }
477  else
478  {
479  return m_nrRequestPackets == 0;
480  }
481 
482  return true;
483 }
484 
487 {
488  return m_queue;
489 }
490 
491 bool
493 {
494  QueueElement element;
495  for (std::deque<QueueElement>::const_iterator iter = m_queue.begin (); iter
496  != m_queue.end (); ++iter)
497  {
498  element = *iter;
499  if (element.m_hdrType.GetType () == packetType)
500  {
501  break;
502  }
503  }
504 
505  if (element.m_fragmentation)
506  {
507  NS_LOG_INFO ("FRAG_DEBUG: CheckForFragmentation"
508  "\n\t\t m_fragmentation is true " << std::endl);
509  }
510 
511  return element.m_fragmentation;
512 }
513 
514 uint32_t
516 {
517  QueueElement element;
518  for (std::deque<QueueElement>::const_iterator iter = m_queue.begin (); iter
519  != m_queue.end (); ++iter)
520  {
521  element = *iter;
522  if (element.m_hdrType.GetType () == packetType)
523  {
524  break;
525  }
526  }
527 
528  NS_LOG_INFO ("\t\t GetFirstPacketHdrSize ()");
529 
530  uint32_t hdrSize = 0;
532  {
533  hdrSize += element.m_hdr.GetSerializedSize ();
534  NS_LOG_INFO ("\t\t\t m_hdr.GetSerializedSize=" <<
535  element.m_hdr.GetSerializedSize ());
536  }
537 
538  hdrSize += element.m_hdrType.GetSerializedSize ();
539  NS_LOG_INFO ("\t\t\t m_hdrType.GetSerializedSize=" <<
540  element.m_hdrType.GetSerializedSize ());
541 
542  if (CheckForFragmentation (packetType))
543  {
544  NS_LOG_INFO ("\t\t\t fragSubhdrSize=2");
545  hdrSize += 2;
546  }
547 
548  NS_LOG_INFO ("\t\t hdrSize=" << hdrSize);
549 
550  return hdrSize;
551 }
552 
553 uint32_t
555 {
556  QueueElement element;
557  for (std::deque<QueueElement>::const_iterator iter = m_queue.begin (); iter
558  != m_queue.end (); ++iter)
559  {
560  element = *iter;
561  if (element.m_hdrType.GetType () == packetType)
562  {
563  break;
564  }
565  }
566 
567  NS_LOG_INFO ("\t\t GetFirstPacketPayloadSize ()");
568 
569  if (CheckForFragmentation (packetType))
570  {
571  NS_LOG_INFO ("\t\t\t fullPayloadSize=" << element.m_packet->GetSize ()
572  << "\n\t\t\t fragmentOffset=" << element.m_fragmentOffset
573  << "\n\t\t\t (fragment)payloadSize=" <<
574  element.m_packet->GetSize () - element.m_fragmentOffset);
575 
576  return element.m_packet->GetSize () - element.m_fragmentOffset;
577  }
578  NS_LOG_INFO ("\t\t payloadSize=" <<
579  element.m_packet->GetSize ());
580 
581  return element.m_packet->GetSize ();
582 }
583 
584 uint32_t
586 {
587  NS_LOG_INFO ("\t GetFirstPacketRequiredByte ()");
588 
589  uint32_t requiredByte = GetFirstPacketPayloadSize (packetType) +
590  GetFirstPacketHdrSize (packetType);
591 
592  NS_LOG_INFO ("\t Required Bytes = " << requiredByte << std::endl);
593 
594  return requiredByte;
595 }
596 
597 void
599 {
600  for (std::deque<QueueElement>::iterator iter = m_queue.begin (); iter
601  != m_queue.end (); ++iter)
602  {
603  if (iter->m_hdrType.GetType () == packetType)
604  {
605  iter->SetFragmentation ();
606  break;
607  }
608  }
609 }
610 
611 void
613 {
614  for (std::deque<QueueElement>::iterator iter = m_queue.begin (); iter
615  != m_queue.end (); ++iter)
616  {
617  if (iter->m_hdrType.GetType () == packetType)
618  {
619  iter->SetFragmentNumber ();
620  break;
621  }
622  }
623 }
624 
625 void
627 {
628  for (std::deque<QueueElement>::iterator iter = m_queue.begin (); iter
629  != m_queue.end (); ++iter)
630  {
631  if (iter->m_hdrType.GetType () == packetType)
632  {
633  iter->SetFragmentOffset (offset);
634  break;
635  }
636  }
637 }
638 
639 void
641 {
642  m_fragmentation = true;
643 }
644 
645 void
647 {
648  m_fragmentNumber++;
649 }
650 
651 void
653 {
654  m_fragmentOffset += offset;
655 }
656 } // 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)
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:79
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
TracedCallback< Ptr< const Packet > > m_traceDrop
std::deque< QueueElement > PacketQueue
void SetType(uint8_t type)
TracedCallback< Ptr< const Packet > > m_traceDequeue
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
uint32_t GetNBytes(void) const
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:744
Ptr< Packet > Peek(GenericMacHeader &hdr) const
Same as Dequeue but does not pop from queue.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:223
network packets
Definition: packet.h:223
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:232
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
performs a COW copy of the packet.
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)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:84
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:64
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:610
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:253
void SetLen(uint16_t len)