From 21af9adaebf2e4f03b48a140ae40bdd7bcdb4536 Mon Sep 17 00:00:00 2001 From: Thomas Deppe Date: Thu, 7 Nov 2024 15:50:38 +0100 Subject: [PATCH] Bluetooth: Controller: Set Extended Advertising Parameters v2 command Implement LE Set Extended Advertising Parameters [v2] command as per bluetooth spec v6.0 (Vol 4 Part E Section 7.8.53). Advertising Coding Selection is marked as supported. Signed-off-by: Thomas Deppe --- .../releases/release-notes-changelog.rst | 4 ++ lib/lte_link_control/modules/ncellmeas.c | 24 ++++--- subsys/bluetooth/controller/hci_internal.c | 10 +++ tests/lib/lte_lc_api/src/lte_lc_api_test.c | 71 ++++++++++++++++++- 4 files changed, 100 insertions(+), 9 deletions(-) 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 28884b4b8c66..fe3255fbff2c 100644 --- a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst +++ b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst @@ -455,6 +455,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/subsys/bluetooth/controller/hci_internal.c b/subsys/bluetooth/controller/hci_internal.c index 84e18c847a03..1726680163ff 100644 --- a/subsys/bluetooth/controller/hci_internal.c +++ b/subsys/bluetooth/controller/hci_internal.c @@ -145,6 +145,7 @@ static bool check_and_handle_is_host_using_legacy_and_extended_commands(uint8_t switch (opcode) { #if defined(CONFIG_BT_BROADCASTER) case SDC_HCI_OPCODE_CMD_LE_SET_EXT_ADV_PARAMS: + case SDC_HCI_OPCODE_CMD_LE_SET_EXT_ADV_PARAMS_V2: case SDC_HCI_OPCODE_CMD_LE_READ_NUMBER_OF_SUPPORTED_ADV_SETS: #endif /* CONFIG_BT_BROADCASTER */ #if defined(CONFIG_BT_PER_ADV_SYNC) @@ -467,6 +468,7 @@ void hci_internal_supported_commands(sdc_hci_ip_supported_commands_t *cmds) #if defined(CONFIG_BT_BROADCASTER) cmds->hci_le_set_advertising_set_random_address = 1; cmds->hci_le_set_extended_advertising_parameters = 1; + cmds->hci_le_set_extended_advertising_parameters_v2 = 1; cmds->hci_le_set_extended_advertising_data = 1; cmds->hci_le_set_extended_scan_response_data = 1; cmds->hci_le_set_extended_advertising_enable = 1; @@ -762,6 +764,9 @@ void hci_internal_le_supported_features( #ifdef CONFIG_BT_CTLR_ADV_EXT features->params.le_extended_advertising = 1; +#ifdef CONFIG_BT_CTLR_PHY_CODED + features->params.advertising_coding_selection = 1; +#endif #endif #if defined(CONFIG_BT_CTLR_ADV_PERIODIC) || defined(CONFIG_BT_CTLR_SYNC_PERIODIC) @@ -1218,6 +1223,11 @@ static uint8_t le_controller_cmd_put(uint8_t const * const cmd, case SDC_HCI_OPCODE_CMD_LE_SET_ADV_SET_RANDOM_ADDRESS: return sdc_hci_cmd_le_set_adv_set_random_address((void *)cmd_params); + case SDC_HCI_OPCODE_CMD_LE_SET_EXT_ADV_PARAMS_V2: + *param_length_out += sizeof(sdc_hci_cmd_le_set_ext_adv_params_v2_return_t); + return sdc_hci_cmd_le_set_ext_adv_params_v2((void *)cmd_params, + (void *)event_out_params); + case SDC_HCI_OPCODE_CMD_LE_SET_EXT_ADV_PARAMS: *param_length_out += sizeof(sdc_hci_cmd_le_set_ext_adv_params_return_t); return sdc_hci_cmd_le_set_ext_adv_params((void *)cmd_params, 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;