A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
bs-scheduler-rtps.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007,2008 INRIA
3 * 2009 TELEMATICS LAB, Politecnico di Bari
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: Giuseppe Piro <g.piro@poliba.it>
19 */
20
21#include "bs-scheduler-rtps.h"
22
23#include "bs-net-device.h"
25#include "cid.h"
26#include "connection-manager.h"
28#include "service-flow-record.h"
29#include "service-flow.h"
30#include "ss-manager.h"
31#include "ss-record.h"
32#include "wimax-connection.h"
33#include "wimax-mac-header.h"
34#include "wimax-mac-queue.h"
35
36#include "ns3/log.h"
37#include "ns3/packet-burst.h"
38#include "ns3/simulator.h"
39
40namespace ns3
41{
42
43NS_LOG_COMPONENT_DEFINE("BSSchedulerRtps");
44
45NS_OBJECT_ENSURE_REGISTERED(BSSchedulerRtps);
46
47TypeId
49{
50 static TypeId tid = TypeId("ns3::BSSchedulerRtps")
52 .SetGroupName("Wimax")
53 .AddConstructor<BSSchedulerRtps>();
54 return tid;
55}
56
58 : m_downlinkBursts(new std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst>>>())
59{
60 SetBs(nullptr);
61}
62
64 : m_downlinkBursts(new std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst>>>())
65{
66 // m_downlinkBursts is filled by AddDownlinkBurst and emptied by
67 // wimax-bs-net-device::sendBurst and wimax-ss-net-device::sendBurst
68 SetBs(bs);
69}
70
72{
73 std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst>>>* downlinkBursts = m_downlinkBursts;
74 std::pair<OfdmDlMapIe*, Ptr<PacketBurst>> pair;
75 while (!downlinkBursts->empty())
76 {
77 pair = downlinkBursts->front();
78 pair.second = nullptr;
79 delete pair.first;
80 }
81
82 SetBs(nullptr);
83 delete m_downlinkBursts;
84 m_downlinkBursts = nullptr;
85}
86
87std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst>>>*
89{
90 return m_downlinkBursts;
91}
92
93void
95 uint8_t diuc,
96 WimaxPhy::ModulationType modulationType,
97 Ptr<PacketBurst> burst)
98{
99 auto dlMapIe = new OfdmDlMapIe();
100 dlMapIe->SetCid(connection->GetCid());
101 dlMapIe->SetDiuc(diuc);
102
103 NS_LOG_INFO("BS scheduler, burst size: " << burst->GetSize() << " bytes"
104 << ", pkts: " << burst->GetNPackets()
105 << ", connection: " << connection->GetTypeStr()
106 << ", CID: " << connection->GetCid());
107 if (connection->GetType() == Cid::TRANSPORT)
108 {
109 NS_LOG_INFO(", SFID: " << connection->GetServiceFlow()->GetSfid() << ", service: "
110 << connection->GetServiceFlow()->GetSchedulingTypeStr());
111 }
112 NS_LOG_INFO(", modulation: " << modulationType << ", DIUC: " << (uint32_t)diuc);
113
114 m_downlinkBursts->emplace_back(dlMapIe, burst);
115}
116
117/**
118 * \brief A DownLink Scheduler for rtPS Flows
119 *
120 * The DL Scheduler assigns the available bandwidth in the following order:
121 * - IR Connections
122 * - Broadcast Connections
123 * - Basic and Primary Connections
124 * - UGS Connections
125 * - rtPS Connections
126 * - nrtPS Connections
127 * - BE Connections
128 * All rtPS flows that have packets in the queue can transmit at least one
129 * packet, according to the available bandwidth.
130 */
131void
133{
134 uint32_t availableSymbols = GetBs()->GetNrDlSymbols();
135
136 BSSchedulerBroadcastConnection(availableSymbols);
137
138 BSSchedulerInitialRangingConnection(availableSymbols);
139
140 BSSchedulerBasicConnection(availableSymbols);
141
142 BSSchedulerPrimaryConnection(availableSymbols);
143
144 BSSchedulerUGSConnection(availableSymbols);
145
146 BSSchedulerRTPSConnection(availableSymbols);
147
148 BSSchedulerNRTPSConnection(availableSymbols);
149
150 BSSchedulerBEConnection(availableSymbols);
151
152 if (!m_downlinkBursts->empty())
153 {
155 "BS scheduler, number of bursts: "
156 << m_downlinkBursts->size() << ", symbols left: " << availableSymbols << std::endl
157 << "BS scheduler, queues:"
158 << " IR " << GetBs()->GetInitialRangingConnection()->GetQueue()->GetSize()
159 << " broadcast " << GetBs()->GetBroadcastConnection()->GetQueue()->GetSize()
160 << " basic "
161 << GetBs()->GetConnectionManager()->GetNPackets(Cid::BASIC, ServiceFlow::SF_TYPE_NONE)
162 << " primary "
163 << GetBs()->GetConnectionManager()->GetNPackets(Cid::PRIMARY, ServiceFlow::SF_TYPE_NONE)
164 << " transport "
165 << GetBs()->GetConnectionManager()->GetNPackets(Cid::TRANSPORT,
167 }
168}
169
172 WimaxPhy::ModulationType modulationType,
173 uint32_t availableSymbols)
174{
175 Time timeStamp;
177 Ptr<Packet> packet;
178 Ptr<PacketBurst> burst = Create<PacketBurst>();
179 uint32_t nrSymbolsRequired = 0;
180
181 // serviceFlow->CleanUpQueue ();
182 Ptr<WimaxConnection> connection = serviceFlow->GetConnection();
183 while (serviceFlow->HasPackets())
184 {
185 uint32_t FirstPacketSize =
186 connection->GetQueue()->GetFirstPacketRequiredByte(MacHeaderType::HEADER_TYPE_GENERIC);
187 nrSymbolsRequired = GetBs()->GetPhy()->GetNrSymbols(FirstPacketSize, modulationType);
188 if (availableSymbols < nrSymbolsRequired &&
189 CheckForFragmentation(connection, availableSymbols, modulationType))
190 {
191 uint32_t availableByte =
192 GetBs()->GetPhy()->GetNrBytes(availableSymbols, modulationType);
193 packet = connection->Dequeue(MacHeaderType::HEADER_TYPE_GENERIC, availableByte);
194 availableSymbols = 0;
195 }
196 else
197 {
198 packet = connection->Dequeue();
199 availableSymbols -= nrSymbolsRequired;
200 }
201 burst->AddPacket(packet);
202 if (availableSymbols <= 0)
203 {
204 break;
205 }
206 }
207 return burst;
208}
209
210bool
212{
213 return false;
214}
215
216void
218{
219 Ptr<WimaxConnection> connection;
222 uint32_t nrSymbolsRequired = 0;
224 Ptr<Packet> packet;
225 Ptr<PacketBurst> burst = Create<PacketBurst>();
226
227 while (GetBs()->GetBroadcastConnection()->HasPackets() && availableSymbols > 0)
228 {
229 connection = GetBs()->GetBroadcastConnection();
230
231 packet = connection->GetQueue()->Peek(hdr);
232 nrSymbolsRequired = GetBs()->GetPhy()->GetNrSymbols(packet->GetSize(), modulationType);
233
234 if (availableSymbols < nrSymbolsRequired &&
235 !CheckForFragmentation(connection, availableSymbols, modulationType))
236 {
237 break;
238 }
239 else if (availableSymbols < nrSymbolsRequired &&
240 CheckForFragmentation(connection, availableSymbols, modulationType))
241 {
242 uint32_t availableByte =
243 GetBs()->GetPhy()->GetNrBytes(availableSymbols, modulationType);
244 packet = connection->Dequeue(MacHeaderType::HEADER_TYPE_GENERIC, availableByte);
245 }
246 else
247 {
248 packet = connection->Dequeue();
249 }
250
251 NS_ASSERT_MSG(hdr.GetCid().GetIdentifier() == connection->GetCid(),
252 "Base station: Error while scheduling broadcast connection: header CID != "
253 "connection CID");
254 burst->AddPacket(packet);
255 availableSymbols -= nrSymbolsRequired;
256 }
257 if (burst->GetNPackets() != 0)
258 {
259 AddDownlinkBurst(connection, diuc, modulationType, burst);
260 }
261}
262
263void
265{
266 Ptr<WimaxConnection> connection;
269 uint32_t nrSymbolsRequired = 0;
271 Ptr<Packet> packet;
272 Ptr<PacketBurst> burst = Create<PacketBurst>();
273
274 while (GetBs()->GetInitialRangingConnection()->HasPackets() && availableSymbols > 0)
275 {
276 connection = GetBs()->GetInitialRangingConnection();
277
278 packet = connection->GetQueue()->Peek(hdr);
279 nrSymbolsRequired = GetBs()->GetPhy()->GetNrSymbols(packet->GetSize(), modulationType);
280
281 // PIRO: check for fragmentation
282 if (availableSymbols < nrSymbolsRequired &&
283 !CheckForFragmentation(connection, availableSymbols, modulationType))
284 {
285 break;
286 }
287 else if (availableSymbols < nrSymbolsRequired &&
288 CheckForFragmentation(connection, availableSymbols, modulationType))
289 {
290 uint32_t availableByte =
291 GetBs()->GetPhy()->GetNrBytes(availableSymbols, modulationType);
292 packet = connection->Dequeue(MacHeaderType::HEADER_TYPE_GENERIC, availableByte);
293 }
294 else
295 {
296 packet = connection->Dequeue();
297 }
298
299 NS_ASSERT_MSG(hdr.GetCid() == connection->GetCid(),
300 "Base station: Error while scheduling initial ranging connection: header CID "
301 "!= connection CID");
302 burst->AddPacket(packet);
303 availableSymbols -= nrSymbolsRequired;
304 }
305 if (burst->GetNPackets())
306 {
307 AddDownlinkBurst(connection, diuc, modulationType, burst);
308 }
309}
310
311void
313{
314 Ptr<WimaxConnection> connection;
317 uint32_t nrSymbolsRequired = 0;
319 Ptr<Packet> packet;
320 Ptr<PacketBurst> burst = Create<PacketBurst>();
321
322 std::vector<Ptr<WimaxConnection>> connections;
323
324 connections = GetBs()->GetConnectionManager()->GetConnections(Cid::BASIC);
325 for (auto iter = connections.begin(); iter != connections.end(); ++iter)
326 {
327 while ((*iter)->HasPackets() && availableSymbols > 0)
328 {
329 connection = *iter;
330
331 modulationType =
332 GetBs()->GetSSManager()->GetSSRecord(connection->GetCid())->GetModulationType();
333 diuc = GetBs()->GetBurstProfileManager()->GetBurstProfile(
334 modulationType,
336
337 packet = connection->GetQueue()->Peek(hdr);
338 nrSymbolsRequired = GetBs()->GetPhy()->GetNrSymbols(packet->GetSize(), modulationType);
339
340 // PIRO: check for fragmentation
341 if (availableSymbols < nrSymbolsRequired &&
342 !CheckForFragmentation(connection, availableSymbols, modulationType))
343 {
344 break;
345 }
346 else if (availableSymbols < nrSymbolsRequired &&
347 CheckForFragmentation(connection, availableSymbols, modulationType))
348 {
349 uint32_t availableByte =
350 GetBs()->GetPhy()->GetNrBytes(availableSymbols, modulationType);
351 packet = connection->Dequeue(MacHeaderType::HEADER_TYPE_GENERIC, availableByte);
352 }
353 else
354 {
355 packet = connection->Dequeue();
356 }
357
358 NS_ASSERT_MSG(hdr.GetCid() == connection->GetCid(),
359 "Base station: Error while scheduling basic connection: header CID != "
360 "connection CID");
361 burst->AddPacket(packet);
362 availableSymbols -= nrSymbolsRequired;
363 }
364 if (burst->GetNPackets() != 0)
365 {
366 AddDownlinkBurst(connection, diuc, modulationType, burst);
367 burst = Create<PacketBurst>();
368 }
369 }
370}
371
372void
374{
375 Ptr<WimaxConnection> connection;
377 uint8_t diuc = 0;
378 uint32_t nrSymbolsRequired = 0;
380 Ptr<Packet> packet;
381 Ptr<PacketBurst> burst = Create<PacketBurst>();
382
383 std::vector<Ptr<WimaxConnection>> connections;
384
385 connections = GetBs()->GetConnectionManager()->GetConnections(Cid::PRIMARY);
386 for (auto iter = connections.begin(); iter != connections.end(); ++iter)
387 {
388 while ((*iter)->HasPackets() && availableSymbols > 0)
389 {
390 connection = *iter;
391
392 modulationType =
393 GetBs()->GetSSManager()->GetSSRecord(connection->GetCid())->GetModulationType();
394 diuc = GetBs()->GetBurstProfileManager()->GetBurstProfile(
395 modulationType,
397
398 packet = connection->GetQueue()->Peek(hdr);
399 nrSymbolsRequired = GetBs()->GetPhy()->GetNrSymbols(packet->GetSize(), modulationType);
400
401 // PIRO: check for fragmentation
402 if (availableSymbols < nrSymbolsRequired &&
403 !CheckForFragmentation(connection, availableSymbols, modulationType))
404 {
405 break;
406 }
407 else if (availableSymbols < nrSymbolsRequired &&
408 CheckForFragmentation(connection, availableSymbols, modulationType))
409 {
410 uint32_t availableByte =
411 GetBs()->GetPhy()->GetNrBytes(availableSymbols, modulationType);
412 packet = connection->Dequeue(MacHeaderType::HEADER_TYPE_GENERIC, availableByte);
413 }
414 else
415 {
416 packet = connection->Dequeue();
417 }
418
419 NS_ASSERT_MSG(hdr.GetCid() == connection->GetCid(),
420 "Base station: Error while scheduling primary connection: header CID != "
421 "connection CID");
422 burst->AddPacket(packet);
423 availableSymbols -= nrSymbolsRequired;
424 }
425 if (burst->GetNPackets() != 0)
426 {
427 AddDownlinkBurst(connection, diuc, modulationType, burst);
428 }
429 }
430}
431
432void
434{
435 Ptr<WimaxConnection> connection;
437 uint8_t diuc;
438 uint32_t nrSymbolsRequired = 0;
440 Ptr<Packet> packet;
441 Ptr<PacketBurst> burst = Create<PacketBurst>();
442
443 Time currentTime = Simulator::Now();
444
445 ServiceFlowRecord* serviceFlowRecord;
446 std::vector<ServiceFlow*> serviceFlows;
447
448 serviceFlows = GetBs()->GetServiceFlowManager()->GetServiceFlows(ServiceFlow::SF_TYPE_UGS);
449 for (auto iter = serviceFlows.begin(); iter != serviceFlows.end(); ++iter)
450 {
451 serviceFlowRecord = (*iter)->GetRecord();
452 // if latency would exceed in case grant is allocated in next frame then allocate in current
453 // frame
454 if ((*iter)->HasPackets() &&
455 ((currentTime - serviceFlowRecord->GetDlTimeStamp()) +
456 GetBs()->GetPhy()->GetFrameDuration()) > MilliSeconds((*iter)->GetMaximumLatency()))
457 {
458 connection = (*iter)->GetConnection();
459 if (connection->GetType() == Cid::MULTICAST)
460 {
461 modulationType = connection->GetServiceFlow()->GetModulation();
462 }
463 else
464 {
465 modulationType =
466 GetBs()->GetSSManager()->GetSSRecord(connection->GetCid())->GetModulationType();
467 }
468 diuc = GetBs()->GetBurstProfileManager()->GetBurstProfile(
469 modulationType,
471
472 nrSymbolsRequired = connection->GetServiceFlow()->GetRecord()->GetGrantSize();
473
474 // Packet fragmentation for UGS connections has not been implemented yet!
475 if (availableSymbols > nrSymbolsRequired)
476 {
477 availableSymbols -= nrSymbolsRequired;
478 burst =
479 CreateUgsBurst(connection->GetServiceFlow(), modulationType, nrSymbolsRequired);
480 if (burst->GetNPackets() != 0)
481 {
482 AddDownlinkBurst(connection, diuc, modulationType, burst);
483 currentTime = Simulator::Now();
484 serviceFlowRecord->SetDlTimeStamp(currentTime);
485 burst = Create<PacketBurst>();
486 }
487 }
488 }
489 }
490}
491
492void
494{
495 Ptr<WimaxConnection> connection;
497 Ptr<Packet> packet;
498 Ptr<PacketBurst> burst = Create<PacketBurst>();
499
500 Time currentTime = Simulator::Now();
501
502 std::vector<Ptr<WimaxConnection>> connections;
503 ServiceFlowRecord* serviceFlowRecord;
504 std::vector<ServiceFlow*> serviceFlows;
505
506 uint32_t symbolsRequired[100];
507 WimaxPhy::ModulationType modulationType_[100];
508 uint8_t diuc_[100];
509 Ptr<WimaxConnection> rtPSConnection[100];
510 uint32_t dataToSend;
511 uint32_t totSymbolsRequired = 0;
512 int nbConnection = 0;
513
514 NS_LOG_INFO("\tDL Scheduler for rtPS flows \n"
515 << "\t\tavailableSymbols = " << availableSymbols);
516
517 serviceFlows = GetBs()->GetServiceFlowManager()->GetServiceFlows(ServiceFlow::SF_TYPE_RTPS);
518 nbConnection = 0;
519 for (auto iter2 = serviceFlows.begin(); iter2 != serviceFlows.end(); ++iter2)
520 {
521 // DL RTPS Scheduler works for all rtPS connection that have packets to transmitt!!!
522 serviceFlowRecord = (*iter2)->GetRecord();
523
524 if ((*iter2)->HasPackets())
525 {
526 currentTime = Simulator::Now();
527 serviceFlowRecord->SetDlTimeStamp(currentTime);
528 rtPSConnection[nbConnection] = (*iter2)->GetConnection();
529 if (rtPSConnection[nbConnection]->GetType() == Cid::MULTICAST)
530 {
531 modulationType_[nbConnection] =
532 rtPSConnection[nbConnection]->GetServiceFlow()->GetModulation();
533 }
534 else
535 {
536 modulationType_[nbConnection] =
537 GetBs()
538 ->GetSSManager()
539 ->GetSSRecord(rtPSConnection[nbConnection]->GetCid())
540 ->GetModulationType();
541 }
542 diuc_[nbConnection] = GetBs()->GetBurstProfileManager()->GetBurstProfile(
543 modulationType_[nbConnection],
545
546 dataToSend = rtPSConnection[nbConnection]->GetQueue()->GetQueueLengthWithMACOverhead();
547 NS_LOG_INFO("\t\tRTPS DL Scheduler for CID = " << rtPSConnection[nbConnection]->GetCid()
548 << "\n\t\t\t dataToSend = "
549 << dataToSend);
550
551 symbolsRequired[nbConnection] =
552 GetBs()->GetPhy()->GetNrSymbols(dataToSend, modulationType_[nbConnection]);
553
554 totSymbolsRequired += symbolsRequired[nbConnection];
555 nbConnection++;
556 }
557 }
558
559 NS_LOG_INFO("\t\ttotSymbolsRequired = " << totSymbolsRequired);
560
561 // Channel Saturation
562 while (totSymbolsRequired > availableSymbols)
563 {
564 NS_LOG_INFO("\tDL Channel Saturation: totSymbolsRequired > availableSymbols_rtPS");
565 double delta = double(availableSymbols) / double(totSymbolsRequired);
566 NS_LOG_INFO("\t\tdelta = " << delta);
567 totSymbolsRequired = 0;
568 for (int i = 0; i < nbConnection; i++)
569 {
570 NS_LOG_INFO("\t\tprevious symbolsRequired[" << i << "] = " << symbolsRequired[i]);
571 symbolsRequired[i] = (uint32_t)std::floor(symbolsRequired[i] * delta);
572 totSymbolsRequired += symbolsRequired[i];
573 NS_LOG_INFO("\t\tnew symbolsRequired[" << i << "] = " << symbolsRequired[i]);
574 }
575 NS_LOG_INFO("\t\ttotSymbolsRequired = " << totSymbolsRequired);
576 }
577
578 // Downlink Bandwidth Allocation
579 for (int i = 0; i < nbConnection; i++)
580 {
581 packet = rtPSConnection[i]->GetQueue()->Peek(hdr);
582 uint32_t symbolsForPacketTransmission = 0;
583 burst = Create<PacketBurst>();
584 NS_LOG_INFO("\t\tCID = " << rtPSConnection[i]->GetCid()
585 << " assignedSymbols = " << symbolsRequired[i]);
586
587 while (symbolsRequired[i] > 0)
588 {
589 symbolsForPacketTransmission = GetBs()->GetPhy()->GetNrSymbols(
590 rtPSConnection[i]->GetQueue()->GetFirstPacketRequiredByte(
592 modulationType_[i]);
593
594 // PIRO: check for fragmentation
595 if (symbolsForPacketTransmission > symbolsRequired[i] &&
596 !CheckForFragmentation(rtPSConnection[i], symbolsRequired[i], modulationType_[i]))
597 {
598 break;
599 }
600 else if (symbolsForPacketTransmission > symbolsRequired[i] &&
601 CheckForFragmentation(rtPSConnection[i],
602 symbolsRequired[i],
603 modulationType_[i]))
604 {
605 uint32_t availableByte =
606 GetBs()->GetPhy()->GetNrBytes(symbolsRequired[i], modulationType_[i]);
607 packet =
608 rtPSConnection[i]->Dequeue(MacHeaderType::HEADER_TYPE_GENERIC, availableByte);
609 symbolsRequired[i] = 0;
610 }
611 else
612 {
613 packet = rtPSConnection[i]->Dequeue();
614 symbolsRequired[i] -= symbolsForPacketTransmission;
615 }
616
617 NS_ASSERT_MSG(hdr.GetCid() == rtPSConnection[i]->GetCid(),
618 "Base station: Error while scheduling RTPs connection: header CID != "
619 "connection CID");
620 burst->AddPacket(packet);
621 }
622
623 if (burst->GetNPackets() != 0)
624 {
625 AddDownlinkBurst(rtPSConnection[i], diuc_[i], modulationType_[i], burst);
626 }
627 }
628
629 availableSymbols -= totSymbolsRequired;
630}
631
632void
634{
635 Ptr<WimaxConnection> connection;
637 uint8_t diuc = 0;
638 uint32_t nrSymbolsRequired = 0;
640 Ptr<Packet> packet;
641 Ptr<PacketBurst> burst = Create<PacketBurst>();
642
643 std::vector<ServiceFlow*> serviceFlows;
644
645 serviceFlows = GetBs()->GetServiceFlowManager()->GetServiceFlows(ServiceFlow::SF_TYPE_NRTPS);
646 for (auto iter = serviceFlows.begin(); iter != serviceFlows.end(); ++iter)
647 {
648 connection = (*iter)->GetConnection();
649
650 while ((*iter)->HasPackets() && availableSymbols > 0)
651 {
652 if (connection->GetType() == Cid::MULTICAST)
653 {
654 modulationType = connection->GetServiceFlow()->GetModulation();
655 }
656 else
657 {
658 modulationType =
659 GetBs()->GetSSManager()->GetSSRecord(connection->GetCid())->GetModulationType();
660 }
661
662 diuc = GetBs()->GetBurstProfileManager()->GetBurstProfile(
663 modulationType,
665
666 packet = connection->GetQueue()->Peek(hdr);
667 nrSymbolsRequired = GetBs()->GetPhy()->GetNrSymbols(packet->GetSize(), modulationType);
668
669 if (availableSymbols < nrSymbolsRequired)
670 {
671 break;
672 }
673
674 packet = connection->Dequeue();
675 NS_ASSERT_MSG(hdr.GetCid() == connection->GetCid(),
676 "Base station: Error while scheduling NRTPs connection: header CID != "
677 "connection CID");
678 burst->AddPacket(packet);
679 availableSymbols -= nrSymbolsRequired;
680 }
681 if (burst->GetNPackets() != 0)
682 {
683 AddDownlinkBurst(connection, diuc, modulationType, burst);
684 burst = Create<PacketBurst>();
685 }
686 }
687}
688
689void
691{
692 Ptr<WimaxConnection> connection;
694 uint8_t diuc = 0;
695 uint32_t nrSymbolsRequired = 0;
697 Ptr<Packet> packet;
698 Ptr<PacketBurst> burst = Create<PacketBurst>();
699
700 std::vector<ServiceFlow*> serviceFlows;
701
702 serviceFlows = GetBs()->GetServiceFlowManager()->GetServiceFlows(ServiceFlow::SF_TYPE_BE);
703 for (auto iter = serviceFlows.begin(); iter != serviceFlows.end(); ++iter)
704 {
705 connection = (*iter)->GetConnection();
706
707 while ((*iter)->HasPackets() && availableSymbols > 0)
708 {
709 if (connection->GetType() == Cid::MULTICAST)
710 {
711 modulationType = connection->GetServiceFlow()->GetModulation();
712 }
713 else
714 {
715 modulationType =
716 GetBs()->GetSSManager()->GetSSRecord(connection->GetCid())->GetModulationType();
717 }
718 diuc = GetBs()->GetBurstProfileManager()->GetBurstProfile(
719 modulationType,
721
722 packet = connection->GetQueue()->Peek(hdr);
723 nrSymbolsRequired = GetBs()->GetPhy()->GetNrSymbols(packet->GetSize(), modulationType);
724
725 if (availableSymbols < nrSymbolsRequired)
726 {
727 break;
728 }
729
730 packet = connection->Dequeue();
732 hdr.GetCid() == connection->GetCid(),
733 "Base station: Error while scheduling BE connection: header CID != connection CID");
734 burst->AddPacket(packet);
735 availableSymbols -= nrSymbolsRequired;
736 }
737 if (burst->GetNPackets() != 0)
738 {
739 AddDownlinkBurst(connection, diuc, modulationType, burst);
740 burst = Create<PacketBurst>();
741 }
742 }
743}
744
745} // namespace ns3
BaseStation Scheduler.
Definition: bs-scheduler.h:48
virtual Ptr< BaseStationNetDevice > GetBs()
Get the base station.
Definition: bs-scheduler.cc:89
virtual void SetBs(Ptr< BaseStationNetDevice > bs)
Set the base station.
Definition: bs-scheduler.cc:83
bool CheckForFragmentation(Ptr< WimaxConnection > connection, int availableSymbols, WimaxPhy::ModulationType modulationType)
Check if the packet fragmentation is possible for transport connection.
Definition: bs-scheduler.cc:95
This class implements a simple downlink scheduler for rtPS flows.
static TypeId GetTypeId()
Get the type ID.
void Schedule() override
Schedule function.
void BSSchedulerPrimaryConnection(uint32_t &availableSymbols)
schedules the primary connection
std::list< std::pair< OfdmDlMapIe *, Ptr< PacketBurst > > > * GetDownlinkBursts() const override
This function returns all the downlink bursts scheduled for the next downlink sub-frame.
void BSSchedulerUGSConnection(uint32_t &availableSymbols)
schedules the UGS connection
void BSSchedulerBEConnection(uint32_t &availableSymbols)
schedules the BE connection
void BSSchedulerBasicConnection(uint32_t &availableSymbols)
schedules the basic connections
void AddDownlinkBurst(Ptr< const WimaxConnection > connection, uint8_t diuc, WimaxPhy::ModulationType modulationType, Ptr< PacketBurst > burst) override
This function adds a downlink burst to the list of downlink bursts scheduled for the next downlink su...
void BSSchedulerInitialRangingConnection(uint32_t &availableSymbols)
schedules the IR connections
void BSSchedulerRTPSConnection(uint32_t &availableSymbols)
Downlink Scheduler for rtPS connections.
void BSSchedulerBroadcastConnection(uint32_t &availableSymbols)
schedules the broadcast connections
void BSSchedulerNRTPSConnection(uint32_t &availableSymbols)
schedules the NRTPS connections
Ptr< PacketBurst > CreateUgsBurst(ServiceFlow *serviceFlow, WimaxPhy::ModulationType modulationType, uint32_t availableSymbols) override
Creates a downlink UGS burst.
bool SelectConnection(Ptr< WimaxConnection > &connection) override
Selects a connection from the list of connections having packets to be sent .
std::list< std::pair< OfdmDlMapIe *, Ptr< PacketBurst > > > * m_downlinkBursts
down link bursts
@ PRIMARY
Definition: cid.h:45
@ TRANSPORT
Definition: cid.h:46
@ MULTICAST
Definition: cid.h:47
@ BASIC
Definition: cid.h:44
uint16_t GetIdentifier() const
Definition: cid.cc:45
This class implements the Generic mac Header as described by IEEE Standard for Local and metropolitan...
Cid GetCid() const
Get CID field.
This class implements the OFDM DL-MAP information element as described by "IEEE Standard for Local an...
this class implement a burst as a list of packets
Definition: packet-burst.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
This class implements service flows as described by the IEEE-802.16 standard.
Definition: service-flow.h:43
bool HasPackets() const
Check if packets are present.
Ptr< WimaxConnection > GetConnection() const
Can return a null connection is this service flow has not been associated yet to a connection.
this class implements a structure to manage some parameters and statistics related to a service flow
void SetDlTimeStamp(Time dlTimeStamp)
Set the DlTimeStamp.
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
ModulationType
ModulationType enumeration.
Definition: wimax-phy.h:54
@ MODULATION_TYPE_BPSK_12
Definition: wimax-phy.h:55
#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
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#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
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint32_t GetSize(Ptr< const Packet > packet, const WifiMacHeader *hdr, bool isAmpdu)
Return the total size of the packet after WifiMacHeader and FCS trailer have been added.
Definition: wifi-utils.cc:132
STL namespace.
#define list