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
48static const Time UL_SRS_DURATION = NanoSeconds(71429 - 1);
49
52static const Time DL_CTRL_DURATION = NanoSeconds(214286 - 1);
53
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
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
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
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 expectedTbs_t::iterator it;
915 it = m_expectedTbs.find(tbId);
916 if (it != m_expectedTbs.end())
917 {
918 // might be a TB of an unreceived packet (due to high progpalosses)
919 m_expectedTbs.erase(it);
920 }
921 // insert new entry
922 tbInfo_t tbInfo = {ndi, size, mcs, map, harqId, rv, 0.0, downlink, false, false};
923 m_expectedTbs.insert(std::pair<TbId_t, tbInfo_t>(tbId, tbInfo));
924}
925
926void
928{
929 NS_LOG_FUNCTION(this << rnti);
930 TbId_t tbId;
931 tbId.m_rnti = rnti;
932 // Remove TB of both the layers
933 for (uint8_t i = 0; i < 2; i++)
934 {
935 tbId.m_layer = i;
936 expectedTbs_t::iterator it;
937 it = m_expectedTbs.find(tbId);
938 if (it != m_expectedTbs.end())
939 {
940 m_expectedTbs.erase(it);
941 }
942 }
943}
944
945void
947{
948 NS_LOG_FUNCTION(this);
949 NS_LOG_LOGIC(this << " state: " << m_state);
950
952
953 // this will trigger CQI calculation and Error Model evaluation
954 // as a side effect, the error model should update the error status of all TBs
955 m_interferenceData->EndRx();
956 NS_LOG_DEBUG(this << " No. of burts " << m_rxPacketBurstList.size());
957 NS_LOG_DEBUG(this << " Expected TBs " << m_expectedTbs.size());
958 expectedTbs_t::iterator itTb = m_expectedTbs.begin();
959
960 // apply transmission mode gain
961 NS_LOG_DEBUG(this << " txMode " << (uint16_t)m_transmissionMode << " gain "
965
966 while (itTb != m_expectedTbs.end())
967 {
970 .empty()) // avoid to check for errors when there is no actual data transmitted
971 {
972 // retrieve HARQ info
973 HarqProcessInfoList_t harqInfoList;
974 if ((*itTb).second.ndi == 0)
975 {
976 // TB retxed: retrieve HARQ history
977 uint16_t ulHarqId = 0;
978 if ((*itTb).second.downlink)
979 {
980 harqInfoList =
981 m_harqPhyModule->GetHarqProcessInfoDl((*itTb).second.harqProcessId,
982 (*itTb).first.m_layer);
983 }
984 else
985 {
986 harqInfoList =
987 m_harqPhyModule->GetHarqProcessInfoUl((*itTb).first.m_rnti, ulHarqId);
988 }
989 }
991 (*itTb).second.rbBitmap,
992 (*itTb).second.size,
993 (*itTb).second.mcs,
994 harqInfoList);
995 (*itTb).second.mi = tbStats.mi;
996 (*itTb).second.corrupt = !(m_random->GetValue() > tbStats.tbler);
997 NS_LOG_DEBUG(this << "RNTI " << (*itTb).first.m_rnti << " size " << (*itTb).second.size
998 << " mcs " << (uint32_t)(*itTb).second.mcs << " bitmap "
999 << (*itTb).second.rbBitmap.size() << " layer "
1000 << (uint16_t)(*itTb).first.m_layer << " TBLER " << tbStats.tbler
1001 << " corrupted " << (*itTb).second.corrupt);
1002 // fire traces on DL/UL reception PHY stats
1004 params.m_timestamp = Simulator::Now().GetMilliSeconds();
1005 params.m_cellId = m_cellId;
1006 params.m_imsi = 0; // it will be set by DlPhyTransmissionCallback in LteHelper
1007 params.m_rnti = (*itTb).first.m_rnti;
1008 params.m_txMode = m_transmissionMode;
1009 params.m_layer = (*itTb).first.m_layer;
1010 params.m_mcs = (*itTb).second.mcs;
1011 params.m_size = (*itTb).second.size;
1012 params.m_rv = (*itTb).second.rv;
1013 params.m_ndi = (*itTb).second.ndi;
1014 params.m_correctness = (uint8_t) !(*itTb).second.corrupt;
1015 params.m_ccId = m_componentCarrierId;
1016 if ((*itTb).second.downlink)
1017 {
1018 // DL
1019 m_dlPhyReception(params);
1020 }
1021 else
1022 {
1023 // UL
1024 params.m_rv = harqInfoList.size();
1025 m_ulPhyReception(params);
1026 }
1027 }
1028
1029 itTb++;
1030 }
1031 std::map<uint16_t, DlInfoListElement_s> harqDlInfoMap;
1032 for (std::list<Ptr<PacketBurst>>::const_iterator i = m_rxPacketBurstList.begin();
1033 i != m_rxPacketBurstList.end();
1034 ++i)
1035 {
1036 for (std::list<Ptr<Packet>>::const_iterator j = (*i)->Begin(); j != (*i)->End(); ++j)
1037 {
1038 // retrieve TB info of this packet
1040 (*j)->PeekPacketTag(tag);
1041 TbId_t tbId;
1042 tbId.m_rnti = tag.GetRnti();
1043 tbId.m_layer = tag.GetLayer();
1044 itTb = m_expectedTbs.find(tbId);
1045 NS_LOG_INFO(this << " Packet of " << tbId.m_rnti << " layer "
1046 << (uint16_t)tag.GetLayer());
1047 if (itTb != m_expectedTbs.end())
1048 {
1049 if (!(*itTb).second.corrupt)
1050 {
1052
1054 {
1056 }
1057 }
1058 else
1059 {
1060 // TB received with errors
1062 }
1063
1064 // send HARQ feedback (if not already done for this TB)
1065 if (!(*itTb).second.harqFeedbackSent)
1066 {
1067 (*itTb).second.harqFeedbackSent = true;
1068 if (!(*itTb).second.downlink)
1069 {
1070 UlInfoListElement_s harqUlInfo;
1071 harqUlInfo.m_rnti = tbId.m_rnti;
1072 harqUlInfo.m_tpc = 0;
1073 if ((*itTb).second.corrupt)
1074 {
1075 harqUlInfo.m_receptionStatus = UlInfoListElement_s::NotOk;
1076 NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " send UL-HARQ-NACK");
1077 m_harqPhyModule->UpdateUlHarqProcessStatus(
1078 tbId.m_rnti,
1079 (*itTb).second.mi,
1080 (*itTb).second.size,
1081 (*itTb).second.size / EffectiveCodingRate[(*itTb).second.mcs]);
1082 }
1083 else
1084 {
1085 harqUlInfo.m_receptionStatus = UlInfoListElement_s::Ok;
1086 NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " send UL-HARQ-ACK");
1087 m_harqPhyModule->ResetUlHarqProcessStatus(tbId.m_rnti,
1088 (*itTb).second.harqProcessId);
1089 }
1091 {
1093 }
1094 }
1095 else
1096 {
1097 std::map<uint16_t, DlInfoListElement_s>::iterator itHarq =
1098 harqDlInfoMap.find(tbId.m_rnti);
1099 if (itHarq == harqDlInfoMap.end())
1100 {
1101 DlInfoListElement_s harqDlInfo;
1103 harqDlInfo.m_rnti = tbId.m_rnti;
1104 harqDlInfo.m_harqProcessId = (*itTb).second.harqProcessId;
1105 if ((*itTb).second.corrupt)
1106 {
1107 harqDlInfo.m_harqStatus.at(tbId.m_layer) =
1109 NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
1110 << (uint16_t)(*itTb).second.harqProcessId
1111 << " layer " << (uint16_t)tbId.m_layer
1112 << " send DL-HARQ-NACK");
1113 m_harqPhyModule->UpdateDlHarqProcessStatus(
1114 (*itTb).second.harqProcessId,
1115 tbId.m_layer,
1116 (*itTb).second.mi,
1117 (*itTb).second.size,
1118 (*itTb).second.size / EffectiveCodingRate[(*itTb).second.mcs]);
1119 }
1120 else
1121 {
1122 harqDlInfo.m_harqStatus.at(tbId.m_layer) = DlInfoListElement_s::ACK;
1123 NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
1124 << (uint16_t)(*itTb).second.harqProcessId
1125 << " layer " << (uint16_t)tbId.m_layer << " size "
1126 << (*itTb).second.size << " send DL-HARQ-ACK");
1127 m_harqPhyModule->ResetDlHarqProcessStatus(
1128 (*itTb).second.harqProcessId);
1129 }
1130 harqDlInfoMap.insert(
1131 std::pair<uint16_t, DlInfoListElement_s>(tbId.m_rnti, harqDlInfo));
1132 }
1133 else
1134 {
1135 if ((*itTb).second.corrupt)
1136 {
1137 (*itHarq).second.m_harqStatus.at(tbId.m_layer) =
1139 NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
1140 << (uint16_t)(*itTb).second.harqProcessId
1141 << " layer " << (uint16_t)tbId.m_layer << " size "
1142 << (*itHarq).second.m_harqStatus.size()
1143 << " send DL-HARQ-NACK");
1144 m_harqPhyModule->UpdateDlHarqProcessStatus(
1145 (*itTb).second.harqProcessId,
1146 tbId.m_layer,
1147 (*itTb).second.mi,
1148 (*itTb).second.size,
1149 (*itTb).second.size / EffectiveCodingRate[(*itTb).second.mcs]);
1150 }
1151 else
1152 {
1153 NS_ASSERT_MSG(tbId.m_layer < (*itHarq).second.m_harqStatus.size(),
1154 " layer " << (uint16_t)tbId.m_layer);
1155 (*itHarq).second.m_harqStatus.at(tbId.m_layer) =
1157 NS_LOG_DEBUG(this << " RNTI " << tbId.m_rnti << " harqId "
1158 << (uint16_t)(*itTb).second.harqProcessId
1159 << " layer " << (uint16_t)tbId.m_layer << " size "
1160 << (*itHarq).second.m_harqStatus.size()
1161 << " send DL-HARQ-ACK");
1162 m_harqPhyModule->ResetDlHarqProcessStatus(
1163 (*itTb).second.harqProcessId);
1164 }
1165 }
1166 } // end if ((*itTb).second.downlink) HARQ
1167 } // end if (!(*itTb).second.harqFeedbackSent)
1168 }
1169 }
1170 }
1171
1172 // send DL HARQ feedback to LtePhy
1173 std::map<uint16_t, DlInfoListElement_s>::iterator itHarq;
1174 for (itHarq = harqDlInfoMap.begin(); itHarq != harqDlInfoMap.end(); itHarq++)
1175 {
1177 {
1178 m_ltePhyDlHarqFeedbackCallback((*itHarq).second);
1179 }
1180 }
1181 // forward control messages of this frame to LtePhy
1182 if (!m_rxControlMessageList.empty())
1183 {
1185 {
1187 }
1188 }
1190 m_rxPacketBurstList.clear();
1191 m_rxControlMessageList.clear();
1192 m_expectedTbs.clear();
1193}
1194
1195void
1197{
1198 NS_LOG_FUNCTION(this);
1199 NS_LOG_LOGIC(this << " state: " << m_state);
1200
1202
1203 // this will trigger CQI calculation and Error Model evaluation
1204 // as a side effect, the error model should update the error status of all TBs
1205 m_interferenceCtrl->EndRx();
1206 // apply transmission mode gain
1207 NS_LOG_DEBUG(this << " txMode " << (uint16_t)m_transmissionMode << " gain "
1210 if (m_transmissionMode > 0)
1211 {
1212 // in case of MIMO, ctrl is always txed as TX diversity
1214 }
1215 // m_sinrPerceived *= m_txModeGain.at (m_transmissionMode);
1216 bool error = false;
1218 {
1220 error = !(m_random->GetValue() > errorRate);
1221 NS_LOG_DEBUG(this << " PCFICH-PDCCH Decodification, errorRate " << errorRate << " error "
1222 << error);
1223 }
1224
1225 if (!error)
1226 {
1228 {
1229 NS_LOG_DEBUG(this << " PCFICH-PDCCH Rxed OK");
1231 }
1232 }
1233 else
1234 {
1236 {
1237 NS_LOG_DEBUG(this << " PCFICH-PDCCH Error");
1239 }
1240 }
1242 m_rxControlMessageList.clear();
1243}
1244
1245void
1247{
1250 m_interferenceCtrl->EndRx();
1251 // nothing to do (used only for SRS at this stage)
1252}
1253
1254void
1256{
1257 m_cellId = cellId;
1258}
1259
1260void
1261LteSpectrumPhy::SetComponentCarrierId(uint8_t componentCarrierId)
1262{
1263 m_componentCarrierId = componentCarrierId;
1264}
1265
1266void
1268{
1269 m_interferenceCtrl->AddRsPowerChunkProcessor(p);
1270}
1271
1272void
1274{
1275 m_interferenceData->AddRsPowerChunkProcessor(p);
1276}
1277
1278void
1280{
1281 m_interferenceData->AddSinrChunkProcessor(p);
1282}
1283
1284void
1286{
1287 m_interferenceCtrl->AddInterferenceChunkProcessor(p);
1288}
1289
1290void
1292{
1293 m_interferenceData->AddInterferenceChunkProcessor(p);
1294}
1295
1296void
1298{
1299 m_interferenceCtrl->AddSinrChunkProcessor(p);
1300}
1301
1302void
1304{
1305 NS_LOG_FUNCTION(this << (uint16_t)txMode);
1306 NS_ASSERT_MSG(txMode < m_txModeGain.size(),
1307 "TransmissionMode not available: 1.." << m_txModeGain.size());
1308 m_transmissionMode = txMode;
1310}
1311
1312void
1313LteSpectrumPhy::SetTxModeGain(uint8_t txMode, double gain)
1314{
1315 NS_LOG_FUNCTION(this << " txmode " << (uint16_t)txMode << " gain " << gain);
1316 if (txMode > 0)
1317 {
1318 // convert to linear
1319 double gainLin = std::pow(10.0, (gain / 10.0));
1320 if (m_txModeGain.size() < txMode)
1321 {
1322 m_txModeGain.resize(txMode);
1323 }
1324 m_txModeGain.at(txMode - 1) = gainLin;
1325 }
1326}
1327
1328int64_t
1330{
1331 NS_LOG_FUNCTION(this << stream);
1332 m_random->SetStream(stream);
1333 return 1;
1334}
1335
1336} // namespace ns3
AttributeValue implementation for Boolean.
Definition: boolean.h:37
bool IsNull() const
Check for null implementation.
Definition: callback.h:567
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
static TbStats_t GetTbDecodificationStats(const SpectrumValue &sinr, const std::vector< int > &map, uint16_t size, uint8_t mcs, HarqProcessInfoList_t miHistory)
run the error-model algorithm for the specified TB
static double GetPcfichPdcchError(const SpectrumValue &sinr)
run the error-model algorithm for the specified PCFICH+PDCCH channels
Tag used to define the RNTI and LC id for each MAC packet trasmitted.
uint16_t GetRnti() const
Get RNTI function.
uint8_t GetLayer() const
Get layer function.
The LteSpectrumPhy models the physical layer of LTE.
void RemoveExpectedTb(uint16_t rnti)
Remove expected transport block.
Ptr< const SpectrumModel > m_rxSpectrumModel
the spectrum model
TracedCallback< Ptr< const PacketBurst > > m_phyTxEndTrace
the phy transmit end trace callback
bool m_dataErrorModelEnabled
when true (default) the phy error model is enabled
void SetState(State newState)
Set the state of the phy layer.
Ptr< LteInterference > m_interferenceData
the data interference
uint8_t m_transmissionMode
for UEs: store the transmission mode
EventId m_endRxDlCtrlEvent
end receive DL control event
void AddCtrlSinrChunkProcessor(Ptr< LteChunkProcessor > p)
void AddDataSinrChunkProcessor(Ptr< LteChunkProcessor > p)
LtePhyUlHarqFeedbackCallback m_ltePhyUlHarqFeedbackCallback
the LTE phy UL HARQ feedback callback
void AddExpectedTb(uint16_t rnti, uint8_t ndi, uint16_t size, uint8_t mcs, std::vector< int > map, uint8_t layer, uint8_t harqId, uint8_t rv, bool downlink)
Ptr< MobilityModel > GetMobility() const override
Get the associated MobilityModel instance.
Ptr< const SpectrumModel > GetRxSpectrumModel() const override
void SetHarqPhyModule(Ptr< LteHarqPhy > harq)
Set HARQ phy function.
LtePhyRxPssCallback m_ltePhyRxPssCallback
the LTE phy receive PSS callback
void StartRxDlCtrl(Ptr< LteSpectrumSignalParametersDlCtrlFrame > lteDlCtrlRxParams)
Start receive DL control function.
void StartRxUlSrs(Ptr< LteSpectrumSignalParametersUlSrsFrame > lteUlSrsRxParams)
Start receive UL SRS function.
void AddDataPowerChunkProcessor(Ptr< LteChunkProcessor > p)
EventId m_endRxDataEvent
end receive data event
void SetLtePhyRxPssCallback(LtePhyRxPssCallback c)
set the callback for the reception of the PSS as part of the interconnections between the LteSpectrum...
void SetAntenna(Ptr< AntennaModel > a)
set the AntennaModel to be used
bool StartTxDataFrame(Ptr< PacketBurst > pb, std::list< Ptr< LteControlMessage > > ctrlMsgList, Time duration)
Start a transmission of data frame in DL and UL.
void StartRxData(Ptr< LteSpectrumSignalParametersDataFrame > params)
Start receive data function.
TracedCallback< PhyReceptionStatParameters > m_dlPhyReception
Trace information regarding PHY stats from DL Rx perspective PhyReceptionStatParameters (see lte-comm...
Ptr< NetDevice > m_device
the device
Ptr< SpectrumChannel > GetChannel()
TracedCallback< Ptr< const PacketBurst > > m_phyTxStartTrace
the phy transmit start trace callback
void DoDispose() override
Destructor implementation.
void EndTxData()
End transmit data function.
void SetTransmissionMode(uint8_t txMode)
void SetLtePhyRxDataEndErrorCallback(LtePhyRxDataEndErrorCallback c)
set the callback for the end of a RX in error, as part of the interconnections between the PHY and th...
SpectrumValue m_sinrPerceived
the preceived SINR
Ptr< SpectrumValue > m_txPsd
the transmit PSD
void AddInterferenceDataChunkProcessor(Ptr< LteChunkProcessor > p)
LteChunkProcessor devoted to evaluate interference + noise power in data symbols of the subframe.
void SetDevice(Ptr< NetDevice > d) override
Set the associated NetDevice instance.
void ChangeState(State newState)
Change state function.
void SetTxModeGain(uint8_t txMode, double gain)
Set transmit mode gain function.
std::vector< double > m_txModeGain
duplicate value of LteUePhy
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Ptr< NetDevice > GetDevice() const override
Get the associated NetDevice instance.
Time m_firstRxStart
the first receive start
Ptr< LteHarqPhy > m_harqPhyModule
the HARQ phy module
void SetLtePhyRxDataEndOkCallback(LtePhyRxDataEndOkCallback c)
set the callback for the successful end of a RX, as part of the interconnections between the PHY and ...
void EndRxUlSrs()
End receive UL SRS function.
void SetLtePhyUlHarqFeedbackCallback(LtePhyUlHarqFeedbackCallback c)
set the callback for the UL HARQ feedback as part of the interconnections between the LteSpectrumPhy ...
void SetChannel(Ptr< SpectrumChannel > c) override
Set the channel attached to this device.
void SetComponentCarrierId(uint8_t componentCarrierId)
TracedCallback< Ptr< const PacketBurst > > m_phyRxStartTrace
the phy receive start trace callback
expectedTbs_t m_expectedTbs
the expected TBS
void EndTxUlSrs()
End transmit UL SRS function.
void SetNoisePowerSpectralDensity(Ptr< const SpectrumValue > noisePsd)
set the noise power spectral density
void UpdateSinrPerceived(const SpectrumValue &sinr)
Ptr< SpectrumChannel > m_channel
the channel
void EndRxDlCtrl()
End receive DL control function.
void SetTxPowerSpectralDensity(Ptr< SpectrumValue > txPsd)
set the Power Spectral Density of outgoing signals in W/Hz.
EventId m_endTxEvent
end transmit event
LtePhyRxDataEndOkCallback m_ltePhyRxDataEndOkCallback
the LTE phy receive data end ok callback
void SetLtePhyRxCtrlEndErrorCallback(LtePhyRxCtrlEndErrorCallback c)
set the callback for the erroneous end of a RX ctrl frame, as part of the interconnections between th...
State m_state
the state
uint16_t m_cellId
the cell ID
Ptr< AntennaModel > m_antenna
the antenna model
void SetLtePhyDlHarqFeedbackCallback(LtePhyDlHarqFeedbackCallback c)
set the callback for the DL HARQ feedback as part of the interconnections between the LteSpectrumPhy ...
Time m_firstRxDuration
the first receive duration
Ptr< PacketBurst > m_txPacketBurst
the transmit packet burst
uint8_t m_componentCarrierId
the component carrier ID
void StartRx(Ptr< SpectrumSignalParameters > params) override
Notify the SpectrumPhy instance of an incoming signal.
Ptr< Object > GetAntenna() const override
Get the AntennaModel used by this SpectrumPhy instance for transmission and/or reception.
LtePhyRxDataEndErrorCallback m_ltePhyRxDataEndErrorCallback
the LTE phy receive data end error callback
bool StartTxDlCtrlFrame(std::list< Ptr< LteControlMessage > > ctrlMsgList, bool pss)
Start a transmission of control frame in DL.
static TypeId GetTypeId()
Get the type ID.
uint8_t m_layersNum
layers num
Ptr< MobilityModel > m_mobility
the modility model
TracedCallback< PhyReceptionStatParameters > m_ulPhyReception
Trace information regarding PHY stats from UL Rx perspective PhyReceptionStatParameters (see lte-comm...
void SetMobility(Ptr< MobilityModel > m) override
Set the mobility model associated with this device.
LtePhyDlHarqFeedbackCallback m_ltePhyDlHarqFeedbackCallback
the LTE phy DL HARQ feedback callback
void EndTxDlCtrl()
End transmit DL control function.
std::list< Ptr< LteControlMessage > > m_rxControlMessageList
the receive control message list
void AddRsPowerChunkProcessor(Ptr< LteChunkProcessor > p)
Ptr< LteInterference > m_interferenceCtrl
the control interference
TracedCallback< Ptr< const Packet > > m_phyRxEndErrorTrace
the phy receive end error trace callback
void EndRxData()
End receive data function.
std::list< Ptr< LteControlMessage > > m_txControlMessageList
the transmit control message list
bool m_ctrlErrorModelEnabled
when true (default) the phy error model is enabled for DL ctrl frame
std::list< Ptr< PacketBurst > > m_rxPacketBurstList
the receive burst list
void AddInterferenceCtrlChunkProcessor(Ptr< LteChunkProcessor > p)
LteChunkProcessor devoted to evaluate interference + noise power in control symbols of the subframe.
TracedCallback< Ptr< const Packet > > m_phyRxEndOkTrace
the phy receive end ok trace callback
bool StartTxUlSrsFrame()
Start a transmission of control frame in UL.
LtePhyRxCtrlEndErrorCallback m_ltePhyRxCtrlEndErrorCallback
the LTE phy receive control end error callback
void SetLtePhyRxCtrlEndOkCallback(LtePhyRxCtrlEndOkCallback c)
set the callback for the successful end of a RX ctrl frame, as part of the interconnections between t...
void Reset()
reset the internal state
EventId m_endRxUlSrsEvent
end receive UL SRS event
void SetCellId(uint16_t cellId)
LtePhyRxCtrlEndOkCallback m_ltePhyRxCtrlEndOkCallback
the LTE phy receive control end ok callback
Ptr< UniformRandomVariable > m_random
Provides uniform random variables.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:200
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:353
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
Abstract base class for Spectrum-aware PHY layers.
Definition: spectrum-phy.h:46
Set of values corresponding to a given SpectrumModel.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
int64_t GetMilliSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:407
@ S
second
Definition: nstime.h:116
static uint8_t TxMode2LayerNum(uint8_t txMode)
Transmit mode 2 layer number.
Definition: lte-common.cc:203
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
double GetValue(double min, double max)
Get the next random value drawn from the distribution.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1372
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool operator==(const EventId &a, const EventId &b)
Definition: event-id.h:157
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:129
bool operator<(const EventId &a, const EventId &b)
Definition: event-id.h:170
std::vector< HarqProcessInfoElement_t > HarqProcessInfoList_t
HarqProcessInfoList_t typedef.
Definition: lte-harq-phy.h:44
static const Time DL_CTRL_DURATION
duration of the control portion of a subframe = 0.001 / 14 * 3 (ctrl fixed to 3 symbols) -1ns as marg...
static const Time UL_SRS_DURATION
duration of SRS portion of UL subframe = 1 symbol for SRS -1ns as margin to avoid overlapping simulat...
static const double EffectiveCodingRate[29]
Effective coding rate.
@ IDLE
Channel is IDLE, no packet is being transmitted.
Definition: csma-channel.h:76
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