A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
lte-enb-phy.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2010 TELEMATICS LAB, DEE - Politecnico di Bari
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: Giuseppe Piro <g.piro@poliba.it>
19  * Marco Miozzo <mmiozzo@cttc.es>
20  */
21 
22 #include <ns3/object-factory.h>
23 #include <ns3/log.h>
24 #include <cmath>
25 #include <ns3/simulator.h>
26 #include <ns3/attribute-accessor-helper.h>
27 #include <ns3/double.h>
28 
29 
30 #include "lte-enb-phy.h"
31 #include "lte-ue-phy.h"
32 #include "lte-net-device.h"
33 #include "lte-spectrum-value-helper.h"
34 #include "lte-control-messages.h"
35 #include "lte-enb-net-device.h"
36 #include "lte-ue-rrc.h"
37 #include "lte-enb-mac.h"
38 #include <ns3/lte-common.h>
39 #include <ns3/lte-vendor-specific-parameters.h>
40 
41 // WILD HACK for the inizialization of direct eNB-UE ctrl messaging
42 #include <ns3/node-list.h>
43 #include <ns3/node.h>
44 #include <ns3/lte-ue-net-device.h>
45 #include <ns3/pointer.h>
46 
47 NS_LOG_COMPONENT_DEFINE ("LteEnbPhy");
48 
49 namespace ns3 {
50 
51 NS_OBJECT_ENSURE_REGISTERED (LteEnbPhy);
52 
53 // duration of the data part of a subframe in DL
54 // = 0.001 / 14 * 11 (fixed to 11 symbols) -1ns as margin to avoid overlapping simulator events
55 static const Time DL_DATA_DURATION = NanoSeconds (785714 -1);
56 
57 // delay from subframe start to transmission of the data in DL
58 // = 0.001 / 14 * 3 (ctrl fixed to 3 symbols)
59 static const Time DL_CTRL_DELAY_FROM_SUBFRAME_START = NanoSeconds (214286);
60 
62 // member SAP forwarders
64 
65 
67 {
68 public:
70 
71  // inherited from LteEnbPhySapProvider
72  virtual void SendMacPdu (Ptr<Packet> p);
73  virtual void SetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth);
74  virtual void SetCellId (uint16_t cellId);
76  virtual uint8_t GetMacChTtiDelay ();
77 
78 
79 private:
80  LteEnbPhy* m_phy;
81 };
82 
83 EnbMemberLteEnbPhySapProvider::EnbMemberLteEnbPhySapProvider (LteEnbPhy* phy) : m_phy (phy)
84 {
85 
86 }
87 
88 void
90 {
91  m_phy->DoSendMacPdu (p);
92 }
93 
94 void
95 EnbMemberLteEnbPhySapProvider::SetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth)
96 {
97  m_phy->DoSetBandwidth (ulBandwidth, dlBandwidth);
98 }
99 
100 void
101 EnbMemberLteEnbPhySapProvider::SetCellId (uint16_t cellId)
102 {
103  m_phy->DoSetCellId (cellId);
104 }
105 
106 void
108 {
109  m_phy->DoSendLteControlMessage (msg);
110 }
111 
112 uint8_t
114 {
115  return (m_phy->DoGetMacChTtiDelay ());
116 }
117 
118 
120 // generic LteEnbPhy methods
122 
123 
124 
126 {
127  NS_LOG_FUNCTION (this);
128  NS_FATAL_ERROR ("This constructor should not be called");
129 }
130 
132  : LtePhy (dlPhy, ulPhy),
133  m_enbPhySapUser (0),
134  m_enbCphySapUser (0),
135  m_nrFrames (0),
136  m_nrSubFrames (0),
137  m_srsPeriodicity (0),
138  m_srsStartTime (Seconds (0)),
139  m_currentSrsOffset (0),
140  m_interferenceSampleCounter (0)
141 {
142  m_enbPhySapProvider = new EnbMemberLteEnbPhySapProvider (this);
143  m_enbCphySapProvider = new MemberLteEnbCphySapProvider<LteEnbPhy> (this);
144  m_harqPhyModule = Create <LteHarqPhy> ();
145  m_downlinkSpectrumPhy->SetHarqPhyModule (m_harqPhyModule);
146  m_uplinkSpectrumPhy->SetHarqPhyModule (m_harqPhyModule);
148 }
149 
150 TypeId
151 LteEnbPhy::GetTypeId (void)
152 {
153  static TypeId tid = TypeId ("ns3::LteEnbPhy")
154  .SetParent<LtePhy> ()
155  .AddConstructor<LteEnbPhy> ()
156  .AddAttribute ("TxPower",
157  "Transmission power in dBm",
158  DoubleValue (30.0),
159  MakeDoubleAccessor (&LteEnbPhy::SetTxPower,
161  MakeDoubleChecker<double> ())
162  .AddAttribute ("NoiseFigure",
163  "Loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver."
164  " According to Wikipedia (http://en.wikipedia.org/wiki/Noise_figure), this is "
165  "\"the difference in decibels (dB) between"
166  " the noise output of the actual receiver to the noise output of an "
167  " ideal receiver with the same overall gain and bandwidth when the receivers "
168  " are connected to sources at the standard noise temperature T0.\" "
169  "In this model, we consider T0 = 290K.",
170  DoubleValue (5.0),
171  MakeDoubleAccessor (&LteEnbPhy::SetNoiseFigure,
173  MakeDoubleChecker<double> ())
174  .AddAttribute ("MacToChannelDelay",
175  "The delay in TTI units that occurs between a scheduling decision in the MAC and the actual start of the transmission by the PHY. This is intended to be used to model the latency of real PHY and MAC implementations.",
176  UintegerValue (2),
177  MakeUintegerAccessor (&LteEnbPhy::SetMacChDelay,
179  MakeUintegerChecker<uint8_t> ())
180  .AddTraceSource ("ReportUeSinr",
181  "Report UEs' averaged linear SINR",
183  .AddAttribute ("UeSinrSamplePeriod",
184  "The sampling period for reporting UEs' SINR stats (default value 1)",
185  UintegerValue (1),
186  MakeUintegerAccessor (&LteEnbPhy::m_srsSamplePeriod),
187  MakeUintegerChecker<uint16_t> ())
188  .AddTraceSource ("ReportInterference",
189  "Report linear interference power per PHY RB",
191  .AddAttribute ("InterferenceSamplePeriod",
192  "The sampling period for reporting interference stats (default value 1)",
193  UintegerValue (1),
194  MakeUintegerAccessor (&LteEnbPhy::m_interferenceSamplePeriod),
195  MakeUintegerChecker<uint16_t> ())
196  .AddTraceSource ("DlPhyTransmission",
197  "DL transmission PHY layer statistics.",
199  .AddAttribute ("DlSpectrumPhy",
200  "The downlink LteSpectrumPhy associated to this LtePhy",
202  PointerValue (),
203  MakePointerAccessor (&LteEnbPhy::GetDlSpectrumPhy),
204  MakePointerChecker <LteSpectrumPhy> ())
205  .AddAttribute ("UlSpectrumPhy",
206  "The uplink LteSpectrumPhy associated to this LtePhy",
208  PointerValue (),
209  MakePointerAccessor (&LteEnbPhy::GetUlSpectrumPhy),
210  MakePointerChecker <LteSpectrumPhy> ())
211  ;
212  return tid;
213 }
214 
215 
216 LteEnbPhy::~LteEnbPhy ()
217 {
218 }
219 
220 void
222 {
223  NS_LOG_FUNCTION (this);
224  m_ueAttached.clear ();
225  m_srsUeOffset.clear ();
226  delete m_enbPhySapProvider;
227  delete m_enbCphySapProvider;
229 }
230 
231 void
233 {
234  NS_LOG_FUNCTION (this);
235  Ptr<SpectrumValue> noisePsd = LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (m_ulEarfcn, m_ulBandwidth, m_noiseFigure);
236  m_uplinkSpectrumPhy->SetNoisePowerSpectralDensity (noisePsd);
238 }
239 
240 
241 void
243 {
244  m_enbPhySapUser = s;
245 }
246 
249 {
250  return (m_enbPhySapProvider);
251 }
252 
253 void
255 {
256  NS_LOG_FUNCTION (this);
257  m_enbCphySapUser = s;
258 }
259 
262 {
263  NS_LOG_FUNCTION (this);
264  return (m_enbCphySapProvider);
265 }
266 
267 void
269 {
270  NS_LOG_FUNCTION (this << pow);
271  m_txPower = pow;
272 }
273 
274 double
276 {
277  NS_LOG_FUNCTION (this);
278  return m_txPower;
279 }
280 
281 void
283 {
284  NS_LOG_FUNCTION (this << nf);
285  m_noiseFigure = nf;
286 }
287 
288 double
290 {
291  NS_LOG_FUNCTION (this);
292  return m_noiseFigure;
293 }
294 
295 void
297 {
298  NS_LOG_FUNCTION (this);
299  m_macChTtiDelay = delay;
300  for (int i = 0; i < m_macChTtiDelay; i++)
301  {
302  Ptr<PacketBurst> pb = CreateObject <PacketBurst> ();
303  m_packetBurstQueue.push_back (pb);
304  std::list<Ptr<LteControlMessage> > l;
305  m_controlMessagesQueue.push_back (l);
306  std::list<UlDciLteControlMessage> l1;
307  m_ulDciQueue.push_back (l1);
308  }
309  for (int i = 0; i < UL_PUSCH_TTIS_DELAY; i++)
310  {
311  std::list<UlDciLteControlMessage> l1;
312  m_ulDciQueue.push_back (l1);
313  }
314 }
315 
316 uint8_t
318 {
319  return (m_macChTtiDelay);
320 }
321 
324 {
325  return m_downlinkSpectrumPhy;
326 }
327 
330 {
331  return m_uplinkSpectrumPhy;
332 }
333 
334 bool
335 LteEnbPhy::AddUePhy (uint16_t rnti)
336 {
337  NS_LOG_FUNCTION (this << rnti);
338  std::set <uint16_t>::iterator it;
339  it = m_ueAttached.find (rnti);
340  if (it == m_ueAttached.end ())
341  {
342  m_ueAttached.insert (rnti);
343  return (true);
344  }
345  else
346  {
347  NS_LOG_ERROR ("UE already attached");
348  return (false);
349  }
350 }
351 
352 bool
353 LteEnbPhy::DeleteUePhy (uint16_t rnti)
354 {
355  NS_LOG_FUNCTION (this << rnti);
356  std::set <uint16_t>::iterator it;
357  it = m_ueAttached.find (rnti);
358  if (it == m_ueAttached.end ())
359  {
360  NS_LOG_ERROR ("UE not attached");
361  return (false);
362  }
363  else
364  {
365  m_ueAttached.erase (it);
366  return (true);
367  }
368 }
369 
370 
371 
372 void
374 {
375  NS_LOG_FUNCTION (this);
376  SetMacPdu (p);
377 }
378 
379 uint8_t
380 LteEnbPhy::DoGetMacChTtiDelay ()
381 {
382  return (m_macChTtiDelay);
383 }
384 
385 
386 void
388 {
389  NS_LOG_FUNCTION (this);
390  m_enbPhySapUser->ReceivePhyPdu (p);
391 }
392 
393 void
394 LteEnbPhy::SetDownlinkSubChannels (std::vector<int> mask)
395 {
396  NS_LOG_FUNCTION (this);
397  m_listOfDownlinkSubchannel = mask;
399  m_downlinkSpectrumPhy->SetTxPowerSpectralDensity (txPsd);
400 }
401 
402 std::vector<int>
404 {
405  NS_LOG_FUNCTION (this);
406  return m_listOfDownlinkSubchannel;
407 }
408 
411 {
412  NS_LOG_FUNCTION (this);
413 
415 
416  return psd;
417 }
418 
419 
420 void
422 {
423  NS_LOG_FUNCTION (this);
424 }
425 
426 
427 void
428 LteEnbPhy::DoSendLteControlMessage (Ptr<LteControlMessage> msg)
429 {
430  NS_LOG_FUNCTION (this << msg);
431  // queues the message (wait for MAC-PHY delay)
432  SetControlMessages (msg);
433 }
434 
435 
436 
437 void
439 {
440  NS_FATAL_ERROR ("Obsolete function");
441  NS_LOG_FUNCTION (this << msg);
442  m_enbPhySapUser->ReceiveLteControlMessage (msg);
443 }
444 
445 void
447 {
448  NS_LOG_FUNCTION (this);
449  std::list<Ptr<LteControlMessage> >::iterator it;
450  for (it = msgList.begin (); it != msgList.end(); it++)
451  {
452  switch ((*it)->GetMessageType ())
453  {
454  case LteControlMessage::RACH_PREAMBLE:
455  {
456  Ptr<RachPreambleLteControlMessage> rachPreamble = DynamicCast<RachPreambleLteControlMessage> (*it);
457  m_enbPhySapUser->ReceiveRachPreamble (rachPreamble->GetRapId ());
458  }
459  break;
460 
461  default:
462  m_enbPhySapUser->ReceiveLteControlMessage (*it);
463  break;
464  }
465  }
466 }
467 
468 
469 
470 void
472 {
473  NS_LOG_FUNCTION (this);
474 
475  ++m_nrFrames;
476  NS_LOG_INFO ("-----frame " << m_nrFrames << "-----");
477  m_nrSubFrames = 0;
478 
479  // send MIB at beginning of every frame
480  m_mib.systemFrameNumber = m_nrSubFrames;
481  Ptr<MibLteControlMessage> mibMsg = Create<MibLteControlMessage> ();
482  mibMsg->SetMib (m_mib);
483  m_controlMessagesQueue.at (0).push_back (mibMsg);
484 
485  StartSubFrame ();
486 }
487 
488 
489 void
491 {
492  NS_LOG_FUNCTION (this);
493 
494  ++m_nrSubFrames;
495  if (m_srsPeriodicity>0)
496  {
497  // might be 0 in case the eNB has no UEs attached
498  NS_ASSERT_MSG (m_nrFrames > 1, "the SRS index check code assumes that frameNo starts at 1");
499  NS_ASSERT_MSG (m_nrSubFrames > 0 && m_nrSubFrames <= 10, "the SRS index check code assumes that subframeNo starts at 1");
500  m_currentSrsOffset = (((m_nrFrames-1)*10 + (m_nrSubFrames-1)) % m_srsPeriodicity);
501  }
502  NS_LOG_INFO ("-----sub frame " << m_nrSubFrames << "-----");
503  m_harqPhyModule->SubframeIndication (m_nrFrames, m_nrSubFrames);
504 
505  // update info on TB to be received
506  std::list<UlDciLteControlMessage> uldcilist = DequeueUlDci ();
507  std::list<UlDciLteControlMessage>::iterator dciIt = uldcilist.begin ();
508  NS_LOG_DEBUG (this << " eNB Expected TBs " << uldcilist.size ());
509  for (dciIt = uldcilist.begin (); dciIt!=uldcilist.end (); dciIt++)
510  {
511  std::set <uint16_t>::iterator it2;
512  it2 = m_ueAttached.find ((*dciIt).GetDci ().m_rnti);
513 
514  if (it2 == m_ueAttached.end ())
515  {
516  NS_LOG_ERROR ("UE not attached");
517  }
518  else
519  {
520  // send info of TB to LteSpectrumPhy
521  // translate to allocation map
522  std::vector <int> rbMap;
523  for (int i = (*dciIt).GetDci ().m_rbStart; i < (*dciIt).GetDci ().m_rbStart + (*dciIt).GetDci ().m_rbLen; i++)
524  {
525  rbMap.push_back (i);
526  }
527  m_uplinkSpectrumPhy->AddExpectedTb ((*dciIt).GetDci ().m_rnti, (*dciIt).GetDci ().m_ndi, (*dciIt).GetDci ().m_tbSize, (*dciIt).GetDci ().m_mcs, rbMap, 0 /* always SISO*/, 0 /* no HARQ proc id in UL*/, 0 /*evaluated by LteSpectrumPhy*/, false /* UL*/);
528  if ((*dciIt).GetDci ().m_ndi==1)
529  {
530  NS_LOG_DEBUG (this << " RNTI " << (*dciIt).GetDci ().m_rnti << " NEW TB");
531  }
532  else
533  {
534  NS_LOG_DEBUG (this << " RNTI " << (*dciIt).GetDci ().m_rnti << " HARQ RETX");
535  }
536  }
537  }
538 
539  // process the current burst of control messages
540  std::list<Ptr<LteControlMessage> > ctrlMsg = GetControlMessages ();
541  m_dlDataRbMap.clear ();
542  if (ctrlMsg.size () > 0)
543  {
544  std::list<Ptr<LteControlMessage> >::iterator it;
545  it = ctrlMsg.begin ();
546  while (it != ctrlMsg.end ())
547  {
548  Ptr<LteControlMessage> msg = (*it);
549  if (msg->GetMessageType () == LteControlMessage::DL_DCI)
550  {
551  Ptr<DlDciLteControlMessage> dci = DynamicCast<DlDciLteControlMessage> (msg);
552  // get the tx power spectral density according to DL-DCI(s)
553  // translate the DCI to Spectrum framework
554  uint32_t mask = 0x1;
555  for (int i = 0; i < 32; i++)
556  {
557  if (((dci->GetDci ().m_rbBitmap & mask) >> i) == 1)
558  {
559  for (int k = 0; k < GetRbgSize (); k++)
560  {
561  m_dlDataRbMap.push_back ((i * GetRbgSize ()) + k);
562  //NS_LOG_DEBUG(this << " [enb]DL-DCI allocated PRB " << (i*GetRbgSize()) + k);
563  }
564  }
565  mask = (mask << 1);
566  }
567  // fire trace of DL Tx PHY stats
568  for (uint8_t i = 0; i < dci->GetDci ().m_mcs.size (); i++)
569  {
571  params.m_cellId = m_cellId;
572  params.m_imsi = 0; // it will be set by DlPhyTransmissionCallback in LteHelper
573  params.m_timestamp = Simulator::Now ().GetMilliSeconds ();
574  params.m_rnti = dci->GetDci ().m_rnti;
575  params.m_txMode = 0; // TBD
576  params.m_layer = i;
577  params.m_mcs = dci->GetDci ().m_mcs.at (i);
578  params.m_size = dci->GetDci ().m_tbsSize.at (i);
579  params.m_rv = dci->GetDci ().m_rv.at (i);
580  params.m_ndi = dci->GetDci ().m_ndi.at (i);
581  m_dlPhyTransmission (params);
582  }
583 
584  }
585  else if (msg->GetMessageType () == LteControlMessage::UL_DCI)
586  {
587  Ptr<UlDciLteControlMessage> dci = DynamicCast<UlDciLteControlMessage> (msg);
588  QueueUlDci (*dci);
589  }
590  else if (msg->GetMessageType () == LteControlMessage::RAR)
591  {
592  Ptr<RarLteControlMessage> rarMsg = DynamicCast<RarLteControlMessage> (msg);
593  for (std::list<RarLteControlMessage::Rar>::const_iterator it = rarMsg->RarListBegin (); it != rarMsg->RarListEnd (); ++it)
594  {
595  if (it->rarPayload.m_grant.m_ulDelay == true)
596  {
597  NS_FATAL_ERROR (" RAR delay is not yet implemented");
598  }
599  UlGrant_s ulGrant = it->rarPayload.m_grant;
600  // translate the UL grant in a standard UL-DCI and queue it
601  UlDciListElement_s dci;
602  dci.m_rnti = ulGrant.m_rnti;
603  dci.m_rbStart = ulGrant.m_rbStart;
604  dci.m_rbLen = ulGrant.m_rbLen;
605  dci.m_tbSize = ulGrant.m_tbSize;
606  dci.m_mcs = ulGrant.m_mcs;
607  dci.m_hopping = ulGrant.m_hopping;
608  dci.m_tpc = ulGrant.m_tpc;
609  dci.m_cqiRequest = ulGrant.m_cqiRequest;
610  dci.m_ndi = 1;
612  msg.SetDci (dci);
613  QueueUlDci (msg);
614  }
615  }
616  it++;
617 
618  }
619  }
620 
621  SendControlChannels (ctrlMsg);
622 
623  // send data frame
625  if (pb)
626  {
627  Simulator::Schedule (DL_CTRL_DELAY_FROM_SUBFRAME_START, // ctrl frame fixed to 3 symbols
629  this,pb);
630  }
631 
632  // trigger the MAC
633  m_enbPhySapUser->SubframeIndication (m_nrFrames, m_nrSubFrames);
634 
637  this);
638 
639 }
640 
641 void
643 {
644  NS_LOG_FUNCTION (this << " eNB " << m_cellId << " start tx ctrl frame");
645  // set the current tx power spectral density (full bandwidth)
646  std::vector <int> dlRb;
647  for (uint8_t i = 0; i < m_dlBandwidth; i++)
648  {
649  dlRb.push_back (i);
650  }
651  SetDownlinkSubChannels (dlRb);
652  NS_LOG_LOGIC (this << " eNB start TX CTRL");
653  m_downlinkSpectrumPhy->StartTxDlCtrlFrame (ctrlMsgList);
654 
655 }
656 
657 void
659 {
660  // set the current tx power spectral density
661  SetDownlinkSubChannels (m_dlDataRbMap);
662  // send the current burts of packets
663  NS_LOG_LOGIC (this << " eNB start TX DATA");
664  std::list<Ptr<LteControlMessage> > ctrlMsgList;
665  ctrlMsgList.clear ();
666  m_downlinkSpectrumPhy->StartTxDataFrame (pb, ctrlMsgList, DL_DATA_DURATION);
667 }
668 
669 
670 void
672 {
673  NS_LOG_FUNCTION (this << Simulator::Now ().GetSeconds ());
674  if (m_nrSubFrames == 10)
675  {
677  }
678  else
679  {
681  }
682 }
683 
684 
685 void
687 {
688  NS_LOG_FUNCTION (this << Simulator::Now ().GetSeconds ());
690 }
691 
692 
693 void
695 {
696  NS_LOG_FUNCTION (this << sinr << Simulator::Now () << m_srsStartTime);
697  // avoid processing SRSs sent with an old SRS configuration index
698  if (Simulator::Now () > m_srsStartTime)
699  {
701  m_enbPhySapUser->UlCqiReport (ulcqi);
702  }
703 }
704 
705 void
707 {
708  NS_LOG_FUNCTION (this << sinr);
710  m_enbPhySapUser->UlCqiReport (ulcqi);
711 }
712 
713 void
715 {
716  NS_LOG_FUNCTION (this << interf);
717  Ptr<SpectrumValue> interfCopy = Create<SpectrumValue> (interf);
718  m_interferenceSampleCounter++;
719  if (m_interferenceSampleCounter == m_interferenceSamplePeriod)
720  {
721  m_reportInterferenceTrace (m_cellId, interfCopy);
722  m_interferenceSampleCounter = 0;
723  }
724 }
725 
726 void
728 {
729  // not used by eNB
730 }
731 
732 
733 
736 {
737  NS_LOG_FUNCTION (this << sinr);
738  Values::const_iterator it;
740  ulcqi.m_ulCqi.m_type = UlCqi_s::PUSCH;
741  int i = 0;
742  for (it = sinr.ConstValuesBegin (); it != sinr.ConstValuesEnd (); it++)
743  {
744  double sinrdb = 10 * std::log10 ((*it));
745 // NS_LOG_DEBUG ("ULCQI RB " << i << " value " << sinrdb);
746  // convert from double to fixed point notation Sxxxxxxxxxxx.xxx
747  int16_t sinrFp = LteFfConverter::double2fpS11dot3 (sinrdb);
748  ulcqi.m_ulCqi.m_sinr.push_back (sinrFp);
749  i++;
750  }
751  return (ulcqi);
752 
753 }
754 
755 
756 void
757 LteEnbPhy::DoSetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth)
758 {
759  NS_LOG_FUNCTION (this << (uint32_t) ulBandwidth << (uint32_t) dlBandwidth);
760  m_ulBandwidth = ulBandwidth;
761  m_dlBandwidth = dlBandwidth;
762 
763  int Type0AllocationRbg[4] = {
764  10, // RGB size 1
765  26, // RGB size 2
766  63, // RGB size 3
767  110 // RGB size 4
768  }; // see table 7.1.6.1-1 of 36.213
769  for (int i = 0; i < 4; i++)
770  {
771  if (dlBandwidth < Type0AllocationRbg[i])
772  {
773  m_rbgSize = i + 1;
774  break;
775  }
776  }
777 }
778 
779 void
780 LteEnbPhy::DoSetEarfcn (uint16_t ulEarfcn, uint16_t dlEarfcn)
781 {
782  NS_LOG_FUNCTION (this << ulEarfcn << dlEarfcn);
783  m_ulEarfcn = ulEarfcn;
784  m_dlEarfcn = dlEarfcn;
785 }
786 
787 
788 void
789 LteEnbPhy::DoAddUe (uint16_t rnti)
790 {
791  NS_LOG_FUNCTION (this << rnti);
792 
793  bool success = AddUePhy (rnti);
794  NS_ASSERT_MSG (success, "AddUePhy() failed");
795 }
796 
797 void
798 LteEnbPhy::DoRemoveUe (uint16_t rnti)
799 {
800  NS_LOG_FUNCTION (this << rnti);
801 
802  bool success = DeleteUePhy (rnti);
803  NS_ASSERT_MSG (success, "DeleteUePhy() failed");
804 }
805 
806 
807 FfMacSchedSapProvider::SchedUlCqiInfoReqParameters
809 {
810  NS_LOG_FUNCTION (this << sinr);
811  Values::const_iterator it;
813  ulcqi.m_ulCqi.m_type = UlCqi_s::SRS;
814  int i = 0;
815  double srsSum = 0.0;
816  for (it = sinr.ConstValuesBegin (); it != sinr.ConstValuesEnd (); it++)
817  {
818  double sinrdb = 10 * log10 ((*it));
819  // NS_LOG_DEBUG ("ULCQI RB " << i << " value " << sinrdb);
820  // convert from double to fixed point notation Sxxxxxxxxxxx.xxx
821  int16_t sinrFp = LteFfConverter::double2fpS11dot3 (sinrdb);
822  srsSum += (*it);
823  ulcqi.m_ulCqi.m_sinr.push_back (sinrFp);
824  i++;
825  }
826  // Insert the user generated the srs as a vendor specific parameter
827  NS_LOG_DEBUG (this << " ENB RX UL-CQI of " << m_srsUeOffset.at (m_currentSrsOffset));
829  vsp.m_type = SRS_CQI_RNTI_VSP;
830  vsp.m_length = sizeof(SrsCqiRntiVsp);
831  Ptr<SrsCqiRntiVsp> rnti = Create <SrsCqiRntiVsp> (m_srsUeOffset.at (m_currentSrsOffset));
832  vsp.m_value = rnti;
833  ulcqi.m_vendorSpecificList.push_back (vsp);
834  // call SRS tracing method
835  CreateSrsReport (m_srsUeOffset.at (m_currentSrsOffset), srsSum / i);
836  return (ulcqi);
837 
838 }
839 
840 
841 void
842 LteEnbPhy::CreateSrsReport(uint16_t rnti, double srs)
843 {
844  NS_LOG_FUNCTION (this << rnti << srs);
845  std::map <uint16_t,uint16_t>::iterator it = m_srsSampleCounterMap.find (rnti);
846  if (it==m_srsSampleCounterMap.end ())
847  {
848  // create new entry
849  m_srsSampleCounterMap.insert (std::pair <uint16_t,uint16_t> (rnti, 0));
850  it = m_srsSampleCounterMap.find (rnti);
851  }
852  (*it).second++;
853  if ((*it).second == m_srsSamplePeriod)
854  {
855  m_reportUeSinr (m_cellId, rnti, srs);
856  (*it).second = 0;
857  }
858 }
859 
860 void
861 LteEnbPhy::DoSetTransmissionMode (uint16_t rnti, uint8_t txMode)
862 {
863  NS_LOG_FUNCTION (this << rnti << (uint16_t)txMode);
864  // UL supports only SISO MODE
865 }
866 
867 void
869 {
870  NS_LOG_FUNCTION (this);
871  m_ulDciQueue.at (UL_PUSCH_TTIS_DELAY - 1).push_back (m);
872 }
873 
874 std::list<UlDciLteControlMessage>
876 {
877  NS_LOG_FUNCTION (this);
878  if (m_ulDciQueue.at (0).size ()>0)
879  {
880  std::list<UlDciLteControlMessage> ret = m_ulDciQueue.at (0);
881  m_ulDciQueue.erase (m_ulDciQueue.begin ());
882  std::list<UlDciLteControlMessage> l;
883  m_ulDciQueue.push_back (l);
884  return (ret);
885  }
886  else
887  {
888  m_ulDciQueue.erase (m_ulDciQueue.begin ());
889  std::list<UlDciLteControlMessage> l;
890  m_ulDciQueue.push_back (l);
891  std::list<UlDciLteControlMessage> emptylist;
892  return (emptylist);
893  }
894 }
895 
896 void
897 LteEnbPhy::DoSetSrsConfigurationIndex (uint16_t rnti, uint16_t srcCi)
898 {
899  NS_LOG_FUNCTION (this);
900  uint16_t p = GetSrsPeriodicity (srcCi);
901  if (p!=m_srsPeriodicity)
902  {
903  // resize the array of offset -> re-initialize variables
904  m_srsUeOffset.clear ();
905  m_srsUeOffset.resize (p, 0);
906  m_srsPeriodicity = p;
907  // inhibit SRS until RRC Connection Reconfiguration propagates
908  // to UEs, otherwise we might be wrong in determining the UE who
909  // actually sent the SRS (if the UE was using a stale SRS config)
910  // if we use a static SRS configuration index, we can have a 0ms guard time
911  m_srsStartTime = Simulator::Now () + MilliSeconds (m_macChTtiDelay) + MilliSeconds (0);
912  }
913 
914  NS_LOG_DEBUG (this << " ENB SRS P " << m_srsPeriodicity << " RNTI " << rnti << " offset " << GetSrsSubframeOffset (srcCi) << " CI " << srcCi);
915  std::map <uint16_t,uint16_t>::iterator it = m_srsCounter.find (rnti);
916  if (it != m_srsCounter.end ())
917  {
918  (*it).second = GetSrsSubframeOffset (srcCi) + 1;
919  }
920  else
921  {
922  m_srsCounter.insert (std::pair<uint16_t, uint16_t> (rnti, GetSrsSubframeOffset (srcCi) + 1));
923  }
924  m_srsUeOffset.at (GetSrsSubframeOffset (srcCi)) = rnti;
925 
926 }
927 
928 
929 void
930 LteEnbPhy::DoSetMasterInformationBlock (LteRrcSap::MasterInformationBlock mib)
931 {
932  NS_LOG_FUNCTION (this);
933  m_mib = mib;
934 }
935 
936 
937 void
938 LteEnbPhy::SetHarqPhyModule (Ptr<LteHarqPhy> harq)
939 {
940  m_harqPhyModule = harq;
941 }
942 
943 
944 void
946 {
947  NS_LOG_FUNCTION (this);
948  // forward to scheduler
949  m_enbPhySapUser->UlInfoListElementHarqFeeback (mes);
950 }
951 
952 };
Values::const_iterator ConstValuesEnd() const
Time NanoSeconds(uint64_t ns)
create ns3::Time instances in units of nanoseconds.
Definition: nstime.h:629
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
void DoSetCellId(uint16_t cellId)
Definition: lte-phy.cc:245
virtual void SendMacPdu(Ptr< Packet > p)
Send the MAC PDU to the channel.
Definition: lte-enb-phy.cc:89
void SetDownlinkSubChannels(std::vector< int > mask)
set the resource blocks (a.k.a. sub channels) to be used in the downlink for transmission ...
Definition: lte-enb-phy.cc:394
void CalcChannelQualityForUe(std::vector< double > sinr, Ptr< LteSpectrumPhy > ue)
Calculate the channel quality for a given UE.
Definition: lte-enb-phy.cc:421
std::list< UlDciLteControlMessage > DequeueUlDci(void)
Definition: lte-enb-phy.cc:875
virtual uint8_t GetMacChTtiDelay()
Get the delay from MAC to Channel expressed in TTIs.
Definition: lte-enb-phy.cc:113
virtual void ReceiveLteControlMessageList(std::list< Ptr< LteControlMessage > >)
PhySpectrum received a new list of LteControlMessage.
Definition: lte-enb-phy.cc:446
uint16_t GetSrsPeriodicity(uint16_t srcCi) const
Definition: lte-phy.cc:147
double GetTti(void) const
Definition: lte-phy.cc:139
virtual Ptr< SpectrumValue > CreateTxPowerSpectralDensity()
Create the PSD for TX.
Definition: lte-enb-phy.cc:410
virtual void SendLteControlMessage(Ptr< LteControlMessage > msg)
Send SendLteControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel.
Definition: lte-enb-phy.cc:107
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
See section 4.3.2 ulDciListElement.
TracedCallback< uint16_t, uint16_t, double > m_reportUeSinr
Definition: lte-enb-phy.h:311
#define NS_LOG_INFO(msg)
Definition: log.h:264
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
See section 4.3.12 ulInfoListElement.
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
virtual void ReceiveRachPreamble(uint32_t prachId)=0
double GetNoiseFigure() const
Definition: lte-enb-phy.cc:289
void SetMacChDelay(uint8_t delay)
Definition: lte-enb-phy.cc:296
virtual void GenerateCtrlCqiReport(const SpectrumValue &sinr)
Definition: lte-enb-phy.cc:694
uint16_t GetSrsSubframeOffset(uint16_t srcCi) const
Definition: lte-phy.cc:165
void DoDispose()
Definition: lte-phy.cc:75
virtual void DoInitialize(void)
Definition: lte-enb-phy.cc:232
virtual void GenerateDataCqiReport(const SpectrumValue &sinr)
Definition: lte-enb-phy.cc:706
uint8_t GetRbgSize(void) const
Definition: lte-phy.cc:183
Ptr< LteSpectrumPhy > GetDlSpectrumPhy() const
Definition: lte-enb-phy.cc:323
virtual void ReceiveLteUlHarqFeedback(UlInfoListElement_s mes)
PhySpectrum generated a new UL HARQ feedback.
Definition: lte-enb-phy.cc:945
Hold an unsigned integer type.
Definition: uinteger.h:46
Define the RNTI that has generated the.
virtual void ReceiveLteControlMessage(Ptr< LteControlMessage > msg)
Receive the control message.
Definition: lte-enb-phy.cc:438
void StartSubFrame(void)
Start a LTE sub frame.
Definition: lte-enb-phy.cc:490
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
See section 4.3.3 vendorSpecifiListElement.
virtual void ReportInterference(const SpectrumValue &interf)
Definition: lte-enb-phy.cc:714
Substitutive structure for specifying BuildRarListElement_s::m_grant field.
void SendControlChannels(std::list< Ptr< LteControlMessage > > ctrlMsgList)
Send the PDCCH and PCFICH in the first 3 symbols.
Definition: lte-enb-phy.cc:642
double GetTxPower() const
Definition: lte-enb-phy.cc:275
virtual void UlInfoListElementHarqFeeback(UlInfoListElement_s params)=0
LteEnbPhySapProvider * GetLteEnbPhySapProvider()
Get the PHY SAP provider.
Definition: lte-enb-phy.cc:248
hold objects of type Ptr<T>
Definition: pointer.h:33
void SetControlMessages(Ptr< LteControlMessage > m)
Definition: lte-phy.cc:214
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
void SetTxPower(double pow)
Definition: lte-enb-phy.cc:268
void SetDci(UlDciListElement_s dci)
add a DCI into the message
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Definition: simulator.h:981
static Time Now(void)
Definition: simulator.cc:179
LteEnbCphySapProvider * GetLteEnbCphySapProvider()
Get the CPHY SAP provider.
Definition: lte-enb-phy.cc:261
FfMacSchedSapProvider::SchedUlCqiInfoReqParameters CreatePuschCqiReport(const SpectrumValue &sinr)
Create the UL CQI feedback from SINR values perceived at the physical layer with the PUSCH signal rec...
Definition: lte-enb-phy.cc:735
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
static Ptr< SpectrumValue > CreateTxPowerSpectralDensity(uint16_t earfcn, uint8_t bandwidth, double powerTx, std::vector< int > activeRbs)
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
std::list< Ptr< LteControlMessage > > GetControlMessages(void)
Definition: lte-phy.cc:222
Ptr< PacketBurst > GetPacketBurst(void)
Definition: lte-phy.cc:195
void SetNoiseFigure(double pow)
Definition: lte-enb-phy.cc:282
void SetLteEnbPhySapUser(LteEnbPhySapUser *s)
Set the PHY SAP User.
Definition: lte-enb-phy.cc:242
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
void StartFrame(void)
Start a LTE frame.
Definition: lte-enb-phy.cc:471
std::vector< int > GetDownlinkSubChannels(void)
Definition: lte-enb-phy.cc:403
virtual void UlCqiReport(FfMacSchedSapProvider::SchedUlCqiInfoReqParameters ulcqi)=0
Returns to MAC level the UL-CQI evaluated.
FfMacSchedSapProvider::SchedUlCqiInfoReqParameters CreateSrsCqiReport(const SpectrumValue &sinr)
Create the UL CQI feedback from SINR values perceived at the physical layer with the SRS signal recei...
Definition: lte-enb-phy.cc:808
void QueueUlDci(UlDciLteControlMessage m)
Definition: lte-enb-phy.cc:868
Time MilliSeconds(uint64_t ms)
create ns3::Time instances in units of milliseconds.
Definition: nstime.h:601
#define NS_LOG_ERROR(msg)
Definition: log.h:237
Values::const_iterator ConstValuesBegin() const
virtual void SubframeIndication(uint32_t frameNo, uint32_t subframeNo)=0
Trigger the start from a new frame (input from Phy layer)
TracedCallback< uint16_t, Ptr< SpectrumValue > > m_reportInterferenceTrace
Definition: lte-enb-phy.h:320
void SendDataChannels(Ptr< PacketBurst > pb)
Send the PDSCH.
Definition: lte-enb-phy.cc:658
virtual void ReceivePhyPdu(Ptr< Packet > p)=0
Hold an floating point type.
Definition: double.h:41
virtual void ReportRsReceivedPower(const SpectrumValue &interf)
Definition: lte-enb-phy.cc:727
Set of values corresponding to a given SpectrumModel.
virtual void DoDispose(void)
Definition: lte-enb-phy.cc:221
void PhyPduReceived(Ptr< Packet > p)
PhySpectrum received a new PHY-PDU.
Definition: lte-enb-phy.cc:387
Ptr< LteSpectrumPhy > GetUlSpectrumPhy() const
Definition: lte-enb-phy.cc:329
void SetMacPdu(Ptr< Packet > p)
Definition: lte-phy.cc:189
a unique identifier for an interface.
Definition: type-id.h:44
uint8_t GetMacChDelay(void) const
Definition: lte-enb-phy.cc:317
int64_t GetMilliSeconds(void) const
Definition: nstime.h:271
TypeId SetParent(TypeId tid)
Definition: type-id.cc:471
void SetLteEnbCphySapUser(LteEnbCphySapUser *s)
Set the CPHY SAP User.
Definition: lte-enb-phy.cc:254
virtual void DoInitialize(void)
Definition: object.cc:342
TracedCallback< PhyTransmissionStatParameters > m_dlPhyTransmission
Definition: lte-enb-phy.h:328
static Ptr< SpectrumValue > CreateNoisePowerSpectralDensity(uint16_t earfcn, uint8_t bandwidth, double noiseFigure)
void EndFrame(void)
End a LTE frame.
Definition: lte-enb-phy.cc:686
void DoSendMacPdu(Ptr< Packet > p)
Queue the MAC PDU to be sent (according to m_macChTtiDelay)
Definition: lte-enb-phy.cc:373
void EndSubFrame(void)
End a LTE sub frame.
Definition: lte-enb-phy.cc:671
virtual void ReceiveLteControlMessage(Ptr< LteControlMessage > msg)=0
Receive SendLteControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel.