diff --git a/src/lte/model/lte-ue-rrc.cc b/src/lte/model/lte-ue-rrc.cc index 2c44981ce..6f22f93d5 100644 --- a/src/lte/model/lte-ue-rrc.cc +++ b/src/lte/model/lte-ue-rrc.cc @@ -651,7 +651,7 @@ LteUeRrc::DoReportUeMeasurements (LteUeCphySapUser::UeMeasurementsParameters par break; } - // Inequality A1-1 (Entering condition): Ms - Hys > Thresh + // Inequality A1-1 (Entering condition): Ms - Hys > Thresh bool entryCond = ms - hys > thresh; if (entryCond && (!isMeasIdInReportList @@ -674,7 +674,7 @@ LteUeRrc::DoReportUeMeasurements (LteUeCphySapUser::UeMeasurementsParameters par eventLeavingCondApplicable = true; } - NS_LOG_LOGIC (this << "event A1: serving cell " << m_cellId + NS_LOG_LOGIC (this << " event A1: serving cell " << m_cellId << " ms=" << ms << " thresh=" << thresh << " entryCond=" << entryCond << " leavingCond=" << leavingCond); @@ -715,7 +715,7 @@ LteUeRrc::DoReportUeMeasurements (LteUeCphySapUser::UeMeasurementsParameters par break; } - // Inequality A2-1 (Entering condition): Ms + Hys < Thresh + // Inequality A2-1 (Entering condition): Ms + Hys < Thresh bool entryCond = ms + hys < thresh; if (entryCond && (!isMeasIdInReportList @@ -727,7 +727,7 @@ LteUeRrc::DoReportUeMeasurements (LteUeCphySapUser::UeMeasurementsParameters par eventEntryCondApplicable = true; } - // Inequality A2-2 (Leaving condition): Ms − Hys > Thresh + // Inequality A2-2 (Leaving condition): Ms - Hys > Thresh bool leavingCond = ms - hys > thresh; if (leavingCond && isMeasIdInReportList @@ -738,7 +738,7 @@ LteUeRrc::DoReportUeMeasurements (LteUeCphySapUser::UeMeasurementsParameters par eventLeavingCondApplicable = true; } - NS_LOG_LOGIC (this << "event A2: serving cell " << m_cellId + NS_LOG_LOGIC (this << " event A2: serving cell " << m_cellId << " ms=" << ms << " thresh=" << thresh << " entryCond=" << entryCond << " leavingCond=" << leavingCond); @@ -807,7 +807,7 @@ LteUeRrc::DoReportUeMeasurements (LteUeCphySapUser::UeMeasurementsParameters par break; } - // Inequality A3-1 (Entering condition): Mn + Ofn + Ocn - Hys > Mp + Ofp + Ocp + Off + // Inequality A3-1 (Entering condition): Mn + Ofn + Ocn - Hys > Mp + Ofp + Ocp + Off bool entryCond = mn + ofn + ocn - hys > mp + ofp + ocp + off; if (entryCond && (!isMeasIdInReportList @@ -830,7 +830,7 @@ LteUeRrc::DoReportUeMeasurements (LteUeCphySapUser::UeMeasurementsParameters par eventLeavingCondApplicable = true; } - NS_LOG_LOGIC (this << "event A3: neighbor cell " << cellId + NS_LOG_LOGIC (this << " event A3: neighbor cell " << cellId << " mn=" << mn << " mp=" << mp << " offset=" << off << " entryCond=" << entryCond << " leavingCond=" << leavingCond); @@ -896,7 +896,7 @@ LteUeRrc::DoReportUeMeasurements (LteUeCphySapUser::UeMeasurementsParameters par break; } - // Inequality A4-1 (Entering condition): Mn + Ofn + Ocn − Hys > Thresh + // Inequality A4-1 (Entering condition): Mn + Ofn + Ocn - Hys > Thresh bool entryCond = mn + ofn + ocn - hys > thresh; if (entryCond && (!isMeasIdInReportList @@ -919,7 +919,7 @@ LteUeRrc::DoReportUeMeasurements (LteUeCphySapUser::UeMeasurementsParameters par eventLeavingCondApplicable = true; } - NS_LOG_LOGIC (this << "event A4: neighbor cell " << cellId + NS_LOG_LOGIC (this << " event A4: neighbor cell " << cellId << " mn=" << mn << " thresh=" << thresh << " entryCond=" << entryCond << " leavingCond=" << leavingCond); @@ -930,13 +930,197 @@ LteUeRrc::DoReportUeMeasurements (LteUeCphySapUser::UeMeasurementsParameters par break; + case LteRrcSap::ReportConfigEutra::EVENT_A5: + { + /* + * Event A5 (PCell becomes worse than threshold1 and neighbour + * becomes better than threshold2) + * Please refer to 3GPP TS 36.331 Section 5.5.4.6 + */ + + double mp; // Mp, the measurement result of the PCell + double mn; // Mn, the measurement result of the neighbouring cell + double ofn = measObjectEutra.offsetFreq; // Ofn, the frequency specific offset of the frequency of the + double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell + double thresh1; // Thresh1, the threshold parameter for this event + double thresh2; // Thresh2, the threshold parameter for this event + double hys = (double) reportConfigEutra.hysteresis * 0.5; // Hys, the hysteresis parameter for this event. See 36.331 section 6.3.5 for the conversion. + + switch (reportConfigEutra.triggerQuantity) + { + case LteRrcSap::ReportConfigEutra::RSRP: + mp = m_storedMeasValues[m_cellId].rsrp; + //mp = EutranMeasurementMapping::QuantizeRsrp (m_storedMeasValues[m_cellId].rsrp); + NS_ASSERT (reportConfigEutra.threshold1.choice + == LteRrcSap::ThresholdEutra::THRESHOLD_RSRP); + thresh1 = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range); + thresh2 = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold2.range); + break; + case LteRrcSap::ReportConfigEutra::RSRQ: + mp = m_storedMeasValues[m_cellId].rsrq; + //mp = EutranMeasurementMapping::QuantizeRsrq (m_storedMeasValues[m_cellId].rsrq); + NS_ASSERT (reportConfigEutra.threshold1.choice + == LteRrcSap::ThresholdEutra::THRESHOLD_RSRQ); + thresh1 = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range); + thresh2 = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold2.range); + break; + default: + NS_FATAL_ERROR ("unsupported triggerQuantity"); + break; + } + + // Inequality A5-1 (Entering condition 1): Mp + Hys < Thresh1 + bool entryCond = mp + hys < thresh1; + if (entryCond) + { + for (std::map::iterator storedMeasIt = m_storedMeasValues.begin (); + storedMeasIt != m_storedMeasValues.end (); + ++storedMeasIt) + { + uint16_t cellId = storedMeasIt->first; + if (cellId == m_cellId) + { + continue; + } + + switch (reportConfigEutra.triggerQuantity) + { + case LteRrcSap::ReportConfigEutra::RSRP: + mn = storedMeasIt->second.rsrp; + //mn = EutranMeasurementMapping::QuantizeRsrp (storedMeasIt->second.rsrp); + break; + case LteRrcSap::ReportConfigEutra::RSRQ: + mn = storedMeasIt->second.rsrq; + //mn = EutranMeasurementMapping::QuantizeRsrq (storedMeasIt->second.rsrq); + break; + default: + NS_FATAL_ERROR ("unsupported triggerQuantity"); + break; + } + + // Inequality A5-2 (Entering condition 2): Mn + Ofn + Ocn - Hys > Thresh2 + entryCond = mn + ofn + ocn - hys > thresh2; + if (entryCond + && (!isMeasIdInReportList + || (isMeasIdInReportList + && (measReportIt->second.cellsTriggeredList.find (cellId) + == measReportIt->second.cellsTriggeredList.end ())))) + { + concernedCellsEntry.push_back (cellId); + eventEntryCondApplicable = true; + } + + NS_LOG_LOGIC (this << " event A5: neighbor cell " << cellId + << " mn=" << mn << " mp=" << mp + << " thresh2=" << thresh2 + << " thresh1=" << thresh1 + << " entryCond=" << entryCond); + + } // end of for (storedMeasIt) + + } // end of if (entryCond) + else + { + NS_LOG_LOGIC (this << " event A5: serving cell " << m_cellId + << " mp=" << mp << " thresh1=" << thresh1 + << " entryCond=" << entryCond); + } + + if (isMeasIdInReportList) + { + // Inequality A5-3 (Leaving condition 1): Mp - Hys > Thresh1 + bool leavingCond = mp - hys > thresh1; + if (leavingCond) + { + // leaving condition 2 does not have to be checked + + for (std::map::iterator storedMeasIt = m_storedMeasValues.begin (); + storedMeasIt != m_storedMeasValues.end (); + ++storedMeasIt) + { + uint16_t cellId = storedMeasIt->first; + if (cellId == m_cellId) + { + continue; + } + + if (measReportIt->second.cellsTriggeredList.find (cellId) + != measReportIt->second.cellsTriggeredList.end ()) + { + concernedCellsLeaving.push_back (cellId); + eventLeavingCondApplicable = true; + } + } + + NS_LOG_LOGIC (this << " event A5: serving cell " << m_cellId + << " mp=" << mp << " thresh1=" << thresh1 + << " leavingCond=" << leavingCond); + + } // end of if (leavingCond) + else + { + for (std::map::iterator storedMeasIt = m_storedMeasValues.begin (); + storedMeasIt != m_storedMeasValues.end (); + ++storedMeasIt) + { + uint16_t cellId = storedMeasIt->first; + if (cellId == m_cellId) + { + continue; + } + + if (measReportIt->second.cellsTriggeredList.find (cellId) + != measReportIt->second.cellsTriggeredList.end ()) + { + switch (reportConfigEutra.triggerQuantity) + { + case LteRrcSap::ReportConfigEutra::RSRP: + mn = storedMeasIt->second.rsrp; + //mn = EutranMeasurementMapping::QuantizeRsrp (storedMeasIt->second.rsrp); + break; + case LteRrcSap::ReportConfigEutra::RSRQ: + mn = storedMeasIt->second.rsrq; + //mn = EutranMeasurementMapping::QuantizeRsrq (storedMeasIt->second.rsrq); + break; + default: + NS_FATAL_ERROR ("unsupported triggerQuantity"); + break; + } + + // Inequality A5-4 (Leaving condition 2): Mn + Ofn + Ocn + Hys < Thresh2 + leavingCond = mn + ofn + ocn + hys < thresh2; + if (leavingCond) + { + concernedCellsLeaving.push_back (cellId); + eventLeavingCondApplicable = true; + } + + NS_LOG_LOGIC (this << " event A5: neighbor cell " << cellId + << " mn=" << mn << " mp=" << mp + << " thresh2=" << thresh2 + << " thresh1=" << thresh1 + << " leavingCond=" << leavingCond); + + } // end of if (measReportIt->second.cellsTriggeredList.find (cellId) + // != measReportIt->second.cellsTriggeredList.end ()) + + } // end of for (storedMeasIt) + + } // end of else of if (entryCond) + + } // end of if (isMeasIdInReportList) + + } // end of case LteRrcSap::ReportConfigEutra::EVENT_A5 + + break; + default: NS_FATAL_ERROR ("unsupported eventId " << reportConfigEutra.eventId); break; } // switch (event type) - NS_LOG_LOGIC (this << "eventEntryCondApplicable=" << eventEntryCondApplicable + NS_LOG_LOGIC (this << " eventEntryCondApplicable=" << eventEntryCondApplicable << " eventLeavingCondApplicable=" << eventLeavingCondApplicable); bool initiateUeMeasurementReportingProcedure = false; @@ -962,9 +1146,9 @@ LteUeRrc::DoReportUeMeasurements (LteUeCphySapUser::UeMeasurementsParameters par measReportIt->second.numberOfReportsSent = 0; initiateUeMeasurementReportingProcedure = true; } - + if (eventLeavingCondApplicable) - { + { NS_ASSERT (measReportIt != m_varMeasReportList.end ()); for (std::list::iterator it = concernedCellsLeaving.begin (); it != concernedCellsLeaving.end (); @@ -980,22 +1164,22 @@ LteUeRrc::DoReportUeMeasurements (LteUeCphySapUser::UeMeasurementsParameters par { initiateUeMeasurementReportingProcedure = true; } - } + } } if (initiateUeMeasurementReportingProcedure) { SendMeasurementReport (measId); - } - + } + if ((measReportIt != m_varMeasReportList.end ()) && (measReportIt->second.cellsTriggeredList.empty ())) { measReportIt->second.periodicReportTimer.Cancel (); m_varMeasReportList.erase (measReportIt); } - - } // for each measId in m_varMeasConfig.measIdList + + } // for each measId in m_varMeasConfig.measIdList } @@ -1492,11 +1676,6 @@ LteUeRrc::ApplyMeasConfig (LteRrcSap::MeasConfig mc) // simplifying assumptions NS_ASSERT_MSG (it->reportConfigEutra.triggerType == LteRrcSap::ReportConfigEutra::EVENT, "only trigger type EVENT is supported"); - NS_ASSERT_MSG (it->reportConfigEutra.eventId == LteRrcSap::ReportConfigEutra::EVENT_A1 - || it->reportConfigEutra.eventId == LteRrcSap::ReportConfigEutra::EVENT_A2 - || it->reportConfigEutra.eventId == LteRrcSap::ReportConfigEutra::EVENT_A3 - || it->reportConfigEutra.eventId == LteRrcSap::ReportConfigEutra::EVENT_A4, - "only events A1, A2, and A4 are supported"); NS_ASSERT_MSG (it->reportConfigEutra.timeToTrigger == 0, "timeToTrigger > 0 is not supported"); uint8_t reportConfigId = it->reportConfigId; diff --git a/src/lte/test/lte-test-ue-measurements.cc b/src/lte/test/lte-test-ue-measurements.cc index 194bc90b1..b7f81db0f 100644 --- a/src/lte/test/lte-test-ue-measurements.cc +++ b/src/lte/test/lte-test-ue-measurements.cc @@ -107,7 +107,7 @@ LteUeMeasurementsTestSuite::LteUeMeasurementsTestSuite () //LogComponentEnable ("LteUeRrc", LOG_WARN); //LogComponentEnable ("LteUeRrc", LOG_LOGIC); - //RunOriginalTestCase (); + RunOriginalTestCase (); RunPiecewiseTestCase1 (); RunPiecewiseTestCase2 (); RunHandoverTestCase (); @@ -255,23 +255,77 @@ LteUeMeasurementsTestSuite::RunPiecewiseTestCase1 () // With normal threshold config.threshold1.range = 54; - expectedTime.clear (); - expectedRsrp.clear (); AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A4 with normal threshold", config, expectedTime, expectedRsrp), TestCase::EXTENSIVE); // With very high threshold config.threshold1.range = 97; - expectedTime.clear (); - expectedRsrp.clear (); AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A4 with very high threshold", config, expectedTime, expectedRsrp), TestCase::EXTENSIVE); // === Event A5 (PCell becomes worse than absolute threshold1 AND neighbour becomes better than another absolute threshold2) === - // TODO + // With low-low threshold + config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A5; + config.threshold1.range = 0; + config.threshold2.range = 0; + expectedTime.clear (); + expectedRsrp.clear (); + AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A5 with low-low threshold", + config, expectedTime, expectedRsrp), + TestCase::EXTENSIVE); + + // With low-normal threshold + config.threshold2.range = 58; + AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A5 with low-normal threshold", + config, expectedTime, expectedRsrp), + TestCase::EXTENSIVE); + + // With low-high threshold + config.threshold2.range = 97; + AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A5 with low-high threshold", + config, expectedTime, expectedRsrp), + TestCase::EXTENSIVE); + + // With normal-low threshold + config.threshold1.range = 58; + config.threshold2.range = 0; + AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A5 with normal-low threshold", + config, expectedTime, expectedRsrp), + TestCase::EXTENSIVE); + + // With normal-normal threshold + config.threshold2.range = 58; + AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A5 with normal-normal threshold", + config, expectedTime, expectedRsrp), + TestCase::EXTENSIVE); + + // With normal-high threshold + config.threshold2.range = 97; + AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A5 with normal-high threshold", + config, expectedTime, expectedRsrp), + TestCase::EXTENSIVE); + + // With high-low threshold + config.threshold1.range = 97; + config.threshold2.range = 0; + AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A5 with high-low threshold", + config, expectedTime, expectedRsrp), + TestCase::EXTENSIVE); + + // With high-normal threshold + config.threshold2.range = 58; + AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A5 with high-normal threshold", + config, expectedTime, expectedRsrp), + TestCase::EXTENSIVE); + + // With high-high threshold + config.threshold2.range = 97; + AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A5 with high-high threshold", + config, expectedTime, expectedRsrp), + TestCase::EXTENSIVE); } // end of void LteUeMeasurementsTestSuite::RunPiecewiseTestCase1 () @@ -418,7 +472,79 @@ LteUeMeasurementsTestSuite::RunPiecewiseTestCase2 () // === Event A5 (PCell becomes worse than absolute threshold1 AND neighbour becomes better than another absolute threshold2) === - // TODO + // With low-low threshold + config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A5; + config.threshold1.range = 0; + config.threshold2.range = 0; + expectedTime.clear (); + expectedRsrp.clear (); + AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with low-low threshold", + config, expectedTime, expectedRsrp), + TestCase::EXTENSIVE); + + // With low-normal threshold + config.threshold2.range = 58; + AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with low-normal threshold", + config, expectedTime, expectedRsrp), + TestCase::EXTENSIVE); + + // With low-high threshold + config.threshold2.range = 97; + AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with low-high threshold", + config, expectedTime, expectedRsrp), + TestCase::EXTENSIVE); + + // With normal-low threshold + config.threshold1.range = 58; + config.threshold2.range = 0; + expectedTime.clear (); + expectedTime << 800 << 1400 << 1640 << 1880; + expectedRsrp.clear (); + expectedRsrp << 52 << 56 << 52 << 56; + AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with normal-low threshold", + config, expectedTime, expectedRsrp), + TestCase::EXTENSIVE); + + // With normal-normal threshold + config.threshold2.range = 58; + AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with normal-normal threshold", + config, expectedTime, expectedRsrp), + TestCase::EXTENSIVE); + + // With normal-high threshold + config.threshold2.range = 97; + AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with normal-high threshold", + config, expectedTime, expectedRsrp), + TestCase::EXTENSIVE); + + // With high-low threshold + config.threshold1.range = 97; + config.threshold2.range = 0; + expectedTime.clear (); + expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120; + expectedRsrp.clear (); + expectedRsrp << 73 << 63 << 72 << 52 << 72 << 59 << 52 << 56 << 59; + AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with high-low threshold", + config, expectedTime, expectedRsrp), + TestCase::EXTENSIVE); + + // With high-normal threshold + config.threshold2.range = 58; + expectedTime.clear (); + expectedTime << 400 << 800 << 1400 << 1640 << 1880; + expectedRsrp.clear (); + expectedRsrp << 63 << 52 << 56 << 52 << 56; + AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with high-normal threshold", + config, expectedTime, expectedRsrp), + TestCase::EXTENSIVE); + + // With high-high threshold + config.threshold2.range = 97; + expectedTime.clear (); + expectedRsrp.clear (); + AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with high-high threshold", + config, expectedTime, expectedRsrp), + TestCase::EXTENSIVE); } // end of void LteUeMeasurementsTestSuite::RunPiecewiseTestCase2 ()