/*
 * Copyright (c) 2020-2021 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <errno.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>

#include <zephyr/autoconf.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/direction.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/hci_types.h>
#include <zephyr/bluetooth/hci_vs.h>
#include <zephyr/bluetooth/l2cap.h>
#include <zephyr/logging/log.h>
#include <zephyr/net_buf.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/sys/atomic.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/check.h>

#include "hci_core.h"
#include "conn_internal.h"
#include "direction_internal.h"

LOG_MODULE_REGISTER(bt_df, CONFIG_BT_DF_LOG_LEVEL);

/* @brief Antenna information for LE Direction Finding */
struct bt_le_df_ant_info {
	/* Bitfield holding optional switching and sampling rates */
	uint8_t switch_sample_rates;
	/* Available antennae number */
	uint8_t num_ant;
	/* Maximum supported antennae switching pattern length */
	uint8_t max_switch_pattern_len;
	/* Maximum length of CTE in 8[us] units */
	uint8_t max_cte_len;
};

static struct bt_le_df_ant_info df_ant_info;
#if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX) || defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
const static uint8_t df_dummy_switch_pattern[BT_HCI_LE_SWITCH_PATTERN_LEN_MIN] = { 0, 0 };
#endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX || CONFIG_BT_DF_CONNECTION_CTE_RX */

#define DF_AOD_TX_1US_SUPPORT(supp)             (supp & BT_HCI_LE_1US_AOD_TX)
#define DF_AOD_RX_1US_SUPPORT(supp)             (supp & BT_HCI_LE_1US_AOD_RX)
#define DF_AOA_RX_1US_SUPPORT(supp)             (supp & BT_HCI_LE_1US_AOA_RX)

#define DF_SAMPLING_ANTENNA_NUMBER_MIN 0x2

#if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX) || defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
static bool valid_cte_rx_common_params(uint8_t cte_types, uint8_t slot_durations,
				       uint8_t num_ant_ids, const uint8_t *ant_ids);
#endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX || CONFIG_BT_DF_CONNECTION_CTE_RX */

#if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX)
static bool valid_cl_cte_rx_params(const struct bt_df_per_adv_sync_cte_rx_param *params);
static int
prepare_cl_cte_rx_enable_cmd_params(struct net_buf **buf, struct bt_le_per_adv_sync *sync,
				    const struct bt_df_per_adv_sync_cte_rx_param *params,
				    bool enable);
static int hci_df_set_cl_cte_rx_enable(struct bt_le_per_adv_sync *sync, bool enable,
				       const struct bt_df_per_adv_sync_cte_rx_param *params);
#endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX */

#if defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
static int prepare_conn_cte_rx_enable_cmd_params(struct net_buf **buf, struct bt_conn *conn,
						 const struct bt_df_conn_cte_rx_param *params,
						 bool enable);
static int hci_df_set_conn_cte_rx_enable(struct bt_conn *conn, bool enable,
					 const struct bt_df_conn_cte_rx_param *params);
#endif /* CONFIG_BT_DF_CONNECTION_CTE_RX */

static uint8_t get_hci_cte_type(enum bt_df_cte_type type)
{
	switch (type) {
	case BT_DF_CTE_TYPE_AOA:
		return BT_HCI_LE_AOA_CTE;
	case BT_DF_CTE_TYPE_AOD_1US:
		return BT_HCI_LE_AOD_CTE_1US;
	case BT_DF_CTE_TYPE_AOD_2US:
		return BT_HCI_LE_AOD_CTE_2US;
	default:
		LOG_ERR("Wrong CTE type");
		return BT_HCI_LE_NO_CTE;
	}
}

static int hci_df_set_cl_cte_tx_params(const struct bt_le_ext_adv *adv,
				    const struct bt_df_adv_cte_tx_param *params)
{
	struct bt_hci_cp_le_set_cl_cte_tx_params *cp;
	struct net_buf *buf;

	/* If AoD is not enabled, ant_ids are ignored by controller:
	 * BT Core spec 5.2 Vol 4, Part E sec. 7.8.80.
	 */
	if (params->cte_type == BT_DF_CTE_TYPE_AOD_1US ||
	    params->cte_type == BT_DF_CTE_TYPE_AOD_2US) {
		if (!BT_FEAT_LE_ANT_SWITCH_TX_AOD(bt_dev.le.features)) {
			return -EINVAL;
		}

		if (params->cte_type == BT_DF_CTE_TYPE_AOD_1US &&
		    !DF_AOD_TX_1US_SUPPORT(df_ant_info.switch_sample_rates)) {
			return -EINVAL;
		}

		if (params->num_ant_ids < BT_HCI_LE_SWITCH_PATTERN_LEN_MIN ||
		    params->num_ant_ids > BT_HCI_LE_SWITCH_PATTERN_LEN_MAX ||
		    !params->ant_ids) {
			return -EINVAL;
		}
	} else if (params->cte_type != BT_DF_CTE_TYPE_AOA) {
		return -EINVAL;
	}

	if (params->cte_len < BT_HCI_LE_CTE_LEN_MIN ||
	    params->cte_len > BT_HCI_LE_CTE_LEN_MAX) {
		return -EINVAL;
	}

	if (params->cte_count < BT_HCI_LE_CTE_COUNT_MIN ||
	    params->cte_count > BT_HCI_LE_CTE_COUNT_MAX) {
		return -EINVAL;
	}

	buf = bt_hci_cmd_alloc(K_FOREVER);
	if (!buf) {
		return -ENOBUFS;
	}

	cp = net_buf_add(buf, sizeof(*cp));
	cp->handle = adv->handle;
	cp->cte_len = params->cte_len;
	cp->cte_type = get_hci_cte_type(params->cte_type);
	cp->cte_count = params->cte_count;

	if (params->num_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_TX_PARAMS,
				    buf, NULL);
}

