A Discrete-Event Network Simulator
API
lte-test-ue-measurements.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Manuel Requena <manuel.requena@cttc.es>
18  * Nicola Baldo <nbaldo@cttc.es>
19  * Marco Miozzo <mmiozzo@cttc.es>
20  * Budiarto Herman <budiarto.herman@magister.fi>
21  */
22 
24 
25 #include <ns3/boolean.h>
26 #include <ns3/callback.h>
27 #include <ns3/config.h>
28 #include <ns3/double.h>
29 #include <ns3/enum.h>
30 #include <ns3/ff-mac-scheduler.h>
31 #include <ns3/internet-stack-helper.h>
32 #include <ns3/ipv4-address-helper.h>
33 #include <ns3/ipv4-interface-container.h>
34 #include <ns3/ipv4-static-routing-helper.h>
35 #include <ns3/log.h>
36 #include <ns3/lte-common.h>
37 #include <ns3/lte-enb-net-device.h>
38 #include <ns3/lte-enb-phy.h>
39 #include <ns3/lte-enb-rrc.h>
40 #include <ns3/lte-helper.h>
41 #include <ns3/lte-ue-net-device.h>
42 #include <ns3/lte-ue-phy.h>
43 #include <ns3/lte-ue-rrc.h>
44 #include <ns3/mobility-helper.h>
45 #include <ns3/net-device-container.h>
46 #include <ns3/node-container.h>
47 #include <ns3/point-to-point-epc-helper.h>
48 #include <ns3/point-to-point-helper.h>
49 #include <ns3/simulator.h>
50 #include <ns3/string.h>
51 
52 using namespace ns3;
53 
54 NS_LOG_COMPONENT_DEFINE("LteUeMeasurementsTest");
55 
56 // ===== LTE-UE-MEASUREMENTS TEST SUITE ==================================== //
57 
58 void
60  std::string path,
61  uint16_t rnti,
62  uint16_t cellId,
63  double rsrp,
64  double rsrq,
65  bool servingCell,
66  uint8_t componentCarrierId)
67 {
68  testcase->ReportUeMeasurements(rnti, cellId, rsrp, rsrq, servingCell);
69 }
70 
71 void
73  std::string path,
74  uint64_t imsi,
75  uint16_t cellId,
76  uint16_t rnti,
78 {
79  testcase->RecvMeasurementReport(imsi, cellId, rnti, meas);
80 }
81 
82 /*
83  * Test Suite
84  */
85 
87  : TestSuite("lte-ue-measurements", SYSTEM)
88 {
89  AddTestCase(new LteUeMeasurementsTestCase("d1=10, d2=10000",
90  10.000000,
91  10000.000000,
92  -53.739702,
93  -113.739702,
94  -3.010305,
95  -63.010305),
96  TestCase::EXTENSIVE);
97  AddTestCase(new LteUeMeasurementsTestCase("d1=20, d2=10000",
98  20.000000,
99  10000.000000,
100  -59.760302,
101  -113.739702,
102  -3.010319,
103  -56.989719),
104  TestCase::EXTENSIVE);
105  AddTestCase(new LteUeMeasurementsTestCase("d1=50, d2=10000",
106  50.000000,
107  10000.000000,
108  -67.719102,
109  -113.739702,
110  -3.010421,
111  -49.031021),
112  TestCase::EXTENSIVE);
113  AddTestCase(new LteUeMeasurementsTestCase("d1=100, d2=10000",
114  100.000000,
115  10000.000000,
116  -73.739702,
117  -113.739702,
118  -3.010783,
119  -43.010783),
120  TestCase::EXTENSIVE);
121  AddTestCase(new LteUeMeasurementsTestCase("d1=200, d2=10000",
122  200.000000,
123  10000.000000,
124  -79.760302,
125  -113.739702,
126  -3.012232,
127  -36.991632),
128  TestCase::EXTENSIVE);
129  AddTestCase(new LteUeMeasurementsTestCase("d1=100, d2=10000",
130  100.000000,
131  10000.000000,
132  -73.739702,
133  -113.739702,
134  -3.010783,
135  -43.010783),
136  TestCase::EXTENSIVE);
137  AddTestCase(new LteUeMeasurementsTestCase("d1=200, d2=10000",
138  200.000000,
139  10000.000000,
140  -79.760302,
141  -113.739702,
142  -3.012232,
143  -36.991632),
144  TestCase::EXTENSIVE);
145  AddTestCase(new LteUeMeasurementsTestCase("d1=500, d2=10000",
146  500.000000,
147  10000.000000,
148  -87.719102,
149  -113.739702,
150  -3.022359,
151  -29.042959),
152  TestCase::EXTENSIVE);
153  AddTestCase(new LteUeMeasurementsTestCase("d1=1000, d2=10000",
154  1000.000000,
155  10000.000000,
156  -93.739702,
157  -113.739702,
158  -3.058336,
159  -23.058336),
160  TestCase::EXTENSIVE);
161  AddTestCase(new LteUeMeasurementsTestCase("d1=2000, d2=10000",
162  2000.000000,
163  10000.000000,
164  -99.760302,
165  -113.739702,
166  -3.199337,
167  -17.178738),
168  TestCase::EXTENSIVE);
169  AddTestCase(new LteUeMeasurementsTestCase("d1=5000, d2=10000",
170  5000.000000,
171  10000.000000,
172  -107.719102,
173  -113.739702,
174  -4.075793,
175  -10.096393),
176  TestCase::QUICK);
177  AddTestCase(new LteUeMeasurementsTestCase("d1=10000, d2=10000",
178  10000.000000,
179  10000.000000,
180  -113.739702,
181  -113.739702,
182  -6.257687,
183  -6.257687),
184  TestCase::EXTENSIVE);
185  AddTestCase(new LteUeMeasurementsTestCase("d1=20000, d2=10000",
186  20000.000000,
187  10000.000000,
188  -119.760302,
189  -113.739702,
190  -10.373365,
191  -4.352765),
192  TestCase::EXTENSIVE);
193  AddTestCase(new LteUeMeasurementsTestCase("d1=50000, d2=10000",
194  50000.000000,
195  10000.000000,
196  -127.719102,
197  -113.739702,
198  -17.605046,
199  -3.625645),
200  TestCase::EXTENSIVE);
201  AddTestCase(new LteUeMeasurementsTestCase("d1=100000, d2=10000",
202  100000.000000,
203  10000.000000,
204  -133.739702,
205  -113.739702,
206  -23.511071,
207  -3.511071),
208  TestCase::EXTENSIVE);
209  AddTestCase(new LteUeMeasurementsTestCase("d1=200000, d2=10000",
210  200000.000000,
211  10000.000000,
212  -139.760302,
213  -113.739702,
214  -29.502549,
215  -3.481949),
216  TestCase::EXTENSIVE);
217  AddTestCase(new LteUeMeasurementsTestCase("d1=500000, d2=10000",
218  500000.000000,
219  10000.000000,
220  -147.719102,
221  -113.739702,
222  -37.453160,
223  -3.473760),
224  TestCase::EXTENSIVE);
225  AddTestCase(new LteUeMeasurementsTestCase("d1=1000000, d2=10000",
226  1000000.000000,
227  10000.000000,
228  -153.739702,
229  -113.739702,
230  -43.472589,
231  -3.472589),
232  TestCase::EXTENSIVE);
233 }
234 
240 
241 /*
242  * Test Case
243  */
244 
246  double d1,
247  double d2,
248  double rsrpDbmUe1,
249  double rsrpDbmUe2,
250  double rsrqDbUe1,
251  double rsrqDbUe2)
252  : TestCase(name),
253  m_d1(d1),
254  m_d2(d2),
255  m_rsrpDbmUeServingCell(rsrpDbmUe1),
256  m_rsrpDbmUeNeighborCell(rsrpDbmUe2),
257  m_rsrqDbUeServingCell(rsrqDbUe1),
258  m_rsrqDbUeNeighborCell(rsrqDbUe2)
259 {
260  NS_LOG_INFO("Test UE Measurements d1 = " << d1 << " m. and d2 = " << d2 << " m.");
261 }
262 
264 {
265 }
266 
267 void
269 {
270  NS_LOG_INFO(this << " " << GetName());
271 
272  Config::SetDefault("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue(false));
273  Config::SetDefault("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue(false));
274  Config::SetDefault("ns3::LteAmc::AmcModel", EnumValue(LteAmc::PiroEW2010));
275  Config::SetDefault("ns3::LteAmc::Ber", DoubleValue(0.00005));
276  Ptr<LteHelper> lteHelper = CreateObject<LteHelper>();
277  lteHelper->SetAttribute("PathlossModel", StringValue("ns3::FriisSpectrumPropagationLossModel"));
278  lteHelper->SetAttribute("UseIdealRrc", BooleanValue(false));
279 
280  // Disable Uplink Power Control
281  Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false));
282 
283  // LogComponentEnable ("LteUeMeasurementsTest", LOG_LEVEL_ALL);
284 
285  // Create Nodes: eNodeB and UE
286  NodeContainer enbNodes;
287  NodeContainer ueNodes1;
288  NodeContainer ueNodes2;
289  enbNodes.Create(2);
290  ueNodes1.Create(1);
291  ueNodes2.Create(1);
292  NodeContainer allNodes = NodeContainer(enbNodes, ueNodes1, ueNodes2);
293 
294  // the topology is the following:
295  // d2
296  // UE1-----------eNB2
297  // | |
298  // d1| |d1
299  // | d2 |
300  // eNB1----------UE2
301  //
302  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
303  positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // eNB1
304  positionAlloc->Add(Vector(m_d2, m_d1, 0.0)); // eNB2
305  positionAlloc->Add(Vector(0.0, m_d1, 0.0)); // UE1
306  positionAlloc->Add(Vector(m_d2, 0.0, 0.0)); // UE2
308  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
309  mobility.SetPositionAllocator(positionAlloc);
310  mobility.Install(allNodes);
311 
312  // Create Devices and install them in the Nodes (eNB and UE)
313  NetDeviceContainer enbDevs;
314  NetDeviceContainer ueDevs1;
315  NetDeviceContainer ueDevs2;
316  lteHelper->SetSchedulerType("ns3::RrFfMacScheduler");
317  lteHelper->SetSchedulerAttribute("UlCqiFilter", EnumValue(FfMacScheduler::PUSCH_UL_CQI));
318  enbDevs = lteHelper->InstallEnbDevice(enbNodes);
319  ueDevs1 = lteHelper->InstallUeDevice(ueNodes1);
320  ueDevs2 = lteHelper->InstallUeDevice(ueNodes2);
321 
322  // Attach UEs to eNodeBs
323  lteHelper->Attach(ueDevs1, enbDevs.Get(0));
324  lteHelper->Attach(ueDevs2, enbDevs.Get(1));
325 
326  // Activate an EPS bearer
327  EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
328  EpsBearer bearer(q);
329  lteHelper->ActivateDataRadioBearer(ueDevs1, bearer);
330  lteHelper->ActivateDataRadioBearer(ueDevs2, bearer);
331 
333  "/NodeList/2/DeviceList/0/ComponentCarrierMapUe/0/LteUePhy/ReportUeMeasurements",
335  Config::Connect("/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
337 
339  "/NodeList/3/DeviceList/0/ComponentCarrierMapUe/0/LteUePhy/ReportUeMeasurements",
341  Config::Connect("/NodeList/1/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
343 
344  // need to allow for RRC connection establishment + SRS
345  Simulator::Stop(Seconds(0.800));
346  Simulator::Run();
347 
348  Simulator::Destroy();
349 }
350 
351 void
353  uint16_t cellId,
354  double rsrp,
355  double rsrq,
356  bool servingCell)
357 {
358  // need to allow for RRC connection establishment + CQI feedback reception + UE measurements
359  // filtering (200 ms)
360  if (Simulator::Now() > MilliSeconds(400))
361  {
362  if (servingCell)
363  {
364  NS_LOG_DEBUG("UE serving cellId " << cellId << " Rxed RSRP " << rsrp << " thr "
365  << m_rsrpDbmUeServingCell << " RSRQ " << rsrq
366  << " thr " << m_rsrqDbUeServingCell);
367  NS_TEST_ASSERT_MSG_EQ_TOL(m_rsrpDbmUeServingCell, rsrp, 0.2, "Wrong RSRP UE 1");
368  NS_TEST_ASSERT_MSG_EQ_TOL(m_rsrqDbUeServingCell, rsrq, 0.2, "Wrong RSRQ UE 1");
369  }
370  else
371  {
372  NS_LOG_DEBUG("UE neighbor cellId " << cellId << " Rxed RSRP " << rsrp << " thr "
373  << m_rsrpDbmUeNeighborCell << " RSRQ " << rsrq
374  << " thr " << m_rsrqDbUeNeighborCell);
375  NS_TEST_ASSERT_MSG_EQ_TOL(m_rsrpDbmUeNeighborCell, rsrp, 0.2, "Wrong RSRP UE 2");
376  NS_TEST_ASSERT_MSG_EQ_TOL(m_rsrqDbUeNeighborCell, rsrq, 0.2, "Wrong RSRQ UE ");
377  }
378  }
379 }
380 
381 void
383  uint16_t cellId,
384  uint16_t rnti,
386 {
387  // need to allow for RRC connection establishment + CQI feedback reception + UE measurements
388  // filtering (200 ms)
389  if (Simulator::Now() > MilliSeconds(400))
390  {
391  if (cellId == imsi)
392  {
393  NS_LOG_DEBUG(
394  this << "Serving Cell: received IMSI " << imsi << " CellId " << cellId << " RNTI "
395  << rnti << " thr "
396  << (uint16_t)EutranMeasurementMapping::Dbm2RsrpRange(m_rsrpDbmUeServingCell)
397  << " RSRP " << (uint16_t)meas.measResults.measResultPCell.rsrpResult
398  << " RSRQ " << (uint16_t)meas.measResults.measResultPCell.rsrqResult << " thr "
399  << (uint16_t)EutranMeasurementMapping::Db2RsrqRange(m_rsrqDbUeServingCell));
401  EutranMeasurementMapping::Dbm2RsrpRange(m_rsrpDbmUeServingCell),
402  "Wrong RSRP ");
404  EutranMeasurementMapping::Db2RsrqRange(m_rsrqDbUeServingCell),
405  "Wrong RSRQ ");
406  }
407  else
408  {
409  NS_LOG_DEBUG(
410  this << "Neighbor cell: received IMSI " << imsi << " CellId " << cellId << " RNTI "
411  << rnti << " thr "
412  << (uint16_t)EutranMeasurementMapping::Dbm2RsrpRange(m_rsrpDbmUeNeighborCell)
413  << " RSRP " << (uint16_t)meas.measResults.measResultPCell.rsrpResult
414  << " RSRQ " << (uint16_t)meas.measResults.measResultPCell.rsrqResult << " thr "
415  << (uint16_t)EutranMeasurementMapping::Db2RsrqRange(m_rsrqDbUeNeighborCell));
417  EutranMeasurementMapping::Dbm2RsrpRange(m_rsrpDbmUeNeighborCell),
418  "Wrong RSRP ");
420  EutranMeasurementMapping::Db2RsrqRange(m_rsrqDbUeNeighborCell),
421  "Wrong RSRQ ");
422  }
423  }
424 }
425 
426 // ===== LTE-UE-MEASUREMENTS-PIECEWISE-1 TEST SUITE ======================== //
427 
428 /*
429  * Overloaded operators, for the convenience of defining test cases
430  */
431 
432 std::vector<Time>&
433 operator<<(std::vector<Time>& v, const uint64_t& ms)
434 {
435  /*
436  * Prior attempt to use seconds as unit of choice resulted in precision lost.
437  * Therefore milliseconds are used now instead.
438  */
439  v.push_back(MilliSeconds(ms) + UE_MEASUREMENT_REPORT_DELAY);
440  return v;
441 }
442 
443 std::vector<uint8_t>&
444 operator<<(std::vector<uint8_t>& v, const uint8_t& range)
445 {
446  v.push_back(range);
447  return v;
448 }
449 
450 /*
451  * Test Suite
452  */
453 
455  : TestSuite("lte-ue-measurements-piecewise-1", SYSTEM)
456 {
457  std::vector<Time> expectedTime;
458  std::vector<uint8_t> expectedRsrp;
459 
460  // === Event A1 (serving cell becomes better than threshold) ===
461 
462  // With very low threshold
464  config.triggerType = LteRrcSap::ReportConfigEutra::EVENT;
465  config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
466  config.threshold1.choice = LteRrcSap::ThresholdEutra::THRESHOLD_RSRP;
467  config.threshold1.range = 0;
468  config.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRP;
469  config.reportInterval = LteRrcSap::ReportConfigEutra::MS120;
470  expectedTime.clear();
471  expectedTime << 200 << 320 << 440 << 560 << 680 << 800 << 920 << 1040 << 1160 << 1280 << 1400
472  << 1520 << 1640 << 1760 << 1880 << 2000 << 2120;
473  expectedRsrp.clear();
474  expectedRsrp << 67 << 67 << 57 << 57 << 66 << 47 << 47 << 66 << 66 << 57 << 51 << 51 << 47 << 47
475  << 51 << 57 << 57;
477  "Piecewise test case 1 - Event A1 with very low threshold",
478  config,
479  expectedTime,
480  expectedRsrp),
481  TestCase::EXTENSIVE);
482 
483  // With normal threshold
484  config.threshold1.range = 54;
485  expectedTime.clear();
486  expectedTime << 200 << 320 << 440 << 560 << 680 << 1000 << 1120 << 1240 << 1360 << 2000 << 2120;
487  expectedRsrp.clear();
488  expectedRsrp << 67 << 67 << 57 << 57 << 66 << 66 << 66 << 57 << 57 << 57 << 57;
490  "Piecewise test case 1 - Event A1 with normal threshold",
491  config,
492  expectedTime,
493  expectedRsrp),
494  TestCase::EXTENSIVE);
495 
496  // With short time-to-trigger
497  config.timeToTrigger = 64;
498  expectedTime.clear();
499  expectedTime << 264 << 384 << 504 << 624 << 744 << 1064 << 1184 << 1304 << 1424 << 2064 << 2184;
500  expectedRsrp.clear();
501  expectedRsrp << 67 << 67 << 57 << 66 << 66 << 66 << 66 << 57 << 51 << 57 << 57;
503  "Piecewise test case 1 - Event A1 with short time-to-trigger",
504  config,
505  expectedTime,
506  expectedRsrp),
507  TestCase::QUICK);
508 
509  // With long time-to-trigger
510  config.timeToTrigger = 128;
511  expectedTime.clear();
512  expectedTime << 328 << 448 << 568 << 688 << 808 << 1128 << 1248 << 1368 << 1488 << 2128;
513  expectedRsrp.clear();
514  expectedRsrp << 67 << 57 << 57 << 66 << 47 << 66 << 57 << 57 << 51 << 57;
516  "Piecewise test case 1 - Event A1 with long time-to-trigger",
517  config,
518  expectedTime,
519  expectedRsrp),
520  TestCase::EXTENSIVE);
521 
522  // With super time-to-trigger
523  config.timeToTrigger = 256;
524  expectedTime.clear();
525  expectedTime << 456 << 576 << 696 << 816 << 936 << 1056 << 1176 << 1296 << 1416 << 1536;
526  expectedRsrp.clear();
527  expectedRsrp << 57 << 57 << 66 << 47 << 47 << 66 << 66 << 57 << 51 << 51;
529  "Piecewise test case 1 - Event A1 with super time-to-trigger",
530  config,
531  expectedTime,
532  expectedRsrp),
533  TestCase::EXTENSIVE);
534 
535  // With hysteresis
536  config.hysteresis = 8;
537  config.timeToTrigger = 0;
538  expectedTime.clear();
539  expectedTime << 200 << 320 << 440 << 560 << 680 << 1000 << 1120 << 1240 << 1360 << 1480 << 2200;
540  expectedRsrp.clear();
541  expectedRsrp << 67 << 67 << 57 << 57 << 66 << 66 << 66 << 57 << 57 << 51 << 67;
542  AddTestCase(
543  new LteUeMeasurementsPiecewiseTestCase1("Piecewise test case 1 - Event A1 with hysteresis",
544  config,
545  expectedTime,
546  expectedRsrp),
547  TestCase::QUICK);
548 
549  // With very high threshold
550  config.threshold1.range = 97;
551  config.hysteresis = 0;
552  expectedTime.clear();
553  expectedRsrp.clear();
555  "Piecewise test case 1 - Event A1 with very high threshold",
556  config,
557  expectedTime,
558  expectedRsrp),
559  TestCase::TAKES_FOREVER);
560 
561  // === Event A2 (serving cell becomes worse than threshold) ===
562 
563  // With very low threshold
564  config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
565  config.threshold1.range = 0;
566  expectedTime.clear();
567  expectedRsrp.clear();
569  "Piecewise test case 1 - Event A2 with very low threshold",
570  config,
571  expectedTime,
572  expectedRsrp),
573  TestCase::TAKES_FOREVER);
574 
575  // With normal threshold
576  config.threshold1.range = 54;
577  expectedTime.clear();
578  expectedTime << 800 << 920 << 1400 << 1520 << 1640 << 1760 << 1880;
579  expectedRsrp.clear();
580  expectedRsrp << 47 << 47 << 51 << 51 << 47 << 47 << 51;
582  "Piecewise test case 1 - Event A2 with normal threshold",
583  config,
584  expectedTime,
585  expectedRsrp),
586  TestCase::QUICK);
587 
588  // With short time-to-trigger
589  config.timeToTrigger = 64;
590  expectedTime.clear();
591  expectedTime << 864 << 984 << 1464 << 1584 << 1704 << 1824 << 1944;
592  expectedRsrp.clear();
593  expectedRsrp << 47 << 47 << 51 << 51 << 47 << 51 << 51;
595  "Piecewise test case 1 - Event A2 with short time-to-trigger",
596  config,
597  expectedTime,
598  expectedRsrp),
599  TestCase::EXTENSIVE);
600 
601  // With long time-to-trigger
602  config.timeToTrigger = 128;
603  expectedTime.clear();
604  expectedTime << 928 << 1048 << 1528 << 1648 << 1768 << 1888 << 2008;
605  expectedRsrp.clear();
606  expectedRsrp << 47 << 66 << 51 << 47 << 47 << 51 << 57;
608  "Piecewise test case 1 - Event A2 with long time-to-trigger",
609  config,
610  expectedTime,
611  expectedRsrp),
612  TestCase::TAKES_FOREVER);
613 
614  // With super time-to-trigger
615  config.timeToTrigger = 256;
616  expectedTime.clear();
617  expectedTime << 1656 << 1776 << 1896 << 2016 << 2136;
618  expectedRsrp.clear();
619  expectedRsrp << 47 << 47 << 51 << 57 << 57;
621  "Piecewise test case 1 - Event A2 with super time-to-trigger",
622  config,
623  expectedTime,
624  expectedRsrp),
625  TestCase::QUICK);
626 
627  // With hysteresis
628  config.hysteresis = 8;
629  config.timeToTrigger = 0;
630  expectedTime.clear();
631  expectedTime << 800 << 920 << 1600 << 1720 << 1840 << 1960 << 2080;
632  expectedRsrp.clear();
633  expectedRsrp << 47 << 47 << 47 << 47 << 51 << 51 << 57;
634  AddTestCase(
635  new LteUeMeasurementsPiecewiseTestCase1("Piecewise test case 1 - Event A2 with hysteresis",
636  config,
637  expectedTime,
638  expectedRsrp),
639  TestCase::EXTENSIVE);
640 
641  // With very high threshold
642  config.threshold1.range = 97;
643  config.hysteresis = 0;
644  expectedTime.clear();
645  expectedTime << 200 << 320 << 440 << 560 << 680 << 800 << 920 << 1040 << 1160 << 1280 << 1400
646  << 1520 << 1640 << 1760 << 1880 << 2000 << 2120;
647  expectedRsrp.clear();
648  expectedRsrp << 67 << 67 << 57 << 57 << 66 << 47 << 47 << 66 << 66 << 57 << 51 << 51 << 47 << 47
649  << 51 << 57 << 57;
651  "Piecewise test case 1 - Event A2 with very high threshold",
652  config,
653  expectedTime,
654  expectedRsrp),
655  TestCase::EXTENSIVE);
656 
657  /*
658  * Event A3, A4, and A5 are not tested intensively here because they depend on
659  * the existence of at least one neighbouring cell, which is not available in
660  * this configuration. Piecewise configuration #2 includes a neighbouring
661  * cell, hence more thorough tests on these events are performed there.
662  */
663 
664  expectedTime.clear();
665  expectedRsrp.clear();
666 
667  // === Event A3 (neighbour becomes offset better than PCell) ===
668 
669  config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
670  config.a3Offset = 0;
671  AddTestCase(new LteUeMeasurementsPiecewiseTestCase1("Piecewise test case 1 - Event A3",
672  config,
673  expectedTime,
674  expectedRsrp),
675  TestCase::EXTENSIVE);
676 
677  // === Event A4 (neighbour becomes better than threshold) ===
678 
679  config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
680  config.threshold1.range = 54;
681  AddTestCase(new LteUeMeasurementsPiecewiseTestCase1("Piecewise test case 1 - Event A4",
682  config,
683  expectedTime,
684  expectedRsrp),
685  TestCase::EXTENSIVE);
686 
687  // === Event A5 (PCell becomes worse than absolute threshold1 AND neighbour becomes better than
688  // another absolute threshold2) ===
689 
690  config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
691  config.threshold2.range = 58;
692  AddTestCase(new LteUeMeasurementsPiecewiseTestCase1("Piecewise test case 1 - Event A5",
693  config,
694  expectedTime,
695  expectedRsrp),
696  TestCase::EXTENSIVE);
697 
698 } // end of LteUeMeasurementsPiecewiseTestSuite1::LteUeMeasurementsPiecewiseTestSuite1
699 
705 
706 /*
707  * Test Case
708  */
709 
711  std::string name,
713  std::vector<Time> expectedTime,
714  std::vector<uint8_t> expectedRsrp)
715  : TestCase(name),
716  m_config(config),
717  m_expectedTime(expectedTime),
718  m_expectedRsrp(expectedRsrp)
719 {
720  // input sanity check
721  uint16_t size = m_expectedTime.size();
722 
723  if (size != m_expectedRsrp.size())
724  {
725  NS_FATAL_ERROR("Vectors of expected results are not of the same size");
726  }
727 
730 
731  NS_LOG_INFO(this << " name=" << name);
732 }
733 
735 {
736  NS_LOG_FUNCTION(this);
737 }
738 
739 void
741 {
742  NS_LOG_INFO(this << " " << GetName());
743 
744  Ptr<LteHelper> lteHelper = CreateObject<LteHelper>();
745  lteHelper->SetAttribute("PathlossModel", StringValue("ns3::FriisSpectrumPropagationLossModel"));
746  lteHelper->SetAttribute("UseIdealRrc", BooleanValue(true));
747 
748  // Disable Uplink Power Control
749  Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false));
750 
751  // Create Nodes: eNodeB and UE
752  NodeContainer enbNodes;
753  NodeContainer ueNodes;
754  enbNodes.Create(1);
755  ueNodes.Create(1);
756 
757  /*
758  * The topology is the following:
759  *
760  * eNodeB UE
761  * | |
762  * x ----- x --------- x --------------- x ------------------- x
763  * 100 m | 200 m | 300 m | 400 m |
764  * | | | |
765  * VeryNear Near Far VeryFar
766  */
767 
768  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
769  positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // eNodeB
770  positionAlloc->Add(Vector(100.0, 0.0, 0.0)); // UE
772  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
773  mobility.SetPositionAllocator(positionAlloc);
774  mobility.Install(enbNodes);
775  mobility.Install(ueNodes);
776  m_ueMobility = ueNodes.Get(0)->GetObject<MobilityModel>();
777 
778  // Disable layer-3 filtering
779  Config::SetDefault("ns3::LteEnbRrc::RsrpFilterCoefficient", UintegerValue(0));
780 
781  // Create Devices and install them in the Nodes (eNB and UE)
782  NetDeviceContainer enbDevs;
783  NetDeviceContainer ueDevs;
784  lteHelper->SetSchedulerType("ns3::RrFfMacScheduler");
785  lteHelper->SetSchedulerAttribute("UlCqiFilter", EnumValue(FfMacScheduler::PUSCH_UL_CQI));
786  enbDevs = lteHelper->InstallEnbDevice(enbNodes);
787  ueDevs = lteHelper->InstallUeDevice(ueNodes);
788 
789  // Setup UE measurement configuration
790  Ptr<LteEnbRrc> enbRrc = enbDevs.Get(0)->GetObject<LteEnbNetDevice>()->GetRrc();
791  m_expectedMeasId = enbRrc->AddUeMeasReportConfig(m_config).at(0);
792 
793  // Attach UE to eNodeB
794  lteHelper->Attach(ueDevs.Get(0), enbDevs.Get(0));
795 
796  // Activate an EPS bearer
797  EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
798  EpsBearer bearer(q);
799  lteHelper->ActivateDataRadioBearer(ueDevs, bearer);
800 
801  // Connect to trace sources
803  "/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
805 
806  /*
807  * Schedule "teleports"
808  * 0 1 2
809  * +-------------------+-------------------+---------> time
810  * VeryNear |------ ---- ---- --------
811  * Near | ---- ----
812  * Far | ---- ----
813  * VeryFar | -- ---- ----
814  */
815  Simulator::Schedule(MilliSeconds(301),
817  this);
818  Simulator::Schedule(MilliSeconds(401),
820  this);
821  Simulator::Schedule(MilliSeconds(601),
823  this);
824  Simulator::Schedule(MilliSeconds(801),
826  this);
827  Simulator::Schedule(MilliSeconds(1001),
829  this);
830  Simulator::Schedule(MilliSeconds(1201),
832  this);
833  Simulator::Schedule(MilliSeconds(1401),
835  this);
836  Simulator::Schedule(MilliSeconds(1601),
838  this);
839  Simulator::Schedule(MilliSeconds(1801),
841  this);
842  Simulator::Schedule(MilliSeconds(2001),
844  this);
845 
846  // Run simulation
847  Simulator::Stop(Seconds(2.201));
848  Simulator::Run();
849  Simulator::Destroy();
850 
851 } // end of void LteUeMeasurementsPiecewiseTestCase1::DoRun ()
852 
853 void
855 {
856  NS_LOG_FUNCTION(this);
857  bool hasEnded = m_itExpectedTime == m_expectedTime.end();
858  NS_TEST_ASSERT_MSG_EQ(hasEnded,
859  true,
860  "Reporting should have occurred at " << m_itExpectedTime->As(Time::S));
861  hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
862  NS_ASSERT(hasEnded);
863 }
864 
865 void
867  std::string context,
868  uint64_t imsi,
869  uint16_t cellId,
870  uint16_t rnti,
872 {
873  NS_LOG_FUNCTION(this << context);
874  NS_ASSERT(rnti == 1);
875  NS_ASSERT(cellId == 1);
876 
877  if (report.measResults.measId == m_expectedMeasId)
878  {
879  // verifying the report completeness
880  LteRrcSap::MeasResults measResults = report.measResults;
881  NS_LOG_DEBUG(
882  this << " rsrp=" << (uint16_t)measResults.measResultPCell.rsrpResult << " ("
883  << EutranMeasurementMapping::RsrpRange2Dbm(measResults.measResultPCell.rsrpResult)
884  << " dBm)"
885  << " rsrq=" << (uint16_t)measResults.measResultPCell.rsrqResult << " ("
886  << EutranMeasurementMapping::RsrqRange2Db(measResults.measResultPCell.rsrqResult)
887  << " dB)");
889  false,
890  "Report should not have neighboring cells information");
891  NS_TEST_ASSERT_MSG_EQ(measResults.measResultListEutra.size(), 0, "Unexpected report size");
892 
893  bool hasEnded = m_itExpectedTime == m_expectedTime.end();
894  NS_TEST_ASSERT_MSG_EQ(hasEnded,
895  false,
896  "Reporting should not have occurred at "
897  << Simulator::Now().As(Time::S));
898  if (!hasEnded)
899  {
900  hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
901  NS_ASSERT(!hasEnded);
902 
903  // using milliseconds to avoid floating-point comparison
904  uint64_t timeNowMs = Simulator::Now().GetMilliSeconds();
905  uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds();
907 
908  uint16_t observedRsrp = measResults.measResultPCell.rsrpResult;
909  uint16_t referenceRsrp = *m_itExpectedRsrp;
911 
912  NS_TEST_ASSERT_MSG_EQ(timeNowMs,
913  timeExpectedMs,
914  "Reporting should not have occurred at this time");
915  NS_TEST_ASSERT_MSG_EQ(observedRsrp,
916  referenceRsrp,
917  "The RSRP observed differs with the reference RSRP");
918  } // end of if (!hasEnded)
919 
920  } // end of if (measResults.measId == m_expectedMeasId)
921 
922 } // end of LteUeMeasurementsPiecewiseTestCase1::RecvMeasurementReportCallback
923 
924 void
926 {
927  NS_LOG_FUNCTION(this);
928  m_ueMobility->SetPosition(Vector(100.0, 0.0, 0.0));
929 }
930 
931 void
933 {
934  NS_LOG_FUNCTION(this);
935  m_ueMobility->SetPosition(Vector(300.0, 0.0, 0.0));
936 }
937 
938 void
940 {
941  NS_LOG_FUNCTION(this);
942  m_ueMobility->SetPosition(Vector(600.0, 0.0, 0.0));
943 }
944 
945 void
947 {
948  NS_LOG_FUNCTION(this);
949  m_ueMobility->SetPosition(Vector(1000.0, 0.0, 0.0));
950 }
951 
952 // ===== LTE-UE-MEASUREMENTS-PIECEWISE-2 TEST SUITE ======================== //
953 
954 /*
955  * Test Suite
956  */
957 
959  : TestSuite("lte-ue-measurements-piecewise-2", SYSTEM)
960 {
961  std::vector<Time> expectedTime;
962  std::vector<uint8_t> expectedRsrp;
963 
964  /*
965  * Higher level of fullness/duration are given to Event A1 and A2 because they
966  * are supposed to be more intensively tested in Piecewise configuration #1.
967  */
968 
969  // === Event A1 (serving cell becomes better than threshold) ===
970 
971  // With very low threshold
973  config.triggerType = LteRrcSap::ReportConfigEutra::EVENT;
974  config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
975  config.threshold1.choice = LteRrcSap::ThresholdEutra::THRESHOLD_RSRP;
976  config.threshold1.range = 0;
977  config.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRP;
978  config.reportInterval = LteRrcSap::ReportConfigEutra::MS240;
979  expectedTime.clear();
980  expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
981  expectedRsrp.clear();
982  expectedRsrp << 73 << 63 << 72 << 52 << 72 << 56 << 52 << 56 << 59;
984  "Piecewise test case 2 - Event A1 with very low threshold",
985  config,
986  expectedTime,
987  expectedRsrp),
988  TestCase::EXTENSIVE);
989 
990  // With normal threshold
991  config.threshold1.range = 58;
992  expectedTime.clear();
993  expectedTime << 200 << 440 << 680 << 1000 << 1240 << 2000;
994  expectedRsrp.clear();
995  expectedRsrp << 73 << 63 << 72 << 72 << 59 << 59;
997  "Piecewise test case 2 - Event A1 with normal threshold",
998  config,
999  expectedTime,
1000  expectedRsrp),
1001  TestCase::TAKES_FOREVER);
1002 
1003  // With hysteresis
1004  config.hysteresis = 6;
1005  expectedTime.clear();
1006  expectedTime << 200 << 440 << 680 << 1000 << 1240 << 1480 << 2200;
1007  expectedRsrp.clear();
1008  expectedRsrp << 73 << 63 << 72 << 72 << 59 << 56 << 72;
1009  AddTestCase(
1010  new LteUeMeasurementsPiecewiseTestCase2("Piecewise test case 2 - Event A1 with hysteresis",
1011  config,
1012  expectedTime,
1013  expectedRsrp),
1014  TestCase::EXTENSIVE);
1015 
1016  // With very high threshold
1017  config.threshold1.range = 97;
1018  config.hysteresis = 0;
1019  expectedTime.clear();
1020  expectedRsrp.clear();
1022  "Piecewise test case 2 - Event A1 with very high threshold",
1023  config,
1024  expectedTime,
1025  expectedRsrp),
1026  TestCase::TAKES_FOREVER);
1027 
1028  // === Event A2 (serving cell becomes worse than threshold) ===
1029 
1030  // With very low threshold
1031  config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
1032  config.threshold1.range = 0;
1033  expectedTime.clear();
1034  expectedRsrp.clear();
1036  "Piecewise test case 2 - Event A2 with very low threshold",
1037  config,
1038  expectedTime,
1039  expectedRsrp),
1040  TestCase::TAKES_FOREVER);
1041 
1042  // With normal threshold
1043  config.threshold1.range = 58;
1044  expectedTime.clear();
1045  expectedTime << 800 << 1400 << 1640 << 1880;
1046  expectedRsrp.clear();
1047  expectedRsrp << 52 << 56 << 52 << 56;
1049  "Piecewise test case 2 - Event A2 with normal threshold",
1050  config,
1051  expectedTime,
1052  expectedRsrp),
1053  TestCase::TAKES_FOREVER);
1054 
1055  // With hysteresis
1056  config.hysteresis = 6;
1057  expectedTime.clear();
1058  expectedTime << 800 << 1600 << 1840 << 2080;
1059  expectedRsrp.clear();
1060  expectedRsrp << 52 << 52 << 56 << 59;
1061  AddTestCase(
1062  new LteUeMeasurementsPiecewiseTestCase2("Piecewise test case 2 - Event A2 with hysteresis",
1063  config,
1064  expectedTime,
1065  expectedRsrp),
1066  TestCase::EXTENSIVE);
1067 
1068  // With very high threshold
1069  config.threshold1.range = 97;
1070  config.hysteresis = 0;
1071  expectedTime.clear();
1072  expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
1073  expectedRsrp.clear();
1074  expectedRsrp << 73 << 63 << 72 << 52 << 72 << 56 << 52 << 56 << 59;
1076  "Piecewise test case 2 - Event A2 with very high threshold",
1077  config,
1078  expectedTime,
1079  expectedRsrp),
1080  TestCase::TAKES_FOREVER);
1081 
1082  // === Event A3 (neighbour becomes offset better than PCell) ===
1083 
1084  // With positive offset
1085  config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
1086  config.threshold1.range = 0;
1087  config.a3Offset = 7;
1088  expectedTime.clear();
1089  expectedTime << 800 << 1600;
1090  expectedRsrp.clear();
1091  expectedRsrp << 52 << 52;
1093  "Piecewise test case 2 - Event A3 with positive offset",
1094  config,
1095  expectedTime,
1096  expectedRsrp),
1097  TestCase::QUICK);
1098 
1099  // With zero offset
1100  config.a3Offset = 0;
1101  expectedTime.clear();
1102  expectedTime << 800 << 1400 << 1640 << 1880;
1103  expectedRsrp.clear();
1104  expectedRsrp << 52 << 56 << 52 << 56;
1105  AddTestCase(
1106  new LteUeMeasurementsPiecewiseTestCase2("Piecewise test case 2 - Event A3 with zero offset",
1107  config,
1108  expectedTime,
1109  expectedRsrp),
1110  TestCase::EXTENSIVE);
1111 
1112  // With short time-to-trigger
1113  config.timeToTrigger = 160;
1114  expectedTime.clear();
1115  expectedTime << 960 << 1560 << 1800 << 2040;
1116  expectedRsrp.clear();
1117  expectedRsrp << 52 << 56 << 56 << 59;
1119  "Piecewise test case 2 - Event A3 with short time-to-trigger",
1120  config,
1121  expectedTime,
1122  expectedRsrp),
1123  TestCase::EXTENSIVE);
1124 
1125  // With super time-to-trigger
1126  config.timeToTrigger = 320;
1127  expectedTime.clear();
1128  expectedTime << 1720 << 1960 << 2200;
1129  expectedRsrp.clear();
1130  expectedRsrp << 52 << 56 << 72;
1132  "Piecewise test case 2 - Event A3 with super time-to-trigger",
1133  config,
1134  expectedTime,
1135  expectedRsrp),
1136  TestCase::QUICK);
1137 
1138  // With hysteresis and reportOnLeave
1139  config.hysteresis = 6;
1140  config.reportOnLeave = true;
1141  config.timeToTrigger = 0;
1142  expectedTime.clear();
1143  expectedTime << 800 << 1000 << 1600 << 1840 << 2080 << 2200;
1144  expectedRsrp.clear();
1145  expectedRsrp << 52 << 72 << 52 << 56 << 59 << 72;
1146  AddTestCase(
1147  new LteUeMeasurementsPiecewiseTestCase2("Piecewise test case 2 - Event A3 with hysteresis",
1148  config,
1149  expectedTime,
1150  expectedRsrp),
1151  TestCase::QUICK);
1152 
1153  // With negative offset
1154  config.a3Offset = -7;
1155  config.hysteresis = 0;
1156  config.reportOnLeave = false;
1157  expectedTime.clear();
1158  expectedTime << 400 << 800 << 1200 << 1440 << 1680 << 1920 << 2160;
1159  expectedRsrp.clear();
1160  expectedRsrp << 63 << 52 << 59 << 56 << 52 << 56 << 59;
1162  "Piecewise test case 2 - Event A3 with negative offset",
1163  config,
1164  expectedTime,
1165  expectedRsrp),
1166  TestCase::EXTENSIVE);
1167 
1168  // === Event A4 (neighbour becomes better than threshold) ===
1169 
1170  // With very low threshold
1171  config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
1172  config.threshold1.range = 0;
1173  config.a3Offset = 0;
1174  expectedTime.clear();
1175  expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
1176  expectedRsrp.clear();
1177  expectedRsrp << 73 << 63 << 72 << 52 << 72 << 56 << 52 << 56 << 59;
1179  "Piecewise test case 2 - Event A4 with very low threshold",
1180  config,
1181  expectedTime,
1182  expectedRsrp),
1183  TestCase::QUICK);
1184 
1185  // With normal threshold
1186  config.threshold1.range = 58;
1187  expectedTime.clear();
1188  expectedTime << 400 << 800 << 1400 << 1640 << 1880;
1189  expectedRsrp.clear();
1190  expectedRsrp << 63 << 52 << 56 << 52 << 56;
1192  "Piecewise test case 2 - Event A4 with normal threshold",
1193  config,
1194  expectedTime,
1195  expectedRsrp),
1196  TestCase::EXTENSIVE);
1197 
1198  // With short time-to-trigger
1199  config.timeToTrigger = 160;
1200  expectedTime.clear();
1201  expectedTime << 560 << 960 << 1560 << 1800 << 2040;
1202  expectedRsrp.clear();
1203  expectedRsrp << 63 << 52 << 56 << 56 << 59;
1205  "Piecewise test case 2 - Event A4 with short time-to-trigger",
1206  config,
1207  expectedTime,
1208  expectedRsrp),
1209  TestCase::QUICK);
1210 
1211  // With super time-to-trigger
1212  config.timeToTrigger = 320;
1213  expectedTime.clear();
1214  expectedTime << 1720 << 1960 << 2200;
1215  expectedRsrp.clear();
1216  expectedRsrp << 52 << 56 << 72;
1218  "Piecewise test case 2 - Event A4 with super time-to-trigger",
1219  config,
1220  expectedTime,
1221  expectedRsrp),
1222  TestCase::TAKES_FOREVER);
1223 
1224  // With hysteresis
1225  config.hysteresis = 6;
1226  config.timeToTrigger = 0;
1227  expectedTime.clear();
1228  expectedTime << 400 << 800 << 1600 << 1840 << 2080;
1229  expectedRsrp.clear();
1230  expectedRsrp << 63 << 52 << 52 << 56 << 59;
1231  AddTestCase(
1232  new LteUeMeasurementsPiecewiseTestCase2("Piecewise test case 2 - Event A4 with hysteresis",
1233  config,
1234  expectedTime,
1235  expectedRsrp),
1236  TestCase::QUICK);
1237 
1238  // With very high threshold
1239  config.threshold1.range = 97;
1240  config.hysteresis = 0;
1241  expectedTime.clear();
1242  expectedRsrp.clear();
1244  "Piecewise test case 2 - Event A4 with very high threshold",
1245  config,
1246  expectedTime,
1247  expectedRsrp),
1248  TestCase::TAKES_FOREVER);
1249 
1250  // === Event A5 (PCell becomes worse than absolute threshold1 AND neighbour becomes better than
1251  // another absolute threshold2) ===
1252 
1253  // With low-low threshold
1254  config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
1255  config.threshold1.range = 0;
1256  config.threshold2.range = 0;
1257  expectedTime.clear();
1258  expectedRsrp.clear();
1260  "Piecewise test case 2 - Event A5 with low-low threshold",
1261  config,
1262  expectedTime,
1263  expectedRsrp),
1264  TestCase::EXTENSIVE);
1265 
1266  // With low-normal threshold
1267  config.threshold2.range = 58;
1269  "Piecewise test case 2 - Event A5 with low-normal threshold",
1270  config,
1271  expectedTime,
1272  expectedRsrp),
1273  TestCase::TAKES_FOREVER);
1274 
1275  // With low-high threshold
1276  config.threshold2.range = 97;
1278  "Piecewise test case 2 - Event A5 with low-high threshold",
1279  config,
1280  expectedTime,
1281  expectedRsrp),
1282  TestCase::TAKES_FOREVER);
1283 
1284  // With normal-low threshold
1285  config.threshold1.range = 58;
1286  config.threshold2.range = 0;
1287  expectedTime.clear();
1288  expectedTime << 800 << 1400 << 1640 << 1880;
1289  expectedRsrp.clear();
1290  expectedRsrp << 52 << 56 << 52 << 56;
1292  "Piecewise test case 2 - Event A5 with normal-low threshold",
1293  config,
1294  expectedTime,
1295  expectedRsrp),
1296  TestCase::EXTENSIVE);
1297 
1298  // With normal-normal threshold
1299  config.threshold2.range = 58;
1300  expectedTime.clear();
1301  expectedTime << 800 << 1400 << 1640 << 1880;
1302  expectedRsrp.clear();
1303  expectedRsrp << 52 << 56 << 52 << 56;
1305  "Piecewise test case 2 - Event A5 with normal-normal threshold",
1306  config,
1307  expectedTime,
1308  expectedRsrp),
1309  TestCase::EXTENSIVE);
1310 
1311  // With short time-to-trigger
1312  config.timeToTrigger = 160;
1313  expectedTime.clear();
1314  expectedTime << 960 << 1560 << 1800 << 2040;
1315  expectedRsrp.clear();
1316  expectedRsrp << 52 << 56 << 56 << 59;
1318  "Piecewise test case 2 - Event A5 with short time-to-trigger",
1319  config,
1320  expectedTime,
1321  expectedRsrp),
1322  TestCase::TAKES_FOREVER);
1323 
1324  // With super time-to-trigger
1325  config.timeToTrigger = 320;
1326  expectedTime.clear();
1327  expectedTime << 1720 << 1960 << 2200;
1328  expectedRsrp.clear();
1329  expectedRsrp << 52 << 56 << 72;
1331  "Piecewise test case 2 - Event A5 with super time-to-trigger",
1332  config,
1333  expectedTime,
1334  expectedRsrp),
1335  TestCase::QUICK);
1336 
1337  // With hysteresis
1338  config.hysteresis = 6;
1339  config.timeToTrigger = 0;
1340  expectedTime.clear();
1341  expectedTime << 800 << 1600 << 1840 << 2080;
1342  expectedRsrp.clear();
1343  expectedRsrp << 52 << 52 << 56 << 59;
1344  AddTestCase(
1345  new LteUeMeasurementsPiecewiseTestCase2("Piecewise test case 2 - Event A5 with hysteresis",
1346  config,
1347  expectedTime,
1348  expectedRsrp),
1349  TestCase::QUICK);
1350 
1351  // With normal-high threshold
1352  config.threshold2.range = 97;
1353  config.hysteresis = 0;
1354  expectedTime.clear();
1355  expectedRsrp.clear();
1357  "Piecewise test case 2 - Event A5 with normal-high threshold",
1358  config,
1359  expectedTime,
1360  expectedRsrp),
1361  TestCase::TAKES_FOREVER);
1362 
1363  // With high-low threshold
1364  config.threshold1.range = 97;
1365  config.threshold2.range = 0;
1366  expectedTime.clear();
1367  expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
1368  expectedRsrp.clear();
1369  expectedRsrp << 73 << 63 << 72 << 52 << 72 << 56 << 52 << 56 << 59;
1371  "Piecewise test case 2 - Event A5 with high-low threshold",
1372  config,
1373  expectedTime,
1374  expectedRsrp),
1375  TestCase::EXTENSIVE);
1376 
1377  // With high-normal threshold
1378  config.threshold2.range = 58;
1379  expectedTime.clear();
1380  expectedTime << 400 << 800 << 1400 << 1640 << 1880;
1381  expectedRsrp.clear();
1382  expectedRsrp << 63 << 52 << 56 << 52 << 56;
1384  "Piecewise test case 2 - Event A5 with high-normal threshold",
1385  config,
1386  expectedTime,
1387  expectedRsrp),
1388  TestCase::TAKES_FOREVER);
1389 
1390  // With high-high threshold
1391  config.threshold2.range = 97;
1392  expectedTime.clear();
1393  expectedRsrp.clear();
1395  "Piecewise test case 2 - Event A5 with high-high threshold",
1396  config,
1397  expectedTime,
1398  expectedRsrp),
1399  TestCase::EXTENSIVE);
1400 
1401 } // end of LteUeMeasurementsPiecewiseTestSuite2::LteUeMeasurementsPiecewiseTestSuite2
1402 
1408 
1409 /*
1410  * Test Case
1411  */
1412 
1414  std::string name,
1416  std::vector<Time> expectedTime,
1417  std::vector<uint8_t> expectedRsrp)
1418  : TestCase(name),
1419  m_config(config),
1420  m_expectedTime(expectedTime),
1421  m_expectedRsrp(expectedRsrp)
1422 {
1423  // input sanity check
1424  uint16_t size = m_expectedTime.size();
1425 
1426  if (size != m_expectedRsrp.size())
1427  {
1428  NS_FATAL_ERROR("Vectors of expected results are not of the same size");
1429  }
1430 
1431  m_itExpectedTime = m_expectedTime.begin();
1432  m_itExpectedRsrp = m_expectedRsrp.begin();
1433 
1434  NS_LOG_INFO(this << " name=" << name);
1435 }
1436 
1438 {
1439  NS_LOG_FUNCTION(this);
1440 }
1441 
1442 void
1444 {
1445  NS_LOG_INFO(this << " " << GetName());
1446 
1447  Ptr<LteHelper> lteHelper = CreateObject<LteHelper>();
1448  lteHelper->SetAttribute("PathlossModel", StringValue("ns3::FriisSpectrumPropagationLossModel"));
1449  lteHelper->SetAttribute("UseIdealRrc", BooleanValue(true));
1450 
1451  // Disable Uplink Power Control
1452  Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false));
1453 
1454  // Create Nodes: eNodeB and UE
1455  NodeContainer enbNodes;
1456  NodeContainer ueNodes;
1457  enbNodes.Create(2);
1458  ueNodes.Create(1);
1459 
1460  /*
1461  * The topology is the following:
1462  *
1463  * eNodeB UE eNodeB
1464  * | | |
1465  * x ---- x --------------- x ------- x --------------- x ---- x
1466  * 50 m | 200 m | 100 m | 200 m | 50 m
1467  * | | | |
1468  * VeryNear Near Far VeryFar
1469  */
1470 
1471  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
1472  positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // Serving eNodeB
1473  positionAlloc->Add(Vector(600.0, 0.0, 0.0)); // Neighbour eNodeB
1474  positionAlloc->Add(Vector(50.0, 0.0, 0.0)); // UE
1476  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
1477  mobility.SetPositionAllocator(positionAlloc);
1478  mobility.Install(enbNodes);
1479  mobility.Install(ueNodes);
1480  m_ueMobility = ueNodes.Get(0)->GetObject<MobilityModel>();
1481 
1482  // Disable layer-3 filtering
1483  Config::SetDefault("ns3::LteEnbRrc::RsrpFilterCoefficient", UintegerValue(0));
1484 
1485  // Create Devices and install them in the Nodes (eNB and UE)
1486  NetDeviceContainer enbDevs;
1487  NetDeviceContainer ueDevs;
1488  lteHelper->SetSchedulerType("ns3::RrFfMacScheduler");
1489  lteHelper->SetSchedulerAttribute("UlCqiFilter", EnumValue(FfMacScheduler::PUSCH_UL_CQI));
1490  enbDevs = lteHelper->InstallEnbDevice(enbNodes);
1491  ueDevs = lteHelper->InstallUeDevice(ueNodes);
1492 
1493  // Setup UE measurement configuration in serving cell
1494  Ptr<LteEnbRrc> enbRrc1 = enbDevs.Get(0)->GetObject<LteEnbNetDevice>()->GetRrc();
1495  m_expectedMeasId = enbRrc1->AddUeMeasReportConfig(m_config).at(0);
1496 
1497  // Disable handover in neighbour cell
1498  Ptr<LteEnbRrc> enbRrc2 = enbDevs.Get(1)->GetObject<LteEnbNetDevice>()->GetRrc();
1499  enbRrc2->SetAttribute("AdmitHandoverRequest", BooleanValue(false));
1500 
1501  // Attach UE to serving eNodeB
1502  lteHelper->Attach(ueDevs.Get(0), enbDevs.Get(0));
1503 
1504  // Activate an EPS bearer
1505  EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
1506  EpsBearer bearer(q);
1507  lteHelper->ActivateDataRadioBearer(ueDevs, bearer);
1508 
1509  // Connect to trace sources in serving eNodeB
1511  "/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
1513 
1514  /*
1515  * Schedule "teleports"
1516  * 0 1 2
1517  * +-------------------+-------------------+---------> time
1518  * VeryNear |------ ---- ---- --------
1519  * Near | ---- ----
1520  * Far | ---- ----
1521  * VeryFar | -- ---- ----
1522  */
1523  Simulator::Schedule(MilliSeconds(301),
1525  this);
1526  Simulator::Schedule(MilliSeconds(401),
1528  this);
1529  Simulator::Schedule(MilliSeconds(601),
1531  this);
1532  Simulator::Schedule(MilliSeconds(801),
1534  this);
1535  Simulator::Schedule(MilliSeconds(1001),
1537  this);
1538  Simulator::Schedule(MilliSeconds(1201),
1540  this);
1541  Simulator::Schedule(MilliSeconds(1401),
1543  this);
1544  Simulator::Schedule(MilliSeconds(1601),
1546  this);
1547  Simulator::Schedule(MilliSeconds(1801),
1549  this);
1550  Simulator::Schedule(MilliSeconds(2001),
1552  this);
1553 
1554  // Run simulation
1555  Simulator::Stop(Seconds(2.201));
1556  Simulator::Run();
1557  Simulator::Destroy();
1558 
1559 } // end of void LteUeMeasurementsPiecewiseTestCase2::DoRun ()
1560 
1561 void
1563 {
1564  NS_LOG_FUNCTION(this);
1565  bool hasEnded = m_itExpectedTime == m_expectedTime.end();
1566  NS_TEST_ASSERT_MSG_EQ(hasEnded,
1567  true,
1568  "Reporting should have occurred at " << m_itExpectedTime->As(Time::S));
1569  hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
1570  NS_ASSERT(hasEnded);
1571 }
1572 
1573 void
1575  std::string context,
1576  uint64_t imsi,
1577  uint16_t cellId,
1578  uint16_t rnti,
1580 {
1581  NS_LOG_FUNCTION(this << context);
1582  NS_ASSERT(rnti == 1);
1583  NS_ASSERT(cellId == 1);
1584 
1585  if (report.measResults.measId == m_expectedMeasId)
1586  {
1587  // verifying the report completeness
1588  LteRrcSap::MeasResults measResults = report.measResults;
1589  NS_LOG_DEBUG(
1590  this << " Serving cellId=" << cellId
1591  << " rsrp=" << (uint16_t)measResults.measResultPCell.rsrpResult << " ("
1592  << EutranMeasurementMapping::RsrpRange2Dbm(measResults.measResultPCell.rsrpResult)
1593  << " dBm)"
1594  << " rsrq=" << (uint16_t)measResults.measResultPCell.rsrqResult << " ("
1595  << EutranMeasurementMapping::RsrqRange2Db(measResults.measResultPCell.rsrqResult)
1596  << " dB)");
1597 
1598  // verifying reported best cells
1599  if (measResults.measResultListEutra.empty())
1600  {
1602  false,
1603  "Unexpected report content");
1604  }
1605  else
1606  {
1608  true,
1609  "Unexpected report content");
1610  auto it = measResults.measResultListEutra.begin();
1611  NS_ASSERT(it != measResults.measResultListEutra.end());
1612  NS_ASSERT(it->physCellId == 2);
1613  NS_TEST_ASSERT_MSG_EQ(it->haveCgiInfo,
1614  false,
1615  "Report contains cgi-info, which is not supported");
1616  NS_TEST_ASSERT_MSG_EQ(it->haveRsrpResult,
1617  true,
1618  "Report does not contain measured RSRP result");
1619  NS_TEST_ASSERT_MSG_EQ(it->haveRsrqResult,
1620  true,
1621  "Report does not contain measured RSRQ result");
1622  NS_LOG_DEBUG(this << " Neighbour cellId=" << it->physCellId
1623  << " rsrp=" << (uint16_t)it->rsrpResult << " ("
1624  << EutranMeasurementMapping::RsrpRange2Dbm(it->rsrpResult) << " dBm)"
1625  << " rsrq=" << (uint16_t)it->rsrqResult << " ("
1626  << EutranMeasurementMapping::RsrqRange2Db(it->rsrqResult) << " dB)");
1627 
1628  } // end of else of if (measResults.measResultListEutra.size () == 0)
1629 
1630  // verifying the report timing
1631  bool hasEnded = m_itExpectedTime == m_expectedTime.end();
1632  NS_TEST_ASSERT_MSG_EQ(hasEnded,
1633  false,
1634  "Reporting should not have occurred at "
1635  << Simulator::Now().As(Time::S));
1636  if (!hasEnded)
1637  {
1638  hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
1639  NS_ASSERT(!hasEnded);
1640 
1641  // using milliseconds to avoid floating-point comparison
1642  uint64_t timeNowMs = Simulator::Now().GetMilliSeconds();
1643  uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds();
1644  m_itExpectedTime++;
1645 
1646  uint16_t observedRsrp = measResults.measResultPCell.rsrpResult;
1647  uint16_t referenceRsrp = *m_itExpectedRsrp;
1648  m_itExpectedRsrp++;
1649 
1650  NS_TEST_ASSERT_MSG_EQ(timeNowMs,
1651  timeExpectedMs,
1652  "Reporting should not have occurred at this time");
1653  NS_TEST_ASSERT_MSG_EQ(observedRsrp,
1654  referenceRsrp,
1655  "The RSRP observed differs with the reference RSRP");
1656 
1657  } // end of if (!hasEnded)
1658 
1659  } // end of if (report.measResults.measId == m_expectedMeasId)
1660 
1661 } // end of void LteUeMeasurementsPiecewiseTestCase2::RecvMeasurementReportCallback
1662 
1663 void
1665 {
1666  NS_LOG_FUNCTION(this);
1667  m_ueMobility->SetPosition(Vector(50.0, 0.0, 0.0));
1668 }
1669 
1670 void
1672 {
1673  NS_LOG_FUNCTION(this);
1674  m_ueMobility->SetPosition(Vector(250.0, 0.0, 0.0));
1675 }
1676 
1677 void
1679 {
1680  NS_LOG_FUNCTION(this);
1681  m_ueMobility->SetPosition(Vector(350.0, 0.0, 0.0));
1682 }
1683 
1684 void
1686 {
1687  NS_LOG_FUNCTION(this);
1688  m_ueMobility->SetPosition(Vector(550.0, 0.0, 0.0));
1689 }
1690 
1691 // ===== LTE-UE-MEASUREMENTS-PIECEWISE-3 TEST SUITE ======================== //
1692 
1693 /*
1694  * Test Suite
1695  */
1696 
1698  : TestSuite("lte-ue-measurements-piecewise-3", SYSTEM)
1699 {
1700  std::vector<Time> expectedTime;
1701 
1702  // === Event A4 (neighbor becomes better than threshold) ===
1703 
1704  // The threshold value was chosen to achieve the following:
1705  // 1. Neighbor 1 (eNB2) RSRP would be above the chosen threshold, hence,
1706  // the UE will include it in its reports to its eNB (eNB1) from the beginning
1707  // of the simulation.
1708  // 2. When neighbor 2 (eNB3) is placed at a very far position, its RSRP would
1709  // be less than the chosen threshold, hence, UE will not include it in its
1710  // initial report(s) to its eNB.
1711  // 3. When neighbor 2 (eNB3) is placed at a near position, its RSRP would
1712  // always be above the chosen threshold, hence, the UE will include it in its
1713  // reports to its eNB (eNB1).
1715  config.triggerType = LteRrcSap::ReportConfigEutra::EVENT;
1716  config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
1717  config.threshold1.choice = LteRrcSap::ThresholdEutra::THRESHOLD_RSRP;
1718  config.threshold1.range = 6;
1719  config.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRP;
1720  config.reportInterval = LteRrcSap::ReportConfigEutra::MS240;
1721  expectedTime.clear();
1722  expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
1723 
1724  AddTestCase(new LteUeMeasurementsPiecewiseTestCase3("Piecewise test case 3 - Event A4",
1725  config,
1726  expectedTime),
1727  TestCase::QUICK);
1728 } // end of LteUeMeasurementsPiecewiseTestSuite3::LteUeMeasurementsPiecewiseTestSuite3
1729 
1735 
1736 /*
1737  * Test Case
1738  */
1739 
1741  std::string name,
1743  std::vector<Time> expectedTime)
1744  : TestCase(name),
1745  m_config(config),
1746  m_expectedTime(expectedTime)
1747 {
1749 
1750  m_itExpectedTime = m_expectedTime.begin();
1751 
1752  NS_LOG_INFO(this << " name=" << name);
1753 }
1754 
1756 {
1757  NS_LOG_FUNCTION(this);
1758 }
1759 
1760 void
1762 {
1763  NS_LOG_INFO(this << " " << GetName());
1764 
1765  Ptr<LteHelper> lteHelper = CreateObject<LteHelper>();
1766  lteHelper->SetAttribute("PathlossModel", StringValue("ns3::FriisSpectrumPropagationLossModel"));
1767  lteHelper->SetAttribute("UseIdealRrc", BooleanValue(true));
1768 
1769  // Disable Uplink Power Control
1770  Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false));
1771 
1772  // Create Nodes: eNodeB and UE
1773  NodeContainer enbNodes;
1774  NodeContainer ueNodes;
1775  enbNodes.Create(3);
1776  ueNodes.Create(1);
1777 
1778  /*
1779  * The topology is the following:
1780  *
1781  * We place the 3rd eNB initially very far so it does not fulfills
1782  * the entry condition to be reported.
1783  *
1784  * eNodeB UE eNodeB eNodeB
1785  * | | | |
1786  * x ---- x --------------- x -------------- x ---------------------x
1787  * 50 m 100 m 500 | 1000000
1788  * Near
1789  */
1790 
1791  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
1792  positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // Serving eNodeB
1793  positionAlloc->Add(Vector(200.0, 0.0, 0.0)); // Neighbour eNodeB1
1794  positionAlloc->Add(Vector(1000700.0, 0.0, 0.0)); // Neighbour eNodeB2
1795  positionAlloc->Add(Vector(50.0, 0.0, 0.0)); // UE
1797  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
1798  mobility.SetPositionAllocator(positionAlloc);
1799  mobility.Install(enbNodes);
1800  mobility.Install(ueNodes);
1801  m_enbMobility = enbNodes.Get(2)->GetObject<MobilityModel>();
1802 
1803  // Disable layer-3 filtering
1804  Config::SetDefault("ns3::LteEnbRrc::RsrpFilterCoefficient", UintegerValue(0));
1805 
1806  // Create Devices and install them in the Nodes (eNB and UE)
1807  NetDeviceContainer enbDevs;
1808  NetDeviceContainer ueDevs;
1809  lteHelper->SetSchedulerType("ns3::RrFfMacScheduler");
1810  lteHelper->SetSchedulerAttribute("UlCqiFilter", EnumValue(FfMacScheduler::PUSCH_UL_CQI));
1811  enbDevs = lteHelper->InstallEnbDevice(enbNodes);
1812  ueDevs = lteHelper->InstallUeDevice(ueNodes);
1813 
1814  // Setup UE measurement configuration in serving cell
1815  Ptr<LteEnbRrc> enbRrc1 = enbDevs.Get(0)->GetObject<LteEnbNetDevice>()->GetRrc();
1816  m_expectedMeasId = enbRrc1->AddUeMeasReportConfig(m_config).at(0);
1817 
1818  // Disable handover in neighbour cells
1819  Ptr<LteEnbRrc> enbRrc2 = enbDevs.Get(1)->GetObject<LteEnbNetDevice>()->GetRrc();
1820  enbRrc2->SetAttribute("AdmitHandoverRequest", BooleanValue(false));
1821  Ptr<LteEnbRrc> enbRrc3 = enbDevs.Get(2)->GetObject<LteEnbNetDevice>()->GetRrc();
1822  enbRrc3->SetAttribute("AdmitHandoverRequest", BooleanValue(false));
1823 
1824  // Attach UE to serving eNodeB
1825  lteHelper->Attach(ueDevs.Get(0), enbDevs.Get(0));
1826 
1827  // Activate an EPS bearer
1828  EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
1829  EpsBearer bearer(q);
1830  lteHelper->ActivateDataRadioBearer(ueDevs, bearer);
1831 
1832  // Connect to trace sources in serving eNodeB
1834  "/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
1836  /*
1837  * Schedule "teleport" for the 2nd neighbour
1838  *
1839  * We bring the 2nd neighbour near once the UE has already scheduled the periodic
1840  * reporting after detecting the 1st neighbour, which ideally should be at
1841  * 200 ms.
1842  */
1843  Simulator::Schedule(MilliSeconds(301),
1845  this);
1846 
1847  // Run simulation
1848  Simulator::Stop(Seconds(2.201));
1849  Simulator::Run();
1850  Simulator::Destroy();
1851 
1852 } // end of void LteUeMeasurementsPiecewiseTestCase3::DoRun ()
1853 
1854 void
1856 {
1857  NS_LOG_FUNCTION(this);
1858  bool hasEnded = m_itExpectedTime == m_expectedTime.end();
1859  NS_TEST_ASSERT_MSG_EQ(hasEnded,
1860  true,
1861  "Reporting should have occurred at " << m_itExpectedTime->GetSeconds()
1862  << "s");
1863 }
1864 
1865 void
1867  std::string context,
1868  uint64_t imsi,
1869  uint16_t cellId,
1870  uint16_t rnti,
1872 {
1873  NS_LOG_FUNCTION(this << context);
1874  NS_ASSERT(rnti == 1);
1875  NS_ASSERT(cellId == 1);
1876 
1877  if (report.measResults.measId == m_expectedMeasId)
1878  {
1879  // verifying the report completeness
1880  LteRrcSap::MeasResults measResults = report.measResults;
1881  NS_LOG_DEBUG(
1882  this << " Serving cellId=" << cellId
1883  << " rsrp=" << (uint16_t)measResults.measResultPCell.rsrpResult << " ("
1884  << EutranMeasurementMapping::RsrpRange2Dbm(measResults.measResultPCell.rsrpResult)
1885  << " dBm)"
1886  << " rsrq=" << (uint16_t)measResults.measResultPCell.rsrqResult << " ("
1887  << EutranMeasurementMapping::RsrqRange2Db(measResults.measResultPCell.rsrqResult)
1888  << " dB)");
1889 
1890  // verifying reported best cells
1891  if (measResults.measResultListEutra.empty())
1892  {
1894  false,
1895  "Unexpected report content");
1896  }
1897  else
1898  {
1900  true,
1901  "Unexpected report content");
1902  auto it = measResults.measResultListEutra.begin();
1903  NS_ASSERT(it != measResults.measResultListEutra.end());
1904  for (const auto& it : measResults.measResultListEutra)
1905  {
1906  NS_ASSERT(it.physCellId == 2 || it.physCellId == 3);
1907  NS_TEST_ASSERT_MSG_EQ(it.haveCgiInfo,
1908  false,
1909  "Report contains cgi-info, which is not supported");
1910  NS_TEST_ASSERT_MSG_EQ(it.haveRsrpResult,
1911  true,
1912  "Report does not contain measured RSRP result");
1913  NS_TEST_ASSERT_MSG_EQ(it.haveRsrqResult,
1914  true,
1915  "Report does not contain measured RSRQ result");
1916  NS_LOG_DEBUG(
1917  this << " Neighbour cellId=" << it.physCellId
1918  << " rsrp=" << (uint16_t)it.rsrpResult << " ("
1919  << EutranMeasurementMapping::RsrpRange2Dbm(it.rsrpResult) << " dBm)"
1920  << " rsrq=" << (uint16_t)it.rsrqResult << " ("
1921  << EutranMeasurementMapping::RsrqRange2Db(it.rsrqResult) << " dB)");
1922  }
1923 
1924  } // end of else of if (measResults.measResultListEutra.size () == 0)
1925 
1926  // verifying the report timing
1927  bool hasEnded = m_itExpectedTime == m_expectedTime.end();
1928  NS_TEST_ASSERT_MSG_EQ(hasEnded,
1929  false,
1930  "Reporting should not have occurred at "
1931  << Simulator::Now().GetSeconds() << "s");
1932  if (!hasEnded)
1933  {
1934  // using milliseconds to avoid floating-point comparison
1935  uint64_t timeNowMs = Simulator::Now().GetMilliSeconds();
1936  uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds();
1937  m_itExpectedTime++;
1938 
1939  NS_TEST_ASSERT_MSG_EQ(timeNowMs,
1940  timeExpectedMs,
1941  "Reporting should not have occurred at this time");
1942 
1943  } // end of if (!hasEnded)
1944 
1945  } // end of if (report.measResults.measId == m_expectedMeasId)
1946 
1947 } // end of void LteUeMeasurementsPiecewiseTestCase3::RecvMeasurementReportCallback
1948 
1949 void
1951 {
1952  NS_LOG_FUNCTION(this);
1953  m_enbMobility->SetPosition(Vector(700.0, 0.0, 0.0));
1954 }
1955 
1956 // ===== LTE-UE-MEASUREMENTS-HANDOVER TEST SUITE =========================== //
1957 
1958 /*
1959  * Test Suite
1960  */
1961 
1963  : TestSuite("lte-ue-measurements-handover", SYSTEM)
1964 {
1965  std::list<LteRrcSap::ReportConfigEutra> sourceConfigList;
1966  std::list<LteRrcSap::ReportConfigEutra> targetConfigList;
1967  std::vector<Time> expectedTime;
1968  std::vector<uint8_t> expectedRsrp;
1969 
1970  LteRrcSap::ReportConfigEutra sourceConfig;
1971  sourceConfig.triggerType = LteRrcSap::ReportConfigEutra::EVENT;
1972  sourceConfig.eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
1973  sourceConfig.threshold1.choice = LteRrcSap::ThresholdEutra::THRESHOLD_RSRP;
1974  sourceConfig.threshold1.range = 0;
1975  sourceConfig.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRP;
1976  sourceConfig.reportInterval = LteRrcSap::ReportConfigEutra::MS240;
1977  sourceConfigList.push_back(sourceConfig);
1978 
1979  LteRrcSap::ReportConfigEutra targetConfig;
1980  targetConfig.triggerType = LteRrcSap::ReportConfigEutra::EVENT;
1981  targetConfig.eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
1982  targetConfig.threshold1.choice = LteRrcSap::ThresholdEutra::THRESHOLD_RSRP;
1983  targetConfig.threshold1.range = 0;
1984  targetConfig.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRP;
1985  targetConfig.reportInterval = LteRrcSap::ReportConfigEutra::MS240;
1986  targetConfigList.push_back(targetConfig);
1987 
1988  // === Report interval difference ===
1989 
1990  // decreasing report interval
1991  sourceConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS480;
1992  targetConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS240;
1993  expectedTime.clear();
1994  expectedTime << 200 << 680 << 1200 << 1440 << 1680 << 1920;
1995  expectedRsrp.clear();
1996  expectedRsrp << 55 << 55 << 53 << 53 << 53 << 53;
1997  AddTestCase(
1998  new LteUeMeasurementsHandoverTestCase("Handover test case - decreasing report interval",
1999  sourceConfigList,
2000  targetConfigList,
2001  expectedTime,
2002  expectedRsrp,
2003  Seconds(2)),
2004  TestCase::TAKES_FOREVER);
2005 
2006  // increasing report interval
2007  sourceConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS120;
2008  targetConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS640;
2009  expectedTime.clear();
2010  expectedTime << 200 << 320 << 440 << 560 << 680 << 800 << 920 << 1200 << 1840;
2011  expectedRsrp.clear();
2012  expectedRsrp << 55 << 55 << 55 << 55 << 55 << 55 << 55 << 53 << 53;
2013  AddTestCase(
2014  new LteUeMeasurementsHandoverTestCase("Handover test case - increasing report interval",
2015  sourceConfigList,
2016  targetConfigList,
2017  expectedTime,
2018  expectedRsrp,
2019  Seconds(2)),
2020  TestCase::QUICK);
2021 
2022  // === Event difference ===
2023 
2024  sourceConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS240;
2025  targetConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS240;
2026  sourceConfigList.front().threshold1.range = 54;
2027  sourceConfigList.front().threshold2.range = 54;
2028  sourceConfigList.front().a3Offset = 1;
2029  targetConfigList.front().threshold1.range = 54;
2030  targetConfigList.front().threshold2.range = 54;
2031  targetConfigList.front().a3Offset = 1;
2032 
2033  // Event A1 to Event A2
2034  sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2035  targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2036  expectedTime.clear();
2037  expectedTime << 200 << 440 << 680 << 920 << 1200 << 1440 << 1680 << 1920;
2038  expectedRsrp.clear();
2039  expectedRsrp << 55 << 55 << 55 << 55 << 53 << 53 << 53 << 53;
2040  AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A1 to Event A2",
2041  sourceConfigList,
2042  targetConfigList,
2043  expectedTime,
2044  expectedRsrp,
2045  Seconds(2)),
2046  TestCase::EXTENSIVE);
2047 
2048  // Event A2 to Event A1
2049  sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2050  targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2051  expectedTime.clear();
2052  expectedRsrp.clear();
2053  AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A2 to Event A1",
2054  sourceConfigList,
2055  targetConfigList,
2056  expectedTime,
2057  expectedRsrp,
2058  Seconds(2)),
2059  TestCase::TAKES_FOREVER);
2060 
2061  // Event A3 to Event A4
2062  sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2063  targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2064  expectedTime.clear();
2065  expectedTime << 1200 << 1440 << 1680 << 1920;
2066  expectedRsrp.clear();
2067  expectedRsrp << 53 << 53 << 53 << 53;
2068  AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A3 to Event A4",
2069  sourceConfigList,
2070  targetConfigList,
2071  expectedTime,
2072  expectedRsrp,
2073  Seconds(2)),
2074  TestCase::TAKES_FOREVER);
2075 
2076  // Event A4 to Event A3
2077  sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2078  targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2079  expectedTime.clear();
2080  expectedTime << 1200 << 1440 << 1680 << 1920;
2081  expectedRsrp.clear();
2082  expectedRsrp << 53 << 53 << 53 << 53;
2083  AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A4 to Event A3",
2084  sourceConfigList,
2085  targetConfigList,
2086  expectedTime,
2087  expectedRsrp,
2088  Seconds(2)),
2089  TestCase::QUICK);
2090 
2091  // Event A2 to Event A3
2092  sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2093  targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2094  expectedTime.clear();
2095  expectedTime << 1200 << 1440 << 1680 << 1920;
2096  expectedRsrp.clear();
2097  expectedRsrp << 53 << 53 << 53 << 53;
2098  AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A2 to Event A3",
2099  sourceConfigList,
2100  targetConfigList,
2101  expectedTime,
2102  expectedRsrp,
2103  Seconds(2)),
2104  TestCase::EXTENSIVE);
2105 
2106  // Event A3 to Event A2
2107  sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2108  targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2109  expectedTime.clear();
2110  expectedTime << 1200 << 1440 << 1680 << 1920;
2111  expectedRsrp.clear();
2112  expectedRsrp << 53 << 53 << 53 << 53;
2113  AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A3 to Event A2",
2114  sourceConfigList,
2115  targetConfigList,
2116  expectedTime,
2117  expectedRsrp,
2118  Seconds(2)),
2119  TestCase::TAKES_FOREVER);
2120 
2121  // Event A4 to Event A5
2122  sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2123  targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
2124  expectedTime.clear();
2125  expectedTime << 1200 << 1440 << 1680 << 1920;
2126  expectedRsrp.clear();
2127  expectedRsrp << 53 << 53 << 53 << 53;
2128  AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A4 to Event A5",
2129  sourceConfigList,
2130  targetConfigList,
2131  expectedTime,
2132  expectedRsrp,
2133  Seconds(2)),
2134  TestCase::TAKES_FOREVER);
2135 
2136  // Event A5 to Event A4
2137  sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
2138  targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2139  expectedTime.clear();
2140  expectedTime << 1200 << 1440 << 1680 << 1920;
2141  expectedRsrp.clear();
2142  expectedRsrp << 53 << 53 << 53 << 53;
2143  AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A5 to Event A4",
2144  sourceConfigList,
2145  targetConfigList,
2146  expectedTime,
2147  expectedRsrp,
2148  Seconds(2)),
2149  TestCase::EXTENSIVE);
2150 
2151  // === Threshold/offset difference ===
2152 
2153  sourceConfigList.front().threshold1.range = 52;
2154  targetConfigList.front().threshold1.range = 56;
2155 
2156  // Event A1
2157  sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2158  targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2159  expectedTime.clear();
2160  expectedTime << 200 << 440 << 680 << 920;
2161  expectedRsrp.clear();
2162  expectedRsrp << 55 << 55 << 55 << 55;
2163  AddTestCase(
2164  new LteUeMeasurementsHandoverTestCase("Handover test case - Event A1 threshold difference",
2165  sourceConfigList,
2166  targetConfigList,
2167  expectedTime,
2168  expectedRsrp,
2169  Seconds(2)),
2170  TestCase::EXTENSIVE);
2171 
2172  // Event A2
2173  sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2174  targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2175  expectedTime.clear();
2176  expectedTime << 1200 << 1440 << 1680 << 1920;
2177  expectedRsrp.clear();
2178  expectedRsrp << 53 << 53 << 53 << 53;
2179  AddTestCase(
2180  new LteUeMeasurementsHandoverTestCase("Handover test case - Event A2 threshold difference",
2181  sourceConfigList,
2182  targetConfigList,
2183  expectedTime,
2184  expectedRsrp,
2185  Seconds(2)),
2186  TestCase::QUICK);
2187 
2188  // Event A3
2189  sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2190  sourceConfigList.front().a3Offset = -30;
2191  targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2192  targetConfigList.front().a3Offset = 30;
2193  expectedTime.clear();
2194  expectedTime << 200 << 440 << 680 << 920;
2195  expectedRsrp.clear();
2196  expectedRsrp << 55 << 55 << 55 << 55;
2197  AddTestCase(
2198  new LteUeMeasurementsHandoverTestCase("Handover test case - Event A3 offset difference",
2199  sourceConfigList,
2200  targetConfigList,
2201  expectedTime,
2202  expectedRsrp,
2203  Seconds(2)),
2204  TestCase::QUICK);
2205 
2206  // Event A4
2207  sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2208  targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2209  expectedTime.clear();
2210  expectedTime << 200 << 440 << 680 << 920;
2211  expectedRsrp.clear();
2212  expectedRsrp << 55 << 55 << 55 << 55;
2213  AddTestCase(
2214  new LteUeMeasurementsHandoverTestCase("Handover test case - Event A4 threshold difference",
2215  sourceConfigList,
2216  targetConfigList,
2217  expectedTime,
2218  expectedRsrp,
2219  Seconds(2)),
2220  TestCase::EXTENSIVE);
2221 
2222  // Event A5
2223  sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
2224  sourceConfigList.front().threshold2.range = 52;
2225  targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
2226  targetConfigList.front().threshold2.range = 56;
2227  expectedTime.clear();
2228  expectedRsrp.clear();
2229  AddTestCase(
2230  new LteUeMeasurementsHandoverTestCase("Handover test case - Event A5 threshold difference",
2231  sourceConfigList,
2232  targetConfigList,
2233  expectedTime,
2234  expectedRsrp,
2235  Seconds(2)),
2236  TestCase::EXTENSIVE);
2237 
2238  // === Time-to-trigger (TTT) difference ===
2239 
2240  sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2241  sourceConfigList.front().a3Offset = 1;
2242  sourceConfigList.front().threshold1.range = 0;
2243  sourceConfigList.front().threshold2.range = 0;
2244  targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2245  targetConfigList.front().a3Offset = 1;
2246  targetConfigList.front().threshold1.range = 0;
2247  targetConfigList.front().threshold2.range = 0;
2248 
2249  // decreasing time-to-trigger (short duration)
2250  sourceConfigList.front().timeToTrigger = 1024;
2251  targetConfigList.front().timeToTrigger = 100;
2252  expectedTime.clear();
2253  expectedTime << 1300 << 1540 << 1780;
2254  expectedRsrp.clear();
2255  expectedRsrp << 53 << 53 << 53;
2256  AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - decreasing TTT (short)",
2257  sourceConfigList,
2258  targetConfigList,
2259  expectedTime,
2260  expectedRsrp,
2261  Seconds(2)),
2262  TestCase::QUICK);
2263 
2264  // decreasing time-to-trigger (longer duration)
2265  sourceConfigList.front().timeToTrigger = 1024;
2266  targetConfigList.front().timeToTrigger = 640;
2267  expectedTime.clear();
2268  expectedTime << 1224 << 1464 << 1704 << 1944 << 2840 << 3080 << 3320 << 3560 << 3800 << 4040;
2269  expectedRsrp.clear();
2270  expectedRsrp << 55 << 55 << 55 << 55 << 53 << 53 << 53 << 53 << 53 << 53;
2271  AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - decreasing TTT (long)",
2272  sourceConfigList,
2273  targetConfigList,
2274  expectedTime,
2275  expectedRsrp,
2276  Seconds(4.2)),
2277  TestCase::EXTENSIVE);
2278 
2279 } // end of LteUeMeasurementsHandoverTestSuite::LteUeMeasurementsHandoverTestSuite
2280 
2286 
2287 /*
2288  * Test Case
2289  */
2290 
2292  std::string name,
2293  std::list<LteRrcSap::ReportConfigEutra> sourceConfigList,
2294  std::list<LteRrcSap::ReportConfigEutra> targetConfigList,
2295  std::vector<Time> expectedTime,
2296  std::vector<uint8_t> expectedRsrp,
2297  Time duration)
2298  : TestCase(name),
2299  m_sourceConfigList(sourceConfigList),
2300  m_targetConfigList(targetConfigList),
2301  m_expectedTime(expectedTime),
2302  m_expectedRsrp(expectedRsrp),
2303  m_duration(duration)
2304 {
2305  // input sanity check
2306  uint16_t size = m_expectedTime.size();
2307 
2308  if (size != m_expectedRsrp.size())
2309  {
2310  NS_FATAL_ERROR("Vectors of expected results are not of the same size");
2311  }
2312 
2313  m_itExpectedTime = m_expectedTime.begin();
2314  m_itExpectedRsrp = m_expectedRsrp.begin();
2315 
2316  NS_LOG_INFO(this << " name=" << name);
2317 }
2318 
2320 {
2321  NS_LOG_FUNCTION(this);
2322 }
2323 
2324 void
2326 {
2327  NS_LOG_INFO(this << " " << GetName());
2328 
2329  Ptr<LteHelper> lteHelper = CreateObject<LteHelper>();
2330  Ptr<PointToPointEpcHelper> epcHelper = CreateObject<PointToPointEpcHelper>();
2331  lteHelper->SetEpcHelper(epcHelper);
2332  lteHelper->SetAttribute("PathlossModel", StringValue("ns3::FriisSpectrumPropagationLossModel"));
2333  lteHelper->SetAttribute("UseIdealRrc", BooleanValue(true));
2334 
2335  // Disable Uplink Power Control
2336  Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false));
2337 
2338  // Create Nodes: eNodeB and UE
2339  NodeContainer enbNodes;
2340  NodeContainer ueNodes;
2341  enbNodes.Create(2);
2342  ueNodes.Create(1);
2343 
2344  /*
2345  * The topology is the following:
2346  *
2347  * eNodeB UE eNodeB
2348  * | | |
2349  * x ------------------- x ----------------------- x
2350  * 400 m 500 m
2351  */
2352 
2353  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
2354  positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // Source eNodeB
2355  positionAlloc->Add(Vector(900.0, 0.0, 0.0)); // Target eNodeB
2356  positionAlloc->Add(Vector(400.0, 0.0, 0.0)); // UE
2358  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2359  mobility.SetPositionAllocator(positionAlloc);
2360  mobility.Install(enbNodes);
2361  mobility.Install(ueNodes);
2362 
2363  // Create P-GW node
2364  Ptr<Node> pgw = epcHelper->GetPgwNode();
2365 
2366  // Create a single RemoteHost
2367  NodeContainer remoteHostContainer;
2368  remoteHostContainer.Create(1);
2369  Ptr<Node> remoteHost = remoteHostContainer.Get(0);
2371  internet.Install(remoteHostContainer);
2372 
2373  // Create the Internet
2374  PointToPointHelper p2ph;
2375  p2ph.SetDeviceAttribute("DataRate", DataRateValue(DataRate("100Gb/s")));
2376  p2ph.SetDeviceAttribute("Mtu", UintegerValue(1500));
2377  p2ph.SetChannelAttribute("Delay", TimeValue(Seconds(0.010)));
2378  NetDeviceContainer internetDevices = p2ph.Install(pgw, remoteHost);
2379  Ipv4AddressHelper ipv4h;
2380  ipv4h.SetBase("1.0.0.0", "255.0.0.0");
2381  Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign(internetDevices);
2382 
2383  // Routing of the Internet Host (towards the LTE network)
2384  Ipv4StaticRoutingHelper ipv4RoutingHelper;
2385  Ptr<Ipv4StaticRouting> remoteHostStaticRouting =
2386  ipv4RoutingHelper.GetStaticRouting(remoteHost->GetObject<Ipv4>());
2387  remoteHostStaticRouting->AddNetworkRouteTo(Ipv4Address("7.0.0.0"), Ipv4Mask("255.0.0.0"), 1);
2388 
2389  // Enable layer-3 filtering
2390  Config::SetDefault("ns3::LteEnbRrc::RsrpFilterCoefficient", UintegerValue(4));
2391 
2392  // Disable control channel error model
2393  Config::SetDefault("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue(false));
2394 
2395  // Create Devices and install them in the Nodes (eNB and UE)
2396  NetDeviceContainer enbDevs;
2397  NetDeviceContainer ueDevs;
2398  enbDevs = lteHelper->InstallEnbDevice(enbNodes);
2399  ueDevs = lteHelper->InstallUeDevice(ueNodes);
2400 
2401  // Setup UE measurement configuration in eNodeBs
2402  uint8_t measId;
2403  Ptr<LteEnbRrc> enbRrc1 = enbDevs.Get(0)->GetObject<LteEnbNetDevice>()->GetRrc();
2404  Ptr<LteEnbRrc> enbRrc2 = enbDevs.Get(1)->GetObject<LteEnbNetDevice>()->GetRrc();
2405 
2406  for (auto itReportConfig = m_sourceConfigList.begin();
2407  itReportConfig != m_sourceConfigList.end();
2408  itReportConfig++)
2409  {
2410  measId = enbRrc1->AddUeMeasReportConfig(*itReportConfig).at(0);
2411  m_expectedSourceCellMeasId.insert(measId);
2412  }
2413 
2414  for (auto itReportConfig = m_targetConfigList.begin();
2415  itReportConfig != m_targetConfigList.end();
2416  itReportConfig++)
2417  {
2418  measId = enbRrc2->AddUeMeasReportConfig(*itReportConfig).at(0);
2419  m_expectedTargetCellMeasId.insert(measId);
2420  }
2421 
2422  // Install the IP stack on the UEs
2423  internet.Install(ueNodes);
2424  Ipv4InterfaceContainer ueIpIfaces;
2425  ueIpIfaces = epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueDevs));
2426 
2427  // Assign IP address to UEs
2428  for (uint32_t u = 0; u < ueNodes.GetN(); ++u)
2429  {
2430  Ptr<Node> ueNode = ueNodes.Get(u);
2431  // Set the default gateway for the UE
2432  Ptr<Ipv4StaticRouting> ueStaticRouting =
2433  ipv4RoutingHelper.GetStaticRouting(ueNode->GetObject<Ipv4>());
2434  ueStaticRouting->SetDefaultRoute(epcHelper->GetUeDefaultGatewayAddress(), 1);
2435  }
2436 
2437  // Attach UE to serving eNodeB
2438  lteHelper->Attach(ueDevs.Get(0), enbDevs.Get(0));
2439 
2440  // Add X2 interface
2441  lteHelper->AddX2Interface(enbNodes);
2442 
2443  // Connect to trace sources in source eNodeB
2445  "/NodeList/3/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
2447 
2448  // Connect to trace sources in target eNodeB
2450  "/NodeList/4/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
2452 
2453  // Schedule handover
2455  ueDevs.Get(0),
2456  enbDevs.Get(0),
2457  enbDevs.Get(1));
2458 
2459  // Run simulation
2460  Simulator::Stop(m_duration);
2461  Simulator::Run();
2462  Simulator::Destroy();
2463 
2464 } // end of void LteUeMeasurementsHandoverTestCase::DoRun ()
2465 
2466 void
2468 {
2469  NS_LOG_FUNCTION(this);
2470  bool hasEnded = m_itExpectedTime == m_expectedTime.end();
2471  NS_TEST_ASSERT_MSG_EQ(hasEnded,
2472  true,
2473  "Reporting should have occurred at " << m_itExpectedTime->As(Time::S));
2474  hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
2475  NS_ASSERT(hasEnded);
2476 }
2477 
2478 void
2480  std::string context,
2481  uint64_t imsi,
2482  uint16_t cellId,
2483  uint16_t rnti,
2485 {
2486  uint8_t measId = report.measResults.measId;
2487  NS_LOG_FUNCTION(this << context << (uint16_t)measId);
2488 
2489  bool isCorrectMeasId;
2490  if (cellId == 1)
2491  {
2492  auto itMeasId = m_expectedSourceCellMeasId.find(measId);
2493  isCorrectMeasId = (itMeasId != m_expectedSourceCellMeasId.end());
2494  }
2495  else if (cellId == 2)
2496  {
2497  auto itMeasId = m_expectedTargetCellMeasId.find(measId);
2498  isCorrectMeasId = (itMeasId != m_expectedTargetCellMeasId.end());
2499  }
2500  else
2501  {
2502  NS_FATAL_ERROR("Invalid cell ID " << cellId);
2503  }
2504 
2505  if (isCorrectMeasId)
2506  {
2507  // verifying the report completeness
2508  LteRrcSap::MeasResults measResults = report.measResults;
2509  NS_LOG_DEBUG(
2510  this << " Serving cellId=" << cellId
2511  << " rsrp=" << (uint16_t)measResults.measResultPCell.rsrpResult << " ("
2512  << EutranMeasurementMapping::RsrpRange2Dbm(measResults.measResultPCell.rsrpResult)
2513  << " dBm)"
2514  << " rsrq=" << (uint16_t)measResults.measResultPCell.rsrqResult << " ("
2515  << EutranMeasurementMapping::RsrqRange2Db(measResults.measResultPCell.rsrqResult)
2516  << " dB)");
2517 
2518  // verifying reported best cells
2519  if (measResults.measResultListEutra.empty())
2520  {
2522  false,
2523  "Unexpected report content");
2524  }
2525  else
2526  {
2528  true,
2529  "Unexpected report content");
2530  auto it = measResults.measResultListEutra.begin();
2531  NS_ASSERT(it != measResults.measResultListEutra.end());
2532  NS_ASSERT(it->physCellId != cellId);
2533  NS_ASSERT(it->physCellId <= 2);
2534  NS_TEST_ASSERT_MSG_EQ(it->haveCgiInfo,
2535  false,
2536  "Report contains cgi-info, which is not supported");
2537  NS_TEST_ASSERT_MSG_EQ(it->haveRsrpResult,
2538  true,
2539  "Report does not contain measured RSRP result");
2540  NS_TEST_ASSERT_MSG_EQ(it->haveRsrqResult,
2541  true,
2542  "Report does not contain measured RSRQ result");
2543  NS_LOG_DEBUG(this << " Neighbour cellId=" << it->physCellId
2544  << " rsrp=" << (uint16_t)it->rsrpResult << " ("
2545  << EutranMeasurementMapping::RsrpRange2Dbm(it->rsrpResult) << " dBm)"
2546  << " rsrq=" << (uint16_t)it->rsrqResult << " ("
2547  << EutranMeasurementMapping::RsrqRange2Db(it->rsrqResult) << " dB)");
2548 
2549  } // end of else of if (measResults.measResultListEutra.size () == 0)
2550 
2551  // verifying the report timing
2552  bool hasEnded = m_itExpectedTime == m_expectedTime.end();
2553  NS_TEST_ASSERT_MSG_EQ(hasEnded,
2554  false,
2555  "Reporting should not have occurred at "
2556  << Simulator::Now().As(Time::S));
2557  if (!hasEnded)
2558  {
2559  hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
2560  NS_ASSERT(!hasEnded);
2561 
2562  // using milliseconds to avoid floating-point comparison
2563  uint64_t timeNowMs = Simulator::Now().GetMilliSeconds();
2564  uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds();
2565  m_itExpectedTime++;
2566 
2567  uint16_t observedRsrp = measResults.measResultPCell.rsrpResult;
2568  uint16_t referenceRsrp = *m_itExpectedRsrp;
2569  m_itExpectedRsrp++;
2570 
2571  NS_TEST_ASSERT_MSG_EQ(timeNowMs,
2572  timeExpectedMs,
2573  "Reporting should not have occurred at this time");
2574  NS_TEST_ASSERT_MSG_EQ(observedRsrp,
2575  referenceRsrp,
2576  "The RSRP observed differs with the reference RSRP");
2577 
2578  } // end of if (!hasEnded)
2579 
2580  } // end of if (report.measResults.measId == correctMeasId)
2581 
2582 } // end of void LteUeMeasurementsHandoverTestCase::RecvMeasurementReportCallback
#define max(a, b)
Definition: 80211b.c:42
Testing UE measurements in LTE with simulation of 2 eNodeB and 1 UE in a handover configuration.
std::vector< uint8_t >::iterator m_itExpectedRsrp
Pointer to the element of m_expectedRsrp which is expected to occur next in the simulation.
std::vector< Time > m_expectedTime
The list of expected time when measurement reports are received by eNodeB.
std::list< LteRrcSap::ReportConfigEutra > m_sourceConfigList
The list of active report triggering configuration for the source eNodeB.
void DoRun() override
Setup the simulation with the intended UE measurement reporting configuration, run it,...
std::set< uint8_t > m_expectedTargetCellMeasId
The list of measurement identities being tested in the target cell.
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)
Constructor.
void RecvMeasurementReportCallback(std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti, LteRrcSap::MeasurementReport report)
Triggers when either one of the eNodeBs receives measurement report from UE, then perform verificatio...
void DoTeardown() override
Runs at the end of the simulation, verifying that all expected measurement reports have been examined...
Time m_duration
Duration of simulation.
std::vector< Time >::iterator m_itExpectedTime
Pointer to the element of m_expectedTime which is expected to occur next in the simulation.
std::list< LteRrcSap::ReportConfigEutra > m_targetConfigList
The list of active report triggering configuration for the target eNodeB.
std::set< uint8_t > m_expectedSourceCellMeasId
The list of measurement identities being tested in the source cell.
std::vector< uint8_t > m_expectedRsrp
The list of expected values of RSRP (in 3GPP range unit) from the measurement reports received.
Test suite for generating calls to UE measurements test case ns3::LteUeMeasurementsHandoverTestCase.
Testing UE measurements in LTE with simulation of 1 eNodeB and 1 UE in piecewise configuration and 12...
std::vector< Time > m_expectedTime
The list of expected time when measurement reports are received by eNodeB.
void TeleportVeryFar()
Teleport far function.
LteRrcSap::ReportConfigEutra m_config
The active report triggering configuration.
uint8_t m_expectedMeasId
The measurement identity being tested.
LteUeMeasurementsPiecewiseTestCase1(std::string name, LteRrcSap::ReportConfigEutra config, std::vector< Time > expectedTime, std::vector< uint8_t > expectedRsrp)
Constructor.
std::vector< Time >::iterator m_itExpectedTime
Pointer to the element of m_expectedTime which is expected to occur next in the simulation.
Ptr< MobilityModel > m_ueMobility
the mobility model
void TeleportVeryNear()
Teleport very near function.
void TeleportNear()
Teleport near function.
std::vector< uint8_t > m_expectedRsrp
The list of expected values of RSRP (in 3GPP range unit) from the measurement reports received.
void DoTeardown() override
Runs at the end of the simulation, verifying that all expected measurement reports have been examined...
std::vector< uint8_t >::iterator m_itExpectedRsrp
Pointer to the element of m_expectedRsrp which is expected to occur next in the simulation.
void RecvMeasurementReportCallback(std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti, LteRrcSap::MeasurementReport report)
Triggers when eNodeB receives measurement report from UE, then perform verification on it.
void DoRun() override
Setup the simulation with the intended UE measurement reporting configuration, run it,...
Testing UE measurements in LTE with simulation of 2 eNodeB and 1 UE in piecewise configuration and 24...
Ptr< MobilityModel > m_ueMobility
the mobility model
std::vector< Time >::iterator m_itExpectedTime
Pointer to the element of m_expectedTime which is expected to occur next in the simulation.
void TeleportVeryNear()
Teleport very near function.
std::vector< uint8_t > m_expectedRsrp
The list of expected values of RSRP (in 3GPP range unit) from the measurement reports received.
void DoTeardown() override
Runs at the end of the simulation, verifying that all expected measurement reports have been examined...
LteUeMeasurementsPiecewiseTestCase2(std::string name, LteRrcSap::ReportConfigEutra config, std::vector< Time > expectedTime, std::vector< uint8_t > expectedRsrp)
Constructor.
LteRrcSap::ReportConfigEutra m_config
The active report triggering configuration.
void DoRun() override
Setup the simulation with the intended UE measurement reporting configuration, run it,...
void RecvMeasurementReportCallback(std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti, LteRrcSap::MeasurementReport report)
Triggers when eNodeB receives measurement report from UE, then perform verification on it.
void TeleportVeryFar()
Teleport very far function.
void TeleportNear()
Teleport near function.
std::vector< uint8_t >::iterator m_itExpectedRsrp
Pointer to the element of m_expectedRsrp which is expected to occur next in the simulation.
uint8_t m_expectedMeasId
The measurement identity being tested.
std::vector< Time > m_expectedTime
The list of expected time when measurement reports are received by eNodeB.
Testing UE measurements in LTE with simulation of 3 eNodeB and 1 UE in piecewise configuration and 24...
Ptr< MobilityModel > m_enbMobility
the mobility model
LteUeMeasurementsPiecewiseTestCase3(std::string name, LteRrcSap::ReportConfigEutra config, std::vector< Time > expectedTime)
Constructor.
void DoTeardown() override
Runs at the end of the simulation, verifying that all expected measurement reports have been examined...
void DoRun() override
Setup the simulation with the intended UE measurement reporting configuration, run it,...
void RecvMeasurementReportCallback(std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti, LteRrcSap::MeasurementReport report)
Triggers when eNodeB receives measurement report from UE, then perform verification on it.
LteRrcSap::ReportConfigEutra m_config
The active report triggering configuration.
uint8_t m_expectedMeasId
The measurement identity being tested.
std::vector< Time > m_expectedTime
The list of expected time when measurement reports are received by eNodeB.
void TeleportEnbNear()
Teleport the eNb near function.
std::vector< Time >::iterator m_itExpectedTime
Pointer to the element of m_expectedTime which is expected to occur next in the simulation.
Test suite for generating calls to UE measurements test case ns3::LteUeMeasurementsPiecewiseTestCase1...
Test suite for generating calls to UE measurements test case ns3::LteUeMeasurementsPiecewiseTestCase2...
Test suite for generating calls to UE measurements test case ns3::LteUeMeasurementsPiecewiseTestCase3...
Test that UE measurements calculation works properly in a scenario with 2 eNodeBs and 2UEs.
double m_d1
distance between UE and ENB node pair
double m_rsrqDbUeServingCell
RSRQ in dBm UE 1.
double m_rsrpDbmUeServingCell
RSRP in dBm UE 1.
LteUeMeasurementsTestCase(std::string name, double d1, double d2, double rsrpDbmUe1, double rsrpDbmUe2, double rsrqDbUe1, double rsrqDbUe2)
Constructor.
void ReportUeMeasurements(uint16_t rnti, uint16_t cellId, double rsrp, double rsrq, bool servingCell)
Report UE measurements function.
void DoRun() override
Implementation to actually run this TestCase.
double m_rsrqDbUeNeighborCell
RSRQ in dBm UE 2.
double m_d2
distance between UE and other ENB node
double m_rsrpDbmUeNeighborCell
RSRP in dBm UE 2.
void RecvMeasurementReport(uint64_t imsi, uint16_t cellId, uint16_t rnti, LteRrcSap::MeasurementReport meas)
Reeive measurement report function.
Test that UE Measurements (see 36.214) calculation works fine in a multi-cell interference scenario.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
Hold variables of type enum.
Definition: enum.h:62
This class contains the specification of EPS Bearers.
Definition: eps-bearer.h:91
Qci
QoS Class Indicator.
Definition: eps-bearer.h:106
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:80
holds a vector of std::pair of Ptr<Ipv4> and interface index.
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:257
Helper class that adds ns3::Ipv4StaticRouting objects.
Ptr< Ipv4StaticRouting > GetStaticRouting(Ptr< Ipv4 > ipv4) const
Try and find the static routing protocol as either the main routing protocol or in the list of routin...
The eNodeB device implementation.
void SetEpcHelper(Ptr< EpcHelper > h)
Set the EpcHelper to be used to setup the EPC network in conjunction with the setup of the LTE radio ...
Definition: lte-helper.cc:285
void SetSchedulerAttribute(std::string n, const AttributeValue &v)
Set an attribute for the scheduler to be created.
Definition: lte-helper.cc:306
void HandoverRequest(Time hoTime, Ptr< NetDevice > ueDev, Ptr< NetDevice > sourceEnbDev, Ptr< NetDevice > targetEnbDev)
Manually trigger an X2-based handover.
Definition: lte-helper.cc:1338
NetDeviceContainer InstallEnbDevice(NodeContainer c)
Create a set of eNodeB devices.
Definition: lte-helper.cc:485
void SetSchedulerType(std::string type)
Set the type of scheduler to be used by eNodeB devices.
Definition: lte-helper.cc:292
void Attach(NetDeviceContainer ueDevices)
Enables automatic attachment of a set of UE devices to a suitable cell using Idle mode initial cell s...
Definition: lte-helper.cc:1039
void ActivateDataRadioBearer(NetDeviceContainer ueDevices, EpsBearer bearer)
Activate a Data Radio Bearer on a given UE devices (for LTE-only simulation).
Definition: lte-helper.cc:1436
NetDeviceContainer InstallUeDevice(NodeContainer c)
Create a set of UE devices.
Definition: lte-helper.cc:500
void AddX2Interface(NodeContainer enbNodes)
Create an X2 interface between all the eNBs in a given set.
Definition: lte-helper.cc:1313
Helper class used to assign positions and mobility models to nodes.
Keep track of the current position and velocity of an object.
void SetPosition(const Vector &position)
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
Ptr< Node > GetPgwNode() const override
Get the PGW node.
Ipv4Address GetUeDefaultGatewayAddress() override
Ipv4InterfaceContainer AssignUeIpv4Address(NetDeviceContainer ueDevices) override
Assign IPv4 addresses to UE devices.
keep track of a set of node pointers.
uint32_t GetN() const
Get the number of Ptr<Node> stored in this container.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:204
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
Build a set of PointToPointNetDevice objects.
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
NetDeviceContainer Install(NodeContainer c)
Hold variables of type string.
Definition: string.h:56
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
std::string GetName() const
Definition: test.cc:373
A suite of tests to run.
Definition: test.h:1256
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
int64_t GetMilliSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:408
std::ostream & operator<<(std::ostream &os, TypeId tid)
Output streamer.
Definition: type-id.cc:1225
Hold an unsigned integer type.
Definition: uinteger.h:45
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:890
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:974
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
static LteUeMeasurementsPiecewiseTestSuite2 lteUeMeasurementsPiecewiseTestSuite2
Static variable for test initialization.
static LteUeMeasurementsHandoverTestSuite lteUeMeasurementsHandoverTestSuite
Static variable for test initialization.
static LteUeMeasurementsTestSuite lteUeMeasurementsTestSuite
Static variable for test initialization.
static LteUeMeasurementsPiecewiseTestSuite1 lteUeMeasurementsPiecewiseTestSuite1
Static variable for test initialization.
static LteUeMeasurementsPiecewiseTestSuite3 lteUeMeasurementsPiecewiseTestSuite3
Static variable for test initialization.
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs &&... bargs)
Make Callbacks with varying number of bound arguments.
Definition: callback.h:765
void(* DataRate)(DataRate oldValue, DataRate newValue)
TracedValue callback signature for DataRate.
Definition: data-rate.h:327
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:305
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:144
#define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report and...
Definition: test.h:337
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
void ReportUeMeasurementsCallback(LteUeMeasurementsTestCase *testcase, std::string path, uint16_t rnti, uint16_t cellId, double rsrp, double rsrq, bool servingCell, uint8_t componentCarrierId)
void RecvMeasurementReportCallback(LteUeMeasurementsTestCase *testcase, std::string path, uint64_t imsi, uint16_t cellId, uint16_t rnti, LteRrcSap::MeasurementReport meas)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
static const Time UE_MEASUREMENT_REPORT_DELAY
Artificial delay of UE measurements procedure.
Definition: lte-ue-rrc.h:63
mobility
Definition: third.py:105
uint8_t rsrqResult
the RSRQ result
Definition: lte-rrc-sap.h:675
uint8_t rsrpResult
the RSRP result
Definition: lte-rrc-sap.h:674
MeasResults structure.
Definition: lte-rrc-sap.h:717
uint8_t measId
measure ID
Definition: lte-rrc-sap.h:718
bool haveMeasResultNeighCells
have measure result neighbor cells
Definition: lte-rrc-sap.h:720
std::list< MeasResultEutra > measResultListEutra
measure result list eutra
Definition: lte-rrc-sap.h:721
MeasResultPCell measResultPCell
measurement result primary cell
Definition: lte-rrc-sap.h:719
MeasurementReport structure.
Definition: lte-rrc-sap.h:948
MeasResults measResults
measure results
Definition: lte-rrc-sap.h:949
Specifies criteria for triggering of an E-UTRA measurement reporting event.
Definition: lte-rrc-sap.h:373
bool reportOnLeave
Indicates whether or not the UE shall initiate the measurement reporting procedure when the leaving c...
Definition: lte-rrc-sap.h:399
uint8_t hysteresis
Parameter used within the entry and leave condition of an event triggered reporting condition.
Definition: lte-rrc-sap.h:407
ThresholdEutra threshold2
Threshold for event A5.
Definition: lte-rrc-sap.h:394
enum ns3::LteRrcSap::ReportConfigEutra::@63 triggerType
Trigger enumeration.
enum ns3::LteRrcSap::ReportConfigEutra::@64 eventId
Event enumeration.
ThresholdEutra threshold1
Threshold for event A1, A2, A4, and A5.
Definition: lte-rrc-sap.h:393
enum ns3::LteRrcSap::ReportConfigEutra::@67 reportInterval
Report interval enumeration.
enum ns3::LteRrcSap::ReportConfigEutra::@65 triggerQuantity
Trigger type enumeration.
int8_t a3Offset
Offset value for Event A3.
Definition: lte-rrc-sap.h:403
uint16_t timeToTrigger
Time during which specific criteria for the event needs to be met in order to trigger a measurement r...
Definition: lte-rrc-sap.h:411
enum ns3::LteRrcSap::ThresholdEutra::@62 choice
Threshold enumeration.
uint8_t range
Value range used in RSRP/RSRQ threshold.
Definition: lte-rrc-sap.h:368