A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
lte-helper.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2011 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> (re-wrote from scratch this helper)
19  * Giuseppe Piro <g.piro@poliba.it> (parts of the PHY & channel creation & configuration copied from the GSoC 2011 code)
20  */
21 
22 
23 #include "lte-helper.h"
24 #include <ns3/string.h>
25 #include <ns3/log.h>
26 #include <ns3/abort.h>
27 #include <ns3/pointer.h>
28 #include <ns3/lte-enb-rrc.h>
29 #include <ns3/epc-ue-nas.h>
30 #include <ns3/epc-enb-application.h>
31 #include <ns3/lte-ue-rrc.h>
32 #include <ns3/lte-ue-mac.h>
33 #include <ns3/lte-enb-mac.h>
34 #include <ns3/lte-enb-net-device.h>
35 #include <ns3/lte-enb-phy.h>
36 #include <ns3/lte-ue-phy.h>
37 #include <ns3/lte-spectrum-phy.h>
38 #include <ns3/lte-sinr-chunk-processor.h>
39 #include <ns3/multi-model-spectrum-channel.h>
40 #include <ns3/friis-spectrum-propagation-loss.h>
41 #include <ns3/trace-fading-loss-model.h>
42 #include <ns3/isotropic-antenna-model.h>
43 #include <ns3/lte-enb-net-device.h>
44 #include <ns3/lte-ue-net-device.h>
45 #include <ns3/ff-mac-scheduler.h>
46 #include <ns3/lte-rlc.h>
47 #include <ns3/lte-rlc-um.h>
48 #include <ns3/lte-rlc-am.h>
49 #include <ns3/epc-enb-s1-sap.h>
50 #include <ns3/lte-rrc-protocol-ideal.h>
51 #include <ns3/lte-rrc-protocol-real.h>
52 #include <ns3/mac-stats-calculator.h>
53 #include <ns3/phy-stats-calculator.h>
54 #include <ns3/phy-tx-stats-calculator.h>
55 #include <ns3/phy-rx-stats-calculator.h>
56 #include <ns3/epc-helper.h>
57 #include <iostream>
58 #include <ns3/buildings-propagation-loss-model.h>
59 #include <ns3/lte-spectrum-value-helper.h>
60 #include <ns3/epc-x2.h>
61 
62 NS_LOG_COMPONENT_DEFINE ("LteHelper");
63 
64 namespace ns3 {
65 
66 NS_OBJECT_ENSURE_REGISTERED (LteHelper);
67 
69  : m_fadingStreamsAssigned (false),
70  m_imsiCounter (0),
71  m_cellIdCounter (0)
72 {
73  NS_LOG_FUNCTION (this);
78 }
79 
80 void
82 {
83  NS_LOG_FUNCTION (this);
86 
88  Ptr<SpectrumPropagationLossModel> dlSplm = m_downlinkPathlossModel->GetObject<SpectrumPropagationLossModel> ();
89  if (dlSplm != 0)
90  {
91  NS_LOG_LOGIC (this << " using a SpectrumPropagationLossModel in DL");
93  }
94  else
95  {
96  NS_LOG_LOGIC (this << " using a PropagationLossModel in DL");
97  Ptr<PropagationLossModel> dlPlm = m_downlinkPathlossModel->GetObject<PropagationLossModel> ();
98  NS_ASSERT_MSG (dlPlm != 0, " " << m_downlinkPathlossModel << " is neither PropagationLossModel nor SpectrumPropagationLossModel");
100  }
101 
104  if (ulSplm != 0)
105  {
106  NS_LOG_LOGIC (this << " using a SpectrumPropagationLossModel in UL");
107  m_uplinkChannel->AddSpectrumPropagationLossModel (ulSplm);
108  }
109  else
110  {
111  NS_LOG_LOGIC (this << " using a PropagationLossModel in UL");
113  NS_ASSERT_MSG (ulPlm != 0, " " << m_uplinkPathlossModel << " is neither PropagationLossModel nor SpectrumPropagationLossModel");
114  m_uplinkChannel->AddPropagationLossModel (ulPlm);
115  }
116  if (!m_fadingModelType.empty ())
117  {
122  }
123  m_phyStats = CreateObject<PhyStatsCalculator> ();
124  m_phyTxStats = CreateObject<PhyTxStatsCalculator> ();
125  m_phyRxStats = CreateObject<PhyRxStatsCalculator> ();
126  m_macStats = CreateObject<MacStatsCalculator> ();
128 
129 }
130 
132 {
133  NS_LOG_FUNCTION (this);
134 }
135 
137 {
138  static TypeId
139  tid =
140  TypeId ("ns3::LteHelper")
141  .SetParent<Object> ()
142  .AddConstructor<LteHelper> ()
143  .AddAttribute ("Scheduler",
144  "The type of scheduler to be used for eNBs. "
145  "The allowed values for this attributes are the type names "
146  "of any class inheriting from ns3::FfMacScheduler.",
147  StringValue ("ns3::PfFfMacScheduler"),
149  MakeStringChecker ())
150  .AddAttribute ("PathlossModel",
151  "The type of pathloss model to be used. "
152  "The allowed values for this attributes are the type names "
153  "of any class inheriting from ns3::PropagationLossModel.",
154  StringValue ("ns3::FriisPropagationLossModel"),
155  MakeStringAccessor (&LteHelper::SetPathlossModelType),
156  MakeStringChecker ())
157  .AddAttribute ("FadingModel",
158  "The type of fading model to be used."
159  "The allowed values for this attributes are the type names "
160  "of any class inheriting from ns3::SpectrumPropagationLossModel."
161  "If the type is set to an empty string, no fading model is used.",
162  StringValue (""),
163  MakeStringAccessor (&LteHelper::SetFadingModel),
164  MakeStringChecker ())
165  .AddAttribute ("UseIdealRrc",
166  "If true, LteRrcProtocolIdeal will be used for RRC signaling. "
167  "If false, LteRrcProtocolReal will be used.",
168  BooleanValue (true),
169  MakeBooleanAccessor (&LteHelper::m_useIdealRrc),
170  MakeBooleanChecker ())
171  ;
172  return tid;
173 }
174 
175 void
177 {
178  NS_LOG_FUNCTION (this);
179  m_downlinkChannel = 0;
180  m_uplinkChannel = 0;
182 }
183 
184 
185 void
187 {
188  NS_LOG_FUNCTION (this << h);
189  m_epcHelper = h;
190 }
191 
192 void
193 LteHelper::SetSchedulerType (std::string type)
194 {
195  NS_LOG_FUNCTION (this << type);
198 }
199 
200 std::string
202 {
203  return m_schedulerFactory.GetTypeId ().GetName ();
204 }
205 
206 void
208 {
209  NS_LOG_FUNCTION (this << n);
210  m_schedulerFactory.Set (n, v);
211 }
212 
213 
214 void
216 {
217  NS_LOG_FUNCTION (this << type);
222 }
223 
224 void
226 {
227  NS_LOG_FUNCTION (this << n);
230 }
231 
232 void
234 {
235  NS_LOG_FUNCTION (this);
236  m_enbNetDeviceFactory.Set (n, v);
237 }
238 
239 
240 void
242 {
243  NS_LOG_FUNCTION (this);
245 }
246 
247 void
249 {
250  NS_LOG_FUNCTION (this);
252 }
253 
254 void
256 {
257  NS_LOG_FUNCTION (this);
259 }
260 
261 void
263 {
264  NS_LOG_FUNCTION (this);
266 }
267 
268 void
269 LteHelper::SetFadingModel (std::string type)
270 {
271  NS_LOG_FUNCTION (this << type);
272  m_fadingModelType = type;
273  if (!type.empty ())
274  {
277  }
278 }
279 
280 void
282 {
283  m_fadingModelFactory.Set (n, v);
284 }
285 
286 void
288 {
289  NS_LOG_FUNCTION (this << type);
291 }
292 
293 void
295 {
296  m_channelFactory.Set (n, v);
297 }
298 
299 
302 {
303  NS_LOG_FUNCTION (this);
304  Initialize (); // will run DoInitialize () if necessary
306  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
307  {
308  Ptr<Node> node = *i;
309  Ptr<NetDevice> device = InstallSingleEnbDevice (node);
310  devices.Add (device);
311  }
312  return devices;
313 }
314 
317 {
318  NS_LOG_FUNCTION (this);
320  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
321  {
322  Ptr<Node> node = *i;
323  Ptr<NetDevice> device = InstallSingleUeDevice (node);
324  devices.Add (device);
325  }
326  return devices;
327 }
328 
329 
332 {
333 
334  NS_ABORT_MSG_IF (m_cellIdCounter == 65535, "max num eNBs exceeded");
335  uint16_t cellId = ++m_cellIdCounter;
336 
337  Ptr<LteSpectrumPhy> dlPhy = CreateObject<LteSpectrumPhy> ();
338  Ptr<LteSpectrumPhy> ulPhy = CreateObject<LteSpectrumPhy> ();
339 
340  Ptr<LteEnbPhy> phy = CreateObject<LteEnbPhy> (dlPhy, ulPhy);
341 
342  Ptr<LteHarqPhy> harq = Create<LteHarqPhy> ();
343  dlPhy->SetHarqPhyModule (harq);
344  ulPhy->SetHarqPhyModule (harq);
345  phy->SetHarqPhyModule (harq);
346 
347  Ptr<LteCtrlSinrChunkProcessor> pCtrl = Create<LteCtrlSinrChunkProcessor> (phy->GetObject<LtePhy> ());
348  ulPhy->AddCtrlSinrChunkProcessor (pCtrl); // for evaluating SRS UL-CQI
349 
350  Ptr<LteDataSinrChunkProcessor> pData = Create<LteDataSinrChunkProcessor> (ulPhy, phy);
351  ulPhy->AddDataSinrChunkProcessor (pData); // for evaluating PUSCH UL-CQI
352 
353  Ptr<LteInterferencePowerChunkProcessor> pInterf = Create<LteInterferencePowerChunkProcessor> (phy);
354  ulPhy->AddInterferenceDataChunkProcessor (pInterf); // for interference power tracing
355 
356  dlPhy->SetChannel (m_downlinkChannel);
357  ulPhy->SetChannel (m_uplinkChannel);
358 
360  NS_ASSERT_MSG (mm, "MobilityModel needs to be set on node before calling LteHelper::InstallUeDevice ()");
361  dlPhy->SetMobility (mm);
362  ulPhy->SetMobility (mm);
363 
364  Ptr<AntennaModel> antenna = (m_enbAntennaModelFactory.Create ())->GetObject<AntennaModel> ();
365  NS_ASSERT_MSG (antenna, "error in creating the AntennaModel object");
366  dlPhy->SetAntenna (antenna);
367  ulPhy->SetAntenna (antenna);
368 
369  Ptr<LteEnbMac> mac = CreateObject<LteEnbMac> ();
371  Ptr<LteEnbRrc> rrc = CreateObject<LteEnbRrc> ();
372 
373  if (m_useIdealRrc)
374  {
375  Ptr<LteEnbRrcProtocolIdeal> rrcProtocol = CreateObject<LteEnbRrcProtocolIdeal> ();
376  rrcProtocol->SetLteEnbRrcSapProvider (rrc->GetLteEnbRrcSapProvider ());
377  rrc->SetLteEnbRrcSapUser (rrcProtocol->GetLteEnbRrcSapUser ());
378  rrc->AggregateObject (rrcProtocol);
379  rrcProtocol->SetCellId (cellId);
380  }
381  else
382  {
383  Ptr<LteEnbRrcProtocolReal> rrcProtocol = CreateObject<LteEnbRrcProtocolReal> ();
384  rrcProtocol->SetLteEnbRrcSapProvider (rrc->GetLteEnbRrcSapProvider ());
385  rrc->SetLteEnbRrcSapUser (rrcProtocol->GetLteEnbRrcSapUser ());
386  rrc->AggregateObject (rrcProtocol);
387  rrcProtocol->SetCellId (cellId);
388  }
389 
390  if (m_epcHelper != 0)
391  {
392  EnumValue epsBearerToRlcMapping;
393  rrc->GetAttribute ("EpsBearerToRlcMapping", epsBearerToRlcMapping);
394  // it does not make sense to use RLC/SM when also using the EPC
395  if (epsBearerToRlcMapping.Get () == LteEnbRrc::RLC_SM_ALWAYS)
396  {
397  rrc->SetAttribute ("EpsBearerToRlcMapping", EnumValue (LteEnbRrc::RLC_UM_ALWAYS));
398  }
399  }
400 
401  rrc->SetLteEnbCmacSapProvider (mac->GetLteEnbCmacSapProvider ());
402  mac->SetLteEnbCmacSapUser (rrc->GetLteEnbCmacSapUser ());
403  rrc->SetLteMacSapProvider (mac->GetLteMacSapProvider ());
404 
405  mac->SetFfMacSchedSapProvider (sched->GetFfMacSchedSapProvider ());
406  mac->SetFfMacCschedSapProvider (sched->GetFfMacCschedSapProvider ());
407 
408  sched->SetFfMacSchedSapUser (mac->GetFfMacSchedSapUser ());
409  sched->SetFfMacCschedSapUser (mac->GetFfMacCschedSapUser ());
410 
411  phy->SetLteEnbPhySapUser (mac->GetLteEnbPhySapUser ());
412  mac->SetLteEnbPhySapProvider (phy->GetLteEnbPhySapProvider ());
413 
414 
415  phy->SetLteEnbCphySapUser (rrc->GetLteEnbCphySapUser ());
416  rrc->SetLteEnbCphySapProvider (phy->GetLteEnbCphySapProvider ());
417 
419  dev->SetNode (n);
420  dev->SetAttribute ("CellId", UintegerValue (cellId));
421  dev->SetAttribute ("LteEnbPhy", PointerValue (phy));
422  dev->SetAttribute ("LteEnbMac", PointerValue (mac));
423  dev->SetAttribute ("FfMacScheduler", PointerValue (sched));
424  dev->SetAttribute ("LteEnbRrc", PointerValue (rrc));
425 
426  phy->SetDevice (dev);
427  dlPhy->SetDevice (dev);
428  ulPhy->SetDevice (dev);
429 
430  n->AddDevice (dev);
431  ulPhy->SetLtePhyRxDataEndOkCallback (MakeCallback (&LteEnbPhy::PhyPduReceived, phy));
432  ulPhy->SetLtePhyRxCtrlEndOkCallback (MakeCallback (&LteEnbPhy::ReceiveLteControlMessageList, phy));
433  ulPhy->SetLtePhyUlHarqFeedbackCallback (MakeCallback (&LteEnbPhy::ReceiveLteUlHarqFeedback, phy));
434  rrc->SetForwardUpCallback (MakeCallback (&LteEnbNetDevice::Receive, dev));
435 
436  NS_LOG_LOGIC ("set the propagation model frequencies");
438  NS_LOG_LOGIC ("DL freq: " << dlFreq);
439  bool dlFreqOk = m_downlinkPathlossModel->SetAttributeFailSafe ("Frequency", DoubleValue (dlFreq));
440  if (!dlFreqOk)
441  {
442  NS_LOG_WARN ("DL propagation model does not have a Frequency attribute");
443  }
445  NS_LOG_LOGIC ("UL freq: " << ulFreq);
446  bool ulFreqOk = m_uplinkPathlossModel->SetAttributeFailSafe ("Frequency", DoubleValue (ulFreq));
447  if (!ulFreqOk)
448  {
449  NS_LOG_WARN ("UL propagation model does not have a Frequency attribute");
450  }
451 
452 
453  dev->Initialize ();
454 
455  m_uplinkChannel->AddRx (ulPhy);
456 
457  if (m_epcHelper != 0)
458  {
459  NS_LOG_INFO ("adding this eNB to the EPC");
460  m_epcHelper->AddEnb (n, dev, dev->GetCellId ());
462  NS_ASSERT_MSG (enbApp != 0, "cannot retrieve EpcEnbApplication");
463 
464  // S1 SAPs
465  rrc->SetS1SapProvider (enbApp->GetS1SapProvider ());
466  enbApp->SetS1SapUser (rrc->GetS1SapUser ());
467 
468  // X2 SAPs
469  Ptr<EpcX2> x2 = n->GetObject<EpcX2> ();
470  x2->SetEpcX2SapUser (rrc->GetEpcX2SapUser ());
471  rrc->SetEpcX2SapProvider (x2->GetEpcX2SapProvider ());
472  }
473 
474  return dev;
475 }
476 
479 {
480  NS_LOG_FUNCTION (this);
481  Ptr<LteSpectrumPhy> dlPhy = CreateObject<LteSpectrumPhy> ();
482  Ptr<LteSpectrumPhy> ulPhy = CreateObject<LteSpectrumPhy> ();
483 
484  Ptr<LteUePhy> phy = CreateObject<LteUePhy> (dlPhy, ulPhy);
485 
486  Ptr<LteHarqPhy> harq = Create<LteHarqPhy> ();
487  dlPhy->SetHarqPhyModule (harq);
488  ulPhy->SetHarqPhyModule (harq);
489  phy->SetHarqPhyModule (harq);
490 
491  Ptr<LteRsReceivedPowerChunkProcessor> pRs = Create<LteRsReceivedPowerChunkProcessor> (phy->GetObject<LtePhy> ());
492  dlPhy->AddRsPowerChunkProcessor (pRs);
493 
494  Ptr<LteInterferencePowerChunkProcessor> pInterf = Create<LteInterferencePowerChunkProcessor> (phy);
495  dlPhy->AddInterferenceCtrlChunkProcessor (pInterf); // for RSRQ evaluation of UE Measurements
496 
497  Ptr<LteCtrlSinrChunkProcessor> pCtrl = Create<LteCtrlSinrChunkProcessor> (phy->GetObject<LtePhy> (), dlPhy);
498  dlPhy->AddCtrlSinrChunkProcessor (pCtrl);
499 
500  Ptr<LteDataSinrChunkProcessor> pData = Create<LteDataSinrChunkProcessor> (dlPhy);
501  dlPhy->AddDataSinrChunkProcessor (pData);
502 
503  dlPhy->SetChannel (m_downlinkChannel);
504  ulPhy->SetChannel (m_uplinkChannel);
505 
507  NS_ASSERT_MSG (mm, "MobilityModel needs to be set on node before calling LteHelper::InstallUeDevice ()");
508  dlPhy->SetMobility (mm);
509  ulPhy->SetMobility (mm);
510 
511  Ptr<AntennaModel> antenna = (m_ueAntennaModelFactory.Create ())->GetObject<AntennaModel> ();
512  NS_ASSERT_MSG (antenna, "error in creating the AntennaModel object");
513  dlPhy->SetAntenna (antenna);
514  ulPhy->SetAntenna (antenna);
515 
516  Ptr<LteUeMac> mac = CreateObject<LteUeMac> ();
517  Ptr<LteUeRrc> rrc = CreateObject<LteUeRrc> ();
518 
519  if (m_useIdealRrc)
520  {
521  Ptr<LteUeRrcProtocolIdeal> rrcProtocol = CreateObject<LteUeRrcProtocolIdeal> ();
522  rrcProtocol->SetUeRrc (rrc);
523  rrc->AggregateObject (rrcProtocol);
524  rrcProtocol->SetLteUeRrcSapProvider (rrc->GetLteUeRrcSapProvider ());
525  rrc->SetLteUeRrcSapUser (rrcProtocol->GetLteUeRrcSapUser ());
526  }
527  else
528  {
529  Ptr<LteUeRrcProtocolReal> rrcProtocol = CreateObject<LteUeRrcProtocolReal> ();
530  rrcProtocol->SetUeRrc (rrc);
531  rrc->AggregateObject (rrcProtocol);
532  rrcProtocol->SetLteUeRrcSapProvider (rrc->GetLteUeRrcSapProvider ());
533  rrc->SetLteUeRrcSapUser (rrcProtocol->GetLteUeRrcSapUser ());
534  }
535 
536  if (m_epcHelper != 0)
537  {
538  rrc->SetUseRlcSm (false);
539  }
540  Ptr<EpcUeNas> nas = CreateObject<EpcUeNas> ();
541 
542  nas->SetAsSapProvider (rrc->GetAsSapProvider ());
543  rrc->SetAsSapUser (nas->GetAsSapUser ());
544 
545  rrc->SetLteUeCmacSapProvider (mac->GetLteUeCmacSapProvider ());
546  mac->SetLteUeCmacSapUser (rrc->GetLteUeCmacSapUser ());
547  rrc->SetLteMacSapProvider (mac->GetLteMacSapProvider ());
548 
549  phy->SetLteUePhySapUser (mac->GetLteUePhySapUser ());
550  mac->SetLteUePhySapProvider (phy->GetLteUePhySapProvider ());
551 
552  phy->SetLteUeCphySapUser (rrc->GetLteUeCphySapUser ());
553  rrc->SetLteUeCphySapProvider (phy->GetLteUeCphySapProvider ());
554 
555  NS_ABORT_MSG_IF (m_imsiCounter >= 0xFFFFFFFF, "max num UEs exceeded");
556  uint64_t imsi = ++m_imsiCounter;
557  Ptr<LteUeNetDevice> dev = CreateObject<LteUeNetDevice> (n, phy, mac, rrc, nas, imsi);
558  phy->SetDevice (dev);
559  dlPhy->SetDevice (dev);
560  ulPhy->SetDevice (dev);
561  nas->SetDevice (dev);
562 
563  n->AddDevice (dev);
564  dlPhy->SetLtePhyRxDataEndOkCallback (MakeCallback (&LteUePhy::PhyPduReceived, phy));
565  dlPhy->SetLtePhyRxCtrlEndOkCallback (MakeCallback (&LteUePhy::ReceiveLteControlMessageList, phy));
566  dlPhy->SetLtePhyRxPssCallback (MakeCallback (&LteUePhy::ReceivePss, phy));
567  dlPhy->SetLtePhyDlHarqFeedbackCallback (MakeCallback (&LteUePhy::ReceiveLteDlHarqFeedback, phy));
568  nas->SetForwardUpCallback (MakeCallback (&LteUeNetDevice::Receive, dev));
569 
570  if (m_epcHelper != 0)
571  {
572  m_epcHelper->AddUe (dev, dev->GetImsi ());
573  }
574 
575  dev->Initialize ();
576 
577  return dev;
578 }
579 
580 
581 void
583 {
584  NS_LOG_FUNCTION (this);
585  for (NetDeviceContainer::Iterator i = ueDevices.Begin (); i != ueDevices.End (); ++i)
586  {
587  Attach (*i, enbDevice);
588  }
589 }
590 
591 void
593 {
594  NS_LOG_FUNCTION (this);
595  //enbRrc->SetCellId (enbDevice->GetObject<LteEnbNetDevice> ()->GetCellId ());
596 
597  Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice> ();
598  Ptr<LteEnbNetDevice> enbLteDevice = enbDevice->GetObject<LteEnbNetDevice> ();
599 
600  Ptr<EpcUeNas> ueNas = ueLteDevice->GetNas ();
601  ueNas->Connect (enbLteDevice->GetCellId (), enbLteDevice->GetDlEarfcn ());
602 
603  if (m_epcHelper != 0)
604  {
605  // activate default EPS bearer
607  }
608 
609  // tricks needed for the simplified LTE-only simulations
610  if (m_epcHelper == 0)
611  {
612  ueDevice->GetObject<LteUeNetDevice> ()->SetTargetEnb (enbDevice->GetObject<LteEnbNetDevice> ());
613  }
614 }
615 
616 void
618 {
619  NS_LOG_FUNCTION (this);
620  for (NetDeviceContainer::Iterator i = ueDevices.Begin (); i != ueDevices.End (); ++i)
621  {
622  AttachToClosestEnb (*i, enbDevices);
623  }
624 }
625 
626 void
628 {
629  NS_LOG_FUNCTION (this);
630  NS_ASSERT_MSG (enbDevices.GetN () > 0, "empty enb device container");
631  Vector uepos = ueDevice->GetNode ()->GetObject<MobilityModel> ()->GetPosition ();
632  double minDistance = std::numeric_limits<double>::infinity ();
633  Ptr<NetDevice> closestEnbDevice;
634  for (NetDeviceContainer::Iterator i = enbDevices.Begin (); i != enbDevices.End (); ++i)
635  {
636  Vector enbpos = (*i)->GetNode ()->GetObject<MobilityModel> ()->GetPosition ();
637  double distance = CalculateDistance (uepos, enbpos);
638  if (distance < minDistance)
639  {
640  minDistance = distance;
641  closestEnbDevice = *i;
642  }
643  }
644  NS_ASSERT (closestEnbDevice != 0);
645  Attach (ueDevice, closestEnbDevice);
646 }
647 
648 void
650 {
651  NS_LOG_FUNCTION (this);
652  for (NetDeviceContainer::Iterator i = ueDevices.Begin (); i != ueDevices.End (); ++i)
653  {
654  ActivateDedicatedEpsBearer (*i, bearer, tft);
655  }
656 }
657 
658 
659 void
661 {
662  NS_LOG_FUNCTION (this);
663 
664  NS_ASSERT_MSG (m_epcHelper != 0, "dedicated EPS bearers cannot be set up when EPC is not used");
665 
666  uint64_t imsi = ueDevice->GetObject<LteUeNetDevice> ()->GetImsi ();
667  m_epcHelper->ActivateEpsBearer (ueDevice, imsi, tft, bearer);
668 }
669 
670 class DrbActivator : public SimpleRefCount<DrbActivator>
671 {
672 public:
673  DrbActivator (Ptr<NetDevice> ueDevice, EpsBearer bearer);
674  static void ActivateCallback (Ptr<DrbActivator> a, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti);
675  void ActivateDrb (uint64_t imsi, uint16_t cellId, uint16_t rnti);
676 private:
677  bool m_active;
680  uint64_t m_imsi;
681 };
682 
684  : m_active (false),
685  m_ueDevice (ueDevice),
686  m_bearer (bearer),
687  m_imsi (m_ueDevice->GetObject<LteUeNetDevice> ()->GetImsi ())
688 {
689 }
690 
691 void
692 DrbActivator::ActivateCallback (Ptr<DrbActivator> a, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
693 {
694  NS_LOG_FUNCTION (a << context << imsi << cellId << rnti);
695  a->ActivateDrb (imsi, cellId, rnti);
696 }
697 
698 void
699 DrbActivator::ActivateDrb (uint64_t imsi, uint16_t cellId, uint16_t rnti)
700 {
701  NS_LOG_FUNCTION (this << imsi << cellId << rnti << m_active);
702  if ((!m_active) && (imsi == m_imsi))
703  {
704  Ptr<LteUeRrc> ueRrc = m_ueDevice->GetObject<LteUeNetDevice> ()->GetRrc ();
706  uint16_t rnti = ueRrc->GetRnti();
707  Ptr<LteEnbNetDevice> enbLteDevice = m_ueDevice->GetObject<LteUeNetDevice> ()->GetTargetEnb ();
708  Ptr<LteEnbRrc> enbRrc = enbLteDevice->GetObject<LteEnbNetDevice> ()->GetRrc ();
709  NS_ASSERT (ueRrc->GetCellId () == enbLteDevice->GetCellId ());
710  Ptr<UeManager> ueManager = enbRrc->GetUeManager (rnti);
711  NS_ASSERT (ueManager->GetState () == UeManager::CONNECTED_NORMALLY ||
712  ueManager->GetState () == UeManager::CONNECTION_RECONFIGURATION);
714  params.rnti = rnti;
715  params.bearer = m_bearer;
716  params.bearerId = 0;
717  params.gtpTeid = 0; // don't care
718  enbRrc->GetS1SapUser ()->DataRadioBearerSetupRequest (params);
719  m_active = true;
720  }
721 }
722 
723 
724 void
726 {
727  NS_LOG_FUNCTION (this << ueDevice);
728  NS_ASSERT_MSG (m_epcHelper == 0, "this method must not be used when EPC is being used");
729 
730  // Normally it is the EPC that takes care of activating DRBs
731  // when the UE gets connected. When the EPC is not used, we achieve
732  // the same behavior by hooking a dedicated DRB activation function
733  // to the Enb RRC Connection Established trace source
734 
735 
736  Ptr<LteEnbNetDevice> enbLteDevice = ueDevice->GetObject<LteUeNetDevice> ()->GetTargetEnb ();
737 
738  std::ostringstream path;
739  path << "/NodeList/" << enbLteDevice->GetNode ()->GetId ()
740  << "/DeviceList/" << enbLteDevice->GetIfIndex ()
741  << "/LteEnbRrc/ConnectionEstablished";
742  Ptr<DrbActivator> arg = Create<DrbActivator> (ueDevice, bearer);
744 }
745 
746 void
748 {
749  NS_LOG_FUNCTION (this);
750 
751  for (NodeContainer::Iterator i = enbNodes.Begin (); i != enbNodes.End (); ++i)
752  {
753  for (NodeContainer::Iterator j = i + 1; j != enbNodes.End (); ++j)
754  {
755  AddX2Interface (*i, *j);
756  }
757  }
758 }
759 
760 void
762 {
763  NS_LOG_FUNCTION (this);
764  NS_LOG_INFO ("setting up the X2 interface");
765 
766  m_epcHelper->AddX2Interface (enbNode1, enbNode2);
767 }
768 
769 void
771 {
772  NS_LOG_FUNCTION (this << ueDev << sourceEnbDev << targetEnbDev);
773  NS_ASSERT_MSG (m_epcHelper, "Handover requires the use of the EPC - did you forget to call LteHelper::SetEpcHelper () ?");
774  Simulator::Schedule (hoTime, &LteHelper::DoHandoverRequest, this, ueDev, sourceEnbDev, targetEnbDev);
775 }
776 
777 void
779 {
780  NS_LOG_FUNCTION (this << ueDev << sourceEnbDev << targetEnbDev);
781 
782  uint16_t targetCellId = targetEnbDev->GetObject<LteEnbNetDevice> ()->GetCellId ();
783  Ptr<LteEnbRrc> sourceRrc = sourceEnbDev->GetObject<LteEnbNetDevice> ()->GetRrc ();
784  uint16_t rnti = ueDev->GetObject<LteUeNetDevice> ()->GetRrc ()->GetRnti ();
785  sourceRrc->SendHandoverRequest (rnti, targetCellId);
786 }
787 
788 
789 
790 
791 
792 void
794 {
795  NS_LOG_FUNCTION (this);
796  for (NetDeviceContainer::Iterator i = ueDevices.Begin (); i != ueDevices.End (); ++i)
797  {
798  ActivateDataRadioBearer (*i, bearer);
799  }
800 }
801 
802 void
804 {
805  LogComponentEnable ("LteHelper", LOG_LEVEL_ALL);
806  LogComponentEnable ("LteEnbRrc", LOG_LEVEL_ALL);
807  LogComponentEnable ("LteUeRrc", LOG_LEVEL_ALL);
808  LogComponentEnable ("LteEnbMac", LOG_LEVEL_ALL);
809  LogComponentEnable ("LteUeMac", LOG_LEVEL_ALL);
810  LogComponentEnable ("LteRlc", LOG_LEVEL_ALL);
811  LogComponentEnable ("LteRlcUm", LOG_LEVEL_ALL);
812  LogComponentEnable ("LteRlcAm", LOG_LEVEL_ALL);
813  LogComponentEnable ("RrFfMacScheduler", LOG_LEVEL_ALL);
814  LogComponentEnable ("PfFfMacScheduler", LOG_LEVEL_ALL);
815 
816  LogComponentEnable ("LtePhy", LOG_LEVEL_ALL);
817  LogComponentEnable ("LteEnbPhy", LOG_LEVEL_ALL);
818  LogComponentEnable ("LteUePhy", LOG_LEVEL_ALL);
819  LogComponentEnable ("LteSpectrumValueHelper", LOG_LEVEL_ALL);
820  LogComponentEnable ("LteSpectrumPhy", LOG_LEVEL_ALL);
821  LogComponentEnable ("LteInterference", LOG_LEVEL_ALL);
822  LogComponentEnable ("LteSinrChunkProcessor", LOG_LEVEL_ALL);
823 
824  std::string propModelStr = m_dlPathlossModelFactory.GetTypeId ().GetName ().erase (0,5).c_str ();
825  LogComponentEnable ("LteNetDevice", LOG_LEVEL_ALL);
826  LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL);
827  LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL);
828 
829  LogComponentEnable ("RadioBearerStatsCalculator", LOG_LEVEL_ALL);
830  LogComponentEnable ("LteStatsCalculator", LOG_LEVEL_ALL);
831  LogComponentEnable ("MacStatsCalculator", LOG_LEVEL_ALL);
832  LogComponentEnable ("PhyTxStatsCalculator", LOG_LEVEL_ALL);
833  LogComponentEnable ("PhyRxStatsCalculator", LOG_LEVEL_ALL);
834  LogComponentEnable ("PhyStatsCalculator", LOG_LEVEL_ALL);
835 
836 
837 }
838 
839 void
841 {
842  EnablePhyTraces ();
843  EnableMacTraces ();
844  EnableRlcTraces ();
845  EnablePdcpTraces ();
846 }
847 
848 void
850 {
851  NS_ASSERT_MSG (m_rlcStats == 0, "please make sure that LteHelper::EnableRlcTraces is called at most once");
852  m_rlcStats = CreateObject<RadioBearerStatsCalculator> ("RLC");
854 }
855 
856 int64_t
858 {
859  int64_t currentStream = stream;
860  if ((m_fadingModule != 0) && (m_fadingStreamsAssigned == false))
861  {
863  if (tflm != 0)
864  {
865  currentStream += tflm->AssignStreams (currentStream);
867  }
868  }
869  Ptr<NetDevice> netDevice;
870  for (NetDeviceContainer::Iterator i = c.Begin (); i != c.End (); ++i)
871  {
872  netDevice = (*i);
873  Ptr<LteEnbNetDevice> lteEnb = DynamicCast<LteEnbNetDevice> (netDevice);
874  if (lteEnb)
875  {
876  Ptr<LteSpectrumPhy> dlPhy = lteEnb->GetPhy ()->GetDownlinkSpectrumPhy ();
877  Ptr<LteSpectrumPhy> ulPhy = lteEnb->GetPhy ()->GetUplinkSpectrumPhy ();
878  currentStream += dlPhy->AssignStreams (currentStream);
879  currentStream += ulPhy->AssignStreams (currentStream);
880  }
881  Ptr<LteUeNetDevice> lteUe = DynamicCast<LteUeNetDevice> (netDevice);
882  if (lteUe)
883  {
884  Ptr<LteSpectrumPhy> dlPhy = lteUe->GetPhy ()->GetDownlinkSpectrumPhy ();
885  Ptr<LteSpectrumPhy> ulPhy = lteUe->GetPhy ()->GetUplinkSpectrumPhy ();
886  Ptr<LteUeMac> ueMac = lteUe->GetMac ();
887  currentStream += dlPhy->AssignStreams (currentStream);
888  currentStream += ulPhy->AssignStreams (currentStream);
889  currentStream += ueMac->AssignStreams (currentStream);
890  }
891  }
892  return (currentStream - stream);
893 }
894 
895 
896 void
898 {
905 }
906 
907 void
909 {
910  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbPhy/DlPhyTransmission",
912 }
913 
914 void
916 {
917  Config::Connect ("/NodeList/*/DeviceList/*/LteUePhy/UlPhyTransmission",
919 }
920 
921 void
923 {
924  Config::Connect ("/NodeList/*/DeviceList/*/LteUePhy/DlSpectrumPhy/DlPhyReception",
926 }
927 
928 void
930 {
931  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbPhy/UlSpectrumPhy/UlPhyReception",
933 }
934 
935 
936 void
938 {
941 }
942 
943 
944 void
946 {
948  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbMac/DlScheduling",
950 }
951 
952 void
954 {
956  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbMac/UlScheduling",
958 }
959 
960 void
962 {
964  Config::Connect ("/NodeList/*/DeviceList/*/LteUePhy/ReportCurrentCellRsrpSinr",
966 }
967 
968 void
970 {
972  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbPhy/ReportUeSinr",
974  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbPhy/ReportInterference",
976 
977 }
978 
981 {
982  return m_rlcStats;
983 }
984 
985 void
987 {
988  NS_ASSERT_MSG (m_pdcpStats == 0, "please make sure that LteHelper::EnablePdcpTraces is called at most once");
989  m_pdcpStats = CreateObject<RadioBearerStatsCalculator> ("PDCP");
991 }
992 
995 {
996  return m_pdcpStats;
997 }
998 
999 } // namespace ns3