5#include "nr-spectrum-phy.h"
7#include "nr-chunk-processor.h"
8#include "nr-gnb-net-device.h"
10#include "nr-lte-mi-error-model.h"
11#include "nr-radio-bearer-tag.h"
12#include "nr-ue-net-device.h"
15#include "ns3/boolean.h"
16#include "ns3/double.h"
17#include "ns3/matrix-based-channel-model.h"
19#include "ns3/trace-source-accessor.h"
26NS_LOG_COMPONENT_DEFINE(
"NrSpectrumPhy");
27NS_OBJECT_ENSURE_REGISTERED(NrSpectrumPhy);
56 NS_ABORT_MSG(
"Unknown state.");
64 NS_LOG_FUNCTION(
this);
65 m_interferenceData = CreateObject<NrInterference>();
66 m_interferenceCtrl = CreateObject<NrInterference>();
67 m_random = CreateObject<UniformRandomVariable>();
68 m_random->SetAttribute(
"Min", DoubleValue(0.0));
69 m_random->SetAttribute(
"Max", DoubleValue(1.0));
79 NS_LOG_FUNCTION(
this);
87 if (m_interferenceData)
89 m_interferenceData->Dispose();
92 if (m_interferenceCtrl)
94 m_interferenceCtrl->Dispose();
97 if (m_interferenceSrs)
99 m_interferenceSrs->Dispose();
100 m_interferenceSrs =
nullptr;
103 if (m_interferenceCsiRs)
105 m_interferenceCsiRs->Dispose();
106 m_interferenceCsiRs =
nullptr;
109 if (m_interferenceCsiIm)
111 m_interferenceCsiIm->Dispose();
112 m_interferenceCsiIm =
nullptr;
115 m_interferenceData =
nullptr;
116 m_interferenceCtrl =
nullptr;
117 m_mobility =
nullptr;
119 m_rxSpectrumModel =
nullptr;
122 m_phyRxDataEndOkCallback = MakeNullCallback<void, const Ptr<Packet>&>();
123 m_phyDlHarqFeedbackCallback = MakeNullCallback<void, const DlHarqInfo&>();
124 m_phyUlHarqFeedbackCallback = MakeNullCallback<void, const UlHarqInfo&>();
125 m_phyRxPssCallback = MakeNullCallback<void, uint16_t, const Ptr<SpectrumValue>&>();
127 SpectrumPhy::DoDispose();
134 TypeId(
"ns3::NrSpectrumPhy")
135 .SetParent<SpectrumPhy>()
136 .AddConstructor<NrSpectrumPhy>()
137 .AddAttribute(
"DataErrorModelEnabled",
138 "Activate/Deactivate the error model of data (TBs of PDSCH and PUSCH) "
139 "[by default is active].",
142 MakeBooleanChecker())
143 .AddAttribute(
"ErrorModelType",
144 "Default type of the Error Model to apply to TBs of PDSCH and PUSCH",
150 "Activate/Deactivate unlicensed mode in which energy detection is performed"
151 " and PHY state machine has an additional state CCA_BUSY.",
154 MakeBooleanChecker())
155 .AddAttribute(
"CcaMode1Threshold",
156 "The energy of a received signal should be higher than "
157 "this threshold (dbm) to allow the PHY layer to declare CCA BUSY state.",
161 MakeDoubleChecker<double>())
164 "number of panels to install on UE/ gNB device",
167 MakeUintegerChecker<uint8_t>())
168 .AddTraceSource(
"RxPacketTraceGnb",
169 "The no. of packets received and transmitted by the Base Station",
170 MakeTraceSourceAccessor(&NrSpectrumPhy::m_rxPacketTraceGnb),
171 "ns3::RxPacketTraceParams::TracedCallback")
172 .AddTraceSource(
"TxPacketTraceGnb",
173 "Traces when the packet is being transmitted by the Base Station",
174 MakeTraceSourceAccessor(&NrSpectrumPhy::m_txPacketTraceGnb),
175 "ns3::GnbPhyPacketCountParameter::TracedCallback")
176 .AddTraceSource(
"RxPacketTraceUe",
177 "The no. of packets received and transmitted by the User Device",
178 MakeTraceSourceAccessor(&NrSpectrumPhy::m_rxPacketTraceUe),
179 "ns3::RxPacketTraceParams::TracedCallback")
182 "This traced callback is triggered every time that the channel is occupied",
183 MakeTraceSourceAccessor(&NrSpectrumPhy::m_channelOccupied),
184 "ns3::Time::TracedCallback")
185 .AddTraceSource(
"TxDataTrace",
186 "Indicates when the channel is being occupied by a data transmission",
187 MakeTraceSourceAccessor(&NrSpectrumPhy::m_txDataTrace),
188 "ns3::Time::TracedCallback")
189 .AddTraceSource(
"TxCtrlTrace",
190 "Indicates when the channel is being occupied by a ctrl transmission",
191 MakeTraceSourceAccessor(&NrSpectrumPhy::m_txCtrlTrace),
192 "ns3::Time::TracedCallback")
193 .AddTraceSource(
"RxDataTrace",
194 "Indicates the reception of data from this cell (reporting the rxPsd "
195 "without interferences)",
196 MakeTraceSourceAccessor(&NrSpectrumPhy::m_rxDataTrace),
197 "ns3::RxDataTracedCallback::TracedCallback")
198 .AddTraceSource(
"DlDataSnrTrace",
199 "Report the SNR computed for each TB in DL",
200 MakeTraceSourceAccessor(&NrSpectrumPhy::m_dlDataSnrTrace),
201 "ns3::NrSpectrumPhy::DataSnrTracedCallback")
202 .AddTraceSource(
"DlCtrlPathloss",
203 "Pathloss calculated for CTRL",
204 MakeTraceSourceAccessor(&NrSpectrumPhy::m_dlCtrlPathlossTrace),
205 "ns3::NrSpectrumPhy::DlPathlossTrace")
206 .AddTraceSource(
"DlDataPathloss",
207 "Pathloss calculated for CTRL",
208 MakeTraceSourceAccessor(&NrSpectrumPhy::m_dlDataPathlossTrace),
209 "ns3::NrSpectrumPhy::DlPathlossTrace");
219Ptr<UniformRandomVariable>
226NrSpectrumPhy::GetNrPhy()
const
232NrSpectrumPhy::GetFirstRxStart()
const
234 return m_firstRxStart;
238NrSpectrumPhy::SetFirstRxStart(Time startTime)
240 m_firstRxStart = startTime;
244NrSpectrumPhy::GetFirstRxDuration()
const
246 return m_firstRxDuration;
250NrSpectrumPhy::SetFirstRxDuration(Time duration)
252 m_firstRxDuration = duration;
258 m_activeTransmissions++;
263 Ptr<const SpectrumValue> spectrumValue,
264 const Time& duration,
266 uint16_t cellId)
const
268 m_rxDataTrace(sfn, spectrumValue, duration, bwpId, cellId);
274 m_txCtrlTrace(duration);
280 m_txDataTrace(duration);
288 NS_LOG_FUNCTION(
this);
289 m_phyRxDataEndOkCallback = c;
295 NS_LOG_FUNCTION(
this);
296 m_phyRxCtrlEndOkCallback = c;
302 NS_LOG_FUNCTION(
this);
303 m_phyRxPssCallback = c;
309 NS_LOG_FUNCTION(
this);
310 m_phyDlHarqFeedbackCallback = c;
316 NS_LOG_FUNCTION(
this);
317 m_phyUlHarqFeedbackCallback = c;
322NrSpectrumPhy::SetDevice(Ptr<NetDevice> d)
324 NS_LOG_FUNCTION(
this << d);
337 m_interferenceSrs = CreateObject<NrInterference>();
338 m_interferenceSrs->TraceConnectWithoutContext(
339 "SnrPerProcessedChunk",
344 m_interferenceCsiRs = CreateObject<NrInterference>();
345 m_interferenceCsiIm = CreateObject<NrInterference>();
346 m_interferenceData->TraceConnectWithoutContext(
347 "SnrPerProcessedChunk",
353NrSpectrumPhy::GetDevice()
const
359NrSpectrumPhy::SetMobility(Ptr<MobilityModel> m)
361 NS_LOG_FUNCTION(
this << m);
366NrSpectrumPhy::GetMobility()
const
372NrSpectrumPhy::SetChannel(Ptr<SpectrumChannel> c)
374 NS_LOG_FUNCTION(
this << c);
384Ptr<const SpectrumModel>
385NrSpectrumPhy::GetRxSpectrumModel()
const
387 return m_rxSpectrumModel;
393 NS_LOG_FUNCTION(
this);
394 NS_ASSERT_MSG(m_numPanels == m_antennaPanels.size(),
"mismatch of number of Panels");
396 return m_antennaPanels.at(m_activePanelIndex);
402 NS_LOG_FUNCTION(
this);
403 NS_ASSERT_MSG(m_numPanels == m_antennaPanels.size(),
"mismatch of number of Panels");
404 return m_antennaPanels.at(index);
410 m_numPanels = numPanel;
422NrSpectrumPhy::SetBeamManager(Ptr<BeamManager> b)
424 NS_LOG_FUNCTION(
this << b);
425 m_beamManagers.resize(1);
426 m_beamManagers[0] = b;
432 NS_LOG_FUNCTION(
this << b);
433 m_beamManagers.emplace_back(b);
437NrSpectrumPhy::GetBeamManager()
439 NS_LOG_FUNCTION(
this);
440 NS_ASSERT_MSG(m_numPanels == m_antennaPanels.size(),
"mismatch of number of Panels");
441 return m_beamManagers.at(m_activePanelIndex);
447 NS_LOG_FUNCTION(
this);
448 NS_ASSERT_MSG(m_numPanels == m_antennaPanels.size(),
"mismatch of number of Panels");
450 auto firstPanelBearingAngleRad =
451 (DynamicCast<UniformPlanarArray>(m_antennaPanels[0]))->GetAlpha();
453 for (
auto i = 0; i < m_numPanels; i++)
455 m_antennaPanels[i]->GetObject<UniformPlanarArray>()->SetAlpha(
463 NS_LOG_FUNCTION(
this);
464 NS_ASSERT_MSG(m_numPanels == m_antennaPanels.size(),
"mismatch of number of Panels");
466 for (
auto i = 0; i < m_numPanels; i++)
468 m_antennaPanels[i]->GetObject<UniformPlanarArray>()->SetAlpha(
475 uint8_t panelIndex)
const
478 return firstPanelBearingAngleRad + 2 * M_PI * (panelIndex) / m_numPanels;
482NrSpectrumPhy::SetErrorModel(Ptr<NrErrorModel> em)
484 NS_LOG_FUNCTION(
this << em);
489NrSpectrumPhy::GetErrorModel()
const
495NrSpectrumPhy::EnableDlDataPathlossTrace()
497 NS_LOG_FUNCTION(
this);
498 m_enableDlDataPathlossTrace =
true;
502NrSpectrumPhy::EnableDlCtrlPathlossTrace()
504 NS_LOG_FUNCTION(
this);
505 m_enableDlCtrlPathlossTrace =
true;
511 NS_LOG_FUNCTION(
this << rnti);
525 NS_LOG_FUNCTION(
this << thresholdDBm);
527 m_ccaMode1ThresholdW = (std::pow(10.0, thresholdDBm / 10.0)) / 1000.0;
534 return 10.0 * std::log10(m_ccaMode1ThresholdW * 1000.0);
540 NS_LOG_FUNCTION(
this << unlicensedMode);
541 m_unlicensedMode = unlicensedMode;
547 NS_LOG_FUNCTION(
this << dataErrorModelEnabled);
548 m_dataErrorModelEnabled = dataErrorModelEnabled;
554 NS_LOG_FUNCTION(
this << errorModelType.GetName());
555 m_errorModelType = errorModelType;
563 NS_LOG_FUNCTION(
this << noisePsd);
565 m_rxSpectrumModel = noisePsd->GetSpectrumModel();
566 m_interferenceData->SetNoisePowerSpectralDensity(noisePsd);
567 m_interferenceCtrl->SetNoisePowerSpectralDensity(noisePsd);
568 if (m_interferenceSrs)
570 m_interferenceSrs->SetNoisePowerSpectralDensity(noisePsd);
572 if (m_interferenceCsiRs)
574 m_interferenceCsiRs->SetNoisePowerSpectralDensity(noisePsd);
575 m_interferenceCsiIm->SetNoisePowerSpectralDensity(noisePsd);
582 NS_LOG_FUNCTION(
this << TxPsd);
586Ptr<const SpectrumValue>
587NrSpectrumPhy::GetTxPowerSpectralDensity()
592Ptr<MatrixBasedChannelModel::Complex3DVector>
593NrSpectrumPhy::CreateSpectrumChannelMatrix(
const Ptr<SpectrumSignalParameters> params)
const
595 auto txAntenna = DynamicCast<PhasedArrayModel>(params->txPhy->GetAntenna());
596 auto rxAntenna = DynamicCast<PhasedArrayModel>(
GetAntenna());
597 NS_ABORT_MSG_UNLESS(txAntenna && rxAntenna,
"Only phased antenna array models are supported.");
599 auto txAntennaPorts = txAntenna->GetNumPorts();
600 auto rxAntennaPorts = rxAntenna->GetNumPorts();
601 NS_ASSERT_MSG(txAntennaPorts == 1 && rxAntennaPorts == 1,
602 "The conversion only fits to a single antenna port in Tx and Rx");
604 Ptr<const SpectrumValue> rxPsd = params->psd;
605 Ptr<const SpectrumValue> txPsd =
606 DynamicCast<NrSpectrumPhy>(params->txPhy)->GetTxPowerSpectralDensity();
607 uint32_t nRb = rxPsd->GetValuesN();
608 Ptr<MatrixBasedChannelModel::Complex3DVector> channelSpct =
609 Create<MatrixBasedChannelModel::Complex3DVector>(rxAntennaPorts, txAntennaPorts, nRb);
610 auto rxRb = rxPsd->ConstValuesBegin();
611 auto txRb = txPsd->ConstValuesBegin();
613 while (rxRb != rxPsd->ConstValuesEnd() && txRb != txPsd->ConstValuesEnd())
615 if (*rxRb != 0.0 && *txRb != 0.0)
617 auto sqrtvit = sqrt(*rxRb / *txRb);
618 for (
size_t u = 0; u < rxAntennaPorts; u++)
620 for (
size_t s = 0; s < txAntennaPorts; s++)
622 channelSpct->Elem(u, s, iRb) = sqrtvit;
636 NS_LOG_FUNCTION(
this);
637 Ptr<const SpectrumValue> rxPsd = params->psd;
638 Time duration = params->duration;
639 NS_LOG_INFO(
"Start receiving signal: " << params->psd <<
" duration= " << duration);
642 if (!params->spectrumChannelMatrix &&
645 params->spectrumChannelMatrix = CreateSpectrumChannelMatrix(params);
649 m_interferenceData->AddSignalMimo(params, duration);
652 if (m_interferenceSrs)
654 m_interferenceSrs->AddSignalMimo(params, duration);
657 Ptr<NrSpectrumSignalParametersDataFrame> nrDataRxParams =
658 DynamicCast<NrSpectrumSignalParametersDataFrame>(params);
660 Ptr<NrSpectrumSignalParametersDlCtrlFrame> dlCtrlRxParams =
661 DynamicCast<NrSpectrumSignalParametersDlCtrlFrame>(params);
663 Ptr<NrSpectrumSignalParametersUlCtrlFrame> ulCtrlRxParams =
664 DynamicCast<NrSpectrumSignalParametersUlCtrlFrame>(params);
666 Ptr<NrSpectrumSignalParametersCsiRs> csiRsRxParams =
667 DynamicCast<NrSpectrumSignalParametersCsiRs>(params);
671 if (m_interferenceCsiIm && m_interferenceCsiIm->IsChunkProcessorSet() &&
672 nrDataRxParams->cellId != m_phy->GetCellId())
674 m_interferenceCsiIm->AddSignalMimo(params, duration);
677 if (nrDataRxParams->cellId ==
GetCellId())
682 auto isIntendedRx = (nrDataRxParams->rnti == m_rnti) || !m_hasRnti;
686 StartRxData(nrDataRxParams);
688 if (!m_isGnb and m_enableDlDataPathlossTrace)
690 Ptr<const SpectrumValue> txPsd =
691 DynamicCast<NrSpectrumPhy>(nrDataRxParams->txPhy)->GetTxPowerSpectralDensity();
692 Ptr<const SpectrumValue> rxPsd = nrDataRxParams->psd;
694 m_dlDataPathloss = 10 * log10(Integral(*txPsd)) - 10 * log10(Integral(*rxPsd));
699 NS_LOG_INFO(
" Received DATA not in sync with this signal (cellId="
700 << nrDataRxParams->cellId <<
", m_cellId=" <<
GetCellId() <<
")");
703 else if (dlCtrlRxParams !=
nullptr)
705 m_interferenceCtrl->AddSignalMimo(params, duration);
709 if (dlCtrlRxParams->pss)
711 if (dlCtrlRxParams->cellId ==
GetCellId())
714 "Receiving PSS from Serving Cell with Id: " << dlCtrlRxParams->cellId);
719 "Receiving PSS from Neighbor Cell with Id: " << dlCtrlRxParams->cellId);
722 if (!m_phyRxPssCallback.IsNull())
724 m_phyRxPssCallback(dlCtrlRxParams->cellId, dlCtrlRxParams->psd);
728 if (dlCtrlRxParams->cellId ==
GetCellId())
730 m_interferenceCtrl->StartRxMimo(params);
731 StartRxDlCtrl(dlCtrlRxParams);
733 if (m_enableDlCtrlPathlossTrace)
735 Ptr<const SpectrumValue> txPsd =
736 DynamicCast<NrSpectrumPhy>(dlCtrlRxParams->txPhy)
737 ->GetTxPowerSpectralDensity();
738 Ptr<const SpectrumValue> rxPsd = dlCtrlRxParams->psd;
739 double pathloss = 10 * log10(Integral(*txPsd)) - 10 * log10(Integral(*rxPsd));
742 GetMobility()->GetObject<Node>()->GetId(),
748 NS_LOG_INFO(
"Received DL CTRL, but not in sync with this signal (cellId="
749 << dlCtrlRxParams->cellId <<
", m_cellId=" <<
GetCellId() <<
")");
754 NS_LOG_DEBUG(
"DL CTRL ignored at gNB");
757 else if (ulCtrlRxParams !=
nullptr)
761 if (ulCtrlRxParams->cellId ==
GetCellId())
763 if (IsOnlySrs(ulCtrlRxParams->ctrlMsgList))
765 StartRxSrs(ulCtrlRxParams);
769 StartRxUlCtrl(ulCtrlRxParams);
774 NS_LOG_INFO(
"Received UL CTRL, but not in sync with this signal (cellId="
775 << ulCtrlRxParams->cellId <<
", m_cellId=" <<
GetCellId() <<
")");
780 NS_LOG_DEBUG(
"UL CTRL ignored at UE device");
783 else if (csiRsRxParams !=
nullptr)
785 if (m_hasRnti && csiRsRxParams->cellId ==
GetCellId())
787 StartRxCsiRs(csiRsRxParams);
792 NS_LOG_INFO(
"Received non-nr signal of duration:" << duration);
798 if (m_unlicensedMode && m_state ==
IDLE)
806 const std::list<Ptr<NrControlMessage>>& ctrlMsgList,
807 const std::shared_ptr<DciInfoElementTdma> dci,
808 const Time& duration)
810 NS_LOG_FUNCTION(
this);
823 NS_FATAL_ERROR(
"Cannot TX while RX.");
829 NS_LOG_WARN(
"Start transmitting DATA while in CCA_BUSY state.");
837 Ptr<NrSpectrumSignalParametersDataFrame> txParams =
838 Create<NrSpectrumSignalParametersDataFrame>();
839 txParams->duration = duration;
840 txParams->txPhy = this->GetObject<SpectrumPhy>();
841 txParams->psd = m_txPsd;
842 txParams->packetBurst = pb;
844 txParams->ctrlMsgList = ctrlMsgList;
845 txParams->rnti = dci->m_rnti;
846 txParams->precodingMatrix = dci->m_precMats;
852 traceParam.m_noBytes = (txParams->packetBurst) ? txParams->packetBurst->GetSize() : 0;
853 traceParam.m_cellId = txParams->cellId;
854 traceParam.m_isTx =
true;
855 traceParam.m_subframeno = 0;
857 m_txPacketTraceGnb(traceParam);
860 m_txDataTrace(duration);
864 m_channel->StartTx(txParams);
868 NS_LOG_WARN(
"Working without channel (i.e., under test)");
872 m_activeTransmissions++;
876 NS_LOG_FUNCTION(
this <<
"Programming Error. Code should not reach this point");
883 return m_state ==
TX;
888 const Time& duration)
890 NS_LOG_FUNCTION(
this << duration.As(Time::S));
891 NS_LOG_LOGIC(
this <<
" state: " << m_state);
902 NS_FATAL_ERROR(
"Cannot TX while RX.");
905 NS_FATAL_ERROR(
"Cannot TX while already TX.");
908 NS_LOG_WARN(
"Start transmitting DL CTRL while in CCA_BUSY state.");
913 Ptr<NrSpectrumSignalParametersDlCtrlFrame> txParams =
914 Create<NrSpectrumSignalParametersDlCtrlFrame>();
915 txParams->duration = duration;
916 txParams->txPhy = GetObject<SpectrumPhy>();
917 txParams->psd = m_txPsd;
919 txParams->pss =
true;
920 txParams->ctrlMsgList = ctrlMsgList;
922 m_txCtrlTrace(duration);
925 m_channel->StartTx(txParams);
929 NS_LOG_WARN(
"Working without channel (i.e., under test)");
933 m_activeTransmissions++;
941 NS_LOG_LOGIC(
this <<
" state: " << m_state);
944 Time duration = NanoSeconds(1);
955 NS_FATAL_ERROR(
"Cannot TX while RX.");
958 NS_FATAL_ERROR(
"Cannot TX while already TX.");
961 NS_LOG_WARN(
"Start transmitting CSI-RS while in CCA_BUSY state.");
965 Ptr<NrSpectrumSignalParametersCsiRs> csiRs = Create<NrSpectrumSignalParametersCsiRs>();
966 csiRs->duration = duration;
967 csiRs->txPhy = GetObject<SpectrumPhy>();
968 csiRs->psd = m_txPsd;
971 csiRs->beamId = beamId;
975 NS_LOG_DEBUG(
"gNB with cellId " <<
GetCellId()
976 <<
" transmitting CSI-RS for RNTI:" << csiRs->rnti);
977 m_channel->StartTx(csiRs);
981 NS_LOG_WARN(
"Working without channel (i.e., under test)");
989 const Time& duration)
991 NS_LOG_FUNCTION(
this << duration.As(Time::S));
992 NS_LOG_LOGIC(
this <<
" state: " << m_state);
1003 NS_FATAL_ERROR(
"Cannot TX while RX.");
1006 NS_FATAL_ERROR(
"Cannot TX while already TX.");
1009 NS_LOG_WARN(
"Start transmitting UL CTRL while in CCA_BUSY state");
1014 Ptr<NrSpectrumSignalParametersUlCtrlFrame> txParams =
1015 Create<NrSpectrumSignalParametersUlCtrlFrame>();
1016 txParams->duration = duration;
1017 txParams->txPhy = GetObject<SpectrumPhy>();
1018 txParams->psd = m_txPsd;
1020 txParams->ctrlMsgList = ctrlMsgList;
1022 m_txCtrlTrace(duration);
1025 m_channel->StartTx(txParams);
1029 NS_LOG_WARN(
"Working without channel (i.e., under test)");
1032 m_activeTransmissions++;
1040 NS_LOG_FUNCTION(
this << p);
1041 m_interferenceData->AddRsPowerChunkProcessor(p);
1047 NS_LOG_FUNCTION(
this);
1048 m_interferenceData->AddSinrChunkProcessor(p);
1052NrSpectrumPhy::AddSrsSinrChunkProcessor(
const Ptr<NrChunkProcessor>& p)
1054 NS_LOG_FUNCTION(
this);
1055 NS_ASSERT_MSG(m_isGnb && m_interferenceSrs,
1056 "SRS interference object does not exist or this device is not gNb so the "
1057 "function should not be called.");
1058 m_interferenceSrs->AddSinrChunkProcessor(p);
1064 NS_LOG_FUNCTION(
this);
1065 Ptr<NrUePhy> phy = (DynamicCast<NrUePhy>(m_phy));
1066 NS_ABORT_MSG_UNLESS(
1068 "This function should only be called for NrSpectrumPhy belonging to NrUEPhy");
1069 phy->ReportDlCtrlSinr(sinr);
1075 NS_LOG_FUNCTION(
this << srsSinr);
1076 NS_LOG_INFO(
"Update SRS SINR perceived with this value: " << srsSinr);
1078 for (
auto& srsCallback : m_srsSinrReportCallback)
1082 Sum(srsSinr) / (srsSinr.GetSpectrumModel()->GetNumBands()));
1089 NS_LOG_FUNCTION(
this << srsSnr);
1090 NS_LOG_INFO(
"Update SRS SNR perceived with this value: " << srsSnr);
1092 for (
auto& srsSnrCallback : m_srsSnrReportCallback)
1094 srsSnrCallback(
GetCellId(), m_currentSrsRnti, srsSnr);
1101 NS_LOG_FUNCTION(
this);
1102 m_interferenceCtrl->AddRsPowerChunkProcessor(p);
1108 NS_LOG_FUNCTION(
this);
1109 m_interferenceCtrl->AddSinrChunkProcessor(p);
1115 NS_LOG_FUNCTION(
this << sinr);
1116 NS_LOG_INFO(
"Update SINR perceived with this value: " << sinr);
1117 m_sinrPerceived = sinr;
1127NrSpectrumPhy::GetPhy()
const
1135 m_antennaPanels.resize(1);
1136 m_antennaPanels[0] = antenna;
1142 m_antennaPanels.emplace_back(antenna);
1148 m_activePanelIndex = panelIndex;
1160 NS_LOG_FUNCTION(
this);
1161 return m_interferenceData;
1167 NS_LOG_FUNCTION(
this);
1171 NS_ASSERT_MSG(m_hasRnti,
"Cannot send TB to a UE whose RNTI has not been set");
1172 NS_ASSERT_MSG(m_rnti == expectedTb.
m_rnti,
1173 "RNTI of the receiving UE must match the RNTI of the TB");
1176 auto it = m_transportBlocks.find(expectedTb.
m_rnti);
1177 if (it != m_transportBlocks.end())
1180 m_transportBlocks.erase(it);
1183 m_transportBlocks.emplace(expectedTb.
m_rnti, expectedTb);
1184 NS_LOG_INFO(
"Add expected TB for rnti "
1186 <<
" mcs=" <<
static_cast<uint32_t
>(expectedTb.
m_mcs)
1187 <<
" symstart=" <<
static_cast<uint32_t
>(expectedTb.
m_symStart)
1188 <<
" numSym=" <<
static_cast<uint32_t
>(expectedTb.
m_numSym));
1192NrSpectrumPhy::AddExpectedSrsRnti(uint16_t rnti)
1194 m_currentSrsRnti = rnti;
1200 m_srsSinrReportCallback.push_back(callback);
1206 m_srsSnrReportCallback.push_back(callback);
1212NrSpectrumPhy::StartRxData(
const Ptr<NrSpectrumSignalParametersDataFrame>& params)
1214 NS_LOG_FUNCTION(
this);
1216 m_rxDataTrace(m_phy->GetCurrentSfnSf(),
1220 m_phy->GetCellId());
1228 NS_FATAL_ERROR(
"gNB transmission overlaps in time with UE transmission. CellId:"
1237 NS_ASSERT_MSG((Sum((*m_txPsd) * (*params->psd)) == 0),
1238 "Transmissions overlap in frequency. Their cellId is:" << params->cellId);
1247 NS_FATAL_ERROR(
"Cannot receive DATA while receiving CTRL.");
1250 NS_LOG_INFO(
"Start receiving DATA while in CCA_BUSY state.");
1256 m_interferenceData->StartRxMimo(params);
1258 if (m_rxPacketBurstList.empty())
1262 m_firstRxStart = Simulator::Now();
1263 m_firstRxDuration = params->duration;
1264 NS_LOG_LOGIC(
this <<
" scheduling EndRx with delay " << params->duration.GetSeconds()
1267 Simulator::Schedule(params->duration, &NrSpectrumPhy::EndRxData,
this);
1271 NS_ASSERT(m_state ==
RX_DATA);
1276 NS_ASSERT((m_firstRxStart == Simulator::Now()) &&
1277 (m_firstRxDuration == params->duration));
1282 if (params->packetBurst && !params->packetBurst->GetPackets().empty())
1284 m_rxPacketBurstList.push_back(params->packetBurst);
1287 m_rxControlMessageList.insert(m_rxControlMessageList.end(),
1288 params->ctrlMsgList.begin(),
1289 params->ctrlMsgList.end());
1291 NS_LOG_LOGIC(
this <<
" numSimultaneousRxEvents = " << m_rxPacketBurstList.size());
1295 NS_FATAL_ERROR(
"Programming Error: Unknown State");
1300NrSpectrumPhy::StartRxDlCtrl(
const Ptr<NrSpectrumSignalParametersDlCtrlFrame>& params)
1306 NS_LOG_FUNCTION(
this);
1307 NS_ASSERT(params->cellId ==
GetCellId() && !m_isGnb);
1312 NS_FATAL_ERROR(
"Cannot RX while TX.");
1315 NS_FATAL_ERROR(
"Cannot RX CTRL while receiving DATA.");
1318 NS_FATAL_ERROR(
"Cannot RX DL CTRL while already receiving DL CTRL.");
1323 NS_FATAL_ERROR(
"UE should never be in RX_UL_CTRL or RX_UL_SRS state.");
1326 NS_LOG_INFO(
"Start receiving CTRL while channel in CCA_BUSY state.");
1329 NS_ASSERT(m_rxControlMessageList.empty());
1330 NS_LOG_LOGIC(
this <<
"receiving DL CTRL from cellId:" << params->cellId
1331 <<
"and scheduling EndRx with delay " << params->duration);
1333 m_rxControlMessageList = params->ctrlMsgList;
1334 Simulator::Schedule(params->duration, &NrSpectrumPhy::EndRxCtrl,
this);
1339 NS_FATAL_ERROR(
"Unknown state.");
1346NrSpectrumPhy::StartRxUlCtrl(
const Ptr<NrSpectrumSignalParametersUlCtrlFrame>& params)
1352 NS_LOG_FUNCTION(
this);
1353 NS_ASSERT(params->cellId ==
GetCellId() && m_isGnb);
1358 NS_FATAL_ERROR(
"Cannot RX UL CTRL while TX.");
1361 NS_FATAL_ERROR(
"Cannot RX UL CTRL while receiving DATA.");
1364 NS_FATAL_ERROR(
"Cannot start RX UL CTRL while already receiving SRS.");
1367 NS_FATAL_ERROR(
"gNB should not be in RX_DL_CTRL state.");
1370 NS_LOG_INFO(
"Start receiving UL CTRL while channel in CCA_BUSY state.");
1379 NS_ASSERT(m_rxControlMessageList.empty());
1380 m_firstRxStart = Simulator::Now();
1381 m_firstRxDuration = params->duration;
1382 NS_LOG_LOGIC(
this <<
" scheduling EndRx with delay " << params->duration);
1384 m_rxControlMessageList = params->ctrlMsgList;
1385 Simulator::Schedule(params->duration, &NrSpectrumPhy::EndRxCtrl,
this);
1390 NS_ASSERT((m_firstRxStart == Simulator::Now()) &&
1391 (m_firstRxDuration == params->duration));
1392 m_rxControlMessageList.insert(m_rxControlMessageList.end(),
1393 params->ctrlMsgList.begin(),
1394 params->ctrlMsgList.end());
1399 NS_FATAL_ERROR(
"unknown state");
1406NrSpectrumPhy::StartRxSrs(
const Ptr<NrSpectrumSignalParametersUlCtrlFrame>& params)
1408 NS_LOG_FUNCTION(
this);
1416 params->ctrlMsgList.size() == 1 &&
1422 NS_FATAL_ERROR(
"Cannot RX SRS while TX.");
1425 NS_FATAL_ERROR(
"Cannot RX SRS while receiving DATA.");
1428 NS_FATAL_ERROR(
"gNB should not be in RX_DL_CTRL state.");
1432 "gNB should not receive simultaneously non SRS and SRS uplink control signals");
1435 NS_LOG_INFO(
"Start receiving UL SRS while channel in CCA_BUSY state.");
1440 m_interferenceSrs->StartRxMimo(params);
1443 NS_ASSERT(m_rxControlMessageList.empty());
1444 m_firstRxStart = Simulator::Now();
1445 m_firstRxDuration = params->duration;
1446 NS_LOG_LOGIC(
this <<
" scheduling EndRx for SRS signal reception with delay "
1447 << params->duration);
1449 m_rxControlMessageList = params->ctrlMsgList;
1450 Simulator::Schedule(params->duration, &NrSpectrumPhy::EndRxSrs,
this);
1456 NS_FATAL_ERROR(
"Not allowed state for starting SRS reception.");
1465 return m_phy->GetCellId();
1471 return m_phy->GetBwpId();
1489 NS_LOG_LOGIC(
this <<
" change state: " << m_state <<
" -> " << newState);
1495 m_channelOccupied(duration);
1502 NS_LOG_FUNCTION(
this);
1506 NS_ASSERT_MSG(m_state ==
TX,
"In EndTx() but state is not TX; state: " << m_state);
1507 NS_LOG_DEBUG(
"Number of active transmissions (before decrement): " << m_activeTransmissions);
1508 NS_ASSERT_MSG(m_activeTransmissions,
"Ending Tx but no active transmissions");
1509 m_activeTransmissions--;
1512 if (m_activeTransmissions == 0)
1515 if (m_unlicensedMode)
1526std::vector<MimoSinrChunk>
1527NrSpectrumPhy::GetMimoSinrForRnti(uint16_t rnti, uint8_t rank)
1532 std::vector<MimoSinrChunk> res;
1533 for (
const auto& chunk : m_mimoSinrPerceived)
1535 if (chunk.rnti == rnti)
1537 res.emplace_back(chunk);
1543 NS_LOG_WARN(
"Did not find any SINR matrix matching the current UE's RNTI " << rnti);
1544 auto sinrMat = NrSinrMatrix{rank, m_rxSpectrumModel->GetNumBands()};
1545 auto dur = NanoSeconds(1);
1546 res.emplace_back(MimoSinrChunk{sinrMat, rnti, dur});
1558 m_sinrAvg += perceivedSinr.ValuesAt(rbIndex);
1559 if (perceivedSinr.ValuesAt(rbIndex) <
m_sinrMin)
1561 m_sinrMin = perceivedSinr.ValuesAt(rbIndex);
1568 <<
" SinrAvg (dB) " << 10 * log(
m_sinrAvg) / log(10));
1572NrSpectrumPhy::CheckTransportBlockCorruptionStatus()
1574 for (
auto& tbIt : m_transportBlocks)
1576 auto rnti = tbIt.first;
1577 auto& tbInfo = tbIt.second;
1579 tbInfo.UpdatePerceivedSinr(m_sinrPerceived);
1581 if ((!m_dataErrorModelEnabled) || (m_rxPacketBurstList.empty()))
1589 tbInfo.m_expected.m_harqProcessId);
1592 "The error model must be a child of NrErrorModel");
1596 ObjectFactory emFactory;
1597 emFactory.SetTypeId(m_errorModelType);
1598 m_errorModel = DynamicCast<NrErrorModel>(emFactory.Create());
1599 NS_ABORT_IF(m_errorModel ==
nullptr);
1605 if (!m_mimoSinrPerceived.empty())
1608 const auto& expectedTb = tbInfo.m_expected;
1609 auto sinrChunks = GetMimoSinrForRnti(expectedTb.m_rnti, expectedTb.m_rank);
1610 NS_ASSERT(!sinrChunks.empty());
1612 tbInfo.m_outputOfEM = m_errorModel->GetTbDecodificationStatsMimo(sinrChunks,
1613 expectedTb.m_rbBitmap,
1614 expectedTb.m_tbSize,
1624 tbInfo.m_outputOfEM =
1625 m_errorModel->GetTbDecodificationStats(m_sinrPerceived,
1626 tbInfo.m_expected.m_rbBitmap,
1627 tbInfo.m_expected.m_tbSize,
1628 tbInfo.m_expected.m_mcs,
1632 tbInfo.m_isCorrupted = m_random->GetValue() <= tbInfo.m_outputOfEM->m_tbler;
1634 if (tbInfo.m_isCorrupted)
1637 "RNTI " << rnti <<
" processId " << +tbInfo.m_expected.m_harqProcessId <<
" size "
1638 << tbInfo.m_expected.m_tbSize <<
" mcs "
1639 << (uint32_t)tbInfo.m_expected.m_mcs <<
"rank" << +tbInfo.m_expected.m_rank
1640 <<
" bitmap " << tbInfo.m_expected.m_rbBitmap.size()
1641 <<
" rv from MAC: " << +tbInfo.m_expected.m_rv
1642 <<
" elements in the history: " << harqInfoList.size() <<
" TBLER "
1643 << tbInfo.m_outputOfEM->m_tbler <<
" corrupted " << tbInfo.m_isCorrupted);
1649NrSpectrumPhy::SendUlHarqFeedback(uint16_t rnti, TransportBlockInfo& tbInfo)
1652 UlHarqInfo harqUlInfo;
1653 harqUlInfo.m_rnti = rnti;
1654 harqUlInfo.m_tpc = 0;
1655 harqUlInfo.m_harqProcessId = tbInfo.m_expected.m_harqProcessId;
1656 harqUlInfo.m_numRetx = tbInfo.m_expected.m_rv;
1657 if (tbInfo.m_isCorrupted)
1659 harqUlInfo.m_receptionStatus = UlHarqInfo::NotOk;
1663 harqUlInfo.m_receptionStatus = UlHarqInfo::Ok;
1667 m_phyUlHarqFeedbackCallback(harqUlInfo);
1670 if (!tbInfo.m_isCorrupted || tbInfo.m_expected.m_rv == 3)
1677 tbInfo.m_expected.m_harqProcessId,
1678 tbInfo.m_outputOfEM);
1683NrSpectrumPhy::SendDlHarqFeedback(uint16_t rnti, TransportBlockInfo& tbInfo)
1686 DlHarqInfo harqDlInfo;
1687 harqDlInfo.m_rnti = rnti;
1688 harqDlInfo.m_harqProcessId = tbInfo.m_expected.m_harqProcessId;
1689 harqDlInfo.m_numRetx = tbInfo.m_expected.m_rv;
1690 harqDlInfo.m_bwpIndex =
GetBwpId();
1691 if (tbInfo.m_isCorrupted)
1697 harqDlInfo.m_harqStatus = DlHarqInfo::ACK;
1701 m_phyDlHarqFeedbackCallback(harqDlInfo);
1704 if (!tbInfo.m_isCorrupted || tbInfo.m_expected.m_rv == 3)
1706 NS_LOG_DEBUG(
"Reset Dl process: " << +tbInfo.m_expected.m_harqProcessId <<
" for RNTI "
1712 NS_LOG_DEBUG(
"Update Dl process: " << +tbInfo.m_expected.m_harqProcessId <<
" for RNTI "
1715 tbInfo.m_expected.m_harqProcessId,
1716 tbInfo.m_outputOfEM);
1722NrSpectrumPhy::ProcessReceivedPacketBurst()
1724 NS_LOG_FUNCTION(
this);
1725 Ptr<NrGnbNetDevice> gnbRx = DynamicCast<NrGnbNetDevice>(GetDevice());
1726 Ptr<NrUeNetDevice> ueRx = DynamicCast<NrUeNetDevice>(GetDevice());
1727 std::map<uint16_t, DlHarqInfo> harqDlInfoMap;
1728 for (
auto packetBurst : m_rxPacketBurstList)
1730 for (
auto packet : packetBurst->GetPackets())
1732 if (packet->GetSize() == 0)
1737 NrRadioBearerTag bearerTag;
1738 if (!packet->PeekPacketTag(bearerTag))
1740 NS_FATAL_ERROR(
"No radio bearer tag found");
1742 uint16_t rnti = bearerTag.GetRnti();
1744 auto itTb = m_transportBlocks.find(rnti);
1745 if (itTb == m_transportBlocks.end())
1750 auto& tbInfo = itTb->second;
1752 if (!tbInfo.m_isCorrupted)
1754 m_phyRxDataEndOkCallback(packet);
1758 NS_LOG_INFO(
"TB failed");
1763 RxPacketTraceParams traceParams(tbInfo,
1764 m_dataErrorModelEnabled,
1769 m_rxPacketTraceGnb(traceParams);
1773 Ptr<NrUePhy> phy = (DynamicCast<NrUePhy>(m_phy));
1774 uint8_t cqi = phy->ComputeCqi(m_sinrPerceived);
1775 RxPacketTraceParams traceParams(tbInfo,
1776 m_dataErrorModelEnabled,
1778 ueRx->GetTargetGnb()->GetCellId(),
1781 m_rxPacketTraceUe(traceParams);
1783 if (m_enableDlDataPathlossTrace)
1787 GetMobility()->GetObject<Node>()->GetId(),
1794 if (!tbInfo.m_harqFeedbackSent)
1796 tbInfo.m_harqFeedbackSent =
true;
1797 if (tbInfo.m_expected.m_isDownlink)
1799 NS_ASSERT(harqDlInfoMap.find(rnti) == harqDlInfoMap.end());
1800 auto harqDlInfo = SendDlHarqFeedback(rnti, tbInfo);
1801 harqDlInfoMap.insert(std::make_pair(rnti, harqDlInfo));
1805 SendUlHarqFeedback(rnti, tbInfo);
1813NrSpectrumPhy::EndRxData()
1815 NS_LOG_FUNCTION(
this);
1816 m_interferenceData->EndRx();
1818 NS_ASSERT(m_state ==
RX_DATA);
1821 CheckTransportBlockCorruptionStatus();
1824 ProcessReceivedPacketBurst();
1827 if (!m_rxControlMessageList.empty() && m_phyRxCtrlEndOkCallback)
1829 m_phyRxCtrlEndOkCallback(m_rxControlMessageList,
GetBwpId());
1834 if (m_unlicensedMode)
1843 m_rxPacketBurstList.clear();
1844 m_transportBlocks.clear();
1845 m_rxControlMessageList.clear();
1849NrSpectrumPhy::EndRxCtrl()
1851 NS_LOG_FUNCTION(
this);
1854 m_interferenceCtrl->EndRx();
1858 if (!m_rxControlMessageList.empty())
1860 if (m_phyRxCtrlEndOkCallback)
1862 m_phyRxCtrlEndOkCallback(m_rxControlMessageList,
GetBwpId());
1867 if (m_unlicensedMode)
1876 m_rxControlMessageList.clear();
1880NrSpectrumPhy::EndRxSrs()
1882 NS_LOG_FUNCTION(
this);
1883 NS_ASSERT(m_state ==
RX_UL_SRS && m_rxControlMessageList.size() == 1);
1888 m_interferenceSrs->EndRx();
1890 if (m_phyRxCtrlEndOkCallback)
1892 m_phyRxCtrlEndOkCallback(m_rxControlMessageList,
GetBwpId());
1896 if (m_unlicensedMode)
1905 m_rxControlMessageList.clear();
1909NrSpectrumPhy::MaybeCcaBusy()
1911 NS_LOG_FUNCTION(
this);
1912 Time delayUntilCcaEnd = m_interferenceData->GetEnergyDuration(m_ccaMode1ThresholdW);
1913 if (!delayUntilCcaEnd.IsZero())
1915 NS_LOG_DEBUG(
"Channel detected BUSY for:" << delayUntilCcaEnd <<
" ns.");
1920 if (m_busyTimeEnds < Simulator::Now() + delayUntilCcaEnd)
1922 m_busyTimeEnds = Simulator::Now() + delayUntilCcaEnd;
1924 if (m_checkIfIsIdleEvent.IsPending())
1926 m_checkIfIsIdleEvent.Cancel();
1929 NS_LOG_DEBUG(
"Check if still BUSY in:" << delayUntilCcaEnd
1930 <<
" us, and that is at "
1932 << Simulator::Now() + delayUntilCcaEnd
1933 <<
" and current time is:" << Simulator::Now());
1935 m_checkIfIsIdleEvent =
1936 Simulator::Schedule(delayUntilCcaEnd, &NrSpectrumPhy::CheckIfStillBusy,
this);
1941 NS_ABORT_MSG_IF(m_checkIfIsIdleEvent.IsPending(),
1942 "Unexpected state: returning to IDLE while there is an event "
1943 "running that should switch from CCA_BUSY to IDLE ?!");
1944 NS_LOG_DEBUG(
"Channel detected IDLE after being in: " << m_state <<
" state.");
1950NrSpectrumPhy::CheckIfStillBusy()
1952 NS_LOG_FUNCTION(
this);
1953 NS_ABORT_MSG_IF(m_state ==
IDLE,
"This function should not be called when in IDLE state.");
1962 Time delayUntilCcaEnd = m_interferenceData->GetEnergyDuration(m_ccaMode1ThresholdW);
1964 if (delayUntilCcaEnd.IsZero())
1966 NS_LOG_INFO(
" Channel found IDLE as expected.");
1970 NS_LOG_INFO(
" Wait while channel BUSY for: " << delayUntilCcaEnd <<
" ns.");
1976NrSpectrumPhy::IsOnlySrs(
const std::list<Ptr<NrControlMessage>>& ctrlMsgList)
1978 NS_ASSERT_MSG(!ctrlMsgList.empty(),
"Passed an empty uplink control list");
1980 return ctrlMsgList.size() == 1 &&
1987 NS_LOG_FUNCTION(
this << dlDataSnr);
1989 Ptr<NrUeNetDevice> ueNetDevice = DynamicCast<NrUeNetDevice>(GetDevice());
1991 m_dlDataSnrTrace(m_phy->GetCurrentSfnSf(),
1994 ueNetDevice->GetImsi(),
2001 NS_LOG_FUNCTION(
this << stream);
2002 m_random->SetStream(stream);
2009 m_mimoSinrPerceived = mimoChunks;
2015 NS_LOG_FUNCTION(
this);
2016 m_interferenceData->AddMimoChunkProcessor(p);
2022 NS_LOG_FUNCTION(
this);
2023 m_interferenceCsiRs->AddMimoChunkProcessor(p);
2029 NS_LOG_FUNCTION(
this);
2030 m_interferenceCsiIm->AddMimoChunkProcessor(p);
2034NrSpectrumPhy::StartRxCsiRs(
const Ptr<NrSpectrumSignalParametersCsiRs>& csiRsParams)
2037 if (csiRsParams->rnti == m_rnti)
2040 m_interferenceCsiRs->AddSignalMimo(csiRsParams, csiRsParams->duration);
2042 m_interferenceCsiRs->StartRxMimo(csiRsParams);
2046 Simulator::Schedule(m_ctrlEndTime - Simulator::Now() + NanoSeconds(2),
2047 &NrSpectrumPhy::CheckIfCsiImNeeded,
2054NrSpectrumPhy::CheckIfCsiImNeeded(
const Ptr<NrSpectrumSignalParametersCsiRs>& csiRsParams)
2056 NS_LOG_FUNCTION(
this);
2058 Ptr<NrUePhy> nrUePhy = DynamicCast<NrUePhy>(m_phy);
2059 bool pdschCsiEnabled = nrUePhy->GetCsiFeedbackType() & CsiFeedbackFlag::CQI_PDSCH_MIMO;
2062 if (m_interferenceCsiIm->IsChunkProcessorSet())
2066 if ((!pdschCsiEnabled) || (pdschCsiEnabled && !IsUeScheduled()))
2068 ScheduleCsiIm(csiRsParams);
2074 if (!pdschCsiEnabled)
2076 nrUePhy->GenerateCsiRsCqi();
2083NrSpectrumPhy::ScheduleCsiIm(Ptr<SpectrumSignalParameters> csiRsParams)
const
2085 NS_LOG_FUNCTION(
this);
2086 NS_ASSERT(m_interferenceCsiIm);
2089 Ptr<SpectrumSignalParameters> fakeCsiImSignal = Create<SpectrumSignalParameters>();
2090 fakeCsiImSignal->duration =
2091 m_phy->GetSymbolPeriod() * (DynamicCast<NrUePhy>(m_phy))->GetCsiImDuration();
2092 fakeCsiImSignal->psd = csiRsParams->psd;
2093 fakeCsiImSignal->spectrumChannelMatrix = csiRsParams->spectrumChannelMatrix;
2094 m_interferenceCsiIm->AddSignalMimo(fakeCsiImSignal, fakeCsiImSignal->duration);
2095 m_interferenceCsiIm->StartRxMimo(fakeCsiImSignal);
2102NrSpectrumPhy::IsUeScheduled()
const
2104 return m_transportBlocks.contains(m_rnti);
2110 m_ctrlEndTime = ctrlEndTime;
std::vector< Ptr< NrErrorModelOutput > > NrErrorModelHistory
Vector of previous output.
static TypeId GetTypeId()
GetTypeId.
void UpdateDlHarqProcessStatus(uint16_t rnti, uint8_t harqProcId, const Ptr< NrErrorModelOutput > &output)
Update the Info associated to the decodification of an HARQ process for DL (asynchronous)
void ResetUlHarqProcessStatus(uint16_t rnti, uint8_t id)
Reset the info associated to the decodification of an HARQ process for UL (asynchronous)
void UpdateUlHarqProcessStatus(uint16_t rnti, uint8_t harqProcId, const Ptr< NrErrorModelOutput > &output)
Update the Info associated to the decodification of an HARQ process for UL (asynchronous)
void ResetDlHarqProcessStatus(uint16_t rnti, uint8_t id)
Reset the info associated to the decodification of an HARQ process for DL (asynchronous)
const NrErrorModel::NrErrorModelHistory & GetHarqProcessInfoDlUl(bool dl, uint16_t rnti, uint8_t harqProcId)
Return the info of the HARQ procId in case of retransmissions for DL/UL (asynchronous)
static TypeId GetTypeId()
GetTypeId.
double CircularBearingAnglesForPanels(double firstPanelBearingAngleRad, uint8_t panelIndex) const
initialize the bearing angles of panels in to cover 360 Degree
void SetUnlicensedMode(bool unlicensedMode)
Sets whether to perform in unlicensed mode in which the channel monitoring is enabled.
void SetErrorModelType(TypeId errorModelType)
Sets the error model type.
void IncrementActiveTransmissions()
Increase the counter of active transmissions.
void NotifyTxCtrlTrace(Time duration) const
call TxCtrlTrace from subclass
void NotifyRxDataTrace(const SfnSf &sfn, Ptr< const SpectrumValue > spectrumValue, const Time &duration, uint16_t bwpId, uint16_t cellId) const
call RxDataTrace from subclass
Ptr< Object > GetPanelByIndex(const uint8_t index) const
Interface enable to access all panels using proper index.
void AddCsiRsMimoChunkProcessor(const Ptr< NrMimoChunkProcessor > &p)
Connect CSI-RS chunk processor with the corresponding CSI-RS interference object.
void UpdateSrsSnrPerceived(const double srsSnr)
SpectrumPhy that will be called when the SNR for the received SRS at gNB is being calculated.
void ReportWbDlDataSnrPerceived(const double dlDataSnr)
Report wideband perceived downlink data SNR.
void UpdateSinrPerceived(const SpectrumValue &sinr)
SpectrumPhy that will be called when the SINR for the received DATA is being calculated by the interf...
NrSpectrumPhy()
NrSpectrumPhy constructor.
void SetPhyRxCtrlEndOkCallback(const NrPhyRxCtrlEndOkCallback &c)
Sets the callback to be called when CTRL is received successfully.
static TypeId GetTypeId()
Get the object TypeId.
void StartTxUlControlFrames(const std::list< Ptr< NrControlMessage > > &ctrlMsgList, const Time &duration)
Start transmission of UL CTRL.
~NrSpectrumPhy() override
~NrSpectrumPhy
std::function< void(const std::list< Ptr< NrControlMessage > > &, uint8_t)> NrPhyRxCtrlEndOkCallback
This callback method type is used to notify that CTRL is received.
Ptr< UniformRandomVariable > GetErrorModelRv() const
Get pointer to error model random variable.
void AddSrsSnrReportCallback(SrsSnrReportCallback callback)
It adds callback to the list of callbacks that will be notified once SRS is being received.
void AddExpectedTb(ExpectedTb expectedTb)
Instruct the Spectrum Model of a incoming transmission.
void SetPhyDlHarqFeedbackCallback(const NrPhyDlHarqFeedbackCallback &c)
Sets the callback to be called when DL HARQ feedback is generated.
void AddBeamManager(Ptr< BeamManager > b)
Adds the beam manager of corresponds spectrum phy of antenna panel, and that beam manager is responsi...
void AddDataPowerChunkProcessor(const Ptr< NrChunkProcessor > &p)
Adds the chunk processor that will process the power for the data.
Ptr< NrInterference > GetNrInterference() const
void SetNumPanels(const uint8_t numPanel)
Set the number of panels in this NrSpectrumPhy.
uint8_t GetNumPanels() const
Get the number of panels in this NrSpectrumPhy.
void DoDispose() override
DoDispose method inherited from Object.
void UpdateSrsSinrPerceived(const SpectrumValue &srsSinr)
SpectrumPhy that will be called when the SINR for the received SRS at gNB is being calculated by the ...
Callback< void, const UlHarqInfo & > NrPhyUlHarqFeedbackCallback
virtual void SetNoisePowerSpectralDensity(const Ptr< const SpectrumValue > &noisePsd)
Sets noise power spectral density to be used by this device.
void SetCcaMode1Threshold(double thresholdDBm)
Set clear channel assessment (CCA) threshold.
void StartTxDlControlFrames(const std::list< Ptr< NrControlMessage > > &ctrlMsgList, const Time &duration)
Starts transmission of DL CTRL.
void InstallPhy(const Ptr< NrPhy > &phyModel)
Set NrPhy of this spectrum phy in order to be able to obtain information such as cellId,...
void SetRnti(uint16_t rnti)
void UpdateMimoSinrPerceived(const std::vector< MimoSinrChunk > &sinr)
Store the SINR chunks for all received signals at end of interference calculations.
bool IsTransmitting()
Return true if the current Phy State is TX.
void AddPanel(const Ptr< Object > antenna)
Add the antenna panel to this NrSpectrumPhy, currently in NR module it is expected to be of type Unif...
double GetCcaMode1Threshold() const
Callback< void, const DlHarqInfo & > NrPhyDlHarqFeedbackCallback
void AddCsiImMimoChunkProcessor(const Ptr< NrMimoChunkProcessor > &p)
Connect CSI-IM chunk processor with the corresponding CSI-IM interference object.
State GetState() const
Get current state.
void SetIsGnb(bool isGnb)
Set whether this spectrum PHY belongs to Gnb or UE TODO NrHelper should be declared as friend and thi...
void EndTx()
Function that is called when the transmission has ended. It is used to update spectrum phy state.
void AddDlCtrlSinrChunkProcessor(const Ptr< NrChunkProcessor > &p)
Adds the chunk processor that will process the received power.
Ptr< SpectrumChannel > GetChannel() const
Get pointer to SpectrumChannel.
int64_t AssignStreams(int64_t stream)
Ptr< SpectrumChannel > GetSpectrumChannel() const
Returns spectrum channel object to which is attached this spectrum phy instance.
void ConfigPanelsBearingAngles()
Either initialize the bearing angles of panels in install step or update all bearing angles based on ...
uint16_t GetCellId() const
void StartTxCsiRs(uint16_t rnti, uint16_t beamId)
Callback< void, uint16_t, const Ptr< SpectrumValue > & > NrPhyRxPssCallback
void SetDataErrorModelEnabled(bool dataErrorModelEnabled)
Enables or disabled data error model.
void SetPhyRxDataEndOkCallback(const NrPhyRxDataEndOkCallback &c)
Sets the callback to be called when DATA is received successfully.
void ReportDlCtrlSinr(const SpectrumValue &sinr)
Called when DlCtrlSinr is fired.
void AddExpectedDlCtrlEnd(Time ctrlEndTime)
Keeps track of when DL CTRL should finish. Needed for CSI-RS and CSI-IM implementation to be able to ...
void SetTxPowerSpectralDensity(const Ptr< SpectrumValue > &txPsd)
Sets transmit power spectral density.
void SetPhyUlHarqFeedbackCallback(const NrPhyUlHarqFeedbackCallback &c)
Sets the callback to be called when UL HARQ feedback is generated.
void SetAntenna(Ptr< Object > antenna)
Sets the antenna of this NrSpectrumPhy instance, currently in NR module it is expected to be of type ...
void AddDataSinrChunkProcessor(const Ptr< NrChunkProcessor > &p)
Adds the chunk processor that will process the interference.
void AddSrsSinrReportCallback(SrsSinrReportCallback callback)
It adds callback to the list of callbacks that will be notified once SRS is being received.
void StartTxDataFrames(const Ptr< PacketBurst > &pb, const std::list< Ptr< NrControlMessage > > &ctrlMsgList, const std::shared_ptr< DciInfoElementTdma > dci, const Time &duration)
Starts transmission of data frames on connected spectrum channel object.
void AddDataMimoChunkProcessor(const Ptr< NrMimoChunkProcessor > &p)
Connect DATA chunk processor with the corresponding DATA interference object.
Callback< void, const Ptr< Packet > & > NrPhyRxDataEndOkCallback
This callback method type is used to notify that DATA is received.
State
Enum that defines possible states of the spectrum phy.
@ TX
Transmitting state (data or ctrl)
@ RX_UL_SRS
Receiving SRS.
@ CCA_BUSY
BUSY state (channel occupied by another entity)
@ RX_UL_CTRL
Receiving UL CTRL.
@ RX_DL_CTRL
Receiving DL CTRL.
@ IDLE
IDLE state (no action in progress)
void AddRsPowerChunkProcessor(const Ptr< NrChunkProcessor > &p)
Adds the chunk processor that will process the received power.
void SetActivePanel(const uint8_t panelIndex)
Set the active antenna panel to this NrSpectrumPhy,.
uint16_t GetBwpId() const
void StartRx(Ptr< SpectrumSignalParameters > params) override
Inherited from SpectrumPhy. When this function is called this spectrum phy starts receiving a signal ...
void ChangeState(State newState, Time duration)
Update the state of the spectrum phy. The states are: IDLE, TX, RX_DATA, RX_DL_CTRL,...
void NotifyTxDataTrace(Time duration) const
call TxDataTrace from subclass
Ptr< Object > GetAntenna() const override
Inherited from SpectrumPhy Note: Implements GetRxAntenna function from SpectrumPhy.
void SetPhyRxPssCallback(const NrPhyRxPssCallback &c)
enum ns3::DlHarqInfo::HarqStatus NACK
HARQ status.
Information about the expected transport block at a certain point in the slot.
uint8_t m_symStart
Sym start.
std::vector< int > m_rbBitmap
RB Bitmap.
The GnbPhyPacketCountParameter struct.
double m_sinrMin
MIN SINR (only between the RB used to transmit the TB)
void UpdatePerceivedSinr(const SpectrumValue &perceivedSinr)
Update minimum and average SINR of the transport block based on perceived SINR.
ExpectedTb m_expected
Expected data from the PHY. Filled by AddExpectedTb.
double m_sinrAvg
AVG SINR (only for the RB used to transmit the TB)