37 #include "ns3/packet-burst.h"
38 #include "ns3/simulator.h"
52 .SetGroupName(
"Wimax")
73 std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst>>>* downlinkBursts =
m_downlinkBursts;
74 std::pair<OfdmDlMapIe*, Ptr<PacketBurst>> pair;
75 while (!downlinkBursts->empty())
77 pair = downlinkBursts->front();
78 pair.second =
nullptr;
87 std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst>>>*
100 dlMapIe->SetCid(connection->GetCid());
101 dlMapIe->SetDiuc(diuc);
103 NS_LOG_INFO(
"BS scheduler, burst size: " << burst->GetSize() <<
" bytes"
104 <<
", pkts: " << burst->GetNPackets()
105 <<
", connection: " << connection->GetTypeStr()
106 <<
", CID: " << connection->GetCid());
109 NS_LOG_INFO(
", SFID: " << connection->GetServiceFlow()->GetSfid() <<
", service: "
110 << connection->GetServiceFlow()->GetSchedulingTypeStr());
112 NS_LOG_INFO(
", modulation: " << modulationType <<
", DIUC: " << (uint32_t)diuc);
134 uint32_t availableSymbols =
GetBs()->GetNrDlSymbols();
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()
173 uint32_t availableSymbols)
179 uint32_t nrSymbolsRequired = 0;
185 uint32_t FirstPacketSize =
187 nrSymbolsRequired =
GetBs()->GetPhy()->GetNrSymbols(FirstPacketSize, modulationType);
188 if (availableSymbols < nrSymbolsRequired &&
191 uint32_t availableByte =
192 GetBs()->GetPhy()->GetNrBytes(availableSymbols, modulationType);
194 availableSymbols = 0;
198 packet = connection->Dequeue();
199 availableSymbols -= nrSymbolsRequired;
201 burst->AddPacket(packet);
202 if (availableSymbols <= 0)
222 uint32_t nrSymbolsRequired = 0;
227 while (
GetBs()->GetBroadcastConnection()->HasPackets() && availableSymbols > 0)
229 connection =
GetBs()->GetBroadcastConnection();
231 packet = connection->GetQueue()->Peek(hdr);
232 nrSymbolsRequired =
GetBs()->GetPhy()->GetNrSymbols(packet->
GetSize(), modulationType);
234 if (availableSymbols < nrSymbolsRequired &&
239 else if (availableSymbols < nrSymbolsRequired &&
242 uint32_t availableByte =
243 GetBs()->GetPhy()->GetNrBytes(availableSymbols, modulationType);
248 packet = connection->Dequeue();
252 "Base station: Error while scheduling broadcast connection: header CID != "
254 burst->AddPacket(packet);
255 availableSymbols -= nrSymbolsRequired;
257 if (burst->GetNPackets() != 0)
269 uint32_t nrSymbolsRequired = 0;
274 while (
GetBs()->GetInitialRangingConnection()->HasPackets() && availableSymbols > 0)
276 connection =
GetBs()->GetInitialRangingConnection();
278 packet = connection->GetQueue()->Peek(hdr);
279 nrSymbolsRequired =
GetBs()->GetPhy()->GetNrSymbols(packet->
GetSize(), modulationType);
282 if (availableSymbols < nrSymbolsRequired &&
287 else if (availableSymbols < nrSymbolsRequired &&
290 uint32_t availableByte =
291 GetBs()->GetPhy()->GetNrBytes(availableSymbols, modulationType);
296 packet = connection->Dequeue();
300 "Base station: Error while scheduling initial ranging connection: header CID "
301 "!= connection CID");
302 burst->AddPacket(packet);
303 availableSymbols -= nrSymbolsRequired;
305 if (burst->GetNPackets())
317 uint32_t nrSymbolsRequired = 0;
322 std::vector<Ptr<WimaxConnection>> connections;
324 connections =
GetBs()->GetConnectionManager()->GetConnections(
Cid::BASIC);
325 for (
auto iter = connections.begin(); iter != connections.end(); ++iter)
327 while ((*iter)->HasPackets() && availableSymbols > 0)
332 GetBs()->GetSSManager()->GetSSRecord(connection->GetCid())->GetModulationType();
333 diuc =
GetBs()->GetBurstProfileManager()->GetBurstProfile(
337 packet = connection->GetQueue()->Peek(hdr);
338 nrSymbolsRequired =
GetBs()->GetPhy()->GetNrSymbols(packet->
GetSize(), modulationType);
341 if (availableSymbols < nrSymbolsRequired &&
346 else if (availableSymbols < nrSymbolsRequired &&
349 uint32_t availableByte =
350 GetBs()->GetPhy()->GetNrBytes(availableSymbols, modulationType);
355 packet = connection->Dequeue();
359 "Base station: Error while scheduling basic connection: header CID != "
361 burst->AddPacket(packet);
362 availableSymbols -= nrSymbolsRequired;
364 if (burst->GetNPackets() != 0)
367 burst = Create<PacketBurst>();
378 uint32_t nrSymbolsRequired = 0;
383 std::vector<Ptr<WimaxConnection>> connections;
386 for (
auto iter = connections.begin(); iter != connections.end(); ++iter)
388 while ((*iter)->HasPackets() && availableSymbols > 0)
393 GetBs()->GetSSManager()->GetSSRecord(connection->GetCid())->GetModulationType();
394 diuc =
GetBs()->GetBurstProfileManager()->GetBurstProfile(
398 packet = connection->GetQueue()->Peek(hdr);
399 nrSymbolsRequired =
GetBs()->GetPhy()->GetNrSymbols(packet->
GetSize(), modulationType);
402 if (availableSymbols < nrSymbolsRequired &&
407 else if (availableSymbols < nrSymbolsRequired &&
410 uint32_t availableByte =
411 GetBs()->GetPhy()->GetNrBytes(availableSymbols, modulationType);
416 packet = connection->Dequeue();
420 "Base station: Error while scheduling primary connection: header CID != "
422 burst->AddPacket(packet);
423 availableSymbols -= nrSymbolsRequired;
425 if (burst->GetNPackets() != 0)
438 uint32_t nrSymbolsRequired = 0;
446 std::vector<ServiceFlow*> serviceFlows;
449 for (
auto iter = serviceFlows.begin(); iter != serviceFlows.end(); ++iter)
451 serviceFlowRecord = (*iter)->GetRecord();
454 if ((*iter)->HasPackets() &&
456 GetBs()->GetPhy()->GetFrameDuration()) >
MilliSeconds((*iter)->GetMaximumLatency()))
458 connection = (*iter)->GetConnection();
461 modulationType = connection->GetServiceFlow()->GetModulation();
466 GetBs()->GetSSManager()->GetSSRecord(connection->GetCid())->GetModulationType();
468 diuc =
GetBs()->GetBurstProfileManager()->GetBurstProfile(
472 nrSymbolsRequired = connection->GetServiceFlow()->GetRecord()->GetGrantSize();
475 if (availableSymbols > nrSymbolsRequired)
477 availableSymbols -= nrSymbolsRequired;
479 CreateUgsBurst(connection->GetServiceFlow(), modulationType, nrSymbolsRequired);
480 if (burst->GetNPackets() != 0)
485 burst = Create<PacketBurst>();
502 std::vector<Ptr<WimaxConnection>> connections;
504 std::vector<ServiceFlow*> serviceFlows;
506 uint32_t symbolsRequired[100];
511 uint32_t totSymbolsRequired = 0;
512 int nbConnection = 0;
515 <<
"\t\tavailableSymbols = " << availableSymbols);
519 for (
auto iter2 = serviceFlows.begin(); iter2 != serviceFlows.end(); ++iter2)
522 serviceFlowRecord = (*iter2)->GetRecord();
524 if ((*iter2)->HasPackets())
528 rtPSConnection[nbConnection] = (*iter2)->GetConnection();
531 modulationType_[nbConnection] =
532 rtPSConnection[nbConnection]->GetServiceFlow()->GetModulation();
536 modulationType_[nbConnection] =
539 ->GetSSRecord(rtPSConnection[nbConnection]->GetCid())
540 ->GetModulationType();
542 diuc_[nbConnection] =
GetBs()->GetBurstProfileManager()->GetBurstProfile(
543 modulationType_[nbConnection],
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 = "
551 symbolsRequired[nbConnection] =
552 GetBs()->GetPhy()->GetNrSymbols(dataToSend, modulationType_[nbConnection]);
554 totSymbolsRequired += symbolsRequired[nbConnection];
559 NS_LOG_INFO(
"\t\ttotSymbolsRequired = " << totSymbolsRequired);
562 while (totSymbolsRequired > availableSymbols)
564 NS_LOG_INFO(
"\tDL Channel Saturation: totSymbolsRequired > availableSymbols_rtPS");
565 double delta = double(availableSymbols) / double(totSymbolsRequired);
567 totSymbolsRequired = 0;
568 for (
int i = 0; i < nbConnection; i++)
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]);
575 NS_LOG_INFO(
"\t\ttotSymbolsRequired = " << totSymbolsRequired);
579 for (
int i = 0; i < nbConnection; i++)
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]);
587 while (symbolsRequired[i] > 0)
589 symbolsForPacketTransmission =
GetBs()->GetPhy()->GetNrSymbols(
590 rtPSConnection[i]->GetQueue()->GetFirstPacketRequiredByte(
595 if (symbolsForPacketTransmission > symbolsRequired[i] &&
600 else if (symbolsForPacketTransmission > symbolsRequired[i] &&
605 uint32_t availableByte =
606 GetBs()->GetPhy()->GetNrBytes(symbolsRequired[i], modulationType_[i]);
609 symbolsRequired[i] = 0;
613 packet = rtPSConnection[i]->Dequeue();
614 symbolsRequired[i] -= symbolsForPacketTransmission;
618 "Base station: Error while scheduling RTPs connection: header CID != "
620 burst->AddPacket(packet);
623 if (burst->GetNPackets() != 0)
629 availableSymbols -= totSymbolsRequired;
638 uint32_t nrSymbolsRequired = 0;
643 std::vector<ServiceFlow*> serviceFlows;
646 for (
auto iter = serviceFlows.begin(); iter != serviceFlows.end(); ++iter)
648 connection = (*iter)->GetConnection();
650 while ((*iter)->HasPackets() && availableSymbols > 0)
654 modulationType = connection->GetServiceFlow()->GetModulation();
659 GetBs()->GetSSManager()->GetSSRecord(connection->GetCid())->GetModulationType();
662 diuc =
GetBs()->GetBurstProfileManager()->GetBurstProfile(
666 packet = connection->GetQueue()->Peek(hdr);
667 nrSymbolsRequired =
GetBs()->GetPhy()->GetNrSymbols(packet->
GetSize(), modulationType);
669 if (availableSymbols < nrSymbolsRequired)
674 packet = connection->Dequeue();
676 "Base station: Error while scheduling NRTPs connection: header CID != "
678 burst->AddPacket(packet);
679 availableSymbols -= nrSymbolsRequired;
681 if (burst->GetNPackets() != 0)
684 burst = Create<PacketBurst>();
695 uint32_t nrSymbolsRequired = 0;
700 std::vector<ServiceFlow*> serviceFlows;
703 for (
auto iter = serviceFlows.begin(); iter != serviceFlows.end(); ++iter)
705 connection = (*iter)->GetConnection();
707 while ((*iter)->HasPackets() && availableSymbols > 0)
711 modulationType = connection->GetServiceFlow()->GetModulation();
716 GetBs()->GetSSManager()->GetSSRecord(connection->GetCid())->GetModulationType();
718 diuc =
GetBs()->GetBurstProfileManager()->GetBurstProfile(
722 packet = connection->GetQueue()->Peek(hdr);
723 nrSymbolsRequired =
GetBs()->GetPhy()->GetNrSymbols(packet->
GetSize(), modulationType);
725 if (availableSymbols < nrSymbolsRequired)
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;
737 if (burst->GetNPackets() != 0)
740 burst = Create<PacketBurst>();
virtual Ptr< BaseStationNetDevice > GetBs()
Get the base station.
virtual void SetBs(Ptr< BaseStationNetDevice > bs)
Set the base station.
bool CheckForFragmentation(Ptr< WimaxConnection > connection, int availableSymbols, WimaxPhy::ModulationType modulationType)
Check if the packet fragmentation is possible for transport connection.
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...
~BSSchedulerRtps() override
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
uint16_t GetIdentifier() const
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
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Smart pointer class similar to boost::intrusive_ptr.
This class implements service flows as described by the IEEE-802.16 standard.
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.
Time GetDlTimeStamp() const
static Time Now()
Return the current simulation virtual time.
Simulation virtual time values and global simulation resolution.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
ModulationType
ModulationType enumeration.
@ MODULATION_TYPE_BPSK_12
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
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.