Add RSRP-RSRQ UE measurement and correspondent c-phy primitive for reporting them to LteUeRrr

This commit is contained in:
Marco Miozzo
2013-02-20 16:35:51 +01:00
parent 35f0e489aa
commit 1468df1fdb
14 changed files with 219 additions and 40 deletions

View File

@@ -725,13 +725,6 @@ According to the considerations above, a model more flexible can be obtained con
Therefore the PHY layer implements the MIMO model as the gain perceived by the receiver when using a MIMO scheme respect to the one obtained using SISO one. We note that, these gains referred to a case where there is no correlation between the antennas in MIMO scheme; therefore do not model degradation due to paths correlation.
.. only:: latex
.. raw:: latex
\clearpage
----------
HARQ
----------
@@ -776,12 +769,41 @@ Finally, the HARQ engine is always active both at MAC and PHY layer; however, in
Interaction between HARQ and LTE protocol stack
.. only:: latex
.. raw:: latex
\clearpage
---------------
UE Measurements
---------------
According to [TS36214]_, the UE has to report a set of measurements of the eNBs that the device is able to perceive: the the reference signal received power (RSRP) and the reference signal received quality (RSRQ). The former is a measure of the received power of a specific eNB, while the latter includes also channel interference and thermal noise.
The UE has to report the measurements jointly with the physical cell identity (PCI) of the cell. Both measurements are performed during the reception of the RS, while the PCI is obtained with the Primary Synchronization Signal (PSS). The PSS is sent by the eNB each 5 subframes and in detail in the subframes 1 and 6.
According to the constraints of the PHY reception chain implementation and in order to maintain the level of computational complexity low, only RSRP can be directly obtained. This is due to the fact that ``LteInterference`` is designed for evaluating the interference only respect to the signal of the eNB attached to. For what concern RSRQ, it can be extracted by the current information available of the cell and the RSRP as detailed in the following:
.. math::
RSRP_i = \frac{\sum_{k=0}^{K-1}(P_i(k))}{K}
RSSI_i^j = \sum_{k=0}^{K-1} ( I_j(k) + P_j(k) + N )
RSRQ_i^j = K \times RSRP_i / RSSI_i^j
wherem :math:`RSRP_i` is the RSRP of cell :math:`i`, :math:`P_i(k)` is the power perceived at the RB :math:`k`, :math:`K` is the total number of RBs, :math:`RSSI_i^j` is the RSSI of the cell :math:`i` when the UE is attached to :math:`j`, :math:`I_j(k)` is the total interference perceived by UE when attached to cell :math:`i` (obtained by the ``LteInterferencePowerChunkProcessor``) in the RB :math:`k`, :math:`P_j(k)` is the power of the perceived of cell :math:`j` in the RB :math:`k` and :math:`N` is the power noise spectral density.
In detail, upon reception of RS and PSS signal, the UE reception chain in ``LteUePhy`` triggers the generation of such report to the upper layers containing the RSRP and RSRQ measurements of the eNB that generated the RS when the measurement is above the one defined by the ns3 attibute ``UeMeasurementSnrThr``.
.. only:: latex
.. raw:: latex
.. raw:: latex
\clearpage
\clearpage
------

View File

@@ -18,6 +18,8 @@ References
.. [TS36213] 3GPP TS 36.213 "E-UTRA Physical layer procedures"
.. [TS36214] 3GPP TS 36.213 "E-UTRA Physical layer Measurements"
.. [TS36300] 3GPP TS 36.300 "E-UTRA and E-UTRAN; Overall description; Stage 2"
.. [TS36304] 3GPP TS 36.104 "E-UTRA User Equipment (UE) procedures in idle mode"

View File

