A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
radio-bearer-stats-connector.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2018 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors:
7 * Nicola Baldo <nbaldo@cttc.es>
8 * Manuel Requena <manuel.requena@cttc.es>
9 */
10
12
14
15#include "ns3/log.h"
16
17namespace ns3
18{
19
20NS_LOG_COMPONENT_DEFINE("RadioBearerStatsConnector");
21
22/**
23 * Less than operator for CellIdRnti, because it is used as key in map
24 */
25bool
28{
29 return ((a.cellId < b.cellId) || ((a.cellId == b.cellId) && (a.rnti < b.rnti)));
30}
31
32/**
33 * This structure is used as interface between trace
34 * sources and RadioBearerStatsCalculator. It stores
35 * and provides calculators with cellId and IMSI,
36 * because most trace sources do not provide it.
37 */
38struct BoundCallbackArgument : public SimpleRefCount<BoundCallbackArgument>
39{
40 public:
41 Ptr<RadioBearerStatsCalculator> stats; //!< statistics calculator
42 uint64_t imsi; //!< imsi
43 uint16_t cellId; //!< cellId
44};
45
46/**
47 * Callback function for DL TX statistics for both RLC and PDCP
48 * @param arg
49 * @param path
50 * @param rnti
51 * @param lcid
52 * @param packetSize
53 */
54void
56 std::string path,
57 uint16_t rnti,
58 uint8_t lcid,
60{
61 NS_LOG_FUNCTION(path << rnti << (uint16_t)lcid << packetSize);
62 arg->stats->DlTxPdu(arg->cellId, arg->imsi, rnti, lcid, packetSize);
63}
64
65/**
66 * Callback function for DL RX statistics for both RLC and PDCP
67 * @param arg
68 * @param path
69 * @param rnti
70 * @param lcid
71 * @param packetSize
72 * @param delay
73 */
74void
76 std::string path,
77 uint16_t rnti,
78 uint8_t lcid,
80 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
86/**
87 * Callback function for UL TX statistics for both RLC and PDCP
88 * @param arg
89 * @param path
90 * @param rnti
91 * @param lcid
92 * @param packetSize
93 */
94void
96 std::string path,
97 uint16_t rnti,
98 uint8_t lcid,
100{
101 NS_LOG_FUNCTION(path << rnti << (uint16_t)lcid << packetSize);
102 arg->stats->UlTxPdu(arg->cellId, arg->imsi, rnti, lcid, packetSize);
103}
104
105/**
106 * Callback function for UL RX statistics for both RLC and PDCP
107 * @param arg
108 * @param path
109 * @param rnti
110 * @param lcid
111 * @param packetSize
112 * @param delay
113 */
114void
116 std::string path,
117 uint16_t rnti,
118 uint8_t lcid,
120 uint64_t delay)
121{
122 NS_LOG_FUNCTION(path << rnti << (uint16_t)lcid << packetSize << delay);
123 arg->stats->UlRxPdu(arg->cellId, arg->imsi, rnti, lcid, packetSize, delay);
124}
125
127 : m_connected(false)
128{
129}
130
131void
137
138void
144
145void
147{
148 NS_LOG_FUNCTION(this);
149 if (!m_connected)
150 {
151 Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/NewUeContext",
153
155 "/NodeList/*/DeviceList/*/LteUeRrc/RandomAccessSuccessful",
157
158 Config::Connect("/NodeList/*/DeviceList/*/LteUeRrc/Srb1Created",
160
161 Config::Connect("/NodeList/*/DeviceList/*/LteUeRrc/DrbCreated",
163
164 m_connected = true;
165 }
166}
167
168void
169RadioBearerStatsConnector::StoreUeManagerPath(std::string context, uint16_t cellId, uint16_t rnti)
170{
171 NS_LOG_FUNCTION(this << context << cellId << rnti);
172 std::string ueManagerPath;
173 ueManagerPath = context.substr(0, context.rfind('/')) + "/UeMap/" + std::to_string(rnti);
174 NS_LOG_DEBUG("ueManagerPath = " << ueManagerPath);
175 CellIdRnti key;
176 key.cellId = cellId;
177 key.rnti = rnti;
178 m_ueManagerPathByCellIdRnti[key] = ueManagerPath;
179
180 Config::Connect(ueManagerPath + "/DrbCreated",
182}
183
184void
186 std::string context,
187 uint16_t cellId,
188 uint16_t rnti)
189{
190 NS_LOG_FUNCTION(c << context << cellId << rnti);
191 c->StoreUeManagerPath(context, cellId, rnti);
192}
193
194void
196 std::string context,
197 uint64_t imsi,
198 uint16_t cellId,
199 uint16_t rnti)
200{
201 NS_LOG_FUNCTION(c << context << imsi << cellId << rnti);
202 c->ConnectTracesSrb0(context, imsi, cellId, rnti);
203}
204
205void
207 std::string context,
208 uint64_t imsi,
209 uint16_t cellId,
210 uint16_t rnti,
211 uint8_t lcid)
212{
213 NS_LOG_FUNCTION(c << context << imsi << cellId << rnti << (uint16_t)lcid);
214 c->ConnectTracesDrbEnb(context, imsi, cellId, rnti, lcid);
215}
216
217void
219 std::string context,
220 uint64_t imsi,
221 uint16_t cellId,
222 uint16_t rnti)
223{
224 NS_LOG_FUNCTION(c << context << imsi << cellId << rnti);
225 c->ConnectTracesSrb1(context, imsi, cellId, rnti);
226}
227
228void
230 std::string context,
231 uint64_t imsi,
232 uint16_t cellId,
233 uint16_t rnti,
234 uint8_t lcid)
235{
236 NS_LOG_FUNCTION(c << context << imsi << cellId << rnti << (uint16_t)lcid);
237 c->ConnectTracesDrbUe(context, imsi, cellId, rnti, lcid);
238}
239
240void
242 uint64_t imsi,
243 uint16_t cellId,
244 uint16_t rnti)
245{
246 NS_LOG_FUNCTION(this << context << imsi << cellId << rnti);
247 std::string ueRrcPath = context.substr(0, context.rfind('/'));
248 NS_LOG_LOGIC("ueRrcPath = " << ueRrcPath);
249 CellIdRnti key;
250 key.cellId = cellId;
251 key.rnti = rnti;
252 auto it = m_ueManagerPathByCellIdRnti.find(key);
254 std::string ueManagerPath = it->second;
255 NS_LOG_LOGIC("ueManagerPath = " << ueManagerPath);
256 if (m_rlcStats)
257 {
259 arg->imsi = imsi;
260 arg->cellId = cellId;
261 arg->stats = m_rlcStats;
262 Config::Connect(ueRrcPath + "/Srb0/LteRlc/TxPDU", MakeBoundCallback(&UlTxPduCallback, arg));
263 Config::Connect(ueRrcPath + "/Srb0/LteRlc/RxPDU", MakeBoundCallback(&DlRxPduCallback, arg));
264 Config::Connect(ueManagerPath + "/Srb0/LteRlc/TxPDU",
266 Config::Connect(ueManagerPath + "/Srb0/LteRlc/RxPDU",
268 }
269}
270
271void
273 uint64_t imsi,
274 uint16_t cellId,
275 uint16_t rnti)
276{
277 NS_LOG_FUNCTION(this << context << imsi << cellId << rnti);
278 std::string ueRrcPath = context.substr(0, context.rfind('/'));
279 NS_LOG_LOGIC("ueRrcPath = " << ueRrcPath);
280 CellIdRnti key;
281 key.cellId = cellId;
282 key.rnti = rnti;
283 auto it = m_ueManagerPathByCellIdRnti.find(key);
285 std::string ueManagerPath = it->second;
286 NS_LOG_LOGIC("ueManagerPath = " << ueManagerPath);
287 if (m_rlcStats)
288 {
290 arg->imsi = imsi;
291 arg->cellId = cellId;
292 arg->stats = m_rlcStats;
293 Config::Connect(ueRrcPath + "/Srb1/LteRlc/TxPDU", MakeBoundCallback(&UlTxPduCallback, arg));
294 Config::Connect(ueRrcPath + "/Srb1/LteRlc/RxPDU", MakeBoundCallback(&DlRxPduCallback, arg));
295 Config::Connect(ueManagerPath + "/Srb1/LteRlc/TxPDU",
297 Config::Connect(ueManagerPath + "/Srb1/LteRlc/RxPDU",
299 }
300 if (m_pdcpStats)
301 {
303 arg->imsi = imsi;
304 arg->cellId = cellId;
305 arg->stats = m_pdcpStats;
306 Config::Connect(ueRrcPath + "/Srb1/LtePdcp/TxPDU",
308 Config::Connect(ueRrcPath + "/Srb1/LtePdcp/RxPDU",
310 Config::Connect(ueManagerPath + "/Srb1/LtePdcp/TxPDU",
312 Config::Connect(ueManagerPath + "/Srb1/LtePdcp/RxPDU",
314 }
315}
316
317void
319 uint64_t imsi,
320 uint16_t cellId,
321 uint16_t rnti,
322 uint8_t lcid)
323{
324 NS_LOG_FUNCTION(this << context << imsi << cellId << rnti << (uint16_t)lcid);
325 NS_LOG_LOGIC("expected context should match /NodeList/*/DeviceList/*/LteEnbRrc/");
326 std::string basePath;
327 basePath =
328 context.substr(0, context.rfind('/')) + "/DataRadioBearerMap/" + std::to_string(lcid - 2);
329 NS_LOG_LOGIC("basePath = " << basePath);
330 if (m_rlcStats)
331 {
333 arg->imsi = imsi;
334 arg->cellId = cellId;
335 arg->stats = m_rlcStats;
336 Config::Connect(basePath + "/LteRlc/TxPDU", MakeBoundCallback(&DlTxPduCallback, arg));
337 Config::Connect(basePath + "/LteRlc/RxPDU", MakeBoundCallback(&UlRxPduCallback, arg));
338 }
339 if (m_pdcpStats)
340 {
342 arg->imsi = imsi;
343 arg->cellId = cellId;
344 arg->stats = m_pdcpStats;
345 bool foundTxPdcp = Config::ConnectFailSafe(basePath + "/LtePdcp/TxPDU",
347 bool foundRxPdcp = Config::ConnectFailSafe(basePath + "/LtePdcp/RxPDU",
349 if (!foundTxPdcp && !foundRxPdcp)
350 {
351 NS_LOG_WARN("Unable to connect PDCP traces. This may happen if RlcSm is used");
352 }
353 }
354}
355
356void
358 uint64_t imsi,
359 uint16_t cellId,
360 uint16_t rnti,
361 uint8_t lcid)
362{
363 NS_LOG_FUNCTION(this << context << imsi << cellId << rnti << (uint16_t)lcid);
364 NS_LOG_LOGIC("expected context should match /NodeList/*/DeviceList/*/LteUeRrc/");
365 std::string basePath;
366 basePath =
367 context.substr(0, context.rfind('/')) + "/DataRadioBearerMap/" + std::to_string(lcid);
368 NS_LOG_LOGIC("basePath = " << basePath);
369 if (m_rlcStats)
370 {
372 arg->imsi = imsi;
373 arg->cellId = cellId;
374 arg->stats = m_rlcStats;
375 Config::Connect(basePath + "/LteRlc/TxPDU", MakeBoundCallback(&UlTxPduCallback, arg));
376 Config::Connect(basePath + "/LteRlc/RxPDU", MakeBoundCallback(&DlRxPduCallback, arg));
377 }
378 if (m_pdcpStats)
379 {
381 arg->imsi = imsi;
382 arg->cellId = cellId;
383 arg->stats = m_pdcpStats;
384 bool foundTxPdcp = Config::ConnectFailSafe(basePath + "/LtePdcp/TxPDU",
386 bool foundRxPdcp = Config::ConnectFailSafe(basePath + "/LtePdcp/RxPDU",
388 if (!foundTxPdcp && !foundRxPdcp)
389 {
390 NS_LOG_WARN("Unable to connect PDCP traces. This may happen if RlcSm is used");
391 }
392 }
393}
394
395void
397 uint64_t imsi,
398 uint16_t cellId,
399 uint16_t rnti)
400{
401 NS_LOG_FUNCTION(this);
402 /**
403 * This method is left empty to be extended in future.
404 * Note: Be aware, that each of the connect method uses
405 * its own BoundCallbackArgument struct as an argument
406 * of the callback. And, if the code to disconnect the
407 * traces would also use their own struct, the traces
408 * will not disconnect, since it changes the parameter
409 * of the callback.
410 */
411}
412
413void
415 uint64_t imsi,
416 uint16_t cellId,
417 uint16_t rnti)
418{
419 NS_LOG_FUNCTION(this);
420 /**
421 * This method is left empty to be extended in future.
422 * Note: Be aware, that each of the connect method uses
423 * its own BoundCallbackArgument struct as an argument
424 * of the callback. And, if the code to disconnect the
425 * traces would also use their own struct, the traces
426 * will not disconnect, since it changes the parameter
427 * of the callback.
428 */
429}
430
431} // namespace ns3
Smart pointer class similar to boost::intrusive_ptr.
This class is very useful when user needs to collect statistics from PDCP and RLC.
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.
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.
Ptr< RadioBearerStatsCalculator > m_rlcStats
Calculator for RLC Statistics.
void EnablePdcpStats(Ptr< RadioBearerStatsCalculator > pdcpStats)
Enables trace sinks for PDCP layer.
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 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.
void StoreUeManagerPath(std::string ueManagerPath, uint16_t cellId, uint16_t rnti)
Creates UE Manager path and stores it in m_ueManagerPathByCellIdRnti.
void EnableRlcStats(Ptr< RadioBearerStatsCalculator > rlcStats)
Enables trace sinks for RLC layer.
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 DisconnectTracesEnb(std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
Disconnects all trace sources at eNB to RLC and PDCP calculators.
Ptr< RadioBearerStatsCalculator > m_pdcpStats
Calculator for PDCP Statistics.
std::map< CellIdRnti, std::string > m_ueManagerPathByCellIdRnti
List UE Manager Paths by CellIdRnti.
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 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,...
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.
void EnsureConnected()
Connects trace sinks to appropriate trace sources.
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.
bool m_connected
true if traces are connected to sinks, initially set to false
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,...
A template-based reference counting class.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
void Connect(std::string path, const CallbackBase &cb)
Definition config.cc:967
bool ConnectFailSafe(std::string path, const CallbackBase &cb)
Definition config.cc:977
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition log.h:250
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs &&... bargs)
Make Callbacks with varying number of bound arguments.
Definition callback.h:745
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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:168
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.
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 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.
This structure is used as interface between trace sources and RadioBearerStatsCalculator.
Ptr< RadioBearerStatsCalculator > stats
statistics calculator
Struct used as key in m_ueManagerPathByCellIdRnti map.
static const uint32_t packetSize
Packet size generated at the AP.