/* @brief Function provides information about DF antennae number and
 *	  controller capabilities related with Constant Tone Extension.
 *
 * @param[out] switch_sample_rates      Optional switching and sampling rates.
 * @param[out] num_ant                  Antennae number.
 * @param[out] max_switch_pattern_len   Maximum supported antennae switching
 *                                      patterns length.
 * @param[out] max_cte_len              Maximum length of CTE in 8[us] units.
 *
 * @return Zero in case of success, other value in case of failure.
 */
static int hci_df_read_ant_info(uint8_t *switch_sample_rates,
				uint8_t *num_ant,
				uint8_t *max_switch_pattern_len,
				uint8_t *max_cte_len)
{
	__ASSERT_NO_MSG(switch_sample_rates);
	__ASSERT_NO_MSG(num_ant);
	__ASSERT_NO_MSG(max_switch_pattern_len);
	__ASSERT_NO_MSG(max_cte_len);

	struct bt_hci_rp_le_read_ant_info *rp;
	struct net_buf *rsp;
	int err;

	err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_ANT_INFO, NULL, &rsp);
	if (err) {
		LOG_ERR("Failed to read antenna information");
		return err;
	}

	rp = (void *)rsp->data;

	LOG_DBG("DF: sw. sample rates: %x ant num: %u , max sw. pattern len: %u,"
		"max CTE len %d",
		rp->switch_sample_rates, rp->num_ant, rp->max_switch_pattern_len, rp->max_cte_len);

	*switch_sample_rates = rp->switch_sample_rates;
	*num_ant = rp->num_ant;
	*max_switch_pattern_len = rp->max_switch_pattern_len;
	*max_cte_len = rp->max_cte_len;

	net_buf_unref(rsp);

	return 0;
}

/* @brief Function handles send of HCI command to enable or disables CTE
 *        transmission for given advertising set.
 *
 * @param[in] adv               Pointer to advertising set
 * @param[in] enable            Enable or disable CTE TX
 *
 * @return Zero in case of success, other value in case of failure.
 */
static int hci_df_set_adv_cte_tx_enable(struct bt_le_ext_adv *adv,
					bool enable)
{
	struct bt_hci_cp_le_set_cl_cte_tx_enable *cp;
	struct bt_hci_cmd_state_set state;
	struct net_buf *buf;

	buf = bt_hci_cmd_alloc(K_FOREVER);
	if (!buf) {
		return -ENOBUFS;
	}

	cp = net_buf_add(buf, sizeof(*cp));
	(void)memset(cp, 0, sizeof(*cp));

	cp->handle = adv->handle;
	cp->cte_enable = enable ? 1 : 0;

	bt_hci_cmd_state_set_init(buf, &state, adv->flags, BT_PER_ADV_CTE_ENABLED,
				  enable);

	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_CL_CTE_TX_ENABLE,
				   buf, NULL);
}

#if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX) || defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
static bool valid_cte_rx_common_params(uint8_t cte_types, uint8_t slot_durations,
				       uint8_t num_ant_ids, const uint8_t *ant_ids)
{
	if (!(cte_types & BT_DF_CTE_TYPE_ALL)) {
		return false;
	}

	if (cte_types & BT_DF_CTE_TYPE_AOA) {
		if (df_ant_info.num_ant < DF_SAMPLING_ANTENNA_NUMBER_MIN ||
		    !BT_FEAT_LE_ANT_SWITCH_RX_AOA(bt_dev.le.features)) {
			return false;
		}

		if (!(slot_durations == BT_HCI_LE_ANTENNA_SWITCHING_SLOT_2US ||
		      (slot_durations == BT_HCI_LE_ANTENNA_SWITCHING_SLOT_1US &&
		       DF_AOA_RX_1US_SUPPORT(df_ant_info.switch_sample_rates)))) {
			return false;
		}

		if (num_ant_ids < BT_HCI_LE_SWITCH_PATTERN_LEN_MIN ||
		    num_ant_ids > df_ant_info.max_switch_pattern_len || !ant_ids) {
			return false;
		}
	}

	return true;
}
#endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX || CONFIG_BT_DF_CONNECTION_CTE_RX */

#if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX)
static bool valid_cl_cte_rx_params(const struct bt_df_per_adv_sync_cte_rx_param *params)
{
	if (params->max_cte_count > BT_HCI_LE_SAMPLE_CTE_COUNT_MAX) {
		return false;
	}

	if (params->cte_types & BT_DF_CTE_TYPE_AOA) {
		return valid_cte_rx_common_params(params->cte_types, params->slot_durations,
						  params->num_ant_ids, params->ant_ids);
	}

	return true;
}

