Skip to content

Commit

Permalink
lib: lte_link_control: fix %NCELLMEAS notification parsing
Browse files Browse the repository at this point in the history
Added handling for %NCELLMEAS notification with status 2 (measurement
interrupted), but no cells.

NRF91-2269

Signed-off-by: Tommi Kangas <[email protected]>
  • Loading branch information
tokangas authored and rlubos committed Dec 20, 2024
1 parent 31d1fa5 commit 64064df
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
-------------------------------------

Expand Down
24 changes: 16 additions & 8 deletions lib/lte_link_control/modules/ncellmeas.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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) {
Expand All @@ -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 */
Expand Down Expand Up @@ -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);
Expand Down
71 changes: 70 additions & 1 deletion tests/lib/lte_lc_api/src/lte_lc_api_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -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(&params);
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;
Expand Down Expand Up @@ -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(&params);
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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 64064df

Please sign in to comment.