A Discrete-Event Network Simulator
API
test-lte-x2-handover.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Nicola Baldo <nbaldo@cttc.es>
18 */
19
20#include <ns3/applications-module.h>
21#include <ns3/core-module.h>
22#include <ns3/internet-module.h>
23#include <ns3/lte-module.h>
24#include <ns3/mobility-module.h>
25#include <ns3/network-module.h>
26#include <ns3/point-to-point-module.h>
27
28using namespace ns3;
29
30NS_LOG_COMPONENT_DEFINE("LteX2HandoverTest");
31
39{
44};
45
54{
55 public:
68 uint32_t nDedicatedBearers,
69 std::list<HandoverEvent> handoverEventList,
70 std::string handoverEventListName,
71 std::string schedulerType,
72 bool admitHo,
73 bool useIdealRrc);
74
75 private:
86 static std::string BuildNameString(uint32_t nUes,
87 uint32_t nDedicatedBearers,
88 std::string handoverEventListName,
89 std::string schedulerType,
90 bool admitHo,
91 bool useIdealRrc);
92 void DoRun() override;
98 void CheckConnected(Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice);
99
104 void TeleportUeToMiddle(Ptr<Node> ueNode);
105
111 void TeleportUeNearTargetEnb(Ptr<Node> ueNode, Ptr<Node> enbNode);
112
115 std::list<HandoverEvent> m_handoverEventList;
117 bool m_epc;
118 std::string m_schedulerType;
123
131 {
137 };
138
145 struct UeData
146 {
148 std::list<BearerData> bearerDataList;
149 };
150
155 void SaveStatsAfterHandover(uint32_t ueIndex);
161
162 std::vector<UeData> m_ueDataVector;
163
168};
169
170std::string
172 uint32_t nDedicatedBearers,
173 std::string handoverEventListName,
174 std::string schedulerType,
175 bool admitHo,
176 bool useIdealRrc)
177{
178 std::ostringstream oss;
179 oss << " nUes=" << nUes << " nDedicatedBearers=" << nDedicatedBearers << " " << schedulerType
180 << " admitHo=" << admitHo << " hoList: " << handoverEventListName;
181 if (useIdealRrc)
182 {
183 oss << ", ideal RRC";
184 }
185 else
186 {
187 oss << ", real RRC";
188 }
189 return oss.str();
190}
191
193 uint32_t nDedicatedBearers,
194 std::list<HandoverEvent> handoverEventList,
195 std::string handoverEventListName,
196 std::string schedulerType,
197 bool admitHo,
198 bool useIdealRrc)
199 : TestCase(BuildNameString(nUes,
200 nDedicatedBearers,
201 handoverEventListName,
202 schedulerType,
203 admitHo,
204 useIdealRrc)),
205 m_nUes(nUes),
206 m_nDedicatedBearers(nDedicatedBearers),
207 m_handoverEventList(handoverEventList),
208 m_handoverEventListName(handoverEventListName),
209 m_epc(true),
210 m_schedulerType(schedulerType),
211 m_admitHo(admitHo),
212 m_useIdealRrc(useIdealRrc),
213 m_maxHoDuration(Seconds(0.1)),
214 m_statsDuration(Seconds(0.1)),
215 m_udpClientInterval(Seconds(0.01)),
216 m_udpClientPktSize(100)
217
218{
219}
220
221void
223{
228 m_admitHo,
230
231 uint32_t previousSeed = RngSeedManager::GetSeed();
232 uint64_t previousRun = RngSeedManager::GetRun();
234 // This test is sensitive to random variable stream assigments
235 RngSeedManager::SetSeed(1);
236 RngSeedManager::SetRun(3);
237 Config::SetDefault("ns3::UdpClient::Interval", TimeValue(m_udpClientInterval));
238 Config::SetDefault("ns3::UdpClient::MaxPackets", UintegerValue(1000000));
239 Config::SetDefault("ns3::UdpClient::PacketSize", UintegerValue(m_udpClientPktSize));
240
241 // Disable Uplink Power Control
242 Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false));
243
244 int64_t stream = 1;
245
246 m_lteHelper = CreateObject<LteHelper>();
247 m_lteHelper->SetAttribute("PathlossModel",
248 StringValue("ns3::FriisSpectrumPropagationLossModel"));
251 "ns3::NoOpHandoverAlgorithm"); // disable automatic handover
253
254 NodeContainer enbNodes;
255 enbNodes.Create(2);
256 NodeContainer ueNodes;
257 ueNodes.Create(m_nUes);
258
259 if (m_epc)
260 {
261 m_epcHelper = CreateObject<PointToPointEpcHelper>();
263 }
264
265 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
266 positionAlloc->Add(Vector(-3000, 0, 0)); // enb0
267 positionAlloc->Add(Vector(3000, 0, 0)); // enb1
268 for (uint32_t i = 0; i < m_nUes; i++)
269 {
270 positionAlloc->Add(Vector(-3000, 100, 0));
271 }
273 mobility.SetPositionAllocator(positionAlloc);
274 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
275 mobility.Install(enbNodes);
276 mobility.Install(ueNodes);
277
278 NetDeviceContainer enbDevices;
279 enbDevices = m_lteHelper->InstallEnbDevice(enbNodes);
280 stream += m_lteHelper->AssignStreams(enbDevices, stream);
281 for (NetDeviceContainer::Iterator it = enbDevices.Begin(); it != enbDevices.End(); ++it)
282 {
283 Ptr<LteEnbRrc> enbRrc = (*it)->GetObject<LteEnbNetDevice>()->GetRrc();
284 enbRrc->SetAttribute("AdmitHandoverRequest", BooleanValue(m_admitHo));
285 }
286
287 NetDeviceContainer ueDevices;
288 ueDevices = m_lteHelper->InstallUeDevice(ueNodes);
289 stream += m_lteHelper->AssignStreams(ueDevices, stream);
290
291 Ipv4Address remoteHostAddr;
292 Ipv4StaticRoutingHelper ipv4RoutingHelper;
293 Ipv4InterfaceContainer ueIpIfaces;
294 Ptr<Node> remoteHost;
295 if (m_epc)
296 {
297 // Create a single RemoteHost
298 NodeContainer remoteHostContainer;
299 remoteHostContainer.Create(1);
300 remoteHost = remoteHostContainer.Get(0);
301 InternetStackHelper internet;
302 internet.Install(remoteHostContainer);
303
304 // Create the Internet
306 p2ph.SetDeviceAttribute("DataRate", DataRateValue(DataRate("100Gb/s")));
307 p2ph.SetDeviceAttribute("Mtu", UintegerValue(1500));
308 p2ph.SetChannelAttribute("Delay", TimeValue(Seconds(0.010)));
310 NetDeviceContainer internetDevices = p2ph.Install(pgw, remoteHost);
311 Ipv4AddressHelper ipv4h;
312 ipv4h.SetBase("1.0.0.0", "255.0.0.0");
313 Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign(internetDevices);
314 // in this container, interface 0 is the pgw, 1 is the remoteHost
315 remoteHostAddr = internetIpIfaces.GetAddress(1);
316
317 Ipv4StaticRoutingHelper ipv4RoutingHelper;
318 Ptr<Ipv4StaticRouting> remoteHostStaticRouting =
319 ipv4RoutingHelper.GetStaticRouting(remoteHost->GetObject<Ipv4>());
320 remoteHostStaticRouting->AddNetworkRouteTo(Ipv4Address("7.0.0.0"),
321 Ipv4Mask("255.0.0.0"),
322 1);
323
324 // Install the IP stack on the UEs
325 internet.Install(ueNodes);
326 ueIpIfaces = m_epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueDevices));
327 }
328
329 // attachment (needs to be done after IP stack configuration)
330 // all UEs attached to eNB 0 at the beginning
331 m_lteHelper->Attach(ueDevices, enbDevices.Get(0));
332
333 if (m_epc)
334 {
335 // always true: bool epcDl = true;
336 // always true: bool epcUl = true;
337 // the rest of this block is copied from lena-dual-stripe
338
339 // Install and start applications on UEs and remote host
340 uint16_t dlPort = 10000;
341 uint16_t ulPort = 20000;
342
343 // randomize a bit start times to avoid simulation artifacts
344 // (e.g., buffer overflows due to packet transmissions happening
345 // exactly at the same time)
346 Ptr<UniformRandomVariable> startTimeSeconds = CreateObject<UniformRandomVariable>();
347 startTimeSeconds->SetAttribute("Min", DoubleValue(0));
348 startTimeSeconds->SetAttribute("Max", DoubleValue(0.010));
349 startTimeSeconds->SetStream(stream++);
350
351 for (uint32_t u = 0; u < ueNodes.GetN(); ++u)
352 {
353 Ptr<Node> ue = ueNodes.Get(u);
354 // Set the default gateway for the UE
355 Ptr<Ipv4StaticRouting> ueStaticRouting =
356 ipv4RoutingHelper.GetStaticRouting(ue->GetObject<Ipv4>());
357 ueStaticRouting->SetDefaultRoute(m_epcHelper->GetUeDefaultGatewayAddress(), 1);
358
359 UeData ueData;
360
361 for (uint32_t b = 0; b < m_nDedicatedBearers; ++b)
362 {
363 ++dlPort;
364 ++ulPort;
365
368 BearerData bearerData = BearerData();
369
370 // always true: if (epcDl)
371 {
372 UdpClientHelper dlClientHelper(ueIpIfaces.GetAddress(u), dlPort);
373 clientApps.Add(dlClientHelper.Install(remoteHost));
374 PacketSinkHelper dlPacketSinkHelper(
375 "ns3::UdpSocketFactory",
376 InetSocketAddress(Ipv4Address::GetAny(), dlPort));
377 ApplicationContainer sinkContainer = dlPacketSinkHelper.Install(ue);
378 bearerData.dlSink = sinkContainer.Get(0)->GetObject<PacketSink>();
379 serverApps.Add(sinkContainer);
380 }
381 // always true: if (epcUl)
382 {
383 UdpClientHelper ulClientHelper(remoteHostAddr, ulPort);
384 clientApps.Add(ulClientHelper.Install(ue));
385 PacketSinkHelper ulPacketSinkHelper(
386 "ns3::UdpSocketFactory",
387 InetSocketAddress(Ipv4Address::GetAny(), ulPort));
388 ApplicationContainer sinkContainer = ulPacketSinkHelper.Install(remoteHost);
389 bearerData.ulSink = sinkContainer.Get(0)->GetObject<PacketSink>();
390 serverApps.Add(sinkContainer);
391 }
392
393 Ptr<EpcTft> tft = Create<EpcTft>();
394 // always true: if (epcDl)
395 {
397 dlpf.localPortStart = dlPort;
398 dlpf.localPortEnd = dlPort;
399 tft->Add(dlpf);
400 }
401 // always true: if (epcUl)
402 {
404 ulpf.remotePortStart = ulPort;
405 ulpf.remotePortEnd = ulPort;
406 tft->Add(ulpf);
407 }
408
409 // always true: if (epcDl || epcUl)
410 {
411 EpsBearer bearer(EpsBearer::NGBR_VIDEO_TCP_DEFAULT);
412 m_lteHelper->ActivateDedicatedEpsBearer(ueDevices.Get(u), bearer, tft);
413 }
414 double d = startTimeSeconds->GetValue();
415 Time startTime = Seconds(d);
416 serverApps.Start(startTime);
417 clientApps.Start(startTime);
418
419 ueData.bearerDataList.push_back(bearerData);
420
421 } // end for b
422
423 m_ueDataVector.push_back(ueData);
424 }
425 }
426 else // (epc == false)
427 {
428 // for radio bearer activation purposes, consider together home UEs and macro UEs
429 for (uint32_t u = 0; u < ueDevices.GetN(); ++u)
430 {
431 Ptr<NetDevice> ueDev = ueDevices.Get(u);
432 for (uint32_t b = 0; b < m_nDedicatedBearers; ++b)
433 {
434 enum EpsBearer::Qci q = EpsBearer::NGBR_VIDEO_TCP_DEFAULT;
435 EpsBearer bearer(q);
436 m_lteHelper->ActivateDataRadioBearer(ueDev, bearer);
437 }
438 }
439 }
440
441 m_lteHelper->AddX2Interface(enbNodes);
442
443 // check initial RRC connection
444 const Time maxRrcConnectionEstablishmentDuration = Seconds(0.080);
445 for (NetDeviceContainer::Iterator it = ueDevices.Begin(); it != ueDevices.End(); ++it)
446 {
447 Simulator::Schedule(maxRrcConnectionEstablishmentDuration,
449 this,
450 *it,
451 enbDevices.Get(0));
452 }
453
454 // schedule handover events and corresponding checks
455
456 Time stopTime = Seconds(0);
457 for (std::list<HandoverEvent>::iterator hoEventIt = m_handoverEventList.begin();
458 hoEventIt != m_handoverEventList.end();
459 ++hoEventIt)
460 {
461 // Teleport the UE between both eNBs just before the handover starts
462 Simulator::Schedule(hoEventIt->startTime - MilliSeconds(10),
464 this,
465 ueNodes.Get(hoEventIt->ueDeviceIndex));
466
467 Simulator::Schedule(hoEventIt->startTime,
469 this,
470 ueDevices.Get(hoEventIt->ueDeviceIndex),
471 enbDevices.Get(hoEventIt->sourceEnbDeviceIndex));
472
473 m_lteHelper->HandoverRequest(hoEventIt->startTime,
474 ueDevices.Get(hoEventIt->ueDeviceIndex),
475 enbDevices.Get(hoEventIt->sourceEnbDeviceIndex),
476 enbDevices.Get(hoEventIt->targetEnbDeviceIndex));
477
478 // Once the handover is finished, teleport the UE near the target eNB
479 Simulator::Schedule(hoEventIt->startTime + MilliSeconds(40),
481 this,
482 ueNodes.Get(hoEventIt->ueDeviceIndex),
483 enbNodes.Get(m_admitHo ? hoEventIt->targetEnbDeviceIndex
484 : hoEventIt->sourceEnbDeviceIndex));
485
486 Time hoEndTime = hoEventIt->startTime + m_maxHoDuration;
487 Simulator::Schedule(hoEndTime,
489 this,
490 ueDevices.Get(hoEventIt->ueDeviceIndex),
491 enbDevices.Get(m_admitHo ? hoEventIt->targetEnbDeviceIndex
492 : hoEventIt->sourceEnbDeviceIndex));
493 Simulator::Schedule(hoEndTime,
495 this,
496 hoEventIt->ueDeviceIndex);
497
498 Time checkStatsAfterHoTime = hoEndTime + m_statsDuration;
499 Simulator::Schedule(checkStatsAfterHoTime,
501 this,
502 hoEventIt->ueDeviceIndex);
503 if (stopTime <= checkStatsAfterHoTime)
504 {
505 stopTime = checkStatsAfterHoTime + MilliSeconds(1);
506 }
507 }
508
509 // m_lteHelper->EnableRlcTraces ();
510 // m_lteHelper->EnablePdcpTraces();
511
512 Simulator::Stop(stopTime);
513
514 Simulator::Run();
515
516 Simulator::Destroy();
517
518 // Undo changes to default settings
520 // Restore the previous settings of RngSeed and RngRun
521 RngSeedManager::SetSeed(previousSeed);
522 RngSeedManager::SetRun(previousRun);
523}
524
525void
527{
528 Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice>();
529 Ptr<LteUeRrc> ueRrc = ueLteDevice->GetRrc();
530 NS_TEST_ASSERT_MSG_EQ(ueRrc->GetState(), LteUeRrc::CONNECTED_NORMALLY, "Wrong LteUeRrc state!");
531
532 Ptr<LteEnbNetDevice> enbLteDevice = enbDevice->GetObject<LteEnbNetDevice>();
533 Ptr<LteEnbRrc> enbRrc = enbLteDevice->GetRrc();
534 uint16_t rnti = ueRrc->GetRnti();
535 Ptr<UeManager> ueManager = enbRrc->GetUeManager(rnti);
536 NS_TEST_ASSERT_MSG_NE(ueManager, nullptr, "RNTI " << rnti << " not found in eNB");
537
538 UeManager::State ueManagerState = ueManager->GetState();
539 NS_TEST_ASSERT_MSG_EQ(ueManagerState, UeManager::CONNECTED_NORMALLY, "Wrong UeManager state!");
540 NS_ASSERT_MSG(ueManagerState == UeManager::CONNECTED_NORMALLY, "Wrong UeManager state!");
541
542 uint16_t ueCellId = ueRrc->GetCellId();
543 uint16_t enbCellId = enbLteDevice->GetCellId();
544 uint8_t ueDlBandwidth = ueRrc->GetDlBandwidth();
545 uint8_t enbDlBandwidth = enbLteDevice->GetDlBandwidth();
546 uint8_t ueUlBandwidth = ueRrc->GetUlBandwidth();
547 uint8_t enbUlBandwidth = enbLteDevice->GetUlBandwidth();
548 uint8_t ueDlEarfcn = ueRrc->GetDlEarfcn();
549 uint8_t enbDlEarfcn = enbLteDevice->GetDlEarfcn();
550 uint8_t ueUlEarfcn = ueRrc->GetUlEarfcn();
551 uint8_t enbUlEarfcn = enbLteDevice->GetUlEarfcn();
552 uint64_t ueImsi = ueLteDevice->GetImsi();
553 uint64_t enbImsi = ueManager->GetImsi();
554
555 NS_TEST_ASSERT_MSG_EQ(ueImsi, enbImsi, "inconsistent IMSI");
556 NS_TEST_ASSERT_MSG_EQ(ueCellId, enbCellId, "inconsistent CellId");
557 NS_TEST_ASSERT_MSG_EQ(ueDlBandwidth, enbDlBandwidth, "inconsistent DlBandwidth");
558 NS_TEST_ASSERT_MSG_EQ(ueUlBandwidth, enbUlBandwidth, "inconsistent UlBandwidth");
559 NS_TEST_ASSERT_MSG_EQ(ueDlEarfcn, enbDlEarfcn, "inconsistent DlEarfcn");
560 NS_TEST_ASSERT_MSG_EQ(ueUlEarfcn, enbUlEarfcn, "inconsistent UlEarfcn");
561
562 ObjectMapValue enbDataRadioBearerMapValue;
563 ueManager->GetAttribute("DataRadioBearerMap", enbDataRadioBearerMapValue);
564 NS_TEST_ASSERT_MSG_EQ(enbDataRadioBearerMapValue.GetN(),
566 "wrong num bearers at eNB");
567
568 ObjectMapValue ueDataRadioBearerMapValue;
569 ueRrc->GetAttribute("DataRadioBearerMap", ueDataRadioBearerMapValue);
570 NS_TEST_ASSERT_MSG_EQ(ueDataRadioBearerMapValue.GetN(),
572 "wrong num bearers at UE");
573
574 ObjectMapValue::Iterator enbBearerIt = enbDataRadioBearerMapValue.Begin();
575 ObjectMapValue::Iterator ueBearerIt = ueDataRadioBearerMapValue.Begin();
576 while (enbBearerIt != enbDataRadioBearerMapValue.End() &&
577 ueBearerIt != ueDataRadioBearerMapValue.End())
578 {
579 Ptr<LteDataRadioBearerInfo> enbDrbInfo =
580 enbBearerIt->second->GetObject<LteDataRadioBearerInfo>();
582 ueBearerIt->second->GetObject<LteDataRadioBearerInfo>();
583 // NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_epsBearer, ueDrbInfo->m_epsBearer, "epsBearer
584 // differs");
585 NS_TEST_ASSERT_MSG_EQ((uint32_t)enbDrbInfo->m_epsBearerIdentity,
586 (uint32_t)ueDrbInfo->m_epsBearerIdentity,
587 "epsBearerIdentity differs");
588 NS_TEST_ASSERT_MSG_EQ((uint32_t)enbDrbInfo->m_drbIdentity,
589 (uint32_t)ueDrbInfo->m_drbIdentity,
590 "drbIdentity differs");
591 // NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_rlcConfig, ueDrbInfo->m_rlcConfig, "rlcConfig
592 // differs");
593 NS_TEST_ASSERT_MSG_EQ((uint32_t)enbDrbInfo->m_logicalChannelIdentity,
594 (uint32_t)ueDrbInfo->m_logicalChannelIdentity,
595 "logicalChannelIdentity differs");
596 // NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_logicalChannelConfig,
597 // ueDrbInfo->m_logicalChannelConfig, "logicalChannelConfig differs");
598
599 ++enbBearerIt;
600 ++ueBearerIt;
601 }
602 NS_ASSERT_MSG(enbBearerIt == enbDataRadioBearerMapValue.End(), "too many bearers at eNB");
603 NS_ASSERT_MSG(ueBearerIt == ueDataRadioBearerMapValue.End(), "too many bearers at UE");
604}
605
606void
608{
609 Ptr<MobilityModel> ueMobility = ueNode->GetObject<MobilityModel>();
610 ueMobility->SetPosition(Vector(0.0, 0.0, 0.0));
611}
612
613void
615{
616 Ptr<MobilityModel> enbMobility = enbNode->GetObject<MobilityModel>();
617 Vector pos = enbMobility->GetPosition();
618
619 Ptr<MobilityModel> ueMobility = ueNode->GetObject<MobilityModel>();
620 ueMobility->SetPosition(pos + Vector(0.0, 100.0, 0.0));
621}
622
623void
625{
626 for (std::list<BearerData>::iterator it = m_ueDataVector.at(ueIndex).bearerDataList.begin();
627 it != m_ueDataVector.at(ueIndex).bearerDataList.end();
628 ++it)
629 {
630 it->dlOldTotalRx = it->dlSink->GetTotalRx();
631 it->ulOldTotalRx = it->ulSink->GetTotalRx();
632 }
633}
634
635void
637{
638 uint32_t b = 1;
639 for (std::list<BearerData>::iterator it = m_ueDataVector.at(ueIndex).bearerDataList.begin();
640 it != m_ueDataVector.at(ueIndex).bearerDataList.end();
641 ++it)
642 {
643 uint32_t dlRx = it->dlSink->GetTotalRx() - it->dlOldTotalRx;
644 uint32_t ulRx = it->ulSink->GetTotalRx() - it->ulOldTotalRx;
645 uint32_t expectedBytes =
647
649 expectedBytes,
650 "too few RX bytes in DL, ue=" << ueIndex << ", b=" << b);
652 expectedBytes,
653 "too few RX bytes in UL, ue=" << ueIndex << ", b=" << b);
654 ++b;
655 }
656}
657
674{
675 public:
677};
678
680 : TestSuite("lte-x2-handover", SYSTEM)
681{
682 // in the following:
683 // fwd means handover from enb 0 to enb 1
684 // bwd means handover from enb 1 to enb 0
685
686 HandoverEvent ue1fwd;
687 ue1fwd.startTime = MilliSeconds(100);
688 ue1fwd.ueDeviceIndex = 0;
689 ue1fwd.sourceEnbDeviceIndex = 0;
690 ue1fwd.targetEnbDeviceIndex = 1;
691
692 HandoverEvent ue1bwd;
693 ue1bwd.startTime = MilliSeconds(400);
694 ue1bwd.ueDeviceIndex = 0;
695 ue1bwd.sourceEnbDeviceIndex = 1;
696 ue1bwd.targetEnbDeviceIndex = 0;
697
698 HandoverEvent ue1fwdagain;
699 ue1fwdagain.startTime = MilliSeconds(700);
700 ue1fwdagain.ueDeviceIndex = 0;
701 ue1fwdagain.sourceEnbDeviceIndex = 0;
702 ue1fwdagain.targetEnbDeviceIndex = 1;
703
704 HandoverEvent ue2fwd;
705 ue2fwd.startTime = MilliSeconds(110);
706 ue2fwd.ueDeviceIndex = 1;
707 ue2fwd.sourceEnbDeviceIndex = 0;
708 ue2fwd.targetEnbDeviceIndex = 1;
709
710 HandoverEvent ue2bwd;
711 ue2bwd.startTime = MilliSeconds(350);
712 ue2bwd.ueDeviceIndex = 1;
713 ue2bwd.sourceEnbDeviceIndex = 1;
714 ue2bwd.targetEnbDeviceIndex = 0;
715
716 std::string hel0name("none");
717 std::list<HandoverEvent> hel0;
718
719 std::string hel1name("1 fwd");
720 const std::list<HandoverEvent> hel1{
721 ue1fwd,
722 };
723
724 std::string hel2name("1 fwd & bwd");
725 const std::list<HandoverEvent> hel2{
726 ue1fwd,
727 ue1bwd,
728 };
729
730 std::string hel3name("1 fwd & bwd & fwd");
731 const std::list<HandoverEvent> hel3{
732 ue1fwd,
733 ue1bwd,
734 ue1fwdagain,
735 };
736
737 std::string hel4name("1+2 fwd");
738 const std::list<HandoverEvent> hel4{
739 ue1fwd,
740 ue2fwd,
741 };
742
743 std::string hel5name("1+2 fwd & bwd");
744 const std::list<HandoverEvent> hel5{
745 ue1fwd,
746 ue1bwd,
747 ue2fwd,
748 ue2bwd,
749 };
750
751 // std::string hel6name("2 fwd");
752 // const std::list<HandoverEvent> hel6{
753 // ue2fwd,
754 // };
755
756 // std::string hel7name("2 fwd & bwd");
757 // const std::list<HandoverEvent> hel7{
758 // ue2fwd,
759 // ue2bwd,
760 // };
761
762 std::vector<std::string> schedulers{
763 "ns3::RrFfMacScheduler",
764 "ns3::PfFfMacScheduler",
765 };
766
767 for (std::vector<std::string>::iterator schedIt = schedulers.begin();
768 schedIt != schedulers.end();
769 ++schedIt)
770 {
771 for (int32_t useIdealRrc = 1; useIdealRrc >= 0; --useIdealRrc)
772 {
773 // nUes, nDBearers, helist, name, sched, admitHo,
774 // idealRrc
776 new LteX2HandoverTestCase(1, 0, hel0, hel0name, *schedIt, true, useIdealRrc),
777 TestCase::EXTENSIVE);
779 new LteX2HandoverTestCase(2, 0, hel0, hel0name, *schedIt, true, useIdealRrc),
780 TestCase::EXTENSIVE);
782 new LteX2HandoverTestCase(1, 5, hel0, hel0name, *schedIt, true, useIdealRrc),
783 TestCase::EXTENSIVE);
785 new LteX2HandoverTestCase(2, 5, hel0, hel0name, *schedIt, true, useIdealRrc),
786 TestCase::EXTENSIVE);
788 new LteX2HandoverTestCase(1, 0, hel1, hel1name, *schedIt, true, useIdealRrc),
789 TestCase::EXTENSIVE);
791 new LteX2HandoverTestCase(1, 1, hel1, hel1name, *schedIt, true, useIdealRrc),
792 TestCase::EXTENSIVE);
794 new LteX2HandoverTestCase(1, 2, hel1, hel1name, *schedIt, true, useIdealRrc),
795 TestCase::EXTENSIVE);
797 new LteX2HandoverTestCase(1, 0, hel1, hel1name, *schedIt, false, useIdealRrc),
798 TestCase::EXTENSIVE);
800 new LteX2HandoverTestCase(1, 1, hel1, hel1name, *schedIt, false, useIdealRrc),
801 TestCase::EXTENSIVE);
803 new LteX2HandoverTestCase(1, 2, hel1, hel1name, *schedIt, false, useIdealRrc),
804 TestCase::EXTENSIVE);
806 new LteX2HandoverTestCase(2, 0, hel1, hel1name, *schedIt, true, useIdealRrc),
807 TestCase::EXTENSIVE);
809 new LteX2HandoverTestCase(2, 1, hel1, hel1name, *schedIt, true, useIdealRrc),
810 TestCase::EXTENSIVE);
812 new LteX2HandoverTestCase(2, 2, hel1, hel1name, *schedIt, true, useIdealRrc),
813 TestCase::EXTENSIVE);
815 new LteX2HandoverTestCase(2, 0, hel1, hel1name, *schedIt, false, useIdealRrc),
816 TestCase::EXTENSIVE);
818 new LteX2HandoverTestCase(2, 1, hel1, hel1name, *schedIt, false, useIdealRrc),
819 TestCase::EXTENSIVE);
821 new LteX2HandoverTestCase(2, 2, hel1, hel1name, *schedIt, false, useIdealRrc),
822 TestCase::EXTENSIVE);
824 new LteX2HandoverTestCase(1, 0, hel2, hel2name, *schedIt, true, useIdealRrc),
825 TestCase::EXTENSIVE);
827 new LteX2HandoverTestCase(1, 1, hel2, hel2name, *schedIt, true, useIdealRrc),
828 TestCase::EXTENSIVE);
830 new LteX2HandoverTestCase(1, 2, hel2, hel2name, *schedIt, true, useIdealRrc),
831 TestCase::EXTENSIVE);
833 new LteX2HandoverTestCase(1, 0, hel3, hel3name, *schedIt, true, useIdealRrc),
834 TestCase::EXTENSIVE);
836 new LteX2HandoverTestCase(1, 1, hel3, hel3name, *schedIt, true, useIdealRrc),
837 TestCase::EXTENSIVE);
839 new LteX2HandoverTestCase(1, 2, hel3, hel3name, *schedIt, true, useIdealRrc),
840 TestCase::EXTENSIVE);
842 new LteX2HandoverTestCase(2, 0, hel3, hel3name, *schedIt, true, useIdealRrc),
843 TestCase::EXTENSIVE);
845 new LteX2HandoverTestCase(2, 1, hel3, hel3name, *schedIt, true, useIdealRrc),
846 TestCase::EXTENSIVE);
848 new LteX2HandoverTestCase(2, 2, hel3, hel3name, *schedIt, true, useIdealRrc),
849 TestCase::QUICK);
851 new LteX2HandoverTestCase(2, 0, hel4, hel4name, *schedIt, true, useIdealRrc),
852 TestCase::EXTENSIVE);
854 new LteX2HandoverTestCase(2, 1, hel4, hel4name, *schedIt, true, useIdealRrc),
855 TestCase::EXTENSIVE);
857 new LteX2HandoverTestCase(2, 2, hel4, hel4name, *schedIt, true, useIdealRrc),
858 TestCase::EXTENSIVE);
860 new LteX2HandoverTestCase(2, 0, hel5, hel5name, *schedIt, true, useIdealRrc),
861 TestCase::EXTENSIVE);
863 new LteX2HandoverTestCase(2, 1, hel5, hel5name, *schedIt, true, useIdealRrc),
864 TestCase::EXTENSIVE);
866 new LteX2HandoverTestCase(2, 2, hel5, hel5name, *schedIt, true, useIdealRrc),
867 TestCase::EXTENSIVE);
869 new LteX2HandoverTestCase(3, 0, hel3, hel3name, *schedIt, true, useIdealRrc),
870 TestCase::EXTENSIVE);
872 new LteX2HandoverTestCase(3, 1, hel3, hel3name, *schedIt, true, useIdealRrc),
873 TestCase::EXTENSIVE);
875 new LteX2HandoverTestCase(3, 2, hel3, hel3name, *schedIt, true, useIdealRrc),
876 TestCase::EXTENSIVE);
878 new LteX2HandoverTestCase(3, 0, hel4, hel4name, *schedIt, true, useIdealRrc),
879 TestCase::EXTENSIVE);
881 new LteX2HandoverTestCase(3, 1, hel4, hel4name, *schedIt, true, useIdealRrc),
882 TestCase::EXTENSIVE);
884 new LteX2HandoverTestCase(3, 2, hel4, hel4name, *schedIt, true, useIdealRrc),
885 TestCase::EXTENSIVE);
887 new LteX2HandoverTestCase(3, 0, hel5, hel5name, *schedIt, true, useIdealRrc),
888 TestCase::EXTENSIVE);
890 new LteX2HandoverTestCase(3, 1, hel5, hel5name, *schedIt, true, useIdealRrc),
891 TestCase::EXTENSIVE);
893 new LteX2HandoverTestCase(3, 2, hel5, hel5name, *schedIt, true, useIdealRrc),
894 TestCase::QUICK);
895 }
896 }
897}
898
static std::string BuildNameString(uint32_t nUes, uint32_t nDedicatedBearers, std::string handoverEventListName, std::string schedulerType, bool admitHo, bool useIdealRrc)
Build name string.
void DoRun() override
Implementation to actually run this TestCase.
Ptr< PointToPointEpcHelper > m_epcHelper
EPC helper.
uint32_t m_nUes
number of UEs in the test
std::string m_handoverEventListName
handover event list name
std::string m_schedulerType
scheduler type
const uint32_t m_udpClientPktSize
UDP client packet size.
bool m_useIdealRrc
whether to use the ideal RRC
const Time m_statsDuration
stats duration
std::vector< UeData > m_ueDataVector
UE data vector.
void CheckConnected(Ptr< NetDevice > ueDevice, Ptr< NetDevice > enbDevice)
Check connected function.
LteX2HandoverTestCase(uint32_t nUes, uint32_t nDedicatedBearers, std::list< HandoverEvent > handoverEventList, std::string handoverEventListName, std::string schedulerType, bool admitHo, bool useIdealRrc)
void TeleportUeNearTargetEnb(Ptr< Node > ueNode, Ptr< Node > enbNode)
Teleport UE near the target eNB of the handover.
bool m_admitHo
whether to admit the handover request
bool m_epc
whether to use EPC
void SaveStatsAfterHandover(uint32_t ueIndex)
Save stats after handover function.
const Time m_maxHoDuration
maximum HO duration
std::list< HandoverEvent > m_handoverEventList
handover event list
void CheckStatsAWhileAfterHandover(uint32_t ueIndex)
Check stats a while after handover function.
uint32_t m_nDedicatedBearers
number of UEs in the test
const Time m_udpClientInterval
UDP client interval.
void TeleportUeToMiddle(Ptr< Node > ueNode)
Teleport UE between both eNBs of the test.
Ptr< LteHelper > m_lteHelper
LTE helper.
LTE X2 Handover 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.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
AttributeValue implementation for DataRate.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
This class contains the specification of EPS Bearers.
Definition: eps-bearer.h:91
Qci
QoS Class Indicator.
Definition: eps-bearer.h:106
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:43
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:79
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:258
Helper class that adds ns3::Ipv4StaticRouting objects.
Ptr< Ipv4StaticRouting > GetStaticRouting(Ptr< Ipv4 > ipv4) const
Try and find the static routing protocol as either the main routing protocol or in the list of routin...
store information on active data radio bearer instance
The eNodeB device implementation.
uint16_t GetDlBandwidth() const
uint32_t GetUlEarfcn() const
uint32_t GetDlEarfcn() const
Ptr< LteEnbRrc > GetRrc() const
uint16_t GetUlBandwidth() const
uint16_t GetCellId() const
void SetEpcHelper(Ptr< EpcHelper > h)
Set the EpcHelper to be used to setup the EPC network in conjunction with the setup of the LTE radio ...
Definition: lte-helper.cc:282
void HandoverRequest(Time hoTime, Ptr< NetDevice > ueDev, Ptr< NetDevice > sourceEnbDev, Ptr< NetDevice > targetEnbDev)
Manually trigger an X2-based handover.
Definition: lte-helper.cc:1343
NetDeviceContainer InstallEnbDevice(NodeContainer c)
Create a set of eNodeB devices.
Definition: lte-helper.cc:482
void SetHandoverAlgorithmType(std::string type)
Set the type of handover algorithm to be used by eNodeB devices.
Definition: lte-helper.cc:337
void SetSchedulerType(std::string type)
Set the type of scheduler to be used by eNodeB devices.
Definition: lte-helper.cc:289
void Attach(NetDeviceContainer ueDevices)
Enables automatic attachment of a set of UE devices to a suitable cell using Idle mode initial cell s...
Definition: lte-helper.cc:1044
void ActivateDataRadioBearer(NetDeviceContainer ueDevices, EpsBearer bearer)
Activate a Data Radio Bearer on a given UE devices (for LTE-only simulation).
Definition: lte-helper.cc:1441
NetDeviceContainer InstallUeDevice(NodeContainer c)
Create a set of UE devices.
Definition: lte-helper.cc:497
void AddX2Interface(NodeContainer enbNodes)
Create an X2 interface between all the eNBs in a given set.
Definition: lte-helper.cc:1318
int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used.
Definition: lte-helper.cc:1572
uint8_t ActivateDedicatedEpsBearer(NetDeviceContainer ueDevices, EpsBearer bearer, Ptr< EpcTft > tft)
Activate a dedicated EPS bearer on a given set of UE devices.
Definition: lte-helper.cc:1159
The LteUeNetDevice class implements the UE net device.
Helper class used to assign positions and mobility models to nodes.
Keep track of the current position and velocity of an object.
Vector GetPosition() const
void SetPosition(const Vector &position)
holds a vector of ns3::NetDevice pointers
uint32_t GetN() const
Get the number of Ptr<NetDevice> stored in this container.
std::vector< Ptr< NetDevice > >::const_iterator Iterator
NetDevice container iterator.
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.
Ptr< Node > GetPgwNode() const override
Get the PGW node.
Ipv4Address GetUeDefaultGatewayAddress() override
Ipv4InterfaceContainer AssignUeIpv4Address(NetDeviceContainer ueDevices) override
Assign IPv4 addresses to UE devices.
keep track of a set of node pointers.
uint32_t GetN() const
Get the number of Ptr<Node> stored in this container.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:258
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
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.
std::map< std::size_t, Ptr< Object > >::const_iterator Iterator
Iterator type for traversing this container.
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
ApplicationContainer Install(NodeContainer c) const
Install an ns3::PacketSinkApplication on each node of the input container configured with all the att...
Receive and consume traffic generated to an IP address and port.
Definition: packet-sink.h:74
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:78
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
Hold variables of type string.
Definition: string.h:42
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:305
A suite of tests to run.
Definition: test.h:1256
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
AttributeValue implementation for Time.
Definition: nstime.h:1425
Create a client application which sends UDP packets carrying a 32bit sequence number and a 64 bit tim...
ApplicationContainer Install(NodeContainer c)
State
The state of the UeManager at the eNB RRC.
Definition: lte-enb-rrc.h:82
Hold an unsigned integer type.
Definition: uinteger.h:45
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
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:86
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:856
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:891
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
void(* DataRate)(DataRate oldValue, DataRate newValue)
TracedValue callback signature for DataRate.
Definition: data-rate.h:328
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:144
#define NS_TEST_ASSERT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report and abort if not.
Definition: test.h:564
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1350
serverApps
Definition: first.py:48
clientApps
Definition: first.py:58
Every class exported by the ns3 library is enclosed in the ns3 namespace.
mobility
Definition: third.py:96
HandoverEvent structure.
uint32_t ueDeviceIndex
UE device index.
Time startTime
start time
uint32_t targetEnbDeviceIndex
target ENB device index
uint32_t sourceEnbDeviceIndex
source ENB device index
uint32_t dlOldTotalRx
DL old total receive.
uint32_t ulOldTotalRx
UL old total receive.
std::list< BearerData > bearerDataList
bearer ID list
Implement the data structure representing a TrafficFlowTemplate Packet Filter.
Definition: epc-tft.h:71
uint16_t localPortEnd
end of the port number range of the UE
Definition: epc-tft.h:132
uint16_t remotePortEnd
end of the port number range of the remote host
Definition: epc-tft.h:130
uint16_t remotePortStart
start of the port number range of the remote host
Definition: epc-tft.h:129
uint16_t localPortStart
start of the port number range of the UE
Definition: epc-tft.h:131
static LteX2HandoverTestSuite g_lteX2HandoverTestSuiteInstance