A Discrete-Event Network Simulator
API
bs-service-flow-manager.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2007,2008, 2009 INRIA, UDcast
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Authors: Jahanzeb Farooq <jahanzeb.farooq@sophia.inria.fr>
18  * Mohamed Amine Ismail <amine.ismail@sophia.inria.fr>
19  */
20 
21 #include "bs-net-device.h"
22 #include "bs-uplink-scheduler.h"
23 #include "connection-manager.h"
24 #include "service-flow-manager.h"
25 #include "service-flow-record.h"
26 #include "service-flow.h"
27 #include "ss-manager.h"
28 #include "ss-record.h"
29 #include "ss-scheduler.h"
30 #include "wimax-connection.h"
31 
32 #include "ns3/buffer.h"
33 #include "ns3/enum.h"
34 #include "ns3/log.h"
35 #include "ns3/node.h"
36 #include "ns3/packet.h"
37 #include "ns3/pointer.h"
38 #include "ns3/simulator.h"
39 
40 #include <stdint.h>
41 
42 namespace ns3
43 {
44 
45 NS_LOG_COMPONENT_DEFINE("BsServiceFlowManager");
46 
48  : m_device(device),
49  m_sfidIndex(100),
50  m_maxDsaRspRetries(100) // default value
51 {
53 }
54 
56 {
57 }
58 
59 /* static */
60 TypeId
62 {
63  static TypeId tid =
64  TypeId("ns3::BsServiceFlowManager").SetParent<ServiceFlowManager>().SetGroupName("Wifi")
65  // No AddConstructor because this class has no default constructor.
66  ;
67  return tid;
68 }
69 
70 void
72 {
74 }
75 
76 void
78 {
79  m_maxDsaRspRetries = maxDsaRspRetries;
80 }
81 
82 uint8_t
84 {
85  return m_maxDsaRspRetries;
86 }
87 
88 EventId
90 {
91  return m_dsaAckTimeoutEvent;
92 }
93 
94 void
96 {
98 }
99 
102 {
104 }
105 
108 {
110 }
111 
112 std::vector<ServiceFlow*>
114 {
115  return ServiceFlowManager::GetServiceFlows(schedulingType);
116 }
117 
118 DsaRsp
119 BsServiceFlowManager::CreateDsaRsp(const ServiceFlow* serviceFlow, uint16_t transactionId)
120 {
121  DsaRsp dsaRsp;
122  dsaRsp.SetTransactionId(transactionId);
123  dsaRsp.SetServiceFlow(*serviceFlow);
124  // assuming SS can supports all of the service flow parameters
126 
127  return dsaRsp;
128 }
129 
130 void
132 {
134 
135  SSRecord* ssRecord = bs->GetSSManager()->GetSSRecord(cid);
136  if (ssRecord == nullptr)
137  {
138  NS_LOG_INFO("SS not registered with the BS CID:" << cid);
139  return;
140  }
141 
142  serviceFlow->SetIsEnabled(true);
143  serviceFlow->SetType(ServiceFlow::SF_TYPE_ACTIVE);
144  ssRecord->AddServiceFlow(serviceFlow);
145 
146  bs->GetUplinkScheduler()->SetupServiceFlow(ssRecord, serviceFlow);
147 
148  Ptr<Packet> p = Create<Packet>();
149  DsaRsp dsaRsp;
150 
151  if (ssRecord->GetDsaRspRetries() == 0)
152  {
153  dsaRsp = CreateDsaRsp(serviceFlow, ssRecord->GetSfTransactionId());
154  p->AddHeader(dsaRsp);
155  ssRecord->SetDsaRsp(dsaRsp);
156  }
157  else
158  {
159  if (ssRecord->GetDsaRspRetries() < m_maxDsaRspRetries)
160  {
161  p->AddHeader(ssRecord->GetDsaRsp());
162  }
163  else
164  {
165  NS_LOG_DEBUG("Service flows could not be initialized!");
166  }
167  }
168 
169  ssRecord->IncrementDsaRspRetries();
171 
173  {
175  }
176 
178 
179  m_dsaAckTimeoutEvent = Simulator::Schedule(bs->GetIntervalT8(),
181  this,
182  serviceFlow,
183  cid);
184  m_device->Enqueue(p, MacHeaderType(), bs->GetConnection(ssRecord->GetPrimaryCid()));
185 }
186 
189 {
190  ServiceFlow* serviceFlow;
192  SSRecord* ssRecord = bs->GetSSManager()->GetSSRecord(cid);
193 
194  NS_LOG_INFO("BsServiceFlowManager: Processing DSA-REQ...");
195  if (ssRecord->GetSfTransactionId() != 0)
196  {
197  // had already received DSA-REQ. DSA-RSP was lost
199  dsaReq.GetTransactionId() == ssRecord->GetSfTransactionId(),
200  "Error while processing DSA request:the received transaction ID is not expected");
201  serviceFlow = GetServiceFlow(ssRecord->GetDsaRsp().GetSfid());
202  }
203  else
204  {
205  ServiceFlow sf = dsaReq.GetServiceFlow();
206  Ptr<WimaxConnection> transportConnection;
207  Ptr<ConnectionManager> BsConManager = bs->GetConnectionManager();
208  transportConnection = BsConManager->CreateConnection(Cid::TRANSPORT);
209  serviceFlow = new ServiceFlow(m_sfidIndex++, sf.GetDirection(), transportConnection);
210  transportConnection->SetServiceFlow(serviceFlow);
211  serviceFlow->CopyParametersFrom(sf);
212  serviceFlow->SetUnsolicitedGrantInterval(1);
213  serviceFlow->SetUnsolicitedPollingInterval(1);
215  AddServiceFlow(serviceFlow);
216  ssRecord->SetSfTransactionId(dsaReq.GetTransactionId());
217  NS_LOG_INFO("BsServiceFlowManager: Creating a new Service flow: SFID = "
218  << serviceFlow->GetSfid() << " CID = " << serviceFlow->GetCid());
219  }
220  return serviceFlow;
221 }
222 
223 void
225  enum WimaxPhy::ModulationType modulation)
226 {
227  ServiceFlow* serviceFlow = new ServiceFlow();
228  serviceFlow->CopyParametersFrom(sf);
230  Ptr<WimaxConnection> multicastConnection =
231  bs->GetConnectionManager()->CreateConnection(Cid::MULTICAST);
232  serviceFlow->SetConnection(multicastConnection);
233  AddServiceFlow(serviceFlow);
234  serviceFlow->SetIsEnabled(true);
235  serviceFlow->SetType(ServiceFlow::SF_TYPE_ACTIVE);
236  serviceFlow->SetIsMulticast(true);
237  serviceFlow->SetModulation(modulation);
238  bs->GetUplinkScheduler()->SetupServiceFlow(nullptr, serviceFlow);
239 }
240 
241 void
243 {
244  ServiceFlow* serviceFlow = ProcessDsaReq(dsaReq, cid);
245  if (serviceFlow)
246  {
247  ScheduleDsaRsp(serviceFlow, cid);
248  }
249  else
250  {
251  NS_LOG_INFO("No service Flow. Could not connect.");
252  }
253 }
254 
255 void
257 {
259  SSRecord* ssRecord = bs->GetSSManager()->GetSSRecord(cid);
260 
261  if (dsaAck.GetTransactionId() != ssRecord->GetSfTransactionId())
262  {
263  return;
264  }
265 
266  ssRecord->SetDsaRspRetries(0);
267  ssRecord->SetSfTransactionId(0);
268 
269  // check if all service flow have been initiated
270  if (AreServiceFlowsAllocated(ssRecord->GetServiceFlows(ServiceFlow::SF_TYPE_ALL)))
271  {
272  ssRecord->SetAreServiceFlowsAllocated(true);
273  }
274 }
275 } // namespace ns3
BaseStation NetDevice.
Definition: bs-net-device.h:54
ServiceFlow * GetServiceFlow(uint32_t sfid) const
uint8_t m_maxDsaRspRetries
maximum number of DSA response retries
void AllocateServiceFlows(const DsaReq &dsaReq, Cid cid)
allocate service flows
void DoDispose() override
Destructor implementation.
Cid m_inuseScheduleDsaRspCid
in use schedule DSA response CID
void AddMulticastServiceFlow(ServiceFlow sf, enum WimaxPhy::ModulationType modulation)
add a multicast service flow
Ptr< WimaxNetDevice > m_device
the device
void ScheduleDsaRsp(ServiceFlow *serviceFlow, Cid cid)
Create DSA response function.
void ProcessDsaAck(const DsaAck &dsaAck, Cid cid)
process a DSA-ACK message
std::vector< ServiceFlow * > GetServiceFlows(ServiceFlow::SchedulingType schedulingType) const
static TypeId GetTypeId()
Register this type.
void AddServiceFlow(ServiceFlow *serviceFlow)
Add a new service flow.
void SetMaxDsaRspRetries(uint8_t maxDsaRspRetries)
set the maximum Dynamic ServiceFlow Add (DSA) retries
DsaRsp CreateDsaRsp(const ServiceFlow *serviceFlow, uint16_t transactionId)
Create DSA response function.
EventId m_dsaAckTimeoutEvent
DSA ack timeout event.
BsServiceFlowManager(Ptr< BaseStationNetDevice > device)
Constructor.
ServiceFlow * ProcessDsaReq(const DsaReq &dsaReq, Cid cid)
process a DSA-Req message
Cid class.
Definition: cid.h:37
@ TRANSPORT
Definition: cid.h:46
@ MULTICAST
Definition: cid.h:47
static Cid InitialRanging()
Definition: cid.cc:87
This class implements the DSA-ACK message described by "IEEE Standard for Local and metropolitan area...
Definition: mac-messages.h:590
uint16_t GetTransactionId() const
Get transaction ID field.
This class implements the DSA-REQ message described by "IEEE Standard for Local and metropolitan area...
Definition: mac-messages.h:386
ServiceFlow GetServiceFlow() const
uint16_t GetTransactionId() const
This class implements the DSA-RSP message described by "IEEE Standard for Local and metropolitan area...
Definition: mac-messages.h:490
void SetConfirmationCode(uint16_t confirmationCode)
set the confirmation code
void SetServiceFlow(ServiceFlow sf)
specify a service flow to be requested by this message
void SetTransactionId(uint16_t transactionId)
set the transaction ID
An identifier for simulation events.
Definition: event-id.h:55
bool IsRunning() const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:76
This class Represents the HT (Header Type) field of generic MAC and bandwidth request headers.
Mac Management messages Section 6.3.2.3 MAC Management messages page 42, Table 14 page 43.
Definition: mac-messages.h:44
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
This class is used by the base station to store some information related to subscriber station in the...
Definition: ss-record.h:46
This class implements service flows as described by the IEEE-802.16 standard.
Definition: service-flow.h:43
uint32_t GetSfid() const
Get SFID.
void SetModulation(enum WimaxPhy::ModulationType modulationType)
Set modulation.
SchedulingType
section 11.13.11 Service flow scheduling type, page 701
Definition: service-flow.h:62
void SetConvergenceSublayerParam(CsParameters csparam)
Set convergence sublayer parameters.
uint16_t GetCid() const
Get CID.
void CopyParametersFrom(ServiceFlow sf)
Copy parameters from another service flow.
void SetIsMulticast(bool isMulticast)
Set is multicast.
void SetUnsolicitedGrantInterval(uint16_t unsolicitedGrantInterval)
Set unsolicited grant interval.
void SetUnsolicitedPollingInterval(uint16_t unsolicitedPollingInterval)
Set unsolicited polling interval.
void SetType(Type type)
Set type of service flow.
Direction GetDirection() const
Get direction.
CsParameters GetConvergenceSublayerParam() const
Get convergence sublayer.
void SetConnection(Ptr< WimaxConnection > connection)
Set connection.
void SetIsEnabled(bool isEnabled)
Set is enabled flag.
The same service flow manager class serves both for BS and SS though some functions are exclusive to ...
std::vector< ServiceFlow * > GetServiceFlows(enum ServiceFlow::SchedulingType schedulingType) const
Get service flows function.
void AddServiceFlow(ServiceFlow *serviceFlow)
Add service flow function.
ServiceFlow * GetServiceFlow(uint32_t sfid) const
Get service flow by flow id.
void DoDispose() override
Destructor implementation.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
Definition: simulator.cc:276
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
ModulationType
ModulationType enumeration.
Definition: wimax-phy.h:54
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
Every class exported by the ns3 library is enclosed in the ns3 namespace.