A Discrete-Event Network Simulator
API
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  * 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  * Authors:
18  * Nicola Baldo <nbaldo@cttc.es>
19  * Manuel Requena <manuel.requena@cttc.es>
20  */
21 
22 #include <ns3/bulk-send-helper.h>
23 #include <ns3/core-module.h>
24 #include <ns3/internet-module.h>
25 #include <ns3/lte-module.h>
26 #include <ns3/mobility-module.h>
27 #include <ns3/network-module.h>
28 #include <ns3/packet-sink-helper.h>
29 #include <ns3/packet-sink.h>
30 #include <ns3/point-to-point-module.h>
31 #include <ns3/udp-client-server-helper.h>
32 
33 using namespace ns3;
34 
35 NS_LOG_COMPONENT_DEFINE("LteX2HandoverMeasuresTest");
36 
43 {
47  uint32_t ueDeviceIndex;
48  uint32_t enbDeviceIndex;
49 
59  CheckPointEvent(Time start, Time stop, Time interval, uint32_t ueIndex, uint32_t enbIndex)
60  : checkStartTime(start),
61  checkStopTime(stop),
62  checkInterval(interval),
63  ueDeviceIndex(ueIndex),
64  enbDeviceIndex(enbIndex)
65  {
66  }
67 };
68 
76 {
77  public:
93  LteX2HandoverMeasuresTestCase(uint32_t nEnbs,
94  uint32_t nUes,
95  uint32_t nDedicatedBearers,
96  std::list<CheckPointEvent> checkPointEventList,
97  std::string checkPointEventListName,
98  bool useUdp,
99  std::string schedulerType,
100  std::string handoverAlgorithmType,
101  bool admitHo,
102  bool useIdealRrc);
103 
104  private:
119  static std::string BuildNameString(uint32_t nEnbs,
120  uint32_t nUes,
121  uint32_t nDedicatedBearers,
122  std::string checkPointEventListName,
123  bool useUdp,
124  std::string schedulerType,
125  std::string handoverAlgorithmType,
126  bool admitHo,
127  bool useIdealRrc);
128  void DoRun() override;
134  void CheckConnected(Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice);
135 
136  uint32_t m_nEnbs;
137  uint32_t m_nUes;
139  std::list<CheckPointEvent> m_checkPointEventList;
141  bool m_epc;
142  bool m_useUdp;
143  std::string m_schedulerType;
145  bool m_admitHo;
149 
155  struct BearerData
156  {
157  uint32_t bid;
160  uint32_t dlOldTotalRx;
161  uint32_t ulOldTotalRx;
162  };
163 
169  struct UeData
170  {
171  uint32_t id;
172  std::list<BearerData> bearerDataList;
173  };
174 
179  void SaveStats(uint32_t ueIndex);
184  void CheckStats(uint32_t ueIndex);
185 
186  std::vector<UeData> m_ueDataVector;
187 
191  const uint32_t m_udpClientPktSize;
192 };
193 
194 std::string
196  uint32_t nUes,
197  uint32_t nDedicatedBearers,
198  std::string checkPointEventListName,
199  bool useUdp,
200  std::string schedulerType,
201  std::string handoverAlgorithmType,
202  bool admitHo,
203  bool useIdealRrc)
204 {
205  std::ostringstream oss;
206  oss << "nEnbs=" << nEnbs << " nUes=" << nUes << " nDedicatedBearers=" << nDedicatedBearers
207  << " udp=" << useUdp << " " << schedulerType << " " << handoverAlgorithmType
208  << " admitHo=" << admitHo << " hoList: " << checkPointEventListName;
209  if (useIdealRrc)
210  {
211  oss << ", ideal RRC";
212  }
213  else
214  {
215  oss << ", real RRC";
216  }
217  return oss.str();
218 }
219 
221  uint32_t nEnbs,
222  uint32_t nUes,
223  uint32_t nDedicatedBearers,
224  std::list<CheckPointEvent> checkPointEventList,
225  std::string checkPointEventListName,
226  bool useUdp,
227  std::string schedulerType,
228  std::string handoverAlgorithmType,
229  bool admitHo,
230  bool useIdealRrc)
231  : TestCase(BuildNameString(nEnbs,
232  nUes,
233  nDedicatedBearers,
234  checkPointEventListName,
235  useUdp,
236  schedulerType,
237  handoverAlgorithmType,
238  admitHo,
239  useIdealRrc)),
240  m_nEnbs(nEnbs),
241  m_nUes(nUes),
242  m_nDedicatedBearers(nDedicatedBearers),
243  m_checkPointEventList(checkPointEventList),
244  m_checkPointEventListName(checkPointEventListName),
245  m_epc(true),
246  m_useUdp(useUdp),
247  m_schedulerType(schedulerType),
248  m_handoverAlgorithmType(handoverAlgorithmType),
249  m_admitHo(admitHo),
250  m_useIdealRrc(useIdealRrc),
251  m_maxHoDuration(Seconds(0.1)),
252  m_statsDuration(Seconds(0.5)),
253  m_udpClientInterval(Seconds(0.01)),
254  m_udpClientPktSize(100)
255 {
256 }
257 
258 void
260 {
262  m_nUes,
265  m_useUdp,
268  m_admitHo,
269  m_useIdealRrc));
270 
271  Config::Reset();
272  Config::SetDefault("ns3::UdpClient::Interval", TimeValue(m_udpClientInterval));
273  Config::SetDefault("ns3::UdpClient::MaxPackets", UintegerValue(1000000));
274  Config::SetDefault("ns3::UdpClient::PacketSize", UintegerValue(m_udpClientPktSize));
275  Config::SetDefault("ns3::LteEnbRrc::HandoverJoiningTimeoutDuration",
276  TimeValue(MilliSeconds(200)));
277  Config::SetDefault("ns3::LteEnbPhy::TxPower", DoubleValue(20));
278 
279  // Disable Uplink Power Control
280  Config::SetDefault("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue(false));
281 
282  int64_t stream = 1;
283 
284  m_lteHelper = CreateObject<LteHelper>();
285  m_lteHelper->SetAttribute("PathlossModel",
286  StringValue("ns3::FriisSpectrumPropagationLossModel"));
289 
290  if (m_handoverAlgorithmType == "ns3::A2A4RsrqHandoverAlgorithm")
291  {
292  m_lteHelper->SetHandoverAlgorithmType("ns3::A2A4RsrqHandoverAlgorithm");
293  m_lteHelper->SetHandoverAlgorithmAttribute("ServingCellThreshold", UintegerValue(30));
294  m_lteHelper->SetHandoverAlgorithmAttribute("NeighbourCellOffset", UintegerValue(1));
295  }
296  else if (m_handoverAlgorithmType == "ns3::A3RsrpHandoverAlgorithm")
297  {
298  m_lteHelper->SetHandoverAlgorithmType("ns3::A3RsrpHandoverAlgorithm");
301  }
302  else
303  {
304  NS_FATAL_ERROR("Unknown handover algorithm " << m_handoverAlgorithmType);
305  }
306 
307  double distance = 1000.0; // m
308  double speed = 150; // m/s
309 
310  NodeContainer enbNodes;
311  enbNodes.Create(m_nEnbs);
312  NodeContainer ueNodes;
313  ueNodes.Create(m_nUes);
314 
315  if (m_epc)
316  {
317  m_epcHelper = CreateObject<PointToPointEpcHelper>();
319  }
320 
321  // Install Mobility Model in eNBs
322  // eNBs are located along a line in the X axis
323  Ptr<ListPositionAllocator> enbPositionAlloc = CreateObject<ListPositionAllocator>();
324  for (uint32_t i = 0; i < m_nEnbs; i++)
325  {
326  Vector enbPosition(distance * (i + 1), 0, 0);
327  enbPositionAlloc->Add(enbPosition);
328  }
329  MobilityHelper enbMobility;
330  enbMobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
331  enbMobility.SetPositionAllocator(enbPositionAlloc);
332  enbMobility.Install(enbNodes);
333 
334  // Install Mobility Model in UE
335  // UE moves with a constant speed along the X axis
336  MobilityHelper ueMobility;
337  ueMobility.SetMobilityModel("ns3::ConstantVelocityMobilityModel");
338  ueMobility.Install(ueNodes);
339  for (uint32_t i = 0; i < m_nUes; i++)
340  {
341  ueNodes.Get(i)->GetObject<MobilityModel>()->SetPosition(Vector(0, 0, 0));
342  ueNodes.Get(i)->GetObject<ConstantVelocityMobilityModel>()->SetVelocity(
343  Vector(speed, 0, 0));
344  }
345 
346  NetDeviceContainer enbDevices;
347  enbDevices = m_lteHelper->InstallEnbDevice(enbNodes);
348  stream += m_lteHelper->AssignStreams(enbDevices, stream);
349  for (auto it = enbDevices.Begin(); it != enbDevices.End(); ++it)
350  {
351  Ptr<LteEnbRrc> enbRrc = (*it)->GetObject<LteEnbNetDevice>()->GetRrc();
352  enbRrc->SetAttribute("AdmitHandoverRequest", BooleanValue(m_admitHo));
353  }
354 
355  NetDeviceContainer ueDevices;
356  ueDevices = m_lteHelper->InstallUeDevice(ueNodes);
357  stream += m_lteHelper->AssignStreams(ueDevices, stream);
358 
359  Ipv4Address remoteHostAddr;
360  Ipv4StaticRoutingHelper ipv4RoutingHelper;
361  Ipv4InterfaceContainer ueIpIfaces;
362  Ptr<Node> remoteHost;
363  if (m_epc)
364  {
365  // Create a single RemoteHost
366  NodeContainer remoteHostContainer;
367  remoteHostContainer.Create(1);
368  remoteHost = remoteHostContainer.Get(0);
370  internet.Install(remoteHostContainer);
371 
372  // Create the Internet
373  PointToPointHelper p2ph;
374  p2ph.SetDeviceAttribute("DataRate", DataRateValue(DataRate("100Gb/s")));
375  p2ph.SetDeviceAttribute("Mtu", UintegerValue(1500));
376  p2ph.SetChannelAttribute("Delay", TimeValue(Seconds(0.010)));
378  NetDeviceContainer internetDevices = p2ph.Install(pgw, remoteHost);
379  Ipv4AddressHelper ipv4h;
380  ipv4h.SetBase("1.0.0.0", "255.0.0.0");
381  Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign(internetDevices);
382  // in this container, interface 0 is the pgw, 1 is the remoteHost
383  remoteHostAddr = internetIpIfaces.GetAddress(1);
384 
385  Ipv4StaticRoutingHelper ipv4RoutingHelper;
386  Ptr<Ipv4StaticRouting> remoteHostStaticRouting =
387  ipv4RoutingHelper.GetStaticRouting(remoteHost->GetObject<Ipv4>());
388  remoteHostStaticRouting->AddNetworkRouteTo(Ipv4Address("7.0.0.0"),
389  Ipv4Mask("255.0.0.0"),
390  1);
391 
392  // Install the IP stack on the UEs
393  internet.Install(ueNodes);
394  ueIpIfaces = m_epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueDevices));
395  }
396 
397  // attachment (needs to be done after IP stack configuration)
398  // all UEs attached to eNB 0 at the beginning
399  m_lteHelper->Attach(ueDevices, enbDevices.Get(0));
400 
401  if (m_epc)
402  {
403  bool epcDl = true;
404  bool epcUl = false;
405  // the rest of this block is copied from lena-dual-stripe
406 
407  // Install and start applications on UEs and remote host
408  uint16_t dlPort = 10000;
409  uint16_t ulPort = 20000;
410 
411  // randomize a bit start times to avoid simulation artifacts
412  // (e.g., buffer overflows due to packet transmissions happening
413  // exactly at the same time)
414  Ptr<UniformRandomVariable> startTimeSeconds = CreateObject<UniformRandomVariable>();
415  startTimeSeconds->SetAttribute("Min", DoubleValue(0));
416  startTimeSeconds->SetAttribute("Max", DoubleValue(0.010));
417  startTimeSeconds->SetStream(stream++);
418 
419  for (uint32_t u = 0; u < ueNodes.GetN(); ++u)
420  {
421  Ptr<Node> ue = ueNodes.Get(u);
422  // Set the default gateway for the UE
423  Ptr<Ipv4StaticRouting> ueStaticRouting =
424  ipv4RoutingHelper.GetStaticRouting(ue->GetObject<Ipv4>());
425  ueStaticRouting->SetDefaultRoute(m_epcHelper->GetUeDefaultGatewayAddress(), 1);
426 
427  UeData ueData;
428 
429  for (uint32_t b = 0; b < m_nDedicatedBearers; ++b)
430  {
431  ++dlPort;
432  ++ulPort;
433 
436  BearerData bearerData = BearerData();
437 
438  if (m_useUdp)
439  {
440  if (epcDl)
441  {
442  UdpClientHelper dlClientHelper(ueIpIfaces.GetAddress(u), dlPort);
443  clientApps.Add(dlClientHelper.Install(remoteHost));
444  PacketSinkHelper dlPacketSinkHelper(
445  "ns3::UdpSocketFactory",
446  InetSocketAddress(Ipv4Address::GetAny(), dlPort));
447  ApplicationContainer sinkContainer = dlPacketSinkHelper.Install(ue);
448  bearerData.dlSink = sinkContainer.Get(0)->GetObject<PacketSink>();
449  serverApps.Add(sinkContainer);
450  }
451  if (epcUl)
452  {
453  UdpClientHelper ulClientHelper(remoteHostAddr, ulPort);
454  clientApps.Add(ulClientHelper.Install(ue));
455  PacketSinkHelper ulPacketSinkHelper(
456  "ns3::UdpSocketFactory",
457  InetSocketAddress(Ipv4Address::GetAny(), ulPort));
458  ApplicationContainer sinkContainer = ulPacketSinkHelper.Install(remoteHost);
459  bearerData.ulSink = sinkContainer.Get(0)->GetObject<PacketSink>();
460  serverApps.Add(sinkContainer);
461  }
462  }
463  else // use TCP
464  {
465  if (epcDl)
466  {
467  BulkSendHelper dlClientHelper(
468  "ns3::TcpSocketFactory",
469  InetSocketAddress(ueIpIfaces.GetAddress(u), dlPort));
470  dlClientHelper.SetAttribute("MaxBytes", UintegerValue(0));
471  clientApps.Add(dlClientHelper.Install(remoteHost));
472  PacketSinkHelper dlPacketSinkHelper(
473  "ns3::TcpSocketFactory",
474  InetSocketAddress(Ipv4Address::GetAny(), dlPort));
475  ApplicationContainer sinkContainer = dlPacketSinkHelper.Install(ue);
476  bearerData.dlSink = sinkContainer.Get(0)->GetObject<PacketSink>();
477  serverApps.Add(sinkContainer);
478  }
479  if (epcUl)
480  {
481  BulkSendHelper ulClientHelper("ns3::TcpSocketFactory",
482  InetSocketAddress(remoteHostAddr, ulPort));
483  ulClientHelper.SetAttribute("MaxBytes", UintegerValue(0));
484  clientApps.Add(ulClientHelper.Install(ue));
485  PacketSinkHelper ulPacketSinkHelper(
486  "ns3::TcpSocketFactory",
487  InetSocketAddress(Ipv4Address::GetAny(), ulPort));
488  ApplicationContainer sinkContainer = ulPacketSinkHelper.Install(remoteHost);
489  bearerData.ulSink = sinkContainer.Get(0)->GetObject<PacketSink>();
490  serverApps.Add(sinkContainer);
491  }
492  } // end if (useUdp)
493 
494  Ptr<EpcTft> tft = Create<EpcTft>();
495  if (epcDl)
496  {
498  dlpf.localPortStart = dlPort;
499  dlpf.localPortEnd = dlPort;
500  tft->Add(dlpf);
501  }
502  if (epcUl)
503  {
505  ulpf.remotePortStart = ulPort;
506  ulpf.remotePortEnd = ulPort;
507  tft->Add(ulpf);
508  }
509 
510  if (epcDl || epcUl)
511  {
512  EpsBearer bearer(EpsBearer::NGBR_VIDEO_TCP_DEFAULT);
513  m_lteHelper->ActivateDedicatedEpsBearer(ueDevices.Get(u), bearer, tft);
514  }
515  Time startTime = Seconds(startTimeSeconds->GetValue());
516  serverApps.Start(startTime);
517  clientApps.Start(startTime);
518 
519  ueData.bearerDataList.push_back(bearerData);
520 
521  } // end for b
522 
523  m_ueDataVector.push_back(ueData);
524  }
525  }
526  else // (epc == false)
527  {
528  // for radio bearer activation purposes, consider together home UEs and macro UEs
529  for (uint32_t u = 0; u < ueDevices.GetN(); ++u)
530  {
531  Ptr<NetDevice> ueDev = ueDevices.Get(u);
532  for (uint32_t b = 0; b < m_nDedicatedBearers; ++b)
533  {
534  EpsBearer::Qci q = EpsBearer::NGBR_VIDEO_TCP_DEFAULT;
535  EpsBearer bearer(q);
536  m_lteHelper->ActivateDataRadioBearer(ueDev, bearer);
537  }
538  }
539  }
540 
541  m_lteHelper->AddX2Interface(enbNodes);
542 
543  // check initial RRC connection
544  const Time maxRrcConnectionEstablishmentDuration = Seconds(0.080);
545  for (auto it = ueDevices.Begin(); it != ueDevices.End(); ++it)
546  {
547  NS_LOG_FUNCTION(maxRrcConnectionEstablishmentDuration);
548  Simulator::Schedule(maxRrcConnectionEstablishmentDuration,
550  this,
551  *it,
552  enbDevices.Get(0));
553  }
554 
555  // schedule the checkpoint events
556 
557  Time stopTime = Seconds(0);
558  for (auto checkPointEventIt = m_checkPointEventList.begin();
559  checkPointEventIt != m_checkPointEventList.end();
560  ++checkPointEventIt)
561  {
562  for (Time checkPointTime = checkPointEventIt->checkStartTime;
563  checkPointTime < checkPointEventIt->checkStopTime;
564  checkPointTime += checkPointEventIt->checkInterval)
565  {
566  Simulator::Schedule(checkPointTime,
568  this,
569  ueDevices.Get(checkPointEventIt->ueDeviceIndex),
570  enbDevices.Get(checkPointEventIt->enbDeviceIndex));
571 
572  Simulator::Schedule(checkPointTime,
574  this,
575  checkPointEventIt->ueDeviceIndex);
576 
577  Time checkStats = checkPointTime + m_statsDuration;
578  Simulator::Schedule(checkStats,
580  this,
581  checkPointEventIt->ueDeviceIndex);
582 
583  if (stopTime <= checkStats)
584  {
585  stopTime = checkStats + Seconds(1);
586  }
587  }
588  }
589 
590  Simulator::Stop(stopTime);
591  Simulator::Run();
592  Simulator::Destroy();
593 }
594 
595 void
597 {
598  NS_LOG_FUNCTION(ueDevice << enbDevice);
599 
600  Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice>();
601  Ptr<LteUeRrc> ueRrc = ueLteDevice->GetRrc();
602  NS_TEST_ASSERT_MSG_EQ(ueRrc->GetState(), LteUeRrc::CONNECTED_NORMALLY, "Wrong LteUeRrc state!");
603 
604  Ptr<LteEnbNetDevice> enbLteDevice = enbDevice->GetObject<LteEnbNetDevice>();
605  Ptr<LteEnbRrc> enbRrc = enbLteDevice->GetRrc();
606  uint16_t rnti = ueRrc->GetRnti();
607  Ptr<UeManager> ueManager = enbRrc->GetUeManager(rnti);
608  NS_TEST_ASSERT_MSG_NE(ueManager, nullptr, "RNTI " << rnti << " not found in eNB");
609 
610  UeManager::State ueManagerState = ueManager->GetState();
611  NS_TEST_ASSERT_MSG_EQ(ueManagerState, UeManager::CONNECTED_NORMALLY, "Wrong UeManager state!");
612  NS_ASSERT_MSG(ueManagerState == UeManager::CONNECTED_NORMALLY, "Wrong UeManager state!");
613 
614  uint16_t ueCellId = ueRrc->GetCellId();
615  uint16_t enbCellId = enbLteDevice->GetCellId();
616  uint8_t ueDlBandwidth = ueRrc->GetDlBandwidth();
617  uint8_t enbDlBandwidth = enbLteDevice->GetDlBandwidth();
618  uint8_t ueUlBandwidth = ueRrc->GetUlBandwidth();
619  uint8_t enbUlBandwidth = enbLteDevice->GetUlBandwidth();
620  uint8_t ueDlEarfcn = ueRrc->GetDlEarfcn();
621  uint8_t enbDlEarfcn = enbLteDevice->GetDlEarfcn();
622  uint8_t ueUlEarfcn = ueRrc->GetUlEarfcn();
623  uint8_t enbUlEarfcn = enbLteDevice->GetUlEarfcn();
624  uint64_t ueImsi = ueLteDevice->GetImsi();
625  uint64_t enbImsi = ueManager->GetImsi();
626 
627  NS_TEST_ASSERT_MSG_EQ(ueImsi, enbImsi, "inconsistent IMSI");
628  NS_TEST_ASSERT_MSG_EQ(ueCellId, enbCellId, "inconsistent CellId");
629  NS_TEST_ASSERT_MSG_EQ(ueDlBandwidth, enbDlBandwidth, "inconsistent DlBandwidth");
630  NS_TEST_ASSERT_MSG_EQ(ueUlBandwidth, enbUlBandwidth, "inconsistent UlBandwidth");
631  NS_TEST_ASSERT_MSG_EQ(ueDlEarfcn, enbDlEarfcn, "inconsistent DlEarfcn");
632  NS_TEST_ASSERT_MSG_EQ(ueUlEarfcn, enbUlEarfcn, "inconsistent UlEarfcn");
633 
634  ObjectMapValue enbDataRadioBearerMapValue;
635  ueManager->GetAttribute("DataRadioBearerMap", enbDataRadioBearerMapValue);
636  NS_TEST_ASSERT_MSG_EQ(enbDataRadioBearerMapValue.GetN(),
638  "wrong num bearers at eNB");
639 
640  ObjectMapValue ueDataRadioBearerMapValue;
641  ueRrc->GetAttribute("DataRadioBearerMap", ueDataRadioBearerMapValue);
642  NS_TEST_ASSERT_MSG_EQ(ueDataRadioBearerMapValue.GetN(),
644  "wrong num bearers at UE");
645 
646  auto enbBearerIt = enbDataRadioBearerMapValue.Begin();
647  auto ueBearerIt = ueDataRadioBearerMapValue.Begin();
648  while (enbBearerIt != enbDataRadioBearerMapValue.End() &&
649  ueBearerIt != ueDataRadioBearerMapValue.End())
650  {
651  Ptr<LteDataRadioBearerInfo> enbDrbInfo =
652  enbBearerIt->second->GetObject<LteDataRadioBearerInfo>();
653  Ptr<LteDataRadioBearerInfo> ueDrbInfo =
654  ueBearerIt->second->GetObject<LteDataRadioBearerInfo>();
655  // NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_epsBearer, ueDrbInfo->m_epsBearer, "epsBearer
656  // differs");
657  NS_TEST_ASSERT_MSG_EQ((uint32_t)enbDrbInfo->m_epsBearerIdentity,
658  (uint32_t)ueDrbInfo->m_epsBearerIdentity,
659  "epsBearerIdentity differs");
660  NS_TEST_ASSERT_MSG_EQ((uint32_t)enbDrbInfo->m_drbIdentity,
661  (uint32_t)ueDrbInfo->m_drbIdentity,
662  "drbIdentity differs");
663  // NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_rlcConfig, ueDrbInfo->m_rlcConfig, "rlcConfig
664  // differs");
665  NS_TEST_ASSERT_MSG_EQ((uint32_t)enbDrbInfo->m_logicalChannelIdentity,
666  (uint32_t)ueDrbInfo->m_logicalChannelIdentity,
667  "logicalChannelIdentity differs");
668  // NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_logicalChannelConfig,
669  // ueDrbInfo->m_logicalChannelConfig, "logicalChannelConfig differs");
670 
671  ++enbBearerIt;
672  ++ueBearerIt;
673  }
674  NS_ASSERT_MSG(enbBearerIt == enbDataRadioBearerMapValue.End(), "too many bearers at eNB");
675  NS_ASSERT_MSG(ueBearerIt == ueDataRadioBearerMapValue.End(), "too many bearers at UE");
676 }
677 
678 void
680 {
681  NS_LOG_FUNCTION(ueIndex);
682  for (auto it = m_ueDataVector.at(ueIndex).bearerDataList.begin();
683  it != m_ueDataVector.at(ueIndex).bearerDataList.end();
684  ++it)
685  {
686  if (it->dlSink)
687  {
688  it->dlOldTotalRx = it->dlSink->GetTotalRx();
689  }
690  if (it->ulSink)
691  {
692  it->ulOldTotalRx = it->ulSink->GetTotalRx();
693  }
694  }
695 }
696 
697 void
699 {
700  NS_LOG_FUNCTION(ueIndex);
701  uint32_t b = 1;
702  for (auto it = m_ueDataVector.at(ueIndex).bearerDataList.begin();
703  it != m_ueDataVector.at(ueIndex).bearerDataList.end();
704  ++it)
705  {
706  uint32_t dlRx = 0;
707  uint32_t ulRx = 0;
708 
709  if (it->dlSink)
710  {
711  dlRx = it->dlSink->GetTotalRx() - it->dlOldTotalRx;
712  }
713 
714  if (it->ulSink)
715  {
716  ulRx = it->ulSink->GetTotalRx() - it->ulOldTotalRx;
717  }
718  double expectedBytes =
720 
721  NS_LOG_LOGIC("expBytes " << expectedBytes << " dlRx " << dlRx << " ulRx " << ulRx);
722 
723  // tolerance
724  if (it->dlSink)
725  {
727  0.500 * expectedBytes,
728  "too few RX bytes in DL, ue=" << ueIndex << ", b=" << b);
729  }
730  if (it->ulSink)
731  {
733  0.500 * expectedBytes,
734  "too few RX bytes in UL, ue=" << ueIndex << ", b=" << b);
735  }
736  ++b;
737  }
738 }
739 
746 {
747  public:
749 };
750 
752  : TestSuite("lte-x2-handover-measures", SYSTEM)
753 {
754  Time checkInterval = Seconds(1);
755 
756  std::string cel1name("ho: 0 -> 1");
757  const std::list<CheckPointEvent> cel1{
758  CheckPointEvent(Seconds(1), Seconds(10.1), checkInterval, 0, 0),
759  CheckPointEvent(Seconds(11), Seconds(17), checkInterval, 0, 1),
760  };
761 
762  std::string cel2name("ho: 0 -> 1 -> 2");
763  const std::list<CheckPointEvent> cel2{
764  CheckPointEvent(Seconds(1), Seconds(10.1), checkInterval, 0, 0),
765  CheckPointEvent(Seconds(11), Seconds(17.1), checkInterval, 0, 1),
766  CheckPointEvent(Seconds(18), Seconds(24), checkInterval, 0, 2),
767  };
768 
769  std::string cel3name("ho: 0 -> 1 -> 2 -> 3");
770  const std::list<CheckPointEvent> cel3{
771  CheckPointEvent(Seconds(1), Seconds(10.1), checkInterval, 0, 0),
772  CheckPointEvent(Seconds(11), Seconds(17.1), checkInterval, 0, 1),
773  CheckPointEvent(Seconds(18), Seconds(24.1), checkInterval, 0, 2),
774  CheckPointEvent(Seconds(25), Seconds(37), checkInterval, 0, 3),
775  };
776 
777  std::string sched = "ns3::PfFfMacScheduler";
778  std::string ho = "ns3::A2A4RsrqHandoverAlgorithm";
779  for (auto useIdealRrc : {true, false})
780  {
781  // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, ho, admitHo, idealRrc
783  1,
784  0,
785  cel1,
786  cel1name,
787  true,
788  sched,
789  ho,
790  true,
791  useIdealRrc),
792  TestCase::TAKES_FOREVER);
794  1,
795  1,
796  cel1,
797  cel1name,
798  true,
799  sched,
800  ho,
801  true,
802  useIdealRrc),
803  TestCase::QUICK);
805  1,
806  2,
807  cel1,
808  cel1name,
809  true,
810  sched,
811  ho,
812  true,
813  useIdealRrc),
814  TestCase::TAKES_FOREVER);
816  1,
817  0,
818  cel2,
819  cel2name,
820  true,
821  sched,
822  ho,
823  true,
824  useIdealRrc),
825  TestCase::TAKES_FOREVER);
827  1,
828  1,
829  cel2,
830  cel2name,
831  true,
832  sched,
833  ho,
834  true,
835  useIdealRrc),
836  TestCase::TAKES_FOREVER);
838  1,
839  2,
840  cel2,
841  cel2name,
842  true,
843  sched,
844  ho,
845  true,
846  useIdealRrc),
847  TestCase::EXTENSIVE);
849  1,
850  0,
851  cel3,
852  cel3name,
853  true,
854  sched,
855  ho,
856  true,
857  useIdealRrc),
858  TestCase::EXTENSIVE);
860  1,
861  1,
862  cel3,
863  cel3name,
864  true,
865  sched,
866  ho,
867  true,
868  useIdealRrc),
869  TestCase::TAKES_FOREVER);
871  1,
872  2,
873  cel3,
874  cel3name,
875  true,
876  sched,
877  ho,
878  true,
879  useIdealRrc),
880  TestCase::TAKES_FOREVER);
881  }
882 
883  sched = "ns3::RrFfMacScheduler";
884  for (auto useIdealRrc : {true, false})
885  {
886  // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, admitHo, idealRrc
888  1,
889  0,
890  cel1,
891  cel1name,
892  true,
893  sched,
894  ho,
895  true,
896  useIdealRrc),
897  TestCase::EXTENSIVE);
899  1,
900  0,
901  cel2,
902  cel2name,
903  true,
904  sched,
905  ho,
906  true,
907  useIdealRrc),
908  TestCase::TAKES_FOREVER);
910  1,
911  0,
912  cel3,
913  cel3name,
914  true,
915  sched,
916  ho,
917  true,
918  useIdealRrc),
919  TestCase::TAKES_FOREVER);
920  }
921 
922  ho = "ns3::A3RsrpHandoverAlgorithm";
923  sched = "ns3::PfFfMacScheduler";
924  for (auto useIdealRrc : {true, false})
925  {
926  // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, admitHo, idealRrc
928  1,
929  0,
930  cel1,
931  cel1name,
932  true,
933  sched,
934  ho,
935  true,
936  useIdealRrc),
937  TestCase::EXTENSIVE);
939  1,
940  0,
941  cel2,
942  cel2name,
943  true,
944  sched,
945  ho,
946  true,
947  useIdealRrc),
948  TestCase::TAKES_FOREVER);
950  1,
951  0,
952  cel3,
953  cel3name,
954  true,
955  sched,
956  ho,
957  true,
958  useIdealRrc),
959  TestCase::TAKES_FOREVER);
960  }
961 
962  sched = "ns3::RrFfMacScheduler";
963  for (auto useIdealRrc : {true, false})
964  {
965  // nEnbs, nUes, nDBearers, celist, name, useUdp, sched, admitHo, idealRrc
967  1,
968  0,
969  cel1,
970  cel1name,
971  true,
972  sched,
973  ho,
974  true,
975  useIdealRrc),
976  TestCase::QUICK);
978  1,
979  0,
980  cel2,
981  cel2name,
982  true,
983  sched,
984  ho,
985  true,
986  useIdealRrc),
987  TestCase::TAKES_FOREVER);
989  1,
990  0,
991  cel3,
992  cel3name,
993  true,
994  sched,
995  ho,
996  true,
997  useIdealRrc),
998  TestCase::EXTENSIVE);
999  }
1000 
1001 } // end of LteX2HandoverMeasuresTestSuite ()
1002 
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.
bool m_useIdealRrc
whether to use ideal RRC
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.
A helper to make it easier to instantiate an ns3::BulkSendApplication on a set of nodes.
void SetAttribute(std::string name, const AttributeValue &value)
Helper function used to set the underlying application attributes, not the socket attributes.
ApplicationContainer Install(NodeContainer c) const
Install an ns3::BulkSendApplication on each node of the input container configured with all the attri...
Mobility model for which the current speed does not change once it has been set and until it is set a...
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.
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:42
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:80
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:257
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:285
void SetHandoverAlgorithmAttribute(std::string n, const AttributeValue &v)
Set an attribute for the handover algorithm to be created.
Definition: lte-helper.cc:348
NetDeviceContainer InstallEnbDevice(NodeContainer c)
Create a set of eNodeB devices.
Definition: lte-helper.cc:485
void SetHandoverAlgorithmType(std::string type)
Set the type of handover algorithm to be used by eNodeB devices.
Definition: lte-helper.cc:340
void SetSchedulerType(std::string type)
Set the type of scheduler to be used by eNodeB devices.
Definition: lte-helper.cc:292
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:1039
void ActivateDataRadioBearer(NetDeviceContainer ueDevices, EpsBearer bearer)
Activate a Data Radio Bearer on a given UE devices (for LTE-only simulation).
Definition: lte-helper.cc:1436
NetDeviceContainer InstallUeDevice(NodeContainer c)
Create a set of UE devices.
Definition: lte-helper.cc:500
void AddX2Interface(NodeContainer enbNodes)
Create an X2 interface between all the eNBs in a given set.
Definition: lte-helper.cc:1313
int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used.
Definition: lte-helper.cc:1567
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:1154
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.
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:204
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.
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:75
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:77
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
Hold variables of type string.
Definition: string.h:56
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:301
A suite of tests to run.
Definition: test.h:1256
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
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:78
Hold an unsigned integer type.
Definition: uinteger.h:45
double GetValue(double min, double max)
Get the next random value drawn from the distribution.
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:855
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:890
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#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.
void(* DataRate)(DataRate oldValue, DataRate newValue)
TracedValue callback signature for DataRate.
Definition: data-rate.h:327
#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
#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:874
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
serverApps
Definition: first.py:54
clientApps
Definition: first.py:64
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
Time checkInterval
check interval
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: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