A Discrete-Event Network Simulator
API
lte-spectrum-phy.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009, 2011 CTTC
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Nicola Baldo <nbaldo@cttc.es>
18  * Giuseppe Piro <g.piro@poliba.it>
19  * Marco Miozzo <marco.miozzo@cttc.es> (add physical error model)
20  */
21 
22 #include "lte-spectrum-phy.h"
23 
24 #include "lte-chunk-processor.h"
25 #include "lte-net-device.h"
26 #include "lte-phy-tag.h"
27 #include "lte-radio-bearer-tag.h"
29 
30 #include <ns3/antenna-model.h>
31 #include <ns3/boolean.h>
32 #include <ns3/config.h>
33 #include <ns3/double.h>
34 #include <ns3/log.h>
35 #include <ns3/lte-mi-error-model.h>
36 #include <ns3/lte-radio-bearer-tag.h>
37 #include <ns3/object-factory.h>
38 #include <ns3/simulator.h>
39 #include <ns3/trace-source-accessor.h>
40 
41 #include <cmath>
42 
43 namespace ns3
44 {
45 
46 NS_LOG_COMPONENT_DEFINE("LteSpectrumPhy");
47 
50 static const Time UL_SRS_DURATION = NanoSeconds(71429 - 1);
51 
54 static const Time DL_CTRL_DURATION = NanoSeconds(214286 - 1);
55 
57 static const double EffectiveCodingRate[29] = {
58  0.08, 0.1, 0.11, 0.15, 0.19, 0.24, 0.3, 0.37, 0.44, 0.51, 0.3, 0.33, 0.37, 0.42, 0.48,
59  0.54, 0.6, 0.43, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.89, 0.92,
60 };
61 
63 {
64 }
65 
66 TbId_t::TbId_t(const uint16_t a, const uint8_t b)
67  : m_rnti(a),
68  m_layer(b)
69 {
70 }
71 
79 bool
80 operator==(const TbId_t& a, const TbId_t& b)
81 {
82  return ((a.m_rnti == b.m_rnti) && (a.m_layer == b.m_layer));
83 }
84 
92 bool
93 operator<(const TbId_t& a, const TbId_t& b)
94 {
95  return ((a.m_rnti < b.m_rnti) || ((a.m_rnti == b.m_rnti) && (a.m_layer < b.m_layer)));
96 }
97 
99 
101  : m_state(IDLE),
102  m_cellId(0),
103  m_componentCarrierId(0),
104  m_transmissionMode(0),
105  m_layersNum(1)
106 {
107  NS_LOG_FUNCTION(this);
108  m_random = CreateObject<UniformRandomVariable>();
109  m_random->SetAttribute("Min", DoubleValue(0.0));
110  m_random->SetAttribute("Max", DoubleValue(1.0));
111  m_interferenceData = CreateObject<LteInterference>();
112  m_interferenceCtrl = CreateObject<LteInterference>();
113 
114  for (uint8_t i = 0; i < 7; i++)
115  {
116  m_txModeGain.push_back(1.0);
117  }
118 }
119 
121 {
122  NS_LOG_FUNCTION(this);
123  m_expectedTbs.clear();
124  m_txModeGain.clear();
125 }
126 
127 void
129 {
130  NS_LOG_FUNCTION(this);
131  m_channel = nullptr;
132  m_mobility = nullptr;
133  m_device = nullptr;
134  m_interferenceData->Dispose();
135  m_interferenceData = nullptr;
136  m_interferenceCtrl->Dispose();
137  m_interferenceCtrl = nullptr;
138  m_ltePhyRxDataEndErrorCallback = MakeNullCallback<void>();
139  m_ltePhyRxDataEndOkCallback = MakeNullCallback<void, Ptr<Packet>>();
140  m_ltePhyRxCtrlEndOkCallback = MakeNullCallback<void, std::list<Ptr<LteControlMessage>>>();
141  m_ltePhyRxCtrlEndErrorCallback = MakeNullCallback<void>();
142  m_ltePhyDlHarqFeedbackCallback = MakeNullCallback<void, DlInfoListElement_s>();
143  m_ltePhyUlHarqFeedbackCallback = MakeNullCallback<void, UlInfoListElement_s>();
144  m_ltePhyRxPssCallback = MakeNullCallback<void, uint16_t, Ptr<SpectrumValue>>();
146 }
147 
155 std::ostream&
156 operator<<(std::ostream& os, LteSpectrumPhy::State s)
157 {
158  switch (s)
159  {
161  os << "IDLE";
162  break;
164  os << "RX_DATA";
165  break;
167  os << "RX_DL_CTRL";
168  break;
170  os << "TX_DATA";
171  break;
173  os << "TX_DL_CTRL";
174  break;
176  os << "TX_UL_SRS";
177  break;
178  default:
179  os << "UNKNOWN";
180  break;
181  }
182  return os;
183 }
184 
185 TypeId
187 {
188  static TypeId tid =
189  TypeId("ns3::LteSpectrumPhy")
191  .SetGroupName("Lte")
192  .AddTraceSource("TxStart",
193  "Trace fired when a new transmission is started",
195  "ns3::PacketBurst::TracedCallback")
196  .AddTraceSource("TxEnd",
197  "Trace fired when a previously started transmission is finished",
199  "ns3::PacketBurst::TracedCallback")
200  .AddTraceSource("RxStart",
201  "Trace fired when the start of a signal is detected",
203  "ns3::PacketBurst::TracedCallback")
204  .AddTraceSource("RxEndOk",
205  "Trace fired when a previously started RX terminates successfully",
207  "ns3::Packet::TracedCallback")
208  .AddTraceSource("RxEndError",
209  "Trace fired when a previously started RX terminates with an error",
211  "ns3::Packet::TracedCallback")
212  .AddAttribute("DataErrorModelEnabled",
213  "Activate/Deactivate the error model of data (TBs of PDSCH and PUSCH) "
214  "[by default is active].",
215  BooleanValue(true),
218  .AddAttribute("CtrlErrorModelEnabled",
219  "Activate/Deactivate the error model of control (PCFICH-PDCCH "
220  "decodification) [by default is active].",
221  BooleanValue(true),
224  .AddTraceSource("DlPhyReception",
225  "DL reception PHY layer statistics.",
227  "ns3::PhyReceptionStatParameters::TracedCallback")
228  .AddTraceSource("UlPhyReception",
229  "DL reception PHY layer statistics.",
231  "ns3::PhyReceptionStatParameters::TracedCallback");
232  return tid;
233 }
234 
237 {
238  NS_LOG_FUNCTION(this);
239  return m_device;
240 }
241 
244 {
245  NS_LOG_FUNCTION(this);
246  return m_mobility;
247 }
248 
249 void
251 {
252  NS_LOG_FUNCTION(this << d);
253  m_device = d;
254 }
255 
256 void
258 {
259  NS_LOG_FUNCTION(this << m);
260  m_mobility = m;
261 }
262 
263 void
265 {
266  NS_LOG_FUNCTION(this << c);
267  m_channel = c;
268 }
269 
272 {
273  return m_channel;
274 }
275 
278 {
279  return m_rxSpectrumModel;
280 }
281 
282 void
284 {
285  NS_LOG_FUNCTION(this << txPsd);
286  NS_ASSERT(txPsd);
287  m_txPsd = txPsd;
288 }
289 
290 void
292 {
293  NS_LOG_FUNCTION(this << noisePsd);
294  NS_ASSERT(noisePsd);
295  m_rxSpectrumModel = noisePsd->GetSpectrumModel();
296  m_interferenceData->SetNoisePowerSpectralDensity(noisePsd);
297  m_interferenceCtrl->SetNoisePowerSpectralDensity(noisePsd);
298 }
299 
300 void
302 {
303  NS_LOG_FUNCTION(this);
304  m_cellId = 0;
305  m_state = IDLE;
306  m_transmissionMode = 0;
307  m_layersNum = 1;
312  m_rxControlMessageList.clear();
313  m_expectedTbs.clear();
314  m_txControlMessageList.clear();
315  m_rxPacketBurstList.clear();
316  m_txPacketBurst = nullptr;
317  m_rxSpectrumModel = nullptr;
318 
319  // Detach from the channel, because receiving any signal without
320  // spectrum model is an error.
321  if (m_channel)
322  {
323  m_channel->RemoveRx(this);
324  }
325 }
326 
327 void
329 {
330  NS_LOG_FUNCTION(this);
332 }
333 
334 void
336 {
337  NS_LOG_FUNCTION(this);
339 }
340 
341 void
343 {
344  NS_LOG_FUNCTION(this);
346 }
347 
348 void
350 {
351  NS_LOG_FUNCTION(this);
353 }
354 
355 void
357 {
358  NS_LOG_FUNCTION(this);
360 }
361 
362 void
364 {
365  NS_LOG_FUNCTION(this);
367 }
368 
369 void
371 {
372  NS_LOG_FUNCTION(this);
374 }
375 
378 {
379  return m_antenna;
380 }
381 
382 void
384 {
385  NS_LOG_FUNCTION(this << a);
386  m_antenna = a;
387 }
388 
389 void
391 {
392  ChangeState(newState);
393 }
394 
395 void
397 {
398  NS_LOG_LOGIC(this << " state: " << m_state << " -> " << newState);
399  m_state = newState;
400 }
401 
402 void
404 {
405  m_harqPhyModule = harq;
406 }
407 
408 bool
410  std::list<Ptr<LteControlMessage>> ctrlMsgList,
411  Time duration)
412 {
413  NS_LOG_FUNCTION(this << pb);
414  NS_LOG_LOGIC(this << " state: " << m_state);
415 
416  m_phyTxStartTrace(pb);
417 
418  switch (m_state)
419  {
420  case RX_DATA:
421  case RX_DL_CTRL:
422  case RX_UL_SRS:
423  NS_FATAL_ERROR("cannot TX while RX: according to FDD channel access, the physical layer "
424  "for transmission cannot be used for reception");
425  break;
426 
427  case TX_DATA:
428  case TX_DL_CTRL:
429  case TX_UL_SRS:
430  NS_FATAL_ERROR("cannot TX while already TX: the MAC should avoid this");
431  break;
432 
433  case IDLE: {
434  /*
435  m_txPsd must be set by the device, according to
436  (i) the available subchannel for transmission
437  (ii) the power transmission
438  */
440  m_txPacketBurst = pb;
441 
442  // we need to convey some PHY meta information to the receiver
443  // to be used for simulation purposes (e.g., the CellId). This
444  // is done by setting the ctrlMsgList parameter of
445  // LteSpectrumSignalParametersDataFrame
449  Create<LteSpectrumSignalParametersDataFrame>();
450  txParams->duration = duration;
451  txParams->txPhy = GetObject<SpectrumPhy>();
452  txParams->txAntenna = m_antenna;
453  txParams->psd = m_txPsd;
454  txParams->packetBurst = pb;
455  txParams->ctrlMsgList = ctrlMsgList;
456  txParams->cellId = m_cellId;
457  m_channel->StartTx(txParams);
459  }
460  return false;
461  break;
462 
463  default:
464  NS_FATAL_ERROR("unknown state");
465  return true;
466  break;
467  }
468 }
469 
470 bool
472 {
473  NS_LOG_FUNCTION(this << " PSS " << (uint16_t)pss);
474  NS_LOG_LOGIC(this << " state: " << m_state);
475 
476  switch (m_state)
477  {
478  case RX_DATA:
479  case RX_DL_CTRL:
480  case RX_UL_SRS:
481  NS_FATAL_ERROR("cannot TX while RX: according to FDD channel access, the physical layer "
482  "for transmission cannot be used for reception");
483  break;
484 
485  case TX_DATA:
486  case TX_DL_CTRL:
487  case TX_UL_SRS:
488  NS_FATAL_ERROR("cannot TX while already TX: the MAC should avoid this");
489  break;
490 
491  case IDLE: {
492  /*
493  m_txPsd must be set by the device, according to
494  (i) the available subchannel for transmission
495  (ii) the power transmission
496  */
498 
499  // we need to convey some PHY meta information to the receiver
500  // to be used for simulation purposes (e.g., the CellId). This
501  // is done by setting the cellId parameter of
502  // LteSpectrumSignalParametersDlCtrlFrame
505 
507  Create<LteSpectrumSignalParametersDlCtrlFrame>();
508  txParams->duration = DL_CTRL_DURATION;
509  txParams->txPhy = GetObject<SpectrumPhy>();
510  txParams->txAntenna = m_antenna;
511  txParams->psd = m_txPsd;
512  txParams->cellId = m_cellId;
513  txParams->pss = pss;
514  txParams->ctrlMsgList = ctrlMsgList;
515  m_channel->StartTx(txParams);
517  }
518  return false;
519  break;
520 
521  default:
522  NS_FATAL_ERROR("unknown state");
523  return true;
524  break;
525  }
526 }
527 
528 bool
530 {
531  NS_LOG_FUNCTION(this);
532  NS_LOG_LOGIC(this << " state: " << m_state);
533 
534  switch (m_state)
535  {
536  case RX_DATA:
537  case RX_DL_CTRL:
538  case RX_UL_SRS:
539  NS_FATAL_ERROR("cannot TX while RX: according to FDD channel access, the physical layer "
540  "for transmission cannot be used for reception");
541  break;
542 
543  case TX_DL_CTRL:
544  case TX_DATA:
545  case TX_UL_SRS:
546  NS_FATAL_ERROR("cannot TX while already TX: the MAC should avoid this");
547  break;
548 
549  case IDLE: {
550  /*
551  m_txPsd must be set by the device, according to
552  (i) the available subchannel for transmission
553  (ii) the power transmission
554  */
556  NS_LOG_LOGIC(this << " m_txPsd: " << *m_txPsd);
557 
558  // we need to convey some PHY meta information to the receiver
559  // to be used for simulation purposes (e.g., the CellId). This
560  // is done by setting the cellId parameter of
561  // LteSpectrumSignalParametersDlCtrlFrame
565  Create<LteSpectrumSignalParametersUlSrsFrame>();
566  txParams->duration = UL_SRS_DURATION;
567  txParams->txPhy = GetObject<SpectrumPhy>();
568  txParams->txAntenna = m_antenna;
569  txParams->psd = m_txPsd;
570  txParams->cellId = m_cellId;
571  m_channel->StartTx(txParams);
573  }
574  return false;
575  break;
576 
577  default:
578  NS_FATAL_ERROR("unknown state");
579  return true;
580  break;
581  }
582 }
583 
584 void
586 {
587  NS_LOG_FUNCTION(this);
588  NS_LOG_LOGIC(this << " state: " << m_state);
589 
592  m_txPacketBurst = nullptr;
593  ChangeState(IDLE);
594 }
595 
596 void
598 {
599  NS_LOG_FUNCTION(this);
600  NS_LOG_LOGIC(this << " state: " << m_state);
601 
604  ChangeState(IDLE);
605 }
606 
607 void
609 {
610  NS_LOG_FUNCTION(this);
611  NS_LOG_LOGIC(this << " state: " << m_state);
612 
615  ChangeState(IDLE);
616 }
617 
618 void
620 {
621  NS_LOG_FUNCTION(this << spectrumRxParams);
622  NS_LOG_LOGIC(this << " state: " << m_state);
623 
624  Ptr<const SpectrumValue> rxPsd = spectrumRxParams->psd;
625  Time duration = spectrumRxParams->duration;
626 
627  // the device might start RX only if the signal is of a type
628  // understood by this device - in this case, an LTE signal.
630  DynamicCast<LteSpectrumSignalParametersDataFrame>(spectrumRxParams);
632  DynamicCast<LteSpectrumSignalParametersDlCtrlFrame>(spectrumRxParams);
634  DynamicCast<LteSpectrumSignalParametersUlSrsFrame>(spectrumRxParams);
635  if (lteDataRxParams)
636  {
637  m_interferenceData->AddSignal(rxPsd, duration);
638  StartRxData(lteDataRxParams);
639  }
640  else if (lteDlCtrlRxParams)
641  {
642  m_interferenceCtrl->AddSignal(rxPsd, duration);
643  StartRxDlCtrl(lteDlCtrlRxParams);
644  }
645  else if (lteUlSrsRxParams)
646  {
647  m_interferenceCtrl->AddSignal(rxPsd, duration);
648  StartRxUlSrs(lteUlSrsRxParams);
649  }
650  else
651  {
652  // other type of signal (could be 3G, GSM, whatever) -> interference
653  m_interferenceData->AddSignal(rxPsd, duration);
654  m_interferenceCtrl->AddSignal(rxPsd, duration);
655  }
656 }
657 
658 void
660 {
661  NS_LOG_FUNCTION(this);
662  switch (m_state)
663  {
664  case TX_DATA:
665  case TX_DL_CTRL:
666  case TX_UL_SRS:
667  NS_FATAL_ERROR("cannot RX while TX: according to FDD channel access, the physical layer "
668  "for transmission cannot be used for reception");
669  break;
670  case RX_DL_CTRL:
671  NS_FATAL_ERROR("cannot RX Data while receiving control");
672  break;
673  case IDLE:
674  case RX_DATA:
675  // the behavior is similar when
676  // we're IDLE or RX because we can receive more signals
677  // simultaneously (e.g., at the eNB).
678  {
679  // To check if we're synchronized to this signal, we check
680  // for the CellId which is reported in the
681  // LteSpectrumSignalParametersDataFrame
682  if (params->cellId == m_cellId)
683  {
684  NS_LOG_LOGIC(this << " synchronized with this signal (cellId=" << params->cellId
685  << ")");
686  if ((m_rxPacketBurstList.empty()) && (m_rxControlMessageList.empty()))
687  {
688  NS_ASSERT(m_state == IDLE);
689  // first transmission, i.e., we're IDLE and we
690  // start RX
692  m_firstRxDuration = params->duration;
693  NS_LOG_LOGIC(this << " scheduling EndRx with delay "
694  << params->duration.As(Time::S));
697  }
698  else
699  {
701  // sanity check: if there are multiple RX events, they
702  // should occur at the same time and have the same
703  // duration, otherwise the interference calculation
704  // won't be correct
706  (m_firstRxDuration == params->duration));
707  }
708 
710  if (params->packetBurst)
711  {
712  m_rxPacketBurstList.push_back(params->packetBurst);
713  m_interferenceData->StartRx(params->psd);
714 
715  m_phyRxStartTrace(params->packetBurst);
716  }
717  NS_LOG_DEBUG(this << " insert msgs " << params->ctrlMsgList.size());
719  params->ctrlMsgList.begin(),
720  params->ctrlMsgList.end());
721 
722  NS_LOG_LOGIC(this << " numSimultaneousRxEvents = " << m_rxPacketBurstList.size());
723  }
724  else
725  {
726  NS_LOG_LOGIC(this << " not in sync with this signal (cellId=" << params->cellId
727  << ", m_cellId=" << m_cellId << ")");
728  }
729  }
730  break;
731 
732  default:
733  NS_FATAL_ERROR("unknown state");
734  break;
735  }
736 
737  NS_LOG_LOGIC(this << " state: " << m_state);
738 }
739 
740 void
742 {
743  NS_LOG_FUNCTION(this);
744 
745  // To check if we're synchronized to this signal, we check
746  // for the CellId which is reported in the
747  // LteSpectrumSignalParametersDlCtrlFrame
748  uint16_t cellId;
749  NS_ASSERT(lteDlCtrlRxParams);
750  cellId = lteDlCtrlRxParams->cellId;
751 
752  switch (m_state)
753  {
754  case TX_DATA:
755  case TX_DL_CTRL:
756  case TX_UL_SRS:
757  case RX_DATA:
758  case RX_UL_SRS:
759  NS_FATAL_ERROR("unexpected event in state " << m_state);
760  break;
761 
762  case RX_DL_CTRL:
763  case IDLE:
764 
765  // common code for the two states
766  // check presence of PSS for UE measuerements
767  if (lteDlCtrlRxParams->pss == true)
768  {
770  {
771  m_ltePhyRxPssCallback(cellId, lteDlCtrlRxParams->psd);
772  }
773  }
774 
775  // differentiated code for the two states
776  switch (m_state)
777  {
778  case RX_DL_CTRL:
779  NS_ASSERT_MSG(m_cellId != cellId, "any other DlCtrl should be from a different cell");
780  NS_LOG_LOGIC(this << " ignoring other DlCtrl (cellId=" << cellId
781  << ", m_cellId=" << m_cellId << ")");
782  break;
783 
784  case IDLE:
785  if (cellId == m_cellId)
786  {
787  NS_LOG_LOGIC(this << " synchronized with this signal (cellId=" << cellId << ")");
788 
791  m_firstRxDuration = lteDlCtrlRxParams->duration;
792  NS_LOG_LOGIC(this << " scheduling EndRx with delay "
793  << lteDlCtrlRxParams->duration);
794 
795  // store the DCIs
796  m_rxControlMessageList = lteDlCtrlRxParams->ctrlMsgList;
797  m_endRxDlCtrlEvent = Simulator::Schedule(lteDlCtrlRxParams->duration,
799  this);
801  m_interferenceCtrl->StartRx(lteDlCtrlRxParams->psd);
802  }
803  else
804  {
805  NS_LOG_LOGIC(this << " not synchronizing with this signal (cellId=" << cellId
806  << ", m_cellId=" << m_cellId << ")");
807  }
808  break;
809 
810  default:
811  NS_FATAL_ERROR("unexpected event in state " << m_state);
812  break;
813  }
814  break; // case RX_DL_CTRL or IDLE
815 
816  default:
817  NS_FATAL_ERROR("unknown state");
818  break;
819  }
820 
821  NS_LOG_LOGIC(this << " state: " << m_state);
822 }
823 
824 void
826 {
827  NS_LOG_FUNCTION(this);
828  switch (m_state)
829  {
830  case TX_DATA:
831  case TX_DL_CTRL:
832  case TX_UL_SRS:
833  NS_FATAL_ERROR("cannot RX while TX: according to FDD channel access, the physical layer "
834  "for transmission cannot be used for reception");
835  break;
836 
837  case RX_DATA:
838  case RX_DL_CTRL:
839  NS_FATAL_ERROR("cannot RX SRS while receiving something else");
840  break;
841 
842  case IDLE:
843  case RX_UL_SRS:
844  // the behavior is similar when
845  // we're IDLE or RX_UL_SRS because we can receive more signals
846  // simultaneously at the eNB
847  {
848  // To check if we're synchronized to this signal, we check
849  // for the CellId which is reported in the
850  // LteSpectrumSignalParametersDlCtrlFrame
851  uint16_t cellId;
852  cellId = lteUlSrsRxParams->cellId;
853  if (cellId == m_cellId)
854  {
855  NS_LOG_LOGIC(this << " synchronized with this signal (cellId=" << cellId << ")");
856  if (m_state == IDLE)
857  {
858  // first transmission, i.e., we're IDLE and we
859  // start RX
862  m_firstRxDuration = lteUlSrsRxParams->duration;
863  NS_LOG_LOGIC(this << " scheduling EndRx with delay "
864  << lteUlSrsRxParams->duration);
865 
866  m_endRxUlSrsEvent = Simulator::Schedule(lteUlSrsRxParams->duration,
868  this);
869  }
870  else if (m_state == RX_UL_SRS)
871  {
872  // sanity check: if there are multiple RX events, they
873  // should occur at the same time and have the same
874  // duration, otherwise the interference calculation
875  // won't be correct
877  (m_firstRxDuration == lteUlSrsRxParams->duration));
878  }
880  m_interferenceCtrl->StartRx(lteUlSrsRxParams->psd);
881  }
882  else
883  {
884  NS_LOG_LOGIC(this << " not in sync with this signal (cellId=" << cellId
885  << ", m_cellId=" << m_cellId << ")");
886  }
887  }
888  break;
889 
890  default:
891  NS_FATAL_ERROR("unknown state");
892  break;
893  }
894 
895  NS_LOG_LOGIC(this << " state: " << m_state);
896 }
897 
898 void
900 {
901  NS_LOG_FUNCTION(this << sinr);
902  m_sinrPerceived = sinr;
903 }
904 
905 void
907  uint8_t ndi,
908  uint16_t size,
909  uint8_t mcs,
910  std::vector<int> map,
911  uint8_t layer,
912  uint8_t harqId,
913  uint8_t rv,
914  bool downlink)
915 {
916  NS_LOG_FUNCTION(this << " rnti: " << rnti << " NDI " << (uint16_t)ndi << " size " << size
917  << " mcs " << (uint16_t)mcs << " layer " << (uint16_t)layer << " rv "
918  << (uint16_t)rv);
919  TbId_t tbId;
920  tbId.m_rnti = rnti;
921  tbId.m_layer = layer;
922  expectedTbs_t::iterator it;
923  it = m_expectedTbs.find(tbId);
924  if (it != m_expectedTbs.end())
925  {
926  // might be a TB of an unreceived packet (due to high progpalosses)
927  m_expectedTbs.erase(it);
928  }
929  // insert new entry
930  tbInfo_t tbInfo = {ndi, size, mcs, map, harqId, rv, 0.0, downlink, false, false};
931  m_expectedTbs.insert(std::pair<TbId_t, tbInfo_t>(tbId, tbInfo));
932 }
933 
934 void
936 {
937  NS_LOG_FUNCTION(this << rnti);
938  TbId_t tbId;
939  tbId.m_rnti = rnti;
940  // Remove TB of both the layers
941  for (uint8_t i = 0; i < 2; i++)
942  {
943  tbId.m_layer = i;
944  expectedTbs_t::iterator it;
945  it = m_expectedTbs.find(tbId);
946  if (it != m_expectedTbs.end())
947  {
948  m_expectedTbs.erase(it);
949  }
950  }
951 }
952 
953 void
955 {
956  NS_LOG_FUNCTION(this);
957  NS_LOG_LOGIC(this << " state: " << m_state);
958 
960 
961  // this will trigger CQI calculation and Error Model evaluation
962  // as a side effect, the error model should update the error status of all TBs
963  m_interferenceData->EndRx();
964  NS_LOG_DEBUG(this << " No. of burts " << m_rxPacketBurstList.size());
965  NS_LOG_DEBUG(this << " Expected TBs " << m_expectedTbs.size());
966  expectedTbs_t::iterator itTb = m_expectedTbs.begin();
967 
968  // apply transmission mode gain
969  NS_LOG_DEBUG(this << " txMode " << (uint16_t)m_transmissionMode << " gain "
973 
974  while (itTb != m_expectedTbs.end())
975  {
978  .empty()) // avoid to check for errors when there is no actual data transmitted
979  {
980  // retrieve HARQ info
981  HarqProcessInfoList_t harqInfoList;
982  if ((*itTb).second.ndi == 0)
983  {
984  // TB retxed: retrieve HARQ history
985  uint16_t ulHarqId = 0;
986  if ((*itTb).second.downlink)
987  {
988  harqInfoList =
989  m_harqPhyModule->GetHarqProcessInfoDl((*itTb).second.harqProcessId,
990  (*itTb).first.m_layer);
991  }
992  else
993  {
994  harqInfoList =
995  m_harqPhyModule->GetHarqProcessInfoUl((*itTb).first.m_rnti, ulHarqId);
996  }
997  }
999  (*itTb).second.rbBitmap,
1000  (*itTb).second.size,
1001  (*itTb).second.mcs,
1002  harqInfoList);
1003  (*itTb).second.mi = tbStats.mi;
1004  (*itTb).second.corrupt = !(m_random->GetValue() > tbStats.tbler);
1005  NS_LOG_DEBUG(this << "RNTI " << (*itTb).first.m_rnti << " size " << (*itTb).second.size
1006  << " mcs " << (uint32_t)(*itTb).second.mcs << " bitmap "
1007  << (*itTb).second.rbBitmap.size() << " layer "
1008  << (uint16_t)(*itTb).first.m_layer << " TBLER " << tbStats.tbler
1009  << " corrupted " << (*itTb).second.corrupt);
1010  // fire traces on DL/UL reception PHY stats
1012  params.m_timestamp = Simulator::Now().GetMilliSeconds();
1013  params.m_cellId = m_cellId;
1014  params.m_imsi = 0; // it will be set by DlPhyTransmissionCallback in LteHelper
1015  params.m_rnti = (*itTb).first.m_rnti;
1016  params.m_txMode = m_transmissionMode;
1017  params.m_layer = (*itTb).first.m_layer;
1018  params.m_mcs = (*itTb).second.mcs;
1019  params.m_size = (*itTb).second.size;
1020  params.m_rv = (*itTb).second.rv;
1021  params.m_ndi = (*itTb).second.ndi;
1022  params.m_correctness = (uint8_t) !(*itTb).second.corrupt;
1023  params.m_ccId = m_componentCarrierId;
1024  if ((*itTb).second.downlink)
1025  {
1026  // DL
1028  }
1029  else
1030  {
1031  // UL
1032  params.m_rv = harqInfoList.size();
1034  }
1035  }
1036 
1037  itTb++;
1038  }
1039  std::map<uint16_t, DlInfoListElement_s> harqDlInfoMap;
1040  for (std::list<Ptr<PacketBurst>>::const_iterator i = m_rxPacketBurstList.begin();
1041  i != m_rxPacketBurstList.end();
1042  ++i)
1043  {
1044  for (std::list<Ptr<Packet>>::const_iterator j = (*i)->Begin(); j != (*i)->End(); ++j)
1045  {
1046  // retrieve TB info of this packet
1047  LteRadioBearerTag tag;
1048  (*j)->PeekPacketTag(tag);
1049  TbId_t tbId;
1050  tbId.m_rnti = tag.GetRnti();
1051  tbId.m_layer = tag.GetLayer();
1052  itTb = m_expectedTbs.find(tbId);
1053  NS_LOG_INFO(this << " Packet of " << tbId.m_rnti << " layer "
1054  << (uint16_t)tag.GetLayer());
1055  if (itTb != m_expectedTbs.end())
1056  {
1057  if (!(*itTb).second.corrupt)
1058  {
1059  m_phyRxEndOkTrace(*j);
1060 
1062  {
1064  }
1065  }
1066  else
1067  {
1068  // TB received with errors
1070  }
1071 
1072  // send HARQ feedback (if not already done for this TB)
1073  if (!(*itTb).second.harqFeedbackSent)
1074  {
1075  (*itTb).second.harqFeedbackSent = true;
1076  if (!(*itTb).second.downlink)
1077  {
1078  UlInfoListElement_s harqUlInfo;
1079  harqUlInfo.m_rnti = tbId.m_rnti;
1080  harqUlInfo.m_tpc = 0;
1081  if ((*itTb).second.corrupt)
1082  {
1083  harqUlInfo.m_receptionStatus = UlInfoListElement_s::NotOk;
1084  NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " send UL-HARQ-NACK");
1085  m_harqPhyModule->UpdateUlHarqProcessStatus(
1086  tbId.m_rnti,
1087  (*itTb).second.mi,
1088  (*itTb).second.size,
1089  (*itTb).second.size / EffectiveCodingRate[(*itTb).second.mcs]);
1090  }
1091  else
1092  {
1093  harqUlInfo.m_receptionStatus = UlInfoListElement_s::Ok;
1094  NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " send UL-HARQ-ACK");
1095  m_harqPhyModule->ResetUlHarqProcessStatus(tbId.m_rnti,
1096  (*itTb).second.harqProcessId);
1097  }
1099  {
1100  m_ltePhyUlHarqFeedbackCallback(harqUlInfo);
1101  }
1102  }
1103  else
1104  {
1105  std::map<uint16_t, DlInfoListElement_s>::iterator itHarq =
1106  harqDlInfoMap.find(tbId.m_rnti);
1107  if (itHarq == harqDlInfoMap.end())
1108  {
1109  DlInfoListElement_s harqDlInfo;
1111  harqDlInfo.m_rnti = tbId.m_rnti;
1112  harqDlInfo.m_harqProcessId = (*itTb).second.harqProcessId;
1113  if ((*itTb).second.corrupt)
1114  {
1115  harqDlInfo.m_harqStatus.at(tbId.m_layer) =
1117  NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
1118  << (uint16_t)(*itTb).second.harqProcessId
1119  << " layer " << (uint16_t)tbId.m_layer
1120  << " send DL-HARQ-NACK");
1121  m_harqPhyModule->UpdateDlHarqProcessStatus(
1122  (*itTb).second.harqProcessId,
1123  tbId.m_layer,
1124  (*itTb).second.mi,
1125  (*itTb).second.size,
1126  (*itTb).second.size / EffectiveCodingRate[(*itTb).second.mcs]);
1127  }
1128  else
1129  {
1130  harqDlInfo.m_harqStatus.at(tbId.m_layer) = DlInfoListElement_s::ACK;
1131  NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
1132  << (uint16_t)(*itTb).second.harqProcessId
1133  << " layer " << (uint16_t)tbId.m_layer << " size "
1134  << (*itTb).second.size << " send DL-HARQ-ACK");
1135  m_harqPhyModule->ResetDlHarqProcessStatus(
1136  (*itTb).second.harqProcessId);
1137  }
1138  harqDlInfoMap.insert(
1139  std::pair<uint16_t, DlInfoListElement_s>(tbId.m_rnti, harqDlInfo));
1140  }
1141  else
1142  {
1143  if ((*itTb).second.corrupt)
1144  {
1145  (*itHarq).second.m_harqStatus.at(tbId.m_layer) =
1147  NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
1148  << (uint16_t)(*itTb).second.harqProcessId
1149  << " layer " << (uint16_t)tbId.m_layer << " size "
1150  << (*itHarq).second.m_harqStatus.size()
1151  << " send DL-HARQ-NACK");
1152  m_harqPhyModule->UpdateDlHarqProcessStatus(
1153  (*itTb).second.harqProcessId,
1154  tbId.m_layer,
1155  (*itTb).second.mi,
1156  (*itTb).second.size,
1157  (*itTb).second.size / EffectiveCodingRate[(*itTb).second.mcs]);
1158  }
1159  else
1160  {
1161  NS_ASSERT_MSG(tbId.m_layer < (*itHarq).second.m_harqStatus.size(),
1162  " layer " << (uint16_t)tbId.m_layer);
1163  (*itHarq).second.m_harqStatus.at(tbId.m_layer) =
1165  NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
1166  << (uint16_t)(*itTb).second.harqProcessId
1167  << " layer " << (uint16_t)tbId.m_layer << " size "
1168  << (*itHarq).second.m_harqStatus.size()
1169  << " send DL-HARQ-ACK");
1170  m_harqPhyModule->ResetDlHarqProcessStatus(
1171  (*itTb).second.harqProcessId);
1172  }
1173  }
1174  } // end if ((*itTb).second.downlink) HARQ
1175  } // end if (!(*itTb).second.harqFeedbackSent)
1176  }
1177  }
1178  }
1179 
1180  // send DL HARQ feedback to LtePhy
1181  std::map<uint16_t, DlInfoListElement_s>::iterator itHarq;
1182  for (itHarq = harqDlInfoMap.begin(); itHarq != harqDlInfoMap.end(); itHarq++)
1183  {
1185  {
1186  m_ltePhyDlHarqFeedbackCallback((*itHarq).second);
1187  }
1188  }
1189  // forward control messages of this frame to LtePhy
1190  if (!m_rxControlMessageList.empty())
1191  {
1193  {
1195  }
1196  }
1197  ChangeState(IDLE);
1198  m_rxPacketBurstList.clear();
1199  m_rxControlMessageList.clear();
1200  m_expectedTbs.clear();
1201 }
1202 
1203 void
1205 {
1206  NS_LOG_FUNCTION(this);
1207  NS_LOG_LOGIC(this << " state: " << m_state);
1208 
1210 
1211  // this will trigger CQI calculation and Error Model evaluation
1212  // as a side effect, the error model should update the error status of all TBs
1213  m_interferenceCtrl->EndRx();
1214  // apply transmission mode gain
1215  NS_LOG_DEBUG(this << " txMode " << (uint16_t)m_transmissionMode << " gain "
1218  if (m_transmissionMode > 0)
1219  {
1220  // in case of MIMO, ctrl is always txed as TX diversity
1221  m_sinrPerceived *= m_txModeGain.at(1);
1222  }
1223  // m_sinrPerceived *= m_txModeGain.at (m_transmissionMode);
1224  bool error = false;
1226  {
1228  error = !(m_random->GetValue() > errorRate);
1229  NS_LOG_DEBUG(this << " PCFICH-PDCCH Decodification, errorRate " << errorRate << " error "
1230  << error);
1231  }
1232 
1233  if (!error)
1234  {
1236  {
1237  NS_LOG_DEBUG(this << " PCFICH-PDCCH Rxed OK");
1239  }
1240  }
1241  else
1242  {
1244  {
1245  NS_LOG_DEBUG(this << " PCFICH-PDCCH Error");
1247  }
1248  }
1249  ChangeState(IDLE);
1250  m_rxControlMessageList.clear();
1251 }
1252 
1253 void
1255 {
1257  ChangeState(IDLE);
1258  m_interferenceCtrl->EndRx();
1259  // nothing to do (used only for SRS at this stage)
1260 }
1261 
1262 void
1264 {
1265  m_cellId = cellId;
1266 }
1267 
1268 void
1269 LteSpectrumPhy::SetComponentCarrierId(uint8_t componentCarrierId)
1270 {
1271  m_componentCarrierId = componentCarrierId;
1272 }
1273 
1274 void
1276 {
1277  m_interferenceCtrl->AddRsPowerChunkProcessor(p);
1278 }
1279 
1280 void
1282 {
1283  m_interferenceData->AddRsPowerChunkProcessor(p);
1284 }
1285 
1286 void
1288 {
1289  m_interferenceData->AddSinrChunkProcessor(p);
1290 }
1291 
1292 void
1294 {
1295  m_interferenceCtrl->AddInterferenceChunkProcessor(p);
1296 }
1297 
1298 void
1300 {
1301  m_interferenceData->AddInterferenceChunkProcessor(p);
1302 }
1303 
1304 void
1306 {
1307  m_interferenceCtrl->AddSinrChunkProcessor(p);
1308 }
1309 
1310 void
1312 {
1313  NS_LOG_FUNCTION(this << (uint16_t)txMode);
1314  NS_ASSERT_MSG(txMode < m_txModeGain.size(),
1315  "TransmissionMode not available: 1.." << m_txModeGain.size());
1316  m_transmissionMode = txMode;
1318 }
1319 
1320 void
1321 LteSpectrumPhy::SetTxModeGain(uint8_t txMode, double gain)
1322 {
1323  NS_LOG_FUNCTION(this << " txmode " << (uint16_t)txMode << " gain " << gain);
1324  if (txMode > 0)
1325  {
1326  // convert to linear
1327  double gainLin = std::pow(10.0, (gain / 10.0));
1328  if (m_txModeGain.size() < txMode)
1329  {
1330  m_txModeGain.resize(txMode);
1331  }
1332  m_txModeGain.at(txMode - 1) = gainLin;
1333  }
1334 }
1335 
1336 int64_t
1338 {
1339  NS_LOG_FUNCTION(this << stream);
1340  m_random->SetStream(stream);
1341  return 1;
1342 }
1343 
1344 } // namespace ns3
AttributeValue implementation for Boolean.
Definition: boolean.h:37
bool IsNull() const
Check for null implementation.
Definition: callback.h:572
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
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
static double GetPcfichPdcchError(const SpectrumValue &sinr)
run the error-model algorithm for the specified PCFICH+PDCCH channels
Tag used to define the RNTI and LC id for each MAC packet trasmitted.
uint16_t GetRnti() const
Get RNTI function.
uint8_t GetLayer() const
Get layer function.
The LteSpectrumPhy models the physical layer of LTE.
void RemoveExpectedTb(uint16_t rnti)
Remove expected transport block.
Ptr< const SpectrumModel > m_rxSpectrumModel
the spectrum model
TracedCallback< Ptr< const PacketBurst > > m_phyTxEndTrace
the phy transmit end trace callback
bool m_dataErrorModelEnabled
when true (default) the phy error model is enabled
void SetState(State newState)
Set the state of the phy layer.
Ptr< LteInterference > m_interferenceData
the data interference
uint8_t m_transmissionMode
for UEs: store the transmission mode
EventId m_endRxDlCtrlEvent
end receive DL control event
void AddCtrlSinrChunkProcessor(Ptr< LteChunkProcessor > p)
void AddDataSinrChunkProcessor(Ptr< LteChunkProcessor > p)
LtePhyUlHarqFeedbackCallback m_ltePhyUlHarqFeedbackCallback
the LTE phy UL HARQ feedback callback
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< MobilityModel > GetMobility() const override
Get the associated MobilityModel instance.
Ptr< const SpectrumModel > GetRxSpectrumModel() const override
void SetHarqPhyModule(Ptr< LteHarqPhy > harq)
Set HARQ phy function.
LtePhyRxPssCallback m_ltePhyRxPssCallback
the LTE phy receive PSS callback
void StartRxDlCtrl(Ptr< LteSpectrumSignalParametersDlCtrlFrame > lteDlCtrlRxParams)
Start receive DL control function.
void StartRxUlSrs(Ptr< LteSpectrumSignalParametersUlSrsFrame > lteUlSrsRxParams)
Start receive UL SRS function.
void AddDataPowerChunkProcessor(Ptr< LteChunkProcessor > p)
EventId m_endRxDataEvent
end receive data event
void SetLtePhyRxPssCallback(LtePhyRxPssCallback c)
set the callback for the reception of the PSS as part of the interconnections between the LteSpectrum...
void SetAntenna(Ptr< AntennaModel > a)
set the AntennaModel to be used
void StartRxData(Ptr< LteSpectrumSignalParametersDataFrame > params)
Start receive data function.
TracedCallback< PhyReceptionStatParameters > m_dlPhyReception
Trace information regarding PHY stats from DL Rx perspective PhyReceptionStatParameters (see lte-comm...
Ptr< NetDevice > m_device
the device
Ptr< SpectrumChannel > GetChannel()
TracedCallback< Ptr< const PacketBurst > > m_phyTxStartTrace
the phy transmit start trace callback
void DoDispose() override
Destructor implementation.
void EndTxData()
End transmit data function.
void SetTransmissionMode(uint8_t txMode)
void SetLtePhyRxDataEndErrorCallback(LtePhyRxDataEndErrorCallback c)
set the callback for the end of a RX in error, as part of the interconnections between the PHY and th...
SpectrumValue m_sinrPerceived
the preceived SINR
Ptr< SpectrumValue > m_txPsd
the transmit PSD
void AddInterferenceDataChunkProcessor(Ptr< LteChunkProcessor > p)
LteChunkProcessor devoted to evaluate interference + noise power in data symbols of the subframe.
void SetDevice(Ptr< NetDevice > d) override
Set the associated NetDevice instance.
void ChangeState(State newState)
Change state function.
void SetTxModeGain(uint8_t txMode, double gain)
Set transmit mode gain function.
std::vector< double > m_txModeGain
duplicate value of LteUePhy
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Ptr< NetDevice > GetDevice() const override
Get the associated NetDevice instance.
Time m_firstRxStart
the first receive start
Ptr< LteHarqPhy > m_harqPhyModule
the HARQ phy module
void SetLtePhyRxDataEndOkCallback(LtePhyRxDataEndOkCallback c)
set the callback for the successful end of a RX, as part of the interconnections between the PHY and ...
void EndRxUlSrs()
End receive UL SRS function.
void SetLtePhyUlHarqFeedbackCallback(LtePhyUlHarqFeedbackCallback c)
set the callback for the UL HARQ feedback as part of the interconnections between the LteSpectrumPhy ...
void SetChannel(Ptr< SpectrumChannel > c) override
Set the channel attached to this device.
void SetComponentCarrierId(uint8_t componentCarrierId)
TracedCallback< Ptr< const PacketBurst > > m_phyRxStartTrace
the phy receive start trace callback
expectedTbs_t m_expectedTbs
the expected TBS
void EndTxUlSrs()
End transmit UL SRS function.
void SetNoisePowerSpectralDensity(Ptr< const SpectrumValue > noisePsd)
set the noise power spectral density
void UpdateSinrPerceived(const SpectrumValue &sinr)
Ptr< SpectrumChannel > m_channel
the channel
void EndRxDlCtrl()
End receive DL control function.
void SetTxPowerSpectralDensity(Ptr< SpectrumValue > txPsd)
set the Power Spectral Density of outgoing signals in W/Hz.
EventId m_endTxEvent
end transmit event
LtePhyRxDataEndOkCallback m_ltePhyRxDataEndOkCallback
the LTE phy receive data end ok callback
void SetLtePhyRxCtrlEndErrorCallback(LtePhyRxCtrlEndErrorCallback c)
set the callback for the erroneous end of a RX ctrl frame, as part of the interconnections between th...
State m_state
the state
uint16_t m_cellId
the cell ID
Ptr< AntennaModel > m_antenna
the antenna model
void SetLtePhyDlHarqFeedbackCallback(LtePhyDlHarqFeedbackCallback c)
set the callback for the DL HARQ feedback as part of the interconnections between the LteSpectrumPhy ...
Time m_firstRxDuration
the first receive duration
Ptr< PacketBurst > m_txPacketBurst
the transmit packet burst
uint8_t m_componentCarrierId
the component carrier ID
void StartRx(Ptr< SpectrumSignalParameters > params) override
Notify the SpectrumPhy instance of an incoming signal.
Ptr< Object > GetAntenna() const override
Get the AntennaModel used by this SpectrumPhy instance for transmission and/or reception.
LtePhyRxDataEndErrorCallback m_ltePhyRxDataEndErrorCallback
the LTE phy receive data end error callback
static TypeId GetTypeId()
Get the type ID.
uint8_t m_layersNum
layers num
Ptr< MobilityModel > m_mobility
the modility model
TracedCallback< PhyReceptionStatParameters > m_ulPhyReception
Trace information regarding PHY stats from UL Rx perspective PhyReceptionStatParameters (see lte-comm...
void SetMobility(Ptr< MobilityModel > m) override
Set the mobility model associated with this device.
LtePhyDlHarqFeedbackCallback m_ltePhyDlHarqFeedbackCallback
the LTE phy DL HARQ feedback callback
void EndTxDlCtrl()
End transmit DL control function.
std::list< Ptr< LteControlMessage > > m_rxControlMessageList
the receive control message list
void AddRsPowerChunkProcessor(Ptr< LteChunkProcessor > p)
Ptr< LteInterference > m_interferenceCtrl
the control interference
TracedCallback< Ptr< const Packet > > m_phyRxEndErrorTrace
the phy receive end error trace callback
void EndRxData()
End receive data function.
std::list< Ptr< LteControlMessage > > m_txControlMessageList
the transmit control message list
bool m_ctrlErrorModelEnabled
when true (default) the phy error model is enabled for DL ctrl frame
bool StartTxDataFrame(Ptr< PacketBurst > pb, std::list< Ptr< LteControlMessage >> ctrlMsgList, Time duration)
Start a transmission of data frame in DL and UL.
std::list< Ptr< PacketBurst > > m_rxPacketBurstList
the receive burst list
void AddInterferenceCtrlChunkProcessor(Ptr< LteChunkProcessor > p)
LteChunkProcessor devoted to evaluate interference + noise power in control symbols of the subframe.
TracedCallback< Ptr< const Packet > > m_phyRxEndOkTrace
the phy receive end ok trace callback
bool StartTxUlSrsFrame()
Start a transmission of control frame in UL.
bool StartTxDlCtrlFrame(std::list< Ptr< LteControlMessage >> ctrlMsgList, bool pss)
Start a transmission of control frame in DL.
LtePhyRxCtrlEndErrorCallback m_ltePhyRxCtrlEndErrorCallback
the LTE phy receive control end error callback
void SetLtePhyRxCtrlEndOkCallback(LtePhyRxCtrlEndOkCallback c)
set the callback for the successful end of a RX ctrl frame, as part of the interconnections between t...
void Reset()
reset the internal state
EventId m_endRxUlSrsEvent
end receive UL SRS event
void SetCellId(uint16_t cellId)
LtePhyRxCtrlEndOkCallback m_ltePhyRxCtrlEndOkCallback
the LTE phy receive control end ok callback
Ptr< UniformRandomVariable > m_random
Provides uniform random variables.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:200
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:353
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
Abstract base class for Spectrum-aware PHY layers.
Definition: spectrum-phy.h:46
Set of values corresponding to a given SpectrumModel.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
int64_t GetMilliSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:407
@ S
second
Definition: nstime.h:116
static uint8_t TxMode2LayerNum(uint8_t txMode)
Transmit mode 2 layer number.
Definition: lte-common.cc:203
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
double GetValue(double min, double max)
Get the next random value drawn from the distribution.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: boolean.h:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1372
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool operator==(const EventId &a, const EventId &b)
Definition: event-id.h:157
bool operator<(const EventId &a, const EventId &b)
Definition: event-id.h:170
std::vector< HarqProcessInfoElement_t > HarqProcessInfoList_t
HarqProcessInfoList_t typedef.
Definition: lte-harq-phy.h:44
static const Time DL_CTRL_DURATION
duration of the control portion of a subframe = 0.001 / 14 * 3 (ctrl fixed to 3 symbols) -1ns as marg...
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:129
static const Time UL_SRS_DURATION
duration of SRS portion of UL subframe = 1 symbol for SRS -1ns as margin to avoid overlapping simulat...
static const double EffectiveCodingRate[29]
Effective coding rate.
params
Fit Fluctuating Two Ray model to the 3GPP TR 38.901 using the Anderson-Darling goodness-of-fit ##.
#define list
See section 4.3.23 dlInfoListElement.
uint8_t m_harqProcessId
HARQ process ID.
std::vector< enum HarqStatus_e > m_harqStatus
HARQ status.
PhyReceptionStatParameters structure.
Definition: lte-common.h:206
Time duration
The duration of the packet transmission.
Ptr< SpectrumValue > psd
The Power Spectral Density of the waveform, in linear units.
TbId_t structure.
uint8_t m_layer
layer
uint16_t m_rnti
RNTI.
TbStats_t structure.
double mi
Mutual information.
double tbler
Transport block BLER.
See section 4.3.12 ulInfoListElement.
uint8_t m_tpc
Tx power control command.
tbInfo_t structure
@ IDLE
The PHY layer is IDLE.