@@ -338,7 +338,7 @@ LteHelper::InstallSingleEnbDevice (Ptr<Node> n)
ulPhy->AddDataSinrChunkProcessor (pData); // for evaluating PUSCH UL-CQI
Ptr<LteInterferencePowerChunkProcessor> pInterf = Create<LteInterferencePowerChunkProcessor> (phy);
ulPhy->AddInterferenceChunkProcessor (pInterf); // for interference power tracing
ulPhy->AddInterferenceDataChunkProcessor (pInterf); // for interference power tracing
dlPhy->SetChannel (m_downlinkChannel);
ulPhy->SetChannel (m_uplinkChannel);
@@ -477,6 +477,9 @@ LteHelper::InstallSingleUeDevice (Ptr<Node> n)
Ptr<LteRsReceivedPowerChunkProcessor> pRs = Create<LteRsReceivedPowerChunkProcessor> (phy->GetObject<LtePhy> ());
dlPhy->AddRsPowerChunkProcessor (pRs);
Ptr<LteInterferencePowerChunkProcessor> pInterf = Create<LteInterferencePowerChunkProcessor> (phy);
dlPhy->AddInterferenceCtrlChunkProcessor (pInterf); // for RSRQ evaluation of UE Measurements
Ptr<LteCtrlSinrChunkProcessor> pCtrl = Create<LteCtrlSinrChunkProcessor> (phy->GetObject<LtePhy> (), dlPhy);
dlPhy->AddCtrlSinrChunkProcessor (pCtrl);
@@ -547,6 +550,7 @@ LteHelper::InstallSingleUeDevice (Ptr<Node> n)
n->AddDevice (dev);
dlPhy->SetLtePhyRxDataEndOkCallback (MakeCallback (&LteUePhy::PhyPduReceived, phy));
dlPhy->SetLtePhyRxCtrlEndOkCallback (MakeCallback (&LteUePhy::ReceiveLteControlMessageList, phy));
dlPhy->SetLtePhyRxPssCallback (MakeCallback (&LteUePhy::ReceivePss, phy));
dlPhy->SetLtePhyDlHarqFeedbackCallback (MakeCallback (&LteUePhy::ReceiveLteDlHarqFeedback, phy));
nas->SetForwardUpCallback (MakeCallback (&LteUeNetDevice::Receive, dev));

View File

@@ -650,7 +650,12 @@ LteEnbPhy::SendControlChannels (std::list<Ptr<LteControlMessage> > ctrlMsgList)
}
SetDownlinkSubChannels (dlRb);
NS_LOG_LOGIC (this << " eNB start TX CTRL");
m_downlinkSpectrumPhy->StartTxDlCtrlFrame (ctrlMsgList);
bool pss = false;
if ((m_nrSubFrames == 1) || (m_nrSubFrames == 6))
{
pss = true;
}
m_downlinkSpectrumPhy->StartTxDlCtrlFrame (ctrlMsgList, pss);
}

View File

@@ -82,14 +82,14 @@ LteInterference::StartRx (Ptr<const SpectrumValue> rxPsd)
{
(*it)->Start ();
}
for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_sinrChunkProcessorList.begin (); it != m_sinrChunkProcessorList.end (); ++it)
{
(*it)->Start ();
}
for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_interfChunkProcessorList.begin (); it != m_interfChunkProcessorList.end (); ++it)
{
(*it)->Start ();
}
for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_sinrChunkProcessorList.begin (); it != m_sinrChunkProcessorList.end (); ++it)
{
(*it)->Start ();
}
}
else
{
@@ -119,14 +119,14 @@ LteInterference::EndRx ()
{
(*it)->End ();
}
for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_sinrChunkProcessorList.begin (); it != m_sinrChunkProcessorList.end (); ++it)
{
(*it)->End ();
}
for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_interfChunkProcessorList.begin (); it != m_interfChunkProcessorList.end (); ++it)
{
(*it)->End ();
}
for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_sinrChunkProcessorList.begin (); it != m_sinrChunkProcessorList.end (); ++it)
{
(*it)->End ();
}
}
}
@@ -196,21 +196,16 @@ LteInterference::ConditionallyEvaluateChunk ()
{
(*it)->EvaluateSinrChunk (sinr, duration);
}
for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_interfChunkProcessorList.begin (); it != m_interfChunkProcessorList.end (); ++it)
{
(*it)->EvaluateSinrChunk (interf, duration);
}
for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_rsPowerChunkProcessorList.begin (); it != m_rsPowerChunkProcessorList.end (); ++it)
{
(*it)->EvaluateSinrChunk (*m_rxSignal, duration);
}
for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_interfChunkProcessorList.begin (); it != m_interfChunkProcessorList.end (); ++it)
{
NS_LOG_DEBUG (this << "ConditionallyEvaluateChunk INTERF ");
(*it)->EvaluateSinrChunk (interf, duration);
}
m_lastChangeTime = Now ();
}
else
{
NS_LOG_DEBUG (this << " NO EV");
}
}
void

