diff --git a/src/lte/examples/lena-rlc-calculator.cc b/src/lte/examples/lena-rlc-calculator.cc new file mode 100644 index 000000000..5d8312522 --- /dev/null +++ b/src/lte/examples/lena-rlc-calculator.cc @@ -0,0 +1,98 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Manuel Requena + */ + + +#include "ns3/core-module.h" +#include "ns3/network-module.h" +#include "ns3/mobility-module.h" +#include "ns3/lte-module.h" +#include "ns3/rlc-stats-calculator.h" + + +#include "ns3/gtk-config-store.h" + +using namespace ns3; + +void TxPduCallback(Ptr rlcStats, std::string path, + uint16_t rnti, uint8_t lcid, uint32_t packetSize) +{ + rlcStats->TxPdu(rnti, lcid, packetSize); +} + +void RxPduCallback(Ptr rlcStats, std::string path, + uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay) +{ + rlcStats->RxPdu(rnti, lcid, packetSize, delay); +} + +int main (int argc, char *argv[]) +{ + LenaHelper lena; + + //lena.EnableLogComponents (); + + // Create Nodes: eNodeB and UE + NodeContainer enbNodes; + NodeContainer ueNodes; + enbNodes.Create (1); + ueNodes.Create (3); + + // Install Mobility Model + MobilityHelper mobility; + mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); + mobility.Install (enbNodes); + mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); + mobility.Install (ueNodes); + + // Create Devices and install them in the Nodes (eNB and UE) + NetDeviceContainer enbDevs; + NetDeviceContainer ueDevs; + enbDevs = lena.InstallEnbDevice (enbNodes); + ueDevs = lena.InstallUeDevice (ueNodes); + + // Attach a UE to a eNB + lena.Attach (ueDevs, enbDevs.Get (0)); + + // Activate an EPS bearer + enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE; + EpsBearer bearer (q); + lena.ActivateEpsBearer (ueDevs, bearer); + + Simulator::Stop (Seconds (0.1)); + + // Insert RLC Performance Calculator + Ptr rlcStats = CreateObject (); + Config::Connect("/NodeList/0/DeviceList/0/LteEnbRrc/UeMap/*/RadioBearerMap/*/LteRlc/TxPDU", + MakeBoundCallback(&TxPduCallback, rlcStats)); + Config::Connect ("/NodeList/0/DeviceList/0/LteEnbRrc/UeMap/*/RadioBearerMap/*/LteRlc/RxPDU", + MakeBoundCallback(&RxPduCallback, rlcStats)); + + Simulator::Run (); + + // Uncomment to show available paths + //GtkConfigStore config; + //config.ConfigureAttributes (); + + Simulator::Destroy (); + + // Generate RLC output + + return 0; +} diff --git a/src/lte/examples/wscript b/src/lte/examples/wscript index 0a4382b32..ac89e1b17 100644 --- a/src/lte/examples/wscript +++ b/src/lte/examples/wscript @@ -7,3 +7,6 @@ def build(bld): obj = bld.create_ns3_program('inter-cell-interference', ['lte']) obj.source = 'inter-cell-interference.cc' + obj = bld.create_ns3_program('lena-rlc-calculator', + ['lte']) + obj.source = 'lena-rlc-calculator.cc' diff --git a/src/lte/helper/lena-helper.cc b/src/lte/helper/lena-helper.cc index a535a9d6b..77e911494 100644 --- a/src/lte/helper/lena-helper.cc +++ b/src/lte/helper/lena-helper.cc @@ -258,6 +258,8 @@ LenaHelper::EnableLogComponents (void) LogComponentEnable ("LteNetDevice", LOG_LEVEL_ALL); LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL); LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL); + + LogComponentEnable ("RlcStatsCalculator", LOG_LEVEL_ALL); } diff --git a/src/lte/helper/rlc-stats-calculator.cc b/src/lte/helper/rlc-stats-calculator.cc new file mode 100644 index 000000000..25df8defd --- /dev/null +++ b/src/lte/helper/rlc-stats-calculator.cc @@ -0,0 +1,203 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Jaume Nin + */ + +#include "rlc-stats-calculator.h" +#include "ns3/string.h" +#include "ns3/nstime.h" +#include + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("RlcStatsCalculator"); + +NS_OBJECT_ENSURE_REGISTERED (RlcStatsCalculator); + +RlcStatsCalculator::RlcStatsCalculator() : + m_outputFilename ("") +{ + NS_LOG_FUNCTION (this); + +} + +RlcStatsCalculator::~RlcStatsCalculator() +{ + NS_LOG_FUNCTION (this); + ShowResults (); +} + +TypeId +RlcStatsCalculator::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::RlcStatsCalculator") + .SetParent () + .AddConstructor () + .AddAttribute ("OutputFilename", + "Name of the file where the output will be saved.", + StringValue ("RlcStats.csv"), + MakeStringAccessor (&RlcStatsCalculator::SetOutputFilename), + MakeStringChecker ()) + ; + return tid; +} + +void +RlcStatsCalculator::SetOutputFilename (std::string outputFilename) +{ + m_outputFilename = outputFilename; +} + +void +RlcStatsCalculator::TxPdu (uint16_t rnti, uint8_t lcid, uint32_t packetSize) +{ + NS_LOG_FUNCTION (this << " TxPDU " << rnti << (uint32_t) lcid << packetSize); + RntiLcidPair pair = RntiLcidPair(rnti, lcid); + uint32Map::iterator it = m_txPackets.find (pair); + m_txPackets[pair]++; +} + +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); + RntiLcidPair pair = RntiLcidPair(rnti, lcid); + + m_rxPackets [pair]++; + m_rxData [pair] += packetSize; + + uint64StatsMap::iterator it = m_delay.find (pair); + if ( it == m_delay.end () ) + { + m_delay[pair] = CreateObject > (); + } + m_delay[pair]->Update (delay); +} + +void +RlcStatsCalculator::ShowResults (void) +{ + uint32Map::iterator it; + uint64Map::iterator itData; + uint64StatsMap::iterator itDelay; + NS_LOG_INFO ( "#Parameter,RNTI,LCID,value"); + for ( it = m_txPackets.begin(); it != m_txPackets.end(); ++it) + { + NS_LOG_INFO ("TxPackets, " << (*it).first.rnti << ", " + << (uint32_t) (*it).first.lcid << ", " + << (*it).second); + } + for ( it = m_rxPackets.begin(); it != m_rxPackets.end(); ++it) + { + NS_LOG_INFO ("RxPackets, " << (*it).first.rnti << ", " + << (uint32_t) (*it).first.lcid << ", " + << (*it).second); + } + for ( itData = m_rxData.begin(); itData != m_rxData.end(); ++itData) + { + NS_LOG_INFO ("RxData, " << (*itData).first.rnti << ", " + << (uint32_t) (*itData).first.lcid << ", " + << (*itData).second); + } + for ( itData = m_rxData.begin(); itData != m_rxData.end(); ++itData) + { + NS_LOG_INFO ("Throughput, " << (*itData).first.rnti << ", " + << (uint32_t) (*itData).first.lcid << ", " + << GetThroughput ((*itData).first) ); + } + for ( itDelay = m_delay.begin (); itDelay != m_delay.end (); ++itDelay) + { + NS_LOG_INFO ("Delay, " << (*itDelay).first.rnti << ", " + << (uint32_t) (*itDelay).first.lcid << ", " + << GetDelay ( (*itDelay).first)); + } +} + +uint32_t +RlcStatsCalculator::GetTxPackets (RntiLcidPair p) +{ + return m_txPackets[p]; +} + +uint32_t +RlcStatsCalculator::GetRxPackets (RntiLcidPair p) +{ + return m_rxPackets[p]; +} + +uint64_t +RlcStatsCalculator::GetRxData (RntiLcidPair p) +{ + return m_rxData[p]; +} + +uint64_t +RlcStatsCalculator::GetDelay (RntiLcidPair p) +{ + uint64StatsMap::iterator it = m_delay.find (p); + if ( it == m_delay.end () ) + { + return 0; + } + return m_delay[p]->getMean (); +} + +double +RlcStatsCalculator::GetThroughput (RntiLcidPair p) +{ + // TODO: Fix throughput calculation with the correct time + //return (double) m_rxData[p] / Simulator::Now().GetSeconds(); + return 0; +} + +uint32_t +RlcStatsCalculator::GetTxPackets (uint16_t rnti, uint8_t lcid) +{ + RntiLcidPair p = RntiLcidPair (rnti, lcid); + return GetTxPackets(p); +} + +uint32_t +RlcStatsCalculator::GetRxPackets (uint16_t rnti, uint8_t lcid) +{ + RntiLcidPair p = RntiLcidPair (rnti, lcid); + return GetRxPackets(p); +} + +uint64_t +RlcStatsCalculator::GetRxData (uint16_t rnti, uint8_t lcid) +{ + RntiLcidPair p = RntiLcidPair (rnti, lcid); + return GetRxData(p); +} + +uint64_t +RlcStatsCalculator::GetDelay (uint16_t rnti, uint8_t lcid) +{ + RntiLcidPair p = RntiLcidPair (rnti, lcid); + return GetDelay(p); +} + +double +RlcStatsCalculator::GetThroughput (uint16_t rnti, uint8_t lcid) +{ + RntiLcidPair p = RntiLcidPair (rnti, lcid); + return GetThroughput(p); +} + +} // namespace ns3 diff --git a/src/lte/helper/rlc-stats-calculator.h b/src/lte/helper/rlc-stats-calculator.h new file mode 100644 index 000000000..d0624dacb --- /dev/null +++ b/src/lte/helper/rlc-stats-calculator.h @@ -0,0 +1,97 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Jaume Nin + */ + +#ifndef RLC_STATS_CALCULATOR_H_ +#define RLC_STATS_CALCULATOR_H_ + +#include "ns3/uinteger.h" +#include "ns3/object.h" +#include "ns3/basic-data-calculators.h" +#include +#include + + + +namespace ns3 { + +struct RntiLcidPair + { + uint16_t rnti; + uint8_t lcid; + + RntiLcidPair (const uint16_t a, const uint8_t b) : + rnti(a), + lcid(b) + { } + + friend bool operator == (const RntiLcidPair &a, const RntiLcidPair &b) + { + return (a.lcid == b.lcid) && (a.rnti == b.rnti); + } + friend bool operator < (const RntiLcidPair &a, const RntiLcidPair &b) + { + return (a.lcid < b.lcid) || (a.rnti < b.rnti); + } + }; + +typedef std::map uint32Map; +typedef std::map uint64Map; +typedef std::map > > uint64StatsMap; +typedef std::pair uint32Pair; +typedef std::pair uint64Pair; +typedef std::pair > > uint64StatsPair; + +class RlcStatsCalculator : public Object +{ +public: + RlcStatsCalculator(); + virtual + ~RlcStatsCalculator(); + static TypeId GetTypeId (void); + + void SetOutputFilename (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); + + uint32_t GetTxPackets (RntiLcidPair p); + uint32_t GetRxPackets (RntiLcidPair p); + uint64_t GetRxData (RntiLcidPair p); + uint64_t GetDelay (RntiLcidPair p); + double GetThroughput (RntiLcidPair 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); + +private: + void ShowResults (void); + std::string m_outputFilename; + uint32Map m_txPackets; + uint32Map m_rxPackets; + uint64Map m_rxData; + uint64StatsMap m_delay; +}; + +} // namespace ns3 + +#endif /* RLC_STATS_CALCULATOR_H_ */ diff --git a/src/lte/model/ff-mac-scheduler.cc b/src/lte/model/ff-mac-scheduler.cc index d179e1cbc..b3f4d205c 100644 --- a/src/lte/model/ff-mac-scheduler.cc +++ b/src/lte/model/ff-mac-scheduler.cc @@ -26,6 +26,8 @@ NS_LOG_COMPONENT_DEFINE ("FfMacScheduler"); namespace ns3 { +NS_OBJECT_ENSURE_REGISTERED (FfMacScheduler); + FfMacScheduler::~FfMacScheduler () { @@ -41,7 +43,7 @@ FfMacScheduler::DoDispose () TypeId FfMacScheduler::GetTypeId (void) { - static TypeId tid = TypeId ("FfMacScheduler") + static TypeId tid = TypeId ("ns3::FfMacScheduler") .SetParent (); return tid; } diff --git a/src/lte/model/lte-enb-rrc.cc b/src/lte/model/lte-enb-rrc.cc index b02b0a5ac..779fd4814 100644 --- a/src/lte/model/lte-enb-rrc.cc +++ b/src/lte/model/lte-enb-rrc.cc @@ -34,6 +34,8 @@ namespace ns3 { + + // /////////////////////////// // CMAC SAP forwarder // /////////////////////////// @@ -83,6 +85,8 @@ private: }; +NS_OBJECT_ENSURE_REGISTERED(EnbRadioBearerInfo); + EnbRadioBearerInfo::EnbRadioBearerInfo (void) { // Nothing to do here @@ -100,7 +104,7 @@ TypeId EnbRadioBearerInfo::GetTypeId (void) TypeId ("ns3::EnbRadioBearerInfo") .SetParent () .AddConstructor () - .AddAttribute ("RLC", "RLC.", + .AddAttribute ("LteRlc", "RLC instance of the radio bearer.", PointerValue (), MakePointerAccessor (&EnbRadioBearerInfo::m_rlc), MakePointerChecker ()) @@ -119,6 +123,7 @@ void EnbRadioBearerInfo::SetRlc(Ptr rlc) * Manages all the radio bearer information possessed by the ENB RRC for a single UE * */ + class UeInfo : public Object { public: @@ -158,6 +163,8 @@ private: uint8_t m_lastAllocatedId; }; +NS_OBJECT_ENSURE_REGISTERED(UeInfo); + UeInfo::UeInfo (void) : m_lastAllocatedId (0) { @@ -228,6 +235,7 @@ UeInfo::RemoveRadioBearer (uint8_t lcid) // eNB RRC methods // /////////////////////////// +NS_OBJECT_ENSURE_REGISTERED (LteEnbRrc); LteEnbRrc::LteEnbRrc () : m_cmacSapProvider (0), @@ -362,7 +370,7 @@ LteEnbRrc::SetupRadioBearer (uint16_t rnti, EpsBearer bearer) // create RLC instance // for now we support RLC SM only - Ptr rlc = CreateObject (); + Ptr rlc = CreateObject (); rlc->SetLteMacSapProvider (m_macSapProvider); rlc->SetRnti (rnti); diff --git a/src/lte/model/lte-rlc.cc b/src/lte/model/lte-rlc.cc index 15a414770..d2a2de0eb 100644 --- a/src/lte/model/lte-rlc.cc +++ b/src/lte/model/lte-rlc.cc @@ -78,7 +78,7 @@ LteRlcSpecificLteMacSapUser::ReceivePdu (Ptr p) /////////////////////////////////////// - +NS_OBJECT_ENSURE_REGISTERED (LteRlc); LteRlc::LteRlc () : m_macSapProvider (0), @@ -91,7 +91,7 @@ LteRlc::LteRlc () TypeId LteRlc::GetTypeId (void) { - static TypeId tid = TypeId ("LteRlc") + static TypeId tid = TypeId ("ns3::LteRlc") .SetParent () .AddTraceSource ("TxPDU", "PDU transmission notified to the MAC.", @@ -143,8 +143,11 @@ LteRlc::GetLteMacSapUser () // ////////////////////////////////////// +NS_OBJECT_ENSURE_REGISTERED (LteRlcSm); + LteRlcSm::LteRlcSm () { + NS_LOG_FUNCTION (this); Simulator::ScheduleNow (&LteRlcSm::Start, this); } @@ -154,9 +157,10 @@ LteRlcSm::~LteRlcSm () NS_LOG_FUNCTION (this); } -TypeId LteRlcSm::GetTypeId (void) +TypeId +LteRlcSm::GetTypeId (void) { - static TypeId tid = TypeId ("LteRlcSm") + static TypeId tid = TypeId ("ns3::LteRlcSm") .SetParent () .AddConstructor () ; @@ -166,23 +170,20 @@ TypeId LteRlcSm::GetTypeId (void) void LteRlcSm::DoReceivePdu (Ptr p) { - NS_LOG_FUNCTION (this << p); - // RLC Performance evaluation RlcTag rlcTag; - Time t; + Time delay; if (p->FindFirstMatchingByteTag(rlcTag)) { - t = Simulator::Now() - rlcTag.getSenderTimestamp (); + delay = Simulator::Now() - rlcTag.getSenderTimestamp (); } - - m_rxPdu(m_rnti, m_lcid, p->GetSize (), t.GetNanoSeconds () ); + NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << p->GetSize () << delay.GetNanoSeconds ()); + m_rxPdu(m_rnti, m_lcid, p->GetSize (), delay.GetNanoSeconds () ); } void LteRlcSm::DoNotifyTxOpportunity (uint32_t bytes) { - NS_LOG_FUNCTION (this << bytes); LteMacSapProvider::TransmitPduParameters params; params.pdu = Create (bytes); params.rnti = m_rnti; @@ -191,6 +192,7 @@ LteRlcSm::DoNotifyTxOpportunity (uint32_t bytes) // RLC Performance evaluation RlcTag tag (Simulator::Now()); params.pdu->AddByteTag (tag); + NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << bytes); m_txPdu(m_rnti, m_lcid, bytes); m_macSapProvider->TransmitPdu (params); diff --git a/src/lte/model/lte-ue-rrc.cc b/src/lte/model/lte-ue-rrc.cc index e58e7252d..f054540ac 100644 --- a/src/lte/model/lte-ue-rrc.cc +++ b/src/lte/model/lte-ue-rrc.cc @@ -67,6 +67,7 @@ UeMemberLteUeCmacSapUser::LcConfigCompleted () // ue RRC methods ///////////////////////////// +NS_OBJECT_ENSURE_REGISTERED (LteUeRrc); LteUeRrc::LteUeRrc () : m_cmacSapProvider (0), diff --git a/src/lte/wscript b/src/lte/wscript index 967ca5a32..f6ad506e9 100644 --- a/src/lte/wscript +++ b/src/lte/wscript @@ -2,7 +2,7 @@ def build(bld): - module = bld.create_ns3_module('lte', ['core', 'network', 'spectrum']) + module = bld.create_ns3_module('lte', ['core', 'network', 'spectrum', 'stats']) module.source = [ 'model/lte-spectrum-phy.cc', 'model/lte-phy.cc', @@ -27,6 +27,7 @@ def build(bld): 'model/lte-ue-net-device.cc', 'model/ideal-control-messages.cc', 'helper/lena-helper.cc', + 'helper/rlc-stats-calculator.cc', 'model/ff-mac-csched-sap.cc', 'model/ff-mac-sched-sap.cc', 'model/lte-mac-sap.cc', @@ -69,6 +70,7 @@ def build(bld): 'model/lte-ue-net-device.h', 'model/ideal-control-messages.h', 'helper/lena-helper.h', + 'helper/rlc-stats-calculator.h', 'model/ff-mac-common.h', 'model/ff-mac-csched-sap.h', 'model/ff-mac-sched-sap.h',