static int
prepare_cl_cte_rx_enable_cmd_params(struct net_buf **buf, struct bt_le_per_adv_sync *sync,
				    const struct bt_df_per_adv_sync_cte_rx_param *params,
				    bool enable)
{
	struct bt_hci_cp_le_set_cl_cte_sampling_enable *cp;
	uint8_t switch_pattern_len;

	if (params->cte_types & BT_DF_CTE_TYPE_AOA) {
		switch_pattern_len = params->num_ant_ids;
	} else {
		switch_pattern_len = ARRAY_SIZE(df_dummy_switch_pattern);
	}

	/* If CTE Rx is enabled, command parameters total length must include
	 * antenna ids, so command size if extended by num_and_ids.
	 */
	*buf = bt_hci_cmd_alloc(K_FOREVER);
	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;

	if (enable) {
		const uint8_t *ant_ids;
		uint8_t *dest_ant_ids;

		cp->max_sampled_cte = params->max_cte_count;

		if (params->cte_types & BT_DF_CTE_TYPE_AOA) {
			cp->slot_durations = params->slot_durations;
			ant_ids = params->ant_ids;
		} else {
			/* Those values are put here due to constraints from HCI command
			 * specification: Bluetooth Core Spec. 5.3 Vol 4,Part E, sec 7.8.82.
			 * There is no right way to successfully send the command to enable CTE
			 * receive for AoD mode (e.g. device equipped with single antenna).
			 */
			cp->slot_durations = BT_HCI_LE_ANTENNA_SWITCHING_SLOT_2US;
			ant_ids = &df_dummy_switch_pattern[0];
		}

		cp->switch_pattern_len = switch_pattern_len;
		dest_ant_ids = net_buf_add(*buf, cp->switch_pattern_len);
		memcpy(dest_ant_ids, ant_ids, cp->switch_pattern_len);
	}

	return 0;
}

static int hci_df_set_cl_cte_rx_enable(struct bt_le_per_adv_sync *sync, bool enable,
				       const struct bt_df_per_adv_sync_cte_rx_param *params)
{
	struct bt_hci_rp_le_set_cl_cte_sampling_enable *rp;
	struct bt_hci_cmd_state_set state;
	struct net_buf *buf, *rsp;
	int err;

	if (enable) {
		if (!valid_cl_cte_rx_params(params)) {
			return -EINVAL;
		}
	}

	err = prepare_cl_cte_rx_enable_cmd_params(&buf, sync, params, enable);
	if (err) {
		return err;
	}

	bt_hci_cmd_state_set_init(buf, &state, sync->flags, BT_PER_ADV_SYNC_CTE_ENABLED, enable);

	err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_CL_CTE_SAMPLING_ENABLE, buf, &rsp);
	if (err) {
		return err;
	}

	rp = (void *)rsp->data;
	if (sync->handle != sys_le16_to_cpu(rp->sync_handle)) {
		err = -EIO;
	} else {
		sync->cte_types = (enable ? params->cte_types : 0);
	}

	net_buf_unref(rsp);

	return err;
}

int hci_df_prepare_connectionless_iq_report(struct net_buf *buf,
					    struct bt_df_per_adv_sync_iq_samples_report *report,
					    struct bt_le_per_adv_sync **per_adv_sync_to_report)
{
	struct bt_hci_evt_le_connectionless_iq_report *evt;
	struct bt_le_per_adv_sync *per_adv_sync;

	if (buf->len < sizeof(*evt)) {
		LOG_ERR("Unexpected end of buffer");
		return -EINVAL;
	}

	evt = net_buf_pull_mem(buf, sizeof(*evt));

	per_adv_sync = bt_hci_per_adv_sync_lookup_handle(sys_le16_to_cpu(evt->sync_handle));

	if (!per_adv_sync) {
		LOG_ERR("Unknown handle 0x%04X for iq samples report",
			sys_le16_to_cpu(evt->sync_handle));
		return -EINVAL;
	}

	if (!atomic_test_bit(per_adv_sync->flags, BT_PER_ADV_SYNC_CTE_ENABLED)) {
		LOG_ERR("Received PA CTE report when CTE receive disabled");
		return -EINVAL;
	}

	if (!(per_adv_sync->cte_types & BIT(evt->cte_type))) {
		LOG_DBG("CTE filtered out by cte_type: %u", evt->cte_type);
		return -EINVAL;
	}

	report->chan_idx = evt->chan_idx;
	report->rssi = sys_le16_to_cpu(evt->rssi);
	report->rssi_ant_id = evt->rssi_ant_id;
	report->cte_type = BIT(evt->cte_type);
	report->packet_status = evt->packet_status;
	report->slot_durations = evt->slot_durations;
	report->per_evt_counter = sys_le16_to_cpu(evt->per_evt_counter);
	report->sample_type = BT_DF_IQ_SAMPLE_8_BITS_INT;
	report->sample_count = evt->sample_count;
	report->sample = &evt->sample[0];

	*per_adv_sync_to_report = per_adv_sync;

	return 0;
}

int hci_df_vs_prepare_connectionless_iq_report(struct net_buf *buf,
					       struct bt_df_per_adv_sync_iq_samples_report *report,
					       struct bt_le_per_adv_sync **per_adv_sync_to_report)
{
	struct bt_hci_evt_vs_le_connectionless_iq_report *evt;
	struct bt_le_per_adv_sync *per_adv_sync;

	if (buf->len < sizeof(*evt)) {
		LOG_ERR("Unexpected end of buffer");
		return -EINVAL;
	}

	evt = net_buf_pull_mem(buf, sizeof(*evt));

	per_adv_sync = bt_hci_per_adv_sync_lookup_handle(sys_le16_to_cpu(evt->sync_handle));

