void BSSchedulerSimple::Schedule()

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));
    }
}