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 }
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
511 m_ueDataVector.push_back(ueData);
512 }
513 }
514 else // (epc == false)
515 {
516 // for radio bearer activation purposes, consider together home UEs and macro UEs
517 for (uint32_t u = 0; u < ueDevices.GetN(); ++u)
518 {
519 Ptr<NetDevice> ueDev = ueDevices.Get(u);
520 for (uint32_t b = 0; b < m_nDedicatedBearers; ++b)
521 {
523 EpsBearer bearer(q);
524 m_lteHelper->ActivateDataRadioBearer(ueDev, bearer);
525 }
526 }
527 }
528
529 m_lteHelper->AddX2Interface(enbNodes);
530
531 // check initial RRC connection
532 const Time maxRrcConnectionEstablishmentDuration = Seconds(0.080);
533 for (auto it = ueDevices.Begin(); it != ueDevices.End(); ++it)
534 {
535 NS_LOG_FUNCTION(maxRrcConnectionEstablishmentDuration);
536 Simulator::Schedule(maxRrcConnectionEstablishmentDuration,
538 this,
539 *it,
540 enbDevices.Get(0));
541 }
542
543 // schedule the checkpoint events
544
546 for (auto checkPointEventIt = m_checkPointEventList.begin();
547 checkPointEventIt != m_checkPointEventList.end();
548 ++checkPointEventIt)
549 {
550 for (Time checkPointTime = checkPointEventIt->checkStartTime;
551 checkPointTime < checkPointEventIt->checkStopTime;
552 checkPointTime += checkPointEventIt->checkInterval)
553 {
554 Simulator::Schedule(checkPointTime,
556 this,
557 ueDevices.Get(checkPointEventIt->ueDeviceIndex),
558 enbDevices.Get(checkPointEventIt->enbDeviceIndex));
559
560 Simulator::Schedule(checkPointTime,
562 this,
563 checkPointEventIt->ueDeviceIndex);
564
565 Time checkStats = checkPointTime + m_statsDuration;
566 Simulator::Schedule(checkStats,
568 this,
569 checkPointEventIt->ueDeviceIndex);
570
571 if (stopTime <= checkStats)
572 {
573 stopTime = checkStats + Seconds(1);
574 }
575 }
576 }
577
581}
582
583void
585{
586 NS_LOG_FUNCTION(ueDevice << enbDevice);
587
588 Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice>();
589 Ptr<LteUeRrc> ueRrc = ueLteDevice->GetRrc();
590 NS_TEST_ASSERT_MSG_EQ(ueRrc->GetState(), LteUeRrc::CONNECTED_NORMALLY, "Wrong LteUeRrc state!");
591
592 Ptr<LteEnbNetDevice> enbLteDevice = enbDevice->GetObject<LteEnbNetDevice>();
593 Ptr<LteEnbRrc> enbRrc = enbLteDevice->GetRrc();
594 uint16_t rnti = ueRrc->GetRnti();
595 Ptr<UeManager> ueManager = enbRrc->GetUeManager(rnti);
596 NS_TEST_ASSERT_MSG_NE(ueManager, nullptr, "RNTI " << rnti << " not found in eNB");
597
598 UeManager::State ueManagerState = ueManager->GetState();
599 NS_TEST_ASSERT_MSG_EQ(ueManagerState, UeManager::CONNECTED_NORMALLY, "Wrong UeManager state!");
600 NS_ASSERT_MSG(ueManagerState == UeManager::CONNECTED_NORMALLY, "Wrong UeManager state!");
601
602 uint16_t ueCellId = ueRrc->GetCellId();
603 uint16_t enbCellId = enbLteDevice->GetCellId();
604 uint8_t ueDlBandwidth = ueRrc->GetDlBandwidth();
605 uint8_t enbDlBandwidth = enbLteDevice->GetDlBandwidth();
606 uint8_t ueUlBandwidth = ueRrc->GetUlBandwidth();
607 uint8_t enbUlBandwidth = enbLteDevice->GetUlBandwidth();
608 uint8_t ueDlEarfcn = ueRrc->GetDlEarfcn();
609 uint8_t enbDlEarfcn = enbLteDevice->GetDlEarfcn();
610 uint8_t ueUlEarfcn = ueRrc->GetUlEarfcn();
611 uint8_t enbUlEarfcn = enbLteDevice->GetUlEarfcn();
612 uint64_t ueImsi = ueLteDevice->GetImsi();
613 uint64_t enbImsi = ueManager->GetImsi();
614
615 NS_TEST_ASSERT_MSG_EQ(ueImsi, enbImsi, "inconsistent IMSI");
616 NS_TEST_ASSERT_MSG_EQ(ueCellId, enbCellId, "inconsistent CellId");
617 NS_TEST_ASSERT_MSG_EQ(ueDlBandwidth, enbDlBandwidth, "inconsistent DlBandwidth");
618 NS_TEST_ASSERT_MSG_EQ(ueUlBandwidth, enbUlBandwidth, "inconsistent UlBandwidth");
619 NS_TEST_ASSERT_MSG_EQ(ueDlEarfcn, enbDlEarfcn, "inconsistent DlEarfcn");
620 NS_TEST_ASSERT_MSG_EQ(ueUlEarfcn, enbUlEarfcn, "inconsistent UlEarfcn");
621
622 ObjectMapValue enbDataRadioBearerMapValue;
623 ueManager->GetAttribute("DataRadioBearerMap", enbDataRadioBearerMapValue);
624 NS_TEST_ASSERT_MSG_EQ(enbDataRadioBearerMapValue.GetN(),
626 "wrong num bearers at eNB");
627
628 ObjectMapValue ueDataRadioBearerMapValue;
629 ueRrc->GetAttribute("DataRadioBearerMap", ueDataRadioBearerMapValue);
630 NS_TEST_ASSERT_MSG_EQ(ueDataRadioBearerMapValue.GetN(),
632 "wrong num bearers at UE");
633
634 auto enbBearerIt = enbDataRadioBearerMapValue.Begin();
635 auto ueBearerIt = ueDataRadioBearerMapValue.Begin();
636 while (enbBearerIt != enbDataRadioBearerMapValue.End() &&
637 ueBearerIt != ueDataRadioBearerMapValue.End())
638 {
639 Ptr<LteDataRadioBearerInfo> enbDrbInfo =
640 enbBearerIt->second->GetObject<LteDataRadioBearerInfo>();
642 ueBearerIt->second->GetObject<LteDataRadioBearerInfo>();
643 // NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_epsBearer, ueDrbInfo->m_epsBearer, "epsBearer
644 // differs");
645 NS_TEST_ASSERT_MSG_EQ((uint32_t)enbDrbInfo->m_epsBearerIdentity,
646 (uint32_t)ueDrbInfo->m_epsBearerIdentity,
647 "epsBearerIdentity differs");
648 NS_TEST_ASSERT_MSG_EQ((uint32_t)enbDrbInfo->m_drbIdentity,
649 (uint32_t)ueDrbInfo->m_drbIdentity,
650 "drbIdentity differs");
651 // NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_rlcConfig, ueDrbInfo->m_rlcConfig, "rlcConfig
652 // differs");
653 NS_TEST_ASSERT_MSG_EQ((uint32_t)enbDrbInfo->m_logicalChannelIdentity,
654 (uint32_t)ueDrbInfo->m_logicalChannelIdentity,
655 "logicalChannelIdentity differs");
656 // NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_logicalChannelConfig,
657 // ueDrbInfo->m_logicalChannelConfig, "logicalChannelConfig differs");
658
659 ++enbBearerIt;
660 ++ueBearerIt;
661 }
662 NS_ASSERT_MSG(enbBearerIt == enbDataRadioBearerMapValue.End(), "too many bearers at eNB");
663 NS_ASSERT_MSG(ueBearerIt == ueDataRadioBearerMapValue.End(), "too many bearers at UE");
664}
665
666void
668{
669 NS_LOG_FUNCTION(ueIndex);
670 for (auto it = m_ueDataVector.at(ueIndex).bearerDataList.begin();
671 it != m_ueDataVector.at(ueIndex).bearerDataList.end();
672 ++it)
673 {
674 if (it->dlSink)
675 {
676 it->dlOldTotalRx = it->dlSink->GetTotalRx();
677 }
678 if (it->ulSink)
679 {
680 it->ulOldTotalRx = it->ulSink->GetTotalRx();
681 }
682 }
683}
684
685void
687{
688 NS_LOG_FUNCTION(ueIndex);
689 uint32_t b = 1;
690 for (auto it = m_ueDataVector.at(ueIndex).bearerDataList.begin();
691 it != m_ueDataVector.at(ueIndex).bearerDataList.end();
692 ++it)
693 {
694 uint32_t dlRx = 0;
695 uint32_t ulRx = 0;
696
697 if (it->dlSink)
698 {
699 dlRx = it->dlSink->GetTotalRx() - it->dlOldTotalRx;
700 }
701
702 if (it->ulSink)
703 {
704 ulRx = it->ulSink->GetTotalRx() - it->ulOldTotalRx;
705 }
706 double expectedBytes =
708
709 NS_LOG_LOGIC("expBytes " << expectedBytes << " dlRx " << dlRx << " ulRx " << ulRx);
710
711 // tolerance
712 if (it->dlSink)
713 {
715 0.500 * expectedBytes,
716 "too few RX bytes in DL, ue=" << ueIndex << ", b=" << b);
717 }
718 if (it->ulSink)
719 {
721 0.500 * expectedBytes,
722 "too few RX bytes in UL, ue=" << ueIndex << ", b=" << b);
723 }
724 ++b;
725 }
726}
727
728/**
729 * @ingroup lte-test
730 *
731 * @brief Lte X2 Handover Measures Test Suite
732 */
738
740 : TestSuite("lte-x2-handover-measures", Type::SYSTEM)
741{
742 Time checkInterval = Seconds(1);
743
744 std::string cel1name("ho: 0 -> 1");
745 const std::list<CheckPointEvent> cel1{
746 CheckPointEvent(Seconds(1), Seconds(10.1), checkInterval, 0, 0),
747 CheckPointEvent(Seconds(11), Seconds(17), checkInterval, 0, 1),
748 };
749
750 std::string cel2name("ho: 0 -> 1 -> 2");
751 const std::list<CheckPointEvent> cel2{
752 CheckPointEvent(Seconds(1), Seconds(10.1), checkInterval, 0, 0),
753 CheckPointEvent(Seconds(11), Seconds(17.1), checkInterval, 0, 1),
754 CheckPointEvent(Seconds(18), Seconds(24), checkInterval, 0, 2),
755 };
756
757 std::string cel3name("ho: 0 -> 1 -> 2 -> 3");
758 const std::list<CheckPointEvent> cel3{
759 CheckPointEvent(Seconds(1), Seconds(10.1), checkInterval, 0, 0),
760 CheckPointEvent(Seconds(11), Seconds(17.1), checkInterval, 0, 1),
761 CheckPointEvent(Seconds(18), Seconds(24.1), checkInterval, 0, 2),
762 CheckPointEvent(Seconds(25), Seconds(37), checkInterval, 0, 3),
763 };
764
765 std::string sched = "ns3::PfFfMacScheduler";
766 std::string ho = "ns3::A2A4RsrqHandoverAlgorithm";
767 for (auto useIdealRrc : {true, false})
768 {
769 // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, ho, admitHo, idealRrc
771 1,
772 0,
773 cel1,
774 cel1name,
775 true,
776 sched,
777 ho,
778 true,
779 useIdealRrc),
780 TestCase::Duration::TAKES_FOREVER);
782 1,
783 1,
784 cel1,
785 cel1name,
786 true,
787 sched,
788 ho,
789 true,
790 useIdealRrc),
791 TestCase::Duration::QUICK);
793 1,
794 2,
795 cel1,
796 cel1name,
797 true,
798 sched,
799 ho,
800 true,
801 useIdealRrc),
802 TestCase::Duration::TAKES_FOREVER);
804 1,
805 0,
806 cel2,
807 cel2name,
808 true,
809 sched,
810 ho,
811 true,
812 useIdealRrc),
813 TestCase::Duration::TAKES_FOREVER);
815 1,
816 1,
817 cel2,
818 cel2name,
819 true,
820 sched,
821 ho,
822 true,
823 useIdealRrc),
824 TestCase::Duration::TAKES_FOREVER);
826 1,
827 2,
828 cel2,
829 cel2name,
830 true,
831 sched,
832 ho,
833 true,
834 useIdealRrc),
835 TestCase::Duration::EXTENSIVE);
837 1,
838 0,
839 cel3,
840 cel3name,
841 true,
842 sched,
843 ho,
844 true,
845 useIdealRrc),
846 TestCase::Duration::EXTENSIVE);
848 1,
849 1,
850 cel3,
851 cel3name,
852 true,
853 sched,
854 ho,
855 true,
856 useIdealRrc),
857 TestCase::Duration::TAKES_FOREVER);
859 1,
860 2,
861 cel3,
862 cel3name,
863 true,
864 sched,
865 ho,
866 true,
867 useIdealRrc),
868 TestCase::Duration::TAKES_FOREVER);
869 }
870
871 sched = "ns3::RrFfMacScheduler";
872 for (auto useIdealRrc : {true, false})
873 {
874 // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, admitHo, idealRrc
876 1,
877 0,
878 cel1,
879 cel1name,
880 true,
881 sched,
882 ho,
883 true,
884 useIdealRrc),
885 TestCase::Duration::EXTENSIVE);
887 1,
888 0,
889 cel2,
890 cel2name,
891 true,
892 sched,
893 ho,
894 true,
895 useIdealRrc),
896 TestCase::Duration::TAKES_FOREVER);
898 1,
899 0,
900 cel3,
901 cel3name,
902 true,
903 sched,
904 ho,
905 true,
906 useIdealRrc),
907 TestCase::Duration::TAKES_FOREVER);
908 }
909
910 ho = "ns3::A3RsrpHandoverAlgorithm";
911 sched = "ns3::PfFfMacScheduler";
912 for (auto useIdealRrc : {true, false})
913 {
914 // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, admitHo, idealRrc
916 1,
917 0,
918 cel1,
919 cel1name,
920 true,
921 sched,
922 ho,
923 true,
924 useIdealRrc),
925 TestCase::Duration::EXTENSIVE);
927 1,
928 0,
929 cel2,
930 cel2name,
931 true,
932 sched,
933 ho,
934 true,
935 useIdealRrc),
936 TestCase::Duration::TAKES_FOREVER);
938 1,
939 0,
940 cel3,
941 cel3name,
942 true,
943 sched,
944 ho,
945 true,
946 useIdealRrc),
947 TestCase::Duration::TAKES_FOREVER);
948 }
949
950 sched = "ns3::RrFfMacScheduler";
951 for (auto useIdealRrc : {true, false})
952 {
953 // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, admitHo, idealRrc
955 1,
956 0,
957 cel1,
958 cel1name,
959 true,
960 sched,
961 ho,
962 true,
963 useIdealRrc),
964 TestCase::Duration::QUICK);
966 1,
967 0,
968 cel2,
969 cel2name,
970 true,
971 sched,
972 ho,
973 true,
974 useIdealRrc),
975 TestCase::Duration::TAKES_FOREVER);
977 1,
978 0,
979 cel3,
980 cel3name,
981 true,
982 sched,
983 ho,
984 true,
985 useIdealRrc),
986 TestCase::Duration::EXTENSIVE);
987 }
988
989} // end of LteX2HandoverMeasuresTestSuite ()
990
991/**
992 * @ingroup lte-test
993 * Static variable for test initialization
994 */
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.
AttributeValue implementation for Boolean.
Definition boolean.h:26
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
AttributeValue implementation for DataRate.
Definition data-rate.h:285
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
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:62
Build a set of PointToPointNetDevice objects.
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
NetDeviceContainer Install(NodeContainer c)
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:561
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static 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
AttributeValue implementation for Time.
Definition nstime.h:1432
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:851
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:886
#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:1345
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1357
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