blob: 68e9288c5c7c8d080fdde661409e2d8c03d7510d [file] [log] [blame]
/*
* Copyright (c) 2021 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/zephyr.h>
#include <stddef.h>
#include <zephyr/ztest.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/sys/byteorder.h>
#include <host/hci_core.h>
#include <bt_common.h>
#include "common.h"
struct ut_bt_df_scan_cte_rx_params {
uint8_t slot_durations;
uint8_t cte_count;
uint8_t num_ant_ids;
uint8_t *ant_ids;
};
static uint8_t g_ant_ids[] = { 0x1, 0x2, 0x3, 0x4, 0x5 };
static struct ut_bt_df_scan_cte_rx_params g_params = {
.slot_durations = BT_HCI_LE_ANTENNA_SWITCHING_SLOT_1US,
.cte_count = BT_HCI_LE_SAMPLE_CTE_ALL,
.num_ant_ids = ARRAY_SIZE(g_ant_ids),
.ant_ids = &g_ant_ids[0]
};
/* Macros delivering common values for unit tests */
#define SYNC_HANDLE_INVALID (CONFIG_BT_PER_ADV_SYNC_MAX + 1)
#define ANTENNA_SWITCHING_SLOT_INVALID \
(BT_HCI_LE_ANTENNA_SWITCHING_SLOT_2US + 1)
#define CTE_COUNT_INVALID (BT_HCI_LE_SAMPLE_CTE_COUNT_MAX + 1)
#define SWITCH_PATTERN_LEN_INVALID \
(CONFIG_BT_CTLR_DF_MAX_ANT_SW_PATTERN_LEN + 1)
/* @brief Function sends HCI_LE_Set_Connectionless_CTE_Sampling_Enable
* to controller.
*
* @param sync_handle Handle of sync set.
* @param sync_flags Flags related with sync set.
* @param params CTE Sampling parameters.
* @param enable Enable or disable CTE RX
*
* @return Zero if success, non-zero value in case of failure.
*/
int send_set_scan_cte_rx_enable(uint16_t sync_handle,
struct ut_bt_df_scan_cte_rx_params *params,
bool enable)
{
struct bt_hci_cp_le_set_cl_cte_sampling_enable *cp;
struct net_buf *buf;
buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_CL_CTE_SAMPLING_ENABLE,
sizeof(*cp) + params->num_ant_ids);
if (!buf) {
return -ENOBUFS;
}
cp = net_buf_add(buf, sizeof(*cp));
(void)memset(cp, 0, sizeof(*cp));
cp->sync_handle = sys_cpu_to_le16(sync_handle);
cp->sampling_enable = enable ? 1 : 0;
cp->slot_durations = params->slot_durations;
cp->max_sampled_cte = params->cte_count;
if (params->num_ant_ids) {
if (params->ant_ids) {
uint8_t *dest_ant_ids =
net_buf_add(buf, params->num_ant_ids);
memcpy(dest_ant_ids, params->ant_ids,
params->num_ant_ids);
}
cp->switch_pattern_len = params->num_ant_ids;
} else {
cp->switch_pattern_len = 0;
}
return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_CL_CTE_SAMPLING_ENABLE,
buf, NULL);
}
ZTEST(test_hci_set_scan_cte_rx_enable, test_set_scan_cte_rx_enable_invalid_scan_set_handle)
{
int err;
err = send_set_scan_cte_rx_enable(SYNC_HANDLE_INVALID, &g_params, true);
zassert_equal(err, -EIO,
"Unexpected error value for enable IQ sampling with wrong sync handle");
}
ZTEST(test_hci_set_scan_cte_rx_enable, test_set_scan_cte_rx_enable_invalid_antenna_slots_value)
{
int err;
uint8_t slot_durations_prev = g_params.slot_durations;
g_params.slot_durations = ANTENNA_SWITCHING_SLOT_INVALID;
err = send_set_scan_cte_rx_enable(g_per_sync->handle, &g_params, true);
zassert_equal(err, -EIO,
"Unexpected error value for enable IQ sampling with wrong antenna switching"
" slots value");
g_params.slot_durations = slot_durations_prev;
}
ZTEST(test_hci_set_scan_cte_rx_enable, test_set_scan_cte_rx_enable_invalid_antenna_pattern_num)
{
int err;
uint8_t num_ant_ids_prev = g_params.num_ant_ids;
uint8_t *ant_ids_prev = g_params.ant_ids;
uint8_t ant_ids[SWITCH_PATTERN_LEN_INVALID] = { 0 };
g_params.num_ant_ids = SWITCH_PATTERN_LEN_INVALID;
g_params.ant_ids = &ant_ids[0];
err = send_set_scan_cte_rx_enable(g_per_sync->handle, &g_params, true);
zassert_equal(err, -EIO,
"Unexpected error value for enable IQ sampling with wrong number"
" of antenna ids.");
g_params.num_ant_ids = num_ant_ids_prev;
g_params.ant_ids = ant_ids_prev;
}
ZTEST(test_hci_set_scan_cte_rx_enable, test_set_scan_cte_rx_enable_invalid_cte_count_value)
{
int err;
uint8_t cte_count_prev = g_params.cte_count;
g_params.cte_count = CTE_COUNT_INVALID;
err = send_set_scan_cte_rx_enable(g_per_sync->handle, &g_params, true);
zassert_equal(err, -EIO,
"Unexpected error value for enable IQ sampling with wrong number of CTEs"
" to sample.");
g_params.cte_count = cte_count_prev;
}
ZTEST(test_hci_set_scan_cte_rx_enable, test_set_scan_cte_rx_enable_with_slot_duration_2us)
{
int err;
uint8_t slot_durations_prev = g_params.slot_durations;
g_params.slot_durations = BT_HCI_LE_ANTENNA_SWITCHING_SLOT_2US;
err = send_set_scan_cte_rx_enable(g_per_sync->handle, &g_params, true);
zassert_equal(err, 0, "Unexpected error value for enable IQ sampling");
g_params.slot_durations = slot_durations_prev;
}
ZTEST(test_hci_set_scan_cte_rx_enable, test_set_scan_cte_rx_enable_with_slot_duration_1us)
{
int err;
uint8_t slot_durations_prev = g_params.slot_durations;
g_params.slot_durations = BT_HCI_LE_ANTENNA_SWITCHING_SLOT_1US;
err = send_set_scan_cte_rx_enable(g_per_sync->handle, &g_params, true);
zassert_equal(err, 0,
"Unexpected error value for enable IQ sampling with 1us slot durations");
g_params.slot_durations = slot_durations_prev;
}
ZTEST(test_hci_set_scan_cte_rx_enable, test_set_scan_cte_rx_enable_with_sample_cte_count_min)
{
int err;
uint8_t cte_count_prev = g_params.cte_count;
g_params.cte_count = BT_HCI_LE_SAMPLE_CTE_COUNT_MIN;
err = send_set_scan_cte_rx_enable(g_per_sync->handle, &g_params, true);
zassert_equal(err, 0,
"Unexpected error value for enable IQ sampling with CTEs count set"
" to min value.");
g_params.cte_count = cte_count_prev;
}
ZTEST(test_hci_set_scan_cte_rx_enable, test_set_scan_cte_rx_enable_with_sample_cte_count_max)
{
int err;
uint8_t cte_count_prev = g_params.cte_count;
g_params.cte_count = BT_HCI_LE_SAMPLE_CTE_COUNT_MAX;
err = send_set_scan_cte_rx_enable(g_per_sync->handle, &g_params, true);
zassert_equal(err, 0,
"Unexpected error value for enable IQ sampling with CTEs count set"
" to max value.");
g_params.cte_count = cte_count_prev;
}
ZTEST(test_hci_set_scan_cte_rx_enable, test_set_scan_cte_rx_enable_with_antenna_switch_patterns_min)
{
int err;
uint8_t num_ant_ids_prev = g_params.num_ant_ids;
uint8_t *ant_ids_prev = g_params.ant_ids;
uint8_t ant_ids[BT_HCI_LE_MAX_SWITCH_PATTERN_LEN_MIN] = { 0 };
g_params.num_ant_ids = BT_HCI_LE_MAX_SWITCH_PATTERN_LEN_MIN;
g_params.ant_ids = &ant_ids[0];
err = send_set_scan_cte_rx_enable(g_per_sync->handle, &g_params, true);
zassert_equal(err, 0,
"Unexpected error value for enable IQ sampling with min number of"
" antenna ids.");
g_params.num_ant_ids = num_ant_ids_prev;
g_params.ant_ids = ant_ids_prev;
}
ZTEST(test_hci_set_scan_cte_rx_enable, test_set_scan_cte_rx_enable_with_antenna_switch_patterns_max)
{
int err;
uint8_t num_ant_ids_prev = g_params.num_ant_ids;
uint8_t *ant_ids_prev = g_params.ant_ids;
uint8_t ant_ids[CONFIG_BT_CTLR_DF_MAX_ANT_SW_PATTERN_LEN] = { 0 };
g_params.num_ant_ids = CONFIG_BT_CTLR_DF_MAX_ANT_SW_PATTERN_LEN;
g_params.ant_ids = &ant_ids[0];
err = send_set_scan_cte_rx_enable(g_per_sync->handle, &g_params, true);
zassert_equal(err, 0,
"Unexpected error value for enable IQ sampling with max number of antenna"
" ids.");
g_params.num_ant_ids = num_ant_ids_prev;
g_params.ant_ids = ant_ids_prev;
}
ZTEST(test_hci_set_scan_cte_rx_disable,
test_set_scan_cte_rx_disable_with_correct_sampling_parameters)
{
int err;
err = send_set_scan_cte_rx_enable(g_per_sync->handle, &g_params, false);
zassert_equal(err, 0, "Unexpected error value for disable IQ sampling.");
}
ZTEST(test_hci_set_scan_cte_rx_disable,
test_set_scan_cte_rx_disable_with_invalid_sampling_parameters)
{
int err;
static struct ut_bt_df_scan_cte_rx_params params_invalid = {
.slot_durations = ANTENNA_SWITCHING_SLOT_INVALID,
.cte_count = CTE_COUNT_INVALID,
.num_ant_ids = 0,
.ant_ids = NULL
};
err = send_set_scan_cte_rx_enable(g_per_sync->handle, &params_invalid,
false);
zassert_equal(err, 0, "Unexpected error value for disable IQ sampling.");
}
ZTEST(test_hci_set_scan_cte_rx_disable, test_set_scan_cte_rx_disable_when_disabled)
{
int err;
err = send_set_scan_cte_rx_enable(g_per_sync->handle, &g_params, false);
zassert_equal(err, 0,
"Unexpected error value for disable IQ sampling when it is disabled.");
}
void set_scan_cte_rx_enable_teardown(void *data)
{
int err;
err = send_set_scan_cte_rx_enable(g_per_sync->handle, &g_params, false);
zassert_equal(err, 0, "Unexpected error value for disable IQ sampling.");
}
void set_scan_cte_rx_disable_setup(void *data)
{
int err;
err = send_set_scan_cte_rx_enable(g_per_sync->handle, &g_params, true);
zassert_equal(err, 0, "Unexpected error value for enable IQ sampling.");
}
static void *common_per_sync_setup(void)
{
ut_bt_setup();
common_create_per_sync_set();
return NULL;
}
ZTEST_SUITE(test_hci_set_scan_cte_rx_enable, NULL, common_per_sync_setup, NULL,
set_scan_cte_rx_enable_teardown, ut_bt_teardown);
ZTEST_SUITE(test_hci_set_scan_cte_rx_disable, NULL, common_per_sync_setup,
set_scan_cte_rx_disable_setup, NULL, ut_bt_teardown);