A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
bandwidth-manager.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007,2008,2009 INRIA, UDcast
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Authors: Jahanzeb Farooq <jahanzeb.farooq@sophia.inria.fr>
19  * Mohamed Amine Ismail <amine.ismail@sophia.inria.fr>
20  * <amine.ismail@UDcast.com>
21  */
22 
23 #include "bandwidth-manager.h"
24 #include "ns3/node.h"
25 #include "bs-net-device.h"
26 #include "ss-net-device.h"
27 #include "ns3/simulator.h"
28 #include "burst-profile-manager.h"
29 #include "ss-manager.h"
30 #include "ss-record.h"
31 #include "service-flow.h"
32 #include "service-flow-record.h"
33 #include "service-flow-manager.h"
34 #include "connection-manager.h"
35 
36 NS_LOG_COMPONENT_DEFINE ("BandwidthManager");
37 
38 namespace ns3 {
39 
40 NS_OBJECT_ENSURE_REGISTERED (BandwidthManager);
41 
42 TypeId BandwidthManager::GetTypeId (void)
43 {
44  static TypeId tid = TypeId ("ns3::BandwidthManager")
45  .SetParent<Object> ();
46  return tid;
47 }
48 
49 BandwidthManager::BandwidthManager (Ptr<WimaxNetDevice> device)
50  : m_device (device),
51  m_nrBwReqsSent (0)
52 {
53 }
54 
55 BandwidthManager::~BandwidthManager (void)
56 {
57 }
58 
59 void
61 {
62  m_device = 0;
63 }
64 
65 uint32_t
66 BandwidthManager::CalculateAllocationSize (const SSRecord *ssRecord, const ServiceFlow *serviceFlow)
67 {
68  Time currentTime = Simulator::Now ();
69  Ptr<BaseStationNetDevice> bs = m_device->GetObject<BaseStationNetDevice> ();
70  uint32_t allocationSize = 0;
71 
72  // if SS has a UGS flow then it must set poll-me bit in order to be polled for non-UGS flows
73  if (serviceFlow->GetSchedulingType () != ServiceFlow::SF_TYPE_UGS
74  && ssRecord->GetHasServiceFlowUgs ()
75  && !ssRecord->GetPollMeBit ())
76  {
77  return 0;
78  }
79 
80  switch (serviceFlow->GetSchedulingType ())
81  {
82  case ServiceFlow::SF_TYPE_UGS:
83  {
84  if ((currentTime - serviceFlow->GetRecord ()->GetGrantTimeStamp ()).GetMilliSeconds ()
85  >= serviceFlow->GetUnsolicitedGrantInterval ())
86  {
87  allocationSize = serviceFlow->GetRecord ()->GetGrantSize ();
88  serviceFlow->GetRecord ()->SetGrantTimeStamp (currentTime);
89  }
90  }
91  break;
92  case ServiceFlow::SF_TYPE_RTPS:
93  {
94  if ((currentTime - serviceFlow->GetRecord ()->GetGrantTimeStamp ()).GetMilliSeconds ()
95  >= serviceFlow->GetUnsolicitedPollingInterval ())
96  {
97  allocationSize = bs->GetBwReqOppSize ();
98  serviceFlow->GetRecord ()->SetGrantTimeStamp (currentTime);
99  }
100  }
101  break;
102  case ServiceFlow::SF_TYPE_NRTPS:
103  {
104  /* nrtPS shall be serviced only if sufficient bandwidth is available after servicing
105  UGS and rtPS scheduling types, hence no specific service interval is used */
106 
107  allocationSize = bs->GetBwReqOppSize ();
108  }
109  break;
110  case ServiceFlow::SF_TYPE_BE:
111  {
112  /* BE shall be serviced only if sufficient bandwidth is available after servicing
113  the rest of three scheduling types, hence no specific service interval is used */
114 
115  allocationSize = bs->GetBwReqOppSize ();
116  }
117  break;
118  default:
119  NS_FATAL_ERROR ("Invalid scheduling type");
120  }
121 
122  return allocationSize;
123 }
124 
125 ServiceFlow*
126 BandwidthManager::SelectFlowForRequest (uint32_t &bytesToRequest)
127 {
128  Ptr<Packet> packet;
129  ServiceFlow *serviceFlow = 0;
130 
131  Ptr<SubscriberStationNetDevice> ss = m_device->GetObject<SubscriberStationNetDevice> ();
132  std::vector<ServiceFlow*> serviceFlows = ss->GetServiceFlowManager ()->GetServiceFlows (ServiceFlow::SF_TYPE_ALL);
133 
134  for (std::vector<ServiceFlow*>::iterator iter = serviceFlows.begin (); iter != serviceFlows.end (); ++iter)
135  {
136  serviceFlow = *iter;
137  if (serviceFlow->GetSchedulingType () == ServiceFlow::SF_TYPE_RTPS
138  || serviceFlow->GetSchedulingType () == ServiceFlow::SF_TYPE_NRTPS
139  || serviceFlow->GetSchedulingType () == ServiceFlow::SF_TYPE_BE)
140  {
141  if (serviceFlow->HasPackets (MacHeaderType::HEADER_TYPE_GENERIC))
142  {
143  // bandwidth is requested for all packets
144  bytesToRequest = serviceFlow->GetQueue ()->GetQueueLengthWithMACOverhead ();
145  break;
146  }
147  }
148  }
149 
150  return serviceFlow;
151 }
152 
153 void
154 BandwidthManager::SendBandwidthRequest (uint8_t uiuc, uint16_t allocationSize)
155 {
156  Ptr<SubscriberStationNetDevice> ss = m_device->GetObject<SubscriberStationNetDevice> ();
157 
158  uint32_t bytesToRequest = 0;
159  ServiceFlow *serviceFlow = SelectFlowForRequest (bytesToRequest);
160 
161  if (!serviceFlow || !bytesToRequest)
162  {
163  return;
164  }
165  BandwidthRequestHeader bwRequestHdr;
166 
167  // bytesToRequest is the queue length of Service Flow and so,
168  // the header type must be HEADER_TYPE_AGGREGATE!
169 
170  bwRequestHdr.SetType ((uint8_t) BandwidthRequestHeader::HEADER_TYPE_AGGREGATE);
171  bwRequestHdr.SetCid (serviceFlow->GetConnection ()->GetCid ());
172  bwRequestHdr.SetBr (bytesToRequest);
173 
174  Ptr<Packet> packet = Create<Packet> ();
175  packet->AddHeader (bwRequestHdr);
176  ss->Enqueue (packet, MacHeaderType (MacHeaderType::HEADER_TYPE_BANDWIDTH), serviceFlow->GetConnection ());
177  m_nrBwReqsSent++;
178  NS_ASSERT_MSG (uiuc == OfdmUlBurstProfile::UIUC_REQ_REGION_FULL, "Send Bandwidth Request: !UIUC_REQ_REGION_FULL");
179  ss->SendBurst (uiuc, allocationSize, serviceFlow->GetConnection (), MacHeaderType::HEADER_TYPE_BANDWIDTH);
180 }
181 
182 void
183 BandwidthManager::ProcessBandwidthRequest (const BandwidthRequestHeader &bwRequestHdr)
184 {
185  Ptr<BaseStationNetDevice> bs = m_device->GetObject<BaseStationNetDevice> ();
186 
187  ServiceFlow *serviceFlow = bs->GetConnectionManager ()->GetConnection (bwRequestHdr.GetCid ())->GetServiceFlow ();
188  if (bwRequestHdr.GetType () == (uint8_t) BandwidthRequestHeader::HEADER_TYPE_INCREMENTAL)
189  {
190  serviceFlow->GetRecord ()->UpdateRequestedBandwidth (bwRequestHdr.GetBr ());
191  }
192  else
193  {
194  serviceFlow->GetRecord ()->SetRequestedBandwidth (bwRequestHdr.GetBr ());
195  bs->GetUplinkScheduler ()->OnSetRequestedBandwidth (serviceFlow->GetRecord ());
196  }
197  bs->GetUplinkScheduler ()->ProcessBandwidthRequest (bwRequestHdr);
198  // update backlogged
199  serviceFlow->GetRecord ()->IncreaseBacklogged (bwRequestHdr.GetBr ());
200 }
201 
202 void
203 BandwidthManager::SetSubframeRatio (void)
204 {
205  // sets ratio of the DL and UL subframes
206 
207  Ptr<BaseStationNetDevice> bs = m_device->GetObject<BaseStationNetDevice> ();
208 
209  uint32_t symbolsPerFrame = bs->GetPhy ()->GetSymbolsPerFrame ();
210 
211  /* temporarily divided in half (360 symbols each), shall actually be determined based on UL and DL traffic*/
212  bs->SetNrDlSymbols (symbolsPerFrame / 2);
213  bs->SetNrUlSymbols (symbolsPerFrame / 2);
214 }
215 
216 uint32_t
217 BandwidthManager::GetSymbolsPerFrameAllocated (void)
218 {
219  Ptr<BaseStationNetDevice> bs = m_device->GetObject<BaseStationNetDevice> ();
220 
221  uint32_t allocationPerFrame = 0;
222 
223  std::vector<SSRecord*> *ssRecords = bs->GetSSManager ()->GetSSRecords ();
224  for (std::vector<SSRecord*>::iterator iter1 = ssRecords->begin (); iter1 != ssRecords->end (); ++iter1)
225  {
226  for (std::vector<ServiceFlow*>::iterator iter2 = (*iter1)->GetServiceFlows (ServiceFlow::SF_TYPE_ALL).begin ();
227  iter2 != (*iter1)->GetServiceFlows (ServiceFlow::SF_TYPE_ALL).end (); ++iter2)
228  {
229  allocationPerFrame += (*iter2)->GetRecord ()->GetGrantSize ();
230  }
231  }
232  return allocationPerFrame;
233 }
234 
235 } // namespace ns3
keep track of time unit.
Definition: nstime.h:149
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
Time GetGrantTimeStamp(void) const
void SetGrantTimeStamp(Time grantTimeStamp)
Set the grant time stamp. Used for data alocation for ugs flows, and unicast poll (bw request) for no...
static Time Now(void)
Definition: simulator.cc:179
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
uint32_t GetGrantSize(void) const
This class is used by the base station to store some information related to subscriber station in the...
Definition: ss-record.h:43