A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
bs-service-flow-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  */
21 
22 #include <stdint.h>
23 #include "ns3/node.h"
24 #include "ns3/simulator.h"
25 #include "ns3/packet.h"
26 #include "service-flow.h"
27 #include "service-flow-manager.h"
28 #include "ns3/log.h"
29 #include "bs-net-device.h"
30 #include "ss-record.h"
31 #include "ns3/pointer.h"
32 #include "ns3/enum.h"
33 #include "wimax-connection.h"
34 #include "ss-manager.h"
35 #include "connection-manager.h"
36 #include "bs-uplink-scheduler.h"
37 #include "ss-scheduler.h"
38 #include "ns3/buffer.h"
39 #include "service-flow-record.h"
40 NS_LOG_COMPONENT_DEFINE ("BsServiceFlowManager");
41 
42 namespace ns3 {
43 
44 BsServiceFlowManager::BsServiceFlowManager (Ptr<BaseStationNetDevice> device)
45  : m_device (device),
46  m_sfidIndex (100),
47  m_maxDsaRspRetries (100) // default value
48 {
49  m_inuseScheduleDsaRspCid = Cid::InitialRanging ();
50 }
51 
52 BsServiceFlowManager::~BsServiceFlowManager (void)
53 {
54 }
55 
56 void
58 {
60 }
61 
62 void
64 {
65  m_maxDsaRspRetries = maxDsaRspRetries;
66 }
67 
68 uint8_t
69 BsServiceFlowManager::GetMaxDsaRspRetries (void) const
70 {
71  return m_maxDsaRspRetries;
72 }
73 
74 EventId
75 BsServiceFlowManager::GetDsaAckTimeoutEvent (void) const
76 {
77  return m_dsaAckTimeoutEvent;
78 }
79 
80 void
82 {
83  ServiceFlowManager::AddServiceFlow (serviceFlow);
84 }
85 
88 {
89  return ServiceFlowManager::GetServiceFlow (sfid);
90 }
91 
94 {
95  return ServiceFlowManager::GetServiceFlow (cid);
96 }
97 
98 std::vector<ServiceFlow*>
99 BsServiceFlowManager::GetServiceFlows (ServiceFlow::SchedulingType schedulingType) const
100 {
101  return ServiceFlowManager::GetServiceFlows (schedulingType);
102 }
103 
104 DsaRsp
105 BsServiceFlowManager::CreateDsaRsp (const ServiceFlow *serviceFlow, uint16_t transactionId)
106 {
107  DsaRsp dsaRsp;
108  dsaRsp.SetTransactionId (transactionId);
109  dsaRsp.SetServiceFlow (*serviceFlow);
110  // assuming SS can supports all of the service flow parameters
111  dsaRsp.SetConfirmationCode (CONFIRMATION_CODE_SUCCESS);
112 
113  return dsaRsp;
114 }
115 
116 void
117 BsServiceFlowManager::ScheduleDsaRsp (ServiceFlow *serviceFlow, Cid cid)
118 {
119  Ptr<BaseStationNetDevice> bs = m_device->GetObject<BaseStationNetDevice> ();
120 
121  SSRecord *ssRecord = bs->GetSSManager ()->GetSSRecord (cid);
122  if (ssRecord == 0)
123  {
124  NS_LOG_INFO ("SS not registered with the BS CID:" << cid);
125  return;
126  }
127 
128  serviceFlow->SetIsEnabled (true);
129  serviceFlow->SetType (ServiceFlow::SF_TYPE_ACTIVE);
130  ssRecord->AddServiceFlow (serviceFlow);
131 
132 
133  bs->GetUplinkScheduler ()->SetupServiceFlow (ssRecord, serviceFlow);
134 
135  Ptr<Packet> p = Create<Packet> ();
136  DsaRsp dsaRsp;
137 
138  if (ssRecord->GetDsaRspRetries () == 0)
139  {
140  dsaRsp = CreateDsaRsp (serviceFlow, ssRecord->GetSfTransactionId ());
141  p->AddHeader (dsaRsp);
142  ssRecord->SetDsaRsp (dsaRsp);
143  }
144  else
145  {
146  if (ssRecord->GetDsaRspRetries () < m_maxDsaRspRetries)
147  {
148  p->AddHeader (ssRecord->GetDsaRsp ());
149  }
150  else
151  {
152  NS_LOG_DEBUG ("Service flows could not be initialized!");
153  }
154  }
155 
156  ssRecord->IncrementDsaRspRetries ();
157  p->AddHeader (ManagementMessageType (ManagementMessageType::MESSAGE_TYPE_DSA_RSP));
158 
159  if (m_dsaAckTimeoutEvent.IsRunning ())
160  {
161  Simulator::Cancel (m_dsaAckTimeoutEvent);
162  }
163 
164  m_inuseScheduleDsaRspCid = cid;
165 
166  m_dsaAckTimeoutEvent = Simulator::Schedule (bs->GetIntervalT8 (),
167  &BsServiceFlowManager::ScheduleDsaRsp,
168  this,
169  serviceFlow,
170  cid);
171  m_device->Enqueue (p, MacHeaderType (), bs->GetConnection (ssRecord->GetPrimaryCid ()));
172 }
173 
174 ServiceFlow*
176 {
177  ServiceFlow * serviceFlow;
178  Ptr<BaseStationNetDevice> bs = m_device->GetObject<BaseStationNetDevice> ();
179  SSRecord *ssRecord = bs->GetSSManager ()->GetSSRecord (cid);
180 
181  NS_LOG_INFO ("BsServiceFlowManager: Processing DSA-REQ...");
182  if (ssRecord->GetSfTransactionId () != 0)
183  {
184  // had already received DSA-REQ. DSA-RSP was lost
185  NS_ASSERT_MSG (dsaReq.GetTransactionId () == ssRecord->GetSfTransactionId (),
186  "Error while processing DSA request:the received transaction ID is not expected");
187  serviceFlow = GetServiceFlow (ssRecord->GetDsaRsp ().GetSfid ());
188  }
189  else
190  {
191  ServiceFlow sf = dsaReq.GetServiceFlow ();
192  Ptr<WimaxConnection> transportConnection;
193  Ptr<ConnectionManager> BsConManager = bs->GetConnectionManager ();
194  transportConnection = BsConManager->CreateConnection (Cid::TRANSPORT);
195  serviceFlow = new ServiceFlow (m_sfidIndex++, sf.GetDirection (), transportConnection);
196  transportConnection->SetServiceFlow (serviceFlow);
197  serviceFlow->CopyParametersFrom (sf);
198  serviceFlow->SetUnsolicitedGrantInterval (1);
199  serviceFlow->SetUnsolicitedPollingInterval (1);
200  serviceFlow->SetConvergenceSublayerParam (sf.GetConvergenceSublayerParam ());
201  AddServiceFlow (serviceFlow);
202  ssRecord->SetSfTransactionId (dsaReq.GetTransactionId ());
203  NS_LOG_INFO ("BsServiceFlowManager: Creating a new Service flow: SFID = " << serviceFlow->GetSfid () << " CID = "
204  << serviceFlow->GetCid ());
205  }
206  return serviceFlow;
207 }
208 
209 void
210 BsServiceFlowManager::AddMulticastServiceFlow (ServiceFlow sf, enum WimaxPhy::ModulationType modulation)
211 {
212  ServiceFlow * serviceFlow = new ServiceFlow ();
213  serviceFlow->CopyParametersFrom (sf);
214  Ptr<BaseStationNetDevice> bs = m_device->GetObject<BaseStationNetDevice> ();
215  Ptr<WimaxConnection> multicastConnection = bs->GetConnectionManager ()->CreateConnection (Cid::MULTICAST);
216  serviceFlow->SetConnection (multicastConnection);
217  AddServiceFlow (serviceFlow);
218  serviceFlow->SetIsEnabled (true);
219  serviceFlow->SetType (ServiceFlow::SF_TYPE_ACTIVE);
220  serviceFlow->SetIsMulticast (true);
221  serviceFlow->SetModulation (modulation);
222  bs->GetUplinkScheduler ()->SetupServiceFlow (0, serviceFlow);
223 }
224 
225 void
226 BsServiceFlowManager::AllocateServiceFlows (const DsaReq &dsaReq, Cid cid)
227 {
228  ServiceFlow *serviceFlow = ProcessDsaReq (dsaReq, cid);
229  if (serviceFlow) {
230  ScheduleDsaRsp (serviceFlow, cid);
231  } else {
232  NS_LOG_INFO ("No service Flow. Could not connect.");
233  }
234 }
235 
236 void
238 {
239  Ptr<BaseStationNetDevice> bs = m_device->GetObject<BaseStationNetDevice> ();
240  SSRecord *ssRecord = bs->GetSSManager ()->GetSSRecord (cid);
241 
242  if (dsaAck.GetTransactionId () != ssRecord->GetSfTransactionId ())
243  {
244  return;
245  }
246 
247  ssRecord->SetDsaRspRetries (0);
248  ssRecord->SetSfTransactionId (0);
249 
250  // check if all service flow have been initiated
251  if (AreServiceFlowsAllocated (ssRecord->GetServiceFlows (ServiceFlow::SF_TYPE_ALL)))
252  {
253  ssRecord->SetAreServiceFlowsAllocated (true);
254  }
255 }
256 } // namespace ns3
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
void SetServiceFlow(ServiceFlow sf)
specify a service flow to be requested by this message
ServiceFlow GetServiceFlow(void) const
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
#define NS_LOG_INFO(msg)
Definition: log.h:264
static void Cancel(const EventId &id)
Definition: simulator.cc:267
bool IsRunning(void) const
Definition: event-id.cc:59
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
static Cid InitialRanging(void)
Definition: cid.cc:82
ServiceFlow * GetServiceFlow(uint32_t sfid) const
Definition: cid.h:35
ServiceFlow * ProcessDsaReq(const DsaReq &dsaReq, Cid cid)
process a DSA-Req message
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
void SetMaxDsaRspRetries(uint8_t maxDsaRspRetries)
set the maximum Dynamic ServiceFlow Add (DSA) retries
void ProcessDsaAck(const DsaAck &dsaAck, Cid cid)
process a DSA-ACK message
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
void AddServiceFlow(ServiceFlow *serviceFlow)
Add a new service flow.
void AddMulticastServiceFlow(ServiceFlow sf, enum WimaxPhy::ModulationType modulation)
add a multicast service flow
This class is used by the base station to store some information related to subscriber station in the...
Definition: ss-record.h:43
std::vector< ServiceFlow * > GetServiceFlows(ServiceFlow::SchedulingType schedulingType) const