1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2011 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  * Author: Jaume Nin <jnin@cttc.es>
19  *         Nicola Baldo <nbaldo@cttc.es>
20  */
21 
22 #include "radio-bearer-stats-calculator.h"
23 #include "ns3/string.h"
24 #include "ns3/nstime.h"
25 #include <ns3/log.h>
26 #include <vector>
27 #include <algorithm>
28 
29 namespace ns3 {
30 
31 NS_LOG_COMPONENT_DEFINE ("RadioBearerStatsCalculator");
32 
33 NS_OBJECT_ENSURE_REGISTERED ( RadioBearerStatsCalculator);
34 
RadioBearerStatsCalculator()35 RadioBearerStatsCalculator::RadioBearerStatsCalculator ()
36   : m_firstWrite (true),
37     m_pendingOutput (false),
38     m_protocolType ("RLC")
39 {
40   NS_LOG_FUNCTION (this);
41 }
42 
RadioBearerStatsCalculator(std::string protocolType)43 RadioBearerStatsCalculator::RadioBearerStatsCalculator (std::string protocolType)
44   : m_firstWrite (true),
45     m_pendingOutput (false)
46 {
47   NS_LOG_FUNCTION (this);
48   m_protocolType = protocolType;
49 }
50 
~RadioBearerStatsCalculator()51 RadioBearerStatsCalculator::~RadioBearerStatsCalculator ()
52 {
53   NS_LOG_FUNCTION (this);
54 }
55 
56 TypeId
GetTypeId(void)57 RadioBearerStatsCalculator::GetTypeId (void)
58 {
59   static TypeId tid =
60     TypeId ("ns3::RadioBearerStatsCalculator")
61     .SetParent<LteStatsCalculator> ().AddConstructor<RadioBearerStatsCalculator> ()
62     .SetGroupName ("Lte")
63     .AddAttribute ("StartTime", "Start time of the on going epoch.",
64                    TimeValue (Seconds (0.)),
65                    MakeTimeAccessor (&RadioBearerStatsCalculator::SetStartTime,
66                                      &RadioBearerStatsCalculator::GetStartTime),
67                    MakeTimeChecker ())
68     .AddAttribute ("EpochDuration", "Epoch duration.",
69                    TimeValue (Seconds (0.25)),
70                    MakeTimeAccessor (&RadioBearerStatsCalculator::GetEpoch,
71                                      &RadioBearerStatsCalculator::SetEpoch),
72                    MakeTimeChecker ())
73     .AddAttribute ("DlRlcOutputFilename",
74                    "Name of the file where the downlink results will be saved.",
75                    StringValue ("DlRlcStats.txt"),
76                    MakeStringAccessor (&LteStatsCalculator::SetDlOutputFilename),
77                    MakeStringChecker ())
78     .AddAttribute ("UlRlcOutputFilename",
79                    "Name of the file where the uplink results will be saved.",
80                    StringValue ("UlRlcStats.txt"),
81                    MakeStringAccessor (&LteStatsCalculator::SetUlOutputFilename),
82                    MakeStringChecker ())
83     .AddAttribute ("DlPdcpOutputFilename",
84                    "Name of the file where the downlink results will be saved.",
85                    StringValue ("DlPdcpStats.txt"),
86                    MakeStringAccessor (&RadioBearerStatsCalculator::SetDlPdcpOutputFilename),
87                    MakeStringChecker ())
88     .AddAttribute ("UlPdcpOutputFilename",
89                    "Name of the file where the uplink results will be saved.",
90                    StringValue ("UlPdcpStats.txt"),
91                    MakeStringAccessor (&RadioBearerStatsCalculator::SetUlPdcpOutputFilename),
92                    MakeStringChecker ())
93   ;
94   return tid;
95 }
96 
97 void
DoDispose()98 RadioBearerStatsCalculator::DoDispose ()
99 {
100   NS_LOG_FUNCTION (this);
101   if (m_pendingOutput)
102     {
103       ShowResults ();
104     }
105 }
106 
107 void
SetStartTime(Time t)108 RadioBearerStatsCalculator::SetStartTime (Time t)
109 {
110   m_startTime = t;
111   RescheduleEndEpoch ();
112 }
113 
114 Time
GetStartTime() const115 RadioBearerStatsCalculator::GetStartTime () const
116 {
117   return m_startTime;
118 }
119 
120 void
SetEpoch(Time e)121 RadioBearerStatsCalculator::SetEpoch (Time e)
122 {
123   m_epochDuration = e;
124   RescheduleEndEpoch ();
125 }
126 
127 Time
GetEpoch() const128 RadioBearerStatsCalculator::GetEpoch () const
129 {
130   return m_epochDuration;
131 }
132 
133 void
UlTxPdu(uint16_t cellId,uint64_t imsi,uint16_t rnti,uint8_t lcid,uint32_t packetSize)134 RadioBearerStatsCalculator::UlTxPdu (uint16_t cellId, uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize)
135 {
136   NS_LOG_FUNCTION (this << "UlTxPDU" << cellId << imsi << rnti << (uint32_t) lcid << packetSize);
137   ImsiLcidPair_t p (imsi, lcid);
138   if (Simulator::Now () >= m_startTime)
139     {
140       m_ulCellId[p] = cellId;
141       m_flowId[p] = LteFlowId_t (rnti, lcid);
142       m_ulTxPackets[p]++;
143       m_ulTxData[p] += packetSize;
144     }
145   m_pendingOutput = true;
146 }
147 
148 void
DlTxPdu(uint16_t cellId,uint64_t imsi,uint16_t rnti,uint8_t lcid,uint32_t packetSize)149 RadioBearerStatsCalculator::DlTxPdu (uint16_t cellId, uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize)
150 {
151   NS_LOG_FUNCTION (this << "DlTxPDU" << cellId << imsi << rnti << (uint32_t) lcid << packetSize);
152   ImsiLcidPair_t p (imsi, lcid);
153   if (Simulator::Now () >= m_startTime)
154     {
155       m_dlCellId[p] = cellId;
156       m_flowId[p] = LteFlowId_t (rnti, lcid);
157       m_dlTxPackets[p]++;
158       m_dlTxData[p] += packetSize;
159     }
160   m_pendingOutput = true;
161 }
162 
163 void
UlRxPdu(uint16_t cellId,uint64_t imsi,uint16_t rnti,uint8_t lcid,uint32_t packetSize,uint64_t delay)164 RadioBearerStatsCalculator::UlRxPdu (uint16_t cellId, uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize,
165                                      uint64_t delay)
166 {
167   NS_LOG_FUNCTION (this << "UlRxPDU" << cellId << imsi << rnti << (uint32_t) lcid << packetSize << delay);
168   ImsiLcidPair_t p (imsi, lcid);
169   if (Simulator::Now () >= m_startTime)
170     {
171       m_ulCellId[p] = cellId;
172       m_ulRxPackets[p]++;
173       m_ulRxData[p] += packetSize;
174 
175       Uint64StatsMap::iterator it = m_ulDelay.find (p);
176       if (it == m_ulDelay.end ())
177         {
178           NS_LOG_DEBUG (this << " Creating UL stats calculators for IMSI " << p.m_imsi << " and LCID " << (uint32_t) p.m_lcId);
179           m_ulDelay[p] = CreateObject<MinMaxAvgTotalCalculator<uint64_t> > ();
180           m_ulPduSize[p] = CreateObject<MinMaxAvgTotalCalculator<uint32_t> > ();
181         }
182       m_ulDelay[p]->Update (delay);
183       m_ulPduSize[p]->Update (packetSize);
184     }
185   m_pendingOutput = true;
186 }
187 
188 void
DlRxPdu(uint16_t cellId,uint64_t imsi,uint16_t rnti,uint8_t lcid,uint32_t packetSize,uint64_t delay)189 RadioBearerStatsCalculator::DlRxPdu (uint16_t cellId, uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
190 {
191   NS_LOG_FUNCTION (this << "DlRxPDU" << cellId << imsi << rnti << (uint32_t) lcid << packetSize << delay);
192   ImsiLcidPair_t p (imsi, lcid);
193   if (Simulator::Now () >= m_startTime)
194     {
195       m_dlCellId[p] = cellId;
196       m_dlRxPackets[p]++;
197       m_dlRxData[p] += packetSize;
198 
199       Uint64StatsMap::iterator it = m_dlDelay.find (p);
200       if (it == m_dlDelay.end ())
201         {
202           NS_LOG_DEBUG (this << " Creating DL stats calculators for IMSI " << p.m_imsi << " and LCID " << (uint32_t) p.m_lcId);
203           m_dlDelay[p] = CreateObject<MinMaxAvgTotalCalculator<uint64_t> > ();
204           m_dlPduSize[p] = CreateObject<MinMaxAvgTotalCalculator<uint32_t> > ();
205         }
206       m_dlDelay[p]->Update (delay);
207       m_dlPduSize[p]->Update (packetSize);
208     }
209   m_pendingOutput = true;
210 }
211 
212 void
ShowResults(void)213 RadioBearerStatsCalculator::ShowResults (void)
214 {
215 
216   NS_LOG_FUNCTION (this << GetUlOutputFilename ().c_str () << GetDlOutputFilename ().c_str ());
217   NS_LOG_INFO ("Write Rlc Stats in " << GetUlOutputFilename ().c_str () << " and in " << GetDlOutputFilename ().c_str ());
218 
219   std::ofstream ulOutFile;
220   std::ofstream dlOutFile;
221 
222   if (m_firstWrite == true)
223     {
224       ulOutFile.open (GetUlOutputFilename ().c_str ());
225       if (!ulOutFile.is_open ())
226         {
227           NS_LOG_ERROR ("Can't open file " << GetUlOutputFilename ().c_str ());
228           return;
229         }
230 
231       dlOutFile.open (GetDlOutputFilename ().c_str ());
232       if (!dlOutFile.is_open ())
233         {
234           NS_LOG_ERROR ("Can't open file " << GetDlOutputFilename ().c_str ());
235           return;
236         }
237       m_firstWrite = false;
238       ulOutFile << "% start\tend\tCellId\tIMSI\tRNTI\tLCID\tnTxPDUs\tTxBytes\tnRxPDUs\tRxBytes\t";
239       ulOutFile << "delay\tstdDev\tmin\tmax\t";
240       ulOutFile << "PduSize\tstdDev\tmin\tmax";
241       ulOutFile << std::endl;
242       dlOutFile << "% start\tend\tCellId\tIMSI\tRNTI\tLCID\tnTxPDUs\tTxBytes\tnRxPDUs\tRxBytes\t";
243       dlOutFile << "delay\tstdDev\tmin\tmax\t";
244       dlOutFile << "PduSize\tstdDev\tmin\tmax";
245       dlOutFile << std::endl;
246     }
247   else
248     {
249       ulOutFile.open (GetUlOutputFilename ().c_str (), std::ios_base::app);
250       if (!ulOutFile.is_open ())
251         {
252           NS_LOG_ERROR ("Can't open file " << GetUlOutputFilename ().c_str ());
253           return;
254         }
255 
256       dlOutFile.open (GetDlOutputFilename ().c_str (), std::ios_base::app);
257       if (!dlOutFile.is_open ())
258         {
259           NS_LOG_ERROR ("Can't open file " << GetDlOutputFilename ().c_str ());
260           return;
261         }
262     }
263 
264   WriteUlResults (ulOutFile);
265   WriteDlResults (dlOutFile);
266   m_pendingOutput = false;
267 
268 }
269 
270 void
WriteUlResults(std::ofstream & outFile)271 RadioBearerStatsCalculator::WriteUlResults (std::ofstream& outFile)
272 {
273   NS_LOG_FUNCTION (this);
274 
275   // Get the unique IMSI/LCID pairs list
276   std::vector < ImsiLcidPair_t > pairVector;
277   for (Uint32Map::iterator it = m_ulTxPackets.begin (); it != m_ulTxPackets.end (); ++it)
278     {
279       if (find (pairVector.begin (), pairVector.end (), (*it).first) == pairVector.end ())
280         {
281           pairVector.push_back ((*it).first);
282         }
283     }
284 
285   for (Uint32Map::iterator it = m_ulRxPackets.begin (); it != m_ulRxPackets.end (); ++it)
286     {
287       if (find (pairVector.begin (), pairVector.end (), (*it).first) == pairVector.end ())
288         {
289           pairVector.push_back ((*it).first);
290         }
291     }
292 
293   Time endTime = m_startTime + m_epochDuration;
294   for (std::vector<ImsiLcidPair_t>::iterator it = pairVector.begin (); it != pairVector.end (); ++it)
295     {
296       ImsiLcidPair_t p = *it;
297       FlowIdMap::const_iterator flowIdIt = m_flowId.find (p);
298       NS_ASSERT_MSG (flowIdIt != m_flowId.end (),
299                      "FlowId (imsi " << p.m_imsi << " lcid " << (uint32_t) p.m_lcId << ") is missing");
300       LteFlowId_t flowId = flowIdIt->second;
301       NS_ASSERT_MSG (flowId.m_lcId == p.m_lcId, "lcid mismatch");
302 
303       outFile << m_startTime.GetSeconds () << "\t";
304       outFile << endTime.GetSeconds () << "\t";
305       outFile << GetUlCellId (p.m_imsi, p.m_lcId) << "\t";
306       outFile << p.m_imsi << "\t";
307       outFile << flowId.m_rnti << "\t";
308       outFile << (uint32_t) flowId.m_lcId << "\t";
309       outFile << GetUlTxPackets (p.m_imsi, p.m_lcId) << "\t";
310       outFile << GetUlTxData (p.m_imsi, p.m_lcId) << "\t";
311       outFile << GetUlRxPackets (p.m_imsi, p.m_lcId) << "\t";
312       outFile << GetUlRxData (p.m_imsi, p.m_lcId) << "\t";
313       std::vector<double> stats = GetUlDelayStats (p.m_imsi, p.m_lcId);
314       for (std::vector<double>::iterator it = stats.begin (); it != stats.end (); ++it)
315         {
316           outFile << (*it) * 1e-9 << "\t";
317         }
318       stats = GetUlPduSizeStats (p.m_imsi, p.m_lcId);
319       for (std::vector<double>::iterator it = stats.begin (); it != stats.end (); ++it)
320         {
321           outFile << (*it) << "\t";
322         }
323       outFile << std::endl;
324     }
325 
326   outFile.close ();
327 }
328 
329 void
WriteDlResults(std::ofstream & outFile)330 RadioBearerStatsCalculator::WriteDlResults (std::ofstream& outFile)
331 {
332   NS_LOG_FUNCTION (this);
333 
334   // Get the unique IMSI/LCID pairs list
335   std::vector < ImsiLcidPair_t > pairVector;
336   for (Uint32Map::iterator it = m_dlTxPackets.begin (); it != m_dlTxPackets.end (); ++it)
337     {
338       if (find (pairVector.begin (), pairVector.end (), (*it).first) == pairVector.end ())
339         {
340           pairVector.push_back ((*it).first);
341         }
342     }
343 
344   for (Uint32Map::iterator it = m_dlRxPackets.begin (); it != m_dlRxPackets.end (); ++it)
345     {
346       if (find (pairVector.begin (), pairVector.end (), (*it).first) == pairVector.end ())
347         {
348           pairVector.push_back ((*it).first);
349         }
350     }
351 
352   Time endTime = m_startTime + m_epochDuration;
353   for (std::vector<ImsiLcidPair_t>::iterator pair = pairVector.begin (); pair != pairVector.end (); ++pair)
354     {
355       ImsiLcidPair_t p = *pair;
356       FlowIdMap::const_iterator flowIdIt = m_flowId.find (p);
357       NS_ASSERT_MSG (flowIdIt != m_flowId.end (),
358                      "FlowId (imsi " << p.m_imsi << " lcid " << (uint32_t) p.m_lcId << ") is missing");
359       LteFlowId_t flowId = flowIdIt->second;
360       NS_ASSERT_MSG (flowId.m_lcId == p.m_lcId, "lcid mismatch");
361 
362       outFile << m_startTime.GetSeconds () << "\t";
363       outFile << endTime.GetSeconds () << "\t";
364       outFile << GetDlCellId (p.m_imsi, p.m_lcId) << "\t";
365       outFile << p.m_imsi << "\t";
366       outFile << flowId.m_rnti << "\t";
367       outFile << (uint32_t) flowId.m_lcId << "\t";
368       outFile << GetDlTxPackets (p.m_imsi, p.m_lcId) << "\t";
369       outFile << GetDlTxData (p.m_imsi, p.m_lcId) << "\t";
370       outFile << GetDlRxPackets (p.m_imsi, p.m_lcId) << "\t";
371       outFile << GetDlRxData (p.m_imsi, p.m_lcId) << "\t";
372       std::vector<double> stats = GetDlDelayStats (p.m_imsi, p.m_lcId);
373       for (std::vector<double>::iterator it = stats.begin (); it != stats.end (); ++it)
374         {
375           outFile << (*it) * 1e-9 << "\t";
376         }
377       stats = GetDlPduSizeStats (p.m_imsi, p.m_lcId);
378       for (std::vector<double>::iterator it = stats.begin (); it != stats.end (); ++it)
379         {
380           outFile << (*it) << "\t";
381         }
382       outFile << std::endl;
383     }
384 
385   outFile.close ();
386 }
387 
388 void
ResetResults(void)389 RadioBearerStatsCalculator::ResetResults (void)
390 {
391   NS_LOG_FUNCTION (this);
392 
393   m_ulTxPackets.erase (m_ulTxPackets.begin (), m_ulTxPackets.end ());
394   m_ulRxPackets.erase (m_ulRxPackets.begin (), m_ulRxPackets.end ());
395   m_ulRxData.erase (m_ulRxData.begin (), m_ulRxData.end ());
396   m_ulTxData.erase (m_ulTxData.begin (), m_ulTxData.end ());
397   m_ulDelay.erase (m_ulDelay.begin (), m_ulDelay.end ());
398   m_ulPduSize.erase (m_ulPduSize.begin (), m_ulPduSize.end ());
399 
400   m_dlTxPackets.erase (m_dlTxPackets.begin (), m_dlTxPackets.end ());
401   m_dlRxPackets.erase (m_dlRxPackets.begin (), m_dlRxPackets.end ());
402   m_dlRxData.erase (m_dlRxData.begin (), m_dlRxData.end ());
403   m_dlTxData.erase (m_dlTxData.begin (), m_dlTxData.end ());
404   m_dlDelay.erase (m_dlDelay.begin (), m_dlDelay.end ());
405   m_dlPduSize.erase (m_dlPduSize.begin (), m_dlPduSize.end ());
406 }
407 
408 void
RescheduleEndEpoch(void)409 RadioBearerStatsCalculator::RescheduleEndEpoch (void)
410 {
411   NS_LOG_FUNCTION (this);
412   m_endEpochEvent.Cancel ();
413   NS_ASSERT (Simulator::Now ().GetMilliSeconds () == 0); // below event time assumes this
414   m_endEpochEvent = Simulator::Schedule (m_startTime + m_epochDuration, &RadioBearerStatsCalculator::EndEpoch, this);
415 }
416 
417 void
EndEpoch(void)418 RadioBearerStatsCalculator::EndEpoch (void)
419 {
420   NS_LOG_FUNCTION (this);
421   ShowResults ();
422   ResetResults ();
423   m_startTime += m_epochDuration;
424   m_endEpochEvent = Simulator::Schedule (m_epochDuration, &RadioBearerStatsCalculator::EndEpoch, this);
425 }
426 
427 uint32_t
GetUlTxPackets(uint64_t imsi,uint8_t lcid)428 RadioBearerStatsCalculator::GetUlTxPackets (uint64_t imsi, uint8_t lcid)
429 {
430   NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid);
431   ImsiLcidPair_t p (imsi, lcid);
432   return m_ulTxPackets[p];
433 }
434 
435 uint32_t
GetUlRxPackets(uint64_t imsi,uint8_t lcid)436 RadioBearerStatsCalculator::GetUlRxPackets (uint64_t imsi, uint8_t lcid)
437 {
438   NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid);
439   ImsiLcidPair_t p (imsi, lcid);
440   return m_ulRxPackets[p];
441 }
442 
443 uint64_t
GetUlTxData(uint64_t imsi,uint8_t lcid)444 RadioBearerStatsCalculator::GetUlTxData (uint64_t imsi, uint8_t lcid)
445 {
446   NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid);
447   ImsiLcidPair_t p (imsi, lcid);
448   return m_ulTxData[p];
449 }
450 
451 uint64_t
GetUlRxData(uint64_t imsi,uint8_t lcid)452 RadioBearerStatsCalculator::GetUlRxData (uint64_t imsi, uint8_t lcid)
453 {
454   NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid);
455   ImsiLcidPair_t p (imsi, lcid);
456   return m_ulRxData[p];
457 }
458 
459 double
GetUlDelay(uint64_t imsi,uint8_t lcid)460 RadioBearerStatsCalculator::GetUlDelay (uint64_t imsi, uint8_t lcid)
461 {
462   NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid);
463   ImsiLcidPair_t p (imsi, lcid);
464   Uint64StatsMap::iterator it = m_ulDelay.find (p);
465   if (it == m_ulDelay.end ())
466     {
467       NS_LOG_ERROR ("UL delay for " << imsi << " - " << (uint16_t) lcid << " not found");
468       return 0;
469 
470     }
471   return m_ulDelay[p]->getMean ();
472 }
473 
474 std::vector<double>
GetUlDelayStats(uint64_t imsi,uint8_t lcid)475 RadioBearerStatsCalculator::GetUlDelayStats (uint64_t imsi, uint8_t lcid)
476 {
477   NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid);
478   ImsiLcidPair_t p (imsi, lcid);
479   std::vector<double> stats;
480   Uint64StatsMap::iterator it = m_ulDelay.find (p);
481   if (it == m_ulDelay.end ())
482     {
483       stats.push_back (0.0);
484       stats.push_back (0.0);
485       stats.push_back (0.0);
486       stats.push_back (0.0);
487       return stats;
488 
489     }
490   stats.push_back (m_ulDelay[p]->getMean ());
491   stats.push_back (m_ulDelay[p]->getStddev ());
492   stats.push_back (m_ulDelay[p]->getMin ());
493   stats.push_back (m_ulDelay[p]->getMax ());
494   return stats;
495 }
496 
497 std::vector<double>
GetUlPduSizeStats(uint64_t imsi,uint8_t lcid)498 RadioBearerStatsCalculator::GetUlPduSizeStats (uint64_t imsi, uint8_t lcid)
499 {
500   NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid);
501   ImsiLcidPair_t p (imsi, lcid);
502   std::vector<double> stats;
503   Uint32StatsMap::iterator it = m_ulPduSize.find (p);
504   if (it == m_ulPduSize.end ())
505     {
506       stats.push_back (0.0);
507       stats.push_back (0.0);
508       stats.push_back (0.0);
509       stats.push_back (0.0);
510       return stats;
511 
512     }
513   stats.push_back (m_ulPduSize[p]->getMean ());
514   stats.push_back (m_ulPduSize[p]->getStddev ());
515   stats.push_back (m_ulPduSize[p]->getMin ());
516   stats.push_back (m_ulPduSize[p]->getMax ());
517   return stats;
518 }
519 
520 uint32_t
GetDlTxPackets(uint64_t imsi,uint8_t lcid)521 RadioBearerStatsCalculator::GetDlTxPackets (uint64_t imsi, uint8_t lcid)
522 {
523   NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid);
524   ImsiLcidPair_t p (imsi, lcid);
525   return m_dlTxPackets[p];
526 }
527 
528 uint32_t
GetDlRxPackets(uint64_t imsi,uint8_t lcid)529 RadioBearerStatsCalculator::GetDlRxPackets (uint64_t imsi, uint8_t lcid)
530 {
531   NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid);
532   ImsiLcidPair_t p (imsi, lcid);
533   return m_dlRxPackets[p];
534 }
535 
536 uint64_t
GetDlTxData(uint64_t imsi,uint8_t lcid)537 RadioBearerStatsCalculator::GetDlTxData (uint64_t imsi, uint8_t lcid)
538 {
539   NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid);
540   ImsiLcidPair_t p (imsi, lcid);
541   return m_dlTxData[p];
542 }
543 
544 uint64_t
GetDlRxData(uint64_t imsi,uint8_t lcid)545 RadioBearerStatsCalculator::GetDlRxData (uint64_t imsi, uint8_t lcid)
546 {
547   NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid);
548   ImsiLcidPair_t p (imsi, lcid);
549   return m_dlRxData[p];
550 }
551 
552 uint32_t
GetUlCellId(uint64_t imsi,uint8_t lcid)553 RadioBearerStatsCalculator::GetUlCellId (uint64_t imsi, uint8_t lcid)
554 {
555   NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid);
556   ImsiLcidPair_t p (imsi, lcid);
557   return m_ulCellId[p];
558 }
559 
560 uint32_t
GetDlCellId(uint64_t imsi,uint8_t lcid)561 RadioBearerStatsCalculator::GetDlCellId (uint64_t imsi, uint8_t lcid)
562 {
563   NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid);
564   ImsiLcidPair_t p (imsi, lcid);
565   return m_dlCellId[p];
566 }
567 
568 double
GetDlDelay(uint64_t imsi,uint8_t lcid)569 RadioBearerStatsCalculator::GetDlDelay (uint64_t imsi, uint8_t lcid)
570 {
571   NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid);
572   ImsiLcidPair_t p (imsi, lcid);
573   Uint64StatsMap::iterator it = m_dlDelay.find (p);
574   if (it == m_dlDelay.end ())
575     {
576       NS_LOG_ERROR ("DL delay for " << imsi << " not found");
577       return 0;
578     }
579   return m_dlDelay[p]->getMean ();
580 }
581 
582 std::vector<double>
GetDlDelayStats(uint64_t imsi,uint8_t lcid)583 RadioBearerStatsCalculator::GetDlDelayStats (uint64_t imsi, uint8_t lcid)
584 {
585   NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid);
586   ImsiLcidPair_t p (imsi, lcid);
587   std::vector<double> stats;
588   Uint64StatsMap::iterator it = m_dlDelay.find (p);
589   if (it == m_dlDelay.end ())
590     {
591       stats.push_back (0.0);
592       stats.push_back (0.0);
593       stats.push_back (0.0);
594       stats.push_back (0.0);
595       return stats;
596 
597     }
598   stats.push_back (m_dlDelay[p]->getMean ());
599   stats.push_back (m_dlDelay[p]->getStddev ());
600   stats.push_back (m_dlDelay[p]->getMin ());
601   stats.push_back (m_dlDelay[p]->getMax ());
602   return stats;
603 }
604 
605 std::vector<double>
GetDlPduSizeStats(uint64_t imsi,uint8_t lcid)606 RadioBearerStatsCalculator::GetDlPduSizeStats (uint64_t imsi, uint8_t lcid)
607 {
608   NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid);
609   ImsiLcidPair_t p (imsi, lcid);
610   std::vector<double> stats;
611   Uint32StatsMap::iterator it = m_dlPduSize.find (p);
612   if (it == m_dlPduSize.end ())
613     {
614       stats.push_back (0.0);
615       stats.push_back (0.0);
616       stats.push_back (0.0);
617       stats.push_back (0.0);
618       return stats;
619 
620     }
621   stats.push_back (m_dlPduSize[p]->getMean ());
622   stats.push_back (m_dlPduSize[p]->getStddev ());
623   stats.push_back (m_dlPduSize[p]->getMin ());
624   stats.push_back (m_dlPduSize[p]->getMax ());
625   return stats;
626 }
627 
628 std::string
GetUlOutputFilename(void)629 RadioBearerStatsCalculator::GetUlOutputFilename (void)
630 {
631   if (m_protocolType == "RLC")
632     {
633       return LteStatsCalculator::GetUlOutputFilename ();
634     }
635   else
636     {
637       return GetUlPdcpOutputFilename ();
638     }
639 }
640 
641 std::string
GetDlOutputFilename(void)642 RadioBearerStatsCalculator::GetDlOutputFilename (void)
643 {
644   if (m_protocolType == "RLC")
645     {
646       return LteStatsCalculator::GetDlOutputFilename ();
647     }
648   else
649     {
650       return GetDlPdcpOutputFilename ();
651     }
652 }
653 
654 void
SetUlPdcpOutputFilename(std::string outputFilename)655 RadioBearerStatsCalculator::SetUlPdcpOutputFilename (std::string outputFilename)
656 {
657   m_ulPdcpOutputFilename = outputFilename;
658 }
659 
660 std::string
GetUlPdcpOutputFilename(void)661 RadioBearerStatsCalculator::GetUlPdcpOutputFilename (void)
662 {
663   return m_ulPdcpOutputFilename;
664 }
665 void
SetDlPdcpOutputFilename(std::string outputFilename)666 RadioBearerStatsCalculator::SetDlPdcpOutputFilename (std::string outputFilename)
667 {
668   m_dlPdcpOutputFilename = outputFilename;
669 }
670 
671 std::string
GetDlPdcpOutputFilename(void)672 RadioBearerStatsCalculator::GetDlPdcpOutputFilename (void)
673 {
674   return m_dlPdcpOutputFilename;
675 }
676 
677 } // namespace ns3
678