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
26namespace ns3 {
27
28NS_LOG_COMPONENT_DEFINE ("RadioBearerStatsConnector");
29
33bool
35{
36 return ( (a.cellId < b.cellId) || ( (a.cellId == b.cellId) && (a.rnti < b.rnti) ) );
37}
38
45struct BoundCallbackArgument : public SimpleRefCount<BoundCallbackArgument>
46{
47public:
49 uint64_t imsi;
50 uint16_t cellId;
51};
52
61void
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
78void
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
94void
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
111void
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
125void
127{
128 m_rlcStats = rlcStats;
130}
131
132void
134{
135 m_pdcpStats = pdcpStats;
137}
138
139void
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
161void
162RadioBearerStatsConnector::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
177void
178RadioBearerStatsConnector::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
184void
185RadioBearerStatsConnector::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
191void
192RadioBearerStatsConnector::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
198void
199RadioBearerStatsConnector::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
205void
206RadioBearerStatsConnector::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
212void
213RadioBearerStatsConnector::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);
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
242void
243RadioBearerStatsConnector::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);
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
287void
288RadioBearerStatsConnector::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
323void
324RadioBearerStatsConnector::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
359void
360RadioBearerStatsConnector::DisconnectTracesEnb (std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
361{
362 NS_LOG_FUNCTION (this);
372}
373
374void
375RadioBearerStatsConnector::DisconnectTracesUe (std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
376{
377 NS_LOG_FUNCTION (this);
387}
388
389} // namespace ns3
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
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:67
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:920
bool ConnectFailSafe(std::string path, const CallbackBase &cb)
Definition: config.cc:929
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#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:265
Callback< R > MakeBoundCallback(R(*fnPtr)(TX), ARG a1)
Make Callbacks with one bound argument.
Definition: callback.h:1709
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:176
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
Pcket size generated at the AP.