	if (!per_adv_sync) {
		LOG_ERR("Unknown handle 0x%04X for iq samples report",
			sys_le16_to_cpu(evt->sync_handle));
		return -EINVAL;
	}

	if (!atomic_test_bit(per_adv_sync->flags, BT_PER_ADV_SYNC_CTE_ENABLED)) {
		LOG_ERR("Received PA CTE report when CTE receive disabled");
		return -EINVAL;
	}

	if (!(per_adv_sync->cte_types & BIT(evt->cte_type))) {
		LOG_DBG("CTE filtered out by cte_type: %u", evt->cte_type);
		return -EINVAL;
	}

	report->chan_idx = evt->chan_idx;
	report->rssi = sys_le16_to_cpu(evt->rssi);
	report->rssi_ant_id = evt->rssi_ant_id;
	report->cte_type = BIT(evt->cte_type);
	report->packet_status = evt->packet_status;
	report->slot_durations = evt->slot_durations;
	report->per_evt_counter = sys_le16_to_cpu(evt->per_evt_counter);
	report->sample_count = evt->sample_count;
	report->sample_type = BT_DF_IQ_SAMPLE_16_BITS_INT;
	report->sample16 = &evt->sample[0];

	*per_adv_sync_to_report = per_adv_sync;

	return 0;
}
#endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX */

#if defined(CONFIG_BT_DF_CONNECTION_CTE_TX)
static bool valid_conn_cte_tx_params(const struct bt_df_conn_cte_tx_param *params)
{
	if (!(params->cte_types & BT_DF_CTE_TYPE_ALL)) {
		return false;
	}

	/* If AoD is not enabled, ant_ids are ignored by controller:
	 * BT Core spec 5.2 Vol 4, Part E sec. 7.8.84.
	 */
	if ((params->cte_types & BT_DF_CTE_TYPE_AOD_1US ||
	     params->cte_types & BT_DF_CTE_TYPE_AOD_1US) &&
	    (params->num_ant_ids < BT_HCI_LE_SWITCH_PATTERN_LEN_MIN ||
	     params->num_ant_ids > BT_HCI_LE_SWITCH_PATTERN_LEN_MAX || !params->ant_ids ||
	     !BT_FEAT_LE_ANT_SWITCH_TX_AOD(bt_dev.le.features))) {
		return false;
	}

	return true;
}

static void prepare_conn_cte_tx_params_cmd(struct net_buf *buf, const struct bt_conn *conn,
					   const struct bt_df_conn_cte_tx_param *params)
{
	struct bt_hci_cp_le_set_conn_cte_tx_params *cp;
	uint8_t *ant_ids;

	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;

	if (params->cte_types & (BT_DF_CTE_TYPE_AOD_1US | BT_DF_CTE_TYPE_AOD_2US)) {
		cp->switch_pattern_len = params->num_ant_ids;

		ant_ids = net_buf_add(buf, cp->switch_pattern_len);
		(void)memcpy(ant_ids, params->ant_ids, cp->switch_pattern_len);
	} else {
		cp->switch_pattern_len = 0U;
	}
}

/**
 * @brief Function sets CTE parameters for connection object
 *
 * @param conn   Connection object
 * @param params CTE transmission parameters.
 *
 * @return Zero in case of success, other value in case of failure.
 */
static int hci_df_set_conn_cte_tx_param(struct bt_conn *conn,
					const struct bt_df_conn_cte_tx_param *params)
{
	struct bt_hci_rp_le_set_conn_cte_tx_params *rp;
	struct bt_hci_cmd_state_set state;
	struct net_buf *buf, *rsp;
	int err;

	/* If AoD is not enabled, ant_ids are ignored by controller:
	 * BT Core spec 5.2 Vol 4, Part E sec. 7.8.84.
	 */
	if (!valid_conn_cte_tx_params(params)) {
		return -EINVAL;
	}

	buf = bt_hci_cmd_alloc(K_FOREVER);
	if (!buf) {
		return -ENOBUFS;
	}

	prepare_conn_cte_tx_params_cmd(buf, conn, params);

	/* CTE transmission parameters must be set only once for connection lifetime, hence the
	 * flag BT_CONN_CTE_TX_PARAMS_SET is always set to true and never set to false.
	 */
	bt_hci_cmd_state_set_init(buf, &state, conn->flags, BT_CONN_CTE_TX_PARAMS_SET, true);

	err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_CONN_CTE_TX_PARAMS, buf, &rsp);
	if (err) {
		return err;
	}

	rp = (void *)rsp->data;
	if (conn->handle != sys_le16_to_cpu(rp->handle)) {
		err = -EIO;
	}

	net_buf_unref(rsp);

	return err;
}
#endif /* CONFIG_BT_DF_CONNECTION_CTE_TX */

