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 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Authors:
18 * Nicola Baldo <nbaldo@cttc.es>
19 * Manuel Requena <manuel.requena@cttc.es>
20 */
21
23
25
26#include "ns3/log.h"
27
28namespace ns3
29{
30
31NS_LOG_COMPONENT_DEFINE("RadioBearerStatsConnector");
32
33/**
34 * Less than operator for CellIdRnti, because it is used as key in map
35 */
36bool
39{
40 return ((a.cellId < b.cellId) || ((a.cellId == b.cellId) && (a.rnti < b.rnti)));
41}
42
43/**
44 * This structure is used as interface between trace
45 * sources and RadioBearerStatsCalculator. It stores
46 * and provides calculators with cellId and IMSI,
47 * because most trace sources do not provide it.
48 */
49struct BoundCallbackArgument : public SimpleRefCount<BoundCallbackArgument>
50{
51 public:
52 Ptr<RadioBearerStatsCalculator> stats; //!< statistics calculator
53 uint64_t imsi; //!< imsi
54 uint16_t cellId; //!< cellId
55};
56
57/**
58 * Callback function for DL TX statistics for both RLC and PDCP
59 * \param arg
60 * \param path
61 * \param rnti
62 * \param lcid
63 * \param packetSize
64 */
65void
67 std::string path,
68 uint16_t rnti,
69 uint8_t lcid,
71{
72 NS_LOG_FUNCTION(path << rnti << (uint16_t)lcid << packetSize);
73 arg->stats->DlTxPdu(arg->cellId, arg->imsi, rnti, lcid, packetSize);
74}
75
76/**
77 * Callback function for DL RX statistics for both RLC and PDCP
78 * \param arg
79 * \param path
80 * \param rnti
81 * \param lcid
82 * \param packetSize
83 * \param delay
84 */
85void
87 std::string path,
88 uint16_t rnti,
89 uint8_t lcid,
91 uint64_t delay)
92{
93 NS_LOG_FUNCTION(path << rnti << (uint16_t)lcid << packetSize << delay);
94 arg->stats->DlRxPdu(arg->cellId, arg->imsi, rnti, lcid, packetSize, delay);
95}
96
97/**
98 * Callback function for UL TX statistics for both RLC and PDCP
99 * \param arg
100 * \param path
101 * \param rnti
102 * \param lcid
103 * \param packetSize
104 */
105void
107 std::string path,
108 uint16_t rnti,
109 uint8_t lcid,
111{
112 NS_LOG_FUNCTION(path << rnti << (uint16_t)lcid << packetSize);
113 arg->stats->UlTxPdu(arg->cellId, arg->imsi, rnti, lcid, packetSize);
114}
115
116/**
117 * Callback function for UL RX statistics for both RLC and PDCP
118 * \param arg
119 * \param path
120 * \param rnti
121 * \param lcid
122 * \param packetSize
123 * \param delay
124 */
125void
127 std::string path,
128 uint16_t rnti,
129 uint8_t lcid,
131 uint64_t delay)
132{
133 NS_LOG_FUNCTION(path << rnti << (uint16_t)lcid << packetSize << delay);
134 arg->stats->UlRxPdu(arg->cellId, arg->imsi, rnti, lcid, packetSize, delay);
135}
136
138 : m_connected(false)
139{
140}
141
142void
144{
145 m_rlcStats = rlcStats;
147}
148
149void
151{
152 m_pdcpStats = pdcpStats;
154}
155
156void
158{
159 NS_LOG_FUNCTION(this);
160 if (!m_connected)
161 {
162 Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/NewUeContext",
164
166 "/NodeList/*/DeviceList/*/LteUeRrc/RandomAccessSuccessful",
168
169 Config::Connect("/NodeList/*/DeviceList/*/LteUeRrc/Srb1Created",
171
172 Config::Connect("/NodeList/*/DeviceList/*/LteUeRrc/DrbCreated",
174
175 m_connected = true;
176 }
177}
178
179void
180RadioBearerStatsConnector::StoreUeManagerPath(std::string context, uint16_t cellId, uint16_t rnti)
181{
182 NS_LOG_FUNCTION(this << context << cellId << rnti);
183 std::string ueManagerPath;
184 ueManagerPath = context.substr(0, context.rfind('/')) + "/UeMap/" + std::to_string(rnti);
185 NS_LOG_DEBUG("ueManagerPath = " << ueManagerPath);
186 CellIdRnti key;
187 key.cellId = cellId;
188 key.rnti = rnti;
189 m_ueManagerPathByCellIdRnti[key] = ueManagerPath;
190
191 Config::Connect(ueManagerPath + "/DrbCreated",
193}
194
195void
197 std::string context,
198 uint16_t cellId,
199 uint16_t rnti)
200{
201 NS_LOG_FUNCTION(c << context << cellId << rnti);
202 c->StoreUeManagerPath(context, cellId, rnti);
203}
204
205void
207 std::string context,
208 uint64_t imsi,
209 uint16_t cellId,
210 uint16_t rnti)
211{
212 NS_LOG_FUNCTION(c << context << imsi << cellId << rnti);
213 c->ConnectTracesSrb0(context, imsi, cellId, rnti);
214}
215
216void
218 std::string context,
219 uint64_t imsi,
220 uint16_t cellId,
221 uint16_t rnti,
222 uint8_t lcid)
223{
224 NS_LOG_FUNCTION(c << context << imsi << cellId << rnti << (uint16_t)lcid);
225 c->ConnectTracesDrbEnb(context, imsi, cellId, rnti, lcid);
226}
227
228void
230 std::string context,
231 uint64_t imsi,
232 uint16_t cellId,
233 uint16_t rnti)
234{
235 NS_LOG_FUNCTION(c << context << imsi << cellId << rnti);
236 c->ConnectTracesSrb1(context, imsi, cellId, rnti);
237}
238
239void
241 std::string context,
242 uint64_t imsi,
243 uint16_t cellId,
244 uint16_t rnti,
245 uint8_t lcid)
246{
247 NS_LOG_FUNCTION(c << context << imsi << cellId << rnti << (uint16_t)lcid);
248 c->ConnectTracesDrbUe(context, imsi, cellId, rnti, lcid);
249}
250
251void
253 uint64_t imsi,
254 uint16_t cellId,
255 uint16_t rnti)
256{
257 NS_LOG_FUNCTION(this << context << imsi << cellId << rnti);
258 std::string ueRrcPath = context.substr(0, context.rfind('/'));
259 NS_LOG_LOGIC("ueRrcPath = " << ueRrcPath);
260 CellIdRnti key;
261 key.cellId = cellId;
262 key.rnti = rnti;
263 auto it = m_ueManagerPathByCellIdRnti.find(key);
265 std::string ueManagerPath = it->second;
266 NS_LOG_LOGIC("ueManagerPath = " << ueManagerPath);
267 if (m_rlcStats)
268 {
269 Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument>();
270 arg->imsi = imsi;
271 arg->cellId = cellId;
272 arg->stats = m_rlcStats;
273 Config::Connect(ueRrcPath + "/Srb0/LteRlc/TxPDU", MakeBoundCallback(&UlTxPduCallback, arg));
274 Config::Connect(ueRrcPath + "/Srb0/LteRlc/RxPDU", MakeBoundCallback(&DlRxPduCallback, arg));
275 Config::Connect(ueManagerPath + "/Srb0/LteRlc/TxPDU",
277 Config::Connect(ueManagerPath + "/Srb0/LteRlc/RxPDU",
279 }
280}
281
282void
284 uint64_t imsi,
285 uint16_t cellId,
286 uint16_t rnti)
287{
288 NS_LOG_FUNCTION(this << context << imsi << cellId << rnti);
289 std::string ueRrcPath = context.substr(0, context.rfind('/'));
290 NS_LOG_LOGIC("ueRrcPath = " << ueRrcPath);
291 CellIdRnti key;
292 key.cellId = cellId;
293 key.rnti = rnti;
294 auto it = m_ueManagerPathByCellIdRnti.find(key);
296 std::string ueManagerPath = it->second;
297 NS_LOG_LOGIC("ueManagerPath = " << ueManagerPath);
298 if (m_rlcStats)
299 {
300 Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument>();
301 arg->imsi = imsi;
302 arg->cellId = cellId;
303 arg->stats = m_rlcStats;
304 Config::Connect(ueRrcPath + "/Srb1/LteRlc/TxPDU", MakeBoundCallback(&UlTxPduCallback, arg));
305 Config::Connect(ueRrcPath + "/Srb1/LteRlc/RxPDU", MakeBoundCallback(&DlRxPduCallback, arg));
306 Config::Connect(ueManagerPath + "/Srb1/LteRlc/TxPDU",
308 Config::Connect(ueManagerPath + "/Srb1/LteRlc/RxPDU",
310 }
311 if (m_pdcpStats)
312 {
313 Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument>();
314 arg->imsi = imsi;
315 arg->cellId = cellId;
316 arg->stats = m_pdcpStats;
317 Config::Connect(ueRrcPath + "/Srb1/LtePdcp/TxPDU",
319 Config::Connect(ueRrcPath + "/Srb1/LtePdcp/RxPDU",
321 Config::Connect(ueManagerPath + "/Srb1/LtePdcp/TxPDU",
323 Config::Connect(ueManagerPath + "/Srb1/LtePdcp/RxPDU",
325 }
326}
327
328void
330 uint64_t imsi,
331 uint16_t cellId,
332 uint16_t rnti,
333 uint8_t lcid)
334{
335 NS_LOG_FUNCTION(this << context << imsi << cellId << rnti << (uint16_t)lcid);
336 NS_LOG_LOGIC("expected context should match /NodeList/*/DeviceList/*/LteEnbRrc/");
337 std::string basePath;
338 basePath =
339 context.substr(0, context.rfind('/')) + "/DataRadioBearerMap/" + std::to_string(lcid - 2);
340 NS_LOG_LOGIC("basePath = " << basePath);
341 if (m_rlcStats)
342 {
343 Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument>();
344 arg->imsi = imsi;
345 arg->cellId = cellId;
346 arg->stats = m_rlcStats;
347 Config::Connect(basePath + "/LteRlc/TxPDU", MakeBoundCallback(&DlTxPduCallback, arg));
348 Config::Connect(basePath + "/LteRlc/RxPDU", MakeBoundCallback(&UlRxPduCallback, arg));
349 }
350 if (m_pdcpStats)
351 {
352 Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument>();
353 arg->imsi = imsi;
354 arg->cellId = cellId;
355 arg->stats = m_pdcpStats;
356 bool foundTxPdcp = Config::ConnectFailSafe(basePath + "/LtePdcp/TxPDU",
358 bool foundRxPdcp = Config::ConnectFailSafe(basePath + "/LtePdcp/RxPDU",
360 if (!foundTxPdcp && !foundRxPdcp)
361 {
362 NS_LOG_WARN("Unable to connect PDCP traces. This may happen if RlcSm is used");
363 }
364 }
365}
366
367void
369 uint64_t imsi,
370 uint16_t cellId,
371 uint16_t rnti,
372 uint8_t lcid)
373{
374 NS_LOG_FUNCTION(this << context << imsi << cellId << rnti << (uint16_t)lcid);
375 NS_LOG_LOGIC("expected context should match /NodeList/*/DeviceList/*/LteUeRrc/");
376 std::string basePath;
377 basePath =
378 context.substr(0, context.rfind('/')) + "/DataRadioBearerMap/" + std::to_string(lcid);
379 NS_LOG_LOGIC("basePath = " << basePath);
380 if (m_rlcStats)
381 {
382 Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument>();
383 arg->imsi = imsi;
384 arg->cellId = cellId;
385 arg->stats = m_rlcStats;
386 Config::Connect(basePath + "/LteRlc/TxPDU", MakeBoundCallback(&UlTxPduCallback, arg));
387 Config::Connect(basePath + "/LteRlc/RxPDU", MakeBoundCallback(&DlRxPduCallback, arg));
388 }
389 if (m_pdcpStats)
390 {
391 Ptr<BoundCallbackArgument> arg = Create<BoundCallbackArgument>();
392 arg->imsi = imsi;
393 arg->cellId = cellId;
394 arg->stats = m_pdcpStats;
395 bool foundTxPdcp = Config::ConnectFailSafe(basePath + "/LtePdcp/TxPDU",
397 bool foundRxPdcp = Config::ConnectFailSafe(basePath + "/LtePdcp/RxPDU",
399 if (!foundTxPdcp && !foundRxPdcp)
400 {
401 NS_LOG_WARN("Unable to connect PDCP traces. This may happen if RlcSm is used");
402 }
403 }
404}
405
406void
408 uint64_t imsi,
409 uint16_t cellId,
410 uint16_t rnti)
411{
412 NS_LOG_FUNCTION(this);
413 /**
414 * This method is left empty to be extended in future.
415 * Note: Be aware, that each of the connect method uses
416 * its own BoundCallbackArgument struct as an argument
417 * of the callback. And, if the code to disconnect the
418 * traces would also use their own struct, the traces
419 * will not disconnect, since it changes the parameter
420 * of the callback.
421 */
422}
423
424void
426 uint64_t imsi,
427 uint16_t cellId,
428 uint16_t rnti)
429{
430 NS_LOG_FUNCTION(this);
431 /**
432 * This method is left empty to be extended in future.
433 * Note: Be aware, that each of the connect method uses
434 * its own BoundCallbackArgument struct as an argument
435 * of the callback. And, if the code to disconnect the
436 * traces would also use their own struct, the traces
437 * will not disconnect, since it changes the parameter
438 * of the callback.
439 */
440}
441
442} // namespace ns3
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
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:66
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:978
bool ConnectFailSafe(std::string path, const CallbackBase &cb)
Definition: config.cc:988
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#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:261
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs &&... bargs)
Make Callbacks with varying number of bound arguments.
Definition: callback.h:767
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:170
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.