A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
test-lte-x2-handover-measures.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2013 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors:
7 * Nicola Baldo <nbaldo@cttc.es>
8 * Manuel Requena <manuel.requena@cttc.es>
9 */
10
11#include <ns3/bulk-send-helper.h>
12#include <ns3/core-module.h>
13#include <ns3/internet-module.h>
14#include <ns3/lte-module.h>
15#include <ns3/mobility-module.h>
16#include <ns3/network-module.h>
17#include <ns3/packet-sink-helper.h>
18#include <ns3/packet-sink.h>
19#include <ns3/point-to-point-module.h>
20#include <ns3/udp-client-server-helper.h>
21
22using namespace ns3;
23
24NS_LOG_COMPONENT_DEFINE("LteX2HandoverMeasuresTest");
25
26/**
27 * \ingroup lte-test
28 *
29 * \brief CheckPointEvent structure
30 */
32{
33 Time checkStartTime; ///< check start time
34 Time checkStopTime; ///< check stop time
35 Time checkInterval; ///< check interval
36 uint32_t ueDeviceIndex; ///< UE device index
37 uint32_t enbDeviceIndex; ///< ENB device index
38
39 /**
40 * Constructor
41 *
42 * \param start the start time
43 * \param stop the stop time
44 * \param interval the interval time
45 * \param ueIndex the UE index
46 * \param enbIndex the ENB index
47 */
48 CheckPointEvent(Time start, Time stop, Time interval, uint32_t ueIndex, uint32_t enbIndex)
49 : checkStartTime(start),
50 checkStopTime(stop),
51 checkInterval(interval),
52 ueDeviceIndex(ueIndex),
53 enbDeviceIndex(enbIndex)
54 {
55 }
56};
57
58/**
59 * \ingroup lte-test
60 *
61 * \brief Test different X2 handover measures and algorithms, e.g. A2A4RsrqHandoverAlgorithm and
62 * A3RsrpHandoverAlgorithm. Test defines different handover parameters and scenario configurations.
63 */
65{
66 public:
67 /**
68 * Constructor.
69 *
70 * \param nEnbs number of eNBs in the test
71 * \param nUes number of UEs in the test
72 * \param nDedicatedBearers number of bearers to be activated per UE
73 * \param checkPointEventList list of check point events
74 * \param checkPointEventListName name of check point event list
75 * \param useUdp true if UDP is to be used, false if TCP is to be used
76 * \param schedulerType type of scheduler to be used (e.g. "ns3::PfFfMacScheduler")
77 * \param handoverAlgorithmType type of handover algorithm to be used (e.g.
78 * "ns3::A3RsrpHandoverAlgorithm")
79 * \param admitHo true if Ho is admitted, false if it is not admitted
80 * \param useIdealRrc true if ideal RRC is to be used, false if real RRC is to be used
81 */
83 uint32_t nUes,
84 uint32_t nDedicatedBearers,
85 std::list<CheckPointEvent> checkPointEventList,
86 std::string checkPointEventListName,
87 bool useUdp,
88 std::string schedulerType,
89 std::string handoverAlgorithmType,
90 bool admitHo,
91 bool useIdealRrc);
92
93 private:
94 /**
95 * Build name string
96 * \param nEnbs number of eNBs in the test
97 * \param nUes number of UEs in the test
98 * \param nDedicatedBearers number of bearers to be activated per UE
99 * \param checkPointEventListName name of check point event list
100 * \param useUdp true if UDP is to be used, false if TCP is to be used
101 * \param schedulerType the scheduler type
102 * \param handoverAlgorithmType type of handover algorithm to be used (e.g.
103 * "ns3::A3RsrpHandoverAlgorithm")
104 * \param admitHo true if Ho is admitted, false if it is not admitted
105 * \param useIdealRrc true if the ideal RRC should be used
106 * \returns the name string
107 */
108 static std::string BuildNameString(uint32_t nEnbs,
109 uint32_t nUes,
110 uint32_t nDedicatedBearers,
111 std::string checkPointEventListName,
112 bool useUdp,
113 std::string schedulerType,
114 std::string handoverAlgorithmType,
115 bool admitHo,
116 bool useIdealRrc);
117 void DoRun() override;
118 /**
119 * Check connected function
120 * \param ueDevice the UE device
121 * \param enbDevice the ENB device
122 */
123 void CheckConnected(Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice);
124
125 uint32_t m_nEnbs; ///< number of eNBs in the test
126 uint32_t m_nUes; ///< number of UEs in the test
127 uint32_t m_nDedicatedBearers; ///< number of UEs in the test
128 std::list<CheckPointEvent> m_checkPointEventList; ///< check point event list
129 std::string m_checkPointEventListName; ///< check point event list name
130 bool m_epc; ///< whether to use EPC
131 bool m_useUdp; ///< whether to use UDP traffic
132 std::string m_schedulerType; ///< scheduler type
133 std::string m_handoverAlgorithmType; ///< handover algorithm type
134 bool m_admitHo; ///< whether to configure to admit handover
135 bool m_useIdealRrc; ///< whether to use ideal RRC
138
139 /**
140 * \ingroup lte-test
141 *
142 * \brief BearerData structure
143 */
145 {
146 uint32_t bid; ///< BID
149 uint32_t dlOldTotalRx; ///< DL old total receive
150 uint32_t ulOldTotalRx; ///< UL old total receive
151 };
152
153 /**
154 * \ingroup lte-test
155 *
156 * \brief UeData structure
157 */
158 struct UeData
159 {
160 uint32_t id; ///< ID
161 std::list<BearerData> bearerDataList; ///< bearer ID list
162 };
163
164 /**
165 * \brief Save stats function
166 * \param ueIndex the index of the UE
167 */
168 void SaveStats(uint32_t ueIndex);
169 /**
170 * \brief Check stats function
171 * \param ueIndex the index of the UE
172 */
173 void CheckStats(uint32_t ueIndex);
174
175 std::vector<UeData> m_ueDataVector; ///< UE data vector
176
177 const Time m_maxHoDuration; ///< maximum HO duration
178 const Time m_statsDuration; ///< stats duration
179 const Time m_udpClientInterval; ///< UDP client interval
180 const uint32_t m_udpClientPktSize; ///< UDP client packet size
181};
182
183std::string
185 uint32_t nUes,
186 uint32_t nDedicatedBearers,
187 std::string checkPointEventListName,
188 bool useUdp,
189 std::string schedulerType,
190 std::string handoverAlgorithmType,
191 bool admitHo,
192 bool useIdealRrc)
193{
194 std::ostringstream oss;
195 oss << "nEnbs=" << nEnbs << " nUes=" << nUes << " nDedicatedBearers=" << nDedicatedBearers
196 << " udp=" << useUdp << " " << schedulerType << " " << handoverAlgorithmType
197 << " admitHo=" << admitHo << " hoList: " << checkPointEventListName;
198 if (useIdealRrc)
199 {
200 oss << ", ideal RRC";
201 }
202 else
203 {
204 oss << ", real RRC";
205 }
206 return oss.str();
207}
208
210 uint32_t nEnbs,
211 uint32_t nUes,
212 uint32_t nDedicatedBearers,
213 std::list<CheckPointEvent> checkPointEventList,
214 std::string checkPointEventListName,
215 bool useUdp,
216 std::string schedulerType,
217 std::string handoverAlgorithmType,
218 bool admitHo,
219 bool useIdealRrc)
220 : TestCase(BuildNameString(nEnbs,
221 nUes,
222 nDedicatedBearers,
223 checkPointEventListName,
224 useUdp,
225 schedulerType,
226 handoverAlgorithmType,
227 admitHo,
228 useIdealRrc)),
229 m_nEnbs(nEnbs),
230 m_nUes(nUes),
231 m_nDedicatedBearers(nDedicatedBearers),
232 m_checkPointEventList(checkPointEventList),
233 m_checkPointEventListName(checkPointEventListName),
234 m_epc(true),
235 m_useUdp(useUdp),
236 m_schedulerType(schedulerType),
237 m_handoverAlgorithmType(handoverAlgorithmType),
238 m_admitHo(admitHo),
239 m_useIdealRrc(useIdealRrc),
240 m_maxHoDuration(Seconds(0.1)),
241 m_statsDuration(Seconds(0.5)),
242 m_udpClientInterval(Seconds(0.01)),
243 m_udpClientPktSize(100)
244{
245}
246
247void
249{
251 m_nUes,
254 m_useUdp,
257 m_admitHo,
259
261 Config::SetDefault("ns3::UdpClient::Interval", TimeValue(m_udpClientInterval));
262 Config::SetDefault("ns3::UdpClient::MaxPackets", UintegerValue(1000000));
263 Config::SetDefault("ns3::UdpClient::PacketSize", UintegerValue(m_udpClientPktSize));
264 Config::SetDefault("ns3::LteEnbRrc::HandoverJoiningTimeoutDuration",
265 TimeValue(MilliSeconds(200)));
266 Config::SetDefault("ns3::LteEnbPhy::TxPower", DoubleValue(20));
267
268 // Disable Uplink Power Control
269 Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false));
270
271 int64_t stream = 1;
272
274 m_lteHelper->SetAttribute("PathlossModel",
275 StringValue("ns3::FriisSpectrumPropagationLossModel"));
276 m_lteHelper->SetAttribute("UseIdealRrc", BooleanValue(m_useIdealRrc));
277 m_lteHelper->SetSchedulerType(m_schedulerType);
278
279 if (m_handoverAlgorithmType == "ns3::A2A4RsrqHandoverAlgorithm")
280 {
281 m_lteHelper->SetHandoverAlgorithmType("ns3::A2A4RsrqHandoverAlgorithm");
282 m_lteHelper->SetHandoverAlgorithmAttribute("ServingCellThreshold", UintegerValue(30));
283 m_lteHelper->SetHandoverAlgorithmAttribute("NeighbourCellOffset", UintegerValue(1));
284 }
285 else if (m_handoverAlgorithmType == "ns3::A3RsrpHandoverAlgorithm")
286 {
287 m_lteHelper->SetHandoverAlgorithmType("ns3::A3RsrpHandoverAlgorithm");
288 m_lteHelper->SetHandoverAlgorithmAttribute("Hysteresis", DoubleValue(1.5));
289 m_lteHelper->SetHandoverAlgorithmAttribute("TimeToTrigger", TimeValue(MilliSeconds(128)));
290 }
291 else
292 {
293 NS_FATAL_ERROR("Unknown handover algorithm " << m_handoverAlgorithmType);
294 }
295
296 double distance = 1000.0; // m
297 double speed = 150; // m/s
298
299 NodeContainer enbNodes;
300 enbNodes.Create(m_nEnbs);
301 NodeContainer ueNodes;
302 ueNodes.Create(m_nUes);
303
304 if (m_epc)
305 {
307 m_lteHelper->SetEpcHelper(m_epcHelper);
308 }
309
310 // Install Mobility Model in eNBs
311 // eNBs are located along a line in the X axis
313 for (uint32_t i = 0; i < m_nEnbs; i++)
314 {
315 Vector enbPosition(distance * (i + 1), 0, 0);
316 enbPositionAlloc->Add(enbPosition);
317 }
318 MobilityHelper enbMobility;
319 enbMobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
320 enbMobility.SetPositionAllocator(enbPositionAlloc);
321 enbMobility.Install(enbNodes);
322
323 // Install Mobility Model in UE
324 // UE moves with a constant speed along the X axis
325 MobilityHelper ueMobility;
326 ueMobility.SetMobilityModel("ns3::ConstantVelocityMobilityModel");
327 ueMobility.Install(ueNodes);
328 for (uint32_t i = 0; i < m_nUes; i++)
329 {
330 ueNodes.Get(i)->GetObject<MobilityModel>()->SetPosition(Vector(0, 0, 0));
331 ueNodes.Get(i)->GetObject<ConstantVelocityMobilityModel>()->SetVelocity(
332 Vector(speed, 0, 0));
333 }
334
335 NetDeviceContainer enbDevices;
336 enbDevices = m_lteHelper->InstallEnbDevice(enbNodes);
337 stream += m_lteHelper->AssignStreams(enbDevices, stream);
338 for (auto it = enbDevices.Begin(); it != enbDevices.End(); ++it)
339 {
340 Ptr<LteEnbRrc> enbRrc = (*it)->GetObject<LteEnbNetDevice>()->GetRrc();
341 enbRrc->SetAttribute("AdmitHandoverRequest", BooleanValue(m_admitHo));
342 }
343
344 NetDeviceContainer ueDevices;
345 ueDevices = m_lteHelper->InstallUeDevice(ueNodes);
346 stream += m_lteHelper->AssignStreams(ueDevices, stream);
347
348 Ipv4Address remoteHostAddr;
349 Ipv4StaticRoutingHelper ipv4RoutingHelper;
350 Ipv4InterfaceContainer ueIpIfaces;
351 Ptr<Node> remoteHost;
352 if (m_epc)
353 {
354 // Create a single RemoteHost
355 NodeContainer remoteHostContainer;
356 remoteHostContainer.Create(1);
357 remoteHost = remoteHostContainer.Get(0);
358 InternetStackHelper internet;
359 internet.Install(remoteHostContainer);
360
361 // Create the Internet
363 p2ph.SetDeviceAttribute("DataRate", DataRateValue(DataRate("100Gb/s")));
364 p2ph.SetDeviceAttribute("Mtu", UintegerValue(1500));
365 p2ph.SetChannelAttribute("Delay", TimeValue(Seconds(0.010)));
366 Ptr<Node> pgw = m_epcHelper->GetPgwNode();
367 NetDeviceContainer internetDevices = p2ph.Install(pgw, remoteHost);
368 Ipv4AddressHelper ipv4h;
369 ipv4h.SetBase("1.0.0.0", "255.0.0.0");
370 Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign(internetDevices);
371 // in this container, interface 0 is the pgw, 1 is the remoteHost
372 remoteHostAddr = internetIpIfaces.GetAddress(1);
373
374 Ipv4StaticRoutingHelper ipv4RoutingHelper;
375 Ptr<Ipv4StaticRouting> remoteHostStaticRouting =
376 ipv4RoutingHelper.GetStaticRouting(remoteHost->GetObject<Ipv4>());
377 remoteHostStaticRouting->AddNetworkRouteTo(Ipv4Address("7.0.0.0"),
378 Ipv4Mask("255.0.0.0"),
379 1);
380
381 // Install the IP stack on the UEs
382 internet.Install(ueNodes);
383 ueIpIfaces = m_epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueDevices));
384 }
385
386 // attachment (needs to be done after IP stack configuration)
387 // all UEs attached to eNB 0 at the beginning
388 m_lteHelper->Attach(ueDevices, enbDevices.Get(0));
389
390 if (m_epc)
391 {
392 bool epcDl = true;
393 bool epcUl = false;
394 // the rest of this block is copied from lena-dual-stripe
395
396 // Install and start applications on UEs and remote host
397 uint16_t dlPort = 10000;
398 uint16_t ulPort = 20000;
399
400 // randomize a bit start times to avoid simulation artifacts
401 // (e.g., buffer overflows due to packet transmissions happening
402 // exactly at the same time)
404 startTimeSeconds->SetAttribute("Min", DoubleValue(0));
405 startTimeSeconds->SetAttribute("Max", DoubleValue(0.010));
406 startTimeSeconds->SetStream(stream++);
407
408 for (uint32_t u = 0; u < ueNodes.GetN(); ++u)
409 {
410 Ptr<Node> ue = ueNodes.Get(u);
411 // Set the default gateway for the UE
412 Ptr<Ipv4StaticRouting> ueStaticRouting =
413 ipv4RoutingHelper.GetStaticRouting(ue->GetObject<Ipv4>());
414 ueStaticRouting->SetDefaultRoute(m_epcHelper->GetUeDefaultGatewayAddress(), 1);
415
416 UeData ueData;
417
418 for (uint32_t b = 0; b < m_nDedicatedBearers; ++b)
419 {
420 ++dlPort;
421 ++ulPort;
422
423 ApplicationContainer clientApps;
424 ApplicationContainer serverApps;
425 BearerData bearerData = BearerData();
426
427 if (m_useUdp)
428 {
429 if (epcDl)
430 {
431 UdpClientHelper dlClientHelper(ueIpIfaces.GetAddress(u), dlPort);
432 clientApps.Add(dlClientHelper.Install(remoteHost));
433 PacketSinkHelper dlPacketSinkHelper(
434 "ns3::UdpSocketFactory",
436 ApplicationContainer sinkContainer = dlPacketSinkHelper.Install(ue);
437 bearerData.dlSink = sinkContainer.Get(0)->GetObject<PacketSink>();
438 serverApps.Add(sinkContainer);
439 }
440 if (epcUl)
441 {
442 UdpClientHelper ulClientHelper(remoteHostAddr, ulPort);
443 clientApps.Add(ulClientHelper.Install(ue));
444 PacketSinkHelper ulPacketSinkHelper(
445 "ns3::UdpSocketFactory",
447 ApplicationContainer sinkContainer = ulPacketSinkHelper.Install(remoteHost);
448 bearerData.ulSink = sinkContainer.Get(0)->GetObject<PacketSink>();
449 serverApps.Add(sinkContainer);
450 }
451 }
452 else // use TCP
453 {
454 if (epcDl)
455 {
456 BulkSendHelper dlClientHelper(
457 "ns3::TcpSocketFactory",
458 InetSocketAddress(ueIpIfaces.GetAddress(u), dlPort));
459 dlClientHelper.SetAttribute("MaxBytes", UintegerValue(0));
460 clientApps.Add(dlClientHelper.Install(remoteHost));
461 PacketSinkHelper dlPacketSinkHelper(
462 "ns3::TcpSocketFactory",
464 ApplicationContainer sinkContainer = dlPacketSinkHelper.Install(ue);
465 bearerData.dlSink = sinkContainer.Get(0)->GetObject<PacketSink>();
466 serverApps.Add(sinkContainer);
467 }
468 if (epcUl)
469 {
470 BulkSendHelper ulClientHelper("ns3::TcpSocketFactory",
471 InetSocketAddress(remoteHostAddr, ulPort));
472 ulClientHelper.SetAttribute("MaxBytes", UintegerValue(0));
473 clientApps.Add(ulClientHelper.Install(ue));
474 PacketSinkHelper ulPacketSinkHelper(
475 "ns3::TcpSocketFactory",
477 ApplicationContainer sinkContainer = ulPacketSinkHelper.Install(remoteHost);
478 bearerData.ulSink = sinkContainer.Get(0)->GetObject<PacketSink>();
479 serverApps.Add(sinkContainer);
480 }
481 } // end if (useUdp)
482
484 if (epcDl)
485 {
487 dlpf.localPortStart = dlPort;
488 dlpf.localPortEnd = dlPort;
489 tft->Add(dlpf);
490 }
491 if (epcUl)
492 {
494 ulpf.remotePortStart = ulPort;
495 ulpf.remotePortEnd = ulPort;
496 tft->Add(ulpf);
497 }
498
499 if (epcDl || epcUl)
500 {
502 m_lteHelper->ActivateDedicatedEpsBearer(ueDevices.Get(u), bearer, tft);
503 }
504 Time startTime = Seconds(startTimeSeconds->GetValue());
505 serverApps.Start(startTime);
506 clientApps.Start(startTime);
507
508 ueData.bearerDataList.push_back(bearerData);
509
510 } // end for b
511
512 m_ueDataVector.push_back(ueData);
513 }
514 }
515 else // (epc == false)
516 {
517 // for radio bearer activation purposes, consider together home UEs and macro UEs
518 for (uint32_t u = 0; u < ueDevices.GetN(); ++u)
519 {
520 Ptr<NetDevice> ueDev = ueDevices.Get(u);
521 for (uint32_t b = 0; b < m_nDedicatedBearers; ++b)
522 {
524 EpsBearer bearer(q);
525 m_lteHelper->ActivateDataRadioBearer(ueDev, bearer);
526 }
527 }
528 }
529
530 m_lteHelper->AddX2Interface(enbNodes);
531
532 // check initial RRC connection
533 const Time maxRrcConnectionEstablishmentDuration = Seconds(0.080);
534 for (auto it = ueDevices.Begin(); it != ueDevices.End(); ++it)
535 {
536 NS_LOG_FUNCTION(maxRrcConnectionEstablishmentDuration);
537 Simulator::Schedule(maxRrcConnectionEstablishmentDuration,
539 this,
540 *it,
541 enbDevices.Get(0));
542 }
543
544 // schedule the checkpoint events
545
546 Time stopTime = Seconds(0);
547 for (auto checkPointEventIt = m_checkPointEventList.begin();
548 checkPointEventIt != m_checkPointEventList.end();
549 ++checkPointEventIt)
550 {
551 for (Time checkPointTime = checkPointEventIt->checkStartTime;
552 checkPointTime < checkPointEventIt->checkStopTime;
553 checkPointTime += checkPointEventIt->checkInterval)
554 {
555 Simulator::Schedule(checkPointTime,
557 this,
558 ueDevices.Get(checkPointEventIt->ueDeviceIndex),
559 enbDevices.Get(checkPointEventIt->enbDeviceIndex));
560
561 Simulator::Schedule(checkPointTime,
563 this,
564 checkPointEventIt->ueDeviceIndex);
565
566 Time checkStats = checkPointTime + m_statsDuration;
567 Simulator::Schedule(checkStats,
569 this,
570 checkPointEventIt->ueDeviceIndex);
571
572 if (stopTime <= checkStats)
573 {
574 stopTime = checkStats + Seconds(1);
575 }
576 }
577 }
578
582}
583
584void
586{
587 NS_LOG_FUNCTION(ueDevice << enbDevice);
588
589 Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice>();
590 Ptr<LteUeRrc> ueRrc = ueLteDevice->GetRrc();
591 NS_TEST_ASSERT_MSG_EQ(ueRrc->GetState(), LteUeRrc::CONNECTED_NORMALLY, "Wrong LteUeRrc state!");
592
593 Ptr<LteEnbNetDevice> enbLteDevice = enbDevice->GetObject<LteEnbNetDevice>();
594 Ptr<LteEnbRrc> enbRrc = enbLteDevice->GetRrc();
595 uint16_t rnti = ueRrc->GetRnti();
596 Ptr<UeManager> ueManager = enbRrc->GetUeManager(rnti);
597 NS_TEST_ASSERT_MSG_NE(ueManager, nullptr, "RNTI " << rnti << " not found in eNB");
598
599 UeManager::State ueManagerState = ueManager->GetState();
600 NS_TEST_ASSERT_MSG_EQ(ueManagerState, UeManager::CONNECTED_NORMALLY, "Wrong UeManager state!");
601 NS_ASSERT_MSG(ueManagerState == UeManager::CONNECTED_NORMALLY, "Wrong UeManager state!");
602
603 uint16_t ueCellId = ueRrc->GetCellId();
604 uint16_t enbCellId = enbLteDevice->GetCellId();
605 uint8_t ueDlBandwidth = ueRrc->GetDlBandwidth();
606 uint8_t enbDlBandwidth = enbLteDevice->GetDlBandwidth();
607 uint8_t ueUlBandwidth = ueRrc->GetUlBandwidth();
608 uint8_t enbUlBandwidth = enbLteDevice->GetUlBandwidth();
609 uint8_t ueDlEarfcn = ueRrc->GetDlEarfcn();
610 uint8_t enbDlEarfcn = enbLteDevice->GetDlEarfcn();
611 uint8_t ueUlEarfcn = ueRrc->GetUlEarfcn();
612 uint8_t enbUlEarfcn = enbLteDevice->GetUlEarfcn();
613 uint64_t ueImsi = ueLteDevice->GetImsi();
614 uint64_t enbImsi = ueManager->GetImsi();
615
616 NS_TEST_ASSERT_MSG_EQ(ueImsi, enbImsi, "inconsistent IMSI");
617 NS_TEST_ASSERT_MSG_EQ(ueCellId, enbCellId, "inconsistent CellId");
618 NS_TEST_ASSERT_MSG_EQ(ueDlBandwidth, enbDlBandwidth, "inconsistent DlBandwidth");
619 NS_TEST_ASSERT_MSG_EQ(ueUlBandwidth, enbUlBandwidth, "inconsistent UlBandwidth");
620 NS_TEST_ASSERT_MSG_EQ(ueDlEarfcn, enbDlEarfcn, "inconsistent DlEarfcn");
621 NS_TEST_ASSERT_MSG_EQ(ueUlEarfcn, enbUlEarfcn, "inconsistent UlEarfcn");
622
623 ObjectMapValue enbDataRadioBearerMapValue;
624 ueManager->GetAttribute("DataRadioBearerMap", enbDataRadioBearerMapValue);
625 NS_TEST_ASSERT_MSG_EQ(enbDataRadioBearerMapValue.GetN(),
627 "wrong num bearers at eNB");
628
629 ObjectMapValue ueDataRadioBearerMapValue;
630 ueRrc->GetAttribute("DataRadioBearerMap", ueDataRadioBearerMapValue);
631 NS_TEST_ASSERT_MSG_EQ(ueDataRadioBearerMapValue.GetN(),
633 "wrong num bearers at UE");
634
635 auto enbBearerIt = enbDataRadioBearerMapValue.Begin();
636 auto ueBearerIt = ueDataRadioBearerMapValue.Begin();
637 while (enbBearerIt != enbDataRadioBearerMapValue.End() &&
638 ueBearerIt != ueDataRadioBearerMapValue.End())
639 {
640 Ptr<LteDataRadioBearerInfo> enbDrbInfo =
641 enbBearerIt->second->GetObject<LteDataRadioBearerInfo>();
643 ueBearerIt->second->GetObject<LteDataRadioBearerInfo>();
644 // NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_epsBearer, ueDrbInfo->m_epsBearer, "epsBearer
645 // differs");
646 NS_TEST_ASSERT_MSG_EQ((uint32_t)enbDrbInfo->m_epsBearerIdentity,
647 (uint32_t)ueDrbInfo->m_epsBearerIdentity,
648 "epsBearerIdentity differs");
649 NS_TEST_ASSERT_MSG_EQ((uint32_t)enbDrbInfo->m_drbIdentity,
650 (uint32_t)ueDrbInfo->m_drbIdentity,
651 "drbIdentity differs");
652 // NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_rlcConfig, ueDrbInfo->m_rlcConfig, "rlcConfig
653 // differs");
654 NS_TEST_ASSERT_MSG_EQ((uint32_t)enbDrbInfo->m_logicalChannelIdentity,
655 (uint32_t)ueDrbInfo->m_logicalChannelIdentity,
656 "logicalChannelIdentity differs");
657 // NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_logicalChannelConfig,
658 // ueDrbInfo->m_logicalChannelConfig, "logicalChannelConfig differs");
659
660 ++enbBearerIt;
661 ++ueBearerIt;
662 }
663 NS_ASSERT_MSG(enbBearerIt == enbDataRadioBearerMapValue.End(), "too many bearers at eNB");
664 NS_ASSERT_MSG(ueBearerIt == ueDataRadioBearerMapValue.End(), "too many bearers at UE");
665}
666
667void
669{
670 NS_LOG_FUNCTION(ueIndex);
671 for (auto it = m_ueDataVector.at(ueIndex).bearerDataList.begin();
672 it != m_ueDataVector.at(ueIndex).bearerDataList.end();
673 ++it)
674 {
675 if (it->dlSink)
676 {
677 it->dlOldTotalRx = it->dlSink->GetTotalRx();
678 }
679 if (it->ulSink)
680 {
681 it->ulOldTotalRx = it->ulSink->GetTotalRx();
682 }
683 }
684}
685
686void
688{
689 NS_LOG_FUNCTION(ueIndex);
690 uint32_t b = 1;
691 for (auto it = m_ueDataVector.at(ueIndex).bearerDataList.begin();
692 it != m_ueDataVector.at(ueIndex).bearerDataList.end();
693 ++it)
694 {
695 uint32_t dlRx = 0;
696 uint32_t ulRx = 0;
697
698 if (it->dlSink)
699 {
700 dlRx = it->dlSink->GetTotalRx() - it->dlOldTotalRx;
701 }
702
703 if (it->ulSink)
704 {
705 ulRx = it->ulSink->GetTotalRx() - it->ulOldTotalRx;
706 }
707 double expectedBytes =
709
710 NS_LOG_LOGIC("expBytes " << expectedBytes << " dlRx " << dlRx << " ulRx " << ulRx);
711
712 // tolerance
713 if (it->dlSink)
714 {
716 0.500 * expectedBytes,
717 "too few RX bytes in DL, ue=" << ueIndex << ", b=" << b);
718 }
719 if (it->ulSink)
720 {
722 0.500 * expectedBytes,
723 "too few RX bytes in UL, ue=" << ueIndex << ", b=" << b);
724 }
725 ++b;
726 }
727}
728
729/**
730 * \ingroup lte-test
731 *
732 * \brief Lte X2 Handover Measures Test Suite
733 */
739
741 : TestSuite("lte-x2-handover-measures", Type::SYSTEM)
742{
743 Time checkInterval = Seconds(1);
744
745 std::string cel1name("ho: 0 -> 1");
746 const std::list<CheckPointEvent> cel1{
747 CheckPointEvent(Seconds(1), Seconds(10.1), checkInterval, 0, 0),
748 CheckPointEvent(Seconds(11), Seconds(17), checkInterval, 0, 1),
749 };
750
751 std::string cel2name("ho: 0 -> 1 -> 2");
752 const std::list<CheckPointEvent> cel2{
753 CheckPointEvent(Seconds(1), Seconds(10.1), checkInterval, 0, 0),
754 CheckPointEvent(Seconds(11), Seconds(17.1), checkInterval, 0, 1),
755 CheckPointEvent(Seconds(18), Seconds(24), checkInterval, 0, 2),
756 };
757
758 std::string cel3name("ho: 0 -> 1 -> 2 -> 3");
759 const std::list<CheckPointEvent> cel3{
760 CheckPointEvent(Seconds(1), Seconds(10.1), checkInterval, 0, 0),
761 CheckPointEvent(Seconds(11), Seconds(17.1), checkInterval, 0, 1),
762 CheckPointEvent(Seconds(18), Seconds(24.1), checkInterval, 0, 2),
763 CheckPointEvent(Seconds(25), Seconds(37), checkInterval, 0, 3),
764 };
765
766 std::string sched = "ns3::PfFfMacScheduler";
767 std::string ho = "ns3::A2A4RsrqHandoverAlgorithm";
768 for (auto useIdealRrc : {true, false})
769 {
770 // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, ho, admitHo, idealRrc
772 1,
773 0,
774 cel1,
775 cel1name,
776 true,
777 sched,
778 ho,
779 true,
780 useIdealRrc),
781 TestCase::Duration::TAKES_FOREVER);
783 1,
784 1,
785 cel1,
786 cel1name,
787 true,
788 sched,
789 ho,
790 true,
791 useIdealRrc),
792 TestCase::Duration::QUICK);
794 1,
795 2,
796 cel1,
797 cel1name,
798 true,
799 sched,
800 ho,
801 true,
802 useIdealRrc),
803 TestCase::Duration::TAKES_FOREVER);
805 1,
806 0,
807 cel2,
808 cel2name,
809 true,
810 sched,
811 ho,
812 true,
813 useIdealRrc),
814 TestCase::Duration::TAKES_FOREVER);
816 1,
817 1,
818 cel2,
819 cel2name,
820 true,
821 sched,
822 ho,
823 true,
824 useIdealRrc),
825 TestCase::Duration::TAKES_FOREVER);
827 1,
828 2,
829 cel2,
830 cel2name,
831 true,
832 sched,
833 ho,
834 true,
835 useIdealRrc),
836 TestCase::Duration::EXTENSIVE);
838 1,
839 0,
840 cel3,
841 cel3name,
842 true,
843 sched,
844 ho,
845 true,
846 useIdealRrc),
847 TestCase::Duration::EXTENSIVE);
849 1,
850 1,
851 cel3,
852 cel3name,
853 true,
854 sched,
855 ho,
856 true,
857 useIdealRrc),
858 TestCase::Duration::TAKES_FOREVER);
860 1,
861 2,
862 cel3,
863 cel3name,
864 true,
865 sched,
866 ho,
867 true,
868 useIdealRrc),
869 TestCase::Duration::TAKES_FOREVER);
870 }
871
872 sched = "ns3::RrFfMacScheduler";
873 for (auto useIdealRrc : {true, false})
874 {
875 // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, admitHo, idealRrc
877 1,
878 0,
879 cel1,
880 cel1name,
881 true,
882 sched,
883 ho,
884 true,
885 useIdealRrc),
886 TestCase::Duration::EXTENSIVE);
888 1,
889 0,
890 cel2,
891 cel2name,
892 true,
893 sched,
894 ho,
895 true,
896 useIdealRrc),
897 TestCase::Duration::TAKES_FOREVER);
899 1,
900 0,
901 cel3,
902 cel3name,
903 true,
904 sched,
905 ho,
906 true,
907 useIdealRrc),
908 TestCase::Duration::TAKES_FOREVER);
909 }
910
911 ho = "ns3::A3RsrpHandoverAlgorithm";
912 sched = "ns3::PfFfMacScheduler";
913 for (auto useIdealRrc : {true, false})
914 {
915 // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, admitHo, idealRrc
917 1,
918 0,
919 cel1,
920 cel1name,
921 true,
922 sched,
923 ho,
924 true,
925 useIdealRrc),
926 TestCase::Duration::EXTENSIVE);
928 1,
929 0,
930 cel2,
931 cel2name,
932 true,
933 sched,
934 ho,
935 true,
936 useIdealRrc),
937 TestCase::Duration::TAKES_FOREVER);
939 1,
940 0,
941 cel3,
942 cel3name,
943 true,
944 sched,
945 ho,
946 true,
947 useIdealRrc),
948 TestCase::Duration::TAKES_FOREVER);
949 }
950
951 sched = "ns3::RrFfMacScheduler";
952 for (auto useIdealRrc : {true, false})
953 {
954 // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, admitHo, idealRrc
956 1,
957 0,
958 cel1,
959 cel1name,
960 true,
961 sched,
962 ho,
963 true,
964 useIdealRrc),
965 TestCase::Duration::QUICK);
967 1,
968 0,
969 cel2,
970 cel2name,
971 true,
972 sched,
973 ho,
974 true,
975 useIdealRrc),
976 TestCase::Duration::TAKES_FOREVER);
978 1,
979 0,
980 cel3,
981 cel3name,
982 true,
983 sched,
984 ho,
985 true,
986 useIdealRrc),
987 TestCase::Duration::EXTENSIVE);
988 }
989
990} // end of LteX2HandoverMeasuresTestSuite ()
991
992/**
993 * \ingroup lte-test
994 * Static variable for test initialization
995 */
Test different X2 handover measures and algorithms, e.g.
Ptr< PointToPointEpcHelper > m_epcHelper
EPC helper.
std::list< CheckPointEvent > m_checkPointEventList
check point event list
std::string m_handoverAlgorithmType
handover algorithm type
bool m_admitHo
whether to configure to admit handover
bool m_useUdp
whether to use UDP traffic
const Time m_udpClientInterval
UDP client interval.
void CheckStats(uint32_t ueIndex)
Check stats function.
LteX2HandoverMeasuresTestCase(uint32_t nEnbs, uint32_t nUes, uint32_t nDedicatedBearers, std::list< CheckPointEvent > checkPointEventList, std::string checkPointEventListName, bool useUdp, std::string schedulerType, std::string handoverAlgorithmType, bool admitHo, bool useIdealRrc)
Constructor.
uint32_t m_nEnbs
number of eNBs in the test
static std::string BuildNameString(uint32_t nEnbs, uint32_t nUes, uint32_t nDedicatedBearers, std::string checkPointEventListName, bool useUdp, std::string schedulerType, std::string handoverAlgorithmType, bool admitHo, bool useIdealRrc)
Build name string.
std::string m_checkPointEventListName
check point event list name
void DoRun() override
Implementation to actually run this TestCase.
void SaveStats(uint32_t ueIndex)
Save stats function.
uint32_t m_nDedicatedBearers
number of UEs in the test
uint32_t m_nUes
number of UEs in the test
std::vector< UeData > m_ueDataVector
UE data vector.
const uint32_t m_udpClientPktSize
UDP client packet size.
const Time m_maxHoDuration
maximum HO duration
void CheckConnected(Ptr< NetDevice > ueDevice, Ptr< NetDevice > enbDevice)
Check connected function.
Lte X2 Handover Measures Test Suite.
holds a vector of ns3::Application pointers.
Ptr< Application > Get(uint32_t i) const
Get the Ptr<Application> stored in this container at a given index.
ApplicationContainer Install(NodeContainer c)
Install an application on each node of the input container configured with all the attributes set wit...
void SetAttribute(const std::string &name, const AttributeValue &value)
Helper function used to set the underlying application attributes.
A helper to make it easier to instantiate an ns3::BulkSendApplication on a set of nodes.
Mobility model for which the current speed does not change once it has been set and until it is set a...
Class for representing data rates.
Definition data-rate.h:78
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
This class contains the specification of EPS Bearers.
Definition eps-bearer.h:80
Qci
QoS Class Indicator.
Definition eps-bearer.h:95
@ NGBR_VIDEO_TCP_DEFAULT
Non-GBR TCP-based Video (Buffered Streaming, e.g., www, e-mail...)
Definition eps-bearer.h:115
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
Ipv4 addresses are stored in host order in this class.
static Ipv4Address GetAny()
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition ipv4.h:69
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
a class to represent an Ipv4 address mask
Helper class that adds ns3::Ipv4StaticRouting objects.
Ptr< Ipv4StaticRouting > GetStaticRouting(Ptr< Ipv4 > ipv4) const
Try and find the static routing protocol as either the main routing protocol or in the list of routin...
store information on active data radio bearer instance
The eNodeB device implementation.
The LteUeNetDevice class implements the UE net device.
Helper class used to assign positions and mobility models to nodes.
void Install(Ptr< Node > node) const
"Layout" a single node according to the current position allocator type.
void SetMobilityModel(std::string type, Ts &&... args)
void SetPositionAllocator(Ptr< PositionAllocator > allocator)
Set the position allocator which will be used to allocate the initial position of every node initiali...
Keep track of the current position and velocity of an object.
holds a vector of ns3::NetDevice pointers
uint32_t GetN() const
Get the number of Ptr<NetDevice> stored in this container.
Iterator Begin() const
Get an iterator which refers to the first NetDevice in the container.
Iterator End() const
Get an iterator which indicates past-the-last NetDevice in the container.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
keep track of a set of node pointers.
uint32_t GetN() const
Get the number of Ptr<Node> stored in this container.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:511
Container for a set of ns3::Object pointers.
std::size_t GetN() const
Get the number of Objects.
Iterator End() const
Get an iterator to the past-the-end Object.
Iterator Begin() const
Get an iterator to the first Object.
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
Receive and consume traffic generated to an IP address and port.
Definition packet-sink.h:64
Build a set of PointToPointNetDevice objects.
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
NetDeviceContainer Install(NodeContainer c)
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static void Run()
Run the simulation.
Definition simulator.cc:167
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
Hold variables of type string.
Definition string.h:45
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
Create a client application which sends UDP packets carrying a 32bit sequence number and a 64 bit tim...
State
The state of the UeManager at the eNB RRC.
Definition lte-enb-rrc.h:67
Hold an unsigned integer type.
Definition uinteger.h:34
Time stopTime
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
void Reset()
Reset the initial value of every attribute as well as the value of every global to what they were bef...
Definition config.cc:848
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:883
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
static LteX2HandoverMeasuresTestSuite g_lteX2HandoverMeasuresTestSuiteInstance
Static variable for test initialization.
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition test.h:134
#define NS_TEST_ASSERT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report and abort if not.
Definition test.h:554
#define NS_TEST_ASSERT_MSG_GT(actual, limit, msg)
Test that an actual value is greater than a limit and report and abort if not.
Definition test.h:864
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1320
Every class exported by the ns3 library is enclosed in the ns3 namespace.
CheckPointEvent structure.
CheckPointEvent(Time start, Time stop, Time interval, uint32_t ueIndex, uint32_t enbIndex)
Constructor.
Time checkStopTime
check stop time
uint32_t enbDeviceIndex
ENB device index.
Time checkStartTime
check start time
uint32_t ueDeviceIndex
UE device index.
std::list< BearerData > bearerDataList
bearer ID list
Implement the data structure representing a TrafficFlowTemplate Packet Filter.
Definition epc-tft.h:60
uint16_t localPortEnd
end of the port number range of the UE
Definition epc-tft.h:121
uint16_t remotePortEnd
end of the port number range of the remote host
Definition epc-tft.h:119
uint16_t remotePortStart
start of the port number range of the remote host
Definition epc-tft.h:118
uint16_t localPortStart
start of the port number range of the UE
Definition epc-tft.h:120