From d71c34afdb04c911cdf71e21f140d8a0158fc768 Mon Sep 17 00:00:00 2001 From: Nicola Baldo Date: Mon, 3 Dec 2012 17:48:23 +0100 Subject: [PATCH] dynamic connection of RadioBearerStatsCalculator so it works properly with handover --- src/lte/examples/lena-rlc-traces.cc | 3 +- src/lte/examples/lena-x2-handover.cc | 143 ++++++++- src/lte/helper/lte-helper.cc | 302 ++++--------------- src/lte/helper/lte-helper.h | 44 +-- src/lte/model/lte-enb-rrc.cc | 25 +- src/lte/model/lte-enb-rrc.h | 12 +- src/lte/model/lte-ue-rrc.cc | 22 +- src/lte/model/lte-ue-rrc.h | 11 +- src/lte/test/lte-test-harq.cc | 2 +- src/lte/test/lte-test-mimo.cc | 2 +- src/lte/test/lte-test-pf-ff-mac-scheduler.cc | 4 +- src/lte/test/lte-test-rr-ff-mac-scheduler.cc | 3 +- src/lte/test/test-lte-epc-e2e-data.cc | 2 +- src/lte/test/test-lte-x2-handover.cc | 9 + src/lte/wscript | 2 + 15 files changed, 291 insertions(+), 295 deletions(-) diff --git a/src/lte/examples/lena-rlc-traces.cc b/src/lte/examples/lena-rlc-traces.cc index 13a23c38d..a3c8664b9 100644 --- a/src/lte/examples/lena-rlc-traces.cc +++ b/src/lte/examples/lena-rlc-traces.cc @@ -46,7 +46,6 @@ int main (int argc, char *argv[]) lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel")); // Enable LTE log components //lteHelper->EnableLogComponents (); - lteHelper->EnableRlcTraces(); // Create Nodes: eNodeB and UE NodeContainer enbNodes; @@ -73,7 +72,7 @@ int main (int argc, char *argv[]) // Activate an EPS bearer enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE; EpsBearer bearer (q); -lteHelper->ActivateDataRadioBearer (ueDevs, bearer); + lteHelper->ActivateDataRadioBearer (ueDevs, bearer); Simulator::Stop (Seconds (2)); diff --git a/src/lte/examples/lena-x2-handover.cc b/src/lte/examples/lena-x2-handover.cc index b867bd4ac..1b8495c47 100644 --- a/src/lte/examples/lena-x2-handover.cc +++ b/src/lte/examples/lena-x2-handover.cc @@ -25,11 +25,51 @@ #include "ns3/lte-module.h" #include "ns3/applications-module.h" #include "ns3/point-to-point-module.h" -#include "ns3/config-store.h" -//#include "ns3/gtk-config-store.h" +#include "ns3/config-store-module.h" using namespace ns3; + + +void +NotifyConnectionEstablishedUe (std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti) +{ + std::cout << context << " UE IMSI " << imsi << ": connected to CellId " << cellid << " with RNTI " << rnti << std::endl; +} + +void +NotifyHandoverStartUe (std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti, uint16_t targetCellId) +{ + std::cout << context << " UE IMSI " << imsi << ": previously connected to CellId " << cellid << " with RNTI " << rnti << ", doing handover to CellId " << targetCellId << std::endl; +} + +void +NotifyHandoverEndOkUe (std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti) +{ + std::cout << context << " UE IMSI " << imsi << ": successful handover to CellId " << cellid << " with RNTI " << rnti << std::endl; +} + +void +NotifyConnectionEstablishedEnb (std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti) +{ + std::cout << context << " eNB CellId " << cellid << ": successful connection of UE with IMSI " << imsi << " RNTI " << rnti << std::endl; +} + +void +NotifyHandoverStartEnb (std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti, uint16_t targetCellId) +{ + std::cout << context << " eNB CellId " << cellid << ": start handover of UE with IMSI " << imsi << " RNTI " << rnti << " to CellId " << targetCellId << std::endl; +} + +void +NotifyHandoverEndOkEnb (std::string context, uint64_t imsi, uint16_t cellid, uint16_t rnti) +{ + std::cout << context << " eNB CellId " << cellid << ": completed handover of UE with IMSI " << imsi << " RNTI " << rnti << std::endl; +} + + + + /** * Sample simulation script for a X2-based handover. * It instantiates two eNodeB, attaches one UE to the 'source' eNB and @@ -54,9 +94,16 @@ main (int argc, char *argv[]) uint16_t numberOfUes = 1; uint16_t numberOfEnbs = 2; + uint16_t numBearersPerUe = 2; double simTime = 0.300; double distance = 100.0; + // change some default attributes so that they are reasonable for + // this scenario, but do this before processing command line + // arguments, so that the user is allowed to override these settings + Config::SetDefault ("ns3::UdpClient::Interval", TimeValue (MilliSeconds(10))); + Config::SetDefault ("ns3::UdpClient::MaxPackets", UintegerValue(1000000)); + // Command line arguments CommandLine cmd; cmd.AddValue("numberOfUes", "Number of UEs", numberOfUes); @@ -88,6 +135,8 @@ main (int argc, char *argv[]) Ipv4AddressHelper ipv4h; ipv4h.SetBase ("1.0.0.0", "255.0.0.0"); Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices); + Ipv4Address remoteHostAddr = internetIpIfaces.GetAddress (1); + // Routing of the Internet Host (towards the LTE network) Ipv4StaticRoutingHelper ipv4RoutingHelper; @@ -122,8 +171,8 @@ main (int argc, char *argv[]) // Install the IP stack on the UEs internet.Install (ueNodes); - Ipv4InterfaceContainer ueIpIface; - ueIpIface = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueLteDevs)); + Ipv4InterfaceContainer ueIpIfaces; + ueIpIfaces = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueLteDevs)); // Assign IP address to UEs, and install applications for (uint32_t u = 0; u < ueNodes.GetN (); ++u) { @@ -140,9 +189,67 @@ main (int argc, char *argv[]) lteHelper->Attach (ueLteDevs.Get(i), enbLteDevs.Get(0)); } - // Activate a dedicated EPS Bearer (including Radio Bearer) between UEs and its eNB - // (note that the default EPS bearer will already have been activated) - // lteHelper->ActivateDedicatedEpsBearer (ueLteDevs, EpsBearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT), EpcTft::Default ()); + + NS_LOG_LOGIC ("setting up applications"); + + // Install and start applications on UEs and remote host + uint16_t dlPort = 10000; + uint16_t ulPort = 20000; + + // randomize a bit start times to avoid simulation artifacts + // (e.g., buffer overflows due to packet transmissions happening + // exactly at the same time) + Ptr startTimeSeconds = CreateObject (); + startTimeSeconds->SetAttribute ("Min", DoubleValue (0)); + startTimeSeconds->SetAttribute ("Max", DoubleValue (0.010)); + + for (uint32_t u = 0; u < numberOfUes; ++u) + { + Ptr ue = ueNodes.Get (u); + // Set the default gateway for the UE + Ptr ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ue->GetObject ()); + ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1); + + for (uint32_t b = 0; b < numBearersPerUe; ++b) + { + ++dlPort; + ++ulPort; + + ApplicationContainer clientApps; + ApplicationContainer serverApps; + + NS_LOG_LOGIC ("installing UDP DL app for UE " << u); + UdpClientHelper dlClientHelper (ueIpIfaces.GetAddress (u), dlPort); + clientApps.Add (dlClientHelper.Install (remoteHost)); + PacketSinkHelper dlPacketSinkHelper ("ns3::UdpSocketFactory", + InetSocketAddress (Ipv4Address::GetAny (), dlPort)); + serverApps.Add (dlPacketSinkHelper.Install (ue)); + + NS_LOG_LOGIC ("installing UDP UL app for UE " << u); + UdpClientHelper ulClientHelper (remoteHostAddr, ulPort); + clientApps.Add (ulClientHelper.Install (ue)); + PacketSinkHelper ulPacketSinkHelper ("ns3::UdpSocketFactory", + InetSocketAddress (Ipv4Address::GetAny (), ulPort)); + serverApps.Add (ulPacketSinkHelper.Install (remoteHost)); + + Ptr tft = Create (); + EpcTft::PacketFilter dlpf; + dlpf.localPortStart = dlPort; + dlpf.localPortEnd = dlPort; + tft->Add (dlpf); + EpcTft::PacketFilter ulpf; + ulpf.remotePortStart = ulPort; + ulpf.remotePortEnd = ulPort; + tft->Add (ulpf); + EpsBearer bearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT); + lteHelper->ActivateDedicatedEpsBearer (ueLteDevs.Get (u), bearer, tft); + + Time startTime = Seconds (startTimeSeconds->GetValue ()); + serverApps.Start (startTime); + clientApps.Start (startTime); + + } // end for b + } // Add X2 inteface @@ -156,6 +263,28 @@ main (int argc, char *argv[]) //p2ph.EnablePcapAll("lena-x2-handover"); lteHelper->EnableMacTraces (); + lteHelper->EnableRlcTraces (); + lteHelper->EnablePdcpTraces (); + Ptr rlcStats = lteHelper->GetRlcStats (); + rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (0.05))); + Ptr pdcpStats = lteHelper->GetPdcpStats (); + pdcpStats->SetAttribute ("EpochDuration", TimeValue (Seconds (0.05))); + + + // connect custom trace sinks for RRC connection establishment and handover notification + Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/ConnectionEstablished", + MakeCallback (&NotifyConnectionEstablishedEnb)); + Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/ConnectionEstablished", + MakeCallback (&NotifyConnectionEstablishedUe)); + Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverStart", + MakeCallback (&NotifyHandoverStartEnb)); + Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/HandoverStart", + MakeCallback (&NotifyHandoverStartUe)); + Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/HandoverEndOk", + MakeCallback (&NotifyHandoverEndOkEnb)); + Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/HandoverEndOk", + MakeCallback (&NotifyHandoverEndOkUe)); + Simulator::Stop(Seconds(simTime)); Simulator::Run(); diff --git a/src/lte/helper/lte-helper.cc b/src/lte/helper/lte-helper.cc index 8bd812c5a..80e08127a 100644 --- a/src/lte/helper/lte-helper.cc +++ b/src/lte/helper/lte-helper.cc @@ -643,44 +643,73 @@ LteHelper::ActivateDedicatedEpsBearer (Ptr ueDevice, EpsBearer bearer m_epcHelper->ActivateEpsBearer (ueDevice, imsi, tft, bearer); } +class DrbActivator : public SimpleRefCount +{ +public: + DrbActivator (Ptr ueDevice, EpsBearer bearer); + static void ActivateCallback (Ptr a, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti); + void ActivateDrb (); +private: + bool m_active; + Ptr m_ueDevice; + EpsBearer m_bearer; +}; + +DrbActivator::DrbActivator (Ptr ueDevice, EpsBearer bearer) + : m_active (false), + m_ueDevice (ueDevice), + m_bearer (bearer) +{ +} + +void +DrbActivator::ActivateCallback (Ptr a, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti) +{ + NS_LOG_FUNCTION (a << context << imsi << cellId << rnti); + a->ActivateDrb (); +} + +void +DrbActivator::ActivateDrb () +{ + NS_LOG_FUNCTION (this << m_active); + if (!m_active) + { + Ptr ueRrc = m_ueDevice->GetObject ()->GetRrc (); + NS_ASSERT (ueRrc->GetState () == LteUeRrc::CONNECTED_NORMALLY); + uint16_t rnti = ueRrc->GetRnti(); + Ptr enbLteDevice = m_ueDevice->GetObject ()->GetTargetEnb (); + Ptr enbRrc = enbLteDevice->GetObject ()->GetRrc (); + NS_ASSERT (ueRrc->GetCellId () == enbLteDevice->GetCellId ()); + Ptr ueManager = enbRrc->GetUeManager (rnti); + NS_ASSERT (ueManager->GetState () == UeManager::CONNECTION_SETUP); + EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters params; + params.rnti = rnti; + params.bearer = m_bearer; + params.bearerId = 0; + params.gtpTeid = 0; // don't care + enbRrc->GetS1SapUser ()->DataRadioBearerSetupRequest (params); + m_active = true; + } +} + + void LteHelper::ActivateDataRadioBearer (Ptr ueDevice, EpsBearer bearer) { NS_LOG_FUNCTION (this << ueDevice); NS_ASSERT_MSG (m_epcHelper == 0, "this method must not be used when EPC is being used"); - /* - * Note: this method is kind of a hack, just because running - * simulations without the EPC is kind of a hack. - */ - - Ptr ueRrc = ueDevice->GetObject ()->GetRrc (); - bool done = false; - if (ueRrc->GetState () == LteUeRrc::CONNECTED_NORMALLY) - { - uint16_t rnti = ueRrc->GetRnti(); - Ptr enbLteDevice = ueDevice->GetObject ()->GetTargetEnb (); - Ptr enbRrc = enbLteDevice->GetObject ()->GetRrc (); - NS_ASSERT (ueRrc->GetCellId () == enbLteDevice->GetCellId ()); - Ptr ueManager = enbRrc->GetUeManager (rnti); - if (ueManager->GetState () == UeManager::CONNECTED_NORMALLY) - { - EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters params; - params.rnti = rnti; - params.bearer = bearer; - params.bearerId = 0; - params.gtpTeid = 0; // don't care - enbRrc->GetS1SapUser ()->DataRadioBearerSetupRequest (params); - done = true; - } - } - - if (!done) // UE not connected yet, try again later - { - // use a function pointer to get around overloading - void (LteHelper::*functionPtr) (NetDeviceContainer ueDevices, EpsBearer bearer) = &LteHelper::ActivateDataRadioBearer; - Simulator::Schedule (Seconds (0.001), functionPtr, this, ueDevice, bearer); - } + // Normally it is the EPC that takes care of activating DRBs + // after the UE gets connected. When the EPC is not used, we achieve + // the same behavior by hooking a dedicated DRB activation function + // to the UE RRC Connection Established trace source + std::ostringstream path; + path << "/NodeList/" << ueDevice->GetNode ()->GetId () + << "/DeviceList/" << ueDevice->GetIfIndex () + << "/LteUeRrc/ConnectionEstablished"; + Ptr arg = Create (ueDevice, bearer); + Config::Connect (path.str (), MakeBoundCallback (&DrbActivator::ActivateCallback, arg)); } void @@ -781,8 +810,7 @@ LteHelper::EnableTraces (void) void LteHelper::EnableRlcTraces (void) { - EnableDlRlcTraces (); - EnableUlRlcTraces (); + m_radioBearerStatsConnector.EnableRlcStats (m_rlcStats); } int64_t @@ -861,55 +889,6 @@ FindCellIdFromEnbRlcPath (std::string path) } } -uint64_t -FindImsiFromUeRlcPath (std::string path) -{ - NS_LOG_FUNCTION (path); - // Sample path input: - // /NodeList/#NodeId/DeviceList/#DeviceId/LteUeRrc/RadioBearer/#LCID/RxPDU - - // We retrieve the LteUeNetDevice path - std::string lteUeNetDevicePath = path.substr (0, path.find ("/LteUeRrc")); - Config::MatchContainer match = Config::LookupMatches (lteUeNetDevicePath); - - if (match.GetN () != 0) - { - Ptr ueNetDevice = match.Get (0); - NS_LOG_LOGIC ("FindImsiFromUeRlcPath: " << path << ", " << ueNetDevice->GetObject ()->GetImsi ()); - return ueNetDevice->GetObject ()->GetImsi (); - } - else - { - NS_FATAL_ERROR ("Lookup " << lteUeNetDevicePath << " got no matches"); - } - -} - -uint16_t -FindCellIdFromUeRlcPath (std::string path) -{ - NS_LOG_FUNCTION (path); - // Sample path input: - // /NodeList/#NodeId/DeviceList/#DeviceId/LteUeRrc/RadioBearer/#LCID/RxPDU - - // We retrieve the LteUeNetDevice path - std::string lteUeNetDevicePath = path.substr (0, path.find ("/LteUeRrc")); - Config::MatchContainer match = Config::LookupMatches (lteUeNetDevicePath); - - if (match.GetN () != 0) - { - Ptr ueNetDevice = match.Get (0); - NS_LOG_LOGIC ("FindImsiFromUeRlcPath: " << path << ", " << ueNetDevice->GetObject ()->GetImsi ()); - return ueNetDevice->GetObject ()->GetRrc ()->GetCellId (); - } - else - { - NS_FATAL_ERROR ("Lookup " << lteUeNetDevicePath << " got no matches"); - } - -} - - uint64_t FindImsiFromEnbMac (std::string path, uint16_t rnti) { @@ -939,131 +918,6 @@ FindCellIdFromEnbMac (std::string path, uint16_t rnti) } -void -DlTxPduCallback (Ptr rlcStats, std::string path, - uint16_t rnti, uint8_t lcid, uint32_t packetSize) -{ - NS_LOG_FUNCTION (rlcStats << path << rnti << (uint16_t)lcid << packetSize); - uint64_t imsi = 0; - if (rlcStats->ExistsImsiPath (path) == true) - { - imsi = rlcStats->GetImsiPath (path); - } - else - { - imsi = FindImsiFromEnbRlcPath (path); - rlcStats->SetImsiPath (path, imsi); - } - uint16_t cellId = 0; - if (rlcStats->ExistsCellIdPath (path) == true) - { - cellId = rlcStats->GetCellIdPath (path); - } - else - { - cellId = FindCellIdFromEnbRlcPath (path); - rlcStats->SetCellIdPath (path, cellId); - } - rlcStats->DlTxPdu (cellId, imsi, rnti, lcid, packetSize); -} - -void -DlRxPduCallback (Ptr rlcStats, std::string path, - uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay) -{ - NS_LOG_FUNCTION (rlcStats << path << rnti << (uint16_t)lcid << packetSize << delay); - uint64_t imsi = 0; - if (rlcStats->ExistsImsiPath (path) == true) - { - imsi = rlcStats->GetImsiPath (path); - } - else - { - imsi = FindImsiFromUeRlcPath (path); - rlcStats->SetImsiPath (path, imsi); - } - - uint16_t cellId = 0; - if (rlcStats->ExistsCellIdPath (path) == true) - { - cellId = rlcStats->GetCellIdPath (path); - } - else - { - cellId = FindCellIdFromUeRlcPath (path); - rlcStats->SetCellIdPath (path, cellId); - } - rlcStats->DlRxPdu (cellId, imsi, rnti, lcid, packetSize, delay); -} - -void -LteHelper::EnableDlRlcTraces (void) -{ - NS_LOG_FUNCTION_NOARGS (); - Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/UeMap/*/DataRadioBearerMap/*/LteRlc/TxPDU", - MakeBoundCallback (&DlTxPduCallback, m_rlcStats)); - Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/DataRadioBearerMap/*/LteRlc/RxPDU", - MakeBoundCallback (&DlRxPduCallback, m_rlcStats)); -} - -void -UlTxPduCallback (Ptr rlcStats, std::string path, - uint16_t rnti, uint8_t lcid, uint32_t packetSize) -{ - NS_LOG_FUNCTION (rlcStats << path << rnti << (uint16_t)lcid << packetSize); - uint64_t imsi = 0; - if (rlcStats->ExistsImsiPath (path) == true) - { - imsi = rlcStats->GetImsiPath (path); - } - else - { - imsi = FindImsiFromUeRlcPath (path); - rlcStats->SetImsiPath (path, imsi); - } - - uint16_t cellId = 0; - if (rlcStats->ExistsCellIdPath (path) == true) - { - cellId = rlcStats->GetCellIdPath (path); - } - else - { - cellId = FindCellIdFromUeRlcPath (path); - rlcStats->SetCellIdPath (path, cellId); - } - rlcStats->UlTxPdu (cellId, imsi, rnti, lcid, packetSize); -} - -void -UlRxPduCallback (Ptr rlcStats, std::string path, - uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay) -{ - NS_LOG_FUNCTION (rlcStats << path << rnti << (uint16_t)lcid << packetSize << delay); - uint64_t imsi = 0; - if (rlcStats->ExistsImsiPath (path) == true) - { - imsi = rlcStats->GetImsiPath (path); - } - else - { - imsi = FindImsiFromEnbRlcPath (path); - rlcStats->SetImsiPath (path, imsi); - } - uint16_t cellId = 0; - if (rlcStats->ExistsCellIdPath (path) == true) - { - cellId = rlcStats->GetCellIdPath (path); - } - else - { - cellId = FindCellIdFromEnbRlcPath (path); - rlcStats->SetCellIdPath (path, cellId); - } - rlcStats->UlRxPdu (cellId, imsi, rnti, lcid, packetSize, delay); -} - - void DlSchedulingCallback (Ptr macStats, std::string path, uint32_t frameNo, uint32_t subframeNo, @@ -1098,16 +952,6 @@ DlSchedulingCallback (Ptr macStats, macStats->DlScheduling (cellId, imsi, frameNo, subframeNo, rnti, mcsTb1, sizeTb1, mcsTb2, sizeTb2); } -void -LteHelper::EnableUlRlcTraces (void) -{ - NS_LOG_FUNCTION_NOARGS (); - Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/DataRadioBearerMap/*/LteRlc/TxPDU", - MakeBoundCallback (&UlTxPduCallback, m_rlcStats)); - Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/UeMap/*/DataRadioBearerMap/*/LteRlc/RxPDU", - MakeBoundCallback (&UlRxPduCallback, m_rlcStats)); -} - void LteHelper::EnableMacTraces (void) { @@ -1172,27 +1016,7 @@ LteHelper::GetRlcStats (void) void LteHelper::EnablePdcpTraces (void) { - EnableDlPdcpTraces (); - EnableUlPdcpTraces (); -} - -void -LteHelper::EnableDlPdcpTraces (void) -{ - NS_LOG_FUNCTION_NOARGS (); - Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/UeMap/*/DataRadioBearerMap/*/LtePdcp/TxPDU", - MakeBoundCallback (&DlTxPduCallback, m_pdcpStats)); - Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/DataRadioBearerMap/*/LtePdcp/RxPDU", - MakeBoundCallback (&DlRxPduCallback, m_pdcpStats)); -} - -void -LteHelper::EnableUlPdcpTraces (void) -{ - Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/DataRadioBearerMap/*/LtePdcp/TxPDU", - MakeBoundCallback (&UlTxPduCallback, m_pdcpStats)); - Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/UeMap/*/DataRadioBearerMap/*/LtePdcp/RxPDU", - MakeBoundCallback (&UlRxPduCallback, m_pdcpStats)); + m_radioBearerStatsConnector.EnablePdcpStats (m_pdcpStats); } Ptr diff --git a/src/lte/helper/lte-helper.h b/src/lte/helper/lte-helper.h index 4fbca4ba0..869ea64d0 100644 --- a/src/lte/helper/lte-helper.h +++ b/src/lte/helper/lte-helper.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -252,17 +253,6 @@ public: void HandoverRequest (Time hoTime, Ptr ueDev, Ptr sourceEnbDev, Ptr targetEnbDev); - /** - * Activate a Data Radio Bearer for a simplified LTE-only simulation - * without EPC. - * - * \param ueDevice the device of the UE for which the radio bearer - * is to be activated - * \param bearer the characteristics of the bearer to be activated - */ - void ActivateDataRadioBearer (Ptr ueDevice, EpsBearer bearer); - - /** * Call ActivateDataRadioBearer (ueDevice, bearer) for each UE * device in a given set @@ -272,6 +262,17 @@ public: */ void ActivateDataRadioBearer (NetDeviceContainer ueDevices, EpsBearer bearer); + /** + * Activate a Data Radio Bearer for a simplified LTE-only simulation + * without EPC. This method will schedule the actual activation of + * the bearer so that it happens after the UE got connected. + * + * \param ueDevice the device of the UE for which the radio bearer + * is to be activated + * \param bearer the characteristics of the bearer to be activated + */ + void ActivateDataRadioBearer (Ptr ueDevice, EpsBearer bearer); + /** * * @@ -315,16 +316,6 @@ public: */ void EnableRlcTraces (void); - /** - * Enable trace sinks for DL RLC layer - */ - void EnableDlRlcTraces (void); - - /** - * Enable trace sinks for UL MAC layer - */ - void EnableUlRlcTraces (void); - /** * * \return the RLC stats calculator object @@ -336,16 +327,6 @@ public: */ void EnablePdcpTraces (void); - /** - * Enable trace sinks for DL PDCP layer - */ - void EnableDlPdcpTraces (void); - - /** - * Enable trace sinks for UL MAC layer - */ - void EnableUlPdcpTraces (void); - /** * * \return the PDCP stats calculator object @@ -403,6 +384,7 @@ private: Ptr m_macStats; Ptr m_rlcStats; Ptr m_pdcpStats; + RadioBearerStatsConnector m_radioBearerStatsConnector; Ptr m_epcHelper; diff --git a/src/lte/model/lte-enb-rrc.cc b/src/lte/model/lte-enb-rrc.cc index 0d0bac90d..89cb23f95 100644 --- a/src/lte/model/lte-enb-rrc.cc +++ b/src/lte/model/lte-enb-rrc.cc @@ -253,8 +253,8 @@ TypeId UeManager::GetTypeId (void) MakeObjectMapChecker ()) .AddTraceSource ("StateTransition", "fired upon every UE state transition seen by the UeManager at the eNB RRC", - MakeTraceSourceAccessor (&UeManager::m_stateTransitionCallback)) - ; + MakeTraceSourceAccessor (&UeManager::m_stateTransitionTrace)) + ; return tid; } @@ -408,6 +408,8 @@ UeManager::SendHandoverCommand (LteRrcSap::RrcConnectionReconfiguration rcr) NS_LOG_FUNCTION (this); m_rrc->m_rrcSapUser->SendRrcConnectionReconfiguration (m_rnti, rcr); SwitchToState (HANDOVER_LEAVING); + NS_ASSERT (rcr.haveMobilityControlInfo); + m_rrc->m_handoverStartTrace (m_imsi, m_rrc->m_cellId, m_rnti, rcr.mobilityControlInfo.targetPhysCellId); } LteRrcSap::RadioResourceConfigDedicated @@ -471,6 +473,7 @@ UeManager::SendUeContextRelease () ueCtxReleaseParams.sourceCellId = m_sourceCellId; m_rrc->m_x2SapProvider->SendUeContextRelease (ueCtxReleaseParams); SwitchToState (CONNECTED_NORMALLY); + m_rrc->m_handoverEndOkTrace (m_imsi, m_rrc->m_cellId, m_rnti); break; default: @@ -525,6 +528,7 @@ UeManager::RecvRrcConnectionSetupCompleted (LteRrcSap::RrcConnectionSetupComplet { case CONNECTION_SETUP: SwitchToState (CONNECTED_NORMALLY); + m_rrc->m_connectionEstablishedTrace (m_imsi, m_rrc->m_cellId, m_rnti); break; default: @@ -541,6 +545,7 @@ UeManager::RecvRrcConnectionReconfigurationCompleted (LteRrcSap::RrcConnectionRe { case CONNECTION_RECONFIGURATION: SwitchToState (CONNECTED_NORMALLY); + m_rrc->m_connectionReconfigurationTrace (m_imsi, m_rrc->m_cellId, m_rnti); break; case HANDOVER_LEAVING: @@ -817,7 +822,7 @@ UeManager::SwitchToState (State newState) State oldState = m_state; m_state = newState; NS_LOG_INFO ("IMSI " << m_imsi << " RNTI " << m_rnti << " UeManager " << ToString (oldState) << " --> " << ToString (newState)); - m_stateTransitionCallback (oldState, newState); + m_stateTransitionTrace (m_imsi, m_rrc->m_cellId, m_rnti, oldState, newState); switch (newState) { @@ -929,7 +934,19 @@ LteEnbRrc::GetTypeId (void) "The interval for sending system information", TimeValue (MilliSeconds (80)), MakeTimeAccessor (&LteEnbRrc::m_systemInformationPeriodicity), - MakeTimeChecker ()) + MakeTimeChecker ()) + .AddTraceSource ("ConnectionEstablished", + "trace fired upon successful RRC connection establishment", + MakeTraceSourceAccessor (&LteEnbRrc::m_connectionEstablishedTrace)) + .AddTraceSource ("ConnectionReconfiguration", + "trace fired upon RRC connection reconfiguration", + MakeTraceSourceAccessor (&LteEnbRrc::m_connectionReconfigurationTrace)) + .AddTraceSource ("HandoverStart", + "trace fired upon start of a handover procedure", + MakeTraceSourceAccessor (&LteEnbRrc::m_handoverStartTrace)) + .AddTraceSource ("HandoverEndOk", + "trace fired upon successful termination of a handover procedure", + MakeTraceSourceAccessor (&LteEnbRrc::m_handoverEndOkTrace)) ; return tid; } diff --git a/src/lte/model/lte-enb-rrc.h b/src/lte/model/lte-enb-rrc.h index 65c0b5a68..19bd3778d 100644 --- a/src/lte/model/lte-enb-rrc.h +++ b/src/lte/model/lte-enb-rrc.h @@ -348,7 +348,8 @@ private: State m_state; LtePdcpSapUser* m_drbPdcpSapUser; bool m_pendingRrcConnectionReconfiguration; - TracedCallback m_stateTransitionCallback; + // imsi cellid rnti old new + TracedCallback m_stateTransitionTrace; uint16_t m_sourceX2apId; uint16_t m_sourceCellId; }; @@ -685,6 +686,15 @@ private: uint16_t m_lastAllocatedConfigurationIndex; bool m_reconfigureUes; + // imsi cellid rnti + TracedCallback m_connectionEstablishedTrace; + // imsi cellid rnti + TracedCallback m_connectionReconfigurationTrace; + // imsi cellid rnti targetCellId + TracedCallback m_handoverStartTrace; + // imsi cellid rnti + TracedCallback m_handoverEndOkTrace; + }; diff --git a/src/lte/model/lte-ue-rrc.cc b/src/lte/model/lte-ue-rrc.cc index fb31e0ac8..7c45d12ab 100644 --- a/src/lte/model/lte-ue-rrc.cc +++ b/src/lte/model/lte-ue-rrc.cc @@ -177,8 +177,20 @@ LteUeRrc::GetTypeId (void) MakeUintegerAccessor (&LteUeRrc::GetRnti), MakeUintegerChecker ()) .AddTraceSource ("StateTransition", - "fired upon every UE RRC state transition", - MakeTraceSourceAccessor (&LteUeRrc::m_stateTransitionCallback)) + "trace fired upon every UE RRC state transition", + MakeTraceSourceAccessor (&LteUeRrc::m_stateTransitionTrace)) + .AddTraceSource ("ConnectionEstablished", + "trace fired upon successful RRC connection establishment", + MakeTraceSourceAccessor (&LteUeRrc::m_connectionEstablishedTrace)) + .AddTraceSource ("ConnectionReconfiguration", + "trace fired upon RRC connection reconfiguration", + MakeTraceSourceAccessor (&LteUeRrc::m_connectionReconfigurationTrace)) + .AddTraceSource ("HandoverStart", + "trace fired upon start of a handover procedure", + MakeTraceSourceAccessor (&LteUeRrc::m_handoverStartTrace)) + .AddTraceSource ("HandoverEndOk", + "trace fired upon successful termination of a handover procedure", + MakeTraceSourceAccessor (&LteUeRrc::m_handoverEndOkTrace)) ; return tid; } @@ -428,6 +440,7 @@ LteUeRrc::DoNotifyRandomAccessSuccessful () msg.rrcTransactionIdentifier = m_lastRrcTransactionIdentifier; m_rrcSapUser->SendRrcConnectionReconfigurationCompleted (msg); SwitchToState (CONNECTED_NORMALLY); + m_handoverEndOkTrace (m_imsi, m_cellId, m_rnti); } break; @@ -564,6 +577,7 @@ LteUeRrc::DoRecvRrcConnectionSetup (LteRrcSap::RrcConnectionSetup msg) msg2.rrcTransactionIdentifier = msg.rrcTransactionIdentifier; m_rrcSapUser->SendRrcConnectionSetupCompleted (msg2); m_asSapUser->NotifyConnectionSuccessful (); + m_connectionEstablishedTrace (m_imsi, m_cellId, m_rnti); } break; @@ -589,6 +603,7 @@ LteUeRrc::DoRecvRrcConnectionReconfiguration (LteRrcSap::RrcConnectionReconfigur NS_LOG_INFO ("haveMobilityControlInfo == true"); SwitchToState (CONNECTED_HANDOVER); const LteRrcSap::MobilityControlInfo& mci = msg.mobilityControlInfo; + m_handoverStartTrace (m_imsi, m_cellId, m_rnti, mci.targetPhysCellId); m_cellId = mci.targetPhysCellId; NS_ASSERT (mci.haveCarrierFreq); NS_ASSERT (mci.haveCarrierBandwidth); @@ -609,6 +624,7 @@ LteUeRrc::DoRecvRrcConnectionReconfiguration (LteRrcSap::RrcConnectionReconfigur LteRrcSap::RrcConnectionReconfigurationCompleted msg2; msg2.rrcTransactionIdentifier = msg.rrcTransactionIdentifier; m_rrcSapUser->SendRrcConnectionReconfigurationCompleted (msg2); + m_connectionReconfigurationTrace (m_imsi, m_cellId, m_rnti); } break; @@ -871,7 +887,7 @@ LteUeRrc::SwitchToState (State newState) State oldState = m_state; m_state = newState; NS_LOG_INFO ("IMSI " << m_imsi << " RNTI " << m_rnti << " UeRrc " << ToString (oldState) << " --> " << ToString (newState)); - m_stateTransitionCallback (oldState, newState); + m_stateTransitionTrace (m_imsi, m_cellId, m_rnti, oldState, newState); switch (newState) { diff --git a/src/lte/model/lte-ue-rrc.h b/src/lte/model/lte-ue-rrc.h index 808e6a3a2..c5f9f6004 100644 --- a/src/lte/model/lte-ue-rrc.h +++ b/src/lte/model/lte-ue-rrc.h @@ -293,7 +293,16 @@ private: uint16_t m_dlEarfcn; /**< downlink carrier frequency */ uint16_t m_ulEarfcn; /**< uplink carrier frequency */ - TracedCallback m_stateTransitionCallback; + // imsi cellid rnti + TracedCallback m_stateTransitionTrace; + // imsi cellid rnti + TracedCallback m_connectionEstablishedTrace; + // imsi cellid rnti + TracedCallback m_connectionReconfigurationTrace; + // imsi cellid rnti targetCellId + TracedCallback m_handoverStartTrace; + // imsi cellid rnti + TracedCallback m_handoverEndOkTrace; bool m_connectionPending; /**< true if a connection request by upper layers is pending */ bool m_receivedMib; /**< true if MIB was received for the current cell */ diff --git a/src/lte/test/lte-test-harq.cc b/src/lte/test/lte-test-harq.cc index a45e32b86..2fd7d9dfb 100644 --- a/src/lte/test/lte-test-harq.cc +++ b/src/lte/test/lte-test-harq.cc @@ -223,7 +223,7 @@ LenaHarqTestCase::DoRun (void) double statsDuration = 4.0; Simulator::Stop (Seconds (statsStartTime + statsDuration - 0.0001)); - Simulator::Schedule (Seconds (statsStartTime), &LteHelper::EnableRlcTraces, lena); + lena->EnableRlcTraces (); Ptr rlcStats = lena->GetRlcStats (); rlcStats->SetAttribute ("StartTime", TimeValue (Seconds (statsStartTime))); rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (statsDuration))); diff --git a/src/lte/test/lte-test-mimo.cc b/src/lte/test/lte-test-mimo.cc index b2c087ad7..274fd9ae4 100644 --- a/src/lte/test/lte-test-mimo.cc +++ b/src/lte/test/lte-test-mimo.cc @@ -173,7 +173,7 @@ LenaMimoTestCase::DoRun (void) uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0)); // need to allow for RRC connection establishment + SRS before enabling traces - Simulator::Schedule (Seconds (0.050), &LteHelper::EnableRlcTraces, lteHelper); + lteHelper->EnableRlcTraces (); lteHelper->EnableMacTraces (); double simulationTime = 0.401; double tolerance = 0.1; 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 86be27e57..7bc4c224b 100644 --- a/src/lte/test/lte-test-pf-ff-mac-scheduler.cc +++ b/src/lte/test/lte-test-pf-ff-mac-scheduler.cc @@ -274,7 +274,7 @@ LenaPfFfMacSchedulerTestCase1::DoRun (void) Simulator::Stop (Seconds (statsStartTime + statsDuration - 0.000001)); lteHelper->EnableMacTraces (); - Simulator::Schedule (Seconds (statsStartTime), &LteHelper::EnableRlcTraces, lteHelper); + lteHelper->EnableRlcTraces (); Ptr rlcStats = lteHelper->GetRlcStats (); rlcStats->SetAttribute ("StartTime", TimeValue (Seconds (statsStartTime))); rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (statsDuration))); @@ -433,7 +433,7 @@ LenaPfFfMacSchedulerTestCase2::DoRun (void) double tolerance = 0.1; Simulator::Stop (Seconds (statsStartTime + statsDuration + 0.000001)); - Simulator::Schedule (Seconds (statsStartTime), &LteHelper::EnableRlcTraces, lteHelper); + lteHelper->EnableRlcTraces (); Ptr rlcStats = lteHelper->GetRlcStats (); rlcStats->SetAttribute ("StartTime", TimeValue (Seconds (statsStartTime))); rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (statsDuration))); 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 782b35cc5..6e1a88e0f 100644 --- a/src/lte/test/lte-test-rr-ff-mac-scheduler.cc +++ b/src/lte/test/lte-test-rr-ff-mac-scheduler.cc @@ -259,12 +259,11 @@ LenaRrFfMacSchedulerTestCase::DoRun (void) double tolerance = 0.1; Simulator::Stop (Seconds (statsStartTime + statsDuration - 0.0001)); - Simulator::Schedule (Seconds (statsStartTime), &LteHelper::EnableRlcTraces, lteHelper); + lteHelper->EnableRlcTraces (); Ptr rlcStats = lteHelper->GetRlcStats (); rlcStats->SetAttribute ("StartTime", TimeValue (Seconds (statsStartTime))); rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (statsDuration))); - Simulator::Run (); /** diff --git a/src/lte/test/test-lte-epc-e2e-data.cc b/src/lte/test/test-lte-epc-e2e-data.cc index 591a03eba..92fb06d85 100644 --- a/src/lte/test/test-lte-epc-e2e-data.cc +++ b/src/lte/test/test-lte-epc-e2e-data.cc @@ -272,7 +272,7 @@ LteEpcE2eDataTestCase::DoRun () Time simulationTime = Seconds (2.0); double statsStartTime = 0.040; // need to allow for RRC connection establishment + SRS - Simulator::Schedule (Seconds (statsStartTime), &LteHelper::EnablePdcpTraces, lteHelper); + lteHelper->EnablePdcpTraces (); lteHelper->GetPdcpStats ()->SetAttribute ("StartTime", TimeValue (Seconds (statsStartTime))); lteHelper->GetPdcpStats ()->SetAttribute ("EpochDuration", TimeValue (simulationTime)); diff --git a/src/lte/test/test-lte-x2-handover.cc b/src/lte/test/test-lte-x2-handover.cc index 9686c7f01..3b8c10f13 100644 --- a/src/lte/test/test-lte-x2-handover.cc +++ b/src/lte/test/test-lte-x2-handover.cc @@ -381,6 +381,12 @@ LteX2HandoverTestCase::DoRun () stopTime = hoEndTime + MilliSeconds (1); } } + + m_lteHelper->EnableRlcTraces (); + Ptr rlcStats = m_lteHelper->GetRlcStats (); + rlcStats->SetAttribute ("StartTime", TimeValue (Seconds (0.101))); + rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (0.1))); + m_lteHelper->EnablePdcpTraces(); Simulator::Stop (stopTime); @@ -571,6 +577,9 @@ LteX2HandoverTestSuite::LteX2HandoverTestSuite () hel7.push_back (ue2fwd); hel7.push_back (ue2bwd); + AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel1, hel0name, true, "ns3::RrFfMacScheduler")); + return; + // nUes, nDBearers, helist, name, useUdp, scheduler AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel0, hel0name, true, "ns3::RrFfMacScheduler")); AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel0, hel0name, true, "ns3::RrFfMacScheduler")); diff --git a/src/lte/wscript b/src/lte/wscript index 56b16e15f..8658d59e7 100644 --- a/src/lte/wscript +++ b/src/lte/wscript @@ -41,6 +41,7 @@ def build(bld): 'helper/lte-stats-calculator.cc', 'helper/epc-helper.cc', 'helper/radio-bearer-stats-calculator.cc', + 'helper/radio-bearer-stats-connector.cc', 'helper/mac-stats-calculator.cc', 'helper/radio-environment-map-helper.cc', 'helper/lte-hex-grid-enb-topology-helper.cc', @@ -162,6 +163,7 @@ def build(bld): 'helper/epc-helper.h', 'helper/mac-stats-calculator.h', 'helper/radio-bearer-stats-calculator.h', + 'helper/radio-bearer-stats-connector.h', 'helper/radio-environment-map-helper.h', 'helper/lte-hex-grid-enb-topology-helper.h', 'model/rem-spectrum-phy.h',