5G-LENA nr-v3.1-14-g738b08bc
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
nr-bearer-stats-connector.cc
1// Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
2// Copyright (c) 2015, NYU WIRELESS, Tandon School of Engineering, New York University
3//
4// SPDX-License-Identifier: GPL-2.0-only
5
6#include "nr-bearer-stats-connector.h"
7
8#include "nr-bearer-stats-calculator.h"
9
10#include <ns3/config.h>
11#include <ns3/log.h>
12
13namespace ns3
14{
15
16NS_LOG_COMPONENT_DEFINE("NrBearerStatsConnector");
17
21bool
22operator<(const NrBearerStatsConnector::CellIdRnti& a, const NrBearerStatsConnector::CellIdRnti& b)
23{
24 return ((a.cellId < b.cellId) || ((a.cellId == b.cellId) && (a.rnti < b.rnti)));
25}
26
33struct NrBoundCallbackArgument : public SimpleRefCount<NrBoundCallbackArgument>
34{
35 public:
36 Ptr<NrBearerStatsBase> stats;
37 uint64_t imsi;
38 uint16_t cellId;
39};
40
49void
50DlTxPduCallback(Ptr<NrBoundCallbackArgument> arg,
51 std::string path,
52 uint16_t rnti,
53 uint8_t lcid,
54 uint32_t packetSize)
55{
56 NS_LOG_FUNCTION(path << rnti << (uint16_t)lcid << packetSize);
57 arg->stats->DlTxPdu(arg->cellId, arg->imsi, rnti, lcid, packetSize);
58}
59
69void
70DlRxPduCallback(Ptr<NrBoundCallbackArgument> arg,
71 std::string path,
72 uint16_t rnti,
73 uint8_t lcid,
74 uint32_t packetSize,
75 uint64_t delay)
76{
77 NS_LOG_FUNCTION(path << rnti << (uint16_t)lcid << packetSize << delay);
78 arg->stats->DlRxPdu(arg->cellId, arg->imsi, rnti, lcid, packetSize, delay);
79}
80
89void
90UlTxPduCallback(Ptr<NrBoundCallbackArgument> arg,
91 std::string path,
92 uint16_t rnti,
93 uint8_t lcid,
94 uint32_t packetSize)
95{
96 NS_LOG_FUNCTION(path << rnti << (uint16_t)lcid << packetSize);
97
98 arg->stats->UlTxPdu(arg->cellId, arg->imsi, rnti, lcid, packetSize);
99}
100
110void
111UlRxPduCallback(Ptr<NrBoundCallbackArgument> arg,
112 std::string path,
113 uint16_t rnti,
114 uint8_t lcid,
115 uint32_t packetSize,
116 uint64_t delay)
117{
118 NS_LOG_FUNCTION(path << rnti << (uint16_t)lcid << packetSize << delay);
119
120 arg->stats->UlRxPdu(arg->cellId, arg->imsi, rnti, lcid, packetSize, delay);
121}
122
124 : m_connected(false)
125{
126}
127
128void
129NrBearerStatsConnector::EnableRlcStats(Ptr<NrBearerStatsBase> rlcStats)
130{
131 m_rlcStats = rlcStats;
133}
134
135void
136NrBearerStatsConnector::EnablePdcpStats(Ptr<NrBearerStatsBase> pdcpStats)
137{
138 m_pdcpStats = pdcpStats;
140}
141
142void
144{
145 NS_LOG_FUNCTION(this);
146 if (!m_connected)
147 {
148 Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/NewUeContext",
149 MakeBoundCallback(&NrBearerStatsConnector::NotifyNewUeContextEnb, this));
150 Config::Connect(
151 "/NodeList/*/DeviceList/*/LteUeRrc/RandomAccessSuccessful",
153 Config::Connect(
154 "/NodeList/*/DeviceList/*/LteEnbRrc/ConnectionReconfiguration",
156 Config::Connect(
157 "/NodeList/*/DeviceList/*/LteUeRrc/ConnectionReconfiguration",
159 Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverStart",
160 MakeBoundCallback(&NrBearerStatsConnector::NotifyHandoverStartEnb, this));
161 Config::Connect("/NodeList/*/DeviceList/*/LteUeRrc/HandoverStart",
162 MakeBoundCallback(&NrBearerStatsConnector::NotifyHandoverStartUe, this));
163 Config::Connect("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverEndOk",
164 MakeBoundCallback(&NrBearerStatsConnector::NotifyHandoverEndOkEnb, this));
165 Config::Connect("/NodeList/*/DeviceList/*/LteUeRrc/HandoverEndOk",
166 MakeBoundCallback(&NrBearerStatsConnector::NotifyHandoverEndOkUe, this));
167 m_connected = true;
168 }
169}
170
171void
173 std::string context,
174 uint64_t imsi,
175 uint16_t cellId,
176 uint16_t rnti)
177{
178 c->ConnectSrb0Traces(context, imsi, cellId, rnti);
179}
180
181void
183 std::string context,
184 uint64_t imsi,
185 uint16_t cellId,
186 uint16_t rnti)
187{
188 c->ConnectSrb1TracesUe(context, imsi, cellId, rnti);
189}
190
191void
193 std::string context,
194 uint64_t imsi,
195 uint16_t cellId,
196 uint16_t rnti)
197{
198 c->ConnectTracesUeIfFirstTime(context, imsi, cellId, rnti);
199}
200
201void
203 std::string context,
204 uint64_t imsi,
205 uint16_t cellId,
206 uint16_t rnti,
207 uint16_t targetCellId)
208{
209 c->DisconnectTracesUe(context, imsi, cellId, rnti);
210}
211
212void
214 std::string context,
215 uint64_t imsi,
216 uint16_t cellId,
217 uint16_t rnti)
218{
219 c->ConnectTracesUe(context, imsi, cellId, rnti);
220}
221
222void
224 std::string context,
225 uint16_t cellId,
226 uint16_t rnti)
227{
228 c->StoreUeManagerPath(context, cellId, rnti);
229}
230
231void
233 std::string context,
234 uint64_t imsi,
235 uint16_t cellId,
236 uint16_t rnti)
237{
238 c->ConnectTracesEnbIfFirstTime(context, imsi, cellId, rnti);
239}
240
241void
243 std::string context,
244 uint64_t imsi,
245 uint16_t cellId,
246 uint16_t rnti,
247 uint16_t targetCellId)
248{
249 c->DisconnectTracesEnb(context, imsi, cellId, rnti);
250}
251
252void
254 std::string context,
255 uint64_t imsi,
256 uint16_t cellId,
257 uint16_t rnti)
258{
259 c->ConnectTracesEnb(context, imsi, cellId, rnti);
260}
261
262void
263NrBearerStatsConnector::StoreUeManagerPath(std::string context, uint16_t cellId, uint16_t rnti)
264{
265 NS_LOG_FUNCTION(this << context << cellId << rnti);
266 std::ostringstream ueManagerPath;
267 ueManagerPath << context.substr(0, context.rfind('/')) << "/UeMap/" << (uint32_t)rnti;
268 CellIdRnti key;
269 key.cellId = cellId;
270 key.rnti = rnti;
271 m_ueManagerPathByCellIdRnti[key] = ueManagerPath.str();
272}
273
274void
275NrBearerStatsConnector::ConnectSrb0Traces(std::string context,
276 uint64_t imsi,
277 uint16_t cellId,
278 uint16_t rnti)
279{
280 NS_LOG_FUNCTION(this << imsi << cellId << rnti);
281 std::string ueRrcPath = context.substr(0, context.rfind('/'));
282 CellIdRnti key;
283 key.cellId = cellId;
284 key.rnti = rnti;
285 std::map<CellIdRnti, std::string>::iterator it = m_ueManagerPathByCellIdRnti.find(key);
286 NS_ASSERT(it != m_ueManagerPathByCellIdRnti.end());
287 std::string ueManagerPath = it->second;
288 NS_LOG_LOGIC(this << " ueManagerPath: " << ueManagerPath);
289 m_ueManagerPathByCellIdRnti.erase(it);
290
291 if (m_rlcStats)
292 {
293 Ptr<NrBoundCallbackArgument> arg = Create<NrBoundCallbackArgument>();
294 arg->imsi = imsi;
295 arg->cellId = cellId;
296 arg->stats = m_rlcStats;
297
298 // disconnect eventually previously connected SRB0 both at UE and eNB
299 Config::Disconnect(ueRrcPath + "/Srb0/LteRlc/TxPDU",
300 MakeBoundCallback(&UlTxPduCallback, arg));
301 Config::Disconnect(ueRrcPath + "/Srb0/LteRlc/RxPDU",
302 MakeBoundCallback(&DlRxPduCallback, arg));
303 Config::Disconnect(ueManagerPath + "/Srb0/LteRlc/TxPDU",
304 MakeBoundCallback(&DlTxPduCallback, arg));
305 Config::Disconnect(ueManagerPath + "/Srb0/LteRlc/RxPDU",
306 MakeBoundCallback(&UlRxPduCallback, arg));
307
308 // connect SRB0 both at UE and eNB
309 Config::Connect(ueRrcPath + "/Srb0/LteRlc/TxPDU", MakeBoundCallback(&UlTxPduCallback, arg));
310 Config::Connect(ueRrcPath + "/Srb0/LteRlc/RxPDU", MakeBoundCallback(&DlRxPduCallback, arg));
311 Config::Connect(ueManagerPath + "/Srb0/LteRlc/TxPDU",
312 MakeBoundCallback(&DlTxPduCallback, arg));
313 Config::Connect(ueManagerPath + "/Srb0/LteRlc/RxPDU",
314 MakeBoundCallback(&UlRxPduCallback, arg));
315
316 // connect SRB1 at eNB only (at UE SRB1 will be setup later)
317 Config::Connect(ueManagerPath + "/Srb1/LteRlc/TxPDU",
318 MakeBoundCallback(&DlTxPduCallback, arg));
319 Config::Connect(ueManagerPath + "/Srb1/LteRlc/RxPDU",
320 MakeBoundCallback(&UlRxPduCallback, arg));
321 }
322 if (m_pdcpStats)
323 {
324 Ptr<NrBoundCallbackArgument> arg = Create<NrBoundCallbackArgument>();
325 arg->imsi = imsi;
326 arg->cellId = cellId;
327 arg->stats = m_pdcpStats;
328
329 // connect SRB1 at eNB only (at UE SRB1 will be setup later)
330 Config::Connect(ueManagerPath + "/Srb1/LtePdcp/RxPDU",
331 MakeBoundCallback(&UlRxPduCallback, arg));
332 Config::Connect(ueManagerPath + "/Srb1/LtePdcp/TxPDU",
333 MakeBoundCallback(&DlTxPduCallback, arg));
334 }
335}
336
337void
338NrBearerStatsConnector::ConnectSrb1TracesUe(std::string ueRrcPath,
339 uint64_t imsi,
340 uint16_t cellId,
341 uint16_t rnti)
342{
343 NS_LOG_FUNCTION(this << imsi << cellId << rnti);
344 if (m_rlcStats)
345 {
346 Ptr<NrBoundCallbackArgument> arg = Create<NrBoundCallbackArgument>();
347 arg->imsi = imsi;
348 arg->cellId = cellId;
349 arg->stats = m_rlcStats;
350 Config::Connect(ueRrcPath + "/Srb1/LteRlc/TxPDU", MakeBoundCallback(&UlTxPduCallback, arg));
351 Config::Connect(ueRrcPath + "/Srb1/LteRlc/RxPDU", MakeBoundCallback(&DlRxPduCallback, arg));
352 }
353 if (m_pdcpStats)
354 {
355 Ptr<NrBoundCallbackArgument> arg = Create<NrBoundCallbackArgument>();
356 arg->imsi = imsi;
357 arg->cellId = cellId;
358 arg->stats = m_pdcpStats;
359 Config::Connect(ueRrcPath + "/Srb1/LtePdcp/RxPDU",
360 MakeBoundCallback(&DlRxPduCallback, arg));
361 Config::Connect(ueRrcPath + "/Srb1/LtePdcp/TxPDU",
362 MakeBoundCallback(&UlTxPduCallback, arg));
363 }
364}
365
366void
367NrBearerStatsConnector::ConnectTracesUeIfFirstTime(std::string context,
368 uint64_t imsi,
369 uint16_t cellId,
370 uint16_t rnti)
371{
372 NS_LOG_FUNCTION(this << context);
373 if (m_imsiSeenUe.find(imsi) == m_imsiSeenUe.end())
374 {
375 m_imsiSeenUe.insert(imsi);
376 ConnectTracesUe(context, imsi, cellId, rnti);
377 }
378}
379
380void
381NrBearerStatsConnector::ConnectTracesEnbIfFirstTime(std::string context,
382 uint64_t imsi,
383 uint16_t cellId,
384 uint16_t rnti)
385{
386 NS_LOG_FUNCTION(this << context);
387 if (m_imsiSeenEnb.find(imsi) == m_imsiSeenEnb.end())
388 {
389 m_imsiSeenEnb.insert(imsi);
390 ConnectTracesEnb(context, imsi, cellId, rnti);
391 }
392}
393
394void
395NrBearerStatsConnector::ConnectTracesUe(std::string context,
396 uint64_t imsi,
397 uint16_t cellId,
398 uint16_t rnti)
399{
400 NS_LOG_FUNCTION(this << context);
401 NS_LOG_LOGIC(this << "expected context should match /NodeList/*/DeviceList/*/LteUeRrc/");
402 std::string basePath = context.substr(0, context.rfind('/'));
403 if (m_rlcStats)
404 {
405 Ptr<NrBoundCallbackArgument> arg = Create<NrBoundCallbackArgument>();
406 arg->imsi = imsi;
407 arg->cellId = cellId;
408 arg->stats = m_rlcStats;
409 Config::Connect(basePath + "/DataRadioBearerMap/*/LteRlc/TxPDU",
410 MakeBoundCallback(&UlTxPduCallback, arg));
411 Config::Connect(basePath + "/DataRadioBearerMap/*/LteRlc/RxPDU",
412 MakeBoundCallback(&DlRxPduCallback, arg));
413 Config::Connect(basePath + "/Srb1/LteRlc/TxPDU", MakeBoundCallback(&UlTxPduCallback, arg));
414 Config::Connect(basePath + "/Srb1/LteRlc/RxPDU", MakeBoundCallback(&DlRxPduCallback, arg));
415 }
416 if (m_pdcpStats)
417 {
418 Ptr<NrBoundCallbackArgument> arg = Create<NrBoundCallbackArgument>();
419 arg->imsi = imsi;
420 arg->cellId = cellId;
421 arg->stats = m_pdcpStats;
422 Config::Connect(basePath + "/DataRadioBearerMap/*/LtePdcp/RxPDU",
423 MakeBoundCallback(&DlRxPduCallback, arg));
424 Config::Connect(basePath + "/DataRadioBearerMap/*/LtePdcp/TxPDU",
425 MakeBoundCallback(&UlTxPduCallback, arg));
426 Config::Connect(basePath + "/Srb1/LtePdcp/RxPDU", MakeBoundCallback(&DlRxPduCallback, arg));
427 Config::Connect(basePath + "/Srb1/LtePdcp/TxPDU", MakeBoundCallback(&UlTxPduCallback, arg));
428 }
429}
430
431void
432NrBearerStatsConnector::ConnectTracesEnb(std::string context,
433 uint64_t imsi,
434 uint16_t cellId,
435 uint16_t rnti)
436{
437 NS_LOG_FUNCTION(this << context);
438 NS_LOG_LOGIC(this << "expected context should match /NodeList/*/DeviceList/*/LteEnbRrc/");
439 std::ostringstream basePath;
440 basePath << context.substr(0, context.rfind('/')) << "/UeMap/" << (uint32_t)rnti;
441 if (m_rlcStats)
442 {
443 Ptr<NrBoundCallbackArgument> arg = Create<NrBoundCallbackArgument>();
444 arg->imsi = imsi;
445 arg->cellId = cellId;
446 arg->stats = m_rlcStats;
447 Config::Connect(basePath.str() + "/DataRadioBearerMap/*/LteRlc/RxPDU",
448 MakeBoundCallback(&UlRxPduCallback, arg));
449 Config::Connect(basePath.str() + "/DataRadioBearerMap/*/LteRlc/TxPDU",
450 MakeBoundCallback(&DlTxPduCallback, arg));
451 Config::Connect(basePath.str() + "/Srb0/LteRlc/RxPDU",
452 MakeBoundCallback(&UlRxPduCallback, arg));
453 Config::Connect(basePath.str() + "/Srb0/LteRlc/TxPDU",
454 MakeBoundCallback(&DlTxPduCallback, arg));
455 Config::Connect(basePath.str() + "/Srb1/LteRlc/RxPDU",
456 MakeBoundCallback(&UlRxPduCallback, arg));
457 Config::Connect(basePath.str() + "/Srb1/LteRlc/TxPDU",
458 MakeBoundCallback(&DlTxPduCallback, arg));
459 }
460 if (m_pdcpStats)
461 {
462 Ptr<NrBoundCallbackArgument> arg = Create<NrBoundCallbackArgument>();
463 arg->imsi = imsi;
464 arg->cellId = cellId;
465 arg->stats = m_pdcpStats;
466 Config::Connect(basePath.str() + "/DataRadioBearerMap/*/LtePdcp/TxPDU",
467 MakeBoundCallback(&DlTxPduCallback, arg));
468 Config::Connect(basePath.str() + "/DataRadioBearerMap/*/LtePdcp/RxPDU",
469 MakeBoundCallback(&UlRxPduCallback, arg));
470 Config::Connect(basePath.str() + "/Srb1/LtePdcp/TxPDU",
471 MakeBoundCallback(&DlTxPduCallback, arg));
472 Config::Connect(basePath.str() + "/Srb1/LtePdcp/RxPDU",
473 MakeBoundCallback(&UlRxPduCallback, arg));
474 }
475}
476
477void
478NrBearerStatsConnector::DisconnectTracesUe(std::string context,
479 uint64_t imsi,
480 uint16_t cellId,
481 uint16_t rnti)
482{
483 NS_LOG_FUNCTION(this);
484}
485
486void
487NrBearerStatsConnector::DisconnectTracesEnb(std::string context,
488 uint64_t imsi,
489 uint16_t cellId,
490 uint16_t rnti)
491{
492 NS_LOG_FUNCTION(this);
493}
494
495Ptr<NrBearerStatsBase>
497{
498 return m_rlcStats;
499}
500
501Ptr<NrBearerStatsBase>
503{
504 return m_pdcpStats;
505}
506
507} // namespace ns3
static void NotifyHandoverStartEnb(NrBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti, uint16_t targetCellId)
static void NotifyConnectionSetupUe(NrBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
static void NotifyRandomAccessSuccessfulUe(NrBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
static void NotifyConnectionReconfigurationEnb(NrBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
Ptr< NrBearerStatsBase > GetPdcpStats()
static void NotifyHandoverEndOkUe(NrBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
void EnablePdcpStats(Ptr< NrBearerStatsBase > pdcpStats)
static void NotifyHandoverStartUe(NrBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti, uint16_t targetCellId)
void EnableRlcStats(Ptr< NrBearerStatsBase > rlcStats)
Ptr< NrBearerStatsBase > GetRlcStats()
static void NotifyHandoverEndOkEnb(NrBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
static void NotifyConnectionReconfigurationUe(NrBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
static void NotifyNewUeContextEnb(NrBearerStatsConnector *c, std::string context, uint16_t cellid, uint16_t rnti)