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