View File

@@ -155,6 +155,7 @@ void LteSpectrumPhy::DoDispose ()
m_ltePhyRxCtrlEndErrorCallback = MakeNullCallback< void > ();
m_ltePhyDlHarqFeedbackCallback = MakeNullCallback< void, DlInfoListElement_s > ();
m_ltePhyUlHarqFeedbackCallback = MakeNullCallback< void, UlInfoListElement_s > ();
m_ltePhyRxPssCallback = MakeNullCallback< void, uint16_t, SpectrumValue > ();
SpectrumPhy::DoDispose ();
}
@@ -354,6 +355,14 @@ LteSpectrumPhy::SetLtePhyRxCtrlEndErrorCallback (LtePhyRxCtrlEndErrorCallback c)
m_ltePhyRxCtrlEndErrorCallback = c;
}
void
LteSpectrumPhy::SetLtePhyRxPssCallback (LtePhyRxPssCallback c)
{
NS_LOG_FUNCTION (this);
m_ltePhyRxPssCallback = c;
}
void
LteSpectrumPhy::SetLtePhyDlHarqFeedbackCallback (LtePhyDlHarqFeedbackCallback c)
{
@@ -463,11 +472,12 @@ LteSpectrumPhy::StartTxDataFrame (Ptr<PacketBurst> pb, std::list<Ptr<LteControlM
}
bool
LteSpectrumPhy::StartTxDlCtrlFrame (std::list<Ptr<LteControlMessage> > ctrlMsgList)
LteSpectrumPhy::StartTxDlCtrlFrame (std::list<Ptr<LteControlMessage> > ctrlMsgList, bool pss)
{
NS_LOG_FUNCTION (this << time);
NS_LOG_FUNCTION (this << time << " PSS " << (uint16_t)pss);
NS_LOG_LOGIC (this << " state: " << m_state);
// m_phyTxStartTrace (pb);
switch (m_state)
@@ -503,6 +513,7 @@ LteSpectrumPhy::StartTxDlCtrlFrame (std::list<Ptr<LteControlMessage> > ctrlMsgLi
txParams->txAntenna = m_antenna;
txParams->psd = m_txPsd;
txParams->cellId = m_cellId;
txParams->pss = pss;
txParams->ctrlMsgList = ctrlMsgList;
m_channel->StartTx (txParams);
m_endTxEvent = Simulator::Schedule (DL_CTRL_DURATION, &LteSpectrumPhy::EndTx, this);
@@ -746,6 +757,18 @@ LteSpectrumPhy::StartRxCtrl (Ptr<SpectrumSignalParameters> params)
cellId = lteUlSrsRxParams->cellId;
dl = false;
}
if (dl)
{
// check presence of PSS for UE measuerements
if (lteDlCtrlRxParams->pss == true)
{
SpectrumValue pssPsd = *params->psd;
if (!m_ltePhyRxPssCallback.IsNull ())
{
m_ltePhyRxPssCallback (cellId, pssPsd);
}
}
}
if (cellId == m_cellId)
{
NS_LOG_LOGIC (this << " synchronized with this signal (cellId=" << cellId << ")");
@@ -786,7 +809,7 @@ LteSpectrumPhy::StartRxCtrl (Ptr<SpectrumSignalParameters> params)
else
{
NS_LOG_LOGIC (this << " not in sync with this signal (cellId="
<< cellId << ", m_cellId=" << m_cellId << ")");
<< cellId << ", m_cellId=" << m_cellId << ")");
}
}
break;
@@ -1105,7 +1128,13 @@ LteSpectrumPhy::AddDataSinrChunkProcessor (Ptr<LteSinrChunkProcessor> p)
}
void
LteSpectrumPhy::AddInterferenceChunkProcessor (Ptr<LteSinrChunkProcessor> p)
LteSpectrumPhy::AddInterferenceCtrlChunkProcessor (Ptr<LteSinrChunkProcessor> p)
{
m_interferenceCtrl->AddInterferenceChunkProcessor (p);
}
void
LteSpectrumPhy::AddInterferenceDataChunkProcessor (Ptr<LteSinrChunkProcessor> p)
{
m_interferenceData->AddInterferenceChunkProcessor (p);
}

