diff --git a/src/lte/examples/lena-rlc-calculator.cc b/src/lte/examples/lena-rlc-calculator.cc index a5b6dd90b..2c3303fb9 100644 --- a/src/lte/examples/lena-rlc-calculator.cc +++ b/src/lte/examples/lena-rlc-calculator.cc @@ -73,7 +73,7 @@ int main (int argc, char *argv[]) EpsBearer bearer (q); lena->ActivateEpsBearer (ueDevs, bearer); - Simulator::Stop (Seconds (0.005)); + Simulator::Stop (Seconds (4)); lena->EnableMacTraces (); lena->EnableRlcTraces (); diff --git a/src/lte/helper/lena-helper.cc b/src/lte/helper/lena-helper.cc index a687bf816..5ae17f8f6 100644 --- a/src/lte/helper/lena-helper.cc +++ b/src/lte/helper/lena-helper.cc @@ -354,7 +354,7 @@ LenaHelper::EnableLogComponents (void) LogComponentEnable ("LteSpectrumPhy", LOG_LEVEL_ALL); LogComponentEnable ("LteInterference", LOG_LEVEL_ALL); LogComponentEnable ("LteSinrChunkProcessor", LOG_LEVEL_ALL); - + LogComponentEnable ("LtePropagationLossModel", LOG_LEVEL_ALL); LogComponentEnable ("LossModel", LOG_LEVEL_ALL); LogComponentEnable ("ShadowingLossModel", LOG_LEVEL_ALL); diff --git a/src/lte/helper/rlc-stats-calculator.cc b/src/lte/helper/rlc-stats-calculator.cc index 6b651a7ce..afe327996 100644 --- a/src/lte/helper/rlc-stats-calculator.cc +++ b/src/lte/helper/rlc-stats-calculator.cc @@ -27,6 +27,29 @@ namespace ns3 { + ImsiLcidPair::ImsiLcidPair () +{ +} + + ImsiLcidPair::ImsiLcidPair (const uint64_t a, const uint8_t b) + : m_imsi(a), + m_lcId(b) +{ +} + +bool +operator == (const ImsiLcidPair &a, const ImsiLcidPair &b) +{ + return ( (a.m_imsi == b.m_imsi) && (a.m_lcId == b.m_lcId) ); +} + +bool +operator < (const ImsiLcidPair& a, const ImsiLcidPair& b) +{ + return ( (a.m_imsi < b.m_imsi) || ( (a.m_imsi == b.m_imsi) && (a.m_lcId < b.m_lcId) ) ); +} + + NS_LOG_COMPONENT_DEFINE ("RlcStatsCalculator"); NS_OBJECT_ENSURE_REGISTERED (RlcStatsCalculator); @@ -91,11 +114,12 @@ void RlcStatsCalculator::UlTxPdu (uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize) { NS_LOG_FUNCTION (this << "UlTxPDU" << imsi << rnti << (uint32_t) lcid << packetSize); + ImsiLcidPair p (imsi, lcid); if (Simulator::Now () > m_startTime ) { - m_flowId[imsi] = LteFlowId_t (rnti, lcid); - m_ulTxPackets[imsi]++; - m_ulTxData[imsi] += packetSize; + m_flowId[p] = LteFlowId_t (rnti, lcid); + m_ulTxPackets[p]++; + m_ulTxData[p] += packetSize; } CheckEpoch (); } @@ -104,11 +128,12 @@ void RlcStatsCalculator::DlTxPdu (uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize) { NS_LOG_FUNCTION (this << "DlTxPDU" << imsi << rnti << (uint32_t) lcid << packetSize); + ImsiLcidPair p (imsi, lcid); if (Simulator::Now () > m_startTime ) { - m_flowId[imsi] = LteFlowId_t (rnti, lcid); - m_dlTxPackets[imsi]++; - m_dlTxData[imsi] += packetSize; + m_flowId[p] = LteFlowId_t (rnti, lcid); + m_dlTxPackets[p]++; + m_dlTxData[p] += packetSize; } CheckEpoch (); } @@ -117,20 +142,23 @@ void RlcStatsCalculator::UlRxPdu (uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay) { NS_LOG_FUNCTION (this << "UlRxPDU" << imsi << rnti << (uint32_t) lcid << packetSize << delay); + ImsiLcidPair p (imsi, lcid); if (Simulator::Now () > m_startTime ) { - m_ulRxPackets[imsi]++; - m_ulRxData[imsi] += packetSize; + m_ulRxPackets[p]++; + m_ulRxData[p] += packetSize; - uint64StatsMap::iterator it = m_ulDelay.find(imsi); + Uint64StatsMap::iterator it = m_ulDelay.find(p); if (it == m_ulDelay.end()) { - m_ulDelay[imsi] = CreateObject > (); - m_ulPduSize[imsi] = CreateObject > (); + NS_LOG_DEBUG (this << " Creating UL stats calculators for IMSI " << p.m_imsi << " and LCI " << (uint32_t) p.m_lcId ); + m_ulDelay[p] = CreateObject > (); + m_ulPduSize[p] = CreateObject > (); } - m_ulDelay[imsi]->Update (delay); - m_ulPduSize[imsi]->Update (packetSize); + m_ulDelay[p]->Update (delay); + m_ulPduSize[p]->Update (packetSize); } + CheckEpoch (); } @@ -138,19 +166,21 @@ void RlcStatsCalculator::DlRxPdu (uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay) { NS_LOG_FUNCTION (this << "DlRxPDU" << imsi << rnti << (uint32_t) lcid << packetSize << delay); + ImsiLcidPair p (imsi, lcid); if (Simulator::Now () > m_startTime ) { - m_dlRxPackets[imsi]++; - m_dlRxData[imsi] += packetSize; + m_dlRxPackets[p]++; + m_dlRxData[p] += packetSize; - uint64StatsMap::iterator it = m_dlDelay.find(imsi); + Uint64StatsMap::iterator it = m_dlDelay.find(p); if (it == m_dlDelay.end()) { - m_dlDelay[imsi] = CreateObject > (); - m_dlPduSize[imsi] = CreateObject > (); + NS_LOG_DEBUG (this << " Creating DL stats calculators for IMSI " << p.m_imsi << " and LCI " << (uint32_t) p.m_lcId ); + m_dlDelay[p] = CreateObject > (); + m_dlPduSize[p] = CreateObject > (); } - m_dlDelay[imsi]->Update(delay); - m_dlPduSize[imsi]->Update (packetSize); + m_dlDelay[p]->Update(delay); + m_dlPduSize[p]->Update (packetSize); } CheckEpoch (); } @@ -182,11 +212,11 @@ RlcStatsCalculator::ShowResults (void) return; } m_firstWrite = false; - ulOutFile << "# start\tend\tIMSI\tRNTI\tLCID\tnTxPDUs\tTxBytes\tnRxPDUs\tRxBytes\t"; + ulOutFile << "% start\tend\tIMSI\tRNTI\tLCID\tnTxPDUs\tTxBytes\tnRxPDUs\tRxBytes\t"; ulOutFile << "delay\tstdDev\tmin\tmax\t"; ulOutFile << "PduSize\tstdDev\tmin\tmax"; ulOutFile << std::endl; - dlOutFile << "# start\tend\tIMSI\tRNTI\tLCID\tnTxPDUs\tTxBytes\tnRxPDUs\tRxBytes\t"; + dlOutFile << "% start\tend\tIMSI\tRNTI\tLCID\tnTxPDUs\tTxBytes\tnRxPDUs\tRxBytes\t"; dlOutFile << "delay\tstdDev\tmin\tmax\t"; dlOutFile << "PduSize\tstdDev\tmin\tmax"; dlOutFile << std::endl; @@ -216,34 +246,36 @@ RlcStatsCalculator::ShowResults (void) void RlcStatsCalculator::WriteUlResults (std::ofstream& outFile) { - // Get the unique IMSI list - std::vector imsiVector; - for (uint32Map::iterator it = m_ulTxPackets.begin(); it != m_ulTxPackets.end(); ++it) + // Get the unique IMSI / LCID list + + std::vector pairVector; + for (Uint32Map::iterator it = m_ulTxPackets.begin(); it != m_ulTxPackets.end(); ++it) { - if (find (imsiVector.begin (), imsiVector.end (), (*it).first ) == imsiVector.end () ) + if (find (pairVector.begin (), pairVector.end (), (*it).first ) == pairVector.end () ) { - imsiVector.push_back ((*it).first); + pairVector.push_back ((*it).first); } } Time endTime = m_startTime + m_epochDuration; - for (std::vector::iterator imsi = imsiVector.begin(); imsi != imsiVector.end(); ++imsi) + for (std::vector::iterator it = pairVector.begin(); it != pairVector.end(); ++it) { + ImsiLcidPair p = *it; outFile << m_startTime.GetNanoSeconds () / 1.0e9 << "\t"; outFile << endTime.GetNanoSeconds() / 1.0e9 << "\t"; - outFile << (*imsi) << "\t"; - outFile << m_flowId[*imsi].m_rnti << "\t"; - outFile << (uint32_t) m_flowId[*imsi].m_lcId << "\t"; - outFile << GetUlTxPackets (*imsi) << "\t"; - outFile << GetUlTxData (*imsi) << "\t"; - outFile << GetUlRxPackets (*imsi) << "\t"; - outFile << GetUlRxData (*imsi) << "\t"; - std::vector stats = GetUlDelayStats (*imsi); + outFile << p.m_imsi << "\t"; + outFile << m_flowId[p].m_rnti << "\t"; + outFile << (uint32_t) m_flowId[p].m_lcId << "\t"; + outFile << GetUlTxPackets (p.m_imsi, p.m_lcId) << "\t"; + outFile << GetUlTxData (p.m_imsi, p.m_lcId) << "\t"; + outFile << GetUlRxPackets (p.m_imsi, p.m_lcId) << "\t"; + outFile << GetUlRxData (p.m_imsi, p.m_lcId) << "\t"; + std::vector stats = GetUlDelayStats (p.m_imsi, p.m_lcId); for( std::vector::iterator it = stats.begin (); it != stats.end (); ++it ) { outFile << (*it) * 1e-9 << "\t"; } - stats = GetUlPduSizeStats (*imsi); + stats = GetUlPduSizeStats (p.m_imsi, p.m_lcId); for( std::vector::iterator it = stats.begin (); it != stats.end (); ++it ) { outFile << (*it) << "\t"; @@ -258,33 +290,34 @@ void RlcStatsCalculator::WriteDlResults (std::ofstream& outFile) { // Get the unique IMSI list - std::vector imsiVector; - for (uint32Map::iterator it = m_ulTxPackets.begin(); it != m_ulTxPackets.end(); ++it) + std::vector pairVector; + for (Uint32Map::iterator it = m_ulTxPackets.begin(); it != m_ulTxPackets.end(); ++it) { - if (find (imsiVector.begin (), imsiVector.end (), (*it).first ) == imsiVector.end () ) + if (find (pairVector.begin (), pairVector.end (), (*it).first ) == pairVector.end () ) { - imsiVector.push_back ((*it).first); + pairVector.push_back ((*it).first); } } Time endTime = m_startTime + m_epochDuration; - for (std::vector::iterator imsi = imsiVector.begin(); imsi != imsiVector.end(); ++imsi) + for (std::vector::iterator pair = pairVector.begin(); pair != pairVector.end(); ++pair) { + ImsiLcidPair p = *pair; outFile << m_startTime.GetNanoSeconds () / 1.0e9 << "\t"; outFile << endTime.GetNanoSeconds() / 1.0e9 << "\t"; - outFile << (*imsi) << "\t"; - outFile << m_flowId[*imsi].m_rnti << "\t"; - outFile << (uint32_t) m_flowId[*imsi].m_lcId << "\t"; - outFile << GetDlTxPackets (*imsi) << "\t"; - outFile << GetDlTxData (*imsi) << "\t"; - outFile << GetDlRxPackets (*imsi) << "\t"; - outFile << GetDlRxData (*imsi) << "\t"; - std::vector stats = GetDlDelayStats (*imsi); + outFile << p.m_imsi << "\t"; + outFile << m_flowId[p].m_rnti << "\t"; + outFile << (uint32_t) m_flowId[p].m_lcId << "\t"; + outFile << GetDlTxPackets (p.m_imsi, p.m_lcId) << "\t"; + outFile << GetDlTxData (p.m_imsi, p.m_lcId) << "\t"; + outFile << GetDlRxPackets (p.m_imsi, p.m_lcId) << "\t"; + outFile << GetDlRxData (p.m_imsi, p.m_lcId) << "\t"; + std::vector stats = GetDlDelayStats (p.m_imsi, p.m_lcId); for( std::vector::iterator it = stats.begin (); it != stats.end (); ++it ) { outFile << (*it) * 1e-9 << "\t"; } - stats = GetDlPduSizeStats (*imsi); + stats = GetDlPduSizeStats (p.m_imsi, p.m_lcId); for( std::vector::iterator it = stats.begin (); it != stats.end (); ++it ) { outFile << (*it) << "\t"; @@ -332,119 +365,132 @@ RlcStatsCalculator::StartEpoch (void) } uint32_t -RlcStatsCalculator::GetUlTxPackets (uint64_t imsi) +RlcStatsCalculator::GetUlTxPackets (uint64_t imsi, uint8_t lcid) { - return m_ulTxPackets[imsi]; + ImsiLcidPair p (imsi, lcid); + return m_ulTxPackets[p]; } uint32_t -RlcStatsCalculator::GetUlRxPackets (uint64_t imsi) +RlcStatsCalculator::GetUlRxPackets (uint64_t imsi, uint8_t lcid) { - return m_ulRxPackets[imsi]; + ImsiLcidPair p (imsi, lcid); + return m_ulRxPackets[p]; } uint64_t -RlcStatsCalculator::GetUlTxData (uint64_t imsi) +RlcStatsCalculator::GetUlTxData (uint64_t imsi, uint8_t lcid) { - return m_ulTxData[imsi]; + ImsiLcidPair p (imsi, lcid); + return m_ulTxData[p]; } uint64_t -RlcStatsCalculator::GetUlRxData (uint64_t imsi) +RlcStatsCalculator::GetUlRxData (uint64_t imsi, uint8_t lcid) { - return m_ulRxData[imsi]; + ImsiLcidPair p (imsi, lcid); + return m_ulRxData[p]; } double -RlcStatsCalculator::GetUlDelay (uint64_t imsi) +RlcStatsCalculator::GetUlDelay (uint64_t imsi, uint8_t lcid) { - uint64StatsMap::iterator it = m_ulDelay.find (imsi); + ImsiLcidPair p (imsi, lcid); + Uint64StatsMap::iterator it = m_ulDelay.find (p); if ( it == m_ulDelay.end () ) { - NS_LOG_ERROR("UL delay for " << imsi << " not found"); + NS_LOG_ERROR("UL delay for " << imsi << " - " << lcid << " not found"); return 0; } - return m_ulDelay[imsi]->getMean (); + return m_ulDelay[p]->getMean (); } std::vector -RlcStatsCalculator::GetUlDelayStats (uint64_t imsi) +RlcStatsCalculator::GetUlDelayStats (uint64_t imsi, uint8_t lcid) { + ImsiLcidPair p (imsi, lcid); std::vector stats; - uint64StatsMap::iterator it = m_ulDelay.find (imsi); + Uint64StatsMap::iterator it = m_ulDelay.find (p); if ( it == m_ulDelay.end () ) { - NS_LOG_ERROR("UL delay for " << imsi << " not found"); + NS_LOG_ERROR("UL delay for " << imsi << " - " << lcid << " not found"); return stats; } - stats.push_back(m_ulDelay[imsi]->getMean ()); - stats.push_back(m_ulDelay[imsi]->getStddev ()); - stats.push_back(m_ulDelay[imsi]->getMin ()); - stats.push_back(m_ulDelay[imsi]->getMax ()); + 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 -RlcStatsCalculator::GetUlPduSizeStats (uint64_t imsi) +RlcStatsCalculator::GetUlPduSizeStats (uint64_t imsi, uint8_t lcid) { + ImsiLcidPair p (imsi, lcid); std::vector stats; - uint32StatsMap::iterator it = m_ulPduSize.find (imsi); + Uint32StatsMap::iterator it = m_ulPduSize.find (p); if ( it == m_ulPduSize.end () ) { - NS_LOG_ERROR("UL PDU Size for " << imsi << " not found"); + NS_LOG_ERROR("UL PDU Size for " << imsi << " - " << lcid << " not found"); return stats; } - stats.push_back (m_ulPduSize[imsi]->getMean ()); - stats.push_back (m_ulPduSize[imsi]->getStddev ()); - stats.push_back (m_ulPduSize[imsi]->getMin ()); - stats.push_back (m_ulPduSize[imsi]->getMax ()); + 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 (uint64_t imsi) +RlcStatsCalculator::GetDlTxPackets (uint64_t imsi, uint8_t lcid) { - return m_dlTxPackets[imsi]; + ImsiLcidPair p (imsi, lcid); + return m_dlTxPackets[p]; } uint32_t -RlcStatsCalculator::GetDlRxPackets (uint64_t imsi) +RlcStatsCalculator::GetDlRxPackets (uint64_t imsi, uint8_t lcid) { - return m_dlRxPackets[imsi]; + ImsiLcidPair p (imsi, lcid); + return m_dlRxPackets[p]; } uint64_t -RlcStatsCalculator::GetDlTxData (uint64_t imsi) +RlcStatsCalculator::GetDlTxData (uint64_t imsi, uint8_t lcid) { - return m_dlTxData[imsi]; + ImsiLcidPair p (imsi, lcid); + return m_dlTxData[p]; } uint64_t -RlcStatsCalculator::GetDlRxData (uint64_t imsi) +RlcStatsCalculator::GetDlRxData (uint64_t imsi, uint8_t lcid) { - return m_dlRxData[imsi]; + ImsiLcidPair p (imsi, lcid); + return m_dlRxData[p]; } double -RlcStatsCalculator::GetDlDelay (uint64_t imsi) +RlcStatsCalculator::GetDlDelay (uint64_t imsi, uint8_t lcid) { - uint64StatsMap::iterator it = m_dlDelay.find (imsi); + ImsiLcidPair p (imsi, lcid); + Uint64StatsMap::iterator it = m_dlDelay.find (p); if ( it == m_dlDelay.end () ) { NS_LOG_ERROR("DL delay for " << imsi << " not found"); return 0; } - return m_dlDelay[imsi]->getMean (); + return m_dlDelay[p]->getMean (); } std::vector -RlcStatsCalculator::GetDlDelayStats (uint64_t imsi) +RlcStatsCalculator::GetDlDelayStats (uint64_t imsi, uint8_t lcid) { + ImsiLcidPair p (imsi, lcid); std::vector stats; - uint64StatsMap::iterator it = m_dlDelay.find (imsi); + Uint64StatsMap::iterator it = m_dlDelay.find (p); if ( it == m_dlDelay.end () ) { @@ -452,18 +498,19 @@ RlcStatsCalculator::GetDlDelayStats (uint64_t imsi) return stats; } - stats.push_back(m_dlDelay[imsi]->getMean ()); - stats.push_back(m_dlDelay[imsi]->getStddev ()); - stats.push_back(m_dlDelay[imsi]->getMin ()); - stats.push_back(m_dlDelay[imsi]->getMax ()); + 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; } std::vector -RlcStatsCalculator::GetDlPduSizeStats (uint64_t imsi) +RlcStatsCalculator::GetDlPduSizeStats (uint64_t imsi, uint8_t lcid) { + ImsiLcidPair p (imsi, lcid); std::vector stats; - uint32StatsMap::iterator it = m_dlPduSize.find (imsi); + Uint32StatsMap::iterator it = m_dlPduSize.find (p); if ( it == m_dlPduSize.end () ) { @@ -471,10 +518,10 @@ RlcStatsCalculator::GetDlPduSizeStats (uint64_t imsi) return stats; } - stats.push_back(m_dlPduSize[imsi]->getMean ()); - stats.push_back(m_dlPduSize[imsi]->getStddev ()); - stats.push_back(m_dlPduSize[imsi]->getMin ()); - stats.push_back(m_dlPduSize[imsi]->getMax ()); + 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; } diff --git a/src/lte/helper/rlc-stats-calculator.h b/src/lte/helper/rlc-stats-calculator.h index c910f0854..9c892d43b 100644 --- a/src/lte/helper/rlc-stats-calculator.h +++ b/src/lte/helper/rlc-stats-calculator.h @@ -32,47 +32,219 @@ namespace ns3 { -typedef std::map uint32Map; -typedef std::map uint64Map; -typedef std::map > > uint32StatsMap; -typedef std::map > > uint64StatsMap; -typedef std::map doubleMap; -typedef std::map flowIdMap; +struct ImsiLcidPair +{ + uint64_t m_imsi; + uint8_t m_lcId; + +public: + ImsiLcidPair (); + ImsiLcidPair (const uint64_t a, const uint8_t b); + + friend bool operator == (const ImsiLcidPair &a, const ImsiLcidPair &b); + friend bool operator < (const ImsiLcidPair &a, const ImsiLcidPair &b); +}; + +typedef std::map Uint32Map; +typedef std::map Uint64Map; +typedef std::map > > Uint32StatsMap; +typedef std::map > > Uint64StatsMap; +typedef std::map DoubleMap; +typedef std::map FlowIdMap; + +/** + * Calculation of statistics from the RLC layer for uplink and downlink, the data is dumped into a file periodically. Metrics considered are: + * - Number of transmitted PDUs + * - Number of received PDUs + * - Number of transmitted bytes + * - Number of received bytes + * - Average, min, max and standard deviation of RLC to RLC delay + * - Average, min, max and standard deviation of RLC PDU size + */ class RlcStatsCalculator : public Object { public: - RlcStatsCalculator(); - virtual - ~RlcStatsCalculator(); + + /** + * Class constructor + */ + RlcStatsCalculator (); + + /** + * Class destructor + */ + virtual ~RlcStatsCalculator (); + + /** + * Inherited from ns3::Object + */ static TypeId GetTypeId (void); + /** + * Set the name of the file where the uplink statistics will be stored. + * + * \param outputFilename string with the name of the file + */ void SetUlOutputFilename (std::string outputFilename); + + /** + * Set the name of the file where the downlink statistics will be stored. + * + * \param outputFilename string with the name of the file + */ void SetDlOutputFilename (std::string outputFilename); + /** + * Notifies the stats calculator that an uplink transmission has occurred. + * @param imsi IMSI of the UE who transmitted the PDU + * @param rnti C-RNTI of the UE who transmitted the PDU + * @param lcid LCID through which the PDU has been transmitted + * @param packetSize size of the PDU in bytes + */ void UlTxPdu (uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize); + + /** + * Notifies the stats calculator that an uplink reception has occurred. + * @param imsi IMSI of the UE who received the PDU + * @param rnti C-RNTI of the UE who received the PDU + * @param lcid LCID through which the PDU has been received + * @param packetSize size of the PDU in bytes + * @param delay RLC to RLC delay in nanoseconds + */ void UlRxPdu (uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay); + /** + * Notifies the stats calculator that an downlink transmission has occurred. + * @param imsi IMSI of the UE who is receiving the PDU + * @param rnti C-RNTI of the UE who is receiving the PDU + * @param lcid LCID through which the PDU has been transmitted + * @param packetSize size of the PDU in bytes + */ void DlTxPdu (uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize); + + /** + * Notifies the stats calculator that an downlink reception has occurred. + * @param imsi IMSI of the UE who received the PDU + * @param rnti C-RNTI of the UE who received the PDU + * @param lcid LCID through which the PDU has been transmitted + * @param packetSize size of the PDU in bytes + * @param delay RLC to RLC delay in nanoseconds + */ void DlRxPdu (uint64_t imsi, uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay); - uint32_t GetUlTxPackets (uint64_t imsi); - uint32_t GetUlRxPackets (uint64_t imsi); - uint64_t GetUlTxData (uint64_t imsi); - uint64_t GetUlRxData (uint64_t imsi); - double GetUlDelay (uint64_t imsi); - std::vector GetUlDelayStats (uint64_t imsi); - std::vector GetUlPduSizeStats (uint64_t imsi); + /** + * Gets the number of transmitted uplink packets. + * @param imsi IMSI of the UE + * @param lcid LCID + * @return number of transmitted uplink packets + */ + uint32_t GetUlTxPackets (uint64_t imsi, uint8_t lcid); + /** + * Gets the number of received uplink packets. + * @param imsi IMSI of the UE + * @param lcid LCID + * @return number of received uplink packets + */ + uint32_t GetUlRxPackets (uint64_t imsi, uint8_t lcid); - uint32_t GetDlTxPackets (uint64_t imsi); - uint32_t GetDlRxPackets (uint64_t imsi); - uint64_t GetDlTxData (uint64_t imsi); - uint64_t GetDlRxData (uint64_t imsi); - double GetDlDelay (uint64_t imsi); - std::vector GetDlDelayStats (uint64_t imsi); - std::vector GetDlPduSizeStats (uint64_t imsi); + /** + * Gets the number of transmitted uplink data bytes. + * @param imsi IMSI of the UE + * @param lcid LCID + * @return number of transmitted data bytes + */ + uint64_t GetUlTxData (uint64_t imsi, uint8_t lcid); + + /** + * Gets the number of received uplink data bytes. + * @param imsi IMSI of the UE + * @param lcid LCID + * @return number of received data bytes + */ + uint64_t GetUlRxData (uint64_t imsi, uint8_t lcid); + + /** + * Gets the uplink RLC to RLC delay + * @param imsi IMSI of the UE + * @param lcid LCID + * @return RLC to RLC delay in seconds + */ + double GetUlDelay (uint64_t imsi, uint8_t lcid); + + /** + * Gets the uplink RLC to RLC statistics: average, min, max and standard deviation. + * @param imsi IMSI of the UE + * @param lcid LCID + * @return RLC to RLC delay statistics average, min, max and standard deviation in seconds + */ + std::vector GetUlDelayStats (uint64_t imsi, uint8_t lcid); + + /** + * Gets the uplink PDU size statistics: average, min, max and standard deviation. + * @param imsi IMSI of the UE + * @param lcid LCID + * @return PDU size statistics average, min, max and standard deviation in seconds + */ + std::vector GetUlPduSizeStats (uint64_t imsi, uint8_t lcid); + + /** + * Gets the number of transmitted downlink data bytes. + * @param imsi IMSI of the UE + * @param lcid LCID + * @return number of transmitted data bytes + */ + uint32_t GetDlTxPackets (uint64_t imsi, uint8_t lcid); + + /** + * Gets the number of received downlink data bytes. + * @param imsi IMSI of the UE + * @param lcid LCID + * @return number of received data bytes + */ + uint32_t GetDlRxPackets (uint64_t imsi, uint8_t lcid); + + /** + * Gets the number of transmitted downlink data bytes. + * @param imsi IMSI of the UE + * @param lcid LCID + * @return number of transmitted data bytes + */ + uint64_t GetDlTxData (uint64_t imsi, uint8_t lcid); + + /** + * Gets the number of received downlink data bytes. + * @param imsi IMSI of the UE + * @param lcid LCID + * @return number of received data bytes + */ + uint64_t GetDlRxData (uint64_t imsi, uint8_t lcid); + + /** + * Gets the downlink RLC to RLC delay + * @param imsi IMSI of the UE + * @param lcid LCID + * @return RLC to RLC delay in seconds + */ + double GetDlDelay (uint64_t imsi, uint8_t lcid); + + /** + * Gets the downlink RLC to RLC statistics: average, min, max and standard deviation. + * @param imsi IMSI of the UE + * @param lcid LCID + * @return RLC to RLC delay statistics average, min, max and standard deviation in seconds + */ + std::vector GetDlDelayStats (uint64_t imsi, uint8_t lcid); + + /** + * Gets the downlink PDU size statistics: average, min, max and standard deviation. + * @param imsi IMSI of the UE + * @param lcid LCID + * @return PDU size statistics average, min, max and standard deviation in seconds + */ + std::vector GetDlPduSizeStats (uint64_t imsi, uint8_t lcid); private: void ShowResults (void); @@ -83,23 +255,23 @@ private: void StartEpoch (void); void CheckEpoch (void); - flowIdMap m_flowId; + FlowIdMap m_flowId; std::string m_dlOutputFilename; - uint32Map m_dlTxPackets; - uint32Map m_dlRxPackets; - uint64Map m_dlTxData; - uint64Map m_dlRxData; - uint64StatsMap m_dlDelay; - uint32StatsMap m_dlPduSize; + 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; + 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 diff --git a/src/lte/model/lte-ue-rrc.cc b/src/lte/model/lte-ue-rrc.cc index 9a940716f..d6ab64a7a 100644 --- a/src/lte/model/lte-ue-rrc.cc +++ b/src/lte/model/lte-ue-rrc.cc @@ -191,6 +191,17 @@ LteUeRrc::GetRnti () return m_rnti; } +std::vector +LteUeRrc::GetLcIdVector () +{ + std::vector v; + for (std::map >::iterator it = m_rlcMap.begin(); it != m_rlcMap.end(); ++it) + { + v.push_back(it->first); + } + return v; +} + } // namespace ns3 diff --git a/src/lte/model/lte-ue-rrc.h b/src/lte/model/lte-ue-rrc.h index 732c9138f..f96468499 100644 --- a/src/lte/model/lte-ue-rrc.h +++ b/src/lte/model/lte-ue-rrc.h @@ -122,6 +122,12 @@ public: */ uint16_t GetRnti (); + /** + * + * @return a vector with the allocated LCID + */ + std::vector GetLcIdVector (); + private: // forwarded from CMAC SAP user void DoLcConfigCompleted (); diff --git a/src/lte/test/lte-test-pf-ff-mac-scheduler.cc b/src/lte/test/lte-test-pf-ff-mac-scheduler.cc index 23d7cacbc..9dc4f922c 100644 --- a/src/lte/test/lte-test-pf-ff-mac-scheduler.cc +++ b/src/lte/test/lte-test-pf-ff-mac-scheduler.cc @@ -35,6 +35,7 @@ #include #include #include +#include #include #include "ns3/string.h" #include "ns3/double.h" @@ -169,7 +170,9 @@ LenaPfFfMacSchedulerTestCase::DoRun (void) { // get the imsi uint64_t imsi = ueDevs.Get (i)-> GetObject ()->GetImsi (); - dlDataRxed.push_back (rlcStats->GetDlRxData (imsi)); + // get the lcId + uint8_t lcId = ueDevs.Get (i)-> GetObject ()->GetRrc ()->GetLcIdVector ().at(0); + dlDataRxed.push_back (rlcStats->GetDlRxData (imsi, lcId)); NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << " thr " << (double)dlDataRxed.at (i) / simulationTime << " ref " << m_thrRef); //NS_TEST_ASSERT_MSG_EQ_TOL ((double)dlDataRxed.at (i) / simulationTime, m_thrRef, m_thrRef * tolerance, " Unfair Throughput!"); } diff --git a/src/lte/test/lte-test-rr-ff-mac-scheduler.cc b/src/lte/test/lte-test-rr-ff-mac-scheduler.cc index eac4c0d60..860894929 100644 --- a/src/lte/test/lte-test-rr-ff-mac-scheduler.cc +++ b/src/lte/test/lte-test-rr-ff-mac-scheduler.cc @@ -35,6 +35,7 @@ #include #include #include +#include #include #include "ns3/string.h" #include "ns3/double.h" @@ -199,7 +200,9 @@ LenaRrFfMacSchedulerTestCase::DoRun (void) { // get the imsi uint64_t imsi = ueDevs.Get (i)-> GetObject ()->GetImsi (); - dlDataRxed.push_back (rlcStats->GetDlRxData (imsi)); + // get the lcId + uint8_t lcId = ueDevs.Get (i)-> GetObject ()->GetRrc ()->GetLcIdVector().at(0); + dlDataRxed.push_back (rlcStats->GetDlRxData (imsi, lcId)); NS_LOG_INFO ("\tUser " << i << " imsi " << imsi << " bytes rxed " << (double)dlDataRxed.at (i) << " thr " << (double)dlDataRxed.at (i) / simulationTime << " ref " << m_thrRef); NS_TEST_ASSERT_MSG_EQ_TOL ((double)dlDataRxed.at (i) / simulationTime, m_thrRef, m_thrRef * tolerance, " Unfair Throughput!"); }