in simulation/src/wimax/model/bs-scheduler-simple.cc [110:219]
void BSSchedulerSimple::Schedule (void)
{
Ptr<WimaxConnection> connection;
WimaxPhy::ModulationType modulationType = WimaxPhy::MODULATION_TYPE_BPSK_12;
uint8_t diuc = OfdmDlBurstProfile::DIUC_BURST_PROFILE_1;
uint32_t nrSymbolsRequired = 0;
GenericMacHeader hdr;
Ptr<Packet> packet;
Ptr<PacketBurst> burst;
ServiceFlow::SchedulingType schedulingType = ServiceFlow::SF_TYPE_NONE;
uint32_t availableSymbols = GetBs ()->GetNrDlSymbols ();
while (SelectConnection (connection))
{
if (connection != GetBs ()->GetInitialRangingConnection () && connection != GetBs ()->GetBroadcastConnection ())
{
/* determines modulation/DIUC only once per burst as it is always same for a particular CID */
if (connection->GetType () == Cid::MULTICAST)
{
modulationType = connection->GetServiceFlow ()->GetModulation ();
}
else
{
modulationType = GetBs ()->GetSSManager ()->GetSSRecord (connection->GetCid ())->GetModulationType ();
}
diuc = GetBs ()->GetBurstProfileManager ()->GetBurstProfile (modulationType,
WimaxNetDevice::DIRECTION_DOWNLINK);
}
else if (connection == GetBs ()->GetInitialRangingConnection () || connection
== GetBs ()->GetBroadcastConnection ())
{
modulationType = WimaxPhy::MODULATION_TYPE_BPSK_12;
diuc = OfdmDlBurstProfile::DIUC_BURST_PROFILE_1;
}
if (connection->GetType () == Cid::TRANSPORT || connection->GetType () == Cid::MULTICAST)
{
schedulingType = (ServiceFlow::SchedulingType) connection->GetSchedulingType ();
}
if (schedulingType == ServiceFlow::SF_TYPE_UGS)
{
nrSymbolsRequired = connection->GetServiceFlow ()->GetRecord ()->GetGrantSize ();
if (nrSymbolsRequired < availableSymbols)
{
burst = CreateUgsBurst (connection->GetServiceFlow (), modulationType, nrSymbolsRequired);
}
else
{
burst = CreateUgsBurst (connection->GetServiceFlow (), modulationType, availableSymbols);
}
if (burst->GetNPackets () != 0)
{
uint32_t BurstSizeSymbols = GetBs ()->GetPhy ()->GetNrSymbols (burst->GetSize (), modulationType);
AddDownlinkBurst (connection, diuc, modulationType, burst);
if (availableSymbols <= BurstSizeSymbols)
{
availableSymbols -= BurstSizeSymbols; /// \todo Overflows but don't know how to fix
break;
}
}
}
else
{
burst = Create<PacketBurst> ();
while (connection->HasPackets () == true)
{
uint32_t FirstPacketSize = connection->GetQueue ()->GetFirstPacketRequiredByte (MacHeaderType::HEADER_TYPE_GENERIC);
nrSymbolsRequired = GetBs ()->GetPhy ()->GetNrSymbols (FirstPacketSize, modulationType);
if (availableSymbols < nrSymbolsRequired && CheckForFragmentation (connection,
availableSymbols,
modulationType))
{
uint32_t availableByte = GetBs ()->GetPhy ()->GetNrBytes (availableSymbols, modulationType);
packet = connection->Dequeue (MacHeaderType::HEADER_TYPE_GENERIC, availableByte);
availableSymbols = 0;
}
else if (availableSymbols >= nrSymbolsRequired)
{
packet = connection->Dequeue ();
availableSymbols -= nrSymbolsRequired;
}
else
{
break;
}
burst->AddPacket (packet);
}
AddDownlinkBurst (connection, diuc, modulationType, burst);
}
if (availableSymbols == 0)
{
break;
}
}
if (m_downlinkBursts->size ())
{
NS_LOG_DEBUG ("BS scheduler, number of bursts: " << m_downlinkBursts->size () << ", symbols left: "
<< availableSymbols << std::endl << "BS scheduler, queues:" << " IR "
<< GetBs ()->GetInitialRangingConnection ()->GetQueue ()->GetSize () << " broadcast "
<< GetBs ()->GetBroadcastConnection ()->GetQueue ()->GetSize () << " basic "
<< GetBs ()->GetConnectionManager ()->GetNPackets (Cid::BASIC, ServiceFlow::SF_TYPE_NONE) << " primary "
<< GetBs ()->GetConnectionManager ()->GetNPackets (Cid::PRIMARY, ServiceFlow::SF_TYPE_NONE) << " transport "
<< GetBs ()->GetConnectionManager ()->GetNPackets (Cid::TRANSPORT, ServiceFlow::SF_TYPE_ALL));
}
}