#if defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
static int prepare_conn_cte_rx_enable_cmd_params(struct net_buf **buf, struct bt_conn *conn,
						 const struct bt_df_conn_cte_rx_param *params,
						 bool enable)
{
	struct bt_hci_cp_le_set_conn_cte_rx_params *cp;
	uint8_t switch_pattern_len;

	if (params->cte_types & BT_DF_CTE_TYPE_AOA) {
		switch_pattern_len = params->num_ant_ids;
	} else {
		switch_pattern_len = ARRAY_SIZE(df_dummy_switch_pattern);
	}

	/* If CTE Rx is enabled, command parameters total length must include
	 * antenna ids, so command size if extended by num_and_ids.
	 */
	*buf = bt_hci_cmd_alloc(K_FOREVER);
	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->sampling_enable = enable ? 1 : 0;

	if (enable) {
		const uint8_t *ant_ids;
		uint8_t *dest_ant_ids;

		if (params->cte_types & BT_DF_CTE_TYPE_AOA) {
			cp->slot_durations = params->slot_durations;
			ant_ids = params->ant_ids;
		} else {
			/* Those values are put here due to constraints from HCI command
			 * specification: Bluetooth Core Spec. 5.3 Vol 4,Part E, sec 7.8.85.
			 * There is no right way to successfully send the command to enable CTE
			 * receive for AoD mode (e.g. device equipped with single antenna).
			 * There is no CTE type in the parameters list, so controller is forced
			 * to check correctness of all parameters always.
			 */
			cp->slot_durations = BT_HCI_LE_ANTENNA_SWITCHING_SLOT_2US;
			ant_ids = &df_dummy_switch_pattern[0];
		}

		cp->switch_pattern_len = switch_pattern_len;
		dest_ant_ids = net_buf_add(*buf, cp->switch_pattern_len);
		(void)memcpy(dest_ant_ids, ant_ids, cp->switch_pattern_len);
	}

	return 0;
}

static int hci_df_set_conn_cte_rx_enable(struct bt_conn *conn, bool enable,
					 const struct bt_df_conn_cte_rx_param *params)
{
	struct bt_hci_rp_le_set_conn_cte_rx_params *rp;
	struct bt_hci_cmd_state_set state;
	struct net_buf *buf, *rsp;
	int err;

	if (enable) {
		if (!valid_cte_rx_common_params(params->cte_types, params->slot_durations,
						params->num_ant_ids, params->ant_ids)) {
			return -EINVAL;
		}
	}

	err = prepare_conn_cte_rx_enable_cmd_params(&buf, conn, params, enable);
	if (err) {
		return err;
	}

	bt_hci_cmd_state_set_init(buf, &state, conn->flags, BT_CONN_CTE_RX_ENABLED, enable);

	err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_CONN_CTE_RX_PARAMS, buf, &rsp);
	if (err) {
		return err;
	}

	rp = (void *)rsp->data;
	if (conn->handle != sys_le16_to_cpu(rp->handle)) {
		err = -EIO;
	} else {
		conn->cte_types = (enable ? params->cte_types : 0);
		/* This flag is set once for connection object. It is never cleared because CTE RX
		 * params must be set at least once for connection object to successfully execute
		 * CTE REQ procedure.
		 */
		atomic_set_bit(conn->flags, BT_CONN_CTE_RX_PARAMS_SET);
	}

	net_buf_unref(rsp);

	return err;
}

int hci_df_prepare_connection_iq_report(struct net_buf *buf,
					 struct bt_df_conn_iq_samples_report *report,
					 struct bt_conn **conn_to_report)
{
	struct bt_hci_evt_le_connection_iq_report *evt;
	struct bt_conn *conn;

	if (buf->len < sizeof(*evt)) {
		LOG_ERR("Unexpected end of buffer");
		return -EINVAL;
	}

	evt = net_buf_pull_mem(buf, sizeof(*evt));

	conn = bt_conn_lookup_handle(sys_le16_to_cpu(evt->conn_handle), BT_CONN_TYPE_LE);
	if (!conn) {
		LOG_ERR("Unknown conn handle 0x%04X for iq samples report",
			sys_le16_to_cpu(evt->conn_handle));
		return -EINVAL;
	}

	if (!atomic_test_bit(conn->flags, BT_CONN_CTE_RX_ENABLED)) {
		LOG_ERR("Received conn CTE report when CTE receive disabled");
		bt_conn_unref(conn);
		return -EINVAL;
	}

	if (!(conn->cte_types & BIT(evt->cte_type))) {
		LOG_DBG("CTE filtered out by cte_type: %u", evt->cte_type);
		bt_conn_unref(conn);
		return -EINVAL;
	}

	report->err = BT_DF_IQ_REPORT_ERR_SUCCESS;
	report->chan_idx = evt->data_chan_idx;
	report->rx_phy = evt->rx_phy;
	report->chan_idx = evt->data_chan_idx;
	report->rssi = evt->rssi;
	report->rssi_ant_id = evt->rssi_ant_id;
	report->cte_type = BIT(evt->cte_type);
	report->packet_status = evt->packet_status;
	report->slot_durations = evt->slot_durations;
	report->conn_evt_counter = sys_le16_to_cpu(evt->conn_evt_counter);
	report->sample_type = BT_DF_IQ_SAMPLE_8_BITS_INT;
	report->sample_count = evt->sample_count;
	report->sample = evt->sample;

	*conn_to_report = conn;

	return 0;
}

int hci_df_vs_prepare_connection_iq_report(struct net_buf *buf,
					   struct bt_df_conn_iq_samples_report *report,
					   struct bt_conn **conn_to_report)
{
	struct bt_hci_evt_vs_le_connection_iq_report *evt;
	struct bt_conn *conn;

	if (buf->len < sizeof(*evt)) {
		LOG_ERR("Unexpected end of buffer");
		return -EINVAL;
	}

	evt = net_buf_pull_mem(buf, sizeof(*evt));

