| /* |
| * Copyright (c) 2021 Nordic Semiconductor ASA |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <zephyr/zephyr.h> |
| #include <stddef.h> |
| #include <ztest.h> |
| |
| #include <zephyr/bluetooth/bluetooth.h> |
| #include <zephyr/bluetooth/hci.h> |
| #include <zephyr/sys/byteorder.h> |
| #include <host/hci_core.h> |
| |
| #include <bt_conn_common.h> |
| #include "test_set_conn_cte_tx_params.h" |
| |
| static uint16_t g_conn_handle; |
| |
| static const uint8_t g_ant_ids[] = { 0x1, 0x2, 0x3, 0x4, 0x5 }; |
| |
| /** |
| * @brief Structure to store CTE receive parameters for unit tests setup. |
| */ |
| struct ut_bt_df_conn_cte_tx_params { |
| uint8_t cte_types; |
| uint8_t switch_pattern_len; |
| const uint8_t *ant_ids; |
| }; |
| |
| static struct ut_bt_df_conn_cte_tx_params g_params; |
| |
| /* Macros delivering common values for unit tests */ |
| #define CONN_HANDLE_INVALID (CONFIG_BT_MAX_CONN + 1) |
| #define ANTENNA_SWITCHING_SLOT_INVALID 0x3 /* BT_HCI_LE_ANTENNA_SWITCHING_SLOT_2US + 1 */ |
| #define CTE_TYPE_NONE_ALLOWED 0x0 /* Any bit is not set */ |
| #define CTE_TYPE_INVALID \ |
| (~(uint8_t)(BT_HCI_LE_AOA_CTE_RSP | BT_HCI_LE_AOD_CTE_RSP_1US | \ |
| BT_HCI_LE_AOD_CTE_RSP_2US)) /* Any other than allowed bit is set */ |
| |
| /* Antenna switch pattern length is stored in 1 octet. If BT Core spec. extends the max value to |
| * UINT8_MAX expected failures may not be checked. If storage size is increased, tests shall be |
| * updated. |
| */ |
| BUILD_ASSERT(CONFIG_BT_CTLR_DF_MAX_ANT_SW_PATTERN_LEN < UINT8_MAX, |
| "Can't test expected failures for switch pattern length longer or " |
| "equal to UINT8_MAX."); |
| #define SWITCH_PATTERN_LEN_TOO_LONG (CONFIG_BT_CTLR_DF_MAX_ANT_SW_PATTERN_LEN + 1) |
| |
| BUILD_ASSERT(BT_HCI_LE_SWITCH_PATTERN_LEN_MIN > 0x0, |
| "Can't test expected failures for switch pattern length smaller or equal to zero."); |
| #define SWITCH_PATTERN_LEN_TOO_SHORT (BT_HCI_LE_SWITCH_PATTERN_LEN_MIN - 1) |
| |
| static int send_set_conn_cte_tx_params(uint16_t conn_handle, |
| const struct ut_bt_df_conn_cte_tx_params *params) |
| { |
| struct bt_hci_cp_le_set_conn_cte_tx_params *cp; |
| uint8_t *dest_ant_ids; |
| struct net_buf *buf; |
| |
| buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_CONN_CTE_TX_PARAMS, |
| sizeof(*cp) + params->switch_pattern_len); |
| if (!buf) { |
| return -ENOBUFS; |
| } |
| |
| cp = net_buf_add(buf, sizeof(*cp)); |
| (void)memset(cp, 0, sizeof(*cp)); |
| |
| cp->handle = sys_cpu_to_le16(conn_handle); |
| cp->cte_types = params->cte_types; |
| |
| dest_ant_ids = net_buf_add(buf, params->switch_pattern_len); |
| |
| if (params->ant_ids) { |
| (void)memcpy(dest_ant_ids, params->ant_ids, params->switch_pattern_len); |
| } |
| cp->switch_pattern_len = params->switch_pattern_len; |
| |
| return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_CONN_CTE_TX_PARAMS, buf, NULL); |
| } |
| |
| void test_set_conn_cte_tx_params_with_invalid_conn_handle(void) |
| { |
| int err; |
| |
| err = send_set_conn_cte_tx_params(CONN_HANDLE_INVALID, &g_params); |
| zassert_equal(err, -EIO, |
| "Unexpected error value for set conn CTE tx params with wrong conn handle"); |
| } |
| |
| void test_set_conn_cte_tx_params_with_cte_type_none(void) |
| { |
| int err; |
| |
| g_params.cte_types = CTE_TYPE_NONE_ALLOWED; |
| |
| err = send_set_conn_cte_tx_params(g_conn_handle, &g_params); |
| zassert_equal(err, -EIO, |
| "Unexpected error value for set conn CTE TX params with invalid slot " |
| "durations"); |
| } |
| |
| void test_set_conn_cte_tx_params_with_cte_type_invalid(void) |
| { |
| int err; |
| |
| g_params.cte_types = CTE_TYPE_INVALID; |
| |
| err = send_set_conn_cte_tx_params(g_conn_handle, &g_params); |
| zassert_equal(err, -EIO, |
| "Unexpected error value for set conn CTE TX params with invalid slot " |
| "durations"); |
| } |
| |
| void test_set_conn_cte_tx_params_with_too_long_switch_pattern_len(void) |
| { |
| int err; |
| uint8_t ant_ids[SWITCH_PATTERN_LEN_TOO_LONG] = { 0 }; |
| |
| g_params.switch_pattern_len = SWITCH_PATTERN_LEN_TOO_LONG; |
| g_params.ant_ids = ant_ids; |
| |
| err = send_set_conn_cte_tx_params(g_conn_handle, &g_params); |
| zassert_equal(err, -EIO, |
| "Unexpected error value for set conn CTE TX params with switch pattern set " |
| "length beyond max value"); |
| } |
| |
| void test_set_conn_cte_tx_params_with_too_short_switch_pattern_len(void) |
| { |
| int err; |
| uint8_t ant_ids[SWITCH_PATTERN_LEN_TOO_SHORT] = { 0 }; |
| |
| g_params.switch_pattern_len = SWITCH_PATTERN_LEN_TOO_SHORT; |
| g_params.ant_ids = &ant_ids[0]; |
| |
| err = send_set_conn_cte_tx_params(g_conn_handle, &g_params); |
| zassert_equal(err, -EIO, |
| "Unexpected error value for set conn CTE TX params with switch pattern set " |
| "length below min value"); |
| } |
| |
| void test_set_conn_cte_tx_params_with_ant_ids_ptr_null(void) |
| { |
| int err; |
| |
| g_params.ant_ids = NULL; |
| |
| err = send_set_conn_cte_tx_params(g_conn_handle, &g_params); |
| /* If size of the command buffer equals to expected value, controller is not able to |
| * identify wrong or missing antenna IDs. It will use provided values as if they were |
| * valid antenna IDs. |
| */ |
| zassert_equal(err, 0, |
| "Unexpected error value for set conn CTE TX params with antenna ids " |
| "pointing NULL"); |
| } |
| |
| void test_set_conn_cte_tx_params_with_correct_params(void) |
| { |
| int err; |
| |
| err = send_set_conn_cte_tx_params(g_conn_handle, &g_params); |
| zassert_equal(err, 0, |
| "Unexpected error value for set conn CTE TX params enabled with correct " |
| "params"); |
| } |
| |
| static void connection_setup(void) |
| { |
| g_params.cte_types = |
| BT_HCI_LE_AOA_CTE_RSP | BT_HCI_LE_AOD_CTE_RSP_1US | BT_HCI_LE_AOD_CTE_RSP_2US; |
| g_params.switch_pattern_len = ARRAY_SIZE(g_ant_ids); |
| g_params.ant_ids = g_ant_ids; |
| |
| g_conn_handle = ut_bt_create_connection(); |
| } |
| |
| static void connection_teardown(void) |
| { |
| ut_bt_destroy_connection(g_conn_handle); |
| } |
| |
| void run_set_conn_cte_tx_params_tests(void) |
| { |
| ztest_test_suite( |
| test_set_conn_cte_tx_params, |
| ztest_unit_test(test_set_conn_cte_tx_params_with_invalid_conn_handle), |
| ztest_unit_test_setup_teardown(test_set_conn_cte_tx_params_with_cte_type_none, |
| connection_setup, connection_teardown), |
| ztest_unit_test_setup_teardown(test_set_conn_cte_tx_params_with_cte_type_invalid, |
| connection_setup, connection_teardown), |
| ztest_unit_test_setup_teardown( |
| test_set_conn_cte_tx_params_with_too_long_switch_pattern_len, |
| connection_setup, connection_teardown), |
| ztest_unit_test_setup_teardown( |
| test_set_conn_cte_tx_params_with_too_short_switch_pattern_len, |
| connection_setup, connection_teardown), |
| ztest_unit_test_setup_teardown(test_set_conn_cte_tx_params_with_ant_ids_ptr_null, |
| connection_setup, connection_teardown), |
| ztest_unit_test_setup_teardown(test_set_conn_cte_tx_params_with_correct_params, |
| connection_setup, connection_teardown)); |
| ztest_run_test_suite(test_set_conn_cte_tx_params); |
| } |