Added DL and UL RLC performance
Added new output data as described in Requirements Documents
This commit is contained in:
@@ -26,20 +26,32 @@
|
||||
#include "ns3/rlc-stats-calculator.h"
|
||||
|
||||
|
||||
//#include "ns3/gtk-config-store.h"
|
||||
#include "ns3/gtk-config-store.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
void TxPduCallback(Ptr<RlcStatsCalculator> rlcStats, std::string path,
|
||||
void UlTxPduCallback(Ptr<RlcStatsCalculator> rlcStats, std::string path,
|
||||
uint16_t rnti, uint8_t lcid, uint32_t packetSize)
|
||||
{
|
||||
rlcStats->TxPdu(rnti, lcid, packetSize);
|
||||
rlcStats->UlTxPdu(rnti, lcid, packetSize);
|
||||
}
|
||||
|
||||
void RxPduCallback(Ptr<RlcStatsCalculator> rlcStats, std::string path,
|
||||
void UlRxPduCallback(Ptr<RlcStatsCalculator> rlcStats, std::string path,
|
||||
uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
|
||||
{
|
||||
rlcStats->RxPdu(rnti, lcid, packetSize, delay);
|
||||
rlcStats->UlRxPdu(rnti, lcid, packetSize, delay);
|
||||
}
|
||||
|
||||
void DlTxPduCallback(Ptr<RlcStatsCalculator> rlcStats, std::string path,
|
||||
uint16_t rnti, uint8_t lcid, uint32_t packetSize)
|
||||
{
|
||||
rlcStats->DlTxPdu(rnti, lcid, packetSize);
|
||||
}
|
||||
|
||||
void DlRxPduCallback(Ptr<RlcStatsCalculator> rlcStats, std::string path,
|
||||
uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
|
||||
{
|
||||
rlcStats->DlRxPdu(rnti, lcid, packetSize, delay);
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
@@ -51,7 +63,7 @@ int main (int argc, char *argv[])
|
||||
cmd.Parse (argc, argv);
|
||||
|
||||
// Enable LTE log components
|
||||
lena.EnableLogComponents ();
|
||||
//lena.EnableLogComponents ();
|
||||
|
||||
// Create Nodes: eNodeB and UE
|
||||
NodeContainer enbNodes;
|
||||
@@ -80,20 +92,25 @@ int main (int argc, char *argv[])
|
||||
EpsBearer bearer (q);
|
||||
lena.ActivateEpsBearer (ueDevs, bearer);
|
||||
|
||||
Simulator::Stop (Seconds (0.1));
|
||||
Simulator::Stop (Seconds (4));
|
||||
|
||||
// Insert RLC Performance Calculator
|
||||
Ptr<RlcStatsCalculator> rlcStats = CreateObject<RlcStatsCalculator> ();
|
||||
Config::Connect("/NodeList/0/DeviceList/0/LteEnbRrc/UeMap/*/RadioBearerMap/*/LteRlc/TxPDU",
|
||||
MakeBoundCallback(&TxPduCallback, rlcStats));
|
||||
MakeBoundCallback(&DlTxPduCallback, rlcStats));
|
||||
Config::Connect("/NodeList/*/DeviceList/0/LteUeRrc/RlcMap/*/RxPDU",
|
||||
MakeBoundCallback(&DlRxPduCallback, rlcStats));
|
||||
|
||||
Config::Connect("/NodeList/*/DeviceList/0/LteUeRrc/RlcMap/*/TxPDU",
|
||||
MakeBoundCallback(&UlTxPduCallback, rlcStats));
|
||||
Config::Connect ("/NodeList/0/DeviceList/0/LteEnbRrc/UeMap/*/RadioBearerMap/*/LteRlc/RxPDU",
|
||||
MakeBoundCallback(&RxPduCallback, rlcStats));
|
||||
MakeBoundCallback(&UlRxPduCallback, rlcStats));
|
||||
|
||||
Simulator::Run ();
|
||||
|
||||
// Uncomment to show available paths
|
||||
//GtkConfigStore config;
|
||||
//config.ConfigureAttributes ();
|
||||
/*GtkConfigStore config;
|
||||
config.ConfigureAttributes ();*/
|
||||
|
||||
Simulator::Destroy ();
|
||||
|
||||
|
||||
@@ -32,7 +32,8 @@ NS_LOG_COMPONENT_DEFINE ("RlcStatsCalculator");
|
||||
NS_OBJECT_ENSURE_REGISTERED (RlcStatsCalculator);
|
||||
|
||||
RlcStatsCalculator::RlcStatsCalculator() :
|
||||
m_outputFilename (""),
|
||||
m_dlOutputFilename (""),
|
||||
m_ulOutputFilename (""),
|
||||
m_firstWrite(true)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
@@ -51,10 +52,15 @@ RlcStatsCalculator::GetTypeId (void)
|
||||
static TypeId tid = TypeId ("ns3::RlcStatsCalculator")
|
||||
.SetParent<Object> ()
|
||||
.AddConstructor<RlcStatsCalculator> ()
|
||||
.AddAttribute ("OutputFilename",
|
||||
"Name of the file where the output will be saved.",
|
||||
StringValue ("RlcStats.csv"),
|
||||
MakeStringAccessor (&RlcStatsCalculator::SetOutputFilename),
|
||||
.AddAttribute ("DlOutputFilename",
|
||||
"Name of the file where the downlink results will be saved.",
|
||||
StringValue ("DlRlcStats.csv"),
|
||||
MakeStringAccessor (&RlcStatsCalculator::SetDlOutputFilename),
|
||||
MakeStringChecker ())
|
||||
.AddAttribute ("UlOutputFilename",
|
||||
"Name of the file where the uplink results will be saved.",
|
||||
StringValue ("UlRlcStats.csv"),
|
||||
MakeStringAccessor (&RlcStatsCalculator::SetUlOutputFilename),
|
||||
MakeStringChecker ())
|
||||
.AddAttribute ("StartTime",
|
||||
"Start time of the on going epoch.",
|
||||
@@ -70,40 +76,81 @@ RlcStatsCalculator::GetTypeId (void)
|
||||
}
|
||||
|
||||
void
|
||||
RlcStatsCalculator::SetOutputFilename (std::string outputFilename)
|
||||
RlcStatsCalculator::SetUlOutputFilename (std::string outputFilename)
|
||||
{
|
||||
m_outputFilename = outputFilename;
|
||||
m_ulOutputFilename = outputFilename;
|
||||
}
|
||||
|
||||
void
|
||||
RlcStatsCalculator::TxPdu (uint16_t rnti, uint8_t lcid, uint32_t packetSize)
|
||||
RlcStatsCalculator::SetDlOutputFilename (std::string outputFilename)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << "TxPDU" << rnti << (uint32_t) lcid << packetSize);
|
||||
m_dlOutputFilename = outputFilename;
|
||||
}
|
||||
|
||||
void
|
||||
RlcStatsCalculator::UlTxPdu (uint16_t rnti, uint8_t lcid, uint32_t packetSize)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << "UlTxPDU" << rnti << (uint32_t) lcid << packetSize);
|
||||
if (Simulator::Now () > m_startTime )
|
||||
{
|
||||
lteFlowId_t pair (rnti, lcid);
|
||||
m_txPackets[pair]++;
|
||||
m_ulTxPackets[pair]++;
|
||||
}
|
||||
CheckEpoch ();
|
||||
}
|
||||
|
||||
void
|
||||
RlcStatsCalculator::RxPdu (uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
|
||||
RlcStatsCalculator::DlTxPdu (uint16_t rnti, uint8_t lcid, uint32_t packetSize)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << "RxPDU" << rnti << (uint32_t) lcid << packetSize << delay);
|
||||
NS_LOG_FUNCTION (this << "DlTxPDU" << rnti << (uint32_t) lcid << packetSize);
|
||||
if (Simulator::Now () > m_startTime )
|
||||
{
|
||||
lteFlowId_t pair (rnti, lcid);
|
||||
m_dlTxPackets[pair]++;
|
||||
}
|
||||
CheckEpoch ();
|
||||
}
|
||||
|
||||
void
|
||||
RlcStatsCalculator::UlRxPdu (uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << "UlRxPDU" << rnti << (uint32_t) lcid << packetSize << delay);
|
||||
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());
|
||||
m_ulRxPackets[pair]++;
|
||||
m_ulRxData[pair] += packetSize;
|
||||
|
||||
uint64StatsMap::iterator it = m_delay.find(pair);
|
||||
if (it == m_delay.end())
|
||||
uint64StatsMap::iterator it = m_ulDelay.find(pair);
|
||||
if (it == m_ulDelay.end())
|
||||
{
|
||||
m_delay[pair] = CreateObject<MinMaxAvgTotalCalculator<uint64_t> > ();
|
||||
}
|
||||
m_delay[pair]->Update(delay);
|
||||
m_ulDelay[pair] = CreateObject<MinMaxAvgTotalCalculator<uint64_t> > ();
|
||||
m_ulPduSize[pair] = CreateObject<MinMaxAvgTotalCalculator<uint32_t> > ();
|
||||
}
|
||||
m_ulDelay[pair]->Update (delay);
|
||||
m_ulPduSize[pair]->Update (packetSize);
|
||||
}
|
||||
CheckEpoch ();
|
||||
}
|
||||
|
||||
void
|
||||
RlcStatsCalculator::DlRxPdu (uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << "UlRxPDU" << rnti << (uint32_t) lcid << packetSize << delay);
|
||||
if (Simulator::Now () > m_startTime )
|
||||
{
|
||||
lteFlowId_t pair(rnti, lcid);
|
||||
m_dlRxPackets[pair]++;
|
||||
m_dlRxData[pair] += packetSize;
|
||||
|
||||
uint64StatsMap::iterator it = m_dlDelay.find(pair);
|
||||
if (it == m_dlDelay.end())
|
||||
{
|
||||
m_dlDelay[pair] = CreateObject<MinMaxAvgTotalCalculator<uint64_t> > ();
|
||||
m_dlPduSize[pair] = CreateObject<MinMaxAvgTotalCalculator<uint32_t> > ();
|
||||
}
|
||||
m_dlDelay[pair]->Update(delay);
|
||||
m_dlPduSize[pair]->Update (packetSize);
|
||||
}
|
||||
CheckEpoch ();
|
||||
}
|
||||
@@ -111,39 +158,69 @@ RlcStatsCalculator::RxPdu (uint16_t rnti, uint8_t lcid, uint32_t packetSize, uin
|
||||
void
|
||||
RlcStatsCalculator::ShowResults (void)
|
||||
{
|
||||
uint32Map::iterator it;
|
||||
|
||||
|
||||
NS_LOG_FUNCTION (this << m_outputFilename.c_str ());
|
||||
NS_LOG_INFO ("Write Rlc Stats in: " << m_outputFilename.c_str ());
|
||||
NS_LOG_FUNCTION (this << m_ulOutputFilename.c_str () << m_dlOutputFilename.c_str () );
|
||||
NS_LOG_INFO ("Write Rlc Stats in " << m_ulOutputFilename.c_str () <<
|
||||
" and in " << m_dlOutputFilename.c_str ());
|
||||
|
||||
std::ofstream m_outFile;
|
||||
std::ofstream ulOutFile;
|
||||
std::ofstream dlOutFile;
|
||||
|
||||
if ( m_firstWrite == true )
|
||||
{
|
||||
m_outFile.open (m_outputFilename.c_str ());
|
||||
if (! m_outFile.is_open ())
|
||||
ulOutFile.open (m_ulOutputFilename.c_str ());
|
||||
if (! ulOutFile.is_open ())
|
||||
{
|
||||
NS_LOG_ERROR ("Can't open file " << m_outputFilename.c_str ());
|
||||
NS_LOG_ERROR ("Can't open file " << m_ulOutputFilename.c_str ());
|
||||
return;
|
||||
}
|
||||
|
||||
dlOutFile.open (m_dlOutputFilename.c_str ());
|
||||
if (! dlOutFile.is_open ())
|
||||
{
|
||||
NS_LOG_ERROR ("Can't open file " << m_dlOutputFilename.c_str ());
|
||||
return;
|
||||
}
|
||||
m_firstWrite = false;
|
||||
m_outFile << "# startTime, endTime, RNTI, LCID, throughput (bps), delay (s), PDU loss ratio (%)" << std::endl;
|
||||
ulOutFile << "# startTime, endTime, RNTI, LCID, nTxPDUs, TxBytes, nRxPDUs, RxBytes, ";
|
||||
ulOutFile << "delay mean, delay std dev, delay min, delay max, ";
|
||||
ulOutFile << "PDU size mean, PDU size std dev, PDU size min, PDU size max, ";
|
||||
ulOutFile << std::endl;
|
||||
dlOutFile << "# startTime, endTime, RNTI, LCID, nTxPDUs, TxBytes, nRxPDUs, RxBytes, ";
|
||||
dlOutFile << "delay mean, delay std dev, delay min, delay max, ";
|
||||
dlOutFile << "PDU size mean, PDU size std dev, PDU size min, PDU size max, ";
|
||||
dlOutFile << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_outFile.open (m_outputFilename.c_str (), std::ios_base::app);
|
||||
if (! m_outFile.is_open ())
|
||||
ulOutFile.open (m_ulOutputFilename.c_str (), std::ios_base::app);
|
||||
if (! ulOutFile.is_open ())
|
||||
{
|
||||
NS_LOG_ERROR ("Can't open file " << m_outputFilename.c_str ());
|
||||
NS_LOG_ERROR ("Can't open file " << m_ulOutputFilename.c_str ());
|
||||
return;
|
||||
}
|
||||
|
||||
dlOutFile.open (m_dlOutputFilename.c_str (), std::ios_base::app);
|
||||
if (! dlOutFile.is_open ())
|
||||
{
|
||||
NS_LOG_ERROR ("Can't open file " << m_dlOutputFilename.c_str ());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
WriteUlResults(ulOutFile);
|
||||
WriteDlResults(dlOutFile);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
RlcStatsCalculator::WriteUlResults (std::ofstream& outFile)
|
||||
{
|
||||
uint32Map::iterator it;
|
||||
|
||||
// Get all the unique lteFlowIds in the calculator
|
||||
std::vector<lteFlowId_t> lteFlowIds;
|
||||
for ( it = m_txPackets.begin(); it != m_txPackets.end(); ++it)
|
||||
for ( it = m_ulTxPackets.begin(); it != m_ulTxPackets.end(); ++it)
|
||||
{
|
||||
if (find (lteFlowIds.begin (), lteFlowIds.end (), (*it).first ) == lteFlowIds.end () )
|
||||
{
|
||||
@@ -155,21 +232,84 @@ RlcStatsCalculator::ShowResults (void)
|
||||
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;
|
||||
outFile << m_startTime.GetNanoSeconds () / 1.0e9 << " ";
|
||||
outFile << endTime.GetNanoSeconds() / 1.0e9 << " ";
|
||||
outFile << (*itFlow).m_rnti << " ";
|
||||
outFile << (uint32_t) (*itFlow).m_lcId << " ";
|
||||
outFile << GetUlTxPackets (*itFlow) << " ";
|
||||
outFile << GetUlTxData (*itFlow) << " ";
|
||||
outFile << GetUlRxPackets (*itFlow) << " ";
|
||||
outFile << GetUlRxData (*itFlow) << " ";
|
||||
std::vector<double> stats = GetUlDelayStats (*itFlow);
|
||||
for( std::vector<double>::iterator it = stats.begin (); it != stats.end (); ++it )
|
||||
{
|
||||
outFile << (*it) * 1e-9 << " ";
|
||||
}
|
||||
stats = GetUlPduSizeStats (*itFlow);
|
||||
for( std::vector<double>::iterator it = stats.begin (); it != stats.end (); ++it )
|
||||
{
|
||||
outFile << (*it) << " ";
|
||||
}
|
||||
outFile << std::endl;
|
||||
}
|
||||
m_outFile.close ();
|
||||
|
||||
outFile.close ();
|
||||
}
|
||||
|
||||
void
|
||||
RlcStatsCalculator::WriteDlResults (std::ofstream& outFile)
|
||||
{
|
||||
uint32Map::iterator it;
|
||||
|
||||
// Get all the unique lteFlowIds in the calculator
|
||||
std::vector<lteFlowId_t> lteFlowIds;
|
||||
for ( it = m_dlTxPackets.begin(); it != m_dlTxPackets.end(); ++it)
|
||||
{
|
||||
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)
|
||||
{
|
||||
outFile << m_startTime.GetNanoSeconds () / 1.0e9 << " ";
|
||||
outFile << endTime.GetNanoSeconds() / 1.0e9 << " ";
|
||||
outFile << (*itFlow).m_rnti << " ";
|
||||
outFile << (uint32_t) (*itFlow).m_lcId << " ";
|
||||
outFile << GetDlTxPackets (*itFlow) << " ";
|
||||
outFile << GetDlTxData (*itFlow) << " ";
|
||||
outFile << GetDlRxPackets (*itFlow) << " ";
|
||||
outFile << GetDlRxData (*itFlow) << " ";
|
||||
std::vector<double> stats = GetDlDelayStats (*itFlow);
|
||||
for( std::vector<double>::iterator it = stats.begin (); it != stats.end (); ++it )
|
||||
{
|
||||
outFile << (*it) * 1e-9 << " ";
|
||||
}
|
||||
stats = GetDlPduSizeStats (*itFlow);
|
||||
for( std::vector<double>::iterator it = stats.begin (); it != stats.end (); ++it )
|
||||
{
|
||||
outFile << (*it) << " ";
|
||||
}
|
||||
outFile << std::endl;
|
||||
}
|
||||
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 () );
|
||||
m_ulTxPackets.erase (m_ulTxPackets.begin (), m_ulTxPackets.end () );
|
||||
m_ulRxPackets.erase (m_ulRxPackets.begin (), m_ulRxPackets.end () );
|
||||
m_ulRxData.erase (m_ulRxData.begin (), m_ulRxData.end () );
|
||||
m_ulDelay.erase (m_ulDelay.begin (), m_ulDelay.end () );
|
||||
|
||||
m_dlTxPackets.erase (m_dlTxPackets.begin (), m_dlTxPackets.end () );
|
||||
m_dlRxPackets.erase (m_dlRxPackets.begin (), m_dlRxPackets.end () );
|
||||
m_dlRxData.erase (m_dlRxData.begin (), m_dlRxData.end () );
|
||||
m_dlDelay.erase (m_dlDelay.begin (), m_dlDelay.end () );
|
||||
}
|
||||
|
||||
void
|
||||
@@ -191,86 +331,255 @@ RlcStatsCalculator::StartEpoch (void)
|
||||
}
|
||||
|
||||
uint32_t
|
||||
RlcStatsCalculator::GetTxPackets (lteFlowId_t p)
|
||||
RlcStatsCalculator::GetUlTxPackets (lteFlowId_t p)
|
||||
{
|
||||
return m_txPackets[p];
|
||||
return m_ulTxPackets[p];
|
||||
}
|
||||
|
||||
uint32_t
|
||||
RlcStatsCalculator::GetRxPackets (lteFlowId_t p)
|
||||
RlcStatsCalculator::GetUlRxPackets (lteFlowId_t p)
|
||||
{
|
||||
return m_rxPackets[p];
|
||||
return m_ulRxPackets[p];
|
||||
}
|
||||
|
||||
uint64_t
|
||||
RlcStatsCalculator::GetRxData (lteFlowId_t p)
|
||||
RlcStatsCalculator::GetUlTxData (lteFlowId_t p)
|
||||
{
|
||||
return m_rxData[p];
|
||||
return m_ulTxData[p];
|
||||
}
|
||||
|
||||
uint64_t
|
||||
RlcStatsCalculator::GetDelay (lteFlowId_t p)
|
||||
RlcStatsCalculator::GetUlRxData (lteFlowId_t p)
|
||||
{
|
||||
uint64StatsMap::iterator it = m_delay.find (p);
|
||||
if ( it == m_delay.end () )
|
||||
return m_ulRxData[p];
|
||||
}
|
||||
|
||||
double
|
||||
RlcStatsCalculator::GetUlDelay (lteFlowId_t p)
|
||||
{
|
||||
uint64StatsMap::iterator it = m_ulDelay.find (p);
|
||||
if ( it == m_ulDelay.end () )
|
||||
{
|
||||
NS_LOG_ERROR("UL delay for " << p.m_rnti << ", " <<
|
||||
(uint32_t) p.m_lcId << " not found");
|
||||
return 0;
|
||||
|
||||
}
|
||||
return m_ulDelay[p]->getMean ();
|
||||
}
|
||||
|
||||
std::vector<double>
|
||||
RlcStatsCalculator::GetUlDelayStats (lteFlowId_t p)
|
||||
{
|
||||
std::vector<double> stats;
|
||||
uint64StatsMap::iterator it = m_ulDelay.find (p);
|
||||
if ( it == m_ulDelay.end () )
|
||||
{
|
||||
NS_LOG_ERROR("UL delay for " << p.m_rnti << ", " <<
|
||||
(uint32_t) p.m_lcId << " not found");
|
||||
return stats;
|
||||
|
||||
}
|
||||
stats.push_back(m_ulDelay[p]->getMean ());
|
||||
stats.push_back(m_ulDelay[p]->getStddev ());
|
||||
stats.push_back(m_ulDelay[p]->getMin ());
|
||||
stats.push_back(m_ulDelay[p]->getMax ());
|
||||
return stats;
|
||||
}
|
||||
|
||||
std::vector<double>
|
||||
RlcStatsCalculator::GetUlPduSizeStats (lteFlowId_t p)
|
||||
{
|
||||
std::vector<double> stats;
|
||||
uint32StatsMap::iterator it = m_ulPduSize.find (p);
|
||||
if ( it == m_ulPduSize.end () )
|
||||
{
|
||||
NS_LOG_ERROR("UL PDU Size for " << p.m_rnti << ", " <<
|
||||
(uint32_t) p.m_lcId << " not found");
|
||||
return stats;
|
||||
|
||||
}
|
||||
stats.push_back (m_ulPduSize[p]->getMean ());
|
||||
stats.push_back (m_ulPduSize[p]->getStddev ());
|
||||
stats.push_back (m_ulPduSize[p]->getMin ());
|
||||
stats.push_back (m_ulPduSize[p]->getMax ());
|
||||
return stats;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
RlcStatsCalculator::GetDlTxPackets (lteFlowId_t p)
|
||||
{
|
||||
return m_dlTxPackets[p];
|
||||
}
|
||||
|
||||
uint32_t
|
||||
RlcStatsCalculator::GetDlRxPackets (lteFlowId_t p)
|
||||
{
|
||||
return m_dlRxPackets[p];
|
||||
}
|
||||
|
||||
uint64_t
|
||||
RlcStatsCalculator::GetDlTxData (lteFlowId_t p)
|
||||
{
|
||||
return m_dlTxData[p];
|
||||
}
|
||||
|
||||
uint64_t
|
||||
RlcStatsCalculator::GetDlRxData (lteFlowId_t p)
|
||||
{
|
||||
return m_dlRxData[p];
|
||||
}
|
||||
|
||||
double
|
||||
RlcStatsCalculator::GetDlDelay (lteFlowId_t p)
|
||||
{
|
||||
uint64StatsMap::iterator it = m_dlDelay.find (p);
|
||||
if ( it == m_dlDelay.end () )
|
||||
{
|
||||
NS_LOG_ERROR("DL delay for " << p.m_rnti << ", " <<
|
||||
(uint32_t) p.m_lcId << " not found");
|
||||
return 0;
|
||||
}
|
||||
return m_delay[p]->getMean ();
|
||||
return m_dlDelay[p]->getMean ();
|
||||
}
|
||||
|
||||
double
|
||||
RlcStatsCalculator::GetThroughput (lteFlowId_t p)
|
||||
std::vector<double>
|
||||
RlcStatsCalculator::GetDlDelayStats (lteFlowId_t p)
|
||||
{
|
||||
return m_throughput[p];
|
||||
std::vector<double> stats;
|
||||
uint64StatsMap::iterator it = m_dlDelay.find (p);
|
||||
if ( it == m_dlDelay.end () )
|
||||
{
|
||||
|
||||
NS_LOG_ERROR("DL delay for " << p.m_rnti << ", " <<
|
||||
(uint32_t) p.m_lcId << " not found");
|
||||
return stats;
|
||||
|
||||
}
|
||||
stats.push_back(m_dlDelay[p]->getMean ());
|
||||
stats.push_back(m_dlDelay[p]->getStddev ());
|
||||
stats.push_back(m_dlDelay[p]->getMin ());
|
||||
stats.push_back(m_dlDelay[p]->getMax ());
|
||||
return stats;
|
||||
}
|
||||
|
||||
double
|
||||
RlcStatsCalculator::GetPacketLossProbability (lteFlowId_t p)
|
||||
std::vector<double>
|
||||
RlcStatsCalculator::GetDlPduSizeStats (lteFlowId_t p)
|
||||
{
|
||||
return (GetTxPackets (p) - GetRxPackets (p)) / (double) GetTxPackets (p);
|
||||
std::vector<double> stats;
|
||||
uint32StatsMap::iterator it = m_dlPduSize.find (p);
|
||||
if ( it == m_dlPduSize.end () )
|
||||
{
|
||||
|
||||
NS_LOG_ERROR("DL delay for " << p.m_rnti << ", " <<
|
||||
(uint32_t) p.m_lcId << " not found");
|
||||
return stats;
|
||||
|
||||
}
|
||||
stats.push_back(m_dlPduSize[p]->getMean ());
|
||||
stats.push_back(m_dlPduSize[p]->getStddev ());
|
||||
stats.push_back(m_dlPduSize[p]->getMin ());
|
||||
stats.push_back(m_dlPduSize[p]->getMax ());
|
||||
return stats;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
RlcStatsCalculator::GetTxPackets (uint16_t rnti, uint8_t lcid)
|
||||
RlcStatsCalculator::GetUlTxPackets (uint16_t rnti, uint8_t lcid)
|
||||
{
|
||||
lteFlowId_t p (rnti, lcid);
|
||||
return GetTxPackets (p);
|
||||
return GetUlTxPackets (p);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
RlcStatsCalculator::GetRxPackets (uint16_t rnti, uint8_t lcid)
|
||||
RlcStatsCalculator::GetUlRxPackets (uint16_t rnti, uint8_t lcid)
|
||||
{
|
||||
lteFlowId_t p (rnti, lcid);
|
||||
return GetRxPackets (p);
|
||||
return GetUlRxPackets (p);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
RlcStatsCalculator::GetRxData (uint16_t rnti, uint8_t lcid)
|
||||
RlcStatsCalculator::GetUlTxData (uint16_t rnti, uint8_t lcid)
|
||||
{
|
||||
lteFlowId_t p (rnti, lcid);
|
||||
return GetRxData (p);
|
||||
return GetUlTxData (p);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
RlcStatsCalculator::GetDelay (uint16_t rnti, uint8_t lcid)
|
||||
RlcStatsCalculator::GetUlRxData (uint16_t rnti, uint8_t lcid)
|
||||
{
|
||||
lteFlowId_t p (rnti, lcid);
|
||||
return GetDelay (p);
|
||||
return GetUlRxData (p);
|
||||
}
|
||||
|
||||
double
|
||||
RlcStatsCalculator::GetThroughput (uint16_t rnti, uint8_t lcid)
|
||||
RlcStatsCalculator::GetUlDelay (uint16_t rnti, uint8_t lcid)
|
||||
{
|
||||
lteFlowId_t p (rnti, lcid);
|
||||
return GetThroughput (p);
|
||||
return GetUlDelay (p);
|
||||
}
|
||||
|
||||
std::vector<double>
|
||||
RlcStatsCalculator::GetUlDelayStats (uint16_t rnti, uint8_t lcid)
|
||||
{
|
||||
lteFlowId_t p (rnti, lcid);
|
||||
return GetUlDelayStats (p);
|
||||
}
|
||||
|
||||
std::vector<double>
|
||||
RlcStatsCalculator::GetUlPduSizeStats (uint16_t rnti, uint8_t lcid)
|
||||
{
|
||||
lteFlowId_t p (rnti, lcid);
|
||||
return GetUlPduSizeStats (p);
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
RlcStatsCalculator::GetDlTxPackets (uint16_t rnti, uint8_t lcid)
|
||||
{
|
||||
lteFlowId_t p (rnti, lcid);
|
||||
return GetDlTxPackets (p);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
RlcStatsCalculator::GetDlRxPackets (uint16_t rnti, uint8_t lcid)
|
||||
{
|
||||
lteFlowId_t p (rnti, lcid);
|
||||
return GetDlRxPackets (p);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
RlcStatsCalculator::GetDlTxData (uint16_t rnti, uint8_t lcid)
|
||||
{
|
||||
lteFlowId_t p (rnti, lcid);
|
||||
return GetDlTxData (p);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
RlcStatsCalculator::GetDlRxData (uint16_t rnti, uint8_t lcid)
|
||||
{
|
||||
lteFlowId_t p (rnti, lcid);
|
||||
return GetDlRxData (p);
|
||||
}
|
||||
|
||||
double
|
||||
RlcStatsCalculator::GetPacketLossProbability (uint16_t rnti, uint8_t lcid)
|
||||
RlcStatsCalculator::GetDlDelay (uint16_t rnti, uint8_t lcid)
|
||||
{
|
||||
lteFlowId_t p (rnti, lcid);
|
||||
return GetPacketLossProbability (p);
|
||||
return GetDlDelay (p);
|
||||
}
|
||||
|
||||
std::vector<double>
|
||||
RlcStatsCalculator::GetDlDelayStats (uint16_t rnti, uint8_t lcid)
|
||||
{
|
||||
lteFlowId_t p (rnti, lcid);
|
||||
return GetDlDelayStats (p);
|
||||
}
|
||||
|
||||
std::vector<double>
|
||||
RlcStatsCalculator::GetDlPduSizeStats (uint16_t rnti, uint8_t lcid)
|
||||
{
|
||||
lteFlowId_t p (rnti, lcid);
|
||||
return GetDlPduSizeStats (p);
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace ns3 {
|
||||
|
||||
typedef std::map<lteFlowId_t, uint32_t> uint32Map;
|
||||
typedef std::map<lteFlowId_t, uint64_t> uint64Map;
|
||||
typedef std::map<lteFlowId_t, Ptr<MinMaxAvgTotalCalculator<uint32_t> > > uint32StatsMap;
|
||||
typedef std::map<lteFlowId_t, Ptr<MinMaxAvgTotalCalculator<uint64_t> > > uint64StatsMap;
|
||||
typedef std::map<lteFlowId_t, double> doubleMap;
|
||||
|
||||
@@ -46,39 +47,72 @@ public:
|
||||
~RlcStatsCalculator();
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
void SetOutputFilename (std::string outputFilename);
|
||||
void SetUlOutputFilename (std::string outputFilename);
|
||||
void SetDlOutputFilename (std::string outputFilename);
|
||||
|
||||
void TxPdu (uint16_t rnti, uint8_t lcid, uint32_t packetSize);
|
||||
void RxPdu (uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay);
|
||||
void UlTxPdu (uint16_t rnti, uint8_t lcid, uint32_t packetSize);
|
||||
void UlRxPdu (uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay);
|
||||
|
||||
uint32_t GetTxPackets (lteFlowId_t p);
|
||||
uint32_t GetRxPackets (lteFlowId_t p);
|
||||
uint64_t GetRxData (lteFlowId_t p);
|
||||
uint64_t GetDelay (lteFlowId_t p);
|
||||
double GetThroughput (lteFlowId_t p);
|
||||
double GetPacketLossProbability (lteFlowId_t p);
|
||||
void DlTxPdu (uint16_t rnti, uint8_t lcid, uint32_t packetSize);
|
||||
void DlRxPdu (uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay);
|
||||
|
||||
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);
|
||||
uint32_t GetUlTxPackets (lteFlowId_t p);
|
||||
uint32_t GetUlRxPackets (lteFlowId_t p);
|
||||
uint64_t GetUlTxData (lteFlowId_t p);
|
||||
uint64_t GetUlRxData (lteFlowId_t p);
|
||||
double GetUlDelay (lteFlowId_t p);
|
||||
std::vector<double> GetUlDelayStats (lteFlowId_t p);
|
||||
std::vector<double> GetUlPduSizeStats (lteFlowId_t p);
|
||||
|
||||
uint32_t GetUlTxPackets (uint16_t rnti, uint8_t lcid);
|
||||
uint32_t GetUlRxPackets (uint16_t rnti, uint8_t lcid);
|
||||
uint64_t GetUlTxData (uint16_t rnti, uint8_t lcid);
|
||||
uint64_t GetUlRxData (uint16_t rnti, uint8_t lcid);
|
||||
double GetUlDelay (uint16_t rnti, uint8_t lcid);
|
||||
std::vector<double> GetUlDelayStats (uint16_t rnti, uint8_t lcid);
|
||||
std::vector<double> GetUlPduSizeStats (uint16_t rnti, uint8_t lcid);
|
||||
|
||||
|
||||
uint32_t GetDlTxPackets (lteFlowId_t p);
|
||||
uint32_t GetDlRxPackets (lteFlowId_t p);
|
||||
uint64_t GetDlTxData (lteFlowId_t p);
|
||||
uint64_t GetDlRxData (lteFlowId_t p);
|
||||
double GetDlDelay (lteFlowId_t p);
|
||||
std::vector<double> GetDlDelayStats (lteFlowId_t p);
|
||||
std::vector<double> GetDlPduSizeStats (lteFlowId_t p);
|
||||
|
||||
uint32_t GetDlTxPackets (uint16_t rnti, uint8_t lcid);
|
||||
uint32_t GetDlRxPackets (uint16_t rnti, uint8_t lcid);
|
||||
uint64_t GetDlTxData (uint16_t rnti, uint8_t lcid);
|
||||
uint64_t GetDlRxData (uint16_t rnti, uint8_t lcid);
|
||||
double GetDlDelay (uint16_t rnti, uint8_t lcid);
|
||||
std::vector<double> GetDlDelayStats (uint16_t rnti, uint8_t lcid);
|
||||
std::vector<double> GetDlPduSizeStats (uint16_t rnti, uint8_t lcid);
|
||||
|
||||
private:
|
||||
void ShowResults (void);
|
||||
void WriteUlResults (std::ofstream& outFile);
|
||||
void WriteDlResults (std::ofstream& outFile);
|
||||
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;
|
||||
std::string m_dlOutputFilename;
|
||||
uint32Map m_dlTxPackets;
|
||||
uint32Map m_dlRxPackets;
|
||||
uint64Map m_dlTxData;
|
||||
uint64Map m_dlRxData;
|
||||
uint64StatsMap m_dlDelay;
|
||||
uint32StatsMap m_dlPduSize;
|
||||
|
||||
std::string m_ulOutputFilename;
|
||||
uint32Map m_ulTxPackets;
|
||||
uint32Map m_ulRxPackets;
|
||||
uint64Map m_ulTxData;
|
||||
uint64Map m_ulRxData;
|
||||
uint64StatsMap m_ulDelay;
|
||||
uint32StatsMap m_ulPduSize;
|
||||
|
||||
/**
|
||||
* Start time of the on going epoch
|
||||
|
||||
@@ -53,7 +53,14 @@ TypeId LteUeNetDevice::GetTypeId (void)
|
||||
static TypeId
|
||||
tid =
|
||||
TypeId ("ns3::LteUeNetDevice")
|
||||
.SetParent<LteNetDevice> ();
|
||||
.SetParent<LteNetDevice> ()
|
||||
.AddAttribute ("LteUeRrc",
|
||||
"The RRC associated to this UeNetDevice",
|
||||
PointerValue (),
|
||||
MakePointerAccessor (&LteUeNetDevice::m_rrc),
|
||||
MakePointerChecker <LteUeRrc> ())
|
||||
;
|
||||
|
||||
return tid;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include <ns3/fatal-error.h>
|
||||
#include <ns3/log.h>
|
||||
#include "ns3/object-map.h"
|
||||
|
||||
#include "lte-ue-rrc.h"
|
||||
#include "lte-rlc.h"
|
||||
@@ -96,7 +97,12 @@ LteUeRrc::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::LteUeRrc")
|
||||
.SetParent<Object> ()
|
||||
.AddConstructor<LteUeRrc> ();
|
||||
.AddConstructor<LteUeRrc> ()
|
||||
.AddAttribute ("RlcMap", "List of UE RadioBearerInfo by LCID.",
|
||||
ObjectMapValue (),
|
||||
MakeObjectMapAccessor (&LteUeRrc::m_rlcMap),
|
||||
MakeObjectMapChecker<LteRlc> ())
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
@@ -139,7 +145,7 @@ LteUeRrc::SetupRadioBearer (uint16_t rnti, EpsBearer bearer, uint8_t lcid)
|
||||
// create RLC instance
|
||||
// for now we support RLC SM only
|
||||
|
||||
Ptr<LteRlc> rlc = Create<LteRlcSm> ();
|
||||
Ptr<LteRlc> rlc = CreateObject<LteRlcSm> ();
|
||||
rlc->SetLteMacSapProvider (m_macSapProvider);
|
||||
rlc->SetRnti (rnti);
|
||||
rlc->SetLcId (lcid);
|
||||
|
||||
Reference in New Issue
Block a user