A Discrete-Event Network Simulator
API
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 namespace ns3 {
33 
34 NS_LOG_COMPONENT_DEFINE ("RadioBearerStatsConnector");
35 
39 bool
41 {
42  return ( (a.cellId < b.cellId) || ( (a.cellId == b.cellId) && (a.rnti < b.rnti) ) );
43 }
44 
51 struct BoundCallbackArgument : public SimpleRefCount<BoundCallbackArgument>
52 {
53 public:
55  uint64_t imsi;
56  uint16_t cellId;
57 };
58 
67 void
69  uint16_t rnti, uint8_t lcid, uint32_t packetSize)
70 {
71  NS_LOG_FUNCTION (path << rnti << (uint16_t)lcid << packetSize);
72  arg->stats->DlTxPdu (arg->cellId, arg->imsi, rnti, lcid, packetSize);
73 }
74 
84 void
86  uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
87 {
88  NS_LOG_FUNCTION (path << rnti << (uint16_t)lcid << packetSize << delay);
89  arg->stats->DlRxPdu (arg->cellId, arg->imsi, rnti, lcid, packetSize, delay);
90 }
91 
100 void
102  uint16_t rnti, uint8_t lcid, uint32_t packetSize)
103 {
104  NS_LOG_FUNCTION (path << rnti << (uint16_t)lcid << packetSize);
105 
106  arg->stats->UlTxPdu (arg->cellId, arg->imsi, rnti, lcid, packetSize);
107 }
108 
118 void
120  uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
121 {
122  NS_LOG_FUNCTION (path << rnti << (uint16_t)lcid << packetSize << delay);
123 
124  arg->stats->UlRxPdu (arg->cellId, arg->imsi, rnti, lcid, packetSize, delay);
125 }
126 
127 
128 
130  : m_connected (false)
131 {
132 }
133 
134 void
136 {
137  m_rlcStats = rlcStats;
138  EnsureConnected ();
139 }
140 
141 void
143 {
144  m_pdcpStats = pdcpStats;
145  EnsureConnected ();
146 }
147 
148 void
150 {
151  NS_LOG_FUNCTION (this);
152  if (!m_connected)
153  {
154  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/NewUeContext",
156  Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/RandomAccessSuccessful",
158  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/ConnectionReconfiguration",
160  Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/ConnectionReconfiguration",
162  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverStart",
164  Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/HandoverStart",
166  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverEndOk",
168  Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/HandoverEndOk",
170  m_connected = true;
171  }
172 }
173 
174 void
175 RadioBearerStatsConnector::NotifyRandomAccessSuccessfulUe (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
176 {
177  c->ConnectSrb0Traces (context, imsi, cellId, rnti);
178 }
179 
180 void
181 RadioBearerStatsConnector::NotifyConnectionSetupUe (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
182 {
183  c->ConnectSrb1TracesUe (context, imsi, cellId, rnti);
184 }
185 
186 void
187 RadioBearerStatsConnector::NotifyConnectionReconfigurationUe (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
188 {
189  c->ConnectTracesUeIfFirstTime (context, imsi, cellId, rnti);
190 }
191 
192 void
193 RadioBearerStatsConnector::NotifyHandoverStartUe (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti, uint16_t targetCellId)
194 {
195  c->DisconnectTracesUe (context, imsi, cellId, rnti);
196 }
197 
198 void
199 RadioBearerStatsConnector::NotifyHandoverEndOkUe (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
200 {
201  c->ConnectTracesUe (context, imsi, cellId, rnti);
202 }
203 
204 void
205 RadioBearerStatsConnector::NotifyNewUeContextEnb (RadioBearerStatsConnector* c, std::string context, uint16_t cellId, uint16_t rnti)
206 {
207  c->StoreUeManagerPath (context, cellId, rnti);
208 }
209 
210 void
211 RadioBearerStatsConnector::NotifyConnectionReconfigurationEnb (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
212 {
213  c->ConnectTracesEnbIfFirstTime (context, imsi, cellId, rnti);
214 }
215 
216 void
217 RadioBearerStatsConnector::NotifyHandoverStartEnb (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti, uint16_t targetCellId)
218 {
219  c->DisconnectTracesEnb (context, imsi, cellId, rnti);
220 }
221 
222 void
223 RadioBearerStatsConnector::NotifyHandoverEndOkEnb (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
224 {
225  c->ConnectTracesEnb (context, imsi, cellId, rnti);
226 }
227 
228 void
229 RadioBearerStatsConnector::StoreUeManagerPath (std::string context, uint16_t cellId, uint16_t rnti)
230 {
231  NS_LOG_FUNCTION (this << context << cellId << rnti);
232  std::ostringstream ueManagerPath;
233  ueManagerPath << context.substr (0, context.rfind ("/")) << "/UeMap/" << (uint32_t) rnti;
234  CellIdRnti key;
235  key.cellId = cellId;
236  key.rnti = rnti;
237  m_ueManagerPathByCellIdRnti[key] = ueManagerPath.str ();
238 }
239 
240 void
241 RadioBearerStatsConnector::ConnectSrb0Traces (std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
242 {
243  NS_LOG_FUNCTION (this << imsi << cellId << rnti);
244  std::string ueRrcPath = context.substr (0, context.rfind ("/"));
245  CellIdRnti key;
246  key.cellId = cellId;
247  key.rnti = rnti;
248  std::map<CellIdRnti, std::string>::iterator it = m_ueManagerPathByCellIdRnti.find (key);
249  NS_ASSERT (it != m_ueManagerPathByCellIdRnti.end ());
250  std::string ueManagerPath = it->second;
251  NS_LOG_LOGIC (this << " ueManagerPath: " << ueManagerPath);
252  m_ueManagerPathByCellIdRnti.erase (it);
253 
254  if (m_rlcStats)
255  {
256  Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
257  arg->imsi = imsi;
258  arg->cellId = cellId;
259  arg->stats = m_rlcStats;
260 
261  // diconnect eventually previously connected SRB0 both at UE and eNB
262  Config::Disconnect (ueRrcPath + "/Srb0/LteRlc/TxPDU",
264  Config::Disconnect (ueRrcPath + "/Srb0/LteRlc/RxPDU",
266  Config::Disconnect (ueManagerPath + "/Srb0/LteRlc/TxPDU",
268  Config::Disconnect (ueManagerPath + "/Srb0/LteRlc/RxPDU",
270 
271  // connect SRB0 both at UE and eNB
272  Config::Connect (ueRrcPath + "/Srb0/LteRlc/TxPDU",
274  Config::Connect (ueRrcPath + "/Srb0/LteRlc/RxPDU",
276  Config::Connect (ueManagerPath + "/Srb0/LteRlc/TxPDU",
278  Config::Connect (ueManagerPath + "/Srb0/LteRlc/RxPDU",
280 
281  // connect SRB1 at eNB only (at UE SRB1 will be setup later)
282  Config::Connect (ueManagerPath + "/Srb1/LteRlc/TxPDU",
284  Config::Connect (ueManagerPath + "/Srb1/LteRlc/RxPDU",
286  }
287  if (m_pdcpStats)
288  {
289  Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
290  arg->imsi = imsi;
291  arg->cellId = cellId;
292  arg->stats = m_pdcpStats;
293 
294  // connect SRB1 at eNB only (at UE SRB1 will be setup later)
295  Config::Connect (ueManagerPath + "/Srb1/LtePdcp/RxPDU",
297  Config::Connect (ueManagerPath + "/Srb1/LtePdcp/TxPDU",
299  }
300 }
301 
302 void
303 RadioBearerStatsConnector::ConnectSrb1TracesUe (std::string ueRrcPath, uint64_t imsi, uint16_t cellId, uint16_t rnti)
304 {
305  NS_LOG_FUNCTION (this << imsi << cellId << rnti);
306  if (m_rlcStats)
307  {
308  Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
309  arg->imsi = imsi;
310  arg->cellId = cellId;
311  arg->stats = m_rlcStats;
312  Config::Connect (ueRrcPath + "/Srb1/LteRlc/TxPDU",
314  Config::Connect (ueRrcPath + "/Srb1/LteRlc/RxPDU",
316  }
317  if (m_pdcpStats)
318  {
319  Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
320  arg->imsi = imsi;
321  arg->cellId = cellId;
322  arg->stats = m_pdcpStats;
323  Config::Connect (ueRrcPath + "/Srb1/LtePdcp/RxPDU",
325  Config::Connect (ueRrcPath + "/Srb1/LtePdcp/TxPDU",
327  }
328 }
329 
330 void
331 RadioBearerStatsConnector::ConnectTracesUeIfFirstTime (std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
332 {
333  NS_LOG_FUNCTION (this << context);
334  if (m_imsiSeenUe.find (imsi) == m_imsiSeenUe.end ())
335  {
336  m_imsiSeenUe.insert (imsi);
337  ConnectTracesUe (context, imsi, cellId, rnti);
338  }
339 }
340 
341 void
342 RadioBearerStatsConnector::ConnectTracesEnbIfFirstTime (std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
343 {
344  NS_LOG_FUNCTION (this << context);
345  if (m_imsiSeenEnb.find (imsi) == m_imsiSeenEnb.end ())
346  {
347  m_imsiSeenEnb.insert (imsi);
348  ConnectTracesEnb (context, imsi, cellId, rnti);
349  }
350 }
351 
352 void
353 RadioBearerStatsConnector::ConnectTracesUe (std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
354 {
355  NS_LOG_FUNCTION (this << context);
356  NS_LOG_LOGIC (this << "expected context should match /NodeList/*/DeviceList/*/LteUeRrc/");
357  std::string basePath = context.substr (0, context.rfind ("/"));
358  if (m_rlcStats)
359  {
360  Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
361  arg->imsi = imsi;
362  arg->cellId = cellId;
363  arg->stats = m_rlcStats;
364  Config::Connect (basePath + "/DataRadioBearerMap/*/LteRlc/TxPDU",
366  Config::Connect (basePath + "/DataRadioBearerMap/*/LteRlc/RxPDU",
368  Config::Connect (basePath + "/Srb1/LteRlc/TxPDU",
370  Config::Connect (basePath + "/Srb1/LteRlc/RxPDU",
372 
373  }
374  if (m_pdcpStats)
375  {
376  Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
377  arg->imsi = imsi;
378  arg->cellId = cellId;
379  arg->stats = m_pdcpStats;
380  Config::Connect (basePath + "/DataRadioBearerMap/*/LtePdcp/RxPDU",
382  Config::Connect (basePath + "/DataRadioBearerMap/*/LtePdcp/TxPDU",
384  Config::Connect (basePath + "/Srb1/LtePdcp/RxPDU",
386  Config::Connect (basePath + "/Srb1/LtePdcp/TxPDU",
388  }
389 }
390 
391 void
392 RadioBearerStatsConnector::ConnectTracesEnb (std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
393 {
394  NS_LOG_FUNCTION (this << context);
395  NS_LOG_LOGIC (this << "expected context should match /NodeList/*/DeviceList/*/LteEnbRrc/");
396  std::ostringstream basePath;
397  basePath << context.substr (0, context.rfind ("/")) << "/UeMap/" << (uint32_t) rnti;
398  if (m_rlcStats)
399  {
400  Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
401  arg->imsi = imsi;
402  arg->cellId = cellId;
403  arg->stats = m_rlcStats;
404  Config::Connect (basePath.str () + "/DataRadioBearerMap/*/LteRlc/RxPDU",
406  Config::Connect (basePath.str () + "/DataRadioBearerMap/*/LteRlc/TxPDU",
408  Config::Connect (basePath.str () + "/Srb0/LteRlc/RxPDU",
410  Config::Connect (basePath.str () + "/Srb0/LteRlc/TxPDU",
412  Config::Connect (basePath.str () + "/Srb1/LteRlc/RxPDU",
414  Config::Connect (basePath.str () + "/Srb1/LteRlc/TxPDU",
416  }
417  if (m_pdcpStats)
418  {
419  Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
420  arg->imsi = imsi;
421  arg->cellId = cellId;
422  arg->stats = m_pdcpStats;
423  Config::Connect (basePath.str () + "/DataRadioBearerMap/*/LtePdcp/TxPDU",
425  Config::Connect (basePath.str () + "/DataRadioBearerMap/*/LtePdcp/RxPDU",
427  Config::Connect (basePath.str () + "/Srb1/LtePdcp/TxPDU",
429  Config::Connect (basePath.str () + "/Srb1/LtePdcp/RxPDU",
431  }
432 }
433 
434 void
435 RadioBearerStatsConnector::DisconnectTracesUe (std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
436 {
437  NS_LOG_FUNCTION (this);
438 }
439 
440 
441 void
442 RadioBearerStatsConnector::DisconnectTracesEnb (std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
443 {
444  NS_LOG_FUNCTION (this);
445 }
446 
447 
448 
449 } // namespace ns3
static void NotifyRandomAccessSuccessfulUe(RadioBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
Function hooked to RandomAccessSuccessful trace source at UE RRC, which is fired upon successful comp...
void ConnectTracesEnbIfFirstTime(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
Connects all trace sources at eNB to RLC and PDCP calculators.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
std::set< uint64_t > m_imsiSeenUe
stores all UEs for which RLC and PDCP traces were connected
Struct used as key in m_ueManagerPathByCellIdRnti map.
Callback< R > MakeBoundCallback(R(*fnPtr)(TX), ARG a1)
Make Callbacks with one bound argument.
Definition: callback.h:1686
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
bool m_connected
true if traces are connected to sinks, initially set to false
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
static void NotifyHandoverEndOkUe(RadioBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
Function hooked to HandoverStart trace source at UE RRC, which is fired upon successful termination o...
void EnablePdcpStats(Ptr< RadioBearerStatsCalculator > pdcpStats)
Enables trace sinks for PDCP layer.
Ptr< RadioBearerStatsCalculator > m_pdcpStats
Calculator for PDCP Statistics.
Ptr< RadioBearerStatsCalculator > stats
statistics calculator
void EnsureConnected()
Connects trace sinks to appropriate trace sources.
void UlRxPduCallback(Ptr< BoundCallbackArgument > arg, std::string path, uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
Callback function for UL RX statistics for both RLC and PDCP.
bool operator<(const EventId &a, const EventId &b)
Definition: event-id.h:153
void DisconnectTracesEnb(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
Disconnects all trace sources at eNB to RLC and PDCP calculators.
This structure is used as interface between trace sources and RadioBearerStatsCalculator.
void ConnectTracesEnb(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
Connects all trace sources at eNB to RLC and PDCP calculators.
void DlRxPduCallback(Ptr< BoundCallbackArgument > arg, std::string path, uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
Callback function for DL RX statistics for both RLC and PDCP.
void EnableRlcStats(Ptr< RadioBearerStatsCalculator > rlcStats)
Enables trace sinks for RLC layer.
std::set< uint64_t > m_imsiSeenEnb
stores all eNBs for which RLC and PDCP traces were connected
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:843
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static void NotifyHandoverStartEnb(RadioBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti, uint16_t targetCellId)
Function hooked to HandoverStart trace source at eNB RRC, which is fired upon start of a handover pro...
static void NotifyNewUeContextEnb(RadioBearerStatsConnector *c, std::string context, uint16_t cellid, uint16_t rnti)
Function hooked to NewUeContext trace source at eNB RRC, which is fired upon creation of a new UE con...
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
void ConnectTracesUe(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
Connects all trace sources at UE to RLC and PDCP calculators.
void DlTxPduCallback(Ptr< BoundCallbackArgument > arg, std::string path, uint16_t rnti, uint8_t lcid, uint32_t packetSize)
Callback function for DL TX statistics for both RLC and PDCP.
std::map< CellIdRnti, std::string > m_ueManagerPathByCellIdRnti
List UE Manager Paths by CellIdRnti.
static void NotifyConnectionSetupUe(RadioBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
Sink connected source of UE Connection Setup trace.
static void NotifyConnectionReconfigurationEnb(RadioBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
Function hooked to ConnectionReconfiguration trace source at eNB RRC, which is fired upon RRC connect...
static void NotifyConnectionReconfigurationUe(RadioBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
Function hooked to ConnectionReconfiguration trace source at UE RRC, which is fired upon RRC connecti...
void UlTxPduCallback(Ptr< BoundCallbackArgument > arg, std::string path, uint16_t rnti, uint8_t lcid, uint32_t packetSize)
Callback function for UL TX statistics for both RLC and PDCP.
void ConnectSrb1TracesUe(std::string ueRrcPath, uint64_t imsi, uint16_t cellId, uint16_t rnti)
Connects Srb1 trace sources at UE to RLC and PDCP calculators.
static void NotifyHandoverEndOkEnb(RadioBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
Function hooked to HandoverEndOk trace source at eNB RRC, which is fired upon successful termination ...
static const uint32_t packetSize
static void NotifyHandoverStartUe(RadioBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti, uint16_t targetCellId)
Function hooked to HandoverStart trace source at UE RRC, which is fired upon start of a handover proc...
void DisconnectTracesUe(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
Disconnects all trace sources at UE to RLC and PDCP calculators.
Ptr< RadioBearerStatsCalculator > m_rlcStats
Calculator for RLC Statistics.
void Disconnect(std::string path, const CallbackBase &cb)
Definition: config.cc:849
This class is very useful when user needs to collect statistics from PDCP and RLC.
void ConnectTracesUeIfFirstTime(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
Connects all trace sources at UE to RLC and PDCP calculators.
A template-based reference counting class.
void StoreUeManagerPath(std::string ueManagerPath, uint16_t cellId, uint16_t rnti)
Creates UE Manager path and stores it in m_ueManagerPathByCellIdRnti.
void ConnectSrb0Traces(std::string ueRrcPath, uint64_t imsi, uint16_t cellId, uint16_t rnti)
Connects Srb0 trace sources at UE and eNB to RLC and PDCP calculators, and Srb1 trace sources at eNB ...