--- a/src/lte/helper/rlc-stats-calculator.cc Fri Apr 01 12:02:18 2011 +0200
+++ b/src/lte/helper/rlc-stats-calculator.cc Mon Apr 04 18:17:17 2011 +0200
@@ -22,6 +22,8 @@
#include "ns3/string.h"
#include "ns3/nstime.h"
#include <ns3/log.h>
+#include <vector>
+#include <algorithm>
namespace ns3 {
@@ -30,7 +32,8 @@
NS_OBJECT_ENSURE_REGISTERED (RlcStatsCalculator);
RlcStatsCalculator::RlcStatsCalculator() :
- m_outputFilename ("")
+ m_outputFilename (""),
+ m_firstWrite(true)
{
NS_LOG_FUNCTION (this);
@@ -53,6 +56,15 @@
StringValue ("RlcStats.csv"),
MakeStringAccessor (&RlcStatsCalculator::SetOutputFilename),
MakeStringChecker ())
+ .AddAttribute ("StartTime",
+ "Start time of the on going epoch.",
+ TimeValue ( Seconds(0.) ),
+ MakeTimeAccessor (&RlcStatsCalculator::m_startTime),
+ MakeTimeChecker ())
+ .AddAttribute("EpochDuration",
+ "Epoch duration.", TimeValue(Seconds(0.25)),
+ MakeTimeAccessor(&RlcStatsCalculator::m_epochDuration),
+ MakeTimeChecker())
;
return tid;
}
@@ -67,81 +79,117 @@
RlcStatsCalculator::TxPdu (uint16_t rnti, uint8_t lcid, uint32_t packetSize)
{
NS_LOG_FUNCTION (this << "TxPDU" << rnti << (uint32_t) lcid << packetSize);
- lteFlowId_t pair (rnti, lcid);
-
- m_txPackets[pair]++;
+ if (Simulator::Now () > m_startTime )
+ {
+ lteFlowId_t pair (rnti, lcid);
+ m_txPackets[pair]++;
+ }
+ CheckEpoch ();
}
void
RlcStatsCalculator::RxPdu (uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
{
NS_LOG_FUNCTION (this << "RxPDU" << rnti << (uint32_t) lcid << packetSize << delay);
- lteFlowId_t pair (rnti, lcid);
-
- m_rxPackets [pair]++;
- m_rxData [pair] += packetSize;
+ if (Simulator::Now () > m_startTime )
+ {
+ lteFlowId_t pair(rnti, lcid);
+ m_rxPackets[pair]++;
+ m_rxData[pair] += packetSize;
+ m_throughput[pair] = 8 * m_rxData[pair] / 1.0e9 * (Simulator::Now().GetNanoSeconds() - m_startTime.GetNanoSeconds());
- uint64StatsMap::iterator it = m_delay.find (pair);
- if ( it == m_delay.end () )
- {
- m_delay[pair] = CreateObject <MinMaxAvgTotalCalculator<uint64_t> > ();
+ uint64StatsMap::iterator it = m_delay.find(pair);
+ if (it == m_delay.end())
+ {
+ m_delay[pair] = CreateObject<MinMaxAvgTotalCalculator<uint64_t> > ();
+ }
+ m_delay[pair]->Update(delay);
}
- m_delay[pair]->Update (delay);
+ CheckEpoch ();
}
void
RlcStatsCalculator::ShowResults (void)
{
uint32Map::iterator it;
- uint64Map::iterator itData;
- uint64StatsMap::iterator itDelay;
+
NS_LOG_FUNCTION (this << m_outputFilename.c_str ());
NS_LOG_INFO ("Write Rlc Stats in: " << m_outputFilename.c_str ());
std::ofstream m_outFile;
- m_outFile.open (m_outputFilename.c_str ());
- if (! m_outFile.is_open ())
- {
- NS_LOG_ERROR ("Can't open file " << m_outputFilename.c_str ());
- return;
- }
+ if ( m_firstWrite == true )
+ {
+ m_outFile.open (m_outputFilename.c_str ());
+ if (! m_outFile.is_open ())
+ {
+ NS_LOG_ERROR ("Can't open file " << m_outputFilename.c_str ());
+ return;
+ }
+ m_firstWrite = false;
+ m_outFile << "# startTime, endTime, RNTI, LCID, throughput (bps), delay (s), PDU loss ratio (%)" << std::endl;
+ }
+ else
+ {
+ m_outFile.open (m_outputFilename.c_str (), std::ios_base::app);
+ if (! m_outFile.is_open ())
+ {
+ NS_LOG_ERROR ("Can't open file " << m_outputFilename.c_str ());
+ return;
+ }
+ }
- m_outFile << "# Parameter, RNTI, LCID, value" << std::endl;
+
+
+ // Get all the unique lteFlowIds in the calculator
+ std::vector<lteFlowId_t> lteFlowIds;
for ( it = m_txPackets.begin(); it != m_txPackets.end(); ++it)
{
- m_outFile << "TxPackets, " << (*it).first.m_rnti << ", "
- << (uint32_t) (*it).first.m_lcId << ", "
- << (*it).second << std::endl;
- }
- for ( it = m_rxPackets.begin(); it != m_rxPackets.end(); ++it)
- {
- m_outFile << "RxPackets, " << (*it).first.m_rnti << ", "
- << (uint32_t) (*it).first.m_lcId << ", "
- << (*it).second << std::endl;
- }
- for ( itData = m_rxData.begin(); itData != m_rxData.end(); ++itData)
- {
- m_outFile << "RxData, " << (*itData).first.m_rnti << ", "
- << (uint32_t) (*itData).first.m_lcId << ", "
- << (*itData).second << std::endl;
- }
- for ( itData = m_rxData.begin(); itData != m_rxData.end(); ++itData)
- {
- m_outFile << "Throughput, " << (*itData).first.m_rnti << ", "
- << (uint32_t) (*itData).first.m_lcId << ", "
- << GetThroughput ((*itData).first) << std::endl;
- }
- for ( itDelay = m_delay.begin (); itDelay != m_delay.end (); ++itDelay)
- {
- m_outFile << "Delay, " << (*itDelay).first.m_rnti << ", "
- << (uint32_t) (*itDelay).first.m_lcId << ", "
- << GetDelay ((*itDelay).first) << std::endl;
+ if (find (lteFlowIds.begin (), lteFlowIds.end (), (*it).first ) == lteFlowIds.end () )
+ {
+ lteFlowIds.push_back ((*it).first);
+ }
}
+ std::vector<lteFlowId_t>::iterator itFlow;
+ Time endTime = m_startTime + m_epochDuration;
+ for ( itFlow = lteFlowIds.begin(); itFlow != lteFlowIds.end(); ++itFlow)
+ {
+ m_outFile << m_startTime.GetNanoSeconds () / 1.0e9 << " " << endTime.GetNanoSeconds() / 1.0e9;
+ m_outFile << " " << (*itFlow).m_rnti << " " << (uint32_t) (*itFlow).m_lcId << " " << GetThroughput (*itFlow);
+ m_outFile << " " << GetDelay(*itFlow) << " " << GetPacketLossProbability (*itFlow) << std::endl;
+ }
m_outFile.close ();
}
+void
+RlcStatsCalculator::ResetResults (void)
+{
+ m_txPackets.erase (m_txPackets.begin (), m_txPackets.end () );
+ m_rxPackets.erase (m_rxPackets.begin (), m_rxPackets.end () );
+ m_rxData.erase (m_rxData.begin (), m_rxData.end () );
+ m_throughput.erase (m_throughput.begin (), m_throughput.end () );
+ m_delay.erase (m_delay.begin (), m_delay.end () );
+}
+
+void
+RlcStatsCalculator::CheckEpoch (void)
+{
+ if ( Simulator::Now () > m_startTime + m_epochDuration )
+ {
+ ShowResults();
+ ResetResults();
+ StartEpoch();
+ }
+
+}
+
+void
+RlcStatsCalculator::StartEpoch (void)
+{
+ m_startTime += m_epochDuration;
+}
+
uint32_t
RlcStatsCalculator::GetTxPackets (lteFlowId_t p)
{
@@ -174,10 +222,13 @@
double
RlcStatsCalculator::GetThroughput (lteFlowId_t p)
{
- // TODO: Fix throughput calculation with the correct time
- // NOTE: At this moment, Simulator::Now() is not available anymore
- //return (double) m_rxData[p] / Simulator::Now().GetSeconds();
- return 0;
+ return m_throughput[p];
+}
+
+double
+RlcStatsCalculator::GetPacketLossProbability (lteFlowId_t p)
+{
+ return (GetTxPackets (p) - GetRxPackets (p)) / (double) GetTxPackets (p);
}
uint32_t
@@ -215,4 +266,11 @@
return GetThroughput (p);
}
+double
+RlcStatsCalculator::GetPacketLossProbability (uint16_t rnti, uint8_t lcid)
+{
+ lteFlowId_t p (rnti, lcid);
+ return GetPacketLossProbability (p);
+}
+
} // namespace ns3
--- a/src/lte/helper/rlc-stats-calculator.h Fri Apr 01 12:02:18 2011 +0200
+++ b/src/lte/helper/rlc-stats-calculator.h Mon Apr 04 18:17:17 2011 +0200
@@ -35,6 +35,7 @@
typedef std::map<lteFlowId_t, uint32_t> uint32Map;
typedef std::map<lteFlowId_t, uint64_t> uint64Map;
typedef std::map<lteFlowId_t, Ptr<MinMaxAvgTotalCalculator<uint64_t> > > uint64StatsMap;
+typedef std::map<lteFlowId_t, double> doubleMap;
class RlcStatsCalculator : public Object
@@ -55,21 +56,42 @@
uint64_t GetRxData (lteFlowId_t p);
uint64_t GetDelay (lteFlowId_t p);
double GetThroughput (lteFlowId_t p);
+ double GetPacketLossProbability (lteFlowId_t p);
uint32_t GetTxPackets (uint16_t rnti, uint8_t lcid);
uint32_t GetRxPackets (uint16_t rnti, uint8_t lcid);
uint64_t GetRxData (uint16_t rnti, uint8_t lcid);
uint64_t GetDelay (uint16_t rnti, uint8_t lcid);
double GetThroughput (uint16_t rnti, uint8_t lcid);
+ double GetPacketLossProbability (uint16_t rnti, uint8_t lcid);
private:
void ShowResults (void);
+ void ResetResults (void);
+
+ void StartEpoch (void);
+ void CheckEpoch (void);
+
std::string m_outputFilename;
std::ofstream m_outFile;
uint32Map m_txPackets;
uint32Map m_rxPackets;
uint64Map m_rxData;
+ doubleMap m_throughput;
uint64StatsMap m_delay;
+
+ /**
+ * Start time of the on going epoch
+ */
+ Time m_startTime;
+
+ /**
+ * Epoch duration
+ */
+ Time m_epochDuration;
+
+ bool m_firstWrite;
+
};
} // namespace ns3