View File

@@ -121,6 +121,13 @@ typedef Callback< void, std::list<Ptr<LteControlMessage> > > LtePhyRxCtrlEndOkCa
*/
typedef Callback< void > LtePhyRxCtrlEndErrorCallback;
/**
* This method is used by the LteSpectrumPhy to notify the UE PHY that a
* PSS has been received
*/
typedef Callback< void, uint16_t, SpectrumValue > LtePhyRxPssCallback;
/**
* This method is used by the LteSpectrumPhy to notify the PHY about
* the status of a certain DL HARQ process
@@ -220,13 +227,13 @@ public:
* Start a transmission of control frame in DL
*
*
* @param dlDci the burst of DL-DCIs to be transmitted
* @param ulDci the burst of UL-DCIs to be transmitted
* @param ctrlMsgList the burst of contrl messages to be transmitted
* @param pss the flag for transmitting the primary synchronization signal
*
* @return true if an error occurred and the transmission was not
* started, false otherwise.
*/
bool StartTxDlCtrlFrame (std::list<Ptr<LteControlMessage> > ctrlMsgList);
bool StartTxDlCtrlFrame (std::list<Ptr<LteControlMessage> > ctrlMsgList, bool pss);
/**
@@ -281,6 +288,14 @@ public:
*/
void SetLtePhyRxCtrlEndErrorCallback (LtePhyRxCtrlEndErrorCallback c);
/**
* set the callback for the reception of the PSS as part
* of the interconnections between the LteSpectrumPhy and the UE PHY
*
* @param c the callback
*/
void SetLtePhyRxPssCallback (LtePhyRxPssCallback c);
/**
* set the callback for the DL HARQ feedback as part of the
* interconnections betweenthe LteSpectrumPhy and the PHY
@@ -328,11 +343,19 @@ public:
/**
* LteSinrChunkProcessor devoted to evaluate intefrerence + noise power
* in data frame
* in control symbols of the subframe
*
* \param p the new LteSinrChunkProcessor to be added to the data processing chain
*/
void AddInterferenceChunkProcessor (Ptr<LteSinrChunkProcessor> p);
void AddInterferenceCtrlChunkProcessor (Ptr<LteSinrChunkProcessor> p);
/**
* LteSinrChunkProcessor devoted to evaluate intefrerence + noise power
* in data symbols of the subframe
*
* \param p the new LteSinrChunkProcessor to be added to the data processing chain
*/
void AddInterferenceDataChunkProcessor (Ptr<LteSinrChunkProcessor> p);
/**
@@ -431,6 +454,7 @@ private:
LtePhyRxCtrlEndOkCallback m_ltePhyRxCtrlEndOkCallback;
LtePhyRxCtrlEndErrorCallback m_ltePhyRxCtrlEndErrorCallback;
LtePhyRxPssCallback m_ltePhyRxPssCallback;
Ptr<LteInterference> m_interferenceData;
Ptr<LteInterference> m_interferenceCtrl;

View File

@@ -101,6 +101,7 @@ LteSpectrumSignalParametersDlCtrlFrame::LteSpectrumSignalParametersDlCtrlFrame (
{
NS_LOG_FUNCTION (this << &p);
cellId = p.cellId;
pss = p.pss;
ctrlMsgList = p.ctrlMsgList;
}

View File

@@ -118,6 +118,7 @@ struct LteSpectrumSignalParametersDlCtrlFrame : public SpectrumSignalParameters
std::list<Ptr<LteControlMessage> > ctrlMsgList;
uint16_t cellId;
bool pss; // primary synchronization signal
};

View File

@@ -114,6 +114,14 @@ public:
* \param mib the Master Information Block received on the BCH
*/
virtual void RecvMasterInformationBlock (LteRrcSap::MasterInformationBlock mib) = 0;
/**
*
* \param cellId the cellId of the eNB reported
* \param rsrp the RSRP measured (see sect. 5.1.1 of 36.214)
* \param rsrq the RSRQ measured (see sect. 5.1.3 of 36.214)
*/
virtual void ReportUeMeasurements (uint16_t cellId, double rsrp, double rsrq) = 0;
};
@@ -220,6 +228,8 @@ public:
// methods inherited from LteUeCphySapUser go here
virtual void RecvMasterInformationBlock (LteRrcSap::MasterInformationBlock mib);
virtual void ReportUeMeasurements (uint16_t cellId, double rsrp, double rsrq);
private:
MemberLteUeCphySapUser ();
C* m_owner;
@@ -243,7 +253,12 @@ MemberLteUeCphySapUser<C>::RecvMasterInformationBlock (LteRrcSap::MasterInformat
m_owner->DoRecvMasterInformationBlock (mib);
}
template <class C>
void
MemberLteUeCphySapUser<C>::ReportUeMeasurements (uint16_t cellId, double rsrp, double rsrq)
{
m_owner->DoReportUeMeasurements (cellId, rsrp, rsrq);
}
} // namespace ns3

