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 
71  LteX2HandoverTestCase (uint32_t nUes, uint32_t nDedicatedBearers, std::list<HandoverEvent> handoverEventList, std::string handoverEventListName, std::string schedulerType, bool admitHo, bool useIdealRrc);
72 
73 private:
84  static std::string BuildNameString (uint32_t nUes, uint32_t nDedicatedBearers, std::string handoverEventListName, std::string schedulerType, bool admitHo, bool useIdealRrc);
85  virtual void DoRun (void);
91  void CheckConnected (Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice);
92 
97  void TeleportUeToMiddle (Ptr<Node> ueNode);
98 
104  void TeleportUeNearTargetEnb (Ptr<Node> ueNode, Ptr<Node> enbNode);
105 
106  uint32_t m_nUes;
108  std::list<HandoverEvent> m_handoverEventList;
110  bool m_epc;
111  std::string m_schedulerType;
112  bool m_admitHo;
116 
123  struct BearerData
124  {
125  uint32_t bid;
128  uint32_t dlOldTotalRx;
129  uint32_t ulOldTotalRx;
130  };
131 
138  struct UeData
139  {
140  uint32_t id;
141  std::list<BearerData> bearerDataList;
142  };
143 
148  void SaveStatsAfterHandover (uint32_t ueIndex);
153  void CheckStatsAWhileAfterHandover (uint32_t ueIndex);
154 
155  std::vector<UeData> m_ueDataVector;
156 
160  const uint32_t m_udpClientPktSize;
161 
162 };
163 
164 
165 std::string LteX2HandoverTestCase::BuildNameString (uint32_t nUes, uint32_t nDedicatedBearers, std::string handoverEventListName, std::string schedulerType, bool admitHo, bool useIdealRrc)
166 {
167  std::ostringstream oss;
168  oss << " nUes=" << nUes
169  << " nDedicatedBearers=" << nDedicatedBearers
170  << " " << schedulerType
171  << " admitHo=" << admitHo
172  << " hoList: " << handoverEventListName;
173  if (useIdealRrc)
174  {
175  oss << ", ideal RRC";
176  }
177  else
178  {
179  oss << ", real RRC";
180  }
181  return oss.str ();
182 }
183 
184 LteX2HandoverTestCase::LteX2HandoverTestCase (uint32_t nUes, uint32_t nDedicatedBearers, std::list<HandoverEvent> handoverEventList, std::string handoverEventListName, std::string schedulerType, bool admitHo, bool useIdealRrc)
185  : TestCase (BuildNameString (nUes, nDedicatedBearers, handoverEventListName, schedulerType, admitHo, useIdealRrc)),
186  m_nUes (nUes),
187  m_nDedicatedBearers (nDedicatedBearers),
188  m_handoverEventList (handoverEventList),
189  m_handoverEventListName (handoverEventListName),
190  m_epc (true),
191  m_schedulerType (schedulerType),
192  m_admitHo (admitHo),
193  m_useIdealRrc (useIdealRrc),
194  m_maxHoDuration (Seconds (0.1)),
195  m_statsDuration (Seconds (0.1)),
196  m_udpClientInterval (Seconds (0.01)),
197  m_udpClientPktSize (100)
198 
199 {
200 }
201 
202 void
204 {
206 
207  Config::Reset ();
208  Config::SetDefault ("ns3::UdpClient::Interval", TimeValue (m_udpClientInterval));
209  Config::SetDefault ("ns3::UdpClient::MaxPackets", UintegerValue (1000000));
210  Config::SetDefault ("ns3::UdpClient::PacketSize", UintegerValue (m_udpClientPktSize));
211 
212  //Disable Uplink Power Control
213  Config::SetDefault ("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue (false));
214 
215  int64_t stream = 1;
216 
217  m_lteHelper = CreateObject<LteHelper> ();
218  m_lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel"));
220  m_lteHelper->SetHandoverAlgorithmType ("ns3::NoOpHandoverAlgorithm"); // disable automatic handover
222 
223 
224  NodeContainer enbNodes;
225  enbNodes.Create (2);
226  NodeContainer ueNodes;
227  ueNodes.Create (m_nUes);
228 
229  if (m_epc)
230  {
231  m_epcHelper = CreateObject<PointToPointEpcHelper> ();
233  }
234 
235  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
236  positionAlloc->Add (Vector (-3000, 0, 0)); // enb0
237  positionAlloc->Add (Vector ( 3000, 0, 0)); // enb1
238  for (uint16_t i = 0; i < m_nUes; i++)
239  {
240  positionAlloc->Add (Vector (-3000, 100, 0));
241  }
243  mobility.SetPositionAllocator (positionAlloc);
244  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
245  mobility.Install (enbNodes);
246  mobility.Install (ueNodes);
247 
248  NetDeviceContainer enbDevices;
249  enbDevices = m_lteHelper->InstallEnbDevice (enbNodes);
250  stream += m_lteHelper->AssignStreams (enbDevices, stream);
251  for (NetDeviceContainer::Iterator it = enbDevices.Begin ();
252  it != enbDevices.End ();
253  ++it)
254  {
255  Ptr<LteEnbRrc> enbRrc = (*it)->GetObject<LteEnbNetDevice> ()->GetRrc ();
256  enbRrc->SetAttribute ("AdmitHandoverRequest", BooleanValue (m_admitHo));
257  }
258 
259  NetDeviceContainer ueDevices;
260  ueDevices = m_lteHelper->InstallUeDevice (ueNodes);
261  stream += m_lteHelper->AssignStreams (ueDevices, stream);
262 
263  Ipv4Address remoteHostAddr;
264  Ipv4StaticRoutingHelper ipv4RoutingHelper;
265  Ipv4InterfaceContainer ueIpIfaces;
266  Ptr<Node> remoteHost;
267  if (m_epc)
268  {
269  // Create a single RemoteHost
270  NodeContainer remoteHostContainer;
271  remoteHostContainer.Create (1);
272  remoteHost = remoteHostContainer.Get (0);
273  InternetStackHelper internet;
274  internet.Install (remoteHostContainer);
275 
276  // Create the Internet
277  PointToPointHelper p2ph;
278  p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s")));
279  p2ph.SetDeviceAttribute ("Mtu", UintegerValue (1500));
280  p2ph.SetChannelAttribute ("Delay", TimeValue (Seconds (0.010)));
281  Ptr<Node> pgw = m_epcHelper->GetPgwNode ();
282  NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost);
283  Ipv4AddressHelper ipv4h;
284  ipv4h.SetBase ("1.0.0.0", "255.0.0.0");
285  Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices);
286  // in this container, interface 0 is the pgw, 1 is the remoteHost
287  remoteHostAddr = internetIpIfaces.GetAddress (1);
288 
289  Ipv4StaticRoutingHelper ipv4RoutingHelper;
290  Ptr<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());
291  remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.0.0.0"), 1);
292 
293  // Install the IP stack on the UEs
294  internet.Install (ueNodes);
295  ueIpIfaces = m_epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueDevices));
296  }
297 
298  // attachment (needs to be done after IP stack configuration)
299  // all UEs attached to eNB 0 at the beginning
300  m_lteHelper->Attach (ueDevices, enbDevices.Get (0));
301 
302  if (m_epc)
303  {
304  // always true: bool epcDl = true;
305  // always true: bool epcUl = true;
306  // the rest of this block is copied from lena-dual-stripe
307 
308 
309  // Install and start applications on UEs and remote host
310  uint16_t dlPort = 10000;
311  uint16_t ulPort = 20000;
312 
313  // randomize a bit start times to avoid simulation artifacts
314  // (e.g., buffer overflows due to packet transmissions happening
315  // exactly at the same time)
316  Ptr<UniformRandomVariable> startTimeSeconds = CreateObject<UniformRandomVariable> ();
317  startTimeSeconds->SetAttribute ("Min", DoubleValue (0));
318  startTimeSeconds->SetAttribute ("Max", DoubleValue (0.010));
319  startTimeSeconds->SetStream (stream++);
320 
321  for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
322  {
323  Ptr<Node> ue = ueNodes.Get (u);
324  // Set the default gateway for the UE
325  Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ue->GetObject<Ipv4> ());
326  ueStaticRouting->SetDefaultRoute (m_epcHelper->GetUeDefaultGatewayAddress (), 1);
327 
328  UeData ueData;
329 
330  for (uint32_t b = 0; b < m_nDedicatedBearers; ++b)
331  {
332  ++dlPort;
333  ++ulPort;
334 
337  BearerData bearerData;
338 
339  // always true: if (epcDl)
340  {
341  UdpClientHelper dlClientHelper (ueIpIfaces.GetAddress (u), dlPort);
342  clientApps.Add (dlClientHelper.Install (remoteHost));
343  PacketSinkHelper dlPacketSinkHelper ("ns3::UdpSocketFactory",
344  InetSocketAddress (Ipv4Address::GetAny (), dlPort));
345  ApplicationContainer sinkContainer = dlPacketSinkHelper.Install (ue);
346  bearerData.dlSink = sinkContainer.Get (0)->GetObject<PacketSink> ();
347  serverApps.Add (sinkContainer);
348 
349  }
350  // always true: if (epcUl)
351  {
352  UdpClientHelper ulClientHelper (remoteHostAddr, ulPort);
353  clientApps.Add (ulClientHelper.Install (ue));
354  PacketSinkHelper ulPacketSinkHelper ("ns3::UdpSocketFactory",
355  InetSocketAddress (Ipv4Address::GetAny (), ulPort));
356  ApplicationContainer sinkContainer = ulPacketSinkHelper.Install (remoteHost);
357  bearerData.ulSink = sinkContainer.Get (0)->GetObject<PacketSink> ();
358  serverApps.Add (sinkContainer);
359  }
360 
361  Ptr<EpcTft> tft = Create<EpcTft> ();
362  // always true: if (epcDl)
363  {
365  dlpf.localPortStart = dlPort;
366  dlpf.localPortEnd = dlPort;
367  tft->Add (dlpf);
368  }
369  // always true: if (epcUl)
370  {
372  ulpf.remotePortStart = ulPort;
373  ulpf.remotePortEnd = ulPort;
374  tft->Add (ulpf);
375  }
376 
377  // always true: if (epcDl || epcUl)
378  {
379  EpsBearer bearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT);
380  m_lteHelper->ActivateDedicatedEpsBearer (ueDevices.Get (u), bearer, tft);
381  }
382  Time startTime = Seconds (startTimeSeconds->GetValue ());
383  serverApps.Start (startTime);
384  clientApps.Start (startTime);
385 
386  ueData.bearerDataList.push_back (bearerData);
387 
388  } // end for b
389 
390  m_ueDataVector.push_back (ueData);
391  }
392 
393  }
394  else // (epc == false)
395  {
396  // for radio bearer activation purposes, consider together home UEs and macro UEs
397  for (uint32_t u = 0; u < ueDevices.GetN (); ++u)
398  {
399  Ptr<NetDevice> ueDev = ueDevices.Get (u);
400  for (uint32_t b = 0; b < m_nDedicatedBearers; ++b)
401  {
402  enum EpsBearer::Qci q = EpsBearer::NGBR_VIDEO_TCP_DEFAULT;
403  EpsBearer bearer (q);
404  m_lteHelper->ActivateDataRadioBearer (ueDev, bearer);
405  }
406  }
407  }
408 
409 
410  m_lteHelper->AddX2Interface (enbNodes);
411 
412  // check initial RRC connection
413  const Time maxRrcConnectionEstablishmentDuration = Seconds (0.080);
414  for (NetDeviceContainer::Iterator it = ueDevices.Begin (); it != ueDevices.End (); ++it)
415  {
416  Simulator::Schedule (maxRrcConnectionEstablishmentDuration,
418  this, *it, enbDevices.Get (0));
419  }
420 
421  // schedule handover events and corresponding checks
422 
423  Time stopTime = Seconds (0);
424  for (std::list<HandoverEvent>::iterator hoEventIt = m_handoverEventList.begin ();
425  hoEventIt != m_handoverEventList.end ();
426  ++hoEventIt)
427  {
428  // Teleport the UE between both eNBs just before the handover starts
429  Simulator::Schedule (hoEventIt->startTime - MilliSeconds (10),
431  this,
432  ueNodes.Get (hoEventIt->ueDeviceIndex));
433 
434  Simulator::Schedule (hoEventIt->startTime,
436  this,
437  ueDevices.Get (hoEventIt->ueDeviceIndex),
438  enbDevices.Get (hoEventIt->sourceEnbDeviceIndex));
439 
440  m_lteHelper->HandoverRequest (hoEventIt->startTime,
441  ueDevices.Get (hoEventIt->ueDeviceIndex),
442  enbDevices.Get (hoEventIt->sourceEnbDeviceIndex),
443  enbDevices.Get (hoEventIt->targetEnbDeviceIndex));
444 
445  // Once the handover is finished, teleport the UE near the target eNB
446  Simulator::Schedule (hoEventIt->startTime + MilliSeconds (40),
448  this,
449  ueNodes.Get (hoEventIt->ueDeviceIndex),
450  enbNodes.Get (m_admitHo ? hoEventIt->targetEnbDeviceIndex
451  : hoEventIt->sourceEnbDeviceIndex));
452 
453  Time hoEndTime = hoEventIt->startTime + m_maxHoDuration;
454  Simulator::Schedule (hoEndTime,
456  this,
457  ueDevices.Get (hoEventIt->ueDeviceIndex),
458  enbDevices.Get (m_admitHo ? hoEventIt->targetEnbDeviceIndex : hoEventIt->sourceEnbDeviceIndex));
459  Simulator::Schedule (hoEndTime, &LteX2HandoverTestCase::SaveStatsAfterHandover,
460  this, hoEventIt->ueDeviceIndex);
461 
462  Time checkStatsAfterHoTime = hoEndTime + m_statsDuration;
463  Simulator::Schedule (checkStatsAfterHoTime, &LteX2HandoverTestCase::CheckStatsAWhileAfterHandover,
464  this, hoEventIt->ueDeviceIndex);
465  if (stopTime <= checkStatsAfterHoTime)
466  {
467  stopTime = checkStatsAfterHoTime + MilliSeconds (1);
468  }
469  }
470 
471  // m_lteHelper->EnableRlcTraces ();
472  // m_lteHelper->EnablePdcpTraces();
473 
474 
475  Simulator::Stop (stopTime);
476 
477  Simulator::Run ();
478 
479  Simulator::Destroy ();
480 
481 }
482 
483 void
485 {
486  Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice> ();
487  Ptr<LteUeRrc> ueRrc = ueLteDevice->GetRrc ();
488  NS_TEST_ASSERT_MSG_EQ (ueRrc->GetState (), LteUeRrc::CONNECTED_NORMALLY, "Wrong LteUeRrc state!");
489 
490 
491  Ptr<LteEnbNetDevice> enbLteDevice = enbDevice->GetObject<LteEnbNetDevice> ();
492  Ptr<LteEnbRrc> enbRrc = enbLteDevice->GetRrc ();
493  uint16_t rnti = ueRrc->GetRnti ();
494  Ptr<UeManager> ueManager = enbRrc->GetUeManager (rnti);
495  NS_TEST_ASSERT_MSG_NE (ueManager, 0, "RNTI " << rnti << " not found in eNB");
496 
497  UeManager::State ueManagerState = ueManager->GetState ();
498  NS_TEST_ASSERT_MSG_EQ (ueManagerState, UeManager::CONNECTED_NORMALLY, "Wrong UeManager state!");
499  NS_ASSERT_MSG (ueManagerState == UeManager::CONNECTED_NORMALLY, "Wrong UeManager state!");
500 
501  uint16_t ueCellId = ueRrc->GetCellId ();
502  uint16_t enbCellId = enbLteDevice->GetCellId ();
503  uint8_t ueDlBandwidth = ueRrc->GetDlBandwidth ();
504  uint8_t enbDlBandwidth = enbLteDevice->GetDlBandwidth ();
505  uint8_t ueUlBandwidth = ueRrc->GetUlBandwidth ();
506  uint8_t enbUlBandwidth = enbLteDevice->GetUlBandwidth ();
507  uint8_t ueDlEarfcn = ueRrc->GetDlEarfcn ();
508  uint8_t enbDlEarfcn = enbLteDevice->GetDlEarfcn ();
509  uint8_t ueUlEarfcn = ueRrc->GetUlEarfcn ();
510  uint8_t enbUlEarfcn = enbLteDevice->GetUlEarfcn ();
511  uint64_t ueImsi = ueLteDevice->GetImsi ();
512  uint64_t enbImsi = ueManager->GetImsi ();
513 
514  NS_TEST_ASSERT_MSG_EQ (ueImsi, enbImsi, "inconsistent IMSI");
515  NS_TEST_ASSERT_MSG_EQ (ueCellId, enbCellId, "inconsistent CellId");
516  NS_TEST_ASSERT_MSG_EQ (ueDlBandwidth, enbDlBandwidth, "inconsistent DlBandwidth");
517  NS_TEST_ASSERT_MSG_EQ (ueUlBandwidth, enbUlBandwidth, "inconsistent UlBandwidth");
518  NS_TEST_ASSERT_MSG_EQ (ueDlEarfcn, enbDlEarfcn, "inconsistent DlEarfcn");
519  NS_TEST_ASSERT_MSG_EQ (ueUlEarfcn, enbUlEarfcn, "inconsistent UlEarfcn");
520 
521  ObjectMapValue enbDataRadioBearerMapValue;
522  ueManager->GetAttribute ("DataRadioBearerMap", enbDataRadioBearerMapValue);
523  NS_TEST_ASSERT_MSG_EQ (enbDataRadioBearerMapValue.GetN (), m_nDedicatedBearers + 1, "wrong num bearers at eNB");
524 
525  ObjectMapValue ueDataRadioBearerMapValue;
526  ueRrc->GetAttribute ("DataRadioBearerMap", ueDataRadioBearerMapValue);
527  NS_TEST_ASSERT_MSG_EQ (ueDataRadioBearerMapValue.GetN (), m_nDedicatedBearers + 1, "wrong num bearers at UE");
528 
529  ObjectMapValue::Iterator enbBearerIt = enbDataRadioBearerMapValue.Begin ();
530  ObjectMapValue::Iterator ueBearerIt = ueDataRadioBearerMapValue.Begin ();
531  while (enbBearerIt != enbDataRadioBearerMapValue.End () &&
532  ueBearerIt != ueDataRadioBearerMapValue.End ())
533  {
534  Ptr<LteDataRadioBearerInfo> enbDrbInfo = enbBearerIt->second->GetObject<LteDataRadioBearerInfo> ();
535  Ptr<LteDataRadioBearerInfo> ueDrbInfo = ueBearerIt->second->GetObject<LteDataRadioBearerInfo> ();
536  //NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_epsBearer, ueDrbInfo->m_epsBearer, "epsBearer differs");
537  NS_TEST_ASSERT_MSG_EQ ((uint32_t) enbDrbInfo->m_epsBearerIdentity, (uint32_t) ueDrbInfo->m_epsBearerIdentity, "epsBearerIdentity differs");
538  NS_TEST_ASSERT_MSG_EQ ((uint32_t) enbDrbInfo->m_drbIdentity, (uint32_t) ueDrbInfo->m_drbIdentity, "drbIdentity differs");
539  //NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_rlcConfig, ueDrbInfo->m_rlcConfig, "rlcConfig differs");
540  NS_TEST_ASSERT_MSG_EQ ((uint32_t) enbDrbInfo->m_logicalChannelIdentity, (uint32_t) ueDrbInfo->m_logicalChannelIdentity, "logicalChannelIdentity differs");
541  //NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_logicalChannelConfig, ueDrbInfo->m_logicalChannelConfig, "logicalChannelConfig differs");
542 
543  ++enbBearerIt;
544  ++ueBearerIt;
545  }
546  NS_ASSERT_MSG (enbBearerIt == enbDataRadioBearerMapValue.End (), "too many bearers at eNB");
547  NS_ASSERT_MSG (ueBearerIt == ueDataRadioBearerMapValue.End (), "too many bearers at UE");
548 }
549 
550 void
552 {
553  Ptr<MobilityModel> ueMobility = ueNode->GetObject<MobilityModel> ();
554  ueMobility->SetPosition (Vector (0.0, 0.0, 0.0));
555 }
556 
557 void
559 {
560  Ptr<MobilityModel> enbMobility = enbNode->GetObject<MobilityModel> ();
561  Vector pos = enbMobility->GetPosition ();
562 
563  Ptr<MobilityModel> ueMobility = ueNode->GetObject<MobilityModel> ();
564  ueMobility->SetPosition (pos + Vector (0.0, 100.0, 0.0));
565 }
566 
567 void
569 {
570  for (std::list<BearerData>::iterator it = m_ueDataVector.at (ueIndex).bearerDataList.begin ();
571  it != m_ueDataVector.at (ueIndex).bearerDataList.end ();
572  ++it)
573  {
574  it->dlOldTotalRx = it->dlSink->GetTotalRx ();
575  it->ulOldTotalRx = it->ulSink->GetTotalRx ();
576  }
577 }
578 
579 void
581 {
582  uint32_t b = 1;
583  for (std::list<BearerData>::iterator it = m_ueDataVector.at (ueIndex).bearerDataList.begin ();
584  it != m_ueDataVector.at (ueIndex).bearerDataList.end ();
585  ++it)
586  {
587  uint32_t dlRx = it->dlSink->GetTotalRx () - it->dlOldTotalRx;
588  uint32_t ulRx = it->ulSink->GetTotalRx () - it->ulOldTotalRx;
589  uint32_t expectedBytes = m_udpClientPktSize * (m_statsDuration.GetSeconds () / m_udpClientInterval.GetSeconds ());
590 
591  NS_TEST_ASSERT_MSG_EQ (dlRx, expectedBytes, "too few RX bytes in DL, ue=" << ueIndex << ", b=" << b);
592  NS_TEST_ASSERT_MSG_EQ (ulRx, expectedBytes, "too few RX bytes in UL, ue=" << ueIndex << ", b=" << b);
593  ++b;
594  }
595 }
596 
597 
614 {
615 public:
617 };
618 
619 
621  : TestSuite ("lte-x2-handover", SYSTEM)
622 {
623  // in the following:
624  // fwd means handover from enb 0 to enb 1
625  // bwd means handover from enb 1 to enb 0
626 
627  HandoverEvent ue1fwd;
628  ue1fwd.startTime = MilliSeconds (100);
629  ue1fwd.ueDeviceIndex = 0;
630  ue1fwd.sourceEnbDeviceIndex = 0;
631  ue1fwd.targetEnbDeviceIndex = 1;
632 
633  HandoverEvent ue1bwd;
634  ue1bwd.startTime = MilliSeconds (400);
635  ue1bwd.ueDeviceIndex = 0;
636  ue1bwd.sourceEnbDeviceIndex = 1;
637  ue1bwd.targetEnbDeviceIndex = 0;
638 
639  HandoverEvent ue1fwdagain;
640  ue1fwdagain.startTime = MilliSeconds (700);
641  ue1fwdagain.ueDeviceIndex = 0;
642  ue1fwdagain.sourceEnbDeviceIndex = 0;
643  ue1fwdagain.targetEnbDeviceIndex = 1;
644 
645  HandoverEvent ue2fwd;
646  ue2fwd.startTime = MilliSeconds (110);
647  ue2fwd.ueDeviceIndex = 1;
648  ue2fwd.sourceEnbDeviceIndex = 0;
649  ue2fwd.targetEnbDeviceIndex = 1;
650 
651  HandoverEvent ue2bwd;
652  ue2bwd.startTime = MilliSeconds (350);
653  ue2bwd.ueDeviceIndex = 1;
654  ue2bwd.sourceEnbDeviceIndex = 1;
655  ue2bwd.targetEnbDeviceIndex = 0;
656 
657  std::string hel0name ("none");
658  std::list<HandoverEvent> hel0;
659 
660  std::string hel1name ("1 fwd");
661  std::list<HandoverEvent> hel1;
662  hel1.push_back (ue1fwd);
663 
664  std::string hel2name ("1 fwd & bwd");
665  std::list<HandoverEvent> hel2;
666  hel2.push_back (ue1fwd);
667  hel2.push_back (ue1bwd);
668 
669  std::string hel3name ("1 fwd & bwd & fwd");
670  std::list<HandoverEvent> hel3;
671  hel3.push_back (ue1fwd);
672  hel3.push_back (ue1bwd);
673  hel3.push_back (ue1fwdagain);
674 
675  std::string hel4name ("1+2 fwd");
676  std::list<HandoverEvent> hel4;
677  hel4.push_back (ue1fwd);
678  hel4.push_back (ue2fwd);
679 
680  std::string hel5name ("1+2 fwd & bwd");
681  std::list<HandoverEvent> hel5;
682  hel5.push_back (ue1fwd);
683  hel5.push_back (ue1bwd);
684  hel5.push_back (ue2fwd);
685  hel5.push_back (ue2bwd);
686 
687  std::string hel6name ("2 fwd");
688  std::list<HandoverEvent> hel6;
689  hel6.push_back (ue2fwd);
690 
691  std::string hel7name ("2 fwd & bwd");
692  std::list<HandoverEvent> hel7;
693  hel7.push_back (ue2fwd);
694  hel7.push_back (ue2bwd);
695 
696  std::vector<std::string> schedulers;
697  schedulers.push_back ("ns3::RrFfMacScheduler");
698  schedulers.push_back ("ns3::PfFfMacScheduler");
699  for (std::vector<std::string>::iterator schedIt = schedulers.begin (); schedIt != schedulers.end (); ++schedIt)
700  {
701  for (int32_t useIdealRrc = 1; useIdealRrc >= 0; --useIdealRrc)
702  {
703  // nUes, nDBearers, helist, name, sched, admitHo, idealRrc
704  AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel0, hel0name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
705  AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel0, hel0name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
706  AddTestCase (new LteX2HandoverTestCase ( 1, 5, hel0, hel0name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
707  AddTestCase (new LteX2HandoverTestCase ( 2, 5, hel0, hel0name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
708  AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel1, hel1name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
709  AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel1, hel1name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
710  AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel1, hel1name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
711  AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel1, hel1name, *schedIt, false, useIdealRrc), TestCase::EXTENSIVE);
712  AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel1, hel1name, *schedIt, false, useIdealRrc), TestCase::EXTENSIVE);
713  AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel1, hel1name, *schedIt, false, useIdealRrc), TestCase::EXTENSIVE);
714  AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel1, hel1name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
715  AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel1, hel1name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
716  AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel1, hel1name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
717  AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel1, hel1name, *schedIt, false, useIdealRrc), TestCase::EXTENSIVE);
718  AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel1, hel1name, *schedIt, false, useIdealRrc), TestCase::EXTENSIVE);
719  AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel1, hel1name, *schedIt, false, useIdealRrc), TestCase::EXTENSIVE);
720  AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel2, hel2name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
721  AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel2, hel2name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
722  AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel2, hel2name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
723  AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel3, hel3name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
724  AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel3, hel3name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
725  AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel3, hel3name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
726  AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel3, hel3name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
727  AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel3, hel3name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
728  AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel3, hel3name, *schedIt, true, useIdealRrc), TestCase::QUICK);
729  AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel4, hel4name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
730  AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel4, hel4name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
731  AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel4, hel4name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
732  AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel5, hel5name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
733  AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel5, hel5name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
734  AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel5, hel5name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
735  AddTestCase (new LteX2HandoverTestCase ( 3, 0, hel3, hel3name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
736  AddTestCase (new LteX2HandoverTestCase ( 3, 1, hel3, hel3name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
737  AddTestCase (new LteX2HandoverTestCase ( 3, 2, hel3, hel3name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
738  AddTestCase (new LteX2HandoverTestCase ( 3, 0, hel4, hel4name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
739  AddTestCase (new LteX2HandoverTestCase ( 3, 1, hel4, hel4name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
740  AddTestCase (new LteX2HandoverTestCase ( 3, 2, hel4, hel4name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
741  AddTestCase (new LteX2HandoverTestCase ( 3, 0, hel5, hel5name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
742  AddTestCase (new LteX2HandoverTestCase ( 3, 1, hel5, hel5name, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
743  AddTestCase (new LteX2HandoverTestCase ( 3, 2, hel5, hel5name, *schedIt, true, useIdealRrc), TestCase::QUICK);
744 
745  }
746  }
747 }
748 
holds a vector of ns3::Application pointers.
uint8_t Add(PacketFilter f)
add a PacketFilter to the Traffic Flow Template
Definition: epc-tft.cc:240
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:103
an Inet address class
static std::string BuildNameString(uint32_t nUes, uint32_t nDedicatedBearers, std::string handoverEventListName, std::string schedulerType, bool admitHo, bool useIdealRrc)
Build name string.
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:86
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.
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.
LteX2HandoverTestCase(uint32_t nUes, uint32_t nDedicatedBearers, std::list< HandoverEvent > handoverEventList, std::string handoverEventListName, std::string schedulerType, bool admitHo, bool useIdealRrc)
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:1246
NetDeviceContainer Install(NodeContainer c)
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:269
A suite of tests to run.
Definition: test.h:1343
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:379
serverApps
Definition: first.py:52
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:961
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1286
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:140
State GetState() const
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:1153
int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used.
Definition: lte-helper.cc:1444
void ActivateDataRadioBearer(NetDeviceContainer ueDevices, EpsBearer bearer)
Activate a Data Radio Bearer on a given UE devices (for LTE-only simulation).
Definition: lte-helper.cc:1314
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:1069
uint32_t targetEnbDeviceIndex
target ENB device index
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)
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:108
Class for representing data rates.
Definition: data-rate.h:88
Keep track of the current position and velocity of an object.
uint64_t GetImsi() const
Get the IMSI.
virtual Ipv4InterfaceContainer AssignUeIpv4Address(NetDeviceContainer ueDevices)
Assign IPv4 addresses to UE devices.
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:1342
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:166
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
Time stopTime
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:470
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:138
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:1221
This class contains the specification of EPS Bearers.
Definition: eps-bearer.h:91
Ptr< PointToPointEpcHelper > m_epcHelper
EPC helper.
void SetPosition(const Vector &position)
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:820
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
#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:88
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
Vector GetPosition(void) const
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:41
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:622
uint8_t m_drbIdentity
DRB identity.
Helper class that adds ns3::Ipv4StaticRouting objects.
AttributeValue implementation for DataRate.
Definition: data-rate.h:229
virtual Ptr< Node > GetPgwNode() const
Get the PGW node.
std::vector< Ptr< NetDevice > >::const_iterator Iterator
NetDevice container iterator.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1278
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:849
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.
void TeleportUeNearTargetEnb(Ptr< Node > ueNode, Ptr< Node > enbNode)
Teleport UE near the target eNB of the handover.
uint32_t ulOldTotalRx
UL old total receive.
clientApps
Definition: first.py:61
bool m_epc
whether to use EPC
HandoverEvent structure.
Qci
QoS Class Indicator.
Definition: eps-bearer.h:106
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.
Container for a set of ns3::Object pointers.
Receive and consume traffic generated to an IP address and port.
Definition: packet-sink.h:71
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
Ptr< Application > Get(uint32_t i) const
Get the Ptr<Application> stored in this container at a given index.
virtual Ipv4Address GetUeDefaultGatewayAddress()
uint16_t remotePortStart
start of the port number range of the remote host
Definition: epc-tft.h:137
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.
void TeleportUeToMiddle(Ptr< Node > ueNode)
Teleport UE between both eNBs of the test.
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:139
uint8_t m_epsBearerIdentity
EPS bearer identity.
The LteUeNetDevice class implements the UE net device.