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 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
601 uint16_t ueCellId = ueRrc->GetCellId();
602 uint16_t enbCellId = enbLteDevice->GetCellId();
603 uint8_t ueDlBandwidth = ueRrc->GetDlBandwidth();
604 uint8_t enbDlBandwidth = enbLteDevice->GetDlBandwidth();
605 uint8_t ueUlBandwidth = ueRrc->GetUlBandwidth();
606 uint8_t enbUlBandwidth = enbLteDevice->GetUlBandwidth();
607 uint8_t ueDlEarfcn = ueRrc->GetDlEarfcn();
608 uint8_t enbDlEarfcn = enbLteDevice->GetDlEarfcn();
609 uint8_t ueUlEarfcn = ueRrc->GetUlEarfcn();
610 uint8_t enbUlEarfcn = enbLteDevice->GetUlEarfcn();
611 uint64_t ueImsi = ueLteDevice->GetImsi();
612 uint64_t enbImsi = ueManager->GetImsi();
613
614 NS_TEST_ASSERT_MSG_EQ(ueImsi, enbImsi, "inconsistent IMSI");
615 NS_TEST_ASSERT_MSG_EQ(ueCellId, enbCellId, "inconsistent CellId");
616 NS_TEST_ASSERT_MSG_EQ(ueDlBandwidth, enbDlBandwidth, "inconsistent DlBandwidth");
617 NS_TEST_ASSERT_MSG_EQ(ueUlBandwidth, enbUlBandwidth, "inconsistent UlBandwidth");
618 NS_TEST_ASSERT_MSG_EQ(ueDlEarfcn, enbDlEarfcn, "inconsistent DlEarfcn");
619 NS_TEST_ASSERT_MSG_EQ(ueUlEarfcn, enbUlEarfcn, "inconsistent UlEarfcn");
620
621 ObjectMapValue enbDataRadioBearerMapValue;
622 ueManager->GetAttribute("DataRadioBearerMap", enbDataRadioBearerMapValue);
623 NS_TEST_ASSERT_MSG_EQ(enbDataRadioBearerMapValue.GetN(),
625 "wrong num bearers at eNB");
626
627 ObjectMapValue ueDataRadioBearerMapValue;
628 ueRrc->GetAttribute("DataRadioBearerMap", ueDataRadioBearerMapValue);
629 NS_TEST_ASSERT_MSG_EQ(ueDataRadioBearerMapValue.GetN(),
631 "wrong num bearers at UE");
632
633 auto enbBearerIt = enbDataRadioBearerMapValue.Begin();
634 auto ueBearerIt = ueDataRadioBearerMapValue.Begin();
635 while (enbBearerIt != enbDataRadioBearerMapValue.End() &&
636 ueBearerIt != ueDataRadioBearerMapValue.End())
637 {
638 Ptr<LteDataRadioBearerInfo> enbDrbInfo =
639 enbBearerIt->second->GetObject<LteDataRadioBearerInfo>();
641 ueBearerIt->second->GetObject<LteDataRadioBearerInfo>();
642 // NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_epsBearer, ueDrbInfo->m_epsBearer, "epsBearer
643 // differs");
644 NS_TEST_ASSERT_MSG_EQ((uint32_t)enbDrbInfo->m_epsBearerIdentity,
645 (uint32_t)ueDrbInfo->m_epsBearerIdentity,
646 "epsBearerIdentity differs");
647 NS_TEST_ASSERT_MSG_EQ((uint32_t)enbDrbInfo->m_drbIdentity,
648 (uint32_t)ueDrbInfo->m_drbIdentity,
649 "drbIdentity differs");
650 // NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_rlcConfig, ueDrbInfo->m_rlcConfig, "rlcConfig
651 // differs");
652 NS_TEST_ASSERT_MSG_EQ((uint32_t)enbDrbInfo->m_logicalChannelIdentity,
653 (uint32_t)ueDrbInfo->m_logicalChannelIdentity,
654 "logicalChannelIdentity differs");
655 // NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_logicalChannelConfig,
656 // ueDrbInfo->m_logicalChannelConfig, "logicalChannelConfig differs");
657
658 ++enbBearerIt;
659 ++ueBearerIt;
660 }
661 NS_ASSERT_MSG(enbBearerIt == enbDataRadioBearerMapValue.End(), "too many bearers at eNB");
662 NS_ASSERT_MSG(ueBearerIt == ueDataRadioBearerMapValue.End(), "too many bearers at UE");
663}
664
665void
667{
668 NS_LOG_FUNCTION(ueIndex);
669 for (auto it = m_ueDataVector.at(ueIndex).bearerDataList.begin();
670 it != m_ueDataVector.at(ueIndex).bearerDataList.end();
671 ++it)
672 {
673 if (it->dlSink)
674 {
675 it->dlOldTotalRx = it->dlSink->GetTotalRx();
676 }
677 if (it->ulSink)
678 {
679 it->ulOldTotalRx = it->ulSink->GetTotalRx();
680 }
681 }
682}
683
684void
686{
687 NS_LOG_FUNCTION(ueIndex);
688 uint32_t b = 1;
689 for (auto it = m_ueDataVector.at(ueIndex).bearerDataList.begin();
690 it != m_ueDataVector.at(ueIndex).bearerDataList.end();
691 ++it)
692 {
693 uint32_t dlRx = 0;
694 uint32_t ulRx = 0;
695
696 if (it->dlSink)
697 {
698 dlRx = it->dlSink->GetTotalRx() - it->dlOldTotalRx;
699 }
700
701 if (it->ulSink)
702 {
703 ulRx = it->ulSink->GetTotalRx() - it->ulOldTotalRx;
704 }
705 double expectedBytes =
707
708 NS_LOG_LOGIC("expBytes " << expectedBytes << " dlRx " << dlRx << " ulRx " << ulRx);
709
710 // tolerance
711 if (it->dlSink)
712 {
714 0.500 * expectedBytes,
715 "too few RX bytes in DL, ue=" << ueIndex << ", b=" << b);
716 }
717 if (it->ulSink)
718 {
720 0.500 * expectedBytes,
721 "too few RX bytes in UL, ue=" << ueIndex << ", b=" << b);
722 }
723 ++b;
724 }
725}
726
727/**
728 * @ingroup lte-test
729 *
730 * @brief Lte X2 Handover Measures Test Suite
731 */
737
739 : TestSuite("lte-x2-handover-measures", Type::SYSTEM)
740{
741 Time checkInterval = Seconds(1);
742
743 std::string cel1name("ho: 0 -> 1");
744 const std::list<CheckPointEvent> cel1{
745 CheckPointEvent(Seconds(1), Seconds(10.1), checkInterval, 0, 0),
746 CheckPointEvent(Seconds(11), Seconds(17), checkInterval, 0, 1),
747 };
748
749 std::string cel2name("ho: 0 -> 1 -> 2");
750 const std::list<CheckPointEvent> cel2{
751 CheckPointEvent(Seconds(1), Seconds(10.1), checkInterval, 0, 0),
752 CheckPointEvent(Seconds(11), Seconds(17.1), checkInterval, 0, 1),
753 CheckPointEvent(Seconds(18), Seconds(24), checkInterval, 0, 2),
754 };
755
756 std::string cel3name("ho: 0 -> 1 -> 2 -> 3");
757 const std::list<CheckPointEvent> cel3{
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.1), checkInterval, 0, 2),
761 CheckPointEvent(Seconds(25), Seconds(37), checkInterval, 0, 3),
762 };
763
764 std::string sched = "ns3::PfFfMacScheduler";
765 std::string ho = "ns3::A2A4RsrqHandoverAlgorithm";
766 for (auto useIdealRrc : {true, false})
767 {
768 // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, ho, admitHo, idealRrc
770 1,
771 0,
772 cel1,
773 cel1name,
774 true,
775 sched,
776 ho,
777 true,
778 useIdealRrc),
781 1,
782 1,
783 cel1,
784 cel1name,
785 true,
786 sched,
787 ho,
788 true,
789 useIdealRrc),
792 1,
793 2,
794 cel1,
795 cel1name,
796 true,
797 sched,
798 ho,
799 true,
800 useIdealRrc),
803 1,
804 0,
805 cel2,
806 cel2name,
807 true,
808 sched,
809 ho,
810 true,
811 useIdealRrc),
814 1,
815 1,
816 cel2,
817 cel2name,
818 true,
819 sched,
820 ho,
821 true,
822 useIdealRrc),
825 1,
826 2,
827 cel2,
828 cel2name,
829 true,
830 sched,
831 ho,
832 true,
833 useIdealRrc),
836 1,
837 0,
838 cel3,
839 cel3name,
840 true,
841 sched,
842 ho,
843 true,
844 useIdealRrc),
847 1,
848 1,
849 cel3,
850 cel3name,
851 true,
852 sched,
853 ho,
854 true,
855 useIdealRrc),
858 1,
859 2,
860 cel3,
861 cel3name,
862 true,
863 sched,
864 ho,
865 true,
866 useIdealRrc),
868 }
869
870 sched = "ns3::RrFfMacScheduler";
871 for (auto useIdealRrc : {true, false})
872 {
873 // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, admitHo, idealRrc
875 1,
876 0,
877 cel1,
878 cel1name,
879 true,
880 sched,
881 ho,
882 true,
883 useIdealRrc),
886 1,
887 0,
888 cel2,
889 cel2name,
890 true,
891 sched,
892 ho,
893 true,
894 useIdealRrc),
897 1,
898 0,
899 cel3,
900 cel3name,
901 true,
902 sched,
903 ho,
904 true,
905 useIdealRrc),
907 }
908
909 ho = "ns3::A3RsrpHandoverAlgorithm";
910 sched = "ns3::PfFfMacScheduler";
911 for (auto useIdealRrc : {true, false})
912 {
913 // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, admitHo, idealRrc
915 1,
916 0,
917 cel1,
918 cel1name,
919 true,
920 sched,
921 ho,
922 true,
923 useIdealRrc),
926 1,
927 0,
928 cel2,
929 cel2name,
930 true,
931 sched,
932 ho,
933 true,
934 useIdealRrc),
937 1,
938 0,
939 cel3,
940 cel3name,
941 true,
942 sched,
943 ho,
944 true,
945 useIdealRrc),
947 }
948
949 sched = "ns3::RrFfMacScheduler";
950 for (auto useIdealRrc : {true, false})
951 {
952 // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, admitHo, idealRrc
954 1,
955 0,
956 cel1,
957 cel1name,
958 true,
959 sched,
960 ho,
961 true,
962 useIdealRrc),
965 1,
966 0,
967 cel2,
968 cel2name,
969 true,
970 sched,
971 ho,
972 true,
973 useIdealRrc),
976 1,
977 0,
978 cel3,
979 cel3name,
980 true,
981 sched,
982 ho,
983 true,
984 useIdealRrc),
986 }
987
988} // end of LteX2HandoverMeasuresTestSuite ()
989
990/**
991 * @ingroup lte-test
992 * Static variable for test initialization
993 */
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: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
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.
Definition ptr.h:67
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
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:293
@ EXTENSIVE
Medium length test.
Definition test.h:1055
@ QUICK
Fast test.
Definition test.h:1054
@ TAKES_FOREVER
Very long running test.
Definition test.h:1056
TestCase(const TestCase &)=delete
Type
Type of test.
Definition test.h:1257
TestSuite(std::string name, Type type=Type::UNIT)
Construct a new test suite.
Definition test.cc:491
Simulation virtual time values and global simulation resolution.
Definition nstime.h:96
AttributeValue implementation for Time.
Definition nstime.h:1456
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: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:439
#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:1369
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1381
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