A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
lte-spectrum-phy.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009, 2011 CTTC
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Nicola Baldo <nbaldo@cttc.es>
7 * Giuseppe Piro <g.piro@poliba.it>
8 * Marco Miozzo <marco.miozzo@cttc.es> (add physical error model)
9 */
10
11#include "lte-spectrum-phy.h"
12
13#include "lte-chunk-processor.h"
15#include "lte-mi-error-model.h"
18
19#include "ns3/antenna-model.h"
20#include "ns3/boolean.h"
21#include "ns3/config.h"
22#include "ns3/double.h"
23#include "ns3/log.h"
24#include "ns3/object-factory.h"
25#include "ns3/simulator.h"
26#include "ns3/trace-source-accessor.h"
27
28#include <cmath>
29
30namespace ns3
31{
32
33NS_LOG_COMPONENT_DEFINE("LteSpectrumPhy");
34
35/// duration of SRS portion of UL subframe
36/// = 1 symbol for SRS -1ns as margin to avoid overlapping simulator events
37static const Time UL_SRS_DURATION = NanoSeconds(71429 - 1);
38
39/// duration of the control portion of a subframe
40/// = 0.001 / 14 * 3 (ctrl fixed to 3 symbols) -1ns as margin to avoid overlapping simulator events
41static const Time DL_CTRL_DURATION = NanoSeconds(214286 - 1);
42
43/// Effective coding rate
44static const double EffectiveCodingRate[29] = {
45 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,
46 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,
47};
48
52
53TbId_t::TbId_t(const uint16_t a, const uint8_t b)
54 : m_rnti(a),
55 m_layer(b)
56{
57}
58
59/**
60 * Equality operator
61 *
62 * @param a lhs
63 * @param b rhs
64 * @returns true if rnti and layer are equal
65 */
66bool
67operator==(const TbId_t& a, const TbId_t& b)
68{
69 return ((a.m_rnti == b.m_rnti) && (a.m_layer == b.m_layer));
70}
71
72/**
73 * Less than operator
74 *
75 * @param a lhs
76 * @param b rhs
77 * @returns true if rnti less than ro rnti equal and layer less than
78 */
79bool
80operator<(const TbId_t& a, const TbId_t& b)
81{
82 return ((a.m_rnti < b.m_rnti) || ((a.m_rnti == b.m_rnti) && (a.m_layer < b.m_layer)));
83}
84
86
88 : m_state(IDLE),
89 m_cellId(0),
93{
94 NS_LOG_FUNCTION(this);
96 m_random->SetAttribute("Min", DoubleValue(0.0));
97 m_random->SetAttribute("Max", DoubleValue(1.0));
100
101 for (uint8_t i = 0; i < 7; i++)
102 {
103 m_txModeGain.push_back(1.0);
104 }
105}
106
108{
109 NS_LOG_FUNCTION(this);
110 m_expectedTbs.clear();
111 m_txModeGain.clear();
112}
113
114void
134
135/**
136 * Output stream output operator
137 *
138 * @param os output stream
139 * @param s state
140 * @returns output stream
141 */
142std::ostream&
143operator<<(std::ostream& os, LteSpectrumPhy::State s)
144{
145 switch (s)
146 {
148 os << "IDLE";
149 break;
151 os << "RX_DATA";
152 break;
154 os << "RX_DL_CTRL";
155 break;
157 os << "RX_UL_SRS";
158 break;
160 os << "TX_DATA";
161 break;
163 os << "TX_DL_CTRL";
164 break;
166 os << "TX_UL_SRS";
167 break;
168 default:
169 os << "UNKNOWN";
170 break;
171 }
172 return os;
173}
174
175TypeId
177{
178 static TypeId tid =
179 TypeId("ns3::LteSpectrumPhy")
181 .SetGroupName("Lte")
182 .AddTraceSource("TxStart",
183 "Trace fired when a new transmission is started",
185 "ns3::PacketBurst::TracedCallback")
186 .AddTraceSource("TxEnd",
187 "Trace fired when a previously started transmission is finished",
189 "ns3::PacketBurst::TracedCallback")
190 .AddTraceSource("RxStart",
191 "Trace fired when the start of a signal is detected",
193 "ns3::PacketBurst::TracedCallback")
194 .AddTraceSource("RxEndOk",
195 "Trace fired when a previously started RX terminates successfully",
197 "ns3::Packet::TracedCallback")
198 .AddTraceSource("RxEndError",
199 "Trace fired when a previously started RX terminates with an error",
201 "ns3::Packet::TracedCallback")
202 .AddAttribute("DataErrorModelEnabled",
203 "Activate/Deactivate the error model of data (TBs of PDSCH and PUSCH) "
204 "[by default is active].",
205 BooleanValue(true),
208 .AddAttribute("CtrlErrorModelEnabled",
209 "Activate/Deactivate the error model of control (PCFICH-PDCCH "
210 "decodification) [by default is active].",
211 BooleanValue(true),
214 .AddTraceSource("DlPhyReception",
215 "DL reception PHY layer statistics.",
217 "ns3::PhyReceptionStatParameters::TracedCallback")
218 .AddTraceSource("UlPhyReception",
219 "DL reception PHY layer statistics.",
221 "ns3::PhyReceptionStatParameters::TracedCallback");
222 return tid;
223}
224
227{
228 NS_LOG_FUNCTION(this);
229 return m_device;
230}
231
234{
235 NS_LOG_FUNCTION(this);
236 return m_mobility;
237}
238
239void
245
246void
252
253void
259
262{
263 return m_channel;
264}
265
271
272void
274{
275 NS_LOG_FUNCTION(this << txPsd);
276 NS_ASSERT(txPsd);
277 m_txPsd = txPsd;
278}
279
280void
282{
283 NS_LOG_FUNCTION(this << noisePsd);
284 NS_ASSERT(noisePsd);
285 m_rxSpectrumModel = noisePsd->GetSpectrumModel();
286 m_interferenceData->SetNoisePowerSpectralDensity(noisePsd);
287 m_interferenceCtrl->SetNoisePowerSpectralDensity(noisePsd);
288}
289
290void
292{
293 NS_LOG_FUNCTION(this);
294 m_cellId = 0;
295 m_state = IDLE;
297 m_layersNum = 1;
298 m_endTxEvent.Cancel();
299 m_endRxDataEvent.Cancel();
300 m_endRxDlCtrlEvent.Cancel();
301 m_endRxUlSrsEvent.Cancel();
303 m_expectedTbs.clear();
305 m_rxPacketBurstList.clear();
306 m_txPacketBurst = nullptr;
307 m_rxSpectrumModel = nullptr;
308
309 // Detach from the channel, because receiving any signal without
310 // spectrum model is an error.
311 if (m_channel)
312 {
313 m_channel->RemoveRx(this);
314 }
315}
316
317void
323
324void
330
331void
337
338void
344
345void
351
352void
358
359void
365
368{
369 return m_antenna;
370}
371
372void
378
379void
381{
382 ChangeState(newState);
383}
384
385void
387{
388 NS_LOG_LOGIC(this << " state: " << m_state << " -> " << newState);
389 m_state = newState;
390}
391
392void
397
398bool
400 std::list<Ptr<LteControlMessage>> ctrlMsgList,
401 Time duration)
402{
403 NS_LOG_FUNCTION(this << pb);
404 NS_LOG_LOGIC(this << " state: " << m_state);
405
407
408 switch (m_state)
409 {
410 case RX_DATA:
411 case RX_DL_CTRL:
412 case RX_UL_SRS:
413 NS_FATAL_ERROR("cannot TX while RX: according to FDD channel access, the physical layer "
414 "for transmission cannot be used for reception");
415 break;
416
417 case TX_DATA:
418 case TX_DL_CTRL:
419 case TX_UL_SRS:
420 NS_FATAL_ERROR("cannot TX while already TX: the MAC should avoid this");
421 break;
422
423 case IDLE: {
424 /*
425 m_txPsd must be set by the device, according to
426 (i) the available subchannel for transmission
427 (ii) the power transmission
428 */
430 m_txPacketBurst = pb;
431
432 // we need to convey some PHY meta information to the receiver
433 // to be used for simulation purposes (e.g., the CellId). This
434 // is done by setting the ctrlMsgList parameter of
435 // LteSpectrumSignalParametersDataFrame
440 txParams->duration = duration;
441 txParams->txPhy = GetObject<SpectrumPhy>();
442 txParams->txAntenna = m_antenna;
443 txParams->psd = m_txPsd;
444 txParams->packetBurst = pb;
445 txParams->ctrlMsgList = ctrlMsgList;
446 txParams->cellId = m_cellId;
447 m_channel->StartTx(txParams);
449 }
450 return false;
451
452 default:
453 NS_FATAL_ERROR("unknown state");
454 return true;
455 }
456}
457
458bool
460{
461 NS_LOG_FUNCTION(this << " PSS " << (uint16_t)pss);
462 NS_LOG_LOGIC(this << " state: " << m_state);
463
464 switch (m_state)
465 {
466 case RX_DATA:
467 case RX_DL_CTRL:
468 case RX_UL_SRS:
469 NS_FATAL_ERROR("cannot TX while RX: according to FDD channel access, the physical layer "
470 "for transmission cannot be used for reception");
471 break;
472
473 case TX_DATA:
474 case TX_DL_CTRL:
475 case TX_UL_SRS:
476 NS_FATAL_ERROR("cannot TX while already TX: the MAC should avoid this");
477 break;
478
479 case IDLE: {
480 /*
481 m_txPsd must be set by the device, according to
482 (i) the available subchannel for transmission
483 (ii) the power transmission
484 */
486
487 // we need to convey some PHY meta information to the receiver
488 // to be used for simulation purposes (e.g., the CellId). This
489 // is done by setting the cellId parameter of
490 // LteSpectrumSignalParametersDlCtrlFrame
493
496 txParams->duration = DL_CTRL_DURATION;
497 txParams->txPhy = GetObject<SpectrumPhy>();
498 txParams->txAntenna = m_antenna;
499 txParams->psd = m_txPsd;
500 txParams->cellId = m_cellId;
501 txParams->pss = pss;
502 txParams->ctrlMsgList = ctrlMsgList;
503 m_channel->StartTx(txParams);
505 }
506 return false;
507
508 default:
509 NS_FATAL_ERROR("unknown state");
510 return true;
511 }
512}
513
514bool
516{
517 NS_LOG_FUNCTION(this);
518 NS_LOG_LOGIC(this << " state: " << m_state);
519
520 switch (m_state)
521 {
522 case RX_DATA:
523 case RX_DL_CTRL:
524 case RX_UL_SRS:
525 NS_FATAL_ERROR("cannot TX while RX: according to FDD channel access, the physical layer "
526 "for transmission cannot be used for reception");
527 break;
528
529 case TX_DL_CTRL:
530 case TX_DATA:
531 case TX_UL_SRS:
532 NS_FATAL_ERROR("cannot TX while already TX: the MAC should avoid this");
533 break;
534
535 case IDLE: {
536 /*
537 m_txPsd must be set by the device, according to
538 (i) the available subchannel for transmission
539 (ii) the power transmission
540 */
542 NS_LOG_LOGIC(this << " m_txPsd: " << *m_txPsd);
543
544 // we need to convey some PHY meta information to the receiver
545 // to be used for simulation purposes (e.g., the CellId). This
546 // is done by setting the cellId parameter of
547 // LteSpectrumSignalParametersDlCtrlFrame
552 txParams->duration = UL_SRS_DURATION;
553 txParams->txPhy = GetObject<SpectrumPhy>();
554 txParams->txAntenna = m_antenna;
555 txParams->psd = m_txPsd;
556 txParams->cellId = m_cellId;
557 m_channel->StartTx(txParams);
559 }
560 return false;
561
562 default:
563 NS_FATAL_ERROR("unknown state");
564 return true;
565 }
566}
567
568void
570{
571 NS_LOG_FUNCTION(this);
572 NS_LOG_LOGIC(this << " state: " << m_state);
573
576 m_txPacketBurst = nullptr;
578}
579
580void
582{
583 NS_LOG_FUNCTION(this);
584 NS_LOG_LOGIC(this << " state: " << m_state);
585
589}
590
591void
593{
594 NS_LOG_FUNCTION(this);
595 NS_LOG_LOGIC(this << " state: " << m_state);
596
600}
601
602void
604{
605 NS_LOG_FUNCTION(this << spectrumRxParams);
606 NS_LOG_LOGIC(this << " state: " << m_state);
607
608 Ptr<const SpectrumValue> rxPsd = spectrumRxParams->psd;
609 Time duration = spectrumRxParams->duration;
610
611 // the device might start RX only if the signal is of a type
612 // understood by this device - in this case, an LTE signal.
619 if (lteDataRxParams)
620 {
621 m_interferenceData->AddSignal(rxPsd, duration);
622 StartRxData(lteDataRxParams);
623 }
624 else if (lteDlCtrlRxParams)
625 {
626 m_interferenceCtrl->AddSignal(rxPsd, duration);
627 StartRxDlCtrl(lteDlCtrlRxParams);
628 }
629 else if (lteUlSrsRxParams)
630 {
631 m_interferenceCtrl->AddSignal(rxPsd, duration);
632 StartRxUlSrs(lteUlSrsRxParams);
633 }
634 else
635 {
636 // other type of signal (could be 3G, GSM, whatever) -> interference
637 m_interferenceData->AddSignal(rxPsd, duration);
638 m_interferenceCtrl->AddSignal(rxPsd, duration);
639 }
640}
641
642void
644{
645 NS_LOG_FUNCTION(this);
646 switch (m_state)
647 {
648 case TX_DATA:
649 case TX_DL_CTRL:
650 case TX_UL_SRS:
651 NS_FATAL_ERROR("cannot RX while TX: according to FDD channel access, the physical layer "
652 "for transmission cannot be used for reception");
653 break;
654 case RX_DL_CTRL:
655 NS_FATAL_ERROR("cannot RX Data while receiving control");
656 break;
657 case IDLE:
658 case RX_DATA:
659 // the behavior is similar when
660 // we're IDLE or RX because we can receive more signals
661 // simultaneously (e.g., at the eNB).
662 {
663 // To check if we're synchronized to this signal, we check
664 // for the CellId which is reported in the
665 // LteSpectrumSignalParametersDataFrame
666 if (params->cellId == m_cellId)
667 {
668 NS_LOG_LOGIC(this << " synchronized with this signal (cellId=" << params->cellId
669 << ")");
670 if ((m_rxPacketBurstList.empty()) && (m_rxControlMessageList.empty()))
671 {
673 // first transmission, i.e., we're IDLE and we
674 // start RX
676 m_firstRxDuration = params->duration;
677 NS_LOG_LOGIC(this << " scheduling EndRx with delay "
678 << params->duration.As(Time::S));
680 Simulator::Schedule(params->duration, &LteSpectrumPhy::EndRxData, this);
681 }
682 else
683 {
685 // sanity check: if there are multiple RX events, they
686 // should occur at the same time and have the same
687 // duration, otherwise the interference calculation
688 // won't be correct
690 (m_firstRxDuration == params->duration));
691 }
692
694 if (params->packetBurst)
695 {
696 m_rxPacketBurstList.push_back(params->packetBurst);
697 m_interferenceData->StartRx(params->psd);
698
699 m_phyRxStartTrace(params->packetBurst);
700 }
701 NS_LOG_DEBUG(this << " insert msgs " << params->ctrlMsgList.size());
703 params->ctrlMsgList.begin(),
704 params->ctrlMsgList.end());
705
706 NS_LOG_LOGIC(this << " numSimultaneousRxEvents = " << m_rxPacketBurstList.size());
707 }
708 else
709 {
710 NS_LOG_LOGIC(this << " not in sync with this signal (cellId=" << params->cellId
711 << ", m_cellId=" << m_cellId << ")");
712 }
713 }
714 break;
715
716 default:
717 NS_FATAL_ERROR("unknown state");
718 break;
719 }
720
721 NS_LOG_LOGIC(this << " state: " << m_state);
722}
723
724void
726{
727 NS_LOG_FUNCTION(this);
728
729 // To check if we're synchronized to this signal, we check
730 // for the CellId which is reported in the
731 // LteSpectrumSignalParametersDlCtrlFrame
732 uint16_t cellId;
733 NS_ASSERT(lteDlCtrlRxParams);
734 cellId = lteDlCtrlRxParams->cellId;
735
736 switch (m_state)
737 {
738 case TX_DATA:
739 case TX_DL_CTRL:
740 case TX_UL_SRS:
741 case RX_DATA:
742 case RX_UL_SRS:
743 NS_FATAL_ERROR("unexpected event in state " << m_state);
744 break;
745
746 case RX_DL_CTRL:
747 case IDLE:
748
749 // common code for the two states
750 // check presence of PSS for UE measuerements
751 if (lteDlCtrlRxParams->pss)
752 {
753 if (!m_ltePhyRxPssCallback.IsNull())
754 {
755 m_ltePhyRxPssCallback(cellId, lteDlCtrlRxParams->psd);
756 }
757 }
758
759 // differentiated code for the two states
760 switch (m_state)
761 {
762 case RX_DL_CTRL:
763 NS_ASSERT_MSG(m_cellId != cellId, "any other DlCtrl should be from a different cell");
764 NS_LOG_LOGIC(this << " ignoring other DlCtrl (cellId=" << cellId
765 << ", m_cellId=" << m_cellId << ")");
766 break;
767
768 case IDLE:
769 if (cellId == m_cellId)
770 {
771 NS_LOG_LOGIC(this << " synchronized with this signal (cellId=" << cellId << ")");
772
775 m_firstRxDuration = lteDlCtrlRxParams->duration;
776 NS_LOG_LOGIC(this << " scheduling EndRx with delay "
777 << lteDlCtrlRxParams->duration);
778
779 // store the DCIs
780 m_rxControlMessageList = lteDlCtrlRxParams->ctrlMsgList;
781 m_endRxDlCtrlEvent = Simulator::Schedule(lteDlCtrlRxParams->duration,
783 this);
785 m_interferenceCtrl->StartRx(lteDlCtrlRxParams->psd);
786 }
787 else
788 {
789 NS_LOG_LOGIC(this << " not synchronizing with this signal (cellId=" << cellId
790 << ", m_cellId=" << m_cellId << ")");
791 }
792 break;
793
794 default:
795 NS_FATAL_ERROR("unexpected event in state " << m_state);
796 break;
797 }
798 break; // case RX_DL_CTRL or IDLE
799
800 default:
801 NS_FATAL_ERROR("unknown state");
802 break;
803 }
804
805 NS_LOG_LOGIC(this << " state: " << m_state);
806}
807
808void
810{
811 NS_LOG_FUNCTION(this);
812 switch (m_state)
813 {
814 case TX_DATA:
815 case TX_DL_CTRL:
816 case TX_UL_SRS:
817 NS_FATAL_ERROR("cannot RX while TX: according to FDD channel access, the physical layer "
818 "for transmission cannot be used for reception");
819 break;
820
821 case RX_DATA:
822 case RX_DL_CTRL:
823 NS_FATAL_ERROR("cannot RX SRS while receiving something else");
824 break;
825
826 case IDLE:
827 case RX_UL_SRS:
828 // the behavior is similar when
829 // we're IDLE or RX_UL_SRS because we can receive more signals
830 // simultaneously at the eNB
831 {
832 // To check if we're synchronized to this signal, we check
833 // for the CellId which is reported in the
834 // LteSpectrumSignalParametersDlCtrlFrame
835 uint16_t cellId;
836 cellId = lteUlSrsRxParams->cellId;
837 if (cellId == m_cellId)
838 {
839 NS_LOG_LOGIC(this << " synchronized with this signal (cellId=" << cellId << ")");
840 if (m_state == IDLE)
841 {
842 // first transmission, i.e., we're IDLE and we
843 // start RX
846 m_firstRxDuration = lteUlSrsRxParams->duration;
847 NS_LOG_LOGIC(this << " scheduling EndRx with delay "
848 << lteUlSrsRxParams->duration);
849
850 m_endRxUlSrsEvent = Simulator::Schedule(lteUlSrsRxParams->duration,
852 this);
853 }
854 else if (m_state == RX_UL_SRS)
855 {
856 // sanity check: if there are multiple RX events, they
857 // should occur at the same time and have the same
858 // duration, otherwise the interference calculation
859 // won't be correct
861 (m_firstRxDuration == lteUlSrsRxParams->duration));
862 }
864 m_interferenceCtrl->StartRx(lteUlSrsRxParams->psd);
865 }
866 else
867 {
868 NS_LOG_LOGIC(this << " not in sync with this signal (cellId=" << cellId
869 << ", m_cellId=" << m_cellId << ")");
870 }
871 }
872 break;
873
874 default:
875 NS_FATAL_ERROR("unknown state");
876 break;
877 }
878
879 NS_LOG_LOGIC(this << " state: " << m_state);
880}
881
882void
884{
885 NS_LOG_FUNCTION(this << sinr);
886 m_sinrPerceived = sinr;
887}
888
889void
891 uint8_t ndi,
892 uint16_t size,
893 uint8_t mcs,
894 std::vector<int> map,
895 uint8_t layer,
896 uint8_t harqId,
897 uint8_t rv,
898 bool downlink)
899{
900 NS_LOG_FUNCTION(this << " rnti: " << rnti << " NDI " << (uint16_t)ndi << " size " << size
901 << " mcs " << (uint16_t)mcs << " layer " << (uint16_t)layer << " rv "
902 << (uint16_t)rv);
903 TbId_t tbId;
904 tbId.m_rnti = rnti;
905 tbId.m_layer = layer;
906 auto it = m_expectedTbs.find(tbId);
907 if (it != m_expectedTbs.end())
908 {
909 // might be a TB of an unreceived packet (due to high propagation losses)
910 m_expectedTbs.erase(it);
911 }
912 // insert new entry
913 tbInfo_t tbInfo = {ndi, size, mcs, map, harqId, rv, 0.0, downlink, false, false};
914 m_expectedTbs.insert(std::pair<TbId_t, tbInfo_t>(tbId, tbInfo));
915}
916
917void
919{
920 NS_LOG_FUNCTION(this << rnti);
921 TbId_t tbId;
922 tbId.m_rnti = rnti;
923 // Remove TB of both the layers
924 for (uint8_t i = 0; i < 2; i++)
925 {
926 tbId.m_layer = i;
927 auto it = m_expectedTbs.find(tbId);
928 if (it != m_expectedTbs.end())
929 {
930 m_expectedTbs.erase(it);
931 }
932 }
933}
934
935void
937{
938 NS_LOG_FUNCTION(this);
939 NS_LOG_LOGIC(this << " state: " << m_state);
940
942
943 // this will trigger CQI calculation and Error Model evaluation
944 // as a side effect, the error model should update the error status of all TBs
945 m_interferenceData->EndRx();
946 NS_LOG_DEBUG(this << " No. of burts " << m_rxPacketBurstList.size());
947 NS_LOG_DEBUG(this << " Expected TBs " << m_expectedTbs.size());
948 auto itTb = m_expectedTbs.begin();
949
950 // apply transmission mode gain
951 NS_LOG_DEBUG(this << " txMode " << (uint16_t)m_transmissionMode << " gain "
955
956 while (itTb != m_expectedTbs.end())
957 {
960 .empty()) // avoid to check for errors when there is no actual data transmitted
961 {
962 // retrieve HARQ info
963 HarqProcessInfoList_t harqInfoList;
964 if ((*itTb).second.ndi == 0)
965 {
966 // TB retxed: retrieve HARQ history
967 uint16_t ulHarqId = 0;
968 if ((*itTb).second.downlink)
969 {
970 harqInfoList =
971 m_harqPhyModule->GetHarqProcessInfoDl((*itTb).second.harqProcessId,
972 (*itTb).first.m_layer);
973 }
974 else
975 {
976 harqInfoList =
977 m_harqPhyModule->GetHarqProcessInfoUl((*itTb).first.m_rnti, ulHarqId);
978 }
979 }
981 (*itTb).second.rbBitmap,
982 (*itTb).second.size,
983 (*itTb).second.mcs,
984 harqInfoList);
985 (*itTb).second.mi = tbStats.mi;
986 (*itTb).second.corrupt = !(m_random->GetValue() > tbStats.tbler);
987 NS_LOG_DEBUG(this << "RNTI " << (*itTb).first.m_rnti << " size " << (*itTb).second.size
988 << " mcs " << (uint32_t)(*itTb).second.mcs << " bitmap "
989 << (*itTb).second.rbBitmap.size() << " layer "
990 << (uint16_t)(*itTb).first.m_layer << " TBLER " << tbStats.tbler
991 << " corrupted " << (*itTb).second.corrupt);
992 // fire traces on DL/UL reception PHY stats
994 params.m_timestamp = Simulator::Now().GetMilliSeconds();
995 params.m_cellId = m_cellId;
996 params.m_imsi = 0; // it will be set by DlPhyTransmissionCallback in LteHelper
997 params.m_rnti = (*itTb).first.m_rnti;
998 params.m_txMode = m_transmissionMode;
999 params.m_layer = (*itTb).first.m_layer;
1000 params.m_mcs = (*itTb).second.mcs;
1001 params.m_size = (*itTb).second.size;
1002 params.m_rv = (*itTb).second.rv;
1003 params.m_ndi = (*itTb).second.ndi;
1004 params.m_correctness = static_cast<uint8_t>(!(*itTb).second.corrupt);
1005 params.m_ccId = m_componentCarrierId;
1006 if ((*itTb).second.downlink)
1007 {
1008 // DL
1009 m_dlPhyReception(params);
1010 }
1011 else
1012 {
1013 // UL
1014 params.m_rv = harqInfoList.size();
1015 m_ulPhyReception(params);
1016 }
1017 }
1018
1019 itTb++;
1020 }
1021 std::map<uint16_t, DlInfoListElement_s> harqDlInfoMap;
1022 for (auto i = m_rxPacketBurstList.begin(); i != m_rxPacketBurstList.end(); ++i)
1023 {
1024 for (auto j = (*i)->Begin(); j != (*i)->End(); ++j)
1025 {
1026 // retrieve TB info of this packet
1028 (*j)->PeekPacketTag(tag);
1029 TbId_t tbId;
1030 tbId.m_rnti = tag.GetRnti();
1031 tbId.m_layer = tag.GetLayer();
1032 itTb = m_expectedTbs.find(tbId);
1033 NS_LOG_INFO(this << " Packet of " << tbId.m_rnti << " layer "
1034 << (uint16_t)tag.GetLayer());
1035 if (itTb == m_expectedTbs.end())
1036 {
1037 continue;
1038 }
1039
1040 if (!(*itTb).second.corrupt)
1041 {
1043
1044 if (!m_ltePhyRxDataEndOkCallback.IsNull())
1045 {
1047 }
1048 }
1049 else
1050 {
1051 // TB received with errors
1053 }
1054
1055 // send HARQ feedback (if not already done for this TB)
1056 if ((*itTb).second.harqFeedbackSent)
1057 {
1058 continue;
1059 }
1060
1061 (*itTb).second.harqFeedbackSent = true;
1062 if (!(*itTb).second.downlink)
1063 {
1064 UlInfoListElement_s harqUlInfo;
1065 harqUlInfo.m_rnti = tbId.m_rnti;
1066 harqUlInfo.m_tpc = 0;
1067 if ((*itTb).second.corrupt)
1068 {
1069 harqUlInfo.m_receptionStatus = UlInfoListElement_s::NotOk;
1070 NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " send UL-HARQ-NACK");
1071 m_harqPhyModule->UpdateUlHarqProcessStatus(
1072 tbId.m_rnti,
1073 (*itTb).second.mi,
1074 (*itTb).second.size,
1075 (*itTb).second.size / EffectiveCodingRate[(*itTb).second.mcs]);
1076 }
1077 else
1078 {
1079 harqUlInfo.m_receptionStatus = UlInfoListElement_s::Ok;
1080 NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " send UL-HARQ-ACK");
1081 m_harqPhyModule->ResetUlHarqProcessStatus(tbId.m_rnti,
1082 (*itTb).second.harqProcessId);
1083 }
1084 if (!m_ltePhyUlHarqFeedbackCallback.IsNull())
1085 {
1087 }
1088 }
1089 else
1090 {
1091 auto itHarq = harqDlInfoMap.find(tbId.m_rnti);
1092 if (itHarq == harqDlInfoMap.end())
1093 {
1094 DlInfoListElement_s harqDlInfo;
1096 harqDlInfo.m_rnti = tbId.m_rnti;
1097 harqDlInfo.m_harqProcessId = (*itTb).second.harqProcessId;
1098 if ((*itTb).second.corrupt)
1099 {
1100 harqDlInfo.m_harqStatus.at(tbId.m_layer) = DlInfoListElement_s::NACK;
1101 NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
1102 << (uint16_t)(*itTb).second.harqProcessId << " layer "
1103 << (uint16_t)tbId.m_layer << " send DL-HARQ-NACK");
1104 m_harqPhyModule->UpdateDlHarqProcessStatus(
1105 (*itTb).second.harqProcessId,
1106 tbId.m_layer,
1107 (*itTb).second.mi,
1108 (*itTb).second.size,
1109 (*itTb).second.size / EffectiveCodingRate[(*itTb).second.mcs]);
1110 }
1111 else
1112 {
1113 harqDlInfo.m_harqStatus.at(tbId.m_layer) = DlInfoListElement_s::ACK;
1114 NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
1115 << (uint16_t)(*itTb).second.harqProcessId << " layer "
1116 << (uint16_t)tbId.m_layer << " size "
1117 << (*itTb).second.size << " send DL-HARQ-ACK");
1118 m_harqPhyModule->ResetDlHarqProcessStatus((*itTb).second.harqProcessId);
1119 }
1120 harqDlInfoMap.insert(
1121 std::pair<uint16_t, DlInfoListElement_s>(tbId.m_rnti, harqDlInfo));
1122 }
1123 else
1124 {
1125 if ((*itTb).second.corrupt)
1126 {
1127 (*itHarq).second.m_harqStatus.at(tbId.m_layer) = DlInfoListElement_s::NACK;
1128 NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
1129 << (uint16_t)(*itTb).second.harqProcessId << " layer "
1130 << (uint16_t)tbId.m_layer << " size "
1131 << (*itHarq).second.m_harqStatus.size()
1132 << " send DL-HARQ-NACK");
1133 m_harqPhyModule->UpdateDlHarqProcessStatus(
1134 (*itTb).second.harqProcessId,
1135 tbId.m_layer,
1136 (*itTb).second.mi,
1137 (*itTb).second.size,
1138 (*itTb).second.size / EffectiveCodingRate[(*itTb).second.mcs]);
1139 }
1140 else
1141 {
1142 NS_ASSERT_MSG(tbId.m_layer < (*itHarq).second.m_harqStatus.size(),
1143 " layer " << (uint16_t)tbId.m_layer);
1144 (*itHarq).second.m_harqStatus.at(tbId.m_layer) = DlInfoListElement_s::ACK;
1145 NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
1146 << (uint16_t)(*itTb).second.harqProcessId << " layer "
1147 << (uint16_t)tbId.m_layer << " size "
1148 << (*itHarq).second.m_harqStatus.size()
1149 << " send DL-HARQ-ACK");
1150 m_harqPhyModule->ResetDlHarqProcessStatus((*itTb).second.harqProcessId);
1151 }
1152 }
1153 }
1154 }
1155 }
1156
1157 // send DL HARQ feedback to LtePhy
1158 for (auto itHarq = harqDlInfoMap.begin(); itHarq != harqDlInfoMap.end(); itHarq++)
1159 {
1160 if (!m_ltePhyDlHarqFeedbackCallback.IsNull())
1161 {
1162 m_ltePhyDlHarqFeedbackCallback((*itHarq).second);
1163 }
1164 }
1165 // forward control messages of this frame to LtePhy
1166 if (!m_rxControlMessageList.empty())
1167 {
1168 if (!m_ltePhyRxCtrlEndOkCallback.IsNull())
1169 {
1171 }
1172 }
1174 m_rxPacketBurstList.clear();
1175 m_rxControlMessageList.clear();
1176 m_expectedTbs.clear();
1177}
1178
1179void
1181{
1182 NS_LOG_FUNCTION(this);
1183 NS_LOG_LOGIC(this << " state: " << m_state);
1184
1186
1187 // this will trigger CQI calculation and Error Model evaluation
1188 // as a side effect, the error model should update the error status of all TBs
1189 m_interferenceCtrl->EndRx();
1190 // apply transmission mode gain
1191 NS_LOG_DEBUG(this << " txMode " << (uint16_t)m_transmissionMode << " gain "
1194 if (m_transmissionMode > 0)
1195 {
1196 // in case of MIMO, ctrl is always txed as TX diversity
1198 }
1199 // m_sinrPerceived *= m_txModeGain.at (m_transmissionMode);
1200 bool error = false;
1202 {
1204 error = !(m_random->GetValue() > errorRate);
1205 NS_LOG_DEBUG(this << " PCFICH-PDCCH Decodification, errorRate " << errorRate << " error "
1206 << error);
1207 }
1208
1209 if (!error)
1210 {
1211 if (!m_ltePhyRxCtrlEndOkCallback.IsNull())
1212 {
1213 NS_LOG_DEBUG(this << " PCFICH-PDCCH Rxed OK");
1215 }
1216 }
1217 else
1218 {
1219 if (!m_ltePhyRxCtrlEndErrorCallback.IsNull())
1220 {
1221 NS_LOG_DEBUG(this << " PCFICH-PDCCH Error");
1223 }
1224 }
1226 m_rxControlMessageList.clear();
1227}
1228
1229void
1231{
1234 m_interferenceCtrl->EndRx();
1235 // nothing to do (used only for SRS at this stage)
1236}
1237
1238void
1240{
1241 m_cellId = cellId;
1242}
1243
1244void
1245LteSpectrumPhy::SetComponentCarrierId(uint8_t componentCarrierId)
1246{
1247 m_componentCarrierId = componentCarrierId;
1248}
1249
1250void
1255
1256void
1261
1262void
1267
1268void
1273
1274void
1279
1280void
1285
1286void
1288{
1289 NS_LOG_FUNCTION(this << (uint16_t)txMode);
1290 NS_ASSERT_MSG(txMode < m_txModeGain.size(),
1291 "TransmissionMode not available: 1.." << m_txModeGain.size());
1292 m_transmissionMode = txMode;
1294}
1295
1296void
1297LteSpectrumPhy::SetTxModeGain(uint8_t txMode, double gain)
1298{
1299 NS_LOG_FUNCTION(this << " txmode " << (uint16_t)txMode << " gain " << gain);
1300 if (txMode > 0)
1301 {
1302 // convert to linear
1303 double gainLin = std::pow(10.0, (gain / 10.0));
1304 if (m_txModeGain.size() < txMode)
1305 {
1306 m_txModeGain.resize(txMode);
1307 }
1308 m_txModeGain.at(txMode - 1) = gainLin;
1309 }
1310}
1311
1312int64_t
1314{
1315 NS_LOG_FUNCTION(this << stream);
1316 m_random->SetStream(stream);
1317 return 1;
1318}
1319
1320} // namespace ns3
AttributeValue implementation for Boolean.
Definition boolean.h:26
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
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
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...
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.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:518
virtual void DoDispose()
Destructor implementation.
Definition object.cc:430
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:580
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:191
Set of values corresponding to a given SpectrumModel.
Simulation virtual time values and global simulation resolution.
Definition nstime.h:96
int64_t GetMilliSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:404
@ S
second
Definition nstime.h:107
static uint8_t TxMode2LayerNum(uint8_t txMode)
Transmit mode 2 layer number.
a unique identifier for an interface.
Definition type-id.h:49
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:999
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#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:75
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition boolean.cc:113
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:70
Callback< R, Args... > MakeNullCallback()
Build null Callbacks which take no arguments, for varying number of template arguments,...
Definition callback.h:734
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:194
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:260
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:274
#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:267
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:627
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:454
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1432
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.
Callback< void, Ptr< Packet > > LtePhyRxDataEndOkCallback
This method is used by the LteSpectrumPhy to notify the PHY that a previously started RX attempt has ...
Callback< void, uint16_t, Ptr< SpectrumValue > > LtePhyRxPssCallback
This method is used by the LteSpectrumPhy to notify the UE PHY that a PSS has been received.
bool operator==(const EventId &a, const EventId &b)
Definition event-id.h:146
Callback< void > LtePhyRxDataEndErrorCallback
This method is used by the LteSpectrumPhy to notify the PHY that a previously started RX attempt has ...
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
Callback< void, std::list< Ptr< LteControlMessage > > > LtePhyRxCtrlEndOkCallback
This method is used by the LteSpectrumPhy to notify the PHY that a previously started RX of a control...
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:605
bool operator<(const EventId &a, const EventId &b)
Definition event-id.h:159
std::vector< HarqProcessInfoElement_t > HarqProcessInfoList_t
HarqProcessInfoList_t typedef.
Callback< void, DlInfoListElement_s > LtePhyDlHarqFeedbackCallback
This method is used by the LteSpectrumPhy to notify the PHY about the status of a certain DL HARQ pro...
Callback< void > LtePhyRxCtrlEndErrorCallback
This method is used by the LteSpectrumPhy to notify the PHY that a previously started RX of a control...
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...
Callback< void, UlInfoListElement_s > LtePhyUlHarqFeedbackCallback
This method is used by the LteSpectrumPhy to notify the PHY about the status of a certain UL HARQ pro...
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.
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:201
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