	conn = bt_conn_lookup_handle(sys_le16_to_cpu(evt->conn_handle), BT_CONN_TYPE_LE);
	if (!conn) {
		LOG_ERR("Unknown conn handle 0x%04X for iq samples report",
			sys_le16_to_cpu(evt->conn_handle));
		return -EINVAL;
	}

	if (!atomic_test_bit(conn->flags, BT_CONN_CTE_RX_ENABLED)) {
		LOG_ERR("Received conn CTE report when CTE receive disabled");
		bt_conn_unref(conn);
		return -EINVAL;
	}

	if (!(conn->cte_types & BIT(evt->cte_type))) {
		LOG_DBG("CTE filtered out by cte_type: %u", evt->cte_type);
		bt_conn_unref(conn);
		return -EINVAL;
	}

	report->err = BT_DF_IQ_REPORT_ERR_SUCCESS;
	report->chan_idx = evt->data_chan_idx;
	report->rx_phy = evt->rx_phy;
	report->chan_idx = evt->data_chan_idx;
	report->rssi = evt->rssi;
	report->rssi_ant_id = evt->rssi_ant_id;
	report->cte_type = BIT(evt->cte_type);
	report->packet_status = evt->packet_status;
	report->slot_durations = evt->slot_durations;
	report->conn_evt_counter = sys_le16_to_cpu(evt->conn_evt_counter);
	report->sample_type = BT_DF_IQ_SAMPLE_16_BITS_INT;
	report->sample_count = evt->sample_count;
	report->sample16 = evt->sample;

	*conn_to_report = conn;

	return 0;
}

#endif /* CONFIG_BT_DF_CONNECTION_CTE_RX */

#if defined(CONFIG_BT_DF_CONNECTION_CTE_REQ)
static bool valid_cte_req_params(const struct bt_conn *conn, uint8_t cte_type,
				    uint8_t cte_length)
{
	if (!(conn->cte_types & cte_type)) {
		return false;
	}

	if (cte_length < BT_HCI_LE_CTE_LEN_MIN || cte_length > BT_HCI_LE_CTE_LEN_MAX) {
		return false;
	}

	return true;
}

static void prepare_conn_cte_req_enable_cmd_params(struct net_buf *buf, const struct bt_conn *conn,
						   const struct bt_df_conn_cte_req_params *params,
						   bool enable)
{
	struct bt_hci_cp_le_conn_cte_req_enable *cp;

	cp = net_buf_add(buf, sizeof(*cp));
	(void)memset(cp, 0, sizeof(*cp));

	cp->handle = sys_cpu_to_le16(conn->handle);
	cp->enable = enable ? 1 : 0;

	if (enable) {
		cp->cte_request_interval = params->interval;
		cp->requested_cte_length = sys_cpu_to_le16(params->cte_length);
		cp->requested_cte_type = get_hci_cte_type(params->cte_type);
	}
}

static int hci_df_set_conn_cte_req_enable(struct bt_conn *conn, bool enable,
					  const struct bt_df_conn_cte_req_params *params)
{
	struct bt_hci_cp_le_conn_cte_req_enable *rp;
	struct bt_hci_cmd_state_set state;
	struct net_buf *buf, *rsp;
	int err;

	if (enable && !valid_cte_req_params(conn, params->cte_type, params->cte_length)) {
		return -EINVAL;
	}

	buf = bt_hci_cmd_alloc(K_FOREVER);
	if (!buf) {
		return -ENOBUFS;
	}

	prepare_conn_cte_req_enable_cmd_params(buf, conn, params, enable);

	bt_hci_cmd_state_set_init(buf, &state, conn->flags, BT_CONN_CTE_REQ_ENABLED, enable);

	err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_CONN_CTE_REQ_ENABLE, buf, &rsp);
	if (err) {
		return err;
	}

	rp = (void *)rsp->data;
	if (conn->handle != sys_le16_to_cpu(rp->handle)) {
		err = -EIO;
	}

	net_buf_unref(rsp);

	return err;
}

int hci_df_prepare_conn_cte_req_failed(struct net_buf *buf,
				       struct bt_df_conn_iq_samples_report *report,
				       struct bt_conn **conn_to_report)
{
	struct bt_hci_evt_le_cte_req_failed *evt;
	struct bt_conn *conn;

	if (buf->len < sizeof(*evt)) {
		LOG_ERR("Unexpected end of buffer");
		return -EINVAL;
	}

	evt = net_buf_pull_mem(buf, sizeof(*evt));

	conn = bt_conn_lookup_handle(sys_le16_to_cpu(evt->conn_handle), BT_CONN_TYPE_LE);
	if (!conn) {
		LOG_ERR("Unknown conn handle 0x%04X for iq samples report",
			sys_le16_to_cpu(evt->conn_handle));
		return -EINVAL;
	}

	if (!atomic_test_bit(conn->flags, BT_CONN_CTE_REQ_ENABLED)) {
		LOG_ERR("Received conn CTE request notification when CTE REQ disabled");
		bt_conn_unref(conn);
		return -EINVAL;
	}

	(void)memset(report, 0U, sizeof(*report));

	if (evt->status == BT_HCI_CTE_REQ_STATUS_RSP_WITHOUT_CTE) {
		report->err = BT_DF_IQ_REPORT_ERR_NO_CTE;
	} else {
		report->err = BT_DF_IQ_REPORT_ERR_PEER_REJECTED;
	}

	*conn_to_report = conn;

	return 0;
}
#endif /* CONFIG_BT_DF_CONNECTION_CTE_REQ */

