A Discrete-Event Network Simulator
QKDNetSim v2.0 (NS-3 v3.41) @ (+)
API
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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-control-messages.h"
26 #include "lte-mi-error-model.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/object-factory.h>
36 #include <ns3/simulator.h>
37 #include <ns3/trace-source-accessor.h>
38 
39 #include <cmath>
40 
41 namespace ns3
42 {
43 
44 NS_LOG_COMPONENT_DEFINE("LteSpectrumPhy");
45 
48 static const Time UL_SRS_DURATION = NanoSeconds(71429 - 1);
49 
52 static const Time DL_CTRL_DURATION = NanoSeconds(214286 - 1);
53 
55 static const double EffectiveCodingRate[29] = {
56  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,
57  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,
58 };
59 
61 {
62 }
63 
64 TbId_t::TbId_t(const uint16_t a, const uint8_t b)
65  : m_rnti(a),
66  m_layer(b)
67 {
68 }
69 
77 bool
78 operator==(const TbId_t& a, const TbId_t& b)
79 {
80  return ((a.m_rnti == b.m_rnti) && (a.m_layer == b.m_layer));
81 }
82 
90 bool
91 operator<(const TbId_t& a, const TbId_t& b)
92 {
93  return ((a.m_rnti < b.m_rnti) || ((a.m_rnti == b.m_rnti) && (a.m_layer < b.m_layer)));
94 }
95 
97 
99  : m_state(IDLE),
100  m_cellId(0),
101  m_componentCarrierId(0),
102  m_transmissionMode(0),
103  m_layersNum(1)
104 {
105  NS_LOG_FUNCTION(this);
106  m_random = CreateObject<UniformRandomVariable>();
107  m_random->SetAttribute("Min", DoubleValue(0.0));
108  m_random->SetAttribute("Max", DoubleValue(1.0));
109  m_interferenceData = CreateObject<LteInterference>();
110  m_interferenceCtrl = CreateObject<LteInterference>();
111 
112  for (uint8_t i = 0; i < 7; i++)
113  {
114  m_txModeGain.push_back(1.0);
115  }
116 }
117 
119 {
120  NS_LOG_FUNCTION(this);
121  m_expectedTbs.clear();
122  m_txModeGain.clear();
123 }
124 
125 void
127 {
128  NS_LOG_FUNCTION(this);
129  m_channel = nullptr;
130  m_mobility = nullptr;
131  m_device = nullptr;
132  m_interferenceData->Dispose();
133  m_interferenceData = nullptr;
134  m_interferenceCtrl->Dispose();
135  m_interferenceCtrl = nullptr;
136  m_ltePhyRxDataEndErrorCallback = MakeNullCallback<void>();
137  m_ltePhyRxDataEndOkCallback = MakeNullCallback<void, Ptr<Packet>>();
138  m_ltePhyRxCtrlEndOkCallback = MakeNullCallback<void, std::list<Ptr<LteControlMessage>>>();
139  m_ltePhyRxCtrlEndErrorCallback = MakeNullCallback<void>();
140  m_ltePhyDlHarqFeedbackCallback = MakeNullCallback<void, DlInfoListElement_s>();
141  m_ltePhyUlHarqFeedbackCallback = MakeNullCallback<void, UlInfoListElement_s>();
142  m_ltePhyRxPssCallback = MakeNullCallback<void, uint16_t, Ptr<SpectrumValue>>();
144 }
145 
153 std::ostream&
154 operator<<(std::ostream& os, LteSpectrumPhy::State s)
155 {
156  switch (s)
157  {
159  os << "IDLE";
160  break;
162  os << "RX_DATA";
163  break;
165  os << "RX_DL_CTRL";
166  break;
168  os << "TX_DATA";
169  break;
171  os << "TX_DL_CTRL";
172  break;
174  os << "TX_UL_SRS";
175  break;
176  default:
177  os << "UNKNOWN";
178  break;
179  }
180  return os;
181 }
182 
183 TypeId
185 {
186  static TypeId tid =
187  TypeId("ns3::LteSpectrumPhy")
189  .SetGroupName("Lte")
190  .AddTraceSource("TxStart",
191  "Trace fired when a new transmission is started",
193  "ns3::PacketBurst::TracedCallback")
194  .AddTraceSource("TxEnd",
195  "Trace fired when a previously started transmission is finished",
197  "ns3::PacketBurst::TracedCallback")
198  .AddTraceSource("RxStart",
199  "Trace fired when the start of a signal is detected",
201  "ns3::PacketBurst::TracedCallback")
202  .AddTraceSource("RxEndOk",
203  "Trace fired when a previously started RX terminates successfully",
205  "ns3::Packet::TracedCallback")
206  .AddTraceSource("RxEndError",
207  "Trace fired when a previously started RX terminates with an error",
209  "ns3::Packet::TracedCallback")
210  .AddAttribute("DataErrorModelEnabled",
211  "Activate/Deactivate the error model of data (TBs of PDSCH and PUSCH) "
212  "[by default is active].",
213  BooleanValue(true),
216  .AddAttribute("CtrlErrorModelEnabled",
217  "Activate/Deactivate the error model of control (PCFICH-PDCCH "
218  "decodification) [by default is active].",
219  BooleanValue(true),
222  .AddTraceSource("DlPhyReception",
223  "DL reception PHY layer statistics.",
225  "ns3::PhyReceptionStatParameters::TracedCallback")
226  .AddTraceSource("UlPhyReception",
227  "DL reception PHY layer statistics.",
229  "ns3::PhyReceptionStatParameters::TracedCallback");
230  return tid;
231 }
232 
235 {
236  NS_LOG_FUNCTION(this);
237  return m_device;
238 }
239 
242 {
243  NS_LOG_FUNCTION(this);
244  return m_mobility;
245 }
246 
247 void
249 {
250  NS_LOG_FUNCTION(this << d);
251  m_device = d;
252 }
253 
254 void
256 {
257  NS_LOG_FUNCTION(this << m);
258  m_mobility = m;
259 }
260 
261 void
263 {
264  NS_LOG_FUNCTION(this << c);
265  m_channel = c;
266 }
267 
270 {
271  return m_channel;
272 }
273 
276 {
277  return m_rxSpectrumModel;
278 }
279 
280 void
282 {
283  NS_LOG_FUNCTION(this << txPsd);
284  NS_ASSERT(txPsd);
285  m_txPsd = txPsd;
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 void
300 {
301  NS_LOG_FUNCTION(this);
302  m_cellId = 0;
303  m_state = IDLE;
304  m_transmissionMode = 0;
305  m_layersNum = 1;
310  m_rxControlMessageList.clear();
311  m_expectedTbs.clear();
312  m_txControlMessageList.clear();
313  m_rxPacketBurstList.clear();
314  m_txPacketBurst = nullptr;
315  m_rxSpectrumModel = nullptr;
316 
317  // Detach from the channel, because receiving any signal without
318  // spectrum model is an error.
319  if (m_channel)
320  {
321  m_channel->RemoveRx(this);
322  }
323 }
324 
325 void
327 {
328  NS_LOG_FUNCTION(this);
330 }
331 
332 void
334 {
335  NS_LOG_FUNCTION(this);
337 }
338 
339 void
341 {
342  NS_LOG_FUNCTION(this);
344 }
345 
346 void
348 {
349  NS_LOG_FUNCTION(this);
351 }
352 
353 void
355 {
356  NS_LOG_FUNCTION(this);
358 }
359 
360 void
362 {
363  NS_LOG_FUNCTION(this);
365 }
366 
367 void
369 {
370  NS_LOG_FUNCTION(this);
372 }
373 
376 {
377  return m_antenna;
378 }
379 
380 void
382 {
383  NS_LOG_FUNCTION(this << a);
384  m_antenna = a;
385 }
386 
387 void
389 {
390  ChangeState(newState);
391 }
392 
393 void
395 {
396  NS_LOG_LOGIC(this << " state: " << m_state << " -> " << newState);
397  m_state = newState;
398 }
399 
400 void
402 {
403  m_harqPhyModule = harq;
404 }
405 
406 bool
408  std::list<Ptr<LteControlMessage>> ctrlMsgList,
409  Time duration)
410 {
411  NS_LOG_FUNCTION(this << pb);
412  NS_LOG_LOGIC(this << " state: " << m_state);
413 
414  m_phyTxStartTrace(pb);
415 
416  switch (m_state)
417  {
418  case RX_DATA:
419  case RX_DL_CTRL:
420  case RX_UL_SRS:
421  NS_FATAL_ERROR("cannot TX while RX: according to FDD channel access, the physical layer "
422  "for transmission cannot be used for reception");
423  break;
424 
425  case TX_DATA:
426  case TX_DL_CTRL:
427  case TX_UL_SRS:
428  NS_FATAL_ERROR("cannot TX while already TX: the MAC should avoid this");
429  break;
430 
431  case IDLE: {
432  /*
433  m_txPsd must be set by the device, according to
434  (i) the available subchannel for transmission
435  (ii) the power transmission
436  */
438  m_txPacketBurst = pb;
439 
440  // we need to convey some PHY meta information to the receiver
441  // to be used for simulation purposes (e.g., the CellId). This
442  // is done by setting the ctrlMsgList parameter of
443  // LteSpectrumSignalParametersDataFrame
447  Create<LteSpectrumSignalParametersDataFrame>();
448  txParams->duration = duration;
449  txParams->txPhy = GetObject<SpectrumPhy>();
450  txParams->txAntenna = m_antenna;
451  txParams->psd = m_txPsd;
452  txParams->packetBurst = pb;
453  txParams->ctrlMsgList = ctrlMsgList;
454  txParams->cellId = m_cellId;
455  m_channel->StartTx(txParams);
457  }
458  return false;
459 
460  default:
461  NS_FATAL_ERROR("unknown state");
462  return true;
463  }
464 }
465 
466 bool
468 {
469  NS_LOG_FUNCTION(this << " PSS " << (uint16_t)pss);
470  NS_LOG_LOGIC(this << " state: " << m_state);
471 
472  switch (m_state)
473  {
474  case RX_DATA:
475  case RX_DL_CTRL:
476  case RX_UL_SRS:
477  NS_FATAL_ERROR("cannot TX while RX: according to FDD channel access, the physical layer "
478  "for transmission cannot be used for reception");
479  break;
480 
481  case TX_DATA:
482  case TX_DL_CTRL:
483  case TX_UL_SRS:
484  NS_FATAL_ERROR("cannot TX while already TX: the MAC should avoid this");
485  break;
486 
487  case IDLE: {
488  /*
489  m_txPsd must be set by the device, according to
490  (i) the available subchannel for transmission
491  (ii) the power transmission
492  */
494 
495  // we need to convey some PHY meta information to the receiver
496  // to be used for simulation purposes (e.g., the CellId). This
497  // is done by setting the cellId parameter of
498  // LteSpectrumSignalParametersDlCtrlFrame
501 
503  Create<LteSpectrumSignalParametersDlCtrlFrame>();
504  txParams->duration = DL_CTRL_DURATION;
505  txParams->txPhy = GetObject<SpectrumPhy>();
506  txParams->txAntenna = m_antenna;
507  txParams->psd = m_txPsd;
508  txParams->cellId = m_cellId;
509  txParams->pss = pss;
510  txParams->ctrlMsgList = ctrlMsgList;
511  m_channel->StartTx(txParams);
513  }
514  return false;
515 
516  default:
517  NS_FATAL_ERROR("unknown state");
518  return true;
519  }
520 }
521 
522 bool
524 {
525  NS_LOG_FUNCTION(this);
526  NS_LOG_LOGIC(this << " state: " << m_state);
527 
528  switch (m_state)
529  {
530  case RX_DATA:
531  case RX_DL_CTRL:
532  case RX_UL_SRS:
533  NS_FATAL_ERROR("cannot TX while RX: according to FDD channel access, the physical layer "
534  "for transmission cannot be used for reception");
535  break;
536 
537  case TX_DL_CTRL:
538  case TX_DATA:
539  case TX_UL_SRS:
540  NS_FATAL_ERROR("cannot TX while already TX: the MAC should avoid this");
541  break;
542 
543  case IDLE: {
544  /*
545  m_txPsd must be set by the device, according to
546  (i) the available subchannel for transmission
547  (ii) the power transmission
548  */
550  NS_LOG_LOGIC(this << " m_txPsd: " << *m_txPsd);
551 
552  // we need to convey some PHY meta information to the receiver
553  // to be used for simulation purposes (e.g., the CellId). This
554  // is done by setting the cellId parameter of
555  // LteSpectrumSignalParametersDlCtrlFrame
559  Create<LteSpectrumSignalParametersUlSrsFrame>();
560  txParams->duration = UL_SRS_DURATION;
561  txParams->txPhy = GetObject<SpectrumPhy>();
562  txParams->txAntenna = m_antenna;
563  txParams->psd = m_txPsd;
564  txParams->cellId = m_cellId;
565  m_channel->StartTx(txParams);
567  }
568  return false;
569 
570  default:
571  NS_FATAL_ERROR("unknown state");
572  return true;
573  }
574 }
575 
576 void
578 {
579  NS_LOG_FUNCTION(this);
580  NS_LOG_LOGIC(this << " state: " << m_state);
581 
584  m_txPacketBurst = nullptr;
585  ChangeState(IDLE);
586 }
587 
588 void
590 {
591  NS_LOG_FUNCTION(this);
592  NS_LOG_LOGIC(this << " state: " << m_state);
593 
596  ChangeState(IDLE);
597 }
598 
599 void
601 {
602  NS_LOG_FUNCTION(this);
603  NS_LOG_LOGIC(this << " state: " << m_state);
604 
607  ChangeState(IDLE);
608 }
609 
610 void
612 {
613  NS_LOG_FUNCTION(this << spectrumRxParams);
614  NS_LOG_LOGIC(this << " state: " << m_state);
615 
616  Ptr<const SpectrumValue> rxPsd = spectrumRxParams->psd;
617  Time duration = spectrumRxParams->duration;
618 
619  // the device might start RX only if the signal is of a type
620  // understood by this device - in this case, an LTE signal.
622  DynamicCast<LteSpectrumSignalParametersDataFrame>(spectrumRxParams);
624  DynamicCast<LteSpectrumSignalParametersDlCtrlFrame>(spectrumRxParams);
626  DynamicCast<LteSpectrumSignalParametersUlSrsFrame>(spectrumRxParams);
627  if (lteDataRxParams)
628  {
629  m_interferenceData->AddSignal(rxPsd, duration);
630  StartRxData(lteDataRxParams);
631  }
632  else if (lteDlCtrlRxParams)
633  {
634  m_interferenceCtrl->AddSignal(rxPsd, duration);
635  StartRxDlCtrl(lteDlCtrlRxParams);
636  }
637  else if (lteUlSrsRxParams)
638  {
639  m_interferenceCtrl->AddSignal(rxPsd, duration);
640  StartRxUlSrs(lteUlSrsRxParams);
641  }
642  else
643  {
644  // other type of signal (could be 3G, GSM, whatever) -> interference
645  m_interferenceData->AddSignal(rxPsd, duration);
646  m_interferenceCtrl->AddSignal(rxPsd, duration);
647  }
648 }
649 
650 void
652 {
653  NS_LOG_FUNCTION(this);
654  switch (m_state)
655  {
656  case TX_DATA:
657  case TX_DL_CTRL:
658  case TX_UL_SRS:
659  NS_FATAL_ERROR("cannot RX while TX: according to FDD channel access, the physical layer "
660  "for transmission cannot be used for reception");
661  break;
662  case RX_DL_CTRL:
663  NS_FATAL_ERROR("cannot RX Data while receiving control");
664  break;
665  case IDLE:
666  case RX_DATA:
667  // the behavior is similar when
668  // we're IDLE or RX because we can receive more signals
669  // simultaneously (e.g., at the eNB).
670  {
671  // To check if we're synchronized to this signal, we check
672  // for the CellId which is reported in the
673  // LteSpectrumSignalParametersDataFrame
674  if (params->cellId == m_cellId)
675  {
676  NS_LOG_LOGIC(this << " synchronized with this signal (cellId=" << params->cellId
677  << ")");
678  if ((m_rxPacketBurstList.empty()) && (m_rxControlMessageList.empty()))
679  {
680  NS_ASSERT(m_state == IDLE);
681  // first transmission, i.e., we're IDLE and we
682  // start RX
684  m_firstRxDuration = params->duration;
685  NS_LOG_LOGIC(this << " scheduling EndRx with delay "
686  << params->duration.As(Time::S));
689  }
690  else
691  {
693  // sanity check: if there are multiple RX events, they
694  // should occur at the same time and have the same
695  // duration, otherwise the interference calculation
696  // won't be correct
698  (m_firstRxDuration == params->duration));
699  }
700 
702  if (params->packetBurst)
703  {
704  m_rxPacketBurstList.push_back(params->packetBurst);
705  m_interferenceData->StartRx(params->psd);
706 
707  m_phyRxStartTrace(params->packetBurst);
708  }
709  NS_LOG_DEBUG(this << " insert msgs " << params->ctrlMsgList.size());
711  params->ctrlMsgList.begin(),
712  params->ctrlMsgList.end());
713 
714  NS_LOG_LOGIC(this << " numSimultaneousRxEvents = " << m_rxPacketBurstList.size());
715  }
716  else
717  {
718  NS_LOG_LOGIC(this << " not in sync with this signal (cellId=" << params->cellId
719  << ", m_cellId=" << m_cellId << ")");
720  }
721  }
722  break;
723 
724  default:
725  NS_FATAL_ERROR("unknown state");
726  break;
727  }
728 
729  NS_LOG_LOGIC(this << " state: " << m_state);
730 }
731 
732 void
734 {
735  NS_LOG_FUNCTION(this);
736 
737  // To check if we're synchronized to this signal, we check
738  // for the CellId which is reported in the
739  // LteSpectrumSignalParametersDlCtrlFrame
740  uint16_t cellId;
741  NS_ASSERT(lteDlCtrlRxParams);
742  cellId = lteDlCtrlRxParams->cellId;
743 
744  switch (m_state)
745  {
746  case TX_DATA:
747  case TX_DL_CTRL:
748  case TX_UL_SRS:
749  case RX_DATA:
750  case RX_UL_SRS:
751  NS_FATAL_ERROR("unexpected event in state " << m_state);
752  break;
753 
754  case RX_DL_CTRL:
755  case IDLE:
756 
757  // common code for the two states
758  // check presence of PSS for UE measuerements
759  if (lteDlCtrlRxParams->pss)
760  {
762  {
763  m_ltePhyRxPssCallback(cellId, lteDlCtrlRxParams->psd);
764  }
765  }
766 
767  // differentiated code for the two states
768  switch (m_state)
769  {
770  case RX_DL_CTRL:
771  NS_ASSERT_MSG(m_cellId != cellId, "any other DlCtrl should be from a different cell");
772  NS_LOG_LOGIC(this << " ignoring other DlCtrl (cellId=" << cellId
773  << ", m_cellId=" << m_cellId << ")");
774  break;
775 
776  case IDLE:
777  if (cellId == m_cellId)
778  {
779  NS_LOG_LOGIC(this << " synchronized with this signal (cellId=" << cellId << ")");
780 
783  m_firstRxDuration = lteDlCtrlRxParams->duration;
784  NS_LOG_LOGIC(this << " scheduling EndRx with delay "
785  << lteDlCtrlRxParams->duration);
786 
787  // store the DCIs
788  m_rxControlMessageList = lteDlCtrlRxParams->ctrlMsgList;
789  m_endRxDlCtrlEvent = Simulator::Schedule(lteDlCtrlRxParams->duration,
791  this);
793  m_interferenceCtrl->StartRx(lteDlCtrlRxParams->psd);
794  }
795  else
796  {
797  NS_LOG_LOGIC(this << " not synchronizing with this signal (cellId=" << cellId
798  << ", m_cellId=" << m_cellId << ")");
799  }
800  break;
801 
802  default:
803  NS_FATAL_ERROR("unexpected event in state " << m_state);
804  break;
805  }
806  break; // case RX_DL_CTRL or IDLE
807 
808  default:
809  NS_FATAL_ERROR("unknown state");
810  break;
811  }
812 
813  NS_LOG_LOGIC(this << " state: " << m_state);
814 }
815 
816 void
818 {
819  NS_LOG_FUNCTION(this);
820  switch (m_state)
821  {
822  case TX_DATA:
823  case TX_DL_CTRL:
824  case TX_UL_SRS:
825  NS_FATAL_ERROR("cannot RX while TX: according to FDD channel access, the physical layer "
826  "for transmission cannot be used for reception");
827  break;
828 
829  case RX_DATA:
830  case RX_DL_CTRL:
831  NS_FATAL_ERROR("cannot RX SRS while receiving something else");
832  break;
833 
834  case IDLE:
835  case RX_UL_SRS:
836  // the behavior is similar when
837  // we're IDLE or RX_UL_SRS because we can receive more signals
838  // simultaneously at the eNB
839  {
840  // To check if we're synchronized to this signal, we check
841  // for the CellId which is reported in the
842  // LteSpectrumSignalParametersDlCtrlFrame
843  uint16_t cellId;
844  cellId = lteUlSrsRxParams->cellId;
845  if (cellId == m_cellId)
846  {
847  NS_LOG_LOGIC(this << " synchronized with this signal (cellId=" << cellId << ")");
848  if (m_state == IDLE)
849  {
850  // first transmission, i.e., we're IDLE and we
851  // start RX
854  m_firstRxDuration = lteUlSrsRxParams->duration;
855  NS_LOG_LOGIC(this << " scheduling EndRx with delay "
856  << lteUlSrsRxParams->duration);
857 
858  m_endRxUlSrsEvent = Simulator::Schedule(lteUlSrsRxParams->duration,
860  this);
861  }
862  else if (m_state == RX_UL_SRS)
863  {
864  // sanity check: if there are multiple RX events, they
865  // should occur at the same time and have the same
866  // duration, otherwise the interference calculation
867  // won't be correct
869  (m_firstRxDuration == lteUlSrsRxParams->duration));
870  }
872  m_interferenceCtrl->StartRx(lteUlSrsRxParams->psd);
873  }
874  else
875  {
876  NS_LOG_LOGIC(this << " not in sync with this signal (cellId=" << cellId
877  << ", m_cellId=" << m_cellId << ")");
878  }
879  }
880  break;
881 
882  default:
883  NS_FATAL_ERROR("unknown state");
884  break;
885  }
886 
887  NS_LOG_LOGIC(this << " state: " << m_state);
888 }
889 
890 void
892 {
893  NS_LOG_FUNCTION(this << sinr);
894  m_sinrPerceived = sinr;
895 }
896 
897 void
899  uint8_t ndi,
900  uint16_t size,
901  uint8_t mcs,
902  std::vector<int> map,
903  uint8_t layer,
904  uint8_t harqId,
905  uint8_t rv,
906  bool downlink)
907 {
908  NS_LOG_FUNCTION(this << " rnti: " << rnti << " NDI " << (uint16_t)ndi << " size " << size
909  << " mcs " << (uint16_t)mcs << " layer " << (uint16_t)layer << " rv "
910  << (uint16_t)rv);
911  TbId_t tbId;
912  tbId.m_rnti = rnti;
913  tbId.m_layer = layer;
914  auto it = m_expectedTbs.find(tbId);
915  if (it != m_expectedTbs.end())
916  {
917  // might be a TB of an unreceived packet (due to high propagation losses)
918  m_expectedTbs.erase(it);
919  }
920  // insert new entry
921  tbInfo_t tbInfo = {ndi, size, mcs, map, harqId, rv, 0.0, downlink, false, false};
922  m_expectedTbs.insert(std::pair<TbId_t, tbInfo_t>(tbId, tbInfo));
923 }
924 
925 void
927 {
928  NS_LOG_FUNCTION(this << rnti);
929  TbId_t tbId;
930  tbId.m_rnti = rnti;
931  // Remove TB of both the layers
932  for (uint8_t i = 0; i < 2; i++)
933  {
934  tbId.m_layer = i;
935  auto it = m_expectedTbs.find(tbId);
936  if (it != m_expectedTbs.end())
937  {
938  m_expectedTbs.erase(it);
939  }
940  }
941 }
942 
943 void
945 {
946  NS_LOG_FUNCTION(this);
947  NS_LOG_LOGIC(this << " state: " << m_state);
948 
950 
951  // this will trigger CQI calculation and Error Model evaluation
952  // as a side effect, the error model should update the error status of all TBs
953  m_interferenceData->EndRx();
954  NS_LOG_DEBUG(this << " No. of burts " << m_rxPacketBurstList.size());
955  NS_LOG_DEBUG(this << " Expected TBs " << m_expectedTbs.size());
956  auto itTb = m_expectedTbs.begin();
957 
958  // apply transmission mode gain
959  NS_LOG_DEBUG(this << " txMode " << (uint16_t)m_transmissionMode << " gain "
963 
964  while (itTb != m_expectedTbs.end())
965  {
968  .empty()) // avoid to check for errors when there is no actual data transmitted
969  {
970  // retrieve HARQ info
971  HarqProcessInfoList_t harqInfoList;
972  if ((*itTb).second.ndi == 0)
973  {
974  // TB retxed: retrieve HARQ history
975  uint16_t ulHarqId = 0;
976  if ((*itTb).second.downlink)
977  {
978  harqInfoList =
979  m_harqPhyModule->GetHarqProcessInfoDl((*itTb).second.harqProcessId,
980  (*itTb).first.m_layer);
981  }
982  else
983  {
984  harqInfoList =
985  m_harqPhyModule->GetHarqProcessInfoUl((*itTb).first.m_rnti, ulHarqId);
986  }
987  }
989  (*itTb).second.rbBitmap,
990  (*itTb).second.size,
991  (*itTb).second.mcs,
992  harqInfoList);
993  (*itTb).second.mi = tbStats.mi;
994  (*itTb).second.corrupt = !(m_random->GetValue() > tbStats.tbler);
995  NS_LOG_DEBUG(this << "RNTI " << (*itTb).first.m_rnti << " size " << (*itTb).second.size
996  << " mcs " << (uint32_t)(*itTb).second.mcs << " bitmap "
997  << (*itTb).second.rbBitmap.size() << " layer "
998  << (uint16_t)(*itTb).first.m_layer << " TBLER " << tbStats.tbler
999  << " corrupted " << (*itTb).second.corrupt);
1000  // fire traces on DL/UL reception PHY stats
1002  params.m_timestamp = Simulator::Now().GetMilliSeconds();
1003  params.m_cellId = m_cellId;
1004  params.m_imsi = 0; // it will be set by DlPhyTransmissionCallback in LteHelper
1005  params.m_rnti = (*itTb).first.m_rnti;
1006  params.m_txMode = m_transmissionMode;
1007  params.m_layer = (*itTb).first.m_layer;
1008  params.m_mcs = (*itTb).second.mcs;
1009  params.m_size = (*itTb).second.size;
1010  params.m_rv = (*itTb).second.rv;
1011  params.m_ndi = (*itTb).second.ndi;
1012  params.m_correctness = (uint8_t) !(*itTb).second.corrupt;
1013  params.m_ccId = m_componentCarrierId;
1014  if ((*itTb).second.downlink)
1015  {
1016  // DL
1018  }
1019  else
1020  {
1021  // UL
1022  params.m_rv = harqInfoList.size();
1024  }
1025  }
1026 
1027  itTb++;
1028  }
1029  std::map<uint16_t, DlInfoListElement_s> harqDlInfoMap;
1030  for (auto i = m_rxPacketBurstList.begin(); i != m_rxPacketBurstList.end(); ++i)
1031  {
1032  for (auto j = (*i)->Begin(); j != (*i)->End(); ++j)
1033  {
1034  // retrieve TB info of this packet
1035  LteRadioBearerTag tag;
1036  (*j)->PeekPacketTag(tag);
1037  TbId_t tbId;
1038  tbId.m_rnti = tag.GetRnti();
1039  tbId.m_layer = tag.GetLayer();
1040  itTb = m_expectedTbs.find(tbId);
1041  NS_LOG_INFO(this << " Packet of " << tbId.m_rnti << " layer "
1042  << (uint16_t)tag.GetLayer());
1043  if (itTb != m_expectedTbs.end())
1044  {
1045  if (!(*itTb).second.corrupt)
1046  {
1047  m_phyRxEndOkTrace(*j);
1048 
1050  {
1052  }
1053  }
1054  else
1055  {
1056  // TB received with errors
1058  }
1059 
1060  // send HARQ feedback (if not already done for this TB)
1061  if (!(*itTb).second.harqFeedbackSent)
1062  {
1063  (*itTb).second.harqFeedbackSent = true;
1064  if (!(*itTb).second.downlink)
1065  {
1066  UlInfoListElement_s harqUlInfo;
1067  harqUlInfo.m_rnti = tbId.m_rnti;
1068  harqUlInfo.m_tpc = 0;
1069  if ((*itTb).second.corrupt)
1070  {
1071  harqUlInfo.m_receptionStatus = UlInfoListElement_s::NotOk;
1072  NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " send UL-HARQ-NACK");
1073  m_harqPhyModule->UpdateUlHarqProcessStatus(
1074  tbId.m_rnti,
1075  (*itTb).second.mi,
1076  (*itTb).second.size,
1077  (*itTb).second.size / EffectiveCodingRate[(*itTb).second.mcs]);
1078  }
1079  else
1080  {
1081  harqUlInfo.m_receptionStatus = UlInfoListElement_s::Ok;
1082  NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " send UL-HARQ-ACK");
1083  m_harqPhyModule->ResetUlHarqProcessStatus(tbId.m_rnti,
1084  (*itTb).second.harqProcessId);
1085  }
1087  {
1088  m_ltePhyUlHarqFeedbackCallback(harqUlInfo);
1089  }
1090  }
1091  else
1092  {
1093  auto itHarq = harqDlInfoMap.find(tbId.m_rnti);
1094  if (itHarq == harqDlInfoMap.end())
1095  {
1096  DlInfoListElement_s harqDlInfo;
1098  harqDlInfo.m_rnti = tbId.m_rnti;
1099  harqDlInfo.m_harqProcessId = (*itTb).second.harqProcessId;
1100  if ((*itTb).second.corrupt)
1101  {
1102  harqDlInfo.m_harqStatus.at(tbId.m_layer) =
1104  NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
1105  << (uint16_t)(*itTb).second.harqProcessId
1106  << " layer " << (uint16_t)tbId.m_layer
1107  << " send DL-HARQ-NACK");
1108  m_harqPhyModule->UpdateDlHarqProcessStatus(
1109  (*itTb).second.harqProcessId,
1110  tbId.m_layer,
1111  (*itTb).second.mi,
1112  (*itTb).second.size,
1113  (*itTb).second.size / EffectiveCodingRate[(*itTb).second.mcs]);
1114  }
1115  else
1116  {
1117  harqDlInfo.m_harqStatus.at(tbId.m_layer) = DlInfoListElement_s::ACK;
1118  NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
1119  << (uint16_t)(*itTb).second.harqProcessId
1120  << " layer " << (uint16_t)tbId.m_layer << " size "
1121  << (*itTb).second.size << " send DL-HARQ-ACK");
1122  m_harqPhyModule->ResetDlHarqProcessStatus(
1123  (*itTb).second.harqProcessId);
1124  }
1125  harqDlInfoMap.insert(
1126  std::pair<uint16_t, DlInfoListElement_s>(tbId.m_rnti, harqDlInfo));
1127  }
1128  else
1129  {
1130  if ((*itTb).second.corrupt)
1131  {
1132  (*itHarq).second.m_harqStatus.at(tbId.m_layer) =
1134  NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
1135  << (uint16_t)(*itTb).second.harqProcessId
1136  << " layer " << (uint16_t)tbId.m_layer << " size "
1137  << (*itHarq).second.m_harqStatus.size()
1138  << " send DL-HARQ-NACK");
1139  m_harqPhyModule->UpdateDlHarqProcessStatus(
1140  (*itTb).second.harqProcessId,
1141  tbId.m_layer,
1142  (*itTb).second.mi,
1143  (*itTb).second.size,
1144  (*itTb).second.size / EffectiveCodingRate[(*itTb).second.mcs]);
1145  }
1146  else
1147  {
1148  NS_ASSERT_MSG(tbId.m_layer < (*itHarq).second.m_harqStatus.size(),
1149  " layer " << (uint16_t)tbId.m_layer);
1150  (*itHarq).second.m_harqStatus.at(tbId.m_layer) =
1152  NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
1153  << (uint16_t)(*itTb).second.harqProcessId
1154  << " layer " << (uint16_t)tbId.m_layer << " size "
1155  << (*itHarq).second.m_harqStatus.size()
1156  << " send DL-HARQ-ACK");
1157  m_harqPhyModule->ResetDlHarqProcessStatus(
1158  (*itTb).second.harqProcessId);
1159  }
1160  }
1161  } // end if ((*itTb).second.downlink) HARQ
1162  } // end if (!(*itTb).second.harqFeedbackSent)
1163  }
1164  }
1165  }
1166 
1167  // send DL HARQ feedback to LtePhy
1168  for (auto itHarq = harqDlInfoMap.begin(); itHarq != harqDlInfoMap.end(); itHarq++)
1169  {
1171  {
1172  m_ltePhyDlHarqFeedbackCallback((*itHarq).second);
1173  }
1174  }
1175  // forward control messages of this frame to LtePhy
1176  if (!m_rxControlMessageList.empty())
1177  {
1179  {
1181  }
1182  }
1183  ChangeState(IDLE);
1184  m_rxPacketBurstList.clear();
1185  m_rxControlMessageList.clear();
1186  m_expectedTbs.clear();
1187 }
1188 
1189 void
1191 {
1192  NS_LOG_FUNCTION(this);
1193  NS_LOG_LOGIC(this << " state: " << m_state);
1194 
1196 
1197  // this will trigger CQI calculation and Error Model evaluation
1198  // as a side effect, the error model should update the error status of all TBs
1199  m_interferenceCtrl->EndRx();
1200  // apply transmission mode gain
1201  NS_LOG_DEBUG(this << " txMode " << (uint16_t)m_transmissionMode << " gain "
1204  if (m_transmissionMode > 0)
1205  {
1206  // in case of MIMO, ctrl is always txed as TX diversity
1207  m_sinrPerceived *= m_txModeGain.at(1);
1208  }
1209  // m_sinrPerceived *= m_txModeGain.at (m_transmissionMode);
1210  bool error = false;
1212  {
1214  error = !(m_random->GetValue() > errorRate);
1215  NS_LOG_DEBUG(this << " PCFICH-PDCCH Decodification, errorRate " << errorRate << " error "
1216  << error);
1217  }
1218 
1219  if (!error)
1220  {
1222  {
1223  NS_LOG_DEBUG(this << " PCFICH-PDCCH Rxed OK");
1225  }
1226  }
1227  else
1228  {
1230  {
1231  NS_LOG_DEBUG(this << " PCFICH-PDCCH Error");
1233  }
1234  }
1235  ChangeState(IDLE);
1236  m_rxControlMessageList.clear();
1237 }
1238 
1239 void
1241 {
1243  ChangeState(IDLE);
1244  m_interferenceCtrl->EndRx();
1245  // nothing to do (used only for SRS at this stage)
1246 }
1247 
1248 void
1250 {
1251  m_cellId = cellId;
1252 }
1253 
1254 void
1255 LteSpectrumPhy::SetComponentCarrierId(uint8_t componentCarrierId)
1256 {
1257  m_componentCarrierId = componentCarrierId;
1258 }
1259 
1260 void
1262 {
1263  m_interferenceCtrl->AddRsPowerChunkProcessor(p);
1264 }
1265 
1266 void
1268 {
1269  m_interferenceData->AddRsPowerChunkProcessor(p);
1270 }
1271 
1272 void
1274 {
1275  m_interferenceData->AddSinrChunkProcessor(p);
1276 }
1277 
1278 void
1280 {
1281  m_interferenceCtrl->AddInterferenceChunkProcessor(p);
1282 }
1283 
1284 void
1286 {
1287  m_interferenceData->AddInterferenceChunkProcessor(p);
1288 }
1289 
1290 void
1292 {
1293  m_interferenceCtrl->AddSinrChunkProcessor(p);
1294 }
1295 
1296 void
1298 {
1299  NS_LOG_FUNCTION(this << (uint16_t)txMode);
1300  NS_ASSERT_MSG(txMode < m_txModeGain.size(),
1301  "TransmissionMode not available: 1.." << m_txModeGain.size());
1302  m_transmissionMode = txMode;
1304 }
1305 
1306 void
1307 LteSpectrumPhy::SetTxModeGain(uint8_t txMode, double gain)
1308 {
1309  NS_LOG_FUNCTION(this << " txmode " << (uint16_t)txMode << " gain " << gain);
1310  if (txMode > 0)
1311  {
1312  // convert to linear
1313  double gainLin = std::pow(10.0, (gain / 10.0));
1314  if (m_txModeGain.size() < txMode)
1315  {
1316  m_txModeGain.resize(txMode);
1317  }
1318  m_txModeGain.at(txMode - 1) = gainLin;
1319  }
1320 }
1321 
1322 int64_t
1324 {
1325  NS_LOG_FUNCTION(this << stream);
1326  m_random->SetStream(stream);
1327  return 1;
1328 }
1329 
1330 } // namespace ns3
bool IsNull() const
Check for null implementation.
Definition: callback.h:569
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 transmitted.
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:204
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:352
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
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:571
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
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:408
@ 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:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
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
#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:1362
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.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
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
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
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:159
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.
@ IDLE
Channel is IDLE, no packet is being transmitted.
Definition: csma-channel.h:76
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< HarqStatus_e > m_harqStatus
HARQ status.
PhyReceptionStatParameters structure.
Definition: lte-common.h:212
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