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