#if defined(CONFIG_BT_DF_CONNECTION_CTE_RSP)
static void prepare_conn_cte_rsp_enable_cmd_params(struct net_buf *buf, const struct bt_conn *conn,
						   bool enable)
{
	struct bt_hci_cp_le_conn_cte_rsp_enable *cp;

	cp = net_buf_add(buf, sizeof(*cp));
	(void)memset(cp, 0, sizeof(*cp));

	cp->handle = sys_cpu_to_le16(conn->handle);
	cp->enable = enable ? 1U : 0U;
}

static int hci_df_set_conn_cte_rsp_enable(struct bt_conn *conn, bool enable)
{
	struct bt_hci_rp_le_conn_cte_rsp_enable *rp;
	struct bt_hci_cmd_state_set state;
	struct net_buf *buf, *rsp;
	int err;

	buf = bt_hci_cmd_alloc(K_FOREVER);
	if (!buf) {
		return -ENOBUFS;
	}

	prepare_conn_cte_rsp_enable_cmd_params(buf, conn, enable);

	bt_hci_cmd_state_set_init(buf, &state, conn->flags, BT_CONN_CTE_RSP_ENABLED, enable);

	err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_CONN_CTE_RSP_ENABLE, buf, &rsp);
	if (err) {
		return err;
	}

	rp = (void *)rsp->data;
	if (conn->handle != sys_le16_to_cpu(rp->handle)) {
		err = -EIO;
	}

	net_buf_unref(rsp);

	return err;
}
#endif /* CONFIG_BT_DF_CONNECTION_CTE_RSP */

/* @brief Function initializes Direction Finding in Host
 *
 * @return Zero in case of success, other value in case of failure.
 */
int le_df_init(void)
{
	uint8_t max_switch_pattern_len;
	uint8_t switch_sample_rates;
	uint8_t max_cte_len;
	uint8_t num_ant;
	int err;

	err = hci_df_read_ant_info(&switch_sample_rates, &num_ant,
			     &max_switch_pattern_len, &max_cte_len);
	if (err) {
		return err;
	}

	df_ant_info.max_switch_pattern_len = max_switch_pattern_len;
	df_ant_info.switch_sample_rates = switch_sample_rates;
	df_ant_info.max_cte_len = max_cte_len;
	df_ant_info.num_ant = num_ant;

	LOG_DBG("DF initialized.");
	return 0;
}

int bt_df_set_adv_cte_tx_param(struct bt_le_ext_adv *adv,
				const struct bt_df_adv_cte_tx_param *params)
{
	__ASSERT_NO_MSG(adv);
	__ASSERT_NO_MSG(params);

	int err;

	if (!BT_FEAT_LE_CONNECTIONLESS_CTE_TX(bt_dev.le.features)) {
		return -ENOTSUP;
	}

	/* Check if BT_ADV_PARAMS_SET is set, because it implies the set
	 * has already been created.
	 */
	if (!atomic_test_bit(adv->flags, BT_ADV_PARAMS_SET)) {
		return -EINVAL;
	}

	if (atomic_test_bit(adv->flags, BT_PER_ADV_CTE_ENABLED)) {
		return -EINVAL;
	}

	err = hci_df_set_cl_cte_tx_params(adv, params);
	if (err) {
		return err;
	}

	atomic_set_bit(adv->flags, BT_PER_ADV_CTE_PARAMS_SET);

	return 0;
}

static int bt_df_set_adv_cte_tx_enabled(struct bt_le_ext_adv *adv, bool enable)
{
	if (!atomic_test_bit(adv->flags, BT_PER_ADV_PARAMS_SET)) {
		return -EINVAL;
	}

	if (!atomic_test_bit(adv->flags, BT_PER_ADV_CTE_PARAMS_SET)) {
		return -EINVAL;
	}

	if (enable == atomic_test_bit(adv->flags, BT_PER_ADV_CTE_ENABLED)) {
		return -EALREADY;
	}

	return hci_df_set_adv_cte_tx_enable(adv, enable);
}

int bt_df_adv_cte_tx_enable(struct bt_le_ext_adv *adv)
{
	__ASSERT_NO_MSG(adv);
	return bt_df_set_adv_cte_tx_enabled(adv, true);
}

int bt_df_adv_cte_tx_disable(struct bt_le_ext_adv *adv)
{
	__ASSERT_NO_MSG(adv);
	return bt_df_set_adv_cte_tx_enabled(adv, false);
}

#if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX)
static int
bt_df_set_per_adv_sync_cte_rx_enable(struct bt_le_per_adv_sync *sync, bool enable,
				     const struct bt_df_per_adv_sync_cte_rx_param *params)
{
	if (!BT_FEAT_LE_CONNECTIONLESS_CTE_RX(bt_dev.le.features)) {
		return -ENOTSUP;
	}

	if (!atomic_test_bit(sync->flags, BT_PER_ADV_SYNC_SYNCED)) {
		return -EINVAL;
	}

	if (!enable &&
	    !atomic_test_bit(sync->flags, BT_PER_ADV_SYNC_CTE_ENABLED)) {
		return -EALREADY;
	}

	return hci_df_set_cl_cte_rx_enable(sync, enable, params);
}

