A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
lte-spectrum-phy.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009, 2011 CTTC
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Nicola Baldo <nbaldo@cttc.es>
19  * Giuseppe Piro <g.piro@poliba.it>
20  * Marco Miozzo <marco.miozzo@cttc.es> (add physical error model)
21  */
22 
23 
24 #include <ns3/object-factory.h>
25 #include <ns3/log.h>
26 #include <cmath>
27 #include <ns3/simulator.h>
28 #include <ns3/trace-source-accessor.h>
29 #include <ns3/antenna-model.h>
30 #include "lte-spectrum-phy.h"
31 #include "lte-spectrum-signal-parameters.h"
32 #include "lte-net-device.h"
33 #include "lte-radio-bearer-tag.h"
34 #include "lte-sinr-chunk-processor.h"
35 #include "lte-phy-tag.h"
36 #include <ns3/lte-mi-error-model.h>
37 #include <ns3/lte-radio-bearer-tag.h>
38 #include <ns3/boolean.h>
39 #include <ns3/double.h>
40 #include <ns3/config.h>
41 
42 NS_LOG_COMPONENT_DEFINE ("LteSpectrumPhy");
43 
44 namespace ns3 {
45 
46 
47 
48 // duration of SRS portion of UL subframe
49 // = 1 symbol for SRS -1ns as margin to avoid overlapping simulator events
50 static const Time UL_SRS_DURATION = NanoSeconds (71429 -1);
51 
52 // duration of the control portion of a subframe
53 // = 0.001 / 14 * 3 (ctrl fixed to 3 symbols) -1ns as margin to avoid overlapping simulator events
54 static const Time DL_CTRL_DURATION = NanoSeconds (214286 -1);
55 
56 double EffectiveCodingRate[29] = {
57  0.08,
58  0.1,
59  0.11,
60  0.15,
61  0.19,
62  0.24,
63  0.3,
64  0.37,
65  0.44,
66  0.51,
67  0.3,
68  0.33,
69  0.37,
70  0.42,
71  0.48,
72  0.54,
73  0.6,
74  0.43,
75  0.45,
76  0.5,
77  0.55,
78  0.6,
79  0.65,
80  0.7,
81  0.75,
82  0.8,
83  0.85,
84  0.89,
85  0.92
86 };
87 
88 
89 
90 
91 TbId_t::TbId_t ()
92 {
93 }
94 
95 TbId_t::TbId_t (const uint16_t a, const uint8_t b)
96 : m_rnti (a),
97  m_layer (b)
98 {
99 }
100 
101 bool
102 operator == (const TbId_t &a, const TbId_t &b)
103 {
104  return ( (a.m_rnti == b.m_rnti) && (a.m_layer == b.m_layer) );
105 }
106 
107 bool
108 operator < (const TbId_t& a, const TbId_t& b)
109 {
110  return ( (a.m_rnti < b.m_rnti) || ( (a.m_rnti == b.m_rnti) && (a.m_layer < b.m_layer) ) );
111 }
112 
113 NS_OBJECT_ENSURE_REGISTERED (LteSpectrumPhy);
114 
115 LteSpectrumPhy::LteSpectrumPhy ()
116  : m_state (IDLE),
117  m_transmissionMode (0),
118  m_layersNum (1)
119 {
120  NS_LOG_FUNCTION (this);
121  m_random = CreateObject<UniformRandomVariable> ();
122  m_random->SetAttribute ("Min", DoubleValue (0.0));
123  m_random->SetAttribute ("Max", DoubleValue (1.0));
124  m_interferenceData = CreateObject<LteInterference> ();
125  m_interferenceCtrl = CreateObject<LteInterference> ();
126 
127  for (uint8_t i = 0; i < 7; i++)
128  {
129  m_txModeGain.push_back (1.0);
130  }
131 }
132 
133 
134 LteSpectrumPhy::~LteSpectrumPhy ()
135 {
136  NS_LOG_FUNCTION (this);
137  m_expectedTbs.clear ();
138  m_txModeGain.clear ();
139 }
140 
142 {
143  NS_LOG_FUNCTION (this);
144  m_channel = 0;
145  m_mobility = 0;
146  m_device = 0;
147  m_interferenceData->Dispose ();
148  m_interferenceData = 0;
149  m_interferenceCtrl->Dispose ();
150  m_interferenceCtrl = 0;
151  m_ltePhyTxEndCallback = MakeNullCallback< void, Ptr<const Packet> > ();
152  m_ltePhyRxDataEndErrorCallback = MakeNullCallback< void > ();
153  m_ltePhyRxDataEndOkCallback = MakeNullCallback< void, Ptr<Packet> > ();
154  m_ltePhyRxCtrlEndOkCallback = MakeNullCallback< void, std::list<Ptr<LteControlMessage> > > ();
155  m_ltePhyRxCtrlEndErrorCallback = MakeNullCallback< void > ();
156  m_ltePhyDlHarqFeedbackCallback = MakeNullCallback< void, DlInfoListElement_s > ();
157  m_ltePhyUlHarqFeedbackCallback = MakeNullCallback< void, UlInfoListElement_s > ();
159 }
160 
161 std::ostream& operator<< (std::ostream& os, LteSpectrumPhy::State s)
162 {
163  switch (s)
164  {
165  case LteSpectrumPhy::IDLE:
166  os << "IDLE";
167  break;
168  case LteSpectrumPhy::RX_DATA:
169  os << "RX_DATA";
170  break;
171  case LteSpectrumPhy::RX_CTRL:
172  os << "RX_CTRL";
173  break;
174  case LteSpectrumPhy::TX:
175  os << "TX";
176  break;
177  default:
178  os << "UNKNOWN";
179  break;
180  }
181  return os;
182 }
183 
184 TypeId
185 LteSpectrumPhy::GetTypeId (void)
186 {
187  static TypeId tid = TypeId ("ns3::LteSpectrumPhy")
188  .SetParent<SpectrumPhy> ()
189  .AddTraceSource ("TxStart",
190  "Trace fired when a new transmission is started",
191  MakeTraceSourceAccessor (&LteSpectrumPhy::m_phyTxStartTrace))
192  .AddTraceSource ("TxEnd",
193  "Trace fired when a previosuly started transmission is finished",
194  MakeTraceSourceAccessor (&LteSpectrumPhy::m_phyTxEndTrace))
195  .AddTraceSource ("RxStart",
196  "Trace fired when the start of a signal is detected",
197  MakeTraceSourceAccessor (&LteSpectrumPhy::m_phyRxStartTrace))
198  .AddTraceSource ("RxEndOk",
199  "Trace fired when a previosuly started RX terminates successfully",
200  MakeTraceSourceAccessor (&LteSpectrumPhy::m_phyRxEndOkTrace))
201  .AddTraceSource ("RxEndError",
202  "Trace fired when a previosuly started RX terminates with an error",
203  MakeTraceSourceAccessor (&LteSpectrumPhy::m_phyRxEndErrorTrace))
204  .AddAttribute ("DataErrorModelEnabled",
205  "Activate/Deactivate the error model of data (TBs of PDSCH and PUSCH) [by default is active].",
206  BooleanValue (true),
207  MakeBooleanAccessor (&LteSpectrumPhy::m_dataErrorModelEnabled),
208  MakeBooleanChecker ())
209  .AddAttribute ("CtrlErrorModelEnabled",
210  "Activate/Deactivate the error model of control (PCFICH-PDCCH decodification) [by default is active].",
211  BooleanValue (true),
212  MakeBooleanAccessor (&LteSpectrumPhy::m_ctrlErrorModelEnabled),
213  MakeBooleanChecker ())
214  .AddTraceSource ("DlPhyReception",
215  "DL reception PHY layer statistics.",
217  .AddTraceSource ("UlPhyReception",
218  "DL reception PHY layer statistics.",
220  ;
221  return tid;
222 }
223 
224 
225 
226 Ptr<NetDevice>
228 {
229  NS_LOG_FUNCTION (this);
230  return m_device;
231 }
232 
233 
236 {
237  NS_LOG_FUNCTION (this);
238  return m_mobility;
239 }
240 
241 
242 void
244 {
245  NS_LOG_FUNCTION (this << d);
246  m_device = d;
247 }
248 
249 
250 void
252 {
253  NS_LOG_FUNCTION (this << m);
254  m_mobility = m;
255 }
256 
257 
258 void
260 {
261  NS_LOG_FUNCTION (this << c);
262  m_channel = c;
263 }
264 
267 {
268  return m_channel;
269 }
270 
273 {
274  return m_rxSpectrumModel;
275 }
276 
277 
278 void
280 {
281  NS_LOG_FUNCTION (this << txPsd);
282  NS_ASSERT (txPsd);
283  m_txPsd = txPsd;
284 }
285 
286 
287 void
289 {
290  NS_LOG_FUNCTION (this << noisePsd);
291  NS_ASSERT (noisePsd);
292  m_rxSpectrumModel = noisePsd->GetSpectrumModel ();
293  m_interferenceData->SetNoisePowerSpectralDensity (noisePsd);
294  m_interferenceCtrl->SetNoisePowerSpectralDensity (noisePsd);
295 }
296 
297 
298 void
300 {
301  NS_LOG_FUNCTION (this);
302  m_cellId = 0;
303  m_state = IDLE;
304  m_transmissionMode = 0;
305  m_layersNum = 1;
306  m_endTxEvent.Cancel ();
307  m_endRxDataEvent.Cancel ();
308  m_endRxDlCtrlEvent.Cancel ();
309  m_endRxUlSrsEvent.Cancel ();
310  m_rxControlMessageList.clear ();
311  m_expectedTbs.clear ();
312  m_txControlMessageList.clear ();
313  m_rxPacketBurstList.clear ();
314  m_txPacketBurst = 0;
315  m_rxSpectrumModel = 0;
316 }
317 
318 
319 
320 void
322 {
323  NS_LOG_FUNCTION (this);
324  m_ltePhyTxEndCallback = c;
325 }
326 
327 
328 void
330 {
331  NS_LOG_FUNCTION (this);
332  m_ltePhyRxDataEndErrorCallback = c;
333 }
334 
335 
336 void
338 {
339  NS_LOG_FUNCTION (this);
340  m_ltePhyRxDataEndOkCallback = c;
341 }
342 
343 void
345 {
346  NS_LOG_FUNCTION (this);
347  m_ltePhyRxCtrlEndOkCallback = c;
348 }
349 
350 void
352 {
353  NS_LOG_FUNCTION (this);
354  m_ltePhyRxCtrlEndErrorCallback = c;
355 }
356 
357 void
359 {
360  NS_LOG_FUNCTION (this);
361  m_ltePhyDlHarqFeedbackCallback = c;
362 }
363 
364 void
366 {
367  NS_LOG_FUNCTION (this);
368  m_ltePhyUlHarqFeedbackCallback = c;
369 }
370 
371 
374 {
375  return m_antenna;
376 }
377 
378 void
380 {
381  NS_LOG_FUNCTION (this << a);
382  m_antenna = a;
383 }
384 
385 void
387 {
388  ChangeState (newState);
389 }
390 
391 
392 void
393 LteSpectrumPhy::ChangeState (State newState)
394 {
395  NS_LOG_LOGIC (this << " state: " << m_state << " -> " << newState);
396  m_state = newState;
397 }
398 
399 
400 void
401 LteSpectrumPhy::SetHarqPhyModule (Ptr<LteHarqPhy> harq)
402 {
403  m_harqPhyModule = harq;
404 }
405 
406 
407 
408 
409 bool
411 {
412  NS_LOG_FUNCTION (this << pb);
413  NS_LOG_LOGIC (this << " state: " << m_state);
414 
415  m_phyTxStartTrace (pb);
416 
417  switch (m_state)
418  {
419  case RX_DATA:
420  case RX_CTRL:
421  NS_FATAL_ERROR ("cannot TX while RX: according to FDD channel acces, the physical layer for transmission cannot be used for reception");
422  break;
423 
424  case TX:
425  NS_FATAL_ERROR ("cannot TX while already TX: the MAC should avoid this");
426  break;
427 
428  case IDLE:
429  {
430  /*
431  m_txPsd must be setted by the device, according to
432  (i) the available subchannel for transmission
433  (ii) the power transmission
434  */
435  NS_ASSERT (m_txPsd);
436  m_txPacketBurst = pb;
437 
438  // we need to convey some PHY meta information to the receiver
439  // to be used for simulation purposes (e.g., the CellId). This
440  // is done by setting the ctrlMsgList parameter of
441  // LteSpectrumSignalParametersDataFrame
442  ChangeState (TX);
443  NS_ASSERT (m_channel);
444  Ptr<LteSpectrumSignalParametersDataFrame> txParams = Create<LteSpectrumSignalParametersDataFrame> ();
445  txParams->duration = duration;
446  txParams->txPhy = GetObject<SpectrumPhy> ();
447  txParams->txAntenna = m_antenna;
448  txParams->psd = m_txPsd;
449  txParams->packetBurst = pb;
450  txParams->ctrlMsgList = ctrlMsgList;
451  txParams->cellId = m_cellId;
452  m_channel->StartTx (txParams);
453  m_endTxEvent = Simulator::Schedule (duration, &LteSpectrumPhy::EndTx, this);
454  }
455  return false;
456  break;
457 
458  default:
459  NS_FATAL_ERROR ("unknown state");
460  return true;
461  break;
462  }
463 }
464 
465 bool
467 {
468  NS_LOG_FUNCTION (this);
469  NS_LOG_LOGIC (this << " state: " << m_state);
470 
471 // m_phyTxStartTrace (pb);
472 
473  switch (m_state)
474  {
475  case RX_DATA:
476  case RX_CTRL:
477  NS_FATAL_ERROR ("cannot TX while RX: according to FDD channel acces, the physical layer for transmission cannot be used for reception");
478  break;
479 
480  case TX:
481  NS_FATAL_ERROR ("cannot TX while already TX: the MAC should avoid this");
482  break;
483 
484  case IDLE:
485  {
486  /*
487  m_txPsd must be setted by the device, according to
488  (i) the available subchannel for transmission
489  (ii) the power transmission
490  */
491  NS_ASSERT (m_txPsd);
492 
493  // we need to convey some PHY meta information to the receiver
494  // to be used for simulation purposes (e.g., the CellId). This
495  // is done by setting the cellId parameter of
496  // LteSpectrumSignalParametersDlCtrlFrame
497  ChangeState (TX);
498  NS_ASSERT (m_channel);
499 
500  Ptr<LteSpectrumSignalParametersDlCtrlFrame> txParams = Create<LteSpectrumSignalParametersDlCtrlFrame> ();
501  txParams->duration = DL_CTRL_DURATION;
502  txParams->txPhy = GetObject<SpectrumPhy> ();
503  txParams->txAntenna = m_antenna;
504  txParams->psd = m_txPsd;
505  txParams->cellId = m_cellId;
506  txParams->ctrlMsgList = ctrlMsgList;
507  m_channel->StartTx (txParams);
508  m_endTxEvent = Simulator::Schedule (DL_CTRL_DURATION, &LteSpectrumPhy::EndTx, this);
509  }
510  return false;
511  break;
512 
513  default:
514  NS_FATAL_ERROR ("unknown state");
515  return true;
516  break;
517  }
518 }
519 
520 
521 bool
523 {
524  NS_LOG_FUNCTION (this);
525  NS_LOG_LOGIC (this << " state: " << m_state);
526 
527  // m_phyTxStartTrace (pb);
528 
529  switch (m_state)
530  {
531  case RX_DATA:
532  case RX_CTRL:
533  NS_FATAL_ERROR ("cannot TX while RX: according to FDD channel acces, the physical layer for transmission cannot be used for reception");
534  break;
535 
536  case TX:
537  NS_FATAL_ERROR ("cannot TX while already TX: the MAC should avoid this");
538  break;
539 
540  case IDLE:
541  {
542  /*
543  m_txPsd must be setted by the device, according to
544  (i) the available subchannel for transmission
545  (ii) the power transmission
546  */
547  NS_ASSERT (m_txPsd);
548  NS_LOG_LOGIC (this << " m_txPsd: " << *m_txPsd);
549 
550  // we need to convey some PHY meta information to the receiver
551  // to be used for simulation purposes (e.g., the CellId). This
552  // is done by setting the cellId parameter of
553  // LteSpectrumSignalParametersDlCtrlFrame
554  ChangeState (TX);
555  NS_ASSERT (m_channel);
556  Ptr<LteSpectrumSignalParametersUlSrsFrame> txParams = Create<LteSpectrumSignalParametersUlSrsFrame> ();
557  txParams->duration = UL_SRS_DURATION;
558  txParams->txPhy = GetObject<SpectrumPhy> ();
559  txParams->txAntenna = m_antenna;
560  txParams->psd = m_txPsd;
561  txParams->cellId = m_cellId;
562  m_channel->StartTx (txParams);
563  m_endTxEvent = Simulator::Schedule (UL_SRS_DURATION, &LteSpectrumPhy::EndTx, this);
564  }
565  return false;
566  break;
567 
568  default:
569  NS_FATAL_ERROR ("unknown state");
570  return true;
571  break;
572  }
573 }
574 
575 
576 
577 void
578 LteSpectrumPhy::EndTx ()
579 {
580  NS_LOG_FUNCTION (this);
581  NS_LOG_LOGIC (this << " state: " << m_state);
582 
583  NS_ASSERT (m_state == TX);
584 
585  m_phyTxEndTrace (m_txPacketBurst);
586 
587  if (!m_ltePhyTxEndCallback.IsNull ())
588  {
589  for (std::list<Ptr<Packet> >::const_iterator iter = m_txPacketBurst->Begin (); iter
590  != m_txPacketBurst->End (); ++iter)
591  {
592  Ptr<Packet> packet = (*iter)->Copy ();
593  m_ltePhyTxEndCallback (packet);
594  }
595  }
596 
597  m_txPacketBurst = 0;
598  ChangeState (IDLE);
599 }
600 
601 
602 void
604 {
605  NS_LOG_FUNCTION (this << spectrumRxParams);
606  NS_LOG_LOGIC (this << " state: " << m_state);
607 
608  Ptr <const SpectrumValue> rxPsd = spectrumRxParams->psd;
609  Time duration = spectrumRxParams->duration;
610 
611  // the device might start RX only if the signal is of a type
612  // understood by this device - in this case, an LTE signal.
613  Ptr<LteSpectrumSignalParametersDataFrame> lteDataRxParams = DynamicCast<LteSpectrumSignalParametersDataFrame> (spectrumRxParams);
614  if (lteDataRxParams != 0)
615  {
616  m_interferenceData->AddSignal (rxPsd, duration);
617  StartRxData (lteDataRxParams);
618  }
619  else
620  {
621  Ptr<LteSpectrumSignalParametersDlCtrlFrame> lteDlCtrlRxParams = DynamicCast<LteSpectrumSignalParametersDlCtrlFrame> (spectrumRxParams);
622  Ptr<LteSpectrumSignalParametersUlSrsFrame> lteUlSrsRxParams = DynamicCast<LteSpectrumSignalParametersUlSrsFrame> (spectrumRxParams);
623  if ((lteDlCtrlRxParams!=0)||(lteUlSrsRxParams!=0))
624  {
625  m_interferenceCtrl->AddSignal (rxPsd, duration);
626  StartRxCtrl (spectrumRxParams);
627  }
628  else
629  {
630  // other type of signal (could be 3G, GSM, whatever) -> interference
631  m_interferenceData->AddSignal (rxPsd, duration);
632  m_interferenceCtrl->AddSignal (rxPsd, duration);
633  }
634  }
635 
636 }
637 
638 void
639 LteSpectrumPhy::StartRxData (Ptr<LteSpectrumSignalParametersDataFrame> params)
640 {
641  NS_LOG_FUNCTION (this);
642  switch (m_state)
643  {
644  case TX:
645  NS_FATAL_ERROR ("cannot RX while TX: according to FDD channel access, the physical layer for transmission cannot be used for reception");
646  break;
647  case RX_CTRL:
648  NS_FATAL_ERROR ("cannot RX Data while receiving control");
649  break;
650  case IDLE:
651  case RX_DATA:
652  // the behavior is similar when
653  // we're IDLE or RX because we can receive more signals
654  // simultaneously (e.g., at the eNB).
655  {
656  // To check if we're synchronized to this signal, we check
657  // for the CellId which is reported in the
658  // LteSpectrumSignalParametersDataFrame
659  if (params->cellId == m_cellId)
660  {
661  NS_LOG_LOGIC (this << " synchronized with this signal (cellId=" << params->cellId << ")");
662  if ((m_rxPacketBurstList.empty ())&&(m_rxControlMessageList.empty ()))
663  {
664  NS_ASSERT (m_state == IDLE);
665  // first transmission, i.e., we're IDLE and we
666  // start RX
667  m_firstRxStart = Simulator::Now ();
668  m_firstRxDuration = params->duration;
669  NS_LOG_LOGIC (this << " scheduling EndRx with delay " << params->duration.GetSeconds () << "s");
670  m_endRxDataEvent = Simulator::Schedule (params->duration, &LteSpectrumPhy::EndRxData, this);
671  }
672  else
673  {
674  NS_ASSERT (m_state == RX_DATA);
675  // sanity check: if there are multiple RX events, they
676  // should occur at the same time and have the same
677  // duration, otherwise the interference calculation
678  // won't be correct
679  NS_ASSERT ((m_firstRxStart == Simulator::Now ())
680  && (m_firstRxDuration == params->duration));
681  }
682 
683  ChangeState (RX_DATA);
684  if (params->packetBurst)
685  {
686  m_rxPacketBurstList.push_back (params->packetBurst);
687  m_interferenceData->StartRx (params->psd);
688 
689  m_phyRxStartTrace (params->packetBurst);
690  }
691  NS_LOG_DEBUG (this << " insert msgs " << params->ctrlMsgList.size ());
692  m_rxControlMessageList.insert (m_rxControlMessageList.end (), params->ctrlMsgList.begin (), params->ctrlMsgList.end ());
693 
694  NS_LOG_LOGIC (this << " numSimultaneousRxEvents = " << m_rxPacketBurstList.size ());
695  }
696  else
697  {
698  NS_LOG_LOGIC (this << " not in sync with this signal (cellId="
699  << params->cellId << ", m_cellId=" << m_cellId << ")");
700  }
701  }
702  break;
703 
704  default:
705  NS_FATAL_ERROR ("unknown state");
706  break;
707  }
708 
709  NS_LOG_LOGIC (this << " state: " << m_state);
710 }
711 
712 
713 
714 void
715 LteSpectrumPhy::StartRxCtrl (Ptr<SpectrumSignalParameters> params)
716 {
717  NS_LOG_FUNCTION (this);
718  switch (m_state)
719  {
720  case TX:
721  NS_FATAL_ERROR ("cannot RX while TX: according to FDD channel access, the physical layer for transmission cannot be used for reception");
722  break;
723  case RX_DATA:
724  NS_FATAL_ERROR ("cannot RX data while receing control");
725  break;
726  case IDLE:
727  case RX_CTRL:
728  // the behavior is similar when
729  // we're IDLE or RX because we can receive more signals
730  // simultaneously (e.g., at the eNB).
731  {
732  // To check if we're synchronized to this signal, we check
733  // for the CellId which is reported in the
734  // LteSpectrumSignalParametersDlCtrlFrame
735  uint16_t cellId;
736  bool dl;
737  Ptr<LteSpectrumSignalParametersDlCtrlFrame> lteDlCtrlRxParams = DynamicCast<LteSpectrumSignalParametersDlCtrlFrame> (params);
738  if (lteDlCtrlRxParams!=0)
739  {
740  cellId = lteDlCtrlRxParams->cellId;
741  dl = true;
742  }
743  else
744  {
745  Ptr<LteSpectrumSignalParametersUlSrsFrame> lteUlSrsRxParams = DynamicCast<LteSpectrumSignalParametersUlSrsFrame> (params);
746  cellId = lteUlSrsRxParams->cellId;
747  dl = false;
748  }
749  if (cellId == m_cellId)
750  {
751  NS_LOG_LOGIC (this << " synchronized with this signal (cellId=" << cellId << ")");
752  if (m_state == IDLE)
753  {
754  // first transmission, i.e., we're IDLE and we
755  // start RX
756  NS_ASSERT (m_rxControlMessageList.empty ());
757  m_firstRxStart = Simulator::Now ();
758  m_firstRxDuration = params->duration;
759  NS_LOG_LOGIC (this << " scheduling EndRx with delay " << params->duration);
760  if (dl==true)
761  {
762  // store the DCIs
763  m_rxControlMessageList = lteDlCtrlRxParams->ctrlMsgList;
764  m_endRxDlCtrlEvent = Simulator::Schedule (params->duration, &LteSpectrumPhy::EndRxDlCtrl, this);
765  }
766  else
767  {
768  m_endRxUlSrsEvent = Simulator::Schedule (params->duration, &LteSpectrumPhy::EndRxUlSrs, this);
769  }
770  }
771  else if (m_state == RX_CTRL)
772  {
773  // sanity check: if there are multiple RX events, they
774  // should occur at the same time and have the same
775  // duration, otherwise the interference calculation
776  // won't be correct
777  NS_ASSERT ((m_firstRxStart == Simulator::Now ())
778  && (m_firstRxDuration == params->duration));
779  }
780 
781  ChangeState (RX_CTRL);
782  m_interferenceCtrl->StartRx (params->psd);
783 
784 // NS_LOG_LOGIC (this << " numSimultaneousRxEvents = " << m_rxPacketBurstList.size ());
785  }
786  else
787  {
788  NS_LOG_LOGIC (this << " not in sync with this signal (cellId="
789  << cellId << ", m_cellId=" << m_cellId << ")");
790  }
791  }
792  break;
793 
794  default:
795  NS_FATAL_ERROR ("unknown state");
796  break;
797  }
798 
799  NS_LOG_LOGIC (this << " state: " << m_state);
800 }
801 
802 
803 void
805 {
806  NS_LOG_FUNCTION (this << sinr);
807  m_sinrPerceived = sinr;
808 }
809 
810 
811 void
812 LteSpectrumPhy::AddExpectedTb (uint16_t rnti, uint8_t ndi, uint16_t size, uint8_t mcs, std::vector<int> map, uint8_t layer, uint8_t harqId,uint8_t rv, bool downlink)
813 {
814  NS_LOG_FUNCTION (this << " rnti: " << rnti << " NDI " << (uint16_t)ndi << " size " << size << " mcs " << (uint16_t)mcs << " layer " << (uint16_t)layer << " rv " << (uint16_t)rv);
815  TbId_t tbId;
816  tbId.m_rnti = rnti;
817  tbId.m_layer = layer;
818  expectedTbs_t::iterator it;
819  it = m_expectedTbs.find (tbId);
820  if (it != m_expectedTbs.end ())
821  {
822  // migth be a TB of an unreceived packet (due to high progpalosses)
823  m_expectedTbs.erase (it);
824  }
825  // insert new entry
826  tbInfo_t tbInfo = {ndi, size, mcs, map, harqId, rv, 0.0, downlink, false, false};
827  m_expectedTbs.insert (std::pair<TbId_t, tbInfo_t> (tbId,tbInfo));
828 }
829 
830 
831 void
832 LteSpectrumPhy::EndRxData ()
833 {
834  NS_LOG_FUNCTION (this);
835  NS_LOG_LOGIC (this << " state: " << m_state);
836 
837  NS_ASSERT (m_state == RX_DATA);
838 
839  // this will trigger CQI calculation and Error Model evaluation
840  // as a side effect, the error model should update the error status of all TBs
841  m_interferenceData->EndRx ();
842  NS_LOG_DEBUG (this << " No. of burts " << m_rxPacketBurstList.size ());
843  NS_LOG_DEBUG (this << " Expected TBs " << m_expectedTbs.size ());
844  expectedTbs_t::iterator itTb = m_expectedTbs.begin ();
845 
846  // apply transmission mode gain
847  NS_LOG_DEBUG (this << " txMode " << (uint16_t)m_transmissionMode << " gain " << m_txModeGain.at (m_transmissionMode));
848  NS_ASSERT (m_transmissionMode < m_txModeGain.size ());
849  m_sinrPerceived *= m_txModeGain.at (m_transmissionMode);
850 
851  while (itTb!=m_expectedTbs.end ())
852  {
853  if ((m_dataErrorModelEnabled)&&(m_rxPacketBurstList.size ()>0)) // avoid to check for errors when there is no actual data transmitted
854  {
855  // retrieve HARQ info
856  HarqProcessInfoList_t harqInfoList;
857  if ((*itTb).second.ndi == 0)
858  {
859  // TB retxed: retrieve HARQ history
860  uint16_t ulHarqId = 0;
861  if ((*itTb).second.downlink)
862  {
863  harqInfoList = m_harqPhyModule->GetHarqProcessInfoDl ((*itTb).second.harqProcessId, (*itTb).first.m_layer);
864  }
865  else
866  {
867  harqInfoList = m_harqPhyModule->GetHarqProcessInfoUl ((*itTb).first.m_rnti, ulHarqId);
868  }
869  }
870  TbStats_t tbStats = LteMiErrorModel::GetTbDecodificationStats (m_sinrPerceived, (*itTb).second.rbBitmap, (*itTb).second.size, (*itTb).second.mcs, harqInfoList);
871  (*itTb).second.mi = tbStats.mi;
872  (*itTb).second.corrupt = m_random->GetValue () > tbStats.tbler ? false : true;
873  NS_LOG_DEBUG (this << "RNTI " << (*itTb).first.m_rnti << " size " << (*itTb).second.size << " mcs " << (uint32_t)(*itTb).second.mcs << " bitmap " << (*itTb).second.rbBitmap.size () << " layer " << (uint16_t)(*itTb).first.m_layer << " TBLER " << tbStats.tbler << " corrupted " << (*itTb).second.corrupt);
874  // fire traces on DL/UL reception PHY stats
875  PhyReceptionStatParameters params;
876  params.m_timestamp = Simulator::Now ().GetMilliSeconds ();
877  params.m_cellId = m_cellId;
878  params.m_imsi = 0; // it will be set by DlPhyTransmissionCallback in LteHelper
879  params.m_rnti = (*itTb).first.m_rnti;
880  params.m_txMode = m_transmissionMode;
881  params.m_layer = (*itTb).first.m_layer;
882  params.m_mcs = (*itTb).second.mcs;
883  params.m_size = (*itTb).second.size;
884  params.m_rv = (*itTb).second.rv;
885  params.m_ndi = (*itTb).second.ndi;
886  params.m_correctness = (uint8_t)!(*itTb).second.corrupt;
887  if ((*itTb).second.downlink)
888  {
889  // DL
890  m_dlPhyReception (params);
891  }
892  else
893  {
894  // UL
895  params.m_rv = harqInfoList.size ();
896  m_ulPhyReception (params);
897  }
898  }
899 
900  itTb++;
901  }
902  std::map <uint16_t, DlInfoListElement_s> harqDlInfoMap;
903  for (std::list<Ptr<PacketBurst> >::const_iterator i = m_rxPacketBurstList.begin ();
904  i != m_rxPacketBurstList.end (); ++i)
905  {
906  for (std::list<Ptr<Packet> >::const_iterator j = (*i)->Begin (); j != (*i)->End (); ++j)
907  {
908  // retrieve TB info of this packet
909  LteRadioBearerTag tag;
910  (*j)->PeekPacketTag (tag);
911  TbId_t tbId;
912  tbId.m_rnti = tag.GetRnti ();
913  tbId.m_layer = tag.GetLayer ();
914  itTb = m_expectedTbs.find (tbId);
915  NS_LOG_INFO (this << " Packet of " << tbId.m_rnti << " layer " << (uint16_t) tag.GetLayer ());
916  if (itTb!=m_expectedTbs.end ())
917  {
918  if (!(*itTb).second.corrupt)
919  {
920  m_phyRxEndOkTrace (*j);
921 
922  if (!m_ltePhyRxDataEndOkCallback.IsNull ())
923  {
924  m_ltePhyRxDataEndOkCallback (*j);
925  }
926  }
927  else
928  {
929  // TB received with errors
930  m_phyRxEndErrorTrace (*j);
931  }
932 
933  // send HARQ feedback (if not already done for this TB)
934  if (!(*itTb).second.harqFeedbackSent)
935  {
936  (*itTb).second.harqFeedbackSent = true;
937  if (!(*itTb).second.downlink)
938  {
939  UlInfoListElement_s harqUlInfo;
940  harqUlInfo.m_rnti = tbId.m_rnti;
941  harqUlInfo.m_tpc = 0;
942  if ((*itTb).second.corrupt)
943  {
944  harqUlInfo.m_receptionStatus = UlInfoListElement_s::NotOk;
945  NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " send UL-HARQ-NACK");
946  m_harqPhyModule->UpdateUlHarqProcessStatus (tbId.m_rnti, (*itTb).second.mi, (*itTb).second.size, (*itTb).second.size / EffectiveCodingRate [(*itTb).second.mcs]);
947  }
948  else
949  {
950  harqUlInfo.m_receptionStatus = UlInfoListElement_s::Ok;
951  NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " send UL-HARQ-ACK");
952  m_harqPhyModule->ResetUlHarqProcessStatus (tbId.m_rnti, (*itTb).second.harqProcessId);
953  }
954  if (!m_ltePhyUlHarqFeedbackCallback.IsNull ())
955  {
956  m_ltePhyUlHarqFeedbackCallback (harqUlInfo);
957  }
958  }
959  else
960  {
961  std::map <uint16_t, DlInfoListElement_s>::iterator itHarq = harqDlInfoMap.find (tbId.m_rnti);
962  if (itHarq==harqDlInfoMap.end ())
963  {
964  DlInfoListElement_s harqDlInfo;
965  harqDlInfo.m_harqStatus.resize (m_layersNum, DlInfoListElement_s::NACK);
966  harqDlInfo.m_rnti = tbId.m_rnti;
967  harqDlInfo.m_harqProcessId = (*itTb).second.harqProcessId;
968  if ((*itTb).second.corrupt)
969  {
970  harqDlInfo.m_harqStatus.at (tbId.m_layer) = DlInfoListElement_s::NACK;
971  NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " harqId " << (uint16_t)(*itTb).second.harqProcessId << " layer " <<(uint16_t)tbId.m_layer << " send DL-HARQ-NACK");
972  m_harqPhyModule->UpdateDlHarqProcessStatus ((*itTb).second.harqProcessId, tbId.m_layer, (*itTb).second.mi, (*itTb).second.size, (*itTb).second.size / EffectiveCodingRate [(*itTb).second.mcs]);
973  }
974  else
975  {
976 
977  harqDlInfo.m_harqStatus.at (tbId.m_layer) = DlInfoListElement_s::ACK;
978  NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " harqId " << (uint16_t)(*itTb).second.harqProcessId << " layer " <<(uint16_t)tbId.m_layer << " size " << (*itTb).second.size << " send DL-HARQ-ACK");
979  m_harqPhyModule->ResetDlHarqProcessStatus ((*itTb).second.harqProcessId);
980  }
981  harqDlInfoMap.insert (std::pair <uint16_t, DlInfoListElement_s> (tbId.m_rnti, harqDlInfo));
982  }
983  else
984  {
985  if ((*itTb).second.corrupt)
986  {
987  (*itHarq).second.m_harqStatus.at (tbId.m_layer) = DlInfoListElement_s::NACK;
988  NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " harqId " << (uint16_t)(*itTb).second.harqProcessId << " layer " <<(uint16_t)tbId.m_layer << " size " << (*itHarq).second.m_harqStatus.size () << " send DL-HARQ-NACK");
989  m_harqPhyModule->UpdateDlHarqProcessStatus ((*itTb).second.harqProcessId, tbId.m_layer, (*itTb).second.mi, (*itTb).second.size, (*itTb).second.size / EffectiveCodingRate [(*itTb).second.mcs]);
990  }
991  else
992  {
993  NS_ASSERT_MSG (tbId.m_layer < (*itHarq).second.m_harqStatus.size (), " layer " << (uint16_t)tbId.m_layer);
994  (*itHarq).second.m_harqStatus.at (tbId.m_layer) = DlInfoListElement_s::ACK;
995  NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " harqId " << (uint16_t)(*itTb).second.harqProcessId << " layer " << (uint16_t)tbId.m_layer << " size " << (*itHarq).second.m_harqStatus.size () << " send DL-HARQ-ACK");
996  m_harqPhyModule->ResetDlHarqProcessStatus ((*itTb).second.harqProcessId);
997  }
998  }
999  } // end if ((*itTb).second.downlink) HARQ
1000  } // end if (!(*itTb).second.harqFeedbackSent)
1001  }
1002  }
1003  }
1004 
1005  // send DL HARQ feedback to LtePhy
1006  std::map <uint16_t, DlInfoListElement_s>::iterator itHarq;
1007  for (itHarq = harqDlInfoMap.begin (); itHarq != harqDlInfoMap.end (); itHarq++)
1008  {
1009  if (!m_ltePhyDlHarqFeedbackCallback.IsNull ())
1010  {
1011  m_ltePhyDlHarqFeedbackCallback ((*itHarq).second);
1012  }
1013  }
1014  // forward control messages of this frame to LtePhy
1015  if (!m_rxControlMessageList.empty ())
1016  {
1017  if (!m_ltePhyRxCtrlEndOkCallback.IsNull ())
1018  {
1019  m_ltePhyRxCtrlEndOkCallback (m_rxControlMessageList);
1020  }
1021  }
1022  ChangeState (IDLE);
1023  m_rxPacketBurstList.clear ();
1024  m_rxControlMessageList.clear ();
1025  m_expectedTbs.clear ();
1026 }
1027 
1028 
1029 void
1030 LteSpectrumPhy::EndRxDlCtrl ()
1031 {
1032  NS_LOG_FUNCTION (this);
1033  NS_LOG_LOGIC (this << " state: " << m_state);
1034 
1035  NS_ASSERT (m_state == RX_CTRL);
1036 
1037  // this will trigger CQI calculation and Error Model evaluation
1038  // as a side effect, the error model should update the error status of all TBs
1039  m_interferenceCtrl->EndRx ();
1040  // apply transmission mode gain
1041  NS_LOG_DEBUG (this << " txMode " << (uint16_t)m_transmissionMode << " gain " << m_txModeGain.at (m_transmissionMode));
1042  NS_ASSERT (m_transmissionMode < m_txModeGain.size ());
1043  if (m_transmissionMode>0)
1044  {
1045  // in case of MIMO, ctrl is always txed as TX diversity
1046  m_sinrPerceived *= m_txModeGain.at (1);
1047  }
1048 // m_sinrPerceived *= m_txModeGain.at (m_transmissionMode);
1049  bool error = false;
1050  if (m_ctrlErrorModelEnabled)
1051  {
1052  double errorRate = LteMiErrorModel::GetPcfichPdcchError (m_sinrPerceived);
1053  errorRate = LteMiErrorModel::GetPcfichPdcchError (m_sinrPerceived);
1054  error = m_random->GetValue () > errorRate ? false : true;
1055  NS_LOG_DEBUG (this << " PCFICH-PDCCH Decodification, errorRate " << errorRate << " error " << error);
1056  }
1057 
1058  if (!error)
1059  {
1060  if (!m_ltePhyRxCtrlEndOkCallback.IsNull ())
1061  {
1062  NS_LOG_DEBUG (this << " PCFICH-PDCCH Rxed OK");
1063  m_ltePhyRxCtrlEndOkCallback (m_rxControlMessageList);
1064  }
1065  }
1066  else
1067  {
1068  if (!m_ltePhyRxCtrlEndErrorCallback.IsNull ())
1069  {
1070  NS_LOG_DEBUG (this << " PCFICH-PDCCH Error");
1071  m_ltePhyRxCtrlEndErrorCallback ();
1072  }
1073  }
1074  ChangeState (IDLE);
1075  m_rxControlMessageList.clear ();
1076 }
1077 
1078 void
1079 LteSpectrumPhy::EndRxUlSrs ()
1080 {
1081  NS_ASSERT (m_state == RX_CTRL);
1082  ChangeState (IDLE);
1083  m_interferenceCtrl->EndRx ();
1084  // nothing to do (used only for SRS at this stage)
1085 }
1086 
1087 void
1088 LteSpectrumPhy::SetCellId (uint16_t cellId)
1089 {
1090  m_cellId = cellId;
1091 }
1092 
1093 
1094 void
1096 {
1097  m_interferenceCtrl->AddRsPowerChunkProcessor (p);
1098 }
1099 
1100 
1101 void
1103 {
1104  m_interferenceData->AddSinrChunkProcessor (p);
1105 }
1106 
1107 void
1109 {
1110  m_interferenceData->AddInterferenceChunkProcessor (p);
1111 }
1112 
1113 void
1115 {
1116  m_interferenceCtrl->AddSinrChunkProcessor (p);
1117 }
1118 
1119 void
1121 {
1122  NS_LOG_FUNCTION (this << (uint16_t) txMode);
1123  NS_ASSERT_MSG (txMode < m_txModeGain.size (), "TransmissionMode not available: 1.." << m_txModeGain.size ());
1124  m_transmissionMode = txMode;
1125  m_layersNum = TransmissionModesLayers::TxMode2LayerNum (txMode);
1126 }
1127 
1128 
1129 void
1130 LteSpectrumPhy::SetTxModeGain (uint8_t txMode, double gain)
1131 {
1132  NS_LOG_FUNCTION (this << " txmode " << (uint16_t)txMode << " gain " << gain);
1133  // convert to linear
1134  gain = std::pow (10.0, (gain / 10.0));
1135  if (m_txModeGain.size () < txMode)
1136  {
1137  m_txModeGain.resize (txMode);
1138  }
1139  std::vector <double> temp;
1140  temp = m_txModeGain;
1141  m_txModeGain.clear ();
1142  for (uint8_t i = 0; i < temp.size (); i++)
1143  {
1144  if (i==txMode-1)
1145  {
1146  m_txModeGain.push_back (gain);
1147  }
1148  else
1149  {
1150  m_txModeGain.push_back (temp.at (i));
1151  }
1152  }
1153 }
1154 
1155 int64_t
1157 {
1158  NS_LOG_FUNCTION (this << stream);
1159  m_random->SetStream (stream);
1160  return 1;
1161 }
1162 
1163 
1164 
1165 } // namespace ns3
void SetLtePhyTxEndCallback(LtePhyTxEndCallback c)
Time NanoSeconds(uint64_t ns)
create ns3::Time instances in units of nanoseconds.
Definition: nstime.h:629
keep track of time unit.
Definition: nstime.h:149
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
void SetState(State newState)
Set the state of the phy layer.
#define NS_ASSERT(condition)
Definition: assert.h:64
void SetLtePhyRxDataEndErrorCallback(LtePhyRxDataEndErrorCallback c)
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
void SetTransmissionMode(uint8_t txMode)
virtual void DoDispose(void)
Definition: object.cc:335
#define NS_LOG_INFO(msg)
Definition: log.h:264
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
Ptr< SpectrumChannel > GetChannel()
static TbStats_t GetTbDecodificationStats(const SpectrumValue &sinr, const std::vector< int > &map, uint16_t size, uint8_t mcs, HarqProcessInfoList_t miHistory)
run the error-model algorithm for the specified TB
void SetNoisePowerSpectralDensity(Ptr< const SpectrumValue > noisePsd)
set the noise power spectral density
Ptr< UniformRandomVariable > m_random
Provides uniform random variables.
void SetDevice(Ptr< NetDevice > d)
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
void SetLtePhyUlHarqFeedbackCallback(LtePhyUlHarqFeedbackCallback c)
void SetLtePhyRxCtrlEndOkCallback(LtePhyRxCtrlEndOkCallback c)
void SetTxPowerSpectralDensity(Ptr< SpectrumValue > txPsd)
void SetLtePhyRxCtrlEndErrorCallback(LtePhyRxCtrlEndErrorCallback c)
bool StartTxDataFrame(Ptr< PacketBurst > pb, std::list< Ptr< LteControlMessage > > ctrlMsgList, Time duration)
int64_t AssignStreams(int64_t stream)
static double GetPcfichPdcchError(const SpectrumValue &sinr)
run the error-model algorithm for the specified PCFICH+PDCCH channels
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
virtual void DoDispose()
Ptr< NetDevice > GetDevice()
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:43
Ptr< Packet > Copy(void) const
Definition: packet.cc:131
void SetAntenna(Ptr< AntennaModel > a)
void AddRsPowerChunkProcessor(Ptr< LteSinrChunkProcessor > p)
void AddExpectedTb(uint16_t rnti, uint8_t ndi, uint16_t size, uint8_t mcs, std::vector< int > map, uint8_t layer, uint8_t harqId, uint8_t rv, bool downlink)
Ptr< const SpectrumModel > GetRxSpectrumModel() const
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Ptr< AntennaModel > GetRxAntenna()
Ptr< MobilityModel > GetMobility()
double GetValue(double min, double max)
Returns a random double from the uniform distribution with the specified range.
bool StartTxDlCtrlFrame(std::list< Ptr< LteControlMessage > > ctrlMsgList)
void SetChannel(Ptr< SpectrumChannel > c)
TracedCallback< PhyReceptionStatParameters > m_ulPhyReception
static Time Now(void)
Definition: simulator.cc:179
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
void SetLtePhyDlHarqFeedbackCallback(LtePhyDlHarqFeedbackCallback c)
void AddCtrlSinrChunkProcessor(Ptr< LteSinrChunkProcessor > p)
void AddDataSinrChunkProcessor(Ptr< LteSinrChunkProcessor > p)
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
void Cancel(void)
Definition: event-id.cc:47
void SetLtePhyRxDataEndOkCallback(LtePhyRxDataEndOkCallback c)
void SetMobility(Ptr< MobilityModel > m)
void AddInterferenceChunkProcessor(Ptr< LteSinrChunkProcessor > p)
void StartRx(Ptr< SpectrumSignalParameters > params)
Set of values corresponding to a given SpectrumModel.
void UpdateSinrPerceived(const SpectrumValue &sinr)
int64_t GetMilliSeconds(void) const
Definition: nstime.h:271
void SetCellId(uint16_t cellId)
TracedCallback< PhyReceptionStatParameters > m_dlPhyReception