5G-LENA nr-v3.3-81-g75c7590d
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/*/NrGnbRrc/NewUeContext",
149 MakeBoundCallback(&NrBearerStatsConnector::NotifyNewUeContextGnb, this));
150 Config::Connect(
151 "/NodeList/*/DeviceList/*/NrUeRrc/RandomAccessSuccessful",
153 Config::Connect(
154 "/NodeList/*/DeviceList/*/NrGnbRrc/ConnectionReconfiguration",
156 Config::Connect(
157 "/NodeList/*/DeviceList/*/NrUeRrc/ConnectionReconfiguration",
159 Config::Connect("/NodeList/*/DeviceList/*/NrGnbRrc/HandoverStart",
160 MakeBoundCallback(&NrBearerStatsConnector::NotifyHandoverStartGnb, this));
161 Config::Connect("/NodeList/*/DeviceList/*/NrUeRrc/HandoverStart",
162 MakeBoundCallback(&NrBearerStatsConnector::NotifyHandoverStartUe, this));
163 Config::Connect("/NodeList/*/DeviceList/*/NrGnbRrc/HandoverEndOk",
164 MakeBoundCallback(&NrBearerStatsConnector::NotifyHandoverEndOkGnb, this));
165 Config::Connect("/NodeList/*/DeviceList/*/NrUeRrc/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->ConnectTracesGnbIfFirstTime(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->DisconnectTracesGnb(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->ConnectTracesGnb(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 gNB
299 Config::Disconnect(ueRrcPath + "/Srb0/NrRlc/TxPDU",
300 MakeBoundCallback(&UlTxPduCallback, arg));
301 Config::Disconnect(ueRrcPath + "/Srb0/NrRlc/RxPDU",
302 MakeBoundCallback(&DlRxPduCallback, arg));
303 Config::Disconnect(ueManagerPath + "/Srb0/NrRlc/TxPDU",
304 MakeBoundCallback(&DlTxPduCallback, arg));
305 Config::Disconnect(ueManagerPath + "/Srb0/NrRlc/RxPDU",
306 MakeBoundCallback(&UlRxPduCallback, arg));
307
308 // connect SRB0 both at UE and gNB
309 Config::Connect(ueRrcPath + "/Srb0/NrRlc/TxPDU", MakeBoundCallback(&UlTxPduCallback, arg));
310 Config::Connect(ueRrcPath + "/Srb0/NrRlc/RxPDU", MakeBoundCallback(&DlRxPduCallback, arg));
311 Config::Connect(ueManagerPath + "/Srb0/NrRlc/TxPDU",
312 MakeBoundCallback(&DlTxPduCallback, arg));
313 Config::Connect(ueManagerPath + "/Srb0/NrRlc/RxPDU",
314 MakeBoundCallback(&UlRxPduCallback, arg));
315
316 // connect SRB1 at gNB only (at UE SRB1 will be setup later)
317 Config::Connect(ueManagerPath + "/Srb1/NrRlc/TxPDU",
318 MakeBoundCallback(&DlTxPduCallback, arg));
319 Config::Connect(ueManagerPath + "/Srb1/NrRlc/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 gNB only (at UE SRB1 will be setup later)
330 Config::Connect(ueManagerPath + "/Srb1/NrPdcp/RxPDU",
331 MakeBoundCallback(&UlRxPduCallback, arg));
332 Config::Connect(ueManagerPath + "/Srb1/NrPdcp/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/NrRlc/TxPDU", MakeBoundCallback(&UlTxPduCallback, arg));
351 Config::Connect(ueRrcPath + "/Srb1/NrRlc/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/NrPdcp/RxPDU", MakeBoundCallback(&DlRxPduCallback, arg));
360 Config::Connect(ueRrcPath + "/Srb1/NrPdcp/TxPDU", MakeBoundCallback(&UlTxPduCallback, arg));
361 }
362}
363
364void
365NrBearerStatsConnector::ConnectTracesUeIfFirstTime(std::string context,
366 uint64_t imsi,
367 uint16_t cellId,
368 uint16_t rnti)
369{
370 NS_LOG_FUNCTION(this << context);
371 if (m_imsiSeenUe.find(imsi) == m_imsiSeenUe.end())
372 {
373 m_imsiSeenUe.insert(imsi);
374 ConnectTracesUe(context, imsi, cellId, rnti);
375 }
376}
377
378void
379NrBearerStatsConnector::ConnectTracesGnbIfFirstTime(std::string context,
380 uint64_t imsi,
381 uint16_t cellId,
382 uint16_t rnti)
383{
384 NS_LOG_FUNCTION(this << context);
385 if (m_imsiSeenGnb.find(imsi) == m_imsiSeenGnb.end())
386 {
387 m_imsiSeenGnb.insert(imsi);
388 ConnectTracesGnb(context, imsi, cellId, rnti);
389 }
390}
391
392void
393NrBearerStatsConnector::ConnectTracesUe(std::string context,
394 uint64_t imsi,
395 uint16_t cellId,
396 uint16_t rnti)
397{
398 NS_LOG_FUNCTION(this << context);
399 NS_LOG_LOGIC(this << "expected context should match /NodeList/*/DeviceList/*/NrUeRrc/");
400 std::string basePath = context.substr(0, context.rfind('/'));
401 if (m_rlcStats)
402 {
403 Ptr<NrBoundCallbackArgument> arg = Create<NrBoundCallbackArgument>();
404 arg->imsi = imsi;
405 arg->cellId = cellId;
406 arg->stats = m_rlcStats;
407 Config::Connect(basePath + "/DataRadioBearerMap/*/NrRlc/TxPDU",
408 MakeBoundCallback(&UlTxPduCallback, arg));
409 Config::Connect(basePath + "/DataRadioBearerMap/*/NrRlc/RxPDU",
410 MakeBoundCallback(&DlRxPduCallback, arg));
411 Config::Connect(basePath + "/Srb1/NrRlc/TxPDU", MakeBoundCallback(&UlTxPduCallback, arg));
412 Config::Connect(basePath + "/Srb1/NrRlc/RxPDU", MakeBoundCallback(&DlRxPduCallback, arg));
413 }
414 if (m_pdcpStats)
415 {
416 Ptr<NrBoundCallbackArgument> arg = Create<NrBoundCallbackArgument>();
417 arg->imsi = imsi;
418 arg->cellId = cellId;
419 arg->stats = m_pdcpStats;
420 Config::Connect(basePath + "/DataRadioBearerMap/*/NrPdcp/RxPDU",
421 MakeBoundCallback(&DlRxPduCallback, arg));
422 Config::Connect(basePath + "/DataRadioBearerMap/*/NrPdcp/TxPDU",
423 MakeBoundCallback(&UlTxPduCallback, arg));
424 Config::Connect(basePath + "/Srb1/NrPdcp/RxPDU", MakeBoundCallback(&DlRxPduCallback, arg));
425 Config::Connect(basePath + "/Srb1/NrPdcp/TxPDU", MakeBoundCallback(&UlTxPduCallback, arg));
426 }
427}
428
429void
430NrBearerStatsConnector::ConnectTracesGnb(std::string context,
431 uint64_t imsi,
432 uint16_t cellId,
433 uint16_t rnti)
434{
435 NS_LOG_FUNCTION(this << context);
436 NS_LOG_LOGIC(this << "expected context should match /NodeList/*/DeviceList/*/NrGnbRrc/");
437 std::ostringstream basePath;
438 basePath << context.substr(0, context.rfind('/')) << "/UeMap/" << (uint32_t)rnti;
439 if (m_rlcStats)
440 {
441 Ptr<NrBoundCallbackArgument> arg = Create<NrBoundCallbackArgument>();
442 arg->imsi = imsi;
443 arg->cellId = cellId;
444 arg->stats = m_rlcStats;
445 Config::Connect(basePath.str() + "/DataRadioBearerMap/*/NrRlc/RxPDU",
446 MakeBoundCallback(&UlRxPduCallback, arg));
447 Config::Connect(basePath.str() + "/DataRadioBearerMap/*/NrRlc/TxPDU",
448 MakeBoundCallback(&DlTxPduCallback, arg));
449 Config::Connect(basePath.str() + "/Srb0/NrRlc/RxPDU",
450 MakeBoundCallback(&UlRxPduCallback, arg));
451 Config::Connect(basePath.str() + "/Srb0/NrRlc/TxPDU",
452 MakeBoundCallback(&DlTxPduCallback, arg));
453 Config::Connect(basePath.str() + "/Srb1/NrRlc/RxPDU",
454 MakeBoundCallback(&UlRxPduCallback, arg));
455 Config::Connect(basePath.str() + "/Srb1/NrRlc/TxPDU",
456 MakeBoundCallback(&DlTxPduCallback, arg));
457 }
458 if (m_pdcpStats)
459 {
460 Ptr<NrBoundCallbackArgument> arg = Create<NrBoundCallbackArgument>();
461 arg->imsi = imsi;
462 arg->cellId = cellId;
463 arg->stats = m_pdcpStats;
464 Config::Connect(basePath.str() + "/DataRadioBearerMap/*/NrPdcp/TxPDU",
465 MakeBoundCallback(&DlTxPduCallback, arg));
466 Config::Connect(basePath.str() + "/DataRadioBearerMap/*/NrPdcp/RxPDU",
467 MakeBoundCallback(&UlRxPduCallback, arg));
468 Config::Connect(basePath.str() + "/Srb1/NrPdcp/TxPDU",
469 MakeBoundCallback(&DlTxPduCallback, arg));
470 Config::Connect(basePath.str() + "/Srb1/NrPdcp/RxPDU",
471 MakeBoundCallback(&UlRxPduCallback, arg));
472 }
473}
474
475void
476NrBearerStatsConnector::DisconnectTracesUe(std::string context,
477 uint64_t imsi,
478 uint16_t cellId,
479 uint16_t rnti)
480{
481 NS_LOG_FUNCTION(this);
482}
483
484void
485NrBearerStatsConnector::DisconnectTracesGnb(std::string context,
486 uint64_t imsi,
487 uint16_t cellId,
488 uint16_t rnti)
489{
490 NS_LOG_FUNCTION(this);
491}
492
493Ptr<NrBearerStatsBase>
495{
496 return m_rlcStats;
497}
498
499Ptr<NrBearerStatsBase>
501{
502 return m_pdcpStats;
503}
504
505} // namespace ns3
static void NotifyHandoverStartGnb(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)
Ptr< NrBearerStatsBase > GetPdcpStats()
static void NotifyHandoverEndOkUe(NrBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)
static void NotifyNewUeContextGnb(NrBearerStatsConnector *c, std::string context, 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 NotifyConnectionReconfigurationGnb(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 NotifyHandoverEndOkGnb(NrBearerStatsConnector *c, std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti)