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