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