int bt_df_per_adv_sync_cte_rx_enable(struct bt_le_per_adv_sync *sync,
				     const struct bt_df_per_adv_sync_cte_rx_param *params)
{
	CHECKIF(!sync) {
		return -EINVAL;
	}
	CHECKIF(!params) {
		return -EINVAL;
	}

	return bt_df_set_per_adv_sync_cte_rx_enable(sync, true, params);
}

int bt_df_per_adv_sync_cte_rx_disable(struct bt_le_per_adv_sync *sync)
{
	CHECKIF(!sync) {
		return -EINVAL;
	}

	return bt_df_set_per_adv_sync_cte_rx_enable(sync, false, NULL);
}
#endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX */

#if defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
static int bt_df_set_conn_cte_rx_enable(struct bt_conn *conn, bool enable,
					const struct bt_df_conn_cte_rx_param *params)
{
	if (!BT_FEAT_LE_RX_CTE(bt_dev.le.features)) {
		LOG_WRN("Receiving Constant Tone Extensions is not supported");
		return -ENOTSUP;
	}

	if (conn->state != BT_CONN_CONNECTED) {
		LOG_ERR("not connected!");
		return -ENOTCONN;
	}

	return hci_df_set_conn_cte_rx_enable(conn, enable, params);
}

int bt_df_conn_cte_rx_enable(struct bt_conn *conn, const struct bt_df_conn_cte_rx_param *params)
{
	CHECKIF(!conn) {
		return -EINVAL;
	}

	CHECKIF(!params) {
		return -EINVAL;
	}

	return bt_df_set_conn_cte_rx_enable(conn, true, params);
}

int bt_df_conn_cte_rx_disable(struct bt_conn *conn)
{
	CHECKIF(!conn) {
		return -EINVAL;
	}

	return bt_df_set_conn_cte_rx_enable(conn, false, NULL);
}
#endif /* CONFIG_BT_DF_CONNECTION_CTE_RX */

#if defined(CONFIG_BT_DF_CONNECTION_CTE_TX)
int bt_df_set_conn_cte_tx_param(struct bt_conn *conn, const struct bt_df_conn_cte_tx_param *params)
{
	CHECKIF(!conn) {
		return -EINVAL;
	}

	CHECKIF(!params) {
		return -EINVAL;
	}

	if (conn->state != BT_CONN_CONNECTED) {
		LOG_ERR("not connected!");
		return -ENOTCONN;
	}

	if (atomic_test_bit(conn->flags, BT_CONN_CTE_RSP_ENABLED)) {
		LOG_WRN("CTE response procedure is enabled");
		return -EINVAL;
	}

	return hci_df_set_conn_cte_tx_param(conn, params);
}

#endif /* CONFIG_BT_DF_CONNECTION_CTE_TX */

#if defined(CONFIG_BT_DF_CONNECTION_CTE_REQ)
static int bt_df_set_conn_cte_req_enable(struct bt_conn *conn, bool enable,
					 const struct bt_df_conn_cte_req_params *params)
{
	if (!BT_FEAT_LE_CONNECTION_CTE_REQ(bt_dev.le.features)) {
		LOG_WRN("Constant Tone Extensions request procedure is not supported");
		return -ENOTSUP;
	}

	if (conn->state != BT_CONN_CONNECTED) {
		LOG_ERR("not connected!");
		return -ENOTCONN;
	}

	if (!atomic_test_bit(conn->flags, BT_CONN_CTE_RX_PARAMS_SET)) {
		LOG_ERR("Can't start CTE request procedure before CTE RX params setup");
		return -EINVAL;
	}

	return hci_df_set_conn_cte_req_enable(conn, enable, params);
}

int bt_df_conn_cte_req_enable(struct bt_conn *conn, const struct bt_df_conn_cte_req_params *params)
{
	CHECKIF(!conn) {
		return -EINVAL;
	}

	CHECKIF(!params) {
		return -EINVAL;
	}

	return bt_df_set_conn_cte_req_enable(conn, true, params);
}

int bt_df_conn_cte_req_disable(struct bt_conn *conn)
{
	CHECKIF(!conn) {
		return -EINVAL;
	}

	return bt_df_set_conn_cte_req_enable(conn, false, NULL);
}
#endif /* CONFIG_BT_DF_CONNECTION_CTE_REQ */

#if defined(CONFIG_BT_DF_CONNECTION_CTE_RSP)
static int bt_df_set_conn_cte_rsp_enable(struct bt_conn *conn, bool enable)
{
	CHECKIF(!conn) {
		return -EINVAL;
	}

	if (!BT_FEAT_LE_CONNECTION_CTE_RESP(bt_dev.le.features)) {
		LOG_WRN("CTE response procedure is not supported");
		return -ENOTSUP;
	}

	if (conn->state != BT_CONN_CONNECTED) {
		LOG_ERR("not connected");
		return -ENOTCONN;
	}

	if (!atomic_test_bit(conn->flags, BT_CONN_CTE_TX_PARAMS_SET)) {
		LOG_ERR("Can't start CTE response procedure before CTE TX params setup");
		return -EINVAL;
	}

	return hci_df_set_conn_cte_rsp_enable(conn, enable);
}

int bt_df_conn_cte_rsp_enable(struct bt_conn *conn)
{
	return bt_df_set_conn_cte_rsp_enable(conn, true);
}

int bt_df_conn_cte_rsp_disable(struct bt_conn *conn)
{
	return bt_df_set_conn_cte_rsp_enable(conn, false);
}
#endif /* CONFIG_BT_DF_CONNECTION_CTE_RSP */
