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"
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
43namespace ns3
44{
45
46NS_LOG_COMPONENT_DEFINE("LteSpectrumPhy");
47
50static const Time UL_SRS_DURATION = NanoSeconds(71429 - 1);
51
54static const Time DL_CTRL_DURATION = NanoSeconds(214286 - 1);
55
57static 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
66TbId_t::TbId_t(const uint16_t a, const uint8_t b)
67 : m_rnti(a),
68 m_layer(b)
69{
70}
71
79bool
80operator==(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
92bool
93operator<(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
127void
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
155std::ostream&
156operator<<(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
185TypeId
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
249void
251{
252 NS_LOG_FUNCTION(this << d);
253 m_device = d;
254}
255
256void
258{
259 NS_LOG_FUNCTION(this << m);
260 m_mobility = m;
261}
262
263void
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
282void
284{
285 NS_LOG_FUNCTION(this << txPsd);
286 NS_ASSERT(txPsd);
287 m_txPsd = txPsd;
288}
289
290void
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
300void
302{
303 NS_LOG_FUNCTION(this);
304 m_cellId = 0;
305 m_state = IDLE;
307 m_layersNum = 1;
313 m_expectedTbs.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
327void
329{
330 NS_LOG_FUNCTION(this);
332}
333
334void
336{
337 NS_LOG_FUNCTION(this);
339}
340
341void
343{
344 NS_LOG_FUNCTION(this);
346}
347
348void
350{
351 NS_LOG_FUNCTION(this);
353}
354
355void
357{
358 NS_LOG_FUNCTION(this);
360}
361
362void
364{
365 NS_LOG_FUNCTION(this);
367}
368
369void
371{
372 NS_LOG_FUNCTION(this);
374}
375
378{
379 return m_antenna;
380}
381
382void
384{
385 NS_LOG_FUNCTION(this << a);
386 m_antenna = a;
387}
388
389void
391{
392 ChangeState(newState);
393}
394
395void
397{
398 NS_LOG_LOGIC(this << " state: " << m_state << " -> " << newState);
399 m_state = newState;
400}
401
402void
404{
405 m_harqPhyModule = harq;
406}
407
408bool
411 Time duration)
412{
413 NS_LOG_FUNCTION(this << pb);
414 NS_LOG_LOGIC(this << " state: " << m_state);
415
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
470bool
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
528bool
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
584void
586{
587 NS_LOG_FUNCTION(this);
588 NS_LOG_LOGIC(this << " state: " << m_state);
589
592 m_txPacketBurst = nullptr;
594}
595
596void
598{
599 NS_LOG_FUNCTION(this);
600 NS_LOG_LOGIC(this << " state: " << m_state);
601
605}
606
607void
609{
610 NS_LOG_FUNCTION(this);
611 NS_LOG_LOGIC(this << " state: " << m_state);
612
616}
617
618void
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
658void
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 {
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
740void
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
824void
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
898void
900{
901 NS_LOG_FUNCTION(this << sinr);
902 m_sinrPerceived = sinr;
903}
904
905void
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
934void
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
953void
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;
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
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 {
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 {
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 }
1198 m_rxPacketBurstList.clear();
1199 m_rxControlMessageList.clear();
1200 m_expectedTbs.clear();
1201}
1202
1203void
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
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 }
1250 m_rxControlMessageList.clear();
1251}
1252
1253void
1255{
1258 m_interferenceCtrl->EndRx();
1259 // nothing to do (used only for SRS at this stage)
1260}
1261
1262void
1264{
1265 m_cellId = cellId;
1266}
1267
1268void
1269LteSpectrumPhy::SetComponentCarrierId(uint8_t componentCarrierId)
1270{
1271 m_componentCarrierId = componentCarrierId;
1272}
1273
1274void
1276{
1277 m_interferenceCtrl->AddRsPowerChunkProcessor(p);
1278}
1279
1280void
1282{
1283 m_interferenceData->AddRsPowerChunkProcessor(p);
1284}
1285
1286void
1288{
1289 m_interferenceData->AddSinrChunkProcessor(p);
1290}
1291
1292void
1294{
1295 m_interferenceCtrl->AddInterferenceChunkProcessor(p);
1296}
1297
1298void
1300{
1301 m_interferenceData->AddInterferenceChunkProcessor(p);
1302}
1303
1304void
1306{
1307 m_interferenceCtrl->AddSinrChunkProcessor(p);
1308}
1309
1310void
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
1320void
1321LteSpectrumPhy::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
1336int64_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
bool StartTxDataFrame(Ptr< PacketBurst > pb, std::list< Ptr< LteControlMessage > > ctrlMsgList, Time duration)
Start a transmission of data frame in DL and UL.
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
bool StartTxDlCtrlFrame(std::list< Ptr< LteControlMessage > > ctrlMsgList, bool pss)
Start a transmission of control frame in DL.
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
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.
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:59
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)
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
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:129
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...
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< 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