A Discrete-Event Network Simulator
API
test-lte-x2-handover.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Nicola Baldo <nbaldo@cttc.es>
19  */
20 
21 
22 #include <ns3/core-module.h>
23 #include <ns3/network-module.h>
24 #include <ns3/mobility-module.h>
25 #include <ns3/lte-module.h>
26 #include <ns3/internet-module.h>
27 #include <ns3/applications-module.h>
28 #include <ns3/point-to-point-module.h>
29 
30 using namespace ns3;
31 
32 NS_LOG_COMPONENT_DEFINE ("LteX2HandoverTest");
33 
41 {
43  uint32_t ueDeviceIndex;
46 };
47 
48 
57 {
58 public:
59 
72  LteX2HandoverTestCase (uint32_t nUes, uint32_t nDedicatedBearers, std::list<HandoverEvent> handoverEventList, std::string handoverEventListName, bool useUdp, std::string schedulerType, bool admitHo, bool useIdealRrc);
73 
74 private:
86  static std::string BuildNameString (uint32_t nUes, uint32_t nDedicatedBearers, std::string handoverEventListName, bool useUdp, std::string schedulerType, bool admitHo, bool useIdealRrc);
87  virtual void DoRun (void);
93  void CheckConnected (Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice);
94 
95  uint32_t m_nUes;
97  std::list<HandoverEvent> m_handoverEventList;
99  bool m_epc;
100  bool m_useUdp;
101  std::string m_schedulerType;
102  bool m_admitHo;
106 
113  struct BearerData
114  {
115  uint32_t bid;
118  uint32_t dlOldTotalRx;
119  uint32_t ulOldTotalRx;
120  };
121 
128  struct UeData
129  {
130  uint32_t id;
131  std::list<BearerData> bearerDataList;
132  };
133 
138  void SaveStatsAfterHandover (uint32_t ueIndex);
143  void CheckStatsAWhileAfterHandover (uint32_t ueIndex);
144 
145  std::vector<UeData> m_ueDataVector;
146 
150  const uint32_t m_udpClientPktSize;
151 
152 };
153 
154 
155 std::string LteX2HandoverTestCase::BuildNameString (uint32_t nUes, uint32_t nDedicatedBearers, std::string handoverEventListName, bool useUdp, std::string schedulerType, bool admitHo, bool useIdealRrc)
156 {
157  std::ostringstream oss;
158  oss << " nUes=" << nUes
159  << " nDedicatedBearers=" << nDedicatedBearers
160  << " udp=" << useUdp
161  << " " << schedulerType
162  << " admitHo=" << admitHo
163  << " hoList: " << handoverEventListName;
164  if (useIdealRrc)
165  {
166  oss << ", ideal RRC";
167  }
168  else
169  {
170  oss << ", real RRC";
171  }
172  return oss.str ();
173 }
174 
175 LteX2HandoverTestCase::LteX2HandoverTestCase (uint32_t nUes, uint32_t nDedicatedBearers, std::list<HandoverEvent> handoverEventList, std::string handoverEventListName, bool useUdp, std::string schedulerType, bool admitHo, bool useIdealRrc)
176  : TestCase (BuildNameString (nUes, nDedicatedBearers, handoverEventListName, useUdp, schedulerType, admitHo, useIdealRrc)),
177  m_nUes (nUes),
178  m_nDedicatedBearers (nDedicatedBearers),
179  m_handoverEventList (handoverEventList),
180  m_handoverEventListName (handoverEventListName),
181  m_epc (true),
182  m_useUdp (useUdp),
183  m_schedulerType (schedulerType),
184  m_admitHo (admitHo),
185  m_useIdealRrc (useIdealRrc),
186  m_maxHoDuration (Seconds (0.1)),
187  m_statsDuration (Seconds (0.1)),
188  m_udpClientInterval (Seconds (0.01)),
189  m_udpClientPktSize (100)
190 
191 {
192 }
193 
194 void
196 {
198 
199  Config::Reset ();
200  Config::SetDefault ("ns3::UdpClient::Interval", TimeValue (m_udpClientInterval));
201  Config::SetDefault ("ns3::UdpClient::MaxPackets", UintegerValue (1000000));
202  Config::SetDefault ("ns3::UdpClient::PacketSize", UintegerValue (m_udpClientPktSize));
203 
204  //Disable Uplink Power Control
205  Config::SetDefault ("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue (false));
206 
207  int64_t stream = 1;
208 
209  m_lteHelper = CreateObject<LteHelper> ();
210  m_lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel"));
212  m_lteHelper->SetHandoverAlgorithmType ("ns3::NoOpHandoverAlgorithm"); // disable automatic handover
214 
215 
216  NodeContainer enbNodes;
217  enbNodes.Create (2);
218  NodeContainer ueNodes;
219  ueNodes.Create (m_nUes);
220 
221  if (m_epc)
222  {
223  m_epcHelper = CreateObject<PointToPointEpcHelper> ();
225  }
226 
227  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
228  positionAlloc->Add (Vector (-3000, 0, 0)); // enb0
229  positionAlloc->Add (Vector ( 3000, 0, 0)); // enb1
230  for (uint16_t i = 0; i < m_nUes; i++)
231  {
232  positionAlloc->Add (Vector (0, 0, 0));
233  }
235  mobility.SetPositionAllocator (positionAlloc);
236  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
237  mobility.Install (enbNodes);
238  mobility.Install (ueNodes);
239 
240  NetDeviceContainer enbDevices;
241  enbDevices = m_lteHelper->InstallEnbDevice (enbNodes);
242  stream += m_lteHelper->AssignStreams (enbDevices, stream);
243  for (NetDeviceContainer::Iterator it = enbDevices.Begin ();
244  it != enbDevices.End ();
245  ++it)
246  {
247  Ptr<LteEnbRrc> enbRrc = (*it)->GetObject<LteEnbNetDevice> ()->GetRrc ();
248  enbRrc->SetAttribute ("AdmitHandoverRequest", BooleanValue (m_admitHo));
249  }
250 
251  NetDeviceContainer ueDevices;
252  ueDevices = m_lteHelper->InstallUeDevice (ueNodes);
253  stream += m_lteHelper->AssignStreams (ueDevices, stream);
254 
255  Ipv4Address remoteHostAddr;
256  Ipv4StaticRoutingHelper ipv4RoutingHelper;
257  Ipv4InterfaceContainer ueIpIfaces;
258  Ptr<Node> remoteHost;
259  if (m_epc)
260  {
261  // Create a single RemoteHost
262  NodeContainer remoteHostContainer;
263  remoteHostContainer.Create (1);
264  remoteHost = remoteHostContainer.Get (0);
265  InternetStackHelper internet;
266  internet.Install (remoteHostContainer);
267 
268  // Create the Internet
269  PointToPointHelper p2ph;
270  p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s")));
271  p2ph.SetDeviceAttribute ("Mtu", UintegerValue (1500));
272  p2ph.SetChannelAttribute ("Delay", TimeValue (Seconds (0.010)));
273  Ptr<Node> pgw = m_epcHelper->GetPgwNode ();
274  NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost);
275  Ipv4AddressHelper ipv4h;
276  ipv4h.SetBase ("1.0.0.0", "255.0.0.0");
277  Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices);
278  // in this container, interface 0 is the pgw, 1 is the remoteHost
279  remoteHostAddr = internetIpIfaces.GetAddress (1);
280 
281  Ipv4StaticRoutingHelper ipv4RoutingHelper;
282  Ptr<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());
283  remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.0.0.0"), 1);
284 
285  // Install the IP stack on the UEs
286  internet.Install (ueNodes);
287  ueIpIfaces = m_epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueDevices));
288  }
289 
290  // attachment (needs to be done after IP stack configuration)
291  // all UEs attached to eNB 0 at the beginning
292  m_lteHelper->Attach (ueDevices, enbDevices.Get (0));
293 
294  if (m_epc)
295  {
296  // always true: bool epcDl = true;
297  // always true: bool epcUl = true;
298  // the rest of this block is copied from lena-dual-stripe
299 
300 
301  // Install and start applications on UEs and remote host
302  uint16_t dlPort = 10000;
303  uint16_t ulPort = 20000;
304 
305  // randomize a bit start times to avoid simulation artifacts
306  // (e.g., buffer overflows due to packet transmissions happening
307  // exactly at the same time)
308  Ptr<UniformRandomVariable> startTimeSeconds = CreateObject<UniformRandomVariable> ();
309  startTimeSeconds->SetAttribute ("Min", DoubleValue (0));
310  startTimeSeconds->SetAttribute ("Max", DoubleValue (0.010));
311  startTimeSeconds->SetStream (stream++);
312 
313  for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
314  {
315  Ptr<Node> ue = ueNodes.Get (u);
316  // Set the default gateway for the UE
317  Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ue->GetObject<Ipv4> ());
318  ueStaticRouting->SetDefaultRoute (m_epcHelper->GetUeDefaultGatewayAddress (), 1);
319 
320  UeData ueData;
321 
322  for (uint32_t b = 0; b < m_nDedicatedBearers; ++b)
323  {
324  ++dlPort;
325  ++ulPort;
326 
329  BearerData bearerData;
330 
331  if (m_useUdp)
332  {
333  // always true: if (epcDl)
334  {
335  UdpClientHelper dlClientHelper (ueIpIfaces.GetAddress (u), dlPort);
336  clientApps.Add (dlClientHelper.Install (remoteHost));
337  PacketSinkHelper dlPacketSinkHelper ("ns3::UdpSocketFactory",
338  InetSocketAddress (Ipv4Address::GetAny (), dlPort));
339  ApplicationContainer sinkContainer = dlPacketSinkHelper.Install (ue);
340  bearerData.dlSink = sinkContainer.Get (0)->GetObject<PacketSink> ();
341  serverApps.Add (sinkContainer);
342 
343  }
344  // always true: if (epcUl)
345  {
346  UdpClientHelper ulClientHelper (remoteHostAddr, ulPort);
347  clientApps.Add (ulClientHelper.Install (ue));
348  PacketSinkHelper ulPacketSinkHelper ("ns3::UdpSocketFactory",
349  InetSocketAddress (Ipv4Address::GetAny (), ulPort));
350  ApplicationContainer sinkContainer = ulPacketSinkHelper.Install (remoteHost);
351  bearerData.ulSink = sinkContainer.Get (0)->GetObject<PacketSink> ();
352  serverApps.Add (sinkContainer);
353  }
354  }
355  else // use TCP
356  {
357  // always true: if (epcDl)
358  {
359  BulkSendHelper dlClientHelper ("ns3::TcpSocketFactory",
360  InetSocketAddress (ueIpIfaces.GetAddress (u), dlPort));
361  dlClientHelper.SetAttribute ("MaxBytes", UintegerValue (0));
362  clientApps.Add (dlClientHelper.Install (remoteHost));
363  PacketSinkHelper dlPacketSinkHelper ("ns3::TcpSocketFactory",
364  InetSocketAddress (Ipv4Address::GetAny (), dlPort));
365  ApplicationContainer sinkContainer = dlPacketSinkHelper.Install (ue);
366  bearerData.dlSink = sinkContainer.Get (0)->GetObject<PacketSink> ();
367  serverApps.Add (sinkContainer);
368  }
369  // always true: if (epcUl)
370  {
371  BulkSendHelper ulClientHelper ("ns3::TcpSocketFactory",
372  InetSocketAddress (remoteHostAddr, ulPort));
373  ulClientHelper.SetAttribute ("MaxBytes", UintegerValue (0));
374  clientApps.Add (ulClientHelper.Install (ue));
375  PacketSinkHelper ulPacketSinkHelper ("ns3::TcpSocketFactory",
376  InetSocketAddress (Ipv4Address::GetAny (), ulPort));
377  ApplicationContainer sinkContainer = ulPacketSinkHelper.Install (remoteHost);
378  bearerData.ulSink = sinkContainer.Get (0)->GetObject<PacketSink> ();
379  serverApps.Add (sinkContainer);
380  }
381  } // end if (useUdp)
382 
383  Ptr<EpcTft> tft = Create<EpcTft> ();
384  // always true: if (epcDl)
385  {
387  dlpf.localPortStart = dlPort;
388  dlpf.localPortEnd = dlPort;
389  tft->Add (dlpf);
390  }
391  // always true: if (epcUl)
392  {
394  ulpf.remotePortStart = ulPort;
395  ulpf.remotePortEnd = ulPort;
396  tft->Add (ulpf);
397  }
398 
399  // always true: if (epcDl || epcUl)
400  {
401  EpsBearer bearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT);
402  m_lteHelper->ActivateDedicatedEpsBearer (ueDevices.Get (u), bearer, tft);
403  }
404  Time startTime = Seconds (startTimeSeconds->GetValue ());
405  serverApps.Start (startTime);
406  clientApps.Start (startTime);
407 
408  ueData.bearerDataList.push_back (bearerData);
409 
410  } // end for b
411 
412  m_ueDataVector.push_back (ueData);
413  }
414 
415  }
416  else // (epc == false)
417  {
418  // for radio bearer activation purposes, consider together home UEs and macro UEs
419  for (uint32_t u = 0; u < ueDevices.GetN (); ++u)
420  {
421  Ptr<NetDevice> ueDev = ueDevices.Get (u);
422  for (uint32_t b = 0; b < m_nDedicatedBearers; ++b)
423  {
424  enum EpsBearer::Qci q = EpsBearer::NGBR_VIDEO_TCP_DEFAULT;
425  EpsBearer bearer (q);
426  m_lteHelper->ActivateDataRadioBearer (ueDev, bearer);
427  }
428  }
429  }
430 
431 
432  m_lteHelper->AddX2Interface (enbNodes);
433 
434  // check initial RRC connection
435  const Time maxRrcConnectionEstablishmentDuration = Seconds (0.080);
436  for (NetDeviceContainer::Iterator it = ueDevices.Begin (); it != ueDevices.End (); ++it)
437  {
438  Simulator::Schedule (maxRrcConnectionEstablishmentDuration,
440  this, *it, enbDevices.Get (0));
441  }
442 
443  // schedule handover events and corresponding checks
444 
445  Time stopTime = Seconds (0);
446  for (std::list<HandoverEvent>::iterator hoEventIt = m_handoverEventList.begin ();
447  hoEventIt != m_handoverEventList.end ();
448  ++hoEventIt)
449  {
450  Simulator::Schedule (hoEventIt->startTime,
452  this,
453  ueDevices.Get (hoEventIt->ueDeviceIndex),
454  enbDevices.Get (hoEventIt->sourceEnbDeviceIndex));
455  m_lteHelper->HandoverRequest (hoEventIt->startTime,
456  ueDevices.Get (hoEventIt->ueDeviceIndex),
457  enbDevices.Get (hoEventIt->sourceEnbDeviceIndex),
458  enbDevices.Get (hoEventIt->targetEnbDeviceIndex));
459  Time hoEndTime = hoEventIt->startTime + m_maxHoDuration;
460  Simulator::Schedule (hoEndTime,
462  this,
463  ueDevices.Get (hoEventIt->ueDeviceIndex),
464  enbDevices.Get (m_admitHo ? hoEventIt->targetEnbDeviceIndex : hoEventIt->sourceEnbDeviceIndex));
465  Simulator::Schedule (hoEndTime, &LteX2HandoverTestCase::SaveStatsAfterHandover,
466  this, hoEventIt->ueDeviceIndex);
467 
468  Time checkStatsAfterHoTime = hoEndTime + m_statsDuration;
469  Simulator::Schedule (checkStatsAfterHoTime, &LteX2HandoverTestCase::CheckStatsAWhileAfterHandover,
470  this, hoEventIt->ueDeviceIndex);
471  if (stopTime <= checkStatsAfterHoTime)
472  {
473  stopTime = checkStatsAfterHoTime + MilliSeconds (1);
474  }
475  }
476 
477  // m_lteHelper->EnableRlcTraces ();
478  // m_lteHelper->EnablePdcpTraces();
479 
480 
481  Simulator::Stop (stopTime);
482 
483  Simulator::Run ();
484 
485  Simulator::Destroy ();
486 
487 }
488 
489 void
491 {
492  Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice> ();
493  Ptr<LteUeRrc> ueRrc = ueLteDevice->GetRrc ();
494  NS_TEST_ASSERT_MSG_EQ (ueRrc->GetState (), LteUeRrc::CONNECTED_NORMALLY, "Wrong LteUeRrc state!");
495 
496 
497  Ptr<LteEnbNetDevice> enbLteDevice = enbDevice->GetObject<LteEnbNetDevice> ();
498  Ptr<LteEnbRrc> enbRrc = enbLteDevice->GetRrc ();
499  uint16_t rnti = ueRrc->GetRnti ();
500  Ptr<UeManager> ueManager = enbRrc->GetUeManager (rnti);
501  NS_TEST_ASSERT_MSG_NE (ueManager, 0, "RNTI " << rnti << " not found in eNB");
502 
503  UeManager::State ueManagerState = ueManager->GetState ();
504  NS_TEST_ASSERT_MSG_EQ (ueManagerState, UeManager::CONNECTED_NORMALLY, "Wrong UeManager state!");
505  NS_ASSERT_MSG (ueManagerState == UeManager::CONNECTED_NORMALLY, "Wrong UeManager state!");
506 
507  uint16_t ueCellId = ueRrc->GetCellId ();
508  uint16_t enbCellId = enbLteDevice->GetCellId ();
509  uint8_t ueDlBandwidth = ueRrc->GetDlBandwidth ();
510  uint8_t enbDlBandwidth = enbLteDevice->GetDlBandwidth ();
511  uint8_t ueUlBandwidth = ueRrc->GetUlBandwidth ();
512  uint8_t enbUlBandwidth = enbLteDevice->GetUlBandwidth ();
513  uint8_t ueDlEarfcn = ueRrc->GetDlEarfcn ();
514  uint8_t enbDlEarfcn = enbLteDevice->GetDlEarfcn ();
515  uint8_t ueUlEarfcn = ueRrc->GetUlEarfcn ();
516  uint8_t enbUlEarfcn = enbLteDevice->GetUlEarfcn ();
517  uint64_t ueImsi = ueLteDevice->GetImsi ();
518  uint64_t enbImsi = ueManager->GetImsi ();
519 
520  NS_TEST_ASSERT_MSG_EQ (ueImsi, enbImsi, "inconsistent IMSI");
521  NS_TEST_ASSERT_MSG_EQ (ueCellId, enbCellId, "inconsistent CellId");
522  NS_TEST_ASSERT_MSG_EQ (ueDlBandwidth, enbDlBandwidth, "inconsistent DlBandwidth");
523  NS_TEST_ASSERT_MSG_EQ (ueUlBandwidth, enbUlBandwidth, "inconsistent UlBandwidth");
524  NS_TEST_ASSERT_MSG_EQ (ueDlEarfcn, enbDlEarfcn, "inconsistent DlEarfcn");
525  NS_TEST_ASSERT_MSG_EQ (ueUlEarfcn, enbUlEarfcn, "inconsistent UlEarfcn");
526 
527  ObjectMapValue enbDataRadioBearerMapValue;
528  ueManager->GetAttribute ("DataRadioBearerMap", enbDataRadioBearerMapValue);
529  NS_TEST_ASSERT_MSG_EQ (enbDataRadioBearerMapValue.GetN (), m_nDedicatedBearers + 1, "wrong num bearers at eNB");
530 
531  ObjectMapValue ueDataRadioBearerMapValue;
532  ueRrc->GetAttribute ("DataRadioBearerMap", ueDataRadioBearerMapValue);
533  NS_TEST_ASSERT_MSG_EQ (ueDataRadioBearerMapValue.GetN (), m_nDedicatedBearers + 1, "wrong num bearers at UE");
534 
535  ObjectMapValue::Iterator enbBearerIt = enbDataRadioBearerMapValue.Begin ();
536  ObjectMapValue::Iterator ueBearerIt = ueDataRadioBearerMapValue.Begin ();
537  while (enbBearerIt != enbDataRadioBearerMapValue.End () &&
538  ueBearerIt != ueDataRadioBearerMapValue.End ())
539  {
540  Ptr<LteDataRadioBearerInfo> enbDrbInfo = enbBearerIt->second->GetObject<LteDataRadioBearerInfo> ();
541  Ptr<LteDataRadioBearerInfo> ueDrbInfo = ueBearerIt->second->GetObject<LteDataRadioBearerInfo> ();
542  //NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_epsBearer, ueDrbInfo->m_epsBearer, "epsBearer differs");
543  NS_TEST_ASSERT_MSG_EQ ((uint32_t) enbDrbInfo->m_epsBearerIdentity, (uint32_t) ueDrbInfo->m_epsBearerIdentity, "epsBearerIdentity differs");
544  NS_TEST_ASSERT_MSG_EQ ((uint32_t) enbDrbInfo->m_drbIdentity, (uint32_t) ueDrbInfo->m_drbIdentity, "drbIdentity differs");
545  //NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_rlcConfig, ueDrbInfo->m_rlcConfig, "rlcConfig differs");
546  NS_TEST_ASSERT_MSG_EQ ((uint32_t) enbDrbInfo->m_logicalChannelIdentity, (uint32_t) ueDrbInfo->m_logicalChannelIdentity, "logicalChannelIdentity differs");
547  //NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_logicalChannelConfig, ueDrbInfo->m_logicalChannelConfig, "logicalChannelConfig differs");
548 
549  ++enbBearerIt;
550  ++ueBearerIt;
551  }
552  NS_ASSERT_MSG (enbBearerIt == enbDataRadioBearerMapValue.End (), "too many bearers at eNB");
553  NS_ASSERT_MSG (ueBearerIt == ueDataRadioBearerMapValue.End (), "too many bearers at UE");
554 }
555 
556 void
558 {
559  for (std::list<BearerData>::iterator it = m_ueDataVector.at (ueIndex).bearerDataList.begin ();
560  it != m_ueDataVector.at (ueIndex).bearerDataList.end ();
561  ++it)
562  {
563  it->dlOldTotalRx = it->dlSink->GetTotalRx ();
564  it->ulOldTotalRx = it->ulSink->GetTotalRx ();
565  }
566 }
567 
568 void
570 {
571  uint32_t b = 1;
572  for (std::list<BearerData>::iterator it = m_ueDataVector.at (ueIndex).bearerDataList.begin ();
573  it != m_ueDataVector.at (ueIndex).bearerDataList.end ();
574  ++it)
575  {
576  uint32_t dlRx = it->dlSink->GetTotalRx () - it->dlOldTotalRx;
577  uint32_t ulRx = it->ulSink->GetTotalRx () - it->ulOldTotalRx;
578  uint32_t expectedBytes = m_udpClientPktSize * (m_statsDuration.GetSeconds () / m_udpClientInterval.GetSeconds ());
579  // tolerance
580  NS_TEST_ASSERT_MSG_GT (dlRx, 0.500 * expectedBytes, "too few RX bytes in DL, ue=" << ueIndex << ", b=" << b);
581  NS_TEST_ASSERT_MSG_GT (ulRx, 0.500 * expectedBytes, "too few RX bytes in UL, ue=" << ueIndex << ", b=" << b);
582  ++b;
583  }
584 }
585 
586 
594 {
595 public:
597 };
598 
599 
601  : TestSuite ("lte-x2-handover", SYSTEM)
602 {
603  // in the following:
604  // fwd means handover from enb 0 to enb 1
605  // bwd means handover from enb 1 to enb 0
606 
607  HandoverEvent ue1fwd;
608  ue1fwd.startTime = MilliSeconds (100);
609  ue1fwd.ueDeviceIndex = 0;
610  ue1fwd.sourceEnbDeviceIndex = 0;
611  ue1fwd.targetEnbDeviceIndex = 1;
612 
613  HandoverEvent ue1bwd;
614  ue1bwd.startTime = MilliSeconds (300);
615  ue1bwd.ueDeviceIndex = 0;
616  ue1bwd.sourceEnbDeviceIndex = 1;
617  ue1bwd.targetEnbDeviceIndex = 0;
618 
619  HandoverEvent ue1fwdagain;
620  ue1fwdagain.startTime = MilliSeconds (500);
621  ue1fwdagain.ueDeviceIndex = 0;
622  ue1fwdagain.sourceEnbDeviceIndex = 0;
623  ue1fwdagain.targetEnbDeviceIndex = 1;
624 
625  HandoverEvent ue2fwd;
626  ue2fwd.startTime = MilliSeconds (110);
627  ue2fwd.ueDeviceIndex = 1;
628  ue2fwd.sourceEnbDeviceIndex = 0;
629  ue2fwd.targetEnbDeviceIndex = 1;
630 
631  HandoverEvent ue2bwd;
632  ue2bwd.startTime = MilliSeconds (250);
633  ue2bwd.ueDeviceIndex = 1;
634  ue2bwd.sourceEnbDeviceIndex = 1;
635  ue2bwd.targetEnbDeviceIndex = 0;
636 
637  std::string hel0name ("none");
638  std::list<HandoverEvent> hel0;
639 
640  std::string hel1name ("1 fwd");
641  std::list<HandoverEvent> hel1;
642  hel1.push_back (ue1fwd);
643 
644  std::string hel2name ("1 fwd & bwd");
645  std::list<HandoverEvent> hel2;
646  hel2.push_back (ue1fwd);
647  hel2.push_back (ue1bwd);
648 
649  std::string hel3name ("1 fwd & bwd & fwd");
650  std::list<HandoverEvent> hel3;
651  hel3.push_back (ue1fwd);
652  hel3.push_back (ue1bwd);
653  hel3.push_back (ue1fwdagain);
654 
655  std::string hel4name ("1+2 fwd");
656  std::list<HandoverEvent> hel4;
657  hel4.push_back (ue1fwd);
658  hel4.push_back (ue2fwd);
659 
660  std::string hel5name ("1+2 fwd & bwd");
661  std::list<HandoverEvent> hel5;
662  hel5.push_back (ue1fwd);
663  hel5.push_back (ue1bwd);
664  hel5.push_back (ue2fwd);
665  hel5.push_back (ue2bwd);
666 
667  std::string hel6name ("2 fwd");
668  std::list<HandoverEvent> hel6;
669  hel6.push_back (ue2fwd);
670 
671  std::string hel7name ("2 fwd & bwd");
672  std::list<HandoverEvent> hel7;
673  hel7.push_back (ue2fwd);
674  hel7.push_back (ue2bwd);
675 
676  std::vector<std::string> schedulers;
677  schedulers.push_back ("ns3::RrFfMacScheduler");
678  schedulers.push_back ("ns3::PfFfMacScheduler");
679  for (std::vector<std::string>::iterator schedIt = schedulers.begin (); schedIt != schedulers.end (); ++schedIt)
680  {
681  for (int32_t useIdealRrc = 1; useIdealRrc >= 0; --useIdealRrc)
682  {
683  // nUes, nDBearers, helist, name, useUdp, sched, admitHo, idealRrc
684  AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel0, hel0name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
685  AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel0, hel0name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
686  AddTestCase (new LteX2HandoverTestCase ( 1, 5, hel0, hel0name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
687  AddTestCase (new LteX2HandoverTestCase ( 2, 5, hel0, hel0name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
688  AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel1, hel1name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
689  AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel1, hel1name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
690  AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel1, hel1name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
691  AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel1, hel1name, true, *schedIt, false, useIdealRrc), TestCase::EXTENSIVE);
692  AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel1, hel1name, true, *schedIt, false, useIdealRrc), TestCase::EXTENSIVE);
693  AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel1, hel1name, true, *schedIt, false, useIdealRrc), TestCase::EXTENSIVE);
694  AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel1, hel1name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
695  AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel1, hel1name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
696  AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel1, hel1name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
697  AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel1, hel1name, true, *schedIt, false, useIdealRrc), TestCase::EXTENSIVE);
698  AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel1, hel1name, true, *schedIt, false, useIdealRrc), TestCase::EXTENSIVE);
699  AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel1, hel1name, true, *schedIt, false, useIdealRrc), TestCase::EXTENSIVE);
700  AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel2, hel2name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
701  AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel2, hel2name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
702  AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel2, hel2name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
703  AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel3, hel3name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
704  AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel3, hel3name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
705  AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel3, hel3name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
706  AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel3, hel3name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
707  AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel3, hel3name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
708  AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel3, hel3name, true, *schedIt, true, useIdealRrc), TestCase::QUICK);
709  AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel4, hel4name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
710  AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel4, hel4name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
711  AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel4, hel4name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
712  AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel5, hel5name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
713  AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel5, hel5name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
714  AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel5, hel5name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
715  AddTestCase (new LteX2HandoverTestCase ( 3, 0, hel3, hel3name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
716  AddTestCase (new LteX2HandoverTestCase ( 3, 1, hel3, hel3name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
717  AddTestCase (new LteX2HandoverTestCase ( 3, 2, hel3, hel3name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
718  AddTestCase (new LteX2HandoverTestCase ( 3, 0, hel4, hel4name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
719  AddTestCase (new LteX2HandoverTestCase ( 3, 1, hel4, hel4name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
720  AddTestCase (new LteX2HandoverTestCase ( 3, 2, hel4, hel4name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
721  AddTestCase (new LteX2HandoverTestCase ( 3, 0, hel5, hel5name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
722  AddTestCase (new LteX2HandoverTestCase ( 3, 1, hel5, hel5name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
723  AddTestCase (new LteX2HandoverTestCase ( 3, 2, hel5, hel5name, true, *schedIt, true, useIdealRrc), TestCase::QUICK);
724 
725  }
726  }
727 }
728 
holds a vector of ns3::Application pointers.
uint8_t Add(PacketFilter f)
add a PacketFilter to the Traffic Flow Template
Definition: epc-tft.cc:224
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
uint32_t m_nDedicatedBearers
number of UEs in the test
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
an Inet address class
std::list< BearerData > bearerDataList
bearer ID list
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
std::string m_handoverEventListName
handover event list name
State
The state of the UeManager at the eNB RRC.
Definition: lte-enb-rrc.h:84
AttributeValue implementation for Boolean.
Definition: boolean.h:36
NetDeviceContainer InstallEnbDevice(NodeContainer c)
Create a set of eNodeB devices.
Definition: lte-helper.cc:474
const uint32_t m_udpClientPktSize
UDP client packet size.
A helper to make it easier to instantiate an ns3::BulkSendApplication on a set of nodes...
Ptr< LteHelper > m_lteHelper
LTE helper.
holds a vector of std::pair of Ptr<Ipv4> and interface index.
void SetDefaultRoute(Ipv4Address nextHop, uint32_t interface, uint32_t metric=0)
Add a default route to the static routing table.
Time startTime
start time
Iterator End(void) const
Get an iterator which indicates past-the-last NetDevice in the container.
NS_ASSERT_MSG(false, "Ipv4AddressGenerator::MaskToIndex(): Impossible")
Hold variables of type string.
Definition: string.h:41
void HandoverRequest(Time hoTime, Ptr< NetDevice > ueDev, Ptr< NetDevice > sourceEnbDev, Ptr< NetDevice > targetEnbDev)
Manually trigger an X2-based handover.
Definition: lte-helper.cc:1242
NetDeviceContainer Install(NodeContainer c)
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:258
A suite of tests to run.
Definition: test.h:1342
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:355
serverApps
Definition: first.py:45
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:957
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1022
ApplicationContainer Install(NodeContainer c) const
Install an ns3::PacketSinkApplication on each node of the input container configured with all the att...
aggregate IP/TCP/UDP functionality to existing Nodes.
uint16_t localPortEnd
end of the port number range of the UE
Definition: epc-tft.h:137
State GetState() const
ApplicationContainer Install(NodeContainer c) const
Install an ns3::BulkSendApplication on each node of the input container configured with all the attri...
uint64_t GetImsi(void) const
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes...
Build a set of PointToPointNetDevice objects.
encapsulates test code
Definition: test.h:1155
int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used.
Definition: lte-helper.cc:1439
static std::string BuildNameString(uint32_t nUes, uint32_t nDedicatedBearers, std::string handoverEventListName, bool useUdp, std::string schedulerType, bool admitHo, bool useIdealRrc)
Build name string.
void ActivateDataRadioBearer(NetDeviceContainer ueDevices, EpsBearer bearer)
Activate a Data Radio Bearer on a given UE devices (for LTE-only simulation).
Definition: lte-helper.cc:1310
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
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:1065
uint32_t targetEnbDeviceIndex
target ENB device index
bool m_useUdp
whether to use UDP traffic
void SetHandoverAlgorithmType(std::string type)
Set the type of handover algorithm to be used by eNodeB devices.
Definition: lte-helper.cc:327
ApplicationContainer Install(NodeContainer c)
double stopTime
void SetSchedulerType(std::string type)
Set the type of scheduler to be used by eNodeB devices.
Definition: lte-helper.cc:279
mobility
Definition: third.py:101
Class for representing data rates.
Definition: data-rate.h:88
uint64_t GetImsi() const
Get the IMSI.
This class contains the specification of EPS Bearers.
Definition: eps-bearer.h:71
LteX2HandoverTestCase(uint32_t nUes, uint32_t nDedicatedBearers, std::list< HandoverEvent > handoverEventList, std::string handoverEventListName, bool useUdp, std::string schedulerType, bool admitHo, bool useIdealRrc)
void SaveStatsAfterHandover(uint32_t ueIndex)
Save stats after handover function.
store information on active data radio bearer instance
uint8_t m_logicalChannelIdentity
logical channel identity
Create a client application which sends UDP packets carrying a 32bit sequence number and a 64 bit tim...
uint32_t m_nUes
number of UEs in the test
AttributeValue implementation for Time.
Definition: nstime.h:1076
uint32_t ueDeviceIndex
UE device index.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
Lte X2 Handover Test Suite.
Iterator Begin(void) const
Get an iterator which refers to the first NetDevice in the container.
Iterator Begin(void) const
Get an iterator to the first Object.
Hold an unsigned integer type.
Definition: uinteger.h:44
double startTime
#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:168
std::map< std::size_t, Ptr< Object > >::const_iterator Iterator
Iterator type for traversing this container.
bool m_admitHo
whether to admit the handover request
std::string m_schedulerType
scheduler type
holds a vector of ns3::NetDevice pointers
Iterator End(void) const
Get an iterator to the past-the-end Object.
static LteX2HandoverTestSuite g_lteX2HandoverTestSuiteInstance
std::vector< UeData > m_ueDataVector
UE data vector.
const Time m_statsDuration
stats duration
std::size_t GetN(void) const
Get the number of Objects.
uint32_t sourceEnbDeviceIndex
source ENB device index
uint32_t GetN(void) const
Get the number of Ptr<Node> stored in this container.
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:76
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:459
std::list< HandoverEvent > m_handoverEventList
handover event list
uint16_t remotePortEnd
end of the port number range of the remote host
Definition: epc-tft.h:135
virtual Ipv4Address GetUeDefaultGatewayAddress()
bool m_useIdealRrc
whether to use the ideal RRC
Every class exported by the ns3 library is enclosed in the ns3 namespace.
keep track of a set of node pointers.
const Time m_udpClientInterval
UDP client interval.
virtual void DoRun(void)
Implementation to actually run this TestCase.
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
void AddX2Interface(NodeContainer enbNodes)
Create an X2 interface between all the eNBs in a given set.
Definition: lte-helper.cc:1217
Ptr< PointToPointEpcHelper > m_epcHelper
EPC helper.
void Reset(void)
Reset the initial value of every attribute as well as the value of every global to what they were bef...
Definition: config.cc:757
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
NetDeviceContainer InstallUeDevice(NodeContainer c)
Create a set of UE devices.
Definition: lte-helper.cc:489
virtual Ipv4InterfaceContainer AssignUeIpv4Address(NetDeviceContainer ueDevices)
Assign IPv4 addresses to UE devices.
void CheckConnected(Ptr< NetDevice > ueDevice, Ptr< NetDevice > enbDevice)
Check connected function.
Helper class used to assign positions and mobility models to nodes.
void AddNetworkRouteTo(Ipv4Address network, Ipv4Mask networkMask, Ipv4Address nextHop, uint32_t interface, uint32_t metric=0)
Add a network route to the static routing table.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
const Time m_maxHoDuration
maximum HO duration
void CheckStatsAWhileAfterHandover(uint32_t ueIndex)
Check stats a while after handover function.
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
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:272
#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:624
uint8_t m_drbIdentity
DRB identity.
Helper class that adds ns3::Ipv4StaticRouting objects.
AttributeValue implementation for DataRate.
Definition: data-rate.h:242
std::vector< Ptr< NetDevice > >::const_iterator Iterator
NetDevice container iterator.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1014
uint32_t GetN(void) const
Get the number of Ptr<NetDevice> stored in this container.
uint32_t dlOldTotalRx
DL old total receive.
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:782
void Add(Vector v)
Add a position to the list of positions.
Ptr< LteUeRrc > GetRrc() const
Get the RRC.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
uint32_t ulOldTotalRx
UL old total receive.
clientApps
Definition: first.py:54
bool m_epc
whether to use EPC
HandoverEvent structure.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
void SetAttribute(std::string name, const AttributeValue &value)
Helper function used to set the underlying application attributes, not the socket attributes...
Container for a set of ns3::Object pointers.
Receive and consume traffic generated to an IP address and port.
Definition: packet-sink.h:68
#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:997
This class can be used to hold variables of floating point type such as &#39;double&#39; or &#39;float&#39;...
Definition: double.h:41
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
The eNodeB device implementation.
void GetAttribute(std::string name, AttributeValue &value) const
Get the value of an attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:223
Qci
QoS Class Indicator.
Definition: eps-bearer.h:77
Ptr< Application > Get(uint32_t i) const
Get the Ptr<Application> stored in this container at a given index.
uint16_t remotePortStart
start of the port number range of the remote host
Definition: epc-tft.h:134
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...
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Implement the data structure representing a TrafficFlowTemplate Packet Filter.
Definition: epc-tft.h:74
uint16_t localPortStart
start of the port number range of the UE
Definition: epc-tft.h:136
uint8_t m_epsBearerIdentity
EPS bearer identity.
The LteUeNetDevice class implements the UE net device.