View File

@@ -121,7 +121,10 @@ LteUePhy::LteUePhy (Ptr<LteSpectrumPhy> dlPhy, Ptr<LteSpectrumPhy> ulPhy)
m_a30CqiPeriocity (MilliSeconds (1)), // ideal behavior
m_uePhySapUser (0),
m_ueCphySapUser (0),
m_subframeNo (0),
m_rsReceivedPowerUpdated (false),
m_rsInterferencePowerUpdated (false),
m_pssReceived (false),
m_rsrpSinrSampleCounter (0)
{
m_amc = CreateObject <LteAmc> ();
@@ -235,6 +238,11 @@ LteUePhy::GetTypeId (void)
PointerValue (),
MakePointerAccessor (&LteUePhy::GetUlSpectrumPhy),
MakePointerChecker <LteSpectrumPhy> ())
.AddAttribute ("RsrqUeMeasThreshold",
"Receive threshold for PSS on RSRQ [W]",
DoubleValue (0.0),
MakeDoubleAccessor (&LteUePhy::m_pssReceptionThreshold ),
MakeDoubleChecker<double> ())
;
return tid;
}
@@ -426,7 +434,9 @@ LteUePhy::GenerateDataCqiReport (const SpectrumValue& sinr)
void
LteUePhy::ReportInterference (const SpectrumValue& interf)
{
// Currently not used by UE
NS_LOG_FUNCTION (this << interf);
m_rsInterferencePowerUpdated = true;
m_rsIntereferencePower = interf;
}
void
@@ -482,6 +492,45 @@ LteUePhy::CreateDlCqiFeedbackMessage (const SpectrumValue& sinr)
m_rsrpSinrSampleCounter = 0;
}
// UE Measurements
if (m_pssReceived)
{
NS_ASSERT_MSG (m_rsInterferencePowerUpdated, " RS interference power info obsolete");
// PSSs received
std::map <uint16_t, SpectrumValue>::iterator itPss = m_pssMap.begin ();
while (itPss != m_pssMap.end ())
{
NS_LOG_DEBUG (this << " PSS received from eNB " << (*itPss).first);
uint8_t rbNum = 0;
SpectrumValue pi = (*itPss).second;
Values::const_iterator itPi;
double rsrpSum = 0.0;
double rsrqSum = 0.0;
Values::const_iterator itInt = m_rsIntereferencePower.ConstValuesBegin ();
Values::const_iterator itPj = m_rsIntereferencePower.ConstValuesBegin ();
Ptr<SpectrumValue> noisePsd = LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (m_ulEarfcn, m_ulBandwidth, m_noiseFigure);
Values::const_iterator itN = noisePsd->ConstValuesBegin ();
for (itPi = pi.ConstValuesBegin (); itPi != pi.ConstValuesEnd (); itPi++, itInt++, itPj++, itN++)
{
rbNum++;
rsrpSum += (*itPi);
rsrqSum += (*itInt) + (*itPj) + (*itN);
}
double rsrp = rsrpSum / (double)rbNum;
double rsrq = rsrpSum / rsrqSum;
if (rsrq > m_pssReceptionThreshold)
{
// report UE Measurements to upper layers
NS_LOG_DEBUG (this << " CellId " << (*itPss).first << " has RSRP " << rsrp << " and RSRQ " << rsrq);
m_ueCphySapUser-> ReportUeMeasurements((*itPss).first, rsrp, rsrq);
}
itPss++;
}
}
// CREATE DlCqiLteControlMessage
@@ -735,6 +784,15 @@ LteUePhy::ReceiveLteControlMessageList (std::list<Ptr<LteControlMessage> > msgLi
}
void
LteUePhy::ReceivePss (uint16_t cellId, SpectrumValue p)
{
NS_LOG_FUNCTION (this << cellId);
m_pssReceived = true;
m_pssMap.insert (std::pair <uint16_t, SpectrumValue> (cellId, p));
}
void
LteUePhy::QueueSubChannelsForTransmission (std::vector <int> rbMap)
{
@@ -751,6 +809,8 @@ LteUePhy::SubframeIndication (uint32_t frameNo, uint32_t subframeNo)
// refresh internal variables
m_rsReceivedPowerUpdated = false;
m_rsInterferencePowerUpdated = false;
m_pssReceived = false;
if (m_ulConfigured)
{
@@ -806,7 +866,7 @@ LteUePhy::SubframeIndication (uint32_t frameNo, uint32_t subframeNo)
// trigger the MAC
m_uePhySapUser->SubframeIndication (frameNo, subframeNo);
m_subframeNo = subframeNo;
++subframeNo;
if (subframeNo > 10)
{

View File

@@ -175,7 +175,10 @@ public:
virtual void ReportInterference (const SpectrumValue& interf);
virtual void ReportRsReceivedPower (const SpectrumValue& power);
// callbacks for LteSpectrumPhy
virtual void ReceiveLteControlMessageList (std::list<Ptr<LteControlMessage> >);
virtual void ReceivePss (uint16_t cellId, SpectrumValue p);
@@ -275,9 +278,19 @@ private:
bool m_dlConfigured;
bool m_ulConfigured;
uint8_t m_subframeNo;
bool m_rsReceivedPowerUpdated;
SpectrumValue m_rsReceivedPower;
bool m_rsInterferencePowerUpdated;
SpectrumValue m_rsIntereferencePower;
bool m_pssReceived;
std::map <uint16_t, SpectrumValue> m_pssMap;
double m_pssReceptionThreshold; // on RSRQ [W]
Ptr<LteHarqPhy> m_harqPhyModule;
uint32_t m_raPreambleId;

View File

@@ -543,6 +543,13 @@ LteUeRrc::DoRecvMasterInformationBlock (LteRrcSap::MasterInformationBlock msg)
}
}
void
LteUeRrc::DoReportUeMeasurements (uint16_t cellId, double rsrp, double rsrq)
{
NS_LOG_FUNCTION (this);
NS_LOG_DEBUG (this << " CellId " << cellId << " RSRP " << rsrp << " RSRQ " << rsrq);
}
// RRC SAP methods

View File

@@ -243,6 +243,7 @@ private:
// CPHY SAP methods
void DoRecvMasterInformationBlock (LteRrcSap::MasterInformationBlock msg);
void DoReportUeMeasurements (uint16_t cellId, double rsrp, double rsrq);
// RRC SAP methods
void DoCompleteSetup (LteUeRrcSapProvider::CompleteSetupParameters params);