From 5c4da02bdd6dc2ffa748b850a0cf52b2e52875d5 Mon Sep 17 00:00:00 2001 From: Nicola Baldo Date: Fri, 23 Nov 2012 17:24:02 +0100 Subject: [PATCH] added lte-x2-handover test suite --- src/lte/helper/lte-helper.cc | 5 +- src/lte/model/lte-enb-rrc.cc | 44 +-- src/lte/test/test-lte-x2-handover.cc | 491 +++++++++++++++++++++++++++ src/lte/wscript | 3 +- 4 files changed, 518 insertions(+), 25 deletions(-) create mode 100644 src/lte/test/test-lte-x2-handover.cc diff --git a/src/lte/helper/lte-helper.cc b/src/lte/helper/lte-helper.cc index a10e9c511..018e44249 100644 --- a/src/lte/helper/lte-helper.cc +++ b/src/lte/helper/lte-helper.cc @@ -664,6 +664,7 @@ void LteHelper::HandoverRequest (Time hoTime, Ptr ueDev, Ptr sourceEnbDev, Ptr targetEnbDev) { NS_LOG_FUNCTION (this << ueDev << sourceEnbDev << targetEnbDev); + NS_ASSERT_MSG (m_epcHelper, "Handover requires the use of the EPC - did you forget to call LteHelper::SetEpcHelper () ?"); Simulator::Schedule (hoTime, &LteHelper::DoHandoverRequest, this, ueDev, sourceEnbDev, targetEnbDev); } @@ -674,8 +675,8 @@ LteHelper::DoHandoverRequest (Ptr ueDev, Ptr sourceEnbDev, uint16_t targetCellId = targetEnbDev->GetObject ()->GetCellId (); Ptr sourceRrc = sourceEnbDev->GetObject ()->GetRrc (); - uint64_t imsi = ueDev->GetObject ()->GetImsi (); - sourceRrc->SendHandoverRequest (imsi, targetCellId); + uint16_t rnti = ueDev->GetObject ()->GetRrc ()->GetRnti (); + sourceRrc->SendHandoverRequest (rnti, targetCellId); } diff --git a/src/lte/model/lte-enb-rrc.cc b/src/lte/model/lte-enb-rrc.cc index 4c5cd35c1..cab161a09 100644 --- a/src/lte/model/lte-enb-rrc.cc +++ b/src/lte/model/lte-enb-rrc.cc @@ -1343,6 +1343,7 @@ LteEnbRrc::GetNewSrsConfigurationIndex () // SRS if (m_srsCurrentPeriodicityId==0) { + NS_ASSERT (m_ueSrsConfigurationIndexSet.empty ()); // no UEs -> init m_ueSrsConfigurationIndexSet.insert (0); m_lastAllocatedConfigurationIndex = 0; @@ -1383,6 +1384,7 @@ LteEnbRrc::GetNewSrsConfigurationIndex () { // find a CI from the available ones std::set::reverse_iterator rit = m_ueSrsConfigurationIndexSet.rbegin (); + NS_ASSERT (rit != m_ueSrsConfigurationIndexSet.rend ()); NS_LOG_DEBUG (this << " lower bound " << (*rit) << " of " << g_srsCiHigh[m_srsCurrentPeriodicityId]); if ((*rit) <= g_srsCiHigh[m_srsCurrentPeriodicityId]) { @@ -1417,37 +1419,35 @@ LteEnbRrc::RemoveSrsConfigurationIndex (uint16_t srcCi) std::set::iterator it = m_ueSrsConfigurationIndexSet.find (srcCi); NS_ASSERT_MSG (it != m_ueSrsConfigurationIndexSet.end (), "request to remove unkwown SRS CI " << srcCi); m_ueSrsConfigurationIndexSet.erase (it); - NS_ASSERT (m_srsCurrentPeriodicityId >= 1 && m_srsCurrentPeriodicityId <= SRS_ENTRIES); + + if (m_ueSrsConfigurationIndexSet.empty ()) + { + m_srsCurrentPeriodicityId = 0; + return; + } + + NS_ASSERT (m_srsCurrentPeriodicityId > 1 && m_srsCurrentPeriodicityId <= SRS_ENTRIES); if (m_ueSrsConfigurationIndexSet.size () < g_srsPeriodicity[m_srsCurrentPeriodicityId - 1]) { // reduce the periodicity m_ueSrsConfigurationIndexSet.clear (); m_srsCurrentPeriodicityId--; - if (m_srsCurrentPeriodicityId==0) + // update all the UE's CI + uint16_t srcCi = g_srsCiLow[m_srsCurrentPeriodicityId]; + std::map >::iterator it; + for (it = m_ueMap.begin (); it != m_ueMap.end (); it++) { - // no active users : renitialize structures - m_lastAllocatedConfigurationIndex = 0; - } - else - { - // update all the UE's CI - uint16_t srcCi = g_srsCiLow[m_srsCurrentPeriodicityId]; - std::map >::iterator it; - for (it = m_ueMap.begin (); it != m_ueMap.end (); it++) - { - (*it).second->SetSrsConfigurationIndex (srcCi); - m_ueSrsConfigurationIndexSet.insert (srcCi); - m_lastAllocatedConfigurationIndex = srcCi; + (*it).second->SetSrsConfigurationIndex (srcCi); + m_ueSrsConfigurationIndexSet.insert (srcCi); + m_lastAllocatedConfigurationIndex = srcCi; - - // update UeManager and trigger/update RRC connection reconfiguration - (*it).second->SetSrsConfigurationIndex (srcCi); + // update UeManager and trigger/update RRC connection reconfiguration + (*it).second->SetSrsConfigurationIndex (srcCi); - // configure PHY - m_cphySapProvider->SetSrsConfigurationIndex ((*it).first, (*it).second->GetSrsConfigurationIndex ()); + // configure PHY + m_cphySapProvider->SetSrsConfigurationIndex ((*it).first, (*it).second->GetSrsConfigurationIndex ()); - srcCi++; - } + srcCi++; } } } diff --git a/src/lte/test/test-lte-x2-handover.cc b/src/lte/test/test-lte-x2-handover.cc new file mode 100644 index 000000000..93f85d0b4 --- /dev/null +++ b/src/lte/test/test-lte-x2-handover.cc @@ -0,0 +1,491 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2012 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: Nicola Baldo + */ + + +#include +#include +#include +#include +#include +#include +#include + +NS_LOG_COMPONENT_DEFINE ("LteX2HandoverTest"); + +namespace ns3 { + +struct HandoverEvent +{ + Time startTime; + uint32_t ueDeviceIndex; + uint32_t sourceEnbDeviceIndex; + uint32_t targetEnbDeviceIndex; +}; + + +class LteX2HandoverTestCase : public TestCase +{ +public: + + /** + * + * + * \param nUes number of UEs in the test + * \param nDedicatedBearers number of bearers to be activated per UE + * \param handoverEventList + * \param handoverEventListName + * \param useUdp true if UDP is to be used, false if TCP is to be used + * + * \return + */ + LteX2HandoverTestCase (uint32_t nUes, uint32_t nDedicatedBearers, std::list handoverEventList, std::string handoverEventListName, bool useUdp, std::string schedulerType); + +private: + static std::string BuildNameString (uint32_t nUes, uint32_t nDedicatedBearers, std::string handoverEventListName, bool useUdp, std::string schedulerType); + virtual void DoRun (void); + void CheckConnected (Ptr ueDevice, Ptr enbDevice); + + + uint32_t m_nUes; // number of UEs in the test + uint32_t m_nDedicatedBearers; // number of UEs in the test + std::list m_handoverEventList; + std::string m_handoverEventListName; + bool m_epc; + bool m_useUdp; + std::string m_schedulerType; + Ptr m_lteHelper; + Ptr m_epcHelper; +}; + + +std::string LteX2HandoverTestCase::BuildNameString (uint32_t nUes, uint32_t nDedicatedBearers, std::string handoverEventListName, bool useUdp, std::string schedulerType) +{ + std::ostringstream oss; + oss << " nUes=" << nUes + << " nDedicatedBearers=" << nDedicatedBearers + << " udp=" << useUdp + << " " << schedulerType + << " hoList: " << handoverEventListName; + return oss.str (); +} + +LteX2HandoverTestCase::LteX2HandoverTestCase (uint32_t nUes, uint32_t nDedicatedBearers, std::list handoverEventList, std::string handoverEventListName, bool useUdp, std::string schedulerType) + : TestCase (BuildNameString (nUes, nDedicatedBearers, handoverEventListName, useUdp, schedulerType)), + m_nUes (nUes), + m_nDedicatedBearers (nDedicatedBearers), + m_handoverEventList (handoverEventList), + m_handoverEventListName (handoverEventListName), + m_epc (true), + m_useUdp (useUdp), + m_schedulerType (schedulerType) +{ +} + +void +LteX2HandoverTestCase::DoRun () +{ + NS_LOG_FUNCTION (this << BuildNameString (m_nUes, m_nDedicatedBearers, m_handoverEventListName, m_useUdp, m_schedulerType)); + + m_lteHelper = CreateObject (); + m_lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel")); + m_lteHelper->SetSchedulerType (m_schedulerType); + + NodeContainer enbNodes; + enbNodes.Create (2); + NodeContainer ueNodes; + ueNodes.Create (m_nUes); + + if (m_epc) + { + m_epcHelper = CreateObject (); + m_lteHelper->SetEpcHelper (m_epcHelper); + } + + Ptr positionAlloc = CreateObject (); + positionAlloc->Add (Vector (-3000, 0, 0)); // enb0 + positionAlloc->Add (Vector ( 3000, 0, 0)); // enb1 + for (uint16_t i = 0; i < m_nUes; i++) + { + positionAlloc->Add (Vector (0, 0, 0)); + } + MobilityHelper mobility; + mobility.SetPositionAllocator (positionAlloc); + mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); + mobility.Install (enbNodes); + mobility.Install (ueNodes); + + NetDeviceContainer enbDevices; + enbDevices = m_lteHelper->InstallEnbDevice (enbNodes); + + NetDeviceContainer ueDevices; + ueDevices = m_lteHelper->InstallUeDevice (ueNodes); + + + + Ipv4Address remoteHostAddr; + Ipv4StaticRoutingHelper ipv4RoutingHelper; + Ipv4InterfaceContainer ueIpIfaces; + Ptr remoteHost; + if (m_epc) + { + // Create a single RemoteHost + NodeContainer remoteHostContainer; + remoteHostContainer.Create (1); + remoteHost = remoteHostContainer.Get (0); + InternetStackHelper internet; + internet.Install (remoteHostContainer); + + // Create the Internet + PointToPointHelper p2ph; + p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s"))); + p2ph.SetDeviceAttribute ("Mtu", UintegerValue (1500)); + p2ph.SetChannelAttribute ("Delay", TimeValue (Seconds (0.010))); + Ptr pgw = m_epcHelper->GetPgwNode (); + NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost); + Ipv4AddressHelper ipv4h; + ipv4h.SetBase ("1.0.0.0", "255.0.0.0"); + Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices); + // in this container, interface 0 is the pgw, 1 is the remoteHost + remoteHostAddr = internetIpIfaces.GetAddress (1); + + Ipv4StaticRoutingHelper ipv4RoutingHelper; + Ptr remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject ()); + remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.0.0.0"), 1); + + // Install the IP stack on the UEs + internet.Install (ueNodes); + ueIpIfaces = m_epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueDevices)); + } + + // attachment (needs to be done after IP stack configuration) + // all UEs attached to eNB 0 at the beginning + m_lteHelper->Attach (ueDevices, enbDevices.Get (0)); + + if (m_epc) + { + bool epcDl = true; + bool epcUl = true; + // the rest of this block is copied from lena-dual-stripe + + + // 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 < ueNodes.GetN (); ++u) + { + Ptr ue = ueNodes.Get (u); + // Set the default gateway for the UE + Ptr ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ue->GetObject ()); + ueStaticRouting->SetDefaultRoute (m_epcHelper->GetUeDefaultGatewayAddress (), 1); + + for (uint32_t b = 0; b < m_nDedicatedBearers; ++b) + { + ++dlPort; + ++ulPort; + + ApplicationContainer clientApps; + ApplicationContainer serverApps; + + if (m_useUdp) + { + if (epcDl) + { + UdpClientHelper dlClientHelper (ueIpIfaces.GetAddress (u), dlPort); + clientApps.Add (dlClientHelper.Install (remoteHost)); + PacketSinkHelper dlPacketSinkHelper ("ns3::UdpSocketFactory", + InetSocketAddress (Ipv4Address::GetAny (), dlPort)); + serverApps.Add (dlPacketSinkHelper.Install (ue)); + } + if (epcUl) + { + UdpClientHelper ulClientHelper (remoteHostAddr, ulPort); + clientApps.Add (ulClientHelper.Install (ue)); + PacketSinkHelper ulPacketSinkHelper ("ns3::UdpSocketFactory", + InetSocketAddress (Ipv4Address::GetAny (), ulPort)); + serverApps.Add (ulPacketSinkHelper.Install (remoteHost)); + } + } + else // use TCP + { + if (epcDl) + { + BulkSendHelper dlClientHelper ("ns3::TcpSocketFactory", + InetSocketAddress (ueIpIfaces.GetAddress (u), dlPort)); + dlClientHelper.SetAttribute ("MaxBytes", UintegerValue (0)); + clientApps.Add (dlClientHelper.Install (remoteHost)); + PacketSinkHelper dlPacketSinkHelper ("ns3::TcpSocketFactory", + InetSocketAddress (Ipv4Address::GetAny (), dlPort)); + serverApps.Add (dlPacketSinkHelper.Install (ue)); + } + if (epcUl) + { + BulkSendHelper ulClientHelper ("ns3::TcpSocketFactory", + InetSocketAddress (remoteHostAddr, ulPort)); + ulClientHelper.SetAttribute ("MaxBytes", UintegerValue (0)); + clientApps.Add (ulClientHelper.Install (ue)); + PacketSinkHelper ulPacketSinkHelper ("ns3::TcpSocketFactory", + InetSocketAddress (Ipv4Address::GetAny (), ulPort)); + serverApps.Add (ulPacketSinkHelper.Install (remoteHost)); + } + } // end if (useUdp) + + Ptr tft = Create (); + if (epcDl) + { + EpcTft::PacketFilter dlpf; + dlpf.localPortStart = dlPort; + dlpf.localPortEnd = dlPort; + tft->Add (dlpf); + } + if (epcUl) + { + EpcTft::PacketFilter ulpf; + ulpf.remotePortStart = ulPort; + ulpf.remotePortEnd = ulPort; + tft->Add (ulpf); + } + + if (epcDl || epcUl) + { + EpsBearer bearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT); + m_lteHelper->ActivateDedicatedEpsBearer (ueDevices.Get (u), bearer, tft); + } + Time startTime = Seconds (startTimeSeconds->GetValue ()); + serverApps.Start (startTime); + clientApps.Start (startTime); + + } // end for b + } + + } + else // (epc == false) + { + // for radio bearer activation purposes, consider together home UEs and macro UEs + for (uint32_t u = 0; u < ueDevices.GetN (); ++u) + { + Ptr ueDev = ueDevices.Get (u); + for (uint32_t b = 0; b < m_nDedicatedBearers; ++b) + { + enum EpsBearer::Qci q = EpsBearer::NGBR_VIDEO_TCP_DEFAULT; + EpsBearer bearer (q); + m_lteHelper->ActivateDataRadioBearer (ueDev, bearer); + } + } + } + + + m_lteHelper->AddX2Interface (enbNodes); + + // check initial RRC connection + const Time maxRrcConnectionEstablishmentDuration = Seconds (0.060); + for (NetDeviceContainer::Iterator it = ueDevices.Begin (); it != ueDevices.End (); ++it) + { + Simulator::Schedule (maxRrcConnectionEstablishmentDuration, + &LteX2HandoverTestCase::CheckConnected, + this, *it, enbDevices.Get (0)); + } + + // schedule handover events and corresponding checks + const Time maxHoDuration = Seconds (0.100); + Time stopTime = Seconds (0); + for (std::list::iterator hoEventIt = m_handoverEventList.begin (); + hoEventIt != m_handoverEventList.end (); + ++hoEventIt) + { + m_lteHelper->HandoverRequest (hoEventIt->startTime, + ueDevices.Get (hoEventIt->ueDeviceIndex), + enbDevices.Get (hoEventIt->sourceEnbDeviceIndex), + enbDevices.Get (hoEventIt->targetEnbDeviceIndex)); + Time hoEndTime = hoEventIt->startTime + maxHoDuration; + Simulator::Schedule (hoEndTime, + &LteX2HandoverTestCase::CheckConnected, + this, + ueDevices.Get (hoEventIt->ueDeviceIndex), + enbDevices.Get (hoEventIt->targetEnbDeviceIndex)); + if (stopTime <= hoEndTime) + { + stopTime = hoEndTime + MilliSeconds (1); + } + } + + + Simulator::Stop (stopTime); + + Simulator::Run (); + + Simulator::Destroy (); + +} + +void +LteX2HandoverTestCase::CheckConnected (Ptr ueDevice, Ptr enbDevice) +{ + Ptr ueLteDevice = ueDevice->GetObject (); + Ptr ueRrc = ueLteDevice->GetRrc (); + NS_TEST_ASSERT_MSG_EQ (ueRrc->GetState (), LteUeRrc::CONNECTED_NORMALLY, "Wrong LteUeRrc state!"); + + + Ptr enbLteDevice = enbDevice->GetObject (); + Ptr enbRrc = enbLteDevice->GetRrc (); + uint16_t rnti = ueRrc->GetRnti (); + Ptr ueManager = enbRrc->GetUeManager (rnti); + NS_TEST_ASSERT_MSG_NE (ueManager, 0, "RNTI " << rnti << " not found in eNB"); + + NS_TEST_ASSERT_MSG_EQ (ueManager->GetState (), UeManager::CONNECTED_NORMALLY, "Wrong UeManager state!"); + + uint16_t ueCellId = ueRrc->GetCellId (); + uint16_t enbCellId = enbLteDevice->GetCellId (); + uint8_t ueDlBandwidth = ueRrc->GetDlBandwidth (); + uint8_t enbDlBandwidth = enbLteDevice->GetDlBandwidth (); + uint8_t ueUlBandwidth = ueRrc->GetUlBandwidth (); + uint8_t enbUlBandwidth = enbLteDevice->GetUlBandwidth (); + uint8_t ueDlEarfcn = ueRrc->GetDlEarfcn (); + uint8_t enbDlEarfcn = enbLteDevice->GetDlEarfcn (); + uint8_t ueUlEarfcn = ueRrc->GetUlEarfcn (); + uint8_t enbUlEarfcn = enbLteDevice->GetUlEarfcn (); + + + NS_TEST_ASSERT_MSG_EQ (ueCellId, enbCellId, "inconsistent CellId"); + NS_TEST_ASSERT_MSG_EQ (ueDlBandwidth, enbDlBandwidth, "inconsistent DlBandwidth"); + NS_TEST_ASSERT_MSG_EQ (ueUlBandwidth, enbUlBandwidth, "inconsistent UlBandwidth"); + NS_TEST_ASSERT_MSG_EQ (ueDlEarfcn, enbDlEarfcn, "inconsistent DlEarfcn"); + NS_TEST_ASSERT_MSG_EQ (ueUlEarfcn, enbUlEarfcn, "inconsistent UlEarfcn"); + + ObjectMapValue enbDataRadioBearerMapValue; + ueManager->GetAttribute ("DataRadioBearerMap", enbDataRadioBearerMapValue); + NS_TEST_ASSERT_MSG_EQ (enbDataRadioBearerMapValue.GetN (), m_nDedicatedBearers + 1, "wrong num bearers at eNB"); + + ObjectMapValue ueDataRadioBearerMapValue; + ueRrc->GetAttribute ("DataRadioBearerMap", ueDataRadioBearerMapValue); + NS_TEST_ASSERT_MSG_EQ (ueDataRadioBearerMapValue.GetN (), m_nDedicatedBearers + 1, "wrong num bearers at UE"); + + ObjectMapValue::Iterator enbBearerIt = enbDataRadioBearerMapValue.Begin (); + ObjectMapValue::Iterator ueBearerIt = ueDataRadioBearerMapValue.Begin (); + while (enbBearerIt != enbDataRadioBearerMapValue.End () && + ueBearerIt != ueDataRadioBearerMapValue.End ()) + { + Ptr enbDrbInfo = enbBearerIt->second->GetObject (); + Ptr ueDrbInfo = ueBearerIt->second->GetObject (); + //NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_epsBearer, ueDrbInfo->m_epsBearer, "epsBearer differs"); + NS_TEST_ASSERT_MSG_EQ ((uint32_t) enbDrbInfo->m_epsBearerIdentity, (uint32_t) ueDrbInfo->m_epsBearerIdentity, "epsBearerIdentity differs"); + NS_TEST_ASSERT_MSG_EQ ((uint32_t) enbDrbInfo->m_drbIdentity, (uint32_t) ueDrbInfo->m_drbIdentity, "drbIdentity differs"); + //NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_rlcConfig, ueDrbInfo->m_rlcConfig, "rlcConfig differs"); + NS_TEST_ASSERT_MSG_EQ ((uint32_t) enbDrbInfo->m_logicalChannelIdentity, (uint32_t) ueDrbInfo->m_logicalChannelIdentity, "logicalChannelIdentity differs"); + //NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_logicalChannelConfig, ueDrbInfo->m_logicalChannelConfig, "logicalChannelConfig differs"); + + ++enbBearerIt; + ++ueBearerIt; + } + NS_ASSERT_MSG (enbBearerIt == enbDataRadioBearerMapValue.End (), "too many bearers at eNB"); + NS_ASSERT_MSG (ueBearerIt == ueDataRadioBearerMapValue.End (), "too many bearers at UE"); +} + + + +class LteX2HandoverTestSuite : public TestSuite +{ +public: + LteX2HandoverTestSuite (); +}; + + +LteX2HandoverTestSuite::LteX2HandoverTestSuite () + : TestSuite ("lte-x2-handover", SYSTEM) +{ + NS_LOG_FUNCTION (this); + + // in the following: + // fwd means handover from enb 0 to enb 1 + // bwd means handover from enb 1 to enb 0 + + HandoverEvent ue0fwd; + ue0fwd.startTime = MilliSeconds (100); + ue0fwd.ueDeviceIndex = 0; + ue0fwd.sourceEnbDeviceIndex = 0; + ue0fwd.targetEnbDeviceIndex = 1; + + HandoverEvent ue0bwd; + ue0bwd.startTime = MilliSeconds (300); + ue0bwd.ueDeviceIndex = 0; + ue0bwd.sourceEnbDeviceIndex = 1; + ue0bwd.targetEnbDeviceIndex = 0; + + HandoverEvent ue1fwd; + ue0fwd.startTime = MilliSeconds (110); + ue1fwd.ueDeviceIndex = 1; + ue1fwd.sourceEnbDeviceIndex = 0; + ue1fwd.targetEnbDeviceIndex = 1; + + HandoverEvent ue1bwd; + ue1bwd.startTime = MilliSeconds (250); + ue1bwd.ueDeviceIndex = 1; + ue1bwd.sourceEnbDeviceIndex = 1; + ue1bwd.targetEnbDeviceIndex = 0; + + std::string hel0name ("none"); + std::list hel0; + + std::string hel1name ("1 fwd"); + std::list hel1; + hel1.push_back (ue0fwd); + + std::string hel2name ("1 fwd & bwd"); + std::list hel2; + hel2.push_back (ue0fwd); + hel2.push_back (ue0bwd); + // 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")); + AddTestCase (new LteX2HandoverTestCase ( 1, 5, hel0, hel0name, true, "ns3::RrFfMacScheduler")); + AddTestCase (new LteX2HandoverTestCase ( 2, 5, hel0, hel0name, true, "ns3::RrFfMacScheduler")); + AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel1, hel1name, true, "ns3::RrFfMacScheduler")); + AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel1, hel1name, true, "ns3::RrFfMacScheduler")); + AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel1, hel1name, true, "ns3::RrFfMacScheduler")); + AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel2, hel2name, true, "ns3::RrFfMacScheduler")); + AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel2, hel2name, true, "ns3::RrFfMacScheduler")); + AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel2, hel2name, true, "ns3::RrFfMacScheduler")); + + // nUes, nDBearers, helist, name, useUdp, scheduler + AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel0, hel0name, true, "ns3::PfFfMacScheduler")); + AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel0, hel0name, true, "ns3::PfFfMacScheduler")); + AddTestCase (new LteX2HandoverTestCase ( 1, 5, hel0, hel0name, true, "ns3::PfFfMacScheduler")); + AddTestCase (new LteX2HandoverTestCase ( 2, 5, hel0, hel0name, true, "ns3::PfFfMacScheduler")); + AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel1, hel1name, true, "ns3::PfFfMacScheduler")); + AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel1, hel1name, true, "ns3::PfFfMacScheduler")); + AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel1, hel1name, true, "ns3::PfFfMacScheduler")); + AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel2, hel2name, true, "ns3::PfFfMacScheduler")); + AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel2, hel2name, true, "ns3::PfFfMacScheduler")); + AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel2, hel2name, true, "ns3::PfFfMacScheduler")); + +} + +static LteX2HandoverTestSuite g_lteX2HandoverTestSuiteInstance; + + + +} // namespace ns3 diff --git a/src/lte/wscript b/src/lte/wscript index 379a64e97..9e6125cf5 100644 --- a/src/lte/wscript +++ b/src/lte/wscript @@ -110,7 +110,8 @@ def build(bld): 'test/lte-test-phy-error-model.cc', 'test/lte-test-mimo.cc', 'test/lte-test-harq.cc', - 'test/test-lte-rrc.cc' + 'test/test-lte-rrc.cc', + 'test/test-lte-x2-handover.cc', ] headers = bld.new_task_gen(features=['ns3header'])