A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
lte-spectrum-phy.cc
Go to the documentation of this file.
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"
32 #include "lte-net-device.h"
33 #include "lte-radio-bearer-tag.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 
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 
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 
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 > ();
158  m_ltePhyRxPssCallback = MakeNullCallback< void, uint16_t, Ptr<SpectrumValue> > ();
160 }
161 
162 std::ostream& operator<< (std::ostream& os, LteSpectrumPhy::State s)
163 {
164  switch (s)
165  {
167  os << "IDLE";
168  break;
170  os << "RX_DATA";
171  break;
173  os << "RX_CTRL";
174  break;
175  case LteSpectrumPhy::TX:
176  os << "TX";
177  break;
178  default:
179  os << "UNKNOWN";
180  break;
181  }
182  return os;
183 }
184 
185 TypeId
187 {
188  static TypeId tid = TypeId ("ns3::LteSpectrumPhy")
190  .AddTraceSource ("TxStart",
191  "Trace fired when a new transmission is started",
193  .AddTraceSource ("TxEnd",
194  "Trace fired when a previosuly started transmission is finished",
196  .AddTraceSource ("RxStart",
197  "Trace fired when the start of a signal is detected",
199  .AddTraceSource ("RxEndOk",
200  "Trace fired when a previosuly started RX terminates successfully",
202  .AddTraceSource ("RxEndError",
203  "Trace fired when a previosuly started RX terminates with an error",
205  .AddAttribute ("DataErrorModelEnabled",
206  "Activate/Deactivate the error model of data (TBs of PDSCH and PUSCH) [by default is active].",
207  BooleanValue (true),
208  MakeBooleanAccessor (&LteSpectrumPhy::m_dataErrorModelEnabled),
209  MakeBooleanChecker ())
210  .AddAttribute ("CtrlErrorModelEnabled",
211  "Activate/Deactivate the error model of control (PCFICH-PDCCH decodification) [by default is active].",
212  BooleanValue (true),
213  MakeBooleanAccessor (&LteSpectrumPhy::m_ctrlErrorModelEnabled),
214  MakeBooleanChecker ())
215  .AddTraceSource ("DlPhyReception",
216  "DL reception PHY layer statistics.",
218  .AddTraceSource ("UlPhyReception",
219  "DL reception PHY layer statistics.",
221  ;
222  return tid;
223 }
224 
225 
226 
229 {
230  NS_LOG_FUNCTION (this);
231  return m_device;
232 }
233 
234 
237 {
238  NS_LOG_FUNCTION (this);
239  return m_mobility;
240 }
241 
242 
243 void
245 {
246  NS_LOG_FUNCTION (this << d);
247  m_device = d;
248 }
249 
250 
251 void
253 {
254  NS_LOG_FUNCTION (this << m);
255  m_mobility = m;
256 }
257 
258 
259 void
261 {
262  NS_LOG_FUNCTION (this << c);
263  m_channel = c;
264 }
265 
268 {
269  return m_channel;
270 }
271 
274 {
275  return m_rxSpectrumModel;
276 }
277 
278 
279 void
281 {
282  NS_LOG_FUNCTION (this << txPsd);
283  NS_ASSERT (txPsd);
284  m_txPsd = txPsd;
285 }
286 
287 
288 void
290 {
291  NS_LOG_FUNCTION (this << noisePsd);
292  NS_ASSERT (noisePsd);
293  m_rxSpectrumModel = noisePsd->GetSpectrumModel ();
294  m_interferenceData->SetNoisePowerSpectralDensity (noisePsd);
295  m_interferenceCtrl->SetNoisePowerSpectralDensity (noisePsd);
296 }
297 
298 
299 void
301 {
302  NS_LOG_FUNCTION (this);
303  m_cellId = 0;
304  m_state = IDLE;
305  m_transmissionMode = 0;
306  m_layersNum = 1;
307  m_endTxEvent.Cancel ();
311  m_rxControlMessageList.clear ();
312  m_expectedTbs.clear ();
313  m_txControlMessageList.clear ();
314  m_rxPacketBurstList.clear ();
315  m_txPacketBurst = 0;
316  m_rxSpectrumModel = 0;
317 }
318 
319 
320 
321 void
323 {
324  NS_LOG_FUNCTION (this);
326 }
327 
328 
329 void
331 {
332  NS_LOG_FUNCTION (this);
334 }
335 
336 
337 void
339 {
340  NS_LOG_FUNCTION (this);
342 }
343 
344 void
346 {
347  NS_LOG_FUNCTION (this);
349 }
350 
351 void
353 {
354  NS_LOG_FUNCTION (this);
356 }
357 
358 
359 void
361 {
362  NS_LOG_FUNCTION (this);
364 }
365 
366 void
368 {
369  NS_LOG_FUNCTION (this);
371 }
372 
373 void
375 {
376  NS_LOG_FUNCTION (this);
378 }
379 
380 
383 {
384  return m_antenna;
385 }
386 
387 void
389 {
390  NS_LOG_FUNCTION (this << a);
391  m_antenna = a;
392 }
393 
394 void
396 {
397  ChangeState (newState);
398 }
399 
400 
401 void
403 {
404  NS_LOG_LOGIC (this << " state: " << m_state << " -> " << newState);
405  m_state = newState;
406 }
407 
408 
409 void
411 {
412  m_harqPhyModule = harq;
413 }
414 
415 
416 
417 
418 bool
420 {
421  NS_LOG_FUNCTION (this << pb);
422  NS_LOG_LOGIC (this << " state: " << m_state);
423 
424  m_phyTxStartTrace (pb);
425 
426  switch (m_state)
427  {
428  case RX_DATA:
429  case RX_CTRL:
430  NS_FATAL_ERROR ("cannot TX while RX: according to FDD channel acces, the physical layer for transmission cannot be used for reception");
431  break;
432 
433  case TX:
434  NS_FATAL_ERROR ("cannot TX while already TX: the MAC should avoid this");
435  break;
436 
437  case IDLE:
438  {
439  /*
440  m_txPsd must be setted by the device, according to
441  (i) the available subchannel for transmission
442  (ii) the power transmission
443  */
444  NS_ASSERT (m_txPsd);
445  m_txPacketBurst = pb;
446 
447  // we need to convey some PHY meta information to the receiver
448  // to be used for simulation purposes (e.g., the CellId). This
449  // is done by setting the ctrlMsgList parameter of
450  // LteSpectrumSignalParametersDataFrame
451  ChangeState (TX);
453  Ptr<LteSpectrumSignalParametersDataFrame> txParams = Create<LteSpectrumSignalParametersDataFrame> ();
454  txParams->duration = duration;
455  txParams->txPhy = GetObject<SpectrumPhy> ();
456  txParams->txAntenna = m_antenna;
457  txParams->psd = m_txPsd;
458  txParams->packetBurst = pb;
459  txParams->ctrlMsgList = ctrlMsgList;
460  txParams->cellId = m_cellId;
461  m_channel->StartTx (txParams);
463  }
464  return false;
465  break;
466 
467  default:
468  NS_FATAL_ERROR ("unknown state");
469  return true;
470  break;
471  }
472 }
473 
474 bool
476 {
477  NS_LOG_FUNCTION (this << " PSS " << (uint16_t)pss);
478  NS_LOG_LOGIC (this << " state: " << m_state);
479 
480 
481 // m_phyTxStartTrace (pb);
482 
483  switch (m_state)
484  {
485  case RX_DATA:
486  case RX_CTRL:
487  NS_FATAL_ERROR ("cannot TX while RX: according to FDD channel acces, the physical layer for transmission cannot be used for reception");
488  break;
489 
490  case TX:
491  NS_FATAL_ERROR ("cannot TX while already TX: the MAC should avoid this");
492  break;
493 
494  case IDLE:
495  {
496  /*
497  m_txPsd must be setted by the device, according to
498  (i) the available subchannel for transmission
499  (ii) the power transmission
500  */
501  NS_ASSERT (m_txPsd);
502 
503  // we need to convey some PHY meta information to the receiver
504  // to be used for simulation purposes (e.g., the CellId). This
505  // is done by setting the cellId parameter of
506  // LteSpectrumSignalParametersDlCtrlFrame
507  ChangeState (TX);
509 
510  Ptr<LteSpectrumSignalParametersDlCtrlFrame> txParams = Create<LteSpectrumSignalParametersDlCtrlFrame> ();
511  txParams->duration = DL_CTRL_DURATION;
512  txParams->txPhy = GetObject<SpectrumPhy> ();
513  txParams->txAntenna = m_antenna;
514  txParams->psd = m_txPsd;
515  txParams->cellId = m_cellId;
516  txParams->pss = pss;
517  txParams->ctrlMsgList = ctrlMsgList;
518  m_channel->StartTx (txParams);
520  }
521  return false;
522  break;
523 
524  default:
525  NS_FATAL_ERROR ("unknown state");
526  return true;
527  break;
528  }
529 }
530 
531 
532 bool
534 {
535  NS_LOG_FUNCTION (this);
536  NS_LOG_LOGIC (this << " state: " << m_state);
537 
538  // m_phyTxStartTrace (pb);
539 
540  switch (m_state)
541  {
542  case RX_DATA:
543  case RX_CTRL:
544  NS_FATAL_ERROR ("cannot TX while RX: according to FDD channel acces, the physical layer for transmission cannot be used for reception");
545  break;
546 
547  case TX:
548  NS_FATAL_ERROR ("cannot TX while already TX: the MAC should avoid this");
549  break;
550 
551  case IDLE:
552  {
553  /*
554  m_txPsd must be setted by the device, according to
555  (i) the available subchannel for transmission
556  (ii) the power transmission
557  */
558  NS_ASSERT (m_txPsd);
559  NS_LOG_LOGIC (this << " m_txPsd: " << *m_txPsd);
560 
561  // we need to convey some PHY meta information to the receiver
562  // to be used for simulation purposes (e.g., the CellId). This
563  // is done by setting the cellId parameter of
564  // LteSpectrumSignalParametersDlCtrlFrame
565  ChangeState (TX);
567  Ptr<LteSpectrumSignalParametersUlSrsFrame> txParams = Create<LteSpectrumSignalParametersUlSrsFrame> ();
568  txParams->duration = UL_SRS_DURATION;
569  txParams->txPhy = GetObject<SpectrumPhy> ();
570  txParams->txAntenna = m_antenna;
571  txParams->psd = m_txPsd;
572  txParams->cellId = m_cellId;
573  m_channel->StartTx (txParams);
575  }
576  return false;
577  break;
578 
579  default:
580  NS_FATAL_ERROR ("unknown state");
581  return true;
582  break;
583  }
584 }
585 
586 
587 
588 void
590 {
591  NS_LOG_FUNCTION (this);
592  NS_LOG_LOGIC (this << " state: " << m_state);
593 
594  NS_ASSERT (m_state == TX);
595 
597 
599  {
600  for (std::list<Ptr<Packet> >::const_iterator iter = m_txPacketBurst->Begin (); iter
601  != m_txPacketBurst->End (); ++iter)
602  {
603  Ptr<Packet> packet = (*iter)->Copy ();
604  m_ltePhyTxEndCallback (packet);
605  }
606  }
607 
608  m_txPacketBurst = 0;
609  ChangeState (IDLE);
610 }
611 
612 
613 void
615 {
616  NS_LOG_FUNCTION (this << spectrumRxParams);
617  NS_LOG_LOGIC (this << " state: " << m_state);
618 
619  Ptr <const SpectrumValue> rxPsd = spectrumRxParams->psd;
620  Time duration = spectrumRxParams->duration;
621 
622  // the device might start RX only if the signal is of a type
623  // understood by this device - in this case, an LTE signal.
624  Ptr<LteSpectrumSignalParametersDataFrame> lteDataRxParams = DynamicCast<LteSpectrumSignalParametersDataFrame> (spectrumRxParams);
625  if (lteDataRxParams != 0)
626  {
627  m_interferenceData->AddSignal (rxPsd, duration);
628  StartRxData (lteDataRxParams);
629  }
630  else
631  {
632  Ptr<LteSpectrumSignalParametersDlCtrlFrame> lteDlCtrlRxParams = DynamicCast<LteSpectrumSignalParametersDlCtrlFrame> (spectrumRxParams);
633  Ptr<LteSpectrumSignalParametersUlSrsFrame> lteUlSrsRxParams = DynamicCast<LteSpectrumSignalParametersUlSrsFrame> (spectrumRxParams);
634  if ((lteDlCtrlRxParams!=0)||(lteUlSrsRxParams!=0))
635  {
636  m_interferenceCtrl->AddSignal (rxPsd, duration);
637  StartRxCtrl (spectrumRxParams);
638  }
639  else
640  {
641  // other type of signal (could be 3G, GSM, whatever) -> interference
642  m_interferenceData->AddSignal (rxPsd, duration);
643  m_interferenceCtrl->AddSignal (rxPsd, duration);
644  }
645  }
646 
647 }
648 
649 void
651 {
652  NS_LOG_FUNCTION (this);
653  switch (m_state)
654  {
655  case TX:
656  NS_FATAL_ERROR ("cannot RX while TX: according to FDD channel access, the physical layer for transmission cannot be used for reception");
657  break;
658  case RX_CTRL:
659  NS_FATAL_ERROR ("cannot RX Data while receiving control");
660  break;
661  case IDLE:
662  case RX_DATA:
663  // the behavior is similar when
664  // we're IDLE or RX because we can receive more signals
665  // simultaneously (e.g., at the eNB).
666  {
667  // To check if we're synchronized to this signal, we check
668  // for the CellId which is reported in the
669  // LteSpectrumSignalParametersDataFrame
670  if (params->cellId == m_cellId)
671  {
672  NS_LOG_LOGIC (this << " synchronized with this signal (cellId=" << params->cellId << ")");
673  if ((m_rxPacketBurstList.empty ())&&(m_rxControlMessageList.empty ()))
674  {
675  NS_ASSERT (m_state == IDLE);
676  // first transmission, i.e., we're IDLE and we
677  // start RX
679  m_firstRxDuration = params->duration;
680  NS_LOG_LOGIC (this << " scheduling EndRx with delay " << params->duration.GetSeconds () << "s");
682  }
683  else
684  {
686  // sanity check: if there are multiple RX events, they
687  // should occur at the same time and have the same
688  // duration, otherwise the interference calculation
689  // won't be correct
691  && (m_firstRxDuration == params->duration));
692  }
693 
695  if (params->packetBurst)
696  {
697  m_rxPacketBurstList.push_back (params->packetBurst);
698  m_interferenceData->StartRx (params->psd);
699 
700  m_phyRxStartTrace (params->packetBurst);
701  }
702  NS_LOG_DEBUG (this << " insert msgs " << params->ctrlMsgList.size ());
703  m_rxControlMessageList.insert (m_rxControlMessageList.end (), params->ctrlMsgList.begin (), params->ctrlMsgList.end ());
704 
705  NS_LOG_LOGIC (this << " numSimultaneousRxEvents = " << m_rxPacketBurstList.size ());
706  }
707  else
708  {
709  NS_LOG_LOGIC (this << " not in sync with this signal (cellId="
710  << params->cellId << ", m_cellId=" << m_cellId << ")");
711  }
712  }
713  break;
714 
715  default:
716  NS_FATAL_ERROR ("unknown state");
717  break;
718  }
719 
720  NS_LOG_LOGIC (this << " state: " << m_state);
721 }
722 
723 
724 
725 void
727 {
728  NS_LOG_FUNCTION (this);
729  switch (m_state)
730  {
731  case TX:
732  NS_FATAL_ERROR ("cannot RX while TX: according to FDD channel access, the physical layer for transmission cannot be used for reception");
733  break;
734  case RX_DATA:
735  NS_FATAL_ERROR ("cannot RX data while receing control");
736  break;
737  case IDLE:
738  case RX_CTRL:
739  // the behavior is similar when
740  // we're IDLE or RX because we can receive more signals
741  // simultaneously (e.g., at the eNB).
742  {
743  // To check if we're synchronized to this signal, we check
744  // for the CellId which is reported in the
745  // LteSpectrumSignalParametersDlCtrlFrame
746  uint16_t cellId;
747  bool dl;
748  Ptr<LteSpectrumSignalParametersDlCtrlFrame> lteDlCtrlRxParams = DynamicCast<LteSpectrumSignalParametersDlCtrlFrame> (params);
749  if (lteDlCtrlRxParams!=0)
750  {
751  cellId = lteDlCtrlRxParams->cellId;
752  dl = true;
753  }
754  else
755  {
756  Ptr<LteSpectrumSignalParametersUlSrsFrame> lteUlSrsRxParams = DynamicCast<LteSpectrumSignalParametersUlSrsFrame> (params);
757  cellId = lteUlSrsRxParams->cellId;
758  dl = false;
759  }
760  if (dl)
761  {
762  // check presence of PSS for UE measuerements
763  if (lteDlCtrlRxParams->pss == true)
764  {
765  SpectrumValue pssPsd = *params->psd;
767  {
768  m_ltePhyRxPssCallback (cellId, params->psd);
769  }
770  }
771  }
772  if (cellId == m_cellId)
773  {
774  NS_LOG_LOGIC (this << " synchronized with this signal (cellId=" << cellId << ")");
775  if (m_state == IDLE)
776  {
777  // first transmission, i.e., we're IDLE and we
778  // start RX
781  m_firstRxDuration = params->duration;
782  NS_LOG_LOGIC (this << " scheduling EndRx with delay " << params->duration);
783  if (dl==true)
784  {
785  // store the DCIs
786  m_rxControlMessageList = lteDlCtrlRxParams->ctrlMsgList;
788  }
789  else
790  {
792  }
793  }
794  else if (m_state == RX_CTRL)
795  {
796  // sanity check: if there are multiple RX events, they
797  // should occur at the same time and have the same
798  // duration, otherwise the interference calculation
799  // won't be correct
801  && (m_firstRxDuration == params->duration));
802  }
803 
805  m_interferenceCtrl->StartRx (params->psd);
806 
807 // NS_LOG_LOGIC (this << " numSimultaneousRxEvents = " << m_rxPacketBurstList.size ());
808  }
809  else
810  {
811  NS_LOG_LOGIC (this << " not in sync with this signal (cellId="
812  << cellId << ", m_cellId=" << m_cellId << ")");
813  }
814  }
815  break;
816 
817  default:
818  NS_FATAL_ERROR ("unknown state");
819  break;
820  }
821 
822  NS_LOG_LOGIC (this << " state: " << m_state);
823 }
824 
825 
826 void
828 {
829  NS_LOG_FUNCTION (this << sinr);
830  m_sinrPerceived = sinr;
831 }
832 
833 
834 void
835 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)
836 {
837  NS_LOG_FUNCTION (this << " rnti: " << rnti << " NDI " << (uint16_t)ndi << " size " << size << " mcs " << (uint16_t)mcs << " layer " << (uint16_t)layer << " rv " << (uint16_t)rv);
838  TbId_t tbId;
839  tbId.m_rnti = rnti;
840  tbId.m_layer = layer;
841  expectedTbs_t::iterator it;
842  it = m_expectedTbs.find (tbId);
843  if (it != m_expectedTbs.end ())
844  {
845  // migth be a TB of an unreceived packet (due to high progpalosses)
846  m_expectedTbs.erase (it);
847  }
848  // insert new entry
849  tbInfo_t tbInfo = {ndi, size, mcs, map, harqId, rv, 0.0, downlink, false, false};
850  m_expectedTbs.insert (std::pair<TbId_t, tbInfo_t> (tbId,tbInfo));
851 }
852 
853 
854 void
856 {
857  NS_LOG_FUNCTION (this);
858  NS_LOG_LOGIC (this << " state: " << m_state);
859 
861 
862  // this will trigger CQI calculation and Error Model evaluation
863  // as a side effect, the error model should update the error status of all TBs
864  m_interferenceData->EndRx ();
865  NS_LOG_DEBUG (this << " No. of burts " << m_rxPacketBurstList.size ());
866  NS_LOG_DEBUG (this << " Expected TBs " << m_expectedTbs.size ());
867  expectedTbs_t::iterator itTb = m_expectedTbs.begin ();
868 
869  // apply transmission mode gain
870  NS_LOG_DEBUG (this << " txMode " << (uint16_t)m_transmissionMode << " gain " << m_txModeGain.at (m_transmissionMode));
873 
874  while (itTb!=m_expectedTbs.end ())
875  {
876  if ((m_dataErrorModelEnabled)&&(m_rxPacketBurstList.size ()>0)) // avoid to check for errors when there is no actual data transmitted
877  {
878  // retrieve HARQ info
879  HarqProcessInfoList_t harqInfoList;
880  if ((*itTb).second.ndi == 0)
881  {
882  // TB retxed: retrieve HARQ history
883  uint16_t ulHarqId = 0;
884  if ((*itTb).second.downlink)
885  {
886  harqInfoList = m_harqPhyModule->GetHarqProcessInfoDl ((*itTb).second.harqProcessId, (*itTb).first.m_layer);
887  }
888  else
889  {
890  harqInfoList = m_harqPhyModule->GetHarqProcessInfoUl ((*itTb).first.m_rnti, ulHarqId);
891  }
892  }
893  TbStats_t tbStats = LteMiErrorModel::GetTbDecodificationStats (m_sinrPerceived, (*itTb).second.rbBitmap, (*itTb).second.size, (*itTb).second.mcs, harqInfoList);
894  (*itTb).second.mi = tbStats.mi;
895  (*itTb).second.corrupt = m_random->GetValue () > tbStats.tbler ? false : true;
896  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);
897  // fire traces on DL/UL reception PHY stats
900  params.m_cellId = m_cellId;
901  params.m_imsi = 0; // it will be set by DlPhyTransmissionCallback in LteHelper
902  params.m_rnti = (*itTb).first.m_rnti;
903  params.m_txMode = m_transmissionMode;
904  params.m_layer = (*itTb).first.m_layer;
905  params.m_mcs = (*itTb).second.mcs;
906  params.m_size = (*itTb).second.size;
907  params.m_rv = (*itTb).second.rv;
908  params.m_ndi = (*itTb).second.ndi;
909  params.m_correctness = (uint8_t)!(*itTb).second.corrupt;
910  if ((*itTb).second.downlink)
911  {
912  // DL
913  m_dlPhyReception (params);
914  }
915  else
916  {
917  // UL
918  params.m_rv = harqInfoList.size ();
919  m_ulPhyReception (params);
920  }
921  }
922 
923  itTb++;
924  }
925  std::map <uint16_t, DlInfoListElement_s> harqDlInfoMap;
926  for (std::list<Ptr<PacketBurst> >::const_iterator i = m_rxPacketBurstList.begin ();
927  i != m_rxPacketBurstList.end (); ++i)
928  {
929  for (std::list<Ptr<Packet> >::const_iterator j = (*i)->Begin (); j != (*i)->End (); ++j)
930  {
931  // retrieve TB info of this packet
932  LteRadioBearerTag tag;
933  (*j)->PeekPacketTag (tag);
934  TbId_t tbId;
935  tbId.m_rnti = tag.GetRnti ();
936  tbId.m_layer = tag.GetLayer ();
937  itTb = m_expectedTbs.find (tbId);
938  NS_LOG_INFO (this << " Packet of " << tbId.m_rnti << " layer " << (uint16_t) tag.GetLayer ());
939  if (itTb!=m_expectedTbs.end ())
940  {
941  if (!(*itTb).second.corrupt)
942  {
943  m_phyRxEndOkTrace (*j);
944 
946  {
948  }
949  }
950  else
951  {
952  // TB received with errors
954  }
955 
956  // send HARQ feedback (if not already done for this TB)
957  if (!(*itTb).second.harqFeedbackSent)
958  {
959  (*itTb).second.harqFeedbackSent = true;
960  if (!(*itTb).second.downlink)
961  {
962  UlInfoListElement_s harqUlInfo;
963  harqUlInfo.m_rnti = tbId.m_rnti;
964  harqUlInfo.m_tpc = 0;
965  if ((*itTb).second.corrupt)
966  {
968  NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " send UL-HARQ-NACK");
969  m_harqPhyModule->UpdateUlHarqProcessStatus (tbId.m_rnti, (*itTb).second.mi, (*itTb).second.size, (*itTb).second.size / EffectiveCodingRate [(*itTb).second.mcs]);
970  }
971  else
972  {
974  NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " send UL-HARQ-ACK");
975  m_harqPhyModule->ResetUlHarqProcessStatus (tbId.m_rnti, (*itTb).second.harqProcessId);
976  }
978  {
979  m_ltePhyUlHarqFeedbackCallback (harqUlInfo);
980  }
981  }
982  else
983  {
984  std::map <uint16_t, DlInfoListElement_s>::iterator itHarq = harqDlInfoMap.find (tbId.m_rnti);
985  if (itHarq==harqDlInfoMap.end ())
986  {
987  DlInfoListElement_s harqDlInfo;
989  harqDlInfo.m_rnti = tbId.m_rnti;
990  harqDlInfo.m_harqProcessId = (*itTb).second.harqProcessId;
991  if ((*itTb).second.corrupt)
992  {
993  harqDlInfo.m_harqStatus.at (tbId.m_layer) = DlInfoListElement_s::NACK;
994  NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " harqId " << (uint16_t)(*itTb).second.harqProcessId << " layer " <<(uint16_t)tbId.m_layer << " send DL-HARQ-NACK");
995  m_harqPhyModule->UpdateDlHarqProcessStatus ((*itTb).second.harqProcessId, tbId.m_layer, (*itTb).second.mi, (*itTb).second.size, (*itTb).second.size / EffectiveCodingRate [(*itTb).second.mcs]);
996  }
997  else
998  {
999 
1000  harqDlInfo.m_harqStatus.at (tbId.m_layer) = DlInfoListElement_s::ACK;
1001  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");
1002  m_harqPhyModule->ResetDlHarqProcessStatus ((*itTb).second.harqProcessId);
1003  }
1004  harqDlInfoMap.insert (std::pair <uint16_t, DlInfoListElement_s> (tbId.m_rnti, harqDlInfo));
1005  }
1006  else
1007  {
1008  if ((*itTb).second.corrupt)
1009  {
1010  (*itHarq).second.m_harqStatus.at (tbId.m_layer) = DlInfoListElement_s::NACK;
1011  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");
1012  m_harqPhyModule->UpdateDlHarqProcessStatus ((*itTb).second.harqProcessId, tbId.m_layer, (*itTb).second.mi, (*itTb).second.size, (*itTb).second.size / EffectiveCodingRate [(*itTb).second.mcs]);
1013  }
1014  else
1015  {
1016  NS_ASSERT_MSG (tbId.m_layer < (*itHarq).second.m_harqStatus.size (), " layer " << (uint16_t)tbId.m_layer);
1017  (*itHarq).second.m_harqStatus.at (tbId.m_layer) = DlInfoListElement_s::ACK;
1018  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");
1019  m_harqPhyModule->ResetDlHarqProcessStatus ((*itTb).second.harqProcessId);
1020  }
1021  }
1022  } // end if ((*itTb).second.downlink) HARQ
1023  } // end if (!(*itTb).second.harqFeedbackSent)
1024  }
1025  }
1026  }
1027 
1028  // send DL HARQ feedback to LtePhy
1029  std::map <uint16_t, DlInfoListElement_s>::iterator itHarq;
1030  for (itHarq = harqDlInfoMap.begin (); itHarq != harqDlInfoMap.end (); itHarq++)
1031  {
1033  {
1034  m_ltePhyDlHarqFeedbackCallback ((*itHarq).second);
1035  }
1036  }
1037  // forward control messages of this frame to LtePhy
1038  if (!m_rxControlMessageList.empty ())
1039  {
1041  {
1043  }
1044  }
1045  ChangeState (IDLE);
1046  m_rxPacketBurstList.clear ();
1047  m_rxControlMessageList.clear ();
1048  m_expectedTbs.clear ();
1049 }
1050 
1051 
1052 void
1054 {
1055  NS_LOG_FUNCTION (this);
1056  NS_LOG_LOGIC (this << " state: " << m_state);
1057 
1058  NS_ASSERT (m_state == RX_CTRL);
1059 
1060  // this will trigger CQI calculation and Error Model evaluation
1061  // as a side effect, the error model should update the error status of all TBs
1062  m_interferenceCtrl->EndRx ();
1063  // apply transmission mode gain
1064  NS_LOG_DEBUG (this << " txMode " << (uint16_t)m_transmissionMode << " gain " << m_txModeGain.at (m_transmissionMode));
1066  if (m_transmissionMode>0)
1067  {
1068  // in case of MIMO, ctrl is always txed as TX diversity
1069  m_sinrPerceived *= m_txModeGain.at (1);
1070  }
1071 // m_sinrPerceived *= m_txModeGain.at (m_transmissionMode);
1072  bool error = false;
1074  {
1077  error = m_random->GetValue () > errorRate ? false : true;
1078  NS_LOG_DEBUG (this << " PCFICH-PDCCH Decodification, errorRate " << errorRate << " error " << error);
1079  }
1080 
1081  if (!error)
1082  {
1084  {
1085  NS_LOG_DEBUG (this << " PCFICH-PDCCH Rxed OK");
1087  }
1088  }
1089  else
1090  {
1092  {
1093  NS_LOG_DEBUG (this << " PCFICH-PDCCH Error");
1095  }
1096  }
1097  ChangeState (IDLE);
1098  m_rxControlMessageList.clear ();
1099 }
1100 
1101 void
1103 {
1104  NS_ASSERT (m_state == RX_CTRL);
1105  ChangeState (IDLE);
1106  m_interferenceCtrl->EndRx ();
1107  // nothing to do (used only for SRS at this stage)
1108 }
1109 
1110 void
1111 LteSpectrumPhy::SetCellId (uint16_t cellId)
1112 {
1113  m_cellId = cellId;
1114 }
1115 
1116 
1117 void
1119 {
1120  m_interferenceCtrl->AddRsPowerChunkProcessor (p);
1121 }
1122 
1123 
1124 void
1126 {
1127  m_interferenceData->AddSinrChunkProcessor (p);
1128 }
1129 
1130 void
1132 {
1133  m_interferenceCtrl->AddInterferenceChunkProcessor (p);
1134 }
1135 
1136 void
1138 {
1139  m_interferenceData->AddInterferenceChunkProcessor (p);
1140 }
1141 
1142 void
1144 {
1145  m_interferenceCtrl->AddSinrChunkProcessor (p);
1146 }
1147 
1148 void
1150 {
1151  NS_LOG_FUNCTION (this << (uint16_t) txMode);
1152  NS_ASSERT_MSG (txMode < m_txModeGain.size (), "TransmissionMode not available: 1.." << m_txModeGain.size ());
1153  m_transmissionMode = txMode;
1155 }
1156 
1157 
1158 void
1159 LteSpectrumPhy::SetTxModeGain (uint8_t txMode, double gain)
1160 {
1161  NS_LOG_FUNCTION (this << " txmode " << (uint16_t)txMode << " gain " << gain);
1162  // convert to linear
1163  gain = std::pow (10.0, (gain / 10.0));
1164  if (m_txModeGain.size () < txMode)
1165  {
1166  m_txModeGain.resize (txMode);
1167  }
1168  std::vector <double> temp;
1169  temp = m_txModeGain;
1170  m_txModeGain.clear ();
1171  for (uint8_t i = 0; i < temp.size (); i++)
1172  {
1173  if (i==txMode-1)
1174  {
1175  m_txModeGain.push_back (gain);
1176  }
1177  else
1178  {
1179  m_txModeGain.push_back (temp.at (i));
1180  }
1181  }
1182 }
1183 
1184 int64_t
1186 {
1187  NS_LOG_FUNCTION (this << stream);
1188  m_random->SetStream (stream);
1189  return 1;
1190 }
1191 
1192 
1193 
1194 } // namespace ns3
static const Time UL_SRS_DURATION
Ptr< LteHarqPhy > m_harqPhyModule
void SetLtePhyTxEndCallback(LtePhyTxEndCallback c)
keep track of time values and allow control of global simulation resolution
Definition: nstime.h:81
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
void StartRxData(Ptr< LteSpectrumSignalParametersDataFrame > params)
Ptr< LteInterference > m_interferenceCtrl
Hold a bool native type.
Definition: boolean.h:38
LtePhyRxCtrlEndOkCallback m_ltePhyRxCtrlEndOkCallback
TracedCallback< Ptr< const PacketBurst > > m_phyTxEndTrace
uint16_t GetRnti(void) const
void SetState(State newState)
Set the state of the phy layer.
bool IsNull(void) const
Definition: callback.h:1014
void AddInterferenceCtrlChunkProcessor(Ptr< LteSinrChunkProcessor > p)
#define NS_ASSERT(condition)
Definition: assert.h:64
TracedCallback< Ptr< const Packet > > m_phyRxEndErrorTrace
void SetLtePhyRxDataEndErrorCallback(LtePhyRxDataEndErrorCallback c)
void SetTxModeGain(uint8_t txMode, double gain)
LtePhyRxCtrlEndErrorCallback m_ltePhyRxCtrlEndErrorCallback
void SetTransmissionMode(uint8_t txMode)
Ptr< SpectrumChannel > m_channel
std::list< Ptr< LteControlMessage > > m_txControlMessageList
LtePhyTxEndCallback m_ltePhyTxEndCallback
virtual void DoDispose(void)
Definition: object.cc:335
#define NS_LOG_INFO(msg)
Definition: log.h:264
expectedTbs_t m_expectedTbs
bool operator<(const Room &a, const Room &b)
Ptr< LteInterference > m_interferenceData
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:824
Ptr< SpectrumChannel > GetChannel()
LtePhyRxDataEndErrorCallback m_ltePhyRxDataEndErrorCallback
See section 4.3.12 ulInfoListElement.
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)
std::list< Ptr< PacketBurst > > m_rxPacketBurstList
static const Time DL_CTRL_DURATION
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
void SetLtePhyUlHarqFeedbackCallback(LtePhyUlHarqFeedbackCallback c)
void ChangeState(State newState)
std::list< Ptr< LteControlMessage > > m_rxControlMessageList
void SetLtePhyRxCtrlEndOkCallback(LtePhyRxCtrlEndOkCallback c)
void SetTxPowerSpectralDensity(Ptr< SpectrumValue > txPsd)
void SetLtePhyRxCtrlEndErrorCallback(LtePhyRxCtrlEndErrorCallback c)
Ptr< AntennaModel > m_antenna
TracedCallback< Ptr< const PacketBurst > > m_phyRxStartTrace
LtePhyRxDataEndOkCallback m_ltePhyRxDataEndOkCallback
static uint8_t TxMode2LayerNum(uint8_t txMode)
Definition: lte-common.cc:170
Ptr< SampleEmitter > s
NS_OBJECT_ENSURE_REGISTERED(AntennaModel)
bool StartTxDataFrame(Ptr< PacketBurst > pb, std::list< Ptr< LteControlMessage > > ctrlMsgList, Time duration)
Ptr< MobilityModel > m_mobility
void SetHarqPhyModule(Ptr< LteHarqPhy > harq)
int64_t AssignStreams(int64_t stream)
static double GetPcfichPdcchError(const SpectrumValue &sinr)
run the error-model algorithm for the specified PCFICH+PDCCH channels
double EffectiveCodingRate[29]
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
#define list
virtual void DoDispose()
See section 4.3.23 dlInfoListElement.
void StartRxCtrl(Ptr< SpectrumSignalParameters > params)
Ptr< NetDevice > GetDevice()
Ptr< SpectrumValue > m_txPsd
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:43
Ptr< Packet > Copy(void) const
Definition: packet.cc:122
void SetAntenna(Ptr< AntennaModel > a)
void AddRsPowerChunkProcessor(Ptr< LteSinrChunkProcessor > p)
uint16_t m_rnti
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()
Ptr< const SpectrumModel > m_rxSpectrumModel
LtePhyDlHarqFeedbackCallback m_ltePhyDlHarqFeedbackCallback
double GetValue(double min, double max)
Returns a random double from the uniform distribution with the specified range.
std::vector< enum HarqStatus_e > m_harqStatus
Ptr< PacketBurst > m_txPacketBurst
void SetChannel(Ptr< SpectrumChannel > c)
TracedCallback< PhyReceptionStatParameters > m_ulPhyReception
static Time Now(void)
Definition: simulator.cc:180
Ptr< NetDevice > m_device
LtePhyUlHarqFeedbackCallback m_ltePhyUlHarqFeedbackCallback
static TypeId GetTypeId(void)
TracedCallback< Ptr< const Packet > > m_phyRxEndOkTrace
bool StartTxDlCtrlFrame(std::list< Ptr< LteControlMessage > > ctrlMsgList, bool pss)
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
void SetLtePhyDlHarqFeedbackCallback(LtePhyDlHarqFeedbackCallback c)
void AddCtrlSinrChunkProcessor(Ptr< LteSinrChunkProcessor > p)
void AddDataSinrChunkProcessor(Ptr< LteSinrChunkProcessor > p)
void SetLtePhyRxPssCallback(LtePhyRxPssCallback c)
NS_LOG_COMPONENT_DEFINE("LteSpectrumPhy")
LtePhyRxPssCallback m_ltePhyRxPssCallback
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
bool operator==(const EventId &a, const EventId &b)
Definition: event-id.cc:89
void AddInterferenceDataChunkProcessor(Ptr< LteSinrChunkProcessor > p)
void Cancel(void)
Definition: event-id.cc:47
void SetLtePhyRxDataEndOkCallback(LtePhyRxDataEndOkCallback c)
void SetMobility(Ptr< MobilityModel > m)
enum ns3::UlInfoListElement_s::ReceptionStatus_e m_receptionStatus
void StartRx(Ptr< SpectrumSignalParameters > params)
Hold an floating point type.
Definition: double.h:41
TracedCallback< Ptr< const PacketBurst > > m_phyTxStartTrace
void SetAttribute(std::string name, const AttributeValue &value)
Definition: object-base.cc:160
Set of values corresponding to a given SpectrumModel.
a unique identifier for an interface.
Definition: type-id.h:49
uint8_t GetLayer(void) const
void UpdateSinrPerceived(const SpectrumValue &sinr)
int64_t GetMilliSeconds(void) const
Definition: nstime.h:275
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
void SetCellId(uint16_t cellId)
SpectrumValue m_sinrPerceived
std::vector< double > m_txModeGain
TracedCallback< PhyReceptionStatParameters > m_dlPhyReception
std::vector< HarqProcessInfoElement_t > HarqProcessInfoList_t
Definition: lte-harq-phy.h:47