6#include "nr-bearer-stats-calculator.h"
18NS_LOG_COMPONENT_DEFINE(
"NrBearerStatsCalculator");
20NS_OBJECT_ENSURE_REGISTERED(NrBearerStatsCalculator);
24 m_pendingOutput(false),
27 NS_LOG_FUNCTION(
this);
32 m_pendingOutput(false)
34 NS_LOG_FUNCTION(
this);
35 m_protocolType = protocolType;
40 NS_LOG_FUNCTION(
this);
47 TypeId(
"ns3::NrBearerStatsCalculator")
49 .AddConstructor<NrBearerStatsCalculator>()
51 .AddAttribute(
"StartTime",
52 "Start time of the on going epoch.",
53 TimeValue(Seconds(0.)),
57 .AddAttribute(
"EpochDuration",
59 TimeValue(Seconds(0.25)),
63 .AddAttribute(
"DlRlcOutputFilename",
64 "Name of the file where the downlink results will be saved.",
65 StringValue(
"NrDlRlcStatsE2E.txt"),
66 MakeStringAccessor(&NrBearerStatsCalculator::m_dlRlcOutputFilename),
68 .AddAttribute(
"UlRlcOutputFilename",
69 "Name of the file where the uplink results will be saved.",
70 StringValue(
"NrUlRlcStatsE2E.txt"),
71 MakeStringAccessor(&NrBearerStatsCalculator::m_ulRlcOutputFilename),
73 .AddAttribute(
"DlPdcpOutputFilename",
74 "Name of the file where the downlink results will be saved.",
75 StringValue(
"NrDlPdcpStatsE2E.txt"),
76 MakeStringAccessor(&NrBearerStatsCalculator::m_dlPdcpOutputFilename),
78 .AddAttribute(
"UlPdcpOutputFilename",
79 "Name of the file where the uplink results will be saved.",
80 StringValue(
"NrUlPdcpStatsE2E.txt"),
81 MakeStringAccessor(&NrBearerStatsCalculator::m_ulPdcpOutputFilename),
87NrBearerStatsCalculator::DoDispose()
89 NS_LOG_FUNCTION(
this);
119 return m_epochDuration;
129 NS_LOG_FUNCTION(
this);
132 if (Simulator::Now() >= m_startTime)
134 m_ulCellId[p] = cellId;
137 m_ulTxData[p] += packetSize;
139 m_pendingOutput =
true;
149 NS_LOG_FUNCTION(
this);
152 if (Simulator::Now() >= m_startTime)
154 m_dlCellId[p] = cellId;
157 m_dlTxData[p] += packetSize;
159 m_pendingOutput =
true;
170 NS_LOG_FUNCTION(
this);
173 if (Simulator::Now() >= m_startTime)
175 m_ulCellId[p] = cellId;
177 m_ulRxData[p] += packetSize;
179 nr::Uint64StatsMap::iterator it = m_ulDelay.find(p);
180 if (it == m_ulDelay.end())
182 NS_LOG_DEBUG(
this <<
" Creating UL stats calculators for IMSI " << p.
m_imsi
183 <<
" and LCID " << (uint32_t)p.
m_lcId);
184 m_ulDelay[p] = CreateObject<MinMaxAvgTotalCalculator<uint64_t>>();
185 m_ulPduSize[p] = CreateObject<MinMaxAvgTotalCalculator<uint32_t>>();
187 m_ulDelay[p]->Update(delay);
188 m_ulPduSize[p]->Update(packetSize);
190 m_pendingOutput =
true;
201 NS_LOG_FUNCTION(
this);
204 if (Simulator::Now() >= m_startTime)
206 m_dlCellId[p] = cellId;
208 m_dlRxData[p] += packetSize;
210 nr::Uint64StatsMap::iterator it = m_dlDelay.find(p);
211 if (it == m_dlDelay.end())
213 NS_LOG_DEBUG(
this <<
" Creating DL stats calculators for IMSI " << p.
m_imsi
214 <<
" and LCID " << (uint32_t)p.
m_lcId);
215 m_dlDelay[p] = CreateObject<MinMaxAvgTotalCalculator<uint64_t>>();
216 m_dlPduSize[p] = CreateObject<MinMaxAvgTotalCalculator<uint32_t>>();
218 m_dlDelay[p]->Update(delay);
219 m_dlPduSize[p]->Update(packetSize);
221 m_pendingOutput =
true;
225NrBearerStatsCalculator::ShowResults()
231 std::ofstream ulOutFile;
232 std::ofstream dlOutFile;
237 if (!ulOutFile.is_open())
244 if (!dlOutFile.is_open())
249 m_firstWrite =
false;
251 <<
"% start(s)\tend(s)\tCellId\tIMSI\tRNTI\tLCID\tnTxPDUs\tTxBytes\tnRxPDUs\tRxBytes\t";
252 ulOutFile <<
"delay(s)\tstdDev(s)\tmin(s)\tmax(s)\t";
253 ulOutFile <<
"PduSize\tstdDev\tmin\tmax";
254 ulOutFile << std::endl;
256 <<
"% start(s)\tend(s)\tCellId\tIMSI\tRNTI\tLCID\tnTxPDUs\tTxBytes\tnRxPDUs\tRxBytes\t";
257 dlOutFile <<
"delay(s)\tstdDev(s)\tmin(s)\tmax(s)\t";
258 dlOutFile <<
"PduSize\tstdDev\tmin\tmax";
259 dlOutFile << std::endl;
264 if (!ulOutFile.is_open())
271 if (!dlOutFile.is_open())
278 WriteUlResults(ulOutFile);
279 WriteDlResults(dlOutFile);
280 m_pendingOutput =
false;
284NrBearerStatsCalculator::WriteUlResults(std::ofstream& outFile)
286 NS_LOG_FUNCTION(
this);
290 std::vector<nr::ImsiLcidPair_t> pairVector;
291 for (
auto& m_ulTxPacket : m_ulTxPackets)
293 if (find(pairVector.begin(), pairVector.end(), m_ulTxPacket.first) == pairVector.end())
295 pairVector.push_back(m_ulTxPacket.first);
299 Time endTime = m_startTime + m_epochDuration;
300 for (
auto p : pairVector)
302 outFile << m_startTime.GetSeconds() <<
"\t";
303 outFile << endTime.GetSeconds() <<
"\t";
304 outFile <<
GetUlCellId(p.m_imsi, p.m_lcId) <<
"\t";
305 outFile << p.m_imsi <<
"\t";
306 outFile << m_flowId[p].m_rnti <<
"\t";
307 outFile << (uint32_t)m_flowId[p].m_lcId <<
"\t";
309 outFile <<
GetUlTxData(p.m_imsi, p.m_lcId) <<
"\t";
311 outFile <<
GetUlRxData(p.m_imsi, p.m_lcId) <<
"\t";
313 for (
double& stat : stats)
315 outFile << stat * 1e-9 <<
"\t";
318 for (
double& stat : stats)
320 outFile << stat <<
"\t";
322 outFile << std::endl;
329NrBearerStatsCalculator::WriteDlResults(std::ofstream& outFile)
331 NS_LOG_FUNCTION(
this);
334 std::vector<nr::ImsiLcidPair_t> pairVector;
335 for (
auto& m_dlTxPacket : m_dlTxPackets)
337 if (find(pairVector.begin(), pairVector.end(), m_dlTxPacket.first) == pairVector.end())
339 pairVector.push_back(m_dlTxPacket.first);
343 Time endTime = m_startTime + m_epochDuration;
344 for (
auto p : pairVector)
346 outFile << m_startTime.GetSeconds() <<
"\t";
347 outFile << endTime.GetSeconds() <<
"\t";
348 outFile <<
GetDlCellId(p.m_imsi, p.m_lcId) <<
"\t";
349 outFile << p.m_imsi <<
"\t";
350 outFile << m_flowId[p].m_rnti <<
"\t";
351 outFile << (uint32_t)m_flowId[p].m_lcId <<
"\t";
353 outFile <<
GetDlTxData(p.m_imsi, p.m_lcId) <<
"\t";
355 outFile <<
GetDlRxData(p.m_imsi, p.m_lcId) <<
"\t";
357 for (
double& stat : stats)
359 outFile << stat * 1e-9 <<
"\t";
362 for (
double& stat : stats)
364 outFile << stat <<
"\t";
366 outFile << std::endl;
373NrBearerStatsCalculator::ResetResults()
375 NS_LOG_FUNCTION(
this);
377 m_ulTxPackets.erase(m_ulTxPackets.begin(), m_ulTxPackets.end());
378 m_ulRxPackets.erase(m_ulRxPackets.begin(), m_ulRxPackets.end());
379 m_ulRxData.erase(m_ulRxData.begin(), m_ulRxData.end());
380 m_ulTxData.erase(m_ulTxData.begin(), m_ulTxData.end());
381 m_ulDelay.erase(m_ulDelay.begin(), m_ulDelay.end());
382 m_ulPduSize.erase(m_ulPduSize.begin(), m_ulPduSize.end());
384 m_dlTxPackets.erase(m_dlTxPackets.begin(), m_dlTxPackets.end());
385 m_dlRxPackets.erase(m_dlRxPackets.begin(), m_dlRxPackets.end());
386 m_dlRxData.erase(m_dlRxData.begin(), m_dlRxData.end());
387 m_dlTxData.erase(m_dlTxData.begin(), m_dlTxData.end());
388 m_dlDelay.erase(m_dlDelay.begin(), m_dlDelay.end());
389 m_dlPduSize.erase(m_dlPduSize.begin(), m_dlPduSize.end());
393NrBearerStatsCalculator::RescheduleEndEpoch()
395 NS_LOG_FUNCTION(
this);
396 m_endEpochEvent.Cancel();
397 NS_ASSERT(Simulator::Now().GetMilliSeconds() == 0);
398 m_endEpochEvent = Simulator::Schedule(m_startTime + m_epochDuration,
399 &NrBearerStatsCalculator::EndEpoch,
404NrBearerStatsCalculator::EndEpoch()
406 NS_LOG_FUNCTION(
this);
409 m_startTime += m_epochDuration;
411 Simulator::Schedule(m_epochDuration, &NrBearerStatsCalculator::EndEpoch,
this);
417 NS_LOG_FUNCTION(
this << imsi << (uint16_t)lcid);
419 return m_ulTxPackets[p];
425 NS_LOG_FUNCTION(
this << imsi << (uint16_t)lcid);
427 return m_ulRxPackets[p];
433 NS_LOG_FUNCTION(
this << imsi << (uint16_t)lcid);
435 return m_ulTxData[p];
441 NS_LOG_FUNCTION(
this << imsi << (uint16_t)lcid);
443 return m_ulRxData[p];
449 NS_LOG_FUNCTION(
this << imsi << (uint16_t)lcid);
451 nr::Uint64StatsMap::iterator it = m_ulDelay.find(p);
452 if (it == m_ulDelay.end())
454 NS_LOG_ERROR(
"UL delay for " << imsi <<
" - " << (uint16_t)lcid <<
" not found");
457 return m_ulDelay[p]->getMean();
463 NS_LOG_FUNCTION(
this << imsi << (uint16_t)lcid);
465 std::vector<double> stats;
466 nr::Uint64StatsMap::iterator it = m_ulDelay.find(p);
467 if (it == m_ulDelay.end())
469 stats.push_back(0.0);
470 stats.push_back(0.0);
471 stats.push_back(0.0);
472 stats.push_back(0.0);
475 stats.push_back(m_ulDelay[p]->getMean());
476 stats.push_back(m_ulDelay[p]->getStddev());
477 stats.push_back(m_ulDelay[p]->getMin());
478 stats.push_back(m_ulDelay[p]->getMax());
485 NS_LOG_FUNCTION(
this << imsi << (uint16_t)lcid);
487 std::vector<double> stats;
488 nr::Uint32StatsMap::iterator it = m_ulPduSize.find(p);
489 if (it == m_ulPduSize.end())
491 stats.push_back(0.0);
492 stats.push_back(0.0);
493 stats.push_back(0.0);
494 stats.push_back(0.0);
497 stats.push_back(m_ulPduSize[p]->getMean());
498 stats.push_back(m_ulPduSize[p]->getStddev());
499 stats.push_back(m_ulPduSize[p]->getMin());
500 stats.push_back(m_ulPduSize[p]->getMax());
507 NS_LOG_FUNCTION(
this << imsi << (uint16_t)lcid);
509 return m_dlTxPackets[p];
515 NS_LOG_FUNCTION(
this << imsi << (uint16_t)lcid);
517 return m_dlRxPackets[p];
523 NS_LOG_FUNCTION(
this << imsi << (uint16_t)lcid);
525 return m_dlTxData[p];
531 NS_LOG_FUNCTION(
this << imsi << (uint16_t)lcid);
533 return m_dlRxData[p];
539 NS_LOG_FUNCTION(
this << imsi << (uint16_t)lcid);
541 return m_ulCellId[p];
547 NS_LOG_FUNCTION(
this << imsi << (uint16_t)lcid);
549 return m_dlCellId[p];
555 NS_LOG_FUNCTION(
this << imsi << (uint16_t)lcid);
557 nr::Uint64StatsMap::iterator it = m_dlDelay.find(p);
558 if (it == m_dlDelay.end())
560 NS_LOG_ERROR(
"DL delay for " << imsi <<
" not found");
563 return m_dlDelay[p]->getMean();
569 NS_LOG_FUNCTION(
this << imsi << (uint16_t)lcid);
571 std::vector<double> stats;
572 nr::Uint64StatsMap::iterator it = m_dlDelay.find(p);
573 if (it == m_dlDelay.end())
575 stats.push_back(0.0);
576 stats.push_back(0.0);
577 stats.push_back(0.0);
578 stats.push_back(0.0);
581 stats.push_back(m_dlDelay[p]->getMean());
582 stats.push_back(m_dlDelay[p]->getStddev());
583 stats.push_back(m_dlDelay[p]->getMin());
584 stats.push_back(m_dlDelay[p]->getMax());
591 NS_LOG_FUNCTION(
this << imsi << (uint16_t)lcid);
593 std::vector<double> stats;
594 nr::Uint32StatsMap::iterator it = m_dlPduSize.find(p);
595 if (it == m_dlPduSize.end())
597 stats.push_back(0.0);
598 stats.push_back(0.0);
599 stats.push_back(0.0);
600 stats.push_back(0.0);
603 stats.push_back(m_dlPduSize[p]->getMean());
604 stats.push_back(m_dlPduSize[p]->getStddev());
605 stats.push_back(m_dlPduSize[p]->getMin());
606 stats.push_back(m_dlPduSize[p]->getMax());
613 if (m_protocolType ==
"RLC")
615 return m_ulRlcOutputFilename;
619 return m_ulPdcpOutputFilename;
626 if (m_protocolType ==
"RLC")
628 return m_dlRlcOutputFilename;
632 return m_dlPdcpOutputFilename;
std::vector< double > GetUlPduSizeStats(uint64_t imsi, uint8_t lcid)
void UlRxPdu(uint16_t cellId, uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay) override
uint64_t GetDlTxData(uint64_t imsi, uint8_t lcid)
std::string GetDlOutputFilename()
double GetUlDelay(uint64_t imsi, uint8_t lcid)
std::vector< double > GetDlDelayStats(uint64_t imsi, uint8_t lcid)
static TypeId GetTypeId()
std::vector< double > GetDlPduSizeStats(uint64_t imsi, uint8_t lcid)
uint64_t GetUlTxData(uint64_t imsi, uint8_t lcid)
uint32_t GetDlCellId(uint64_t imsi, uint8_t lcid)
NrBearerStatsCalculator()
uint32_t GetDlRxPackets(uint64_t imsi, uint8_t lcid)
void SetStartTime(Time t)
void DlTxPdu(uint16_t cellId, uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize) override
void UlTxPdu(uint16_t cellId, uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize) override
uint64_t GetDlRxData(uint64_t imsi, uint8_t lcid)
uint32_t GetUlCellId(uint64_t imsi, uint8_t lcid)
uint32_t GetUlTxPackets(uint64_t imsi, uint8_t lcid)
Time GetStartTime() const
void DlRxPdu(uint16_t cellId, uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay) override
double GetDlDelay(uint64_t imsi, uint8_t lcid)
uint32_t GetUlRxPackets(uint64_t imsi, uint8_t lcid)
std::string GetUlOutputFilename()
uint64_t GetUlRxData(uint64_t imsi, uint8_t lcid)
std::vector< double > GetUlDelayStats(uint64_t imsi, uint8_t lcid)
~NrBearerStatsCalculator() override
uint32_t GetDlTxPackets(uint64_t imsi, uint8_t lcid)