A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
lte-helper.cc
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/isotropic-antenna-model.h>
42 #include <ns3/lte-enb-net-device.h>
43 #include <ns3/lte-ue-net-device.h>
44 #include <ns3/ff-mac-scheduler.h>
45 #include <ns3/lte-rlc.h>
46 #include <ns3/lte-rlc-um.h>
47 #include <ns3/lte-rlc-am.h>
48 #include <ns3/epc-enb-s1-sap.h>
49 #include <ns3/lte-rrc-protocol-ideal.h>
50 #include <ns3/lte-rrc-protocol-real.h>
51 
52 #include <ns3/epc-helper.h>
53 #include <iostream>
54 #include <ns3/buildings-propagation-loss-model.h>
55 #include <ns3/lte-spectrum-value-helper.h>
56 #include <ns3/epc-x2.h>
57 
58 NS_LOG_COMPONENT_DEFINE ("LteHelper");
59 
60 namespace ns3 {
61 
62 NS_OBJECT_ENSURE_REGISTERED (LteHelper);
63 
64 LteHelper::LteHelper (void)
65  : m_imsiCounter (0),
66  m_cellIdCounter (0)
67 {
68  NS_LOG_FUNCTION (this);
69  m_enbNetDeviceFactory.SetTypeId (LteEnbNetDevice::GetTypeId ());
70  m_enbAntennaModelFactory.SetTypeId (IsotropicAntennaModel::GetTypeId ());
71  m_ueAntennaModelFactory.SetTypeId (IsotropicAntennaModel::GetTypeId ());
72  m_channelFactory.SetTypeId (MultiModelSpectrumChannel::GetTypeId ());
73 }
74 
75 void
77 {
78  NS_LOG_FUNCTION (this);
79  m_downlinkChannel = m_channelFactory.Create<SpectrumChannel> ();
80  m_uplinkChannel = m_channelFactory.Create<SpectrumChannel> ();
81 
82  m_downlinkPathlossModel = m_dlPathlossModelFactory.Create ();
83  Ptr<SpectrumPropagationLossModel> dlSplm = m_downlinkPathlossModel->GetObject<SpectrumPropagationLossModel> ();
84  if (dlSplm != 0)
85  {
86  NS_LOG_LOGIC (this << " using a SpectrumPropagationLossModel in DL");
87  m_downlinkChannel->AddSpectrumPropagationLossModel (dlSplm);
88  }
89  else
90  {
91  NS_LOG_LOGIC (this << " using a PropagationLossModel in DL");
92  Ptr<PropagationLossModel> dlPlm = m_downlinkPathlossModel->GetObject<PropagationLossModel> ();
93  NS_ASSERT_MSG (dlPlm != 0, " " << m_downlinkPathlossModel << " is neither PropagationLossModel nor SpectrumPropagationLossModel");
94  m_downlinkChannel->AddPropagationLossModel (dlPlm);
95  }
96 
97  m_uplinkPathlossModel = m_ulPathlossModelFactory.Create ();
99  if (ulSplm != 0)
100  {
101  NS_LOG_LOGIC (this << " using a SpectrumPropagationLossModel in UL");
102  m_uplinkChannel->AddSpectrumPropagationLossModel (ulSplm);
103  }
104  else
105  {
106  NS_LOG_LOGIC (this << " using a PropagationLossModel in UL");
107  Ptr<PropagationLossModel> ulPlm = m_uplinkPathlossModel->GetObject<PropagationLossModel> ();
108  NS_ASSERT_MSG (ulPlm != 0, " " << m_uplinkPathlossModel << " is neither PropagationLossModel nor SpectrumPropagationLossModel");
109  m_uplinkChannel->AddPropagationLossModel (ulPlm);
110  }
111  if (!m_fadingModelType.empty ())
112  {
113  Ptr<SpectrumPropagationLossModel> m_fadingModule;
114  m_fadingModule = m_fadingModelFactory.Create<SpectrumPropagationLossModel> ();
115  m_fadingModule->Initialize ();
116  m_downlinkChannel->AddSpectrumPropagationLossModel (m_fadingModule);
117  m_uplinkChannel->AddSpectrumPropagationLossModel (m_fadingModule);
118  }
119  m_phyStats = CreateObject<PhyStatsCalculator> ();
120  m_phyTxStats = CreateObject<PhyTxStatsCalculator> ();
121  m_phyRxStats = CreateObject<PhyRxStatsCalculator> ();
122  m_macStats = CreateObject<MacStatsCalculator> ();
124 
125 }
126 
127 LteHelper::~LteHelper (void)
128 {
129  NS_LOG_FUNCTION (this);
130 }
131 
132 TypeId LteHelper::GetTypeId (void)
133 {
134  static TypeId
135  tid =
136  TypeId ("ns3::LteHelper")
137  .SetParent<Object> ()
138  .AddConstructor<LteHelper> ()
139  .AddAttribute ("Scheduler",
140  "The type of scheduler to be used for eNBs",
141  StringValue ("ns3::PfFfMacScheduler"),
142  MakeStringAccessor (&LteHelper::SetSchedulerType),
143  MakeStringChecker ())
144  .AddAttribute ("PathlossModel",
145  "The type of pathloss model to be used",
146  StringValue ("ns3::FriisPropagationLossModel"),
147  MakeStringAccessor (&LteHelper::SetPathlossModelType),
148  MakeStringChecker ())
149  .AddAttribute ("FadingModel",
150  "The type of fading model to be used. If the type is set "
151  "to an empty string, no fading model is used.",
152  StringValue (""),
153  MakeStringAccessor (&LteHelper::SetFadingModel),
154  MakeStringChecker ())
155  .AddAttribute ("UseIdealRrc",
156  "If true, LteRrcProtocolIdeal will be used for RRC signaling. "
157  "If false, LteRrcProtocolReal will be used.",
158  BooleanValue (true),
159  MakeBooleanAccessor (&LteHelper::m_useIdealRrc),
160  MakeBooleanChecker ())
161  ;
162  return tid;
163 }
164 
165 void
167 {
168  NS_LOG_FUNCTION (this);
169  m_downlinkChannel = 0;
170  m_uplinkChannel = 0;
172 }
173 
174 
175 void
177 {
178  NS_LOG_FUNCTION (this << h);
179  m_epcHelper = h;
180 }
181 
182 void
183 LteHelper::SetSchedulerType (std::string type)
184 {
185  NS_LOG_FUNCTION (this << type);
186  m_schedulerFactory = ObjectFactory ();
187  m_schedulerFactory.SetTypeId (type);
188 }
189 
190 void
192 {
193  NS_LOG_FUNCTION (this << n);
194  m_schedulerFactory.Set (n, v);
195 }
196 
197 
198 void
200 {
201  NS_LOG_FUNCTION (this << type);
202  m_dlPathlossModelFactory = ObjectFactory ();
203  m_dlPathlossModelFactory.SetTypeId (type);
204  m_ulPathlossModelFactory = ObjectFactory ();
205  m_ulPathlossModelFactory.SetTypeId (type);
206 }
207 
208 void
210 {
211  NS_LOG_FUNCTION (this << n);
212  m_dlPathlossModelFactory.Set (n, v);
213  m_ulPathlossModelFactory.Set (n, v);
214 }
215 
216 void
218 {
219  NS_LOG_FUNCTION (this);
220  m_enbNetDeviceFactory.Set (n, v);
221 }
222 
223 
224 void
226 {
227  NS_LOG_FUNCTION (this);
228  m_enbAntennaModelFactory.SetTypeId (type);
229 }
230 
231 void
233 {
234  NS_LOG_FUNCTION (this);
235  m_enbAntennaModelFactory.Set (n, v);
236 }
237 
238 void
240 {
241  NS_LOG_FUNCTION (this);
242  m_ueAntennaModelFactory.SetTypeId (type);
243 }
244 
245 void
247 {
248  NS_LOG_FUNCTION (this);
249  m_ueAntennaModelFactory.Set (n, v);
250 }
251 
252 void
253 LteHelper::SetFadingModel (std::string type)
254 {
255  NS_LOG_FUNCTION (this << type);
256  m_fadingModelType = type;
257  if (!type.empty ())
258  {
259  m_fadingModelFactory = ObjectFactory ();
260  m_fadingModelFactory.SetTypeId (type);
261  }
262 }
263 
264 void
266 {
267  m_fadingModelFactory.Set (n, v);
268 }
269 
270 void
272 {
273  NS_LOG_FUNCTION (this << type);
274  m_channelFactory.SetTypeId (type);
275 }
276 
277 void
279 {
280  m_channelFactory.Set (n, v);
281 }
282 
283 
286 {
287  NS_LOG_FUNCTION (this);
288  Initialize (); // will run DoInitialize () if necessary
289  NetDeviceContainer devices;
290  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
291  {
292  Ptr<Node> node = *i;
293  Ptr<NetDevice> device = InstallSingleEnbDevice (node);
294  devices.Add (device);
295  }
296  return devices;
297 }
298 
301 {
302  NS_LOG_FUNCTION (this);
303  NetDeviceContainer devices;
304  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
305  {
306  Ptr<Node> node = *i;
307  Ptr<NetDevice> device = InstallSingleUeDevice (node);
308  devices.Add (device);
309  }
310  return devices;
311 }
312 
313 
315 LteHelper::InstallSingleEnbDevice (Ptr<Node> n)
316 {
317 
318  NS_ABORT_MSG_IF (m_cellIdCounter == 65535, "max num eNBs exceeded");
319  uint16_t cellId = ++m_cellIdCounter;
320 
321  Ptr<LteSpectrumPhy> dlPhy = CreateObject<LteSpectrumPhy> ();
322  Ptr<LteSpectrumPhy> ulPhy = CreateObject<LteSpectrumPhy> ();
323 
324  Ptr<LteEnbPhy> phy = CreateObject<LteEnbPhy> (dlPhy, ulPhy);
325 
326  Ptr<LteHarqPhy> harq = Create<LteHarqPhy> ();
327  dlPhy->SetHarqPhyModule (harq);
328  ulPhy->SetHarqPhyModule (harq);
329  phy->SetHarqPhyModule (harq);
330 
331  Ptr<LteCtrlSinrChunkProcessor> pCtrl = Create<LteCtrlSinrChunkProcessor> (phy->GetObject<LtePhy> ());
332  ulPhy->AddCtrlSinrChunkProcessor (pCtrl); // for evaluating SRS UL-CQI
333 
334  Ptr<LteDataSinrChunkProcessor> pData = Create<LteDataSinrChunkProcessor> (ulPhy, phy);
335  ulPhy->AddDataSinrChunkProcessor (pData); // for evaluating PUSCH UL-CQI
336 
337  Ptr<LteInterferencePowerChunkProcessor> pInterf = Create<LteInterferencePowerChunkProcessor> (phy);
338  ulPhy->AddInterferenceChunkProcessor (pInterf); // for interference power tracing
339 
340  dlPhy->SetChannel (m_downlinkChannel);
341  ulPhy->SetChannel (m_uplinkChannel);
342 
344  NS_ASSERT_MSG (mm, "MobilityModel needs to be set on node before calling LteHelper::InstallUeDevice ()");
345  dlPhy->SetMobility (mm);
346  ulPhy->SetMobility (mm);
347 
348  Ptr<AntennaModel> antenna = (m_enbAntennaModelFactory.Create ())->GetObject<AntennaModel> ();
349  NS_ASSERT_MSG (antenna, "error in creating the AntennaModel object");
350  dlPhy->SetAntenna (antenna);
351  ulPhy->SetAntenna (antenna);
352 
353  Ptr<LteEnbMac> mac = CreateObject<LteEnbMac> ();
354  Ptr<FfMacScheduler> sched = m_schedulerFactory.Create<FfMacScheduler> ();
355  Ptr<LteEnbRrc> rrc = CreateObject<LteEnbRrc> ();
356 
357  if (m_useIdealRrc)
358  {
359  Ptr<LteEnbRrcProtocolIdeal> rrcProtocol = CreateObject<LteEnbRrcProtocolIdeal> ();
360  rrcProtocol->SetLteEnbRrcSapProvider (rrc->GetLteEnbRrcSapProvider ());
361  rrc->SetLteEnbRrcSapUser (rrcProtocol->GetLteEnbRrcSapUser ());
362  rrc->AggregateObject (rrcProtocol);
363  rrcProtocol->SetCellId (cellId);
364  }
365  else
366  {
367  Ptr<LteEnbRrcProtocolReal> rrcProtocol = CreateObject<LteEnbRrcProtocolReal> ();
368  rrcProtocol->SetLteEnbRrcSapProvider (rrc->GetLteEnbRrcSapProvider ());
369  rrc->SetLteEnbRrcSapUser (rrcProtocol->GetLteEnbRrcSapUser ());
370  rrc->AggregateObject (rrcProtocol);
371  rrcProtocol->SetCellId (cellId);
372  }
373 
374  if (m_epcHelper != 0)
375  {
376  EnumValue epsBearerToRlcMapping;
377  rrc->GetAttribute ("EpsBearerToRlcMapping", epsBearerToRlcMapping);
378  // it does not make sense to use RLC/SM when also using the EPC
379  if (epsBearerToRlcMapping.Get () == LteEnbRrc::RLC_SM_ALWAYS)
380  {
381  rrc->SetAttribute ("EpsBearerToRlcMapping", EnumValue (LteEnbRrc::RLC_UM_ALWAYS));
382  }
383  }
384 
385  rrc->SetLteEnbCmacSapProvider (mac->GetLteEnbCmacSapProvider ());
386  mac->SetLteEnbCmacSapUser (rrc->GetLteEnbCmacSapUser ());
387  rrc->SetLteMacSapProvider (mac->GetLteMacSapProvider ());
388 
389  mac->SetFfMacSchedSapProvider (sched->GetFfMacSchedSapProvider ());
390  mac->SetFfMacCschedSapProvider (sched->GetFfMacCschedSapProvider ());
391 
392  sched->SetFfMacSchedSapUser (mac->GetFfMacSchedSapUser ());
393  sched->SetFfMacCschedSapUser (mac->GetFfMacCschedSapUser ());
394 
395  phy->SetLteEnbPhySapUser (mac->GetLteEnbPhySapUser ());
396  mac->SetLteEnbPhySapProvider (phy->GetLteEnbPhySapProvider ());
397 
398 
399  phy->SetLteEnbCphySapUser (rrc->GetLteEnbCphySapUser ());
400  rrc->SetLteEnbCphySapProvider (phy->GetLteEnbCphySapProvider ());
401 
402  Ptr<LteEnbNetDevice> dev = m_enbNetDeviceFactory.Create<LteEnbNetDevice> ();
403  dev->SetNode (n);
404  dev->SetAttribute ("CellId", UintegerValue (cellId));
405  dev->SetAttribute ("LteEnbPhy", PointerValue (phy));
406  dev->SetAttribute ("LteEnbMac", PointerValue (mac));
407  dev->SetAttribute ("FfMacScheduler", PointerValue (sched));
408  dev->SetAttribute ("LteEnbRrc", PointerValue (rrc));
409 
410  phy->SetDevice (dev);
411  dlPhy->SetDevice (dev);
412  ulPhy->SetDevice (dev);
413 
414  n->AddDevice (dev);
415  ulPhy->SetLtePhyRxDataEndOkCallback (MakeCallback (&LteEnbPhy::PhyPduReceived, phy));
416  ulPhy->SetLtePhyRxCtrlEndOkCallback (MakeCallback (&LteEnbPhy::ReceiveLteControlMessageList, phy));
417  ulPhy->SetLtePhyUlHarqFeedbackCallback (MakeCallback (&LteEnbPhy::ReceiveLteUlHarqFeedback, phy));
418  rrc->SetForwardUpCallback (MakeCallback (&LteEnbNetDevice::Receive, dev));
419 
420  NS_LOG_LOGIC ("set the propagation model frequencies");
421  double dlFreq = LteSpectrumValueHelper::GetCarrierFrequency (dev->GetDlEarfcn ());
422  NS_LOG_LOGIC ("DL freq: " << dlFreq);
423  bool dlFreqOk = m_downlinkPathlossModel->SetAttributeFailSafe ("Frequency", DoubleValue (dlFreq));
424  if (!dlFreqOk)
425  {
426  NS_LOG_WARN ("DL propagation model does not have a Frequency attribute");
427  }
428  double ulFreq = LteSpectrumValueHelper::GetCarrierFrequency (dev->GetUlEarfcn ());
429  NS_LOG_LOGIC ("UL freq: " << ulFreq);
430  bool ulFreqOk = m_uplinkPathlossModel->SetAttributeFailSafe ("Frequency", DoubleValue (ulFreq));
431  if (!ulFreqOk)
432  {
433  NS_LOG_WARN ("UL propagation model does not have a Frequency attribute");
434  }
435 
436 
437  dev->Initialize ();
438 
439  m_uplinkChannel->AddRx (ulPhy);
440 
441  if (m_epcHelper != 0)
442  {
443  NS_LOG_INFO ("adding this eNB to the EPC");
444  m_epcHelper->AddEnb (n, dev, dev->GetCellId ());
445  Ptr<EpcEnbApplication> enbApp = n->GetApplication (0)->GetObject<EpcEnbApplication> ();
446  NS_ASSERT_MSG (enbApp != 0, "cannot retrieve EpcEnbApplication");
447 
448  // S1 SAPs
449  rrc->SetS1SapProvider (enbApp->GetS1SapProvider ());
450  enbApp->SetS1SapUser (rrc->GetS1SapUser ());
451 
452  // X2 SAPs
453  Ptr<EpcX2> x2 = n->GetObject<EpcX2> ();
454  x2->SetEpcX2SapUser (rrc->GetEpcX2SapUser ());
455  rrc->SetEpcX2SapProvider (x2->GetEpcX2SapProvider ());
456  }
457 
458  return dev;
459 }
460 
461 Ptr<NetDevice>
462 LteHelper::InstallSingleUeDevice (Ptr<Node> n)
463 {
464  NS_LOG_FUNCTION (this);
465  Ptr<LteSpectrumPhy> dlPhy = CreateObject<LteSpectrumPhy> ();
466  Ptr<LteSpectrumPhy> ulPhy = CreateObject<LteSpectrumPhy> ();
467 
468  Ptr<LteUePhy> phy = CreateObject<LteUePhy> (dlPhy, ulPhy);
469 
470  Ptr<LteHarqPhy> harq = Create<LteHarqPhy> ();
471  dlPhy->SetHarqPhyModule (harq);
472  ulPhy->SetHarqPhyModule (harq);
473  phy->SetHarqPhyModule (harq);
474 
475  Ptr<LteRsReceivedPowerChunkProcessor> pRs = Create<LteRsReceivedPowerChunkProcessor> (phy->GetObject<LtePhy> ());
476  dlPhy->AddRsPowerChunkProcessor (pRs);
477 
478  Ptr<LteCtrlSinrChunkProcessor> pCtrl = Create<LteCtrlSinrChunkProcessor> (phy->GetObject<LtePhy> (), dlPhy);
479  dlPhy->AddCtrlSinrChunkProcessor (pCtrl);
480 
481  Ptr<LteDataSinrChunkProcessor> pData = Create<LteDataSinrChunkProcessor> (dlPhy);
482  dlPhy->AddDataSinrChunkProcessor (pData);
483 
484  dlPhy->SetChannel (m_downlinkChannel);
485  ulPhy->SetChannel (m_uplinkChannel);
486 
487  Ptr<MobilityModel> mm = n->GetObject<MobilityModel> ();
488  NS_ASSERT_MSG (mm, "MobilityModel needs to be set on node before calling LteHelper::InstallUeDevice ()");
489  dlPhy->SetMobility (mm);
490  ulPhy->SetMobility (mm);
491 
492  Ptr<AntennaModel> antenna = (m_ueAntennaModelFactory.Create ())->GetObject<AntennaModel> ();
493  NS_ASSERT_MSG (antenna, "error in creating the AntennaModel object");
494  dlPhy->SetAntenna (antenna);
495  ulPhy->SetAntenna (antenna);
496 
497  Ptr<LteUeMac> mac = CreateObject<LteUeMac> ();
498  Ptr<LteUeRrc> rrc = CreateObject<LteUeRrc> ();
499 
500  if (m_useIdealRrc)
501  {
502  Ptr<LteUeRrcProtocolIdeal> rrcProtocol = CreateObject<LteUeRrcProtocolIdeal> ();
503  rrcProtocol->SetUeRrc (rrc);
504  rrc->AggregateObject (rrcProtocol);
505  rrcProtocol->SetLteUeRrcSapProvider (rrc->GetLteUeRrcSapProvider ());
506  rrc->SetLteUeRrcSapUser (rrcProtocol->GetLteUeRrcSapUser ());
507  }
508  else
509  {
510  Ptr<LteUeRrcProtocolReal> rrcProtocol = CreateObject<LteUeRrcProtocolReal> ();
511  rrcProtocol->SetUeRrc (rrc);
512  rrc->AggregateObject (rrcProtocol);
513  rrcProtocol->SetLteUeRrcSapProvider (rrc->GetLteUeRrcSapProvider ());
514  rrc->SetLteUeRrcSapUser (rrcProtocol->GetLteUeRrcSapUser ());
515  }
516 
517  if (m_epcHelper != 0)
518  {
519  rrc->SetUseRlcSm (false);
520  }
521  Ptr<EpcUeNas> nas = CreateObject<EpcUeNas> ();
522 
523  nas->SetAsSapProvider (rrc->GetAsSapProvider ());
524  rrc->SetAsSapUser (nas->GetAsSapUser ());
525 
526  rrc->SetLteUeCmacSapProvider (mac->GetLteUeCmacSapProvider ());
527  mac->SetLteUeCmacSapUser (rrc->GetLteUeCmacSapUser ());
528  rrc->SetLteMacSapProvider (mac->GetLteMacSapProvider ());
529 
530  phy->SetLteUePhySapUser (mac->GetLteUePhySapUser ());
531  mac->SetLteUePhySapProvider (phy->GetLteUePhySapProvider ());
532 
533  phy->SetLteUeCphySapUser (rrc->GetLteUeCphySapUser ());
534  rrc->SetLteUeCphySapProvider (phy->GetLteUeCphySapProvider ());
535 
536  NS_ABORT_MSG_IF (m_imsiCounter >= 0xFFFFFFFF, "max num UEs exceeded");
537  uint64_t imsi = ++m_imsiCounter;
538  Ptr<LteUeNetDevice> dev = CreateObject<LteUeNetDevice> (n, phy, mac, rrc, nas, imsi);
539  phy->SetDevice (dev);
540  dlPhy->SetDevice (dev);
541  ulPhy->SetDevice (dev);
542  nas->SetDevice (dev);
543 
544  n->AddDevice (dev);
545  dlPhy->SetLtePhyRxDataEndOkCallback (MakeCallback (&LteUePhy::PhyPduReceived, phy));
546  dlPhy->SetLtePhyRxCtrlEndOkCallback (MakeCallback (&LteUePhy::ReceiveLteControlMessageList, phy));
547  dlPhy->SetLtePhyDlHarqFeedbackCallback (MakeCallback (&LteUePhy::ReceiveLteDlHarqFeedback, phy));
548  nas->SetForwardUpCallback (MakeCallback (&LteUeNetDevice::Receive, dev));
549 
550  if (m_epcHelper != 0)
551  {
552  m_epcHelper->AddUe (dev, dev->GetImsi ());
553  }
554 
555  dev->Initialize ();
556 
557  return dev;
558 }
559 
560 
561 void
563 {
564  NS_LOG_FUNCTION (this);
565  for (NetDeviceContainer::Iterator i = ueDevices.Begin (); i != ueDevices.End (); ++i)
566  {
567  Attach (*i, enbDevice);
568  }
569 }
570 
571 void
573 {
574  NS_LOG_FUNCTION (this);
575  //enbRrc->SetCellId (enbDevice->GetObject<LteEnbNetDevice> ()->GetCellId ());
576 
577  Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice> ();
578  Ptr<LteEnbNetDevice> enbLteDevice = enbDevice->GetObject<LteEnbNetDevice> ();
579 
580  Ptr<EpcUeNas> ueNas = ueLteDevice->GetNas ();
581  ueNas->Connect (enbLteDevice->GetCellId (), enbLteDevice->GetDlEarfcn ());
582 
583  if (m_epcHelper != 0)
584  {
585  // activate default EPS bearer
586  m_epcHelper->ActivateEpsBearer (ueDevice, ueLteDevice->GetImsi (), EpcTft::Default (), EpsBearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT));
587  }
588 
589  // tricks needed for the simplified LTE-only simulations
590  if (m_epcHelper == 0)
591  {
592  ueDevice->GetObject<LteUeNetDevice> ()->SetTargetEnb (enbDevice->GetObject<LteEnbNetDevice> ());
593  }
594 }
595 
596 void
598 {
599  NS_LOG_FUNCTION (this);
600  for (NetDeviceContainer::Iterator i = ueDevices.Begin (); i != ueDevices.End (); ++i)
601  {
602  AttachToClosestEnb (*i, enbDevices);
603  }
604 }
605 
606 void
608 {
609  NS_LOG_FUNCTION (this);
610  NS_ASSERT_MSG (enbDevices.GetN () > 0, "empty enb device container");
611  Vector uepos = ueDevice->GetNode ()->GetObject<MobilityModel> ()->GetPosition ();
612  double minDistance = std::numeric_limits<double>::infinity ();
613  Ptr<NetDevice> closestEnbDevice;
614  for (NetDeviceContainer::Iterator i = enbDevices.Begin (); i != enbDevices.End (); ++i)
615  {
616  Vector enbpos = (*i)->GetNode ()->GetObject<MobilityModel> ()->GetPosition ();
617  double distance = CalculateDistance (uepos, enbpos);
618  if (distance < minDistance)
619  {
620  minDistance = distance;
621  closestEnbDevice = *i;
622  }
623  }
624  NS_ASSERT (closestEnbDevice != 0);
625  Attach (ueDevice, closestEnbDevice);
626 }
627 
628 void
630 {
631  NS_LOG_FUNCTION (this);
632  for (NetDeviceContainer::Iterator i = ueDevices.Begin (); i != ueDevices.End (); ++i)
633  {
634  ActivateDedicatedEpsBearer (*i, bearer, tft);
635  }
636 }
637 
638 
639 void
641 {
642  NS_LOG_FUNCTION (this);
643 
644  NS_ASSERT_MSG (m_epcHelper != 0, "dedicated EPS bearers cannot be set up when EPC is not used");
645 
646  uint64_t imsi = ueDevice->GetObject<LteUeNetDevice> ()->GetImsi ();
647  m_epcHelper->ActivateEpsBearer (ueDevice, imsi, tft, bearer);
648 }
649 
650 class DrbActivator : public SimpleRefCount<DrbActivator>
651 {
652 public:
653  DrbActivator (Ptr<NetDevice> ueDevice, EpsBearer bearer);
654  static void ActivateCallback (Ptr<DrbActivator> a, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti);
655  void ActivateDrb (uint64_t imsi, uint16_t cellId, uint16_t rnti);
656 private:
657  bool m_active;
658  Ptr<NetDevice> m_ueDevice;
659  EpsBearer m_bearer;
660  uint64_t m_imsi;
661 };
662 
663 DrbActivator::DrbActivator (Ptr<NetDevice> ueDevice, EpsBearer bearer)
664  : m_active (false),
665  m_ueDevice (ueDevice),
666  m_bearer (bearer),
667  m_imsi (m_ueDevice->GetObject<LteUeNetDevice> ()->GetImsi ())
668 {
669 }
670 
671 void
672 DrbActivator::ActivateCallback (Ptr<DrbActivator> a, std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
673 {
674  NS_LOG_FUNCTION (a << context << imsi << cellId << rnti);
675  a->ActivateDrb (imsi, cellId, rnti);
676 }
677 
678 void
679 DrbActivator::ActivateDrb (uint64_t imsi, uint16_t cellId, uint16_t rnti)
680 {
681  NS_LOG_FUNCTION (this << imsi << cellId << rnti << m_active);
682  if ((!m_active) && (imsi == m_imsi))
683  {
684  Ptr<LteUeRrc> ueRrc = m_ueDevice->GetObject<LteUeNetDevice> ()->GetRrc ();
685  NS_ASSERT (ueRrc->GetState () == LteUeRrc::CONNECTED_NORMALLY);
686  uint16_t rnti = ueRrc->GetRnti();
687  Ptr<LteEnbNetDevice> enbLteDevice = m_ueDevice->GetObject<LteUeNetDevice> ()->GetTargetEnb ();
688  Ptr<LteEnbRrc> enbRrc = enbLteDevice->GetObject<LteEnbNetDevice> ()->GetRrc ();
689  NS_ASSERT (ueRrc->GetCellId () == enbLteDevice->GetCellId ());
690  Ptr<UeManager> ueManager = enbRrc->GetUeManager (rnti);
691  NS_ASSERT (ueManager->GetState () == UeManager::CONNECTED_NORMALLY ||
692  ueManager->GetState () == UeManager::CONNECTION_RECONFIGURATION);
693  EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters params;
694  params.rnti = rnti;
695  params.bearer = m_bearer;
696  params.bearerId = 0;
697  params.gtpTeid = 0; // don't care
698  enbRrc->GetS1SapUser ()->DataRadioBearerSetupRequest (params);
699  m_active = true;
700  }
701 }
702 
703 
704 void
706 {
707  NS_LOG_FUNCTION (this << ueDevice);
708  NS_ASSERT_MSG (m_epcHelper == 0, "this method must not be used when EPC is being used");
709 
710  // Normally it is the EPC that takes care of activating DRBs
711  // when the UE gets connected. When the EPC is not used, we achieve
712  // the same behavior by hooking a dedicated DRB activation function
713  // to the Enb RRC Connection Established trace source
714 
715 
716  Ptr<LteEnbNetDevice> enbLteDevice = ueDevice->GetObject<LteUeNetDevice> ()->GetTargetEnb ();
717 
718  std::ostringstream path;
719  path << "/NodeList/" << enbLteDevice->GetNode ()->GetId ()
720  << "/DeviceList/" << enbLteDevice->GetIfIndex ()
721  << "/LteEnbRrc/ConnectionEstablished";
722  Ptr<DrbActivator> arg = Create<DrbActivator> (ueDevice, bearer);
723  Config::Connect (path.str (), MakeBoundCallback (&DrbActivator::ActivateCallback, arg));
724 }
725 
726 void
728 {
729  NS_LOG_FUNCTION (this);
730 
731  for (NodeContainer::Iterator i = enbNodes.Begin (); i != enbNodes.End (); ++i)
732  {
733  for (NodeContainer::Iterator j = i + 1; j != enbNodes.End (); ++j)
734  {
735  AddX2Interface (*i, *j);
736  }
737  }
738 }
739 
740 void
742 {
743  NS_LOG_FUNCTION (this);
744  NS_LOG_INFO ("setting up the X2 interface");
745 
746  m_epcHelper->AddX2Interface (enbNode1, enbNode2);
747 }
748 
749 void
751 {
752  NS_LOG_FUNCTION (this << ueDev << sourceEnbDev << targetEnbDev);
753  NS_ASSERT_MSG (m_epcHelper, "Handover requires the use of the EPC - did you forget to call LteHelper::SetEpcHelper () ?");
754  Simulator::Schedule (hoTime, &LteHelper::DoHandoverRequest, this, ueDev, sourceEnbDev, targetEnbDev);
755 }
756 
757 void
758 LteHelper::DoHandoverRequest (Ptr<NetDevice> ueDev, Ptr<NetDevice> sourceEnbDev, Ptr<NetDevice> targetEnbDev)
759 {
760  NS_LOG_FUNCTION (this << ueDev << sourceEnbDev << targetEnbDev);
761 
762  uint16_t targetCellId = targetEnbDev->GetObject<LteEnbNetDevice> ()->GetCellId ();
763  Ptr<LteEnbRrc> sourceRrc = sourceEnbDev->GetObject<LteEnbNetDevice> ()->GetRrc ();
764  uint16_t rnti = ueDev->GetObject<LteUeNetDevice> ()->GetRrc ()->GetRnti ();
765  sourceRrc->SendHandoverRequest (rnti, targetCellId);
766 }
767 
768 
769 
770 
771 
772 void
774 {
775  NS_LOG_FUNCTION (this);
776  for (NetDeviceContainer::Iterator i = ueDevices.Begin (); i != ueDevices.End (); ++i)
777  {
778  ActivateDataRadioBearer (*i, bearer);
779  }
780 }
781 
782 void
784 {
785  LogComponentEnable ("LteHelper", LOG_LEVEL_ALL);
786  LogComponentEnable ("LteEnbRrc", LOG_LEVEL_ALL);
787  LogComponentEnable ("LteUeRrc", LOG_LEVEL_ALL);
788  LogComponentEnable ("LteEnbMac", LOG_LEVEL_ALL);
789  LogComponentEnable ("LteUeMac", LOG_LEVEL_ALL);
790  LogComponentEnable ("LteRlc", LOG_LEVEL_ALL);
791  LogComponentEnable ("LteRlcUm", LOG_LEVEL_ALL);
792  LogComponentEnable ("LteRlcAm", LOG_LEVEL_ALL);
793  LogComponentEnable ("RrFfMacScheduler", LOG_LEVEL_ALL);
794  LogComponentEnable ("PfFfMacScheduler", LOG_LEVEL_ALL);
795 
796  LogComponentEnable ("LtePhy", LOG_LEVEL_ALL);
797  LogComponentEnable ("LteEnbPhy", LOG_LEVEL_ALL);
798  LogComponentEnable ("LteUePhy", LOG_LEVEL_ALL);
799  LogComponentEnable ("LteSpectrumValueHelper", LOG_LEVEL_ALL);
800  LogComponentEnable ("LteSpectrumPhy", LOG_LEVEL_ALL);
801  LogComponentEnable ("LteInterference", LOG_LEVEL_ALL);
802  LogComponentEnable ("LteSinrChunkProcessor", LOG_LEVEL_ALL);
803 
804  std::string propModelStr = m_dlPathlossModelFactory.GetTypeId ().GetName ().erase (0,5).c_str ();
805  LogComponentEnable ("LteNetDevice", LOG_LEVEL_ALL);
806  LogComponentEnable ("LteUeNetDevice", LOG_LEVEL_ALL);
807  LogComponentEnable ("LteEnbNetDevice", LOG_LEVEL_ALL);
808 
809  LogComponentEnable ("RadioBearerStatsCalculator", LOG_LEVEL_ALL);
810  LogComponentEnable ("LteStatsCalculator", LOG_LEVEL_ALL);
811  LogComponentEnable ("MacStatsCalculator", LOG_LEVEL_ALL);
812  LogComponentEnable ("PhyTxStatsCalculator", LOG_LEVEL_ALL);
813  LogComponentEnable ("PhyRxStatsCalculator", LOG_LEVEL_ALL);
814  LogComponentEnable ("PhyStatsCalculator", LOG_LEVEL_ALL);
815 
816 
817 }
818 
819 void
821 {
822  EnablePhyTraces ();
823  EnableMacTraces ();
824  EnableRlcTraces ();
825  EnablePdcpTraces ();
826 }
827 
828 void
830 {
831  NS_ASSERT_MSG (m_rlcStats == 0, "please make sure that LteHelper::EnableRlcTraces is called at most once");
832  m_rlcStats = CreateObject<RadioBearerStatsCalculator> ("RLC");
833  m_radioBearerStatsConnector.EnableRlcStats (m_rlcStats);
834 }
835 
836 int64_t
838 {
839  int64_t currentStream = stream;
840  Ptr<NetDevice> netDevice;
841  for (NetDeviceContainer::Iterator i = c.Begin (); i != c.End (); ++i)
842  {
843  netDevice = (*i);
844  Ptr<LteEnbNetDevice> lteEnb = DynamicCast<LteEnbNetDevice> (netDevice);
845  if (lteEnb)
846  {
847  Ptr<LteSpectrumPhy> dlPhy = lteEnb->GetPhy ()->GetDownlinkSpectrumPhy ();
848  Ptr<LteSpectrumPhy> ulPhy = lteEnb->GetPhy ()->GetUplinkSpectrumPhy ();
849  currentStream += dlPhy->AssignStreams (currentStream);
850  currentStream += ulPhy->AssignStreams (currentStream);
851  }
852  Ptr<LteUeNetDevice> lteUe = DynamicCast<LteUeNetDevice> (netDevice);
853  if (lteUe)
854  {
855  Ptr<LteSpectrumPhy> dlPhy = lteUe->GetPhy ()->GetDownlinkSpectrumPhy ();
856  Ptr<LteSpectrumPhy> ulPhy = lteUe->GetPhy ()->GetUplinkSpectrumPhy ();
857  Ptr<LteUeMac> ueMac = lteUe->GetMac ();
858  currentStream += dlPhy->AssignStreams (currentStream);
859  currentStream += ulPhy->AssignStreams (currentStream);
860  currentStream += ueMac->AssignStreams (currentStream);
861  }
862  }
863  return (currentStream - stream);
864 }
865 
866 uint64_t
867 FindImsiFromEnbRlcPath (std::string path)
868 {
869  NS_LOG_FUNCTION (path);
870  // Sample path input:
871  // /NodeList/#NodeId/DeviceList/#DeviceId/LteEnbRrc/UeMap/#C-RNTI/DataRadioBearerMap/#LCID/LteRlc/RxPDU
872 
873  // We retrieve the UeManager associated to the C-RNTI and perform the IMSI lookup
874  std::string ueMapPath = path.substr (0, path.find ("/DataRadioBearerMap"));
875  Config::MatchContainer match = Config::LookupMatches (ueMapPath);
876 
877  if (match.GetN () != 0)
878  {
879  Ptr<Object> ueInfo = match.Get (0);
880  NS_LOG_LOGIC ("FindImsiFromEnbRlcPath: " << path << ", " << ueInfo->GetObject<UeManager> ()->GetImsi ());
881  return ueInfo->GetObject<UeManager> ()->GetImsi ();
882  }
883  else
884  {
885  NS_FATAL_ERROR ("Lookup " << ueMapPath << " got no matches");
886  }
887 }
888 
889 uint64_t
890 FindImsiFromUePhy (std::string path)
891 {
892  NS_LOG_FUNCTION (path);
893  // Sample path input:
894  // /NodeList/#NodeId/DeviceList/#DeviceId/LteUePhy
895 
896  // We retrieve the UeInfo associated to the C-RNTI and perform the IMSI lookup
897  std::string ueRlcPath = path.substr (0, path.find ("/LteUePhy"));
898  ueRlcPath += "/LteUeRrc";
899  Config::MatchContainer match = Config::LookupMatches (ueRlcPath);
900 
901  if (match.GetN () != 0)
902  {
903  Ptr<Object> ueRrc = match.Get (0);
904  return ueRrc->GetObject<LteUeRrc> ()->GetImsi ();
905  }
906  else
907  {
908  NS_FATAL_ERROR ("Lookup " << ueRlcPath << " got no matches");
909  }
910  return 0;
911 }
912 
913 
914 uint64_t
915 FindImsiFromLteNetDevice (std::string path)
916 {
917  NS_LOG_FUNCTION (path);
918  // Sample path input:
919  // /NodeList/#NodeId/DeviceList/#DeviceId/
920 
921  // We retrieve the Imsi associated to the LteUeNetDevice
922  Config::MatchContainer match = Config::LookupMatches (path);
923 
924  if (match.GetN () != 0)
925  {
926  Ptr<Object> ueNetDevice = match.Get (0);
927  NS_LOG_LOGIC ("FindImsiFromLteNetDevice: " << path << ", " << ueNetDevice->GetObject<LteUeNetDevice> ()->GetImsi ());
928  return ueNetDevice->GetObject<LteUeNetDevice> ()->GetImsi ();
929  }
930  else
931  {
932  NS_FATAL_ERROR ("Lookup " << path << " got no matches");
933  }
934 }
935 
936 uint16_t
937 FindCellIdFromEnbRlcPath (std::string path)
938 {
939  NS_LOG_FUNCTION (path);
940  // Sample path input:
941  // /NodeList/#NodeId/DeviceList/#DeviceId/LteEnbRrc/UeMap/#C-RNTI/DataRadioBearerMap/#LCID/LteRlc/RxPDU
942 
943  // We retrieve the CellId associated to the Enb
944  std::string enbNetDevicePath = path.substr (0, path.find ("/LteEnbRrc"));
945  Config::MatchContainer match = Config::LookupMatches (enbNetDevicePath);
946  if (match.GetN () != 0)
947  {
948  Ptr<Object> enbNetDevice = match.Get (0);
949  NS_LOG_LOGIC ("FindCellIdFromEnbRlcPath: " << path << ", " << enbNetDevice->GetObject<LteEnbNetDevice> ()->GetCellId ());
950  return enbNetDevice->GetObject<LteEnbNetDevice> ()->GetCellId ();
951  }
952  else
953  {
954  NS_FATAL_ERROR ("Lookup " << enbNetDevicePath << " got no matches");
955  }
956 }
957 
958 uint64_t
959 FindImsiFromEnbMac (std::string path, uint16_t rnti)
960 {
961  NS_LOG_FUNCTION (path << rnti);
962 
963  // /NodeList/#NodeId/DeviceList/#DeviceId/LteEnbMac/DlScheduling
964  std::ostringstream oss;
965  std::string p = path.substr (0, path.find ("/LteEnbMac"));
966  oss << rnti;
967  p += "/LteEnbRrc/UeMap/" + oss.str ();
968  uint64_t imsi = FindImsiFromEnbRlcPath (p);
969  NS_LOG_LOGIC ("FindImsiFromEnbMac: " << path << ", " << rnti << ", " << imsi);
970  return imsi;
971 }
972 
973 uint16_t
974 FindCellIdFromEnbMac (std::string path, uint16_t rnti)
975 {
976  NS_LOG_FUNCTION (path << rnti);
977  // /NodeList/#NodeId/DeviceList/#DeviceId/LteEnbMac/DlScheduling
978  std::ostringstream oss;
979  std::string p = path.substr (0, path.find ("/LteEnbMac"));
980  oss << rnti;
981  p += "/LteEnbRrc/UeMap/" + oss.str ();
982  uint16_t cellId = FindCellIdFromEnbRlcPath (p);
983  NS_LOG_LOGIC ("FindCellIdFromEnbMac: " << path << ", "<< rnti << ", " << cellId);
984  return cellId;
985 }
986 
987 
988 uint64_t
989 FindImsiForEnb (std::string path, uint16_t rnti)
990 {
991  NS_LOG_FUNCTION (path << rnti);
992  uint64_t imsi = 0;
993  if (path.find ("/DlPhyTransmission"))
994  {
995  // /NodeList/0/DeviceList/0/LteEnbPhy/DlPhyTransmission/LteEnbRrc/UeMap/1
996  std::ostringstream oss;
997  std::string p = path.substr (0, path.find ("/LteEnbPhy"));
998  oss << rnti;
999  p += "/LteEnbRrc/UeMap/" + oss.str ();
1000  imsi = FindImsiFromEnbRlcPath (p);
1001  NS_LOG_LOGIC ("FindImsiForEnb[Tx]: " << path << ", " << rnti << ", " << imsi);
1002  }
1003  else if (path.find ("/UlPhyReception"))
1004  {
1005  std::string p = path.substr (0, path.find ("/LteUePhy"));
1006  imsi = FindImsiFromLteNetDevice (p);
1007  NS_LOG_LOGIC ("FindImsiForEnb[Rx]: " << path << ", " << rnti << ", " << imsi);
1008  }
1009  return imsi;
1010 }
1011 
1012 
1013 uint64_t
1014 FindImsiForUe (std::string path, uint16_t rnti)
1015 {
1016  NS_LOG_FUNCTION (path << rnti);
1017  uint64_t imsi = 0;
1018  if (path.find ("/UlPhyTransmission"))
1019  {
1020  std::string p = path.substr (0, path.find ("/LteUePhy"));
1021  imsi = FindImsiFromLteNetDevice (p);
1022  NS_LOG_LOGIC ("FindImsiForUe[Tx]: " << path << ", " << rnti << ", " << imsi);
1023  }
1024  else if (path.find ("/DlPhyReception"))
1025  {
1026  // /NodeList/0/DeviceList/0/LteEnbPhy/LteSpectrumPhy
1027  std::ostringstream oss;
1028  std::string p = path.substr (0, path.find ("/LteEnbPhy"));
1029  oss << rnti;
1030  p += "/LteEnbRrc/UeMap/" + oss.str ();
1031  imsi = FindImsiFromEnbRlcPath (p);
1032  NS_LOG_LOGIC ("FindImsiForUe[Rx]: " << path << ", " << rnti << ", " << imsi);
1033  }
1034  return imsi;
1035 }
1036 
1037 void
1038 DlPhyTransmissionCallback (Ptr<PhyTxStatsCalculator> phyTxStats,
1039  std::string path, PhyTransmissionStatParameters params)
1040 {
1041  NS_LOG_FUNCTION (phyTxStats << path);
1042  uint64_t imsi = 0;
1043  std::ostringstream pathAndRnti;
1044  pathAndRnti << path << "/" << params.m_rnti;
1045  if (phyTxStats->ExistsImsiPath (pathAndRnti.str ()) == true)
1046  {
1047  imsi = phyTxStats->GetImsiPath (pathAndRnti.str ());
1048  }
1049  else
1050  {
1051  imsi = FindImsiForEnb (path, params.m_rnti);
1052  phyTxStats->SetImsiPath (pathAndRnti.str (), imsi);
1053  }
1054 
1055  params.m_imsi = imsi;
1056  phyTxStats->DlPhyTransmission (params);
1057 }
1058 
1059 void
1060 UlPhyTransmissionCallback (Ptr<PhyTxStatsCalculator> phyTxStats,
1061  std::string path, PhyTransmissionStatParameters params)
1062 {
1063  NS_LOG_FUNCTION (phyTxStats << path);
1064  uint64_t imsi = 0;
1065  std::ostringstream pathAndRnti;
1066  pathAndRnti << path << "/" << params.m_rnti;
1067  if (phyTxStats->ExistsImsiPath (pathAndRnti.str ()) == true)
1068  {
1069  imsi = phyTxStats->GetImsiPath (pathAndRnti.str ());
1070  }
1071  else
1072  {
1073  imsi = FindImsiForUe (path, params.m_rnti);
1074  phyTxStats->SetImsiPath (pathAndRnti.str (), imsi);
1075  }
1076 
1077  params.m_imsi = imsi;
1078  phyTxStats->UlPhyTransmission (params);
1079 }
1080 
1081 
1082 void
1083 DlPhyReceptionCallback (Ptr<PhyRxStatsCalculator> phyRxStats,
1084  std::string path, PhyReceptionStatParameters params)
1085 {
1086  NS_LOG_FUNCTION (phyRxStats << path);
1087  uint64_t imsi = 0;
1088  std::ostringstream pathAndRnti;
1089  pathAndRnti << path << "/" << params.m_rnti;
1090  if (phyRxStats->ExistsImsiPath (pathAndRnti.str ()) == true)
1091  {
1092  imsi = phyRxStats->GetImsiPath (pathAndRnti.str ());
1093  }
1094  else
1095  {
1096  imsi = FindImsiForUe (path, params.m_rnti);
1097  phyRxStats->SetImsiPath (pathAndRnti.str (), imsi);
1098  }
1099 
1100  params.m_imsi = imsi;
1101  phyRxStats->DlPhyReception (params);
1102 }
1103 
1104 void
1105 UlPhyReceptionCallback (Ptr<PhyRxStatsCalculator> phyRxStats,
1106  std::string path, PhyReceptionStatParameters params)
1107 {
1108  NS_LOG_FUNCTION (phyRxStats << path);
1109  uint64_t imsi = 0;
1110  std::ostringstream pathAndRnti;
1111  pathAndRnti << path << "/" << params.m_rnti;
1112  if (phyRxStats->ExistsImsiPath (pathAndRnti.str ()) == true)
1113  {
1114  imsi = phyRxStats->GetImsiPath (pathAndRnti.str ());
1115  }
1116  else
1117  {
1118  imsi = FindImsiForEnb (path, params.m_rnti);
1119  phyRxStats->SetImsiPath (pathAndRnti.str (), imsi);
1120  }
1121 
1122  params.m_imsi = imsi;
1123  phyRxStats->UlPhyReception (params);
1124 }
1125 
1126 void
1128 {
1129  EnableDlPhyTraces ();
1130  EnableUlPhyTraces ();
1135 }
1136 
1137 void
1139 {
1140  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbPhy/DlPhyTransmission",
1141  MakeBoundCallback (&DlPhyTransmissionCallback, m_phyTxStats));
1142 }
1143 
1144 void
1146 {
1147  Config::Connect ("/NodeList/*/DeviceList/*/LteUePhy/UlPhyTransmission",
1148  MakeBoundCallback (&UlPhyTransmissionCallback, m_phyTxStats));
1149 }
1150 
1151 void
1153 {
1154  Config::Connect ("/NodeList/*/DeviceList/*/LteUePhy/DlSpectrumPhy/DlPhyReception",
1155  MakeBoundCallback (&DlPhyReceptionCallback, m_phyRxStats));
1156 }
1157 
1158 void
1160 {
1161  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbPhy/UlSpectrumPhy/UlPhyReception",
1162  MakeBoundCallback (&UlPhyReceptionCallback, m_phyRxStats));
1163 }
1164 
1165 
1166 
1167 void
1168 DlSchedulingCallback (Ptr<MacStatsCalculator> macStats,
1169  std::string path, uint32_t frameNo, uint32_t subframeNo,
1170  uint16_t rnti, uint8_t mcsTb1, uint16_t sizeTb1,
1171  uint8_t mcsTb2, uint16_t sizeTb2)
1172 {
1173  NS_LOG_FUNCTION (macStats << path);
1174  uint64_t imsi = 0;
1175  std::ostringstream pathAndRnti;
1176  pathAndRnti << path << "/" << rnti;
1177  if (macStats->ExistsImsiPath (pathAndRnti.str ()) == true)
1178  {
1179  imsi = macStats->GetImsiPath (pathAndRnti.str ());
1180  }
1181  else
1182  {
1183  imsi = FindImsiFromEnbMac (path, rnti);
1184  macStats->SetImsiPath (pathAndRnti.str (), imsi);
1185  }
1186 
1187  uint16_t cellId = 0;
1188  if (macStats->ExistsCellIdPath (pathAndRnti.str ()) == true)
1189  {
1190  cellId = macStats->GetCellIdPath (pathAndRnti.str ());
1191  }
1192  else
1193  {
1194  cellId = FindCellIdFromEnbMac (path, rnti);
1195  macStats->SetCellIdPath (pathAndRnti.str (), cellId);
1196  }
1197 
1198  macStats->DlScheduling (cellId, imsi, frameNo, subframeNo, rnti, mcsTb1, sizeTb1, mcsTb2, sizeTb2);
1199 }
1200 
1201 
1202 
1203 void
1205 {
1206  EnableDlMacTraces ();
1207  EnableUlMacTraces ();
1208 }
1209 
1210 
1211 void
1213 {
1215  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbMac/DlScheduling",
1216  MakeBoundCallback (&DlSchedulingCallback, m_macStats));
1217 }
1218 
1219 void
1220 UlSchedulingCallback (Ptr<MacStatsCalculator> macStats, std::string path,
1221  uint32_t frameNo, uint32_t subframeNo, uint16_t rnti,
1222  uint8_t mcs, uint16_t size)
1223 {
1224  NS_LOG_FUNCTION (macStats << path);
1225 
1226  uint64_t imsi = 0;
1227  std::ostringstream pathAndRnti;
1228  pathAndRnti << path << "/" << rnti;
1229  if (macStats->ExistsImsiPath (pathAndRnti.str ()) == true)
1230  {
1231  imsi = macStats->GetImsiPath (pathAndRnti.str ());
1232  }
1233  else
1234  {
1235  imsi = FindImsiFromEnbMac (path, rnti);
1236  macStats->SetImsiPath (pathAndRnti.str (), imsi);
1237  }
1238  uint16_t cellId = 0;
1239  if (macStats->ExistsCellIdPath (pathAndRnti.str ()) == true)
1240  {
1241  cellId = macStats->GetCellIdPath (pathAndRnti.str ());
1242  }
1243  else
1244  {
1245  cellId = FindCellIdFromEnbMac (path, rnti);
1246  macStats->SetCellIdPath (pathAndRnti.str (), cellId);
1247  }
1248 
1249  macStats->UlScheduling (cellId, imsi, frameNo, subframeNo, rnti, mcs, size);
1250 }
1251 
1252 void
1254 {
1256  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbMac/UlScheduling",
1257  MakeBoundCallback (&UlSchedulingCallback, m_macStats));
1258 }
1259 
1260 void
1261 ReportCurrentCellRsrpSinrCallback (Ptr<PhyStatsCalculator> phyStats,
1262  std::string path, uint16_t cellId, uint16_t rnti,
1263  double rsrp, double sinr)
1264 {
1265  NS_LOG_FUNCTION (phyStats << path);
1266  uint64_t imsi = 0;
1267  std::string pathUePhy = path.substr (0, path.find ("/ReportCurrentCellRsrpSinr"));
1268  if (phyStats->ExistsImsiPath (pathUePhy) == true)
1269  {
1270  imsi = phyStats->GetImsiPath (pathUePhy);
1271  }
1272  else
1273  {
1274  imsi = FindImsiFromUePhy (pathUePhy);
1275  phyStats->SetImsiPath (pathUePhy, imsi);
1276  }
1277 
1278  phyStats->ReportCurrentCellRsrpSinr (cellId, imsi, rnti, rsrp,sinr);
1279 }
1280 
1281 void
1283 {
1285  Config::Connect ("/NodeList/*/DeviceList/*/LteUePhy/ReportCurrentCellRsrpSinr",
1286  MakeBoundCallback (&ReportCurrentCellRsrpSinrCallback, m_phyStats));
1287 }
1288 
1289 void
1290 ReportUeSinr (Ptr<PhyStatsCalculator> phyStats, std::string path,
1291  uint16_t cellId, uint16_t rnti, double sinrLinear)
1292 {
1293  NS_LOG_FUNCTION (phyStats << path);
1294 
1295  uint64_t imsi = 0;
1296  std::ostringstream pathAndRnti;
1297  pathAndRnti << path << "/" << rnti;
1298  std::string pathEnbMac = path.substr (0, path.find ("LteEnbPhy/ReportUeSinr"));
1299  pathEnbMac += "LteEnbMac/DlScheduling";
1300  if (phyStats->ExistsImsiPath (pathAndRnti.str ()) == true)
1301  {
1302  imsi = phyStats->GetImsiPath (pathAndRnti.str ());
1303  }
1304  else
1305  {
1306  imsi = FindImsiFromEnbMac (pathEnbMac, rnti);
1307  phyStats->SetImsiPath (pathAndRnti.str (), imsi);
1308  }
1309 
1310  phyStats->ReportUeSinr (cellId, imsi, rnti, sinrLinear);
1311 }
1312 
1313 void
1314 ReportInterference (Ptr<PhyStatsCalculator> phyStats, std::string path,
1315  uint16_t cellId, Ptr<SpectrumValue> interference)
1316 {
1317  NS_LOG_FUNCTION (phyStats << path);
1318  phyStats->ReportInterference (cellId, interference);
1319 }
1320 
1321 void
1323 {
1325  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbPhy/ReportUeSinr",
1326  MakeBoundCallback (&ReportUeSinr, m_phyStats));
1327  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbPhy/ReportInterference",
1328  MakeBoundCallback (&ReportInterference, m_phyStats));
1329 
1330 }
1331 
1334 {
1335  return m_rlcStats;
1336 }
1337 
1338 void
1340 {
1341  NS_ASSERT_MSG (m_pdcpStats == 0, "please make sure that LteHelper::EnablePdcpTraces is called at most once");
1342  m_pdcpStats = CreateObject<RadioBearerStatsCalculator> ("PDCP");
1343  m_radioBearerStatsConnector.EnablePdcpStats (m_pdcpStats);
1344 }
1345 
1348 {
1349  return m_pdcpStats;
1350 }
1351 
1352 } // namespace ns3
Iterator Begin(void) const
Get an iterator which refers to the first NetDevice in the container.
TypeId GetTypeId(void) const
keep track of time unit.
Definition: nstime.h:149
void SetPathlossModelAttribute(std::string n, const AttributeValue &v)
Definition: lte-helper.cc:209
virtual void AddPropagationLossModel(Ptr< PropagationLossModel > loss)=0
void EnableDlRxPhyTraces(void)
Definition: lte-helper.cc:1152
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
NetDeviceContainer InstallEnbDevice(NodeContainer c)
Definition: lte-helper.cc:285
void EnableLogComponents(void)
Definition: lte-helper.cc:783
void HandoverRequest(Time hoTime, Ptr< NetDevice > ueDev, Ptr< NetDevice > sourceEnbDev, Ptr< NetDevice > targetEnbDev)
Definition: lte-helper.cc:750
Hold a value for an Attribute.
Definition: attribute.h:51
void EnableDlPhyTraces(void)
Definition: lte-helper.cc:1282
void SetCellIdPath(std::string path, uint16_t cellId)
virtual void ReceiveLteControlMessageList(std::list< Ptr< LteControlMessage > >)
PhySpectrum received a new list of LteControlMessage.
Definition: lte-enb-phy.cc:446
void SetUeAntennaModelAttribute(std::string n, const AttributeValue &v)
Definition: lte-helper.cc:246
void SetFadingModel(std::string model)
Definition: lte-helper.cc:253
static Ptr< EpcTft > Default()
Definition: epc-tft.cc:141
void ReportUeSinr(uint16_t cellId, uint64_t imsi, uint16_t rnti, double sinrLinear)
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
void EnableRlcTraces(void)
Definition: lte-helper.cc:829
void SetTypeId(TypeId tid)
Iterator End(void) const
Get an iterator which indicates past-the-last Node in the container.
bool SetAttributeFailSafe(std::string name, const AttributeValue &value)
Definition: object-base.cc:180
virtual void DoDispose(void)
Definition: object.cc:335
#define NS_LOG_INFO(msg)
Definition: log.h:264
void SetUeAntennaModelType(std::string type)
Definition: lte-helper.cc:239
#define NS_LOG_FUNCTION_NOARGS()
Definition: log.h:275
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Definition: lte-helper.cc:837
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:728
void ActivateDataRadioBearer(NetDeviceContainer ueDevices, EpsBearer bearer)
Definition: lte-helper.cc:773
a 3d vector
Definition: vector.h:31
void EnableUlRxPhyTraces(void)
Definition: lte-helper.cc:1159
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
void SetSchedulerType(std::string type)
Definition: lte-helper.cc:183
uint32_t GetN(void) const
Get the number of Ptr<NetDevice> stored in this container.
void EnablePdcpTraces(void)
Definition: lte-helper.cc:1339
void AttachToClosestEnb(NetDeviceContainer ueDevices, NetDeviceContainer enbDevices)
Definition: lte-helper.cc:597
Keep track of the current position and velocity of an object.
static double GetCarrierFrequency(uint16_t earfcn)
Config::MatchContainer LookupMatches(std::string path)
Definition: config.cc:739
Ptr< Application > GetApplication(uint32_t index) const
Definition: node.cc:159
double CalculateDistance(const Vector3D &a, const Vector3D &b)
Definition: vector.cc:71
Ptr< Object > Create(void) const
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
void EnableTraces(void)
Definition: lte-helper.cc:820
virtual void ReceiveLteUlHarqFeedback(UlInfoListElement_s mes)
PhySpectrum generated a new UL HARQ feedback.
Definition: lte-enb-phy.cc:945
void SetSchedulerAttribute(std::string n, const AttributeValue &v)
Definition: lte-helper.cc:191
void Attach(NetDeviceContainer ueDevices, Ptr< NetDevice > enbDevice)
Definition: lte-helper.cc:562
holds a vector of ns3::NetDevice pointers
virtual void AddSpectrumPropagationLossModel(Ptr< SpectrumPropagationLossModel > loss)=0
void EnablePhyTraces(void)
Definition: lte-helper.cc:1127
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:502
uint64_t GetImsi(void)
Definition: lte-enb-rrc.cc:942
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
void SetEnbAntennaModelType(std::string type)
Definition: lte-helper.cc:225
uint32_t GetN(void) const
Definition: config.cc:63
void SetSpectrumChannelType(std::string type)
Definition: lte-helper.cc:271
void SetFadingModelAttribute(std::string n, const AttributeValue &v)
Definition: lte-helper.cc:265
void EnableDlMacTraces(void)
Definition: lte-helper.cc:1212
virtual void ReceiveLteDlHarqFeedback(DlInfoListElement_s mes)
PhySpectrum generated a new DL HARQ feedback.
Definition: lte-ue-phy.cc:1041
void ActivateDedicatedEpsBearer(NetDeviceContainer ueDevices, EpsBearer bearer, Ptr< EpcTft > tft)
Definition: lte-helper.cc:629
keep track of a set of node pointers.
void EnableUlTxPhyTraces(void)
Definition: lte-helper.cc:1145
void DlScheduling(uint16_t cellId, uint64_t imsi, uint32_t frameNo, uint32_t subframeNo, uint16_t rnti, uint8_t mcsTb1, uint16_t sizeTb1, uint8_t mcsTb2, uint16_t sizeTb2)
Iterator Begin(void) const
Get an iterator which refers to the first Node in the container.
bool ExistsCellIdPath(std::string path)
void AddX2Interface(NodeContainer enbNodes)
Definition: lte-helper.cc:727
Ptr< Object > Get(uint32_t i) const
Definition: config.cc:69
std::string GetName(void) const
Definition: type-id.cc:518
void Set(std::string name, const AttributeValue &value)
void EnableUlPhyTraces(void)
Definition: lte-helper.cc:1322
hold a set of objects which match a specific search string.
Definition: config.h:127
void EnableDlTxPhyTraces(void)
Definition: lte-helper.cc:1138
void Receive(Ptr< Packet > p)
void EnableUlMacTraces(void)
Definition: lte-helper.cc:1253
uint16_t GetCellIdPath(std::string path)
uint64_t GetImsiPath(std::string path)
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
Ptr< RadioBearerStatsCalculator > GetRlcStats(void)
Definition: lte-helper.cc:1333
NetDeviceContainer InstallUeDevice(NodeContainer c)
Definition: lte-helper.cc:300
Ptr< RadioBearerStatsCalculator > GetPdcpStats(void)
Definition: lte-helper.cc:1347
virtual void DoDispose(void)
Definition: lte-helper.cc:166
instantiate subclasses of ns3::Object.
Modelize the propagation loss through a transmission medium.
void SetEpcHelper(Ptr< EpcHelper > h)
Definition: lte-helper.cc:176
uint32_t AddDevice(Ptr< NetDevice > device)
Definition: node.cc:119
#define NS_LOG_WARN(msg)
Definition: log.h:246
void SetPathlossModelType(std::string type)
Definition: lte-helper.cc:199
void Initialize(void)
Definition: object.cc:179
void SetEnbAntennaModelAttribute(std::string n, const AttributeValue &v)
Definition: lte-helper.cc:232
void SetSpectrumChannelAttribute(std::string n, const AttributeValue &v)
Definition: lte-helper.cc:278
void PhyPduReceived(Ptr< Packet > p)
PhySpectrum received a new PHY-PDU.
Definition: lte-ue-phy.cc:335
virtual void DoInitialize(void)
Definition: lte-helper.cc:76
spectrum-aware propagation loss model
void SetImsiPath(std::string path, uint64_t imsi)
void EnableMacTraces(void)
Definition: lte-helper.cc:1204
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if cond is true.
Definition: abort.h:98
Iterator End(void) const
Get an iterator which indicates past-the-last NetDevice in the container.
void SetAttribute(std::string name, const AttributeValue &value)
Definition: object-base.cc:160
Ptr< T > GetObject(void) const
Definition: object.h:332
A template-based reference counting class.
void PhyPduReceived(Ptr< Packet > p)
PhySpectrum received a new PHY-PDU.
Definition: lte-enb-phy.cc:387
bool ExistsImsiPath(std::string path)
virtual void DoInitialize(void)
Definition: object.cc:342
void UlScheduling(uint16_t cellId, uint64_t imsi, uint32_t frameNo, uint32_t subframeNo, uint16_t rnti, uint8_t mcs, uint16_t sizeTb)
void LogComponentEnable(char const *name, enum LogLevel level)
Definition: log.cc:311
void SetEnbDeviceAttribute(std::string n, const AttributeValue &v)
Definition: lte-helper.cc:217
void ReportCurrentCellRsrpSinr(uint16_t cellId, uint64_t imsi, uint16_t rnti, double rsrp, double sinr)