diff --git a/src/lte/model/lte-ue-cphy-sap.h b/src/lte/model/lte-ue-cphy-sap.h index 123dddadf..ee5fa3390 100644 --- a/src/lte/model/lte-ue-cphy-sap.h +++ b/src/lte/model/lte-ue-cphy-sap.h @@ -124,34 +124,72 @@ public: virtual void ConfigureReferenceSignalPower (int8_t referenceSignalPower) = 0; /** + * \brief Set Rnti function * * \param rnti the cell-specific UE identifier */ virtual void SetRnti (uint16_t rnti) = 0; /** + * \brief Set transmission mode + * * \param txMode the transmissionMode of the user */ virtual void SetTransmissionMode (uint8_t txMode) = 0; /** + * \brief Set SRS configuration index + * * \param srcCi the SRS configuration index */ virtual void SetSrsConfigurationIndex (uint16_t srcCi) = 0; /** + * \brief Set P_A value for UE power control + * * \param pa the P_A value */ virtual void SetPa (double pa) = 0; /** - * \param rsrpFilterCoefficient value. Determines the strength of - * smoothing effect induced by layer 3 filtering of RSRP - * used for uplink power control in all attached UE. + * \brief Set RSRP filter coefficient. + * + * Determines the strength of smoothing effect induced by layer 3 + * filtering of RSRP used for uplink power control in all attached UE. * If equals to 0, no layer 3 filtering is applicable. + * + * \param rsrpFilterCoefficient value. */ virtual void SetRsrpFilterCoefficient (uint8_t rsrpFilterCoefficient) = 0; + /** + * \brief Reset the PHY after radio link failure function + * It resets the physical layer parameters of the + * UE after RLF. + * + */ + virtual void ResetPhyAfterRlf () = 0; + + /** + * \brief Reset radio link failure parameters + * + * Upon receiving N311 in-sync indications from the UE + * PHY the UE RRC instructs the UE PHY to reset the + * RLF parameters so, it can start RLF detection again. + * + */ + virtual void ResetRlfParams () = 0; + + /** + * \brief Start in-sync detection function + * When T310 timer is started, it indicates that physical layer + * problems are detected at the UE and the recovery process is + * started by checking if the radio frames are in-sync for N311 + * consecutive times. + * + */ + virtual void StartInSnycDetection () = 0; + }; @@ -192,22 +230,24 @@ public: /** * \brief Relay an MIB message from the PHY entity to the RRC layer. - * \param cellId the ID of the eNodeB where the message originates from - * \param mib the Master Information Block message * * This function is typically called after PHY receives an MIB message over * the BCH. + * + * \param cellId the ID of the eNodeB where the message originates from + * \param mib the Master Information Block message. */ virtual void RecvMasterInformationBlock (uint16_t cellId, LteRrcSap::MasterInformationBlock mib) = 0; /** * \brief Relay an SIB1 message from the PHY entity to the RRC layer. - * \param cellId the ID of the eNodeB where the message originates from - * \param sib1 the System Information Block Type 1 message * * This function is typically called after PHY receives an SIB1 message over * the BCH. + * + * \param cellId the ID of the eNodeB where the message originates from + * \param sib1 the System Information Block Type 1 message */ virtual void RecvSystemInformationBlockType1 (uint16_t cellId, LteRrcSap::SystemInformationBlockType1 sib1) = 0; @@ -215,10 +255,35 @@ public: /** * \brief Send a report of RSRP and RSRQ values perceived from PSS by the PHY * entity (after applying layer-1 filtering) to the RRC layer. + * * \param params the structure containing a vector of cellId, RSRP and RSRQ */ virtual void ReportUeMeasurements (UeMeasurementsParameters params) = 0; + /** + * \brief Send an out of sync indication to UE RRC. + * + * When the number of out-of-sync indications + * are equal to N310, RRC starts the T310 timer. + */ + virtual void NotifyOutOfSync () = 0; + + /** + * \brief Send an in sync indication to UE RRC. + * + * When the number of in-sync indications + * are equal to N311, RRC stops the T310 timer. + */ + virtual void NotifyInSync () = 0; + + /** + * \brief Reset the sync indication counter. + * + * Resets the sync indication counter of RRC if the Qin or Qout condition + * is not fulfilled for the number of consecutive frames. + */ + virtual void ResetSyncIndicationCounter () = 0; + }; @@ -253,6 +318,9 @@ public: virtual void SetSrsConfigurationIndex (uint16_t srcCi); virtual void SetPa (double pa); virtual void SetRsrpFilterCoefficient (uint8_t rsrpFilterCoefficient); + virtual void ResetPhyAfterRlf (); + virtual void ResetRlfParams (); + virtual void StartInSnycDetection (); private: MemberLteUeCphySapProvider (); @@ -354,6 +422,26 @@ MemberLteUeCphySapProvider::SetRsrpFilterCoefficient (uint8_t rsrpFilterCoeff m_owner->DoSetRsrpFilterCoefficient (rsrpFilterCoefficient); } +template +void +MemberLteUeCphySapProvider::ResetPhyAfterRlf () +{ + m_owner->DoResetPhyAfterRlf (); +} + +template +void MemberLteUeCphySapProvider::ResetRlfParams () +{ + m_owner->DoResetRlfParams (); +} + +template +void MemberLteUeCphySapProvider::StartInSnycDetection () +{ + m_owner->DoStartInSnycDetection (); +} + + /** * Template for the implementation of the LteUeCphySapUser as a member @@ -377,6 +465,9 @@ public: virtual void RecvSystemInformationBlockType1 (uint16_t cellId, LteRrcSap::SystemInformationBlockType1 sib1); virtual void ReportUeMeasurements (LteUeCphySapUser::UeMeasurementsParameters params); + virtual void NotifyOutOfSync (); + virtual void NotifyInSync (); + virtual void ResetSyncIndicationCounter (); private: MemberLteUeCphySapUser (); @@ -417,6 +508,27 @@ MemberLteUeCphySapUser::ReportUeMeasurements (LteUeCphySapUser::UeMeasurement m_owner->DoReportUeMeasurements (params); } +template +void +MemberLteUeCphySapUser::NotifyOutOfSync () +{ + m_owner->DoNotifyOutOfSync (); +} + +template +void +MemberLteUeCphySapUser::NotifyInSync () +{ + m_owner->DoNotifyInSync (); +} + +template +void +MemberLteUeCphySapUser::ResetSyncIndicationCounter () +{ + m_owner->DoResetSyncIndicationCounter (); +} + } // namespace ns3 diff --git a/src/lte/model/lte-ue-phy-sap.h b/src/lte/model/lte-ue-phy-sap.h index 27b2c48c5..aa19f40fa 100644 --- a/src/lte/model/lte-ue-phy-sap.h +++ b/src/lte/model/lte-ue-phy-sap.h @@ -29,32 +29,34 @@ namespace ns3 { class LteControlMessage; -/** -* Service Access Point (SAP) offered by the UE-PHY to the UE-MAC -* -* This is the PHY SAP Provider, i.e., the part of the SAP that contains -* the PHY methods called by the MAC -*/ + /** + * Service Access Point (SAP) offered by the UE-PHY to the UE-MAC + * + * This is the PHY SAP Provider, i.e., the part of the SAP that contains + * the PHY methods called by the MAC + */ class LteUePhySapProvider { public: virtual ~LteUePhySapProvider (); /** - * \brief Send the MAC PDU to the channel - * \param p the MAC PDU to send - * \return true if - */ + * \brief Send the MAC PDU to the channel + * + * \param p the MAC PDU to send + * \return true if + */ virtual void SendMacPdu (Ptr p) = 0; /** - * \brief Send SendLteControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel - * \param msg the Ideal Control Message to send - */ + * \brief Send SendLteControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel + * + * \param msg the Ideal Control Message to send + */ virtual void SendLteControlMessage (Ptr msg) = 0; /** - * send a preamble on the PRACH + * \brief Send a preamble on the PRACH * * \param prachId the ID of the preamble * \param raRnti the RA RNTI @@ -70,12 +72,12 @@ public: }; -/** -* Service Access Point (SAP) offered by the PHY to the MAC -* -* This is the PHY SAP User, i.e., the part of the SAP that contains the MAC -* methods called by the PHY -*/ + /** + * Service Access Point (SAP) offered by the PHY to the MAC + * + * This is the PHY SAP User, i.e., the part of the SAP that contains the MAC + * methods called by the PHY + */ class LteUePhySapUser { public: @@ -83,23 +85,27 @@ public: /** - * Called by the Phy to notify the MAC of the reception of a new PHY-PDU - * - * \param p - */ + * \brief Receive Phy Pdu funtion. + * + * It is called by the Phy to notify the MAC of the reception of a new PHY-PDU + * + * \param p + */ virtual void ReceivePhyPdu (Ptr p) = 0; /** - * \brief Trigger the start from a new frame (input from Phy layer) - * \param frameNo frame number - * \param subframeNo subframe number - */ + * \brief Trigger the start from a new frame (input from Phy layer) + * + * \param frameNo frame number + * \param subframeNo subframe number + */ virtual void SubframeIndication (uint32_t frameNo, uint32_t subframeNo) = 0; /** - * \brief Receive SendLteControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel - * \param msg the Ideal Control Message to receive - */ + * \brief Receive SendLteControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel + * + * \param msg the Ideal Control Message to receive + */ virtual void ReceiveLteControlMessage (Ptr msg) = 0; }; diff --git a/src/lte/model/lte-ue-phy.cc b/src/lte/model/lte-ue-phy.cc index 2dbc6fdda..feab95c21 100644 --- a/src/lte/model/lte-ue-phy.cc +++ b/src/lte/model/lte-ue-phy.cc @@ -310,6 +310,32 @@ LteUePhy::GetTypeId (void) BooleanValue (true), MakeBooleanAccessor (&LteUePhy::m_enableUplinkPowerControl), MakeBooleanChecker ()) + .AddAttribute ("Qout", + "corresponds to 10% block error rate of a hypothetical PDCCH transmission" + "taking into account the PCFICH errors with transmission parameters." + "see 3GPP TS 36.213 4.2.1 and TS 36.133 7.6", + DoubleValue (-5), + MakeDoubleAccessor (&LteUePhy::m_qOut), + MakeDoubleChecker ()) + .AddAttribute ("Qin", + "corresponds to 2% block error rate of a hypothetical PDCCH transmission" + "taking into account the PCFICH errors with transmission parameters." + "see 3GPP TS 36.213 4.2.1 and TS 36.133 7.6", + DoubleValue (-3.9), + MakeDoubleAccessor (&LteUePhy::m_qIn), + MakeDoubleChecker ()) + .AddAttribute ("NumQoutEvalSf", + "This specifies the total number of consecutive subframes" + "which corresponds to the Qout evaluation period", + UintegerValue (200), //see 3GPP 3GPP TS 36.133 7.6.2.1 + MakeUintegerAccessor (&LteUePhy::m_numOfQoutEvalSf), + MakeUintegerChecker ()) + .AddAttribute ("NumQinEvalSf", + "This specifies the total number of consecutive subframes" + "which corresponds to the Qin evaluation period", + UintegerValue (100), //see 3GPP 3GPP TS 36.133 7.6.2.1 + MakeUintegerAccessor (&LteUePhy::m_numOfQinEvalSf), + MakeUintegerChecker ()) ; return tid; } @@ -551,6 +577,10 @@ LteUePhy::GenerateCqiRsrpRsrq (const SpectrumValue& sinr) } double avSinr = (rbNum > 0) ? (sum / rbNum) : DBL_MAX; NS_LOG_INFO (this << " cellId " << m_cellId << " rnti " << m_rnti << " RSRP " << rsrp << " SINR " << avSinr << " ComponentCarrierId " << (uint16_t) m_componentCarrierId); + if (m_isConnected) //trigger RLF detection only when UE has an active RRC connection + { + RlfDetection (10 * log10 (avSinr)); + } m_reportCurrentCellRsrpSinrTrace (m_cellId, m_rnti, rsrp, avSinr, (uint16_t) m_componentCarrierId); m_rsrpSinrSampleCounter = 0; @@ -882,9 +912,16 @@ LteUePhy::DoSendRachPreamble (uint32_t raPreambleId, uint32_t raRnti) void LteUePhy::DoNotifyConnectionSuccessful () { + /** + * Radio link failure detection should take place only on the + * primary carrier to avoid errors due to multiple calls to the + * same methods at the RRC layer + */ if (m_componentCarrierId == 0) { m_isConnected = true; + // Initialize the parameters for radio link failure detection + InitializeRlfParams (); } } @@ -1395,6 +1432,128 @@ LteUePhy::DoSetRsrpFilterCoefficient (uint8_t rsrpFilterCoefficient) m_powerControl->SetRsrpFilterCoefficient (rsrpFilterCoefficient); } +void +LteUePhy::DoResetPhyAfterRlf () +{ + NS_LOG_FUNCTION (this); + m_downlinkSpectrumPhy->m_harqPhyModule->ClearDlHarqBuffer (m_rnti); //flush HARQ buffers + m_dataInterferencePowerUpdated = false; + m_rsInterferencePowerUpdated = false; + DoReset (); +} + +void +LteUePhy::DoResetRlfParams () +{ + NS_LOG_FUNCTION (this); + + InitializeRlfParams (); +} + +void +LteUePhy::DoStartInSnycDetection () +{ + NS_LOG_FUNCTION (this); + // indicates that the downlink radio link quality has to be monitored for in-sync indications + m_downlinkInSync = false; +} + +void +LteUePhy::InitializeRlfParams () +{ + NS_LOG_FUNCTION (this); + m_numOfSubframes = 0; + m_sinrDbFrame = 0; + m_numOfFrames = 0; + m_downlinkInSync = true; +} + +void +LteUePhy::RlfDetection (double sinrDb) +{ + NS_LOG_FUNCTION (this << sinrDb); + m_sinrDbFrame += sinrDb; + m_numOfSubframes++; + NS_LOG_LOGIC ("No of Subframes: " << m_numOfSubframes << " UE synchronized: " << m_downlinkInSync); + //check for out_of_snyc indications first when UE is both DL and UL synchronized + //m_downlinkInSync=true indicates that the evaluation is for out-of-sync indications + if (m_downlinkInSync && m_numOfSubframes == 10) + { + /** + * For every frame, if the downlink radio link quality(avg SINR) + * is less than the threshold Qout, then the frame cannot be decoded + */ + if ((m_sinrDbFrame / m_numOfSubframes) < m_qOut) + { + m_numOfFrames++; //increment the counter if a frame cannot be decoded + NS_LOG_LOGIC ("No of Frames which cannot be decoded: " << m_numOfFrames); + } + else + { + /** + * If the downlink radio link quality(avg SINR) is greater + * than the threshold Qout, then the frame counter is reset + * since only consecutive frames should be considered. + */ + NS_LOG_INFO ("Reseting frame counter at phy. Current value = " << m_numOfFrames); + m_numOfFrames = 0; + // Also reset the sync indicator counter at RRC + m_ueCphySapUser->ResetSyncIndicationCounter (); + } + m_numOfSubframes = 0; + m_sinrDbFrame = 0; + } + /** + * Once the number of consecutive frames which cannot be decoded equals the Qout evaluation period (i.e 200ms), + * then an out-of-sync indication is sent to the RRC layer + */ + if (m_downlinkInSync && (m_numOfFrames * 10) == m_numOfQoutEvalSf) + { + NS_LOG_LOGIC ("Notify out of snyc indication to RRC layer"); + m_ueCphySapUser->NotifyOutOfSync (); + m_numOfFrames = 0; + } + //check for in_snyc indications when T310 timer is started + //m_downlinkInSync=false indicates that the evaluation is for in-sync indications + if (!m_downlinkInSync && m_numOfSubframes == 10) + { + /** + * For every frame, if the downlink radio link quality(avg SINR) + * is greater than the threshold Qin, then the frame can be + * successfully decoded. + */ + if ((m_sinrDbFrame / m_numOfSubframes) > m_qIn) + { + m_numOfFrames++; //increment the counter if a frame can be decoded + NS_LOG_LOGIC ("No of Frames successfully decoded: " << m_numOfFrames); + } + else + { + /** + * If the downlink radio link quality(avg SINR) is less + * than the threshold Qin, then the frame counter is reset + * since only consecutive frames should be considered + */ + m_numOfFrames = 0; + // Also reset the sync indicator counter at RRC + m_ueCphySapUser->ResetSyncIndicationCounter (); + } + m_numOfSubframes = 0; + m_sinrDbFrame = 0; + } + /** + * Once the number of consecutive frames which can be decoded equals the Qin evaluation period (i.e 100ms), + * then an in-sync indication is sent to the RRC layer + */ + if (!m_downlinkInSync && (m_numOfFrames * 10) == m_numOfQinEvalSf) + { + NS_LOG_LOGIC ("Notify in snyc indication to RRC layer"); + m_ueCphySapUser->NotifyInSync (); + m_numOfFrames = 0; + } +} + + void LteUePhy::SetTxMode1Gain (double gain) { diff --git a/src/lte/model/lte-ue-phy.h b/src/lte/model/lte-ue-phy.h index 427e4482a..07f377988 100644 --- a/src/lte/model/lte-ue-phy.h +++ b/src/lte/model/lte-ue-phy.h @@ -92,93 +92,118 @@ public: /** * \brief Get the PHY SAP provider + * * \return a pointer to the SAP Provider */ LteUePhySapProvider* GetLteUePhySapProvider (); /** * \brief Set the PHY SAP User + * * \param s a pointer to the SAP user */ void SetLteUePhySapUser (LteUePhySapUser* s); /** * \brief Get the CPHY SAP provider + * * \return a pointer to the SAP Provider */ LteUeCphySapProvider* GetLteUeCphySapProvider (); /** * \brief Set the CPHY SAP User + * * \param s a pointer to the SAP user */ void SetLteUeCphySapUser (LteUeCphySapUser* s); /** + * \brief Set transmit power + * * \param pow the transmission power in dBm */ void SetTxPower (double pow); /** + * \brief Get transmit power + * * \return the transmission power in dBm */ double GetTxPower () const; /** + * \brief Get Uplink power control + * * \return ptr to UE Uplink Power Control entity */ Ptr GetUplinkPowerControl () const; /** + * \brief Set noise figure + * * \param nf the noise figure in dB */ void SetNoiseFigure (double nf); /** + * \brief Get noise figure + * * \return the noise figure in dB */ double GetNoiseFigure () const; /** + * \brief Get MAC to Channel delay + * * \returns the TTI delay between MAC and channel */ uint8_t GetMacChDelay (void) const; /** + * \brief Get Downlink spectrum phy + * * \return a pointer to the LteSpectrumPhy instance relative to the downlink */ Ptr GetDlSpectrumPhy () const; /** + * \brief Get Uplink spectrum phy + * * \return a pointer to the LteSpectrumPhy instance relative to the uplink */ Ptr GetUlSpectrumPhy () const; /** * \brief Create the PSD for the TX + * * \return the pointer to the PSD */ virtual Ptr CreateTxPowerSpectralDensity (); /** * \brief Set a list of sub channels to use in TX + * * \param mask a list of sub channels */ void SetSubChannelsForTransmission (std::vector mask); /** * \brief Get a list of sub channels to use in RX + * * \return a list of sub channels */ std::vector GetSubChannelsForTransmission (void); /** * \brief Get a list of sub channels to use in RX + * * \param mask list of sub channels */ void SetSubChannelsForReception (std::vector mask); /** * \brief Get a list of sub channels to use in RX + * * \return a list of sub channels */ std::vector GetSubChannelsForReception (void); @@ -186,6 +211,7 @@ public: /** * \brief Create the DL CQI feedback from SINR values perceived at * the physical layer with the signal received from eNB + * * \param sinr SINR values vector * \return a DL CQI control message containing the CQI feedback */ @@ -229,6 +255,7 @@ public: /** * \brief PhySpectrum received a new PHY-PDU + * * \param p the packet received */ void PhyPduReceived (Ptr p); @@ -250,17 +277,21 @@ public: /** * \brief PhySpectrum generated a new DL HARQ feedback + * * \param mes the DlInfoListElement_s */ virtual void ReceiveLteDlHarqFeedback (DlInfoListElement_s mes); /** * \brief Set the HARQ PHY module + * * \param harq the HARQ PHY module */ void SetHarqPhyModule (Ptr harq); /** + * \brief Get state of the UE physical layer + * * \return The current state */ State GetState () const; @@ -306,7 +337,7 @@ public: private: /** - * Set transmit mode 1 gain function + * \brief Set transmit mode 1 gain function * * \param [in] gain */ @@ -318,49 +349,51 @@ private: */ void SetTxMode2Gain (double gain); /** - * Set transmit mode 3 gain function + * \brief Set transmit mode 3 gain function * * \param [in] gain */ void SetTxMode3Gain (double gain); /** - * Set transmit mode 4 gain function + * \brief Set transmit mode 4 gain function * * \param [in] gain */ void SetTxMode4Gain (double gain); /** - * Set transmit mode 5 gain function + * \brief Set transmit mode 5 gain function * * \param [in] gain */ void SetTxMode5Gain (double gain); /** - * Set transmit mode 6 gain function + * \brief Set transmit mode 6 gain function * * \param [in] gain */ void SetTxMode6Gain (double gain); /** - * Set transmit mode 7 gain function + * \brief Set transmit mode 7 gain function * * \param [in] gain */ void SetTxMode7Gain (double gain); /** - * Set transmit mode gain function + * \brief Set transmit mode gain function * * \param [in] txMode * \param [in] gain */ void SetTxModeGain (uint8_t txMode, double gain); /** - * queue subchannels for transmission function + * \brief Queue subchannels for transmission function * * \param [in] rbMap */ void QueueSubChannelsForTransmission (std::vector rbMap); /** + * \brief Get CQI, RSRP, and RSRQ + * * internal method that takes care of generating CQI reports, * calculating the RSRP and RSRQ metrics, and generating RSRP+SINR traces * @@ -383,67 +416,138 @@ private: */ void SetDownlinkCqiPeriodicity (Time cqiPeriodicity); /** - * Switch the UE PHY to the given state. + * \brief Switch the UE PHY to the given state. * \param s the destination state */ void SwitchToState (State s); // UE CPHY SAP methods - /// Reset function + /** + * \brief Do Reset function + */ void DoReset (); /** - * Start the cell search function + * \brief Start the cell search function + * * \param dlEarfcn the DL EARFCN */ void DoStartCellSearch (uint32_t dlEarfcn); /** - * Synchronize with ENB function + * \brief Synchronize with ENB function + * * \param cellId the cell ID */ void DoSynchronizeWithEnb (uint16_t cellId); /** - * Synchronize with ENB function + * \brief Synchronize with ENB function + * * \param cellId the cell ID * \param dlEarfcn the DL EARFCN */ void DoSynchronizeWithEnb (uint16_t cellId, uint32_t dlEarfcn); /** - * Set DL bandwidth function + * \brief Set DL bandwidth function + * * \param dlBandwidth the DL bandwidth */ void DoSetDlBandwidth (uint8_t dlBandwidth); /** - * Configure UL uplink function + * \brief Configure UL uplink function + * * \param ulEarfcn UL EARFCN * \param ulBandwidth the UL bandwidth */ void DoConfigureUplink (uint32_t ulEarfcn, uint8_t ulBandwidth); /** - * Configure reference signal power function + * \brief Configure reference signal power function + * * \param referenceSignalPower reference signal power in dBm */ void DoConfigureReferenceSignalPower (int8_t referenceSignalPower); /** - * Set RNTI function + * \brief Set RNTI function + * * \param rnti the RNTI */ void DoSetRnti (uint16_t rnti); /** - * Set transmission mode function + * \brief Set transmission mode function + * * \param txMode the transmission mode */ void DoSetTransmissionMode (uint8_t txMode); /** - * Set SRS configuration index function + * \brief Set SRS configuration index function + * * \param srcCi the SRS configuration index */ void DoSetSrsConfigurationIndex (uint16_t srcCi); /** - * Set PA function + * \brief Set PA function + * * \param pa the PA value */ void DoSetPa (double pa); /** + * \brief Reset Phy after radio link failure function + * + * It resets the physical layer parameters of the + * UE after RLF. + * + */ + void DoResetPhyAfterRlf (); + /** + * \brief Reset radio link failure parameters + * + * Upon receiving N311 in-sync indications from the UE + * PHY, the UE RRC instructs the UE PHY to reset the + * RLF parameters so, it can start RLF detection again. + * + */ + void DoResetRlfParams (); + + /** + * \brief Start in Snyc detection function + * + * When T310 timer is started, it indicates that physical layer + * problems are detected at the UE and the recovery process is + * started by checking if the radio frames are in-sync for N311 + * consecutive times. + * + */ + void DoStartInSnycDetection (); + + /** + * \brief Radio link failure detection function + * + * Radio link monitoring is started to detect downlink radio link + * quality when the UE is both uplink and downlink synchronized + * (UE in CONNECTED_NORMALLY state). + * Upon detection of radio link failure, RRC connection is released + * and the UE starts the cell selection again. The procedure is implemented + * as per 3GPP TS 36.213 4.2.1 and TS 36.133 7.6. When the downlink + * radio link quality estimated over the last 200 ms period becomes worse than + * the threshold Qout, an out-of-sync indication is sent to RRC. When the + * downlink radio link quality estimated over the last 100 ms period becomes + * better than the threshold Qin, an in-sync indication is sent to RRC. + * + * \param sinrdB the average SINR value in dB measured across + * all resource blocks + * + */ + void RlfDetection (double sinrdB); + /** + * \brief Initialize radio link failure parameters + * + * Upon receiving the notification about the successful RRC connection + * establishment, the UE phy initialize the RLF parameters to be + * ready for RLF detection. + * + */ + void InitializeRlfParams (); + /** + * \brief Do set RSRP filter coefficient + * * \param rsrpFilterCoefficient value. Determines the strength of * smoothing effect induced by layer 3 filtering of RSRP * used for uplink power control in all attached UE. @@ -454,12 +558,14 @@ private: // UE PHY SAP methods virtual void DoSendMacPdu (Ptr p); /** - * Send LTE control message function + * \brief Send LTE control message function + * * \param msg the LTE control message */ virtual void DoSendLteControlMessage (Ptr msg); /** - * Send RACH preamble function + * \brief Send RACH preamble function + * * \param prachId the RACH preamble ID * \param raRnti the rnti */ @@ -623,6 +729,27 @@ private: ///the configured bandwidth bool m_isConnected; ///< set when UE RRC is in CONNECTED_NORMALLY state + /** + * The 'Qin' attribute. + * corresponds to 2% block error rate of a hypothetical PDCCH transmission + * taking into account the PCFICH errors. + */ + double m_qIn; + + /** + * The 'Qout' attribute. + * corresponds to 2% block error rate of a hypothetical PDCCH transmission + * taking into account the PCFICH errors. + */ + double m_qOut; + + uint16_t m_numOfQoutEvalSf; ///< the downlink radio link quality is estimated over this period for detecting out-of-syncs + uint16_t m_numOfQinEvalSf; ///< the downlink radio link quality is estimated over this period for detecting in-syncs + + bool m_downlinkInSync; ///< when set, DL SINR evaluation for out-of-sync indications is conducted. + uint16_t m_numOfSubframes; ///< count the number of subframes for which the downlink radio link quality is estimated + uint16_t m_numOfFrames; ///< count the number of frames for which the downlink radio link quality is estimated + double m_sinrDbFrame; ///< the average SINR per radio frame }; // end of `class LteUePhy` diff --git a/src/lte/model/lte-ue-rrc.cc b/src/lte/model/lte-ue-rrc.cc index 5301c6405..3086a89d6 100644 --- a/src/lte/model/lte-ue-rrc.cc +++ b/src/lte/model/lte-ue-rrc.cc @@ -146,6 +146,8 @@ LteUeRrc::LteUeRrc () m_hasReceivedSib1 (false), m_hasReceivedSib2 (false), m_csgWhiteList (0), + m_noOfSyncIndications (0), + m_leaveConnectedMode (false), m_numberOfComponentCarriers (MIN_NO_CC) { NS_LOG_FUNCTION (this); @@ -221,6 +223,25 @@ LteUeRrc::GetTypeId (void) TimeValue (MilliSeconds (100)), MakeTimeAccessor (&LteUeRrc::m_t300), MakeTimeChecker ()) + .AddAttribute ("T310", + "Timer for detecting the Radio link failure " + "(i.e., the radio link is deemed as failed if this timer expires)" + "Valid values: 0ms 50ms, 100ms, 200ms, 500ms, 1000ms, 2000ms", + TimeValue (MilliSeconds (1000)), //see 3GPP 36.331 UE-TimersAndConstants & RLF-TimersAndConstants + MakeTimeAccessor (&LteUeRrc::m_t310), + MakeTimeChecker ()) + .AddAttribute ("N310", + "This specifies the maximum number of out-of-sync indications" + "Valid values: 1, 2, 3, 4, 6, 8, 10, 20", + UintegerValue (6), //see 3GPP 36.331 UE-TimersAndConstants & RLF-TimersAndConstants + MakeUintegerAccessor (&LteUeRrc::m_n310), + MakeUintegerChecker ()) + .AddAttribute ("N311", + "This specifies the maximum number of in-sync indications" + "Valid values: 1, 2, 3, 4, 5, 6, 8, 10", + UintegerValue (2), //see 3GPP 36.331 UE-TimersAndConstants & RLF-TimersAndConstants + MakeUintegerAccessor (&LteUeRrc::m_n311), + MakeUintegerChecker ()) .AddTraceSource ("MibReceived", "trace fired upon reception of Master Information Block", MakeTraceSourceAccessor (&LteUeRrc::m_mibReceivedTrace), @@ -289,6 +310,14 @@ LteUeRrc::GetTypeId (void) "trace fired after DRB is created", MakeTraceSourceAccessor (&LteUeRrc::m_drbCreatedTrace), "ns3::LteUeRrc::ImsiCidRntiLcIdTracedCallback") + .AddTraceSource ("RadioLinkFailure", + "trace fired upon failure of radio link", + MakeTraceSourceAccessor (&LteUeRrc::m_radioLinkFailureTrace), + "ns3::LteUeRrc::ImsiCidRntiTracedCallback") + .AddTraceSource ("PhySyncDetection", + "trace fired upon failure of radio link", + MakeTraceSourceAccessor (&LteUeRrc::m_phySyncDetectionTrace), + "ns3::LteUeRrc::PhySyncDetectionTracedCallback") ; return tid; } @@ -972,12 +1001,15 @@ LteUeRrc::DoRecvRrcConnectionSetup (LteRrcSap::RrcConnectionSetup msg) ApplyRadioResourceConfigDedicated (msg.radioResourceConfigDedicated); m_connectionTimeout.Cancel (); SwitchToState (CONNECTED_NORMALLY); + m_leaveConnectedMode = false; LteRrcSap::RrcConnectionSetupCompleted msg2; msg2.rrcTransactionIdentifier = msg.rrcTransactionIdentifier; m_rrcSapUser->SendRrcConnectionSetupCompleted (msg2); m_asSapUser->NotifyConnectionSuccessful (); m_cmacSapProvider.at (0)->NotifyConnectionSuccessful (); m_connectionEstablishedTrace (m_imsi, m_cellId, m_rnti); + NS_ABORT_MSG_IF (m_noOfSyncIndications > 0, "Sync indications should be zero " + "when a new RRC connection is established. Current value = " << (uint16_t) m_noOfSyncIndications); } break; @@ -991,7 +1023,7 @@ void LteUeRrc::DoRecvRrcConnectionReconfiguration (LteRrcSap::RrcConnectionReconfiguration msg) { NS_LOG_FUNCTION (this << " RNTI " << m_rnti); - NS_LOG_INFO ("DoRecvRrcConnectionReconfiguration haveNonCriticalExtension:" << msg.haveNonCriticalExtension ); + NS_LOG_INFO ("DoRecvRrcConnectionReconfiguration haveNonCriticalExtension:" << msg.haveNonCriticalExtension); switch (m_state) { case CONNECTED_NORMALLY: @@ -1110,7 +1142,7 @@ LteUeRrc::DoRecvRrcConnectionReestablishmentReject (LteRrcSap::RrcConnectionRees * \todo After receiving RRC Connection Re-establishment Reject, stop * timer T301. See Section 5.3.7.8 of 3GPP TS 36.331. */ - LeaveConnectedMode (); + m_asSapUser->NotifyConnectionReleased (); // Inform upper layers } break; @@ -1234,6 +1266,20 @@ LteUeRrc::EvaluateCellForSelection () m_cphySapProvider.at(0)->SynchronizeWithEnb (cellId, m_dlEarfcn); m_cphySapProvider.at(0)->SetDlBandwidth (m_dlBandwidth); m_initialCellSelectionEndOkTrace (m_imsi, cellId); + // Once the UE is connected, m_connectionPending is + // set to false. So, when RLF occurs and UE performs + // cell selection upon leaving RRC_CONNECTED state, + // the following call to DoConnect will make the + // m_connectionPending to be true again. Thus, + // upon calling SwitchToState (IDLE_CAMPED_NORMALLY) + // UE state is instantly change to IDLE_WAIT_SIB2. + // This will make the UE to read the SIB2 message + // and start random access. + if (!m_connectionPending) + { + NS_LOG_DEBUG ("Calling DoConnect in state = " << ToString (m_state)); + DoConnect (); + } SwitchToState (IDLE_CAMPED_NORMALLY); } else @@ -2990,17 +3036,43 @@ void LteUeRrc::LeaveConnectedMode () { NS_LOG_FUNCTION (this << m_imsi); - m_asSapUser->NotifyConnectionReleased (); - m_cmacSapProvider.at (0)->RemoveLc (1); - std::map >::iterator it; - for (it = m_drbMap.begin (); it != m_drbMap.end (); ++it) + m_leaveConnectedMode = true; + m_radioLinkFailureDetected.Cancel (); + m_storedMeasValues.clear (); + m_noOfSyncIndications = 0; + + std::map::iterator measIdIt; + for (measIdIt = m_varMeasConfig.measIdList.begin (); + measIdIt != m_varMeasConfig.measIdList.end (); ++measIdIt) { - m_cmacSapProvider.at (0)->RemoveLc (it->second->m_logicalChannelIdentity); + VarMeasReportListClear (measIdIt->second.measId); + CancelEnteringTrigger (measIdIt->second.measId, measIdIt->first); + } + m_varMeasConfig.measIdList.clear (); + + m_ccmRrcSapProvider->Reset (); + + for (uint32_t i = 0; i < m_numberOfComponentCarriers; i++) + { + m_cmacSapProvider.at (i)->Reset (); // reset the MAC + } + m_drbMap.clear (); m_bid2DrbidMap.clear (); - m_srb1 = 0; - SwitchToState (IDLE_CAMPED_NORMALLY); + m_srb1 = nullptr; + m_hasReceivedMib = false; + m_hasReceivedSib1 = false; + m_hasReceivedSib2 = false; + + for (uint32_t i = 0; i < m_numberOfComponentCarriers; i++) + { + m_cphySapProvider.at (i)->ResetPhyAfterRlf (); //reset the PHY + } + SwitchToState (IDLE_START); + DoStartCellSelection (m_dlEarfcn); + + DoSetTemporaryCellRnti (0); // discard temporary cell RNTI } void @@ -3052,7 +3124,14 @@ LteUeRrc::SwitchToState (State newState) switch (newState) { case IDLE_START: - NS_FATAL_ERROR ("cannot switch to an initial state"); + if (m_leaveConnectedMode) + { + NS_LOG_INFO ("Starting initial cell selection after RLF"); + } + else + { + NS_FATAL_ERROR ("cannot switch to an initial state"); + } break; case IDLE_CELL_SEARCH: @@ -3152,6 +3231,60 @@ LteUeRrc::SaveScellUeMeasurements (uint16_t sCellId, double rsrp, double rsrq, } // end of void SaveUeMeasurements +void +LteUeRrc::RadioLinkFailureDetected () +{ + NS_LOG_FUNCTION (this << m_imsi << m_rnti); + m_radioLinkFailureTrace (m_imsi, m_cellId, m_rnti); + SwitchToState (CONNECTED_PHY_PROBLEM); + m_asSapUser->NotifyConnectionReleased (); +} + +void +LteUeRrc::DoNotifyInSync () +{ + NS_LOG_FUNCTION (this << m_imsi); + m_noOfSyncIndications++; + NS_LOG_INFO ("noOfSyncIndications " << (uint16_t) m_noOfSyncIndications); + m_phySyncDetectionTrace (m_imsi, m_rnti, m_cellId, "Notify in sync", m_noOfSyncIndications); + if (m_noOfSyncIndications == m_n311) + { + m_radioLinkFailureDetected.Cancel (); + m_noOfSyncIndications = 0; + m_cphySapProvider.at (0)->ResetRlfParams (); + } +} + +void +LteUeRrc::DoNotifyOutOfSync () +{ + NS_LOG_FUNCTION (this << m_imsi); + m_noOfSyncIndications++; + NS_LOG_INFO (this << " Total Number of Sync indications from PHY " + << (uint16_t) m_noOfSyncIndications << "N310 value : " << (uint16_t) m_n310); + m_phySyncDetectionTrace (m_imsi, m_rnti, m_cellId, "Notify out of sync", m_noOfSyncIndications); + if (m_noOfSyncIndications == m_n310) + { + m_radioLinkFailureDetected = Simulator::Schedule (m_t310, &LteUeRrc::RadioLinkFailureDetected, this); + if (m_radioLinkFailureDetected.IsRunning ()) + { + NS_LOG_INFO ("t310 started"); + } + m_cphySapProvider.at (0)->StartInSnycDetection (); + m_noOfSyncIndications = 0; + } +} + +void +LteUeRrc::DoResetSyncIndicationCounter () +{ + NS_LOG_FUNCTION (this << m_imsi); + + NS_LOG_DEBUG ("The number of sync indication received by RRC from PHY: " << (uint16_t) m_noOfSyncIndications); + m_noOfSyncIndications = 0; +} + + } // namespace ns3 diff --git a/src/lte/model/lte-ue-rrc.h b/src/lte/model/lte-ue-rrc.h index 8fe8c544a..2bb8f5138 100644 --- a/src/lte/model/lte-ue-rrc.h +++ b/src/lte/model/lte-ue-rrc.h @@ -361,6 +361,19 @@ public: typedef void (* SCarrierConfiguredTracedCallback) (Ptr, std::list); + /** + * TracedCallback signature for in-sync and out-of-sync detection events. + * + * + * \param [in] imsi + * \param [in] rnti + * \param [in] cellId + * \param [in] type + * \param [in] count + */ + typedef void (*PhySyncDetectionTracedCallback) + (uint64_t imsi, uint16_t rnti, uint16_t cellId, std::string type, uint16_t count); + private: @@ -690,7 +703,16 @@ private: void ApplyRadioResourceConfigDedicatedSecondaryCarrier (LteRrcSap::NonCriticalExtensionConfiguration nonCec); /// Start connection function void StartConnection (); - /// Leave connected mode + /** + * \brief Leave connected mode method + * Resets the UE back to an appropiate state depending + * on the nature of cause. For example, the UE is move + * to the IDLE_START state upon radio link failure. At + * RRC, all radio bearers except SRB 0 are removed, + * measurement reports are cleared and the appropriate + * flags are reset to their default values. This method + * in turn triggers the reset methods of UE PHY and MAC layers. + */ void LeaveConnectedMode (); /// Dispose old SRB1 void DisposeOldSrb1 (); @@ -870,6 +892,17 @@ private: * Exporting IMSI, cell ID, RNTI, and LCID */ TracedCallback m_drbCreatedTrace; + /** + * The 'PhySyncDetection' trace source. Fired when UE RRC + * receives in-sync or out-of-sync indications from UE PHY + * + */ + TracedCallback m_phySyncDetectionTrace; + /** + * The 'RadioLinkFailure' trace source. Fired when T310 timer expires. + * + */ + TracedCallback m_radioLinkFailureTrace; /// True if a connection request by upper layers is pending. bool m_connectionPending; @@ -1039,7 +1072,7 @@ private: * applied to the measurement results and they are used by *UE measurements* * function: * - LteUeRrc::MeasurementReportTriggering: in this case it is not set any - * measurement related to seconday carrier components since the + * measurement related to secondary carrier components since the * A6 event is not implemented * - LteUeRrc::SendMeasurementReport: in this case the report are sent. */ @@ -1179,6 +1212,81 @@ private: */ void ConnectionTimeout (); + /** + * The 'T310' attribute. After detecting N310 out-of-sync indications, + * if number of in-sync indications detected is less than N311 before this + * time, then the radio link is considered to have failed and the UE + * transitions to state CONNECTED_PHY_PROMLEM and eventually IDLE_START + * and UE context at eNodeB is destroyed. RRC connection re-establishment + * is not initiated after this time. See 3GPP TS 36.331 7.3. + */ + Time m_t310; + + /** + * The 'N310' attribute. This specifies the maximum + * consecutive out-of-sync indications from lower layers. + */ + uint8_t m_n310; + + /** + * The 'N311' attribute. This specifies the minimum + * consecutive in-sync indications from lower layers. + */ + uint8_t m_n311; + + /** + * Time limit (given by m_t310) before the radio link is considered to have failed. + * It is set upon detecting physical layer problems i.e. upon receiving + * N310 consecutive out-of-sync indications from lower layers. Calling + * LteUeRrc::RadioLinkFailureDetected() when it expires. + * It is cancelled upon receiving N311 consecutive in-sync indications. Upon + * expiry, the UE transitions to RRC_IDLE and no RRC connection + * re-establishment is initiated. + */ + EventId m_radioLinkFailureDetected; + + uint8_t m_noOfSyncIndications; ///< number of in-sync or out-of-sync indications coming from PHY layer + + bool m_leaveConnectedMode; ///< true if UE NAS ask UE RRC to leave connected mode, e.g., after RLF, i.e. T310 has expired + + /** + * \brief Radio link failure detected function + * + * Upon detection of radio link failure, the UE is reverted + * back to idle state and the UE context at eNodeB and EPC + * is deleted, thus releasing the RRC connection. The eNodeB is notified + * in an ideal way since there is no radio link failure detection + * implemented at the eNodeB. If the deletion process is not synchronous, + * then errors occur due to triggering of assert messages. + */ + void RadioLinkFailureDetected (); + + /** + * \brief Do notify in sync function + * + * Triggered upon receiving an in sync indication from UE PHY. + * When the count equals N311, then T310 is cancelled. + */ + void DoNotifyInSync (); + + /** + * \brief Do notify out of sync function + * + * Triggered upon receiving an out of sync indication from UE PHY. + * When the count equals N310, then T310 is started. + */ + void DoNotifyOutOfSync (); + + /** + * \brief Do reset sync indication counter function + * + * Reset the sync indication counter + * if the Qin or Qout condition at PHY + * is not fulfilled for the number of + * consecutive frames. + */ + void DoResetSyncIndicationCounter (); + public: /** * The number of component carriers.