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
45// ===== LTE-UE-MEASUREMENTS TEST SUITE ==================================== //
46
47void
49 std::string path,
50 uint16_t rnti,
51 uint16_t cellId,
52 double rsrp,
53 double rsrq,
54 bool servingCell,
55 uint8_t componentCarrierId)
56{
57 testcase->ReportUeMeasurements(rnti, cellId, rsrp, rsrq, servingCell);
58}
59
60void
62 std::string path,
63 uint64_t imsi,
64 uint16_t cellId,
65 uint16_t rnti,
67{
68 testcase->RecvMeasurementReport(imsi, cellId, rnti, meas);
69}
70
71/*
72 * Test Suite
73 */
74
76 : TestSuite("lte-ue-measurements", Type::SYSTEM)
77{
78 AddTestCase(new LteUeMeasurementsTestCase("d1=10, d2=10000",
79 10.000000,
80 10000.000000,
81 -53.739702,
82 -113.739702,
83 -3.010305,
84 -63.010305),
85 TestCase::Duration::EXTENSIVE);
86 AddTestCase(new LteUeMeasurementsTestCase("d1=20, d2=10000",
87 20.000000,
88 10000.000000,
89 -59.760302,
90 -113.739702,
91 -3.010319,
92 -56.989719),
93 TestCase::Duration::EXTENSIVE);
94 AddTestCase(new LteUeMeasurementsTestCase("d1=50, d2=10000",
95 50.000000,
96 10000.000000,
97 -67.719102,
98 -113.739702,
99 -3.010421,
100 -49.031021),
101 TestCase::Duration::EXTENSIVE);
102 AddTestCase(new LteUeMeasurementsTestCase("d1=100, d2=10000",
103 100.000000,
104 10000.000000,
105 -73.739702,
106 -113.739702,
107 -3.010783,
108 -43.010783),
109 TestCase::Duration::EXTENSIVE);
110 AddTestCase(new LteUeMeasurementsTestCase("d1=200, d2=10000",
111 200.000000,
112 10000.000000,
113 -79.760302,
114 -113.739702,
115 -3.012232,
116 -36.991632),
117 TestCase::Duration::EXTENSIVE);
118 AddTestCase(new LteUeMeasurementsTestCase("d1=100, d2=10000",
119 100.000000,
120 10000.000000,
121 -73.739702,
122 -113.739702,
123 -3.010783,
124 -43.010783),
125 TestCase::Duration::EXTENSIVE);
126 AddTestCase(new LteUeMeasurementsTestCase("d1=200, d2=10000",
127 200.000000,
128 10000.000000,
129 -79.760302,
130 -113.739702,
131 -3.012232,
132 -36.991632),
133 TestCase::Duration::EXTENSIVE);
134 AddTestCase(new LteUeMeasurementsTestCase("d1=500, d2=10000",
135 500.000000,
136 10000.000000,
137 -87.719102,
138 -113.739702,
139 -3.022359,
140 -29.042959),
141 TestCase::Duration::EXTENSIVE);
142 AddTestCase(new LteUeMeasurementsTestCase("d1=1000, d2=10000",
143 1000.000000,
144 10000.000000,
145 -93.739702,
146 -113.739702,
147 -3.058336,
148 -23.058336),
149 TestCase::Duration::EXTENSIVE);
150 AddTestCase(new LteUeMeasurementsTestCase("d1=2000, d2=10000",
151 2000.000000,
152 10000.000000,
153 -99.760302,
154 -113.739702,
155 -3.199337,
156 -17.178738),
157 TestCase::Duration::EXTENSIVE);
158 AddTestCase(new LteUeMeasurementsTestCase("d1=5000, d2=10000",
159 5000.000000,
160 10000.000000,
161 -107.719102,
162 -113.739702,
163 -4.075793,
164 -10.096393),
165 TestCase::Duration::QUICK);
166 AddTestCase(new LteUeMeasurementsTestCase("d1=10000, d2=10000",
167 10000.000000,
168 10000.000000,
169 -113.739702,
170 -113.739702,
171 -6.257687,
172 -6.257687),
173 TestCase::Duration::EXTENSIVE);
174 AddTestCase(new LteUeMeasurementsTestCase("d1=20000, d2=10000",
175 20000.000000,
176 10000.000000,
177 -119.760302,
178 -113.739702,
179 -10.373365,
180 -4.352765),
181 TestCase::Duration::EXTENSIVE);
182 AddTestCase(new LteUeMeasurementsTestCase("d1=50000, d2=10000",
183 50000.000000,
184 10000.000000,
185 -127.719102,
186 -113.739702,
187 -17.605046,
188 -3.625645),
189 TestCase::Duration::EXTENSIVE);
190 AddTestCase(new LteUeMeasurementsTestCase("d1=100000, d2=10000",
191 100000.000000,
192 10000.000000,
193 -133.739702,
194 -113.739702,
195 -23.511071,
196 -3.511071),
197 TestCase::Duration::EXTENSIVE);
198 AddTestCase(new LteUeMeasurementsTestCase("d1=200000, d2=10000",
199 200000.000000,
200 10000.000000,
201 -139.760302,
202 -113.739702,
203 -29.502549,
204 -3.481949),
205 TestCase::Duration::EXTENSIVE);
206 AddTestCase(new LteUeMeasurementsTestCase("d1=500000, d2=10000",
207 500000.000000,
208 10000.000000,
209 -147.719102,
210 -113.739702,
211 -37.453160,
212 -3.473760),
213 TestCase::Duration::EXTENSIVE);
214 AddTestCase(new LteUeMeasurementsTestCase("d1=1000000, d2=10000",
215 1000000.000000,
216 10000.000000,
217 -153.739702,
218 -113.739702,
219 -43.472589,
220 -3.472589),
221 TestCase::Duration::EXTENSIVE);
222}
223
224/**
225 * @ingroup lte-test
226 * Static variable for test initialization
227 */
229
230/*
231 * Test Case
232 */
233
235 double d1,
236 double d2,
237 double rsrpDbmUe1,
238 double rsrpDbmUe2,
239 double rsrqDbUe1,
240 double rsrqDbUe2)
241 : TestCase(name),
242 m_d1(d1),
243 m_d2(d2),
244 m_rsrpDbmUeServingCell(rsrpDbmUe1),
245 m_rsrpDbmUeNeighborCell(rsrpDbmUe2),
246 m_rsrqDbUeServingCell(rsrqDbUe1),
247 m_rsrqDbUeNeighborCell(rsrqDbUe2)
248{
249 NS_LOG_INFO("Test UE Measurements d1 = " << d1 << " m. and d2 = " << d2 << " m.");
250}
251
255
256void
258{
259 NS_LOG_INFO(this << " " << GetName());
260
261 Config::SetDefault("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue(false));
262 Config::SetDefault("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue(false));
263 Config::SetDefault("ns3::LteAmc::AmcModel", EnumValue(LteAmc::PiroEW2010));
264 Config::SetDefault("ns3::LteAmc::Ber", DoubleValue(0.00005));
266 lteHelper->SetAttribute("PathlossModel", StringValue("ns3::FriisSpectrumPropagationLossModel"));
267 lteHelper->SetAttribute("UseIdealRrc", BooleanValue(false));
268
269 // Disable Uplink Power Control
270 Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false));
271
272 // LogComponentEnable ("LteUeMeasurementsTest", LOG_LEVEL_ALL);
273
274 // Create Nodes: eNodeB and UE
275 NodeContainer enbNodes;
276 NodeContainer ueNodes1;
277 NodeContainer ueNodes2;
278 enbNodes.Create(2);
279 ueNodes1.Create(1);
280 ueNodes2.Create(1);
281 NodeContainer allNodes = NodeContainer(enbNodes, ueNodes1, ueNodes2);
282
283 // the topology is the following:
284 // d2
285 // UE1-----------eNB2
286 // | |
287 // d1| |d1
288 // | d2 |
289 // eNB1----------UE2
290 //
292 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // eNB1
293 positionAlloc->Add(Vector(m_d2, m_d1, 0.0)); // eNB2
294 positionAlloc->Add(Vector(0.0, m_d1, 0.0)); // UE1
295 positionAlloc->Add(Vector(m_d2, 0.0, 0.0)); // UE2
296 MobilityHelper mobility;
297 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
298 mobility.SetPositionAllocator(positionAlloc);
299 mobility.Install(allNodes);
300
301 // Create Devices and install them in the Nodes (eNB and UE)
302 NetDeviceContainer enbDevs;
303 NetDeviceContainer ueDevs1;
304 NetDeviceContainer ueDevs2;
305 lteHelper->SetSchedulerType("ns3::RrFfMacScheduler");
306 lteHelper->SetSchedulerAttribute("UlCqiFilter", EnumValue(FfMacScheduler::PUSCH_UL_CQI));
307 enbDevs = lteHelper->InstallEnbDevice(enbNodes);
308 ueDevs1 = lteHelper->InstallUeDevice(ueNodes1);
309 ueDevs2 = lteHelper->InstallUeDevice(ueNodes2);
310
311 // Attach UEs to eNodeBs
312 lteHelper->Attach(ueDevs1, enbDevs.Get(0));
313 lteHelper->Attach(ueDevs2, enbDevs.Get(1));
314
315 // Activate an EPS bearer
317 EpsBearer bearer(q);
318 lteHelper->ActivateDataRadioBearer(ueDevs1, bearer);
319 lteHelper->ActivateDataRadioBearer(ueDevs2, bearer);
320
322 "/NodeList/2/DeviceList/0/ComponentCarrierMapUe/0/LteUePhy/ReportUeMeasurements",
324 Config::Connect("/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
326
328 "/NodeList/3/DeviceList/0/ComponentCarrierMapUe/0/LteUePhy/ReportUeMeasurements",
330 Config::Connect("/NodeList/1/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
332
333 // need to allow for RRC connection establishment + SRS
334 Simulator::Stop(Seconds(0.800));
336
338}
339
340void
342 uint16_t cellId,
343 double rsrp,
344 double rsrq,
345 bool servingCell)
346{
347 // need to allow for RRC connection establishment + CQI feedback reception + UE measurements
348 // filtering (200 ms)
349 if (Simulator::Now() > MilliSeconds(400))
350 {
351 if (servingCell)
352 {
353 NS_LOG_DEBUG("UE serving cellId " << cellId << " Rxed RSRP " << rsrp << " thr "
354 << m_rsrpDbmUeServingCell << " RSRQ " << rsrq
355 << " thr " << m_rsrqDbUeServingCell);
356 NS_TEST_ASSERT_MSG_EQ_TOL(m_rsrpDbmUeServingCell, rsrp, 0.2, "Wrong RSRP UE 1");
357 NS_TEST_ASSERT_MSG_EQ_TOL(m_rsrqDbUeServingCell, rsrq, 0.2, "Wrong RSRQ UE 1");
358 }
359 else
360 {
361 NS_LOG_DEBUG("UE neighbor cellId " << cellId << " Rxed RSRP " << rsrp << " thr "
362 << m_rsrpDbmUeNeighborCell << " RSRQ " << rsrq
363 << " thr " << m_rsrqDbUeNeighborCell);
364 NS_TEST_ASSERT_MSG_EQ_TOL(m_rsrpDbmUeNeighborCell, rsrp, 0.2, "Wrong RSRP UE 2");
365 NS_TEST_ASSERT_MSG_EQ_TOL(m_rsrqDbUeNeighborCell, rsrq, 0.2, "Wrong RSRQ UE ");
366 }
367 }
368}
369
370void
372 uint16_t cellId,
373 uint16_t rnti,
375{
376 // need to allow for RRC connection establishment + CQI feedback reception + UE measurements
377 // filtering (200 ms)
378 if (Simulator::Now() > MilliSeconds(400))
379 {
380 if (cellId == imsi)
381 {
383 this << "Serving Cell: received IMSI " << imsi << " CellId " << cellId << " RNTI "
384 << rnti << " thr "
386 << " RSRP " << (uint16_t)meas.measResults.measResultPCell.rsrpResult
387 << " RSRQ " << (uint16_t)meas.measResults.measResultPCell.rsrqResult << " thr "
391 "Wrong RSRP ");
394 "Wrong RSRQ ");
395 }
396 else
397 {
399 this << "Neighbor cell: received IMSI " << imsi << " CellId " << cellId << " RNTI "
400 << rnti << " thr "
402 << " RSRP " << (uint16_t)meas.measResults.measResultPCell.rsrpResult
403 << " RSRQ " << (uint16_t)meas.measResults.measResultPCell.rsrqResult << " thr "
407 "Wrong RSRP ");
410 "Wrong RSRQ ");
411 }
412 }
413}
414
415// ===== LTE-UE-MEASUREMENTS-PIECEWISE-1 TEST SUITE ======================== //
416
417/*
418 * Overloaded operators, for the convenience of defining test cases
419 */
420
421std::vector<Time>&
422operator<<(std::vector<Time>& v, const uint64_t& ms)
423{
424 /*
425 * Prior attempt to use seconds as unit of choice resulted in precision lost.
426 * Therefore milliseconds are used now instead.
427 */
428 v.push_back(MilliSeconds(ms) + UE_MEASUREMENT_REPORT_DELAY);
429 return v;
430}
431
432std::vector<uint8_t>&
433operator<<(std::vector<uint8_t>& v, const uint8_t& range)
434{
435 v.push_back(range);
436 return v;
437}
438
439/*
440 * Test Suite
441 */
442
444 : TestSuite("lte-ue-measurements-piecewise-1", Type::SYSTEM)
445{
446 std::vector<Time> expectedTime;
447 std::vector<uint8_t> expectedRsrp;
448
449 // === Event A1 (serving cell becomes better than threshold) ===
450
451 // With very low threshold
456 config.threshold1.range = 0;
459 expectedTime.clear();
460 expectedTime << 200 << 320 << 440 << 560 << 680 << 800 << 920 << 1040 << 1160 << 1280 << 1400
461 << 1520 << 1640 << 1760 << 1880 << 2000 << 2120;
462 expectedRsrp.clear();
463 expectedRsrp << 67 << 67 << 57 << 57 << 66 << 47 << 47 << 66 << 66 << 57 << 51 << 51 << 47 << 47
464 << 51 << 57 << 57;
466 "Piecewise test case 1 - Event A1 with very low threshold",
467 config,
468 expectedTime,
469 expectedRsrp),
470 TestCase::Duration::EXTENSIVE);
471
472 // With normal threshold
473 config.threshold1.range = 54;
474 expectedTime.clear();
475 expectedTime << 200 << 320 << 440 << 560 << 680 << 1000 << 1120 << 1240 << 1360 << 2000 << 2120;
476 expectedRsrp.clear();
477 expectedRsrp << 67 << 67 << 57 << 57 << 66 << 66 << 66 << 57 << 57 << 57 << 57;
479 "Piecewise test case 1 - Event A1 with normal threshold",
480 config,
481 expectedTime,
482 expectedRsrp),
483 TestCase::Duration::EXTENSIVE);
484
485 // With short time-to-trigger
486 config.timeToTrigger = 64;
487 expectedTime.clear();
488 expectedTime << 264 << 384 << 504 << 624 << 744 << 1064 << 1184 << 1304 << 1424 << 2064 << 2184;
489 expectedRsrp.clear();
490 expectedRsrp << 67 << 67 << 57 << 66 << 66 << 66 << 66 << 57 << 51 << 57 << 57;
492 "Piecewise test case 1 - Event A1 with short time-to-trigger",
493 config,
494 expectedTime,
495 expectedRsrp),
496 TestCase::Duration::QUICK);
497
498 // With long time-to-trigger
499 config.timeToTrigger = 128;
500 expectedTime.clear();
501 expectedTime << 328 << 448 << 568 << 688 << 808 << 1128 << 1248 << 1368 << 1488 << 2128;
502 expectedRsrp.clear();
503 expectedRsrp << 67 << 57 << 57 << 66 << 47 << 66 << 57 << 57 << 51 << 57;
505 "Piecewise test case 1 - Event A1 with long time-to-trigger",
506 config,
507 expectedTime,
508 expectedRsrp),
509 TestCase::Duration::EXTENSIVE);
510
511 // With super time-to-trigger
512 config.timeToTrigger = 256;
513 expectedTime.clear();
514 expectedTime << 456 << 576 << 696 << 816 << 936 << 1056 << 1176 << 1296 << 1416 << 1536;
515 expectedRsrp.clear();
516 expectedRsrp << 57 << 57 << 66 << 47 << 47 << 66 << 66 << 57 << 51 << 51;
518 "Piecewise test case 1 - Event A1 with super time-to-trigger",
519 config,
520 expectedTime,
521 expectedRsrp),
522 TestCase::Duration::EXTENSIVE);
523
524 // With hysteresis
525 config.hysteresis = 8;
526 config.timeToTrigger = 0;
527 expectedTime.clear();
528 expectedTime << 200 << 320 << 440 << 560 << 680 << 1000 << 1120 << 1240 << 1360 << 1480 << 2200;
529 expectedRsrp.clear();
530 expectedRsrp << 67 << 67 << 57 << 57 << 66 << 66 << 66 << 57 << 57 << 51 << 67;
532 new LteUeMeasurementsPiecewiseTestCase1("Piecewise test case 1 - Event A1 with hysteresis",
533 config,
534 expectedTime,
535 expectedRsrp),
536 TestCase::Duration::QUICK);
537
538 // With very high threshold
539 config.threshold1.range = 97;
540 config.hysteresis = 0;
541 expectedTime.clear();
542 expectedRsrp.clear();
544 "Piecewise test case 1 - Event A1 with very high threshold",
545 config,
546 expectedTime,
547 expectedRsrp),
548 TestCase::Duration::TAKES_FOREVER);
549
550 // === Event A2 (serving cell becomes worse than threshold) ===
551
552 // With very low threshold
554 config.threshold1.range = 0;
555 expectedTime.clear();
556 expectedRsrp.clear();
558 "Piecewise test case 1 - Event A2 with very low threshold",
559 config,
560 expectedTime,
561 expectedRsrp),
562 TestCase::Duration::TAKES_FOREVER);
563
564 // With normal threshold
565 config.threshold1.range = 54;
566 expectedTime.clear();
567 expectedTime << 800 << 920 << 1400 << 1520 << 1640 << 1760 << 1880;
568 expectedRsrp.clear();
569 expectedRsrp << 47 << 47 << 51 << 51 << 47 << 47 << 51;
571 "Piecewise test case 1 - Event A2 with normal threshold",
572 config,
573 expectedTime,
574 expectedRsrp),
575 TestCase::Duration::QUICK);
576
577 // With short time-to-trigger
578 config.timeToTrigger = 64;
579 expectedTime.clear();
580 expectedTime << 864 << 984 << 1464 << 1584 << 1704 << 1824 << 1944;
581 expectedRsrp.clear();
582 expectedRsrp << 47 << 47 << 51 << 51 << 47 << 51 << 51;
584 "Piecewise test case 1 - Event A2 with short time-to-trigger",
585 config,
586 expectedTime,
587 expectedRsrp),
588 TestCase::Duration::EXTENSIVE);
589
590 // With long time-to-trigger
591 config.timeToTrigger = 128;
592 expectedTime.clear();
593 expectedTime << 928 << 1048 << 1528 << 1648 << 1768 << 1888 << 2008;
594 expectedRsrp.clear();
595 expectedRsrp << 47 << 66 << 51 << 47 << 47 << 51 << 57;
597 "Piecewise test case 1 - Event A2 with long time-to-trigger",
598 config,
599 expectedTime,
600 expectedRsrp),
601 TestCase::Duration::TAKES_FOREVER);
602
603 // With super time-to-trigger
604 config.timeToTrigger = 256;
605 expectedTime.clear();
606 expectedTime << 1656 << 1776 << 1896 << 2016 << 2136;
607 expectedRsrp.clear();
608 expectedRsrp << 47 << 47 << 51 << 57 << 57;
610 "Piecewise test case 1 - Event A2 with super time-to-trigger",
611 config,
612 expectedTime,
613 expectedRsrp),
614 TestCase::Duration::QUICK);
615
616 // With hysteresis
617 config.hysteresis = 8;
618 config.timeToTrigger = 0;
619 expectedTime.clear();
620 expectedTime << 800 << 920 << 1600 << 1720 << 1840 << 1960 << 2080;
621 expectedRsrp.clear();
622 expectedRsrp << 47 << 47 << 47 << 47 << 51 << 51 << 57;
624 new LteUeMeasurementsPiecewiseTestCase1("Piecewise test case 1 - Event A2 with hysteresis",
625 config,
626 expectedTime,
627 expectedRsrp),
628 TestCase::Duration::EXTENSIVE);
629
630 // With very high threshold
631 config.threshold1.range = 97;
632 config.hysteresis = 0;
633 expectedTime.clear();
634 expectedTime << 200 << 320 << 440 << 560 << 680 << 800 << 920 << 1040 << 1160 << 1280 << 1400
635 << 1520 << 1640 << 1760 << 1880 << 2000 << 2120;
636 expectedRsrp.clear();
637 expectedRsrp << 67 << 67 << 57 << 57 << 66 << 47 << 47 << 66 << 66 << 57 << 51 << 51 << 47 << 47
638 << 51 << 57 << 57;
640 "Piecewise test case 1 - Event A2 with very high threshold",
641 config,
642 expectedTime,
643 expectedRsrp),
644 TestCase::Duration::EXTENSIVE);
645
646 /*
647 * Event A3, A4, and A5 are not tested intensively here because they depend on
648 * the existence of at least one neighbouring cell, which is not available in
649 * this configuration. Piecewise configuration #2 includes a neighbouring
650 * cell, hence more thorough tests on these events are performed there.
651 */
652
653 expectedTime.clear();
654 expectedRsrp.clear();
655
656 // === Event A3 (neighbour becomes offset better than PCell) ===
657
659 config.a3Offset = 0;
660 AddTestCase(new LteUeMeasurementsPiecewiseTestCase1("Piecewise test case 1 - Event A3",
661 config,
662 expectedTime,
663 expectedRsrp),
664 TestCase::Duration::EXTENSIVE);
665
666 // === Event A4 (neighbour becomes better than threshold) ===
667
669 config.threshold1.range = 54;
670 AddTestCase(new LteUeMeasurementsPiecewiseTestCase1("Piecewise test case 1 - Event A4",
671 config,
672 expectedTime,
673 expectedRsrp),
674 TestCase::Duration::EXTENSIVE);
675
676 // === Event A5 (PCell becomes worse than absolute threshold1 AND neighbour becomes better than
677 // another absolute threshold2) ===
678
680 config.threshold2.range = 58;
681 AddTestCase(new LteUeMeasurementsPiecewiseTestCase1("Piecewise test case 1 - Event A5",
682 config,
683 expectedTime,
684 expectedRsrp),
685 TestCase::Duration::EXTENSIVE);
686
687} // end of LteUeMeasurementsPiecewiseTestSuite1::LteUeMeasurementsPiecewiseTestSuite1
688
689/**
690 * @ingroup lte-test
691 * Static variable for test initialization
692 */
694
695/*
696 * Test Case
697 */
698
700 std::string name,
702 std::vector<Time> expectedTime,
703 std::vector<uint8_t> expectedRsrp)
704 : TestCase(name),
705 m_config(config),
706 m_expectedTime(expectedTime),
707 m_expectedRsrp(expectedRsrp)
708{
709 // input sanity check
710 uint16_t size = m_expectedTime.size();
711
712 if (size != m_expectedRsrp.size())
713 {
714 NS_FATAL_ERROR("Vectors of expected results are not of the same size");
715 }
716
719
720 NS_LOG_INFO(this << " name=" << name);
721}
722
727
728void
730{
731 NS_LOG_INFO(this << " " << GetName());
732
734 lteHelper->SetAttribute("PathlossModel", StringValue("ns3::FriisSpectrumPropagationLossModel"));
735 lteHelper->SetAttribute("UseIdealRrc", BooleanValue(true));
736
737 // Disable Uplink Power Control
738 Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false));
739
740 // Create Nodes: eNodeB and UE
741 NodeContainer enbNodes;
742 NodeContainer ueNodes;
743 enbNodes.Create(1);
744 ueNodes.Create(1);
745
746 /*
747 * The topology is the following:
748 *
749 * eNodeB UE
750 * | |
751 * x ----- x --------- x --------------- x ------------------- x
752 * 100 m | 200 m | 300 m | 400 m |
753 * | | | |
754 * VeryNear Near Far VeryFar
755 */
756
758 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // eNodeB
759 positionAlloc->Add(Vector(100.0, 0.0, 0.0)); // UE
760 MobilityHelper mobility;
761 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
762 mobility.SetPositionAllocator(positionAlloc);
763 mobility.Install(enbNodes);
764 mobility.Install(ueNodes);
765 m_ueMobility = ueNodes.Get(0)->GetObject<MobilityModel>();
766
767 // Disable layer-3 filtering
768 Config::SetDefault("ns3::LteEnbRrc::RsrpFilterCoefficient", UintegerValue(0));
769
770 // Create Devices and install them in the Nodes (eNB and UE)
771 NetDeviceContainer enbDevs;
772 NetDeviceContainer ueDevs;
773 lteHelper->SetSchedulerType("ns3::RrFfMacScheduler");
774 lteHelper->SetSchedulerAttribute("UlCqiFilter", EnumValue(FfMacScheduler::PUSCH_UL_CQI));
775 enbDevs = lteHelper->InstallEnbDevice(enbNodes);
776 ueDevs = lteHelper->InstallUeDevice(ueNodes);
777
778 // Setup UE measurement configuration
779 Ptr<LteEnbRrc> enbRrc = enbDevs.Get(0)->GetObject<LteEnbNetDevice>()->GetRrc();
780 m_expectedMeasId = enbRrc->AddUeMeasReportConfig(m_config).at(0);
781
782 // Attach UE to eNodeB
783 lteHelper->Attach(ueDevs.Get(0), enbDevs.Get(0));
784
785 // Activate an EPS bearer
787 EpsBearer bearer(q);
788 lteHelper->ActivateDataRadioBearer(ueDevs, bearer);
789
790 // Connect to trace sources
792 "/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
794
795 /*
796 * Schedule "teleports"
797 * 0 1 2
798 * +-------------------+-------------------+---------> time
799 * VeryNear |------ ---- ---- --------
800 * Near | ---- ----
801 * Far | ---- ----
802 * VeryFar | -- ---- ----
803 */
806 this);
809 this);
812 this);
815 this);
818 this);
821 this);
824 this);
827 this);
830 this);
833 this);
834
835 // Run simulation
836 Simulator::Stop(Seconds(2.201));
839}
840
841void
843{
844 NS_LOG_FUNCTION(this);
845 bool hasEnded = m_itExpectedTime == m_expectedTime.end();
846 NS_TEST_ASSERT_MSG_EQ(hasEnded,
847 true,
848 "Reporting should have occurred at " << m_itExpectedTime->As(Time::S));
849 hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
850 NS_ASSERT(hasEnded);
851}
852
853void
855 std::string context,
856 uint64_t imsi,
857 uint16_t cellId,
858 uint16_t rnti,
860{
861 NS_LOG_FUNCTION(this << context);
862 NS_ASSERT(rnti == 1);
863 NS_ASSERT(cellId == 1);
864
865 if (report.measResults.measId == m_expectedMeasId)
866 {
867 // verifying the report completeness
868 LteRrcSap::MeasResults measResults = report.measResults;
870 this << " rsrp=" << (uint16_t)measResults.measResultPCell.rsrpResult << " ("
872 << " dBm)"
873 << " rsrq=" << (uint16_t)measResults.measResultPCell.rsrqResult << " ("
875 << " dB)");
877 false,
878 "Report should not have neighboring cells information");
879 NS_TEST_ASSERT_MSG_EQ(measResults.measResultListEutra.size(), 0, "Unexpected report size");
880
881 bool hasEnded = m_itExpectedTime == m_expectedTime.end();
882 NS_TEST_ASSERT_MSG_EQ(hasEnded,
883 false,
884 "Reporting should not have occurred at "
885 << Simulator::Now().As(Time::S));
886 if (!hasEnded)
887 {
888 hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
889 NS_ASSERT(!hasEnded);
890
891 // using milliseconds to avoid floating-point comparison
892 uint64_t timeNowMs = Simulator::Now().GetMilliSeconds();
893 uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds();
895
896 uint16_t observedRsrp = measResults.measResultPCell.rsrpResult;
897 uint16_t referenceRsrp = *m_itExpectedRsrp;
899
900 NS_TEST_ASSERT_MSG_EQ(timeNowMs,
901 timeExpectedMs,
902 "Reporting should not have occurred at this time");
903 NS_TEST_ASSERT_MSG_EQ(observedRsrp,
904 referenceRsrp,
905 "The RSRP observed differs with the reference RSRP");
906 }
907 }
908}
909
910void
912{
913 NS_LOG_FUNCTION(this);
914 m_ueMobility->SetPosition(Vector(100.0, 0.0, 0.0));
915}
916
917void
919{
920 NS_LOG_FUNCTION(this);
921 m_ueMobility->SetPosition(Vector(300.0, 0.0, 0.0));
922}
923
924void
926{
927 NS_LOG_FUNCTION(this);
928 m_ueMobility->SetPosition(Vector(600.0, 0.0, 0.0));
929}
930
931void
933{
934 NS_LOG_FUNCTION(this);
935 m_ueMobility->SetPosition(Vector(1000.0, 0.0, 0.0));
936}
937
938// ===== LTE-UE-MEASUREMENTS-PIECEWISE-2 TEST SUITE ======================== //
939
940/*
941 * Test Suite
942 */
943
945 : TestSuite("lte-ue-measurements-piecewise-2", Type::SYSTEM)
946{
947 std::vector<Time> expectedTime;
948 std::vector<uint8_t> expectedRsrp;
949
950 /*
951 * Higher level of fullness/duration are given to Event A1 and A2 because they
952 * are supposed to be more intensively tested in Piecewise configuration #1.
953 */
954
955 // === Event A1 (serving cell becomes better than threshold) ===
956
957 // With very low threshold
962 config.threshold1.range = 0;
965 expectedTime.clear();
966 expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
967 expectedRsrp.clear();
968 expectedRsrp << 73 << 63 << 72 << 52 << 72 << 56 << 52 << 56 << 59;
970 "Piecewise test case 2 - Event A1 with very low threshold",
971 config,
972 expectedTime,
973 expectedRsrp),
974 TestCase::Duration::EXTENSIVE);
975
976 // With normal threshold
977 config.threshold1.range = 58;
978 expectedTime.clear();
979 expectedTime << 200 << 440 << 680 << 1000 << 1240 << 2000;
980 expectedRsrp.clear();
981 expectedRsrp << 73 << 63 << 72 << 72 << 59 << 59;
983 "Piecewise test case 2 - Event A1 with normal threshold",
984 config,
985 expectedTime,
986 expectedRsrp),
987 TestCase::Duration::TAKES_FOREVER);
988
989 // With hysteresis
990 config.hysteresis = 6;
991 expectedTime.clear();
992 expectedTime << 200 << 440 << 680 << 1000 << 1240 << 1480 << 2200;
993 expectedRsrp.clear();
994 expectedRsrp << 73 << 63 << 72 << 72 << 59 << 56 << 72;
996 new LteUeMeasurementsPiecewiseTestCase2("Piecewise test case 2 - Event A1 with hysteresis",
997 config,
998 expectedTime,
999 expectedRsrp),
1000 TestCase::Duration::EXTENSIVE);
1001
1002 // With very high threshold
1003 config.threshold1.range = 97;
1004 config.hysteresis = 0;
1005 expectedTime.clear();
1006 expectedRsrp.clear();
1008 "Piecewise test case 2 - Event A1 with very high threshold",
1009 config,
1010 expectedTime,
1011 expectedRsrp),
1012 TestCase::Duration::TAKES_FOREVER);
1013
1014 // === Event A2 (serving cell becomes worse than threshold) ===
1015
1016 // With very low threshold
1018 config.threshold1.range = 0;
1019 expectedTime.clear();
1020 expectedRsrp.clear();
1022 "Piecewise test case 2 - Event A2 with very low threshold",
1023 config,
1024 expectedTime,
1025 expectedRsrp),
1026 TestCase::Duration::TAKES_FOREVER);
1027
1028 // With normal threshold
1029 config.threshold1.range = 58;
1030 expectedTime.clear();
1031 expectedTime << 800 << 1400 << 1640 << 1880;
1032 expectedRsrp.clear();
1033 expectedRsrp << 52 << 56 << 52 << 56;
1035 "Piecewise test case 2 - Event A2 with normal threshold",
1036 config,
1037 expectedTime,
1038 expectedRsrp),
1039 TestCase::Duration::TAKES_FOREVER);
1040
1041 // With hysteresis
1042 config.hysteresis = 6;
1043 expectedTime.clear();
1044 expectedTime << 800 << 1600 << 1840 << 2080;
1045 expectedRsrp.clear();
1046 expectedRsrp << 52 << 52 << 56 << 59;
1048 new LteUeMeasurementsPiecewiseTestCase2("Piecewise test case 2 - Event A2 with hysteresis",
1049 config,
1050 expectedTime,
1051 expectedRsrp),
1052 TestCase::Duration::EXTENSIVE);
1053
1054 // With very high threshold
1055 config.threshold1.range = 97;
1056 config.hysteresis = 0;
1057 expectedTime.clear();
1058 expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
1059 expectedRsrp.clear();
1060 expectedRsrp << 73 << 63 << 72 << 52 << 72 << 56 << 52 << 56 << 59;
1062 "Piecewise test case 2 - Event A2 with very high threshold",
1063 config,
1064 expectedTime,
1065 expectedRsrp),
1066 TestCase::Duration::TAKES_FOREVER);
1067
1068 // === Event A3 (neighbour becomes offset better than PCell) ===
1069
1070 // With positive offset
1072 config.threshold1.range = 0;
1073 config.a3Offset = 7;
1074 expectedTime.clear();
1075 expectedTime << 800 << 1600;
1076 expectedRsrp.clear();
1077 expectedRsrp << 52 << 52;
1079 "Piecewise test case 2 - Event A3 with positive offset",
1080 config,
1081 expectedTime,
1082 expectedRsrp),
1083 TestCase::Duration::QUICK);
1084
1085 // With zero offset
1086 config.a3Offset = 0;
1087 expectedTime.clear();
1088 expectedTime << 800 << 1400 << 1640 << 1880;
1089 expectedRsrp.clear();
1090 expectedRsrp << 52 << 56 << 52 << 56;
1092 new LteUeMeasurementsPiecewiseTestCase2("Piecewise test case 2 - Event A3 with zero offset",
1093 config,
1094 expectedTime,
1095 expectedRsrp),
1096 TestCase::Duration::EXTENSIVE);
1097
1098 // With short time-to-trigger
1099 config.timeToTrigger = 160;
1100 expectedTime.clear();
1101 expectedTime << 960 << 1560 << 1800 << 2040;
1102 expectedRsrp.clear();
1103 expectedRsrp << 52 << 56 << 56 << 59;
1105 "Piecewise test case 2 - Event A3 with short time-to-trigger",
1106 config,
1107 expectedTime,
1108 expectedRsrp),
1109 TestCase::Duration::EXTENSIVE);
1110
1111 // With super time-to-trigger
1112 config.timeToTrigger = 320;
1113 expectedTime.clear();
1114 expectedTime << 1720 << 1960 << 2200;
1115 expectedRsrp.clear();
1116 expectedRsrp << 52 << 56 << 72;
1118 "Piecewise test case 2 - Event A3 with super time-to-trigger",
1119 config,
1120 expectedTime,
1121 expectedRsrp),
1122 TestCase::Duration::QUICK);
1123
1124 // With hysteresis and reportOnLeave
1125 config.hysteresis = 6;
1126 config.reportOnLeave = true;
1127 config.timeToTrigger = 0;
1128 expectedTime.clear();
1129 expectedTime << 800 << 1000 << 1600 << 1840 << 2080 << 2200;
1130 expectedRsrp.clear();
1131 expectedRsrp << 52 << 72 << 52 << 56 << 59 << 72;
1133 new LteUeMeasurementsPiecewiseTestCase2("Piecewise test case 2 - Event A3 with hysteresis",
1134 config,
1135 expectedTime,
1136 expectedRsrp),
1137 TestCase::Duration::QUICK);
1138
1139 // With negative offset
1140 config.a3Offset = -7;
1141 config.hysteresis = 0;
1142 config.reportOnLeave = false;
1143 expectedTime.clear();
1144 expectedTime << 400 << 800 << 1200 << 1440 << 1680 << 1920 << 2160;
1145 expectedRsrp.clear();
1146 expectedRsrp << 63 << 52 << 59 << 56 << 52 << 56 << 59;
1148 "Piecewise test case 2 - Event A3 with negative offset",
1149 config,
1150 expectedTime,
1151 expectedRsrp),
1152 TestCase::Duration::EXTENSIVE);
1153
1154 // === Event A4 (neighbour becomes better than threshold) ===
1155
1156 // With very low threshold
1158 config.threshold1.range = 0;
1159 config.a3Offset = 0;
1160 expectedTime.clear();
1161 expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
1162 expectedRsrp.clear();
1163 expectedRsrp << 73 << 63 << 72 << 52 << 72 << 56 << 52 << 56 << 59;
1165 "Piecewise test case 2 - Event A4 with very low threshold",
1166 config,
1167 expectedTime,
1168 expectedRsrp),
1169 TestCase::Duration::QUICK);
1170
1171 // With normal threshold
1172 config.threshold1.range = 58;
1173 expectedTime.clear();
1174 expectedTime << 400 << 800 << 1400 << 1640 << 1880;
1175 expectedRsrp.clear();
1176 expectedRsrp << 63 << 52 << 56 << 52 << 56;
1178 "Piecewise test case 2 - Event A4 with normal threshold",
1179 config,
1180 expectedTime,
1181 expectedRsrp),
1182 TestCase::Duration::EXTENSIVE);
1183
1184 // With short time-to-trigger
1185 config.timeToTrigger = 160;
1186 expectedTime.clear();
1187 expectedTime << 560 << 960 << 1560 << 1800 << 2040;
1188 expectedRsrp.clear();
1189 expectedRsrp << 63 << 52 << 56 << 56 << 59;
1191 "Piecewise test case 2 - Event A4 with short time-to-trigger",
1192 config,
1193 expectedTime,
1194 expectedRsrp),
1195 TestCase::Duration::QUICK);
1196
1197 // With super time-to-trigger
1198 config.timeToTrigger = 320;
1199 expectedTime.clear();
1200 expectedTime << 1720 << 1960 << 2200;
1201 expectedRsrp.clear();
1202 expectedRsrp << 52 << 56 << 72;
1204 "Piecewise test case 2 - Event A4 with super time-to-trigger",
1205 config,
1206 expectedTime,
1207 expectedRsrp),
1208 TestCase::Duration::TAKES_FOREVER);
1209
1210 // With hysteresis
1211 config.hysteresis = 6;
1212 config.timeToTrigger = 0;
1213 expectedTime.clear();
1214 expectedTime << 400 << 800 << 1600 << 1840 << 2080;
1215 expectedRsrp.clear();
1216 expectedRsrp << 63 << 52 << 52 << 56 << 59;
1218 new LteUeMeasurementsPiecewiseTestCase2("Piecewise test case 2 - Event A4 with hysteresis",
1219 config,
1220 expectedTime,
1221 expectedRsrp),
1222 TestCase::Duration::QUICK);
1223
1224 // With very high threshold
1225 config.threshold1.range = 97;
1226 config.hysteresis = 0;
1227 expectedTime.clear();
1228 expectedRsrp.clear();
1230 "Piecewise test case 2 - Event A4 with very high threshold",
1231 config,
1232 expectedTime,
1233 expectedRsrp),
1234 TestCase::Duration::TAKES_FOREVER);
1235
1236 // === Event A5 (PCell becomes worse than absolute threshold1 AND neighbour becomes better than
1237 // another absolute threshold2) ===
1238
1239 // With low-low threshold
1241 config.threshold1.range = 0;
1242 config.threshold2.range = 0;
1243 expectedTime.clear();
1244 expectedRsrp.clear();
1246 "Piecewise test case 2 - Event A5 with low-low threshold",
1247 config,
1248 expectedTime,
1249 expectedRsrp),
1250 TestCase::Duration::EXTENSIVE);
1251
1252 // With low-normal threshold
1253 config.threshold2.range = 58;
1255 "Piecewise test case 2 - Event A5 with low-normal threshold",
1256 config,
1257 expectedTime,
1258 expectedRsrp),
1259 TestCase::Duration::TAKES_FOREVER);
1260
1261 // With low-high threshold
1262 config.threshold2.range = 97;
1264 "Piecewise test case 2 - Event A5 with low-high threshold",
1265 config,
1266 expectedTime,
1267 expectedRsrp),
1268 TestCase::Duration::TAKES_FOREVER);
1269
1270 // With normal-low threshold
1271 config.threshold1.range = 58;
1272 config.threshold2.range = 0;
1273 expectedTime.clear();
1274 expectedTime << 800 << 1400 << 1640 << 1880;
1275 expectedRsrp.clear();
1276 expectedRsrp << 52 << 56 << 52 << 56;
1278 "Piecewise test case 2 - Event A5 with normal-low threshold",
1279 config,
1280 expectedTime,
1281 expectedRsrp),
1282 TestCase::Duration::EXTENSIVE);
1283
1284 // With normal-normal threshold
1285 config.threshold2.range = 58;
1286 expectedTime.clear();
1287 expectedTime << 800 << 1400 << 1640 << 1880;
1288 expectedRsrp.clear();
1289 expectedRsrp << 52 << 56 << 52 << 56;
1291 "Piecewise test case 2 - Event A5 with normal-normal threshold",
1292 config,
1293 expectedTime,
1294 expectedRsrp),
1295 TestCase::Duration::EXTENSIVE);
1296
1297 // With short time-to-trigger
1298 config.timeToTrigger = 160;
1299 expectedTime.clear();
1300 expectedTime << 960 << 1560 << 1800 << 2040;
1301 expectedRsrp.clear();
1302 expectedRsrp << 52 << 56 << 56 << 59;
1304 "Piecewise test case 2 - Event A5 with short time-to-trigger",
1305 config,
1306 expectedTime,
1307 expectedRsrp),
1308 TestCase::Duration::TAKES_FOREVER);
1309
1310 // With super time-to-trigger
1311 config.timeToTrigger = 320;
1312 expectedTime.clear();
1313 expectedTime << 1720 << 1960 << 2200;
1314 expectedRsrp.clear();
1315 expectedRsrp << 52 << 56 << 72;
1317 "Piecewise test case 2 - Event A5 with super time-to-trigger",
1318 config,
1319 expectedTime,
1320 expectedRsrp),
1321 TestCase::Duration::QUICK);
1322
1323 // With hysteresis
1324 config.hysteresis = 6;
1325 config.timeToTrigger = 0;
1326 expectedTime.clear();
1327 expectedTime << 800 << 1600 << 1840 << 2080;
1328 expectedRsrp.clear();
1329 expectedRsrp << 52 << 52 << 56 << 59;
1331 new LteUeMeasurementsPiecewiseTestCase2("Piecewise test case 2 - Event A5 with hysteresis",
1332 config,
1333 expectedTime,
1334 expectedRsrp),
1335 TestCase::Duration::QUICK);
1336
1337 // With normal-high threshold
1338 config.threshold2.range = 97;
1339 config.hysteresis = 0;
1340 expectedTime.clear();
1341 expectedRsrp.clear();
1343 "Piecewise test case 2 - Event A5 with normal-high threshold",
1344 config,
1345 expectedTime,
1346 expectedRsrp),
1347 TestCase::Duration::TAKES_FOREVER);
1348
1349 // With high-low threshold
1350 config.threshold1.range = 97;
1351 config.threshold2.range = 0;
1352 expectedTime.clear();
1353 expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
1354 expectedRsrp.clear();
1355 expectedRsrp << 73 << 63 << 72 << 52 << 72 << 56 << 52 << 56 << 59;
1357 "Piecewise test case 2 - Event A5 with high-low threshold",
1358 config,
1359 expectedTime,
1360 expectedRsrp),
1361 TestCase::Duration::EXTENSIVE);
1362
1363 // With high-normal threshold
1364 config.threshold2.range = 58;
1365 expectedTime.clear();
1366 expectedTime << 400 << 800 << 1400 << 1640 << 1880;
1367 expectedRsrp.clear();
1368 expectedRsrp << 63 << 52 << 56 << 52 << 56;
1370 "Piecewise test case 2 - Event A5 with high-normal threshold",
1371 config,
1372 expectedTime,
1373 expectedRsrp),
1374 TestCase::Duration::TAKES_FOREVER);
1375
1376 // With high-high threshold
1377 config.threshold2.range = 97;
1378 expectedTime.clear();
1379 expectedRsrp.clear();
1381 "Piecewise test case 2 - Event A5 with high-high threshold",
1382 config,
1383 expectedTime,
1384 expectedRsrp),
1385 TestCase::Duration::EXTENSIVE);
1386
1387} // end of LteUeMeasurementsPiecewiseTestSuite2::LteUeMeasurementsPiecewiseTestSuite2
1388
1389/**
1390 * @ingroup lte-test
1391 * Static variable for test initialization
1392 */
1394
1395/*
1396 * Test Case
1397 */
1398
1400 std::string name,
1402 std::vector<Time> expectedTime,
1403 std::vector<uint8_t> expectedRsrp)
1404 : TestCase(name),
1405 m_config(config),
1406 m_expectedTime(expectedTime),
1407 m_expectedRsrp(expectedRsrp)
1408{
1409 // input sanity check
1410 uint16_t size = m_expectedTime.size();
1411
1412 if (size != m_expectedRsrp.size())
1413 {
1414 NS_FATAL_ERROR("Vectors of expected results are not of the same size");
1415 }
1416
1419
1420 NS_LOG_INFO(this << " name=" << name);
1421}
1422
1427
1428void
1430{
1431 NS_LOG_INFO(this << " " << GetName());
1432
1434 lteHelper->SetAttribute("PathlossModel", StringValue("ns3::FriisSpectrumPropagationLossModel"));
1435 lteHelper->SetAttribute("UseIdealRrc", BooleanValue(true));
1436
1437 // Disable Uplink Power Control
1438 Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false));
1439
1440 // Create Nodes: eNodeB and UE
1441 NodeContainer enbNodes;
1442 NodeContainer ueNodes;
1443 enbNodes.Create(2);
1444 ueNodes.Create(1);
1445
1446 /*
1447 * The topology is the following:
1448 *
1449 * eNodeB UE eNodeB
1450 * | | |
1451 * x ---- x --------------- x ------- x --------------- x ---- x
1452 * 50 m | 200 m | 100 m | 200 m | 50 m
1453 * | | | |
1454 * VeryNear Near Far VeryFar
1455 */
1456
1458 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // Serving eNodeB
1459 positionAlloc->Add(Vector(600.0, 0.0, 0.0)); // Neighbour eNodeB
1460 positionAlloc->Add(Vector(50.0, 0.0, 0.0)); // UE
1461 MobilityHelper mobility;
1462 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
1463 mobility.SetPositionAllocator(positionAlloc);
1464 mobility.Install(enbNodes);
1465 mobility.Install(ueNodes);
1466 m_ueMobility = ueNodes.Get(0)->GetObject<MobilityModel>();
1467
1468 // Disable layer-3 filtering
1469 Config::SetDefault("ns3::LteEnbRrc::RsrpFilterCoefficient", UintegerValue(0));
1470
1471 // Create Devices and install them in the Nodes (eNB and UE)
1472 NetDeviceContainer enbDevs;
1473 NetDeviceContainer ueDevs;
1474 lteHelper->SetSchedulerType("ns3::RrFfMacScheduler");
1475 lteHelper->SetSchedulerAttribute("UlCqiFilter", EnumValue(FfMacScheduler::PUSCH_UL_CQI));
1476 enbDevs = lteHelper->InstallEnbDevice(enbNodes);
1477 ueDevs = lteHelper->InstallUeDevice(ueNodes);
1478
1479 // Setup UE measurement configuration in serving cell
1480 Ptr<LteEnbRrc> enbRrc1 = enbDevs.Get(0)->GetObject<LteEnbNetDevice>()->GetRrc();
1481 m_expectedMeasId = enbRrc1->AddUeMeasReportConfig(m_config).at(0);
1482
1483 // Disable handover in neighbour cell
1484 Ptr<LteEnbRrc> enbRrc2 = enbDevs.Get(1)->GetObject<LteEnbNetDevice>()->GetRrc();
1485 enbRrc2->SetAttribute("AdmitHandoverRequest", BooleanValue(false));
1486
1487 // Attach UE to serving eNodeB
1488 lteHelper->Attach(ueDevs.Get(0), enbDevs.Get(0));
1489
1490 // Activate an EPS bearer
1492 EpsBearer bearer(q);
1493 lteHelper->ActivateDataRadioBearer(ueDevs, bearer);
1494
1495 // Connect to trace sources in serving eNodeB
1497 "/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
1499
1500 /*
1501 * Schedule "teleports"
1502 * 0 1 2
1503 * +-------------------+-------------------+---------> time
1504 * VeryNear |------ ---- ---- --------
1505 * Near | ---- ----
1506 * Far | ---- ----
1507 * VeryFar | -- ---- ----
1508 */
1511 this);
1514 this);
1517 this);
1520 this);
1523 this);
1526 this);
1529 this);
1532 this);
1535 this);
1538 this);
1539
1540 // Run simulation
1541 Simulator::Stop(Seconds(2.201));
1544}
1545
1546void
1548{
1549 NS_LOG_FUNCTION(this);
1550 bool hasEnded = m_itExpectedTime == m_expectedTime.end();
1551 NS_TEST_ASSERT_MSG_EQ(hasEnded,
1552 true,
1553 "Reporting should have occurred at " << m_itExpectedTime->As(Time::S));
1554 hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
1555 NS_ASSERT(hasEnded);
1556}
1557
1558void
1560 std::string context,
1561 uint64_t imsi,
1562 uint16_t cellId,
1563 uint16_t rnti,
1565{
1566 NS_LOG_FUNCTION(this << context);
1567 NS_ASSERT(rnti == 1);
1568 NS_ASSERT(cellId == 1);
1569
1570 if (report.measResults.measId != m_expectedMeasId)
1571 {
1572 return;
1573 }
1574
1575 // verifying the report completeness
1576 LteRrcSap::MeasResults measResults = report.measResults;
1578 this << " Serving cellId=" << cellId
1579 << " rsrp=" << (uint16_t)measResults.measResultPCell.rsrpResult << " ("
1581 << " dBm)"
1582 << " rsrq=" << (uint16_t)measResults.measResultPCell.rsrqResult << " ("
1584 << " dB)");
1585
1586 // verifying reported best cells
1587 if (measResults.measResultListEutra.empty())
1588 {
1590 false,
1591 "Unexpected report content");
1592 }
1593 else
1594 {
1596 true,
1597 "Unexpected report content");
1598 auto it = measResults.measResultListEutra.begin();
1599 NS_ASSERT(it != measResults.measResultListEutra.end());
1600 NS_ASSERT(it->physCellId == 2);
1601 NS_TEST_ASSERT_MSG_EQ(it->haveCgiInfo,
1602 false,
1603 "Report contains cgi-info, which is not supported");
1604 NS_TEST_ASSERT_MSG_EQ(it->haveRsrpResult,
1605 true,
1606 "Report does not contain measured RSRP result");
1607 NS_TEST_ASSERT_MSG_EQ(it->haveRsrqResult,
1608 true,
1609 "Report does not contain measured RSRQ result");
1610 NS_LOG_DEBUG(this << " Neighbour cellId=" << it->physCellId
1611 << " rsrp=" << (uint16_t)it->rsrpResult << " ("
1612 << EutranMeasurementMapping::RsrpRange2Dbm(it->rsrpResult) << " dBm)"
1613 << " rsrq=" << (uint16_t)it->rsrqResult << " ("
1614 << EutranMeasurementMapping::RsrqRange2Db(it->rsrqResult) << " dB)");
1615 }
1616
1617 // verifying the report timing
1618 bool hasEnded = m_itExpectedTime == m_expectedTime.end();
1619 NS_TEST_ASSERT_MSG_EQ(hasEnded,
1620 false,
1621 "Reporting should not have occurred at " << Simulator::Now().As(Time::S));
1622 if (hasEnded)
1623 {
1624 return;
1625 }
1626
1627 hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
1628 NS_ASSERT(!hasEnded);
1629
1630 // using milliseconds to avoid floating-point comparison
1631 uint64_t timeNowMs = Simulator::Now().GetMilliSeconds();
1632 uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds();
1634
1635 uint16_t observedRsrp = measResults.measResultPCell.rsrpResult;
1636 uint16_t referenceRsrp = *m_itExpectedRsrp;
1638
1639 NS_TEST_ASSERT_MSG_EQ(timeNowMs,
1640 timeExpectedMs,
1641 "Reporting should not have occurred at this time");
1642 NS_TEST_ASSERT_MSG_EQ(observedRsrp,
1643 referenceRsrp,
1644 "The RSRP observed differs with the reference RSRP");
1645}
1646
1647void
1649{
1650 NS_LOG_FUNCTION(this);
1651 m_ueMobility->SetPosition(Vector(50.0, 0.0, 0.0));
1652}
1653
1654void
1656{
1657 NS_LOG_FUNCTION(this);
1658 m_ueMobility->SetPosition(Vector(250.0, 0.0, 0.0));
1659}
1660
1661void
1663{
1664 NS_LOG_FUNCTION(this);
1665 m_ueMobility->SetPosition(Vector(350.0, 0.0, 0.0));
1666}
1667
1668void
1670{
1671 NS_LOG_FUNCTION(this);
1672 m_ueMobility->SetPosition(Vector(550.0, 0.0, 0.0));
1673}
1674
1675// ===== LTE-UE-MEASUREMENTS-PIECEWISE-3 TEST SUITE ======================== //
1676
1677/*
1678 * Test Suite
1679 */
1680
1682 : TestSuite("lte-ue-measurements-piecewise-3", Type::SYSTEM)
1683{
1684 std::vector<Time> expectedTime;
1685
1686 // === Event A4 (neighbor becomes better than threshold) ===
1687
1688 // The threshold value was chosen to achieve the following:
1689 // 1. Neighbor 1 (eNB2) RSRP would be above the chosen threshold, hence,
1690 // the UE will include it in its reports to its eNB (eNB1) from the beginning
1691 // of the simulation.
1692 // 2. When neighbor 2 (eNB3) is placed at a very far position, its RSRP would
1693 // be less than the chosen threshold, hence, UE will not include it in its
1694 // initial report(s) to its eNB.
1695 // 3. When neighbor 2 (eNB3) is placed at a near position, its RSRP would
1696 // always be above the chosen threshold, hence, the UE will include it in its
1697 // reports to its eNB (eNB1).
1702 config.threshold1.range = 6;
1705 expectedTime.clear();
1706 expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
1707
1708 AddTestCase(new LteUeMeasurementsPiecewiseTestCase3("Piecewise test case 3 - Event A4",
1709 config,
1710 expectedTime),
1711 TestCase::Duration::QUICK);
1712} // end of LteUeMeasurementsPiecewiseTestSuite3::LteUeMeasurementsPiecewiseTestSuite3
1713
1714/**
1715 * @ingroup lte-test
1716 * Static variable for test initialization
1717 */
1719
1720/*
1721 * Test Case
1722 */
1723
1725 std::string name,
1727 std::vector<Time> expectedTime)
1728 : TestCase(name),
1729 m_config(config),
1730 m_expectedTime(expectedTime)
1731{
1732 m_expectedMeasId = std::numeric_limits<uint8_t>::max();
1733
1735
1736 NS_LOG_INFO(this << " name=" << name);
1737}
1738
1743
1744void
1746{
1747 NS_LOG_INFO(this << " " << GetName());
1748
1750 lteHelper->SetAttribute("PathlossModel", StringValue("ns3::FriisSpectrumPropagationLossModel"));
1751 lteHelper->SetAttribute("UseIdealRrc", BooleanValue(true));
1752
1753 // Disable Uplink Power Control
1754 Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false));
1755
1756 // Create Nodes: eNodeB and UE
1757 NodeContainer enbNodes;
1758 NodeContainer ueNodes;
1759 enbNodes.Create(3);
1760 ueNodes.Create(1);
1761
1762 /*
1763 * The topology is the following:
1764 *
1765 * We place the 3rd eNB initially very far so it does not fulfills
1766 * the entry condition to be reported.
1767 *
1768 * eNodeB UE eNodeB eNodeB
1769 * | | | |
1770 * x ---- x --------------- x -------------- x ---------------------x
1771 * 50 m 100 m 500 | 1000000
1772 * Near
1773 */
1774
1776 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // Serving eNodeB
1777 positionAlloc->Add(Vector(200.0, 0.0, 0.0)); // Neighbour eNodeB1
1778 positionAlloc->Add(Vector(1000700.0, 0.0, 0.0)); // Neighbour eNodeB2
1779 positionAlloc->Add(Vector(50.0, 0.0, 0.0)); // UE
1780 MobilityHelper mobility;
1781 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
1782 mobility.SetPositionAllocator(positionAlloc);
1783 mobility.Install(enbNodes);
1784 mobility.Install(ueNodes);
1785 m_enbMobility = enbNodes.Get(2)->GetObject<MobilityModel>();
1786
1787 // Disable layer-3 filtering
1788 Config::SetDefault("ns3::LteEnbRrc::RsrpFilterCoefficient", UintegerValue(0));
1789
1790 // Create Devices and install them in the Nodes (eNB and UE)
1791 NetDeviceContainer enbDevs;
1792 NetDeviceContainer ueDevs;
1793 lteHelper->SetSchedulerType("ns3::RrFfMacScheduler");
1794 lteHelper->SetSchedulerAttribute("UlCqiFilter", EnumValue(FfMacScheduler::PUSCH_UL_CQI));
1795 enbDevs = lteHelper->InstallEnbDevice(enbNodes);
1796 ueDevs = lteHelper->InstallUeDevice(ueNodes);
1797
1798 // Setup UE measurement configuration in serving cell
1799 Ptr<LteEnbRrc> enbRrc1 = enbDevs.Get(0)->GetObject<LteEnbNetDevice>()->GetRrc();
1800 m_expectedMeasId = enbRrc1->AddUeMeasReportConfig(m_config).at(0);
1801
1802 // Disable handover in neighbour cells
1803 Ptr<LteEnbRrc> enbRrc2 = enbDevs.Get(1)->GetObject<LteEnbNetDevice>()->GetRrc();
1804 enbRrc2->SetAttribute("AdmitHandoverRequest", BooleanValue(false));
1805 Ptr<LteEnbRrc> enbRrc3 = enbDevs.Get(2)->GetObject<LteEnbNetDevice>()->GetRrc();
1806 enbRrc3->SetAttribute("AdmitHandoverRequest", BooleanValue(false));
1807
1808 // Attach UE to serving eNodeB
1809 lteHelper->Attach(ueDevs.Get(0), enbDevs.Get(0));
1810
1811 // Activate an EPS bearer
1813 EpsBearer bearer(q);
1814 lteHelper->ActivateDataRadioBearer(ueDevs, bearer);
1815
1816 // Connect to trace sources in serving eNodeB
1818 "/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
1820 /*
1821 * Schedule "teleport" for the 2nd neighbour
1822 *
1823 * We bring the 2nd neighbour near once the UE has already scheduled the periodic
1824 * reporting after detecting the 1st neighbour, which ideally should be at
1825 * 200 ms.
1826 */
1829 this);
1830
1831 // Run simulation
1832 Simulator::Stop(Seconds(2.201));
1835}
1836
1837void
1839{
1840 NS_LOG_FUNCTION(this);
1841 bool hasEnded = m_itExpectedTime == m_expectedTime.end();
1842 NS_TEST_ASSERT_MSG_EQ(hasEnded,
1843 true,
1844 "Reporting should have occurred at " << m_itExpectedTime->GetSeconds()
1845 << "s");
1846}
1847
1848void
1850 std::string context,
1851 uint64_t imsi,
1852 uint16_t cellId,
1853 uint16_t rnti,
1855{
1856 NS_LOG_FUNCTION(this << context);
1857 NS_ASSERT(rnti == 1);
1858 NS_ASSERT(cellId == 1);
1859
1860 if (report.measResults.measId != m_expectedMeasId)
1861 {
1862 return;
1863 }
1864
1865 // verifying the report completeness
1866 LteRrcSap::MeasResults measResults = report.measResults;
1868 this << " Serving cellId=" << cellId
1869 << " rsrp=" << (uint16_t)measResults.measResultPCell.rsrpResult << " ("
1871 << " dBm)"
1872 << " rsrq=" << (uint16_t)measResults.measResultPCell.rsrqResult << " ("
1874 << " dB)");
1875
1876 // verifying reported best cells
1877 if (measResults.measResultListEutra.empty())
1878 {
1880 false,
1881 "Unexpected report content");
1882 }
1883 else
1884 {
1886 true,
1887 "Unexpected report content");
1888 auto it = measResults.measResultListEutra.begin();
1889 NS_ASSERT(it != measResults.measResultListEutra.end());
1890 for (const auto& it : measResults.measResultListEutra)
1891 {
1892 NS_ASSERT(it.physCellId == 2 || it.physCellId == 3);
1893 NS_TEST_ASSERT_MSG_EQ(it.haveCgiInfo,
1894 false,
1895 "Report contains cgi-info, which is not supported");
1896 NS_TEST_ASSERT_MSG_EQ(it.haveRsrpResult,
1897 true,
1898 "Report does not contain measured RSRP result");
1899 NS_TEST_ASSERT_MSG_EQ(it.haveRsrqResult,
1900 true,
1901 "Report does not contain measured RSRQ result");
1902 NS_LOG_DEBUG(this << " Neighbour cellId=" << it.physCellId
1903 << " rsrp=" << (uint16_t)it.rsrpResult << " ("
1904 << EutranMeasurementMapping::RsrpRange2Dbm(it.rsrpResult) << " dBm)"
1905 << " rsrq=" << (uint16_t)it.rsrqResult << " ("
1906 << EutranMeasurementMapping::RsrqRange2Db(it.rsrqResult) << " dB)");
1907 }
1908 }
1909
1910 // verifying the report timing
1911 bool hasEnded = m_itExpectedTime == m_expectedTime.end();
1912 NS_TEST_ASSERT_MSG_EQ(hasEnded,
1913 false,
1914 "Reporting should not have occurred at " << Simulator::Now().GetSeconds()
1915 << "s");
1916 if (hasEnded)
1917 {
1918 return;
1919 }
1920
1921 // using milliseconds to avoid floating-point comparison
1922 uint64_t timeNowMs = Simulator::Now().GetMilliSeconds();
1923 uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds();
1925
1926 NS_TEST_ASSERT_MSG_EQ(timeNowMs,
1927 timeExpectedMs,
1928 "Reporting should not have occurred at this time");
1929}
1930
1931void
1933{
1934 NS_LOG_FUNCTION(this);
1935 m_enbMobility->SetPosition(Vector(700.0, 0.0, 0.0));
1936}
1937
1938// ===== LTE-UE-MEASUREMENTS-HANDOVER TEST SUITE =========================== //
1939
1940/*
1941 * Test Suite
1942 */
1943
1945 : TestSuite("lte-ue-measurements-handover", Type::SYSTEM)
1946{
1947 std::list<LteRrcSap::ReportConfigEutra> sourceConfigList;
1948 std::list<LteRrcSap::ReportConfigEutra> targetConfigList;
1949 std::vector<Time> expectedTime;
1950 std::vector<uint8_t> expectedRsrp;
1951
1952 LteRrcSap::ReportConfigEutra sourceConfig;
1956 sourceConfig.threshold1.range = 0;
1959 sourceConfigList.push_back(sourceConfig);
1960
1961 LteRrcSap::ReportConfigEutra targetConfig;
1965 targetConfig.threshold1.range = 0;
1968 targetConfigList.push_back(targetConfig);
1969
1970 // === Report interval difference ===
1971
1972 // decreasing report interval
1973 sourceConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS480;
1974 targetConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS240;
1975 expectedTime.clear();
1976 expectedTime << 200 << 680 << 1200 << 1440 << 1680 << 1920;
1977 expectedRsrp.clear();
1978 expectedRsrp << 55 << 55 << 53 << 53 << 53 << 53;
1980 new LteUeMeasurementsHandoverTestCase("Handover test case - decreasing report interval",
1981 sourceConfigList,
1982 targetConfigList,
1983 expectedTime,
1984 expectedRsrp,
1985 Seconds(2)),
1986 TestCase::Duration::TAKES_FOREVER);
1987
1988 // increasing report interval
1989 sourceConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS120;
1990 targetConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS640;
1991 expectedTime.clear();
1992 expectedTime << 200 << 320 << 440 << 560 << 680 << 800 << 920 << 1200 << 1840;
1993 expectedRsrp.clear();
1994 expectedRsrp << 55 << 55 << 55 << 55 << 55 << 55 << 55 << 53 << 53;
1996 new LteUeMeasurementsHandoverTestCase("Handover test case - increasing report interval",
1997 sourceConfigList,
1998 targetConfigList,
1999 expectedTime,
2000 expectedRsrp,
2001 Seconds(2)),
2002 TestCase::Duration::QUICK);
2003
2004 // === Event difference ===
2005
2006 sourceConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS240;
2007 targetConfigList.front().reportInterval = LteRrcSap::ReportConfigEutra::MS240;
2008 sourceConfigList.front().threshold1.range = 54;
2009 sourceConfigList.front().threshold2.range = 54;
2010 sourceConfigList.front().a3Offset = 1;
2011 targetConfigList.front().threshold1.range = 54;
2012 targetConfigList.front().threshold2.range = 54;
2013 targetConfigList.front().a3Offset = 1;
2014
2015 // Event A1 to Event A2
2016 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2017 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2018 expectedTime.clear();
2019 expectedTime << 200 << 440 << 680 << 920 << 1200 << 1440 << 1680 << 1920;
2020 expectedRsrp.clear();
2021 expectedRsrp << 55 << 55 << 55 << 55 << 53 << 53 << 53 << 53;
2022 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A1 to Event A2",
2023 sourceConfigList,
2024 targetConfigList,
2025 expectedTime,
2026 expectedRsrp,
2027 Seconds(2)),
2028 TestCase::Duration::EXTENSIVE);
2029
2030 // Event A2 to Event A1
2031 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2032 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2033 expectedTime.clear();
2034 expectedRsrp.clear();
2035 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A2 to Event A1",
2036 sourceConfigList,
2037 targetConfigList,
2038 expectedTime,
2039 expectedRsrp,
2040 Seconds(2)),
2041 TestCase::Duration::TAKES_FOREVER);
2042
2043 // Event A3 to Event A4
2044 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2045 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2046 expectedTime.clear();
2047 expectedTime << 1200 << 1440 << 1680 << 1920;
2048 expectedRsrp.clear();
2049 expectedRsrp << 53 << 53 << 53 << 53;
2050 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A3 to Event A4",
2051 sourceConfigList,
2052 targetConfigList,
2053 expectedTime,
2054 expectedRsrp,
2055 Seconds(2)),
2056 TestCase::Duration::TAKES_FOREVER);
2057
2058 // Event A4 to Event A3
2059 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2060 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2061 expectedTime.clear();
2062 expectedTime << 1200 << 1440 << 1680 << 1920;
2063 expectedRsrp.clear();
2064 expectedRsrp << 53 << 53 << 53 << 53;
2065 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A4 to Event A3",
2066 sourceConfigList,
2067 targetConfigList,
2068 expectedTime,
2069 expectedRsrp,
2070 Seconds(2)),
2071 TestCase::Duration::QUICK);
2072
2073 // Event A2 to Event A3
2074 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2075 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2076 expectedTime.clear();
2077 expectedTime << 1200 << 1440 << 1680 << 1920;
2078 expectedRsrp.clear();
2079 expectedRsrp << 53 << 53 << 53 << 53;
2080 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A2 to Event A3",
2081 sourceConfigList,
2082 targetConfigList,
2083 expectedTime,
2084 expectedRsrp,
2085 Seconds(2)),
2086 TestCase::Duration::EXTENSIVE);
2087
2088 // Event A3 to Event A2
2089 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2090 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2091 expectedTime.clear();
2092 expectedTime << 1200 << 1440 << 1680 << 1920;
2093 expectedRsrp.clear();
2094 expectedRsrp << 53 << 53 << 53 << 53;
2095 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A3 to Event A2",
2096 sourceConfigList,
2097 targetConfigList,
2098 expectedTime,
2099 expectedRsrp,
2100 Seconds(2)),
2101 TestCase::Duration::TAKES_FOREVER);
2102
2103 // Event A4 to Event A5
2104 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2105 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
2106 expectedTime.clear();
2107 expectedTime << 1200 << 1440 << 1680 << 1920;
2108 expectedRsrp.clear();
2109 expectedRsrp << 53 << 53 << 53 << 53;
2110 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A4 to Event A5",
2111 sourceConfigList,
2112 targetConfigList,
2113 expectedTime,
2114 expectedRsrp,
2115 Seconds(2)),
2116 TestCase::Duration::TAKES_FOREVER);
2117
2118 // Event A5 to Event A4
2119 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
2120 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2121 expectedTime.clear();
2122 expectedTime << 1200 << 1440 << 1680 << 1920;
2123 expectedRsrp.clear();
2124 expectedRsrp << 53 << 53 << 53 << 53;
2125 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - Event A5 to Event A4",
2126 sourceConfigList,
2127 targetConfigList,
2128 expectedTime,
2129 expectedRsrp,
2130 Seconds(2)),
2131 TestCase::Duration::EXTENSIVE);
2132
2133 // === Threshold/offset difference ===
2134
2135 sourceConfigList.front().threshold1.range = 52;
2136 targetConfigList.front().threshold1.range = 56;
2137
2138 // Event A1
2139 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2140 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2141 expectedTime.clear();
2142 expectedTime << 200 << 440 << 680 << 920;
2143 expectedRsrp.clear();
2144 expectedRsrp << 55 << 55 << 55 << 55;
2146 new LteUeMeasurementsHandoverTestCase("Handover test case - Event A1 threshold difference",
2147 sourceConfigList,
2148 targetConfigList,
2149 expectedTime,
2150 expectedRsrp,
2151 Seconds(2)),
2152 TestCase::Duration::EXTENSIVE);
2153
2154 // Event A2
2155 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2156 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
2157 expectedTime.clear();
2158 expectedTime << 1200 << 1440 << 1680 << 1920;
2159 expectedRsrp.clear();
2160 expectedRsrp << 53 << 53 << 53 << 53;
2162 new LteUeMeasurementsHandoverTestCase("Handover test case - Event A2 threshold difference",
2163 sourceConfigList,
2164 targetConfigList,
2165 expectedTime,
2166 expectedRsrp,
2167 Seconds(2)),
2168 TestCase::Duration::QUICK);
2169
2170 // Event A3
2171 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2172 sourceConfigList.front().a3Offset = -30;
2173 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
2174 targetConfigList.front().a3Offset = 30;
2175 expectedTime.clear();
2176 expectedTime << 200 << 440 << 680 << 920;
2177 expectedRsrp.clear();
2178 expectedRsrp << 55 << 55 << 55 << 55;
2180 new LteUeMeasurementsHandoverTestCase("Handover test case - Event A3 offset difference",
2181 sourceConfigList,
2182 targetConfigList,
2183 expectedTime,
2184 expectedRsrp,
2185 Seconds(2)),
2186 TestCase::Duration::QUICK);
2187
2188 // Event A4
2189 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2190 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
2191 expectedTime.clear();
2192 expectedTime << 200 << 440 << 680 << 920;
2193 expectedRsrp.clear();
2194 expectedRsrp << 55 << 55 << 55 << 55;
2196 new LteUeMeasurementsHandoverTestCase("Handover test case - Event A4 threshold difference",
2197 sourceConfigList,
2198 targetConfigList,
2199 expectedTime,
2200 expectedRsrp,
2201 Seconds(2)),
2202 TestCase::Duration::EXTENSIVE);
2203
2204 // Event A5
2205 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
2206 sourceConfigList.front().threshold2.range = 52;
2207 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
2208 targetConfigList.front().threshold2.range = 56;
2209 expectedTime.clear();
2210 expectedRsrp.clear();
2212 new LteUeMeasurementsHandoverTestCase("Handover test case - Event A5 threshold difference",
2213 sourceConfigList,
2214 targetConfigList,
2215 expectedTime,
2216 expectedRsrp,
2217 Seconds(2)),
2218 TestCase::Duration::EXTENSIVE);
2219
2220 // === Time-to-trigger (TTT) difference ===
2221
2222 sourceConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2223 sourceConfigList.front().a3Offset = 1;
2224 sourceConfigList.front().threshold1.range = 0;
2225 sourceConfigList.front().threshold2.range = 0;
2226 targetConfigList.front().eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
2227 targetConfigList.front().a3Offset = 1;
2228 targetConfigList.front().threshold1.range = 0;
2229 targetConfigList.front().threshold2.range = 0;
2230
2231 // decreasing time-to-trigger (short duration)
2232 sourceConfigList.front().timeToTrigger = 1024;
2233 targetConfigList.front().timeToTrigger = 100;
2234 expectedTime.clear();
2235 expectedTime << 1300 << 1540 << 1780;
2236 expectedRsrp.clear();
2237 expectedRsrp << 53 << 53 << 53;
2238 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - decreasing TTT (short)",
2239 sourceConfigList,
2240 targetConfigList,
2241 expectedTime,
2242 expectedRsrp,
2243 Seconds(2)),
2244 TestCase::Duration::QUICK);
2245
2246 // decreasing time-to-trigger (longer duration)
2247 sourceConfigList.front().timeToTrigger = 1024;
2248 targetConfigList.front().timeToTrigger = 640;
2249 expectedTime.clear();
2250 expectedTime << 1224 << 1464 << 1704 << 1944 << 2840 << 3080 << 3320 << 3560 << 3800 << 4040;
2251 expectedRsrp.clear();
2252 expectedRsrp << 55 << 55 << 55 << 55 << 53 << 53 << 53 << 53 << 53 << 53;
2253 AddTestCase(new LteUeMeasurementsHandoverTestCase("Handover test case - decreasing TTT (long)",
2254 sourceConfigList,
2255 targetConfigList,
2256 expectedTime,
2257 expectedRsrp,
2258 Seconds(4.2)),
2259 TestCase::Duration::EXTENSIVE);
2260
2261} // end of LteUeMeasurementsHandoverTestSuite::LteUeMeasurementsHandoverTestSuite
2262
2263/**
2264 * @ingroup lte-test
2265 * Static variable for test initialization
2266 */
2268
2269/*
2270 * Test Case
2271 */
2272
2274 std::string name,
2275 std::list<LteRrcSap::ReportConfigEutra> sourceConfigList,
2276 std::list<LteRrcSap::ReportConfigEutra> targetConfigList,
2277 std::vector<Time> expectedTime,
2278 std::vector<uint8_t> expectedRsrp,
2279 Time duration)
2280 : TestCase(name),
2281 m_sourceConfigList(sourceConfigList),
2282 m_targetConfigList(targetConfigList),
2283 m_expectedTime(expectedTime),
2284 m_expectedRsrp(expectedRsrp),
2285 m_duration(duration)
2286{
2287 // input sanity check
2288 uint16_t size = m_expectedTime.size();
2289
2290 if (size != m_expectedRsrp.size())
2291 {
2292 NS_FATAL_ERROR("Vectors of expected results are not of the same size");
2293 }
2294
2297
2298 NS_LOG_INFO(this << " name=" << name);
2299}
2300
2305
2306void
2308{
2309 NS_LOG_INFO(this << " " << GetName());
2310
2313 lteHelper->SetEpcHelper(epcHelper);
2314 lteHelper->SetAttribute("PathlossModel", StringValue("ns3::FriisSpectrumPropagationLossModel"));
2315 lteHelper->SetAttribute("UseIdealRrc", BooleanValue(true));
2316
2317 // Disable Uplink Power Control
2318 Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false));
2319
2320 // Create Nodes: eNodeB and UE
2321 NodeContainer enbNodes;
2322 NodeContainer ueNodes;
2323 enbNodes.Create(2);
2324 ueNodes.Create(1);
2325
2326 /*
2327 * The topology is the following:
2328 *
2329 * eNodeB UE eNodeB
2330 * | | |
2331 * x ------------------- x ----------------------- x
2332 * 400 m 500 m
2333 */
2334
2336 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // Source eNodeB
2337 positionAlloc->Add(Vector(900.0, 0.0, 0.0)); // Target eNodeB
2338 positionAlloc->Add(Vector(400.0, 0.0, 0.0)); // UE
2339 MobilityHelper mobility;
2340 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2341 mobility.SetPositionAllocator(positionAlloc);
2342 mobility.Install(enbNodes);
2343 mobility.Install(ueNodes);
2344
2345 // Create P-GW node
2346 Ptr<Node> pgw = epcHelper->GetPgwNode();
2347
2348 // Create a single RemoteHost
2349 NodeContainer remoteHostContainer;
2350 remoteHostContainer.Create(1);
2351 Ptr<Node> remoteHost = remoteHostContainer.Get(0);
2352 InternetStackHelper internet;
2353 internet.Install(remoteHostContainer);
2354
2355 // Create the Internet
2356 PointToPointHelper p2ph;
2357 p2ph.SetDeviceAttribute("DataRate", DataRateValue(DataRate("100Gb/s")));
2358 p2ph.SetDeviceAttribute("Mtu", UintegerValue(1500));
2359 p2ph.SetChannelAttribute("Delay", TimeValue(Seconds(0.010)));
2360 NetDeviceContainer internetDevices = p2ph.Install(pgw, remoteHost);
2361 Ipv4AddressHelper ipv4h;
2362 ipv4h.SetBase("1.0.0.0", "255.0.0.0");
2363 Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign(internetDevices);
2364
2365 // Routing of the Internet Host (towards the LTE network)
2366 Ipv4StaticRoutingHelper ipv4RoutingHelper;
2367 Ptr<Ipv4StaticRouting> remoteHostStaticRouting =
2368 ipv4RoutingHelper.GetStaticRouting(remoteHost->GetObject<Ipv4>());
2369 remoteHostStaticRouting->AddNetworkRouteTo(Ipv4Address("7.0.0.0"), Ipv4Mask("255.0.0.0"), 1);
2370
2371 // Enable layer-3 filtering
2372 Config::SetDefault("ns3::LteEnbRrc::RsrpFilterCoefficient", UintegerValue(4));
2373
2374 // Disable control channel error model
2375 Config::SetDefault("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue(false));
2376
2377 // Create Devices and install them in the Nodes (eNB and UE)
2378 NetDeviceContainer enbDevs;
2379 NetDeviceContainer ueDevs;
2380 enbDevs = lteHelper->InstallEnbDevice(enbNodes);
2381 ueDevs = lteHelper->InstallUeDevice(ueNodes);
2382
2383 // Setup UE measurement configuration in eNodeBs
2384 uint8_t measId;
2385 Ptr<LteEnbRrc> enbRrc1 = enbDevs.Get(0)->GetObject<LteEnbNetDevice>()->GetRrc();
2386 Ptr<LteEnbRrc> enbRrc2 = enbDevs.Get(1)->GetObject<LteEnbNetDevice>()->GetRrc();
2387
2388 for (auto itReportConfig = m_sourceConfigList.begin();
2389 itReportConfig != m_sourceConfigList.end();
2390 itReportConfig++)
2391 {
2392 measId = enbRrc1->AddUeMeasReportConfig(*itReportConfig).at(0);
2393 m_expectedSourceCellMeasId.insert(measId);
2394 }
2395
2396 for (auto itReportConfig = m_targetConfigList.begin();
2397 itReportConfig != m_targetConfigList.end();
2398 itReportConfig++)
2399 {
2400 measId = enbRrc2->AddUeMeasReportConfig(*itReportConfig).at(0);
2401 m_expectedTargetCellMeasId.insert(measId);
2402 }
2403
2404 // Install the IP stack on the UEs
2405 internet.Install(ueNodes);
2406 Ipv4InterfaceContainer ueIpIfaces;
2407 ueIpIfaces = epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueDevs));
2408
2409 // Assign IP address to UEs
2410 for (uint32_t u = 0; u < ueNodes.GetN(); ++u)
2411 {
2412 Ptr<Node> ueNode = ueNodes.Get(u);
2413 // Set the default gateway for the UE
2414 Ptr<Ipv4StaticRouting> ueStaticRouting =
2415 ipv4RoutingHelper.GetStaticRouting(ueNode->GetObject<Ipv4>());
2416 ueStaticRouting->SetDefaultRoute(epcHelper->GetUeDefaultGatewayAddress(), 1);
2417 }
2418
2419 // Attach UE to serving eNodeB
2420 lteHelper->Attach(ueDevs.Get(0), enbDevs.Get(0));
2421
2422 // Add X2 interface
2423 lteHelper->AddX2Interface(enbNodes);
2424
2425 // Connect to trace sources in source eNodeB
2427 "/NodeList/3/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
2429
2430 // Connect to trace sources in target eNodeB
2432 "/NodeList/4/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
2434
2435 // Schedule handover
2436 lteHelper->HandoverRequest(MilliSeconds(m_duration.GetMilliSeconds() / 2),
2437 ueDevs.Get(0),
2438 enbDevs.Get(0),
2439 enbDevs.Get(1));
2440
2441 // Run simulation
2445}
2446
2447void
2449{
2450 NS_LOG_FUNCTION(this);
2451 bool hasEnded = m_itExpectedTime == m_expectedTime.end();
2452 NS_TEST_ASSERT_MSG_EQ(hasEnded,
2453 true,
2454 "Reporting should have occurred at " << m_itExpectedTime->As(Time::S));
2455 hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
2456 NS_ASSERT(hasEnded);
2457}
2458
2459void
2461 std::string context,
2462 uint64_t imsi,
2463 uint16_t cellId,
2464 uint16_t rnti,
2466{
2467 uint8_t measId = report.measResults.measId;
2468 NS_LOG_FUNCTION(this << context << (uint16_t)measId);
2469
2470 bool isCorrectMeasId;
2471 if (cellId == 1)
2472 {
2473 auto itMeasId = m_expectedSourceCellMeasId.find(measId);
2474 isCorrectMeasId = (itMeasId != m_expectedSourceCellMeasId.end());
2475 }
2476 else if (cellId == 2)
2477 {
2478 auto itMeasId = m_expectedTargetCellMeasId.find(measId);
2479 isCorrectMeasId = (itMeasId != m_expectedTargetCellMeasId.end());
2480 }
2481 else
2482 {
2483 NS_FATAL_ERROR("Invalid cell ID " << cellId);
2484 }
2485
2486 if (!isCorrectMeasId)
2487 {
2488 return;
2489 }
2490
2491 // verifying the report completeness
2492 LteRrcSap::MeasResults measResults = report.measResults;
2494 this << " Serving cellId=" << cellId
2495 << " rsrp=" << (uint16_t)measResults.measResultPCell.rsrpResult << " ("
2497 << " dBm)"
2498 << " rsrq=" << (uint16_t)measResults.measResultPCell.rsrqResult << " ("
2500 << " dB)");
2501
2502 // verifying reported best cells
2503 if (measResults.measResultListEutra.empty())
2504 {
2506 false,
2507 "Unexpected report content");
2508 }
2509 else
2510 {
2512 true,
2513 "Unexpected report content");
2514 auto it = measResults.measResultListEutra.begin();
2515 NS_ASSERT(it != measResults.measResultListEutra.end());
2516 NS_ASSERT(it->physCellId != cellId);
2517 NS_ASSERT(it->physCellId <= 2);
2518 NS_TEST_ASSERT_MSG_EQ(it->haveCgiInfo,
2519 false,
2520 "Report contains cgi-info, which is not supported");
2521 NS_TEST_ASSERT_MSG_EQ(it->haveRsrpResult,
2522 true,
2523 "Report does not contain measured RSRP result");
2524 NS_TEST_ASSERT_MSG_EQ(it->haveRsrqResult,
2525 true,
2526 "Report does not contain measured RSRQ result");
2527 NS_LOG_DEBUG(this << " Neighbour cellId=" << it->physCellId
2528 << " rsrp=" << (uint16_t)it->rsrpResult << " ("
2529 << EutranMeasurementMapping::RsrpRange2Dbm(it->rsrpResult) << " dBm)"
2530 << " rsrq=" << (uint16_t)it->rsrqResult << " ("
2531 << EutranMeasurementMapping::RsrqRange2Db(it->rsrqResult) << " dB)");
2532 }
2533
2534 // verifying the report timing
2535 bool hasEnded = m_itExpectedTime == m_expectedTime.end();
2536 NS_TEST_ASSERT_MSG_EQ(hasEnded,
2537 false,
2538 "Reporting should not have occurred at " << Simulator::Now().As(Time::S));
2539 if (hasEnded)
2540 {
2541 return;
2542 }
2543
2544 hasEnded = m_itExpectedRsrp == m_expectedRsrp.end();
2545 NS_ASSERT(!hasEnded);
2546
2547 // using milliseconds to avoid floating-point comparison
2548 uint64_t timeNowMs = Simulator::Now().GetMilliSeconds();
2549 uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds();
2551
2552 uint16_t observedRsrp = measResults.measResultPCell.rsrpResult;
2553 uint16_t referenceRsrp = *m_itExpectedRsrp;
2555
2556 NS_TEST_ASSERT_MSG_EQ(timeNowMs,
2557 timeExpectedMs,
2558 "Reporting should not have occurred at this time");
2559 NS_TEST_ASSERT_MSG_EQ(observedRsrp,
2560 referenceRsrp,
2561 "The RSRP observed differs with the reference RSRP");
2562}
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:94
int64_t GetMilliSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:397
@ S
second
Definition nstime.h:105
AttributeValue implementation for Time.
Definition nstime.h:1432
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 Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1345
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1357
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
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
const Time UE_MEASUREMENT_REPORT_DELAY
Artificial delay of UE measurements procedure.
Definition lte-ue-rrc.cc:35
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.