A Discrete-Event Network Simulator
API
lte-test-secondary-cell-handover.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Alexander Krotov
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Alexander Krotov <krotov@iitp.ru>
18  *
19  */
20 
21 #include <ns3/boolean.h>
22 #include <ns3/double.h>
23 #include <ns3/friis-spectrum-propagation-loss.h>
24 #include <ns3/integer.h>
25 #include <ns3/internet-stack-helper.h>
26 #include <ns3/log.h>
27 #include <ns3/lte-enb-net-device.h>
28 #include <ns3/lte-helper.h>
29 #include <ns3/lte-ue-net-device.h>
30 #include <ns3/lte-ue-rrc.h>
31 #include <ns3/mobility-helper.h>
32 #include <ns3/point-to-point-epc-helper.h>
33 #include <ns3/simulator.h>
34 #include <ns3/test.h>
35 
36 using namespace ns3;
37 
38 NS_LOG_COMPONENT_DEFINE("LteSecondaryCellHandoverTest");
39 
47 {
48  public:
56  LteSecondaryCellHandoverTestCase(std::string name, bool useIdealRrc);
57 
62  void ShutdownCell(uint32_t cellId);
63 
71  void UeHandoverStartCallback(uint64_t imsi,
72  uint16_t sourceCellId,
73  uint16_t rnti,
74  uint16_t targetCellId);
75 
76  private:
80  void DoRun() override;
81 
85  void DoTeardown() override;
86 
89 
91 
93 };
94 
96  bool useIdealRrc)
97  : TestCase{name},
98  m_useIdealRrc{useIdealRrc},
99  m_numberOfComponentCarriers{2},
100  m_hasUeHandoverStarted{false}
101 {
102 }
103 
104 void
106 {
107  Ptr<LteEnbPhy> phy = m_sourceEnbDev->GetPhy(cellId - 1);
108  phy->SetTxPower(1);
109 }
110 
111 void
113  uint16_t sourceCellId,
114  uint16_t rnti,
115  uint16_t targetCellId)
116 {
117  NS_LOG_FUNCTION(this << imsi << sourceCellId << rnti << targetCellId);
118  m_hasUeHandoverStarted = true;
119 }
120 
121 void
123 {
124  NS_LOG_FUNCTION(this << GetName());
125 
126  Config::SetDefault("ns3::LteEnbNetDevice::DlEarfcn", UintegerValue(100));
127  Config::SetDefault("ns3::LteEnbNetDevice::UlEarfcn", UintegerValue(100 + 18000));
128  Config::SetDefault("ns3::LteEnbNetDevice::DlBandwidth", UintegerValue(25));
129  Config::SetDefault("ns3::LteEnbNetDevice::UlBandwidth", UintegerValue(25));
130  Config::SetDefault("ns3::LteUeNetDevice::DlEarfcn", UintegerValue(100));
131 
132  // Create helpers.
133  auto lteHelper = CreateObject<LteHelper>();
134  lteHelper->SetAttribute("PathlossModel",
136  lteHelper->SetAttribute("UseIdealRrc", BooleanValue(m_useIdealRrc));
137  lteHelper->SetAttribute("NumberOfComponentCarriers",
139 
140  // Configure handover algorithm.
141  lteHelper->SetHandoverAlgorithmType("ns3::A3RsrpHandoverAlgorithm");
142  lteHelper->SetHandoverAlgorithmAttribute("Hysteresis", DoubleValue(1.5));
143  lteHelper->SetHandoverAlgorithmAttribute("TimeToTrigger", TimeValue(MilliSeconds(128)));
144 
145  auto epcHelper = CreateObject<PointToPointEpcHelper>();
146  lteHelper->SetEpcHelper(epcHelper);
147 
148  // Create nodes.
149  auto enbNode = CreateObject<Node>();
150  auto ueNode = CreateObject<Node>();
151 
152  // Setup node mobility.
154  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
155  mobility.Install(enbNode);
156  mobility.Install(ueNode);
157 
158  // Physical layer.
159  m_sourceEnbDev = DynamicCast<LteEnbNetDevice>(lteHelper->InstallEnbDevice(enbNode).Get(0));
160  auto ueDevs = lteHelper->InstallUeDevice(ueNode);
161  auto ueDev = DynamicCast<LteUeNetDevice>(ueDevs.Get(0));
162 
163  // Network layer.
165  internet.Install(ueNode);
166  epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueDev));
167 
168  uint16_t sourceCellId = m_sourceEnbDev->GetCellId();
169  Simulator::Schedule(Seconds(0.5),
171  this,
172  sourceCellId);
173 
174  // Setup traces.
175  ueDev->GetRrc()->TraceConnectWithoutContext(
176  "HandoverStart",
178 
179  std::map<uint8_t, Ptr<ComponentCarrierUe>> ueCcMap = ueDev->GetCcMap();
180  ueDev->SetDlEarfcn(ueCcMap.at(0)->GetDlEarfcn());
181  lteHelper->Attach(ueDev, m_sourceEnbDev, 0);
182 
183  // Run simulation.
184  Simulator::Stop(Seconds(1));
185  Simulator::Run();
186  Simulator::Destroy();
187 }
188 
189 void
191 {
192  NS_LOG_FUNCTION(this);
193  NS_TEST_ASSERT_MSG_EQ(m_hasUeHandoverStarted, true, "Handover did not occur");
194 }
195 
202 {
203  public:
205 };
206 
208  : TestSuite{"lte-secondary-cell-handover", SYSTEM}
209 {
210  AddTestCase(new LteSecondaryCellHandoverTestCase("Ideal RRC", true), TestCase::QUICK);
211  AddTestCase(new LteSecondaryCellHandoverTestCase("Real RRC", false), TestCase::QUICK);
212 }
213 
Test measurement-based handover to secondary cell.
void UeHandoverStartCallback(uint64_t imsi, uint16_t sourceCellId, uint16_t rnti, uint16_t targetCellId)
Callback method indicating start of UE handover.
bool m_useIdealRrc
whether LTE is configured to use ideal RRC
Ptr< LteEnbNetDevice > m_sourceEnbDev
Source eNB device.
void ShutdownCell(uint32_t cellId)
Shutdown cellId by reducing its power to 1 dBm.
LteSecondaryCellHandoverTestCase(std::string name, bool useIdealRrc)
Creates an instance of the measurement-based secondary cell handover test case.
uint8_t m_numberOfComponentCarriers
Number of component carriers.
void DoTeardown() override
Verify that handover has occurred during the simulation.
bool m_hasUeHandoverStarted
true if UE started handover
LTE measurement-based handover to secondary cell test suite.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
aggregate IP/TCP/UDP functionality to existing Nodes.
Ptr< LteEnbPhy > GetPhy() const
uint16_t GetCellId() const
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
std::string GetName() const
Definition: test.cc:373
A suite of tests to run.
Definition: test.h:1256
Hold an unsigned integer type.
Definition: uinteger.h:45
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:890
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
static LteSecondaryCellHandoverTestSuite g_lteSecondaryCellHandoverTestSuiteInstance
Static variable for test initialization.
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:144
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
mobility
Definition: third.py:105
phy
Definition: third.py:89