23 #include <ns3/object-factory.h>
27 #include <ns3/simulator.h>
28 #include <ns3/double.h>
39 #include <ns3/lte-common.h>
40 #include <ns3/pointer.h>
121 m_p10CqiPeriocity (MilliSeconds (1)),
122 m_a30CqiPeriocity (MilliSeconds (1)),
126 m_rsReceivedPowerUpdated (false),
127 m_rsInterferencePowerUpdated (false),
128 m_pssReceived (false),
129 m_ueMeasurementsFilterPeriod (MilliSeconds (200)),
130 m_ueMeasurementsFilterLast (MilliSeconds (0)),
131 m_rsrpSinrSampleCounter (0)
133 m_amc = CreateObject <LteAmc> ();
139 "Cannot create UE devices after simulation started");
168 .AddConstructor<LteUePhy> ()
169 .AddAttribute (
"TxPower",
170 "Transmission power in dBm",
174 MakeDoubleChecker<double> ())
175 .AddAttribute (
"NoiseFigure",
176 "Loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver."
177 " According to Wikipedia (http://en.wikipedia.org/wiki/Noise_figure), this is "
178 "\"the difference in decibels (dB) between"
179 " the noise output of the actual receiver to the noise output of an "
180 " ideal receiver with the same overall gain and bandwidth when the receivers "
181 " are connected to sources at the standard noise temperature T0.\" "
182 "In this model, we consider T0 = 290K.",
186 MakeDoubleChecker<double> ())
187 .AddAttribute (
"TxMode1Gain",
188 "Transmission mode 1 gain in dB",
191 MakeDoubleChecker<double> ())
192 .AddAttribute (
"TxMode2Gain",
193 "Transmission mode 2 gain in dB",
196 MakeDoubleChecker<double> ())
197 .AddAttribute (
"TxMode3Gain",
198 "Transmission mode 3 gain in dB",
201 MakeDoubleChecker<double> ())
202 .AddAttribute (
"TxMode4Gain",
203 "Transmission mode 4 gain in dB",
206 MakeDoubleChecker<double> ())
207 .AddAttribute (
"TxMode5Gain",
208 "Transmission mode 5 gain in dB",
211 MakeDoubleChecker<double> ())
212 .AddAttribute (
"TxMode6Gain",
213 "Transmission mode 6 gain in dB",
216 MakeDoubleChecker<double> ())
217 .AddAttribute (
"TxMode7Gain",
218 "Transmission mode 7 gain in dB",
221 MakeDoubleChecker<double> ())
222 .AddTraceSource (
"ReportCurrentCellRsrpSinr",
223 "RSRP and SINR statistics.",
225 .AddAttribute (
"RsrpSinrSamplePeriod",
226 "The sampling period for reporting RSRP-SINR stats (default value 1)",
229 MakeUintegerChecker<uint16_t> ())
230 .AddTraceSource (
"UlPhyTransmission",
231 "DL transmission PHY layer statistics.",
233 .AddAttribute (
"DlSpectrumPhy",
234 "The downlink LteSpectrumPhy associated to this LtePhy",
238 MakePointerChecker <LteSpectrumPhy> ())
239 .AddAttribute (
"UlSpectrumPhy",
240 "The uplink LteSpectrumPhy associated to this LtePhy",
244 MakePointerChecker <LteSpectrumPhy> ())
245 .AddAttribute (
"RsrqUeMeasThreshold",
246 "Receive threshold for PSS on RSRQ [dB]",
249 MakeDoubleChecker<double> ())
250 .AddAttribute (
"UeMeasurementsFilterPeriod",
251 "Time period for reporting UE measurements (default 200 ms.) ",
255 .AddTraceSource (
"ReportUeMeasurements",
256 "Report UE measurements RSRP (dBm) and RSRQ (dB).",
449 Values::const_iterator it;
455 double powerTxW = ((*it) * 180000.0) / 12.0;
459 double rsrp = (rbNum > 0) ? (sum / rbNum) : DBL_MAX;
468 double avSinr = (rbNum > 0) ? (sum / rbNum) : DBL_MAX;
481 std::list <PssElement>::iterator itPss =
m_pssList.begin ();
485 double rsrqSum = 0.0;
492 double noisePowerTxW = ((*itIntN) * 180000.0) / 12.0;
493 double intPowerTxW = ((*itPj) * 180000.0) / 12.0;
494 rsrqSum += (2 * (noisePowerTxW + intPowerTxW));
497 double rsrp_dBm = 10 * log10 (1000 * ((*itPss).pssPsdSum / (
double)rbNum));
498 double rsrq_dB = 10 * log10 ((*itPss).pssPsdSum / rsrqSum);
503 NS_LOG_INFO (
this <<
" PSS received from CellId " << (*itPss).cellId <<
" has RSRP " << rsrp_dBm <<
" and RSRQ " << rsrq_dB <<
" RBnum " << (uint16_t)rbNum);
505 std::map <uint16_t, UeMeasurementsElement>::iterator itMeasMap =
m_UeMeasurementsMap.find ((*itPss).cellId);
514 m_UeMeasurementsMap.insert (std::pair <uint16_t, UeMeasurementsElement> ((*itPss).cellId, newEl));
518 (*itMeasMap).second.rsrpSum += rsrp_dBm;
519 (*itMeasMap).second.rsrpNum++;
520 (*itMeasMap).second.rsrqSum += rsrq_dB;
521 (*itMeasMap).second.rsrqNum++;
572 std::vector<int> cqi;
578 int nbSubChannels = cqi.size ();
580 int activeSubChannels = 0;
582 for (
int i = 0; i < nbSubChannels; i++)
584 if (cqi.at (i) != -1)
586 cqiSum += cqi.at (i);
589 NS_LOG_DEBUG (
this <<
" subch " << i <<
" cqi " << cqi.at (i));
596 for (
int i = 0; i < nLayer; i++)
598 if (activeSubChannels > 0)
600 dlcqi.m_wbCqi.push_back ((uint16_t) cqiSum / activeSubChannels);
605 dlcqi.m_wbCqi.push_back (1);
616 int nbSubChannels = cqi.size ();
622 for (
int i = 0; i < nbSubChannels; i++)
624 if (cqi.at (i) != -1)
626 cqiSum += cqi.at (i);
630 if (cqiNum == rbgSize)
636 for (
int i = 0; i < nLayer; i++)
638 hlCqi.
m_sbCqi.push_back ((uint16_t) cqiSum / rbgSize);
650 dlcqi.m_sbMeasResult = rbgMeas;
653 msg->SetDlCqi (dlcqi);
664 std::map <uint16_t, UeMeasurementsElement>::iterator it;
667 double avg_rsrp = (*it).second.rsrpSum / (double)(*it).second.rsrpNum;
668 double avg_rsrq = (*it).second.rsrqSum / (
double)(*it).second.rsrqNum;
669 NS_LOG_DEBUG (
this <<
" CellId " << (*it).first <<
" RSRP " << avg_rsrp <<
" (nSamples " << (*it).second.rsrpNum <<
") RSRQ " << avg_rsrq <<
" (nSamples " << (*it).second.rsrpNum <<
")");
700 msg->SetRapId (raPreambleId);
712 std::list<Ptr<LteControlMessage> >::iterator it;
713 for (it = msgList.begin (); it != msgList.end(); it++)
728 if (dci.m_resAlloc != 0)
733 std::vector <int> dlRb;
737 for (
int i = 0; i < 32; i++)
739 if (((dci.m_rbBitmap & mask) >> i) == 1)
743 dlRb.push_back ((i * GetRbgSize ()) + k);
751 NS_LOG_DEBUG (
this <<
" UE " <<
m_rnti <<
" DL-DCI " << dci.m_rnti <<
" bitmap " << dci.m_rbBitmap);
752 for (uint8_t i = 0; i < dci.m_tbsSize.size (); i++)
754 m_downlinkSpectrumPhy->AddExpectedTb (dci.m_rnti, dci.m_ndi.at (i), dci.m_tbsSize.at (i), dci.m_mcs.at (i), dlRb, i, dci.m_harqProcess, dci.m_rv.at (i),
true );
772 std::vector <int> ulRb;
773 for (
int i = 0; i < dci.m_rbLen; i++)
775 ulRb.push_back (i + dci.m_rbStart);
788 params.
m_mcs = dci.m_mcs;
789 params.
m_size = dci.m_tbSize;
790 params.
m_rv = harqInfoList.size ();
791 params.
m_ndi = dci.m_ndi;
799 if (rarMsg->GetRaRnti () ==
m_raRnti)
801 for (std::list<RarLteControlMessage::Rar>::const_iterator it = rarMsg->RarListBegin (); it != rarMsg->RarListEnd (); ++it)
812 std::vector <int> ulRb;
813 for (
int i = 0; i < it->rarPayload.m_grant.m_rbLen; i++)
815 ulRb.push_back (i + it->rarPayload.m_grant.m_rbStart);
860 Values::const_iterator itPi;
861 for (itPi = p->ConstValuesBegin (); itPi != p->ConstValuesEnd (); itPi++)
864 double powerTxW = ((*itPi) * 180000.0) / 12.0;
886 NS_ASSERT_MSG (frameNo > 0,
"the SRS index check code assumes that frameNo starts at 1");
908 NS_ASSERT_MSG (subframeNo > 0 && subframeNo <= 10,
"the SRS index check code assumes that subframeNo starts at 1");
930 if (ctrlMsg.size ()>0)
932 NS_LOG_LOGIC (
this <<
" UE - start TX PUCCH (NO PUSCH)");
933 std::vector <int> dlRb;
965 std::vector <int> dlRb;
999 std::list<Ptr<LteControlMessage> > l;
1002 std::vector <int> ulRb;
1043 for (
int i = 0; i < 4; i++)
1045 if (dlBandwidth < Type0AllocationRbg[i])
1147 double gainLin = std::pow (10.0, (gain / 10.0));
1152 std::vector <double> temp;
1155 for (uint8_t i = 0; i < temp.size (); i++)
1178 msg->SetDlHarqFeedback (m);
Values::const_iterator ConstValuesEnd() const
See section 4.3.1 dlDciListElement.
double GetNoiseFigure() const
Ptr< LteSpectrumPhy > GetUlSpectrumPhy() const
SpectrumValue m_rsIntereferencePower
keep track of time values and allow control of global simulation resolution
#define NS_LOG_FUNCTION(parameters)
virtual void ReceiveLteControlMessage(Ptr< LteControlMessage > msg)=0
Receive SendLteControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel.
See section 4.3.25 sbMeasResult.
std::vector< struct UeMeasurementsElement > m_ueMeasurementsList
LteUePhySapUser * m_uePhySapUser
void SetNoiseFigure(double pow)
void SetTxMode5Gain(double gain)
virtual void SendMacPdu(Ptr< Packet > p)
Send the MAC PDU to the channel.
virtual void GenerateDataCqiReport(const SpectrumValue &sinr)
std::list< PssElement > m_pssList
void SetTxMode2Gain(double gain)
uint8_t GetMacChDelay(void) const
void DoConfigureUplink(uint16_t ulEarfcn, uint8_t ulBandwidth)
std::vector< Ptr< PacketBurst > > m_packetBurstQueue
std::vector< int > GetSubChannelsForTransmission(void)
Get a list of sub channels to use in RX.
virtual void GenerateCtrlCqiReport(const SpectrumValue &sinr)
TracedCallback< uint16_t, uint16_t, double, double > m_reportCurrentCellRsrpSinrTrace
void DoSyncronizeWithEnb(uint16_t cellId, uint16_t dlEarfcn)
void SetSubChannelsForTransmission(std::vector< int > mask)
Set a list of sub channels to use in TX.
uint16_t GetSrsPeriodicity(uint16_t srcCi) const
double GetTti(void) const
LteUePhySapProvider * m_uePhySapProvider
#define NS_ASSERT(condition)
void SetTxMode6Gain(double gain)
#define NS_LOG_COMPONENT_DEFINE(name)
Ptr< LteSpectrumPhy > m_downlinkSpectrumPhy
See section 4.3.2 ulDciListElement.
virtual void SendLteControlMessage(Ptr< LteControlMessage > msg)
Send SendLteControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel.
See section 4.3.24 cqiListElement.
std::vector< double > m_txModeGain
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
void QueueSubChannelsForTransmission(std::vector< int > rbMap)
void SetTxModeGain(uint8_t txMode, double gain)
std::map< uint16_t, UeMeasurementsElement > m_UeMeasurementsMap
virtual void DoSendMacPdu(Ptr< Packet > p)
Queue the MAC PDU to be sent (according to m_macChTtiDelay)
std::vector< int > GetSubChannelsForReception(void)
Get a list of sub channels to use in RX.
This class defines all functions to create spectrum model for lte.
uint8_t m_transmissionMode
void SetHarqPhyModule(Ptr< LteHarqPhy > harq)
Set the HARQ PHY module.
Ptr< LteNetDevice > GetDevice()
Get the device where the phy layer is attached.
#define NS_FATAL_ERROR(msg)
fatal error handling
void DoSetSrsConfigurationIndex(uint16_t srcCi)
void DoSetTransmissionMode(uint8_t txMode)
UeMemberLteUePhySapProvider(LteUePhy *phy)
double m_pssReceptionThreshold
TracedCallback< uint16_t, uint16_t, double, double, bool > m_reportUeMeasurements
uint16_t GetSrsSubframeOffset(uint16_t srcCi) const
LteUeCphySapUser * m_ueCphySapUser
void DoSetDlBandwidth(uint8_t ulBandwidth)
hold objects of type ns3::Time
uint8_t GetRbgSize(void) const
uint16_t m_rsrpSinrSamplePeriod
See section 4.3.27 higherLayerSelected.
void SetLteUePhySapUser(LteUePhySapUser *s)
Set the PHY SAP User.
Hold an unsigned integer type.
void SetTxMode3Gain(double gain)
static uint8_t TxMode2LayerNum(uint8_t txMode)
NS_OBJECT_ENSURE_REGISTERED(AntennaModel)
Ptr< DlCqiLteControlMessage > CreateDlCqiFeedbackMessage(const SpectrumValue &sinr)
Create the DL CQI feedback from SINR values perceived at the physical layer with the signal received ...
void SetTxMode4Gain(double gain)
void SendSrs()
Send the SRS signal in the last symbols of the frame.
bool m_rsInterferencePowerUpdated
#define NS_LOG_LOGIC(msg)
std::vector< uint8_t > m_sbCqi
void SetTxMode7Gain(double gain)
See section 4.3.23 dlInfoListElement.
virtual void DoSendRachPreamble(uint32_t prachId, uint32_t raRnti)
virtual void ReceiveLteDlHarqFeedback(DlInfoListElement_s mes)
PhySpectrum generated a new DL HARQ feedback.
static const Time UL_DATA_DURATION
Ptr< LteHarqPhy > m_harqPhyModule
hold objects of type Ptr<T>
void SetControlMessages(Ptr< LteControlMessage > m)
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
uint16_t m_rsrpSinrSampleCounter
SpectrumValue m_rsReceivedPower
double GetTxPower() const
uint16_t m_srsSubframeOffset
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
void SubframeIndication(uint32_t frameNo, uint32_t subframeNo)
trigger from eNB the start from a new frame
virtual void DoInitialize(void)
#define NS_ASSERT_MSG(condition, message)
static Ptr< SpectrumValue > CreateTxPowerSpectralDensity(uint16_t earfcn, uint8_t bandwidth, double powerTx, std::vector< int > activeRbs)
void SetTxMode1Gain(double gain)
std::vector< int > m_subChannelsForTransmission
std::vector< std::vector< int > > m_subChannelsForTransmissionQueue
std::list< Ptr< LteControlMessage > > GetControlMessages(void)
LteUeCphySapProvider * m_ueCphySapProvider
Ptr< PacketBurst > GetPacketBurst(void)
std::vector< int > m_subChannelsForReception
static const Time UL_SRS_DELAY_FROM_SUBFRAME_START
int Type0AllocationRbg[4]
#define NS_LOG_DEBUG(msg)
virtual void ReceiveLteControlMessageList(std::list< Ptr< LteControlMessage > >)
void SetTxPower(double pow)
virtual void ReceivePss(uint16_t cellId, Ptr< SpectrumValue > p)
uint16_t m_srsPeriodicity
LteUePhySapProvider * GetLteUePhySapProvider()
Get the PHY SAP provider.
virtual void SendRachPreamble(uint32_t prachId, uint32_t raRnti)
void SetLteUeCphySapUser(LteUeCphySapUser *s)
Set the CPHY SAP User.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range. Both limits are inclusive.
friend class UeMemberLteUePhySapProvider
void PhyPduReceived(Ptr< Packet > p)
PhySpectrum received a new PHY-PDU.
Values::const_iterator ConstValuesBegin() const
virtual void DoSendLteControlMessage(Ptr< LteControlMessage > msg)
std::vector< std::list< Ptr< LteControlMessage > > > m_controlMessagesQueue
bool m_rsReceivedPowerUpdated
Ptr< LteSpectrumPhy > GetDlSpectrumPhy() const
Ptr< LteSpectrumPhy > m_uplinkSpectrumPhy
virtual void ReportRsReceivedPower(const SpectrumValue &power)
LteUeCphySapProvider * GetLteUeCphySapProvider()
Get the CPHY SAP provider.
Hold an floating point type.
Set of values corresponding to a given SpectrumModel.
void SetMacPdu(Ptr< Packet > p)
std::vector< struct HigherLayerSelected_s > m_higherLayerSelected
a unique identifier for an interface.
int64_t GetMilliSeconds(void) const
TypeId SetParent(TypeId tid)
virtual void DoInitialize(void)
TracedCallback< PhyTransmissionStatParameters > m_ulPhyTransmission
static TypeId GetTypeId(void)
void ReportUeMeasurements()
virtual void ReportInterference(const SpectrumValue &interf)
virtual void RecvMasterInformationBlock(LteRrcSap::MasterInformationBlock mib)=0
virtual void ReceivePhyPdu(Ptr< Packet > p)=0
static Ptr< SpectrumValue > CreateNoisePowerSpectralDensity(uint16_t earfcn, uint8_t bandwidth, double noiseFigure)
virtual Ptr< SpectrumValue > CreateTxPowerSpectralDensity()
Create the PSD for the TX.
#define UL_PUSCH_TTIS_DELAY
void DoSetRnti(uint16_t rnti)
virtual void SubframeIndication(uint32_t frameNo, uint32_t subframeNo)=0
Trigger the start from a new frame (input from Phy layer)
std::vector< HarqProcessInfoElement_t > HarqProcessInfoList_t
void SetSubChannelsForReception(std::vector< int > mask)
Get a list of sub channels to use in RX.
virtual void DoDispose(void)
Time m_ueMeasurementsFilterPeriod