WiMAX module suports several uplink schedulers. Juliana scheduler's working in this revision
authorFlavio Kubota <flaviokubota@gmail.com>
Tue Aug 11 16:41:52 2009 -0300 (6 months ago)
changeset 4535a256721e6d19
parent 4534 d83c8c86b46b
child 4536 81219a14ab71
WiMAX module suports several uplink schedulers. Juliana scheduler's working in this revision
examples/my-simple-wimax.cc
examples/simple-wimax.cc
examples/wimax-multicast.cc
scratch/my-simple-wimax.cc
scratch/nrtps.cc
scratch/rtps.cc
scratch/wimax-multicast.cc
scratch/wimax.cc
src/devices/wimax/bandwidth-manager.cc
src/devices/wimax/bandwidth-manager.h
src/devices/wimax/uplink-scheduler-mbqos.cc
src/devices/wimax/uplink-scheduler-mbqos.h
src/devices/wimax/uplink-scheduler-qos.cc
src/devices/wimax/uplink-scheduler.cc
src/devices/wimax/uplink-scheduler.h
src/devices/wimax/wscript
src/helper/wimax-helper.cc
src/helper/wimax-helper.h
     1.1 --- a/examples/my-simple-wimax.cc	Tue Aug 11 15:03:05 2009 -0300
     1.2 +++ b/examples/my-simple-wimax.cc	Tue Aug 11 16:41:52 2009 -0300
     1.3 @@ -77,9 +77,9 @@
     1.4    NetDeviceContainer ssDevs, bsDevs;
     1.5  
     1.6    ssDevs = wimax.Install(ssNodes, WimaxHelper::DEVICE_TYPE_SUBSCRIBER_STATION,
     1.7 -      WimaxHelper::SIMPLE_PHY_TYPE_OFDM);
     1.8 +      WimaxHelper::SIMPLE_PHY_TYPE_OFDM, WimaxHelper::SCHED_TYPE_SIMPLE);
     1.9    bsDevs = wimax.Install(bsNodes, WimaxHelper::DEVICE_TYPE_BASE_STATION,
    1.10 -      WimaxHelper::SIMPLE_PHY_TYPE_OFDM);
    1.11 +      WimaxHelper::SIMPLE_PHY_TYPE_OFDM, WimaxHelper::SCHED_TYPE_SIMPLE);
    1.12  
    1.13    Ptr<WimaxSubscriberStationNetDevice> ss[nbSS];
    1.14  
     2.1 --- a/examples/simple-wimax.cc	Tue Aug 11 15:03:05 2009 -0300
     2.2 +++ b/examples/simple-wimax.cc	Tue Aug 11 16:41:52 2009 -0300
     2.3 @@ -140,8 +140,8 @@
     2.4    packetSocket.Install (bsNodes);
     2.5    packetSocket.Install (ssNodes);
     2.6  
     2.7 -  bsDevs = wimax.Install (bsNodes, WimaxHelper::DEVICE_TYPE_BASE_STATION, WimaxHelper::SIMPLE_PHY_TYPE_OFDM);
     2.8 -  ssDevs = wimax.Install (ssNodes, WimaxHelper::DEVICE_TYPE_SUBSCRIBER_STATION, WimaxHelper::SIMPLE_PHY_TYPE_OFDM);
     2.9 +  bsDevs = wimax.Install (bsNodes, WimaxHelper::DEVICE_TYPE_BASE_STATION, WimaxHelper::SIMPLE_PHY_TYPE_OFDM, WimaxHelper::SCHED_TYPE_SIMPLE);
    2.10 +  ssDevs = wimax.Install (ssNodes, WimaxHelper::DEVICE_TYPE_SUBSCRIBER_STATION, WimaxHelper::SIMPLE_PHY_TYPE_OFDM, WimaxHelper::SCHED_TYPE_SIMPLE);
    2.11  
    2.12    Ptr<WimaxBaseStationNetDevice> bs = bsDevs.Get (0)->GetObject<WimaxBaseStationNetDevice> ();
    2.13    Ptr<WimaxSubscriberStationNetDevice> ss1 = ssDevs.Get (0)->GetObject<WimaxSubscriberStationNetDevice> ();
     3.1 --- a/examples/wimax-multicast.cc	Tue Aug 11 15:03:05 2009 -0300
     3.2 +++ b/examples/wimax-multicast.cc	Tue Aug 11 16:41:52 2009 -0300
     3.3 @@ -107,14 +107,14 @@
     3.4        channel[i] = CreateObject<simpleOfdmWimaxChannel> ();
     3.5        ssDevs[i] = wimax.Install(ssNodes,
     3.6            WimaxHelper::DEVICE_TYPE_SUBSCRIBER_STATION,
     3.7 -          WimaxHelper::SIMPLE_PHY_TYPE_OFDM, channel[i]);
     3.8 +          WimaxHelper::SIMPLE_PHY_TYPE_OFDM, channel[i], WimaxHelper::SCHED_TYPE_SIMPLE);
     3.9      }
    3.10  
    3.11    for (int i = 0; i < nbBS; i++)
    3.12      {
    3.13        Ptr<WimaxNetDevice> dev = wimax.Install(bsNodes.Get(i),
    3.14            WimaxHelper::DEVICE_TYPE_BASE_STATION,
    3.15 -          WimaxHelper::SIMPLE_PHY_TYPE_OFDM, channel[i]);
    3.16 +          WimaxHelper::SIMPLE_PHY_TYPE_OFDM, channel[i], WimaxHelper::SCHED_TYPE_SIMPLE);
    3.17        bsDevs.Add(dev);
    3.18      }
    3.19  
     4.1 --- a/scratch/my-simple-wimax.cc	Tue Aug 11 15:03:05 2009 -0300
     4.2 +++ b/scratch/my-simple-wimax.cc	Tue Aug 11 16:41:52 2009 -0300
     4.3 @@ -186,8 +186,8 @@
     4.4    packetSocket.Install (bsNodes);
     4.5    packetSocket.Install (ssNodes);
     4.6  
     4.7 -  bsDevs = wimax.Install (bsNodes, WimaxHelper::DEVICE_TYPE_BASE_STATION, WimaxHelper::SIMPLE_PHY_TYPE_OFDM);
     4.8 -  ssDevs = wimax.Install (ssNodes, WimaxHelper::DEVICE_TYPE_SUBSCRIBER_STATION, WimaxHelper::SIMPLE_PHY_TYPE_OFDM);
     4.9 +  bsDevs = wimax.Install (bsNodes, WimaxHelper::DEVICE_TYPE_BASE_STATION, WimaxHelper::SIMPLE_PHY_TYPE_OFDM, WimaxHelper::SCHED_TYPE_SIMPLE);
    4.10 +  ssDevs = wimax.Install (ssNodes, WimaxHelper::DEVICE_TYPE_SUBSCRIBER_STATION, WimaxHelper::SIMPLE_PHY_TYPE_OFDM, WimaxHelper::SCHED_TYPE_SIMPLE);
    4.11  
    4.12    Ptr<WimaxBaseStationNetDevice> bs = bsDevs.Get (0)->GetObject<WimaxBaseStationNetDevice> ();
    4.13    Ptr<WimaxSubscriberStationNetDevice> ss1 = ssDevs.Get (0)->GetObject<WimaxSubscriberStationNetDevice> ();
     5.1 --- a/scratch/nrtps.cc	Tue Aug 11 15:03:05 2009 -0300
     5.2 +++ b/scratch/nrtps.cc	Tue Aug 11 16:41:52 2009 -0300
     5.3 @@ -125,9 +125,9 @@
     5.4    bsNodes.Create(nbBS);
     5.5  
     5.6    ssDevs = wimax.Install(ssNodes, WimaxHelper::DEVICE_TYPE_SUBSCRIBER_STATION,
     5.7 -			 WimaxHelper::SIMPLE_PHY_TYPE_OFDM);
     5.8 +			 WimaxHelper::SIMPLE_PHY_TYPE_OFDM, WimaxHelper::SCHED_TYPE_MBQOS);
     5.9    bsDevs = wimax.Install(bsNodes, WimaxHelper::DEVICE_TYPE_BASE_STATION,
    5.10 -			 WimaxHelper::SIMPLE_PHY_TYPE_OFDM);
    5.11 +			 WimaxHelper::SIMPLE_PHY_TYPE_OFDM, WimaxHelper::SCHED_TYPE_MBQOS);
    5.12    
    5.13    Ptr<WimaxSubscriberStationNetDevice> ss[nbSS];
    5.14    
     6.1 --- a/scratch/rtps.cc	Tue Aug 11 15:03:05 2009 -0300
     6.2 +++ b/scratch/rtps.cc	Tue Aug 11 16:41:52 2009 -0300
     6.3 @@ -93,9 +93,9 @@
     6.4    bsNodes.Create(nbBS);
     6.5  
     6.6    ssDevs = wimax.Install(ssNodes, WimaxHelper::DEVICE_TYPE_SUBSCRIBER_STATION,
     6.7 -			 WimaxHelper::SIMPLE_PHY_TYPE_OFDM);
     6.8 +			 WimaxHelper::SIMPLE_PHY_TYPE_OFDM, WimaxHelper::SCHED_TYPE_SIMPLE);
     6.9    bsDevs = wimax.Install(bsNodes, WimaxHelper::DEVICE_TYPE_BASE_STATION,
    6.10 -			 WimaxHelper::SIMPLE_PHY_TYPE_OFDM);
    6.11 +			 WimaxHelper::SIMPLE_PHY_TYPE_OFDM, WimaxHelper::SCHED_TYPE_SIMPLE);
    6.12    
    6.13    Ptr<WimaxSubscriberStationNetDevice> ss[nbSS];
    6.14    
     7.1 --- a/scratch/wimax-multicast.cc	Tue Aug 11 15:03:05 2009 -0300
     7.2 +++ b/scratch/wimax-multicast.cc	Tue Aug 11 16:41:52 2009 -0300
     7.3 @@ -116,10 +116,10 @@
     7.4        channel[i]->SetPropagationModel(simpleOfdmWimaxChannel::COST231_PROPAGATION);
     7.5        ssDevs[i] = wimax.Install(ssNodes,
     7.6            WimaxHelper::DEVICE_TYPE_SUBSCRIBER_STATION,
     7.7 -          WimaxHelper::SIMPLE_PHY_TYPE_OFDM, channel[i]);
     7.8 +          WimaxHelper::SIMPLE_PHY_TYPE_OFDM, channel[i], WimaxHelper::SCHED_TYPE_SIMPLE);
     7.9        Ptr<WimaxNetDevice> dev = wimax.Install(bsNodes.Get(i),
    7.10            WimaxHelper::DEVICE_TYPE_BASE_STATION,
    7.11 -          WimaxHelper::SIMPLE_PHY_TYPE_OFDM, channel[i]);
    7.12 +          WimaxHelper::SIMPLE_PHY_TYPE_OFDM, channel[i], WimaxHelper::SCHED_TYPE_SIMPLE);
    7.13  
    7.14        BSPosition[i] = CreateObject<ConstantPositionMobilityModel> ();
    7.15        //BSPosition[i]->SetPosition(Vector(i%MAXDIST,0,0));
     8.1 --- a/scratch/wimax.cc	Tue Aug 11 15:03:05 2009 -0300
     8.2 +++ b/scratch/wimax.cc	Tue Aug 11 16:41:52 2009 -0300
     8.3 @@ -179,8 +179,8 @@
     8.4    bsNodes.Create (number_bs);
     8.5    ssNodes.Create (number_ss);
     8.6  
     8.7 -  bsDevs = wimax.Install (bsNodes, WimaxHelper::DEVICE_TYPE_BASE_STATION, WimaxHelper::SIMPLE_PHY_TYPE_OFDM);
     8.8 -  ssDevs = wimax.Install (ssNodes, WimaxHelper::DEVICE_TYPE_SUBSCRIBER_STATION, WimaxHelper::SIMPLE_PHY_TYPE_OFDM);
     8.9 +  bsDevs = wimax.Install (bsNodes, WimaxHelper::DEVICE_TYPE_BASE_STATION, WimaxHelper::SIMPLE_PHY_TYPE_OFDM, WimaxHelper::SCHED_TYPE_SIMPLE);
    8.10 +  ssDevs = wimax.Install (ssNodes, WimaxHelper::DEVICE_TYPE_SUBSCRIBER_STATION, WimaxHelper::SIMPLE_PHY_TYPE_OFDM, WimaxHelper::SCHED_TYPE_SIMPLE);
    8.11  
    8.12  
    8.13    std::vector<Ptr<WimaxBaseStationNetDevice> > bs;
     9.1 --- a/src/devices/wimax/bandwidth-manager.cc	Tue Aug 11 15:03:05 2009 -0300
     9.2 +++ b/src/devices/wimax/bandwidth-manager.cc	Tue Aug 11 16:41:52 2009 -0300
     9.3 @@ -205,42 +205,7 @@
     9.4          serviceFlow->GetRecord()->SetRequestedBandwidth(bwRequestHdr.GetBr());
     9.5        }
     9.6  
     9.7 -    // Flavio Kubota: Enqueue requests for uplink scheduler.
     9.8 -    UlJob *job = new UlJob ();
     9.9 -    Ptr<WimaxConnection> connectionIdentifier = bs->GetConnectionManager ()->GetConnection(bwRequestHdr.GetCid ().Copy ());
    9.10 -    SSRecord *ssRecord = bs->GetSSManager ()->GetSSRecord (connectionIdentifier->GetCid ());
    9.11 -
    9.12 -    u_int32_t size = bwRequestHdr.GetBr ();
    9.13 -    Time deadline = DetermineDeadline (serviceFlow);
    9.14 -    Time currentTime = Simulator::Now ();
    9.15 -    Time period = deadline; /* So that deadline is properly updated.. */
    9.16 -
    9.17 -    // Record data in job
    9.18 -    job->SetSsRecord (ssRecord);
    9.19 -    job->SetServiceFlow (serviceFlow);
    9.20 -    job->SetSize (size);
    9.21 -    job->SetDeadline (deadline);
    9.22 -    job->SetReleaseTime (currentTime);
    9.23 -    job->SetSchedulingType (serviceFlow->GetSchedulingType());
    9.24 -    job->SetPeriod (period);
    9.25 -    job->SetType(DATA);
    9.26 -
    9.27 -    // Enqueue job in Uplink Scheduler
    9.28 -    switch (serviceFlow->GetSchedulingType())
    9.29 -    {
    9.30 -      case QoSParameterSet::SCHEDULING_TYPE_RTPS:
    9.31 -        bs->GetUplinkScheduler ()->EnqueueJob (UlJob::INTERMEDIATE, *job);
    9.32 -        break;
    9.33 -      case QoSParameterSet::SCHEDULING_TYPE_NRTPS:
    9.34 -        bs->GetUplinkScheduler ()->EnqueueJob (UlJob::INTERMEDIATE, *job);
    9.35 -        break;
    9.36 -      case QoSParameterSet::SCHEDULING_TYPE_BE:
    9.37 -        bs->GetUplinkScheduler ()->EnqueueJob (UlJob::LOW, *job);
    9.38 -        break;
    9.39 -      default:
    9.40 -        bs->GetUplinkScheduler ()->EnqueueJob (UlJob::LOW, *job);
    9.41 -        break;
    9.42 -    }
    9.43 +    bs->GetUplinkScheduler ()->ProcessBandwidthRequest (bwRequestHdr);
    9.44  
    9.45      // update backlogged
    9.46      serviceFlow->GetRecord ()->UpdateBacklogged (bwRequestHdr.GetBr ());
    9.47 @@ -286,16 +251,4 @@
    9.48      return allocatedSymbols;
    9.49    }
    9.50  
    9.51 -  /*
    9.52 -   * Flavio Kubota: Calculate Deadline of requests according to QoS parameter
    9.53 -   * */
    9.54 -  Time
    9.55 -  BandwidthManager::DetermineDeadline(ServiceFlow *serviceFlow)
    9.56 -  {
    9.57 -    uint32_t latency = serviceFlow->GetParameterSet()->GetMaxLatency ();
    9.58 -    Time lastGrantTime = serviceFlow->GetRecord ()->GetLastGrantTime ();
    9.59 -    Time deadline =  MilliSeconds(latency) + lastGrantTime;
    9.60 -    return deadline;
    9.61 -  }
    9.62 -
    9.63  }//namespace ns3
    10.1 --- a/src/devices/wimax/bandwidth-manager.h	Tue Aug 11 15:03:05 2009 -0300
    10.2 +++ b/src/devices/wimax/bandwidth-manager.h	Tue Aug 11 16:41:52 2009 -0300
    10.3 @@ -58,8 +58,7 @@
    10.4      SetSubframeRatio(void);
    10.5      uint32_t
    10.6      GetSymbolsPerFrameAllocated(void);
    10.7 -    Time
    10.8 -    DetermineDeadline(ServiceFlow *serviceFlow);
    10.9 +
   10.10    private:
   10.11      Ptr<WimaxNetDevice> m_device;
   10.12  
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/src/devices/wimax/uplink-scheduler-mbqos.cc	Tue Aug 11 16:41:52 2009 -0300
    11.3 @@ -0,0 +1,1072 @@
    11.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
    11.5 +/*
    11.6 + * Copyright (c) 2007,2008 INRIA
    11.7 + *
    11.8 + * This program is free software; you can redistribute it and/or modify
    11.9 + * it under the terms of the GNU General Public License version 2 as
   11.10 + * published by the Free Software Foundation;
   11.11 + *
   11.12 + * This program is distributed in the hope that it will be useful,
   11.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11.15 + * GNU General Public License for more details.
   11.16 + *
   11.17 + * You should have received a copy of the GNU General Public License
   11.18 + * along with this program; if not, write to the Free Software
   11.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   11.20 + *
   11.21 + * Author: Jahanzeb Farooq <jahanzeb.farooq@sophia.inria.fr>
   11.22 + */
   11.23 +
   11.24 +#include "uplink-scheduler-mbqos.h"
   11.25 +#include "wimax-bs-net-device.h"
   11.26 +#include "ns3/simulator.h"
   11.27 +#include "connection-identifier.h"
   11.28 +#include "burst-profile-manager.h"
   11.29 +#include "ss-manager.h"
   11.30 +#include "ns3/log.h"
   11.31 +#include "ns3/uinteger.h"
   11.32 +#include "ss-record.h"
   11.33 +#include "qos-parameter-set.h"
   11.34 +#include "service-flow.h"
   11.35 +#include "service-flow-record.h"
   11.36 +#include "bs-link-manager.h"
   11.37 +#include "bandwidth-manager.h"
   11.38 +#include "connection-manager.h"
   11.39 +
   11.40 +NS_LOG_COMPONENT_DEFINE ("UplinkSchedulerMBQoS");
   11.41 +
   11.42 +namespace ns3
   11.43 +{
   11.44 +
   11.45 +  NS_OBJECT_ENSURE_REGISTERED (UplinkSchedulerMBQoS);
   11.46 +
   11.47 +  UplinkSchedulerMBQoS::UplinkSchedulerMBQoS()
   11.48 +  {
   11.49 +  }
   11.50 +
   11.51 +  UplinkSchedulerMBQoS::~UplinkSchedulerMBQoS(void)
   11.52 +  {
   11.53 +    m_bs = 0;
   11.54 +    m_uplinkAllocations.clear();
   11.55 +  }
   11.56 +
   11.57 +  uint8_t
   11.58 +  UplinkSchedulerMBQoS::GetNrIrOppsAllocated(void) const
   11.59 +  {
   11.60 +    return m_nrIrOppsAllocated;
   11.61 +  }
   11.62 +
   11.63 +  bool
   11.64 +  UplinkSchedulerMBQoS::GetIsIrIntrvlAllocated(void) const
   11.65 +  {
   11.66 +    return m_isIrIntrvlAllocated;
   11.67 +  }
   11.68 +
   11.69 +  bool
   11.70 +  UplinkSchedulerMBQoS::GetIsInvIrIntrvlAllocated(void) const
   11.71 +  {
   11.72 +    return m_isInvIrIntrvlAllocated;
   11.73 +  }
   11.74 +
   11.75 +  std::list<OfdmUlMapIe>
   11.76 +  UplinkSchedulerMBQoS::GetUplinkAllocations(void) const
   11.77 +  {
   11.78 +    return m_uplinkAllocations;
   11.79 +  }
   11.80 +
   11.81 +  void
   11.82 +  UplinkSchedulerMBQoS::GetChannelDescriptorsToUpdate(bool &updateDcd,
   11.83 +      bool &updateUcd, bool &sendDcd, bool &sendUcd)
   11.84 +  {
   11.85 +    /*XXX, DCD and UCD shall actually be updated when channel or burst profile definitions
   11.86 +     change. burst profiles are updated based on number of SSs, network conditions and etc.
   11.87 +     for now temporarily assuming DCD/UCD shall be updated everytime */
   11.88 +
   11.89 +    uint32_t randNr = rand();
   11.90 +    if (randNr % 5 == 0 || m_bs->GetNrDcdSent() == 0)
   11.91 +      sendDcd = true;
   11.92 +
   11.93 +    randNr = rand();
   11.94 +    if (randNr % 5 == 0 || m_bs->GetNrUcdSent() == 0)
   11.95 +      sendUcd = true;
   11.96 +
   11.97 +    //-------------------------------------
   11.98 +    //additional, just to send more frequently
   11.99 +    if (!sendDcd)
  11.100 +      {
  11.101 +        randNr = rand();
  11.102 +        if (randNr % 4 == 0)
  11.103 +          sendDcd = true;
  11.104 +      }
  11.105 +
  11.106 +    if (!sendUcd)
  11.107 +      {
  11.108 +        randNr = rand();
  11.109 +        if (randNr % 4 == 0)
  11.110 +          sendUcd = true;
  11.111 +      }
  11.112 +    //-------------------------------------
  11.113 +
  11.114 +    Time timeSinceLastDcd = Simulator::Now() - m_dcdTimeStamp;
  11.115 +    Time timeSinceLastUcd = Simulator::Now() - m_ucdTimeStamp;
  11.116 +
  11.117 +    if (timeSinceLastDcd > m_bs->GetDcdInterval())
  11.118 +      {
  11.119 +        sendDcd = true;
  11.120 +        m_dcdTimeStamp = Simulator::Now();
  11.121 +      }
  11.122 +
  11.123 +    if (timeSinceLastUcd > m_bs->GetUcdInterval())
  11.124 +      {
  11.125 +        sendUcd = true;
  11.126 +        m_ucdTimeStamp = Simulator::Now();
  11.127 +      }
  11.128 +  }
  11.129 +
  11.130 +  uint32_t
  11.131 +  UplinkSchedulerMBQoS::CalculateAllocationStartTime(void)
  11.132 +  {
  11.133 +    return m_bs->GetNrDlSymbols() * m_bs->GetPhy()->GetPsPerSymbol()
  11.134 +        + m_bs->GetTtg();
  11.135 +  }
  11.136 +
  11.137 +  void
  11.138 +  UplinkSchedulerMBQoS::AddUplinkAllocation(OfdmUlMapIe &ulMapIe,
  11.139 +      const uint32_t &allocationSize, uint32_t &symbolsToAllocation,
  11.140 +      uint32_t &availableSymbols)
  11.141 +  {
  11.142 +    ulMapIe.SetDuration(allocationSize);
  11.143 +    ulMapIe.SetStartTime(symbolsToAllocation);
  11.144 +    m_uplinkAllocations.push_back(ulMapIe);
  11.145 +    symbolsToAllocation += allocationSize;
  11.146 +    availableSymbols -= allocationSize;
  11.147 +  }
  11.148 +
  11.149 +
  11.150 +  void
  11.151 +  UplinkSchedulerMBQoS::UplinkSchedWindowTimer (void)
  11.152 +  {
  11.153 +    int32_t min_bw = 0;
  11.154 +    std::vector<SSRecord*> *ssRecords = m_bs->GetSSManager ()->GetSSRecords ();
  11.155 +    int windowSize = 1; // in seconds
  11.156 +
  11.157 +    /* For each SS */
  11.158 +    for (std::vector<SSRecord*>::iterator iter = ssRecords->begin ();
  11.159 +    iter != ssRecords->end (); ++iter)
  11.160 +      {
  11.161 +        SSRecord *ssRecord = *iter;
  11.162 +        std::vector<ServiceFlow*> *serviceFlows = ssRecord->GetServiceFlows (QoSParameterSet::SCHEDULING_TYPE_ALL);
  11.163 +
  11.164 +        /* For each flow */
  11.165 +        for (std::vector<ServiceFlow*>::iterator iter2 = serviceFlows->begin ();
  11.166 +        iter2 != serviceFlows->end (); ++iter2)
  11.167 +          {
  11.168 +            ServiceFlow *serviceFlow = *iter2;
  11.169 +            if ((serviceFlow->GetSchedulingType () == QoSParameterSet::SCHEDULING_TYPE_RTPS) ||
  11.170 +                (serviceFlow->GetSchedulingType () == QoSParameterSet::SCHEDULING_TYPE_NRTPS ))
  11.171 +              {
  11.172 +                QoSParameterSet *qosParameterSet = serviceFlow-> GetParameterSet ();
  11.173 +                min_bw = (int) ceil(qosParameterSet->GetMinReservedTrafficRate () / windowSize );
  11.174 +
  11.175 +                /* This way we can compensate flows which did not get min_bw in the previous window */
  11.176 +                if ((serviceFlow->GetRecord ()->GetBacklogged () > 0) && (serviceFlow->GetRecord ()->GetBwSinceLastExpiry () < min_bw))
  11.177 +                  {
  11.178 +                    serviceFlow->GetRecord ()->UpdateBwSinceLastExpiry(-min_bw);
  11.179 +
  11.180 +                    /* if backlogged < granted_bw then we don't need to provide granted_bw + min_bw in next window, but backlogged + min_bw */
  11.181 +                    if (serviceFlow->GetRecord ()->GetBacklogged () < abs (serviceFlow->GetRecord ()->GetBwSinceLastExpiry ()))
  11.182 +                      {
  11.183 +                        serviceFlow->GetRecord ()->SetBwSinceLastExpiry (-serviceFlow->GetRecord ()->GetBacklogged ());
  11.184 +                      }
  11.185 +                  }
  11.186 +                else
  11.187 +                  {
  11.188 +                    serviceFlow->GetRecord ()->SetBwSinceLastExpiry (0);
  11.189 +                  }
  11.190 +              }
  11.191 +          }
  11.192 +      }
  11.193 +
  11.194 +    Simulator::Schedule( Seconds(1), &UplinkSchedulerMBQoS::UplinkSchedWindowTimer, this);
  11.195 +  }
  11.196 +
  11.197 +  void
  11.198 +  UplinkSchedulerMBQoS::Schedule(void)
  11.199 +  {
  11.200 +    m_uplinkAllocations.clear();
  11.201 +    m_isIrIntrvlAllocated = false;
  11.202 +    m_isInvIrIntrvlAllocated = false;
  11.203 +    bool allocationForDsa = false;
  11.204 +
  11.205 +    uint32_t symbolsToAllocation = 0;
  11.206 +    uint32_t allocationSize = 0; //size in symbols
  11.207 +    uint32_t availableSymbols = m_bs->GetNrUlSymbols();
  11.208 +    uint32_t availableSymbolsAux = m_bs->GetNrUlSymbols();
  11.209 +
  11.210 +    AllocateInitialRangingInterval(symbolsToAllocation, availableSymbols);
  11.211 +
  11.212 +
  11.213 +    std::vector<SSRecord*> *ssRecords = m_bs->GetSSManager()->GetSSRecords();
  11.214 +    for (std::vector<SSRecord*>::iterator iter = ssRecords->begin(); iter
  11.215 +        != ssRecords->end(); ++iter)
  11.216 +      {
  11.217 +        SSRecord *ssRecord = *iter;
  11.218 +
  11.219 +        if (ssRecord->GetIsBroadcastSS()) continue;
  11.220 +        Ptr<ConnectionIdentifier> cid = ssRecord->GetBasicCid();
  11.221 +        OfdmUlMapIe ulMapIe;
  11.222 +        ulMapIe.SetCid(*cid);
  11.223 +
  11.224 +        if (ssRecord->GetPollForRanging() && ssRecord->GetRangingStatus()
  11.225 +            == WimaxNetDevice::RANGING_STATUS_CONTINUE)
  11.226 +          {
  11.227 +
  11.228 +            //SS's ranging is not yet complete
  11.229 +            //allocating invited initial ranging interval
  11.230 +            ulMapIe.SetUiuc(OfdmUlBurstProfile::UIUC_INITIAL_RANGING);
  11.231 +            allocationSize = m_bs->GetRangReqOppSize();
  11.232 +            m_isInvIrIntrvlAllocated = true;
  11.233 +
  11.234 +            if (availableSymbols >= allocationSize)
  11.235 +              {
  11.236 +                /*
  11.237 +                 #ifdef JDEBUG2
  11.238 +                 std::cout
  11.239 +                 << "BS uplink scheduler, invited ranging allocation, size: "
  11.240 +                 << allocationSize << " symbols" << ", modulation: BPSK 1/2"
  11.241 +                 << std::endl;
  11.242 +                 #endif
  11.243 +                 */
  11.244 +
  11.245 +                AddUplinkAllocation(ulMapIe, allocationSize,
  11.246 +                    symbolsToAllocation, availableSymbols);
  11.247 +              }
  11.248 +            else
  11.249 +              {
  11.250 +
  11.251 +                break;
  11.252 +              }
  11.253 +          }
  11.254 +        else
  11.255 +          {
  11.256 +            //WimaxPhy::ModulationType modulationType = m_bs->GetBurstProfileManager ()->GetModulationTypeForBurst (cid);
  11.257 +            WimaxPhy::ModulationType modulationType =
  11.258 +                ssRecord->GetModulationType();
  11.259 +
  11.260 +            //need to update because modulation/FEC to UIUC mapping may vary over time
  11.261 +            ulMapIe.SetUiuc(m_bs->GetBurstProfileManager()->GetBurstProfile(
  11.262 +                modulationType, WimaxNetDevice::DIRECTION_UPLINK));
  11.263 +
  11.264 +            /*
  11.265 +             #ifdef JDEBUG2
  11.266 +             std::cout << "BS uplink scheduler, creating allocations for SS (Basic CID: " << (uint32_t) cid->GetIdentifier () << ")"
  11.267 +             << ", modulation: " << modulationType
  11.268 +             << ", UIUC: " << (uint32_t) ulMapIe.GetUiuc ()
  11.269 +             << std::endl;
  11.270 +             #endif
  11.271 +             */
  11.272 +
  11.273 +            //establish service flows for SS
  11.274 +            if (ssRecord-> GetRangingStatus()
  11.275 +                == WimaxNetDevice::RANGING_STATUS_SUCCESS
  11.276 +                && !ssRecord->GetAreServiceFlowsAllocated())
  11.277 +              {
  11.278 +
  11.279 +                //allocating grant (with arbitrary size) to allow SS to send DSA messages DSA-REQ and DSA-ACK (See Question 145)
  11.280 +                //only one DSA allocation per frame
  11.281 +                if (!allocationForDsa)
  11.282 +                  {
  11.283 +                    allocationSize = m_bs->GetPhy()->GetNrSymbols(
  11.284 +                        sizeof(DsaReq), modulationType);
  11.285 +
  11.286 +                    if (availableSymbols >= allocationSize)
  11.287 +                      {
  11.288 +                        /*
  11.289 +                         #ifdef JDEBUG2
  11.290 +                         std::cout
  11.291 +                         << "BS uplink scheduler, DSA allocation, size: "
  11.292 +                         << allocationSize << std::endl;
  11.293 +                         #endif
  11.294 +                         */
  11.295 +
  11.296 +                        AddUplinkAllocation(ulMapIe, allocationSize,
  11.297 +                            symbolsToAllocation, availableSymbols);
  11.298 +                        allocationForDsa = true;
  11.299 +                      }
  11.300 +                    else
  11.301 +                      {
  11.302 +                        break;
  11.303 +                      }
  11.304 +                  }
  11.305 +              }
  11.306 +            else
  11.307 +              {
  11.308 +                //all service flows associated to SS are established now
  11.309 +
  11.310 +              /* Implementation of uplink scheduler
  11.311 +               * [1] Freitag, J.; da Fonseca, N.L.S., "Uplink Scheduling with Quality of Service in IEEE 802.16 Networks,"
  11.312 +               * Global Telecommunications Conference, 2007. GLOBECOM '07. IEEE , vol., no., pp.2503-2508, 26-30 Nov. 2007
  11.313 +               * URL: http://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=4411386&isnumber=4410910 */
  11.314 +
  11.315 +              // Step 1
  11.316 +              if (availableSymbols)
  11.317 +                {
  11.318 +                  /*allocating grants for data transmission for UGS flows (Data Grant Burst Type IEs, 6.3.7.4.3.3)
  11.319 +                          (grant has been referred by different names e.g. transmission opportunity, slot,         uplink allocation, etc)*/
  11.320 +
  11.321 +                  if (ssRecord->GetHasServiceFlowUgs())
  11.322 +                  {
  11.323 +
  11.324 +                    Time frame_duration = m_bs->GetPhy ()->GetFrameDuration();
  11.325 +                    Time timestamp = ssRecord->GetServiceFlow(QoSParameterSet::SCHEDULING_TYPE_UGS)->GetRecord()->GetLastGrantTime() +
  11.326 +                                     MilliSeconds (ssRecord->GetServiceFlow(QoSParameterSet::SCHEDULING_TYPE_UGS)->GetParameterSet()->GetUnsolicitedGrantInterval());
  11.327 +                    Time uInterval = MilliSeconds (ssRecord->GetServiceFlow(QoSParameterSet::SCHEDULING_TYPE_UGS)->GetParameterSet()->GetUnsolicitedGrantInterval());
  11.328 +
  11.329 +                    Scalar frame = ((timestamp - Simulator::Now ()) / frame_duration);
  11.330 +/*
  11.331 +                    if (frame.GetDouble() <= 1)
  11.332 +                    {
  11.333 +                      UlJob *jobUGS = new UlJob ();
  11.334 +                      jobUGS->SetSsRecord (ssRecord);
  11.335 +                      jobUGS->SetSchedulingType (QoSParameterSet::SCHEDULING_TYPE_UGS);
  11.336 +                      jobUGS->SetType (UNICAST_POLLING);
  11.337 +                      EnqueueJob (UlJob::HIGH, *jobUGS);
  11.338 +                    }*/
  11.339 +
  11.340 +                    ServiceUnsolicitedGrants (ssRecord, QoSParameterSet::SCHEDULING_TYPE_UGS, ulMapIe,
  11.341 +                                                   modulationType, symbolsToAllocation, availableSymbols);
  11.342 +
  11.343 +                  }
  11.344 +
  11.345 +
  11.346 +                  // allocate unicast polls for rtPS flows if bandwidth is available
  11.347 +                  if (ssRecord->GetHasServiceFlowRtps())
  11.348 +                  {
  11.349 +                    UlJob *jobRTPSPoll = new UlJob ();
  11.350 +                    jobRTPSPoll->SetSsRecord (ssRecord);
  11.351 +                    jobRTPSPoll->SetSchedulingType (QoSParameterSet::SCHEDULING_TYPE_RTPS);
  11.352 +                    jobRTPSPoll->SetType (UNICAST_POLLING);
  11.353 +                    EnqueueJob (UlJob::HIGH, *jobRTPSPoll);
  11.354 +                  }
  11.355 +
  11.356 +                  if (ssRecord->GetHasServiceFlowNrtps())
  11.357 +                  {
  11.358 +                    // allocate unicast polls for nrtPS flows if bandwidth is available
  11.359 +                    UlJob *jobNRTPSPoll = new UlJob ();
  11.360 +                    jobNRTPSPoll->SetSsRecord (ssRecord);
  11.361 +                    jobNRTPSPoll->SetSchedulingType (QoSParameterSet::SCHEDULING_TYPE_NRTPS);
  11.362 +                    jobNRTPSPoll->SetType (UNICAST_POLLING);
  11.363 +                    EnqueueJob (UlJob::HIGH, *jobNRTPSPoll);
  11.364 +                  }
  11.365 +
  11.366 +                  if (ssRecord->GetHasServiceFlowBe())
  11.367 +                  {
  11.368 +                    // finally allocate unicast polls for BE flows if bandwidth is available
  11.369 +                    UlJob *jobBEPoll = new UlJob ();
  11.370 +                    jobBEPoll->SetSsRecord(ssRecord);
  11.371 +                    jobBEPoll->SetSchedulingType(QoSParameterSet::SCHEDULING_TYPE_BE);
  11.372 +                    jobBEPoll->SetType(UNICAST_POLLING);
  11.373 +                    EnqueueJob (UlJob::HIGH, *jobBEPoll);
  11.374 +                  }
  11.375 +                }
  11.376 +              }
  11.377 +          }
  11.378 +      }
  11.379 +
  11.380 +    availableSymbolsAux = availableSymbols;
  11.381 +
  11.382 +    //    uint32_t symbolsUsed = QueueSymbols();
  11.383 +    // Step 2 - Check Deadline - Migrate requests with deadline expiring
  11.384 +     CheckDeadline(availableSymbolsAux);
  11.385 +
  11.386 +     // Step 3 - Check Minimum Bandwidth
  11.387 +     CheckMinimumBandwidth(availableSymbolsAux);
  11.388 +
  11.389 +
  11.390 +     if (!m_uplinkJobs_high.empty()) {
  11.391 +         int x = m_uplinkJobs_high.size();
  11.392 +         fprintf(stdout,"DEBUG: Queue size before high: %d\n", m_uplinkJobs_high.size());
  11.393 +     }
  11.394 +     /* Scheduling high priority queue */
  11.395 +     while ((availableSymbols) && (!m_uplinkJobs_high.empty()))
  11.396 +       {
  11.397 +
  11.398 +         UlJob job = m_uplinkJobs_high.front();
  11.399 +         OfdmUlMapIe ulMapIe;
  11.400 +         SSRecord * ssRecord = job.GetSsRecord();
  11.401 +         QoSParameterSet::SchedulingType schedulingType = job.GetSchedulingType();
  11.402 +
  11.403 +         Ptr<ConnectionIdentifier> cid = ssRecord->GetBasicCid ();
  11.404 +         ulMapIe.SetCid (*cid);
  11.405 +         //WimaxPhy::ModulationType modulationType = m_bs->GetBurstProfileManager ()->GetModulationTypeForBurst (cid);
  11.406 +         WimaxPhy::ModulationType modulationType = ssRecord->GetModulationType ();
  11.407 +         //need to update because modulation/FEC to UIUC mapping may vary over time
  11.408 +         ulMapIe.SetUiuc (m_bs->GetBurstProfileManager ()->GetBurstProfile (modulationType, WimaxNetDevice::DIRECTION_UPLINK));
  11.409 +
  11.410 +         ReqType reqType = job.GetType();
  11.411 +
  11.412 +         if (reqType == UNICAST_POLLING)
  11.413 +           {
  11.414 +             ServiceUnsolicitedGrants (ssRecord, schedulingType, ulMapIe,
  11.415 +                 modulationType, symbolsToAllocation, availableSymbols);
  11.416 +             fprintf(stdout, "DEBUG Flavio: Serving high priority queue polling(connection=%d);\n",cid->GetIdentifier());
  11.417 +           }
  11.418 +         else if (reqType == DATA)
  11.419 +           {
  11.420 +           fprintf(stdout, "DEBUG Flavio: Serving high priority queue;(connection=%d)\n",cid->GetIdentifier());
  11.421 +             ServiceBandwidthRequests (ssRecord, schedulingType, ulMapIe,
  11.422 +                 modulationType, symbolsToAllocation, availableSymbols);
  11.423 +           }
  11.424 +         m_uplinkJobs_high.pop_front();
  11.425 +       }
  11.426 +     if (!m_uplinkJobs_high.empty())
  11.427 +       fprintf(stdout,"DEBUG: Queue size after high: %d\n",m_uplinkJobs_high.size());
  11.428 +     else
  11.429 +       fprintf(stdout,"DEBUG: Queue size after high: 0\n");
  11.430 +
  11.431 +
  11.432 +     if (!m_uplinkJobs_inter.empty())
  11.433 +       fprintf(stdout, "DEBUG: Queue size before inter: %d\n",  m_uplinkJobs_inter.size());
  11.434 +     /* Scheduling intermediate priority queue */
  11.435 +     while ((availableSymbols) && (!m_uplinkJobs_inter.empty()))
  11.436 +       {
  11.437 +
  11.438 +         UlJob job = m_uplinkJobs_inter.front();
  11.439 +         OfdmUlMapIe ulMapIe;
  11.440 +         SSRecord * ssRecord = job.GetSsRecord();
  11.441 +         QoSParameterSet::SchedulingType schedulingType = job.GetSchedulingType();
  11.442 +
  11.443 +         Ptr<ConnectionIdentifier> cid = ssRecord->GetBasicCid ();
  11.444 +         ulMapIe.SetCid (*cid);
  11.445 +         //WimaxPhy::ModulationType modulationType = m_bs->GetBurstProfileManager ()->GetModulationTypeForBurst (cid);
  11.446 +         WimaxPhy::ModulationType modulationType = ssRecord->GetModulationType ();
  11.447 +         //need to update because modulation/FEC to UIUC mapping may vary over time
  11.448 +         ulMapIe.SetUiuc (m_bs->GetBurstProfileManager ()->GetBurstProfile (modulationType, WimaxNetDevice::DIRECTION_UPLINK));
  11.449 +
  11.450 +         ReqType reqType = job.GetType();
  11.451 +
  11.452 +         if (reqType == UNICAST_POLLING)
  11.453 +           {
  11.454 +             ServiceUnsolicitedGrants (ssRecord, schedulingType, ulMapIe,
  11.455 +                 modulationType, symbolsToAllocation, availableSymbols);
  11.456 +           }
  11.457 +         else if (reqType == DATA)
  11.458 +           {
  11.459 +           fprintf(stdout, "DEBUG Flavio: Serving inter pririty queue data(connection=%d);\n",cid->GetIdentifier());
  11.460 +             ServiceBandwidthRequests (ssRecord, schedulingType, ulMapIe,
  11.461 +                 modulationType, symbolsToAllocation, availableSymbols);
  11.462 +           }
  11.463 +         m_uplinkJobs_inter.pop_front();
  11.464 +       }
  11.465 +     if (!m_uplinkJobs_inter.empty())
  11.466 +       fprintf(stdout, "DEBUG: Queue size after inter: %d\n", m_uplinkJobs_inter.size());
  11.467 +     else
  11.468 +       fprintf(stdout, "DEBUG: Queue size after inter: 0\n");
  11.469 +
  11.470 +     /* Scheduling low priority queue */
  11.471 +     while ((availableSymbols) && (!m_uplinkJobs_low.empty()))
  11.472 +       {
  11.473 +
  11.474 +         UlJob job = m_uplinkJobs_low.front();
  11.475 +         OfdmUlMapIe ulMapIe;
  11.476 +         SSRecord * ssRecord = job.GetSsRecord();
  11.477 +         QoSParameterSet::SchedulingType schedulingType = job.GetSchedulingType();
  11.478 +
  11.479 +         Ptr<ConnectionIdentifier> cid = ssRecord->GetBasicCid ();
  11.480 +         ulMapIe.SetCid (*cid);
  11.481 +         //WimaxPhy::ModulationType modulationType = m_bs->GetBurstProfileManager ()->GetModulationTypeForBurst (cid);
  11.482 +         WimaxPhy::ModulationType modulationType = ssRecord->GetModulationType ();
  11.483 +         //need to update because modulation/FEC to UIUC mapping may vary over time
  11.484 +         ulMapIe.SetUiuc (m_bs->GetBurstProfileManager ()->GetBurstProfile (modulationType, WimaxNetDevice::DIRECTION_UPLINK));
  11.485 +
  11.486 +         ReqType reqType = job.GetType();
  11.487 +
  11.488 +         if (reqType == UNICAST_POLLING)
  11.489 +           {
  11.490 +             ServiceUnsolicitedGrants (ssRecord, schedulingType, ulMapIe,
  11.491 +                 modulationType, symbolsToAllocation, availableSymbols);
  11.492 +           }
  11.493 +         else if (reqType == DATA)
  11.494 +           {
  11.495 +           fprintf(stdout, "DEBUG Flavio: Serving low priority queue data(connection=%d);\n",cid->GetIdentifier());
  11.496 +             ServiceBandwidthRequests (ssRecord, schedulingType, ulMapIe,
  11.497 +                 modulationType, symbolsToAllocation, availableSymbols);
  11.498 +           }
  11.499 +         m_uplinkJobs_low.pop_front();
  11.500 +       }
  11.501 +
  11.502 +    OfdmUlMapIe ulMapIeEnd;
  11.503 +    ulMapIeEnd.SetCid(*CreateObject<ConnectionIdentifier> ("Identifier",
  11.504 +        UintegerValue(0)));
  11.505 +    ulMapIeEnd.SetStartTime(symbolsToAllocation);
  11.506 +    ulMapIeEnd.SetUiuc(OfdmUlBurstProfile::UIUC_END_OF_MAP);
  11.507 +    ulMapIeEnd.SetDuration(0);
  11.508 +    m_uplinkAllocations.push_back(ulMapIeEnd);
  11.509 +
  11.510 +    /*
  11.511 +     #ifdef JDEBUG2
  11.512 +     if (m_uplinkAllocations.size() > 1) //ignoring End of Map UL-MAP IE
  11.513 +     std::cout << "BS uplink scheduler, total allocations: "
  11.514 +     << m_uplinkAllocations.size() - 1 << ", symbols left: "
  11.515 +     << availableSymbols << std::endl;
  11.516 +     #endif
  11.517 +     */
  11.518 +
  11.519 +    //setting DL/UL subframe allocation for the next frame
  11.520 +    m_bs->GetBandwidthManager()->SetSubframeRatio();
  11.521 +  }
  11.522 +
  11.523 +  void
  11.524 +  UplinkSchedulerMBQoS::EnqueueJob (UlJob::JobPriority priority, UlJob job)
  11.525 +  {
  11.526 +    switch (priority)
  11.527 +    {
  11.528 +    case UlJob::HIGH:
  11.529 +      m_uplinkJobs_high.push_back (job);
  11.530 +      break;
  11.531 +    case UlJob::INTERMEDIATE:
  11.532 +      m_uplinkJobs_inter.push_back (job);
  11.533 +      break;
  11.534 +    case UlJob::LOW:
  11.535 +      m_uplinkJobs_low.push_back (job);
  11.536 +    }
  11.537 +  }
  11.538 +
  11.539 +  UlJob
  11.540 +  UplinkSchedulerMBQoS::DequeueJob (UlJob::JobPriority priority)
  11.541 +  {
  11.542 +    UlJob job_front;
  11.543 +    switch (priority)
  11.544 +    {
  11.545 +    case UlJob::HIGH:
  11.546 +      job_front = m_uplinkJobs_high.front();
  11.547 +      m_uplinkJobs_high.pop_front();
  11.548 +      break;
  11.549 +    case UlJob::INTERMEDIATE:
  11.550 +      job_front = m_uplinkJobs_inter.front();
  11.551 +      m_uplinkJobs_inter.pop_front();
  11.552 +      break;
  11.553 +    case UlJob::LOW:
  11.554 +      job_front = m_uplinkJobs_low.front();
  11.555 +      m_uplinkJobs_low.pop_front();
  11.556 +    }
  11.557 +    return job_front;
  11.558 +  }
  11.559 +
  11.560 +
  11.561 +
  11.562 +  bool
  11.563 +  UplinkSchedulerMBQoS::CheckDeadline (uint32_t &availableSymbols)
  11.564 +  {
  11.565 +
  11.566 +    // for each request in the imermediate queue
  11.567 +    if (m_uplinkJobs_inter.size() > 0)
  11.568 +    {
  11.569 +
  11.570 +      std::list<UlJob>::iterator iter = m_uplinkJobs_inter.begin();
  11.571 +      std::list<UlJob>::iterator iterPrev = m_uplinkJobs_inter.begin();
  11.572 +
  11.573 +      while (iter != m_uplinkJobs_inter.end() && availableSymbols)
  11.574 +      {
  11.575 +
  11.576 +        UlJob job = *iter;
  11.577 +
  11.578 +        /*std::cout << "Job info: " << job.GetSsRecord()->GetBasicCid()
  11.579 +                    << std::endl;*/
  11.580 +
  11.581 +
  11.582 +        if (job.GetSchedulingType() == QoSParameterSet::SCHEDULING_TYPE_RTPS)
  11.583 +        {
  11.584 +          ServiceFlow *serviceFlow = job.GetServiceFlow ();
  11.585 +          Time deadline = job.GetDeadline();
  11.586 +          Time frame_duration = m_bs->GetPhy ()->GetFrameDuration();
  11.587 +
  11.588 +          Scalar frame = ((deadline - Simulator::Now ()) / frame_duration);
  11.589 +
  11.590 +          std::cout << "Now: " << Simulator::Now ()
  11.591 +              << " Deadline: " << deadline
  11.592 +              << " Frame duration" << frame_duration
  11.593 +              << std::endl;
  11.594 +
  11.595 +          // TODO: subtrair simbolos
  11.596 +
  11.597 +          if (frame.GetDouble() <= 1)
  11.598 +          {
  11.599 +            // verificar se tem espaco
  11.600 +            // migrate request
  11.601 +            UlJob jobTmp = job;
  11.602 +            EnqueueJob (UlJob::HIGH, jobTmp);
  11.603 +            //m_uplinkJobs_inter.remove (job);
  11.604 +            m_uplinkJobs_inter.erase (iter);
  11.605 +            iter = m_uplinkJobs_inter.begin();
  11.606 +
  11.607 +          }
  11.608 +          else
  11.609 +          {
  11.610 +            iter++;
  11.611 +          }
  11.612 +        }
  11.613 +        else
  11.614 +        {
  11.615 +          iter++;
  11.616 +        }
  11.617 +      }
  11.618 +    }
  11.619 +  }
  11.620 +
  11.621 +  int
  11.622 +  UplinkSchedulerMBQoS::ComparePriority (PriorityUlJob & a, PriorityUlJob & b)
  11.623 +  {
  11.624 +    const PriorityUlJob A;
  11.625 +    const PriorityUlJob B;
  11.626 +
  11.627 +    if (a.GetPriority () < b.GetPriority ())
  11.628 +      return 1;
  11.629 +    if (a.GetPriority () > b.GetPriority ())
  11.630 +      return -1;
  11.631 +
  11.632 +    if (a.GetUlJob()->GetServiceFlow()->GetRecord()->GetBacklogged() < b.GetUlJob()->GetServiceFlow()->GetRecord()->GetBacklogged())
  11.633 +      return 1;
  11.634 +    if (a.GetUlJob()->GetServiceFlow()->GetRecord()->GetBacklogged() > b.GetUlJob()->GetServiceFlow()->GetRecord()->GetBacklogged())
  11.635 +        return -1;
  11.636 +    return 0;
  11.637 +  }
  11.638 +
  11.639 +  bool
  11.640 +  UplinkSchedulerMBQoS::CheckMinimumBandwidth(uint32_t &availableSymbols)
  11.641 +  {
  11.642 +    std::list<PriorityUlJob> priorityUlJobs;
  11.643 +
  11.644 +    // For each connection of type rtPS or nrtPS
  11.645 +    std::vector<SSRecord*> *ssRecords = m_bs->GetSSManager ()->GetSSRecords ();
  11.646 +    for (std::vector<SSRecord*>::iterator iter = ssRecords->begin ();
  11.647 +        iter != ssRecords->end (); ++iter)
  11.648 +    {
  11.649 +      SSRecord *ssRecord = *iter;
  11.650 +      std::vector<ServiceFlow*> *serviceFlows = ssRecord->GetServiceFlows(QoSParameterSet::SCHEDULING_TYPE_ALL);
  11.651 +      for (std::vector<ServiceFlow*>::iterator iter2 = serviceFlows->begin ();
  11.652 +             iter2 != serviceFlows->end (); ++iter2)
  11.653 +        {
  11.654 +          ServiceFlow *serviceFlow = *iter2;
  11.655 +          if (serviceFlow->GetSchedulingType() == QoSParameterSet::SCHEDULING_TYPE_RTPS ||
  11.656 +              serviceFlow->GetSchedulingType() == QoSParameterSet::SCHEDULING_TYPE_NRTPS)
  11.657 +          {
  11.658 +            serviceFlow->GetRecord ()->SetBackloggedTemp (serviceFlow->GetRecord ()->GetBacklogged ());
  11.659 +            serviceFlow->GetRecord ()->SetGrantedBandwidthTemp (serviceFlow->GetRecord ()->GetBwSinceLastExpiry ());
  11.660 +          }
  11.661 +        }
  11.662 +    }
  11.663 +
  11.664 +
  11.665 +    // for each request in the imermediate queue
  11.666 +    for ( std::list<UlJob>::const_iterator iter = m_uplinkJobs_inter.begin(); iter != m_uplinkJobs_inter.end(); ++iter)
  11.667 +    {
  11.668 +      UlJob job = *iter;
  11.669 +      //SSRecord ssRecord = job.GetSsRecord();
  11.670 +      ServiceFlow *serviceFlow = job.GetServiceFlow ();
  11.671 +      if ((job.GetSchedulingType() == QoSParameterSet::SCHEDULING_TYPE_RTPS ||
  11.672 +           job.GetSchedulingType() == QoSParameterSet::SCHEDULING_TYPE_NRTPS)
  11.673 +           && (serviceFlow->GetRecord ()->GetBacklogged () > 0))
  11.674 +      {
  11.675 +        uint32_t minReservedTrafficRate = serviceFlow->GetParameterSet ()->GetMinReservedTrafficRate ();
  11.676 +        uint32_t grantedBandwidth = serviceFlow->GetRecord ()-> GetBwSinceLastExpiry ();
  11.677 +
  11.678 +        PriorityUlJob priorityUlJob ;
  11.679 +        priorityUlJob.SetUlJob(&job);
  11.680 +        // pri_array
  11.681 +        if (minReservedTrafficRate <= grantedBandwidth)
  11.682 +        {
  11.683 +          priorityUlJob.SetPriority(-10000);
  11.684 +        }
  11.685 +        else
  11.686 +        {
  11.687 +          u_int32_t allocationSize = serviceFlow->GetRecord ()->GetRequestedBandwidth () - serviceFlow->GetRecord ()-> GetGrantedBandwidth ();
  11.688 +          u_int32_t sduSize = serviceFlow->GetParameterSet ()->GetSduSize ();
  11.689 +
  11.690 +          if (allocationSize > 0)
  11.691 +          {
  11.692 +            if (sduSize > 0)
  11.693 +            {
  11.694 +             //if SDU size is mentioned, grant of that size
  11.695 +              allocationSize = sduSize;
  11.696 +            }
  11.697 +          }
  11.698 +          // TODO: atualizar available symbols e verificar available symbols
  11.699 +          int priority = serviceFlow->GetRecord ()->GetBackloggedTemp () - ( serviceFlow->GetRecord ()->GetGrantedBandwidthTemp () - minReservedTrafficRate );
  11.700 +          priorityUlJob.SetPriority (priority);
  11.701 +          serviceFlow->GetRecord ()->SetGrantedBandwidthTemp (serviceFlow->GetRecord ()->GetGrantedBandwidthTemp () + allocationSize);
  11.702 +          serviceFlow->GetRecord ()->SetBackloggedTemp ( serviceFlow->GetRecord ()->GetBackloggedTemp() - allocationSize );
  11.703 +        }
  11.704 +
  11.705 +        priorityUlJobs.push_back (priorityUlJob);
  11.706 +      }
  11.707 +    }
  11.708 +
  11.709 +    // TODO: rever sort
  11.710 +    //priorityUlJobs.sort ( &UplinkSchedulerMBQoS::ComparePriority );
  11.711 +    priorityUlJobs.sort ( SortProcess() );
  11.712 +
  11.713 +    for ( std::list<PriorityUlJob>::const_iterator iter = priorityUlJobs.begin(); iter != priorityUlJobs.end(); ++iter)
  11.714 +    {
  11.715 +      PriorityUlJob priorityUlJob = *iter;
  11.716 +      UlJob *job_priority = priorityUlJob.GetUlJob();
  11.717 +      UlJob job = *job_priority;
  11.718 +      // verificar se tem espaco
  11.719 +      // migrate request
  11.720 +      m_uplinkJobs_inter.remove (job);
  11.721 +      EnqueueJob (UlJob::HIGH, job);
  11.722 +    }
  11.723 +
  11.724 +  }
  11.725 +
  11.726 +
  11.727 +
  11.728 +  void
  11.729 +  UplinkSchedulerMBQoS::ServiceUnsolicitedGrants(const SSRecord *ssRecord,
  11.730 +      QoSParameterSet::SchedulingType schedulingType, OfdmUlMapIe &ulMapIe,
  11.731 +      const WimaxPhy::ModulationType modulationType,
  11.732 +      uint32_t &symbolsToAllocation, uint32_t &availableSymbols)
  11.733 +  {
  11.734 +    uint32_t allocationSize = 0; //size in symbols
  11.735 +    uint8_t uiuc = ulMapIe.GetUiuc(); //SS's burst profile
  11.736 +    std::vector<ServiceFlow*> *serviceFlows = ssRecord->GetServiceFlows(
  11.737 +        schedulingType);
  11.738 +
  11.739 +    for (std::vector<ServiceFlow*>::iterator iter = serviceFlows->begin(); iter
  11.740 +        != serviceFlows->end(); ++iter)
  11.741 +      {
  11.742 +        ServiceFlow *serviceFlow = *iter;
  11.743 +
  11.744 +        /* in case of rtPS, nrtPS and BE, allocating unicast polls for bandwidth requests (Request IEs, 6.3.7.4.3.1).
  11.745 +         in case of UGS, allocating grants for data transmission (Data Grant Burst Type IEs, 6.3.7.4.3.3) (grant has
  11.746 +         been referred in this code by different names e.g. transmission opportunity, slot, allocation, etc) */
  11.747 +
  11.748 +        allocationSize = m_bs->GetBandwidthManager()->CalculateAllocationSize(
  11.749 +            ssRecord, serviceFlow);
  11.750 +
  11.751 +        // Flavio : it will checked in CheckMinimumBandwidth
  11.752 +        //verifying that minimum reserved traffic rate of nrtPS flow is maintained
  11.753 +       /* if (serviceFlow->GetSchedulingType()
  11.754 +            == QoSParameterSet::SCHEDULING_TYPE_NRTPS)
  11.755 +          {
  11.756 +            Time currentTime = Simulator::Now();
  11.757 +            ServiceFlowRecord *record = serviceFlow->GetRecord();
  11.758 +            if (currentTime - record->GetGrantTimeStamp() > Seconds(1))
  11.759 +              {
  11.760 +                uint32_t bps = (record->GetBwSinceLastExpiry() * 8);
  11.761 +                if (bps
  11.762 +                    < serviceFlow->GetParameterSet()->GetMinReservedTrafficRate())
  11.763 +                  {
  11.764 +                    ServiceBandwidthRequests(serviceFlow, schedulingType,
  11.765 +                        ulMapIe, modulationType, symbolsToAllocation,
  11.766 +                        availableSymbols);
  11.767 +                    record->SetBwSinceLastExpiry(0);
  11.768 +                    record->SetGrantTimeStamp(currentTime);
  11.769 +                  }
  11.770 +              }
  11.771 +          }*/
  11.772 +
  11.773 +        if (availableSymbols < allocationSize)
  11.774 +          break;
  11.775 +
  11.776 +        if (allocationSize > 0)
  11.777 +          {
  11.778 +            ulMapIe.SetStartTime(symbolsToAllocation);
  11.779 +            if (serviceFlow->GetSchedulingType()
  11.780 +                != QoSParameterSet::SCHEDULING_TYPE_UGS)
  11.781 +              {
  11.782 +                //special burst profile with most robust modulation type is used for unicast polls (Request IEs)
  11.783 +                ulMapIe.SetUiuc(OfdmUlBurstProfile::UIUC_REQ_REGION_FULL);
  11.784 +              }
  11.785 +          }
  11.786 +        else
  11.787 +          {
  11.788 +            continue;
  11.789 +          }
  11.790 +
  11.791 +#ifdef JDEBUG2
  11.792 +        if (serviceFlow->GetSchedulingType()
  11.793 +            == QoSParameterSet::SCHEDULING_TYPE_UGS)
  11.794 +          {
  11.795 +            std::cout << "BS uplink scheduler, UGS allocation, size: "
  11.796 +                << allocationSize << " symbols";
  11.797 +          }
  11.798 +        else
  11.799 +          {
  11.800 +            std::cout << "BS uplink scheduler, "
  11.801 +                << serviceFlow->GetParameterSet()->GetSchedulingTypeStr()
  11.802 +                << " unicast poll, size: " << allocationSize << " symbols"
  11.803 +                << ", modulation: BPSK 1/2";
  11.804 +          }
  11.805 +
  11.806 +        std::cout << ", CID: "
  11.807 +            << (uint32_t) serviceFlow->GetConnection()->GetCid()->GetIdentifier()
  11.808 +            << ", SFID: " << serviceFlow->GetSfid() << std::endl;
  11.809 +#endif
  11.810 +
  11.811 +        serviceFlow->GetRecord ()->SetLastGrantTime(Simulator::Now());
  11.812 +        AddUplinkAllocation(ulMapIe, allocationSize, symbolsToAllocation,
  11.813 +            availableSymbols);
  11.814 +        ulMapIe.SetUiuc(uiuc);
  11.815 +      }
  11.816 +  }
  11.817 +
  11.818 +  void
  11.819 +  UplinkSchedulerMBQoS::ServiceBandwidthRequests(const SSRecord *ssRecord,
  11.820 +      QoSParameterSet::SchedulingType schedulingType, OfdmUlMapIe &ulMapIe,
  11.821 +      const WimaxPhy::ModulationType modulationType,
  11.822 +      uint32_t &symbolsToAllocation, uint32_t &availableSymbols)
  11.823 +  {
  11.824 +    std::vector<ServiceFlow*> *serviceFlows = ssRecord->GetServiceFlows(
  11.825 +        schedulingType);
  11.826 +
  11.827 +    for (std::vector<ServiceFlow*>::iterator iter = serviceFlows->begin(); iter
  11.828 +        != serviceFlows->end(); ++iter)
  11.829 +      {
  11.830 +        if (!ServiceBandwidthRequests(*iter, schedulingType, ulMapIe,
  11.831 +            modulationType, symbolsToAllocation, availableSymbols))
  11.832 +          {
  11.833 +            break;
  11.834 +          }
  11.835 +      }
  11.836 +  }
  11.837 +
  11.838 +  bool
  11.839 +  UplinkSchedulerMBQoS::ServiceBandwidthRequests(ServiceFlow *serviceFlow,
  11.840 +      QoSParameterSet::SchedulingType schedulingType, OfdmUlMapIe &ulMapIe,
  11.841 +      const WimaxPhy::ModulationType modulationType,
  11.842 +      uint32_t &symbolsToAllocation, uint32_t &availableSymbols)
  11.843 +  {
  11.844 +    uint32_t allocSizeBytes = 0;
  11.845 +    uint32_t allocSizeSymbols = 0;
  11.846 +    uint16_t sduSize = 0;
  11.847 +
  11.848 +    ServiceFlowRecord *record = serviceFlow->GetRecord();
  11.849 +    sduSize = serviceFlow->GetParameterSet()->GetSduSize();
  11.850 +
  11.851 +    uint32_t requiredBandwidth = record->GetRequestedBandwidth()
  11.852 +        - record->GetGrantedBandwidth();
  11.853 +    if (requiredBandwidth > 0)
  11.854 +      {
  11.855 +        if (sduSize > 0)
  11.856 +          {
  11.857 +            //if SDU size is mentioned, allocate grant of that size
  11.858 +            allocSizeBytes = sduSize;
  11.859 +            allocSizeSymbols = m_bs->GetPhy()->GetNrSymbols(sduSize,
  11.860 +                modulationType);
  11.861 +
  11.862 +          }
  11.863 +        else
  11.864 +          {
  11.865 +            allocSizeBytes = requiredBandwidth;
  11.866 +            allocSizeSymbols = m_bs->GetPhy()->GetNrSymbols(requiredBandwidth,
  11.867 +                modulationType);
  11.868 +          }
  11.869 +
  11.870 +        if (availableSymbols >= allocSizeSymbols)
  11.871 +          {
  11.872 +#ifdef JDEBUG2
  11.873 +            std::cout << "BS uplink scheduler, "
  11.874 +                << serviceFlow->GetParameterSet()->GetSchedulingTypeStr()
  11.875 +                << " allocation, size: " << allocSizeSymbols << " symbols"
  11.876 +                << ", CID: "
  11.877 +                << (uint32_t) serviceFlow->GetConnection()->GetCid()->GetIdentifier()
  11.878 +                << ", SFID: " << serviceFlow->GetSfid() << ", bw requested: "
  11.879 +                << record->GetRequestedBandwidth() << ", bw granted: "
  11.880 +                << record->GetGrantedBandwidth() << std::endl;
  11.881 +#endif
  11.882 +
  11.883 +            record->UpdateGrantedBandwidth(allocSizeBytes);
  11.884 +
  11.885 +            //if (schedulingType == QoSParameterSet::SCHEDULING_TYPE_NRTPS)
  11.886 +            //  {
  11.887 +                record->SetBwSinceLastExpiry(allocSizeBytes);
  11.888 +            //  }
  11.889 +
  11.890 +            if (serviceFlow->GetRecord ()->GetBacklogged () < allocSizeBytes)
  11.891 +             {
  11.892 +               serviceFlow->GetRecord ()->SetBacklogged (0);
  11.893 +             }
  11.894 +             else
  11.895 +             {
  11.896 +               serviceFlow->GetRecord ()->UpdateBacklogged (-allocSizeBytes);
  11.897 +             }
  11.898 +
  11.899 +            AddUplinkAllocation(ulMapIe, allocSizeSymbols, symbolsToAllocation,
  11.900 +                availableSymbols);
  11.901 +          }
  11.902 +        else
  11.903 +          {
  11.904 +            return false;
  11.905 +          }
  11.906 +      }
  11.907 +    return true;
  11.908 +  }
  11.909 +
  11.910 +  void
  11.911 +  UplinkSchedulerMBQoS::AllocateInitialRangingInterval(
  11.912 +      uint32_t &symbolsToAllocation, uint32_t &availableSymbols)
  11.913 +  {
  11.914 +    Time ssUlStartTime = Seconds(CalculateAllocationStartTime()
  11.915 +        * m_bs->GetPsDuration().GetSeconds());
  11.916 +    m_nrIrOppsAllocated
  11.917 +        = m_bs->GetLinkManager()->CalculateRangingOppsToAllocate();
  11.918 +    uint32_t allocationSize = m_nrIrOppsAllocated * m_bs->GetRangReqOppSize();
  11.919 +    Time timeSinceLastIrInterval = Simulator::Now() - m_timeStampIrInterval;
  11.920 +
  11.921 +    //adding one frame because may be the time has not elapsed now but will elapse before the next frame is sent
  11.922 +    if (timeSinceLastIrInterval + m_bs->GetPhy()->GetFrameDuration()
  11.923 +        > m_bs->GetInitialRangingInterval() && availableSymbols
  11.924 +        >= allocationSize)
  11.925 +      {
  11.926 +        m_isIrIntrvlAllocated = true;
  11.927 +        OfdmUlMapIe ulMapIeIr;
  11.928 +        ulMapIeIr.SetCid(*m_bs->GetBroadcastConnection()->GetCid());
  11.929 +        ulMapIeIr.SetStartTime(symbolsToAllocation);
  11.930 +        ulMapIeIr.SetUiuc(OfdmUlBurstProfile::UIUC_INITIAL_RANGING);
  11.931 +
  11.932 +#ifdef JDEBUG2
  11.933 +        std::cout << "BS uplink scheduler, initial ranging allocation, size: "
  11.934 +            << allocationSize << " symbols" << ", modulation: BPSK 1/2"
  11.935 +            << std::endl;
  11.936 +#endif
  11.937 +
  11.938 +        //marking start and end of each TO, only for debugging
  11.939 +        for (uint8_t i = 0; i < m_nrIrOppsAllocated; i++)
  11.940 +          {
  11.941 +            m_bs->MarkRangingOppStart(ssUlStartTime + Seconds(
  11.942 +                symbolsToAllocation * m_bs->GetSymbolDuration().GetSeconds())
  11.943 +                + Seconds(i * m_bs->GetRangReqOppSize()
  11.944 +                    * m_bs->GetSymbolDuration().GetSeconds()));
  11.945 +          }
  11.946 +
  11.947 +        AddUplinkAllocation(ulMapIeIr, allocationSize, symbolsToAllocation,
  11.948 +            availableSymbols);
  11.949 +        m_timeStampIrInterval = Simulator::Now();
  11.950 +      }
  11.951 +  }
  11.952 +
  11.953 +  void
  11.954 +  UplinkSchedulerMBQoS::SetupServiceFlow(SSRecord *ssRecord,
  11.955 +      ServiceFlow *serviceFlow)
  11.956 +  {
  11.957 +    uint8_t delayNrFrames = 1;
  11.958 +    uint32_t bitsPerSecond =
  11.959 +        serviceFlow->GetParameterSet()->GetMinReservedTrafficRate();
  11.960 +    uint32_t bytesPerFrame = (uint32_t((double) (bitsPerSecond)
  11.961 +        * m_bs->GetPhy()->GetFrameDuration().GetSeconds())) / 8;
  11.962 +    uint32_t frameDurationMSec =
  11.963 +        m_bs->GetPhy()->GetFrameDuration().GetMilliSeconds();
  11.964 +
  11.965 +    switch (serviceFlow->GetSchedulingType())
  11.966 +      {
  11.967 +    case QoSParameterSet::SCHEDULING_TYPE_UGS:
  11.968 +      {
  11.969 +        uint32_t grantSize = m_bs->GetPhy()->GetNrSymbols(bytesPerFrame,
  11.970 +            ssRecord->GetModulationType());
  11.971 +        serviceFlow->GetRecord()->SetGrantSize(grantSize);
  11.972 +
  11.973 +        uint32_t toleratedJitter =
  11.974 +            serviceFlow->GetParameterSet()->GetToleratedJitter();
  11.975 +
  11.976 +        if (toleratedJitter > frameDurationMSec)
  11.977 +          {
  11.978 +            delayNrFrames = (uint8_t)(toleratedJitter / frameDurationMSec);
  11.979 +          }
  11.980 +
  11.981 +        //uint32_t availableSymbolsPerFrame = m_device->GetNrDlSymbols () - GetSymbolsPerFrameAllocated ();
  11.982 +
  11.983 +        uint16_t interval = delayNrFrames * frameDurationMSec;
  11.984 +        serviceFlow->GetParameterSet()->SetUnsolicitedGrantInterval(interval);
  11.985 +      }
  11.986 +      break;
  11.987 +    case QoSParameterSet::SCHEDULING_TYPE_RTPS:
  11.988 +      {
  11.989 +        if (serviceFlow->GetParameterSet()->GetSduSize() > bytesPerFrame)
  11.990 +          {
  11.991 +            delayNrFrames = (uint8_t)(
  11.992 +                serviceFlow->GetParameterSet()->GetSduSize() / bytesPerFrame);
  11.993 +          }
  11.994 +
  11.995 +        uint16_t interval = delayNrFrames * frameDurationMSec;
  11.996 +        serviceFlow->GetParameterSet()->SetUnsolicitedPollingInterval(interval);
  11.997 +      }
  11.998 +      break;
  11.999 +    case QoSParameterSet::SCHEDULING_TYPE_NRTPS:
 11.1000 +      {
 11.1001 +        //no real-time guarantees are given to NRTPS, serviced based on available bandwidth
 11.1002 +      }
 11.1003 +      break;
 11.1004 +    case QoSParameterSet::SCHEDULING_TYPE_BE:
 11.1005 +      {
 11.1006 +        //no real-time guarantees are given to BE, serviced based on available bandwidth
 11.1007 +      }
 11.1008 +      break;
 11.1009 +    default:
 11.1010 +      NS_ASSERT(false);
 11.1011 +      }
 11.1012 +  }
 11.1013 +
 11.1014 +  void
 11.1015 +  UplinkSchedulerMBQoS::ProcessBandwidthRequest (const BandwidthRequestHeader &bwRequestHdr)
 11.1016 +  {
 11.1017 +    // Flavio Kubota: Enqueue requests for uplink scheduler.
 11.1018 +    UlJob *job = new UlJob ();
 11.1019 +    Ptr<WimaxConnection> connectionIdentifier = m_bs->GetConnectionManager ()->GetConnection(bwRequestHdr.GetCid ().Copy ());
 11.1020 +    SSRecord *ssRecord = m_bs->GetSSManager ()->GetSSRecord (connectionIdentifier->GetCid ());
 11.1021 +    ServiceFlow *serviceFlow = m_bs->GetConnectionManager()->GetConnection(
 11.1022 +        bwRequestHdr.GetCid().Copy())->GetServiceFlow();
 11.1023 +
 11.1024 +    u_int32_t size = bwRequestHdr.GetBr ();
 11.1025 +    Time deadline = DetermineDeadline (serviceFlow);
 11.1026 +    Time currentTime = Simulator::Now ();
 11.1027 +    Time period = deadline; // So that deadline is properly updated..
 11.1028 +
 11.1029 +    // Record data in job
 11.1030 +    job->SetSsRecord (ssRecord);
 11.1031 +    job->SetServiceFlow (serviceFlow);
 11.1032 +    job->SetSize (size);
 11.1033 +    job->SetDeadline (deadline);
 11.1034 +    job->SetReleaseTime (currentTime);
 11.1035 +    job->SetSchedulingType (serviceFlow->GetSchedulingType());
 11.1036 +    job->SetPeriod (period);
 11.1037 +    job->SetType(DATA);
 11.1038 +
 11.1039 +    // Enqueue job in Uplink Scheduler
 11.1040 +    switch (serviceFlow->GetSchedulingType())
 11.1041 +    {
 11.1042 +      case QoSParameterSet::SCHEDULING_TYPE_RTPS:
 11.1043 +        EnqueueJob (UlJob::INTERMEDIATE, *job);
 11.1044 +        break;
 11.1045 +      case QoSParameterSet::SCHEDULING_TYPE_NRTPS:
 11.1046 +        EnqueueJob (UlJob::INTERMEDIATE, *job);
 11.1047 +        break;
 11.1048 +      case QoSParameterSet::SCHEDULING_TYPE_BE:
 11.1049 +        EnqueueJob (UlJob::LOW, *job);
 11.1050 +        break;
 11.1051 +      default:
 11.1052 +        EnqueueJob (UlJob::LOW, *job);
 11.1053 +        break;
 11.1054 +    }
 11.1055 +  }
 11.1056 +
 11.1057 +  /*
 11.1058 +   * Flavio Kubota: Calculate Deadline of requests according to QoS parameter
 11.1059 +   * */
 11.1060 +  Time
 11.1061 +  UplinkSchedulerMBQoS::DetermineDeadline(ServiceFlow *serviceFlow)
 11.1062 +  {
 11.1063 +    uint32_t latency = serviceFlow->GetParameterSet()->GetMaxLatency ();
 11.1064 +    Time lastGrantTime = serviceFlow->GetRecord ()->GetLastGrantTime ();
 11.1065 +    Time deadline =  MilliSeconds(latency) + lastGrantTime;
 11.1066 +    return deadline;
 11.1067 +  }
 11.1068 +
 11.1069 +  void
 11.1070 +  UplinkSchedulerMBQoS::ConfigureBs (Ptr<WimaxBaseStationNetDevice> bs)
 11.1071 +  {
 11.1072 +    m_bs = bs;
 11.1073 +  }
 11.1074 +
 11.1075 +}//namespace ns3
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/src/devices/wimax/uplink-scheduler-mbqos.h	Tue Aug 11 16:41:52 2009 -0300
    12.3 @@ -0,0 +1,144 @@
    12.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
    12.5 +/*
    12.6 + * Copyright (c) 2007,2008 INRIA
    12.7 + *
    12.8 + * This program is free software; you can redistribute it and/or modify
    12.9 + * it under the terms of the GNU General Public License version 2 as
   12.10 + * published by the Free Software Foundation;
   12.11 + *
   12.12 + * This program is distributed in the hope that it will be useful,
   12.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   12.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12.15 + * GNU General Public License for more details.
   12.16 + *
   12.17 + * You should have received a copy of the GNU General Public License
   12.18 + * along with this program; if not, write to the Free Software
   12.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   12.20 + *
   12.21 + * Author: Jahanzeb Farooq <jahanzeb.farooq@sophia.inria.fr>
   12.22 + */
   12.23 +
   12.24 +#ifndef UPLINK_SCHEDULER_MBQOS_H
   12.25 +#define UPLINK_SCHEDULER_MBQOS_H
   12.26 +
   12.27 +#include <stdint.h>
   12.28 +#include "ul-mac-messages.h"
   12.29 +#include "ns3/nstime.h"
   12.30 +#include "qos-parameter-set.h"
   12.31 +#include "wimax-phy.h"
   12.32 +#include "ul-job.h"
   12.33 +#include "service-flow-record.h"
   12.34 +#include "ns3/object.h"
   12.35 +#include "uplink-scheduler.h"
   12.36 +
   12.37 +namespace ns3
   12.38 +{
   12.39 +
   12.40 +  class WimaxBaseStationNetDevice;
   12.41 +  class SSRecord;
   12.42 +  class ServiceFlow;
   12.43 +  class ServiceFlowRecord;
   12.44 +  class UlJob;
   12.45 +
   12.46 +  class UplinkSchedulerMBQoS : public UplinkScheduler
   12.47 +  {
   12.48 +  public:
   12.49 +    UplinkSchedulerMBQoS ();
   12.50 +    ~UplinkSchedulerMBQoS (void);
   12.51 +
   12.52 +
   12.53 +    uint8_t
   12.54 +    GetNrIrOppsAllocated(void) const;
   12.55 +    bool
   12.56 +    GetIsIrIntrvlAllocated(void) const;
   12.57 +    bool
   12.58 +    GetIsInvIrIntrvlAllocated(void) const;
   12.59 +    std::list<OfdmUlMapIe>
   12.60 +    GetUplinkAllocations(void) const;
   12.61 +
   12.62 +    /**
   12.63 +     * Determines if channel descriptors sent in the current frame are
   12.64 +     * required to be updated
   12.65 +     */
   12.66 +    void
   12.67 +    GetChannelDescriptorsToUpdate(bool&, bool&, bool&, bool&);
   12.68 +    uint32_t
   12.69 +    CalculateAllocationStartTime(void);
   12.70 +    void
   12.71 +    AddUplinkAllocation(OfdmUlMapIe &ulMapIe, const uint32_t &allocationSize,
   12.72 +        uint32_t &symbolsToAllocation, uint32_t &availableSymbols);
   12.73 +
   12.74 +    void
   12.75 +    Schedule(void);
   12.76 +    void
   12.77 +    ServiceUnsolicitedGrants(const SSRecord *ssRecord,
   12.78 +        QoSParameterSet::SchedulingType schedulingType, OfdmUlMapIe &ulMapIe,
   12.79 +        const WimaxPhy::ModulationType modulationType,
   12.80 +        uint32_t &symbolsToAllocation, uint32_t &availableSymbols);
   12.81 +    void
   12.82 +    ServiceBandwidthRequests(const SSRecord *ssRecord,
   12.83 +        QoSParameterSet::SchedulingType schedulingType, OfdmUlMapIe &ulMapIe,
   12.84 +        const WimaxPhy::ModulationType modulationType,
   12.85 +        uint32_t &symbolsToAllocation, uint32_t &availableSymbols);
   12.86 +    bool
   12.87 +    ServiceBandwidthRequests(ServiceFlow *serviceFlow,
   12.88 +        QoSParameterSet::SchedulingType schedulingType, OfdmUlMapIe &ulMapIe,
   12.89 +        const WimaxPhy::ModulationType modulationType,
   12.90 +        uint32_t &symbolsToAllocation, uint32_t &availableSymbols);
   12.91 +    void
   12.92 +    AllocateInitialRangingInterval(uint32_t &symbolsToAllocation,
   12.93 +        uint32_t &availableSymbols);
   12.94 +    void
   12.95 +    SetupServiceFlow(SSRecord *ssRecord, ServiceFlow *serviceFlow);
   12.96 +
   12.97 +    // Check deadline from jobs. Migrate requests if necessary
   12.98 +    bool
   12.99 +    CheckDeadline (uint32_t &availableSymbols);
  12.100 +
  12.101 +    // Check if Minimum bandwidth is garantee. Migrate requests if necessary
  12.102 +    bool
  12.103 +    CheckMinimumBandwidth (uint32_t &availableSymbols);
  12.104 +
  12.105 +    void
  12.106 +    UplinkSchedWindowTimer (void);
  12.107 +
  12.108 +    // Enqueue a job at correct queue
  12.109 +    void
  12.110 +    EnqueueJob (UlJob::JobPriority priority, UlJob job);
  12.111 +    // Dequeue a job from a queue
  12.112 +    UlJob
  12.113 +    DequeueJob (UlJob::JobPriority priority);
  12.114 +
  12.115 +    // Compare priority from two jobs
  12.116 +    int
  12.117 +    ComparePriority (PriorityUlJob & a, PriorityUlJob & b);
  12.118 +
  12.119 +    void
  12.120 +    ProcessBandwidthRequest (const BandwidthRequestHeader &bwRequestHdr);
  12.121 +
  12.122 +    Time
  12.123 +    DetermineDeadline(ServiceFlow *serviceFlow);
  12.124 +
  12.125 +    void
  12.126 +    ConfigureBs (Ptr<WimaxBaseStationNetDevice> bs);
  12.127 +
  12.128 +  private:
  12.129 +    Ptr<WimaxBaseStationNetDevice> m_bs;
  12.130 +    std::list<OfdmUlMapIe> m_uplinkAllocations;
  12.131 +
  12.132 +    // queues for scheduler
  12.133 +    std::list<UlJob> m_uplinkJobs_high;
  12.134 +    std::list<UlJob> m_uplinkJobs_inter;
  12.135 +    std::list<UlJob> m_uplinkJobs_low;
  12.136 +
  12.137 +    Time m_timeStampIrInterval;
  12.138 +    uint8_t m_nrIrOppsAllocated;
  12.139 +    bool m_isIrIntrvlAllocated;
  12.140 +    bool m_isInvIrIntrvlAllocated;
  12.141 +    Time m_dcdTimeStamp;
  12.142 +    Time m_ucdTimeStamp;
  12.143 +  };
  12.144 +
  12.145 +}//namespace ns3
  12.146 +
  12.147 +#endif /* UPLINK_SCHEDULER_MBQOS_H */
    13.1 --- a/src/devices/wimax/uplink-scheduler-qos.cc	Tue Aug 11 15:03:05 2009 -0300
    13.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.3 @@ -1,61 +0,0 @@
    13.4 -#include "uplink-scheduler-qos.h"
    13.5 -#include "wimax-bs-net-device.h"
    13.6 -#include "ns3/simulator.h"
    13.7 -#include "connection-identifier.h"
    13.8 -#include "burst-profile-manager.h"
    13.9 -#include "ss-manager.h"
   13.10 -#include "ns3/log.h"
   13.11 -#include "ns3/uinteger.h"
   13.12 -#include "ss-record.h"
   13.13 -#include "qos-parameter-set.h"
   13.14 -#include "service-flow.h"
   13.15 -#include "service-flow-record.h"
   13.16 -#include "bs-link-manager.h"
   13.17 -#include "bandwidth-manager.h"
   13.18 -
   13.19 -NS_LOG_COMPONENT_DEFINE ("UplinkSchedulerQoS");
   13.20 -
   13.21 -namespace ns3
   13.22 -{
   13.23 -
   13.24 -  NS_OBJECT_ENSURE_REGISTERED (UplinkSchedulerQoS);
   13.25 -
   13.26 -  UplinkSchedulerQoS::UplinkSchedulerQoS()
   13.27 -  {
   13.28 -  }
   13.29 -/*
   13.30 -  UplinkSchedulerQoS::UplinkSchedulerQoS(Ptr<WimaxBaseStationNetDevice> bs) :
   13.31 -    m_bs(bs), m_timeStampIrInterval(Seconds(0)), m_nrIrOppsAllocated(0),
   13.32 -        m_isIrIntrvlAllocated(false), m_isInvIrIntrvlAllocated(false),
   13.33 -        m_dcdTimeStamp(Simulator::Now()), m_ucdTimeStamp(Simulator::Now())
   13.34 -  {
   13.35 -  }*/
   13.36 -
   13.37 -  UplinkSchedulerQoS::~UplinkSchedulerQoS(void)
   13.38 -  {
   13.39 -    //m_bs = 0;
   13.40 -    //m_uplinkAllocations.clear();
   13.41 -
   13.42 -  }
   13.43 -
   13.44 -  void
   13.45 -  UplinkSchedulerQoS::Schedule (void)
   13.46 -  {
   13.47 -
   13.48 -   // UplinkScheduler::Schedule();
   13.49 -    fprintf(stderr,"NEW Scheduler!!!!\n");
   13.50 -
   13.51 -  }
   13.52 -
   13.53 -  void
   13.54 -  UplinkSchedulerQoS::EnqueueJob (UlJob::JobPriority priority, UlJob job)
   13.55 -  {
   13.56 -    exit(1);
   13.57 -  }
   13.58 -
   13.59 -  void
   13.60 -  UplinkSchedulerQoS::Test ()
   13.61 -  {
   13.62 -    fprintf(stderr,"New\n");
   13.63 -  }
   13.64 -}
    14.1 --- a/src/devices/wimax/uplink-scheduler.cc	Tue Aug 11 15:03:05 2009 -0300
    14.2 +++ b/src/devices/wimax/uplink-scheduler.cc	Tue Aug 11 16:41:52 2009 -0300
    14.3 @@ -38,9 +38,10 @@
    14.4  namespace ns3
    14.5  {
    14.6  
    14.7 -  NS_OBJECT_ENSURE_REGISTERED (UplinkScheduler);
    14.8 -
    14.9 -  UplinkScheduler::UplinkScheduler()
   14.10 +  UplinkScheduler::UplinkScheduler(void) :
   14.11 +    m_bs(0), m_timeStampIrInterval(Seconds(0)), m_nrIrOppsAllocated(0),
   14.12 +        m_isIrIntrvlAllocated(false), m_isInvIrIntrvlAllocated(false),
   14.13 +        m_dcdTimeStamp(Simulator::Now()), m_ucdTimeStamp(Simulator::Now())
   14.14    {
   14.15    }
   14.16  
   14.17 @@ -57,14 +58,6 @@
   14.18      m_uplinkAllocations.clear();
   14.19    }
   14.20  
   14.21 -  TypeId
   14.22 -  UplinkScheduler::GetTypeId(void)
   14.23 -  {
   14.24 -    static TypeId tid =
   14.25 -        TypeId("ns3::UplinkScheduler") .SetParent<Object> () .AddConstructor<UplinkScheduler> ();
   14.26 -    return tid;
   14.27 -  }
   14.28 -
   14.29    uint8_t
   14.30    UplinkScheduler::GetNrIrOppsAllocated(void) const
   14.31    {
   14.32 @@ -157,54 +150,6 @@
   14.33      availableSymbols -= allocationSize;
   14.34    }
   14.35  
   14.36 -
   14.37 -  void
   14.38 -  UplinkScheduler::UplinkSchedWindowTimer (void)
   14.39 -  {
   14.40 -    int32_t min_bw = 0;
   14.41 -    std::vector<SSRecord*> *ssRecords = m_bs->GetSSManager ()->GetSSRecords ();
   14.42 -    int windowSize = 1; // in seconds
   14.43 -
   14.44 -    /* For each SS */
   14.45 -    for (std::vector<SSRecord*>::iterator iter = ssRecords->begin ();
   14.46 -    iter != ssRecords->end (); ++iter)
   14.47 -      {
   14.48 -        SSRecord *ssRecord = *iter;
   14.49 -        std::vector<ServiceFlow*> *serviceFlows = ssRecord->GetServiceFlows (QoSParameterSet::SCHEDULING_TYPE_ALL);
   14.50 -
   14.51 -        /* For each flow */
   14.52 -        for (std::vector<ServiceFlow*>::iterator iter2 = serviceFlows->begin ();
   14.53 -        iter2 != serviceFlows->end (); ++iter2)
   14.54 -          {
   14.55 -            ServiceFlow *serviceFlow = *iter2;
   14.56 -            if ((serviceFlow->GetSchedulingType () == QoSParameterSet::SCHEDULING_TYPE_RTPS) ||
   14.57 -                (serviceFlow->GetSchedulingType () == QoSParameterSet::SCHEDULING_TYPE_NRTPS ))
   14.58 -              {
   14.59 -                QoSParameterSet *qosParameterSet = serviceFlow-> GetParameterSet ();
   14.60 -                min_bw = (int) ceil(qosParameterSet->GetMinReservedTrafficRate () / windowSize );
   14.61 -
   14.62 -                /* This way we can compensate flows which did not get min_bw in the previous window */
   14.63 -                if ((serviceFlow->GetRecord ()->GetBacklogged () > 0) && (serviceFlow->GetRecord ()->GetBwSinceLastExpiry () < min_bw))
   14.64 -                  {
   14.65 -                    serviceFlow->GetRecord ()->UpdateBwSinceLastExpiry(-min_bw);
   14.66 -
   14.67 -                    /* if backlogged < granted_bw then we don't need to provide granted_bw + min_bw in next window, but backlogged + min_bw */
   14.68 -                    if (serviceFlow->GetRecord ()->GetBacklogged () < abs (serviceFlow->GetRecord ()->GetBwSinceLastExpiry ()))
   14.69 -                      {
   14.70 -                        serviceFlow->GetRecord ()->SetBwSinceLastExpiry (-serviceFlow->GetRecord ()->GetBacklogged ());
   14.71 -                      }
   14.72 -                  }
   14.73 -                else
   14.74 -                  {
   14.75 -                    serviceFlow->GetRecord ()->SetBwSinceLastExpiry (0);
   14.76 -                  }
   14.77 -              }
   14.78 -          }
   14.79 -      }
   14.80 -
   14.81 -    Simulator::Schedule( Seconds(1), &UplinkScheduler::UplinkSchedWindowTimer, this);
   14.82 -  }
   14.83 -
   14.84    void
   14.85    UplinkScheduler::Schedule(void)
   14.86    {
   14.87 @@ -216,7 +161,6 @@
   14.88      uint32_t symbolsToAllocation = 0;
   14.89      uint32_t allocationSize = 0; //size in symbols
   14.90      uint32_t availableSymbols = m_bs->GetNrUlSymbols();
   14.91 -    uint32_t availableSymbolsAux = m_bs->GetNrUlSymbols();
   14.92  
   14.93      AllocateInitialRangingInterval(symbolsToAllocation, availableSymbols);
   14.94  
   14.95 @@ -318,198 +262,60 @@
   14.96                {
   14.97                  //all service flows associated to SS are established now
   14.98  
   14.99 -              /* Implementation of uplink scheduler
  14.100 -               * [1] Freitag, J.; da Fonseca, N.L.S., "Uplink Scheduling with Quality of Service in IEEE 802.16 Networks,"
  14.101 -               * Global Telecommunications Conference, 2007. GLOBECOM '07. IEEE , vol., no., pp.2503-2508, 26-30 Nov. 2007
  14.102 -               * URL: http://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=4411386&isnumber=4410910 */
  14.103 +                /*allocating grants for data transmission for UGS flows (Data Grant Burst Type IEs, 6.3.7.4.3.3)
  14.104 +                 (grant has been referred by different names e.g. transmission opportunity, slot, uplink allocation, etc)*/
  14.105 +                ServiceUnsolicitedGrants(ssRecord,
  14.106 +                    QoSParameterSet::SCHEDULING_TYPE_UGS, ulMapIe,
  14.107 +                    modulationType, symbolsToAllocation, availableSymbols);
  14.108  
  14.109 -              // Step 1
  14.110 -              if (availableSymbols)
  14.111 -                {
  14.112 -                  /*allocating grants for data transmission for UGS flows (Data Grant Burst Type IEs, 6.3.7.4.3.3)
  14.113 -                          (grant has been referred by different names e.g. transmission opportunity, slot,         uplink allocation, etc)*/
  14.114 -
  14.115 -                  if (ssRecord->GetHasServiceFlowUgs())
  14.116 +                //allocate unicast polls for rtPS flows if bandwidth is available
  14.117 +                if (availableSymbols)
  14.118                    {
  14.119 -
  14.120 -                    Time frame_duration = m_bs->GetPhy ()->GetFrameDuration();
  14.121 -                    Time timestamp = ssRecord->GetServiceFlow(QoSParameterSet::SCHEDULING_TYPE_UGS)->GetRecord()->GetLastGrantTime() +
  14.122 -                                     MilliSeconds (ssRecord->GetServiceFlow(QoSParameterSet::SCHEDULING_TYPE_UGS)->GetParameterSet()->GetUnsolicitedGrantInterval());
  14.123 -                    Time uInterval = MilliSeconds (ssRecord->GetServiceFlow(QoSParameterSet::SCHEDULING_TYPE_UGS)->GetParameterSet()->GetUnsolicitedGrantInterval());
  14.124 -
  14.125 -                    Scalar frame = ((timestamp - Simulator::Now ()) / frame_duration);
  14.126 -/*
  14.127 -                    if (frame.GetDouble() <= 1)
  14.128 -                    {
  14.129 -                      UlJob *jobUGS = new UlJob ();
  14.130 -                      jobUGS->SetSsRecord (ssRecord);
  14.131 -                      jobUGS->SetSchedulingType (QoSParameterSet::SCHEDULING_TYPE_UGS);
  14.132 -                      jobUGS->SetType (UNICAST_POLLING);
  14.133 -                      EnqueueJob (UlJob::HIGH, *jobUGS);
  14.134 -                    }*/
  14.135 -
  14.136 -                    ServiceUnsolicitedGrants (ssRecord, QoSParameterSet::SCHEDULING_TYPE_UGS, ulMapIe,
  14.137 -                                                   modulationType, symbolsToAllocation, availableSymbols);
  14.138 -
  14.139 +                    ServiceUnsolicitedGrants(ssRecord,
  14.140 +                        QoSParameterSet::SCHEDULING_TYPE_RTPS, ulMapIe,
  14.141 +                        modulationType, symbolsToAllocation, availableSymbols);
  14.142 +                  }
  14.143 +                //allocate unicast polls for nrtPS flows if bandwidth is available
  14.144 +                if (availableSymbols)
  14.145 +                  {
  14.146 +                    ServiceUnsolicitedGrants(ssRecord,
  14.147 +                        QoSParameterSet::SCHEDULING_TYPE_NRTPS, ulMapIe,
  14.148 +                        modulationType, symbolsToAllocation, availableSymbols);
  14.149 +                  }
  14.150 +                //finally allocate unicast polls for BE flows if bandwidth is available
  14.151 +                if (availableSymbols)
  14.152 +                  {
  14.153 +                    ServiceUnsolicitedGrants(ssRecord,
  14.154 +                        QoSParameterSet::SCHEDULING_TYPE_BE, ulMapIe,
  14.155 +                        modulationType, symbolsToAllocation, availableSymbols);
  14.156                    }
  14.157  
  14.158 +                //now allocating grants for non-UGS flows (i.e., in response of bandwidth requests)
  14.159  
  14.160 -                  // allocate unicast polls for rtPS flows if bandwidth is available
  14.161 -                  if (ssRecord->GetHasServiceFlowRtps())
  14.162 +                if (availableSymbols)
  14.163                    {
  14.164 -                    UlJob *jobRTPSPoll = new UlJob ();
  14.165 -                    jobRTPSPoll->SetSsRecord (ssRecord);
  14.166 -                    jobRTPSPoll->SetSchedulingType (QoSParameterSet::SCHEDULING_TYPE_RTPS);
  14.167 -                    jobRTPSPoll->SetType (UNICAST_POLLING);
  14.168 -                    EnqueueJob (UlJob::HIGH, *jobRTPSPoll);
  14.169 +                    ServiceBandwidthRequests(ssRecord,
  14.170 +                        QoSParameterSet::SCHEDULING_TYPE_RTPS, ulMapIe,
  14.171 +                        modulationType, symbolsToAllocation, availableSymbols);
  14.172                    }
  14.173 -
  14.174 -                  if (ssRecord->GetHasServiceFlowNrtps())
  14.175 +                //allocate unicast polls for nrtPS flows if bandwidth is available
  14.176 +                if (availableSymbols)
  14.177                    {
  14.178 -                    // allocate unicast polls for nrtPS flows if bandwidth is available
  14.179 -                    UlJob *jobNRTPSPoll = new UlJob ();
  14.180 -                    jobNRTPSPoll->SetSsRecord (ssRecord);
  14.181 -                    jobNRTPSPoll->SetSchedulingType (QoSParameterSet::SCHEDULING_TYPE_NRTPS);
  14.182 -                    jobNRTPSPoll->SetType (UNICAST_POLLING);
  14.183 -                    EnqueueJob (UlJob::HIGH, *jobNRTPSPoll);
  14.184 +                    ServiceBandwidthRequests(ssRecord,
  14.185 +                        QoSParameterSet::SCHEDULING_TYPE_NRTPS, ulMapIe,
  14.186 +                        modulationType, symbolsToAllocation, availableSymbols);
  14.187                    }
  14.188 -
  14.189 -                  if (ssRecord->GetHasServiceFlowBe())
  14.190 +                //finally allocate unicast polls for BE flows if bandwidth is available
  14.191 +                if (availableSymbols)
  14.192                    {
  14.193 -                    // finally allocate unicast polls for BE flows if bandwidth is available
  14.194 -                    UlJob *jobBEPoll = new UlJob ();
  14.195 -                    jobBEPoll->SetSsRecord(ssRecord);
  14.196 -                    jobBEPoll->SetSchedulingType(QoSParameterSet::SCHEDULING_TYPE_BE);
  14.197 -                    jobBEPoll->SetType(UNICAST_POLLING);
  14.198 -                    EnqueueJob (UlJob::HIGH, *jobBEPoll);
  14.199 +                    ServiceBandwidthRequests(ssRecord,
  14.200 +                        QoSParameterSet::SCHEDULING_TYPE_BE, ulMapIe,
  14.201 +                        modulationType, symbolsToAllocation, availableSymbols);
  14.202                    }
  14.203 -                }
  14.204                }
  14.205            }
  14.206        }
  14.207  
  14.208 -    availableSymbolsAux = availableSymbols;
  14.209 -
  14.210 -    //    uint32_t symbolsUsed = QueueSymbols();
  14.211 -    // Step 2 - Check Deadline - Migrate requests with deadline expiring
  14.212 -     CheckDeadline(availableSymbolsAux);
  14.213 -
  14.214 -     // Step 3 - Check Minimum Bandwidth
  14.215 -     CheckMinimumBandwidth(availableSymbolsAux);
  14.216 -
  14.217 -
  14.218 -     if (!m_uplinkJobs_high.empty()) {
  14.219 -         int x = m_uplinkJobs_high.size();
  14.220 -         fprintf(stdout,"DEBUG: Queue size before high: %d\n", m_uplinkJobs_high.size());
  14.221 -     }
  14.222 -     /* Scheduling high priority queue */
  14.223 -     while ((availableSymbols) && (!m_uplinkJobs_high.empty()))
  14.224 -       {
  14.225 -
  14.226 -         UlJob job = m_uplinkJobs_high.front();
  14.227 -         OfdmUlMapIe ulMapIe;
  14.228 -         SSRecord * ssRecord = job.GetSsRecord();
  14.229 -         QoSParameterSet::SchedulingType schedulingType = job.GetSchedulingType();
  14.230 -
  14.231 -         Ptr<ConnectionIdentifier> cid = ssRecord->GetBasicCid ();
  14.232 -         ulMapIe.SetCid (*cid);
  14.233 -         //WimaxPhy::ModulationType modulationType = m_bs->GetBurstProfileManager ()->GetModulationTypeForBurst (cid);
  14.234 -         WimaxPhy::ModulationType modulationType = ssRecord->GetModulationType ();
  14.235 -         //need to update because modulation/FEC to UIUC mapping may vary over time
  14.236 -         ulMapIe.SetUiuc (m_bs->GetBurstProfileManager ()->GetBurstProfile (modulationType, WimaxNetDevice::DIRECTION_UPLINK));
  14.237 -
  14.238 -         ReqType reqType = job.GetType();
  14.239 -
  14.240 -         if (reqType == UNICAST_POLLING)
  14.241 -           {
  14.242 -             ServiceUnsolicitedGrants (ssRecord, schedulingType, ulMapIe,
  14.243 -                 modulationType, symbolsToAllocation, availableSymbols);
  14.244 -             fprintf(stdout, "DEBUG Flavio: Serving high priority queue polling(connection=%d);\n",cid->GetIdentifier());
  14.245 -           }
  14.246 -         else if (reqType == DATA)
  14.247 -           {
  14.248 -           fprintf(stdout, "DEBUG Flavio: Serving high priority queue;(connection=%d)\n",cid->GetIdentifier());
  14.249 -             ServiceBandwidthRequests (ssRecord, schedulingType, ulMapIe,
  14.250 -                 modulationType, symbolsToAllocation, availableSymbols);
  14.251 -           }
  14.252 -         m_uplinkJobs_high.pop_front();
  14.253 -       }
  14.254 -     if (!m_uplinkJobs_high.empty())
  14.255 -       fprintf(stdout,"DEBUG: Queue size after high: %d\n",m_uplinkJobs_high.size());
  14.256 -     else
  14.257 -       fprintf(stdout,"DEBUG: Queue size after high: 0\n");
  14.258 -
  14.259 -
  14.260 -     if (!m_uplinkJobs_inter.empty())
  14.261 -       fprintf(stdout, "DEBUG: Queue size before inter: %d\n",  m_uplinkJobs_inter.size());
  14.262 -     /* Scheduling intermediate priority queue */
  14.263 -     while ((availableSymbols) && (!m_uplinkJobs_inter.empty()))
  14.264 -       {
  14.265 -
  14.266 -         UlJob job = m_uplinkJobs_inter.front();
  14.267 -         OfdmUlMapIe ulMapIe;
  14.268 -         SSRecord * ssRecord = job.GetSsRecord();
  14.269 -         QoSParameterSet::SchedulingType schedulingType = job.GetSchedulingType();
  14.270 -
  14.271 -         Ptr<ConnectionIdentifier> cid = ssRecord->GetBasicCid ();
  14.272 -         ulMapIe.SetCid (*cid);
  14.273 -         //WimaxPhy::ModulationType modulationType = m_bs->GetBurstProfileManager ()->GetModulationTypeForBurst (cid);
  14.274 -         WimaxPhy::ModulationType modulationType = ssRecord->GetModulationType ();
  14.275 -         //need to update because modulation/FEC to UIUC mapping may vary over time
  14.276 -         ulMapIe.SetUiuc (m_bs->GetBurstProfileManager ()->GetBurstProfile (modulationType, WimaxNetDevice::DIRECTION_UPLINK));
  14.277 -
  14.278 -         ReqType reqType = job.GetType();
  14.279 -
  14.280 -         if (reqType == UNICAST_POLLING)
  14.281 -           {
  14.282 -             ServiceUnsolicitedGrants (ssRecord, schedulingType, ulMapIe,
  14.283 -                 modulationType, symbolsToAllocation, availableSymbols);
  14.284 -           }
  14.285 -         else if (reqType == DATA)
  14.286 -           {
  14.287 -           fprintf(stdout, "DEBUG Flavio: Serving inter pririty queue data(connection=%d);\n",cid->GetIdentifier());
  14.288 -             ServiceBandwidthRequests (ssRecord, schedulingType, ulMapIe,
  14.289 -                 modulationType, symbolsToAllocation, availableSymbols);
  14.290 -           }
  14.291 -         m_uplinkJobs_inter.pop_front();
  14.292 -       }
  14.293 -     if (!m_uplinkJobs_inter.empty())
  14.294 -       fprintf(stdout, "DEBUG: Queue size after inter: %d\n", m_uplinkJobs_inter.size());
  14.295 -     else
  14.296 -       fprintf(stdout, "DEBUG: Queue size after inter: 0\n");
  14.297 -
  14.298 -     /* Scheduling low priority queue */
  14.299 -     while ((availableSymbols) && (!m_uplinkJobs_low.empty()))
  14.300 -       {
  14.301 -
  14.302 -         UlJob job = m_uplinkJobs_low.front();
  14.303 -         OfdmUlMapIe ulMapIe;
  14.304 -         SSRecord * ssRecord = job.GetSsRecord();
  14.305 -         QoSParameterSet::SchedulingType schedulingType = job.GetSchedulingType();
  14.306 -
  14.307 -         Ptr<ConnectionIdentifier> cid = ssRecord->GetBasicCid ();
  14.308 -         ulMapIe.SetCid (*cid);
  14.309 -         //WimaxPhy::ModulationType modulationType = m_bs->GetBurstProfileManager ()->GetModulationTypeForBurst (cid);
  14.310 -         WimaxPhy::ModulationType modulationType = ssRecord->GetModulationType ();
  14.311 -         //need to update because modulation/FEC to UIUC mapping may vary over time
  14.312 -         ulMapIe.SetUiuc (m_bs->GetBurstProfileManager ()->GetBurstProfile (modulationType, WimaxNetDevice::DIRECTION_UPLINK));
  14.313 -
  14.314 -         ReqType reqType = job.GetType();
  14.315 -
  14.316 -         if (reqType == UNICAST_POLLING)
  14.317 -           {
  14.318 -             ServiceUnsolicitedGrants (ssRecord, schedulingType, ulMapIe,
  14.319 -                 modulationType, symbolsToAllocation, availableSymbols);
  14.320 -           }
  14.321 -         else if (reqType == DATA)
  14.322 -           {
  14.323 -           fprintf(stdout, "DEBUG Flavio: Serving low priority queue data(connection=%d);\n",cid->GetIdentifier());
  14.324 -             ServiceBandwidthRequests (ssRecord, schedulingType, ulMapIe,
  14.325 -                 modulationType, symbolsToAllocation, availableSymbols);
  14.326 -           }
  14.327 -         m_uplinkJobs_low.pop_front();
  14.328 -       }
  14.329 -
  14.330      OfdmUlMapIe ulMapIeEnd;
  14.331      ulMapIeEnd.SetCid(*CreateObject<ConnectionIdentifier> ("Identifier",
  14.332          UintegerValue(0)));
  14.333 @@ -532,211 +338,6 @@
  14.334    }
  14.335  
  14.336    void
  14.337 -  UplinkScheduler::EnqueueJob (UlJob::JobPriority priority, UlJob job)
  14.338 -  {
  14.339 -    switch (priority)
  14.340 -    {
  14.341 -    case UlJob::HIGH:
  14.342 -      m_uplinkJobs_high.push_back (job);
  14.343 -      break;
  14.344 -    case UlJob::INTERMEDIATE:
  14.345 -      m_uplinkJobs_inter.push_back (job);
  14.346 -      break;
  14.347 -    case UlJob::LOW:
  14.348 -      m_uplinkJobs_low.push_back (job);
  14.349 -    }
  14.350 -  }
  14.351 -
  14.352 -  UlJob
  14.353 -  UplinkScheduler::DequeueJob (UlJob::JobPriority priority)
  14.354 -  {
  14.355 -    UlJob job_front;
  14.356 -    switch (priority)
  14.357 -    {
  14.358 -    case UlJob::HIGH:
  14.359 -      job_front = m_uplinkJobs_high.front();
  14.360 -      m_uplinkJobs_high.pop_front();
  14.361 -      break;
  14.362 -    case UlJob::INTERMEDIATE:
  14.363 -      job_front = m_uplinkJobs_inter.front();
  14.364 -      m_uplinkJobs_inter.pop_front();
  14.365 -      break;
  14.366 -    case UlJob::LOW:
  14.367 -      job_front = m_uplinkJobs_low.front();
  14.368 -      m_uplinkJobs_low.pop_front();
  14.369 -    }
  14.370 -    return job_front;
  14.371 -  }
  14.372 -
  14.373 -
  14.374 -
  14.375 -  bool
  14.376 -  UplinkScheduler::CheckDeadline (uint32_t &availableSymbols)
  14.377 -  {
  14.378 -
  14.379 -    // for each request in the imermediate queue
  14.380 -    if (m_uplinkJobs_inter.size() > 0)
  14.381 -    {
  14.382 -
  14.383 -      std::list<UlJob>::iterator iter = m_uplinkJobs_inter.begin();
  14.384 -      std::list<UlJob>::iterator iterPrev = m_uplinkJobs_inter.begin();
  14.385 -
  14.386 -      while (iter != m_uplinkJobs_inter.end() && availableSymbols)
  14.387 -      {
  14.388 -
  14.389 -        UlJob job = *iter;
  14.390 -
  14.391 -        /*std::cout << "Job info: " << job.GetSsRecord()->GetBasicCid()
  14.392 -                    << std::endl;*/
  14.393 -
  14.394 -
  14.395 -        if (job.GetSchedulingType() == QoSParameterSet::SCHEDULING_TYPE_RTPS)
  14.396 -        {
  14.397 -          ServiceFlow *serviceFlow = job.GetServiceFlow ();
  14.398 -          Time deadline = job.GetDeadline();
  14.399 -          Time frame_duration = m_bs->GetPhy ()->GetFrameDuration();
  14.400 -
  14.401 -          Scalar frame = ((deadline - Simulator::Now ()) / frame_duration);
  14.402 -
  14.403 -          std::cout << "Now: " << Simulator::Now ()
  14.404 -              << " Deadline: " << deadline
  14.405 -              << " Frame duration" << frame_duration
  14.406 -              << std::endl;
  14.407 -
  14.408 -          // TODO: subtrair simbolos
  14.409 -
  14.410 -          if (frame.GetDouble() <= 1)
  14.411 -          {
  14.412 -            // verificar se tem espaco
  14.413 -            // migrate request
  14.414 -            UlJob jobTmp = job;
  14.415 -            EnqueueJob (UlJob::HIGH, jobTmp);
  14.416 -            //m_uplinkJobs_inter.remove (job);
  14.417 -            m_uplinkJobs_inter.erase (iter);
  14.418 -            iter = m_uplinkJobs_inter.begin();
  14.419 -
  14.420 -          }
  14.421 -          else
  14.422 -          {
  14.423 -            iter++;
  14.424 -          }
  14.425 -        }
  14.426 -        else
  14.427 -        {
  14.428 -          iter++;
  14.429 -        }
  14.430 -      }
  14.431 -    }
  14.432 -  }
  14.433 -
  14.434 -  int
  14.435 -  UplinkScheduler::ComparePriority (PriorityUlJob & a, PriorityUlJob & b)
  14.436 -  {
  14.437 -    const PriorityUlJob A;
  14.438 -    const PriorityUlJob B;
  14.439 -
  14.440 -    if (a.GetPriority () < b.GetPriority ())
  14.441 -      return 1;
  14.442 -    if (a.GetPriority () > b.GetPriority ())
  14.443 -      return -1;
  14.444 -
  14.445 -    if (a.GetUlJob()->GetServiceFlow()->GetRecord()->GetBacklogged() < b.GetUlJob()->GetServiceFlow()->GetRecord()->GetBacklogged())
  14.446 -      return 1;
  14.447 -    if (a.GetUlJob()->GetServiceFlow()->GetRecord()->GetBacklogged() > b.GetUlJob()->GetServiceFlow()->GetRecord()->GetBacklogged())
  14.448 -        return -1;
  14.449 -    return 0;
  14.450 -  }
  14.451 -
  14.452 -  bool
  14.453 -  UplinkScheduler::CheckMinimumBandwidth(uint32_t &availableSymbols)
  14.454 -  {
  14.455 -    std::list<PriorityUlJob> priorityUlJobs;
  14.456 -
  14.457 -    // For each connection of type rtPS or nrtPS
  14.458 -    std::vector<SSRecord*> *ssRecords = m_bs->GetSSManager ()->GetSSRecords ();
  14.459 -    for (std::vector<SSRecord*>::iterator iter = ssRecords->begin ();
  14.460 -        iter != ssRecords->end (); ++iter)
  14.461 -    {
  14.462 -      SSRecord *ssRecord = *iter;
  14.463 -      std::vector<ServiceFlow*> *serviceFlows = ssRecord->GetServiceFlows(QoSParameterSet::SCHEDULING_TYPE_ALL);
  14.464 -      for (std::vector<ServiceFlow*>::iterator iter2 = serviceFlows->begin ();
  14.465 -             iter2 != serviceFlows->end (); ++iter2)
  14.466 -        {
  14.467 -          ServiceFlow *serviceFlow = *iter2;
  14.468 -          if (serviceFlow->GetSchedulingType() == QoSParameterSet::SCHEDULING_TYPE_RTPS ||
  14.469 -              serviceFlow->GetSchedulingType() == QoSParameterSet::SCHEDULING_TYPE_NRTPS)
  14.470 -          {
  14.471 -            serviceFlow->GetRecord ()->SetBackloggedTemp (serviceFlow->GetRecord ()->GetBacklogged ());
  14.472 -            serviceFlow->GetRecord ()->SetGrantedBandwidthTemp (serviceFlow->GetRecord ()->GetBwSinceLastExpiry ());
  14.473 -          }
  14.474 -        }
  14.475 -    }
  14.476 -
  14.477 -
  14.478 -    // for each request in the imermediate queue
  14.479 -    for ( std::list<UlJob>::const_iterator iter = m_uplinkJobs_inter.begin(); iter != m_uplinkJobs_inter.end(); ++iter)
  14.480 -    {
  14.481 -      UlJob job = *iter;
  14.482 -      //SSRecord ssRecord = job.GetSsRecord();
  14.483 -      ServiceFlow *serviceFlow = job.GetServiceFlow ();
  14.484 -      if ((job.GetSchedulingType() == QoSParameterSet::SCHEDULING_TYPE_RTPS ||
  14.485 -           job.GetSchedulingType() == QoSParameterSet::SCHEDULING_TYPE_NRTPS)
  14.486 -           && (serviceFlow->GetRecord ()->GetBacklogged () > 0))
  14.487 -      {
  14.488 -        uint32_t minReservedTrafficRate = serviceFlow->GetParameterSet ()->GetMinReservedTrafficRate ();
  14.489 -        uint32_t grantedBandwidth = serviceFlow->GetRecord ()-> GetBwSinceLastExpiry ();
  14.490 -
  14.491 -        PriorityUlJob priorityUlJob ;
  14.492 -        priorityUlJob.SetUlJob(&job);
  14.493 -        // pri_array
  14.494 -        if (minReservedTrafficRate <= grantedBandwidth)
  14.495 -        {
  14.496 -          priorityUlJob.SetPriority(-10000);
  14.497 -        }
  14.498 -        else
  14.499 -        {
  14.500 -          u_int32_t allocationSize = serviceFlow->GetRecord ()->GetRequestedBandwidth () - serviceFlow->GetRecord ()-> GetGrantedBandwidth ();
  14.501 -          u_int32_t sduSize = serviceFlow->GetParameterSet ()->GetSduSize ();
  14.502 -
  14.503 -          if (allocationSize > 0)
  14.504 -          {
  14.505 -            if (sduSize > 0)
  14.506 -            {
  14.507 -             //if SDU size is mentioned, grant of that size
  14.508 -              allocationSize = sduSize;
  14.509 -            }
  14.510 -          }
  14.511 -          // TODO: atualizar available symbols e verificar available symbols
  14.512 -          int priority = serviceFlow->GetRecord ()->GetBackloggedTemp () - ( serviceFlow->GetRecord ()->GetGrantedBandwidthTemp () - minReservedTrafficRate );
  14.513 -          priorityUlJob.SetPriority (priority);
  14.514 -          serviceFlow->GetRecord ()->SetGrantedBandwidthTemp (serviceFlow->GetRecord ()->GetGrantedBandwidthTemp () + allocationSize);
  14.515 -          serviceFlow->GetRecord ()->SetBackloggedTemp ( serviceFlow->GetRecord ()->GetBackloggedTemp() - allocationSize );
  14.516 -        }
  14.517 -
  14.518 -        priorityUlJobs.push_back (priorityUlJob);
  14.519 -      }
  14.520 -    }
  14.521 -
  14.522 -    // TODO: rever sort
  14.523 -    //priorityUlJobs.sort ( &UplinkScheduler::ComparePriority );
  14.524 -    priorityUlJobs.sort ( SortProcess() );
  14.525 -
  14.526 -    for ( std::list<PriorityUlJob>::const_iterator iter = priorityUlJobs.begin(); iter != priorityUlJobs.end(); ++iter)
  14.527 -    {
  14.528 -      PriorityUlJob priorityUlJob = *iter;
  14.529 -      UlJob *job_priority = priorityUlJob.GetUlJob();
  14.530 -      UlJob job = *job_priority;
  14.531 -      // verificar se tem espaco
  14.532 -      // migrate request
  14.533 -      m_uplinkJobs_inter.remove (job);
  14.534 -      EnqueueJob (UlJob::HIGH, job);
  14.535 -    }
  14.536 -
  14.537 -  }
  14.538 -
  14.539 -
  14.540 -
  14.541 -  void
  14.542    UplinkScheduler::ServiceUnsolicitedGrants(const SSRecord *ssRecord,
  14.543        QoSParameterSet::SchedulingType schedulingType, OfdmUlMapIe &ulMapIe,
  14.544        const WimaxPhy::ModulationType modulationType,
  14.545 @@ -759,9 +360,8 @@
  14.546          allocationSize = m_bs->GetBandwidthManager()->CalculateAllocationSize(
  14.547              ssRecord, serviceFlow);
  14.548  
  14.549 -        // Flavio : it will checked in CheckMinimumBandwidth
  14.550          //verifying that minimum reserved traffic rate of nrtPS flow is maintained
  14.551 -       /* if (serviceFlow->GetSchedulingType()
  14.552 +        if (serviceFlow->GetSchedulingType()
  14.553              == QoSParameterSet::SCHEDULING_TYPE_NRTPS)
  14.554            {
  14.555              Time currentTime = Simulator::Now();
  14.556 @@ -779,7 +379,7 @@
  14.557                      record->SetGrantTimeStamp(currentTime);
  14.558                    }
  14.559                }
  14.560 -          }*/
  14.561 +          }
  14.562  
  14.563          if (availableSymbols < allocationSize)
  14.564            break;
  14.565 @@ -819,7 +419,6 @@
  14.566              << ", SFID: " << serviceFlow->GetSfid() << std::endl;
  14.567  #endif
  14.568  
  14.569 -        serviceFlow->GetRecord ()->SetLastGrantTime(Simulator::Now());
  14.570          AddUplinkAllocation(ulMapIe, allocationSize, symbolsToAllocation,
  14.571              availableSymbols);
  14.572          ulMapIe.SetUiuc(uiuc);
  14.573 @@ -869,7 +468,7 @@
  14.574              allocSizeBytes = sduSize;
  14.575              allocSizeSymbols = m_bs->GetPhy()->GetNrSymbols(sduSize,
  14.576                  modulationType);
  14.577 -
  14.578 +            ;
  14.579            }
  14.580          else
  14.581            {
  14.582 @@ -893,19 +492,10 @@
  14.583  
  14.584              record->UpdateGrantedBandwidth(allocSizeBytes);
  14.585  
  14.586 -            //if (schedulingType == QoSParameterSet::SCHEDULING_TYPE_NRTPS)
  14.587 -            //  {
  14.588 +            if (schedulingType == QoSParameterSet::SCHEDULING_TYPE_NRTPS)
  14.589 +              {
  14.590                  record->SetBwSinceLastExpiry(allocSizeBytes);
  14.591 -            //  }
  14.592 -
  14.593 -            if (serviceFlow->GetRecord ()->GetBacklogged () < allocSizeBytes)
  14.594 -             {
  14.595 -               serviceFlow->GetRecord ()->SetBacklogged (0);
  14.596 -             }
  14.597 -             else
  14.598 -             {
  14.599 -               serviceFlow->GetRecord ()->UpdateBacklogged (-allocSizeBytes);
  14.600 -             }
  14.601 +              }
  14.602  
  14.603              AddUplinkAllocation(ulMapIe, allocSizeSymbols, symbolsToAllocation,
  14.604                  availableSymbols);
  14.605 @@ -1023,9 +613,15 @@
  14.606    }
  14.607  
  14.608    void
  14.609 -  UplinkScheduler::ConfigureBs(Ptr<WimaxBaseStationNetDevice> bs)
  14.610 +  UplinkScheduler::ConfigureBs (Ptr<WimaxBaseStationNetDevice> bs)
  14.611    {
  14.612      m_bs = bs;
  14.613    }
  14.614  
  14.615 +  void
  14.616 +  UplinkScheduler::ProcessBandwidthRequest (const BandwidthRequestHeader &bwRequestHdr)
  14.617 +  {
  14.618 +
  14.619 +  }
  14.620 +
  14.621  }//namespace ns3
    15.1 --- a/src/devices/wimax/uplink-scheduler.h	Tue Aug 11 15:03:05 2009 -0300
    15.2 +++ b/src/devices/wimax/uplink-scheduler.h	Tue Aug 11 16:41:52 2009 -0300
    15.3 @@ -26,9 +26,6 @@
    15.4  #include "ns3/nstime.h"
    15.5  #include "qos-parameter-set.h"
    15.6  #include "wimax-phy.h"
    15.7 -#include "ul-job.h"
    15.8 -#include "service-flow-record.h"
    15.9 -#include "ns3/object.h"
   15.10  
   15.11  namespace ns3
   15.12  {
   15.13 @@ -36,96 +33,66 @@
   15.14    class WimaxBaseStationNetDevice;
   15.15    class SSRecord;
   15.16    class ServiceFlow;
   15.17 -  class ServiceFlowRecord;
   15.18 -  class UlJob;
   15.19  
   15.20    class UplinkScheduler : public Object
   15.21    {
   15.22    public:
   15.23 -    UplinkScheduler ();
   15.24 +    UplinkScheduler (void);
   15.25      UplinkScheduler(Ptr<WimaxBaseStationNetDevice> bs);
   15.26      ~UplinkScheduler(void);
   15.27  
   15.28 -    static TypeId
   15.29 -    GetTypeId(void);
   15.30 -
   15.31 -    uint8_t
   15.32 +    virtual uint8_t
   15.33      GetNrIrOppsAllocated(void) const;
   15.34 -    bool
   15.35 +    virtual bool
   15.36      GetIsIrIntrvlAllocated(void) const;
   15.37 -    bool
   15.38 +    virtual bool
   15.39      GetIsInvIrIntrvlAllocated(void) const;
   15.40 -    std::list<OfdmUlMapIe>
   15.41 +    virtual std::list<OfdmUlMapIe>
   15.42      GetUplinkAllocations(void) const;
   15.43  
   15.44      /**
   15.45       * Determines if channel descriptors sent in the current frame are
   15.46       * required to be updated
   15.47       */
   15.48 -    void
   15.49 +    virtual void
   15.50      GetChannelDescriptorsToUpdate(bool&, bool&, bool&, bool&);
   15.51 -    uint32_t
   15.52 +    virtual uint32_t
   15.53      CalculateAllocationStartTime(void);
   15.54 -    void
   15.55 +    virtual void
   15.56      AddUplinkAllocation(OfdmUlMapIe &ulMapIe, const uint32_t &allocationSize,
   15.57          uint32_t &symbolsToAllocation, uint32_t &availableSymbols);
   15.58 -
   15.59 -    void
   15.60 +    virtual void
   15.61      Schedule(void);
   15.62 -    void
   15.63 +    virtual void
   15.64      ServiceUnsolicitedGrants(const SSRecord *ssRecord,
   15.65          QoSParameterSet::SchedulingType schedulingType, OfdmUlMapIe &ulMapIe,
   15.66          const WimaxPhy::ModulationType modulationType,
   15.67          uint32_t &symbolsToAllocation, uint32_t &availableSymbols);
   15.68 -    void
   15.69 +    virtual void
   15.70      ServiceBandwidthRequests(const SSRecord *ssRecord,
   15.71          QoSParameterSet::SchedulingType schedulingType, OfdmUlMapIe &ulMapIe,
   15.72          const WimaxPhy::ModulationType modulationType,
   15.73          uint32_t &symbolsToAllocation, uint32_t &availableSymbols);
   15.74 -    bool
   15.75 +    virtual bool
   15.76      ServiceBandwidthRequests(ServiceFlow *serviceFlow,
   15.77          QoSParameterSet::SchedulingType schedulingType, OfdmUlMapIe &ulMapIe,
   15.78          const WimaxPhy::ModulationType modulationType,
   15.79          uint32_t &symbolsToAllocation, uint32_t &availableSymbols);
   15.80 -    void
   15.81 +    virtual void
   15.82      AllocateInitialRangingInterval(uint32_t &symbolsToAllocation,
   15.83          uint32_t &availableSymbols);
   15.84 -    void
   15.85 +    virtual void
   15.86      SetupServiceFlow(SSRecord *ssRecord, ServiceFlow *serviceFlow);
   15.87  
   15.88 -    // Check deadline from jobs. Migrate requests if necessary
   15.89 -    bool
   15.90 -    CheckDeadline (uint32_t &availableSymbols);
   15.91 +    virtual void
   15.92 +    ProcessBandwidthRequest (const BandwidthRequestHeader &bwRequestHdr);
   15.93  
   15.94 -    // Check if Minimum bandwidth is garantee. Migrate requests if necessary
   15.95 -    bool
   15.96 -    CheckMinimumBandwidth (uint32_t &availableSymbols);
   15.97 -
   15.98 -    void
   15.99 -    UplinkSchedWindowTimer (void);
  15.100 -
  15.101 -    // Enqueue a job at correct queue
  15.102 -    void
  15.103 -    EnqueueJob (UlJob::JobPriority priority, UlJob job);
  15.104 -    // Dequeue a job from a queue
  15.105 -    UlJob
  15.106 -    DequeueJob (UlJob::JobPriority priority);
  15.107 -
  15.108 -    // Compare priority from two jobs
  15.109 -    int
  15.110 -    ComparePriority (PriorityUlJob & a, PriorityUlJob & b);
  15.111 -
  15.112 -    void
  15.113 -    ConfigureBs(Ptr<WimaxBaseStationNetDevice> bs);
  15.114 +    virtual void
  15.115 +    ConfigureBs (Ptr<WimaxBaseStationNetDevice> bs);
  15.116  
  15.117    private:
  15.118      Ptr<WimaxBaseStationNetDevice> m_bs;
  15.119      std::list<OfdmUlMapIe> m_uplinkAllocations;
  15.120 -
  15.121 -    // queues for scheduler
  15.122 -    std::list<UlJob> m_uplinkJobs_high;
  15.123 -    std::list<UlJob> m_uplinkJobs_inter;
  15.124 -    std::list<UlJob> m_uplinkJobs_low;
  15.125      Time m_timeStampIrInterval;
  15.126      uint8_t m_nrIrOppsAllocated;
  15.127      bool m_isIrIntrvlAllocated;
    16.1 --- a/src/devices/wimax/wscript	Tue Aug 11 15:03:05 2009 -0300
    16.2 +++ b/src/devices/wimax/wscript	Tue Aug 11 16:41:52 2009 -0300
    16.3 @@ -44,6 +44,7 @@
    16.4              'ss-manager.cc',
    16.5              'connection-manager.cc',
    16.6              'uplink-scheduler.cc',
    16.7 +            'uplink-scheduler-mbqos.cc',
    16.8              'uplink-scheduler-qos.cc',
    16.9              'bs-scheduler.cc',
   16.10              'wimax-mac-queue.cc',
   16.11 @@ -114,6 +115,7 @@
   16.12              'cost231-propagation-model.h',
   16.13              'propagation.h',
   16.14              'uplink-scheduler.h',
   16.15 +            'uplink-scheduler-mbqos.h',
   16.16              'uplink-scheduler-qos.h',
   16.17              'ul-job.h',
   16.18              'service-flow-record.h'
    17.1 --- a/src/helper/wimax-helper.cc	Tue Aug 11 15:03:05 2009 -0300
    17.2 +++ b/src/helper/wimax-helper.cc	Tue Aug 11 16:41:52 2009 -0300
    17.3 @@ -203,8 +203,8 @@
    17.4          case SCHED_TYPE_SIMPLE:
    17.5            uplinkScheduler = CreateObject<UplinkScheduler> ();
    17.6            break;
    17.7 -        case SCHED_TYPE_QOS:
    17.8 -          uplinkScheduler = CreateObject<UplinkSchedulerQoS> ();
    17.9 +        case SCHED_TYPE_MBQOS:
   17.10 +          uplinkScheduler = CreateObject<UplinkSchedulerMBQoS> ();
   17.11            break;
   17.12        }
   17.13      return uplinkScheduler;
   17.14 @@ -212,9 +212,9 @@
   17.15  
   17.16    NetDeviceContainer
   17.17    WimaxHelper::Install(NodeContainer c, NetDeviceType deviceType,
   17.18 -      PhyType phyType)
   17.19 +      PhyType phyType, SchedulerType schedulerType)
   17.20    {
   17.21 -    SchedulerType schedulerType = SCHED_TYPE_QOS;
   17.22 +    //SchedulerType schedulerType = SCHED_TYPE_MBQOS;
   17.23  
   17.24      NetDeviceContainer devices;
   17.25      for (NodeContainer::Iterator i = c.Begin(); i != c.End(); i++)
   17.26 @@ -251,7 +251,7 @@
   17.27  
   17.28    NetDeviceContainer
   17.29    WimaxHelper::Install(NodeContainer c, NetDeviceType deviceType,
   17.30 -      PhyType phyType, Ptr<WimaxChannel> channel)
   17.31 +      PhyType phyType, Ptr<WimaxChannel> channel, SchedulerType schedulerType)
   17.32    {
   17.33      NetDeviceContainer devices;
   17.34      for (NodeContainer::Iterator i = c.Begin(); i != c.End(); i++)
   17.35 @@ -259,13 +259,21 @@
   17.36          Ptr<Node> node = *i;
   17.37          Ptr<WimaxPhy> phy = CreatePhyWithoutChannel(phyType);
   17.38          Ptr<WimaxNetDevice> device;
   17.39 +        Ptr<UplinkScheduler> uplinkScheduler = CreateUplinkScheduler (schedulerType);
   17.40  
   17.41          if (deviceType == DEVICE_TYPE_BASE_STATION)
   17.42 -          device = CreateObject<WimaxBaseStationNetDevice> ("Node",
   17.43 -              PointerValue(node), "Phy", PointerValue(phy));
   17.44 +          {
   17.45 +            Ptr<WimaxBaseStationNetDevice> deviceBS;
   17.46 +            deviceBS = CreateObject<WimaxBaseStationNetDevice> ("Node",
   17.47 +              PointerValue(node), "Phy", PointerValue(phy), "UplinkScheduler", PointerValue(uplinkScheduler));
   17.48 +              device = deviceBS;
   17.49 +              uplinkScheduler->ConfigureBs (deviceBS);
   17.50 +          }
   17.51          else
   17.52 +          {
   17.53            device = CreateObject<WimaxSubscriberStationNetDevice> ("Node",
   17.54                PointerValue(node), "Phy", PointerValue(phy));
   17.55 +          }
   17.56  
   17.57          device->SetAddress(Mac48Address::Allocate());
   17.58          phy->SetDevice(device);
   17.59 @@ -280,19 +288,26 @@
   17.60  
   17.61    Ptr<WimaxNetDevice>
   17.62    WimaxHelper::Install(Ptr<Node> node, NetDeviceType deviceType,
   17.63 -      PhyType phyType, Ptr<WimaxChannel> channel)
   17.64 +      PhyType phyType, Ptr<WimaxChannel> channel, SchedulerType schedulerType)
   17.65    {
   17.66  
   17.67      Ptr<WimaxPhy> phy = CreatePhyWithoutChannel(phyType);
   17.68      Ptr<WimaxNetDevice> device;
   17.69 +    Ptr<UplinkScheduler> uplinkScheduler = CreateUplinkScheduler (schedulerType);
   17.70  
   17.71      if (deviceType == DEVICE_TYPE_BASE_STATION)
   17.72 -      device = CreateObject<WimaxBaseStationNetDevice> ("Node", PointerValue(
   17.73 -          node), "Phy", PointerValue(phy));
   17.74 +      {
   17.75 +        Ptr<WimaxBaseStationNetDevice> deviceBS;
   17.76 +        deviceBS = CreateObject<WimaxBaseStationNetDevice> ("Node", PointerValue(
   17.77 +          node), "Phy", PointerValue(phy), "UplinkScheduler", PointerValue(uplinkScheduler));
   17.78 +          device = deviceBS;
   17.79 +          uplinkScheduler->ConfigureBs (deviceBS);
   17.80 +      }
   17.81      else
   17.82 -      device = CreateObject<WimaxSubscriberStationNetDevice> ("Node",
   17.83 +      {
   17.84 +        device = CreateObject<WimaxSubscriberStationNetDevice> ("Node",
   17.85            PointerValue(node), "Phy", PointerValue(phy));
   17.86 -
   17.87 +      }
   17.88      device->SetAddress(Mac48Address::Allocate());
   17.89      phy->SetDevice(device);
   17.90      device->Start();
    18.1 --- a/src/helper/wimax-helper.h	Tue Aug 11 15:03:05 2009 -0300
    18.2 +++ b/src/helper/wimax-helper.h	Tue Aug 11 16:41:52 2009 -0300
    18.3 @@ -32,7 +32,7 @@
    18.4  #include "ns3/service-flow.h"
    18.5  #include "ns3/propagation.h"
    18.6  #include "ns3/uplink-scheduler.h"
    18.7 -#include "ns3/uplink-scheduler-qos.h"
    18.8 +#include "ns3/uplink-scheduler-mbqos.h"
    18.9  
   18.10  namespace ns3
   18.11  {
   18.12 @@ -60,7 +60,7 @@
   18.13  
   18.14      enum SchedulerType
   18.15      {
   18.16 -      SCHED_TYPE_SIMPLE, SCHED_TYPE_QOS
   18.17 +      SCHED_TYPE_SIMPLE, SCHED_TYPE_MBQOS
   18.18      };
   18.19  
   18.20      WimaxHelper(void);
   18.21 @@ -109,7 +109,7 @@
   18.22       * depending on the type parameter) is attached to the shared input channel.
   18.23       */
   18.24      NetDeviceContainer
   18.25 -    Install(NodeContainer c, NetDeviceType type, PhyType phyType);
   18.26 +    Install(NodeContainer c, NetDeviceType type, PhyType phyType, SchedulerType schedulerType);
   18.27  
   18.28      QoSParameterSet*
   18.29      CreateUgsParameterSet(uint32_t minReservedTrafficRate, uint32_t maxLatency,
   18.30 @@ -180,17 +180,17 @@
   18.31  
   18.32      NetDeviceContainer
   18.33      Install(NodeContainer c, NetDeviceType deviceType, PhyType phyType, Ptr<
   18.34 -        WimaxChannel> channel);
   18.35 +        WimaxChannel> channel, SchedulerType schedulerType);
   18.36      NetDeviceContainer
   18.37      Install(NodeContainer c, NetDeviceType deviceType, PhyType phyType, Ptr<
   18.38 -        WimaxChannel> channel, SchedulerType schedulerType);
   18.39 +        WimaxChannel> channel, SchedulerType schedulerType, SchedulerType schedulerType);
   18.40      Ptr<WimaxPhy>
   18.41      CreatePhyWithoutChannel(PhyType phyType);
   18.42  
   18.43  
   18.44      Ptr<WimaxNetDevice>
   18.45      Install(Ptr<Node> node, NetDeviceType deviceType, PhyType phyType, Ptr<
   18.46 -        WimaxChannel> channel);
   18.47 +        WimaxChannel> channel, SchedulerType schedulerType);
   18.48    private:
   18.49      static void
   18.50      AsciiEnqueueEvent(std::ostream *os, std::string path,