A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wimax-mac-queue.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007,2008 INRIA, UDcast
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Jahanzeb Farooq <jahanzeb.farooq@sophia.inria.fr>
18 * Mohamed Amine Ismail <Amine.Ismail@sophia.inria.fr>
19 * <Amine.Ismail@UDcast.com>
20 */
21
22#include "wimax-mac-queue.h"
23
24#include "ns3/log.h"
25#include "ns3/packet.h"
26#include "ns3/simulator.h"
27#include "ns3/trace-source-accessor.h"
28#include "ns3/uinteger.h"
29
30namespace ns3
31{
32
33NS_LOG_COMPONENT_DEFINE("WimaxMacQueue");
34
35NS_OBJECT_ENSURE_REGISTERED(WimaxMacQueue);
36
38 : m_packet(Create<Packet>()),
39 m_hdrType(MacHeaderType()),
40 m_hdr(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,
51 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
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
68 Header has already been added to the packet) in which case Generic MAC Header will not be added
69 to it. this will only happen in the case of SS as only SS sends the bandwidth request packet.
70 */
71 if (m_hdrType.GetType() == MacHeaderType::HEADER_TYPE_GENERIC)
72 {
73 size += m_hdr.GetSerializedSize();
74 }
75
76 return size;
77}
78
81{
82 static TypeId tid = TypeId("ns3::WimaxMacQueue")
84 .SetGroupName("Wimax")
85 .AddAttribute("MaxSize",
86 "Maximum size",
87 UintegerValue(1024),
90 MakeUintegerChecker<uint32_t>())
91 .AddTraceSource("Enqueue",
92 "Enqueue trace",
94 "ns3::Packet::TracedCallback")
95 .AddTraceSource("Dequeue",
96 "Dequeue trace",
98 "ns3::Packet::TracedCallback")
99 .AddTraceSource("Drop",
100 "Drop trace",
102 "ns3::Packet::TracedCallback");
103 return tid;
104}
105
107 : m_maxSize(0),
108 m_bytes(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 MacHeaderType& hdrType,
141 const GenericMacHeader& hdr)
142{
143 if (m_queue.size() == m_maxSize)
144 {
145 m_traceDrop(packet);
146 return false;
147 }
148
149 m_traceEnqueue(packet);
150 QueueElement element(packet, hdrType, hdr, Simulator::Now());
151 m_queue.push_back(element);
152
154 {
156 }
157 else
158 {
160 }
161
162 m_bytes += element.GetSize();
163 return true;
164}
165
168{
169 if (!IsEmpty())
170 {
171 QueueElement element = Front(packetType);
172 Pop(packetType);
173
175 {
176 NS_LOG_INFO("Enqueued Packet IS A data packet");
178 "Can not enqueue more packets: no space left in the queue");
180 }
181 else
182 {
183 NS_LOG_INFO("Enqueued Packet IS A Request BW packet");
185 "Can not enqueue more packets: no space left in the queue");
187 }
188
189 Ptr<Packet> packet = element.m_packet;
190
191 if (!element.m_fragmentation)
192 {
193 NS_LOG_INFO("FRAG_DEBUG: Enqueued Packet IS NOT a fragment" << std::endl);
194 /*check because may be it is a bandwidth request packet (in which case a Bandwidth
195 Request Header has already been added to the packet) in which case Generic MAC Header
196 will not be added to it. this will only happen in the case of SS as only SS sends the
197 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="
222 << fragmentOffset << "\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
236 Request Header has already been added to the packet) in which case Generic MAC Header
237 will not be added to it. this will only happen in the case of SS as only SS sends the
238 bandwidth request packet. */
240 {
241 uint8_t tmpType = element.m_hdr.GetType();
242 tmpType |= 4;
243 element.m_hdr.SetType(tmpType);
244
245 uint32_t length = fragmentSize + element.m_hdr.GetSerializedSize() +
246 fragmentSubhdr.GetSerializedSize();
247 element.m_hdr.SetLen((uint16_t)length);
248
249 fragment->AddHeader(element.m_hdr);
250 }
251 fragment->AddHeader(element.m_hdrType);
252 m_bytes -= fragmentSize;
253
254 m_traceDequeue(fragment);
255 return fragment;
256 }
257 }
258 return nullptr;
259}
260
263{
264 if (!IsEmpty())
265 {
266 NS_LOG_INFO("FRAG_DEBUG: Dequeue function" << std::endl);
267 QueueElement element = Front(packetType);
268
269 uint32_t headerSize =
270 2 + element.m_hdr.GetSerializedSize() + element.m_hdrType.GetSerializedSize();
271
272 // Create a fragment
273 uint32_t maxFragmentSize = availableByte - headerSize;
274 uint32_t fragmentOffset = element.m_fragmentOffset; // It is the latest byte sent.
275
276 Ptr<Packet> packet = element.m_packet->Copy();
277 NS_LOG_INFO("\t Create a fragment"
278 "\n\t\t availableByte="
279 << availableByte << "\n\t\t headerSize=" << headerSize
280 << "\n\t\t maxFragmentSize=" << maxFragmentSize
281 << ""
282 "\n\t\t fragmentOffset="
283 << fragmentOffset << "\n\t\t payloadSize=" << packet->GetSize() << std::endl);
284 Ptr<Packet> fragment = packet->CreateFragment(fragmentOffset, 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
307 Header has already been added to the packet) in which case Generic MAC Header will not be
308 added to it. this will only happen in the case of SS as only SS sends the bandwidth
309 request packet. */
311 {
312 uint8_t tmpType = element.m_hdr.GetType();
313 tmpType |= 4;
314 element.m_hdr.SetType(tmpType);
315
316 uint32_t length = maxFragmentSize + element.m_hdr.GetSerializedSize() +
317 fragmentSubhdr.GetSerializedSize();
318 element.m_hdr.SetLen((uint16_t)length);
319
320 fragment->AddHeader(element.m_hdr);
321 }
322 fragment->AddHeader(element.m_hdrType);
323
324 m_traceDequeue(fragment);
325 return fragment;
326 }
327 return nullptr;
328}
329
332{
333 if (!IsEmpty())
334 {
335 QueueElement element = m_queue.front();
336 hdr = element.m_hdr;
337 Ptr<Packet> packet = element.m_packet->Copy();
338
339 // this function must not be used by SS as it may be then a bandwidth request header
340 packet->AddHeader(element.m_hdr);
341 return packet;
342 }
343
344 return nullptr;
345}
346
349{
350 if (!IsEmpty())
351 {
352 QueueElement element = m_queue.front();
353 hdr = element.m_hdr;
354 timeStamp = element.m_timeStamp;
355 Ptr<Packet> packet = element.m_packet->Copy();
356
357 // this function must not be used for by SS as it may be then a bandwidth request header
358 packet->AddHeader(element.m_hdr);
359 return packet;
360 }
361
362 return nullptr;
363}
364
367{
368 if (!IsEmpty())
369 {
370 QueueElement element = Front(packetType);
371 Ptr<Packet> packet = element.m_packet->Copy();
372
373 /*check because may be it is a bandwidth request packet (in which case a Bandwidth Request
374 Header has already been added to the packet) in which case Generic MAC Header will not be
375 added to it. this will only happen in the case of SS as only SS sends the bandwidth request
376 packet. */
378 {
379 packet->AddHeader(element.m_hdr);
380 }
381 return packet;
382 }
383
384 return nullptr;
385}
386
389{
390 if (!IsEmpty())
391 {
392 QueueElement element = Front(packetType);
393 timeStamp = element.m_timeStamp;
394 Ptr<Packet> packet = element.m_packet->Copy();
395
396 /*check because may be it is a bandwidth request packet (in which case a Bandwidth Request
397 Header has already been added to the packet) in which case Generic MAC Header will not be
398 added to it. this will only happen in the case of SS as only SS sends the bandwidth request
399 packet. */
401 {
402 packet->AddHeader(element.m_hdr);
403 }
404 return packet;
405 }
406
407 return nullptr;
408}
409
412{
413 return m_queue.size();
414}
415
418{
419 return m_bytes;
420}
421
424{
425 uint32_t queueSize = GetNBytes();
426 // Add MAC Overhead
427 queueSize += GetSize() * 6;
429 if (CheckForFragmentation(packetType))
430 {
431 queueSize += 2;
432 }
433 return queueSize;
434}
435
438{
439 QueueElement element;
440
441 for (std::deque<QueueElement>::const_iterator iter = m_queue.begin(); iter != m_queue.end();
442 ++iter)
443 {
444 element = *iter;
445 if (element.m_hdrType.GetType() == packetType)
446 {
447 break;
448 }
449 }
450
451 return element;
452}
453
454void
456{
457 QueueElement element;
458
459 for (std::deque<QueueElement>::iterator iter = m_queue.begin(); iter != m_queue.end(); ++iter)
460 {
461 element = *iter;
462 if (element.m_hdrType.GetType() == packetType)
463 {
464 m_queue.erase(iter);
465 break;
466 }
467 }
468}
469
470bool
472{
473 return m_queue.empty();
474}
475
476bool
478{
479 if (packetType == MacHeaderType::HEADER_TYPE_GENERIC)
480 {
481 return m_nrDataPackets == 0;
482 }
483 else
484 {
485 return m_nrRequestPackets == 0;
486 }
487
488 return true;
489}
490
493{
494 return m_queue;
495}
496
497bool
499{
500 QueueElement element;
501 for (std::deque<QueueElement>::const_iterator iter = m_queue.begin(); iter != m_queue.end();
502 ++iter)
503 {
504 element = *iter;
505 if (element.m_hdrType.GetType() == packetType)
506 {
507 break;
508 }
509 }
510
511 if (element.m_fragmentation)
512 {
513 NS_LOG_INFO("FRAG_DEBUG: CheckForFragmentation"
514 "\n\t\t m_fragmentation is true "
515 << std::endl);
516 }
517
518 return element.m_fragmentation;
519}
520
523{
524 QueueElement element;
525 for (std::deque<QueueElement>::const_iterator iter = m_queue.begin(); iter != m_queue.end();
526 ++iter)
527 {
528 element = *iter;
529 if (element.m_hdrType.GetType() == packetType)
530 {
531 break;
532 }
533 }
534
535 NS_LOG_INFO("\t\t GetFirstPacketHdrSize ()");
536
537 uint32_t hdrSize = 0;
539 {
540 hdrSize += element.m_hdr.GetSerializedSize();
541 NS_LOG_INFO("\t\t\t m_hdr.GetSerializedSize=" << element.m_hdr.GetSerializedSize());
542 }
543
544 hdrSize += element.m_hdrType.GetSerializedSize();
545 NS_LOG_INFO("\t\t\t m_hdrType.GetSerializedSize=" << element.m_hdrType.GetSerializedSize());
546
547 if (CheckForFragmentation(packetType))
548 {
549 NS_LOG_INFO("\t\t\t fragSubhdrSize=2");
550 hdrSize += 2;
551 }
552
553 NS_LOG_INFO("\t\t hdrSize=" << hdrSize);
554
555 return hdrSize;
556}
557
560{
561 QueueElement element;
562 for (std::deque<QueueElement>::const_iterator iter = m_queue.begin(); iter != m_queue.end();
563 ++iter)
564 {
565 element = *iter;
566 if (element.m_hdrType.GetType() == packetType)
567 {
568 break;
569 }
570 }
571
572 NS_LOG_INFO("\t\t GetFirstPacketPayloadSize ()");
573
574 if (CheckForFragmentation(packetType))
575 {
576 NS_LOG_INFO("\t\t\t fullPayloadSize="
577 << element.m_packet->GetSize() << "\n\t\t\t fragmentOffset="
578 << element.m_fragmentOffset << "\n\t\t\t (fragment)payloadSize="
579 << element.m_packet->GetSize() - element.m_fragmentOffset);
580
581 return element.m_packet->GetSize() - element.m_fragmentOffset;
582 }
583 NS_LOG_INFO("\t\t payloadSize=" << 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 =
594 GetFirstPacketPayloadSize(packetType) + 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 != m_queue.end(); ++iter)
605 {
606 if (iter->m_hdrType.GetType() == packetType)
607 {
608 iter->SetFragmentation();
609 break;
610 }
611 }
612}
613
614void
616{
617 for (std::deque<QueueElement>::iterator iter = m_queue.begin(); iter != m_queue.end(); ++iter)
618 {
619 if (iter->m_hdrType.GetType() == packetType)
620 {
621 iter->SetFragmentNumber();
622 break;
623 }
624 }
625}
626
627void
629{
630 for (std::deque<QueueElement>::iterator iter = m_queue.begin(); iter != m_queue.end(); ++iter)
631 {
632 if (iter->m_hdrType.GetType() == packetType)
633 {
634 iter->SetFragmentOffset(offset);
635 break;
636 }
637 }
638}
639
640void
642{
643 m_fragmentation = true;
644}
645
646void
648{
649 m_fragmentNumber++;
650}
651
652void
654{
655 m_fragmentOffset += offset;
656}
657} // namespace ns3
This class implements the fragmentation sub-header as described by IEEE Standard for Local and metrop...
uint32_t GetSerializedSize() const override
void SetFsn(uint8_t fsn)
Set FSN field.
void SetFc(uint8_t fc)
Set FC field.
This class implements the Generic mac Header as described by IEEE Standard for Local and metropolitan...
uint8_t GetType() const
Get type field.
void SetType(uint8_t type)
Set type field.
uint32_t GetSerializedSize() const override
void SetLen(uint16_t len)
Set length field.
This class Represents the HT (Header Type) field of generic MAC and bandwidth request headers.
HeaderType
Header type enumeration.
uint32_t GetSerializedSize() const override
uint8_t GetType() const
Get type field.
A base class which provides memory management and object aggregation.
Definition: object.h:89
network packets
Definition: packet.h:239
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
Hold an unsigned integer type.
Definition: uinteger.h:45
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
uint32_t GetNBytes() const
Get number of bytes in queue.
static TypeId GetTypeId()
Get the type ID.
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.
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
uint32_t GetQueueLengthWithMACOverhead()
Get queue length considering also the MAC overhead.
bool IsEmpty() const
Check if queue is empty.
const WimaxMacQueue::PacketQueue & GetPacketQueue() const
Get packet queue function.
TracedCallback< Ptr< const Packet > > m_traceDrop
drop trace callback
uint32_t GetMaxSize() const
uint32_t GetSize() const
Get size of queue.
#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:86
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition: ptr.h:481
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
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() 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...
void SetFragmentNumber()
Set fragment number.
MacHeaderType m_hdrType
header type
GenericMacHeader m_hdr
header
void SetFragmentOffset(uint32_t offset)
Set fragment offset.
void SetFragmentation()
Set fragmentation.