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{
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 (auto iter = m_queue.begin(); iter != m_queue.end(); ++iter)
442 {
443 element = *iter;
444 if (element.m_hdrType.GetType() == packetType)
445 {
446 break;
447 }
448 }
449
450 return element;
451}
452
453void
455{
456 QueueElement element;
457
458 for (auto iter = m_queue.begin(); iter != m_queue.end(); ++iter)
459 {
460 element = *iter;
461 if (element.m_hdrType.GetType() == packetType)
462 {
463 m_queue.erase(iter);
464 break;
465 }
466 }
467}
468
469bool
471{
472 return m_queue.empty();
473}
474
475bool
477{
478 if (packetType == MacHeaderType::HEADER_TYPE_GENERIC)
479 {
480 return m_nrDataPackets == 0;
481 }
482 else
483 {
484 return m_nrRequestPackets == 0;
485 }
486
487 return true;
488}
489
492{
493 return m_queue;
494}
495
496bool
498{
499 QueueElement element;
500 for (auto iter = m_queue.begin(); iter != 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 "
513 << std::endl);
514 }
515
516 return element.m_fragmentation;
517}
518
521{
522 QueueElement element;
523 for (auto iter = m_queue.begin(); iter != 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=" << element.m_hdr.GetSerializedSize());
539 }
540
541 hdrSize += element.m_hdrType.GetSerializedSize();
542 NS_LOG_INFO("\t\t\t m_hdrType.GetSerializedSize=" << element.m_hdrType.GetSerializedSize());
543
544 if (CheckForFragmentation(packetType))
545 {
546 NS_LOG_INFO("\t\t\t fragSubhdrSize=2");
547 hdrSize += 2;
548 }
549
550 NS_LOG_INFO("\t\t hdrSize=" << hdrSize);
551
552 return hdrSize;
553}
554
557{
558 QueueElement element;
559 for (auto iter = m_queue.begin(); iter != 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="
573 << element.m_packet->GetSize() << "\n\t\t\t fragmentOffset="
574 << element.m_fragmentOffset << "\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=" << element.m_packet->GetSize());
580
581 return element.m_packet->GetSize();
582}
583
586{
587 NS_LOG_INFO("\t GetFirstPacketRequiredByte ()");
588
589 uint32_t requiredByte =
590 GetFirstPacketPayloadSize(packetType) + GetFirstPacketHdrSize(packetType);
591
592 NS_LOG_INFO("\t Required Bytes = " << requiredByte << std::endl);
593
594 return requiredByte;
595}
596
597void
599{
600 for (auto iter = m_queue.begin(); iter != m_queue.end(); ++iter)
601 {
602 if (iter->m_hdrType.GetType() == packetType)
603 {
604 iter->SetFragmentation();
605 break;
606 }
607 }
608}
609
610void
612{
613 for (auto iter = m_queue.begin(); iter != m_queue.end(); ++iter)
614 {
615 if (iter->m_hdrType.GetType() == packetType)
616 {
617 iter->SetFragmentNumber();
618 break;
619 }
620 }
621}
622
623void
625{
626 for (auto iter = m_queue.begin(); iter != m_queue.end(); ++iter)
627 {
628 if (iter->m_hdrType.GetType() == packetType)
629 {
630 iter->SetFragmentOffset(offset);
631 break;
632 }
633 }
634}
635
636void
638{
639 m_fragmentation = true;
640}
641
642void
644{
645 m_fragmentNumber++;
646}
647
648void
650{
651 m_fragmentOffset += offset;
652}
653} // 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:77
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
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:932
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:442
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
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.
std::ofstream queueSize