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