From 42935dffca54468db8d65c3e693c023d36fc65bd Mon Sep 17 00:00:00 2001 From: Budiarto Herman Date: Sun, 18 Aug 2013 21:03:52 +0300 Subject: [PATCH] Handover algorithm based on Event A3 and RSRP --- src/lte/examples/lena-x2-handover-measures.cc | 10 +- .../model/a2-a4-rsrq-handover-algorithm.cc | 4 +- src/lte/model/a2-a4-rsrq-handover-algorithm.h | 5 + src/lte/model/a3-rsrp-handover-algorithm.cc | 183 ++++++++++++++++++ src/lte/model/a3-rsrp-handover-algorithm.h | 93 +++++++++ src/lte/test/test-lte-x2-handover-measures.cc | 150 ++++++++------ src/lte/wscript | 2 + 7 files changed, 391 insertions(+), 56 deletions(-) create mode 100644 src/lte/model/a3-rsrp-handover-algorithm.cc create mode 100644 src/lte/model/a3-rsrp-handover-algorithm.h diff --git a/src/lte/examples/lena-x2-handover-measures.cc b/src/lte/examples/lena-x2-handover-measures.cc index 539adcf09..646c95d44 100644 --- a/src/lte/examples/lena-x2-handover-measures.cc +++ b/src/lte/examples/lena-x2-handover-measures.cc @@ -137,6 +137,7 @@ main (int argc, char *argv[]) // LogComponentEnable ("LteUeRrc", logLevel); // LogComponentEnable ("LteUeNetDevice", logLevel); // LogComponentEnable ("A2A4RsrqHandoverAlgorithm", logLevel); + // LogComponentEnable ("A3RsrpHandoverAlgorithm", logLevel); uint16_t numberOfUes = 1; uint16_t numberOfEnbs = 2; @@ -167,12 +168,19 @@ main (int argc, char *argv[]) Ptr epcHelper = CreateObject (); lteHelper->SetEpcHelper (epcHelper); lteHelper->SetSchedulerType ("ns3::RrFfMacScheduler"); + lteHelper->SetHandoverAlgorithmType ("ns3::A2A4RsrqHandoverAlgorithm"); lteHelper->SetHandoverAlgorithmAttribute ("ServingCellThreshold", - UintegerValue (15)); + UintegerValue (30)); lteHelper->SetHandoverAlgorithmAttribute ("NeighbourCellOffset", UintegerValue (1)); + // lteHelper->SetHandoverAlgorithmType ("ns3::A3RsrpHandoverAlgorithm"); + // lteHelper->SetHandoverAlgorithmAttribute ("Hysteresis", + // DoubleValue (3.0)); + // lteHelper->SetHandoverAlgorithmAttribute ("TimeToTrigger", + // TimeValue (MilliSeconds (256))); + Ptr pgw = epcHelper->GetPgwNode (); // Create a single RemoteHost diff --git a/src/lte/model/a2-a4-rsrq-handover-algorithm.cc b/src/lte/model/a2-a4-rsrq-handover-algorithm.cc index a4efb1d30..9b13d5478 100644 --- a/src/lte/model/a2-a4-rsrq-handover-algorithm.cc +++ b/src/lte/model/a2-a4-rsrq-handover-algorithm.cc @@ -39,6 +39,8 @@ NS_OBJECT_ENSURE_REGISTERED (A2A4RsrqHandoverAlgorithm); A2A4RsrqHandoverAlgorithm::A2A4RsrqHandoverAlgorithm () : m_a2MeasId (0), m_a4MeasId (0), + m_servingCellThreshold (30), + m_neighbourCellOffset (1), m_handoverManagementSapUser (0) { NS_LOG_FUNCTION (this); @@ -149,7 +151,7 @@ A2A4RsrqHandoverAlgorithm::DoReportUeMeas (uint16_t rnti, ++it) { NS_ASSERT_MSG (it->haveRsrqResult == true, - "RSRQ measure missing for cellId " << it->physCellId); + "RSRQ measurement is missing from cellId " << it->physCellId); UpdateNeighbourMeasurements (rnti, it->physCellId, it->rsrqResult); } } diff --git a/src/lte/model/a2-a4-rsrq-handover-algorithm.h b/src/lte/model/a2-a4-rsrq-handover-algorithm.h index f9f5fd9fd..ed97d25f5 100644 --- a/src/lte/model/a2-a4-rsrq-handover-algorithm.h +++ b/src/lte/model/a2-a4-rsrq-handover-algorithm.h @@ -47,6 +47,11 @@ namespace ns3 { * * When the first and second conditions above are fulfilled, the algorithm * triggers a handover. + * + * Note that the attributes must be set before the handover algorithm object is + * instantiated in order for them to take effect, i.e. before calling + * LteHelper::InstallSingleEnbDevice. Subsequent changes to the attribute values + * after that will not have any effect. */ class A2A4RsrqHandoverAlgorithm : public LteHandoverAlgorithm { diff --git a/src/lte/model/a3-rsrp-handover-algorithm.cc b/src/lte/model/a3-rsrp-handover-algorithm.cc new file mode 100644 index 000000000..1d80ba207 --- /dev/null +++ b/src/lte/model/a3-rsrp-handover-algorithm.cc @@ -0,0 +1,183 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2013 University of Jyvaskyla + * + * 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: Budiarto Herman + * + */ + +#include "a3-rsrp-handover-algorithm.h" +#include +#include +#include +#include + +NS_LOG_COMPONENT_DEFINE ("A3RsrpHandoverAlgorithm"); + +namespace ns3 { + +NS_OBJECT_ENSURE_REGISTERED (A3RsrpHandoverAlgorithm); + + +A3RsrpHandoverAlgorithm::A3RsrpHandoverAlgorithm () + : m_handoverManagementSapUser (0) +{ + m_handoverManagementSapProvider = new MemberLteHandoverManagementSapProvider (this); +} + + +A3RsrpHandoverAlgorithm::~A3RsrpHandoverAlgorithm () +{ +} + + +void +A3RsrpHandoverAlgorithm::DoDispose () +{ + delete m_handoverManagementSapProvider; +} + + +TypeId +A3RsrpHandoverAlgorithm::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::A3RsrpHandoverAlgorithm") + .SetParent () + .AddConstructor () + .AddAttribute ("Hysteresis", + "Handover margin (hysteresis) in dB " + "(rounded to the nearest multiple of 0.5 dB)", + DoubleValue (3.0), + MakeDoubleAccessor (&A3RsrpHandoverAlgorithm::m_hysteresisDb), + MakeDoubleChecker (0.0, 15.0)) // Hysteresis IE value range is [0..30] as per Section 6.3.5 of 3GPP TS 36.331 + .AddAttribute ("TimeToTrigger", + "Time during which neighbour cell's RSRP " + "must continuously higher than serving cell's RSRP " + "in order to trigger a handover", + TimeValue (MilliSeconds (256)), // 3GPP time-to-trigger median value as per Section 6.3.5 of 3GPP TS 36.331 + MakeTimeAccessor (&A3RsrpHandoverAlgorithm::m_timeToTrigger), + MakeTimeChecker ()) + ; + return tid; +} + + +void +A3RsrpHandoverAlgorithm::SetLteHandoverManagementSapUser (LteHandoverManagementSapUser* s) +{ + m_handoverManagementSapUser = s; +} + + +LteHandoverManagementSapProvider* +A3RsrpHandoverAlgorithm::GetLteHandoverManagementSapProvider () +{ + return m_handoverManagementSapProvider; +} + + +void +A3RsrpHandoverAlgorithm::DoInitialize () +{ + NS_LOG_FUNCTION (this); + + uint8_t hysteresisIeValue = EutranMeasurementMapping::ActualHysteresis2IeValue (m_hysteresisDb); + NS_LOG_LOGIC (this << " requesting Event A3 measurements" + << " (hysteresis=" << (uint16_t) hysteresisIeValue << ")" + << " (ttt=" << m_timeToTrigger.GetMilliSeconds () << ")"); + + LteRrcSap::ReportConfigEutra reportConfig; + reportConfig.eventId = LteRrcSap::ReportConfigEutra::EVENT_A3; + reportConfig.a3Offset = 0; + reportConfig.hysteresis = hysteresisIeValue; + reportConfig.timeToTrigger = m_timeToTrigger.GetMilliSeconds (); + reportConfig.reportOnLeave = false; + reportConfig.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRP; + reportConfig.reportInterval = LteRrcSap::ReportConfigEutra::MS1024; + m_measId = m_handoverManagementSapUser->AddUeMeasReportConfigForHandover (reportConfig); + + LteHandoverAlgorithm::DoInitialize (); +} + + +void +A3RsrpHandoverAlgorithm::DoReportUeMeas (uint16_t rnti, + LteRrcSap::MeasResults measResults) +{ + NS_LOG_FUNCTION (this << rnti << (uint16_t) measResults.measId); + + if (measResults.measId != m_measId) + { + NS_LOG_WARN ("Ignoring measId " << (uint16_t) measResults.measId); + } + else + { + if (measResults.haveMeasResultNeighCells + && !measResults.measResultListEutra.empty ()) + { + uint16_t bestNeighbourCellId = 0; + uint8_t bestNeighbourRsrp = -std::numeric_limits::infinity (); + + for (std::list ::iterator it = measResults.measResultListEutra.begin (); + it != measResults.measResultListEutra.end (); + ++it) + { + if (it->haveRsrpResult) + { + if ((bestNeighbourRsrp < it->rsrpResult) + && IsValidNeighbour (it->physCellId)) + { + bestNeighbourCellId = it->physCellId; + bestNeighbourRsrp = it->rsrpResult; + } + } + else + { + NS_LOG_WARN ("RSRP measurement is missing from cell ID " << it->physCellId); + } + } + + if (bestNeighbourCellId > 0) + { + NS_LOG_LOGIC ("Trigger Handover to cellId " << bestNeighbourCellId); + NS_LOG_LOGIC ("target cell RSRP " << (uint16_t) bestNeighbourRsrp); + NS_LOG_LOGIC ("serving cell RSRP " << (uint16_t) measResults.rsrpResult); + + // Inform eNodeB RRC about handover + m_handoverManagementSapUser->TriggerHandover (rnti, + bestNeighbourCellId); + } + } + else + { + NS_LOG_WARN (this << " Event A3 received without measurement results from neighbouring cells"); + } + } // end of else of if (measResults.measId != m_measId) + +} // end of DoReportUeMeas + + +bool +A3RsrpHandoverAlgorithm::IsValidNeighbour (uint16_t cellId) +{ + NS_LOG_FUNCTION (this << cellId); + + // TODO + return true; +} + + +} // end of namespace ns3 diff --git a/src/lte/model/a3-rsrp-handover-algorithm.h b/src/lte/model/a3-rsrp-handover-algorithm.h new file mode 100644 index 000000000..28410e4a8 --- /dev/null +++ b/src/lte/model/a3-rsrp-handover-algorithm.h @@ -0,0 +1,93 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2013 University of Jyvaskyla + * + * 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: Budiarto Herman + * + */ + +#ifndef A3_RSRP_HANDOVER_ALGORITHM_H +#define A3_RSRP_HANDOVER_ALGORITHM_H + +#include +#include +#include +#include + +namespace ns3 { + + +/** + * \brief A handover algorithm based on RSRP and Event A3. + * + * The algorithm utilizes Event A3 (Section 5.5.4.4 of 3GPP TS 36.331) UE + * measurements and the Reference Signal Reference Power (RSRP). It is defined + * as the event when the UE perceives that a neighbour cell's RSRP is better + * than the serving cell's RSRP. + * + * Handover margin (a.k.a. hysteresis) and time-to-trigger (TTT) can be + * configured to delay the event triggering. The values of these parameters + * apply to all attached UEs. Note that these attributes must be set before the + * handover algorithm object is instantiated in order for them to take effect, + * i.e. before calling LteHelper::InstallSingleEnbDevice. Subsequent changes to + * the attribute values after that will not have any effect. + */ +class A3RsrpHandoverAlgorithm : public LteHandoverAlgorithm +{ +public: + A3RsrpHandoverAlgorithm (); + virtual ~A3RsrpHandoverAlgorithm (); + + // inherited from Object + virtual void DoDispose (void); + static TypeId GetTypeId (void); + + // inherited from LteHandoverAlgorithm + virtual void SetLteHandoverManagementSapUser (LteHandoverManagementSapUser* s); + virtual LteHandoverManagementSapProvider* GetLteHandoverManagementSapProvider (); + + friend class MemberLteHandoverManagementSapProvider; + +protected: + // inherited from Object + virtual void DoInitialize (); + +private: + + // Handover Management SAP implementation + void DoReportUeMeas (uint16_t rnti, LteRrcSap::MeasResults measResults); + + // Internal method + bool IsValidNeighbour (uint16_t cellId); + + // The expected measurement identity + uint8_t m_measId; + + // Class attributes + double m_hysteresisDb; + Time m_timeToTrigger; + + // Handover Management SAPs + LteHandoverManagementSapUser* m_handoverManagementSapUser; + LteHandoverManagementSapProvider* m_handoverManagementSapProvider; + +}; // end of class A3RsrpHandoverAlgorithm + + +} // end of namespace ns3 + + +#endif /* A3_RSRP_HANDOVER_ALGORITHM_H */ diff --git a/src/lte/test/test-lte-x2-handover-measures.cc b/src/lte/test/test-lte-x2-handover-measures.cc index 6fdb0a9f6..7f25935c4 100644 --- a/src/lte/test/test-lte-x2-handover-measures.cc +++ b/src/lte/test/test-lte-x2-handover-measures.cc @@ -63,17 +63,26 @@ public: * \param checkPointEventList * \param checkPointEventListName * \param useUdp true if UDP is to be used, false if TCP is to be used + * \param schedulerType type of scheduler to be used (e.g. "ns3::PfFfMacScheduler") + * \param handoverAlgorithmType type of handover algorithm to be used (e.g. "ns3::A3RsrpHandoverAlgorithm") + * \param admitHo + * \param useIdealRrc true if ideal RRC is to be used, false if real RRC is to be used * * \return */ LteX2HandoverMeasuresTestCase (uint32_t nEnbs, uint32_t nUes, uint32_t nDedicatedBearers, - std::list checkPointEventList, std::string checkPointEventListName, - bool useUdp, std::string schedulerType, bool admitHo, bool useIdealRrc); + std::list checkPointEventList, + std::string checkPointEventListName, + bool useUdp, std::string schedulerType, + std::string handoverAlgorithmType, bool admitHo, + bool useIdealRrc); private: static std::string BuildNameString (uint32_t nEnbs, uint32_t nUes, uint32_t nDedicatedBearers, std::string checkPointEventListName, - bool useUdp, std::string schedulerType, bool admitHo, bool useIdealRrc); + bool useUdp, std::string schedulerType, + std::string handoverAlgorithmType, bool admitHo, + bool useIdealRrc); virtual void DoRun (void); void CheckConnected (Ptr ueDevice, Ptr enbDevice); @@ -85,6 +94,7 @@ private: bool m_epc; bool m_useUdp; std::string m_schedulerType; + std::string m_handoverAlgorithmType; bool m_admitHo; bool m_useIdealRrc; Ptr m_lteHelper; @@ -120,7 +130,9 @@ private: std::string LteX2HandoverMeasuresTestCase::BuildNameString (uint32_t nEnbs, uint32_t nUes, uint32_t nDedicatedBearers, std::string checkPointEventListName, - bool useUdp, std::string schedulerType, bool admitHo, bool useIdealRrc) + bool useUdp, std::string schedulerType, + std::string handoverAlgorithmType, bool admitHo, + bool useIdealRrc) { std::ostringstream oss; oss << "nEnbs=" << nEnbs @@ -128,6 +140,7 @@ LteX2HandoverMeasuresTestCase::BuildNameString (uint32_t nEnbs, uint32_t nUes, u << " nDedicatedBearers=" << nDedicatedBearers << " udp=" << useUdp << " " << schedulerType + << " " << handoverAlgorithmType << " admitHo=" << admitHo << " hoList: " << checkPointEventListName; if (useIdealRrc) @@ -142,9 +155,14 @@ LteX2HandoverMeasuresTestCase::BuildNameString (uint32_t nEnbs, uint32_t nUes, u } LteX2HandoverMeasuresTestCase::LteX2HandoverMeasuresTestCase (uint32_t nEnbs, uint32_t nUes, uint32_t nDedicatedBearers, - std::list checkPointEventList, std::string checkPointEventListName, - bool useUdp, std::string schedulerType, bool admitHo, bool useIdealRrc) - : TestCase (BuildNameString (nEnbs, nUes, nDedicatedBearers, checkPointEventListName, useUdp, schedulerType, admitHo, useIdealRrc)), + std::list checkPointEventList, + std::string checkPointEventListName, + bool useUdp, std::string schedulerType, + std::string handoverAlgorithmType, bool admitHo, + bool useIdealRrc) + : TestCase (BuildNameString (nEnbs, nUes, nDedicatedBearers, + checkPointEventListName, useUdp, schedulerType, + handoverAlgorithmType, admitHo, useIdealRrc)), m_nEnbs (nEnbs), m_nUes (nUes), m_nDedicatedBearers (nDedicatedBearers), @@ -153,6 +171,7 @@ LteX2HandoverMeasuresTestCase::LteX2HandoverMeasuresTestCase (uint32_t nEnbs, ui m_epc (true), m_useUdp (useUdp), m_schedulerType (schedulerType), + m_handoverAlgorithmType (handoverAlgorithmType), m_admitHo (admitHo), m_useIdealRrc (useIdealRrc), m_maxHoDuration (Seconds (0.1)), @@ -167,7 +186,9 @@ LteX2HandoverMeasuresTestCase::DoRun () { NS_LOG_FUNCTION (this << BuildNameString (m_nEnbs, m_nUes, m_nDedicatedBearers, m_checkPointEventListName, - m_useUdp, m_schedulerType, m_admitHo, m_useIdealRrc)); + m_useUdp, m_schedulerType, + m_handoverAlgorithmType, m_admitHo, + m_useIdealRrc)); Config::Reset (); Config::SetDefault ("ns3::UdpClient::Interval", TimeValue (m_udpClientInterval)); @@ -183,12 +204,27 @@ LteX2HandoverMeasuresTestCase::DoRun () m_lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel")); m_lteHelper->SetAttribute ("UseIdealRrc", BooleanValue (m_useIdealRrc)); m_lteHelper->SetSchedulerType (m_schedulerType); - m_lteHelper->SetHandoverAlgorithmType ("ns3::A2A4RsrqHandoverAlgorithm"); - m_lteHelper->SetHandoverAlgorithmAttribute ("ServingCellThreshold", - UintegerValue (30)); - m_lteHelper->SetHandoverAlgorithmAttribute ("NeighbourCellOffset", - UintegerValue (1)); + if (m_handoverAlgorithmType == "ns3::A2A4RsrqHandoverAlgorithm") + { + m_lteHelper->SetHandoverAlgorithmType ("ns3::A2A4RsrqHandoverAlgorithm"); + m_lteHelper->SetHandoverAlgorithmAttribute ("ServingCellThreshold", + UintegerValue (30)); + m_lteHelper->SetHandoverAlgorithmAttribute ("NeighbourCellOffset", + UintegerValue (1)); + } + else if (m_handoverAlgorithmType == "ns3::A3RsrpHandoverAlgorithm") + { + m_lteHelper->SetHandoverAlgorithmType ("ns3::A3RsrpHandoverAlgorithm"); + m_lteHelper->SetHandoverAlgorithmAttribute ("Hysteresis", + DoubleValue (1.5)); + m_lteHelper->SetHandoverAlgorithmAttribute ("TimeToTrigger", + TimeValue (MilliSeconds (128))); + } + else + { + NS_FATAL_ERROR ("Unknown handover algorithm " << m_handoverAlgorithmType); + } double distance = 1000.0; // m double speed = 150; // m/s @@ -609,62 +645,68 @@ LteX2HandoverMeasuresTestSuite::LteX2HandoverMeasuresTestSuite () std::string cel1name ("ho: 0 -> 1"); std::list cel1; cel1.push_back (CheckPointEvent (Seconds (1), Seconds (10.1), checkInterval, 0, 0)); - cel1.push_back (CheckPointEvent (Seconds (11), Seconds (37), checkInterval, 0, 1)); + cel1.push_back (CheckPointEvent (Seconds (11), Seconds (17), checkInterval, 0, 1)); std::string cel2name ("ho: 0 -> 1 -> 2"); std::list cel2; - cel2.push_back (CheckPointEvent (Seconds (1), Seconds (10.1), Seconds (1), 0, 0)); - cel2.push_back (CheckPointEvent (Seconds (11), Seconds (17.1), Seconds (1), 0, 1)); - cel2.push_back (CheckPointEvent (Seconds (18), Seconds (37), Seconds (1), 0, 2)); + cel2.push_back (CheckPointEvent (Seconds (1), Seconds (10.1), checkInterval, 0, 0)); + cel2.push_back (CheckPointEvent (Seconds (11), Seconds (17.1), checkInterval, 0, 1)); + cel2.push_back (CheckPointEvent (Seconds (18), Seconds (24), checkInterval, 0, 2)); std::string cel3name ("ho: 0 -> 1 -> 2 -> 3"); std::list cel3; - cel3.push_back (CheckPointEvent (Seconds (1), Seconds (10.1), Seconds (1), 0, 0)); - cel3.push_back (CheckPointEvent (Seconds (11), Seconds (17.1), Seconds (1), 0, 1)); - cel3.push_back (CheckPointEvent (Seconds (18), Seconds (24.1), Seconds (1), 0, 2)); - cel3.push_back (CheckPointEvent (Seconds (25), Seconds (37), Seconds (1), 0, 3)); + cel3.push_back (CheckPointEvent (Seconds (1), Seconds (10.1), checkInterval, 0, 0)); + cel3.push_back (CheckPointEvent (Seconds (11), Seconds (17.1), checkInterval, 0, 1)); + cel3.push_back (CheckPointEvent (Seconds (18), Seconds (24.1), checkInterval, 0, 2)); + cel3.push_back (CheckPointEvent (Seconds (25), Seconds (37), checkInterval, 0, 3)); int32_t useIdealRrc; - std::vector schedulers; - schedulers.push_back ("ns3::PfFfMacScheduler"); - for (std::vector::iterator schedIt = schedulers.begin (); schedIt != schedulers.end (); ++schedIt) + std::string sched = "ns3::PfFfMacScheduler"; + std::string ho = "ns3::A2A4RsrqHandoverAlgorithm"; + for (useIdealRrc = 1; useIdealRrc >= 0; --useIdealRrc) { - for (useIdealRrc = 1; useIdealRrc >= 0; --useIdealRrc) - { - // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, admitHo, idealRrc - AddTestCase (new LteX2HandoverMeasuresTestCase ( 2, 1, 0, cel1, cel1name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE); - AddTestCase (new LteX2HandoverMeasuresTestCase ( 2, 1, 1, cel1, cel1name, true, *schedIt, true, useIdealRrc), TestCase::QUICK); - AddTestCase (new LteX2HandoverMeasuresTestCase ( 2, 1, 2, cel1, cel1name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE); - AddTestCase (new LteX2HandoverMeasuresTestCase ( 3, 1, 0, cel2, cel2name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE); - AddTestCase (new LteX2HandoverMeasuresTestCase ( 3, 1, 1, cel2, cel2name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE); - AddTestCase (new LteX2HandoverMeasuresTestCase ( 3, 1, 2, cel2, cel2name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE); - AddTestCase (new LteX2HandoverMeasuresTestCase ( 4, 1, 0, cel3, cel3name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE); - AddTestCase (new LteX2HandoverMeasuresTestCase ( 4, 1, 1, cel3, cel3name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE); - AddTestCase (new LteX2HandoverMeasuresTestCase ( 4, 1, 2, cel3, cel3name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE); - } + // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, ho, admitHo, idealRrc + AddTestCase (new LteX2HandoverMeasuresTestCase (2, 1, 0, cel1, cel1name, true, sched, ho, true, useIdealRrc), TestCase::TAKES_FOREVER); + AddTestCase (new LteX2HandoverMeasuresTestCase (2, 1, 1, cel1, cel1name, true, sched, ho, true, useIdealRrc), TestCase::QUICK); + AddTestCase (new LteX2HandoverMeasuresTestCase (2, 1, 2, cel1, cel1name, true, sched, ho, true, useIdealRrc), TestCase::TAKES_FOREVER); + AddTestCase (new LteX2HandoverMeasuresTestCase (3, 1, 0, cel2, cel2name, true, sched, ho, true, useIdealRrc), TestCase::TAKES_FOREVER); + AddTestCase (new LteX2HandoverMeasuresTestCase (3, 1, 1, cel2, cel2name, true, sched, ho, true, useIdealRrc), TestCase::TAKES_FOREVER); + AddTestCase (new LteX2HandoverMeasuresTestCase (3, 1, 2, cel2, cel2name, true, sched, ho, true, useIdealRrc), TestCase::EXTENSIVE); + AddTestCase (new LteX2HandoverMeasuresTestCase (4, 1, 0, cel3, cel3name, true, sched, ho, true, useIdealRrc), TestCase::EXTENSIVE); + AddTestCase (new LteX2HandoverMeasuresTestCase (4, 1, 1, cel3, cel3name, true, sched, ho, true, useIdealRrc), TestCase::TAKES_FOREVER); + AddTestCase (new LteX2HandoverMeasuresTestCase (4, 1, 2, cel3, cel3name, true, sched, ho, true, useIdealRrc), TestCase::TAKES_FOREVER); } - schedulers.resize (0); - schedulers.push_back ("ns3::RrFfMacScheduler"); - for (std::vector::iterator schedIt = schedulers.begin (); schedIt != schedulers.end (); ++schedIt) + sched = "ns3::RrFfMacScheduler"; + for (useIdealRrc = 1; useIdealRrc >= 0; --useIdealRrc) { - for (useIdealRrc = 1; useIdealRrc >= 0; --useIdealRrc) - { - // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, admitHo, idealRrc - AddTestCase (new LteX2HandoverMeasuresTestCase ( 2, 1, 0, cel1, cel1name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE); -// AddTestCase (new LteX2HandoverMeasuresTestCase ( 2, 1, 1, cel1b, cel1bname, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE); -// AddTestCase (new LteX2HandoverMeasuresTestCase ( 2, 1, 2, cel1, cel1name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE); - AddTestCase (new LteX2HandoverMeasuresTestCase ( 3, 1, 0, cel2, cel2name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE); -// AddTestCase (new LteX2HandoverMeasuresTestCase ( 3, 1, 1, cel2, cel2name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE); -// AddTestCase (new LteX2HandoverMeasuresTestCase ( 3, 1, 2, cel2, cel2name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE); - AddTestCase (new LteX2HandoverMeasuresTestCase ( 4, 1, 0, cel3, cel3name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE); -// AddTestCase (new LteX2HandoverMeasuresTestCase ( 4, 1, 1, cel3, cel3name, true, *schedIt, true, useIdealRrc), TestCase::QUICK); -// AddTestCase (new LteX2HandoverMeasuresTestCase ( 4, 1, 2, cel3, cel3name, true, *schedIt, true, useIdealRrc), TestCase::QUICK); - } + // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, admitHo, idealRrc + AddTestCase (new LteX2HandoverMeasuresTestCase (2, 1, 0, cel1, cel1name, true, sched, ho, true, useIdealRrc), TestCase::EXTENSIVE); + AddTestCase (new LteX2HandoverMeasuresTestCase (3, 1, 0, cel2, cel2name, true, sched, ho, true, useIdealRrc), TestCase::TAKES_FOREVER); + AddTestCase (new LteX2HandoverMeasuresTestCase (4, 1, 0, cel3, cel3name, true, sched, ho, true, useIdealRrc), TestCase::TAKES_FOREVER); } -} + ho = "ns3::A3RsrpHandoverAlgorithm"; + sched = "ns3::PfFfMacScheduler"; + for (useIdealRrc = 1; useIdealRrc >= 0; --useIdealRrc) + { + // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, admitHo, idealRrc + AddTestCase (new LteX2HandoverMeasuresTestCase (2, 1, 0, cel1, cel1name, true, sched, ho, true, useIdealRrc), TestCase::EXTENSIVE); + AddTestCase (new LteX2HandoverMeasuresTestCase (3, 1, 0, cel2, cel2name, true, sched, ho, true, useIdealRrc), TestCase::TAKES_FOREVER); + AddTestCase (new LteX2HandoverMeasuresTestCase (4, 1, 0, cel3, cel3name, true, sched, ho, true, useIdealRrc), TestCase::TAKES_FOREVER); + } + + sched = "ns3::RrFfMacScheduler"; + for (useIdealRrc = 1; useIdealRrc >= 0; --useIdealRrc) + { + // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, admitHo, idealRrc + AddTestCase (new LteX2HandoverMeasuresTestCase (2, 1, 0, cel1, cel1name, true, sched, ho, true, useIdealRrc), TestCase::QUICK); + AddTestCase (new LteX2HandoverMeasuresTestCase (3, 1, 0, cel2, cel2name, true, sched, ho, true, useIdealRrc), TestCase::TAKES_FOREVER); + AddTestCase (new LteX2HandoverMeasuresTestCase (4, 1, 0, cel3, cel3name, true, sched, ho, true, useIdealRrc), TestCase::EXTENSIVE); + } + +} // end of LteX2HandoverMeasuresTestSuite () static LteX2HandoverMeasuresTestSuite g_lteX2HandoverMeasuresTestSuiteInstance; diff --git a/src/lte/wscript b/src/lte/wscript index c2c84612d..113683d43 100644 --- a/src/lte/wscript +++ b/src/lte/wscript @@ -101,6 +101,7 @@ def build(bld): 'model/lte-handover-management-sap.cc', 'model/lte-handover-algorithm.cc', 'model/a2-a4-rsrq-handover-algorithm.cc', + 'model/a3-rsrp-handover-algorithm.cc', 'model/no-op-handover-algorithm.cc', 'model/lte-anr-sap.cc', 'model/lte-anr.cc', @@ -252,6 +253,7 @@ def build(bld): 'model/lte-handover-management-sap.h', 'model/lte-handover-algorithm.h', 'model/a2-a4-rsrq-handover-algorithm.h', + 'model/a3-rsrp-handover-algorithm.h', 'model/no-op-handover-algorithm.h', 'model/lte-anr-sap.h', 'model/lte-anr.h',