A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
lte-ue-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 <marco.miozzo@cttc.es>
20  * Nicola Baldo <nbaldo@cttc.es>
21  */
22 
23 #include <ns3/object-factory.h>
24 #include <ns3/log.h>
25 #include <cmath>
26 #include <ns3/simulator.h>
27 #include <ns3/double.h>
28 #include "lte-ue-phy.h"
29 #include "lte-enb-phy.h"
30 #include "lte-net-device.h"
31 #include "lte-ue-net-device.h"
32 #include "lte-enb-net-device.h"
33 #include "lte-spectrum-value-helper.h"
34 #include "lte-amc.h"
35 #include "lte-ue-mac.h"
36 #include "ff-mac-common.h"
37 #include "lte-sinr-chunk-processor.h"
38 #include <ns3/lte-common.h>
39 #include <ns3/pointer.h>
40 
41 NS_LOG_COMPONENT_DEFINE ("LteUePhy");
42 
43 namespace ns3 {
44 
45 
46 
47 
48 // duration of data portion of UL subframe
49 // = TTI - 1 symbol for SRS - 1ns as margin to avoid overlapping simulator events
50 // (symbol duration in nanoseconds = TTI / 14 (rounded))
51 // in other words, duration of data portion of UL subframe = TTI*(13/14) -1ns
52 static const Time UL_DATA_DURATION = NanoSeconds (1e6 - 71429 - 1);
53 
54 // delay from subframe start to transmission of SRS
55 // = TTI - 1 symbol for SRS
56 static const Time UL_SRS_DELAY_FROM_SUBFRAME_START = NanoSeconds (1e6 - 71429);
57 
58 
59 
60 
62 // member SAP forwarders
64 
65 
67 {
68 public:
70 
71  // inherited from LtePhySapProvider
72  virtual void SendMacPdu (Ptr<Packet> p);
74  virtual void SendRachPreamble (uint32_t prachId, uint32_t raRnti);
75 
76 private:
77  LteUePhy* m_phy;
78 };
79 
80 UeMemberLteUePhySapProvider::UeMemberLteUePhySapProvider (LteUePhy* phy) : m_phy (phy)
81 {
82 
83 }
84 
85 void
87 {
88  m_phy->DoSendMacPdu (p);
89 }
90 
91 void
93 {
94  m_phy->DoSendLteControlMessage (msg);
95 }
96 
97 void
98 UeMemberLteUePhySapProvider::SendRachPreamble (uint32_t prachId, uint32_t raRnti)
99 {
100  m_phy->DoSendRachPreamble (prachId, raRnti);
101 }
102 
103 
105 // LteUePhy methods
107 
108 
109 NS_OBJECT_ENSURE_REGISTERED (LteUePhy);
110 
111 
113 {
114  NS_LOG_FUNCTION (this);
115  NS_FATAL_ERROR ("This constructor should not be called");
116 }
117 
119  : LtePhy (dlPhy, ulPhy),
120  m_p10CqiPeriocity (MilliSeconds (1)), // ideal behavior
121  m_a30CqiPeriocity (MilliSeconds (1)), // ideal behavior
122  m_uePhySapUser (0),
123  m_ueCphySapUser (0),
124  m_rsReceivedPowerUpdated (false),
125  m_rsrpSinrSampleCounter (0)
126 {
127  m_amc = CreateObject <LteAmc> ();
128  m_uePhySapProvider = new UeMemberLteUePhySapProvider (this);
129  m_ueCphySapProvider = new MemberLteUeCphySapProvider<LteUePhy> (this);
130  m_macChTtiDelay = UL_PUSCH_TTIS_DELAY;
131 
132  NS_ASSERT_MSG (Simulator::Now ().GetNanoSeconds () == 0,
133  "Cannot create UE devices after simulation started");
135 
136  DoReset ();
137 }
138 
139 
140 LteUePhy::~LteUePhy ()
141 {
142  m_txModeGain.clear ();
143 }
144 
145 void
147 {
148  NS_LOG_FUNCTION (this);
149  delete m_uePhySapProvider;
150  delete m_ueCphySapProvider;
152 }
153 
154 
155 
156 TypeId
157 LteUePhy::GetTypeId (void)
158 {
159  static TypeId tid = TypeId ("ns3::LteUePhy")
160  .SetParent<LtePhy> ()
161  .AddConstructor<LteUePhy> ()
162  .AddAttribute ("TxPower",
163  "Transmission power in dBm",
164  DoubleValue (10.0),
165  MakeDoubleAccessor (&LteUePhy::SetTxPower,
167  MakeDoubleChecker<double> ())
168  .AddAttribute ("NoiseFigure",
169  "Loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver."
170  " According to Wikipedia (http://en.wikipedia.org/wiki/Noise_figure), this is "
171  "\"the difference in decibels (dB) between"
172  " the noise output of the actual receiver to the noise output of an "
173  " ideal receiver with the same overall gain and bandwidth when the receivers "
174  " are connected to sources at the standard noise temperature T0.\" "
175  "In this model, we consider T0 = 290K.",
176  DoubleValue (9.0),
177  MakeDoubleAccessor (&LteUePhy::SetNoiseFigure,
179  MakeDoubleChecker<double> ())
180  .AddAttribute ("TxMode1Gain",
181  "Transmission mode 1 gain in dB",
182  DoubleValue (0.0),
183  MakeDoubleAccessor (&LteUePhy::SetTxMode1Gain ),
184  MakeDoubleChecker<double> ())
185  .AddAttribute ("TxMode2Gain",
186  "Transmission mode 2 gain in dB",
187  DoubleValue (4.2),
188  MakeDoubleAccessor (&LteUePhy::SetTxMode2Gain ),
189  MakeDoubleChecker<double> ())
190  .AddAttribute ("TxMode3Gain",
191  "Transmission mode 3 gain in dB",
192  DoubleValue (-2.8),
193  MakeDoubleAccessor (&LteUePhy::SetTxMode3Gain ),
194  MakeDoubleChecker<double> ())
195  .AddAttribute ("TxMode4Gain",
196  "Transmission mode 4 gain in dB",
197  DoubleValue (0.0),
198  MakeDoubleAccessor (&LteUePhy::SetTxMode4Gain ),
199  MakeDoubleChecker<double> ())
200  .AddAttribute ("TxMode5Gain",
201  "Transmission mode 5 gain in dB",
202  DoubleValue (0.0),
203  MakeDoubleAccessor (&LteUePhy::SetTxMode5Gain ),
204  MakeDoubleChecker<double> ())
205  .AddAttribute ("TxMode6Gain",
206  "Transmission mode 6 gain in dB",
207  DoubleValue (0.0),
208  MakeDoubleAccessor (&LteUePhy::SetTxMode6Gain ),
209  MakeDoubleChecker<double> ())
210  .AddAttribute ("TxMode7Gain",
211  "Transmission mode 7 gain in dB",
212  DoubleValue (0.0),
213  MakeDoubleAccessor (&LteUePhy::SetTxMode7Gain ),
214  MakeDoubleChecker<double> ())
215  .AddTraceSource ("ReportCurrentCellRsrpSinr",
216  "RSRP and SINR statistics.",
218  .AddAttribute ("RsrpSinrSamplePeriod",
219  "The sampling period for reporting RSRP-SINR stats (default value 1)",
220  UintegerValue (1),
221  MakeUintegerAccessor (&LteUePhy::m_rsrpSinrSamplePeriod),
222  MakeUintegerChecker<uint16_t> ())
223  .AddTraceSource ("UlPhyTransmission",
224  "DL transmission PHY layer statistics.",
226  .AddAttribute ("DlSpectrumPhy",
227  "The downlink LteSpectrumPhy associated to this LtePhy",
229  PointerValue (),
230  MakePointerAccessor (&LteUePhy::GetDlSpectrumPhy),
231  MakePointerChecker <LteSpectrumPhy> ())
232  .AddAttribute ("UlSpectrumPhy",
233  "The uplink LteSpectrumPhy associated to this LtePhy",
235  PointerValue (),
236  MakePointerAccessor (&LteUePhy::GetUlSpectrumPhy),
237  MakePointerChecker <LteSpectrumPhy> ())
238  ;
239  return tid;
240 }
241 
242 void
244 {
245  NS_LOG_FUNCTION (this);
247 }
248 
249 void
251 {
252  NS_LOG_FUNCTION (this);
253  m_uePhySapUser = s;
254 }
255 
258 {
259  NS_LOG_FUNCTION (this);
260  return (m_uePhySapProvider);
261 }
262 
263 
264 void
266 {
267  NS_LOG_FUNCTION (this);
268  m_ueCphySapUser = s;
269 }
270 
273 {
274  NS_LOG_FUNCTION (this);
275  return (m_ueCphySapProvider);
276 }
277 
278 void
280 {
281  NS_LOG_FUNCTION (this << nf);
282  m_noiseFigure = nf;
283 }
284 
285 double
287 {
288  NS_LOG_FUNCTION (this);
289  return m_noiseFigure;
290 }
291 
292 void
294 {
295  NS_LOG_FUNCTION (this << pow);
296  m_txPower = pow;
297 }
298 
299 double
301 {
302  NS_LOG_FUNCTION (this);
303  return m_txPower;
304 }
305 
306 
307 uint8_t
309 {
310  return (m_macChTtiDelay);
311 }
312 
315 {
316  return m_downlinkSpectrumPhy;
317 }
318 
321 {
322  return m_uplinkSpectrumPhy;
323 }
324 
325 void
327 {
328  NS_LOG_FUNCTION (this);
329 
330  SetMacPdu (p);
331 }
332 
333 
334 void
336 {
337  m_uePhySapUser->ReceivePhyPdu (p);
338 }
339 
340 void
342 {
343  NS_LOG_FUNCTION (this);
344 
345  m_subChannelsForTransmission = mask;
346 
348  m_uplinkSpectrumPhy->SetTxPowerSpectralDensity (txPsd);
349 }
350 
351 
352 void
353 LteUePhy::SetSubChannelsForReception (std::vector <int> mask)
354 {
355  NS_LOG_FUNCTION (this);
356  m_subChannelsForReception = mask;
357 }
358 
359 
360 std::vector <int>
362 {
363  NS_LOG_FUNCTION (this);
364  return m_subChannelsForTransmission;
365 }
366 
367 
368 std::vector <int>
370 {
371  NS_LOG_FUNCTION (this);
372  return m_subChannelsForReception;
373 }
374 
375 
378 {
379  NS_LOG_FUNCTION (this);
380  LteSpectrumValueHelper psdHelper;
381  Ptr<SpectrumValue> psd = psdHelper.CreateTxPowerSpectralDensity (m_ulEarfcn, m_ulBandwidth, m_txPower, GetSubChannelsForTransmission ());
382 
383  return psd;
384 }
385 
386 void
388 {
389  NS_LOG_FUNCTION (this);
390 
391  if (!(m_dlConfigured && m_ulConfigured))
392  {
393  return;
394  }
395 
396  // check periodic wideband CQI
398  {
399  Ptr<LteUeNetDevice> thisDevice = GetDevice ()->GetObject<LteUeNetDevice> ();
401  if (msg)
402  {
403  DoSendLteControlMessage (msg);
404  }
406  }
407  // check aperiodic high-layer configured subband CQI
408  if (Simulator::Now () > m_a30CqiLast + m_a30CqiPeriocity)
409  {
410  Ptr<LteUeNetDevice> thisDevice = GetDevice ()->GetObject<LteUeNetDevice> ();
412  if (msg)
413  {
414  DoSendLteControlMessage (msg);
415  }
416  m_a30CqiLast = Simulator::Now ();
417  }
418 }
419 
420 void
422 {
423  // Not used by UE, CQI are based only on RS
424 }
425 
426 void
428 {
429  // Currently not used by UE
430 }
431 
432 void
434 {
435  NS_LOG_FUNCTION (this << power);
436  m_rsReceivedPowerUpdated = true;
437  m_rsReceivedPower = power;
438 }
439 
440 
441 
444 {
445  NS_LOG_FUNCTION (this);
446 
447  if (m_rnti == 0)
448  {
449  // abort method, the UE is still not registered
450  return (0);
451  }
452 
453  // apply transmission mode gain
454  NS_ASSERT (m_transmissionMode < m_txModeGain.size ());
455  SpectrumValue newSinr = sinr;
456  newSinr *= m_txModeGain.at (m_transmissionMode);
457 
458  m_rsrpSinrSampleCounter++;
459  if (m_rsrpSinrSampleCounter==m_rsrpSinrSamplePeriod)
460  {
461  NS_ASSERT_MSG (m_rsReceivedPowerUpdated, " RS received power info obsolete");
462  // RSRP evaluated as averaged received power among RBs
463  double sum = 0.0;
464  uint8_t rbNum = 0;
465  Values::const_iterator it;
466  for (it = m_rsReceivedPower.ConstValuesBegin (); it != m_rsReceivedPower.ConstValuesEnd (); it++)
467  {
468  // convert PSD [W/Hz] to linear power [W] for the single RE
469  // we consider only one RE for the RS since the channel is
470  // flat within the same RB
471  double powerTxW = ((*it) * 180000.0) / 12.0;
472  sum += powerTxW;
473  rbNum++;
474  }
475  double rsrp = sum / (double)rbNum;
476  // averaged SINR among RBs
477  sum = 0.0;
478  rbNum = 0;
479  for (it = sinr.ConstValuesBegin (); it != sinr.ConstValuesEnd (); it++)
480  {
481  sum += (*it);
482  rbNum++;
483  }
484  double avSinr = sum / (double)rbNum;
485  NS_LOG_INFO (this << " cellId " << m_cellId << " rnti " << m_rnti << " RSRP " << rsrp << " SINR " << avSinr);
486 
487  m_reportCurrentCellRsrpSinrTrace (m_cellId, m_rnti, rsrp, avSinr);
488  m_rsrpSinrSampleCounter = 0;
489  }
490 
491 
492 
493  // CREATE DlCqiLteControlMessage
494  Ptr<DlCqiLteControlMessage> msg = Create<DlCqiLteControlMessage> ();
495  CqiListElement_s dlcqi;
496  std::vector<int> cqi;
498  {
499  cqi = m_amc->CreateCqiFeedbacks (newSinr, m_dlBandwidth);
500 
501  int nLayer = TransmissionModesLayers::TxMode2LayerNum (m_transmissionMode);
502  int nbSubChannels = cqi.size ();
503  double cqiSum = 0.0;
504  int activeSubChannels = 0;
505  // average the CQIs of the different RBs
506  for (int i = 0; i < nbSubChannels; i++)
507  {
508  if (cqi.at (i) != -1)
509  {
510  cqiSum += cqi.at (i);
511  activeSubChannels++;
512  }
513  NS_LOG_DEBUG (this << " subch " << i << " cqi " << cqi.at (i));
514  }
515  dlcqi.m_rnti = m_rnti;
516  dlcqi.m_ri = 1; // not yet used
517  dlcqi.m_cqiType = CqiListElement_s::P10; // Peridic CQI using PUCCH wideband
518  NS_ASSERT_MSG (nLayer > 0, " nLayer negative");
519  NS_ASSERT_MSG (nLayer < 3, " nLayer limit is 2s");
520  for (int i = 0; i < nLayer; i++)
521  {
522  if (activeSubChannels > 0)
523  {
524  dlcqi.m_wbCqi.push_back ((uint16_t) cqiSum / activeSubChannels);
525  }
526  else
527  {
528  // approximate with the worst case -> CQI = 1
529  dlcqi.m_wbCqi.push_back (1);
530  }
531  }
532  //NS_LOG_DEBUG (this << " Generate P10 CQI feedback " << (uint16_t) cqiSum / activeSubChannels);
533  dlcqi.m_wbPmi = 0; // not yet used
534  // dl.cqi.m_sbMeasResult others CQI report modes: not yet implemented
535  }
536  else if (Simulator::Now () > m_a30CqiLast + m_a30CqiPeriocity)
537  {
538  cqi = m_amc->CreateCqiFeedbacks (newSinr, GetRbgSize ());
539  int nLayer = TransmissionModesLayers::TxMode2LayerNum (m_transmissionMode);
540  int nbSubChannels = cqi.size ();
541  int rbgSize = GetRbgSize ();
542  double cqiSum = 0.0;
543  int cqiNum = 0;
544  SbMeasResult_s rbgMeas;
545  //NS_LOG_DEBUG (this << " Create A30 CQI feedback, RBG " << rbgSize << " cqiNum " << nbSubChannels << " band " << (uint16_t)m_dlBandwidth);
546  for (int i = 0; i < nbSubChannels; i++)
547  {
548  if (cqi.at (i) != -1)
549  {
550  cqiSum += cqi.at (i);
551  }
552  // else "nothing" no CQI is treated as CQI = 0 (worst case scenario)
553  cqiNum++;
554  if (cqiNum == rbgSize)
555  {
556  // average the CQIs of the different RBGs
557  //NS_LOG_DEBUG (this << " RBG CQI " << (uint16_t) cqiSum / rbgSize);
558  HigherLayerSelected_s hlCqi;
559  hlCqi.m_sbPmi = 0; // not yet used
560  for (int i = 0; i < nLayer; i++)
561  {
562  hlCqi.m_sbCqi.push_back ((uint16_t) cqiSum / rbgSize);
563  }
564  rbgMeas.m_higherLayerSelected.push_back (hlCqi);
565  cqiSum = 0.0;
566  cqiNum = 0;
567  }
568  }
569  dlcqi.m_rnti = m_rnti;
570  dlcqi.m_ri = 1; // not yet used
571  dlcqi.m_cqiType = CqiListElement_s::A30; // Aperidic CQI using PUSCH
572  //dlcqi.m_wbCqi.push_back ((uint16_t) cqiSum / nbSubChannels);
573  dlcqi.m_wbPmi = 0; // not yet used
574  dlcqi.m_sbMeasResult = rbgMeas;
575  }
576 
577  msg->SetDlCqi (dlcqi);
578  return msg;
579 }
580 
581 
582 
583 void
584 LteUePhy::DoSendLteControlMessage (Ptr<LteControlMessage> msg)
585 {
586  NS_LOG_FUNCTION (this << msg);
587 
588  SetControlMessages (msg);
589 }
590 
591 void
592 LteUePhy::DoSendRachPreamble (uint32_t raPreambleId, uint32_t raRnti)
593 {
594  NS_LOG_FUNCTION (this << raPreambleId);
595 
596  // unlike other control messages, RACH preamble is sent ASAP
597  Ptr<RachPreambleLteControlMessage> msg = Create<RachPreambleLteControlMessage> ();
598  msg->SetRapId (raPreambleId);
599  m_raPreambleId = raPreambleId;
600  m_raRnti = raRnti;
601  m_controlMessagesQueue.at (0).push_back (msg);
602 }
603 
604 
605 void
606 LteUePhy::ReceiveLteControlMessageList (std::list<Ptr<LteControlMessage> > msgList)
607 {
608  NS_LOG_FUNCTION (this);
609 
610  std::list<Ptr<LteControlMessage> >::iterator it;
611  for (it = msgList.begin (); it != msgList.end(); it++)
612  {
613  Ptr<LteControlMessage> msg = (*it);
614 
615  if (msg->GetMessageType () == LteControlMessage::DL_DCI)
616  {
617  Ptr<DlDciLteControlMessage> msg2 = DynamicCast<DlDciLteControlMessage> (msg);
618 
619  DlDciListElement_s dci = msg2->GetDci ();
620  if (dci.m_rnti != m_rnti)
621  {
622  // DCI not for me
623  continue;
624  }
625 
626  if (dci.m_resAlloc != 0)
627  {
628  NS_FATAL_ERROR ("Resource Allocation type not implemented");
629  }
630 
631  std::vector <int> dlRb;
632 
633  // translate the DCI to Spectrum framework
634  uint32_t mask = 0x1;
635  for (int i = 0; i < 32; i++)
636  {
637  if (((dci.m_rbBitmap & mask) >> i) == 1)
638  {
639  for (int k = 0; k < GetRbgSize (); k++)
640  {
641  dlRb.push_back ((i * GetRbgSize ()) + k);
642 // NS_LOG_DEBUG(this << " RNTI " << m_rnti << " RBG " << i << " DL-DCI allocated PRB " << (i*GetRbgSize()) + k);
643  }
644  }
645  mask = (mask << 1);
646  }
647 
648  // send TB info to LteSpectrumPhy
649  NS_LOG_DEBUG (this << " UE " << m_rnti << " DL-DCI " << dci.m_rnti << " bitmap " << dci.m_rbBitmap);
650  for (uint8_t i = 0; i < dci.m_tbsSize.size (); i++)
651  {
652  m_downlinkSpectrumPhy->AddExpectedTb (dci.m_rnti, dci.m_ndi.at (i), dci.m_tbsSize.at (i), dci.m_mcs.at (i), dlRb, i, dci.m_harqProcess, dci.m_rv.at (i), true /* DL */);
653  }
654 
656 
657 
658  }
659  else if (msg->GetMessageType () == LteControlMessage::UL_DCI)
660  {
661  // set the uplink bandwidht according to the UL-CQI
662  Ptr<UlDciLteControlMessage> msg2 = DynamicCast<UlDciLteControlMessage> (msg);
663  UlDciListElement_s dci = msg2->GetDci ();
664  if (dci.m_rnti != m_rnti)
665  {
666  // DCI not for me
667  continue;
668  }
669  NS_LOG_INFO (this << " UL DCI");
670  std::vector <int> ulRb;
671  for (int i = 0; i < dci.m_rbLen; i++)
672  {
673  ulRb.push_back (i + dci.m_rbStart);
674  //NS_LOG_DEBUG (this << " UE RB " << i + dci.m_rbStart);
675  }
676  QueueSubChannelsForTransmission (ulRb);
677  // fire trace of UL Tx PHY stats
678  HarqProcessInfoList_t harqInfoList = m_harqPhyModule->GetHarqProcessInfoUl (m_rnti, 0);
679  PhyTransmissionStatParameters params;
680  params.m_cellId = m_cellId;
681  params.m_imsi = 0; // it will be set by DlPhyTransmissionCallback in LteHelper
682  params.m_timestamp = Simulator::Now ().GetMilliSeconds () + UL_PUSCH_TTIS_DELAY;
683  params.m_rnti = m_rnti;
684  params.m_txMode = 0; // always SISO for UE
685  params.m_layer = 0;
686  params.m_mcs = dci.m_mcs;
687  params.m_size = dci.m_tbSize;
688  params.m_rv = harqInfoList.size ();
689  params.m_ndi = dci.m_ndi;
690  m_ulPhyTransmission (params);
691  // pass the info to the MAC
692  m_uePhySapUser->ReceiveLteControlMessage (msg);
693  }
694  else if (msg->GetMessageType () == LteControlMessage::RAR)
695  {
696  Ptr<RarLteControlMessage> rarMsg = DynamicCast<RarLteControlMessage> (msg);
697  if (rarMsg->GetRaRnti () == m_raRnti)
698  {
699  for (std::list<RarLteControlMessage::Rar>::const_iterator it = rarMsg->RarListBegin (); it != rarMsg->RarListEnd (); ++it)
700  {
701  if (it->rapId != m_raPreambleId)
702  {
703  // UL grant not for me
704  continue;
705  }
706  else
707  {
708  NS_LOG_INFO ("received RAR RNTI " << m_raRnti);
709  // set the uplink bandwidht according to the UL grant
710  std::vector <int> ulRb;
711  for (int i = 0; i < it->rarPayload.m_grant.m_rbLen; i++)
712  {
713  ulRb.push_back (i + it->rarPayload.m_grant.m_rbStart);
714  }
715 
716  QueueSubChannelsForTransmission (ulRb);
717  // pass the info to the MAC
718  m_uePhySapUser->ReceiveLteControlMessage (msg);
719  // reset RACH variables with out of range values
720  m_raPreambleId = 255;
721  m_raRnti = 11;
722  }
723  }
724  }
725  }
726  else if (msg->GetMessageType () == LteControlMessage::MIB)
727  {
728  NS_LOG_INFO ("received MIB");
729  Ptr<MibLteControlMessage> msg2 = DynamicCast<MibLteControlMessage> (msg);
730  m_ueCphySapUser->RecvMasterInformationBlock (msg2->GetMib ());
731  }
732  else
733  {
734  // pass the message to UE-MAC
735  m_uePhySapUser->ReceiveLteControlMessage (msg);
736  }
737 
738  }
739 
740 
741 }
742 
743 
744 void
745 LteUePhy::QueueSubChannelsForTransmission (std::vector <int> rbMap)
746 {
747  m_subChannelsForTransmissionQueue.at (m_macChTtiDelay - 1) = rbMap;
748 }
749 
750 
751 void
752 LteUePhy::SubframeIndication (uint32_t frameNo, uint32_t subframeNo)
753 {
754  NS_LOG_FUNCTION (this << frameNo << subframeNo);
755 
756  NS_ASSERT_MSG (frameNo > 0, "the SRS index check code assumes that frameNo starts at 1");
757 
758  // refresh internal variables
759  m_rsReceivedPowerUpdated = false;
760 
761  if (m_ulConfigured)
762  {
763  // update uplink transmission mask according to previous UL-CQIs
764  SetSubChannelsForTransmission (m_subChannelsForTransmissionQueue.at (0));
765 
766  // shift the queue
767  for (uint8_t i = 1; i < m_macChTtiDelay; i++)
768  {
769  m_subChannelsForTransmissionQueue.at (i-1) = m_subChannelsForTransmissionQueue.at (i);
770  }
771  m_subChannelsForTransmissionQueue.at (m_macChTtiDelay-1).clear ();
772 
773  if (m_srsConfigured && (m_srsStartTime <= Simulator::Now ()))
774  {
775 
776  NS_ASSERT_MSG (subframeNo > 0 && subframeNo <= 10, "the SRS index check code assumes that subframeNo starts at 1");
777  if ((((frameNo-1)*10 + (subframeNo-1)) % m_srsPeriodicity) == m_srsSubframeOffset)
778  {
779  NS_LOG_INFO ("frame " << frameNo << " subframe " << subframeNo << " sending SRS (offset=" << m_srsSubframeOffset << ", period=" << m_srsPeriodicity << ")");
780  m_sendSrsEvent = Simulator::Schedule (UL_SRS_DELAY_FROM_SUBFRAME_START,
782  this);
783  }
784  }
785 
786  std::list<Ptr<LteControlMessage> > ctrlMsg = GetControlMessages ();
787  // send packets in queue
788  NS_LOG_LOGIC (this << " UE - start slot for PUSCH + PUCCH - RNTI " << m_rnti << " CELLID " << m_cellId);
789  // send the current burts of packets
791  if (pb)
792  {
793  m_uplinkSpectrumPhy->StartTxDataFrame (pb, ctrlMsg, UL_DATA_DURATION);
794  }
795  else
796  {
797  // send only PUCCH (ideal: fake null bandwidth signal)
798  if (ctrlMsg.size ()>0)
799  {
800  NS_LOG_LOGIC (this << " UE - start TX PUCCH (NO PUSCH)");
801  std::vector <int> dlRb;
803  m_uplinkSpectrumPhy->StartTxDataFrame (pb, ctrlMsg, UL_DATA_DURATION);
804  }
805  else
806  {
807  NS_LOG_LOGIC (this << " UE - UL NOTHING TO SEND");
808  }
809  }
810  } // m_configured
811 
812  // trigger the MAC
813  m_uePhySapUser->SubframeIndication (frameNo, subframeNo);
814 
815 
816  ++subframeNo;
817  if (subframeNo > 10)
818  {
819  ++frameNo;
820  subframeNo = 1;
821  }
822 
823  // schedule next subframe indication
824  Simulator::Schedule (Seconds (GetTti ()), &LteUePhy::SubframeIndication, this, frameNo, subframeNo);
825 }
826 
827 void
829 {
830  NS_LOG_FUNCTION (this << " UE " << m_rnti << " start tx SRS, cell Id " << (uint32_t) m_cellId);
831  NS_ASSERT (m_cellId > 0);
832  // set the current tx power spectral density (full bandwidth)
833  std::vector <int> dlRb;
834  for (uint8_t i = 0; i < m_ulBandwidth; i++)
835  {
836  dlRb.push_back (i);
837  }
839  m_uplinkSpectrumPhy->StartTxUlSrsFrame ();
840 }
841 
842 
843 void
844 LteUePhy::DoReset ()
845 {
846  NS_LOG_FUNCTION (this);
847 
848  m_rnti = 0;
849  m_transmissionMode = 0;
850  m_srsPeriodicity = 0;
851  m_srsConfigured = false;
852  m_dlConfigured = false;
853  m_ulConfigured = false;
854  m_raPreambleId = 255; // value out of range
855  m_raRnti = 11; // value out of range
856  m_rsrpSinrSampleCounter = 0;
858  m_a30CqiLast = Simulator::Now ();
859 
860  m_packetBurstQueue.clear ();
861  m_controlMessagesQueue.clear ();
862  m_subChannelsForTransmissionQueue.clear ();
863  for (int i = 0; i < m_macChTtiDelay; i++)
864  {
865  Ptr<PacketBurst> pb = CreateObject <PacketBurst> ();
866  m_packetBurstQueue.push_back (pb);
867  std::list<Ptr<LteControlMessage> > l;
868  m_controlMessagesQueue.push_back (l);
869  }
870  std::vector <int> ulRb;
871  m_subChannelsForTransmissionQueue.resize (m_macChTtiDelay, ulRb);
872 
873  m_sendSrsEvent.Cancel ();
874  m_downlinkSpectrumPhy->Reset ();
875  m_uplinkSpectrumPhy->Reset ();
876 }
877 
878 void
879 LteUePhy::DoSyncronizeWithEnb (uint16_t cellId, uint16_t dlEarfcn)
880 {
881  NS_LOG_FUNCTION (this << cellId);
882  m_cellId = cellId;
883  m_dlEarfcn = dlEarfcn;
884  m_downlinkSpectrumPhy->SetCellId (cellId);
885  m_uplinkSpectrumPhy->SetCellId (cellId);
886 
887  // configure DL for receing the BCH with the minimum bandwith
888  m_dlBandwidth = 6;
889  Ptr<SpectrumValue> noisePsd = LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (m_dlEarfcn, m_dlBandwidth, m_noiseFigure);
890  m_downlinkSpectrumPhy->SetNoisePowerSpectralDensity (noisePsd);
891  m_downlinkSpectrumPhy->GetChannel ()->AddRx (m_downlinkSpectrumPhy);
892 
893  m_dlConfigured = false;
894  m_ulConfigured = false;
895 }
896 
897 void
898 LteUePhy::DoSetDlBandwidth (uint8_t dlBandwidth)
899 {
900  NS_LOG_FUNCTION (this << (uint32_t) dlBandwidth);
901  if (m_dlBandwidth != dlBandwidth)
902  {
903  m_dlBandwidth = dlBandwidth;
904 
905  int Type0AllocationRbg[4] = {
906  10, // RGB size 1
907  26, // RGB size 2
908  63, // RGB size 3
909  110 // RGB size 4
910  }; // see table 7.1.6.1-1 of 36.213
911  for (int i = 0; i < 4; i++)
912  {
913  if (dlBandwidth < Type0AllocationRbg[i])
914  {
915  m_rbgSize = i + 1;
916  break;
917  }
918  }
919 
920  Ptr<SpectrumValue> noisePsd = LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (m_dlEarfcn, m_dlBandwidth, m_noiseFigure);
921  m_downlinkSpectrumPhy->SetNoisePowerSpectralDensity (noisePsd);
922  m_downlinkSpectrumPhy->GetChannel ()->AddRx (m_downlinkSpectrumPhy);
923  }
924  m_dlConfigured = true;
925 }
926 
927 
928 void
929 LteUePhy::DoConfigureUplink (uint16_t ulEarfcn, uint8_t ulBandwidth)
930 {
931  m_ulEarfcn = ulEarfcn;
932  m_ulBandwidth = ulBandwidth;
933  m_ulConfigured = true;
934 }
935 
936 
937 void
938 LteUePhy::DoSetRnti (uint16_t rnti)
939 {
940  NS_LOG_FUNCTION (this << rnti);
941  m_rnti = rnti;
942 }
943 
944 void
945 LteUePhy::DoSetTransmissionMode (uint8_t txMode)
946 {
947  NS_LOG_FUNCTION (this << (uint16_t)txMode);
948  m_transmissionMode = txMode;
949  m_downlinkSpectrumPhy->SetTransmissionMode (txMode);
950 }
951 
952 void
953 LteUePhy::DoSetSrsConfigurationIndex (uint16_t srcCi)
954 {
955  NS_LOG_FUNCTION (this << srcCi);
956  m_srsPeriodicity = GetSrsPeriodicity (srcCi);
957  m_srsSubframeOffset = GetSrsSubframeOffset (srcCi);
958  m_srsConfigured = true;
959 
960  // a guard time is needed for the case where the SRS periodicity is changed dynamically at run time
961  // if we use a static one, we can have a 0ms guard time
962  m_srsStartTime = Simulator::Now () + MilliSeconds (0);
963  NS_LOG_DEBUG (this << " UE SRS P " << m_srsPeriodicity << " RNTI " << m_rnti << " offset " << m_srsSubframeOffset << " cellId " << m_cellId << " CI " << srcCi);
964 }
965 
966 
967 void
968 LteUePhy::SetTxMode1Gain (double gain)
969 {
970  SetTxModeGain (1, gain);
971 }
972 
973 void
974 LteUePhy::SetTxMode2Gain (double gain)
975 {
976  SetTxModeGain (2, gain);
977 }
978 
979 void
980 LteUePhy::SetTxMode3Gain (double gain)
981 {
982  SetTxModeGain (3, gain);
983 }
984 
985 void
986 LteUePhy::SetTxMode4Gain (double gain)
987 {
988  SetTxModeGain (4, gain);
989 }
990 
991 void
992 LteUePhy::SetTxMode5Gain (double gain)
993 {
994  SetTxModeGain (5, gain);
995 }
996 
997 void
998 LteUePhy::SetTxMode6Gain (double gain)
999 {
1000  SetTxModeGain (6, gain);
1001 }
1002 
1003 void
1004 LteUePhy::SetTxMode7Gain (double gain)
1005 {
1006  SetTxModeGain (7, gain);
1007 }
1008 
1009 
1010 void
1011 LteUePhy::SetTxModeGain (uint8_t txMode, double gain)
1012 {
1013  NS_LOG_FUNCTION (this << gain);
1014  // convert to linear
1015  double gainLin = std::pow (10.0, (gain / 10.0));
1016  if (m_txModeGain.size () < txMode)
1017  {
1018  m_txModeGain.resize (txMode);
1019  }
1020  std::vector <double> temp;
1021  temp = m_txModeGain;
1022  m_txModeGain.clear ();
1023  for (uint8_t i = 0; i < temp.size (); i++)
1024  {
1025  if (i==txMode-1)
1026  {
1027  m_txModeGain.push_back (gainLin);
1028  }
1029  else
1030  {
1031  m_txModeGain.push_back (temp.at (i));
1032  }
1033  }
1034  // forward the info to DL LteSpectrumPhy
1035  m_downlinkSpectrumPhy->SetTxModeGain (txMode, gain);
1036 }
1037 
1038 
1039 
1040 void
1042 {
1043  NS_LOG_FUNCTION (this);
1044  // generate feedback to eNB and send it through ideal PUCCH
1045  Ptr<DlHarqFeedbackLteControlMessage> msg = Create<DlHarqFeedbackLteControlMessage> ();
1046  msg->SetDlHarqFeedback (m);
1047  SetControlMessages (msg);
1048 }
1049 
1050 void
1052 {
1053  m_harqPhyModule = harq;
1054 }
1055 
1056 
1057 } // namespace ns3
Values::const_iterator ConstValuesEnd() const
double GetNoiseFigure() const
Definition: lte-ue-phy.cc:286
Time NanoSeconds(uint64_t ns)
create ns3::Time instances in units of nanoseconds.
Definition: nstime.h:629
Ptr< LteSpectrumPhy > GetUlSpectrumPhy() const
Definition: lte-ue-phy.cc:320
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
virtual void ReceiveLteControlMessage(Ptr< LteControlMessage > msg)=0
Receive SendLteControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel.
See section 4.3.25 sbMeasResult.
void SetNoiseFigure(double pow)
Definition: lte-ue-phy.cc:279
virtual void SendMacPdu(Ptr< Packet > p)
Send the MAC PDU to the channel.
Definition: lte-ue-phy.cc:86
virtual void GenerateDataCqiReport(const SpectrumValue &sinr)
Definition: lte-ue-phy.cc:421
uint8_t GetMacChDelay(void) const
Definition: lte-ue-phy.cc:308
std::vector< int > GetSubChannelsForTransmission(void)
Get a list of sub channels to use in RX.
Definition: lte-ue-phy.cc:361
virtual void GenerateCtrlCqiReport(const SpectrumValue &sinr)
Definition: lte-ue-phy.cc:387
TracedCallback< uint16_t, uint16_t, double, double > m_reportCurrentCellRsrpSinrTrace
Definition: lte-ue-phy.h:290
void SetSubChannelsForTransmission(std::vector< int > mask)
Set a list of sub channels to use in TX.
Definition: lte-ue-phy.cc:341
uint16_t GetSrsPeriodicity(uint16_t srcCi) const
Definition: lte-phy.cc:147
double GetTti(void) const
Definition: lte-phy.cc:139
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
virtual void SendLteControlMessage(Ptr< LteControlMessage > msg)
Send SendLteControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel.
Definition: lte-ue-phy.cc:92
See section 4.3.24 cqiListElement.
#define NS_LOG_INFO(msg)
Definition: log.h:264
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
virtual void DoSendMacPdu(Ptr< Packet > p)
Queue the MAC PDU to be sent (according to m_macChTtiDelay)
Definition: lte-ue-phy.cc:326
std::vector< int > GetSubChannelsForReception(void)
Get a list of sub channels to use in RX.
Definition: lte-ue-phy.cc:369
This class defines all functions to create spectrum model for lte.
void SetHarqPhyModule(Ptr< LteHarqPhy > harq)
Set the HARQ PHY module.
Definition: lte-ue-phy.cc:1051
Ptr< LteNetDevice > GetDevice()
Get the device where the phy layer is attached.
Definition: lte-phy.cc:97
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
uint16_t GetSrsSubframeOffset(uint16_t srcCi) const
Definition: lte-phy.cc:165
void DoDispose()
Definition: lte-phy.cc:75
uint8_t GetRbgSize(void) const
Definition: lte-phy.cc:183
See section 4.3.27 higherLayerSelected.
void SetLteUePhySapUser(LteUePhySapUser *s)
Set the PHY SAP User.
Definition: lte-ue-phy.cc:250
Hold an unsigned integer type.
Definition: uinteger.h:46
Ptr< DlCqiLteControlMessage > CreateDlCqiFeedbackMessage(const SpectrumValue &sinr)
Create the DL CQI feedback from SINR values perceived at the physical layer with the signal received ...
Definition: lte-ue-phy.cc:443
void SendSrs()
Send the SRS signal in the last symbols of the frame.
Definition: lte-ue-phy.cc:828
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
See section 4.3.23 dlInfoListElement.
virtual void ReceiveLteDlHarqFeedback(DlInfoListElement_s mes)
PhySpectrum generated a new DL HARQ feedback.
Definition: lte-ue-phy.cc:1041
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)
double GetTxPower() const
Definition: lte-ue-phy.cc:300
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Definition: simulator.h:981
static Time Now(void)
Definition: simulator.cc:179
void SubframeIndication(uint32_t frameNo, uint32_t subframeNo)
trigger from eNB the start from a new frame
Definition: lte-ue-phy.cc:752
virtual void DoInitialize(void)
Definition: lte-ue-phy.cc:243
#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 m_p10CqiPeriocity
Definition: lte-ue-phy.h:251
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
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
void SetTxPower(double pow)
Definition: lte-ue-phy.cc:293
LteUePhySapProvider * GetLteUePhySapProvider()
Get the PHY SAP provider.
Definition: lte-ue-phy.cc:257
void Cancel(void)
Definition: event-id.cc:47
virtual void SendRachPreamble(uint32_t prachId, uint32_t raRnti)
Definition: lte-ue-phy.cc:98
void SetLteUeCphySapUser(LteUeCphySapUser *s)
Set the CPHY SAP User.
Definition: lte-ue-phy.cc:265
Time MilliSeconds(uint64_t ms)
create ns3::Time instances in units of milliseconds.
Definition: nstime.h:601
void PhyPduReceived(Ptr< Packet > p)
PhySpectrum received a new PHY-PDU.
Definition: lte-ue-phy.cc:335
Values::const_iterator ConstValuesBegin() const
Ptr< LteSpectrumPhy > GetDlSpectrumPhy() const
Definition: lte-ue-phy.cc:314
virtual void ReportRsReceivedPower(const SpectrumValue &power)
Definition: lte-ue-phy.cc:433
Time m_p10CqiLast
Definition: lte-ue-phy.h:252
LteUeCphySapProvider * GetLteUeCphySapProvider()
Get the CPHY SAP provider.
Definition: lte-ue-phy.cc:272
Hold an floating point type.
Definition: double.h:41
Set of values corresponding to a given SpectrumModel.
void SetMacPdu(Ptr< Packet > p)
Definition: lte-phy.cc:189
a unique identifier for an interface.
Definition: type-id.h:44
int64_t GetMilliSeconds(void) const
Definition: nstime.h:271
TypeId SetParent(TypeId tid)
Definition: type-id.cc:471
virtual void DoInitialize(void)
Definition: object.cc:342
TracedCallback< PhyTransmissionStatParameters > m_ulPhyTransmission
Definition: lte-ue-phy.h:300
virtual void ReportInterference(const SpectrumValue &interf)
Definition: lte-ue-phy.cc:427
virtual void RecvMasterInformationBlock(LteRrcSap::MasterInformationBlock mib)=0
virtual void ReceivePhyPdu(Ptr< Packet > p)=0
static Ptr< SpectrumValue > CreateNoisePowerSpectralDensity(uint16_t earfcn, uint8_t bandwidth, double noiseFigure)
virtual Ptr< SpectrumValue > CreateTxPowerSpectralDensity()
Create the PSD for the TX.
Definition: lte-ue-phy.cc:377
virtual void SubframeIndication(uint32_t frameNo, uint32_t subframeNo)=0
Trigger the start from a new frame (input from Phy layer)
void SetSubChannelsForReception(std::vector< int > mask)
Get a list of sub channels to use in RX.
Definition: lte-ue-phy.cc:353
virtual void DoDispose(void)
Definition: lte-ue-phy.cc:146