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
62{
63}
64
65TbId_t::TbId_t(const uint16_t a, const uint8_t b)
66 : m_rnti(a),
67 m_layer(b)
68{
69}
70
78bool
79operator==(const TbId_t& a, const TbId_t& b)
80{
81 return ((a.m_rnti == b.m_rnti) && (a.m_layer == b.m_layer));
82}
83
91bool
92operator<(const TbId_t& a, const TbId_t& b)
93{
94 return ((a.m_rnti < b.m_rnti) || ((a.m_rnti == b.m_rnti) && (a.m_layer < b.m_layer)));
95}
96
98
100 : m_state(IDLE),
101 m_cellId(0),
102 m_componentCarrierId(0),
103 m_transmissionMode(0),
104 m_layersNum(1)
105{
106 NS_LOG_FUNCTION(this);
107 m_random = CreateObject<UniformRandomVariable>();
108 m_random->SetAttribute("Min", DoubleValue(0.0));
109 m_random->SetAttribute("Max", DoubleValue(1.0));
110 m_interferenceData = CreateObject<LteInterference>();
111 m_interferenceCtrl = CreateObject<LteInterference>();
112
113 for (uint8_t i = 0; i < 7; i++)
114 {
115 m_txModeGain.push_back(1.0);
116 }
117}
118
120{
121 NS_LOG_FUNCTION(this);
122 m_expectedTbs.clear();
123 m_txModeGain.clear();
124}
125
126void
128{
129 NS_LOG_FUNCTION(this);
130 m_channel = nullptr;
131 m_mobility = nullptr;
132 m_device = nullptr;
133 m_interferenceData->Dispose();
134 m_interferenceData = nullptr;
135 m_interferenceCtrl->Dispose();
136 m_interferenceCtrl = nullptr;
137 m_ltePhyRxDataEndErrorCallback = MakeNullCallback<void>();
138 m_ltePhyRxDataEndOkCallback = MakeNullCallback<void, Ptr<Packet>>();
139 m_ltePhyRxCtrlEndOkCallback = MakeNullCallback<void, std::list<Ptr<LteControlMessage>>>();
140 m_ltePhyRxCtrlEndErrorCallback = MakeNullCallback<void>();
141 m_ltePhyDlHarqFeedbackCallback = MakeNullCallback<void, DlInfoListElement_s>();
142 m_ltePhyUlHarqFeedbackCallback = MakeNullCallback<void, UlInfoListElement_s>();
143 m_ltePhyRxPssCallback = MakeNullCallback<void, uint16_t, Ptr<SpectrumValue>>();
145}
146
154std::ostream&
155operator<<(std::ostream& os, LteSpectrumPhy::State s)
156{
157 switch (s)
158 {
160 os << "IDLE";
161 break;
163 os << "RX_DATA";
164 break;
166 os << "RX_DL_CTRL";
167 break;
169 os << "TX_DATA";
170 break;
172 os << "TX_DL_CTRL";
173 break;
175 os << "TX_UL_SRS";
176 break;
177 default:
178 os << "UNKNOWN";
179 break;
180 }
181 return os;
182}
183
184TypeId
186{
187 static TypeId tid =
188 TypeId("ns3::LteSpectrumPhy")
190 .SetGroupName("Lte")
191 .AddTraceSource("TxStart",
192 "Trace fired when a new transmission is started",
194 "ns3::PacketBurst::TracedCallback")
195 .AddTraceSource("TxEnd",
196 "Trace fired when a previously started transmission is finished",
198 "ns3::PacketBurst::TracedCallback")
199 .AddTraceSource("RxStart",
200 "Trace fired when the start of a signal is detected",
202 "ns3::PacketBurst::TracedCallback")
203 .AddTraceSource("RxEndOk",
204 "Trace fired when a previously started RX terminates successfully",
206 "ns3::Packet::TracedCallback")
207 .AddTraceSource("RxEndError",
208 "Trace fired when a previously started RX terminates with an error",
210 "ns3::Packet::TracedCallback")
211 .AddAttribute("DataErrorModelEnabled",
212 "Activate/Deactivate the error model of data (TBs of PDSCH and PUSCH) "
213 "[by default is active].",
214 BooleanValue(true),
217 .AddAttribute("CtrlErrorModelEnabled",
218 "Activate/Deactivate the error model of control (PCFICH-PDCCH "
219 "decodification) [by default is active].",
220 BooleanValue(true),
223 .AddTraceSource("DlPhyReception",
224 "DL reception PHY layer statistics.",
226 "ns3::PhyReceptionStatParameters::TracedCallback")
227 .AddTraceSource("UlPhyReception",
228 "DL reception PHY layer statistics.",
230 "ns3::PhyReceptionStatParameters::TracedCallback");
231 return tid;
232}
233
236{
237 NS_LOG_FUNCTION(this);
238 return m_device;
239}
240
243{
244 NS_LOG_FUNCTION(this);
245 return m_mobility;
246}
247
248void
250{
251 NS_LOG_FUNCTION(this << d);
252 m_device = d;
253}
254
255void
257{
258 NS_LOG_FUNCTION(this << m);
259 m_mobility = m;
260}
261
262void
264{
265 NS_LOG_FUNCTION(this << c);
266 m_channel = c;
267}
268
271{
272 return m_channel;
273}
274
277{
278 return m_rxSpectrumModel;
279}
280
281void
283{
284 NS_LOG_FUNCTION(this << txPsd);
285 NS_ASSERT(txPsd);
286 m_txPsd = txPsd;
287}
288
289void
291{
292 NS_LOG_FUNCTION(this << noisePsd);
293 NS_ASSERT(noisePsd);
294 m_rxSpectrumModel = noisePsd->GetSpectrumModel();
295 m_interferenceData->SetNoisePowerSpectralDensity(noisePsd);
296 m_interferenceCtrl->SetNoisePowerSpectralDensity(noisePsd);
297}
298
299void
301{
302 NS_LOG_FUNCTION(this);
303 m_cellId = 0;
304 m_state = IDLE;
306 m_layersNum = 1;
312 m_expectedTbs.clear();
314 m_rxPacketBurstList.clear();
315 m_txPacketBurst = nullptr;
316 m_rxSpectrumModel = nullptr;
317
318 // Detach from the channel, because receiving any signal without
319 // spectrum model is an error.
320 if (m_channel)
321 {
322 m_channel->RemoveRx(this);
323 }
324}
325
326void
328{
329 NS_LOG_FUNCTION(this);
331}
332
333void
335{
336 NS_LOG_FUNCTION(this);
338}
339
340void
342{
343 NS_LOG_FUNCTION(this);
345}
346
347void
349{
350 NS_LOG_FUNCTION(this);
352}
353
354void
356{
357 NS_LOG_FUNCTION(this);
359}
360
361void
363{
364 NS_LOG_FUNCTION(this);
366}
367
368void
370{
371 NS_LOG_FUNCTION(this);
373}
374
377{
378 return m_antenna;
379}
380
381void
383{
384 NS_LOG_FUNCTION(this << a);
385 m_antenna = a;
386}
387
388void
390{
391 ChangeState(newState);
392}
393
394void
396{
397 NS_LOG_LOGIC(this << " state: " << m_state << " -> " << newState);
398 m_state = newState;
399}
400
401void
403{
404 m_harqPhyModule = harq;
405}
406
407bool
410 Time duration)
411{
412 NS_LOG_FUNCTION(this << pb);
413 NS_LOG_LOGIC(this << " state: " << m_state);
414
416
417 switch (m_state)
418 {
419 case RX_DATA:
420 case RX_DL_CTRL:
421 case RX_UL_SRS:
422 NS_FATAL_ERROR("cannot TX while RX: according to FDD channel access, the physical layer "
423 "for transmission cannot be used for reception");
424 break;
425
426 case TX_DATA:
427 case TX_DL_CTRL:
428 case TX_UL_SRS:
429 NS_FATAL_ERROR("cannot TX while already TX: the MAC should avoid this");
430 break;
431
432 case IDLE: {
433 /*
434 m_txPsd must be set by the device, according to
435 (i) the available subchannel for transmission
436 (ii) the power transmission
437 */
439 m_txPacketBurst = pb;
440
441 // we need to convey some PHY meta information to the receiver
442 // to be used for simulation purposes (e.g., the CellId). This
443 // is done by setting the ctrlMsgList parameter of
444 // LteSpectrumSignalParametersDataFrame
448 Create<LteSpectrumSignalParametersDataFrame>();
449 txParams->duration = duration;
450 txParams->txPhy = GetObject<SpectrumPhy>();
451 txParams->txAntenna = m_antenna;
452 txParams->psd = m_txPsd;
453 txParams->packetBurst = pb;
454 txParams->ctrlMsgList = ctrlMsgList;
455 txParams->cellId = m_cellId;
456 m_channel->StartTx(txParams);
458 }
459 return false;
460 break;
461
462 default:
463 NS_FATAL_ERROR("unknown state");
464 return true;
465 break;
466 }
467}
468
469bool
471{
472 NS_LOG_FUNCTION(this << " PSS " << (uint16_t)pss);
473 NS_LOG_LOGIC(this << " state: " << m_state);
474
475 switch (m_state)
476 {
477 case RX_DATA:
478 case RX_DL_CTRL:
479 case RX_UL_SRS:
480 NS_FATAL_ERROR("cannot TX while RX: according to FDD channel access, the physical layer "
481 "for transmission cannot be used for reception");
482 break;
483
484 case TX_DATA:
485 case TX_DL_CTRL:
486 case TX_UL_SRS:
487 NS_FATAL_ERROR("cannot TX while already TX: the MAC should avoid this");
488 break;
489
490 case IDLE: {
491 /*
492 m_txPsd must be set by the device, according to
493 (i) the available subchannel for transmission
494 (ii) the power transmission
495 */
497
498 // we need to convey some PHY meta information to the receiver
499 // to be used for simulation purposes (e.g., the CellId). This
500 // is done by setting the cellId parameter of
501 // LteSpectrumSignalParametersDlCtrlFrame
504
506 Create<LteSpectrumSignalParametersDlCtrlFrame>();
507 txParams->duration = DL_CTRL_DURATION;
508 txParams->txPhy = GetObject<SpectrumPhy>();
509 txParams->txAntenna = m_antenna;
510 txParams->psd = m_txPsd;
511 txParams->cellId = m_cellId;
512 txParams->pss = pss;
513 txParams->ctrlMsgList = ctrlMsgList;
514 m_channel->StartTx(txParams);
516 }
517 return false;
518 break;
519
520 default:
521 NS_FATAL_ERROR("unknown state");
522 return true;
523 break;
524 }
525}
526
527bool
529{
530 NS_LOG_FUNCTION(this);
531 NS_LOG_LOGIC(this << " state: " << m_state);
532
533 switch (m_state)
534 {
535 case RX_DATA:
536 case RX_DL_CTRL:
537 case RX_UL_SRS:
538 NS_FATAL_ERROR("cannot TX while RX: according to FDD channel access, the physical layer "
539 "for transmission cannot be used for reception");
540 break;
541
542 case TX_DL_CTRL:
543 case TX_DATA:
544 case TX_UL_SRS:
545 NS_FATAL_ERROR("cannot TX while already TX: the MAC should avoid this");
546 break;
547
548 case IDLE: {
549 /*
550 m_txPsd must be set by the device, according to
551 (i) the available subchannel for transmission
552 (ii) the power transmission
553 */
555 NS_LOG_LOGIC(this << " m_txPsd: " << *m_txPsd);
556
557 // we need to convey some PHY meta information to the receiver
558 // to be used for simulation purposes (e.g., the CellId). This
559 // is done by setting the cellId parameter of
560 // LteSpectrumSignalParametersDlCtrlFrame
564 Create<LteSpectrumSignalParametersUlSrsFrame>();
565 txParams->duration = UL_SRS_DURATION;
566 txParams->txPhy = GetObject<SpectrumPhy>();
567 txParams->txAntenna = m_antenna;
568 txParams->psd = m_txPsd;
569 txParams->cellId = m_cellId;
570 m_channel->StartTx(txParams);
572 }
573 return false;
574 break;
575
576 default:
577 NS_FATAL_ERROR("unknown state");
578 return true;
579 break;
580 }
581}
582
583void
585{
586 NS_LOG_FUNCTION(this);
587 NS_LOG_LOGIC(this << " state: " << m_state);
588
591 m_txPacketBurst = nullptr;
593}
594
595void
597{
598 NS_LOG_FUNCTION(this);
599 NS_LOG_LOGIC(this << " state: " << m_state);
600
604}
605
606void
608{
609 NS_LOG_FUNCTION(this);
610 NS_LOG_LOGIC(this << " state: " << m_state);
611
615}
616
617void
619{
620 NS_LOG_FUNCTION(this << spectrumRxParams);
621 NS_LOG_LOGIC(this << " state: " << m_state);
622
623 Ptr<const SpectrumValue> rxPsd = spectrumRxParams->psd;
624 Time duration = spectrumRxParams->duration;
625
626 // the device might start RX only if the signal is of a type
627 // understood by this device - in this case, an LTE signal.
629 DynamicCast<LteSpectrumSignalParametersDataFrame>(spectrumRxParams);
631 DynamicCast<LteSpectrumSignalParametersDlCtrlFrame>(spectrumRxParams);
633 DynamicCast<LteSpectrumSignalParametersUlSrsFrame>(spectrumRxParams);
634 if (lteDataRxParams)
635 {
636 m_interferenceData->AddSignal(rxPsd, duration);
637 StartRxData(lteDataRxParams);
638 }
639 else if (lteDlCtrlRxParams)
640 {
641 m_interferenceCtrl->AddSignal(rxPsd, duration);
642 StartRxDlCtrl(lteDlCtrlRxParams);
643 }
644 else if (lteUlSrsRxParams)
645 {
646 m_interferenceCtrl->AddSignal(rxPsd, duration);
647 StartRxUlSrs(lteUlSrsRxParams);
648 }
649 else
650 {
651 // other type of signal (could be 3G, GSM, whatever) -> interference
652 m_interferenceData->AddSignal(rxPsd, duration);
653 m_interferenceCtrl->AddSignal(rxPsd, duration);
654 }
655}
656
657void
659{
660 NS_LOG_FUNCTION(this);
661 switch (m_state)
662 {
663 case TX_DATA:
664 case TX_DL_CTRL:
665 case TX_UL_SRS:
666 NS_FATAL_ERROR("cannot RX while TX: according to FDD channel access, the physical layer "
667 "for transmission cannot be used for reception");
668 break;
669 case RX_DL_CTRL:
670 NS_FATAL_ERROR("cannot RX Data while receiving control");
671 break;
672 case IDLE:
673 case RX_DATA:
674 // the behavior is similar when
675 // we're IDLE or RX because we can receive more signals
676 // simultaneously (e.g., at the eNB).
677 {
678 // To check if we're synchronized to this signal, we check
679 // for the CellId which is reported in the
680 // LteSpectrumSignalParametersDataFrame
681 if (params->cellId == m_cellId)
682 {
683 NS_LOG_LOGIC(this << " synchronized with this signal (cellId=" << params->cellId
684 << ")");
685 if ((m_rxPacketBurstList.empty()) && (m_rxControlMessageList.empty()))
686 {
688 // first transmission, i.e., we're IDLE and we
689 // start RX
691 m_firstRxDuration = params->duration;
692 NS_LOG_LOGIC(this << " scheduling EndRx with delay "
693 << params->duration.As(Time::S));
695 Simulator::Schedule(params->duration, &LteSpectrumPhy::EndRxData, this);
696 }
697 else
698 {
700 // sanity check: if there are multiple RX events, they
701 // should occur at the same time and have the same
702 // duration, otherwise the interference calculation
703 // won't be correct
705 (m_firstRxDuration == params->duration));
706 }
707
709 if (params->packetBurst)
710 {
711 m_rxPacketBurstList.push_back(params->packetBurst);
712 m_interferenceData->StartRx(params->psd);
713
714 m_phyRxStartTrace(params->packetBurst);
715 }
716 NS_LOG_DEBUG(this << " insert msgs " << params->ctrlMsgList.size());
718 params->ctrlMsgList.begin(),
719 params->ctrlMsgList.end());
720
721 NS_LOG_LOGIC(this << " numSimultaneousRxEvents = " << m_rxPacketBurstList.size());
722 }
723 else
724 {
725 NS_LOG_LOGIC(this << " not in sync with this signal (cellId=" << params->cellId
726 << ", m_cellId=" << m_cellId << ")");
727 }
728 }
729 break;
730
731 default:
732 NS_FATAL_ERROR("unknown state");
733 break;
734 }
735
736 NS_LOG_LOGIC(this << " state: " << m_state);
737}
738
739void
741{
742 NS_LOG_FUNCTION(this);
743
744 // To check if we're synchronized to this signal, we check
745 // for the CellId which is reported in the
746 // LteSpectrumSignalParametersDlCtrlFrame
747 uint16_t cellId;
748 NS_ASSERT(lteDlCtrlRxParams);
749 cellId = lteDlCtrlRxParams->cellId;
750
751 switch (m_state)
752 {
753 case TX_DATA:
754 case TX_DL_CTRL:
755 case TX_UL_SRS:
756 case RX_DATA:
757 case RX_UL_SRS:
758 NS_FATAL_ERROR("unexpected event in state " << m_state);
759 break;
760
761 case RX_DL_CTRL:
762 case IDLE:
763
764 // common code for the two states
765 // check presence of PSS for UE measuerements
766 if (lteDlCtrlRxParams->pss == true)
767 {
769 {
770 m_ltePhyRxPssCallback(cellId, lteDlCtrlRxParams->psd);
771 }
772 }
773
774 // differentiated code for the two states
775 switch (m_state)
776 {
777 case RX_DL_CTRL:
778 NS_ASSERT_MSG(m_cellId != cellId, "any other DlCtrl should be from a different cell");
779 NS_LOG_LOGIC(this << " ignoring other DlCtrl (cellId=" << cellId
780 << ", m_cellId=" << m_cellId << ")");
781 break;
782
783 case IDLE:
784 if (cellId == m_cellId)
785 {
786 NS_LOG_LOGIC(this << " synchronized with this signal (cellId=" << cellId << ")");
787
790 m_firstRxDuration = lteDlCtrlRxParams->duration;
791 NS_LOG_LOGIC(this << " scheduling EndRx with delay "
792 << lteDlCtrlRxParams->duration);
793
794 // store the DCIs
795 m_rxControlMessageList = lteDlCtrlRxParams->ctrlMsgList;
796 m_endRxDlCtrlEvent = Simulator::Schedule(lteDlCtrlRxParams->duration,
798 this);
800 m_interferenceCtrl->StartRx(lteDlCtrlRxParams->psd);
801 }
802 else
803 {
804 NS_LOG_LOGIC(this << " not synchronizing with this signal (cellId=" << cellId
805 << ", m_cellId=" << m_cellId << ")");
806 }
807 break;
808
809 default:
810 NS_FATAL_ERROR("unexpected event in state " << m_state);
811 break;
812 }
813 break; // case RX_DL_CTRL or IDLE
814
815 default:
816 NS_FATAL_ERROR("unknown state");
817 break;
818 }
819
820 NS_LOG_LOGIC(this << " state: " << m_state);
821}
822
823void
825{
826 NS_LOG_FUNCTION(this);
827 switch (m_state)
828 {
829 case TX_DATA:
830 case TX_DL_CTRL:
831 case TX_UL_SRS:
832 NS_FATAL_ERROR("cannot RX while TX: according to FDD channel access, the physical layer "
833 "for transmission cannot be used for reception");
834 break;
835
836 case RX_DATA:
837 case RX_DL_CTRL:
838 NS_FATAL_ERROR("cannot RX SRS while receiving something else");
839 break;
840
841 case IDLE:
842 case RX_UL_SRS:
843 // the behavior is similar when
844 // we're IDLE or RX_UL_SRS because we can receive more signals
845 // simultaneously at the eNB
846 {
847 // To check if we're synchronized to this signal, we check
848 // for the CellId which is reported in the
849 // LteSpectrumSignalParametersDlCtrlFrame
850 uint16_t cellId;
851 cellId = lteUlSrsRxParams->cellId;
852 if (cellId == m_cellId)
853 {
854 NS_LOG_LOGIC(this << " synchronized with this signal (cellId=" << cellId << ")");
855 if (m_state == IDLE)
856 {
857 // first transmission, i.e., we're IDLE and we
858 // start RX
861 m_firstRxDuration = lteUlSrsRxParams->duration;
862 NS_LOG_LOGIC(this << " scheduling EndRx with delay "
863 << lteUlSrsRxParams->duration);
864
865 m_endRxUlSrsEvent = Simulator::Schedule(lteUlSrsRxParams->duration,
867 this);
868 }
869 else if (m_state == RX_UL_SRS)
870 {
871 // sanity check: if there are multiple RX events, they
872 // should occur at the same time and have the same
873 // duration, otherwise the interference calculation
874 // won't be correct
876 (m_firstRxDuration == lteUlSrsRxParams->duration));
877 }
879 m_interferenceCtrl->StartRx(lteUlSrsRxParams->psd);
880 }
881 else
882 {
883 NS_LOG_LOGIC(this << " not in sync with this signal (cellId=" << cellId
884 << ", m_cellId=" << m_cellId << ")");
885 }
886 }
887 break;
888
889 default:
890 NS_FATAL_ERROR("unknown state");
891 break;
892 }
893
894 NS_LOG_LOGIC(this << " state: " << m_state);
895}
896
897void
899{
900 NS_LOG_FUNCTION(this << sinr);
901 m_sinrPerceived = sinr;
902}
903
904void
906 uint8_t ndi,
907 uint16_t size,
908 uint8_t mcs,
909 std::vector<int> map,
910 uint8_t layer,
911 uint8_t harqId,
912 uint8_t rv,
913 bool downlink)
914{
915 NS_LOG_FUNCTION(this << " rnti: " << rnti << " NDI " << (uint16_t)ndi << " size " << size
916 << " mcs " << (uint16_t)mcs << " layer " << (uint16_t)layer << " rv "
917 << (uint16_t)rv);
918 TbId_t tbId;
919 tbId.m_rnti = rnti;
920 tbId.m_layer = layer;
921 expectedTbs_t::iterator it;
922 it = m_expectedTbs.find(tbId);
923 if (it != m_expectedTbs.end())
924 {
925 // migth be a TB of an unreceived packet (due to high progpalosses)
926 m_expectedTbs.erase(it);
927 }
928 // insert new entry
929 tbInfo_t tbInfo = {ndi, size, mcs, map, harqId, rv, 0.0, downlink, false, false};
930 m_expectedTbs.insert(std::pair<TbId_t, tbInfo_t>(tbId, tbInfo));
931}
932
933void
935{
936 NS_LOG_FUNCTION(this << rnti);
937 TbId_t tbId;
938 tbId.m_rnti = rnti;
939 // Remove TB of both the layers
940 for (uint8_t i = 0; i < 2; i++)
941 {
942 tbId.m_layer = i;
943 expectedTbs_t::iterator it;
944 it = m_expectedTbs.find(tbId);
945 if (it != m_expectedTbs.end())
946 {
947 m_expectedTbs.erase(it);
948 }
949 }
950}
951
952void
954{
955 NS_LOG_FUNCTION(this);
956 NS_LOG_LOGIC(this << " state: " << m_state);
957
959
960 // this will trigger CQI calculation and Error Model evaluation
961 // as a side effect, the error model should update the error status of all TBs
962 m_interferenceData->EndRx();
963 NS_LOG_DEBUG(this << " No. of burts " << m_rxPacketBurstList.size());
964 NS_LOG_DEBUG(this << " Expected TBs " << m_expectedTbs.size());
965 expectedTbs_t::iterator itTb = m_expectedTbs.begin();
966
967 // apply transmission mode gain
968 NS_LOG_DEBUG(this << " txMode " << (uint16_t)m_transmissionMode << " gain "
972
973 while (itTb != m_expectedTbs.end())
974 {
976 (m_rxPacketBurstList.size() >
977 0)) // avoid to check for errors when there is no actual data transmitted
978 {
979 // retrieve HARQ info
980 HarqProcessInfoList_t harqInfoList;
981 if ((*itTb).second.ndi == 0)
982 {
983 // TB retxed: retrieve HARQ history
984 uint16_t ulHarqId = 0;
985 if ((*itTb).second.downlink)
986 {
987 harqInfoList =
988 m_harqPhyModule->GetHarqProcessInfoDl((*itTb).second.harqProcessId,
989 (*itTb).first.m_layer);
990 }
991 else
992 {
993 harqInfoList =
994 m_harqPhyModule->GetHarqProcessInfoUl((*itTb).first.m_rnti, ulHarqId);
995 }
996 }
998 (*itTb).second.rbBitmap,
999 (*itTb).second.size,
1000 (*itTb).second.mcs,
1001 harqInfoList);
1002 (*itTb).second.mi = tbStats.mi;
1003 (*itTb).second.corrupt = !(m_random->GetValue() > tbStats.tbler);
1004 NS_LOG_DEBUG(this << "RNTI " << (*itTb).first.m_rnti << " size " << (*itTb).second.size
1005 << " mcs " << (uint32_t)(*itTb).second.mcs << " bitmap "
1006 << (*itTb).second.rbBitmap.size() << " layer "
1007 << (uint16_t)(*itTb).first.m_layer << " TBLER " << tbStats.tbler
1008 << " corrupted " << (*itTb).second.corrupt);
1009 // fire traces on DL/UL reception PHY stats
1012 params.m_cellId = m_cellId;
1013 params.m_imsi = 0; // it will be set by DlPhyTransmissionCallback in LteHelper
1014 params.m_rnti = (*itTb).first.m_rnti;
1016 params.m_layer = (*itTb).first.m_layer;
1017 params.m_mcs = (*itTb).second.mcs;
1018 params.m_size = (*itTb).second.size;
1019 params.m_rv = (*itTb).second.rv;
1020 params.m_ndi = (*itTb).second.ndi;
1021 params.m_correctness = (uint8_t) !(*itTb).second.corrupt;
1023 if ((*itTb).second.downlink)
1024 {
1025 // DL
1026 m_dlPhyReception(params);
1027 }
1028 else
1029 {
1030 // UL
1031 params.m_rv = harqInfoList.size();
1032 m_ulPhyReception(params);
1033 }
1034 }
1035
1036 itTb++;
1037 }
1038 std::map<uint16_t, DlInfoListElement_s> harqDlInfoMap;
1039 for (std::list<Ptr<PacketBurst>>::const_iterator i = m_rxPacketBurstList.begin();
1040 i != m_rxPacketBurstList.end();
1041 ++i)
1042 {
1043 for (std::list<Ptr<Packet>>::const_iterator j = (*i)->Begin(); j != (*i)->End(); ++j)
1044 {
1045 // retrieve TB info of this packet
1047 (*j)->PeekPacketTag(tag);
1048 TbId_t tbId;
1049 tbId.m_rnti = tag.GetRnti();
1050 tbId.m_layer = tag.GetLayer();
1051 itTb = m_expectedTbs.find(tbId);
1052 NS_LOG_INFO(this << " Packet of " << tbId.m_rnti << " layer "
1053 << (uint16_t)tag.GetLayer());
1054 if (itTb != m_expectedTbs.end())
1055 {
1056 if (!(*itTb).second.corrupt)
1057 {
1059
1061 {
1063 }
1064 }
1065 else
1066 {
1067 // TB received with errors
1069 }
1070
1071 // send HARQ feedback (if not already done for this TB)
1072 if (!(*itTb).second.harqFeedbackSent)
1073 {
1074 (*itTb).second.harqFeedbackSent = true;
1075 if (!(*itTb).second.downlink)
1076 {
1077 UlInfoListElement_s harqUlInfo;
1078 harqUlInfo.m_rnti = tbId.m_rnti;
1079 harqUlInfo.m_tpc = 0;
1080 if ((*itTb).second.corrupt)
1081 {
1082 harqUlInfo.m_receptionStatus = UlInfoListElement_s::NotOk;
1083 NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " send UL-HARQ-NACK");
1084 m_harqPhyModule->UpdateUlHarqProcessStatus(
1085 tbId.m_rnti,
1086 (*itTb).second.mi,
1087 (*itTb).second.size,
1088 (*itTb).second.size / EffectiveCodingRate[(*itTb).second.mcs]);
1089 }
1090 else
1091 {
1092 harqUlInfo.m_receptionStatus = UlInfoListElement_s::Ok;
1093 NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " send UL-HARQ-ACK");
1094 m_harqPhyModule->ResetUlHarqProcessStatus(tbId.m_rnti,
1095 (*itTb).second.harqProcessId);
1096 }
1098 {
1100 }
1101 }
1102 else
1103 {
1104 std::map<uint16_t, DlInfoListElement_s>::iterator itHarq =
1105 harqDlInfoMap.find(tbId.m_rnti);
1106 if (itHarq == harqDlInfoMap.end())
1107 {
1108 DlInfoListElement_s harqDlInfo;
1110 harqDlInfo.m_rnti = tbId.m_rnti;
1111 harqDlInfo.m_harqProcessId = (*itTb).second.harqProcessId;
1112 if ((*itTb).second.corrupt)
1113 {
1114 harqDlInfo.m_harqStatus.at(tbId.m_layer) =
1116 NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
1117 << (uint16_t)(*itTb).second.harqProcessId
1118 << " layer " << (uint16_t)tbId.m_layer
1119 << " send DL-HARQ-NACK");
1120 m_harqPhyModule->UpdateDlHarqProcessStatus(
1121 (*itTb).second.harqProcessId,
1122 tbId.m_layer,
1123 (*itTb).second.mi,
1124 (*itTb).second.size,
1125 (*itTb).second.size / EffectiveCodingRate[(*itTb).second.mcs]);
1126 }
1127 else
1128 {
1129 harqDlInfo.m_harqStatus.at(tbId.m_layer) = DlInfoListElement_s::ACK;
1130 NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
1131 << (uint16_t)(*itTb).second.harqProcessId
1132 << " layer " << (uint16_t)tbId.m_layer << " size "
1133 << (*itTb).second.size << " send DL-HARQ-ACK");
1134 m_harqPhyModule->ResetDlHarqProcessStatus(
1135 (*itTb).second.harqProcessId);
1136 }
1137 harqDlInfoMap.insert(
1138 std::pair<uint16_t, DlInfoListElement_s>(tbId.m_rnti, harqDlInfo));
1139 }
1140 else
1141 {
1142 if ((*itTb).second.corrupt)
1143 {
1144 (*itHarq).second.m_harqStatus.at(tbId.m_layer) =
1146 NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
1147 << (uint16_t)(*itTb).second.harqProcessId
1148 << " layer " << (uint16_t)tbId.m_layer << " size "
1149 << (*itHarq).second.m_harqStatus.size()
1150 << " send DL-HARQ-NACK");
1151 m_harqPhyModule->UpdateDlHarqProcessStatus(
1152 (*itTb).second.harqProcessId,
1153 tbId.m_layer,
1154 (*itTb).second.mi,
1155 (*itTb).second.size,
1156 (*itTb).second.size / EffectiveCodingRate[(*itTb).second.mcs]);
1157 }
1158 else
1159 {
1160 NS_ASSERT_MSG(tbId.m_layer < (*itHarq).second.m_harqStatus.size(),
1161 " layer " << (uint16_t)tbId.m_layer);
1162 (*itHarq).second.m_harqStatus.at(tbId.m_layer) =
1164 NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
1165 << (uint16_t)(*itTb).second.harqProcessId
1166 << " layer " << (uint16_t)tbId.m_layer << " size "
1167 << (*itHarq).second.m_harqStatus.size()
1168 << " send DL-HARQ-ACK");
1169 m_harqPhyModule->ResetDlHarqProcessStatus(
1170 (*itTb).second.harqProcessId);
1171 }
1172 }
1173 } // end if ((*itTb).second.downlink) HARQ
1174 } // end if (!(*itTb).second.harqFeedbackSent)
1175 }
1176 }
1177 }
1178
1179 // send DL HARQ feedback to LtePhy
1180 std::map<uint16_t, DlInfoListElement_s>::iterator itHarq;
1181 for (itHarq = harqDlInfoMap.begin(); itHarq != harqDlInfoMap.end(); itHarq++)
1182 {
1184 {
1185 m_ltePhyDlHarqFeedbackCallback((*itHarq).second);
1186 }
1187 }
1188 // forward control messages of this frame to LtePhy
1189 if (!m_rxControlMessageList.empty())
1190 {
1192 {
1194 }
1195 }
1197 m_rxPacketBurstList.clear();
1198 m_rxControlMessageList.clear();
1199 m_expectedTbs.clear();
1200}
1201
1202void
1204{
1205 NS_LOG_FUNCTION(this);
1206 NS_LOG_LOGIC(this << " state: " << m_state);
1207
1209
1210 // this will trigger CQI calculation and Error Model evaluation
1211 // as a side effect, the error model should update the error status of all TBs
1212 m_interferenceCtrl->EndRx();
1213 // apply transmission mode gain
1214 NS_LOG_DEBUG(this << " txMode " << (uint16_t)m_transmissionMode << " gain "
1217 if (m_transmissionMode > 0)
1218 {
1219 // in case of MIMO, ctrl is always txed as TX diversity
1221 }
1222 // m_sinrPerceived *= m_txModeGain.at (m_transmissionMode);
1223 bool error = false;
1225 {
1227 error = !(m_random->GetValue() > errorRate);
1228 NS_LOG_DEBUG(this << " PCFICH-PDCCH Decodification, errorRate " << errorRate << " error "
1229 << error);
1230 }
1231
1232 if (!error)
1233 {
1235 {
1236 NS_LOG_DEBUG(this << " PCFICH-PDCCH Rxed OK");
1238 }
1239 }
1240 else
1241 {
1243 {
1244 NS_LOG_DEBUG(this << " PCFICH-PDCCH Error");
1246 }
1247 }
1249 m_rxControlMessageList.clear();
1250}
1251
1252void
1254{
1257 m_interferenceCtrl->EndRx();
1258 // nothing to do (used only for SRS at this stage)
1259}
1260
1261void
1263{
1264 m_cellId = cellId;
1265}
1266
1267void
1268LteSpectrumPhy::SetComponentCarrierId(uint8_t componentCarrierId)
1269{
1270 m_componentCarrierId = componentCarrierId;
1271}
1272
1273void
1275{
1276 m_interferenceCtrl->AddRsPowerChunkProcessor(p);
1277}
1278
1279void
1281{
1282 m_interferenceData->AddRsPowerChunkProcessor(p);
1283}
1284
1285void
1287{
1288 m_interferenceData->AddSinrChunkProcessor(p);
1289}
1290
1291void
1293{
1294 m_interferenceCtrl->AddInterferenceChunkProcessor(p);
1295}
1296
1297void
1299{
1300 m_interferenceData->AddInterferenceChunkProcessor(p);
1301}
1302
1303void
1305{
1306 m_interferenceCtrl->AddSinrChunkProcessor(p);
1307}
1308
1309void
1311{
1312 NS_LOG_FUNCTION(this << (uint16_t)txMode);
1313 NS_ASSERT_MSG(txMode < m_txModeGain.size(),
1314 "TransmissionMode not available: 1.." << m_txModeGain.size());
1315 m_transmissionMode = txMode;
1317}
1318
1319void
1320LteSpectrumPhy::SetTxModeGain(uint8_t txMode, double gain)
1321{
1322 NS_LOG_FUNCTION(this << " txmode " << (uint16_t)txMode << " gain " << gain);
1323 if (txMode > 0)
1324 {
1325 // convert to linear
1326 double gainLin = std::pow(10.0, (gain / 10.0));
1327 if (m_txModeGain.size() < txMode)
1328 {
1329 m_txModeGain.resize(txMode);
1330 }
1331 m_txModeGain.at(txMode - 1) = gainLin;
1332 }
1333}
1334
1335int64_t
1337{
1338 NS_LOG_FUNCTION(this << stream);
1339 m_random->SetStream(stream);
1340 return 1;
1341}
1342
1343} // namespace ns3
AttributeValue implementation for Boolean.
Definition: boolean.h:37
bool IsNull() const
Check for null implementation.
Definition: callback.h:556
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:258
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:205
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
#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:160
#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:45
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1374
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
#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
uint8_t m_txMode
the transmission Mode
Definition: lte-common.h:211
uint8_t m_rv
the redundancy version (HARQ)
Definition: lte-common.h:215
uint8_t m_layer
the layer (cw) of the transmission
Definition: lte-common.h:212
uint64_t m_imsi
IMSI of the scheduled UE.
Definition: lte-common.h:209
uint8_t m_correctness
correctness of the TB received
Definition: lte-common.h:217
uint16_t m_rnti
C-RNTI scheduled.
Definition: lte-common.h:210
uint16_t m_cellId
Cell ID of the attached Enb.
Definition: lte-common.h:208
uint8_t m_ndi
new data indicator flag
Definition: lte-common.h:216
uint8_t m_mcs
MCS for transport block.
Definition: lte-common.h:213
int64_t m_timestamp
in millisecond
Definition: lte-common.h:207
uint16_t m_size
Size of transport block.
Definition: lte-common.h:214
uint8_t m_ccId
component carrier id
Definition: lte-common.h:218
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