A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
test-lte-x2-handover.cc
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 NS_LOG_COMPONENT_DEFINE ("LteX2HandoverTest");
31 
32 namespace ns3 {
33 
35 {
36  Time startTime;
37  uint32_t ueDeviceIndex;
38  uint32_t sourceEnbDeviceIndex;
39  uint32_t targetEnbDeviceIndex;
40 };
41 
42 
44 {
45 public:
46 
58  LteX2HandoverTestCase (uint32_t nUes, uint32_t nDedicatedBearers, std::list<HandoverEvent> handoverEventList, std::string handoverEventListName, bool useUdp, std::string schedulerType, bool admitHo, bool useIdealRrc);
59 
60 private:
61  static std::string BuildNameString (uint32_t nUes, uint32_t nDedicatedBearers, std::string handoverEventListName, bool useUdp, std::string schedulerType, bool admitHo, bool useIdealRrc);
62  virtual void DoRun (void);
63  void CheckConnected (Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice);
64 
65  uint32_t m_nUes; // number of UEs in the test
66  uint32_t m_nDedicatedBearers; // number of UEs in the test
67  std::list<HandoverEvent> m_handoverEventList;
68  std::string m_handoverEventListName;
69  bool m_epc;
70  bool m_useUdp;
71  std::string m_schedulerType;
72  bool m_admitHo;
73  bool m_useIdealRrc;
74  Ptr<LteHelper> m_lteHelper;
75  Ptr<EpcHelper> m_epcHelper;
76 
77  struct BearerData
78  {
79  uint32_t bid;
80  Ptr<PacketSink> dlSink;
81  Ptr<PacketSink> ulSink;
82  uint32_t dlOldTotalRx;
83  uint32_t ulOldTotalRx;
84  };
85 
86  struct UeData
87  {
88  uint32_t id;
89  std::list<BearerData> bearerDataList;
90  };
91 
92  void SaveStatsAfterHandover (uint32_t ueIndex);
93  void CheckStatsAWhileAfterHandover (uint32_t ueIndex);
94 
95  std::vector<UeData> m_ueDataVector;
96 
97  const Time m_maxHoDuration;
98  const Time m_statsDuration;
99 
100 };
101 
102 
103 std::string LteX2HandoverTestCase::BuildNameString (uint32_t nUes, uint32_t nDedicatedBearers, std::string handoverEventListName, bool useUdp, std::string schedulerType, bool admitHo, bool useIdealRrc)
104 {
105  std::ostringstream oss;
106  oss << " nUes=" << nUes
107  << " nDedicatedBearers=" << nDedicatedBearers
108  << " udp=" << useUdp
109  << " " << schedulerType
110  << " admitHo=" << admitHo
111  << " hoList: " << handoverEventListName;
112  if (useIdealRrc)
113  {
114  oss << ", ideal RRC";
115  }
116  else
117  {
118  oss << ", real RRC";
119  }
120  return oss.str ();
121 }
122 
123 LteX2HandoverTestCase::LteX2HandoverTestCase (uint32_t nUes, uint32_t nDedicatedBearers, std::list<HandoverEvent> handoverEventList, std::string handoverEventListName, bool useUdp, std::string schedulerType, bool admitHo, bool useIdealRrc)
124  : TestCase (BuildNameString (nUes, nDedicatedBearers, handoverEventListName, useUdp, schedulerType, admitHo, useIdealRrc)),
125  m_nUes (nUes),
126  m_nDedicatedBearers (nDedicatedBearers),
127  m_handoverEventList (handoverEventList),
128  m_handoverEventListName (handoverEventListName),
129  m_epc (true),
130  m_useUdp (useUdp),
131  m_schedulerType (schedulerType),
132  m_admitHo (admitHo),
133  m_useIdealRrc (useIdealRrc),
134  m_maxHoDuration (Seconds (0.1)),
135  m_statsDuration (Seconds (0.5))
136 {
137 }
138 
139 void
141 {
142  NS_LOG_FUNCTION (this << BuildNameString (m_nUes, m_nDedicatedBearers, m_handoverEventListName, m_useUdp, m_schedulerType, m_admitHo, m_useIdealRrc));
143 
144  Config::Reset ();
145  Config::SetDefault ("ns3::UdpClient::Interval", TimeValue (MilliSeconds(100)));
146  Config::SetDefault ("ns3::UdpClient::MaxPackets", UintegerValue(1000000));
147  Config::SetDefault ("ns3::UdpClient::PacketSize", UintegerValue(100));
148 
149  int64_t stream = 1;
150 
151  m_lteHelper = CreateObject<LteHelper> ();
152  m_lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel"));
153  m_lteHelper->SetSchedulerType (m_schedulerType);
154  m_lteHelper->SetAttribute ("UseIdealRrc", BooleanValue (m_useIdealRrc));
155 
156 
157  NodeContainer enbNodes;
158  enbNodes.Create (2);
159  NodeContainer ueNodes;
160  ueNodes.Create (m_nUes);
161 
162  if (m_epc)
163  {
164  m_epcHelper = CreateObject<EpcHelper> ();
165  m_lteHelper->SetEpcHelper (m_epcHelper);
166  }
167 
168  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
169  positionAlloc->Add (Vector (-3000, 0, 0)); // enb0
170  positionAlloc->Add (Vector ( 3000, 0, 0)); // enb1
171  for (uint16_t i = 0; i < m_nUes; i++)
172  {
173  positionAlloc->Add (Vector (0, 0, 0));
174  }
175  MobilityHelper mobility;
176  mobility.SetPositionAllocator (positionAlloc);
177  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
178  mobility.Install (enbNodes);
179  mobility.Install (ueNodes);
180 
181  NetDeviceContainer enbDevices;
182  enbDevices = m_lteHelper->InstallEnbDevice (enbNodes);
183  stream += m_lteHelper->AssignStreams (enbDevices, stream);
184  for (NetDeviceContainer::Iterator it = enbDevices.Begin ();
185  it != enbDevices.End ();
186  ++it)
187  {
188  Ptr<LteEnbRrc> enbRrc = (*it)->GetObject<LteEnbNetDevice> ()->GetRrc ();
189  enbRrc->SetAttribute ("AdmitHandoverRequest", BooleanValue (m_admitHo));
190  }
191 
192  NetDeviceContainer ueDevices;
193  ueDevices = m_lteHelper->InstallUeDevice (ueNodes);
194  stream += m_lteHelper->AssignStreams (ueDevices, stream);
195 
196  Ipv4Address remoteHostAddr;
197  Ipv4StaticRoutingHelper ipv4RoutingHelper;
198  Ipv4InterfaceContainer ueIpIfaces;
199  Ptr<Node> remoteHost;
200  if (m_epc)
201  {
202  // Create a single RemoteHost
203  NodeContainer remoteHostContainer;
204  remoteHostContainer.Create (1);
205  remoteHost = remoteHostContainer.Get (0);
206  InternetStackHelper internet;
207  internet.Install (remoteHostContainer);
208 
209  // Create the Internet
210  PointToPointHelper p2ph;
211  p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s")));
212  p2ph.SetDeviceAttribute ("Mtu", UintegerValue (1500));
213  p2ph.SetChannelAttribute ("Delay", TimeValue (Seconds (0.010)));
214  Ptr<Node> pgw = m_epcHelper->GetPgwNode ();
215  NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost);
216  Ipv4AddressHelper ipv4h;
217  ipv4h.SetBase ("1.0.0.0", "255.0.0.0");
218  Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices);
219  // in this container, interface 0 is the pgw, 1 is the remoteHost
220  remoteHostAddr = internetIpIfaces.GetAddress (1);
221 
222  Ipv4StaticRoutingHelper ipv4RoutingHelper;
223  Ptr<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());
224  remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.0.0.0"), 1);
225 
226  // Install the IP stack on the UEs
227  internet.Install (ueNodes);
228  ueIpIfaces = m_epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueDevices));
229  }
230 
231  // attachment (needs to be done after IP stack configuration)
232  // all UEs attached to eNB 0 at the beginning
233  m_lteHelper->Attach (ueDevices, enbDevices.Get (0));
234 
235  if (m_epc)
236  {
237  bool epcDl = true;
238  bool epcUl = true;
239  // the rest of this block is copied from lena-dual-stripe
240 
241 
242  // Install and start applications on UEs and remote host
243  uint16_t dlPort = 10000;
244  uint16_t ulPort = 20000;
245 
246  // randomize a bit start times to avoid simulation artifacts
247  // (e.g., buffer overflows due to packet transmissions happening
248  // exactly at the same time)
249  Ptr<UniformRandomVariable> startTimeSeconds = CreateObject<UniformRandomVariable> ();
250  startTimeSeconds->SetAttribute ("Min", DoubleValue (0));
251  startTimeSeconds->SetAttribute ("Max", DoubleValue (0.010));
252  startTimeSeconds->SetStream (stream++);
253 
254  for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
255  {
256  Ptr<Node> ue = ueNodes.Get (u);
257  // Set the default gateway for the UE
258  Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ue->GetObject<Ipv4> ());
259  ueStaticRouting->SetDefaultRoute (m_epcHelper->GetUeDefaultGatewayAddress (), 1);
260 
261  UeData ueData;
262 
263  for (uint32_t b = 0; b < m_nDedicatedBearers; ++b)
264  {
265  ++dlPort;
266  ++ulPort;
267 
268  ApplicationContainer clientApps;
269  ApplicationContainer serverApps;
270  BearerData bearerData;
271 
272  if (m_useUdp)
273  {
274  if (epcDl)
275  {
276  UdpClientHelper dlClientHelper (ueIpIfaces.GetAddress (u), dlPort);
277  clientApps.Add (dlClientHelper.Install (remoteHost));
278  PacketSinkHelper dlPacketSinkHelper ("ns3::UdpSocketFactory",
280  ApplicationContainer sinkContainer = dlPacketSinkHelper.Install (ue);
281  bearerData.dlSink = sinkContainer.Get (0)->GetObject<PacketSink> ();
282  serverApps.Add (sinkContainer);
283 
284  }
285  if (epcUl)
286  {
287  UdpClientHelper ulClientHelper (remoteHostAddr, ulPort);
288  clientApps.Add (ulClientHelper.Install (ue));
289  PacketSinkHelper ulPacketSinkHelper ("ns3::UdpSocketFactory",
291  ApplicationContainer sinkContainer = ulPacketSinkHelper.Install (remoteHost);
292  bearerData.ulSink = sinkContainer.Get (0)->GetObject<PacketSink> ();
293  serverApps.Add (sinkContainer);
294  }
295  }
296  else // use TCP
297  {
298  if (epcDl)
299  {
300  BulkSendHelper dlClientHelper ("ns3::TcpSocketFactory",
301  InetSocketAddress (ueIpIfaces.GetAddress (u), dlPort));
302  dlClientHelper.SetAttribute ("MaxBytes", UintegerValue (0));
303  clientApps.Add (dlClientHelper.Install (remoteHost));
304  PacketSinkHelper dlPacketSinkHelper ("ns3::TcpSocketFactory",
306  ApplicationContainer sinkContainer = dlPacketSinkHelper.Install (ue);
307  bearerData.dlSink = sinkContainer.Get (0)->GetObject<PacketSink> ();
308  serverApps.Add (sinkContainer);
309  }
310  if (epcUl)
311  {
312  BulkSendHelper ulClientHelper ("ns3::TcpSocketFactory",
313  InetSocketAddress (remoteHostAddr, ulPort));
314  ulClientHelper.SetAttribute ("MaxBytes", UintegerValue (0));
315  clientApps.Add (ulClientHelper.Install (ue));
316  PacketSinkHelper ulPacketSinkHelper ("ns3::TcpSocketFactory",
318  ApplicationContainer sinkContainer = ulPacketSinkHelper.Install (remoteHost);
319  bearerData.ulSink = sinkContainer.Get (0)->GetObject<PacketSink> ();
320  serverApps.Add (sinkContainer);
321  }
322  } // end if (useUdp)
323 
324  Ptr<EpcTft> tft = Create<EpcTft> ();
325  if (epcDl)
326  {
328  dlpf.localPortStart = dlPort;
329  dlpf.localPortEnd = dlPort;
330  tft->Add (dlpf);
331  }
332  if (epcUl)
333  {
335  ulpf.remotePortStart = ulPort;
336  ulpf.remotePortEnd = ulPort;
337  tft->Add (ulpf);
338  }
339 
340  if (epcDl || epcUl)
341  {
342  EpsBearer bearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT);
343  m_lteHelper->ActivateDedicatedEpsBearer (ueDevices.Get (u), bearer, tft);
344  }
345  Time startTime = Seconds (startTimeSeconds->GetValue ());
346  serverApps.Start (startTime);
347  clientApps.Start (startTime);
348 
349  ueData.bearerDataList.push_back (bearerData);
350 
351  } // end for b
352 
353  m_ueDataVector.push_back (ueData);
354  }
355 
356  }
357  else // (epc == false)
358  {
359  // for radio bearer activation purposes, consider together home UEs and macro UEs
360  for (uint32_t u = 0; u < ueDevices.GetN (); ++u)
361  {
362  Ptr<NetDevice> ueDev = ueDevices.Get (u);
363  for (uint32_t b = 0; b < m_nDedicatedBearers; ++b)
364  {
365  enum EpsBearer::Qci q = EpsBearer::NGBR_VIDEO_TCP_DEFAULT;
366  EpsBearer bearer (q);
367  m_lteHelper->ActivateDataRadioBearer (ueDev, bearer);
368  }
369  }
370  }
371 
372 
373  m_lteHelper->AddX2Interface (enbNodes);
374 
375  // check initial RRC connection
376  const Time maxRrcConnectionEstablishmentDuration = Seconds (0.080);
377  for (NetDeviceContainer::Iterator it = ueDevices.Begin (); it != ueDevices.End (); ++it)
378  {
379  Simulator::Schedule (maxRrcConnectionEstablishmentDuration,
380  &LteX2HandoverTestCase::CheckConnected,
381  this, *it, enbDevices.Get (0));
382  }
383 
384  // schedule handover events and corresponding checks
385 
386  Time stopTime = Seconds (0);
387  for (std::list<HandoverEvent>::iterator hoEventIt = m_handoverEventList.begin ();
388  hoEventIt != m_handoverEventList.end ();
389  ++hoEventIt)
390  {
391  Simulator::Schedule (hoEventIt->startTime,
392  &LteX2HandoverTestCase::CheckConnected,
393  this,
394  ueDevices.Get (hoEventIt->ueDeviceIndex),
395  enbDevices.Get (hoEventIt->sourceEnbDeviceIndex));
396  m_lteHelper->HandoverRequest (hoEventIt->startTime,
397  ueDevices.Get (hoEventIt->ueDeviceIndex),
398  enbDevices.Get (hoEventIt->sourceEnbDeviceIndex),
399  enbDevices.Get (hoEventIt->targetEnbDeviceIndex));
400  Time hoEndTime = hoEventIt->startTime + m_maxHoDuration;
401  Simulator::Schedule (hoEndTime,
402  &LteX2HandoverTestCase::CheckConnected,
403  this,
404  ueDevices.Get (hoEventIt->ueDeviceIndex),
405  enbDevices.Get (m_admitHo ? hoEventIt->targetEnbDeviceIndex : hoEventIt->sourceEnbDeviceIndex));
406  Simulator::Schedule (hoEndTime, &LteX2HandoverTestCase::SaveStatsAfterHandover,
407  this, hoEventIt->ueDeviceIndex);
408  Time checkStatsAfterHoTime = hoEndTime + m_statsDuration;
409  Simulator::Schedule (checkStatsAfterHoTime, &LteX2HandoverTestCase::CheckStatsAWhileAfterHandover,
410  this, hoEventIt->ueDeviceIndex);
411  if (stopTime <= hoEndTime)
412  {
413  stopTime = hoEndTime + MilliSeconds (1);
414  }
415  }
416 
417  m_lteHelper->EnableRlcTraces ();
418  Ptr<RadioBearerStatsCalculator> rlcStats = m_lteHelper->GetRlcStats ();
419  rlcStats->SetAttribute ("StartTime", TimeValue (Seconds (0.101)));
420  rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (0.1)));
421  m_lteHelper->EnablePdcpTraces();
422 
423 
424  Simulator::Stop (stopTime);
425 
426  Simulator::Run ();
427 
429 
430 }
431 
432 void
433 LteX2HandoverTestCase::CheckConnected (Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice)
434 {
435  Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice> ();
436  Ptr<LteUeRrc> ueRrc = ueLteDevice->GetRrc ();
437  NS_TEST_ASSERT_MSG_EQ (ueRrc->GetState (), LteUeRrc::CONNECTED_NORMALLY, "Wrong LteUeRrc state!");
438 
439 
440  Ptr<LteEnbNetDevice> enbLteDevice = enbDevice->GetObject<LteEnbNetDevice> ();
441  Ptr<LteEnbRrc> enbRrc = enbLteDevice->GetRrc ();
442  uint16_t rnti = ueRrc->GetRnti ();
443  Ptr<UeManager> ueManager = enbRrc->GetUeManager (rnti);
444  NS_TEST_ASSERT_MSG_NE (ueManager, 0, "RNTI " << rnti << " not found in eNB");
445 
446  UeManager::State ueManagerState = ueManager->GetState ();
447  NS_TEST_ASSERT_MSG_EQ (ueManagerState, UeManager::CONNECTED_NORMALLY, "Wrong UeManager state!");
448  NS_ASSERT_MSG (ueManagerState == UeManager::CONNECTED_NORMALLY, "Wrong UeManager state!");
449 
450  uint16_t ueCellId = ueRrc->GetCellId ();
451  uint16_t enbCellId = enbLteDevice->GetCellId ();
452  uint8_t ueDlBandwidth = ueRrc->GetDlBandwidth ();
453  uint8_t enbDlBandwidth = enbLteDevice->GetDlBandwidth ();
454  uint8_t ueUlBandwidth = ueRrc->GetUlBandwidth ();
455  uint8_t enbUlBandwidth = enbLteDevice->GetUlBandwidth ();
456  uint8_t ueDlEarfcn = ueRrc->GetDlEarfcn ();
457  uint8_t enbDlEarfcn = enbLteDevice->GetDlEarfcn ();
458  uint8_t ueUlEarfcn = ueRrc->GetUlEarfcn ();
459  uint8_t enbUlEarfcn = enbLteDevice->GetUlEarfcn ();
460  uint64_t ueImsi = ueLteDevice->GetImsi ();
461  uint64_t enbImsi = ueManager->GetImsi ();
462 
463  NS_TEST_ASSERT_MSG_EQ (ueImsi, enbImsi, "inconsistent IMSI");
464  NS_TEST_ASSERT_MSG_EQ (ueCellId, enbCellId, "inconsistent CellId");
465  NS_TEST_ASSERT_MSG_EQ (ueDlBandwidth, enbDlBandwidth, "inconsistent DlBandwidth");
466  NS_TEST_ASSERT_MSG_EQ (ueUlBandwidth, enbUlBandwidth, "inconsistent UlBandwidth");
467  NS_TEST_ASSERT_MSG_EQ (ueDlEarfcn, enbDlEarfcn, "inconsistent DlEarfcn");
468  NS_TEST_ASSERT_MSG_EQ (ueUlEarfcn, enbUlEarfcn, "inconsistent UlEarfcn");
469 
470  ObjectMapValue enbDataRadioBearerMapValue;
471  ueManager->GetAttribute ("DataRadioBearerMap", enbDataRadioBearerMapValue);
472  NS_TEST_ASSERT_MSG_EQ (enbDataRadioBearerMapValue.GetN (), m_nDedicatedBearers + 1, "wrong num bearers at eNB");
473 
474  ObjectMapValue ueDataRadioBearerMapValue;
475  ueRrc->GetAttribute ("DataRadioBearerMap", ueDataRadioBearerMapValue);
476  NS_TEST_ASSERT_MSG_EQ (ueDataRadioBearerMapValue.GetN (), m_nDedicatedBearers + 1, "wrong num bearers at UE");
477 
478  ObjectMapValue::Iterator enbBearerIt = enbDataRadioBearerMapValue.Begin ();
479  ObjectMapValue::Iterator ueBearerIt = ueDataRadioBearerMapValue.Begin ();
480  while (enbBearerIt != enbDataRadioBearerMapValue.End () &&
481  ueBearerIt != ueDataRadioBearerMapValue.End ())
482  {
483  Ptr<LteDataRadioBearerInfo> enbDrbInfo = enbBearerIt->second->GetObject<LteDataRadioBearerInfo> ();
484  Ptr<LteDataRadioBearerInfo> ueDrbInfo = ueBearerIt->second->GetObject<LteDataRadioBearerInfo> ();
485  //NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_epsBearer, ueDrbInfo->m_epsBearer, "epsBearer differs");
486  NS_TEST_ASSERT_MSG_EQ ((uint32_t) enbDrbInfo->m_epsBearerIdentity, (uint32_t) ueDrbInfo->m_epsBearerIdentity, "epsBearerIdentity differs");
487  NS_TEST_ASSERT_MSG_EQ ((uint32_t) enbDrbInfo->m_drbIdentity, (uint32_t) ueDrbInfo->m_drbIdentity, "drbIdentity differs");
488  //NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_rlcConfig, ueDrbInfo->m_rlcConfig, "rlcConfig differs");
489  NS_TEST_ASSERT_MSG_EQ ((uint32_t) enbDrbInfo->m_logicalChannelIdentity, (uint32_t) ueDrbInfo->m_logicalChannelIdentity, "logicalChannelIdentity differs");
490  //NS_TEST_ASSERT_MSG_EQ (enbDrbInfo->m_logicalChannelConfig, ueDrbInfo->m_logicalChannelConfig, "logicalChannelConfig differs");
491 
492  ++enbBearerIt;
493  ++ueBearerIt;
494  }
495  NS_ASSERT_MSG (enbBearerIt == enbDataRadioBearerMapValue.End (), "too many bearers at eNB");
496  NS_ASSERT_MSG (ueBearerIt == ueDataRadioBearerMapValue.End (), "too many bearers at UE");
497 }
498 
499 void
500 LteX2HandoverTestCase::SaveStatsAfterHandover (uint32_t ueIndex)
501 {
502  for (std::list<BearerData>::iterator it = m_ueDataVector.at (ueIndex).bearerDataList.begin ();
503  it != m_ueDataVector.at (ueIndex).bearerDataList.end ();
504  ++it)
505  {
506  it->dlOldTotalRx = it->dlSink->GetTotalRx ();
507  it->ulOldTotalRx = it->ulSink->GetTotalRx ();
508  }
509 }
510 
511 void
512 LteX2HandoverTestCase::CheckStatsAWhileAfterHandover (uint32_t ueIndex)
513 {
514  uint32_t b = 1;
515  for (std::list<BearerData>::iterator it = m_ueDataVector.at (ueIndex).bearerDataList.begin ();
516  it != m_ueDataVector.at (ueIndex).bearerDataList.end ();
517  ++it)
518  {
519  uint32_t dlRx = it->dlSink->GetTotalRx () - it->dlOldTotalRx;
520  uint32_t ulRx = it->ulSink->GetTotalRx () - it->ulOldTotalRx;
521  // udpclient pktsize interval
522  uint32_t expectedBytes = 100.0 * (0.100 / m_statsDuration.GetSeconds ());
523  // tolerance
524  NS_TEST_ASSERT_MSG_GT (dlRx, 0.500 * expectedBytes, "too few RX bytes in DL, ue=" << ueIndex << ", b=" << b);
525  NS_TEST_ASSERT_MSG_GT (ulRx, 0.500 * expectedBytes, "too few RX bytes in UL, ue=" << ueIndex << ", b=" << b);
526  ++b;
527  }
528 }
529 
530 
532 {
533 public:
535 };
536 
537 
538 LteX2HandoverTestSuite::LteX2HandoverTestSuite ()
539  : TestSuite ("lte-x2-handover", SYSTEM)
540 {
541  // in the following:
542  // fwd means handover from enb 0 to enb 1
543  // bwd means handover from enb 1 to enb 0
544 
545  HandoverEvent ue1fwd;
546  ue1fwd.startTime = MilliSeconds (100);
547  ue1fwd.ueDeviceIndex = 0;
548  ue1fwd.sourceEnbDeviceIndex = 0;
549  ue1fwd.targetEnbDeviceIndex = 1;
550 
551  HandoverEvent ue1bwd;
552  ue1bwd.startTime = MilliSeconds (300);
553  ue1bwd.ueDeviceIndex = 0;
554  ue1bwd.sourceEnbDeviceIndex = 1;
555  ue1bwd.targetEnbDeviceIndex = 0;
556 
557  HandoverEvent ue1fwdagain;
558  ue1fwdagain.startTime = MilliSeconds (500);
559  ue1fwdagain.ueDeviceIndex = 0;
560  ue1fwdagain.sourceEnbDeviceIndex = 0;
561  ue1fwdagain.targetEnbDeviceIndex = 1;
562 
563  HandoverEvent ue2fwd;
564  ue2fwd.startTime = MilliSeconds (110);
565  ue2fwd.ueDeviceIndex = 1;
566  ue2fwd.sourceEnbDeviceIndex = 0;
567  ue2fwd.targetEnbDeviceIndex = 1;
568 
569  HandoverEvent ue2bwd;
570  ue2bwd.startTime = MilliSeconds (250);
571  ue2bwd.ueDeviceIndex = 1;
572  ue2bwd.sourceEnbDeviceIndex = 1;
573  ue2bwd.targetEnbDeviceIndex = 0;
574 
575  std::string hel0name ("none");
576  std::list<HandoverEvent> hel0;
577 
578  std::string hel1name ("1 fwd");
579  std::list<HandoverEvent> hel1;
580  hel1.push_back (ue1fwd);
581 
582  std::string hel2name ("1 fwd & bwd");
583  std::list<HandoverEvent> hel2;
584  hel2.push_back (ue1fwd);
585  hel2.push_back (ue1bwd);
586 
587  std::string hel3name ("1 fwd & bwd & fwd");
588  std::list<HandoverEvent> hel3;
589  hel3.push_back (ue1fwd);
590  hel3.push_back (ue1bwd);
591  hel3.push_back (ue1fwdagain);
592 
593  std::string hel4name ("1+2 fwd");
594  std::list<HandoverEvent> hel4;
595  hel4.push_back (ue1fwd);
596  hel4.push_back (ue2fwd);
597 
598  std::string hel5name ("1+2 fwd & bwd");
599  std::list<HandoverEvent> hel5;
600  hel5.push_back (ue1fwd);
601  hel5.push_back (ue1bwd);
602  hel5.push_back (ue2fwd);
603  hel5.push_back (ue2bwd);
604 
605  std::string hel6name ("2 fwd");
606  std::list<HandoverEvent> hel6;
607  hel6.push_back (ue2fwd);
608 
609  std::string hel7name ("2 fwd & bwd");
610  std::list<HandoverEvent> hel7;
611  hel7.push_back (ue2fwd);
612  hel7.push_back (ue2bwd);
613 
614  std::vector<std::string> schedulers;
615  schedulers.push_back ("ns3::RrFfMacScheduler");
616  schedulers.push_back ("ns3::PfFfMacScheduler");
617  for (std::vector<std::string>::iterator schedIt = schedulers.begin (); schedIt != schedulers.end (); ++schedIt)
618  {
619  for (int32_t useIdealRrc = 1; useIdealRrc >= 0; --useIdealRrc)
620  {
621  // nUes, nDBearers, helist, name, useUdp, sched, admitHo, idealRrc
622  AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel0, hel0name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
623  AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel0, hel0name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
624  AddTestCase (new LteX2HandoverTestCase ( 1, 5, hel0, hel0name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
625  AddTestCase (new LteX2HandoverTestCase ( 2, 5, hel0, hel0name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
626  AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel1, hel1name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
627  AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel1, hel1name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
628  AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel1, hel1name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
629  AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel1, hel1name, true, *schedIt, false, useIdealRrc), TestCase::EXTENSIVE);
630  AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel1, hel1name, true, *schedIt, false, useIdealRrc), TestCase::EXTENSIVE);
631  AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel1, hel1name, true, *schedIt, false, useIdealRrc), TestCase::EXTENSIVE);
632  AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel1, hel1name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
633  AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel1, hel1name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
634  AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel1, hel1name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
635  AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel1, hel1name, true, *schedIt, false, useIdealRrc), TestCase::EXTENSIVE);
636  AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel1, hel1name, true, *schedIt, false, useIdealRrc), TestCase::EXTENSIVE);
637  AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel1, hel1name, true, *schedIt, false, useIdealRrc), TestCase::EXTENSIVE);
638  AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel2, hel2name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
639  AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel2, hel2name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
640  AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel2, hel2name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
641  AddTestCase (new LteX2HandoverTestCase ( 1, 0, hel3, hel3name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
642  AddTestCase (new LteX2HandoverTestCase ( 1, 1, hel3, hel3name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
643  AddTestCase (new LteX2HandoverTestCase ( 1, 2, hel3, hel3name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
644  AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel3, hel3name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
645  AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel3, hel3name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
646  AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel3, hel3name, true, *schedIt, true, useIdealRrc), TestCase::QUICK);
647  AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel4, hel4name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
648  AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel4, hel4name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
649  AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel4, hel4name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
650  AddTestCase (new LteX2HandoverTestCase ( 2, 0, hel5, hel5name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
651  AddTestCase (new LteX2HandoverTestCase ( 2, 1, hel5, hel5name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
652  AddTestCase (new LteX2HandoverTestCase ( 2, 2, hel5, hel5name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
653  AddTestCase (new LteX2HandoverTestCase ( 3, 0, hel3, hel3name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
654  AddTestCase (new LteX2HandoverTestCase ( 3, 1, hel3, hel3name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
655  AddTestCase (new LteX2HandoverTestCase ( 3, 2, hel3, hel3name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
656  AddTestCase (new LteX2HandoverTestCase ( 3, 0, hel4, hel4name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
657  AddTestCase (new LteX2HandoverTestCase ( 3, 1, hel4, hel4name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
658  AddTestCase (new LteX2HandoverTestCase ( 3, 2, hel4, hel4name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
659  AddTestCase (new LteX2HandoverTestCase ( 3, 0, hel5, hel5name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
660  AddTestCase (new LteX2HandoverTestCase ( 3, 1, hel5, hel5name, true, *schedIt, true, useIdealRrc), TestCase::EXTENSIVE);
661  AddTestCase (new LteX2HandoverTestCase ( 3, 2, hel5, hel5name, true, *schedIt, true, useIdealRrc), TestCase::QUICK);
662 
663  }
664  }
665 }
666 
667 static LteX2HandoverTestSuite g_lteX2HandoverTestSuiteInstance;
668 
669 
670 
671 } // namespace ns3
holds a vector of ns3::Application pointers.
Iterator Begin(void) const
Get an iterator which refers to the first NetDevice in the container.
keep track of time unit.
Definition: nstime.h:149
an Inet address class
static Ipv4Address GetAny(void)
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
Hold a bool native type.
Definition: boolean.h:38
A helper to make it easier to instantiate an ns3::BulkSendApplication on a set of nodes...
holds a vector of std::pair of Ptr<Ipv4> and interface index.
void Reset(void)
Definition: config.cc:642
hold variables of type string
Definition: string.h:19
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
NetDeviceContainer Install(NodeContainer c)
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:210
void Add(ApplicationContainer other)
Append the contents of another ApplicationContainer to the end of this container. ...
A suite of tests to run.
Definition: test.h:962
static void Run(void)
Definition: simulator.cc:157
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
aggregate IP/TCP/UDP functionality to existing Nodes.
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:834
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
void SetDeviceAttribute(std::string name, const AttributeValue &value)
a 3d vector
Definition: vector.h:31
ApplicationContainer Install(NodeContainer c)
uint32_t GetN(void) const
Get the number of Ptr<Node> stored in this container.
uint32_t GetN(void) const
Get the number of Ptr<NetDevice> stored in this container.
Class for representing data rates.
Definition: data-rate.h:71
double GetSeconds(void) const
Definition: nstime.h:262
ApplicationContainer Install(NodeContainer c) const
void Install(Ptr< Node > node) const
"Layout" a single node according to the current position allocator type.
Create a client application which sends udp packets carrying a 32bit sequence number and a 64 bit tim...
hold objects of type ns3::Time
Definition: nstime.h:700
Hold an unsigned integer type.
Definition: uinteger.h:46
Fast test.
Definition: test.h:843
holds a vector of ns3::NetDevice pointers
void Start(Time start)
Arrange for all of the Applications in this container to Start() at the Time given as a parameter...
virtual void DoRun(void)
Implementation to actually run this test case.
static void Destroy(void)
Definition: simulator.cc:121
Access to the Ipv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:75
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:667
keep track of a set of node pointers.
Ptr< Application > Get(uint32_t i) const
Get the Ptr<Application> stored in this container at a given index.
void SetMobilityModel(std::string type, std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue(), std::string n8="", const AttributeValue &v8=EmptyAttributeValue(), std::string n9="", const AttributeValue &v9=EmptyAttributeValue())
double GetValue(double min, double max)
Returns a random double from the uniform distribution with the specified range.
void Install(std::string nodeName) const
void AddTestCase(TestCase *testCase) NS_DEPRECATED
Add an individual test case to this test suite.
Definition: test.cc:172
void SetChannelAttribute(std::string name, const AttributeValue &value)
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
Helper class used to assign positions and mobility models to nodes.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
Ptr< Ipv4StaticRouting > GetStaticRouting(Ptr< Ipv4 > ipv4) const
Helper class that adds ns3::Ipv4StaticRouting objects.
hold objects of type ns3::DataRate
static void Stop(void)
Definition: simulator.cc:164
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
LteX2HandoverTestCase(uint32_t nUes, uint32_t nDedicatedBearers, std::list< HandoverEvent > handoverEventList, std::string handoverEventListName, bool useUdp, std::string schedulerType, bool admitHo, bool useIdealRrc)
ApplicationContainer Install(NodeContainer c) const
Time MilliSeconds(uint64_t ms)
create ns3::Time instances in units of milliseconds.
Definition: nstime.h:601
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)
contain a set of ns3::Object pointers.
Receive and consume traffic generated to an IP address and port.
Definition: packet-sink.h:68
void SetPositionAllocator(Ptr< PositionAllocator > allocator)
Iterator End(void) const
Get an iterator which indicates past-the-last NetDevice in the container.
Hold an floating point type.
Definition: double.h:41
void SetAttribute(std::string name, const AttributeValue &value)
Definition: object-base.cc:160
Ptr< T > GetObject(void) const
Definition: object.h:332
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const