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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Jahanzeb Farooq <jahanzeb.farooq@sophia.inria.fr>
7 * Mohamed Amine Ismail <Amine.Ismail@sophia.inria.fr>
8 * <Amine.Ismail@UDcast.com>
9 */
10
11#include "wimax-mac-queue.h"
12
13#include "ns3/log.h"
14#include "ns3/packet.h"
15#include "ns3/simulator.h"
16#include "ns3/trace-source-accessor.h"
17#include "ns3/uinteger.h"
18
19namespace ns3
20{
21
22NS_LOG_COMPONENT_DEFINE("WimaxMacQueue");
23
24NS_OBJECT_ENSURE_REGISTERED(WimaxMacQueue);
25
27 : m_packet(Create<Packet>()),
28 m_hdrType(MacHeaderType()),
29 m_hdr(GenericMacHeader()),
30 m_timeStamp(Seconds(0)),
31 m_fragmentation(false),
32 m_fragmentNumber(0),
33 m_fragmentOffset(0)
34{
35}
36
38 const MacHeaderType& hdrType,
39 const GenericMacHeader& hdr,
40 Time timeStamp)
41 : m_packet(packet),
42 m_hdrType(hdrType),
43 m_hdr(hdr),
44 m_timeStamp(timeStamp),
45 m_fragmentation(false),
46 m_fragmentNumber(0),
47 m_fragmentOffset(0)
48{
49}
50
53{
54 uint32_t size = m_packet->GetSize() + m_hdrType.GetSerializedSize();
55
56 /*check because may be it is a bandwidth request packet (in which case a Bandwidth Request
57 Header has already been added to the packet) in which case Generic MAC Header will not be added
58 to it. this will only happen in the case of SS as only SS sends the bandwidth request packet.
59 */
60 if (m_hdrType.GetType() == MacHeaderType::HEADER_TYPE_GENERIC)
61 {
62 size += m_hdr.GetSerializedSize();
63 }
64
65 return size;
66}
67
70{
71 static TypeId tid = TypeId("ns3::WimaxMacQueue")
73 .SetGroupName("Wimax")
74 .AddAttribute("MaxSize",
75 "Maximum size",
76 UintegerValue(1024),
80 .AddTraceSource("Enqueue",
81 "Enqueue trace",
83 "ns3::Packet::TracedCallback")
84 .AddTraceSource("Dequeue",
85 "Dequeue trace",
87 "ns3::Packet::TracedCallback")
88 .AddTraceSource("Drop",
89 "Drop trace",
91 "ns3::Packet::TracedCallback");
92 return tid;
93}
94
102
104 : m_maxSize(maxSize),
105 m_bytes(0),
106 m_nrDataPackets(0),
107 m_nrRequestPackets(0)
108{
109}
110
114
115void
117{
118 m_maxSize = maxSize;
119}
120
123{
124 return m_maxSize;
125}
126
127bool
129 const MacHeaderType& hdrType,
130 const GenericMacHeader& hdr)
131{
132 if (m_queue.size() == m_maxSize)
133 {
134 m_traceDrop(packet);
135 return false;
136 }
137
138 m_traceEnqueue(packet);
139 QueueElement element(packet, hdrType, hdr, Simulator::Now());
140 m_queue.push_back(element);
141
143 {
145 }
146 else
147 {
149 }
150
151 m_bytes += element.GetSize();
152 return true;
153}
154
157{
158 if (!IsEmpty())
159 {
160 QueueElement element = Front(packetType);
161 Pop(packetType);
162
164 {
165 NS_LOG_INFO("Enqueued Packet IS A data packet");
167 "Can not enqueue more packets: no space left in the queue");
169 }
170 else
171 {
172 NS_LOG_INFO("Enqueued Packet IS A Request BW packet");
174 "Can not enqueue more packets: no space left in the queue");
176 }
177
178 Ptr<Packet> packet = element.m_packet;
179
180 if (!element.m_fragmentation)
181 {
182 NS_LOG_INFO("FRAG_DEBUG: Enqueued Packet IS NOT a fragment" << std::endl);
183 /*check because may be it is a bandwidth request packet (in which case a Bandwidth
184 Request Header has already been added to the packet) in which case Generic MAC Header
185 will not be added to it. this will only happen in the case of SS as only SS sends the
186 bandwidth request packet. */
187 m_bytes -= element.GetSize();
189 {
190 packet->AddHeader(element.m_hdr);
191 }
192 packet->AddHeader(element.m_hdrType);
193
194 m_traceDequeue(packet);
195 return packet;
196 }
197 else
198 {
199 /*
200 The enqueued packet is a fragment (the latest fragment)
201 We must modify type field of the m_hdr and add a fragmentation Subhdr
202 */
203 NS_LOG_INFO("\t Enqueued Packet IS a fragment, add subhdr" << std::endl);
204
205 // Create a fragment
206 uint32_t fragmentOffset = element.m_fragmentOffset;
207 uint32_t fragmentSize = element.m_packet->GetSize() - fragmentOffset;
208
209 NS_LOG_INFO("\t Create a fragment"
210 "\n\t\t fragmentOffset="
211 << fragmentOffset << "\n\t\t packetSize=" << element.m_packet->GetSize()
212 << "\n\t\t fragmentSize=" << fragmentSize << std::endl);
213
214 Ptr<Packet> fragment = packet->CreateFragment(fragmentOffset, fragmentSize);
215
216 FragmentationSubheader fragmentSubhdr;
217 NS_LOG_INFO("\t Latest Fragment" << std::endl);
218 fragmentSubhdr.SetFc(2); // This is the latest fragment
219 fragmentSubhdr.SetFsn(element.m_fragmentNumber);
220
221 NS_LOG_INFO("\t FragmentSize=" << fragment->GetSize() << std::endl);
222 fragment->AddHeader(fragmentSubhdr);
223
224 /*check because may be it is a bandwidth request packet (in which case a Bandwidth
225 Request Header has already been added to the packet) in which case Generic MAC Header
226 will not be added to it. this will only happen in the case of SS as only SS sends the
227 bandwidth request packet. */
229 {
230 uint8_t tmpType = element.m_hdr.GetType();
231 tmpType |= 4;
232 element.m_hdr.SetType(tmpType);
233
234 uint32_t length = fragmentSize + element.m_hdr.GetSerializedSize() +
235 fragmentSubhdr.GetSerializedSize();
236 element.m_hdr.SetLen((uint16_t)length);
237
238 fragment->AddHeader(element.m_hdr);
239 }
240 fragment->AddHeader(element.m_hdrType);
241 m_bytes -= fragmentSize;
242
243 m_traceDequeue(fragment);
244 return fragment;
245 }
246 }
247 return nullptr;
248}
249
252{
253 if (!IsEmpty())
254 {
255 NS_LOG_INFO("FRAG_DEBUG: Dequeue function" << std::endl);
256 QueueElement element = Front(packetType);
257
258 uint32_t headerSize =
259 2 + element.m_hdr.GetSerializedSize() + element.m_hdrType.GetSerializedSize();
260
261 // Create a fragment
262 uint32_t maxFragmentSize = availableByte - headerSize;
263 uint32_t fragmentOffset = element.m_fragmentOffset; // It is the latest byte sent.
264
265 Ptr<Packet> packet = element.m_packet->Copy();
266 NS_LOG_INFO("\t Create a fragment"
267 "\n\t\t availableByte="
268 << availableByte << "\n\t\t headerSize=" << headerSize
269 << "\n\t\t maxFragmentSize=" << maxFragmentSize
270 << ""
271 "\n\t\t fragmentOffset="
272 << fragmentOffset << "\n\t\t payloadSize=" << packet->GetSize() << std::endl);
273 Ptr<Packet> fragment = packet->CreateFragment(fragmentOffset, maxFragmentSize);
274 m_bytes -= maxFragmentSize;
275
276 FragmentationSubheader fragmentSubhdr;
277 if (!element.m_fragmentation)
278 {
279 NS_LOG_INFO("\t First Fragment" << std::endl);
280 SetFragmentation(packetType);
281 fragmentSubhdr.SetFc(1);
282 }
283 else
284 {
285 NS_LOG_INFO("\t Middle Fragment" << std::endl);
286 fragmentSubhdr.SetFc(3);
287 }
288 fragmentSubhdr.SetFsn(element.m_fragmentNumber);
289 NS_LOG_INFO("\t FragmentSize=" << fragment->GetSize() << std::endl);
290 fragment->AddHeader(fragmentSubhdr);
291
292 SetFragmentNumber(packetType);
293 SetFragmentOffset(packetType, maxFragmentSize);
294
295 /*check because may be it is a bandwidth request packet (in which case a Bandwidth Request
296 Header has already been added to the packet) in which case Generic MAC Header will not be
297 added to it. this will only happen in the case of SS as only SS sends the bandwidth
298 request packet. */
300 {
301 uint8_t tmpType = element.m_hdr.GetType();
302 tmpType |= 4;
303 element.m_hdr.SetType(tmpType);
304
305 uint32_t length = maxFragmentSize + element.m_hdr.GetSerializedSize() +
306 fragmentSubhdr.GetSerializedSize();
307 element.m_hdr.SetLen((uint16_t)length);
308
309 fragment->AddHeader(element.m_hdr);
310 }
311 fragment->AddHeader(element.m_hdrType);
312
313 m_traceDequeue(fragment);
314 return fragment;
315 }
316 return nullptr;
317}
318
321{
322 if (!IsEmpty())
323 {
324 QueueElement element = m_queue.front();
325 hdr = element.m_hdr;
326 Ptr<Packet> packet = element.m_packet->Copy();
327
328 // this function must not be used by SS as it may be then a bandwidth request header
329 packet->AddHeader(element.m_hdr);
330 return packet;
331 }
332
333 return nullptr;
334}
335
338{
339 if (!IsEmpty())
340 {
341 QueueElement element = m_queue.front();
342 hdr = element.m_hdr;
343 timeStamp = element.m_timeStamp;
344 Ptr<Packet> packet = element.m_packet->Copy();
345
346 // this function must not be used for by SS as it may be then a bandwidth request header
347 packet->AddHeader(element.m_hdr);
348 return packet;
349 }
350
351 return nullptr;
352}
353
356{
357 if (!IsEmpty())
358 {
359 QueueElement element = Front(packetType);
360 Ptr<Packet> packet = element.m_packet->Copy();
361
362 /*check because may be it is a bandwidth request packet (in which case a Bandwidth Request
363 Header has already been added to the packet) in which case Generic MAC Header will not be
364 added to it. this will only happen in the case of SS as only SS sends the bandwidth request
365 packet. */
367 {
368 packet->AddHeader(element.m_hdr);
369 }
370 return packet;
371 }
372
373 return nullptr;
374}
375
378{
379 if (!IsEmpty())
380 {
381 QueueElement element = Front(packetType);
382 timeStamp = element.m_timeStamp;
383 Ptr<Packet> packet = element.m_packet->Copy();
384
385 /*check because may be it is a bandwidth request packet (in which case a Bandwidth Request
386 Header has already been added to the packet) in which case Generic MAC Header will not be
387 added to it. this will only happen in the case of SS as only SS sends the bandwidth request
388 packet. */
390 {
391 packet->AddHeader(element.m_hdr);
392 }
393 return packet;
394 }
395
396 return nullptr;
397}
398
401{
402 return m_queue.size();
403}
404
407{
408 return m_bytes;
409}
410
413{
415 // Add MAC Overhead
416 queueSize += GetSize() * 6;
418 if (CheckForFragmentation(packetType))
419 {
420 queueSize += 2;
421 }
422 return queueSize;
423}
424
427{
428 QueueElement element;
429
430 for (auto iter = m_queue.begin(); iter != m_queue.end(); ++iter)
431 {
432 element = *iter;
433 if (element.m_hdrType.GetType() == packetType)
434 {
435 break;
436 }
437 }
438
439 return element;
440}
441
442void
444{
445 QueueElement element;
446
447 for (auto iter = m_queue.begin(); iter != m_queue.end(); ++iter)
448 {
449 element = *iter;
450 if (element.m_hdrType.GetType() == packetType)
451 {
452 m_queue.erase(iter);
453 break;
454 }
455 }
456}
457
458bool
460{
461 return m_queue.empty();
462}
463
464bool
466{
467 if (packetType == MacHeaderType::HEADER_TYPE_GENERIC)
468 {
469 return m_nrDataPackets == 0;
470 }
471 else
472 {
473 return m_nrRequestPackets == 0;
474 }
475
476 return true;
477}
478
481{
482 return m_queue;
483}
484
485bool
487{
488 QueueElement element;
489 for (auto iter = m_queue.begin(); iter != m_queue.end(); ++iter)
490 {
491 element = *iter;
492 if (element.m_hdrType.GetType() == packetType)
493 {
494 break;
495 }
496 }
497
498 if (element.m_fragmentation)
499 {
500 NS_LOG_INFO("FRAG_DEBUG: CheckForFragmentation"
501 "\n\t\t m_fragmentation is true "
502 << std::endl);
503 }
504
505 return element.m_fragmentation;
506}
507
510{
511 QueueElement element;
512 for (auto iter = m_queue.begin(); iter != m_queue.end(); ++iter)
513 {
514 element = *iter;
515 if (element.m_hdrType.GetType() == packetType)
516 {
517 break;
518 }
519 }
520
521 NS_LOG_INFO("\t\t GetFirstPacketHdrSize ()");
522
523 uint32_t hdrSize = 0;
525 {
526 hdrSize += element.m_hdr.GetSerializedSize();
527 NS_LOG_INFO("\t\t\t m_hdr.GetSerializedSize=" << element.m_hdr.GetSerializedSize());
528 }
529
530 hdrSize += element.m_hdrType.GetSerializedSize();
531 NS_LOG_INFO("\t\t\t m_hdrType.GetSerializedSize=" << element.m_hdrType.GetSerializedSize());
532
533 if (CheckForFragmentation(packetType))
534 {
535 NS_LOG_INFO("\t\t\t fragSubhdrSize=2");
536 hdrSize += 2;
537 }
538
539 NS_LOG_INFO("\t\t hdrSize=" << hdrSize);
540
541 return hdrSize;
542}
543
546{
547 QueueElement element;
548 for (auto iter = m_queue.begin(); iter != m_queue.end(); ++iter)
549 {
550 element = *iter;
551 if (element.m_hdrType.GetType() == packetType)
552 {
553 break;
554 }
555 }
556
557 NS_LOG_INFO("\t\t GetFirstPacketPayloadSize ()");
558
559 if (CheckForFragmentation(packetType))
560 {
561 NS_LOG_INFO("\t\t\t fullPayloadSize="
562 << element.m_packet->GetSize() << "\n\t\t\t fragmentOffset="
563 << element.m_fragmentOffset << "\n\t\t\t (fragment)payloadSize="
564 << element.m_packet->GetSize() - element.m_fragmentOffset);
565
566 return element.m_packet->GetSize() - element.m_fragmentOffset;
567 }
568 NS_LOG_INFO("\t\t payloadSize=" << element.m_packet->GetSize());
569
570 return element.m_packet->GetSize();
571}
572
575{
576 NS_LOG_INFO("\t GetFirstPacketRequiredByte ()");
577
578 uint32_t requiredByte =
579 GetFirstPacketPayloadSize(packetType) + GetFirstPacketHdrSize(packetType);
580
581 NS_LOG_INFO("\t Required Bytes = " << requiredByte << std::endl);
582
583 return requiredByte;
584}
585
586void
588{
589 for (auto iter = m_queue.begin(); iter != m_queue.end(); ++iter)
590 {
591 if (iter->m_hdrType.GetType() == packetType)
592 {
593 iter->SetFragmentation();
594 break;
595 }
596 }
597}
598
599void
601{
602 for (auto iter = m_queue.begin(); iter != m_queue.end(); ++iter)
603 {
604 if (iter->m_hdrType.GetType() == packetType)
605 {
606 iter->SetFragmentNumber();
607 break;
608 }
609 }
610}
611
612void
614{
615 for (auto iter = m_queue.begin(); iter != m_queue.end(); ++iter)
616 {
617 if (iter->m_hdrType.GetType() == packetType)
618 {
619 iter->SetFragmentOffset(offset);
620 break;
621 }
622 }
623}
624
625void
630
631void
633{
634 m_fragmentNumber++;
635}
636
637void
639{
640 m_fragmentOffset += offset;
641}
642} // 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:78
network packets
Definition packet.h:228
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition packet.h:850
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition packet.cc:120
Smart pointer class similar to boost::intrusive_ptr.
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Hold an unsigned integer type.
Definition uinteger.h:34
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:75
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition uinteger.h:35
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
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
void SetFragmentOffset(uint32_t offset)
Set fragment offset.
void SetFragmentation()
Set fragmentation.
std::ofstream queueSize