22 #include "bs-scheduler-rtps.h"
23 #include "ns3/simulator.h"
24 #include "bs-net-device.h"
25 #include "ns3/packet-burst.h"
27 #include "wimax-mac-header.h"
28 #include "ss-record.h"
29 #include "wimax-mac-queue.h"
31 #include "burst-profile-manager.h"
32 #include "wimax-connection.h"
33 #include "connection-manager.h"
34 #include "ss-manager.h"
35 #include "service-flow.h"
36 #include "service-flow-record.h"
37 #include "service-flow-manager.h"
38 #include "wimax-mac-queue.h"
44 NS_OBJECT_ENSURE_REGISTERED (BSSchedulerRtps);
47 BSSchedulerRtps::GetTypeId (
void)
49 static TypeId tid = TypeId (
"ns3::BSSchedulerRtps").SetParent<Object> ().AddConstructor<BSSchedulerRtps> ();
53 BSSchedulerRtps::BSSchedulerRtps ()
54 : m_downlinkBursts (new std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > > ())
59 BSSchedulerRtps::BSSchedulerRtps (Ptr<BaseStationNetDevice> bs)
60 : m_downlinkBursts (new std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > > ())
67 BSSchedulerRtps::~BSSchedulerRtps (
void)
70 std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > > *downlinkBursts = m_downlinkBursts;
71 std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > pair;
72 while (downlinkBursts->size ())
74 pair = downlinkBursts->front ();
80 delete m_downlinkBursts;
84 std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > >*
85 BSSchedulerRtps::GetDownlinkBursts (
void)
const
87 return m_downlinkBursts;
91 BSSchedulerRtps::AddDownlinkBurst (Ptr<const WimaxConnection> connection,
93 WimaxPhy::ModulationType modulationType,
94 Ptr<PacketBurst> burst)
96 OfdmDlMapIe *dlMapIe =
new OfdmDlMapIe ();
97 dlMapIe->SetCid (connection->GetCid ());
98 dlMapIe->SetDiuc (diuc);
100 NS_LOG_INFO (
"BS scheduler, burst size: " << burst->GetSize () <<
" bytes" <<
", pkts: " << burst->GetNPackets ()
101 <<
", connection: " << connection->GetTypeStr () <<
", CID: "
102 << connection->GetCid ());
103 if (connection->GetType () == Cid::TRANSPORT)
105 NS_LOG_INFO (
", SFID: " << connection->GetServiceFlow ()->GetSfid () <<
", service: "
106 << connection->GetServiceFlow ()->GetSchedulingTypeStr ());
108 NS_LOG_INFO (
", modulation: " << modulationType <<
", DIUC: " << (uint32_t) diuc);
110 m_downlinkBursts->push_back (std::make_pair (dlMapIe, burst));
131 uint32_t availableSymbols = GetBs ()->GetNrDlSymbols ();
133 BSSchedulerBroadcastConnection (availableSymbols);
135 BSSchedulerInitialRangingConnection (availableSymbols);
137 BSSchedulerBasicConnection (availableSymbols);
139 BSSchedulerPrimaryConnection (availableSymbols);
141 BSSchedulerUGSConnection (availableSymbols);
145 BSSchedulerNRTPSConnection (availableSymbols);
147 BSSchedulerBEConnection (availableSymbols);
149 if (m_downlinkBursts->size ())
151 NS_LOG_DEBUG (
"BS scheduler, number of bursts: " << m_downlinkBursts->size () <<
", symbols left: "
152 << availableSymbols << std::endl <<
"BS scheduler, queues:" <<
" IR "
153 << GetBs ()->GetInitialRangingConnection ()->GetQueue ()->GetSize ()
155 << GetBs ()->GetBroadcastConnection ()->GetQueue ()->GetSize ()
157 << GetBs ()->GetConnectionManager ()->GetNPackets (Cid::BASIC, ServiceFlow::SF_TYPE_NONE)
159 << GetBs ()->GetConnectionManager ()->GetNPackets (Cid::PRIMARY, ServiceFlow::SF_TYPE_NONE)
161 << GetBs ()->GetConnectionManager ()->GetNPackets (Cid::TRANSPORT, ServiceFlow::SF_TYPE_ALL));
167 WimaxPhy::ModulationType modulationType,
168 uint32_t availableSymbols)
174 uint32_t nrSymbolsRequired = 0;
178 while (serviceFlow->HasPackets ())
180 uint32_t FirstPacketSize = connection->GetQueue ()->GetFirstPacketRequiredByte (MacHeaderType::HEADER_TYPE_GENERIC);
181 nrSymbolsRequired = GetBs ()->GetPhy ()->GetNrSymbols (FirstPacketSize,modulationType);
182 if (availableSymbols < nrSymbolsRequired && CheckForFragmentation (connection,
186 uint32_t availableByte = GetBs ()->GetPhy ()->GetNrBytes (availableSymbols, modulationType);
187 packet = connection->Dequeue (MacHeaderType::HEADER_TYPE_GENERIC, availableByte);
188 availableSymbols = 0;
192 packet = connection->Dequeue ();
193 availableSymbols -= nrSymbolsRequired;
195 burst->AddPacket (packet);
196 if (availableSymbols <= 0)
206 BSSchedulerRtps::SelectConnection (Ptr<WimaxConnection> &connection)
212 BSSchedulerRtps::BSSchedulerBroadcastConnection (uint32_t &availableSymbols)
214 Ptr<WimaxConnection> connection;
215 WimaxPhy::ModulationType modulationType = WimaxPhy::MODULATION_TYPE_BPSK_12;
216 uint8_t diuc = OfdmDlBurstProfile::DIUC_BURST_PROFILE_1;
217 uint32_t nrSymbolsRequired = 0;
218 GenericMacHeader hdr;
220 Ptr<PacketBurst> burst = Create<PacketBurst> ();
222 while (GetBs ()->GetBroadcastConnection ()->HasPackets () && availableSymbols > 0)
224 connection = GetBs ()->GetBroadcastConnection ();
226 packet = connection->GetQueue ()->Peek (hdr);
227 nrSymbolsRequired = GetBs ()->GetPhy ()->GetNrSymbols (packet->GetSize (), modulationType);
229 if (availableSymbols < nrSymbolsRequired
230 && !CheckForFragmentation (connection, availableSymbols, modulationType))
234 else if (availableSymbols < nrSymbolsRequired
235 && CheckForFragmentation (connection, availableSymbols, modulationType))
237 uint32_t availableByte = GetBs ()->GetPhy ()->
238 GetNrBytes (availableSymbols, modulationType);
239 packet = connection->Dequeue (MacHeaderType::HEADER_TYPE_GENERIC,
244 packet = connection->Dequeue ();
247 NS_ASSERT_MSG (hdr.GetCid ().GetIdentifier () == connection->GetCid (),
248 "Base station: Error while scheduling broadcast connection: header CID != connection CID");
249 burst->AddPacket (packet);
250 availableSymbols -= nrSymbolsRequired;
252 if (burst->GetNPackets () != 0)
254 AddDownlinkBurst (connection, diuc, modulationType, burst);
259 BSSchedulerRtps::BSSchedulerInitialRangingConnection (uint32_t &availableSymbols)
261 Ptr<WimaxConnection> connection;
262 WimaxPhy::ModulationType modulationType = WimaxPhy::MODULATION_TYPE_BPSK_12;
263 uint8_t diuc = OfdmDlBurstProfile::DIUC_BURST_PROFILE_1;
264 uint32_t nrSymbolsRequired = 0;
265 GenericMacHeader hdr;
267 Ptr<PacketBurst> burst = Create<PacketBurst> ();
269 while (GetBs ()->GetInitialRangingConnection ()->HasPackets () && availableSymbols > 0)
271 connection = GetBs ()->GetInitialRangingConnection ();
273 packet = connection->GetQueue ()->Peek (hdr);
274 nrSymbolsRequired = GetBs ()->GetPhy ()->GetNrSymbols (packet->GetSize (), modulationType);
277 if (availableSymbols < nrSymbolsRequired
278 && !CheckForFragmentation (connection, availableSymbols, modulationType))
282 else if (availableSymbols < nrSymbolsRequired
283 && CheckForFragmentation (connection, availableSymbols, modulationType))
285 uint32_t availableByte = GetBs ()->GetPhy ()->
286 GetNrBytes (availableSymbols, modulationType);
287 packet = connection->Dequeue (MacHeaderType::HEADER_TYPE_GENERIC,
292 packet = connection->Dequeue ();
296 "Base station: Error while scheduling initial ranging connection: header CID != connection CID");
297 burst->AddPacket (packet);
298 availableSymbols -= nrSymbolsRequired;
300 if (burst->GetNPackets ())
302 AddDownlinkBurst (connection, diuc, modulationType, burst);
307 BSSchedulerRtps::BSSchedulerBasicConnection (uint32_t &availableSymbols)
309 Ptr<WimaxConnection> connection;
310 WimaxPhy::ModulationType modulationType = WimaxPhy::MODULATION_TYPE_BPSK_12;
311 uint8_t diuc = OfdmDlBurstProfile::DIUC_BURST_PROFILE_1;
312 uint32_t nrSymbolsRequired = 0;
313 GenericMacHeader hdr;
315 Ptr<PacketBurst> burst = Create<PacketBurst> ();
317 std::vector<Ptr<WimaxConnection> >::const_iterator iter;
318 std::vector<Ptr<WimaxConnection> > connections;
320 connections = GetBs ()->GetConnectionManager ()->GetConnections (Cid::BASIC);
321 for (iter = connections.begin (); iter != connections.end (); ++iter)
323 while ((*iter)->HasPackets () && availableSymbols > 0)
327 modulationType = GetBs ()->GetSSManager ()->GetSSRecord (connection->GetCid ())->GetModulationType ();
328 diuc = GetBs ()->GetBurstProfileManager ()->GetBurstProfile (modulationType,
329 WimaxNetDevice::DIRECTION_DOWNLINK);
331 packet = connection->GetQueue ()->Peek (hdr);
332 nrSymbolsRequired = GetBs ()->GetPhy ()->GetNrSymbols (packet->GetSize (), modulationType);
335 if (availableSymbols < nrSymbolsRequired
336 && !CheckForFragmentation (connection, availableSymbols, modulationType))
340 else if (availableSymbols < nrSymbolsRequired
341 && CheckForFragmentation (connection, availableSymbols, modulationType))
343 uint32_t availableByte = GetBs ()->GetPhy ()->
344 GetNrBytes (availableSymbols, modulationType);
345 packet = connection->Dequeue (MacHeaderType::HEADER_TYPE_GENERIC, availableByte);
349 packet = connection->Dequeue ();
353 "Base station: Error while scheduling basic connection: header CID != connection CID");
354 burst->AddPacket (packet);
355 availableSymbols -= nrSymbolsRequired;
357 if (burst->GetNPackets () != 0)
359 AddDownlinkBurst (connection, diuc, modulationType, burst);
360 burst = Create<PacketBurst> ();
366 BSSchedulerRtps::BSSchedulerPrimaryConnection (uint32_t &availableSymbols)
368 Ptr<WimaxConnection> connection;
369 WimaxPhy::ModulationType modulationType = WimaxPhy::MODULATION_TYPE_BPSK_12;
371 uint32_t nrSymbolsRequired = 0;
372 GenericMacHeader hdr;
374 Ptr<PacketBurst> burst = Create<PacketBurst> ();
376 std::vector<Ptr<WimaxConnection> >::const_iterator iter;
377 std::vector<Ptr<WimaxConnection> > connections;
379 connections = GetBs ()->GetConnectionManager ()->GetConnections (Cid::PRIMARY);
380 for (iter = connections.begin (); iter != connections.end (); ++iter)
382 while ((*iter)->HasPackets () && availableSymbols > 0)
386 modulationType = GetBs ()->GetSSManager ()->GetSSRecord (connection->GetCid ())->GetModulationType ();
387 diuc = GetBs ()->GetBurstProfileManager ()->GetBurstProfile (modulationType,
388 WimaxNetDevice::DIRECTION_DOWNLINK);
390 packet = connection->GetQueue ()->Peek (hdr);
391 nrSymbolsRequired = GetBs ()->GetPhy ()->GetNrSymbols (packet->GetSize (), modulationType);
394 if (availableSymbols < nrSymbolsRequired
395 && !CheckForFragmentation (connection, availableSymbols, modulationType))
399 else if (availableSymbols < nrSymbolsRequired
400 && CheckForFragmentation (connection, availableSymbols, modulationType))
402 uint32_t availableByte = GetBs ()->GetPhy ()->
403 GetNrBytes (availableSymbols, modulationType);
404 packet = connection->Dequeue (MacHeaderType::HEADER_TYPE_GENERIC, availableByte);
408 packet = connection->Dequeue ();
412 "Base station: Error while scheduling primary connection: header CID != connection CID");
413 burst->AddPacket (packet);
414 availableSymbols -= nrSymbolsRequired;
416 if (burst->GetNPackets () != 0)
418 AddDownlinkBurst (connection, diuc, modulationType, burst);
424 BSSchedulerRtps::BSSchedulerUGSConnection (uint32_t &availableSymbols)
426 Ptr<WimaxConnection> connection;
427 WimaxPhy::ModulationType modulationType = WimaxPhy::MODULATION_TYPE_BPSK_12;
429 uint32_t nrSymbolsRequired = 0;
430 GenericMacHeader hdr;
432 Ptr<PacketBurst> burst = Create<PacketBurst> ();
436 std::vector<ServiceFlow*>::iterator iter;
437 ServiceFlowRecord *serviceFlowRecord;
438 std::vector<ServiceFlow*> serviceFlows;
440 serviceFlows = GetBs ()->GetServiceFlowManager ()->GetServiceFlows (ServiceFlow::SF_TYPE_UGS);
441 for (iter = serviceFlows.begin (); iter != serviceFlows.end (); ++iter)
443 serviceFlowRecord = (*iter)->GetRecord ();
445 if ((*iter)->HasPackets () && ((currentTime - serviceFlowRecord->GetDlTimeStamp ())
446 + GetBs ()->GetPhy ()->GetFrameDuration ()) >
MilliSeconds ((*iter)->GetMaximumLatency ()))
448 connection = (*iter)->GetConnection ();
449 if (connection->GetType () == Cid::MULTICAST)
451 modulationType = connection->GetServiceFlow ()->GetModulation ();
455 modulationType = GetBs ()->GetSSManager ()->GetSSRecord (connection->GetCid ())->GetModulationType ();
457 diuc = GetBs ()->GetBurstProfileManager ()->GetBurstProfile (modulationType,
458 WimaxNetDevice::DIRECTION_DOWNLINK);
460 nrSymbolsRequired = connection->GetServiceFlow ()->GetRecord ()->GetGrantSize ();
463 if (availableSymbols > nrSymbolsRequired)
465 availableSymbols -= nrSymbolsRequired;
466 burst = CreateUgsBurst (connection->GetServiceFlow (), modulationType, nrSymbolsRequired);
467 if (burst->GetNPackets () != 0)
469 AddDownlinkBurst (connection, diuc, modulationType, burst);
471 serviceFlowRecord->SetDlTimeStamp (currentTime);
472 burst = Create<PacketBurst> ();
491 std::vector<Ptr<WimaxConnection> >::const_iterator iter;
492 std::vector<Ptr<WimaxConnection> > connections;
493 std::vector<ServiceFlow*>::iterator iter2;
495 std::vector<ServiceFlow*> serviceFlows;
497 uint32_t symbolsRequired[100];
498 WimaxPhy::ModulationType modulationType_[100];
502 uint32_t totSymbolsRequired = 0;
503 int nbConnection = 0;
505 NS_LOG_INFO (
"\tDL Scheduler for rtPS flows \n" <<
"\t\tavailableSymbols = " << availableSymbols);
507 serviceFlows = GetBs ()->GetServiceFlowManager ()->GetServiceFlows (ServiceFlow::SF_TYPE_RTPS);
509 for (iter2 = serviceFlows.begin (); iter2 != serviceFlows.end (); ++iter2)
512 serviceFlowRecord = (*iter2)->GetRecord ();
514 if ((*iter2)->HasPackets ())
518 rtPSConnection[nbConnection] = (*iter2)->GetConnection ();
519 if (rtPSConnection[nbConnection]->GetType () == Cid::MULTICAST)
521 modulationType_[nbConnection] = rtPSConnection[nbConnection]->GetServiceFlow ()->GetModulation ();
525 modulationType_[nbConnection]
526 = GetBs ()->GetSSManager ()->GetSSRecord (rtPSConnection[nbConnection]->GetCid ())->GetModulationType ();
529 = GetBs ()->GetBurstProfileManager ()->GetBurstProfile (modulationType_[nbConnection],
530 WimaxNetDevice::DIRECTION_DOWNLINK);
532 dataToSend = rtPSConnection[nbConnection]->GetQueue ()->GetQueueLengthWithMACOverhead ();
533 NS_LOG_INFO (
"\t\tRTPS DL Scheduler for CID = " << rtPSConnection[nbConnection]->GetCid ()
534 <<
"\n\t\t\t dataToSend = " << dataToSend);
536 symbolsRequired[nbConnection] = GetBs ()->GetPhy ()->GetNrSymbols (dataToSend,
537 modulationType_[nbConnection]);
539 totSymbolsRequired += symbolsRequired[nbConnection];
544 NS_LOG_INFO (
"\t\ttotSymbolsRequired = " << totSymbolsRequired);
547 while (totSymbolsRequired > availableSymbols)
549 NS_LOG_INFO (
"\tDL Channel Saturation: totSymbolsRequired > availableSymbols_rtPS");
550 double delta = double(availableSymbols) / double(totSymbolsRequired);
552 totSymbolsRequired = 0;
553 for (
int i = 0; i < nbConnection; i++)
555 NS_LOG_INFO (
"\t\tprevious symbolsRequired[" << i <<
"] = " << symbolsRequired[i]);
556 symbolsRequired[i] = (uint32_t) std::floor (symbolsRequired[i] * delta);
557 totSymbolsRequired += symbolsRequired[i];
558 NS_LOG_INFO (
"\t\tnew symbolsRequired[" << i <<
"] = " << symbolsRequired[i]);
560 NS_LOG_INFO (
"\t\ttotSymbolsRequired = " << totSymbolsRequired);
564 for (
int i = 0; i < nbConnection; i++)
567 packet = rtPSConnection[i]->GetQueue ()->Peek (hdr);
568 uint32_t symbolsForPacketTransmission = 0;
569 burst = Create<PacketBurst> ();
570 NS_LOG_INFO (
"\t\tCID = " << rtPSConnection[i]->GetCid () <<
" assignedSymbols = " << symbolsRequired[i]);
572 while (symbolsRequired[i] > 0)
574 symbolsForPacketTransmission = GetBs ()->GetPhy ()
575 ->GetNrSymbols (rtPSConnection[i]->GetQueue ()
576 ->GetFirstPacketRequiredByte (MacHeaderType::HEADER_TYPE_GENERIC),
580 if (symbolsForPacketTransmission > symbolsRequired[i]
581 && !CheckForFragmentation (rtPSConnection[i],
587 else if (symbolsForPacketTransmission > symbolsRequired[i]
588 && CheckForFragmentation (rtPSConnection[i],
592 uint32_t availableByte = GetBs ()->GetPhy ()->
593 GetNrBytes (symbolsRequired[i], modulationType_[i]);
594 packet = rtPSConnection[i]->Dequeue (MacHeaderType::HEADER_TYPE_GENERIC, availableByte);
595 symbolsRequired[i] = 0;
599 packet = rtPSConnection[i]->Dequeue ();
600 symbolsRequired[i] -= symbolsForPacketTransmission;
603 NS_ASSERT_MSG (hdr.GetCid () == rtPSConnection[i]->GetCid (),
604 "Base station: Error while scheduling RTPs connection: header CID != connection CID");
605 burst->AddPacket (packet);
608 if (burst->GetNPackets () != 0)
610 AddDownlinkBurst (rtPSConnection[i], diuc_[i], modulationType_[i], burst);
614 availableSymbols -= totSymbolsRequired;
618 BSSchedulerRtps::BSSchedulerNRTPSConnection (uint32_t &availableSymbols)
621 WimaxPhy::ModulationType modulationType = WimaxPhy::MODULATION_TYPE_BPSK_12;
623 uint32_t nrSymbolsRequired = 0;
628 std::vector<ServiceFlow*>::iterator iter;
629 std::vector<ServiceFlow*> serviceFlows;
631 serviceFlows = GetBs ()->GetServiceFlowManager ()->GetServiceFlows (ServiceFlow::SF_TYPE_NRTPS);
632 for (iter = serviceFlows.begin (); iter != serviceFlows.end (); ++iter)
634 connection = (*iter)->GetConnection ();
636 while ((*iter)->HasPackets () && availableSymbols > 0)
638 if (connection->GetType () == Cid::MULTICAST)
640 modulationType = connection->GetServiceFlow ()->GetModulation ();
644 modulationType = GetBs ()->GetSSManager ()->GetSSRecord (connection->GetCid ())->GetModulationType ();
647 diuc = GetBs ()->GetBurstProfileManager ()->GetBurstProfile (modulationType,
648 WimaxNetDevice::DIRECTION_DOWNLINK);
650 packet = connection->GetQueue ()->Peek (hdr);
651 nrSymbolsRequired = GetBs ()->GetPhy ()->GetNrSymbols (packet->
GetSize (), modulationType);
653 if (availableSymbols < nrSymbolsRequired)
658 packet = connection->Dequeue ();
660 "Base station: Error while scheduling NRTPs connection: header CID != connection CID");
661 burst->AddPacket (packet);
662 availableSymbols -= nrSymbolsRequired;
664 if (burst->GetNPackets () != 0)
666 AddDownlinkBurst (connection, diuc, modulationType, burst);
667 burst = Create<PacketBurst> ();
673 BSSchedulerRtps::BSSchedulerBEConnection (uint32_t &availableSymbols)
675 Ptr<WimaxConnection> connection;
676 WimaxPhy::ModulationType modulationType = WimaxPhy::MODULATION_TYPE_BPSK_12;
678 uint32_t nrSymbolsRequired = 0;
679 GenericMacHeader hdr;
681 Ptr<PacketBurst> burst = Create<PacketBurst> ();
683 std::vector<ServiceFlow*>::iterator iter;
684 std::vector<ServiceFlow*> serviceFlows;
686 serviceFlows = GetBs ()->GetServiceFlowManager ()->GetServiceFlows (ServiceFlow::SF_TYPE_BE);
687 for (iter = serviceFlows.begin (); iter != serviceFlows.end (); ++iter)
689 connection = (*iter)->GetConnection ();
691 while ((*iter)->HasPackets () && availableSymbols > 0)
693 if (connection->GetType () == Cid::MULTICAST)
695 modulationType = connection->GetServiceFlow ()->GetModulation ();
699 modulationType = GetBs ()->GetSSManager ()->GetSSRecord (connection->GetCid ())->GetModulationType ();
701 diuc = GetBs ()->GetBurstProfileManager ()->GetBurstProfile (modulationType,
702 WimaxNetDevice::DIRECTION_DOWNLINK);
704 packet = connection->GetQueue ()->Peek (hdr);
705 nrSymbolsRequired = GetBs ()->GetPhy ()->GetNrSymbols (packet->GetSize (), modulationType);
707 if (availableSymbols < nrSymbolsRequired)
712 packet = connection->Dequeue ();
714 "Base station: Error while scheduling BE connection: header CID != connection CID");
715 burst->AddPacket (packet);
716 availableSymbols -= nrSymbolsRequired;
718 if (burst->GetNPackets () != 0)
720 AddDownlinkBurst (connection, diuc, modulationType, burst);
721 burst = Create<PacketBurst> ();
smart pointer class similar to boost::intrusive_ptr
this class implements a structure to manage some parameters and statistics related to a service flow ...
#define NS_LOG_COMPONENT_DEFINE(name)
uint32_t GetSize(void) const
void BSSchedulerRTPSConnection(uint32_t &availableSymbols)
Downlink Scheduler for rtPS connections.
#define NS_ASSERT_MSG(condition, message)
void Schedule(void)
Schedule function.
void SetDlTimeStamp(Time dlTimeStamp)
Set the DlTimeStamp.
#define NS_LOG_DEBUG(msg)
Time MilliSeconds(uint64_t ms)
create ns3::Time instances in units of milliseconds.