1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  * Author: Manuel Requena <manuel.requena@cttc.es>
19  *         Nicola Baldo <nbaldo@cttc.es>
20  *         Marco Miozzo <mmiozzo@cttc.es>
21  *         Budiarto Herman <budiarto.herman@magister.fi>
22  */
23 
24 #include <ns3/simulator.h>
25 #include <ns3/log.h>
26 #include <ns3/callback.h>
27 #include <ns3/config.h>
28 #include <ns3/string.h>
29 #include <ns3/double.h>
30 #include <ns3/enum.h>
31 #include <ns3/boolean.h>
32 
33 #include <ns3/mobility-helper.h>
34 #include <ns3/lte-helper.h>
35 #include <ns3/point-to-point-epc-helper.h>
36 #include <ns3/internet-stack-helper.h>
37 #include <ns3/point-to-point-helper.h>
38 #include <ns3/ipv4-address-helper.h>
39 #include <ns3/ipv4-static-routing-helper.h>
40 
41 #include <ns3/node-container.h>
42 #include <ns3/net-device-container.h>
43 #include <ns3/ipv4-interface-container.h>
44 
45 #include <ns3/ff-mac-scheduler.h>
46 #include <ns3/lte-enb-net-device.h>
47 #include <ns3/lte-enb-phy.h>
48 #include <ns3/lte-enb-rrc.h>
49 #include <ns3/lte-ue-net-device.h>
50 #include <ns3/lte-ue-phy.h>
51 #include <ns3/lte-ue-rrc.h>
52 
53 #include "lte-test-ue-measurements.h"
54 #include <ns3/lte-common.h>
55 
56 using namespace ns3;
57 
58 NS_LOG_COMPONENT_DEFINE ("LteUeMeasurementsTest");
59 
60 // ===== LTE-UE-MEASUREMENTS TEST SUITE ==================================== //
61 
62 void
ReportUeMeasurementsCallback(LteUeMeasurementsTestCase * testcase,std::string path,uint16_t rnti,uint16_t cellId,double rsrp,double rsrq,bool servingCell,uint8_t componentCarrierId)63 ReportUeMeasurementsCallback (LteUeMeasurementsTestCase *testcase,
64                               std::string path, uint16_t rnti, uint16_t cellId,
65                               double rsrp, double rsrq, bool servingCell, uint8_t componentCarrierId)
66 {
67   testcase->ReportUeMeasurements (rnti, cellId, rsrp, rsrq, servingCell);
68 }
69 
70 void
RecvMeasurementReportCallback(LteUeMeasurementsTestCase * testcase,std::string path,uint64_t imsi,uint16_t cellId,uint16_t rnti,LteRrcSap::MeasurementReport meas)71 RecvMeasurementReportCallback (LteUeMeasurementsTestCase *testcase,
72                                std::string path, uint64_t imsi, uint16_t cellId,
73                                uint16_t rnti, LteRrcSap::MeasurementReport meas)
74 {
75   testcase->RecvMeasurementReport (imsi, cellId, rnti, meas);
76 }
77 
78 
79 /*
80  * Test Suite
81  */
82 
LteUeMeasurementsTestSuite()83 LteUeMeasurementsTestSuite::LteUeMeasurementsTestSuite ()
84   : TestSuite ("lte-ue-measurements", SYSTEM)
85 {
86 
87   AddTestCase (new LteUeMeasurementsTestCase ("d1=10, d2=10000",  10.000000, 10000.000000, -53.739702, -113.739702, -3.010305, -63.010305), TestCase::EXTENSIVE);
88   AddTestCase (new LteUeMeasurementsTestCase ("d1=20, d2=10000",  20.000000, 10000.000000, -59.760302, -113.739702, -3.010319, -56.989719), TestCase::EXTENSIVE);
89   AddTestCase (new LteUeMeasurementsTestCase ("d1=50, d2=10000",  50.000000, 10000.000000, -67.719102, -113.739702, -3.010421, -49.031021), TestCase::EXTENSIVE);
90   AddTestCase (new LteUeMeasurementsTestCase ("d1=100, d2=10000",  100.000000, 10000.000000, -73.739702, -113.739702, -3.010783, -43.010783), TestCase::EXTENSIVE);
91   AddTestCase (new LteUeMeasurementsTestCase ("d1=200, d2=10000",  200.000000, 10000.000000, -79.760302, -113.739702, -3.012232, -36.991632), TestCase::EXTENSIVE);
92   AddTestCase (new LteUeMeasurementsTestCase ("d1=100, d2=10000",  100.000000, 10000.000000, -73.739702, -113.739702, -3.010783, -43.010783), TestCase::EXTENSIVE);
93   AddTestCase (new LteUeMeasurementsTestCase ("d1=200, d2=10000",  200.000000, 10000.000000, -79.760302, -113.739702, -3.012232, -36.991632), TestCase::EXTENSIVE);
94   AddTestCase (new LteUeMeasurementsTestCase ("d1=500, d2=10000",  500.000000, 10000.000000, -87.719102, -113.739702, -3.022359, -29.042959), TestCase::EXTENSIVE);
95   AddTestCase (new LteUeMeasurementsTestCase ("d1=1000, d2=10000",  1000.000000, 10000.000000, -93.739702, -113.739702, -3.058336, -23.058336), TestCase::EXTENSIVE);
96   AddTestCase (new LteUeMeasurementsTestCase ("d1=2000, d2=10000",  2000.000000, 10000.000000, -99.760302, -113.739702, -3.199337, -17.178738), TestCase::EXTENSIVE);
97   AddTestCase (new LteUeMeasurementsTestCase ("d1=5000, d2=10000",  5000.000000, 10000.000000, -107.719102, -113.739702, -4.075793, -10.096393), TestCase::QUICK);
98   AddTestCase (new LteUeMeasurementsTestCase ("d1=10000, d2=10000",  10000.000000, 10000.000000, -113.739702, -113.739702, -6.257687, -6.257687), TestCase::EXTENSIVE);
99   AddTestCase (new LteUeMeasurementsTestCase ("d1=20000, d2=10000",  20000.000000, 10000.000000, -119.760302, -113.739702, -10.373365, -4.352765), TestCase::EXTENSIVE);
100   AddTestCase (new LteUeMeasurementsTestCase ("d1=50000, d2=10000",  50000.000000, 10000.000000, -127.719102, -113.739702, -17.605046, -3.625645), TestCase::EXTENSIVE);
101   AddTestCase (new LteUeMeasurementsTestCase ("d1=100000, d2=10000",  100000.000000, 10000.000000, -133.739702, -113.739702, -23.511071, -3.511071), TestCase::EXTENSIVE);
102   AddTestCase (new LteUeMeasurementsTestCase ("d1=200000, d2=10000",  200000.000000, 10000.000000, -139.760302, -113.739702, -29.502549, -3.481949), TestCase::EXTENSIVE);
103   AddTestCase (new LteUeMeasurementsTestCase ("d1=500000, d2=10000",  500000.000000, 10000.000000, -147.719102, -113.739702, -37.453160, -3.473760), TestCase::EXTENSIVE);
104   AddTestCase (new LteUeMeasurementsTestCase ("d1=1000000, d2=10000",  1000000.000000, 10000.000000, -153.739702, -113.739702, -43.472589, -3.472589), TestCase::EXTENSIVE);
105 }
106 
107 static LteUeMeasurementsTestSuite lteUeMeasurementsTestSuite;
108 
109 
110 /*
111  * Test Case
112  */
113 
LteUeMeasurementsTestCase(std::string name,double d1,double d2,double rsrpDbmUe1,double rsrpDbmUe2,double rsrqDbUe1,double rsrqDbUe2)114 LteUeMeasurementsTestCase::LteUeMeasurementsTestCase (std::string name,
115                                                       double d1, double d2,
116                                                       double rsrpDbmUe1,
117                                                       double rsrpDbmUe2,
118                                                       double rsrqDbUe1,
119                                                       double rsrqDbUe2)
120   : TestCase (name),
121     m_d1 (d1),
122     m_d2 (d2),
123     m_rsrpDbmUeServingCell (rsrpDbmUe1),
124     m_rsrpDbmUeNeighborCell (rsrpDbmUe2),
125     m_rsrqDbUeServingCell (rsrqDbUe1),
126     m_rsrqDbUeNeighborCell (rsrqDbUe2)
127 {
128   NS_LOG_INFO ("Test UE Measurements d1 = " << d1 << " m. and d2 = " << d2 << " m.");
129 }
130 
~LteUeMeasurementsTestCase()131 LteUeMeasurementsTestCase::~LteUeMeasurementsTestCase ()
132 {}
133 
134 void
DoRun(void)135 LteUeMeasurementsTestCase::DoRun (void)
136 {
137   NS_LOG_INFO (this << " " << GetName ());
138 
139   Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
140   Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));
141   Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
142   Config::SetDefault ("ns3::LteAmc::Ber", DoubleValue (0.00005));
143   Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
144   lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel"));
145   lteHelper->SetAttribute ("UseIdealRrc", BooleanValue (false));
146 
147   //Disable Uplink Power Control
148   Config::SetDefault ("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue (false));
149 
150   // LogComponentEnable ("LteUeMeasurementsTest", LOG_LEVEL_ALL);
151 
152   // Create Nodes: eNodeB and UE
153   NodeContainer enbNodes;
154   NodeContainer ueNodes1;
155   NodeContainer ueNodes2;
156   enbNodes.Create (2);
157   ueNodes1.Create (1);
158   ueNodes2.Create (1);
159   NodeContainer allNodes = NodeContainer (enbNodes, ueNodes1, ueNodes2);
160 
161   // the topology is the following:
162   //         d2
163   //  UE1-----------eNB2
164   //   |             |
165   // d1|             |d1
166   //   |     d2      |
167   //  eNB1----------UE2
168   //
169   Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
170   positionAlloc->Add (Vector (0.0, 0.0, 0.0));   // eNB1
171   positionAlloc->Add (Vector (m_d2, m_d1, 0.0)); // eNB2
172   positionAlloc->Add (Vector (0.0, m_d1, 0.0));  // UE1
173   positionAlloc->Add (Vector (m_d2, 0.0, 0.0));  // UE2
174   MobilityHelper mobility;
175   mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
176   mobility.SetPositionAllocator (positionAlloc);
177   mobility.Install (allNodes);
178 
179   // Create Devices and install them in the Nodes (eNB and UE)
180   NetDeviceContainer enbDevs;
181   NetDeviceContainer ueDevs1;
182   NetDeviceContainer ueDevs2;
183   lteHelper->SetSchedulerType ("ns3::RrFfMacScheduler");
184   lteHelper->SetSchedulerAttribute ("UlCqiFilter", EnumValue (FfMacScheduler::PUSCH_UL_CQI));
185   enbDevs = lteHelper->InstallEnbDevice (enbNodes);
186   ueDevs1 = lteHelper->InstallUeDevice (ueNodes1);
187   ueDevs2 = lteHelper->InstallUeDevice (ueNodes2);
188 
189   // Attach UEs to eNodeBs
190   lteHelper->Attach (ueDevs1, enbDevs.Get (0));
191   lteHelper->Attach (ueDevs2, enbDevs.Get (1));
192 
193   // Activate an EPS bearer
194   enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
195   EpsBearer bearer (q);
196   lteHelper->ActivateDataRadioBearer (ueDevs1, bearer);
197   lteHelper->ActivateDataRadioBearer (ueDevs2, bearer);
198 
199 
200   Config::Connect ("/NodeList/2/DeviceList/0/ComponentCarrierMapUe/0/LteUePhy/ReportUeMeasurements",
201                    MakeBoundCallback (&ReportUeMeasurementsCallback, this));
202   Config::Connect ("/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
203                    MakeBoundCallback (&RecvMeasurementReportCallback, this));
204 
205   Config::Connect ("/NodeList/3/DeviceList/0/ComponentCarrierMapUe/0/LteUePhy/ReportUeMeasurements",
206                    MakeBoundCallback (&ReportUeMeasurementsCallback, this));
207   Config::Connect ("/NodeList/1/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
208                    MakeBoundCallback (&RecvMeasurementReportCallback, this));
209 
210   // need to allow for RRC connection establishment + SRS
211   Simulator::Stop (Seconds (0.800));
212   Simulator::Run ();
213 
214   Simulator::Destroy ();
215 
216 }
217 
218 void
ReportUeMeasurements(uint16_t rnti,uint16_t cellId,double rsrp,double rsrq,bool servingCell)219 LteUeMeasurementsTestCase::ReportUeMeasurements (uint16_t rnti, uint16_t cellId,
220                                                  double rsrp, double rsrq,
221                                                  bool servingCell)
222 {
223   // need to allow for RRC connection establishment + CQI feedback reception + UE measurements filtering (200 ms)
224   if (Simulator::Now () > MilliSeconds (400))
225     {
226       if (servingCell)
227         {
228           NS_LOG_DEBUG ("UE serving cellId " << cellId << " Rxed RSRP " << rsrp << " thr " << m_rsrpDbmUeServingCell << " RSRQ " << rsrq << " thr " << m_rsrqDbUeServingCell);
229           NS_TEST_ASSERT_MSG_EQ_TOL (m_rsrpDbmUeServingCell, rsrp, 0.2, "Wrong RSRP UE 1");
230           NS_TEST_ASSERT_MSG_EQ_TOL (m_rsrqDbUeServingCell, rsrq, 0.2, "Wrong RSRQ UE 1");
231         }
232       else
233         {
234           NS_LOG_DEBUG ("UE neighbor cellId " << cellId << " Rxed RSRP " << rsrp << " thr " << m_rsrpDbmUeNeighborCell << " RSRQ " << rsrq << " thr " << m_rsrqDbUeNeighborCell);
235           NS_TEST_ASSERT_MSG_EQ_TOL (m_rsrpDbmUeNeighborCell, rsrp, 0.2, "Wrong RSRP UE 2");
236           NS_TEST_ASSERT_MSG_EQ_TOL (m_rsrqDbUeNeighborCell, rsrq, 0.2, "Wrong RSRQ UE ");
237         }
238     }
239 }
240 
241 void
RecvMeasurementReport(uint64_t imsi,uint16_t cellId,uint16_t rnti,LteRrcSap::MeasurementReport meas)242 LteUeMeasurementsTestCase::RecvMeasurementReport (uint64_t imsi, uint16_t cellId, uint16_t rnti,
243                                                   LteRrcSap::MeasurementReport meas)
244 {
245   // need to allow for RRC connection establishment + CQI feedback reception + UE measurements filtering (200 ms)
246   if (Simulator::Now () > MilliSeconds (400))
247     {
248       if (cellId == imsi)
249         {
250           NS_LOG_DEBUG (this << "Serving Cell: received IMSI " << imsi << " CellId " << cellId << " RNTI " << rnti
251                              << " thr " << (uint16_t) EutranMeasurementMapping::Dbm2RsrpRange (m_rsrpDbmUeServingCell)
252                              << " RSRP " << (uint16_t) meas.measResults.rsrpResult
253                              << " RSRQ " << (uint16_t)meas.measResults.rsrqResult
254                              << " thr " << (uint16_t) EutranMeasurementMapping::Db2RsrqRange (m_rsrqDbUeServingCell));
255           NS_TEST_ASSERT_MSG_EQ (meas.measResults.rsrpResult,
256                                  EutranMeasurementMapping::Dbm2RsrpRange (m_rsrpDbmUeServingCell),
257                                  "Wrong RSRP ");
258           NS_TEST_ASSERT_MSG_EQ (meas.measResults.rsrqResult,
259                                  EutranMeasurementMapping::Db2RsrqRange (m_rsrqDbUeServingCell),
260                                  "Wrong RSRQ ");
261         }
262       else
263         {
264           NS_LOG_DEBUG (this << "Neighbor cell: received IMSI " << imsi << " CellId " << cellId << " RNTI " << rnti
265                              << " thr " << (uint16_t) EutranMeasurementMapping::Dbm2RsrpRange (m_rsrpDbmUeNeighborCell)
266                              << " RSRP " << (uint16_t) meas.measResults.rsrpResult
267                              << " RSRQ " << (uint16_t)meas.measResults.rsrqResult
268                              << " thr " << (uint16_t) EutranMeasurementMapping::Db2RsrqRange (m_rsrqDbUeNeighborCell));
269           NS_TEST_ASSERT_MSG_EQ (meas.measResults.rsrpResult,
270                                  EutranMeasurementMapping::Dbm2RsrpRange (m_rsrpDbmUeNeighborCell),
271                                  "Wrong RSRP ");
272           NS_TEST_ASSERT_MSG_EQ (meas.measResults.rsrqResult,
273                                  EutranMeasurementMapping::Db2RsrqRange (m_rsrqDbUeNeighborCell),
274                                  "Wrong RSRQ ");
275         }
276     }
277 }
278 
279 
280 // ===== LTE-UE-MEASUREMENTS-PIECEWISE-1 TEST SUITE ======================== //
281 
282 /*
283  * Overloaded operators, for the convenience of defining test cases
284  */
285 
286 std::vector<Time>&
operator <<(std::vector<Time> & v,const uint64_t & ms)287 operator<< (std::vector<Time>& v, const uint64_t& ms)
288 {
289   /*
290    * Prior attempt to use seconds as unit of choice resulted in precision lost.
291    * Therefore milliseconds are used now instead.
292    */
293   v.push_back (MilliSeconds (ms) + UE_MEASUREMENT_REPORT_DELAY);
294   return v;
295 }
296 
297 std::vector<uint8_t>&
operator <<(std::vector<uint8_t> & v,const uint8_t & range)298 operator<< (std::vector<uint8_t>& v, const uint8_t& range)
299 {
300   v.push_back (range);
301   return v;
302 }
303 
304 
305 /*
306  * Test Suite
307  */
308 
LteUeMeasurementsPiecewiseTestSuite1()309 LteUeMeasurementsPiecewiseTestSuite1::LteUeMeasurementsPiecewiseTestSuite1 ()
310   : TestSuite ("lte-ue-measurements-piecewise-1", SYSTEM)
311 {
312   std::vector<Time> expectedTime;
313   std::vector<uint8_t> expectedRsrp;
314 
315   // === Event A1 (serving cell becomes better than threshold) ===
316 
317   // With very low threshold
318   LteRrcSap::ReportConfigEutra config;
319   config.triggerType = LteRrcSap::ReportConfigEutra::EVENT;
320   config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
321   config.threshold1.choice = LteRrcSap::ThresholdEutra::THRESHOLD_RSRP;
322   config.threshold1.range = 0;
323   config.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRP;
324   config.reportInterval = LteRrcSap::ReportConfigEutra::MS120;
325   expectedTime.clear ();
326   expectedTime << 200 << 320 << 440 << 560 << 680 << 800 << 920 << 1040 << 1160 << 1280
327                << 1400 << 1520 << 1640 << 1760 << 1880 << 2000 << 2120;
328   expectedRsrp.clear ();
329   expectedRsrp << 67 << 67 << 57 << 57 << 66 << 47 << 47 << 66 << 66 << 57
330                << 51 << 51 << 47 << 47 << 51 << 57 << 57;
331   AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A1 with very low threshold",
332                                                         config, expectedTime, expectedRsrp),
333                TestCase::EXTENSIVE);
334 
335   // With normal threshold
336   config.threshold1.range = 54;
337   expectedTime.clear ();
338   expectedTime << 200 << 320 << 440 << 560 << 680 << 1000 << 1120 << 1240 << 1360 << 2000
339                << 2120;
340   expectedRsrp.clear ();
341   expectedRsrp << 67 << 67 << 57 << 57 << 66 << 66 << 66 << 57 << 57 << 57
342                << 57;
343   AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A1 with normal threshold",
344                                                         config, expectedTime, expectedRsrp),
345                TestCase::EXTENSIVE);
346 
347   // With short time-to-trigger
348   config.timeToTrigger = 64;
349   expectedTime.clear ();
350   expectedTime << 264 << 384 << 504 << 624 << 744 << 1064 << 1184 << 1304 << 1424 << 2064
351                << 2184;
352   expectedRsrp.clear ();
353   expectedRsrp << 67 << 67 << 57 << 66 << 66 << 66 << 66 << 57 << 51 << 57
354                << 57;
355   AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A1 with short time-to-trigger",
356                                                         config, expectedTime, expectedRsrp),
357                TestCase::QUICK);
358 
359   // With long time-to-trigger
360   config.timeToTrigger = 128;
361   expectedTime.clear ();
362   expectedTime << 328 << 448 << 568 << 688 << 808 << 1128 << 1248 << 1368 << 1488 << 2128;
363   expectedRsrp.clear ();
364   expectedRsrp << 67 << 57 << 57 << 66 << 47 << 66 << 57 << 57 << 51 << 57;
365   AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A1 with long time-to-trigger",
366                                                         config, expectedTime, expectedRsrp),
367                TestCase::EXTENSIVE);
368 
369   // With super time-to-trigger
370   config.timeToTrigger = 256;
371   expectedTime.clear ();
372   expectedTime << 456 << 576 << 696 << 816 << 936 << 1056 << 1176 << 1296 << 1416 << 1536;
373   expectedRsrp.clear ();
374   expectedRsrp << 57 << 57 << 66 << 47 << 47 << 66 << 66 << 57 << 51 << 51;
375   AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A1 with super time-to-trigger",
376                                                         config, expectedTime, expectedRsrp),
377                TestCase::EXTENSIVE);
378 
379   // With hysteresis
380   config.hysteresis = 8;
381   config.timeToTrigger = 0;
382   expectedTime.clear ();
383   expectedTime << 200 << 320 << 440 << 560 << 680 << 1000 << 1120 << 1240 << 1360 << 1480
384                << 2200;
385   expectedRsrp.clear ();
386   expectedRsrp << 67 << 67 << 57 << 57 << 66 << 66 << 66 << 57 << 57 << 51
387                << 67;
388   AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A1 with hysteresis",
389                                                         config, expectedTime, expectedRsrp),
390                TestCase::QUICK);
391 
392   // With very high threshold
393   config.threshold1.range = 97;
394   config.hysteresis = 0;
395   expectedTime.clear ();
396   expectedRsrp.clear ();
397   AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A1 with very high threshold",
398                                                         config, expectedTime, expectedRsrp),
399                TestCase::TAKES_FOREVER);
400 
401   // === Event A2 (serving cell becomes worse than threshold) ===
402 
403   // With very low threshold
404   config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
405   config.threshold1.range = 0;
406   expectedTime.clear ();
407   expectedRsrp.clear ();
408   AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A2 with very low threshold",
409                                                         config, expectedTime, expectedRsrp),
410                TestCase::TAKES_FOREVER);
411 
412   // With normal threshold
413   config.threshold1.range = 54;
414   expectedTime.clear ();
415   expectedTime << 800 << 920 << 1400 << 1520 << 1640 << 1760 << 1880;
416   expectedRsrp.clear ();
417   expectedRsrp << 47 << 47 << 51 << 51 << 47 << 47 << 51;
418   AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A2 with normal threshold",
419                                                         config, expectedTime, expectedRsrp),
420                TestCase::QUICK);
421 
422   // With short time-to-trigger
423   config.timeToTrigger = 64;
424   expectedTime.clear ();
425   expectedTime << 864 << 984 << 1464 << 1584 << 1704 << 1824 << 1944;
426   expectedRsrp.clear ();
427   expectedRsrp << 47 << 47 << 51 << 51 << 47 << 51 << 51;
428   AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A2 with short time-to-trigger",
429                                                         config, expectedTime, expectedRsrp),
430                TestCase::EXTENSIVE);
431 
432   // With long time-to-trigger
433   config.timeToTrigger = 128;
434   expectedTime.clear ();
435   expectedTime << 928 << 1048 << 1528 << 1648 << 1768 << 1888 << 2008;
436   expectedRsrp.clear ();
437   expectedRsrp << 47 << 66 << 51 << 47 << 47 << 51 << 57;
438   AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A2 with long time-to-trigger",
439                                                         config, expectedTime, expectedRsrp),
440                TestCase::TAKES_FOREVER);
441 
442   // With super time-to-trigger
443   config.timeToTrigger = 256;
444   expectedTime.clear ();
445   expectedTime << 1656 << 1776 << 1896 << 2016 << 2136;
446   expectedRsrp.clear ();
447   expectedRsrp << 47 << 47 << 51 << 57 << 57;
448   AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A2 with super time-to-trigger",
449                                                         config, expectedTime, expectedRsrp),
450                TestCase::QUICK);
451 
452   // With hysteresis
453   config.hysteresis = 8;
454   config.timeToTrigger = 0;
455   expectedTime.clear ();
456   expectedTime << 800 << 920 << 1600 << 1720 << 1840 << 1960 << 2080;
457   expectedRsrp.clear ();
458   expectedRsrp << 47 << 47 << 47 << 47 << 51 << 51 << 57;
459   AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A2 with hysteresis",
460                                                         config, expectedTime, expectedRsrp),
461                TestCase::EXTENSIVE);
462 
463   // With very high threshold
464   config.threshold1.range = 97;
465   config.hysteresis = 0;
466   expectedTime.clear ();
467   expectedTime << 200 << 320 << 440 << 560 << 680 << 800 << 920 << 1040 << 1160 << 1280
468                << 1400 << 1520 << 1640 << 1760 << 1880 << 2000 << 2120;
469   expectedRsrp.clear ();
470   expectedRsrp << 67 << 67 << 57 << 57 << 66 << 47 << 47 << 66 << 66 << 57
471                << 51 << 51 << 47 << 47 << 51 << 57 << 57;
472   AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A2 with very high threshold",
473                                                         config, expectedTime, expectedRsrp),
474                TestCase::EXTENSIVE);
475 
476   /*
477    * Event A3, A4, and A5 are not tested intensively here because they depend on
478    * the existence of at least one neighbouring cell, which is not available in
479    * this configuration. Piecewise configuration #2 includes a neighbouring
480    * cell, hence more thorough tests on these events are performed there.
481    */
482 
483   expectedTime.clear ();
484   expectedRsrp.clear ();
485 
486   // === Event A3 (neighbour becomes offset better than PCell) ===
487 
488   config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
489   config.a3Offset = 0;
490   AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A3",
491                                                         config, expectedTime, expectedRsrp),
492                TestCase::EXTENSIVE);
493 
494   // === Event A4 (neighbour becomes better than threshold) ===
495 
496   config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
497   config.threshold1.range = 54;
498   AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A4",
499                                                         config, expectedTime, expectedRsrp),
500                TestCase::EXTENSIVE);
501 
502   // === Event A5 (PCell becomes worse than absolute threshold1 AND neighbour becomes better than another absolute threshold2) ===
503 
504   config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
505   config.threshold2.range = 58;
506   AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A5",
507                                                         config, expectedTime, expectedRsrp),
508                TestCase::EXTENSIVE);
509 
510 } // end of LteUeMeasurementsPiecewiseTestSuite1::LteUeMeasurementsPiecewiseTestSuite1
511 
512 static LteUeMeasurementsPiecewiseTestSuite1 lteUeMeasurementsPiecewiseTestSuite1;
513 
514 
515 /*
516  * Test Case
517  */
518 
LteUeMeasurementsPiecewiseTestCase1(std::string name,LteRrcSap::ReportConfigEutra config,std::vector<Time> expectedTime,std::vector<uint8_t> expectedRsrp)519 LteUeMeasurementsPiecewiseTestCase1::LteUeMeasurementsPiecewiseTestCase1 (
520   std::string name, LteRrcSap::ReportConfigEutra config,
521   std::vector<Time> expectedTime, std::vector<uint8_t> expectedRsrp)
522   : TestCase (name),
523     m_config (config),
524     m_expectedTime (expectedTime),
525     m_expectedRsrp (expectedRsrp)
526 {
527   // input sanity check
528   uint16_t size = m_expectedTime.size ();
529 
530   if (size != m_expectedRsrp.size ())
531     {
532       NS_FATAL_ERROR ("Vectors of expected results are not of the same size");
533     }
534 
535   m_itExpectedTime = m_expectedTime.begin ();
536   m_itExpectedRsrp = m_expectedRsrp.begin ();
537 
538   NS_LOG_INFO (this << " name=" << name);
539 }
540 
~LteUeMeasurementsPiecewiseTestCase1()541 LteUeMeasurementsPiecewiseTestCase1::~LteUeMeasurementsPiecewiseTestCase1 ()
542 {
543   NS_LOG_FUNCTION (this);
544 }
545 
546 void
DoRun()547 LteUeMeasurementsPiecewiseTestCase1::DoRun ()
548 {
549   NS_LOG_INFO (this << " " << GetName ());
550 
551   Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
552   lteHelper->SetAttribute ("PathlossModel",
553                            StringValue ("ns3::FriisSpectrumPropagationLossModel"));
554   lteHelper->SetAttribute ("UseIdealRrc", BooleanValue (true));
555 
556   //Disable Uplink Power Control
557   Config::SetDefault ("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue (false));
558 
559   // Create Nodes: eNodeB and UE
560   NodeContainer enbNodes;
561   NodeContainer ueNodes;
562   enbNodes.Create (1);
563   ueNodes.Create (1);
564 
565   /*
566    * The topology is the following:
567    *
568    * eNodeB     UE
569    *    |       |
570    *    x ----- x --------- x --------------- x ------------------- x
571    *      100 m |   200 m   |      300 m      |        400 m        |
572    *            |           |                 |                     |
573    *         VeryNear      Near              Far                 VeryFar
574    */
575 
576   Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
577   positionAlloc->Add (Vector (0.0, 0.0, 0.0)); // eNodeB
578   positionAlloc->Add (Vector (100.0, 0.0, 0.0)); // UE
579   MobilityHelper mobility;
580   mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
581   mobility.SetPositionAllocator (positionAlloc);
582   mobility.Install (enbNodes);
583   mobility.Install (ueNodes);
584   m_ueMobility = ueNodes.Get (0)->GetObject<MobilityModel> ();
585 
586   // Disable layer-3 filtering
587   Config::SetDefault ("ns3::LteEnbRrc::RsrpFilterCoefficient",
588                       UintegerValue (0));
589 
590   // Create Devices and install them in the Nodes (eNB and UE)
591   NetDeviceContainer enbDevs;
592   NetDeviceContainer ueDevs;
593   lteHelper->SetSchedulerType ("ns3::RrFfMacScheduler");
594   lteHelper->SetSchedulerAttribute ("UlCqiFilter",
595                                     EnumValue (FfMacScheduler::PUSCH_UL_CQI));
596   enbDevs = lteHelper->InstallEnbDevice (enbNodes);
597   ueDevs = lteHelper->InstallUeDevice (ueNodes);
598 
599   // Setup UE measurement configuration
600   Ptr<LteEnbRrc> enbRrc = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ()->GetRrc ();
601   m_expectedMeasId = enbRrc->AddUeMeasReportConfig (m_config);
602 
603   // Attach UE to eNodeB
604   lteHelper->Attach (ueDevs.Get (0), enbDevs.Get (0));
605 
606   // Activate an EPS bearer
607   enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
608   EpsBearer bearer (q);
609   lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
610 
611   // Connect to trace sources
612   Config::Connect ("/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
613                    MakeCallback (&LteUeMeasurementsPiecewiseTestCase1::RecvMeasurementReportCallback,
614                                  this));
615 
616   /*
617    * Schedule "teleports"
618    *          0                   1                   2
619    *          +-------------------+-------------------+---------> time
620    * VeryNear |------  ----    ----                    --------
621    *     Near |                    ----            ----
622    *      Far |                        ----    ----
623    *  VeryFar |      --    ----            ----
624    */
625   Simulator::Schedule (MilliSeconds (301),
626                        &LteUeMeasurementsPiecewiseTestCase1::TeleportVeryFar, this);
627   Simulator::Schedule (MilliSeconds (401),
628                        &LteUeMeasurementsPiecewiseTestCase1::TeleportVeryNear, this);
629   Simulator::Schedule (MilliSeconds (601),
630                        &LteUeMeasurementsPiecewiseTestCase1::TeleportVeryFar, this);
631   Simulator::Schedule (MilliSeconds (801),
632                        &LteUeMeasurementsPiecewiseTestCase1::TeleportVeryNear, this);
633   Simulator::Schedule (MilliSeconds (1001),
634                        &LteUeMeasurementsPiecewiseTestCase1::TeleportNear, this);
635   Simulator::Schedule (MilliSeconds (1201),
636                        &LteUeMeasurementsPiecewiseTestCase1::TeleportFar, this);
637   Simulator::Schedule (MilliSeconds (1401),
638                        &LteUeMeasurementsPiecewiseTestCase1::TeleportVeryFar, this);
639   Simulator::Schedule (MilliSeconds (1601),
640                        &LteUeMeasurementsPiecewiseTestCase1::TeleportFar, this);
641   Simulator::Schedule (MilliSeconds (1801),
642                        &LteUeMeasurementsPiecewiseTestCase1::TeleportNear, this);
643   Simulator::Schedule (MilliSeconds (2001),
644                        &LteUeMeasurementsPiecewiseTestCase1::TeleportVeryNear, this);
645 
646   // Run simulation
647   Simulator::Stop (Seconds (2.201));
648   Simulator::Run ();
649   Simulator::Destroy ();
650 
651 } // end of void LteUeMeasurementsPiecewiseTestCase1::DoRun ()
652 
653 void
DoTeardown()654 LteUeMeasurementsPiecewiseTestCase1::DoTeardown ()
655 {
656   NS_LOG_FUNCTION (this);
657   bool hasEnded = m_itExpectedTime == m_expectedTime.end ();
658   NS_TEST_ASSERT_MSG_EQ (hasEnded, true,
659                          "Reporting should have occurred at " << m_itExpectedTime->As (Time::S));
660   hasEnded = m_itExpectedRsrp == m_expectedRsrp.end ();
661   NS_ASSERT (hasEnded);
662 }
663 
664 void
RecvMeasurementReportCallback(std::string context,uint64_t imsi,uint16_t cellId,uint16_t rnti,LteRrcSap::MeasurementReport report)665 LteUeMeasurementsPiecewiseTestCase1::RecvMeasurementReportCallback (
666   std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti,
667   LteRrcSap::MeasurementReport report)
668 {
669   NS_LOG_FUNCTION (this << context);
670   NS_ASSERT (rnti == 1);
671   NS_ASSERT (cellId == 1);
672 
673   if (report.measResults.measId == m_expectedMeasId)
674     {
675       // verifying the report completeness
676       LteRrcSap::MeasResults measResults = report.measResults;
677       NS_LOG_DEBUG (this << " rsrp=" << (uint16_t) measResults.rsrpResult
678                          << " (" << EutranMeasurementMapping::RsrpRange2Dbm (measResults.rsrpResult) << " dBm)"
679                          << " rsrq=" << (uint16_t) measResults.rsrqResult
680                          << " (" << EutranMeasurementMapping::RsrqRange2Db (measResults.rsrqResult) << " dB)");
681       NS_TEST_ASSERT_MSG_EQ (measResults.haveMeasResultNeighCells, false,
682                              "Report should not have neighboring cells information");
683       NS_TEST_ASSERT_MSG_EQ (measResults.measResultListEutra.size (), 0,
684                              "Unexpected report size");
685 
686       bool hasEnded = m_itExpectedTime == m_expectedTime.end ();
687       NS_TEST_ASSERT_MSG_EQ (hasEnded, false,
688                              "Reporting should not have occurred at "
689                              << Simulator::Now ().As (Time::S));
690       if (!hasEnded)
691         {
692           hasEnded = m_itExpectedRsrp == m_expectedRsrp.end ();
693           NS_ASSERT (!hasEnded);
694 
695           // using milliseconds to avoid floating-point comparison
696           uint64_t timeNowMs = Simulator::Now ().GetMilliSeconds ();
697           uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds ();
698           m_itExpectedTime++;
699 
700           uint16_t observedRsrp = measResults.rsrpResult;
701           uint16_t referenceRsrp = *m_itExpectedRsrp;
702           m_itExpectedRsrp++;
703 
704           NS_TEST_ASSERT_MSG_EQ (timeNowMs, timeExpectedMs,
705                                  "Reporting should not have occurred at this time");
706           NS_TEST_ASSERT_MSG_EQ (observedRsrp, referenceRsrp,
707                                  "The RSRP observed differs with the reference RSRP");
708         } // end of if (!hasEnded)
709 
710     } // end of if (measResults.measId == m_expectedMeasId)
711 
712 } // end of LteUeMeasurementsPiecewiseTestCase1::RecvMeasurementReportCallback
713 
714 void
TeleportVeryNear()715 LteUeMeasurementsPiecewiseTestCase1::TeleportVeryNear ()
716 {
717   NS_LOG_FUNCTION (this);
718   m_ueMobility->SetPosition (Vector (100.0, 0.0, 0.0));
719 }
720 
721 void
TeleportNear()722 LteUeMeasurementsPiecewiseTestCase1::TeleportNear ()
723 {
724   NS_LOG_FUNCTION (this);
725   m_ueMobility->SetPosition (Vector (300.0, 0.0, 0.0));
726 }
727 
728 void
TeleportFar()729 LteUeMeasurementsPiecewiseTestCase1::TeleportFar ()
730 {
731   NS_LOG_FUNCTION (this);
732   m_ueMobility->SetPosition (Vector (600.0, 0.0, 0.0));
733 }
734 
735 void
TeleportVeryFar()736 LteUeMeasurementsPiecewiseTestCase1::TeleportVeryFar ()
737 {
738   NS_LOG_FUNCTION (this);
739   m_ueMobility->SetPosition (Vector (1000.0, 0.0, 0.0));
740 }
741 
742 
743 // ===== LTE-UE-MEASUREMENTS-PIECEWISE-2 TEST SUITE ======================== //
744 
745 /*
746  * Test Suite
747  */
748 
LteUeMeasurementsPiecewiseTestSuite2()749 LteUeMeasurementsPiecewiseTestSuite2::LteUeMeasurementsPiecewiseTestSuite2 ()
750   : TestSuite ("lte-ue-measurements-piecewise-2", SYSTEM)
751 {
752   std::vector<Time> expectedTime;
753   std::vector<uint8_t> expectedRsrp;
754 
755   /*
756    * Higher level of fullness/duration are given to Event A1 and A2 because they
757    * are supposed to be more intensively tested in Piecewise configuration #1.
758    */
759 
760   // === Event A1 (serving cell becomes better than threshold) ===
761 
762   // With very low threshold
763   LteRrcSap::ReportConfigEutra config;
764   config.triggerType = LteRrcSap::ReportConfigEutra::EVENT;
765   config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
766   config.threshold1.choice = LteRrcSap::ThresholdEutra::THRESHOLD_RSRP;
767   config.threshold1.range = 0;
768   config.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRP;
769   config.reportInterval = LteRrcSap::ReportConfigEutra::MS240;
770   expectedTime.clear ();
771   expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
772   expectedRsrp.clear ();
773   expectedRsrp << 73 << 63 << 72 << 52 << 72 << 56 << 52 << 56 << 59;
774   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A1 with very low threshold",
775                                                         config, expectedTime, expectedRsrp),
776                TestCase::EXTENSIVE);
777 
778   // With normal threshold
779   config.threshold1.range = 58;
780   expectedTime.clear ();
781   expectedTime << 200 << 440 << 680 << 1000 << 1240 << 2000;
782   expectedRsrp.clear ();
783   expectedRsrp << 73 << 63 << 72 << 72 << 59 << 59;
784   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A1 with normal threshold",
785                                                         config, expectedTime, expectedRsrp),
786                TestCase::TAKES_FOREVER);
787 
788   // With hysteresis
789   config.hysteresis = 6;
790   expectedTime.clear ();
791   expectedTime << 200 << 440 << 680 << 1000 << 1240 << 1480 << 2200;
792   expectedRsrp.clear ();
793   expectedRsrp << 73 << 63 << 72 << 72 << 59 << 56 << 72;
794   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A1 with hysteresis",
795                                                         config, expectedTime, expectedRsrp),
796                TestCase::EXTENSIVE);
797 
798   // With very high threshold
799   config.threshold1.range = 97;
800   config.hysteresis = 0;
801   expectedTime.clear ();
802   expectedRsrp.clear ();
803   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A1 with very high threshold",
804                                                         config, expectedTime, expectedRsrp),
805                TestCase::TAKES_FOREVER);
806 
807   // === Event A2 (serving cell becomes worse than threshold) ===
808 
809   // With very low threshold
810   config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
811   config.threshold1.range = 0;
812   expectedTime.clear ();
813   expectedRsrp.clear ();
814   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A2 with very low threshold",
815                                                         config, expectedTime, expectedRsrp),
816                TestCase::TAKES_FOREVER);
817 
818   // With normal threshold
819   config.threshold1.range = 58;
820   expectedTime.clear ();
821   expectedTime << 800 << 1400 << 1640 << 1880;
822   expectedRsrp.clear ();
823   expectedRsrp << 52 << 56 << 52 << 56;
824   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A2 with normal threshold",
825                                                         config, expectedTime, expectedRsrp),
826                TestCase::TAKES_FOREVER);
827 
828   // With hysteresis
829   config.hysteresis = 6;
830   expectedTime.clear ();
831   expectedTime << 800 << 1600 << 1840 << 2080;
832   expectedRsrp.clear ();
833   expectedRsrp << 52 << 52 << 56 << 59;
834   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A2 with hysteresis",
835                                                         config, expectedTime, expectedRsrp),
836                TestCase::EXTENSIVE);
837 
838   // With very high threshold
839   config.threshold1.range = 97;
840   config.hysteresis = 0;
841   expectedTime.clear ();
842   expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
843   expectedRsrp.clear ();
844   expectedRsrp << 73 << 63 << 72 << 52 << 72 << 56 << 52 << 56 << 59;
845   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A2 with very high threshold",
846                                                         config, expectedTime, expectedRsrp),
847                TestCase::TAKES_FOREVER);
848 
849   // === Event A3 (neighbour becomes offset better than PCell) ===
850 
851   // With positive offset
852   config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
853   config.threshold1.range = 0;
854   config.a3Offset = 7;
855   expectedTime.clear ();
856   expectedTime << 800 << 1600;
857   expectedRsrp.clear ();
858   expectedRsrp << 52 << 52;
859   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A3 with positive offset",
860                                                         config, expectedTime, expectedRsrp),
861                TestCase::QUICK);
862 
863   // With zero offset
864   config.a3Offset = 0;
865   expectedTime.clear ();
866   expectedTime << 800 << 1400 << 1640 << 1880;
867   expectedRsrp.clear ();
868   expectedRsrp << 52 << 56 << 52 << 56;
869   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A3 with zero offset",
870                                                         config, expectedTime, expectedRsrp),
871                TestCase::EXTENSIVE);
872 
873   // With short time-to-trigger
874   config.timeToTrigger = 160;
875   expectedTime.clear ();
876   expectedTime << 960 << 1560 << 1800 << 2040;
877   expectedRsrp.clear ();
878   expectedRsrp << 52 << 56 << 56 << 59;
879   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A3 with short time-to-trigger",
880                                                         config, expectedTime, expectedRsrp),
881                TestCase::EXTENSIVE);
882 
883   // With super time-to-trigger
884   config.timeToTrigger = 320;
885   expectedTime.clear ();
886   expectedTime << 1720 << 1960 << 2200;
887   expectedRsrp.clear ();
888   expectedRsrp << 52 << 56 << 72;
889   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A3 with super time-to-trigger",
890                                                         config, expectedTime, expectedRsrp),
891                TestCase::QUICK);
892 
893   // With hysteresis and reportOnLeave
894   config.hysteresis = 6;
895   config.reportOnLeave = true;
896   config.timeToTrigger = 0;
897   expectedTime.clear ();
898   expectedTime << 800 << 1000 << 1600 << 1840 << 2080 << 2200;
899   expectedRsrp.clear ();
900   expectedRsrp << 52 << 72 << 52 << 56 << 59 << 72;
901   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A3 with hysteresis",
902                                                         config, expectedTime, expectedRsrp),
903                TestCase::QUICK);
904 
905   // With negative offset
906   config.a3Offset = -7;
907   config.hysteresis = 0;
908   config.reportOnLeave = false;
909   expectedTime.clear ();
910   expectedTime << 400 << 800 << 1200 << 1440 << 1680 << 1920 << 2160;
911   expectedRsrp.clear ();
912   expectedRsrp << 63 << 52 << 59 << 56 << 52 << 56 << 59;
913   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A3 with negative offset",
914                                                         config, expectedTime, expectedRsrp),
915                TestCase::EXTENSIVE);
916 
917   // === Event A4 (neighbour becomes better than threshold) ===
918 
919   // With very low threshold
920   config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
921   config.threshold1.range = 0;
922   config.a3Offset = 0;
923   expectedTime.clear ();
924   expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
925   expectedRsrp.clear ();
926   expectedRsrp << 73 << 63 << 72 << 52 << 72 << 56 << 52 << 56 << 59;
927   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A4 with very low threshold",
928                                                         config, expectedTime, expectedRsrp),
929                TestCase::QUICK);
930 
931   // With normal threshold
932   config.threshold1.range = 58;
933   expectedTime.clear ();
934   expectedTime << 400 << 800 << 1400 << 1640 << 1880;
935   expectedRsrp.clear ();
936   expectedRsrp << 63 << 52 << 56 << 52 << 56;
937   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A4 with normal threshold",
938                                                         config, expectedTime, expectedRsrp),
939                TestCase::EXTENSIVE);
940 
941   // With short time-to-trigger
942   config.timeToTrigger = 160;
943   expectedTime.clear ();
944   expectedTime << 560 << 960 << 1560 << 1800 << 2040;
945   expectedRsrp.clear ();
946   expectedRsrp << 63 << 52 << 56 << 56 << 59;
947   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A4 with short time-to-trigger",
948                                                         config, expectedTime, expectedRsrp),
949                TestCase::QUICK);
950 
951   // With super time-to-trigger
952   config.timeToTrigger = 320;
953   expectedTime.clear ();
954   expectedTime << 1720 << 1960 << 2200;
955   expectedRsrp.clear ();
956   expectedRsrp << 52 << 56 << 72;
957   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A4 with super time-to-trigger",
958                                                         config, expectedTime, expectedRsrp),
959                TestCase::TAKES_FOREVER);
960 
961   // With hysteresis
962   config.hysteresis = 6;
963   config.timeToTrigger = 0;
964   expectedTime.clear ();
965   expectedTime << 400 << 800 << 1600 << 1840 << 2080;
966   expectedRsrp.clear ();
967   expectedRsrp << 63 << 52 << 52 << 56 << 59;
968   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A4 with hysteresis",
969                                                         config, expectedTime, expectedRsrp),
970                TestCase::QUICK);
971 
972   // With very high threshold
973   config.threshold1.range = 97;
974   config.hysteresis = 0;
975   expectedTime.clear ();
976   expectedRsrp.clear ();
977   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A4 with very high threshold",
978                                                         config, expectedTime, expectedRsrp),
979                TestCase::TAKES_FOREVER);
980 
981   // === Event A5 (PCell becomes worse than absolute threshold1 AND neighbour becomes better than another absolute threshold2) ===
982 
983   // With low-low threshold
984   config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
985   config.threshold1.range = 0;
986   config.threshold2.range = 0;
987   expectedTime.clear ();
988   expectedRsrp.clear ();
989   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with low-low threshold",
990                                                         config, expectedTime, expectedRsrp),
991                TestCase::EXTENSIVE);
992 
993   // With low-normal threshold
994   config.threshold2.range = 58;
995   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with low-normal threshold",
996                                                         config, expectedTime, expectedRsrp),
997                TestCase::TAKES_FOREVER);
998 
999   // With low-high threshold
1000   config.threshold2.range = 97;
1001   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with low-high threshold",
1002                                                         config, expectedTime, expectedRsrp),
1003                TestCase::TAKES_FOREVER);
1004 
1005   // With normal-low threshold
1006   config.threshold1.range = 58;
1007   config.threshold2.range = 0;
1008   expectedTime.clear ();
1009   expectedTime << 800 << 1400 << 1640 << 1880;
1010   expectedRsrp.clear ();
1011   expectedRsrp << 52 << 56 << 52 << 56;
1012   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with normal-low threshold",
1013                                                         config, expectedTime, expectedRsrp),
1014                TestCase::EXTENSIVE);
1015 
1016   // With normal-normal threshold
1017   config.threshold2.range = 58;
1018   expectedTime.clear ();
1019   expectedTime << 800 << 1400 << 1640 << 1880;
1020   expectedRsrp.clear ();
1021   expectedRsrp << 52 << 56 << 52 << 56;
1022   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with normal-normal threshold",
1023                                                         config, expectedTime, expectedRsrp),
1024                TestCase::EXTENSIVE);
1025 
1026   // With short time-to-trigger
1027   config.timeToTrigger = 160;
1028   expectedTime.clear ();
1029   expectedTime << 960 << 1560 << 1800 << 2040;
1030   expectedRsrp.clear ();
1031   expectedRsrp << 52 << 56 << 56 << 59;
1032   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with short time-to-trigger",
1033                                                         config, expectedTime, expectedRsrp),
1034                TestCase::TAKES_FOREVER);
1035 
1036   // With super time-to-trigger
1037   config.timeToTrigger = 320;
1038   expectedTime.clear ();
1039   expectedTime << 1720 << 1960 << 2200;
1040   expectedRsrp.clear ();
1041   expectedRsrp << 52 << 56 << 72;
1042   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with super time-to-trigger",
1043                                                         config, expectedTime, expectedRsrp),
1044                TestCase::QUICK);
1045 
1046   // With hysteresis
1047   config.hysteresis = 6;
1048   config.timeToTrigger = 0;
1049   expectedTime.clear ();
1050   expectedTime << 800 << 1600 << 1840 << 2080;
1051   expectedRsrp.clear ();
1052   expectedRsrp << 52 << 52 << 56 << 59;
1053   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with hysteresis",
1054                                                         config, expectedTime, expectedRsrp),
1055                TestCase::QUICK);
1056 
1057   // With normal-high threshold
1058   config.threshold2.range = 97;
1059   config.hysteresis = 0;
1060   expectedTime.clear ();
1061   expectedRsrp.clear ();
1062   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with normal-high threshold",
1063                                                         config, expectedTime, expectedRsrp),
1064                TestCase::TAKES_FOREVER);
1065 
1066   // With high-low threshold
1067   config.threshold1.range = 97;
1068   config.threshold2.range = 0;
1069   expectedTime.clear ();
1070   expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
1071   expectedRsrp.clear ();
1072   expectedRsrp << 73 << 63 << 72 << 52 << 72 << 56 << 52 << 56 << 59;
1073   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with high-low threshold",
1074                                                         config, expectedTime, expectedRsrp),
1075                TestCase::EXTENSIVE);
1076 
1077   // With high-normal threshold
1078   config.threshold2.range = 58;
1079   expectedTime.clear ();
1080   expectedTime << 400 << 800 << 1400 << 1640 << 1880;
1081   expectedRsrp.clear ();
1082   expectedRsrp << 63 << 52 << 56 << 52 << 56;
1083   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with high-normal threshold",
1084                                                         config, expectedTime, expectedRsrp),
1085                TestCase::TAKES_FOREVER);
1086 
1087   // With high-high threshold
1088   config.threshold2.range = 97;
1089   expectedTime.clear ();
1090   expectedRsrp.clear ();
1091   AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with high-high threshold",
1092                                                         config, expectedTime, expectedRsrp),
1093                TestCase::EXTENSIVE);
1094 
1095 } // end of LteUeMeasurementsPiecewiseTestSuite2::LteUeMeasurementsPiecewiseTestSuite2
1096 
1097 static LteUeMeasurementsPiecewiseTestSuite2 lteUeMeasurementsPiecewiseTestSuite2;
1098 
1099 
1100 /*
1101  * Test Case
1102  */
1103 
LteUeMeasurementsPiecewiseTestCase2(std::string name,LteRrcSap::ReportConfigEutra config,std::vector<Time> expectedTime,std::vector<uint8_t> expectedRsrp)1104 LteUeMeasurementsPiecewiseTestCase2::LteUeMeasurementsPiecewiseTestCase2 (
1105   std::string name, LteRrcSap::ReportConfigEutra config,
1106   std::vector<Time> expectedTime, std::vector<uint8_t> expectedRsrp)
1107   : TestCase (name),
1108     m_config (config),
1109     m_expectedTime (expectedTime),
1110     m_expectedRsrp (expectedRsrp)
1111 {
1112   // input sanity check
1113   uint16_t size = m_expectedTime.size ();
1114 
1115   if (size != m_expectedRsrp.size ())
1116     {
1117       NS_FATAL_ERROR ("Vectors of expected results are not of the same size");
1118     }
1119 
1120   m_itExpectedTime = m_expectedTime.begin ();
1121   m_itExpectedRsrp = m_expectedRsrp.begin ();
1122 
1123   NS_LOG_INFO (this << " name=" << name);
1124 }
1125 
~LteUeMeasurementsPiecewiseTestCase2()1126 LteUeMeasurementsPiecewiseTestCase2::~LteUeMeasurementsPiecewiseTestCase2 ()
1127 {
1128   NS_LOG_FUNCTION (this);
1129 }
1130 
1131 void
DoRun()1132 LteUeMeasurementsPiecewiseTestCase2::DoRun ()
1133 {
1134   NS_LOG_INFO (this << " " << GetName ());
1135 
1136   Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
1137   lteHelper->SetAttribute ("PathlossModel",
1138                            StringValue ("ns3::FriisSpectrumPropagationLossModel"));
1139   lteHelper->SetAttribute ("UseIdealRrc", BooleanValue (true));
1140 
1141   //Disable Uplink Power Control
1142   Config::SetDefault ("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue (false));
1143 
1144   // Create Nodes: eNodeB and UE
1145   NodeContainer enbNodes;
1146   NodeContainer ueNodes;
1147   enbNodes.Create (2);
1148   ueNodes.Create (1);
1149 
1150   /*
1151    * The topology is the following:
1152    *
1153    * eNodeB    UE                                                eNodeB
1154    *    |      |                                                    |
1155    *    x ---- x --------------- x ------- x --------------- x ---- x
1156    *      50 m |      200 m      |  100 m  |      200 m      | 50 m
1157    *           |                 |         |                 |
1158    *        VeryNear            Near      Far             VeryFar
1159    */
1160 
1161   Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
1162   positionAlloc->Add (Vector (0.0, 0.0, 0.0)); // Serving eNodeB
1163   positionAlloc->Add (Vector (600.0, 0.0, 0.0)); // Neighbour eNodeB
1164   positionAlloc->Add (Vector (50.0, 0.0, 0.0)); // UE
1165   MobilityHelper mobility;
1166   mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
1167   mobility.SetPositionAllocator (positionAlloc);
1168   mobility.Install (enbNodes);
1169   mobility.Install (ueNodes);
1170   m_ueMobility = ueNodes.Get (0)->GetObject<MobilityModel> ();
1171 
1172   // Disable layer-3 filtering
1173   Config::SetDefault ("ns3::LteEnbRrc::RsrpFilterCoefficient",
1174                       UintegerValue (0));
1175 
1176   // Create Devices and install them in the Nodes (eNB and UE)
1177   NetDeviceContainer enbDevs;
1178   NetDeviceContainer ueDevs;
1179   lteHelper->SetSchedulerType ("ns3::RrFfMacScheduler");
1180   lteHelper->SetSchedulerAttribute ("UlCqiFilter",
1181                                     EnumValue (FfMacScheduler::PUSCH_UL_CQI));
1182   enbDevs = lteHelper->InstallEnbDevice (enbNodes);
1183   ueDevs = lteHelper->InstallUeDevice (ueNodes);
1184 
1185   // Setup UE measurement configuration in serving cell
1186   Ptr<LteEnbRrc> enbRrc1 = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ()->GetRrc ();
1187   m_expectedMeasId = enbRrc1->AddUeMeasReportConfig (m_config);
1188 
1189   // Disable handover in neighbour cell
1190   Ptr<LteEnbRrc> enbRrc2 = enbDevs.Get (1)->GetObject<LteEnbNetDevice> ()->GetRrc ();
1191   enbRrc2->SetAttribute ("AdmitHandoverRequest", BooleanValue (false));
1192 
1193   // Attach UE to serving eNodeB
1194   lteHelper->Attach (ueDevs.Get (0), enbDevs.Get (0));
1195 
1196   // Activate an EPS bearer
1197   enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
1198   EpsBearer bearer (q);
1199   lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
1200 
1201   // Connect to trace sources in serving eNodeB
1202   Config::Connect ("/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
1203                    MakeCallback (&LteUeMeasurementsPiecewiseTestCase2::RecvMeasurementReportCallback,
1204                                  this));
1205 
1206   /*
1207    * Schedule "teleports"
1208    *          0                   1                   2
1209    *          +-------------------+-------------------+---------> time
1210    * VeryNear |------  ----    ----                    --------
1211    *     Near |                    ----            ----
1212    *      Far |                        ----    ----
1213    *  VeryFar |      --    ----            ----
1214    */
1215   Simulator::Schedule (MilliSeconds (301),
1216                        &LteUeMeasurementsPiecewiseTestCase2::TeleportVeryFar, this);
1217   Simulator::Schedule (MilliSeconds (401),
1218                        &LteUeMeasurementsPiecewiseTestCase2::TeleportVeryNear, this);
1219   Simulator::Schedule (MilliSeconds (601),
1220                        &LteUeMeasurementsPiecewiseTestCase2::TeleportVeryFar, this);
1221   Simulator::Schedule (MilliSeconds (801),
1222                        &LteUeMeasurementsPiecewiseTestCase2::TeleportVeryNear, this);
1223   Simulator::Schedule (MilliSeconds (1001),
1224                        &LteUeMeasurementsPiecewiseTestCase2::TeleportNear, this);
1225   Simulator::Schedule (MilliSeconds (1201),
1226                        &LteUeMeasurementsPiecewiseTestCase2::TeleportFar, this);
1227   Simulator::Schedule (MilliSeconds (1401),
1228                        &LteUeMeasurementsPiecewiseTestCase2::TeleportVeryFar, this);
1229   Simulator::Schedule (MilliSeconds (1601),
1230                        &LteUeMeasurementsPiecewiseTestCase2::TeleportFar, this);
1231   Simulator::Schedule (MilliSeconds (1801),
1232                        &LteUeMeasurementsPiecewiseTestCase2::TeleportNear, this);
1233   Simulator::Schedule (MilliSeconds (2001),
1234                        &LteUeMeasurementsPiecewiseTestCase2::TeleportVeryNear, this);
1235 
1236   // Run simulation
1237   Simulator::Stop (Seconds (2.201));
1238   Simulator::Run ();
1239   Simulator::Destroy ();
1240 
1241 } // end of void LteUeMeasurementsPiecewiseTestCase2::DoRun ()
1242 
1243 void
DoTeardown()1244 LteUeMeasurementsPiecewiseTestCase2::DoTeardown ()
1245 {
1246   NS_LOG_FUNCTION (this);
1247   bool hasEnded = m_itExpectedTime == m_expectedTime.end ();
1248   NS_TEST_ASSERT_MSG_EQ (hasEnded, true,
1249                          "Reporting should have occurred at " << m_itExpectedTime->As (Time::S));
1250   hasEnded = m_itExpectedRsrp == m_expectedRsrp.end ();
1251   NS_ASSERT (hasEnded);
1252 }
1253 
1254 void
RecvMeasurementReportCallback(std::string context,uint64_t imsi,uint16_t cellId,uint16_t rnti,LteRrcSap::MeasurementReport report)1255 LteUeMeasurementsPiecewiseTestCase2::RecvMeasurementReportCallback (
1256   std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti,
1257   LteRrcSap::MeasurementReport report)
1258 {
1259   NS_LOG_FUNCTION (this << context);
1260   NS_ASSERT (rnti == 1);
1261   NS_ASSERT (cellId == 1);
1262 
1263   if (report.measResults.measId == m_expectedMeasId)
1264     {
1265       // verifying the report completeness
1266       LteRrcSap::MeasResults measResults = report.measResults;
1267       NS_LOG_DEBUG (this << " Serving cellId=" << cellId
1268                          << " rsrp=" << (uint16_t) measResults.rsrpResult
1269                          << " (" << EutranMeasurementMapping::RsrpRange2Dbm (measResults.rsrpResult) << " dBm)"
1270                          << " rsrq=" << (uint16_t) measResults.rsrqResult
1271                          << " (" << EutranMeasurementMapping::RsrqRange2Db (measResults.rsrqResult) << " dB)");
1272 
1273       // verifying reported best cells
1274       if (measResults.measResultListEutra.size () == 0)
1275         {
1276           NS_TEST_ASSERT_MSG_EQ (measResults.haveMeasResultNeighCells, false,
1277                                  "Unexpected report content");
1278         }
1279       else
1280         {
1281           NS_TEST_ASSERT_MSG_EQ (measResults.haveMeasResultNeighCells, true,
1282                                  "Unexpected report content");
1283           std::list<LteRrcSap::MeasResultEutra>::iterator it = measResults.measResultListEutra.begin ();
1284           NS_ASSERT (it != measResults.measResultListEutra.end ());
1285           NS_ASSERT (it->physCellId == 2);
1286           NS_TEST_ASSERT_MSG_EQ (it->haveCgiInfo, false,
1287                                  "Report contains cgi-info, which is not supported");
1288           NS_TEST_ASSERT_MSG_EQ (it->haveRsrpResult, true,
1289                                  "Report does not contain measured RSRP result");
1290           NS_TEST_ASSERT_MSG_EQ (it->haveRsrqResult, true,
1291                                  "Report does not contain measured RSRQ result");
1292           NS_LOG_DEBUG (this << " Neighbour cellId=" << it->physCellId
1293                              << " rsrp=" << (uint16_t) it->rsrpResult
1294                              << " (" << EutranMeasurementMapping::RsrpRange2Dbm (it->rsrpResult) << " dBm)"
1295                              << " rsrq=" << (uint16_t) it->rsrqResult
1296                              << " (" << EutranMeasurementMapping::RsrqRange2Db (it->rsrqResult) << " dB)");
1297 
1298         } // end of else of if (measResults.measResultListEutra.size () == 0)
1299 
1300       // verifying the report timing
1301       bool hasEnded = m_itExpectedTime == m_expectedTime.end ();
1302       NS_TEST_ASSERT_MSG_EQ (hasEnded, false,
1303                              "Reporting should not have occurred at "
1304                              << Simulator::Now ().As (Time::S));
1305       if (!hasEnded)
1306         {
1307           hasEnded = m_itExpectedRsrp == m_expectedRsrp.end ();
1308           NS_ASSERT (!hasEnded);
1309 
1310           // using milliseconds to avoid floating-point comparison
1311           uint64_t timeNowMs = Simulator::Now ().GetMilliSeconds ();
1312           uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds ();
1313           m_itExpectedTime++;
1314 
1315           uint16_t observedRsrp = measResults.rsrpResult;
1316           uint16_t referenceRsrp = *m_itExpectedRsrp;
1317           m_itExpectedRsrp++;
1318 
1319           NS_TEST_ASSERT_MSG_EQ (timeNowMs, timeExpectedMs,
1320                                  "Reporting should not have occurred at this time");
1321           NS_TEST_ASSERT_MSG_EQ (observedRsrp, referenceRsrp,
1322                                  "The RSRP observed differs with the reference RSRP");
1323 
1324         } // end of if (!hasEnded)
1325 
1326     } // end of if (report.measResults.measId == m_expectedMeasId)
1327 
1328 } // end of void LteUeMeasurementsPiecewiseTestCase2::RecvMeasurementReportCallback
1329 
1330 void
TeleportVeryNear()1331 LteUeMeasurementsPiecewiseTestCase2::TeleportVeryNear ()
1332 {
1333   NS_LOG_FUNCTION (this);
1334   m_ueMobility->SetPosition (Vector (50.0, 0.0, 0.0));
1335 }
1336 
1337 void
TeleportNear()1338 LteUeMeasurementsPiecewiseTestCase2::TeleportNear ()
1339 {
1340   NS_LOG_FUNCTION (this);
1341   m_ueMobility->SetPosition (Vector (250.0, 0.0, 0.0));
1342 }
1343 
1344 void
TeleportFar()1345 LteUeMeasurementsPiecewiseTestCase2::TeleportFar ()
1346 {
1347   NS_LOG_FUNCTION (this);
1348   m_ueMobility->SetPosition (Vector (350.0, 0.0, 0.0));
1349 }
1350 
1351 void
TeleportVeryFar()1352 LteUeMeasurementsPiecewiseTestCase2::TeleportVeryFar ()
1353 {
1354   NS_LOG_FUNCTION (this);
1355   m_ueMobility->SetPosition (Vector (550.0, 0.0, 0.0));
1356 }
1357 
1358 
1359 // ===== LTE-UE-MEASUREMENTS-PIECEWISE-3 TEST SUITE ======================== //
1360 
1361 /*
1362  * Test Suite
1363  */
1364 
LteUeMeasurementsPiecewiseTestSuite3()1365 LteUeMeasurementsPiecewiseTestSuite3::LteUeMeasurementsPiecewiseTestSuite3 ()
1366   : TestSuite ("lte-ue-measurements-piecewise-3", SYSTEM)
1367 {
1368   std::vector<Time> expectedTime;
1369 
1370   // === Event A4 (neighbor becomes better than threshold) ===
1371 
1372   //The threshold value was chosen to achieve the following:
1373   //1. Neighbor 1 (eNB2) RSRP would be above the chosen threshold, hence,
1374   //the UE will include it in its reports to its eNB (eNB1) from the beginning
1375   //of the simulation.
1376   //2. When neighbor 2 (eNB3) is placed at a very far position, its RSRP would
1377   //be less than the chosen threshold, hence, UE will not include it in its
1378   //initial report(s) to its eNB.
1379   //3. When neighbor 2 (eNB3) is placed at a near position, its RSRP would
1380   //always be above the chosen threshold, hence, the UE will include it in its
1381   //reports to its eNB (eNB1).
1382   LteRrcSap::ReportConfigEutra config;
1383   config.triggerType = LteRrcSap::ReportConfigEutra::EVENT;
1384   config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
1385   config.threshold1.choice = LteRrcSap::ThresholdEutra::THRESHOLD_RSRP;
1386   config.threshold1.range = 6;
1387   config.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRP;
1388   config.reportInterval = LteRrcSap::ReportConfigEutra::MS240;
1389   expectedTime.clear ();
1390   expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
1391 
1392   AddTestCase (new LteUeMeasurementsPiecewiseTestCase3 ("Piecewise test case 3 - Event A4",
1393                                                         config, expectedTime),TestCase::QUICK);
1394 } // end of LteUeMeasurementsPiecewiseTestSuite3::LteUeMeasurementsPiecewiseTestSuite3
1395 
1396 static LteUeMeasurementsPiecewiseTestSuite3 lteUeMeasurementsPiecewiseTestSuite3;
1397 
1398 
1399 /*
1400  * Test Case
1401  */
1402 
LteUeMeasurementsPiecewiseTestCase3(std::string name,LteRrcSap::ReportConfigEutra config,std::vector<Time> expectedTime)1403 LteUeMeasurementsPiecewiseTestCase3::LteUeMeasurementsPiecewiseTestCase3 (
1404   std::string name, LteRrcSap::ReportConfigEutra config,
1405   std::vector<Time> expectedTime)
1406   : TestCase (name),
1407     m_config (config),
1408     m_expectedTime (expectedTime)
1409 {
1410   m_expectedMeasId = std::numeric_limits<uint8_t>::max ();
1411 
1412   m_itExpectedTime = m_expectedTime.begin ();
1413 
1414   NS_LOG_INFO (this << " name=" << name);
1415 }
1416 
~LteUeMeasurementsPiecewiseTestCase3()1417 LteUeMeasurementsPiecewiseTestCase3::~LteUeMeasurementsPiecewiseTestCase3 ()
1418 {
1419   NS_LOG_FUNCTION (this);
1420 }
1421 
1422 void
DoRun()1423 LteUeMeasurementsPiecewiseTestCase3::DoRun ()
1424 {
1425   NS_LOG_INFO (this << " " << GetName ());
1426 
1427   Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
1428   lteHelper->SetAttribute ("PathlossModel",
1429                            StringValue ("ns3::FriisSpectrumPropagationLossModel"));
1430   lteHelper->SetAttribute ("UseIdealRrc", BooleanValue (true));
1431 
1432   //Disable Uplink Power Control
1433   Config::SetDefault ("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue (false));
1434 
1435   // Create Nodes: eNodeB and UE
1436   NodeContainer enbNodes;
1437   NodeContainer ueNodes;
1438   enbNodes.Create (3);
1439   ueNodes.Create (1);
1440 
1441   /*
1442    * The topology is the following:
1443    *
1444    * We place the 3rd eNB initially very far so it does not fulfills
1445    * the entry condition to be reported.
1446    *
1447    * eNodeB    UE              eNodeB                                  eNodeB
1448    *    |      |                 |                                       |
1449    *    x ---- x --------------- x -------------- x ---------------------x
1450    *      50 m         100 m             500      |         1000000
1451    *                                             Near
1452    */
1453 
1454   Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
1455   positionAlloc->Add (Vector (0.0, 0.0, 0.0)); // Serving eNodeB
1456   positionAlloc->Add (Vector (200.0, 0.0, 0.0)); // Neighbour eNodeB1
1457   positionAlloc->Add (Vector (1000700.0, 0.0, 0.0)); // Neighbour eNodeB2
1458   positionAlloc->Add (Vector (50.0, 0.0, 0.0)); // UE
1459   MobilityHelper mobility;
1460   mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
1461   mobility.SetPositionAllocator (positionAlloc);
1462   mobility.Install (enbNodes);
1463   mobility.Install (ueNodes);
1464   m_enbMobility = enbNodes.Get (2)->GetObject<MobilityModel> ();
1465 
1466   // Disable layer-3 filtering
1467   Config::SetDefault ("ns3::LteEnbRrc::RsrpFilterCoefficient",
1468                       UintegerValue (0));
1469 
1470   // Create Devices and install them in the Nodes (eNB and UE)
1471   NetDeviceContainer enbDevs;
1472   NetDeviceContainer ueDevs;
1473   lteHelper->SetSchedulerType ("ns3::RrFfMacScheduler");
1474   lteHelper->SetSchedulerAttribute ("UlCqiFilter",
1475                                     EnumValue (FfMacScheduler::PUSCH_UL_CQI));
1476   enbDevs = lteHelper->InstallEnbDevice (enbNodes);
1477   ueDevs = lteHelper->InstallUeDevice (ueNodes);
1478 
1479   // Setup UE measurement configuration in serving cell
1480   Ptr<LteEnbRrc> enbRrc1 = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ()->GetRrc ();
1481   m_expectedMeasId = enbRrc1->AddUeMeasReportConfig (m_config);
1482 
1483   // Disable handover in neighbour cells
1484   Ptr<LteEnbRrc> enbRrc2 = enbDevs.Get (1)->GetObject<LteEnbNetDevice> ()->GetRrc ();
1485   enbRrc2->SetAttribute ("AdmitHandoverRequest", BooleanValue (false));
1486   Ptr<LteEnbRrc> enbRrc3 = enbDevs.Get (2)->GetObject<LteEnbNetDevice> ()->GetRrc ();
1487   enbRrc3->SetAttribute ("AdmitHandoverRequest", BooleanValue (false));
1488 
1489   // Attach UE to serving eNodeB
1490   lteHelper->Attach (ueDevs.Get (0), enbDevs.Get (0));
1491 
1492   // Activate an EPS bearer
1493   enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
1494   EpsBearer bearer (q);
1495   lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
1496 
1497   // Connect to trace sources in serving eNodeB
1498   Config::Connect ("/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
1499                    MakeCallback (&LteUeMeasurementsPiecewiseTestCase3::RecvMeasurementReportCallback,
1500                                  this));
1501   /*
1502    * Schedule "teleport" for the 2nd neighbour
1503    *
1504    * We bring the 2nd neighbour near once the UE has already scheduled the periodic
1505    * reporting after detecting the 1st neighbour, which ideally should be at
1506    * 200 ms.
1507    */
1508   Simulator::Schedule (MilliSeconds (301),
1509                        &LteUeMeasurementsPiecewiseTestCase3::TeleportEnbNear, this);
1510 
1511   // Run simulation
1512   Simulator::Stop (Seconds (2.201));
1513   Simulator::Run ();
1514   Simulator::Destroy ();
1515 
1516 } // end of void LteUeMeasurementsPiecewiseTestCase3::DoRun ()
1517 
1518 void
DoTeardown()1519 LteUeMeasurementsPiecewiseTestCase3::DoTeardown ()
1520 {
1521   NS_LOG_FUNCTION (this);
1522   bool hasEnded = m_itExpectedTime == m_expectedTime.end ();
1523   NS_TEST_ASSERT_MSG_EQ (hasEnded, true,
1524                          "Reporting should have occurred at " << m_itExpectedTime->GetSeconds () << "s");
1525 }
1526 
1527 void
RecvMeasurementReportCallback(std::string context,uint64_t imsi,uint16_t cellId,uint16_t rnti,LteRrcSap::MeasurementReport report)1528 LteUeMeasurementsPiecewiseTestCase3::RecvMeasurementReportCallback (
1529   std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti,
1530   LteRrcSap::MeasurementReport report)
1531 {
1532   NS_LOG_FUNCTION (this << context);
1533   NS_ASSERT (rnti == 1);
1534   NS_ASSERT (cellId == 1);
1535 
1536   if (report.measResults.measId == m_expectedMeasId)
1537     {
1538       // verifying the report completeness
1539       LteRrcSap::MeasResults measResults = report.measResults;
1540       NS_LOG_DEBUG (this << " Serving cellId=" << cellId
1541                          << " rsrp=" << (uint16_t) measResults.rsrpResult
1542                          << " (" << EutranMeasurementMapping::RsrpRange2Dbm (measResults.rsrpResult) << " dBm)"
1543                          << " rsrq=" << (uint16_t) measResults.rsrqResult
1544                          << " (" << EutranMeasurementMapping::RsrqRange2Db (measResults.rsrqResult) << " dB)");
1545 
1546       // verifying reported best cells
1547       if (measResults.measResultListEutra.size () == 0)
1548         {
1549           NS_TEST_ASSERT_MSG_EQ (measResults.haveMeasResultNeighCells, false,
1550                                  "Unexpected report content");
1551         }
1552       else
1553         {
1554           NS_TEST_ASSERT_MSG_EQ (measResults.haveMeasResultNeighCells, true,
1555                                  "Unexpected report content");
1556           std::list<LteRrcSap::MeasResultEutra>::iterator it = measResults.measResultListEutra.begin ();
1557           NS_ASSERT (it != measResults.measResultListEutra.end ());
1558           for (const auto &it:measResults.measResultListEutra)
1559             {
1560               NS_ASSERT (it.physCellId == 2 || it.physCellId == 3);
1561               NS_TEST_ASSERT_MSG_EQ (it.haveCgiInfo, false,
1562                                      "Report contains cgi-info, which is not supported");
1563               NS_TEST_ASSERT_MSG_EQ (it.haveRsrpResult, true,
1564                                      "Report does not contain measured RSRP result");
1565               NS_TEST_ASSERT_MSG_EQ (it.haveRsrqResult, true,
1566                                      "Report does not contain measured RSRQ result");
1567               NS_LOG_DEBUG (this << " Neighbour cellId=" << it.physCellId
1568                             << " rsrp=" << (uint16_t) it.rsrpResult
1569                             << " (" << EutranMeasurementMapping::RsrpRange2Dbm (it.rsrpResult) << " dBm)"
1570                             << " rsrq=" << (uint16_t) it.rsrqResult
1571                             << " (" << EutranMeasurementMapping::RsrqRange2Db (it.rsrqResult) << " dB)");
1572             }
1573 
1574         } // end of else of if (measResults.measResultListEutra.size () == 0)
1575 
1576       // verifying the report timing
1577       bool hasEnded = m_itExpectedTime == m_expectedTime.end ();
1578       NS_TEST_ASSERT_MSG_EQ (hasEnded, false,
1579                              "Reporting should not have occurred at "
1580                              << Simulator::Now ().GetSeconds () << "s");
1581       if (!hasEnded)
1582         {
1583           // using milliseconds to avoid floating-point comparison
1584           uint64_t timeNowMs = Simulator::Now ().GetMilliSeconds ();
1585           uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds ();
1586           m_itExpectedTime++;
1587 
1588 
1589           NS_TEST_ASSERT_MSG_EQ (timeNowMs, timeExpectedMs,
1590                                  "Reporting should not have occurred at this time");
1591 
1592         } // end of if (!hasEnded)
1593 
1594     } // end of if (report.measResults.measId == m_expectedMeasId)
1595 
1596 } // end of void LteUeMeasurementsPiecewiseTestCase3::RecvMeasurementReportCallback
1597 
1598 void
TeleportEnbNear()1599 LteUeMeasurementsPiecewiseTestCase3::TeleportEnbNear ()
1600 {
1601   NS_LOG_FUNCTION (this);
1602   m_enbMobility->SetPosition (Vector (700.0, 0.0, 0.0));
1603 }
1604 
1605 
1606 // ===== LTE-UE-MEASUREMENTS-HANDOVER TEST SUITE =========================== //
1607 
1608 /*
1609  * Test Suite
1610  */
1611 
LteUeMeasurementsHandoverTestSuite()1612 LteUeMeasurementsHandoverTestSuite::LteUeMeasurementsHandoverTestSuite ()
1613   : TestSuite ("lte-ue-measurements-handover", SYSTEM)
1614 {
1615   std::list<LteRrcSap::ReportConfigEutra> sourceConfigList;
1616   std::list<LteRrcSap::ReportConfigEutra> targetConfigList;
1617   std::vector<Time> expectedTime;
1618   std::vector<uint8_t> expectedRsrp;
1619 
1620   LteRrcSap::ReportConfigEutra sourceConfig;
1621   sourceConfig.triggerType = LteRrcSap::ReportConfigEutra::EVENT;
1622   sourceConfig.eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
1623   sourceConfig.threshold1.choice = LteRrcSap::ThresholdEutra::THRESHOLD_RSRP;
1624   sourceConfig.threshold1.range = 0;
1625   sourceConfig.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRP;
1626   sourceConfig.reportInterval = LteRrcSap::ReportConfigEutra::MS240;
1627   sourceConfigList.push_back (sourceConfig);
1628 
1629   LteRrcSap::ReportConfigEutra targetConfig;
1630   targetConfig.triggerType = LteRrcSap::ReportConfigEutra::EVENT;
1631   targetConfig.eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
1632   targetConfig.threshold1.choice = LteRrcSap::ThresholdEutra::THRESHOLD_RSRP;
1633   targetConfig.threshold1.range = 0;
1634   targetConfig.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRP;
1635   targetConfig.reportInterval = LteRrcSap::ReportConfigEutra::MS240;
1636   targetConfigList.push_back (targetConfig);
1637 
1638   // === Report interval difference ===
1639 
1640   // decreasing report interval
1641   sourceConfigList.front ().reportInterval = LteRrcSap::ReportConfigEutra::MS480;
1642   targetConfigList.front ().reportInterval = LteRrcSap::ReportConfigEutra::MS240;
1643   expectedTime.clear ();
1644   expectedTime << 200 << 680 << 1200 << 1440 << 1680 << 1920;
1645   expectedRsrp.clear ();
1646   expectedRsrp << 55 << 55 << 53 << 53 << 53 << 53;
1647   AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - decreasing report interval",
1648                                                       sourceConfigList, targetConfigList,
1649                                                       expectedTime, expectedRsrp,
1650                                                       Seconds (2)),
1651                TestCase::TAKES_FOREVER);
1652 
1653   // increasing report interval
1654   sourceConfigList.front ().reportInterval = LteRrcSap::ReportConfigEutra::MS120;
1655   targetConfigList.front ().reportInterval = LteRrcSap::ReportConfigEutra::MS640;
1656   expectedTime.clear ();
1657   expectedTime << 200 << 320 << 440 << 560 << 680 << 800 << 920 << 1200 << 1840;
1658   expectedRsrp.clear ();
1659   expectedRsrp << 55 << 55 << 55 << 55 << 55 << 55 << 55 << 53 << 53;
1660   AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - increasing report interval",
1661                                                       sourceConfigList, targetConfigList,
1662                                                       expectedTime, expectedRsrp,
1663                                                       Seconds (2)),
1664                TestCase::QUICK);
1665 
1666   // === Event difference ===
1667 
1668   sourceConfigList.front ().reportInterval = LteRrcSap::ReportConfigEutra::MS240;
1669   targetConfigList.front ().reportInterval = LteRrcSap::ReportConfigEutra::MS240;
1670   sourceConfigList.front ().threshold1.range = 54;
1671   sourceConfigList.front ().threshold2.range = 54;
1672   sourceConfigList.front ().a3Offset = 1;
1673   targetConfigList.front ().threshold1.range = 54;
1674   targetConfigList.front ().threshold2.range = 54;
1675   targetConfigList.front ().a3Offset = 1;
1676 
1677   // Event A1 to Event A2
1678   sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
1679   targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
1680   expectedTime.clear ();
1681   expectedTime << 200 << 440 << 680 << 920 << 1200 << 1440 << 1680 << 1920;
1682   expectedRsrp.clear ();
1683   expectedRsrp << 55 << 55 << 55 << 55 << 53 << 53 << 53 << 53;
1684   AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A1 to Event A2",
1685                                                       sourceConfigList, targetConfigList,
1686                                                       expectedTime, expectedRsrp,
1687                                                       Seconds (2)),
1688                TestCase::EXTENSIVE);
1689 
1690   // Event A2 to Event A1
1691   sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
1692   targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
1693   expectedTime.clear ();
1694   expectedRsrp.clear ();
1695   AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A2 to Event A1",
1696                                                       sourceConfigList, targetConfigList,
1697                                                       expectedTime, expectedRsrp,
1698                                                       Seconds (2)),
1699                TestCase::TAKES_FOREVER);
1700 
1701   // Event A3 to Event A4
1702   sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
1703   targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
1704   expectedTime.clear ();
1705   expectedTime << 1200 << 1440 << 1680 << 1920;
1706   expectedRsrp.clear ();
1707   expectedRsrp << 53 << 53 << 53 << 53;
1708   AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A3 to Event A4",
1709                                                       sourceConfigList, targetConfigList,
1710                                                       expectedTime, expectedRsrp,
1711                                                       Seconds (2)),
1712                TestCase::TAKES_FOREVER);
1713 
1714   // Event A4 to Event A3
1715   sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
1716   targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
1717   expectedTime.clear ();
1718   expectedTime << 1200 << 1440 << 1680 << 1920;
1719   expectedRsrp.clear ();
1720   expectedRsrp << 53 << 53 << 53 << 53;
1721   AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A4 to Event A3",
1722                                                       sourceConfigList, targetConfigList,
1723                                                       expectedTime, expectedRsrp,
1724                                                       Seconds (2)),
1725                TestCase::QUICK);
1726 
1727   // Event A2 to Event A3
1728   sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
1729   targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
1730   expectedTime.clear ();
1731   expectedTime << 1200 << 1440 << 1680 << 1920;
1732   expectedRsrp.clear ();
1733   expectedRsrp << 53 << 53 << 53 << 53;
1734   AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A2 to Event A3",
1735                                                       sourceConfigList, targetConfigList,
1736                                                       expectedTime, expectedRsrp,
1737                                                       Seconds (2)),
1738                TestCase::EXTENSIVE);
1739 
1740   // Event A3 to Event A2
1741   sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
1742   targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
1743   expectedTime.clear ();
1744   expectedTime << 1200 << 1440 << 1680 << 1920;
1745   expectedRsrp.clear ();
1746   expectedRsrp << 53 << 53 << 53 << 53;
1747   AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A3 to Event A2",
1748                                                       sourceConfigList, targetConfigList,
1749                                                       expectedTime, expectedRsrp,
1750                                                       Seconds (2)),
1751                TestCase::TAKES_FOREVER);
1752 
1753   // Event A4 to Event A5
1754   sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
1755   targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
1756   expectedTime.clear ();
1757   expectedTime << 1200 << 1440 << 1680 << 1920;
1758   expectedRsrp.clear ();
1759   expectedRsrp << 53 << 53 << 53 << 53;
1760   AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A4 to Event A5",
1761                                                       sourceConfigList, targetConfigList,
1762                                                       expectedTime, expectedRsrp,
1763                                                       Seconds (2)),
1764                TestCase::TAKES_FOREVER);
1765 
1766   // Event A5 to Event A4
1767   sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
1768   targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
1769   expectedTime.clear ();
1770   expectedTime << 1200 << 1440 << 1680 << 1920;
1771   expectedRsrp.clear ();
1772   expectedRsrp << 53 << 53 << 53 << 53;
1773   AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A5 to Event A4",
1774                                                       sourceConfigList, targetConfigList,
1775                                                       expectedTime, expectedRsrp,
1776                                                       Seconds (2)),
1777                TestCase::EXTENSIVE);
1778 
1779   // === Threshold/offset difference ===
1780 
1781   sourceConfigList.front ().threshold1.range = 52;
1782   targetConfigList.front ().threshold1.range = 56;
1783 
1784   // Event A1
1785   sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
1786   targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
1787   expectedTime.clear ();
1788   expectedTime << 200 << 440 << 680 << 920;
1789   expectedRsrp.clear ();
1790   expectedRsrp << 55 << 55 << 55 << 55;
1791   AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A1 threshold difference",
1792                                                       sourceConfigList, targetConfigList,
1793                                                       expectedTime, expectedRsrp,
1794                                                       Seconds (2)),
1795                TestCase::EXTENSIVE);
1796 
1797   // Event A2
1798   sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
1799   targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
1800   expectedTime.clear ();
1801   expectedTime << 1200 << 1440 << 1680 << 1920;
1802   expectedRsrp.clear ();
1803   expectedRsrp << 53 << 53 << 53 << 53;
1804   AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A2 threshold difference",
1805                                                       sourceConfigList, targetConfigList,
1806                                                       expectedTime, expectedRsrp,
1807                                                       Seconds (2)),
1808                TestCase::QUICK);
1809 
1810   // Event A3
1811   sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
1812   sourceConfigList.front ().a3Offset = -30;
1813   targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
1814   targetConfigList.front ().a3Offset = 30;
1815   expectedTime.clear ();
1816   expectedTime << 200 << 440 << 680 << 920;
1817   expectedRsrp.clear ();
1818   expectedRsrp << 55 << 55 << 55 << 55;
1819   AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A3 offset difference",
1820                                                       sourceConfigList, targetConfigList,
1821                                                       expectedTime, expectedRsrp,
1822                                                       Seconds (2)),
1823                TestCase::QUICK);
1824 
1825   // Event A4
1826   sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
1827   targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
1828   expectedTime.clear ();
1829   expectedTime << 200 << 440 << 680 << 920;
1830   expectedRsrp.clear ();
1831   expectedRsrp << 55 << 55 << 55 << 55;
1832   AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A4 threshold difference",
1833                                                       sourceConfigList, targetConfigList,
1834                                                       expectedTime, expectedRsrp,
1835                                                       Seconds (2)),
1836                TestCase::EXTENSIVE);
1837 
1838   // Event A5
1839   sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
1840   sourceConfigList.front ().threshold2.range = 52;
1841   targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
1842   targetConfigList.front ().threshold2.range = 56;
1843   expectedTime.clear ();
1844   expectedRsrp.clear ();
1845   AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - Event A5 threshold difference",
1846                                                       sourceConfigList, targetConfigList,
1847                                                       expectedTime, expectedRsrp,
1848                                                       Seconds (2)),
1849                TestCase::EXTENSIVE);
1850 
1851   // === Time-to-trigger (TTT) difference ===
1852 
1853   sourceConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
1854   sourceConfigList.front ().a3Offset = 1;
1855   sourceConfigList.front ().threshold1.range = 0;
1856   sourceConfigList.front ().threshold2.range = 0;
1857   targetConfigList.front ().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
1858   targetConfigList.front ().a3Offset = 1;
1859   targetConfigList.front ().threshold1.range = 0;
1860   targetConfigList.front ().threshold2.range = 0;
1861 
1862   // decreasing time-to-trigger (short duration)
1863   sourceConfigList.front ().timeToTrigger = 1024;
1864   targetConfigList.front ().timeToTrigger = 100;
1865   expectedTime.clear ();
1866   expectedTime << 1300 << 1540 << 1780;
1867   expectedRsrp.clear ();
1868   expectedRsrp << 53 << 53 << 53;
1869   AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - decreasing TTT (short)",
1870                                                       sourceConfigList, targetConfigList,
1871                                                       expectedTime, expectedRsrp,
1872                                                       Seconds (2)),
1873                TestCase::QUICK);
1874 
1875   // decreasing time-to-trigger (longer duration)
1876   sourceConfigList.front ().timeToTrigger = 1024;
1877   targetConfigList.front ().timeToTrigger = 640;
1878   expectedTime.clear ();
1879   expectedTime << 1224 << 1464 << 1704 << 1944 << 2840 << 3080 << 3320 << 3560 << 3800 << 4040;
1880   expectedRsrp.clear ();
1881   expectedRsrp << 55 << 55 << 55 << 55 << 53 << 53 << 53 << 53 << 53 << 53;
1882   AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case - decreasing TTT (long)",
1883                                                       sourceConfigList, targetConfigList,
1884                                                       expectedTime, expectedRsrp,
1885                                                       Seconds (4.2)),
1886                TestCase::EXTENSIVE);
1887 
1888 } // end of LteUeMeasurementsHandoverTestSuite::LteUeMeasurementsHandoverTestSuite
1889 
1890 static LteUeMeasurementsHandoverTestSuite lteUeMeasurementsHandoverTestSuite;
1891 
1892 
1893 /*
1894  * Test Case
1895  */
1896 
LteUeMeasurementsHandoverTestCase(std::string name,std::list<LteRrcSap::ReportConfigEutra> sourceConfigList,std::list<LteRrcSap::ReportConfigEutra> targetConfigList,std::vector<Time> expectedTime,std::vector<uint8_t> expectedRsrp,Time duration)1897 LteUeMeasurementsHandoverTestCase::LteUeMeasurementsHandoverTestCase (
1898   std::string name,
1899   std::list<LteRrcSap::ReportConfigEutra> sourceConfigList,
1900   std::list<LteRrcSap::ReportConfigEutra> targetConfigList,
1901   std::vector<Time> expectedTime, std::vector<uint8_t> expectedRsrp,
1902   Time duration)
1903   : TestCase (name),
1904     m_sourceConfigList (sourceConfigList),
1905     m_targetConfigList (targetConfigList),
1906     m_expectedTime (expectedTime),
1907     m_expectedRsrp (expectedRsrp),
1908     m_duration (duration)
1909 {
1910   // input sanity check
1911   uint16_t size = m_expectedTime.size ();
1912 
1913   if (size != m_expectedRsrp.size ())
1914     {
1915       NS_FATAL_ERROR ("Vectors of expected results are not of the same size");
1916     }
1917 
1918   m_itExpectedTime = m_expectedTime.begin ();
1919   m_itExpectedRsrp = m_expectedRsrp.begin ();
1920 
1921   NS_LOG_INFO (this << " name=" << name);
1922 }
1923 
~LteUeMeasurementsHandoverTestCase()1924 LteUeMeasurementsHandoverTestCase::~LteUeMeasurementsHandoverTestCase ()
1925 {
1926   NS_LOG_FUNCTION (this);
1927 }
1928 
1929 void
DoRun()1930 LteUeMeasurementsHandoverTestCase::DoRun ()
1931 {
1932   NS_LOG_INFO (this << " " << GetName ());
1933 
1934   Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
1935   Ptr<PointToPointEpcHelper> epcHelper = CreateObject<PointToPointEpcHelper> ();
1936   lteHelper->SetEpcHelper (epcHelper);
1937   lteHelper->SetAttribute ("PathlossModel",
1938                            StringValue ("ns3::FriisSpectrumPropagationLossModel"));
1939   lteHelper->SetAttribute ("UseIdealRrc", BooleanValue (true));
1940 
1941   //Disable Uplink Power Control
1942   Config::SetDefault ("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue (false));
1943 
1944 
1945   // Create Nodes: eNodeB and UE
1946   NodeContainer enbNodes;
1947   NodeContainer ueNodes;
1948   enbNodes.Create (2);
1949   ueNodes.Create (1);
1950 
1951   /*
1952    * The topology is the following:
1953    *
1954    * eNodeB                   UE                     eNodeB
1955    *    |                     |                         |
1956    *    x ------------------- x ----------------------- x
1957    *             400 m                   500 m
1958    */
1959 
1960   Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
1961   positionAlloc->Add (Vector (0.0, 0.0, 0.0)); // Source eNodeB
1962   positionAlloc->Add (Vector (900.0, 0.0, 0.0)); // Target eNodeB
1963   positionAlloc->Add (Vector (400.0, 0.0, 0.0)); // UE
1964   MobilityHelper mobility;
1965   mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
1966   mobility.SetPositionAllocator (positionAlloc);
1967   mobility.Install (enbNodes);
1968   mobility.Install (ueNodes);
1969 
1970   // Create P-GW node
1971   Ptr<Node> pgw = epcHelper->GetPgwNode ();
1972 
1973   // Create a single RemoteHost
1974   NodeContainer remoteHostContainer;
1975   remoteHostContainer.Create (1);
1976   Ptr<Node> remoteHost = remoteHostContainer.Get (0);
1977   InternetStackHelper internet;
1978   internet.Install (remoteHostContainer);
1979 
1980   // Create the Internet
1981   PointToPointHelper p2ph;
1982   p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s")));
1983   p2ph.SetDeviceAttribute ("Mtu", UintegerValue (1500));
1984   p2ph.SetChannelAttribute ("Delay", TimeValue (Seconds (0.010)));
1985   NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost);
1986   Ipv4AddressHelper ipv4h;
1987   ipv4h.SetBase ("1.0.0.0", "255.0.0.0");
1988   Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices);
1989 
1990   // Routing of the Internet Host (towards the LTE network)
1991   Ipv4StaticRoutingHelper ipv4RoutingHelper;
1992   Ptr<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());
1993   remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.0.0.0"), 1);
1994 
1995   // Enable layer-3 filtering
1996   Config::SetDefault ("ns3::LteEnbRrc::RsrpFilterCoefficient",
1997                       UintegerValue (4));
1998 
1999   // Disable control channel error model
2000   Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled",
2001                       BooleanValue (false));
2002 
2003   // Create Devices and install them in the Nodes (eNB and UE)
2004   NetDeviceContainer enbDevs;
2005   NetDeviceContainer ueDevs;
2006   enbDevs = lteHelper->InstallEnbDevice (enbNodes);
2007   ueDevs = lteHelper->InstallUeDevice (ueNodes);
2008 
2009   // Setup UE measurement configuration in eNodeBs
2010   uint8_t measId;
2011   std::list<LteRrcSap::ReportConfigEutra>::const_iterator itReportConfig;
2012   Ptr<LteEnbRrc> enbRrc1 = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ()->GetRrc ();
2013   Ptr<LteEnbRrc> enbRrc2 = enbDevs.Get (1)->GetObject<LteEnbNetDevice> ()->GetRrc ();
2014 
2015   for (itReportConfig = m_sourceConfigList.begin ();
2016        itReportConfig != m_sourceConfigList.end (); itReportConfig++)
2017     {
2018       measId = enbRrc1->AddUeMeasReportConfig (*itReportConfig);
2019       m_expectedSourceCellMeasId.insert (measId);
2020     }
2021 
2022   for (itReportConfig = m_targetConfigList.begin ();
2023        itReportConfig != m_targetConfigList.end (); itReportConfig++)
2024     {
2025       measId = enbRrc2->AddUeMeasReportConfig (*itReportConfig);
2026       m_expectedTargetCellMeasId.insert (measId);
2027     }
2028 
2029   // Install the IP stack on the UEs
2030   internet.Install (ueNodes);
2031   Ipv4InterfaceContainer ueIpIfaces;
2032   ueIpIfaces = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueDevs));
2033 
2034   // Assign IP address to UEs
2035   for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
2036     {
2037       Ptr<Node> ueNode = ueNodes.Get (u);
2038       // Set the default gateway for the UE
2039       Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ueNode->GetObject<Ipv4> ());
2040       ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1);
2041     }
2042 
2043   // Attach UE to serving eNodeB
2044   lteHelper->Attach (ueDevs.Get (0), enbDevs.Get (0));
2045 
2046   // Add X2 interface
2047   lteHelper->AddX2Interface (enbNodes);
2048 
2049   // Connect to trace sources in source eNodeB
2050   Config::Connect ("/NodeList/3/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
2051                    MakeCallback (&LteUeMeasurementsHandoverTestCase::RecvMeasurementReportCallback,
2052                                  this));
2053 
2054   // Connect to trace sources in target eNodeB
2055   Config::Connect ("/NodeList/4/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
2056                    MakeCallback (&LteUeMeasurementsHandoverTestCase::RecvMeasurementReportCallback,
2057                                  this));
2058 
2059   // Schedule handover
2060   lteHelper->HandoverRequest (MilliSeconds (m_duration.GetMilliSeconds () / 2),
2061                               ueDevs.Get (0), enbDevs.Get (0), enbDevs.Get (1));
2062 
2063   // Run simulation
2064   Simulator::Stop (m_duration);
2065   Simulator::Run ();
2066   Simulator::Destroy ();
2067 
2068 } // end of void LteUeMeasurementsHandoverTestCase::DoRun ()
2069 
2070 void
DoTeardown()2071 LteUeMeasurementsHandoverTestCase::DoTeardown ()
2072 {
2073   NS_LOG_FUNCTION (this);
2074   bool hasEnded = m_itExpectedTime == m_expectedTime.end ();
2075   NS_TEST_ASSERT_MSG_EQ (hasEnded, true,
2076                          "Reporting should have occurred at " << m_itExpectedTime->As (Time::S));
2077   hasEnded = m_itExpectedRsrp == m_expectedRsrp.end ();
2078   NS_ASSERT (hasEnded);
2079 }
2080 
2081 void
RecvMeasurementReportCallback(std::string context,uint64_t imsi,uint16_t cellId,uint16_t rnti,LteRrcSap::MeasurementReport report)2082 LteUeMeasurementsHandoverTestCase::RecvMeasurementReportCallback (
2083   std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti,
2084   LteRrcSap::MeasurementReport report)
2085 {
2086   uint8_t measId = report.measResults.measId;
2087   NS_LOG_FUNCTION (this << context << (uint16_t) measId);
2088 
2089   bool isCorrectMeasId;
2090   if (cellId == 1)
2091     {
2092       std::set<uint8_t>::iterator itMeasId = m_expectedSourceCellMeasId.find (measId);
2093       isCorrectMeasId = (itMeasId != m_expectedSourceCellMeasId.end ());
2094     }
2095   else if (cellId == 2)
2096     {
2097       std::set<uint8_t>::iterator itMeasId = m_expectedTargetCellMeasId.find (measId);
2098       isCorrectMeasId = (itMeasId != m_expectedTargetCellMeasId.end ());
2099     }
2100   else
2101     {
2102       NS_FATAL_ERROR ("Invalid cell ID " << cellId);
2103     }
2104 
2105   if (isCorrectMeasId)
2106     {
2107       // verifying the report completeness
2108       LteRrcSap::MeasResults measResults = report.measResults;
2109       NS_LOG_DEBUG (this << " Serving cellId=" << cellId
2110                          << " rsrp=" << (uint16_t) measResults.rsrpResult
2111                          << " (" << EutranMeasurementMapping::RsrpRange2Dbm (measResults.rsrpResult) << " dBm)"
2112                          << " rsrq=" << (uint16_t) measResults.rsrqResult
2113                          << " (" << EutranMeasurementMapping::RsrqRange2Db (measResults.rsrqResult) << " dB)");
2114 
2115       // verifying reported best cells
2116       if (measResults.measResultListEutra.size () == 0)
2117         {
2118           NS_TEST_ASSERT_MSG_EQ (measResults.haveMeasResultNeighCells, false,
2119                                  "Unexpected report content");
2120         }
2121       else
2122         {
2123           NS_TEST_ASSERT_MSG_EQ (measResults.haveMeasResultNeighCells, true,
2124                                  "Unexpected report content");
2125           std::list<LteRrcSap::MeasResultEutra>::iterator it = measResults.measResultListEutra.begin ();
2126           NS_ASSERT (it != measResults.measResultListEutra.end ());
2127           NS_ASSERT (it->physCellId != cellId);
2128           NS_ASSERT (it->physCellId <= 2);
2129           NS_TEST_ASSERT_MSG_EQ (it->haveCgiInfo, false,
2130                                  "Report contains cgi-info, which is not supported");
2131           NS_TEST_ASSERT_MSG_EQ (it->haveRsrpResult, true,
2132                                  "Report does not contain measured RSRP result");
2133           NS_TEST_ASSERT_MSG_EQ (it->haveRsrqResult, true,
2134                                  "Report does not contain measured RSRQ result");
2135           NS_LOG_DEBUG (this << " Neighbour cellId=" << it->physCellId
2136                              << " rsrp=" << (uint16_t) it->rsrpResult
2137                              << " (" << EutranMeasurementMapping::RsrpRange2Dbm (it->rsrpResult) << " dBm)"
2138                              << " rsrq=" << (uint16_t) it->rsrqResult
2139                              << " (" << EutranMeasurementMapping::RsrqRange2Db (it->rsrqResult) << " dB)");
2140 
2141         } // end of else of if (measResults.measResultListEutra.size () == 0)
2142 
2143       // verifying the report timing
2144       bool hasEnded = m_itExpectedTime == m_expectedTime.end ();
2145       NS_TEST_ASSERT_MSG_EQ (hasEnded, false,
2146                              "Reporting should not have occurred at "
2147                              << Simulator::Now ().As (Time::S));
2148       if (!hasEnded)
2149         {
2150           hasEnded = m_itExpectedRsrp == m_expectedRsrp.end ();
2151           NS_ASSERT (!hasEnded);
2152 
2153           // using milliseconds to avoid floating-point comparison
2154           uint64_t timeNowMs = Simulator::Now ().GetMilliSeconds ();
2155           uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds ();
2156           m_itExpectedTime++;
2157 
2158           uint16_t observedRsrp = measResults.rsrpResult;
2159           uint16_t referenceRsrp = *m_itExpectedRsrp;
2160           m_itExpectedRsrp++;
2161 
2162           NS_TEST_ASSERT_MSG_EQ (timeNowMs, timeExpectedMs,
2163                                  "Reporting should not have occurred at this time");
2164           NS_TEST_ASSERT_MSG_EQ (observedRsrp, referenceRsrp,
2165                                  "The RSRP observed differs with the reference RSRP");
2166 
2167         } // end of if (!hasEnded)
2168 
2169     } // end of if (report.measResults.measId == correctMeasId)
2170 
2171 } // end of void LteUeMeasurementsHandoverTestCase::RecvMeasurementReportCallback
2172