A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
radio-bearer-stats-connector.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
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  * Author: Nicola Baldo <nbaldo@cttc.es>
19  */
20 
21 
22 #include <ns3/log.h>
23 
24 
27 #include <ns3/lte-enb-rrc.h>
28 #include <ns3/lte-enb-net-device.h>
29 #include <ns3/lte-ue-rrc.h>
30 #include <ns3/lte-ue-net-device.h>
31 
32 NS_LOG_COMPONENT_DEFINE ("RadioBearerStatsConnector");
33 
34 
35 namespace ns3 {
36 
37 
38 
39 bool
41 {
42  return ( (a.cellId < b.cellId) || ( (a.cellId == b.cellId) && (a.rnti < b.rnti) ) );
43 }
44 
45 struct BoundCallbackArgument : public SimpleRefCount<BoundCallbackArgument>
46 {
47 public:
49  uint64_t imsi;
50  uint16_t cellId;
51 };
52 
53 
54 void
56  uint16_t rnti, uint8_t lcid, uint32_t packetSize)
57 {
58  NS_LOG_LOGIC (path << rnti << (uint16_t)lcid << packetSize);
59  arg->stats->DlTxPdu (arg->cellId, arg->imsi, rnti, lcid, packetSize);
60 }
61 
62 void
64  uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
65 {
66  NS_LOG_LOGIC (path << rnti << (uint16_t)lcid << packetSize << delay);
67  arg->stats->DlRxPdu (arg->cellId, arg->imsi, rnti, lcid, packetSize, delay);
68 }
69 
70 
71 
72 void
74  uint16_t rnti, uint8_t lcid, uint32_t packetSize)
75 {
76  NS_LOG_LOGIC (path << rnti << (uint16_t)lcid << packetSize);
77 
78  arg->stats->UlTxPdu (arg->cellId, arg->imsi, rnti, lcid, packetSize);
79 }
80 
81 void
83  uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
84 {
85  NS_LOG_LOGIC (path << rnti << (uint16_t)lcid << packetSize << delay);
86 
87  arg->stats->UlRxPdu (arg->cellId, arg->imsi, rnti, lcid, packetSize, delay);
88 }
89 
90 
91 
93  : m_connected (false)
94 {
95 }
96 
97 void
99 {
100  m_rlcStats = rlcStats;
101  EnsureConnected ();
102 }
103 
104 void
106 {
107  m_pdcpStats = pdcpStats;
108  EnsureConnected ();
109 }
110 
111 void
113 {
114  NS_LOG_FUNCTION (this);
115  if (!m_connected)
116  {
117  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/NewUeContext",
119  Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/RandomAccessSuccessful",
121  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/ConnectionReconfiguration",
123  Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/ConnectionReconfiguration",
125  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverStart",
127  Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/HandoverStart",
129  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverEndOk",
131  Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/HandoverEndOk",
133  m_connected = true;
134  }
135 }
136 
137 void
138 RadioBearerStatsConnector::NotifyRandomAccessSuccessfulUe (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
139 {
140  c->ConnectSrb0Traces (context, imsi, cellId, rnti);
141 }
142 
143 void
144 RadioBearerStatsConnector::NotifyConnectionSetupUe (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
145 {
146  c->ConnectSrb1TracesUe (context, imsi, cellId, rnti);
147 }
148 
149 void
150 RadioBearerStatsConnector::NotifyConnectionReconfigurationUe (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
151 {
152  c->ConnectTracesUeIfFirstTime (context, imsi, cellId, rnti);
153 }
154 
155 void
156 RadioBearerStatsConnector::NotifyHandoverStartUe (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti, uint16_t targetCellId)
157 {
158  c->DisconnectTracesUe (context, imsi, cellId, rnti);
159 }
160 
161 void
162 RadioBearerStatsConnector::NotifyHandoverEndOkUe (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
163 {
164  c->ConnectTracesUe (context, imsi, cellId, rnti);
165 }
166 
167 void
168 RadioBearerStatsConnector::NotifyNewUeContextEnb (RadioBearerStatsConnector* c, std::string context, uint16_t cellId, uint16_t rnti)
169 {
170  c->StoreUeManagerPath (context, cellId, rnti);
171 }
172 
173 void
174 RadioBearerStatsConnector::NotifyConnectionReconfigurationEnb (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
175 {
176  c->ConnectTracesEnbIfFirstTime (context, imsi, cellId, rnti);
177 }
178 
179 void
180 RadioBearerStatsConnector::NotifyHandoverStartEnb (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti, uint16_t targetCellId)
181 {
182  c->DisconnectTracesEnb (context, imsi, cellId, rnti);
183 }
184 
185 void
186 RadioBearerStatsConnector::NotifyHandoverEndOkEnb (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
187 {
188  c->ConnectTracesEnb (context, imsi, cellId, rnti);
189 }
190 
191 void
192 RadioBearerStatsConnector::StoreUeManagerPath (std::string context, uint16_t cellId, uint16_t rnti)
193 {
194  NS_LOG_FUNCTION (this << context << cellId << rnti);
195  std::ostringstream ueManagerPath;
196  ueManagerPath << context.substr (0, context.rfind ("/")) << "/UeMap/" << (uint32_t) rnti;
197  CellIdRnti key;
198  key.cellId = cellId;
199  key.rnti = rnti;
200  m_ueManagerPathByCellIdRnti[key] = ueManagerPath.str ();
201 }
202 
203 void
204 RadioBearerStatsConnector::ConnectSrb0Traces (std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
205 {
206  NS_LOG_FUNCTION (this << imsi << cellId << rnti);
207  std::string ueRrcPath = context.substr (0, context.rfind ("/"));
208  CellIdRnti key;
209  key.cellId = cellId;
210  key.rnti = rnti;
211  std::map<CellIdRnti, std::string>::iterator it = m_ueManagerPathByCellIdRnti.find (key);
212  NS_ASSERT (it != m_ueManagerPathByCellIdRnti.end ());
213  std::string ueManagerPath = it->second;
214  NS_LOG_LOGIC (this << " ueManagerPath: " << ueManagerPath);
215  m_ueManagerPathByCellIdRnti.erase (it);
216 
217  if (m_rlcStats)
218  {
219  Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
220  arg->imsi = imsi;
221  arg->cellId = cellId;
222  arg->stats = m_rlcStats;
223 
224  // diconnect eventually previously connected SRB0 both at UE and eNB
225  Config::Disconnect (ueRrcPath + "/Srb0/LteRlc/TxPDU",
227  Config::Disconnect (ueRrcPath + "/Srb0/LteRlc/RxPDU",
229  Config::Disconnect (ueManagerPath + "/Srb0/LteRlc/TxPDU",
231  Config::Disconnect (ueManagerPath + "/Srb0/LteRlc/RxPDU",
233 
234  // connect SRB0 both at UE and eNB
235  Config::Connect (ueRrcPath + "/Srb0/LteRlc/TxPDU",
237  Config::Connect (ueRrcPath + "/Srb0/LteRlc/RxPDU",
239  Config::Connect (ueManagerPath + "/Srb0/LteRlc/TxPDU",
241  Config::Connect (ueManagerPath + "/Srb0/LteRlc/RxPDU",
243 
244  // connect SRB1 at eNB only (at UE SRB1 will be setup later)
245  Config::Connect (ueManagerPath + "/Srb1/LteRlc/TxPDU",
247  Config::Connect (ueManagerPath + "/Srb1/LteRlc/RxPDU",
249  }
250  if (m_pdcpStats)
251  {
252  Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
253  arg->imsi = imsi;
254  arg->cellId = cellId;
255  arg->stats = m_pdcpStats;
256 
257  // connect SRB1 at eNB only (at UE SRB1 will be setup later)
258  Config::Connect (ueManagerPath + "/Srb1/LtePdcp/RxPDU",
260  Config::Connect (ueManagerPath + "/Srb1/LtePdcp/TxPDU",
262  }
263 }
264 
265 void
266 RadioBearerStatsConnector::ConnectSrb1TracesUe (std::string ueRrcPath, uint64_t imsi, uint16_t cellId, uint16_t rnti)
267 {
268  NS_LOG_FUNCTION (this << imsi << cellId << rnti);
269  if (m_rlcStats)
270  {
271  Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
272  arg->imsi = imsi;
273  arg->cellId = cellId;
274  arg->stats = m_rlcStats;
275  Config::Connect (ueRrcPath + "/Srb1/LteRlc/TxPDU",
277  Config::Connect (ueRrcPath + "/Srb1/LteRlc/RxPDU",
279  }
280  if (m_pdcpStats)
281  {
282  Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
283  arg->imsi = imsi;
284  arg->cellId = cellId;
285  arg->stats = m_pdcpStats;
286  Config::Connect (ueRrcPath + "/Srb1/LtePdcp/RxPDU",
288  Config::Connect (ueRrcPath + "/Srb1/LtePdcp/TxPDU",
290  }
291 }
292 
293 void
294 RadioBearerStatsConnector::ConnectTracesUeIfFirstTime (std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
295 {
296  NS_LOG_FUNCTION (this << context);
297  if (m_imsiSeenUe.find (imsi) == m_imsiSeenUe.end ())
298  {
299  m_imsiSeenUe.insert (imsi);
300  ConnectTracesUe (context, imsi, cellId, rnti);
301  }
302 }
303 
304 void
305 RadioBearerStatsConnector::ConnectTracesEnbIfFirstTime (std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
306 {
307  NS_LOG_FUNCTION (this << context);
308  if (m_imsiSeenEnb.find (imsi) == m_imsiSeenEnb.end ())
309  {
310  m_imsiSeenEnb.insert (imsi);
311  ConnectTracesEnb (context, imsi, cellId, rnti);
312  }
313 }
314 
315 void
316 RadioBearerStatsConnector::ConnectTracesUe (std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
317 {
318  NS_LOG_FUNCTION (this << context);
319  NS_LOG_LOGIC (this << "expected context should match /NodeList/*/DeviceList/*/LteUeRrc/");
320  std::string basePath = context.substr (0, context.rfind ("/"));
321  if (m_rlcStats)
322  {
323  Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
324  arg->imsi = imsi;
325  arg->cellId = cellId;
326  arg->stats = m_rlcStats;
327  Config::Connect (basePath + "/DataRadioBearerMap/*/LteRlc/TxPDU",
329  Config::Connect (basePath + "/DataRadioBearerMap/*/LteRlc/RxPDU",
331  Config::Connect (basePath + "/Srb1/LteRlc/TxPDU",
333  Config::Connect (basePath + "/Srb1/LteRlc/RxPDU",
335 
336  }
337  if (m_pdcpStats)
338  {
339  Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
340  arg->imsi = imsi;
341  arg->cellId = cellId;
342  arg->stats = m_pdcpStats;
343  Config::Connect (basePath + "/DataRadioBearerMap/*/LtePdcp/RxPDU",
345  Config::Connect (basePath + "/DataRadioBearerMap/*/LtePdcp/TxPDU",
347  Config::Connect (basePath + "/Srb1/LtePdcp/RxPDU",
349  Config::Connect (basePath + "/Srb1/LtePdcp/TxPDU",
351  }
352 }
353 
354 void
355 RadioBearerStatsConnector::ConnectTracesEnb (std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
356 {
357  NS_LOG_FUNCTION (this << context);
358  NS_LOG_LOGIC (this << "expected context should match /NodeList/*/DeviceList/*/LteEnbRrc/");
359  std::ostringstream basePath;
360  basePath << context.substr (0, context.rfind ("/")) << "/UeMap/" << (uint32_t) rnti;
361  if (m_rlcStats)
362  {
363  Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
364  arg->imsi = imsi;
365  arg->cellId = cellId;
366  arg->stats = m_rlcStats;
367  Config::Connect (basePath.str () + "/DataRadioBearerMap/*/LteRlc/RxPDU",
369  Config::Connect (basePath.str () + "/DataRadioBearerMap/*/LteRlc/TxPDU",
371  Config::Connect (basePath.str () + "/Srb0/LteRlc/RxPDU",
373  Config::Connect (basePath.str () + "/Srb0/LteRlc/TxPDU",
375  Config::Connect (basePath.str () + "/Srb1/LteRlc/RxPDU",
377  Config::Connect (basePath.str () + "/Srb1/LteRlc/TxPDU",
379  }
380  if (m_pdcpStats)
381  {
382  Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
383  arg->imsi = imsi;
384  arg->cellId = cellId;
385  arg->stats = m_pdcpStats;
386  Config::Connect (basePath.str () + "/DataRadioBearerMap/*/LtePdcp/TxPDU",
388  Config::Connect (basePath.str () + "/DataRadioBearerMap/*/LtePdcp/RxPDU",
390  Config::Connect (basePath.str () + "/Srb1/LtePdcp/TxPDU",
392  Config::Connect (basePath.str () + "/Srb1/LtePdcp/RxPDU",
394  }
395 }
396 
397 void
398 RadioBearerStatsConnector::DisconnectTracesUe (std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
399 {
400  NS_LOG_FUNCTION (this);
401 }
402 
403 
404 void
405 RadioBearerStatsConnector::DisconnectTracesEnb (std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
406 {
407  NS_LOG_FUNCTION (this);
408 }
409 
410 
411 
412 } // namespace ns3
static void NotifyRandomAccessSuccessfulUe(RadioBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
void ConnectTracesEnbIfFirstTime(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
Callback< R > MakeBoundCallback(R(*fnPtr)(TX), ARG a1)
Build bound Callbacks which take varying numbers of arguments, and potentially returning a value...
Definition: callback.h:1463
void Disconnect(std::string path, const CallbackBase &cb)
Definition: config.cc:734
#define NS_ASSERT(condition)
Definition: assert.h:64
static void NotifyHandoverEndOkUe(RadioBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
void EnablePdcpStats(Ptr< RadioBearerStatsCalculator > pdcpStats)
Ptr< RadioBearerStatsCalculator > m_pdcpStats
bool operator<(const Room &a, const Room &b)
Ptr< RadioBearerStatsCalculator > stats
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:728
void UlRxPduCallback(Ptr< BoundCallbackArgument > arg, std::string path, uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
void DisconnectTracesEnb(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
NS_LOG_COMPONENT_DEFINE("RadioBearerStatsConnector")
void ConnectTracesEnb(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
void DlRxPduCallback(Ptr< BoundCallbackArgument > arg, std::string path, uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
void EnableRlcStats(Ptr< RadioBearerStatsCalculator > rlcStats)
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
static void NotifyHandoverStartEnb(RadioBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti, uint16_t targetCellId)
static void NotifyNewUeContextEnb(RadioBearerStatsConnector *c, std::string context, uint16_t cellid, uint16_t rnti)
void ConnectTracesUe(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
void DlTxPduCallback(Ptr< BoundCallbackArgument > arg, std::string path, uint16_t rnti, uint8_t lcid, uint32_t packetSize)
std::map< CellIdRnti, std::string > m_ueManagerPathByCellIdRnti
static void NotifyConnectionSetupUe(RadioBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
static void NotifyConnectionReconfigurationEnb(RadioBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
static void NotifyConnectionReconfigurationUe(RadioBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
void UlTxPduCallback(Ptr< BoundCallbackArgument > arg, std::string path, uint16_t rnti, uint8_t lcid, uint32_t packetSize)
void ConnectSrb1TracesUe(std::string ueRrcPath, uint64_t imsi, uint16_t cellId, uint16_t rnti)
static void NotifyHandoverEndOkEnb(RadioBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
static void NotifyHandoverStartUe(RadioBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti, uint16_t targetCellId)
void DisconnectTracesUe(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
Ptr< RadioBearerStatsCalculator > m_rlcStats
void ConnectTracesUeIfFirstTime(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
A template-based reference counting class.
void StoreUeManagerPath(std::string ueManagerPath, uint16_t cellId, uint16_t rnti)
void ConnectSrb0Traces(std::string ueRrcPath, uint64_t imsi, uint16_t cellId, uint16_t rnti)