A Discrete-Event Network Simulator
API
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
30namespace ns3 {
31
32NS_LOG_COMPONENT_DEFINE ("WimaxMacQueue");
33
34NS_OBJECT_ENSURE_REGISTERED (WimaxMacQueue);
35
37 : m_packet (Create<Packet> ()),
38 m_hdrType (MacHeaderType ()),
39 m_hdr (
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
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
79{
80 static TypeId tid = TypeId ("ns3::WimaxMacQueue")
81 .SetParent<Object> ()
82 .SetGroupName("Wimax")
83 .AddAttribute (
84 "MaxSize",
85 "Maximum size",
86 UintegerValue (1024),
89 MakeUintegerChecker<uint32_t> ())
90 .AddTraceSource ("Enqueue",
91 "Enqueue trace",
93 "ns3::Packet::TracedCallback")
94 .AddTraceSource ("Dequeue",
95 "Dequeue trace",
97 "ns3::Packet::TracedCallback")
98 .AddTraceSource ("Drop",
99 "Drop trace",
101 "ns3::Packet::TracedCallback")
102 ;
103 return tid;
104}
105
107 : m_maxSize (0),
108 m_bytes (0),
109 m_nrDataPackets (0),
111{
112}
113
115 : m_maxSize (maxSize),
116 m_bytes (0),
117 m_nrDataPackets (0),
118 m_nrRequestPackets (0)
119{
120}
121
123{
124}
125
126void
128{
129 m_maxSize = maxSize;
130}
131
134{
135 return m_maxSize;
136}
137
138bool
140 const GenericMacHeader &hdr)
141{
142
143 if (m_queue.size () == m_maxSize)
144 {
145
146 m_traceDrop (packet);
147 return false;
148 }
149
150 m_traceEnqueue (packet);
151 QueueElement element (packet, hdrType, hdr, Simulator::Now ());
152 m_queue.push_back (element);
153
155 {
157 }
158 else
159 {
161 }
162
163 m_bytes += element.GetSize ();
164 return true;
165}
166
169{
170 if (!IsEmpty ())
171 {
172 QueueElement element = Front (packetType);
173 Pop (packetType);
174
176 {
177 NS_LOG_INFO ("Enqueued Packet IS A data packet");
179 "Can not enqueue more packets: no space left in the queue");
181 }
182 else
183 {
184 NS_LOG_INFO ("Enqueued Packet IS A Request BW packet");
186 "Can not enqueue more packets: no space left in the queue");
188 }
189
190 Ptr<Packet> packet = element.m_packet;
191
192 if (!element.m_fragmentation)
193 {
194 NS_LOG_INFO ("FRAG_DEBUG: Enqueued Packet IS NOT a fragment" << std::endl);
195 /*check because may be it is a bandwidth request packet (in which case a Bandwidth Request Header
196 has already been added to the packet) in which case Generic MAC Header will not be added to it.
197 this will only happen in the case of SS as only SS sends the bandwidth request packet. */
198 m_bytes -= element.GetSize ();
200 {
201 packet->AddHeader (element.m_hdr);
202 }
203 packet->AddHeader (element.m_hdrType);
204
205 m_traceDequeue (packet);
206 return packet;
207 }
208 else
209 {
210 /*
211 The enqueued packet is a fragment (the latest fragment)
212 We must modify type field of the m_hdr and add a fragmentation Subhdr
213 */
214 NS_LOG_INFO ("\t Enqueued Packet IS a fragment, add subhdr" << std::endl);
215
216 // Create a fragment
217 uint32_t fragmentOffset = element.m_fragmentOffset;
218 uint32_t fragmentSize = element.m_packet->GetSize () - fragmentOffset;
219
220 NS_LOG_INFO ("\t Create a fragment"
221 "\n\t\t fragmentOffset=" << fragmentOffset <<
222 "\n\t\t packetSize=" << element.m_packet->GetSize () <<
223 "\n\t\t fragmentSize=" << fragmentSize << std::endl);
224
225 Ptr<Packet> fragment = packet->CreateFragment (fragmentOffset,fragmentSize);
226
227 FragmentationSubheader fragmentSubhdr;
228 NS_LOG_INFO ("\t Latest Fragment" << std::endl);
229 fragmentSubhdr.SetFc (2); // This is the latest fragment
230 fragmentSubhdr.SetFsn (element.m_fragmentNumber);
231
232 NS_LOG_INFO ("\t FragmentSize=" << fragment->GetSize () << std::endl);
233 fragment->AddHeader (fragmentSubhdr);
234
235 /*check because may be it is a bandwidth request packet (in which case a Bandwidth Request Header
236 has already been added to the packet) in which case Generic MAC Header will not be added to it.
237 this will only happen in the case of SS as only SS sends the bandwidth request packet. */
239 {
240 uint8_t tmpType = element.m_hdr.GetType ();
241 tmpType |= 4;
242 element.m_hdr.SetType (tmpType);
243
244 uint32_t length = fragmentSize + element.m_hdr.GetSerializedSize ()
245 + fragmentSubhdr.GetSerializedSize ();
246 element.m_hdr.SetLen ((uint16_t)length);
247
248 fragment->AddHeader (element.m_hdr);
249 }
250 fragment->AddHeader (element.m_hdrType);
251 m_bytes -= fragmentSize;
252
253 m_traceDequeue (fragment);
254 return fragment;
255 }
256 }
257 return 0;
258}
259
262{
263 if (!IsEmpty ())
264 {
265 NS_LOG_INFO ("FRAG_DEBUG: Dequeue function" << std::endl);
266 QueueElement element = Front (packetType);
267
268 uint32_t headerSize = 2 + element.m_hdr.GetSerializedSize () +
269 element.m_hdrType.GetSerializedSize ();
270
271 // Create a fragment
272 uint32_t maxFragmentSize = availableByte - headerSize;
273 uint32_t fragmentOffset = element.m_fragmentOffset; // It is the latest byte sent.
274
275 Ptr<Packet> packet = element.m_packet->Copy ();
276 NS_LOG_INFO ("\t Create a fragment"
277 "\n\t\t availableByte=" << availableByte <<
278 "\n\t\t headerSize=" << headerSize <<
279 "\n\t\t maxFragmentSize=" << maxFragmentSize << ""
280 "\n\t\t fragmentOffset=" << fragmentOffset <<
281 "\n\t\t payloadSize=" << packet->GetSize ()
282 << std::endl);
283 Ptr<Packet> fragment = packet->CreateFragment (fragmentOffset,
284 maxFragmentSize);
285 m_bytes -= maxFragmentSize;
286
287 FragmentationSubheader fragmentSubhdr;
288 if (!element.m_fragmentation)
289 {
290 NS_LOG_INFO ("\t First Fragment" << std::endl);
291 SetFragmentation (packetType);
292 fragmentSubhdr.SetFc (1);
293 }
294 else
295 {
296 NS_LOG_INFO ("\t Middle Fragment" << std::endl);
297 fragmentSubhdr.SetFc (3);
298 }
299 fragmentSubhdr.SetFsn (element.m_fragmentNumber);
300 NS_LOG_INFO ("\t FragmentSize=" << fragment->GetSize () << std::endl);
301 fragment->AddHeader (fragmentSubhdr);
302
303 SetFragmentNumber (packetType);
304 SetFragmentOffset (packetType, maxFragmentSize);
305
306 /*check because may be it is a bandwidth request packet (in which case a Bandwidth Request Header
307 has already been added to the packet) in which case Generic MAC Header will not be added to it.
308 this will only happen in the case of SS as only SS sends the bandwidth request packet. */
310 {
311 uint8_t tmpType = element.m_hdr.GetType ();
312 tmpType |= 4;
313 element.m_hdr.SetType (tmpType);
314
315 uint32_t length = maxFragmentSize + element.m_hdr.GetSerializedSize ()
316 + fragmentSubhdr.GetSerializedSize ();
317 element.m_hdr.SetLen ((uint16_t)length);
318
319 fragment->AddHeader (element.m_hdr);
320 }
321 fragment->AddHeader (element.m_hdrType);
322
323 m_traceDequeue (fragment);
324 return fragment;
325 }
326 return 0;
327}
328
331{
332 if (!IsEmpty ())
333 {
334 QueueElement element = m_queue.front ();
335 hdr = element.m_hdr;
336 Ptr<Packet> packet = element.m_packet->Copy ();
337
338 // this function must not be used by SS as it may be then a bandwidth request header
339 packet->AddHeader (element.m_hdr);
340 return packet;
341 }
342
343 return 0;
344}
345
348{
349 if (!IsEmpty ())
350 {
351 QueueElement element = m_queue.front ();
352 hdr = element.m_hdr;
353 timeStamp = element.m_timeStamp;
354 Ptr<Packet> packet = element.m_packet->Copy ();
355
356 // this function must not be used for by SS as it may be then a bandwidth request header
357 packet->AddHeader (element.m_hdr);
358 return packet;
359 }
360
361 return 0;
362}
363
366{
367 if (!IsEmpty ())
368 {
369 QueueElement element = Front (packetType);
370 Ptr<Packet> packet = element.m_packet->Copy ();
371
372 /*check because may be it is a bandwidth request packet (in which case a Bandwidth Request Header
373 has already been added to the packet) in which case Generic MAC Header will not be added to it.
374 this will only happen in the case of SS as only SS sends the bandwidth request packet. */
376 {
377 packet->AddHeader (element.m_hdr);
378 }
379 return packet;
380 }
381
382 return 0;
383}
384
387 Time &timeStamp) const
388{
389 if (!IsEmpty ())
390 {
391 QueueElement element = Front (packetType);
392 timeStamp = element.m_timeStamp;
393 Ptr<Packet> packet = element.m_packet->Copy ();
394
395 /*check because may be it is a bandwidth request packet (in which case a Bandwidth Request Header
396 has already been added to the packet) in which case Generic MAC Header will not be added to it.
397 this will only happen in the case of SS as only SS sends the bandwidth request packet. */
399 {
400 packet->AddHeader (element.m_hdr);
401 }
402 return packet;
403 }
404
405 return 0;
406}
407
410{
411 return m_queue.size ();
412}
413
416{
417 return m_bytes;
418}
419
421{
422 uint32_t queueSize = GetNBytes ();
423 // Add MAC Overhead
424 queueSize += GetSize () * 6;
426 if (CheckForFragmentation (packetType))
427 {
428 queueSize += 2;
429 }
430 return queueSize;
431}
432
435{
436 QueueElement element;
437
438 for (std::deque<QueueElement>::const_iterator iter = m_queue.begin (); iter
439 != m_queue.end (); ++iter)
440 {
441 element = *iter;
442 if (element.m_hdrType.GetType () == packetType)
443 {
444 break;
445 }
446 }
447
448 return element;
449}
450
451void
453{
454 QueueElement element;
455
456 for (std::deque<QueueElement>::iterator iter = m_queue.begin (); iter
457 != m_queue.end (); ++iter)
458 {
459 element = *iter;
460 if (element.m_hdrType.GetType () == packetType)
461 {
462 m_queue.erase (iter);
463 break;
464 }
465 }
466}
467
468bool
470{
471 return m_queue.empty ();
472}
473
474bool
476{
477 if (packetType == MacHeaderType::HEADER_TYPE_GENERIC)
478 {
479 return m_nrDataPackets == 0;
480 }
481 else
482 {
483 return m_nrRequestPackets == 0;
484 }
485
486 return true;
487}
488
491{
492 return m_queue;
493}
494
495bool
497{
498 QueueElement element;
499 for (std::deque<QueueElement>::const_iterator iter = m_queue.begin (); iter
500 != m_queue.end (); ++iter)
501 {
502 element = *iter;
503 if (element.m_hdrType.GetType () == packetType)
504 {
505 break;
506 }
507 }
508
509 if (element.m_fragmentation)
510 {
511 NS_LOG_INFO ("FRAG_DEBUG: CheckForFragmentation"
512 "\n\t\t m_fragmentation is true " << std::endl);
513 }
514
515 return element.m_fragmentation;
516}
517
520{
521 QueueElement element;
522 for (std::deque<QueueElement>::const_iterator iter = m_queue.begin (); iter
523 != m_queue.end (); ++iter)
524 {
525 element = *iter;
526 if (element.m_hdrType.GetType () == packetType)
527 {
528 break;
529 }
530 }
531
532 NS_LOG_INFO ("\t\t GetFirstPacketHdrSize ()");
533
534 uint32_t hdrSize = 0;
536 {
537 hdrSize += element.m_hdr.GetSerializedSize ();
538 NS_LOG_INFO ("\t\t\t m_hdr.GetSerializedSize=" <<
539 element.m_hdr.GetSerializedSize ());
540 }
541
542 hdrSize += element.m_hdrType.GetSerializedSize ();
543 NS_LOG_INFO ("\t\t\t m_hdrType.GetSerializedSize=" <<
544 element.m_hdrType.GetSerializedSize ());
545
546 if (CheckForFragmentation (packetType))
547 {
548 NS_LOG_INFO ("\t\t\t fragSubhdrSize=2");
549 hdrSize += 2;
550 }
551
552 NS_LOG_INFO ("\t\t hdrSize=" << hdrSize);
553
554 return hdrSize;
555}
556
559{
560 QueueElement element;
561 for (std::deque<QueueElement>::const_iterator iter = m_queue.begin (); iter
562 != m_queue.end (); ++iter)
563 {
564 element = *iter;
565 if (element.m_hdrType.GetType () == packetType)
566 {
567 break;
568 }
569 }
570
571 NS_LOG_INFO ("\t\t GetFirstPacketPayloadSize ()");
572
573 if (CheckForFragmentation (packetType))
574 {
575 NS_LOG_INFO ("\t\t\t fullPayloadSize=" << element.m_packet->GetSize ()
576 << "\n\t\t\t fragmentOffset=" << element.m_fragmentOffset
577 << "\n\t\t\t (fragment)payloadSize=" <<
578 element.m_packet->GetSize () - element.m_fragmentOffset);
579
580 return element.m_packet->GetSize () - element.m_fragmentOffset;
581 }
582 NS_LOG_INFO ("\t\t payloadSize=" <<
583 element.m_packet->GetSize ());
584
585 return element.m_packet->GetSize ();
586}
587
590{
591 NS_LOG_INFO ("\t GetFirstPacketRequiredByte ()");
592
593 uint32_t requiredByte = GetFirstPacketPayloadSize (packetType) +
594 GetFirstPacketHdrSize (packetType);
595
596 NS_LOG_INFO ("\t Required Bytes = " << requiredByte << std::endl);
597
598 return requiredByte;
599}
600
601void
603{
604 for (std::deque<QueueElement>::iterator iter = m_queue.begin (); iter
605 != m_queue.end (); ++iter)
606 {
607 if (iter->m_hdrType.GetType () == packetType)
608 {
609 iter->SetFragmentation ();
610 break;
611 }
612 }
613}
614
615void
617{
618 for (std::deque<QueueElement>::iterator iter = m_queue.begin (); iter
619 != m_queue.end (); ++iter)
620 {
621 if (iter->m_hdrType.GetType () == packetType)
622 {
623 iter->SetFragmentNumber ();
624 break;
625 }
626 }
627}
628
629void
631{
632 for (std::deque<QueueElement>::iterator iter = m_queue.begin (); iter
633 != m_queue.end (); ++iter)
634 {
635 if (iter->m_hdrType.GetType () == packetType)
636 {
637 iter->SetFragmentOffset (offset);
638 break;
639 }
640 }
641}
642
643void
645{
646 m_fragmentation = true;
647}
648
649void
651{
652 m_fragmentNumber++;
653}
654
655void
657{
658 m_fragmentOffset += offset;
659}
660} // namespace ns3
This class implements the fragmentation sub-header as described by IEEE Standard for Local and metrop...
void SetFsn(uint8_t fsn)
Set FSN field.
void SetFc(uint8_t fc)
Set FC field.
uint32_t GetSerializedSize(void) const
This class implements the Generic mac Header as described by IEEE Standard for Local and metropolitan...
uint8_t GetType(void) const
Get type field.
void SetType(uint8_t type)
Set type field.
void SetLen(uint16_t len)
Set length field.
uint32_t GetSerializedSize(void) const
This class Represents the HT (Header Type) field of generic MAC and bandwidth request headers.
uint8_t GetType(void) const
Get type field.
HeaderType
Header type enumeration.
uint32_t GetSerializedSize(void) const
A base class which provides memory management and object aggregation.
Definition: object.h:88
network packets
Definition: packet.h:232
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
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:227
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Hold an unsigned integer type.
Definition: uinteger.h:44
std::deque< QueueElement > PacketQueue
PacketQueue typedef.
Ptr< Packet > Peek(GenericMacHeader &hdr) const
Exclusively for BS.
uint32_t GetFirstPacketPayloadSize(MacHeaderType::HeaderType packetType)
Get first packet payload size of the specified type.
WimaxMacQueue::QueueElement Front(MacHeaderType::HeaderType packetType) const
In the case of non-UGS service flows at the SS side the queue will store both data packets and bandwi...
void Pop(MacHeaderType::HeaderType packetType)
Pop function.
void SetMaxSize(uint32_t maxSize)
set the maximum queue size
TracedCallback< Ptr< const Packet > > m_traceDequeue
dequeue trace callback
uint32_t GetFirstPacketRequiredByte(MacHeaderType::HeaderType packetType)
Get required number of bytes to hold first packet of packetType.
Ptr< Packet > Dequeue(MacHeaderType::HeaderType packetType)
Dequeue a packet of type packetType from the queue.
TracedCallback< Ptr< const Packet > > m_traceEnqueue
enqueue trace callback
static TypeId GetTypeId(void)
Get the type ID.
uint32_t GetQueueLengthWithMACOverhead(void)
Get queue length considering also the MAC overhead.
uint32_t GetSize(void) const
Get size of queue.
uint32_t GetMaxSize(void) const
uint32_t GetFirstPacketHdrSize(MacHeaderType::HeaderType packetType)
Get first packet header size of the specified type.
uint32_t m_bytes
bytes
void SetFragmentNumber(MacHeaderType::HeaderType packetType)
Set fragment number for first packet of type packetType.
void SetFragmentation(MacHeaderType::HeaderType packetType)
Set fragmentation function.
const WimaxMacQueue::PacketQueue & GetPacketQueue(void) const
Get packet queue function.
uint32_t GetNBytes(void) const
Get number of bytes in queue.
void SetFragmentOffset(MacHeaderType::HeaderType packetType, uint32_t offset)
Set fragment offset for first packet of type packetType.
bool CheckForFragmentation(MacHeaderType::HeaderType packetType)
Check for fragmentation of the first packet of the specified type.
uint32_t m_nrDataPackets
number data packets
uint32_t m_maxSize
maximum size
bool Enqueue(Ptr< Packet > packet, const MacHeaderType &hdrType, const GenericMacHeader &hdr)
Enqueue a packet.
PacketQueue m_queue
the queue
uint32_t m_nrRequestPackets
number request packets
bool IsEmpty(void) const
Check if queue is empty.
TracedCallback< Ptr< const Packet > > m_traceDrop
drop trace callback
#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:88
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:45
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition: ptr.h:409
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint32_t m_fragmentNumber
incremented when a new fragment is sent
uint32_t GetSize(void) const
Get size function.
uint32_t m_fragmentOffset
tracks the start of the next fragment into the packet
bool m_fragmentation
To manage fragmentation feature, each QueueElement have 3 new fields: m_fragmentation that becomes tr...
MacHeaderType m_hdrType
header type
void SetFragmentation(void)
Set fragmentation.
void SetFragmentNumber(void)
Set fragment number.
GenericMacHeader m_hdr
header
void SetFragmentOffset(uint32_t offset)
Set fragment offset.