7#define NS_LOG_APPEND_CONTEXT \
10 std::clog << " [ CellId " << GetCellId() << ", bwpId " << GetBwpId() << "] "; \
15#include "beam-manager.h"
16#include "nr-ch-access-manager.h"
17#include "nr-radio-bearer-tag.h"
18#include "nr-ue-net-device.h"
19#include "nr-ue-power-control.h"
21#include <ns3/boolean.h>
22#include <ns3/double.h>
26#include <ns3/pointer.h>
27#include <ns3/simulator.h>
35const Time NR_DEFAULT_PMI_INTERVAL_WB{MilliSeconds(10)};
36const Time NR_DEFAULT_PMI_INTERVAL_SB{MilliSeconds(2)};
38NS_LOG_COMPONENT_DEFINE(
"NrUePhy");
39NS_OBJECT_ENSURE_REGISTERED(NrUePhy);
43 NS_LOG_FUNCTION(
this);
44 m_wbCqiLast = Simulator::Now();
46 m_powerControl = CreateObject<NrUePowerControl>(
this);
47 m_isConnected =
false;
48 Simulator::Schedule(m_ueMeasurementsFilterPeriod, &NrUePhy::ReportUeMeasurements,
this);
53 NS_LOG_FUNCTION(
this);
59 NS_LOG_FUNCTION(
this);
60 delete m_ueCphySapProvider;
63 m_powerControl->Dispose();
64 m_powerControl =
nullptr;
78 TypeId(
"ns3::NrUePhy")
80 .AddConstructor<NrUePhy>()
81 .AddAttribute(
"TxPower",
82 "Transmission power in dBm",
85 MakeDoubleChecker<double>())
88 "Loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver."
89 " According to Wikipedia (http://en.wikipedia.org/wiki/Noise_figure), this is "
90 "\"the difference in decibels (dB) between"
91 " the noise output of the actual receiver to the noise output of an "
92 " ideal receiver with the same overall gain and bandwidth when the receivers "
93 " are connected to sources at the standard noise temperature T0.\" "
94 "In this model, we consider T0 = 290K.",
98 MakeDoubleChecker<double>())
100 "PowerAllocationType",
101 "Defines the type of the power allocation. Currently are supported "
102 "two types: \"UniformPowerAllocBw\", which is a uniform power allocation over all "
103 "bandwidth (over all RBs), and \"UniformPowerAllocBw\", which is a uniform "
104 "power allocation over used (active) RBs. By default is set a uniform power "
105 "allocation over used RBs .",
106 EnumValue(NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_USED),
107 MakeEnumAccessor<NrSpectrumValueHelper::PowerAllocationType>(
110 MakeEnumChecker(NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_BW,
111 "UniformPowerAllocBw",
112 NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_USED,
113 "UniformPowerAllocUsed"))
114 .AddAttribute(
"SpectrumPhy",
115 "The SpectrumPhy associated to this NrPhy",
119 MakePointerChecker<NrSpectrumPhy>())
120 .AddAttribute(
"LBTThresholdForCtrl",
121 "After a DL/UL transmission, if we have less than this value to send the "
122 "UL CTRL, we consider the channel as granted",
123 TimeValue(MicroSeconds(25)),
124 MakeTimeAccessor(&NrUePhy::m_lbtThresholdForCtrl),
126 .AddAttribute(
"TbDecodeLatency",
127 "Transport block decode latency",
128 TimeValue(MicroSeconds(100)),
131 .AddAttribute(
"EnableUplinkPowerControl",
132 "If true, Uplink Power Control will be enabled.",
134 MakeBooleanAccessor(&NrUePhy::SetEnableUplinkPowerControl),
135 MakeBooleanChecker())
136 .AddAttribute(
"WbPmiUpdateInterval",
137 "Wideband PMI update interval",
138 TimeValue(NR_DEFAULT_PMI_INTERVAL_WB),
139 MakeTimeAccessor(&NrUePhy::m_wbPmiUpdateInterval),
141 .AddAttribute(
"SbPmiUpdateInterval",
142 "Subband PMI update interval",
143 TimeValue(NR_DEFAULT_PMI_INTERVAL_SB),
144 MakeTimeAccessor(&NrUePhy::m_sbPmiUpdateInterval),
146 .AddTraceSource(
"DlDataSinr",
147 "DL DATA SINR statistics.",
148 MakeTraceSourceAccessor(&NrUePhy::m_dlDataSinrTrace),
149 "ns3::NrUePhy::DlDataSinrTracedCallback")
150 .AddTraceSource(
"DlCtrlSinr",
151 "Report the SINR computed for DL CTRL",
152 MakeTraceSourceAccessor(&NrUePhy::m_dlCtrlSinrTrace),
153 "ns3::NrUePhy::DlCtrlSinrTracedCallback")
154 .AddAttribute(
"UeMeasurementsFilterPeriod",
155 "Time period for reporting UE measurements, i.e., the"
156 "length of layer-1 filtering.",
157 TimeValue(MilliSeconds(200)),
158 MakeTimeAccessor(&NrUePhy::m_ueMeasurementsFilterPeriod),
160 .AddTraceSource(
"ReportUplinkTbSize",
161 "Report allocated uplink TB size for trace.",
162 MakeTraceSourceAccessor(&NrUePhy::m_reportUlTbSize),
163 "ns3::UlTbSize::TracedCallback")
164 .AddTraceSource(
"ReportDownlinkTbSize",
165 "Report allocated downlink TB size for trace.",
166 MakeTraceSourceAccessor(&NrUePhy::m_reportDlTbSize),
167 "ns3::DlTbSize::TracedCallback")
168 .AddTraceSource(
"ReportRsrp",
170 MakeTraceSourceAccessor(&NrUePhy::m_reportRsrpTrace),
171 "ns3::CurrentRsrp::TracedCallback")
172 .AddTraceSource(
"UePhyRxedCtrlMsgsTrace",
173 "Ue PHY Control Messages Traces.",
174 MakeTraceSourceAccessor(&NrUePhy::m_phyRxedCtrlMsgsTrace),
175 "ns3::NrPhyRxTrace::RxedUePhyCtrlMsgsTracedCallback")
176 .AddTraceSource(
"UePhyTxedCtrlMsgsTrace",
177 "Ue PHY Control Messages Traces.",
178 MakeTraceSourceAccessor(&NrUePhy::m_phyTxedCtrlMsgsTrace),
179 "ns3::NrPhyRxTrace::TxedUePhyCtrlMsgsTracedCallback")
180 .AddTraceSource(
"UePhyRxedDlDciTrace",
181 "Ue PHY DL DCI Traces.",
182 MakeTraceSourceAccessor(&NrUePhy::m_phyUeRxedDlDciTrace),
183 "ns3::NrPhyRxTrace::RxedUePhyDlDciTracedCallback")
184 .AddTraceSource(
"UePhyTxedHarqFeedbackTrace",
185 "Ue PHY DL HARQ Feedback Traces.",
186 MakeTraceSourceAccessor(&NrUePhy::m_phyUeTxedHarqFeedbackTrace),
187 "ns3::NrPhyRxTrace::TxedUePhyHarqFeedbackTracedCallback")
188 .AddTraceSource(
"ReportPowerSpectralDensity",
189 "Power Spectral Density data.",
190 MakeTraceSourceAccessor(&NrUePhy::m_reportPowerSpectralDensity),
191 "ns3::NrUePhy::PowerSpectralDensityTracedCallback")
192 .AddTraceSource(
"ReportUeMeasurements",
193 "Report UE measurements RSRP (dBm) and RSRQ (dB).",
194 MakeTraceSourceAccessor(&NrUePhy::m_reportUeMeasurements),
195 "ns3::NrUePhy::RsrpRsrqTracedCallback")
196 .AddAttribute(
"EnableRlfDetection",
197 "If true, RLF detection will be enabled.",
199 MakeBooleanAccessor(&NrUePhy::m_enableRlfDetection),
200 MakeBooleanChecker());
205NrUePhy::ChannelAccessGranted([[maybe_unused]]
const Time& time)
207 NS_LOG_FUNCTION(
this);
209 m_channelStatus = GRANTED;
213NrUePhy::ChannelAccessDenied()
215 NS_LOG_FUNCTION(
this);
216 m_channelStatus = NONE;
222 NS_LOG_FUNCTION(
this);
229 NS_LOG_FUNCTION(
this);
230 return (m_ueCphySapProvider);
234NrUePhy::SetEnableUplinkPowerControl(
bool enable)
236 m_enableUplinkPowerControl = enable;
243 m_powerControl->SetTxPower(pow);
261 NS_LOG_FUNCTION(
this);
262 return m_powerControl;
278 m_pmSearch->SetAmc(amc);
283NrUePhy::SetSubChannelsForTransmission(
const std::vector<int>& mask, uint32_t numSym)
288 m_reportPowerSpectralDensity(m_currentSlot,
299NrUePhy::DoSendControlMessage(Ptr<NrControlMessage> msg)
301 NS_LOG_FUNCTION(
this << msg);
306NrUePhy::DoSendControlMessageNow(Ptr<NrControlMessage> msg)
308 NS_LOG_FUNCTION(
this << msg);
313NrUePhy::ProcessDataDci(
const SfnSf& ulSfnSf,
314 const std::shared_ptr<DciInfoElementTdma>& dciInfoElem)
316 NS_LOG_FUNCTION(
this);
318 NS_LOG_DEBUG(
"UE" << m_rnti <<
" UL-DCI received for slot " << ulSfnSf <<
" symStart "
319 <<
static_cast<uint32_t
>(dciInfoElem->m_symStart) <<
" numSym "
320 <<
static_cast<uint32_t
>(dciInfoElem->m_numSym) <<
" tbs "
321 << dciInfoElem->m_tbSize <<
" harqId "
322 <<
static_cast<uint32_t
>(dciInfoElem->m_harqProcess));
324 if (ulSfnSf == m_currentSlot)
326 InsertAllocation(dciInfoElem);
330 InsertFutureAllocation(ulSfnSf, dciInfoElem);
335NrUePhy::SendRachPreamble(uint32_t PreambleId, uint32_t Rnti)
337 NS_LOG_FUNCTION(
this << PreambleId);
339 Ptr<NrRachPreambleMessage> msg = Create<NrRachPreambleMessage>();
341 msg->SetRapId(PreambleId);
346NrUePhy::ProcessSrsDci(
const SfnSf& ulSfnSf,
const std::shared_ptr<DciInfoElementTdma>& dciInfoElem)
348 NS_LOG_FUNCTION(
this);
350 if (ulSfnSf == m_currentSlot)
352 InsertAllocation(dciInfoElem);
356 InsertFutureAllocation(ulSfnSf, dciInfoElem);
363 NS_LOG_FUNCTION(
this);
372 m_ulCtrlSyms = ulCtrlSyms;
378 m_dlCtrlSyms = dlCtrlSyms;
384 m_numRbPerRbg = numRbPerRbg;
390 NS_LOG_FUNCTION(
this);
392 static std::unordered_map<std::string, LteNrTddSlotType> lookupTable = {
399 std::vector<LteNrTddSlotType> vector;
400 std::stringstream ss(pattern);
402 std::vector<std::string> extracted;
404 while (std::getline(ss, token,
'|'))
406 extracted.push_back(token);
409 vector.reserve(extracted.size());
410 for (
const auto& v : extracted)
412 vector.push_back(lookupTable[v]);
421 return m_numRbPerRbg;
425NrUePhy::ComputeAvgSinr(
const SpectrumValue& sinr)
430 Values::const_iterator it;
432 for (it = sinr.ConstValuesBegin(); it != sinr.ConstValuesEnd(); it++)
438 double avrgSinr = (rbNum > 0) ? (sum / rbNum) : DBL_MAX;
444NrUePhy::InsertAllocation(
const std::shared_ptr<DciInfoElementTdma>& dci)
446 NS_LOG_FUNCTION(
this);
448 VarTtiAllocInfo varTtiInfo(dci);
455NrUePhy::InsertFutureAllocation(
const SfnSf& sfnSf,
const std::shared_ptr<DciInfoElementTdma>& dci)
457 NS_LOG_FUNCTION(
this);
459 VarTtiAllocInfo varTtiInfo(dci);
463 ulSlot.m_varTtiAllocInfo.push_back(varTtiInfo);
464 std::stable_sort(ulSlot.m_varTtiAllocInfo.begin(), ulSlot.m_varTtiAllocInfo.end());
468 SlotAllocInfo slotAllocInfo = SlotAllocInfo(sfnSf);
469 slotAllocInfo.m_varTtiAllocInfo.push_back(varTtiInfo);
477 NS_LOG_FUNCTION(
this);
481 auto dciMsg = DynamicCast<NrDlDciMessage>(msg);
482 auto dciInfoElem = dciMsg->GetDciInfoElement();
486 if (dciInfoElem->m_rnti != 0 && dciInfoElem->m_rnti != m_rnti)
491 SfnSf dciSfn = m_currentSlot;
492 uint32_t k0Delay = dciMsg->GetKDelay();
495 NS_LOG_DEBUG(
"UE" << m_rnti <<
" DL-DCI received for slot " << dciSfn <<
" symStart "
496 <<
static_cast<uint32_t
>(dciInfoElem->m_symStart) <<
" numSym "
497 <<
static_cast<uint32_t
>(dciInfoElem->m_numSym) <<
" tbs "
498 << dciInfoElem->m_tbSize <<
" harqId "
499 <<
static_cast<uint32_t
>(dciInfoElem->m_harqProcess));
503 auto it = m_harqIdToK1Map.find(dciInfoElem->m_harqProcess);
504 if (it != m_harqIdToK1Map.end())
506 m_harqIdToK1Map.erase(m_harqIdToK1Map.find(dciInfoElem->m_harqProcess));
509 m_harqIdToK1Map.insert(std::make_pair(dciInfoElem->m_harqProcess, dciMsg->GetK1Delay()));
511 m_phyUeRxedDlDciTrace(m_currentSlot,
515 dciInfoElem->m_harqProcess,
516 dciMsg->GetK1Delay());
518 InsertAllocation(dciInfoElem);
522 if (m_enableUplinkPowerControl)
524 m_powerControl->ReportTpcPusch(dciInfoElem->m_tpc);
525 m_powerControl->ReportTpcPucch(dciInfoElem->m_tpc);
530 auto dciMsg = DynamicCast<NrUlDciMessage>(msg);
531 auto dciInfoElem = dciMsg->GetDciInfoElement();
535 if (dciInfoElem->m_rnti != 0 && dciInfoElem->m_rnti != m_rnti)
540 SfnSf ulSfnSf = m_currentSlot;
541 uint32_t k2Delay = dciMsg->GetKDelay();
542 ulSfnSf.
Add(k2Delay);
546 ProcessDataDci(ulSfnSf, dciInfoElem);
551 ProcessSrsDci(ulSfnSf, dciInfoElem);
557 NS_LOG_DEBUG(
"received MIB");
558 Ptr<NrMibMessage> msg2 = DynamicCast<NrMibMessage>(msg);
564 Ptr<NrSib1Message> msg2 = DynamicCast<NrSib1Message>(msg);
570 Ptr<NrRarMessage> rarMsg = DynamicCast<NrRarMessage>(msg);
576 NS_LOG_INFO(
"Message type not recognized " << msg->GetMessageType());
583NrUePhy::ProcessRar(
const Ptr<NrRarMessage>& rarMsg)
585 NS_LOG_FUNCTION(
this);
588 for (
auto it = rarMsg->RarListBegin(); it != rarMsg->RarListEnd(); ++it)
590 NS_LOG_INFO(
"Received RAR in slot" << m_currentSlot <<
" with RA preamble ID: "
591 << std::to_string(it->rarPayload.raPreambleId));
594 NS_LOG_INFO(
"Received RAR with RA preamble ID:" << +it->rarPayload.raPreambleId
595 <<
" current RA preamble ID is :"
598 SfnSf ulSfnSf = m_currentSlot;
599 uint32_t k2Delay = it->rarPayload.k2Delay;
600 ulSfnSf.
Add(k2Delay);
601 NS_LOG_DEBUG(
"Insert RAR UL DCI allocation for " << ulSfnSf);
602 ProcessDataDci(ulSfnSf, (*it).rarPayload.ulMsg3Dci);
614 NS_LOG_DEBUG(
"Skipping RAR, does not contain preamble ID."
615 <<
"\n My preamble id: " << std::to_string(
m_raPreambleId) <<
" found:");
616 for (
auto it = rarMsg->RarListBegin(); it != rarMsg->RarListEnd(); ++it)
618 NS_LOG_DEBUG(
"rapId: " << std::to_string(it->rapId));
625NrUePhy::TryToPerformLbt()
627 NS_LOG_FUNCTION(
this);
628 uint8_t ulCtrlSymStart = 0;
629 uint8_t ulCtrlNumSym = 0;
636 ulCtrlSymStart = alloc.m_dci->m_symStart;
637 ulCtrlNumSym = alloc.m_dci->m_numSym;
642 if (ulCtrlNumSym != 0)
650 m_lbtThresholdForCtrl;
655 int64_t dciEndsAt = m_lastSlotStart.GetMicroSeconds() +
656 ((alloc.m_dci->m_numSym + alloc.m_dci->m_symStart) * symbolPeriod);
664 if (limit.GetMicroSeconds() < dciEndsAt)
666 NS_LOG_INFO(
"This data DCI ends at "
667 << MicroSeconds(dciEndsAt)
668 <<
" which is inside the LBT shared COT (the limit is " << limit
669 <<
"). No need for LBT");
672 m_channelStatus = GRANTED;
676 NS_LOG_INFO(
"This data DCI starts at "
677 << +alloc.m_dci->m_symStart <<
" for " << +alloc.m_dci->m_numSym
678 <<
" ends at " << MicroSeconds(dciEndsAt)
679 <<
" which is outside the LBT shared COT (the limit is " << limit
683 if (m_channelStatus != GRANTED)
685 Time sched = m_lastSlotStart - Simulator::Now() + (
GetSymbolPeriod() * ulCtrlSymStart) -
687 NS_LOG_DEBUG(
"Scheduling an LBT for sending the UL CTRL at "
688 << Simulator::Now() + sched);
690 m_lbtEvent = Simulator::Schedule(sched, &NrUePhy::RequestAccess,
this);
694 NS_LOG_DEBUG(
"Not scheduling LBT: the UE has a channel status that is GRANTED");
699 NS_LOG_INFO(
"Not scheduling LBT; the UE has no UL CTRL symbols available");
704NrUePhy::RequestAccess()
706 NS_LOG_FUNCTION(
this);
707 NS_LOG_DEBUG(
"Request access because we have to transmit UL CTRL");
708 m_cam->RequestAccess();
713NrUePhy::PushCtrlAllocations(
const SfnSf currentSfnSf)
715 NS_LOG_FUNCTION(
this);
719 std::vector<uint8_t> rbgBitmask(
GetRbNum(), 1);
724 NS_LOG_INFO(
"TDD Pattern unknown, insert DL CTRL at the beginning of the slot");
725 VarTtiAllocInfo dlCtrlSlot(std::make_shared<DciInfoElementTdma>(0,
734 uint64_t currentSlotN = currentSfnSf.Normalize() %
m_tddPattern.size();
738 NS_LOG_DEBUG(
"The current TDD pattern indicates that we are in a "
740 <<
" slot, so insert DL CTRL at the beginning of the slot");
741 VarTtiAllocInfo dlCtrlSlot(std::make_shared<DciInfoElementTdma>(0,
750 NS_LOG_DEBUG(
"The current TDD pattern indicates that we are in a "
752 <<
" slot, so insert UL CTRL at the end of the slot");
753 VarTtiAllocInfo ulCtrlSlot(
764NrUePhy::StartSlot(
const SfnSf& s)
766 NS_LOG_FUNCTION(
this);
768 m_lastSlotStart = Simulator::Now();
784 PushCtrlAllocations(m_currentSlot);
789 <<
" composed by the following allocations, total "
793 std::string direction;
805 switch (alloc.m_dci->m_type)
809 NS_LOG_DEBUG(
"Allocation from sym "
810 <<
static_cast<uint32_t
>(alloc.m_dci->m_symStart) <<
" to sym "
811 <<
static_cast<uint32_t
>(alloc.m_dci->m_numSym + alloc.m_dci->m_symStart)
812 <<
" direction " << direction <<
" type " << type);
816 NS_LOG_INFO(
"Allocation from sym "
817 <<
static_cast<uint32_t
>(alloc.m_dci->m_symStart) <<
" to sym "
818 <<
static_cast<uint32_t
>(alloc.m_dci->m_numSym + alloc.m_dci->m_symStart)
819 <<
" direction " << direction <<
" type " << type);
823 NS_LOG_DEBUG(
"Allocation from sym "
824 <<
static_cast<uint32_t
>(alloc.m_dci->m_symStart) <<
" to sym "
825 <<
static_cast<uint32_t
>(alloc.m_dci->m_numSym + alloc.m_dci->m_symStart)
826 <<
" direction " << direction <<
" type " << type);
830 NS_LOG_DEBUG(
"Allocation from sym "
831 <<
static_cast<uint32_t
>(alloc.m_dci->m_symStart) <<
" to sym "
832 <<
static_cast<uint32_t
>(alloc.m_dci->m_numSym + alloc.m_dci->m_symStart)
833 <<
" direction " << direction <<
" type " << type);
836 NS_LOG_ERROR(
"Unknown type DciInfoElementTdma::VarTtiType " << alloc.m_dci->m_type);
845 auto nextVarTtiStart =
GetSymbolPeriod() * allocation.m_dci->m_symStart;
855 for (
const auto& msg : ctrlMsgs)
861 Simulator::Schedule(nextVarTtiStart, &NrUePhy::StartVarTti,
this, allocation.m_dci);
865NrUePhy::DlCtrl(
const std::shared_ptr<DciInfoElementTdma>& dci)
867 NS_LOG_FUNCTION(
this);
871 NS_LOG_DEBUG(
"UE" << m_rnti
872 <<
" RXing DL CTRL frame for"
874 << +dci->m_symStart <<
"-" << +(dci->m_symStart + dci->m_numSym - 1)
875 <<
"\t start " << Simulator::Now() <<
" end "
876 << (Simulator::Now() + varTtiDuration));
878 m_tryToPerformLbt =
true;
880 return varTtiDuration;
884NrUePhy::UlSrs(
const std::shared_ptr<DciInfoElementTdma>& dci)
886 NS_LOG_FUNCTION(
this);
888 std::vector<int> channelRbs;
889 for (uint32_t i = 0; i <
GetRbNum(); i++)
891 channelRbs.push_back(
static_cast<int>(i));
893 SetSubChannelsForTransmission(channelRbs, dci->m_numSym);
895 std::list<Ptr<NrControlMessage>> srsMsg;
896 Ptr<NrSrsMessage> srs = Create<NrSrsMessage>();
898 srsMsg.emplace_back(srs);
901 m_phyTxedCtrlMsgsTrace(m_currentSlot,
GetCellId(), dci->m_rnti,
GetBwpId(), *srsMsg.begin());
902 m_spectrumPhy->StartTxUlControlFrames(srsMsg, varTtiDuration - NanoSeconds(1.0));
904 NS_LOG_DEBUG(
"UE" << m_rnti <<
" TXing UL SRS frame for symbols " << +dci->m_symStart <<
"-"
905 << +(dci->m_symStart + dci->m_numSym - 1) <<
"\t start " << Simulator::Now()
906 <<
" end " << (Simulator::Now() + varTtiDuration - NanoSeconds(1.0)));
908 ChannelAccessDenied();
909 return varTtiDuration;
913NrUePhy::UlCtrl(
const std::shared_ptr<DciInfoElementTdma>& dci)
915 NS_LOG_FUNCTION(
this);
921 NS_LOG_DEBUG(
"UE" << m_rnti <<
" reserved space for UL CTRL frame for symbols "
922 << +dci->m_symStart <<
"-" << +(dci->m_symStart + dci->m_numSym - 1)
923 <<
"\t start " << Simulator::Now() <<
" end "
924 << (Simulator::Now() + varTtiDuration - NanoSeconds(1.0))
925 <<
" but no data to transmit");
927 return varTtiDuration;
929 else if (m_channelStatus != GRANTED)
931 NS_LOG_INFO(
"UE" << m_rnti <<
" has to transmit CTRL but channel not granted");
933 return varTtiDuration;
938 m_phyTxedCtrlMsgsTrace(m_currentSlot,
GetCellId(), dci->m_rnti,
GetBwpId(), msg);
942 Ptr<NrDlHarqFeedbackMessage> harqMsg = DynamicCast<NrDlHarqFeedbackMessage>(msg);
943 uint8_t harqId = harqMsg->GetDlHarqFeedback().m_harqProcessId;
945 auto it = m_harqIdToK1Map.find(harqId);
946 if (it != m_harqIdToK1Map.end())
948 m_phyUeTxedHarqFeedbackTrace(m_currentSlot,
952 static_cast<uint32_t
>(harqId),
958 std::vector<int> channelRbs;
959 for (uint32_t i = 0; i <
GetRbNum(); i++)
961 channelRbs.push_back(
static_cast<int>(i));
964 if (m_enableUplinkPowerControl)
966 m_txPower = m_powerControl->GetPucchTxPower(channelRbs.size());
968 SetSubChannelsForTransmission(channelRbs, dci->m_numSym);
970 NS_LOG_DEBUG(
"UE" << m_rnti <<
" TXing UL CTRL frame for symbols " << +dci->m_symStart <<
"-"
971 << +(dci->m_symStart + dci->m_numSym - 1) <<
"\t start " << Simulator::Now()
972 <<
" end " << (Simulator::Now() + varTtiDuration - NanoSeconds(1.0)));
974 SendCtrlChannels(varTtiDuration - NanoSeconds(1.0));
976 ChannelAccessDenied();
977 return varTtiDuration;
981NrUePhy::DlData(
const std::shared_ptr<DciInfoElementTdma>& dci)
983 NS_LOG_FUNCTION(
this);
985 m_receptionEnabled =
true;
987 NS_ASSERT(dci->m_rnti == m_rnti);
1000 m_reportDlTbSize(
m_netDevice->GetObject<NrUeNetDevice>()->GetImsi(), dci->m_tbSize);
1001 NS_LOG_INFO(
"UE" << m_rnti <<
" RXing DL DATA frame for symbols " << +dci->m_symStart <<
"-"
1002 << +(dci->m_symStart + dci->m_numSym - 1) <<
" num of rbg assigned: "
1004 <<
". RX will take place for " << varTtiDuration);
1006 return varTtiDuration;
1010NrUePhy::UlData(
const std::shared_ptr<DciInfoElementTdma>& dci)
1012 NS_LOG_FUNCTION(
this);
1013 if (m_enableUplinkPowerControl)
1015 m_txPower = m_powerControl->GetPuschTxPower(
1020 std::list<Ptr<NrControlMessage>> ctrlMsg;
1021 Ptr<PacketBurst> pktBurst =
GetPacketBurst(m_currentSlot, dci->m_symStart, dci->m_rnti);
1022 if (pktBurst && pktBurst->GetNPackets() > 0)
1024 std::list<Ptr<Packet>> pkts = pktBurst->GetPackets();
1025 NrRadioBearerTag bearerTag;
1026 if (!pkts.front()->PeekPacketTag(bearerTag))
1028 NS_FATAL_ERROR(
"No radio bearer tag");
1037 NS_FATAL_ERROR(
"The UE " << dci->m_rnti <<
" has been scheduled without data");
1041 NS_LOG_WARN(
"Not sending MSG3. Probably in RRC IDEAL mode.");
1042 return varTtiDuration;
1045 m_reportUlTbSize(
m_netDevice->GetObject<NrUeNetDevice>()->GetImsi(), dci->m_tbSize);
1047 NS_LOG_DEBUG(
"UE" << m_rnti <<
" TXing UL DATA frame for"
1048 <<
" symbols " << +dci->m_symStart <<
"-"
1049 << +(dci->m_symStart + dci->m_numSym - 1) <<
"\t start " << Simulator::Now()
1050 <<
" end " << (Simulator::Now() + varTtiDuration));
1052 Simulator::Schedule(NanoSeconds(1.0),
1053 &NrUePhy::SendDataChannels,
1058 varTtiDuration - NanoSeconds(2.0));
1059 return varTtiDuration;
1063NrUePhy::StartVarTti(
const std::shared_ptr<DciInfoElementTdma>& dci)
1065 NS_LOG_FUNCTION(
this);
1066 Time varTtiDuration;
1068 m_currTbs = dci->m_tbSize;
1069 m_receptionEnabled =
false;
1073 varTtiDuration = DlCtrl(dci);
1077 varTtiDuration = UlCtrl(dci);
1081 varTtiDuration = UlSrs(dci);
1085 varTtiDuration = DlData(dci);
1090 varTtiDuration = UlData(dci);
1093 Simulator::Schedule(varTtiDuration, &NrUePhy::EndVarTti,
this, dci);
1097NrUePhy::EndVarTti(
const std::shared_ptr<DciInfoElementTdma>& dci)
1099 NS_LOG_FUNCTION(
this);
1100 NS_LOG_DEBUG(
"DCI started at symbol "
1101 <<
static_cast<uint32_t
>(dci->m_symStart) <<
" which lasted for "
1102 <<
static_cast<uint32_t
>(dci->m_numSym) <<
" symbols finished");
1104 if (m_tryToPerformLbt)
1107 m_tryToPerformLbt =
false;
1113 m_currentSlot.
Add(1);
1115 Simulator::Schedule(m_lastSlotStart +
GetSlotPeriod() - Simulator::Now(),
1116 &NrUePhy::StartSlot,
1125 Time nextVarTtiStart =
GetSymbolPeriod() * allocation.m_dci->m_symStart;
1127 Simulator::Schedule(nextVarTtiStart + m_lastSlotStart - Simulator::Now(),
1128 &NrUePhy::StartVarTti,
1133 m_receptionEnabled =
false;
1139 Simulator::ScheduleWithContext(
m_netDevice->GetNode()->GetId(),
1148NrUePhy::SendDataChannels(
const Ptr<PacketBurst>& pb,
1149 const std::list<Ptr<NrControlMessage>>& ctrlMsg,
1150 const std::shared_ptr<DciInfoElementTdma>& dci,
1151 const Time& duration)
1153 if (pb->GetNPackets() > 0)
1156 if (!pb->GetPackets().front()->PeekPacketTag(tag))
1158 NS_FATAL_ERROR(
"No radio bearer tag");
1162 m_spectrumPhy->StartTxDataFrames(pb, ctrlMsg, dci, duration);
1166NrUePhy::SendCtrlChannels(Time duration)
1173NrUePhy::CreateDlCqiFeedbackMessage(
const SpectrumValue& sinr)
1175 NS_LOG_FUNCTION(
this);
1177 Ptr<NrDlCqiMessage> msg = Create<NrDlCqiMessage>();
1181 dlcqi.m_rnti = m_rnti;
1184 std::vector<int> cqi;
1186 msg->SetDlCqi(dlcqi);
1193 NS_LOG_FUNCTION(
this);
1195 if (m_ulConfigured && (m_rnti > 0) && m_receptionEnabled)
1199 if (Simulator::Now() > m_wbCqiLast)
1201 Ptr<NrDlCqiMessage> msg = CreateDlCqiFeedbackMessage(sinr);
1205 DoSendControlMessage(msg);
1214 NS_LOG_FUNCTION(
this);
1216 Ptr<NrDlHarqFeedbackMessage> msg = Create<NrDlHarqFeedbackMessage>();
1218 msg->SetDlHarqFeedback(m);
1222 NS_LOG_DEBUG(
"ReceiveNrDlHarqFeedback"
1223 <<
" Harq Process " <<
static_cast<uint32_t
>(k1It->first)
1224 <<
" K1: " << k1It->second <<
" Frame " << m_currentSlot);
1226 Time
event = m_lastSlotStart + (
GetSlotPeriod() * k1It->second);
1227 if (event <= Simulator::Now())
1229 Simulator::ScheduleNow(&NrUePhy::DoSendControlMessageNow,
this, msg);
1233 Simulator::Schedule(event - Simulator::Now(), &NrUePhy::DoSendControlMessageNow,
this, msg);
1240 NS_LOG_FUNCTION(
this);
1241 NS_ASSERT(cam !=
nullptr);
1243 m_cam->SetAccessGrantedCallback(
1244 std::bind(&NrUePhy::ChannelAccessGranted,
this, std::placeholders::_1));
1245 m_cam->SetAccessDeniedCallback(std::bind(&NrUePhy::ChannelAccessDenied,
this));
1251 return m_currentSlot;
1263 NS_LOG_FUNCTION(
this);
1265 m_isConnected =
false;
1269NrUePhy::DoStartCellSearch(uint16_t dlEarfcn)
1271 NS_LOG_FUNCTION(
this << dlEarfcn);
1272 DoSetInitialBandwidth();
1276NrUePhy::DoSynchronizeWithGnb(uint16_t cellId, uint16_t dlEarfcn)
1278 NS_LOG_FUNCTION(
this << cellId << dlEarfcn);
1279 DoSynchronizeWithGnb(cellId);
1283NrUePhy::DoSetPa(
double pa)
1285 NS_LOG_FUNCTION(
this << pa);
1289NrUePhy::DoSetRsrpFilterCoefficient(uint8_t rsrpFilterCoefficient)
1291 NS_LOG_FUNCTION(
this << +rsrpFilterCoefficient);
1295NrUePhy::DoSynchronizeWithGnb(uint16_t cellId)
1297 NS_LOG_FUNCTION(
this << cellId);
1299 DoSetInitialBandwidth();
1305 NS_LOG_FUNCTION(
this);
1307 NS_FATAL_ERROR(
"ERROR");
1313 NS_LOG_FUNCTION(
this);
1314 Simulator::ScheduleWithContext(nodeId,
1316 &NrUePhy::StartEventLoop,
1326 NS_LOG_FUNCTION(
this << rsReceivedPower);
1327 m_rsrp = 10 * log10(Integral(rsReceivedPower)) + 30;
1328 NS_LOG_DEBUG(
"RSRP value updated: " << m_rsrp <<
" dBm");
1330 if (m_enableUplinkPowerControl)
1332 m_powerControl->SetLoggingInfo(
GetCellId(), m_rnti);
1333 m_powerControl->SetRsrp(m_rsrp);
1340 NS_LOG_FUNCTION(
this);
1345 uint32_t subcarrierSpacing;
1346 subcarrierSpacing = 15000 *
static_cast<uint32_t
>(std::pow(2,
GetNumerology()));
1348 Values::const_iterator itPi;
1349 for (itPi = p->ConstValuesBegin(); itPi != p->ConstValuesEnd(); itPi++)
1352 double powerTxW = (*itPi) * subcarrierSpacing;
1358 double rsrp = 10 * log10(1000 * (sum /
static_cast<double>(nRB)));
1360 NS_LOG_DEBUG(
"RSRP value updated: " << rsrp <<
" dBm"
1361 <<
" for Cell Id: " << cellId <<
" RNTI: " << m_rnti);
1364 std::map<uint16_t, UeMeasurementsElement>::iterator itMeasMap =
1365 m_ueMeasurementsMap.find(cellId);
1366 if (itMeasMap == m_ueMeasurementsMap.end())
1369 UeMeasurementsElement newEl;
1370 newEl.rsrpSum = rsrp;
1375 NS_LOG_DEBUG(
"New RSRP entry for Cell Id: " << cellId <<
" RNTI: " << m_rnti
1376 <<
" RSRP: " << newEl.rsrpSum <<
" dBm"
1377 <<
" number of entries: " << +newEl.rsrpNum);
1379 m_ueMeasurementsMap.insert(std::pair<uint16_t, UeMeasurementsElement>(cellId, newEl));
1383 (*itMeasMap).second.rsrpSum += rsrp;
1384 (*itMeasMap).second.rsrpNum++;
1386 NS_LOG_DEBUG(
"Update RSRP entry for Cell Id: "
1387 << cellId <<
" RNTI: " << m_rnti
1388 <<
" RSRP Sum: " << (*itMeasMap).second.rsrpSum <<
" dBm"
1389 <<
" number of entries: " << +((*itMeasMap).second.rsrpNum));
1394NrUePhy::ReportUeMeasurements()
1396 NS_LOG_FUNCTION(
this);
1400 std::map<uint16_t, UeMeasurementsElement>::iterator it;
1401 for (it = m_ueMeasurementsMap.begin(); it != m_ueMeasurementsMap.end(); it++)
1404 double avg_rsrq = 0;
1405 if ((*it).second.rsrpNum != 0)
1407 avg_rsrp = (*it).second.rsrpSum /
static_cast<double>((*it).second.rsrpNum);
1411 NS_LOG_WARN(
" RSRP nSamples is zero!");
1415 NS_LOG_DEBUG(
" Report UE Measurements for CellId "
1416 << (*it).first <<
" Reporting UE " << m_rnti <<
" Av. RSRP " << avg_rsrp
1417 <<
" (nSamples " << +((*it).second.rsrpNum) <<
")"
1424 if (m_isConnected && m_enableRlfDetection)
1426 double avrgSinrForRlf = ComputeAvgSinr(m_ctrlSinrForRlf);
1427 RlfDetection(10 * log10(avrgSinrForRlf));
1430 NrUeCphySapUser::UeMeasurementsElement newEl;
1431 newEl.m_cellId = (*it).first;
1432 newEl.m_rsrp = avg_rsrp;
1433 newEl.m_rsrq = avg_rsrq;
1437 m_reportUeMeasurements(m_rnti,
1448 m_ueMeasurementsMap.clear();
1449 Simulator::Schedule(m_ueMeasurementsFilterPeriod, &NrUePhy::ReportUeMeasurements,
this);
1455 NS_LOG_FUNCTION(
this);
1456 uint32_t rbUsed = 0;
1457 double sinrSum = 0.0;
1459 for (uint32_t i = 0; i < sinr.GetValuesN(); i++)
1461 double currentSinr = sinr.ValuesAt(i);
1462 if (currentSinr != 0)
1465 sinrSum += currentSinr;
1476 NS_LOG_FUNCTION(
this);
1478 uint8_t wbCqi = m_amc->CreateCqiFeedbackWbTdma(sinr, mcs);
1483NrUePhy::StartEventLoop(uint16_t frame, uint8_t subframe, uint16_t slot)
1485 NS_LOG_FUNCTION(
this);
1489 NS_LOG_INFO(
"Initial bandwidth not set, configuring the default one for Cell ID: "
1491 DoSetInitialBandwidth();
1494 NS_LOG_INFO(
"PHY starting. Configuration: "
1496 <<
"\t TxPower: " <<
m_txPower <<
" dBm" << std::endl
1503 <<
"Attached to physical channel: " << std::endl
1508 StartSlot(startSlot);
1512NrUePhy::DoSetInitialBandwidth()
1514 NS_LOG_FUNCTION(
this);
1516 double initialBandwidthHz =
1519 uint16_t initialBandwidthIn100KHz = ceil(initialBandwidthHz / (100 * 1000));
1521 uint16_t initialBandwidthWithOverhead = initialBandwidthIn100KHz / (1 -
GetRbOverhead());
1523 NS_ABORT_MSG_IF(initialBandwidthWithOverhead == 0,
1524 " Initial bandwidth could not be set. Parameters provided are: "
1525 "\n dlBandwidthInRBNum = "
1527 <<
"\n NrSpectrumValueHelper::SUBCARRIERS_PER_RB = "
1531 DoSetDlBandwidth(initialBandwidthWithOverhead);
1535NrUePhy::DoGetCellId()
1541NrUePhy::DoGetDlEarfcn()
1545 NS_LOG_FUNCTION(
this);
1546 NS_LOG_WARN(
"DoGetDlEarfcn function is called. This function should be removed in future once "
1547 "NR has its own RRC.");
1552NrUePhy::DoSetDlBandwidth(uint16_t dlBandwidth)
1554 NS_LOG_FUNCTION(
this << +dlBandwidth);
1558 NS_LOG_DEBUG(
"PHY reconfiguring. Result: "
1560 <<
"\t TxPower: " <<
m_txPower <<
" dBm" << std::endl
1567 <<
"Attached to physical channel: " << std::endl
1574NrUePhy::DoConfigureUplink(uint16_t ulEarfcn, uint8_t ulBandwidth)
1576 NS_LOG_FUNCTION(
this << ulEarfcn << +ulBandwidth);
1578 m_ulConfigured =
true;
1582NrUePhy::DoConfigureReferenceSignalPower(int8_t referenceSignalPower)
1584 NS_LOG_FUNCTION(
this << referenceSignalPower);
1585 m_powerControl->ConfigureReferenceSignalPower(referenceSignalPower);
1589NrUePhy::DoSetRnti(uint16_t rnti)
1591 NS_LOG_FUNCTION(
this << rnti);
1597NrUePhy::DoSetTransmissionMode(uint8_t txMode)
1599 NS_LOG_FUNCTION(
this << +txMode);
1603NrUePhy::DoSetSrsConfigurationIndex(uint16_t srcCi)
1605 NS_LOG_FUNCTION(
this << srcCi);
1615NrUePhy::DoNotifyConnectionSuccessful()
1624 m_isConnected =
true;
1626 InitializeRlfParams();
1631NrUePhy::DoResetPhyAfterRlf()
1633 NS_LOG_FUNCTION(
this);
1639NrUePhy::DoResetRlfParams()
1641 NS_LOG_FUNCTION(
this);
1642 InitializeRlfParams();
1646NrUePhy::DoStartInSyncDetection()
1648 NS_LOG_FUNCTION(
this);
1650 m_downlinkInSync =
false;
1654NrUePhy::InitializeRlfParams()
1656 NS_LOG_FUNCTION(
this);
1657 m_numOfSubframes = 0;
1660 m_downlinkInSync =
true;
1664NrUePhy::RlfDetection(
double sinrDb)
1666 NS_LOG_FUNCTION(
this << sinrDb);
1667 m_sinrDbFrame += sinrDb;
1669 NS_LOG_LOGIC(
"No of Subframes: " << m_numOfSubframes
1670 <<
" UE synchronized: " << m_downlinkInSync);
1673 if (m_downlinkInSync && m_numOfSubframes == 10)
1679 if ((m_sinrDbFrame / m_numOfSubframes) < m_qOut)
1682 NS_LOG_LOGIC(
"No of Frames which cannot be decoded: " << m_numOfFrames);
1691 NS_LOG_INFO(
"Resetting frame counter at phy. Current value = " << m_numOfFrames);
1696 m_numOfSubframes = 0;
1704 if (m_downlinkInSync && (m_numOfFrames * 10) == m_numOfQoutEvalSf)
1706 NS_LOG_LOGIC(
"At " << Simulator::Now().As(Time::MS)
1707 <<
" ms UE PHY sending out of sync indication to UE RRC layer");
1713 if (!m_downlinkInSync && m_numOfSubframes == 10)
1720 if ((m_sinrDbFrame / m_numOfSubframes) > m_qIn)
1723 NS_LOG_LOGIC(
"No of Frames successfully decoded: " << m_numOfFrames);
1736 m_numOfSubframes = 0;
1743 if (!m_downlinkInSync && (m_numOfFrames * 10) == m_numOfQinEvalSf)
1745 NS_LOG_LOGIC(
"At " << Simulator::Now().As(Time::MS)
1746 <<
" ms UE PHY sending in sync indication to UE RRC layer");
1753NrUePhy::DoSetImsi(uint64_t imsi)
1755 NS_LOG_FUNCTION(
this);
1762 NS_LOG_FUNCTION(
this);
1764 if (!m_ulConfigured || (m_rnti == 0))
1770 if (!m_receptionEnabled)
1783 auto cqi = m_pmSearch->CreateCqiFeedbackMimo(rxSignal, pmiUpdateParams);
1787 .m_cqiType = cqi.m_cqiType,
1788 .m_wbCqi = cqi.m_wbCqi,
1789 .m_wbPmi = cqi.m_wbPmi,
1790 .m_sbCqis = cqi.m_sbCqis,
1791 .m_sbPmis = cqi.m_sbPmis,
1793 .m_optPrecMat = cqi.m_optPrecMat,
1796 auto msg = Create<NrDlCqiMessage>();
1798 msg->SetDlCqi(dlcqi);
1800 DoSendControlMessage(msg);
1812 auto now = Simulator::Now();
1813 if (now > m_wbPmiLastUpdate + m_wbPmiUpdateInterval)
1815 pmiUpdate.updateWb =
true;
1816 m_wbPmiLastUpdate = now;
1818 if (now > m_sbPmiLastUpdate + m_sbPmiUpdateInterval)
1820 pmiUpdate.updateSb =
true;
1821 m_sbPmiLastUpdate = now;
1829 m_pmSearch = pmSearch;
1831 m_pmSearch->SetAmc(m_amc);
@ UL_DCI
The resources allocation map from the BS to the attached UEs (UL)
@ DL_HARQ
DL HARQ feedback.
@ MIB
Master Information Block.
@ RAR
Random Access Response.
@ SIB1
System Information Block Type 1.
@ DL_DCI
The resources allocation map from the BS to the attached UEs (DL)
The base class for gNb and UE physical layer.
Time GetSymbolPeriod() const
Get SymbolPeriod.
Ptr< NrSpectrumPhy > m_spectrumPhy
Pointer to the (owned) spectrum phy.
SlotAllocInfo RetrieveSlotAllocInfo()
Get the head for the slot allocation info, and delete it from the internal list.
uint16_t GetCellId() const
uint16_t GetNumerology() const
Get the configured numerology.
Ptr< NrSpectrumPhy > GetSpectrumPhy() const
Retrieve the SpectrumPhy pointer.
void EncodeCtrlMsg(const Ptr< NrControlMessage > &msg)
Take the control messages, and put it in a list that will be sent at the first occasion.
virtual void SetTbDecodeLatency(const Time &us)
Configures TB decode latency.
std::list< Ptr< NrControlMessage > > m_ctrlMsgs
CTRL messages to be sent.
void PushBackSlotAllocInfo(const SlotAllocInfo &slotAllocInfo)
Store the slot allocation info.
Ptr< PacketBurst > GetPacketBurst(SfnSf sf, uint8_t sym, uint16_t rnti)
Retrieve the PacketBurst at the slot/symbol specified.
void SetPowerAllocationType(enum NrSpectrumValueHelper::PowerAllocationType powerAllocationType)
Set power allocation type. There are currently supported two types: one that distributes uniformly en...
static std::string GetPattern(const std::vector< LteNrTddSlotType > &pattern)
Get a string representation of a pattern.
Time GetSlotPeriod() const
Get the slot period.
virtual std::list< Ptr< NrControlMessage > > PopCurrentSlotCtrlMsgs()
Extract and return the message list that is at the beginning of the queue.
SlotAllocInfo m_currSlotAllocInfo
Current slot allocation.
enum NrSpectrumValueHelper::PowerAllocationType GetPowerAllocationType() const
Get the power allocation type.
void EnqueueCtrlMsgNow(const Ptr< NrControlMessage > &msg)
Enqueue a CTRL message without considering L1L2CtrlLatency.
uint32_t GetChannelBandwidth() const
Retrieve the channel bandwidth, in Hz.
virtual Time GetTbDecodeLatency() const
Returns Transport Block decode latency.
SlotAllocInfo & PeekSlotAllocInfo(const SfnSf &sfnsf)
Peek the SlotAllocInfo at the SfnSf specified.
double GetCentralFrequency() const
Retrieve the frequency (in Hz) of this PHY's channel.
double m_noiseFigure
Noise figure (attribute)
uint32_t m_raPreambleId
Preamble ID.
double GetNoiseFigure() const
Get the NoiseFigure value.
void SetNoiseFigure(double d)
Set the NoiseFigure value.
double m_txPower
Transmission power (attribute)
void InitializeMessageList()
Initialize the message list.
Ptr< SpectrumValue > GetTxPowerSpectralDensity(const std::vector< int > &rbIndexVector)
void SetChannelBandwidth(uint16_t bandwidth)
Function to set the channel bandwidth, used also by child classes, i.e., see functions DoSetDlBanwidt...
uint16_t GetBwpId() const
std::vector< int > FromRBGBitmaskToRBAssignment(const std::vector< uint8_t > rbgBitmask) const
Transform a MAC-made vector of RBG to a PHY-ready vector of SINR indices.
Ptr< NrNetDevice > m_netDevice
Pointer to the owner netDevice.
bool SlotAllocInfoExists(const SfnSf &sfnsf) const
Check if the SlotAllocationInfo for that slot exists.
uint32_t GetSubcarrierSpacing() const
Retrieve the subcarrier spacing in Hz. Subcarrier spacing is updated when the numerology is being upd...
uint32_t GetSymbolsPerSlot() const
Get the number of symbols in a slot.
std::vector< LteNrTddSlotType > m_tddPattern
Pattern.
double GetRbOverhead() const
Get the bandwidth overhead used when calculating the usable RB number.
uint32_t GetRbNum() const
Get the number of Resource block configured.
void EnqueueCtrlMessage(const Ptr< NrControlMessage > &m)
Enqueue a ctrl message, keeping in consideration L1L2CtrlDelay.
void DoDispose() override
DoDispose method inherited from Object.
void DoSetCellId(uint16_t cellId)
Set the cell ID.
Tag used to define the RNTI and LC id for each MAC packet transmitted.
static const uint8_t SUBCARRIERS_PER_RB
subcarriers per resource block
virtual void ReportUeMeasurements(UeMeasurementsParameters params)=0
Send a report of RSRP and RSRQ values perceived from PSS by the PHY entity (after applying layer-1 fi...
virtual void ResetSyncIndicationCounter()=0
Reset the sync indication counter.
virtual void RecvSystemInformationBlockType1(uint16_t cellId, NrRrcSap::SystemInformationBlockType1 sib1)=0
Relay an SIB1 message from the PHY entity to the RRC layer.
virtual void RecvMasterInformationBlock(uint16_t cellId, NrRrcSap::MasterInformationBlock mib)=0
Relay an MIB message from the PHY entity to the RRC layer.
virtual void NotifyOutOfSync()=0
Send an out of sync indication to UE RRC.
virtual void NotifyInSync()=0
Send an in sync indication to UE RRC.
void SetUplinkPowerControl(Ptr< NrUePowerControl > pc)
Allow configuration of uplink power control algorithm. E.g. necessary in FDD, when measurements are r...
void SetPhySapUser(NrUePhySapUser *ptr)
Install the PHY sap user (AKA the UE MAC)
void ScheduleStartEventLoop(uint32_t nodeId, uint16_t frame, uint8_t subframe, uint16_t slot) override
Start the ue Event Loop.
void ReceivePss(uint16_t cellId, const Ptr< SpectrumValue > &p)
Receive PSS and calculate RSRQ in dBm.
void EnqueueDlHarqFeedback(const DlHarqInfo &m)
Get the HARQ feedback (on the transmission) from NrSpectrumPhy and send it through ideal PUCCH to gNB...
void SetTxPower(double pow)
Set the transmission power for the UE.
NrUePhy()
NrUePhy default constructor.
void SetNumRbPerRbg(uint32_t numRbPerRbg)
Function that sets the number of RBs per RBG. This function will be soon deprecated,...
BeamId GetBeamId(uint16_t rnti) const override
Get the beam id for the specified user.
~NrUePhy() override
~NrUePhy
Ptr< NrPmSearch > GetPmSearch() const
Get the precoding matrix search engine.
NrPmSearch::PmiUpdate CheckUpdatePmi()
Check if updates to wideband and/or subband PMI are necessary. This function is used to limit the fre...
void SetPmSearch(Ptr< NrPmSearch > pmSearch)
Set the precoding matrix search engine.
uint32_t GetNumRbPerRbg() const override
Protected function that is used to get the number of resource blocks per resource block group.
NrUeCphySapProvider * GetUeCphySapProvider() __attribute__((warn_unused_result))
Retrieve the pointer for the C PHY SAP provider (AKA the PHY interface towards the RRC)
uint8_t ComputeCqi(const SpectrumValue &sinr)
Compute the CQI based on the SINR.
void SetDlAmc(const Ptr< const NrAmc > &amc)
Set the AMC pointer from the GNB.
double GetTxPower() const override
Retrieve the TX power of the UE.
void SetDlCtrlSyms(uint8_t dlCtrlSyms)
Set the number of DL CTRL symbols.
double GetRsrp() const
Returns the latest measured RSRP value Called by NrUePowerControl.
void DoDispose() override
DoDispose method inherited from Object.
Ptr< NrUePowerControl > GetUplinkPowerControl() const
Get NR uplink power control entity.
void GenerateDlCqiReport(const SpectrumValue &sinr)
Generate a DL CQI report.
void SetCam(const Ptr< NrChAccessManager > &cam)
Set the channel access manager interface for this instance of the PHY.
void SetPattern(const std::string &pattern)
Set the UE pattern.
void GenerateDlCqiReportMimo(const std::vector< MimoSignalChunk > &mimoChunks)
Generate DL CQI, PMI, and RI (channel quality precoding matrix and rank indicators)
void SetUlCtrlSyms(uint8_t ulCtrlSyms)
Set the number of UL CTRL symbols.
uint16_t GetRnti() const __attribute__((warn_unused_result))
Get the current RNTI of the user.
void RegisterToGnb(uint16_t bwpId)
Register the UE to a certain Gnb.
const SfnSf & GetCurrentSfnSf() const override
Get the current SfnSf.
void SetUeCphySapUser(NrUeCphySapUser *s)
Install ue C PHY SAP user (AKA the PHY interface towards the RRC)
void PhyCtrlMessagesReceived(const Ptr< NrControlMessage > &msg)
Receive a list of CTRL messages.
void ReportDlCtrlSinr(const SpectrumValue &sinr)
Called when DlCtrlSinr is fired.
void PhyDataPacketReceived(const Ptr< Packet > &p)
Receive a PHY data packet.
void ReportRsReceivedPower(const SpectrumValue &power)
Called when rsReceivedPower is fired.
static TypeId GetTypeId()
Get the object TypeId.
SAP interface between the UE PHY and the UE MAC.
virtual void ReceiveControlMessage(Ptr< NrControlMessage > msg)=0
Receive SendNrControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel.
virtual void ReceivePhyPdu(Ptr< Packet > p)=0
Notify the MAC of the reception of a new PHY-PDU.
virtual void SlotIndication(SfnSf s)=0
Trigger the indication of a new slot for the MAC.
void Add(uint32_t slotN)
Add to this SfnSf a number of slot indicated by the first parameter.
@ F
DL CTRL + DL DATA + UL DATA + UL CTRL.
@ S
DL CTRL + DL DATA + UL CTRL.
@ CTRL
Used for DL/UL CTRL.
@ DATA
Used for DL/UL DATA.
@ SRS
Used for SRS (it would be like DCI format 2_3)
enum ns3::DlCqiInfo::DlCqiType WB
The type of the CQI.
A struct that contains info for the DL HARQ.
uint8_t m_harqProcessId
ProcessId.
Helper struct for processing and storing received signals for use in CSI feedback.
Parameters that define if PMI should be updated or if previous PMI values are used.
UeMeasurementsParameters structure.
std::vector< UeMeasurementsElement > m_ueMeasurementsList
UE measurement list.
uint8_t m_componentCarrierId
component carrier ID
SfnSf m_sfnSf
SfnSf of this allocation.
std::deque< VarTtiAllocInfo > m_varTtiAllocInfo
queue of allocations