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)
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),
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 // Call AssignStreams in the EpcHelper only once by setting 'assignEpcStreams' only once
338 // Then, increment the stream value by 1000 (a magic number that should ensure that there
339 // are no overlapping stream assignments) each time that AssignStreams is called,
340 // to lessen the possibility that random variable stream assignment changes propagate
341 // to other objects.
342 m_lteHelper->AssignStreams(enbDevices, stream, false);
343 stream += 1000;
344 for (auto it = enbDevices.Begin(); it != enbDevices.End(); ++it)
345 {
346 Ptr<LteEnbRrc> enbRrc = (*it)->GetObject<LteEnbNetDevice>()->GetRrc();
347 enbRrc->SetAttribute("AdmitHandoverRequest", BooleanValue(m_admitHo));
348 }
349
350 NetDeviceContainer ueDevices;
351 ueDevices = m_lteHelper->InstallUeDevice(ueNodes);
352 m_lteHelper->AssignStreams(ueDevices, stream, true);
353 stream += 1000;
354
355 Ipv4Address remoteHostAddr;
356 Ipv4StaticRoutingHelper ipv4RoutingHelper;
357 Ipv4InterfaceContainer ueIpIfaces;
358 Ptr<Node> remoteHost;
359 if (m_epc)
360 {
361 // Create a single RemoteHost
362 NodeContainer remoteHostContainer;
363 remoteHostContainer.Create(1);
364 remoteHost = remoteHostContainer.Get(0);
365 InternetStackHelper internet;
366 internet.Install(remoteHostContainer);
367
368 // Create the Internet
370 p2ph.SetDeviceAttribute("DataRate", DataRateValue(DataRate("100Gb/s")));
371 p2ph.SetDeviceAttribute("Mtu", UintegerValue(1500));
372 p2ph.SetChannelAttribute("Delay", TimeValue(Seconds(0.010)));
373 Ptr<Node> pgw = m_epcHelper->GetPgwNode();
374 NetDeviceContainer internetDevices = p2ph.Install(pgw, remoteHost);
375 Ipv4AddressHelper ipv4h;
376 ipv4h.SetBase("1.0.0.0", "255.0.0.0");
377 Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign(internetDevices);
378 // in this container, interface 0 is the pgw, 1 is the remoteHost
379 remoteHostAddr = internetIpIfaces.GetAddress(1);
380
381 Ipv4StaticRoutingHelper ipv4RoutingHelper;
382 Ptr<Ipv4StaticRouting> remoteHostStaticRouting =
383 ipv4RoutingHelper.GetStaticRouting(remoteHost->GetObject<Ipv4>());
384 remoteHostStaticRouting->AddNetworkRouteTo(Ipv4Address("7.0.0.0"),
385 Ipv4Mask("255.0.0.0"),
386 1);
387
388 // Install the IP stack on the UEs
389 internet.Install(ueNodes);
390 ueIpIfaces = m_epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueDevices));
391 }
392
393 // attachment (needs to be done after IP stack configuration)
394 // all UEs attached to eNB 0 at the beginning
395 m_lteHelper->Attach(ueDevices, enbDevices.Get(0));
396
397 if (m_epc)
398 {
399 bool epcDl = true;
400 bool epcUl = false;
401 // the rest of this block is copied from lena-dual-stripe
402
403 // Install and start applications on UEs and remote host
404 uint16_t dlPort = 10000;
405 uint16_t ulPort = 20000;
406
407 // randomize a bit start times to avoid simulation artifacts
408 // (e.g., buffer overflows due to packet transmissions happening
409 // exactly at the same time)
411 startTimeSeconds->SetAttribute("Min", DoubleValue(0));
412 startTimeSeconds->SetAttribute("Max", DoubleValue(0.010));
413 startTimeSeconds->SetStream(stream++);
414
415 for (uint32_t u = 0; u < ueNodes.GetN(); ++u)
416 {
417 Ptr<Node> ue = ueNodes.Get(u);
418 // Set the default gateway for the UE
419 Ptr<Ipv4StaticRouting> ueStaticRouting =
420 ipv4RoutingHelper.GetStaticRouting(ue->GetObject<Ipv4>());
421 ueStaticRouting->SetDefaultRoute(m_epcHelper->GetUeDefaultGatewayAddress(), 1);
422
423 UeData ueData;
424
425 for (uint32_t b = 0; b < m_nDedicatedBearers; ++b)
426 {
427 ++dlPort;
428 ++ulPort;
429
430 ApplicationContainer clientApps;
431 ApplicationContainer serverApps;
432 BearerData bearerData = BearerData();
433
434 if (m_useUdp)
435 {
436 if (epcDl)
437 {
438 UdpClientHelper dlClientHelper(ueIpIfaces.GetAddress(u), dlPort);
439 clientApps.Add(dlClientHelper.Install(remoteHost));
440 PacketSinkHelper dlPacketSinkHelper(
441 "ns3::UdpSocketFactory",
443 ApplicationContainer sinkContainer = dlPacketSinkHelper.Install(ue);
444 bearerData.dlSink = sinkContainer.Get(0)->GetObject<PacketSink>();
445 serverApps.Add(sinkContainer);
446 }
447 if (epcUl)
448 {
449 UdpClientHelper ulClientHelper(remoteHostAddr, ulPort);
450 clientApps.Add(ulClientHelper.Install(ue));
451 PacketSinkHelper ulPacketSinkHelper(
452 "ns3::UdpSocketFactory",
454 ApplicationContainer sinkContainer = ulPacketSinkHelper.Install(remoteHost);
455 bearerData.ulSink = sinkContainer.Get(0)->GetObject<PacketSink>();
456 serverApps.Add(sinkContainer);
457 }
458 }
459 else // use TCP
460 {
461 if (epcDl)
462 {
463 BulkSendHelper dlClientHelper(
464 "ns3::TcpSocketFactory",
465 InetSocketAddress(ueIpIfaces.GetAddress(u), dlPort));
466 dlClientHelper.SetAttribute("MaxBytes", UintegerValue(0));
467 clientApps.Add(dlClientHelper.Install(remoteHost));
468 PacketSinkHelper dlPacketSinkHelper(
469 "ns3::TcpSocketFactory",
471 ApplicationContainer sinkContainer = dlPacketSinkHelper.Install(ue);
472 bearerData.dlSink = sinkContainer.Get(0)->GetObject<PacketSink>();
473 serverApps.Add(sinkContainer);
474 }
475 if (epcUl)
476 {
477 BulkSendHelper ulClientHelper("ns3::TcpSocketFactory",
478 InetSocketAddress(remoteHostAddr, ulPort));
479 ulClientHelper.SetAttribute("MaxBytes", UintegerValue(0));
480 clientApps.Add(ulClientHelper.Install(ue));
481 PacketSinkHelper ulPacketSinkHelper(
482 "ns3::TcpSocketFactory",
484 ApplicationContainer sinkContainer = ulPacketSinkHelper.Install(remoteHost);
485 bearerData.ulSink = sinkContainer.Get(0)->GetObject<PacketSink>();
486 serverApps.Add(sinkContainer);
487 }
488 }
489
491 if (epcDl)
492 {
494 dlpf.localPortStart = dlPort;
495 dlpf.localPortEnd = dlPort;
496 tft->Add(dlpf);
497 }
498 if (epcUl)
499 {
501 ulpf.remotePortStart = ulPort;
502 ulpf.remotePortEnd = ulPort;
503 tft->Add(ulpf);
504 }
505
506 if (epcDl || epcUl)
507 {
509 m_lteHelper->ActivateDedicatedEpsBearer(ueDevices.Get(u), bearer, tft);
510 }
511 Time startTime = Seconds(startTimeSeconds->GetValue());
512 serverApps.Start(startTime);
513 clientApps.Start(startTime);
514
515 ueData.bearerDataList.push_back(bearerData);
516 }
517
518 m_ueDataVector.push_back(ueData);
519 }
520 }
521 else // (epc == false)
522 {
523 // for radio bearer activation purposes, consider together home UEs and macro UEs
524 for (uint32_t u = 0; u < ueDevices.GetN(); ++u)
525 {
526 Ptr<NetDevice> ueDev = ueDevices.Get(u);
527 for (uint32_t b = 0; b < m_nDedicatedBearers; ++b)
528 {
530 EpsBearer bearer(q);
531 m_lteHelper->ActivateDataRadioBearer(ueDev, bearer);
532 }
533 }
534 }
535
536 m_lteHelper->AddX2Interface(enbNodes);
537
538 // check initial RRC connection
539 const Time maxRrcConnectionEstablishmentDuration = Seconds(0.080);
540 for (auto it = ueDevices.Begin(); it != ueDevices.End(); ++it)
541 {
542 NS_LOG_FUNCTION(maxRrcConnectionEstablishmentDuration);
543 Simulator::Schedule(maxRrcConnectionEstablishmentDuration,
545 this,
546 *it,
547 enbDevices.Get(0));
548 }
549
550 // schedule the checkpoint events
551
553 for (auto checkPointEventIt = m_checkPointEventList.begin();
554 checkPointEventIt != m_checkPointEventList.end();
555 ++checkPointEventIt)
556 {
557 for (Time checkPointTime = checkPointEventIt->checkStartTime;
558 checkPointTime < checkPointEventIt->checkStopTime;
559 checkPointTime += checkPointEventIt->checkInterval)
560 {
561 Simulator::Schedule(checkPointTime,
563 this,
564 ueDevices.Get(checkPointEventIt->ueDeviceIndex),
565 enbDevices.Get(checkPointEventIt->enbDeviceIndex));
566
567 Simulator::Schedule(checkPointTime,
569 this,
570 checkPointEventIt->ueDeviceIndex);
571
572 Time checkStats = checkPointTime + m_statsDuration;
573 Simulator::Schedule(checkStats,
575 this,
576 checkPointEventIt->ueDeviceIndex);
577
578 if (stopTime <= checkStats)
579 {
580 stopTime = checkStats + Seconds(1);
581 }
582 }
583 }
584
588}
589
590void
592{
593 NS_LOG_FUNCTION(ueDevice << enbDevice);
594
595 Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice>();
596 Ptr<LteUeRrc> ueRrc = ueLteDevice->GetRrc();
597 NS_TEST_ASSERT_MSG_EQ(ueRrc->GetState(), LteUeRrc::CONNECTED_NORMALLY, "Wrong LteUeRrc state!");
598
599 Ptr<LteEnbNetDevice> enbLteDevice = enbDevice->GetObject<LteEnbNetDevice>();
600 Ptr<LteEnbRrc> enbRrc = enbLteDevice->GetRrc();
601 uint16_t rnti = ueRrc->GetRnti();
602 Ptr<UeManager> ueManager = enbRrc->GetUeManager(rnti);
603 NS_TEST_ASSERT_MSG_NE(ueManager, nullptr, "RNTI " << rnti << " not found in eNB");
604
605 UeManager::State ueManagerState = ueManager->GetState();
606 NS_TEST_ASSERT_MSG_EQ(ueManagerState, UeManager::CONNECTED_NORMALLY, "Wrong UeManager state!");
607
608 uint16_t ueCellId = ueRrc->GetCellId();
609 uint16_t enbCellId = enbLteDevice->GetCellId();
610 uint8_t ueDlBandwidth = ueRrc->GetDlBandwidth();
611 uint8_t enbDlBandwidth = enbLteDevice->GetDlBandwidth();
612 uint8_t ueUlBandwidth = ueRrc->GetUlBandwidth();
613 uint8_t enbUlBandwidth = enbLteDevice->GetUlBandwidth();
614 uint8_t ueDlEarfcn = ueRrc->GetDlEarfcn();
615 uint8_t enbDlEarfcn = enbLteDevice->GetDlEarfcn();
616 uint8_t ueUlEarfcn = ueRrc->GetUlEarfcn();
617 uint8_t enbUlEarfcn = enbLteDevice->GetUlEarfcn();
618 uint64_t ueImsi = ueLteDevice->GetImsi();
619 uint64_t enbImsi = ueManager->GetImsi();
620
621 NS_TEST_ASSERT_MSG_EQ(ueImsi, enbImsi, "inconsistent IMSI");
622 NS_TEST_ASSERT_MSG_EQ(ueCellId, enbCellId, "inconsistent CellId");
623 NS_TEST_ASSERT_MSG_EQ(ueDlBandwidth, enbDlBandwidth, "inconsistent DlBandwidth");
624 NS_TEST_ASSERT_MSG_EQ(ueUlBandwidth, enbUlBandwidth, "inconsistent UlBandwidth");
625 NS_TEST_ASSERT_MSG_EQ(ueDlEarfcn, enbDlEarfcn, "inconsistent DlEarfcn");
626 NS_TEST_ASSERT_MSG_EQ(ueUlEarfcn, enbUlEarfcn, "inconsistent UlEarfcn");
627
628 ObjectMapValue enbDataRadioBearerMapValue;
629 ueManager->GetAttribute("DataRadioBearerMap", enbDataRadioBearerMapValue);
630 NS_TEST_ASSERT_MSG_EQ(enbDataRadioBearerMapValue.GetN(),
632 "wrong num bearers at eNB");
633
634 ObjectMapValue ueDataRadioBearerMapValue;
635 ueRrc->GetAttribute("DataRadioBearerMap", ueDataRadioBearerMapValue);
636 NS_TEST_ASSERT_MSG_EQ(ueDataRadioBearerMapValue.GetN(),
638 "wrong num bearers at UE");
639
640 auto enbBearerIt = enbDataRadioBearerMapValue.Begin();
641 auto ueBearerIt = ueDataRadioBearerMapValue.Begin();
642 while (enbBearerIt != enbDataRadioBearerMapValue.End() &&
643 ueBearerIt != ueDataRadioBearerMapValue.End())
644 {
645 Ptr<LteDataRadioBearerInfo> enbDrbInfo =
646 enbBearerIt->second->GetObject<LteDataRadioBearerInfo>();
648 ueBearerIt->second->GetObject<LteDataRadioBearerInfo>();
649 // NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_epsBearer, ueDrbInfo->m_epsBearer, "epsBearer
650 // differs");
651 NS_TEST_ASSERT_MSG_EQ((uint32_t)enbDrbInfo->m_epsBearerIdentity,
652 (uint32_t)ueDrbInfo->m_epsBearerIdentity,
653 "epsBearerIdentity differs");
654 NS_TEST_ASSERT_MSG_EQ((uint32_t)enbDrbInfo->m_drbIdentity,
655 (uint32_t)ueDrbInfo->m_drbIdentity,
656 "drbIdentity differs");
657 // NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_rlcConfig, ueDrbInfo->m_rlcConfig, "rlcConfig
658 // differs");
659 NS_TEST_ASSERT_MSG_EQ((uint32_t)enbDrbInfo->m_logicalChannelIdentity,
660 (uint32_t)ueDrbInfo->m_logicalChannelIdentity,
661 "logicalChannelIdentity differs");
662 // NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_logicalChannelConfig,
663 // ueDrbInfo->m_logicalChannelConfig, "logicalChannelConfig differs");
664
665 ++enbBearerIt;
666 ++ueBearerIt;
667 }
668 NS_ASSERT_MSG(enbBearerIt == enbDataRadioBearerMapValue.End(), "too many bearers at eNB");
669 NS_ASSERT_MSG(ueBearerIt == ueDataRadioBearerMapValue.End(), "too many bearers at UE");
670}
671
672void
674{
675 NS_LOG_FUNCTION(ueIndex);
676 for (auto it = m_ueDataVector.at(ueIndex).bearerDataList.begin();
677 it != m_ueDataVector.at(ueIndex).bearerDataList.end();
678 ++it)
679 {
680 if (it->dlSink)
681 {
682 it->dlOldTotalRx = it->dlSink->GetTotalRx();
683 }
684 if (it->ulSink)
685 {
686 it->ulOldTotalRx = it->ulSink->GetTotalRx();
687 }
688 }
689}
690
691void
693{
694 NS_LOG_FUNCTION(ueIndex);
695 uint32_t b = 1;
696 for (auto it = m_ueDataVector.at(ueIndex).bearerDataList.begin();
697 it != m_ueDataVector.at(ueIndex).bearerDataList.end();
698 ++it)
699 {
700 uint32_t dlRx = 0;
701 uint32_t ulRx = 0;
702
703 if (it->dlSink)
704 {
705 dlRx = it->dlSink->GetTotalRx() - it->dlOldTotalRx;
706 }
707
708 if (it->ulSink)
709 {
710 ulRx = it->ulSink->GetTotalRx() - it->ulOldTotalRx;
711 }
712 double expectedBytes =
714
715 NS_LOG_LOGIC("expBytes " << expectedBytes << " dlRx " << dlRx << " ulRx " << ulRx);
716
717 // tolerance
718 if (it->dlSink)
719 {
721 0.500 * expectedBytes,
722 "too few RX bytes in DL, ue=" << ueIndex << ", b=" << b);
723 }
724 if (it->ulSink)
725 {
727 0.500 * expectedBytes,
728 "too few RX bytes in UL, ue=" << ueIndex << ", b=" << b);
729 }
730 ++b;
731 }
732}
733
734/**
735 * @ingroup lte-test
736 *
737 * @brief Lte X2 Handover Measures Test Suite
738 */
744
746 : TestSuite("lte-x2-handover-measures", Type::SYSTEM)
747{
748 Time checkInterval = Seconds(1);
749
750 std::string cel1name("ho: 0 -> 1");
751 const std::list<CheckPointEvent> cel1{
752 CheckPointEvent(Seconds(1), Seconds(10.1), checkInterval, 0, 0),
753 CheckPointEvent(Seconds(11), Seconds(17), checkInterval, 0, 1),
754 };
755
756 std::string cel2name("ho: 0 -> 1 -> 2");
757 const std::list<CheckPointEvent> cel2{
758 CheckPointEvent(Seconds(1), Seconds(10.1), checkInterval, 0, 0),
759 CheckPointEvent(Seconds(11), Seconds(17.1), checkInterval, 0, 1),
760 CheckPointEvent(Seconds(18), Seconds(24), checkInterval, 0, 2),
761 };
762
763 std::string cel3name("ho: 0 -> 1 -> 2 -> 3");
764 const std::list<CheckPointEvent> cel3{
765 CheckPointEvent(Seconds(1), Seconds(10.1), checkInterval, 0, 0),
766 CheckPointEvent(Seconds(11), Seconds(17.1), checkInterval, 0, 1),
767 CheckPointEvent(Seconds(18), Seconds(24.1), checkInterval, 0, 2),
768 CheckPointEvent(Seconds(25), Seconds(37), checkInterval, 0, 3),
769 };
770
771 std::string sched = "ns3::PfFfMacScheduler";
772 std::string ho = "ns3::A2A4RsrqHandoverAlgorithm";
773 for (auto useIdealRrc : {true, false})
774 {
775 // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, ho, admitHo, idealRrc
777 1,
778 0,
779 cel1,
780 cel1name,
781 true,
782 sched,
783 ho,
784 true,
785 useIdealRrc),
788 1,
789 1,
790 cel1,
791 cel1name,
792 true,
793 sched,
794 ho,
795 true,
796 useIdealRrc),
799 1,
800 2,
801 cel1,
802 cel1name,
803 true,
804 sched,
805 ho,
806 true,
807 useIdealRrc),
810 1,
811 0,
812 cel2,
813 cel2name,
814 true,
815 sched,
816 ho,
817 true,
818 useIdealRrc),
821 1,
822 1,
823 cel2,
824 cel2name,
825 true,
826 sched,
827 ho,
828 true,
829 useIdealRrc),
832 1,
833 2,
834 cel2,
835 cel2name,
836 true,
837 sched,
838 ho,
839 true,
840 useIdealRrc),
843 1,
844 0,
845 cel3,
846 cel3name,
847 true,
848 sched,
849 ho,
850 true,
851 useIdealRrc),
854 1,
855 1,
856 cel3,
857 cel3name,
858 true,
859 sched,
860 ho,
861 true,
862 useIdealRrc),
865 1,
866 2,
867 cel3,
868 cel3name,
869 true,
870 sched,
871 ho,
872 true,
873 useIdealRrc),
875 }
876
877 sched = "ns3::RrFfMacScheduler";
878 for (auto useIdealRrc : {true, false})
879 {
880 // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, admitHo, idealRrc
882 1,
883 0,
884 cel1,
885 cel1name,
886 true,
887 sched,
888 ho,
889 true,
890 useIdealRrc),
893 1,
894 0,
895 cel2,
896 cel2name,
897 true,
898 sched,
899 ho,
900 true,
901 useIdealRrc),
904 1,
905 0,
906 cel3,
907 cel3name,
908 true,
909 sched,
910 ho,
911 true,
912 useIdealRrc),
914 }
915
916 ho = "ns3::A3RsrpHandoverAlgorithm";
917 sched = "ns3::PfFfMacScheduler";
918 for (auto useIdealRrc : {true, false})
919 {
920 // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, admitHo, idealRrc
922 1,
923 0,
924 cel1,
925 cel1name,
926 true,
927 sched,
928 ho,
929 true,
930 useIdealRrc),
933 1,
934 0,
935 cel2,
936 cel2name,
937 true,
938 sched,
939 ho,
940 true,
941 useIdealRrc),
944 1,
945 0,
946 cel3,
947 cel3name,
948 true,
949 sched,
950 ho,
951 true,
952 useIdealRrc),
954 }
955
956 sched = "ns3::RrFfMacScheduler";
957 for (auto useIdealRrc : {true, false})
958 {
959 // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, admitHo, idealRrc
961 1,
962 0,
963 cel1,
964 cel1name,
965 true,
966 sched,
967 ho,
968 true,
969 useIdealRrc),
972 1,
973 0,
974 cel2,
975 cel2name,
976 true,
977 sched,
978 ho,
979 true,
980 useIdealRrc),
983 1,
984 0,
985 cel3,
986 cel3name,
987 true,
988 sched,
989 ho,
990 true,
991 useIdealRrc),
993 }
994
995} // end of LteX2HandoverMeasuresTestSuite ()
996
997/**
998 * @ingroup lte-test
999 * Static variable for test initialization
1000 */
uint32_t q
uint32_t u
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:252
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:518
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:61
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.
Definition ptr.h:70
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:580
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:125
static void Run()
Run the simulation.
Definition simulator.cc:161
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:169
Hold variables of type string.
Definition string.h:45
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:296
@ EXTENSIVE
Medium length test.
Definition test.h:1058
@ QUICK
Fast test.
Definition test.h:1057
@ TAKES_FOREVER
Very long running test.
Definition test.h:1059
TestCase(const TestCase &)=delete
Caller graph was not generated because of its size.
Type
Type of test.
Definition test.h:1271
TestSuite(std::string name, Type type=Type::UNIT)
Construct a new test suite.
Definition test.cc:494
Simulation virtual time values and global simulation resolution.
Definition nstime.h:95
AttributeValue implementation for Time.
Definition nstime.h:1375
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
ObjectPtrContainerValue ObjectMapValue
ObjectMapValue is an alias for ObjectPtrContainerValue.
Definition object-map.h:29
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:194
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:274
#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:627
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:454
#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:133
#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:553
#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:863
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1273
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1290
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