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-2018 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  * Authors: Nicola Baldo <nbaldo@cttc.es>
19  * Manuel Requena <manuel.requena@cttc.es>
20  */
21 
22 #include "ns3/log.h"
25 
26 namespace ns3 {
27 
28 NS_LOG_COMPONENT_DEFINE ("RadioBearerStatsConnector");
29 
33 bool
35 {
36  return ( (a.cellId < b.cellId) || ( (a.cellId == b.cellId) && (a.rnti < b.rnti) ) );
37 }
38 
45 struct BoundCallbackArgument : public SimpleRefCount<BoundCallbackArgument>
46 {
47 public:
49  uint64_t imsi;
50  uint16_t cellId;
51 };
52 
61 void
63  uint16_t rnti, uint8_t lcid, uint32_t packetSize)
64 {
65  NS_LOG_FUNCTION (path << rnti << (uint16_t)lcid << packetSize);
66  arg->stats->DlTxPdu (arg->cellId, arg->imsi, rnti, lcid, packetSize);
67 }
68 
78 void
80  uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
81 {
82  NS_LOG_FUNCTION (path << rnti << (uint16_t)lcid << packetSize << delay);
83  arg->stats->DlRxPdu (arg->cellId, arg->imsi, rnti, lcid, packetSize, delay);
84 }
85 
94 void
96  uint16_t rnti, uint8_t lcid, uint32_t packetSize)
97 {
98  NS_LOG_FUNCTION (path << rnti << (uint16_t)lcid << packetSize);
99  arg->stats->UlTxPdu (arg->cellId, arg->imsi, rnti, lcid, packetSize);
100 }
101 
111 void
113  uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
114 {
115  NS_LOG_FUNCTION (path << rnti << (uint16_t)lcid << packetSize << delay);
116  arg->stats->UlRxPdu (arg->cellId, arg->imsi, rnti, lcid, packetSize, delay);
117 }
118 
119 
121  : m_connected (false)
122 {
123 }
124 
125 void
127 {
128  m_rlcStats = rlcStats;
129  EnsureConnected ();
130 }
131 
132 void
134 {
135  m_pdcpStats = pdcpStats;
136  EnsureConnected ();
137 }
138 
139 void
141 {
142  NS_LOG_FUNCTION (this);
143  if (!m_connected)
144  {
145  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/NewUeContext",
147 
148  Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/RandomAccessSuccessful",
150 
151  Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/Srb1Created",
153 
154  Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/DrbCreated",
156 
157  m_connected = true;
158  }
159 }
160 
161 void
162 RadioBearerStatsConnector::StoreUeManagerPath (std::string context, uint16_t cellId, uint16_t rnti)
163 {
164  NS_LOG_FUNCTION (this << context << cellId << rnti);
165  std::string ueManagerPath;
166  ueManagerPath = context.substr (0, context.rfind ("/")) + "/UeMap/" + std::to_string (rnti);
167  NS_LOG_DEBUG ("ueManagerPath = " << ueManagerPath);
168  CellIdRnti key;
169  key.cellId = cellId;
170  key.rnti = rnti;
171  m_ueManagerPathByCellIdRnti[key] = ueManagerPath;
172 
173  Config::Connect (ueManagerPath + "/DrbCreated",
175 }
176 
177 void
178 RadioBearerStatsConnector::NotifyNewUeContextEnb (RadioBearerStatsConnector* c, std::string context, uint16_t cellId, uint16_t rnti)
179 {
180  NS_LOG_FUNCTION (c << context << cellId << rnti);
181  c->StoreUeManagerPath (context, cellId, rnti);
182 }
183 
184 void
185 RadioBearerStatsConnector::NotifyRandomAccessSuccessfulUe (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
186 {
187  NS_LOG_FUNCTION (c << context << imsi << cellId << rnti);
188  c->ConnectTracesSrb0 (context, imsi, cellId, rnti);
189 }
190 
191 void
192 RadioBearerStatsConnector::CreatedDrbEnb (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti, uint8_t lcid)
193 {
194  NS_LOG_FUNCTION (c << context << imsi << cellId << rnti << (uint16_t)lcid);
195  c->ConnectTracesDrbEnb (context, imsi, cellId, rnti, lcid);
196 }
197 
198 void
199 RadioBearerStatsConnector::CreatedSrb1Ue (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
200 {
201  NS_LOG_FUNCTION (c << context << imsi << cellId << rnti);
202  c->ConnectTracesSrb1 (context, imsi, cellId, rnti);
203 }
204 
205 void
206 RadioBearerStatsConnector::CreatedDrbUe (RadioBearerStatsConnector* c, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti, uint8_t lcid)
207 {
208  NS_LOG_FUNCTION (c << context << imsi << cellId << rnti << (uint16_t)lcid);
209  c->ConnectTracesDrbUe (context, imsi, cellId, rnti, lcid);
210 }
211 
212 void
213 RadioBearerStatsConnector::ConnectTracesSrb0 (std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
214 {
215  NS_LOG_FUNCTION (this << context << imsi << cellId << rnti);
216  std::string ueRrcPath = context.substr (0, context.rfind ("/"));
217  NS_LOG_LOGIC ("ueRrcPath = " << ueRrcPath);
218  CellIdRnti key;
219  key.cellId = cellId;
220  key.rnti = rnti;
221  std::map<CellIdRnti, std::string>::iterator it = m_ueManagerPathByCellIdRnti.find (key);
222  NS_ASSERT (it != m_ueManagerPathByCellIdRnti.end ());
223  std::string ueManagerPath = it->second;
224  NS_LOG_LOGIC ("ueManagerPath = " << ueManagerPath);
225  if (m_rlcStats)
226  {
227  Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
228  arg->imsi = imsi;
229  arg->cellId = cellId;
230  arg->stats = m_rlcStats;
231  Config::Connect (ueRrcPath + "/Srb0/LteRlc/TxPDU",
233  Config::Connect (ueRrcPath + "/Srb0/LteRlc/RxPDU",
235  Config::Connect (ueManagerPath + "/Srb0/LteRlc/TxPDU",
237  Config::Connect (ueManagerPath + "/Srb0/LteRlc/RxPDU",
239  }
240 }
241 
242 void
243 RadioBearerStatsConnector::ConnectTracesSrb1 (std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
244 {
245  NS_LOG_FUNCTION (this << context << imsi << cellId << rnti);
246  std::string ueRrcPath = context.substr (0, context.rfind ("/"));
247  NS_LOG_LOGIC ("ueRrcPath = " << ueRrcPath);
248  CellIdRnti key;
249  key.cellId = cellId;
250  key.rnti = rnti;
251  std::map<CellIdRnti, std::string>::iterator it = m_ueManagerPathByCellIdRnti.find (key);
252  NS_ASSERT (it != m_ueManagerPathByCellIdRnti.end ());
253  std::string ueManagerPath = it->second;
254  NS_LOG_LOGIC ("ueManagerPath = " << ueManagerPath);
255  if (m_rlcStats)
256  {
257  Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
258  arg->imsi = imsi;
259  arg->cellId = cellId;
260  arg->stats = m_rlcStats;
261  Config::Connect (ueRrcPath + "/Srb1/LteRlc/TxPDU",
263  Config::Connect (ueRrcPath + "/Srb1/LteRlc/RxPDU",
265  Config::Connect (ueManagerPath + "/Srb1/LteRlc/TxPDU",
267  Config::Connect (ueManagerPath + "/Srb1/LteRlc/RxPDU",
269  }
270  if (m_pdcpStats)
271  {
272  Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
273  arg->imsi = imsi;
274  arg->cellId = cellId;
275  arg->stats = m_pdcpStats;
276  Config::Connect (ueRrcPath + "/Srb1/LtePdcp/TxPDU",
278  Config::Connect (ueRrcPath + "/Srb1/LtePdcp/RxPDU",
280  Config::Connect (ueManagerPath + "/Srb1/LtePdcp/TxPDU",
282  Config::Connect (ueManagerPath + "/Srb1/LtePdcp/RxPDU",
284  }
285 }
286 
287 void
288 RadioBearerStatsConnector::ConnectTracesDrbEnb (std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti, uint8_t lcid)
289 {
290  NS_LOG_FUNCTION (this << context << imsi << cellId << rnti << (uint16_t)lcid);
291  NS_LOG_LOGIC ("expected context should match /NodeList/*/DeviceList/*/LteEnbRrc/");
292  std::string basePath;
293  basePath = context.substr (0, context.rfind ("/")) + "/DataRadioBearerMap/" + std::to_string (lcid - 2);
294  NS_LOG_LOGIC ("basePath = " << basePath);
295  if (m_rlcStats)
296  {
297  Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
298  arg->imsi = imsi;
299  arg->cellId = cellId;
300  arg->stats = m_rlcStats;
301  Config::Connect (basePath + "/LteRlc/TxPDU",
303  Config::Connect (basePath + "/LteRlc/RxPDU",
305  }
306  if (m_pdcpStats)
307  {
308  Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
309  arg->imsi = imsi;
310  arg->cellId = cellId;
311  arg->stats = m_pdcpStats;
312  bool foundTxPdcp = Config::ConnectFailSafe (basePath + "/LtePdcp/TxPDU",
314  bool foundRxPdcp = Config::ConnectFailSafe (basePath + "/LtePdcp/RxPDU",
316  if (!foundTxPdcp && !foundRxPdcp)
317  {
318  NS_LOG_WARN ("Unable to connect PDCP traces. This may happen if RlcSm is used");
319  }
320  }
321 }
322 
323 void
324 RadioBearerStatsConnector::ConnectTracesDrbUe (std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti, uint8_t lcid)
325 {
326  NS_LOG_FUNCTION (this << context << imsi << cellId << rnti << (uint16_t)lcid);
327  NS_LOG_LOGIC ("expected context should match /NodeList/*/DeviceList/*/LteUeRrc/");
328  std::string basePath;
329  basePath = context.substr (0, context.rfind ("/")) + "/DataRadioBearerMap/" + std::to_string (lcid);
330  NS_LOG_LOGIC ("basePath = " << basePath);
331  if (m_rlcStats)
332  {
333  Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
334  arg->imsi = imsi;
335  arg->cellId = cellId;
336  arg->stats = m_rlcStats;
337  Config::Connect (basePath + "/LteRlc/TxPDU",
339  Config::Connect (basePath + "/LteRlc/RxPDU",
341  }
342  if (m_pdcpStats)
343  {
344  Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument> ();
345  arg->imsi = imsi;
346  arg->cellId = cellId;
347  arg->stats = m_pdcpStats;
348  bool foundTxPdcp = Config::ConnectFailSafe (basePath + "/LtePdcp/TxPDU",
350  bool foundRxPdcp = Config::ConnectFailSafe (basePath + "/LtePdcp/RxPDU",
352  if (!foundTxPdcp && !foundRxPdcp)
353  {
354  NS_LOG_WARN ("Unable to connect PDCP traces. This may happen if RlcSm is used");
355  }
356  }
357 }
358 
359 void
360 RadioBearerStatsConnector::DisconnectTracesEnb (std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
361 {
362  NS_LOG_FUNCTION (this);
372 }
373 
374 void
375 RadioBearerStatsConnector::DisconnectTracesUe (std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
376 {
377  NS_LOG_FUNCTION (this);
387 }
388 
389 } // 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...
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 "...
void ConnectTracesSrb0(std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
Connects SRB0 trace sources at UE and eNB to RLC and PDCP calculators.
Struct used as key in m_ueManagerPathByCellIdRnti map.
static void CreatedDrbEnb(RadioBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti, uint8_t lcid)
Function hooked to DrbCreated trace source at UE manager in eNB RRC, which is fired when DRB is creat...
static const uint32_t packetSize
Callback< R > MakeBoundCallback(R(*fnPtr)(TX), ARG a1)
Make Callbacks with one bound argument.
Definition: callback.h:1703
#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:205
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.
void ConnectTracesDrbUe(std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti, uint8_t lcid)
Connects DRB trace sources at UE to RLC and PDCP calculators.
void ConnectTracesDrbEnb(std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti, uint8_t lcid)
Connects DRB trace sources at eNB to RLC and PDCP calculators.
bool operator<(const EventId &a, const EventId &b)
Definition: event-id.h:160
static void CreatedSrb1Ue(RadioBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
Function hooked to Srb1Created trace source at UE RRC, which is fired when SRB1 is created...
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 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.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:920
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool ConnectFailSafe(std::string path, const CallbackBase &cb)
This function will attempt to find all trace sources which match the input path and will then connect...
Definition: config.cc:929
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...
void ConnectTracesSrb1(std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
Connects SRB1 trace sources at UE and eNB to RLC and PDCP calculators.
static void CreatedDrbUe(RadioBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti, uint8_t lcid)
Function hooked to DrbCreated trace source at UE RRC, which is fired when DRB is created, i.e.
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.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
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 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.
This class is very useful when user needs to collect statistics from PDCP and RLC.
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.