diff --git a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst index ee95f56af1d9..31120bd431f3 100644 --- a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst +++ b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst @@ -456,6 +456,10 @@ Modem libraries * Added the :c:func:`pdn_dynamic_params_get_v6` function to get PDN parameters for IPv6-only. +* :ref:`lte_lc_readme` library: + + * Fixed handling of ``%NCELLMEAS`` notification with status 2 (measurement interrupted) and no cells. + Multiprotocol Service Layer libraries ------------------------------------- diff --git a/lib/lte_link_control/modules/ncellmeas.c b/lib/lte_link_control/modules/ncellmeas.c index f6c8bb19dbf0..23003b0114b9 100644 --- a/lib/lte_link_control/modules/ncellmeas.c +++ b/lib/lte_link_control/modules/ncellmeas.c @@ -167,6 +167,10 @@ static int parse_ncellmeas_gci(struct lte_lc_ncellmeas_params *params, const cha goto clean_exit; } else if (status == AT_NCELLMEAS_STATUS_VALUE_INCOMPLETE) { LOG_WRN("NCELLMEAS interrupted; results incomplete"); + if (param_count == 3) { + /* No results, skip parsing. */ + goto clean_exit; + } } /* Go through the cells */ @@ -425,6 +429,14 @@ static int parse_ncellmeas(const char *at_response, struct lte_lc_cells_info *ce err = at_parser_init(&parser, at_response); __ASSERT_NO_MSG(err == 0); + err = at_parser_cmd_count_get(&parser, &count); + if (err) { + LOG_ERR("Could not get NCELLMEAS param count, " + "potentially malformed notification, error: %d", + err); + goto clean_exit; + } + /* Status code */ err = at_parser_num_get(&parser, AT_NCELLMEAS_STATUS_INDEX, &status); if (err) { @@ -437,6 +449,10 @@ static int parse_ncellmeas(const char *at_response, struct lte_lc_cells_info *ce goto clean_exit; } else if (status == AT_NCELLMEAS_STATUS_VALUE_INCOMPLETE) { LOG_WRN("NCELLMEAS interrupted; results incomplete"); + if (count == 2) { + /* No results, skip parsing. */ + goto clean_exit; + } } /* Current cell ID */ @@ -518,14 +534,6 @@ static int parse_ncellmeas(const char *at_response, struct lte_lc_cells_info *ce size_t ta_meas_time_index = AT_NCELLMEAS_PRE_NCELLS_PARAMS_COUNT + cells->ncells_count * AT_NCELLMEAS_N_PARAMS_COUNT; - err = at_parser_cmd_count_get(&parser, &count); - if (err) { - LOG_ERR("Could not get NCELLMEAS param count, " - "potentially malformed notification, error: %d", - err); - goto clean_exit; - } - if (count > ta_meas_time_index) { err = at_parser_num_get(&parser, ta_meas_time_index, &cells->current_cell.timing_advance_meas_time); diff --git a/tests/lib/lte_lc_api/src/lte_lc_api_test.c b/tests/lib/lte_lc_api/src/lte_lc_api_test.c index dd23dd6241b2..db8960ce211e 100644 --- a/tests/lib/lte_lc_api/src/lte_lc_api_test.c +++ b/tests/lib/lte_lc_api/src/lte_lc_api_test.c @@ -2691,6 +2691,41 @@ void test_lte_lc_neighbor_cell_measurement_normal_status_incomplete(void) at_monitor_dispatch(at_notif); } +void test_lte_lc_neighbor_cell_measurement_normal_status_incomplete_no_cells(void) +{ + int ret; + struct lte_lc_ncellmeas_params params = { + .search_type = LTE_LC_NEIGHBOR_SEARCH_TYPE_DEFAULT, + .gci_count = 0, + }; + strcpy(at_notif, + "%NCELLMEAS: 2\r\n"); + + lte_lc_callback_count_expected = 1; + + __mock_nrf_modem_at_printf_ExpectAndReturn("AT%NCELLMEAS", EXIT_SUCCESS); + + ret = lte_lc_neighbor_cell_measurement(¶ms); + TEST_ASSERT_EQUAL(EXIT_SUCCESS, ret); + + test_event_data[0].type = LTE_LC_EVT_NEIGHBOR_CELL_MEAS; + test_event_data[0].cells_info.current_cell.mcc = 0; + test_event_data[0].cells_info.current_cell.mnc = 0; + test_event_data[0].cells_info.current_cell.id = LTE_LC_CELL_EUTRAN_ID_INVALID; + test_event_data[0].cells_info.current_cell.tac = 0; + test_event_data[0].cells_info.current_cell.earfcn = 0; + test_event_data[0].cells_info.current_cell.timing_advance = 0; + test_event_data[0].cells_info.current_cell.timing_advance_meas_time = 0; + test_event_data[0].cells_info.current_cell.measurement_time = 0; + test_event_data[0].cells_info.current_cell.phys_cell_id = 0; + test_event_data[0].cells_info.current_cell.rsrp = 0; + test_event_data[0].cells_info.current_cell.rsrq = 0; + test_event_data[0].cells_info.ncells_count = 0; + test_event_data[0].cells_info.gci_cells_count = 0; + + at_monitor_dispatch(at_notif); +} + void test_lte_lc_neighbor_cell_measurement_cell_id_missing_fail(void) { int ret; @@ -2955,6 +2990,41 @@ void test_lte_lc_neighbor_cell_measurement_gci_status_incomplete(void) at_monitor_dispatch(at_notif); } +void test_lte_lc_neighbor_cell_measurement_gci_status_incomplete_no_cells(void) +{ + int ret; + struct lte_lc_ncellmeas_params params = { + .search_type = LTE_LC_NEIGHBOR_SEARCH_TYPE_GCI_DEFAULT, + .gci_count = 2, + }; + strcpy(at_notif, + "%NCELLMEAS: 2\r\n"); + + lte_lc_callback_count_expected = 1; + + __mock_nrf_modem_at_printf_ExpectAndReturn("AT%NCELLMEAS=3,2", EXIT_SUCCESS); + + ret = lte_lc_neighbor_cell_measurement(¶ms); + TEST_ASSERT_EQUAL(EXIT_SUCCESS, ret); + + test_event_data[0].type = LTE_LC_EVT_NEIGHBOR_CELL_MEAS; + test_event_data[0].cells_info.current_cell.mcc = 0; + test_event_data[0].cells_info.current_cell.mnc = 0; + test_event_data[0].cells_info.current_cell.id = LTE_LC_CELL_EUTRAN_ID_INVALID; + test_event_data[0].cells_info.current_cell.tac = 0; + test_event_data[0].cells_info.current_cell.earfcn = 0; + test_event_data[0].cells_info.current_cell.timing_advance = 0; + test_event_data[0].cells_info.current_cell.timing_advance_meas_time = 0; + test_event_data[0].cells_info.current_cell.measurement_time = 0; + test_event_data[0].cells_info.current_cell.phys_cell_id = 0; + test_event_data[0].cells_info.current_cell.rsrp = 0; + test_event_data[0].cells_info.current_cell.rsrq = 0; + test_event_data[0].cells_info.ncells_count = 0; + test_event_data[0].cells_info.gci_cells_count = 0; + + at_monitor_dispatch(at_notif); +} + void test_lte_lc_neighbor_cell_measurement_gci_max_length(void) { int ret; @@ -3775,7 +3845,6 @@ void test_lte_lc_neighbor_cell_measurement_no_event_handler(void) lte_lc_register_handler(lte_lc_event_handler); } - void test_lte_lc_modem_sleep_event(void) { lte_lc_callback_count_expected = 6;