/* hci_core.c - HCI core Bluetooth handling */

/*
 * Copyright (c) 2017-2021 Nordic Semiconductor ASA
 * Copyright (c) 2015-2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <zephyr/sys/atomic.h>
#include <zephyr/sys/check.h>
#include <zephyr/sys/util.h>
#include <zephyr/sys/slist.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/debug/stack.h>
#include <zephyr/sys/__assert.h>
#include <soc.h>

#include <zephyr/settings/settings.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/l2cap.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/hci_vs.h>
#include <zephyr/drivers/bluetooth/hci_driver.h>

#include "common/bt_str.h"
#include "common/assert.h"

#include "common/rpa.h"
#include "keys.h"
#include "monitor.h"
#include "hci_core.h"
#include "hci_ecc.h"
#include "ecc.h"
#include "id.h"
#include "adv.h"
#include "scan.h"

#include "addr_internal.h"
#include "conn_internal.h"
#include "iso_internal.h"
#include "l2cap_internal.h"
#include "gatt_internal.h"
#include "smp.h"
#include "crypto.h"
#include "settings.h"

#if defined(CONFIG_BT_CLASSIC)
#include "classic/br.h"
#endif

#if defined(CONFIG_BT_DF)
#include "direction_internal.h"
#endif /* CONFIG_BT_DF */

#define LOG_LEVEL CONFIG_BT_HCI_CORE_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(bt_hci_core);

#define HCI_CMD_TIMEOUT      K_SECONDS(10)

/* Stacks for the threads */
static void rx_work_handler(struct k_work *work);
static K_WORK_DEFINE(rx_work, rx_work_handler);
#if defined(CONFIG_BT_RECV_WORKQ_BT)
static struct k_work_q bt_workq;
static K_KERNEL_STACK_DEFINE(rx_thread_stack, CONFIG_BT_RX_STACK_SIZE);
#endif /* CONFIG_BT_RECV_WORKQ_BT */
static struct k_thread tx_thread_data;
static K_KERNEL_STACK_DEFINE(tx_thread_stack, CONFIG_BT_HCI_TX_STACK_SIZE);

static void init_work(struct k_work *work);

struct bt_dev bt_dev = {
	.init          = Z_WORK_INITIALIZER(init_work),
#if defined(CONFIG_BT_PRIVACY)
	.rpa_timeout   = CONFIG_BT_RPA_TIMEOUT,
#endif
#if defined(CONFIG_BT_DEVICE_APPEARANCE_DYNAMIC)
	.appearance = CONFIG_BT_DEVICE_APPEARANCE,
#endif
};

static bt_ready_cb_t ready_cb;

#if defined(CONFIG_BT_HCI_VS_EVT_USER)
static bt_hci_vnd_evt_cb_t *hci_vnd_evt_cb;
#endif /* CONFIG_BT_HCI_VS_EVT_USER */

struct cmd_data {
	/** HCI status of the command completion */
	uint8_t  status;

	/** The command OpCode that the buffer contains */
	uint16_t opcode;

	/** The state to update when command completes with success. */
	struct bt_hci_cmd_state_set *state;

	/** Used by bt_hci_cmd_send_sync. */
	struct k_sem *sync;
};

static struct cmd_data cmd_data[CONFIG_BT_BUF_CMD_TX_COUNT];

#define cmd(buf) (&cmd_data[net_buf_id(buf)])
#define acl(buf) ((struct acl_data *)net_buf_user_data(buf))

void bt_hci_cmd_state_set_init(struct net_buf *buf,
			       struct bt_hci_cmd_state_set *state,
			       atomic_t *target, int bit, bool val)
{
	state->target = target;
	state->bit = bit;
	state->val = val;
	cmd(buf)->state = state;
}

/* HCI command buffers. Derive the needed size from both Command and Event
 * buffer length since the buffer is also used for the response event i.e
 * command complete or command status.
 */
#define CMD_BUF_SIZE MAX(BT_BUF_EVT_RX_SIZE, BT_BUF_CMD_TX_SIZE)
NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, CONFIG_BT_BUF_CMD_TX_COUNT,
			  CMD_BUF_SIZE, sizeof(struct bt_buf_data), NULL);

struct event_handler {
	uint8_t event;
	uint8_t min_len;
	void (*handler)(struct net_buf *buf);
};

#define EVENT_HANDLER(_evt, _handler, _min_len) \
{ \
	.event = _evt, \
	.handler = _handler, \
	.min_len = _min_len, \
}

static int handle_event_common(uint8_t event, struct net_buf *buf,
			       const struct event_handler *handlers, size_t num_handlers)
{
	size_t i;

	for (i = 0; i < num_handlers; i++) {
		const struct event_handler *handler = &handlers[i];

		if (handler->event != event) {
			continue;
		}

		if (buf->len < handler->min_len) {
			LOG_ERR("Too small (%u bytes) event 0x%02x", buf->len, event);
			return -EINVAL;
		}

		handler->handler(buf);
		return 0;
	}

	return -EOPNOTSUPP;
}

static void handle_event(uint8_t event, struct net_buf *buf, const struct event_handler *handlers,
			 size_t num_handlers)
{
	int err;

	err = handle_event_common(event, buf, handlers, num_handlers);
	if (err == -EOPNOTSUPP) {
		LOG_WRN("Unhandled event 0x%02x len %u: %s", event, buf->len,
			bt_hex(buf->data, buf->len));
	}

	/* Other possible errors are handled by handle_event_common function */
}

static void handle_vs_event(uint8_t event, struct net_buf *buf,
			    const struct event_handler *handlers, size_t num_handlers)
{
	int err;

	err = handle_event_common(event, buf, handlers, num_handlers);
	if (err == -EOPNOTSUPP) {
		LOG_WRN("Unhandled vendor-specific event: %s", bt_hex(buf->data, buf->len));
	}

	/* Other possible errors are handled by handle_event_common function */
}

#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
void bt_hci_host_num_completed_packets(struct net_buf *buf)
{

	struct bt_hci_cp_host_num_completed_packets *cp;
	uint16_t handle = acl(buf)->handle;
	struct bt_hci_handle_count *hc;
	struct bt_conn *conn;
	uint8_t index = acl(buf)->index;

	net_buf_destroy(buf);

	/* Do nothing if controller to host flow control is not supported */
	if (!BT_CMD_TEST(bt_dev.supported_commands, 10, 5)) {
		return;
	}

	conn = bt_conn_lookup_index(index);
	if (!conn) {
		LOG_WRN("Unable to look up conn with index 0x%02x", index);
		return;
	}

	if (conn->state != BT_CONN_CONNECTED &&
	    conn->state != BT_CONN_DISCONNECTING) {
		LOG_WRN("Not reporting packet for non-connected conn");
		bt_conn_unref(conn);
		return;
	}

	bt_conn_unref(conn);

	LOG_DBG("Reporting completed packet for handle %u", handle);

	buf = bt_hci_cmd_create(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS,
				sizeof(*cp) + sizeof(*hc));
	if (!buf) {
		LOG_ERR("Unable to allocate new HCI command");
		return;
	}

	cp = net_buf_add(buf, sizeof(*cp));
	cp->num_handles = sys_cpu_to_le16(1);

	hc = net_buf_add(buf, sizeof(*hc));
	hc->handle = sys_cpu_to_le16(handle);
	hc->count  = sys_cpu_to_le16(1);

	bt_hci_cmd_send(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS, buf);
}
#endif /* defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL) */

struct net_buf *bt_hci_cmd_create(uint16_t opcode, uint8_t param_len)
{
	struct bt_hci_cmd_hdr *hdr;
	struct net_buf *buf;

	LOG_DBG("opcode 0x%04x param_len %u", opcode, param_len);

	buf = net_buf_alloc(&hci_cmd_pool, K_FOREVER);
	__ASSERT_NO_MSG(buf);

	LOG_DBG("buf %p", buf);

	net_buf_reserve(buf, BT_BUF_RESERVE);

	bt_buf_set_type(buf, BT_BUF_CMD);

	cmd(buf)->opcode = opcode;
	cmd(buf)->sync = NULL;
	cmd(buf)->state = NULL;

	hdr = net_buf_add(buf, sizeof(*hdr));
	hdr->opcode = sys_cpu_to_le16(opcode);
	hdr->param_len = param_len;

	return buf;
}

int bt_hci_cmd_send(uint16_t opcode, struct net_buf *buf)
{
	if (!buf) {
		buf = bt_hci_cmd_create(opcode, 0);
		if (!buf) {
			return -ENOBUFS;
		}
	}

	LOG_DBG("opcode 0x%04x len %u", opcode, buf->len);

	/* Host Number of Completed Packets can ignore the ncmd value
	 * and does not generate any cmd complete/status events.
	 */
	if (opcode == BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS) {
		int err;

		err = bt_send(buf);
		if (err) {
			LOG_ERR("Unable to send to driver (err %d)", err);
			net_buf_unref(buf);
		}

		return err;
	}

	net_buf_put(&bt_dev.cmd_tx_queue, buf);

	return 0;
}

int bt_hci_cmd_send_sync(uint16_t opcode, struct net_buf *buf,
			 struct net_buf **rsp)
{
	struct k_sem sync_sem;
	uint8_t status;
	int err;

	if (!buf) {
		buf = bt_hci_cmd_create(opcode, 0);
		if (!buf) {
			return -ENOBUFS;
		}
	}

	LOG_DBG("buf %p opcode 0x%04x len %u", buf, opcode, buf->len);

	k_sem_init(&sync_sem, 0, 1);
	cmd(buf)->sync = &sync_sem;

	net_buf_put(&bt_dev.cmd_tx_queue, net_buf_ref(buf));

	err = k_sem_take(&sync_sem, HCI_CMD_TIMEOUT);
	BT_ASSERT_MSG(err == 0, "command opcode 0x%04x timeout with err %d", opcode, err);

	status = cmd(buf)->status;
	if (status) {
		LOG_WRN("opcode 0x%04x status 0x%02x", opcode, status);
		net_buf_unref(buf);

		switch (status) {
		case BT_HCI_ERR_CONN_LIMIT_EXCEEDED:
			return -ECONNREFUSED;
		case BT_HCI_ERR_INSUFFICIENT_RESOURCES:
			return -ENOMEM;
		case BT_HCI_ERR_INVALID_PARAM:
			return -EINVAL;
		default:
			return -EIO;
		}
	}

	LOG_DBG("rsp %p opcode 0x%04x len %u", buf, opcode, buf->len);

	if (rsp) {
		*rsp = buf;
	} else {
		net_buf_unref(buf);
	}

	return 0;
}

int bt_hci_le_rand(void *buffer, size_t len)
{
	struct bt_hci_rp_le_rand *rp;
	struct net_buf *rsp;
	size_t count;
	int err;

	/* Check first that HCI_LE_Rand is supported */
	if (!BT_CMD_TEST(bt_dev.supported_commands, 27, 7)) {
		return -ENOTSUP;
	}

	while (len > 0) {
		/* Number of bytes to fill on this iteration */
		count = MIN(len, sizeof(rp->rand));
		/* Request the next 8 bytes over HCI */
		err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_RAND, NULL, &rsp);
		if (err) {
			return err;
		}
		/* Copy random data into buffer */
		rp = (void *)rsp->data;
		memcpy(buffer, rp->rand, count);

		net_buf_unref(rsp);
		buffer = (uint8_t *)buffer + count;
		len -= count;
	}

	return 0;
}

static int hci_le_read_max_data_len(uint16_t *tx_octets, uint16_t *tx_time)
{
	struct bt_hci_rp_le_read_max_data_len *rp;
	struct net_buf *rsp;
	int err;

	err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_MAX_DATA_LEN, NULL, &rsp);
	if (err) {
		LOG_ERR("Failed to read DLE max data len");
		return err;
	}

	rp = (void *)rsp->data;
	*tx_octets = sys_le16_to_cpu(rp->max_tx_octets);
	*tx_time = sys_le16_to_cpu(rp->max_tx_time);
	net_buf_unref(rsp);

	if (!IN_RANGE(*tx_octets, BT_HCI_LE_MAX_TX_OCTETS_MIN, BT_HCI_LE_MAX_TX_OCTETS_MAX)) {
		LOG_WRN("tx_octets exceeds the valid range %u", *tx_octets);
	}
	if (!IN_RANGE(*tx_time, BT_HCI_LE_MAX_TX_TIME_MIN, BT_HCI_LE_MAX_TX_TIME_MAX)) {
		LOG_WRN("tx_time exceeds the valid range %u", *tx_time);
	}

	return 0;
}

uint8_t bt_get_phy(uint8_t hci_phy)
{
	switch (hci_phy) {
	case BT_HCI_LE_PHY_1M:
		return BT_GAP_LE_PHY_1M;
	case BT_HCI_LE_PHY_2M:
		return BT_GAP_LE_PHY_2M;
	case BT_HCI_LE_PHY_CODED:
		return BT_GAP_LE_PHY_CODED;
	default:
		return 0;
	}
}

int bt_get_df_cte_type(uint8_t hci_cte_type)
{
	switch (hci_cte_type) {
	case BT_HCI_LE_AOA_CTE:
		return BT_DF_CTE_TYPE_AOA;
	case BT_HCI_LE_AOD_CTE_1US:
		return BT_DF_CTE_TYPE_AOD_1US;
	case BT_HCI_LE_AOD_CTE_2US:
		return BT_DF_CTE_TYPE_AOD_2US;
	case BT_HCI_LE_NO_CTE:
		return BT_DF_CTE_TYPE_NONE;
	default:
		return BT_DF_CTE_TYPE_NONE;
	}
}

#if defined(CONFIG_BT_CONN_TX)
static void hci_num_completed_packets(struct net_buf *buf)
{
	struct bt_hci_evt_num_completed_packets *evt = (void *)buf->data;
	int i;

	if (sizeof(*evt) + sizeof(evt->h[0]) * evt->num_handles > buf->len) {
		LOG_ERR("evt num_handles (=%u) too large (%u > %u)",
			evt->num_handles,
			sizeof(*evt) + sizeof(evt->h[0]) * evt->num_handles,
			buf->len);
		return;
	}

	LOG_DBG("num_handles %u", evt->num_handles);

	for (i = 0; i < evt->num_handles; i++) {
		uint16_t handle, count;
		struct bt_conn *conn;

		handle = sys_le16_to_cpu(evt->h[i].handle);
		count = sys_le16_to_cpu(evt->h[i].count);

		LOG_DBG("handle %u count %u", handle, count);

		conn = bt_conn_lookup_handle(handle, BT_CONN_TYPE_ALL);
		if (!conn) {
			LOG_ERR("No connection for handle %u", handle);
			continue;
		}

		while (count--) {
			struct bt_conn_tx *tx;
			sys_snode_t *node;
			unsigned int key;

			key = irq_lock();

			if (conn->pending_no_cb) {
				conn->pending_no_cb--;
				irq_unlock(key);
				k_sem_give(bt_conn_get_pkts(conn));
				continue;
			}

			node = sys_slist_get(&conn->tx_pending);
			irq_unlock(key);

			if (!node) {
				LOG_ERR("packets count mismatch");
				break;
			}

			tx = CONTAINER_OF(node, struct bt_conn_tx, node);

			key = irq_lock();
			conn->pending_no_cb = tx->pending_no_cb;
			tx->pending_no_cb = 0U;
			sys_slist_append(&conn->tx_complete, &tx->node);
			irq_unlock(key);

			k_work_submit(&conn->tx_complete_work);
			k_sem_give(bt_conn_get_pkts(conn));
		}

		bt_conn_unref(conn);
	}
}
#endif /* CONFIG_BT_CONN_TX */

#if defined(CONFIG_BT_CONN)
static void hci_acl(struct net_buf *buf)
{
	struct bt_hci_acl_hdr *hdr;
	uint16_t handle, len;
	struct bt_conn *conn;
	uint8_t flags;

	LOG_DBG("buf %p", buf);
	if (buf->len < sizeof(*hdr)) {
		LOG_ERR("Invalid HCI ACL packet size (%u)", buf->len);
		net_buf_unref(buf);
		return;
	}

	hdr = net_buf_pull_mem(buf, sizeof(*hdr));
	len = sys_le16_to_cpu(hdr->len);
	handle = sys_le16_to_cpu(hdr->handle);
	flags = bt_acl_flags(handle);

	acl(buf)->handle = bt_acl_handle(handle);
	acl(buf)->index = BT_CONN_INDEX_INVALID;

	LOG_DBG("handle %u len %u flags %u", acl(buf)->handle, len, flags);

	if (buf->len != len) {
		LOG_ERR("ACL data length mismatch (%u != %u)", buf->len, len);
		net_buf_unref(buf);
		return;
	}

	conn = bt_conn_lookup_handle(acl(buf)->handle, BT_CONN_TYPE_ALL);
	if (!conn) {
		LOG_ERR("Unable to find conn for handle %u", acl(buf)->handle);
		net_buf_unref(buf);
		return;
	}

	acl(buf)->index = bt_conn_index(conn);

	bt_conn_recv(conn, buf, flags);
	bt_conn_unref(conn);
}

static void hci_data_buf_overflow(struct net_buf *buf)
{
	struct bt_hci_evt_data_buf_overflow *evt = (void *)buf->data;

	LOG_WRN("Data buffer overflow (link type 0x%02x)", evt->link_type);
}

#if defined(CONFIG_BT_CENTRAL)
static void set_phy_conn_param(const struct bt_conn *conn,
			       struct bt_hci_ext_conn_phy *phy)
{
	phy->conn_interval_min = sys_cpu_to_le16(conn->le.interval_min);
	phy->conn_interval_max = sys_cpu_to_le16(conn->le.interval_max);
	phy->conn_latency = sys_cpu_to_le16(conn->le.latency);
	phy->supervision_timeout = sys_cpu_to_le16(conn->le.timeout);

	phy->min_ce_len = 0;
	phy->max_ce_len = 0;
}

int bt_le_create_conn_ext(const struct bt_conn *conn)
{
	struct bt_hci_cp_le_ext_create_conn *cp;
	struct bt_hci_ext_conn_phy *phy;
	struct bt_hci_cmd_state_set state;
	bool use_filter = false;
	struct net_buf *buf;
	uint8_t own_addr_type;
	uint8_t num_phys;
	int err;

	if (IS_ENABLED(CONFIG_BT_FILTER_ACCEPT_LIST)) {
		use_filter = atomic_test_bit(conn->flags, BT_CONN_AUTO_CONNECT);
	}

	err = bt_id_set_create_conn_own_addr(use_filter, &own_addr_type);
	if (err) {
		return err;
	}

	num_phys = (!(bt_dev.create_param.options &
		      BT_CONN_LE_OPT_NO_1M) ? 1 : 0) +
		   ((bt_dev.create_param.options &
		      BT_CONN_LE_OPT_CODED) ? 1 : 0);

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_EXT_CREATE_CONN, sizeof(*cp) +
				num_phys * sizeof(*phy));
	if (!buf) {
		return -ENOBUFS;
	}

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

	if (use_filter) {
		/* User Initiated procedure use fast scan parameters. */
		bt_addr_le_copy(&cp->peer_addr, BT_ADDR_LE_ANY);
		cp->filter_policy = BT_HCI_LE_CREATE_CONN_FP_FILTER;
	} else {
		const bt_addr_le_t *peer_addr = &conn->le.dst;

#if defined(CONFIG_BT_SMP)
		if (bt_dev.le.rl_entries > bt_dev.le.rl_size) {
			/* Host resolving is used, use the RPA directly. */
			peer_addr = &conn->le.resp_addr;
		}
#endif
		bt_addr_le_copy(&cp->peer_addr, peer_addr);
		cp->filter_policy = BT_HCI_LE_CREATE_CONN_FP_NO_FILTER;
	}

	cp->own_addr_type = own_addr_type;
	cp->phys = 0;

	if (!(bt_dev.create_param.options & BT_CONN_LE_OPT_NO_1M)) {
		cp->phys |= BT_HCI_LE_EXT_SCAN_PHY_1M;
		phy = net_buf_add(buf, sizeof(*phy));
		phy->scan_interval = sys_cpu_to_le16(
			bt_dev.create_param.interval);
		phy->scan_window = sys_cpu_to_le16(
			bt_dev.create_param.window);
		set_phy_conn_param(conn, phy);
	}

	if (bt_dev.create_param.options & BT_CONN_LE_OPT_CODED) {
		cp->phys |= BT_HCI_LE_EXT_SCAN_PHY_CODED;
		phy = net_buf_add(buf, sizeof(*phy));
		phy->scan_interval = sys_cpu_to_le16(
			bt_dev.create_param.interval_coded);
		phy->scan_window = sys_cpu_to_le16(
			bt_dev.create_param.window_coded);
		set_phy_conn_param(conn, phy);
	}

	bt_hci_cmd_state_set_init(buf, &state, bt_dev.flags,
				  BT_DEV_INITIATING, true);

	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_EXT_CREATE_CONN, buf, NULL);
}

int bt_le_create_conn_synced(const struct bt_conn *conn, const struct bt_le_ext_adv *adv,
			     uint8_t subevent)
{
	struct bt_hci_cp_le_ext_create_conn_v2 *cp;
	struct bt_hci_ext_conn_phy *phy;
	struct bt_hci_cmd_state_set state;
	struct net_buf *buf;
	uint8_t own_addr_type;
	int err;

	err = bt_id_set_create_conn_own_addr(false, &own_addr_type);
	if (err) {
		return err;
	}

	/* There shall only be one Initiating_PHYs */
	buf = bt_hci_cmd_create(BT_HCI_OP_LE_EXT_CREATE_CONN_V2, sizeof(*cp) + sizeof(*phy));
	if (!buf) {
		return -ENOBUFS;
	}

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

	cp->subevent = subevent;
	cp->adv_handle = adv->handle;
	bt_addr_le_copy(&cp->peer_addr, &conn->le.dst);
	cp->filter_policy = BT_HCI_LE_CREATE_CONN_FP_NO_FILTER;
	cp->own_addr_type = own_addr_type;

	/* The Initiating_PHY is the secondary phy of the corresponding ext adv set */
	if (adv->options & BT_LE_ADV_OPT_CODED) {
		cp->phys = BT_HCI_LE_EXT_SCAN_PHY_CODED;
	} else if (adv->options & BT_LE_ADV_OPT_NO_2M) {
		cp->phys = BT_HCI_LE_EXT_SCAN_PHY_1M;
	} else {
		cp->phys = BT_HCI_LE_EXT_SCAN_PHY_2M;
	}

	phy = net_buf_add(buf, sizeof(*phy));
	(void)memset(phy, 0, sizeof(*phy));
	set_phy_conn_param(conn, phy);

	bt_hci_cmd_state_set_init(buf, &state, bt_dev.flags, BT_DEV_INITIATING, true);

	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_EXT_CREATE_CONN_V2, buf, NULL);
}

static int bt_le_create_conn_legacy(const struct bt_conn *conn)
{
	struct bt_hci_cp_le_create_conn *cp;
	struct bt_hci_cmd_state_set state;
	bool use_filter = false;
	struct net_buf *buf;
	uint8_t own_addr_type;
	int err;

	if (IS_ENABLED(CONFIG_BT_FILTER_ACCEPT_LIST)) {
		use_filter = atomic_test_bit(conn->flags, BT_CONN_AUTO_CONNECT);
	}

	err = bt_id_set_create_conn_own_addr(use_filter, &own_addr_type);
	if (err) {
		return err;
	}

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_CREATE_CONN, sizeof(*cp));
	if (!buf) {
		return -ENOBUFS;
	}

	cp = net_buf_add(buf, sizeof(*cp));
	memset(cp, 0, sizeof(*cp));
	cp->own_addr_type = own_addr_type;

	if (use_filter) {
		/* User Initiated procedure use fast scan parameters. */
		bt_addr_le_copy(&cp->peer_addr, BT_ADDR_LE_ANY);
		cp->filter_policy = BT_HCI_LE_CREATE_CONN_FP_FILTER;
	} else {
		const bt_addr_le_t *peer_addr = &conn->le.dst;

#if defined(CONFIG_BT_SMP)
		if (bt_dev.le.rl_entries > bt_dev.le.rl_size) {
			/* Host resolving is used, use the RPA directly. */
			peer_addr = &conn->le.resp_addr;
		}
#endif
		bt_addr_le_copy(&cp->peer_addr, peer_addr);
		cp->filter_policy = BT_HCI_LE_CREATE_CONN_FP_NO_FILTER;
	}

	cp->scan_interval = sys_cpu_to_le16(bt_dev.create_param.interval);
	cp->scan_window = sys_cpu_to_le16(bt_dev.create_param.window);

	cp->conn_interval_min = sys_cpu_to_le16(conn->le.interval_min);
	cp->conn_interval_max = sys_cpu_to_le16(conn->le.interval_max);
	cp->conn_latency = sys_cpu_to_le16(conn->le.latency);
	cp->supervision_timeout = sys_cpu_to_le16(conn->le.timeout);

	bt_hci_cmd_state_set_init(buf, &state, bt_dev.flags,
				  BT_DEV_INITIATING, true);

	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CREATE_CONN, buf, NULL);
}

int bt_le_create_conn(const struct bt_conn *conn)
{
	if (IS_ENABLED(CONFIG_BT_EXT_ADV) &&
	    BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features)) {
		return bt_le_create_conn_ext(conn);
	}

	return bt_le_create_conn_legacy(conn);
}

int bt_le_create_conn_cancel(void)
{
	struct net_buf *buf;
	struct bt_hci_cmd_state_set state;

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_CREATE_CONN_CANCEL, 0);

	bt_hci_cmd_state_set_init(buf, &state, bt_dev.flags,
				  BT_DEV_INITIATING, false);

	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CREATE_CONN_CANCEL, buf, NULL);
}
#endif /* CONFIG_BT_CENTRAL */

int bt_hci_disconnect(uint16_t handle, uint8_t reason)
{
	struct net_buf *buf;
	struct bt_hci_cp_disconnect *disconn;

	buf = bt_hci_cmd_create(BT_HCI_OP_DISCONNECT, sizeof(*disconn));
	if (!buf) {
		return -ENOBUFS;
	}

	disconn = net_buf_add(buf, sizeof(*disconn));
	disconn->handle = sys_cpu_to_le16(handle);
	disconn->reason = reason;

	return bt_hci_cmd_send_sync(BT_HCI_OP_DISCONNECT, buf, NULL);
}

static uint16_t disconnected_handles[CONFIG_BT_MAX_CONN];
static uint8_t disconnected_handles_reason[CONFIG_BT_MAX_CONN];
static void disconnected_handles_reset(void)
{
	(void)memset(disconnected_handles, 0, sizeof(disconnected_handles));
}

static void conn_handle_disconnected(uint16_t handle, uint8_t disconnect_reason)
{
	for (int i = 0; i < ARRAY_SIZE(disconnected_handles); i++) {
		if (!disconnected_handles[i]) {
			/* Use invalid connection handle bits so that connection
			 * handle 0 can be used as a valid non-zero handle.
			 */
			disconnected_handles[i] = ~BT_ACL_HANDLE_MASK | handle;
			disconnected_handles_reason[i] = disconnect_reason;
		}
	}
}

/** @returns the disconnect reason. */
static uint8_t conn_handle_is_disconnected(uint16_t handle)
{
	handle |= ~BT_ACL_HANDLE_MASK;

	for (int i = 0; i < ARRAY_SIZE(disconnected_handles); i++) {
		if (disconnected_handles[i] == handle) {
			disconnected_handles[i] = 0;
			return disconnected_handles_reason[i];
		}
	}

	return 0;
}

static void hci_disconn_complete_prio(struct net_buf *buf)
{
	struct bt_hci_evt_disconn_complete *evt = (void *)buf->data;
	uint16_t handle = sys_le16_to_cpu(evt->handle);
	struct bt_conn *conn;

	LOG_DBG("status 0x%02x handle %u reason 0x%02x", evt->status, handle, evt->reason);

	if (evt->status) {
		return;
	}

	conn = bt_conn_lookup_handle(handle, BT_CONN_TYPE_ALL);
	if (!conn) {
		/* Priority disconnect complete event received before normal
		 * connection complete event.
		 */
		conn_handle_disconnected(handle, evt->reason);
		return;
	}

	conn->err = evt->reason;

	bt_conn_set_state(conn, BT_CONN_DISCONNECT_COMPLETE);
	bt_conn_unref(conn);
}

static void hci_disconn_complete(struct net_buf *buf)
{
	struct bt_hci_evt_disconn_complete *evt = (void *)buf->data;
	uint16_t handle = sys_le16_to_cpu(evt->handle);
	struct bt_conn *conn;

	LOG_DBG("status 0x%02x handle %u reason 0x%02x", evt->status, handle, evt->reason);

	if (evt->status) {
		return;
	}

	conn = bt_conn_lookup_handle(handle, BT_CONN_TYPE_ALL);
	if (!conn) {
		LOG_ERR("Unable to look up conn with handle %u", handle);
		return;
	}

	bt_conn_set_state(conn, BT_CONN_DISCONNECTED);

	if (conn->type != BT_CONN_TYPE_LE) {
#if defined(CONFIG_BT_CLASSIC)
		if (conn->type == BT_CONN_TYPE_SCO) {
			bt_sco_cleanup(conn);
			return;
		}
		/*
		 * If only for one connection session bond was set, clear keys
		 * database row for this connection.
		 */
		if (conn->type == BT_CONN_TYPE_BR &&
		    atomic_test_and_clear_bit(conn->flags, BT_CONN_BR_NOBOND)) {
			bt_keys_link_key_clear(conn->br.link_key);
		}
#endif
		bt_conn_unref(conn);
		return;
	}

#if defined(CONFIG_BT_CENTRAL) && !defined(CONFIG_BT_FILTER_ACCEPT_LIST)
	if (atomic_test_bit(conn->flags, BT_CONN_AUTO_CONNECT)) {
		bt_conn_set_state(conn, BT_CONN_CONNECTING_SCAN);
		bt_le_scan_update(false);
	}
#endif /* defined(CONFIG_BT_CENTRAL) && !defined(CONFIG_BT_FILTER_ACCEPT_LIST) */

	bt_conn_unref(conn);
}

static int hci_le_read_remote_features(struct bt_conn *conn)
{
	struct bt_hci_cp_le_read_remote_features *cp;
	struct net_buf *buf;

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_READ_REMOTE_FEATURES,
				sizeof(*cp));
	if (!buf) {
		return -ENOBUFS;
	}

	cp = net_buf_add(buf, sizeof(*cp));
	cp->handle = sys_cpu_to_le16(conn->handle);
	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_REMOTE_FEATURES, buf, NULL);
}

static int hci_read_remote_version(struct bt_conn *conn)
{
	struct bt_hci_cp_read_remote_version_info *cp;
	struct net_buf *buf;

	if (conn->state != BT_CONN_CONNECTED) {
		return -ENOTCONN;
	}

	/* Remote version cannot change. */
	if (atomic_test_bit(conn->flags, BT_CONN_AUTO_VERSION_INFO)) {
		return 0;
	}

	buf = bt_hci_cmd_create(BT_HCI_OP_READ_REMOTE_VERSION_INFO,
				sizeof(*cp));
	if (!buf) {
		return -ENOBUFS;
	}

	cp = net_buf_add(buf, sizeof(*cp));
	cp->handle = sys_cpu_to_le16(conn->handle);

	return bt_hci_cmd_send_sync(BT_HCI_OP_READ_REMOTE_VERSION_INFO, buf,
				    NULL);
}

/* LE Data Length Change Event is optional so this function just ignore
 * error and stack will continue to use default values.
 */
int bt_le_set_data_len(struct bt_conn *conn, uint16_t tx_octets, uint16_t tx_time)
{
	struct bt_hci_cp_le_set_data_len *cp;
	struct net_buf *buf;

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_DATA_LEN, sizeof(*cp));
	if (!buf) {
		return -ENOBUFS;
	}

	cp = net_buf_add(buf, sizeof(*cp));
	cp->handle = sys_cpu_to_le16(conn->handle);
	cp->tx_octets = sys_cpu_to_le16(tx_octets);
	cp->tx_time = sys_cpu_to_le16(tx_time);

	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_DATA_LEN, buf, NULL);
}

#if defined(CONFIG_BT_USER_PHY_UPDATE)
static int hci_le_read_phy(struct bt_conn *conn)
{
	struct bt_hci_cp_le_read_phy *cp;
	struct bt_hci_rp_le_read_phy *rp;
	struct net_buf *buf, *rsp;
	int err;

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_READ_PHY, sizeof(*cp));
	if (!buf) {
		return -ENOBUFS;
	}

	cp = net_buf_add(buf, sizeof(*cp));
	cp->handle = sys_cpu_to_le16(conn->handle);

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

	rp = (void *)rsp->data;
	conn->le.phy.tx_phy = bt_get_phy(rp->tx_phy);
	conn->le.phy.rx_phy = bt_get_phy(rp->rx_phy);
	net_buf_unref(rsp);

	return 0;
}
#endif /* defined(CONFIG_BT_USER_PHY_UPDATE) */

int bt_le_set_phy(struct bt_conn *conn, uint8_t all_phys,
		  uint8_t pref_tx_phy, uint8_t pref_rx_phy, uint8_t phy_opts)
{
	struct bt_hci_cp_le_set_phy *cp;
	struct net_buf *buf;

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_PHY, sizeof(*cp));
	if (!buf) {
		return -ENOBUFS;
	}

	cp = net_buf_add(buf, sizeof(*cp));
	cp->handle = sys_cpu_to_le16(conn->handle);
	cp->all_phys = all_phys;
	cp->tx_phys = pref_tx_phy;
	cp->rx_phys = pref_rx_phy;
	cp->phy_opts = phy_opts;

	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_PHY, buf, NULL);
}

static struct bt_conn *find_pending_connect(uint8_t role, bt_addr_le_t *peer_addr)
{
	struct bt_conn *conn;

	/*
	 * Make lookup to check if there's a connection object in
	 * CONNECT or CONNECT_AUTO state associated with passed peer LE address.
	 */
	if (IS_ENABLED(CONFIG_BT_CENTRAL) && role == BT_HCI_ROLE_CENTRAL) {
		conn = bt_conn_lookup_state_le(BT_ID_DEFAULT, peer_addr,
					       BT_CONN_CONNECTING);
		if (IS_ENABLED(CONFIG_BT_FILTER_ACCEPT_LIST) && !conn) {
			conn = bt_conn_lookup_state_le(BT_ID_DEFAULT,
						       BT_ADDR_LE_NONE,
						       BT_CONN_CONNECTING_AUTO);
		}

		return conn;
	}

	if (IS_ENABLED(CONFIG_BT_PERIPHERAL) && role == BT_HCI_ROLE_PERIPHERAL) {
		conn = bt_conn_lookup_state_le(bt_dev.adv_conn_id, peer_addr,
					       BT_CONN_CONNECTING_DIR_ADV);
		if (!conn) {
			conn = bt_conn_lookup_state_le(bt_dev.adv_conn_id,
						       BT_ADDR_LE_NONE,
						       BT_CONN_CONNECTING_ADV);
		}

		return conn;
	}

	return NULL;
}

/* We don't want the application to get a PHY update callback upon connection
 * establishment on 2M PHY. Therefore we must prevent issuing LE Set PHY
 * in this scenario.
 */
static bool skip_auto_phy_update_on_conn_establishment(struct bt_conn *conn)
{
#if defined(CONFIG_BT_USER_PHY_UPDATE)
	if (IS_ENABLED(CONFIG_BT_AUTO_PHY_UPDATE) &&
	    IS_ENABLED(CONFIG_BT_EXT_ADV) &&
	    BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features)) {
		if (conn->le.phy.tx_phy == BT_HCI_LE_PHY_2M &&
		    conn->le.phy.rx_phy == BT_HCI_LE_PHY_2M) {
			return true;
		}
	}
#else
	ARG_UNUSED(conn);
#endif /* defined(CONFIG_BT_USER_PHY_UPDATE) */

	return false;
}

static void conn_auto_initiate(struct bt_conn *conn)
{
	int err;

	if (conn->state != BT_CONN_CONNECTED) {
		/* It is possible that connection was disconnected directly from
		 * connected callback so we must check state before doing
		 * connection parameters update.
		 */
		return;
	}

	if (!atomic_test_bit(conn->flags, BT_CONN_AUTO_FEATURE_EXCH) &&
	    ((conn->role == BT_HCI_ROLE_CENTRAL) ||
	     BT_FEAT_LE_PER_INIT_FEAT_XCHG(bt_dev.le.features))) {
		err = hci_le_read_remote_features(conn);
		if (err) {
			LOG_ERR("Failed read remote features (%d)", err);
		}
	}

	if (IS_ENABLED(CONFIG_BT_REMOTE_VERSION) &&
	    !atomic_test_bit(conn->flags, BT_CONN_AUTO_VERSION_INFO)) {
		err = hci_read_remote_version(conn);
		if (err) {
			LOG_ERR("Failed read remote version (%d)", err);
		}
	}

	if (IS_ENABLED(CONFIG_BT_AUTO_PHY_UPDATE) &&
	    BT_FEAT_LE_PHY_2M(bt_dev.le.features) &&
	    !skip_auto_phy_update_on_conn_establishment(conn)) {
		err = bt_le_set_phy(conn, 0U, BT_HCI_LE_PHY_PREFER_2M,
				    BT_HCI_LE_PHY_PREFER_2M,
				    BT_HCI_LE_PHY_CODED_ANY);
		if (err) {
			LOG_ERR("Failed LE Set PHY (%d)", err);
		}
	}

	if (IS_ENABLED(CONFIG_BT_AUTO_DATA_LEN_UPDATE) &&
	    BT_FEAT_LE_DLE(bt_dev.le.features)) {
		if (IS_BT_QUIRK_NO_AUTO_DLE(&bt_dev)) {
			uint16_t tx_octets, tx_time;

			err = hci_le_read_max_data_len(&tx_octets, &tx_time);
			if (!err) {
				err = bt_le_set_data_len(conn,
						tx_octets, tx_time);
				if (err) {
					LOG_ERR("Failed to set data len (%d)", err);
				}
			}
		} else {
			/* No need to auto-initiate DLE procedure.
			 * It is done by the controller.
			 */
		}
	}
}

static void le_conn_complete_cancel(uint8_t err)
{
	struct bt_conn *conn;

	/* Handle create connection cancel.
	 *
	 * There is no need to check ID address as only one
	 * connection in central role can be in pending state.
	 */
	conn = find_pending_connect(BT_HCI_ROLE_CENTRAL, NULL);
	if (!conn) {
		LOG_ERR("No pending central connection");
		return;
	}

	conn->err = err;

	/* Handle cancellation of outgoing connection attempt. */
	if (!IS_ENABLED(CONFIG_BT_FILTER_ACCEPT_LIST)) {
		/* We notify before checking autoconnect flag
		 * as application may choose to change it from
		 * callback.
		 */
		bt_conn_set_state(conn, BT_CONN_DISCONNECTED);
		/* Check if device is marked for autoconnect. */
		if (atomic_test_bit(conn->flags, BT_CONN_AUTO_CONNECT)) {
			/* Restart passive scanner for device */
			bt_conn_set_state(conn, BT_CONN_CONNECTING_SCAN);
		}
	} else {
		if (atomic_test_bit(conn->flags, BT_CONN_AUTO_CONNECT)) {
			/* Restart FAL initiator after RPA timeout. */
			bt_le_create_conn(conn);
		} else {
			/* Create connection canceled by timeout */
			bt_conn_set_state(conn, BT_CONN_DISCONNECTED);
		}
	}

	bt_conn_unref(conn);
}

static void le_conn_complete_adv_timeout(void)
{
	if (!(IS_ENABLED(CONFIG_BT_EXT_ADV) &&
	      BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features))) {
		struct bt_le_ext_adv *adv = bt_le_adv_lookup_legacy();
		struct bt_conn *conn;

		/* Handle advertising timeout after high duty cycle directed
		 * advertising.
		 */

		atomic_clear_bit(adv->flags, BT_ADV_ENABLED);

		if (IS_ENABLED(CONFIG_BT_EXT_ADV) &&
		    !BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features)) {
			/* No advertising set terminated event, must be a
			 * legacy advertiser set.
			 */
			bt_le_adv_delete_legacy();
		}

		/* There is no need to check ID address as only one
		 * connection in peripheral role can be in pending state.
		 */
		conn = find_pending_connect(BT_HCI_ROLE_PERIPHERAL, NULL);
		if (!conn) {
			LOG_ERR("No pending peripheral connection");
			return;
		}

		conn->err = BT_HCI_ERR_ADV_TIMEOUT;
		bt_conn_set_state(conn, BT_CONN_DISCONNECTED);

		bt_conn_unref(conn);
	}
}

static void enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt)
{
#if defined(CONFIG_BT_CONN) && (CONFIG_BT_EXT_ADV_MAX_ADV_SET > 1)
	if (IS_ENABLED(CONFIG_BT_PERIPHERAL) &&
		evt->role == BT_HCI_ROLE_PERIPHERAL &&
		evt->status == BT_HCI_ERR_SUCCESS &&
		(IS_ENABLED(CONFIG_BT_EXT_ADV) &&
				BT_FEAT_LE_EXT_ADV(bt_dev.le.features))) {

		/* Cache the connection complete event. Process it later.
		 * See bt_dev.cached_conn_complete.
		 */
		for (int i = 0; i < ARRAY_SIZE(bt_dev.cached_conn_complete); i++) {
			if (!bt_dev.cached_conn_complete[i].valid) {
				(void)memcpy(&bt_dev.cached_conn_complete[i].evt,
					evt,
					sizeof(struct bt_hci_evt_le_enh_conn_complete));
				bt_dev.cached_conn_complete[i].valid = true;
				return;
			}
		}

		__ASSERT(false, "No more cache entries available."
				"This should not happen by design");

		return;
	}
#endif
	bt_hci_le_enh_conn_complete(evt);
}

static void translate_addrs(bt_addr_le_t *peer_addr, bt_addr_le_t *id_addr,
			    const struct bt_hci_evt_le_enh_conn_complete *evt, uint8_t id)
{
	if (bt_addr_le_is_resolved(&evt->peer_addr)) {
		bt_addr_le_copy_resolved(id_addr, &evt->peer_addr);

		bt_addr_copy(&peer_addr->a, &evt->peer_rpa);
		peer_addr->type = BT_ADDR_LE_RANDOM;
	} else {
		bt_addr_le_copy(id_addr, bt_lookup_id_addr(id, &evt->peer_addr));
		bt_addr_le_copy(peer_addr, &evt->peer_addr);
	}
}

static void update_conn(struct bt_conn *conn, const bt_addr_le_t *id_addr,
			const struct bt_hci_evt_le_enh_conn_complete *evt)
{
	conn->handle = sys_le16_to_cpu(evt->handle);
	bt_addr_le_copy(&conn->le.dst, id_addr);
	conn->le.interval = sys_le16_to_cpu(evt->interval);
	conn->le.latency = sys_le16_to_cpu(evt->latency);
	conn->le.timeout = sys_le16_to_cpu(evt->supv_timeout);
	conn->role = evt->role;
	conn->err = 0U;

#if defined(CONFIG_BT_USER_DATA_LEN_UPDATE)
	conn->le.data_len.tx_max_len = BT_GAP_DATA_LEN_DEFAULT;
	conn->le.data_len.tx_max_time = BT_GAP_DATA_TIME_DEFAULT;
	conn->le.data_len.rx_max_len = BT_GAP_DATA_LEN_DEFAULT;
	conn->le.data_len.rx_max_time = BT_GAP_DATA_TIME_DEFAULT;
#endif
}

void bt_hci_le_enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt)
{
	uint16_t handle = sys_le16_to_cpu(evt->handle);
	uint8_t disconnect_reason = conn_handle_is_disconnected(handle);
	bt_addr_le_t peer_addr, id_addr;
	struct bt_conn *conn;
	uint8_t id;

	LOG_DBG("status 0x%02x handle %u role %u peer %s peer RPA %s", evt->status, handle,
		evt->role, bt_addr_le_str(&evt->peer_addr), bt_addr_str(&evt->peer_rpa));
	LOG_DBG("local RPA %s", bt_addr_str(&evt->local_rpa));

#if defined(CONFIG_BT_SMP)
	bt_id_pending_keys_update();
#endif

	if (evt->status) {
		if (IS_ENABLED(CONFIG_BT_PERIPHERAL) &&
		    evt->status == BT_HCI_ERR_ADV_TIMEOUT) {
			le_conn_complete_adv_timeout();
			return;
		}

		if (IS_ENABLED(CONFIG_BT_CENTRAL) &&
		    evt->status == BT_HCI_ERR_UNKNOWN_CONN_ID) {
			le_conn_complete_cancel(evt->status);
			bt_le_scan_update(false);
			return;
		}

		if (IS_ENABLED(CONFIG_BT_CENTRAL) && IS_ENABLED(CONFIG_BT_PER_ADV_RSP) &&
		    evt->status == BT_HCI_ERR_CONN_FAIL_TO_ESTAB) {
			le_conn_complete_cancel(evt->status);

			atomic_clear_bit(bt_dev.flags, BT_DEV_INITIATING);

			return;
		}

		LOG_WRN("Unexpected status 0x%02x", evt->status);

		return;
	}

	id = evt->role == BT_HCI_ROLE_PERIPHERAL ? bt_dev.adv_conn_id : BT_ID_DEFAULT;
	translate_addrs(&peer_addr, &id_addr, evt, id);

	conn = find_pending_connect(evt->role, &id_addr);

	if (IS_ENABLED(CONFIG_BT_PERIPHERAL) &&
	    evt->role == BT_HCI_ROLE_PERIPHERAL &&
	    !(IS_ENABLED(CONFIG_BT_EXT_ADV) &&
	      BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features))) {
		struct bt_le_ext_adv *adv = bt_le_adv_lookup_legacy();
		/* Clear advertising even if we are not able to add connection
		 * object to keep host in sync with controller state.
		 */
		atomic_clear_bit(adv->flags, BT_ADV_ENABLED);
		(void)bt_le_lim_adv_cancel_timeout(adv);
	}

	if (IS_ENABLED(CONFIG_BT_CENTRAL) &&
	    evt->role == BT_HCI_ROLE_CENTRAL) {
		/* Clear initiating even if we are not able to add connection
		 * object to keep the host in sync with controller state.
		 */
		atomic_clear_bit(bt_dev.flags, BT_DEV_INITIATING);
	}

	if (!conn) {
		LOG_ERR("No pending conn for peer %s", bt_addr_le_str(&evt->peer_addr));
		bt_hci_disconnect(handle, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
		return;
	}

	update_conn(conn, &id_addr, evt);

#if defined(CONFIG_BT_USER_PHY_UPDATE)
	conn->le.phy.tx_phy = BT_GAP_LE_PHY_1M;
	conn->le.phy.rx_phy = BT_GAP_LE_PHY_1M;
#endif
	/*
	 * Use connection address (instead of identity address) as initiator
	 * or responder address. Only peripheral needs to be updated. For central all
	 * was set during outgoing connection creation.
	 */
	if (IS_ENABLED(CONFIG_BT_PERIPHERAL) &&
	    conn->role == BT_HCI_ROLE_PERIPHERAL) {
		bt_addr_le_copy(&conn->le.init_addr, &peer_addr);

		if (!(IS_ENABLED(CONFIG_BT_EXT_ADV) &&
		      BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features))) {
			struct bt_le_ext_adv *adv = bt_le_adv_lookup_legacy();

			if (IS_ENABLED(CONFIG_BT_PRIVACY) &&
			    !atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY)) {
				conn->le.resp_addr.type = BT_ADDR_LE_RANDOM;
				if (!bt_addr_eq(&evt->local_rpa, BT_ADDR_ANY)) {
					bt_addr_copy(&conn->le.resp_addr.a,
						     &evt->local_rpa);
				} else {
					bt_addr_copy(&conn->le.resp_addr.a,
						     &bt_dev.random_addr.a);
				}
			} else {
				bt_addr_le_copy(&conn->le.resp_addr,
						&bt_dev.id_addr[conn->id]);
			}
		} else {
			/* Copy the local RPA and handle this in advertising set
			 * terminated event.
			 */
			bt_addr_copy(&conn->le.resp_addr.a, &evt->local_rpa);
		}

		/* if the controller supports, lets advertise for another
		 * peripheral connection.
		 * check for connectable advertising state is sufficient as
		 * this is how this le connection complete for peripheral occurred.
		 */
		if (BT_LE_STATES_PER_CONN_ADV(bt_dev.le.states)) {
			bt_le_adv_resume();
		}

		if (IS_ENABLED(CONFIG_BT_EXT_ADV) &&
		    !BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features)) {
			struct bt_le_ext_adv *adv = bt_le_adv_lookup_legacy();
			/* No advertising set terminated event, must be a
			 * legacy advertiser set.
			 */
			if (!atomic_test_bit(adv->flags, BT_ADV_PERSIST)) {
				bt_le_adv_delete_legacy();
			}
		}
	}

	if (IS_ENABLED(CONFIG_BT_CENTRAL) &&
	    conn->role == BT_HCI_ROLE_CENTRAL) {
		bt_addr_le_copy(&conn->le.resp_addr, &peer_addr);

		if (IS_ENABLED(CONFIG_BT_PRIVACY)) {
			conn->le.init_addr.type = BT_ADDR_LE_RANDOM;
			if (!bt_addr_eq(&evt->local_rpa, BT_ADDR_ANY)) {
				bt_addr_copy(&conn->le.init_addr.a,
					     &evt->local_rpa);
			} else {
				bt_addr_copy(&conn->le.init_addr.a,
					     &bt_dev.random_addr.a);
			}
		} else {
			bt_addr_le_copy(&conn->le.init_addr,
					&bt_dev.id_addr[conn->id]);
		}
	}

#if defined(CONFIG_BT_USER_PHY_UPDATE)
	if (IS_ENABLED(CONFIG_BT_EXT_ADV) &&
	    BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features)) {
		int err;

		err = hci_le_read_phy(conn);
		if (err) {
			LOG_WRN("Failed to read PHY (%d)", err);
		}
	}
#endif /* defined(CONFIG_BT_USER_PHY_UPDATE) */

	bt_conn_set_state(conn, BT_CONN_CONNECTED);

	if (disconnect_reason) {
		/* Mark the connection as already disconnected before calling
		 * the connected callback, so that the application cannot
		 * start sending packets
		 */
		conn->err = disconnect_reason;
		bt_conn_set_state(conn, BT_CONN_DISCONNECT_COMPLETE);
	}

	bt_conn_connected(conn);

	/* Start auto-initiated procedures */
	conn_auto_initiate(conn);

	bt_conn_unref(conn);

	if (IS_ENABLED(CONFIG_BT_CENTRAL) &&
	    conn->role == BT_HCI_ROLE_CENTRAL) {
		bt_le_scan_update(false);
	}
}

#if defined(CONFIG_BT_PER_ADV_SYNC_RSP)
void bt_hci_le_enh_conn_complete_sync(struct bt_hci_evt_le_enh_conn_complete_v2 *evt,
				      struct bt_le_per_adv_sync *sync)
{
	uint16_t handle = sys_le16_to_cpu(evt->handle);
	uint8_t disconnect_reason = conn_handle_is_disconnected(handle);
	bt_addr_le_t peer_addr, id_addr;
	struct bt_conn *conn;

	if (!sync->num_subevents) {
		LOG_ERR("Unexpected connection complete event");

		return;
	}

	conn = bt_conn_add_le(BT_ID_DEFAULT, BT_ADDR_LE_ANY);
	if (!conn) {
		LOG_ERR("Unable to allocate connection");
		/* Tell the controller to disconnect to keep it in sync with
		 * the host state and avoid a "rogue" connection.
		 */
		bt_hci_disconnect(handle, BT_HCI_ERR_REMOTE_USER_TERM_CONN);

		return;
	}

	LOG_DBG("status 0x%02x handle %u role %u peer %s peer RPA %s", evt->status, handle,
		evt->role, bt_addr_le_str(&evt->peer_addr), bt_addr_str(&evt->peer_rpa));
	LOG_DBG("local RPA %s", bt_addr_str(&evt->local_rpa));

	if (evt->role != BT_HCI_ROLE_PERIPHERAL) {
		LOG_ERR("PAwR sync always becomes peripheral");

		return;
	}

#if defined(CONFIG_BT_SMP)
	bt_id_pending_keys_update();
#endif

	if (evt->status) {
		LOG_ERR("Unexpected status 0x%02x", evt->status);

		return;
	}

	translate_addrs(&peer_addr, &id_addr, (const struct bt_hci_evt_le_enh_conn_complete *)evt,
			BT_ID_DEFAULT);
	update_conn(conn, &id_addr, (const struct bt_hci_evt_le_enh_conn_complete *)evt);

#if defined(CONFIG_BT_USER_PHY_UPDATE)
	/* The connection is always initated on the same phy as the PAwR advertiser */
	conn->le.phy.tx_phy = sync->phy;
	conn->le.phy.rx_phy = sync->phy;
#endif

	bt_addr_le_copy(&conn->le.init_addr, &peer_addr);

	if (IS_ENABLED(CONFIG_BT_PRIVACY)) {
		conn->le.resp_addr.type = BT_ADDR_LE_RANDOM;
		bt_addr_copy(&conn->le.resp_addr.a, &evt->local_rpa);
	} else {
		bt_addr_le_copy(&conn->le.resp_addr, &bt_dev.id_addr[conn->id]);
	}

	bt_conn_set_state(conn, BT_CONN_CONNECTED);

	if (disconnect_reason) {
		/* Mark the connection as already disconnected before calling
		 * the connected callback, so that the application cannot
		 * start sending packets
		 */
		conn->err = disconnect_reason;
		bt_conn_set_state(conn, BT_CONN_DISCONNECT_COMPLETE);
	}

	bt_conn_connected(conn);

	/* Since we don't give the application a reference to manage
	 * for peripheral connections, we need to release this reference here.
	 */
	bt_conn_unref(conn);

	/* Start auto-initiated procedures */
	conn_auto_initiate(conn);
}
#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */

static void le_enh_conn_complete(struct net_buf *buf)
{
	enh_conn_complete((void *)buf->data);
}

#if defined(CONFIG_BT_PER_ADV_RSP) || defined(CONFIG_BT_PER_ADV_SYNC_RSP)
static void le_enh_conn_complete_v2(struct net_buf *buf)
{
	struct bt_hci_evt_le_enh_conn_complete_v2 *evt =
		(struct bt_hci_evt_le_enh_conn_complete_v2 *)buf->data;

	if (evt->adv_handle == BT_HCI_ADV_HANDLE_INVALID &&
	    evt->sync_handle == BT_HCI_SYNC_HANDLE_INVALID) {
		/* The connection was not created via PAwR, handle the event like v1 */
		enh_conn_complete((struct bt_hci_evt_le_enh_conn_complete *)evt);
	}
#if defined(CONFIG_BT_PER_ADV_RSP)
	else if (evt->adv_handle != BT_HCI_ADV_HANDLE_INVALID &&
		 evt->sync_handle == BT_HCI_SYNC_HANDLE_INVALID) {
		/* The connection was created via PAwR advertiser, it can be handled like v1 */
		enh_conn_complete((struct bt_hci_evt_le_enh_conn_complete *)evt);
	}
#endif /* CONFIG_BT_PER_ADV_RSP */
#if defined(CONFIG_BT_PER_ADV_SYNC_RSP)
	else if (evt->adv_handle == BT_HCI_ADV_HANDLE_INVALID &&
		 evt->sync_handle != BT_HCI_SYNC_HANDLE_INVALID) {
		/* Created via PAwR sync, no adv set terminated event, needs separate handling */
		struct bt_le_per_adv_sync *sync;

		sync = bt_hci_get_per_adv_sync(evt->sync_handle);
		if (!sync) {
			LOG_ERR("Unknown sync handle %d", evt->sync_handle);

			return;
		}

		bt_hci_le_enh_conn_complete_sync(evt, sync);
	}
#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */
	else {
		LOG_ERR("Invalid connection complete event");
	}
}
#endif /* CONFIG_BT_PER_ADV_RSP || CONFIG_BT_PER_ADV_SYNC_RSP */

static void le_legacy_conn_complete(struct net_buf *buf)
{
	struct bt_hci_evt_le_conn_complete *evt = (void *)buf->data;
	struct bt_hci_evt_le_enh_conn_complete enh;

	LOG_DBG("status 0x%02x role %u %s", evt->status, evt->role,
		bt_addr_le_str(&evt->peer_addr));

	enh.status         = evt->status;
	enh.handle         = evt->handle;
	enh.role           = evt->role;
	enh.interval       = evt->interval;
	enh.latency        = evt->latency;
	enh.supv_timeout   = evt->supv_timeout;
	enh.clock_accuracy = evt->clock_accuracy;

	bt_addr_le_copy(&enh.peer_addr, &evt->peer_addr);

	if (IS_ENABLED(CONFIG_BT_PRIVACY)) {
		bt_addr_copy(&enh.local_rpa, &bt_dev.random_addr.a);
	} else {
		bt_addr_copy(&enh.local_rpa, BT_ADDR_ANY);
	}

	bt_addr_copy(&enh.peer_rpa, BT_ADDR_ANY);

	enh_conn_complete(&enh);
}

static void le_remote_feat_complete(struct net_buf *buf)
{
	struct bt_hci_evt_le_remote_feat_complete *evt = (void *)buf->data;
	uint16_t handle = sys_le16_to_cpu(evt->handle);
	struct bt_conn *conn;

	conn = bt_conn_lookup_handle(handle, BT_CONN_TYPE_LE);
	if (!conn) {
		LOG_ERR("Unable to lookup conn for handle %u", handle);
		return;
	}

	if (!evt->status) {
		memcpy(conn->le.features, evt->features,
		       sizeof(conn->le.features));
	}

	atomic_set_bit(conn->flags, BT_CONN_AUTO_FEATURE_EXCH);

	if (IS_ENABLED(CONFIG_BT_REMOTE_INFO) &&
	    !IS_ENABLED(CONFIG_BT_REMOTE_VERSION)) {
		notify_remote_info(conn);
	}

	bt_conn_unref(conn);
}

#if defined(CONFIG_BT_DATA_LEN_UPDATE)
static void le_data_len_change(struct net_buf *buf)
{
	struct bt_hci_evt_le_data_len_change *evt = (void *)buf->data;
	uint16_t handle = sys_le16_to_cpu(evt->handle);
	struct bt_conn *conn;

	conn = bt_conn_lookup_handle(handle, BT_CONN_TYPE_LE);
	if (!conn) {
		LOG_ERR("Unable to lookup conn for handle %u", handle);
		return;
	}

#if defined(CONFIG_BT_USER_DATA_LEN_UPDATE)
	uint16_t max_tx_octets = sys_le16_to_cpu(evt->max_tx_octets);
	uint16_t max_rx_octets = sys_le16_to_cpu(evt->max_rx_octets);
	uint16_t max_tx_time = sys_le16_to_cpu(evt->max_tx_time);
	uint16_t max_rx_time = sys_le16_to_cpu(evt->max_rx_time);

	if (!IN_RANGE(max_tx_octets, BT_HCI_LE_MAX_TX_OCTETS_MIN, BT_HCI_LE_MAX_TX_OCTETS_MAX)) {
		LOG_WRN("max_tx_octets exceeds the valid range %u", max_tx_octets);
	}
	if (!IN_RANGE(max_rx_octets, BT_HCI_LE_MAX_RX_OCTETS_MIN, BT_HCI_LE_MAX_RX_OCTETS_MAX)) {
		LOG_WRN("max_rx_octets exceeds the valid range %u", max_rx_octets);
	}
	if (!IN_RANGE(max_tx_time, BT_HCI_LE_MAX_TX_TIME_MIN, BT_HCI_LE_MAX_TX_TIME_MAX)) {
		LOG_WRN("max_tx_time exceeds the valid range %u", max_tx_time);
	}
	if (!IN_RANGE(max_rx_time, BT_HCI_LE_MAX_RX_TIME_MIN, BT_HCI_LE_MAX_RX_TIME_MAX)) {
		LOG_WRN("max_rx_time exceeds the valid range %u", max_rx_time);
	}

	LOG_DBG("max. tx: %u (%uus), max. rx: %u (%uus)", max_tx_octets, max_tx_time, max_rx_octets,
		max_rx_time);

	conn->le.data_len.tx_max_len = max_tx_octets;
	conn->le.data_len.tx_max_time = max_tx_time;
	conn->le.data_len.rx_max_len = max_rx_octets;
	conn->le.data_len.rx_max_time = max_rx_time;
	notify_le_data_len_updated(conn);
#endif

	bt_conn_unref(conn);
}
#endif /* CONFIG_BT_DATA_LEN_UPDATE */

#if defined(CONFIG_BT_PHY_UPDATE)
static void le_phy_update_complete(struct net_buf *buf)
{
	struct bt_hci_evt_le_phy_update_complete *evt = (void *)buf->data;
	uint16_t handle = sys_le16_to_cpu(evt->handle);
	struct bt_conn *conn;

	conn = bt_conn_lookup_handle(handle, BT_CONN_TYPE_LE);
	if (!conn) {
		LOG_ERR("Unable to lookup conn for handle %u", handle);
		return;
	}

	LOG_DBG("PHY updated: status: 0x%02x, tx: %u, rx: %u", evt->status, evt->tx_phy,
		evt->rx_phy);

#if defined(CONFIG_BT_USER_PHY_UPDATE)
	conn->le.phy.tx_phy = bt_get_phy(evt->tx_phy);
	conn->le.phy.rx_phy = bt_get_phy(evt->rx_phy);
	notify_le_phy_updated(conn);
#endif

	bt_conn_unref(conn);
}
#endif /* CONFIG_BT_PHY_UPDATE */

bool bt_le_conn_params_valid(const struct bt_le_conn_param *param)
{
	if (IS_ENABLED(CONFIG_BT_CONN_PARAM_ANY)) {
		return true;
	}

	/* All limits according to BT Core spec 5.0 [Vol 2, Part E, 7.8.12] */

	if (param->interval_min > param->interval_max ||
	    param->interval_min < 6 || param->interval_max > 3200) {
		return false;
	}

	if (param->latency > 499) {
		return false;
	}

	if (param->timeout < 10 || param->timeout > 3200 ||
	    ((param->timeout * 4U) <=
	     ((1U + param->latency) * param->interval_max))) {
		return false;
	}

	return true;
}

static void le_conn_param_neg_reply(uint16_t handle, uint8_t reason)
{
	struct bt_hci_cp_le_conn_param_req_neg_reply *cp;
	struct net_buf *buf;

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY,
				sizeof(*cp));
	if (!buf) {
		LOG_ERR("Unable to allocate buffer");
		return;
	}

	cp = net_buf_add(buf, sizeof(*cp));
	cp->handle = sys_cpu_to_le16(handle);
	cp->reason = sys_cpu_to_le16(reason);

	bt_hci_cmd_send(BT_HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY, buf);
}

static int le_conn_param_req_reply(uint16_t handle,
				   const struct bt_le_conn_param *param)
{
	struct bt_hci_cp_le_conn_param_req_reply *cp;
	struct net_buf *buf;

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_CONN_PARAM_REQ_REPLY, sizeof(*cp));
	if (!buf) {
		return -ENOBUFS;
	}

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

	cp->handle = sys_cpu_to_le16(handle);
	cp->interval_min = sys_cpu_to_le16(param->interval_min);
	cp->interval_max = sys_cpu_to_le16(param->interval_max);
	cp->latency = sys_cpu_to_le16(param->latency);
	cp->timeout = sys_cpu_to_le16(param->timeout);

	return bt_hci_cmd_send(BT_HCI_OP_LE_CONN_PARAM_REQ_REPLY, buf);
}

static void le_conn_param_req(struct net_buf *buf)
{
	struct bt_hci_evt_le_conn_param_req *evt = (void *)buf->data;
	struct bt_le_conn_param param;
	struct bt_conn *conn;
	uint16_t handle;

	handle = sys_le16_to_cpu(evt->handle);
	param.interval_min = sys_le16_to_cpu(evt->interval_min);
	param.interval_max = sys_le16_to_cpu(evt->interval_max);
	param.latency = sys_le16_to_cpu(evt->latency);
	param.timeout = sys_le16_to_cpu(evt->timeout);

	conn = bt_conn_lookup_handle(handle, BT_CONN_TYPE_LE);
	if (!conn) {
		LOG_ERR("Unable to lookup conn for handle %u", handle);
		le_conn_param_neg_reply(handle, BT_HCI_ERR_UNKNOWN_CONN_ID);
		return;
	}

	if (!le_param_req(conn, &param)) {
		le_conn_param_neg_reply(handle, BT_HCI_ERR_INVALID_LL_PARAM);
	} else {
		le_conn_param_req_reply(handle, &param);
	}

	bt_conn_unref(conn);
}

static void le_conn_update_complete(struct net_buf *buf)
{
	struct bt_hci_evt_le_conn_update_complete *evt = (void *)buf->data;
	struct bt_conn *conn;
	uint16_t handle;

	handle = sys_le16_to_cpu(evt->handle);

	LOG_DBG("status 0x%02x, handle %u", evt->status, handle);

	conn = bt_conn_lookup_handle(handle, BT_CONN_TYPE_LE);
	if (!conn) {
		LOG_ERR("Unable to lookup conn for handle %u", handle);
		return;
	}

	if (evt->status == BT_HCI_ERR_UNSUPP_REMOTE_FEATURE &&
	    conn->role == BT_HCI_ROLE_PERIPHERAL &&
	    !atomic_test_and_set_bit(conn->flags,
				     BT_CONN_PERIPHERAL_PARAM_L2CAP)) {
		/* CPR not supported, let's try L2CAP CPUP instead */
		struct bt_le_conn_param param;

		param.interval_min = conn->le.interval_min;
		param.interval_max = conn->le.interval_max;
		param.latency = conn->le.pending_latency;
		param.timeout = conn->le.pending_timeout;

		bt_l2cap_update_conn_param(conn, &param);
	} else {
		if (!evt->status) {
			conn->le.interval = sys_le16_to_cpu(evt->interval);
			conn->le.latency = sys_le16_to_cpu(evt->latency);
			conn->le.timeout = sys_le16_to_cpu(evt->supv_timeout);

#if defined(CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS)
			atomic_clear_bit(conn->flags,
					 BT_CONN_PERIPHERAL_PARAM_AUTO_UPDATE);
		} else if (atomic_test_bit(conn->flags,
					   BT_CONN_PERIPHERAL_PARAM_AUTO_UPDATE) &&
			   evt->status == BT_HCI_ERR_UNSUPP_LL_PARAM_VAL &&
			   conn->le.conn_param_retry_countdown) {
			conn->le.conn_param_retry_countdown--;
			k_work_schedule(&conn->deferred_work,
					K_MSEC(CONFIG_BT_CONN_PARAM_RETRY_TIMEOUT));
		} else {
			atomic_clear_bit(conn->flags,
					 BT_CONN_PERIPHERAL_PARAM_AUTO_UPDATE);
#endif /* CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS */

		}

		notify_le_param_updated(conn);
	}

	bt_conn_unref(conn);
}

#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
static int set_flow_control(void)
{
	struct bt_hci_cp_host_buffer_size *hbs;
	struct net_buf *buf;
	int err;

	/* Check if host flow control is actually supported */
	if (!BT_CMD_TEST(bt_dev.supported_commands, 10, 5)) {
		LOG_WRN("Controller to host flow control not supported");
		return 0;
	}

	buf = bt_hci_cmd_create(BT_HCI_OP_HOST_BUFFER_SIZE,
				sizeof(*hbs));
	if (!buf) {
		return -ENOBUFS;
	}

	hbs = net_buf_add(buf, sizeof(*hbs));
	(void)memset(hbs, 0, sizeof(*hbs));
	hbs->acl_mtu = sys_cpu_to_le16(CONFIG_BT_BUF_ACL_RX_SIZE);
	hbs->acl_pkts = sys_cpu_to_le16(CONFIG_BT_BUF_ACL_RX_COUNT);

	err = bt_hci_cmd_send_sync(BT_HCI_OP_HOST_BUFFER_SIZE, buf, NULL);
	if (err) {
		return err;
	}

	buf = bt_hci_cmd_create(BT_HCI_OP_SET_CTL_TO_HOST_FLOW, 1);
	if (!buf) {
		return -ENOBUFS;
	}

	net_buf_add_u8(buf, BT_HCI_CTL_TO_HOST_FLOW_ENABLE);
	return bt_hci_cmd_send_sync(BT_HCI_OP_SET_CTL_TO_HOST_FLOW, buf, NULL);
}
#endif /* CONFIG_BT_HCI_ACL_FLOW_CONTROL */

static void unpair(uint8_t id, const bt_addr_le_t *addr)
{
	struct bt_keys *keys = NULL;
	struct bt_conn *conn = bt_conn_lookup_addr_le(id, addr);

	if (conn) {
		/* Clear the conn->le.keys pointer since we'll invalidate it,
		 * and don't want any subsequent code (like disconnected
		 * callbacks) accessing it.
		 */
		if (conn->type == BT_CONN_TYPE_LE) {
			keys = conn->le.keys;
			conn->le.keys = NULL;
		}

		bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
		bt_conn_unref(conn);
	}

	if (IS_ENABLED(CONFIG_BT_CLASSIC)) {
		/* LE Public may indicate BR/EDR as well */
		if (addr->type == BT_ADDR_LE_PUBLIC) {
			bt_keys_link_key_clear_addr(&addr->a);
		}
	}

	if (IS_ENABLED(CONFIG_BT_SMP)) {
		if (!keys) {
			keys = bt_keys_find_addr(id, addr);
		}

		if (keys) {
			bt_keys_clear(keys);
		}
	}

	bt_gatt_clear(id, addr);

#if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_CLASSIC)
	struct bt_conn_auth_info_cb *listener, *next;

	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&bt_auth_info_cbs, listener,
					  next, node) {
		if (listener->bond_deleted) {
			listener->bond_deleted(id, addr);
		}
	}
#endif /* defined(CONFIG_BT_SMP) || defined(CONFIG_BT_CLASSIC) */
}

static void unpair_remote(const struct bt_bond_info *info, void *data)
{
	uint8_t *id = (uint8_t *) data;

	unpair(*id, &info->addr);
}

int bt_unpair(uint8_t id, const bt_addr_le_t *addr)
{
	if (id >= CONFIG_BT_ID_MAX) {
		return -EINVAL;
	}

	if (IS_ENABLED(CONFIG_BT_SMP)) {
		if (!addr || bt_addr_le_eq(addr, BT_ADDR_LE_ANY)) {
			bt_foreach_bond(id, unpair_remote, &id);
		} else {
			unpair(id, addr);
		}
	} else {
		CHECKIF(addr == NULL) {
			LOG_DBG("addr is NULL");
			return -EINVAL;
		}

		unpair(id, addr);
	}

	return 0;
}

#endif /* CONFIG_BT_CONN */

#if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_CLASSIC)
enum bt_security_err bt_security_err_get(uint8_t hci_err)
{
	switch (hci_err) {
	case BT_HCI_ERR_SUCCESS:
		return BT_SECURITY_ERR_SUCCESS;
	case BT_HCI_ERR_AUTH_FAIL:
		return BT_SECURITY_ERR_AUTH_FAIL;
	case BT_HCI_ERR_PIN_OR_KEY_MISSING:
		return BT_SECURITY_ERR_PIN_OR_KEY_MISSING;
	case BT_HCI_ERR_PAIRING_NOT_SUPPORTED:
		return BT_SECURITY_ERR_PAIR_NOT_SUPPORTED;
	case BT_HCI_ERR_PAIRING_NOT_ALLOWED:
		return BT_SECURITY_ERR_PAIR_NOT_ALLOWED;
	case BT_HCI_ERR_INVALID_PARAM:
		return BT_SECURITY_ERR_INVALID_PARAM;
	default:
		return BT_SECURITY_ERR_UNSPECIFIED;
	}
}
#endif /* defined(CONFIG_BT_SMP) || defined(CONFIG_BT_CLASSIC) */

#if defined(CONFIG_BT_SMP)
static bool update_sec_level(struct bt_conn *conn)
{
	if (conn->le.keys && (conn->le.keys->flags & BT_KEYS_AUTHENTICATED)) {
		if (conn->le.keys->flags & BT_KEYS_SC &&
		    conn->le.keys->enc_size == BT_SMP_MAX_ENC_KEY_SIZE) {
			conn->sec_level = BT_SECURITY_L4;
		} else {
			conn->sec_level = BT_SECURITY_L3;
		}
	} else {
		conn->sec_level = BT_SECURITY_L2;
	}

	return !(conn->required_sec_level > conn->sec_level);
}
#endif /* CONFIG_BT_SMP */

#if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_CLASSIC)
static void hci_encrypt_change(struct net_buf *buf)
{
	struct bt_hci_evt_encrypt_change *evt = (void *)buf->data;
	uint16_t handle = sys_le16_to_cpu(evt->handle);
	uint8_t status = evt->status;
	struct bt_conn *conn;

	LOG_DBG("status 0x%02x handle %u encrypt 0x%02x", evt->status, handle, evt->encrypt);

	conn = bt_conn_lookup_handle(handle, BT_CONN_TYPE_ALL);
	if (!conn) {
		LOG_ERR("Unable to look up conn with handle %u", handle);
		return;
	}

	if (status) {
		bt_conn_security_changed(conn, status,
					 bt_security_err_get(status));
		bt_conn_unref(conn);
		return;
	}

	conn->encrypt = evt->encrypt;

#if defined(CONFIG_BT_SMP)
	if (conn->type == BT_CONN_TYPE_LE) {
		/*
		 * we update keys properties only on successful encryption to
		 * avoid losing valid keys if encryption was not successful.
		 *
		 * Update keys with last pairing info for proper sec level
		 * update. This is done only for LE transport, for BR/EDR keys
		 * are updated on HCI 'Link Key Notification Event'
		 */
		if (conn->encrypt) {
			bt_smp_update_keys(conn);
		}

		if (!update_sec_level(conn)) {
			status = BT_HCI_ERR_AUTH_FAIL;
		}
	}
#endif /* CONFIG_BT_SMP */
#if defined(CONFIG_BT_CLASSIC)
	if (conn->type == BT_CONN_TYPE_BR) {
		if (!bt_br_update_sec_level(conn)) {
			bt_conn_unref(conn);
			return;
		}

		if (IS_ENABLED(CONFIG_BT_SMP)) {
			/*
			 * Start SMP over BR/EDR if we are pairing and are
			 * central on the link
			 */
			if (atomic_test_bit(conn->flags, BT_CONN_BR_PAIRING) &&
			    conn->role == BT_CONN_ROLE_CENTRAL) {
				bt_smp_br_send_pairing_req(conn);
			}
		}
	}
#endif /* CONFIG_BT_CLASSIC */

	bt_conn_security_changed(conn, status, bt_security_err_get(status));

	if (status) {
		LOG_ERR("Failed to set required security level");
		bt_conn_disconnect(conn, status);
	}

	bt_conn_unref(conn);
}

static void hci_encrypt_key_refresh_complete(struct net_buf *buf)
{
	struct bt_hci_evt_encrypt_key_refresh_complete *evt = (void *)buf->data;
	uint8_t status = evt->status;
	struct bt_conn *conn;
	uint16_t handle;

	handle = sys_le16_to_cpu(evt->handle);

	LOG_DBG("status 0x%02x handle %u", evt->status, handle);

	conn = bt_conn_lookup_handle(handle, BT_CONN_TYPE_ALL);
	if (!conn) {
		LOG_ERR("Unable to look up conn with handle %u", handle);
		return;
	}

	if (status) {
		bt_conn_security_changed(conn, status,
					 bt_security_err_get(status));
		bt_conn_unref(conn);
		return;
	}

	/*
	 * Update keys with last pairing info for proper sec level update.
	 * This is done only for LE transport. For BR/EDR transport keys are
	 * updated on HCI 'Link Key Notification Event', therefore update here
	 * only security level based on available keys and encryption state.
	 */
#if defined(CONFIG_BT_SMP)
	if (conn->type == BT_CONN_TYPE_LE) {
		bt_smp_update_keys(conn);

		if (!update_sec_level(conn)) {
			status = BT_HCI_ERR_AUTH_FAIL;
		}
	}
#endif /* CONFIG_BT_SMP */
#if defined(CONFIG_BT_CLASSIC)
	if (conn->type == BT_CONN_TYPE_BR) {
		if (!bt_br_update_sec_level(conn)) {
			bt_conn_unref(conn);
			return;
		}
	}
#endif /* CONFIG_BT_CLASSIC */

	bt_conn_security_changed(conn, status, bt_security_err_get(status));
	if (status) {
		LOG_ERR("Failed to set required security level");
		bt_conn_disconnect(conn, status);
	}

	bt_conn_unref(conn);
}
#endif /* CONFIG_BT_SMP || CONFIG_BT_CLASSIC */

#if defined(CONFIG_BT_REMOTE_VERSION)
static void bt_hci_evt_read_remote_version_complete(struct net_buf *buf)
{
	struct bt_hci_evt_remote_version_info *evt;
	struct bt_conn *conn;
	uint16_t handle;

	evt = net_buf_pull_mem(buf, sizeof(*evt));
	handle = sys_le16_to_cpu(evt->handle);
	conn = bt_conn_lookup_handle(handle, BT_CONN_TYPE_ALL);
	if (!conn) {
		LOG_ERR("No connection for handle %u", handle);
		return;
	}

	if (!evt->status) {
		conn->rv.version = evt->version;
		conn->rv.manufacturer = sys_le16_to_cpu(evt->manufacturer);
		conn->rv.subversion = sys_le16_to_cpu(evt->subversion);
	}

	atomic_set_bit(conn->flags, BT_CONN_AUTO_VERSION_INFO);

	if (IS_ENABLED(CONFIG_BT_REMOTE_INFO)) {
		/* Remote features is already present */
		notify_remote_info(conn);
	}

	bt_conn_unref(conn);
}
#endif /* CONFIG_BT_REMOTE_VERSION */

static void hci_hardware_error(struct net_buf *buf)
{
	struct bt_hci_evt_hardware_error *evt;

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

	LOG_ERR("Hardware error, hardware code: %d", evt->hardware_code);
}

#if defined(CONFIG_BT_SMP)
static void le_ltk_neg_reply(uint16_t handle)
{
	struct bt_hci_cp_le_ltk_req_neg_reply *cp;
	struct net_buf *buf;

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_LTK_REQ_NEG_REPLY, sizeof(*cp));
	if (!buf) {
		LOG_ERR("Out of command buffers");

		return;
	}

	cp = net_buf_add(buf, sizeof(*cp));
	cp->handle = sys_cpu_to_le16(handle);

	bt_hci_cmd_send(BT_HCI_OP_LE_LTK_REQ_NEG_REPLY, buf);
}

static void le_ltk_reply(uint16_t handle, uint8_t *ltk)
{
	struct bt_hci_cp_le_ltk_req_reply *cp;
	struct net_buf *buf;

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_LTK_REQ_REPLY,
				sizeof(*cp));
	if (!buf) {
		LOG_ERR("Out of command buffers");
		return;
	}

	cp = net_buf_add(buf, sizeof(*cp));
	cp->handle = sys_cpu_to_le16(handle);
	memcpy(cp->ltk, ltk, sizeof(cp->ltk));

	bt_hci_cmd_send(BT_HCI_OP_LE_LTK_REQ_REPLY, buf);
}

static void le_ltk_request(struct net_buf *buf)
{
	struct bt_hci_evt_le_ltk_request *evt = (void *)buf->data;
	struct bt_conn *conn;
	uint16_t handle;
	uint8_t ltk[16];

	handle = sys_le16_to_cpu(evt->handle);

	LOG_DBG("handle %u", handle);

	conn = bt_conn_lookup_handle(handle, BT_CONN_TYPE_LE);
	if (!conn) {
		LOG_ERR("Unable to lookup conn for handle %u", handle);
		return;
	}

	if (bt_smp_request_ltk(conn, evt->rand, evt->ediv, ltk)) {
		le_ltk_reply(handle, ltk);
	} else {
		le_ltk_neg_reply(handle);
	}

	bt_conn_unref(conn);
}
#endif /* CONFIG_BT_SMP */

static void hci_reset_complete(struct net_buf *buf)
{
	uint8_t status = buf->data[0];
	atomic_t flags;

	LOG_DBG("status 0x%02x", status);

	if (status) {
		return;
	}

	if (IS_ENABLED(CONFIG_BT_OBSERVER)) {
		bt_scan_reset();
	}

#if defined(CONFIG_BT_CLASSIC)
	bt_br_discovery_reset();
#endif /* CONFIG_BT_CLASSIC */

	flags = (atomic_get(bt_dev.flags) & BT_DEV_PERSISTENT_FLAGS);
	atomic_set(bt_dev.flags, flags);
}

static void hci_cmd_done(uint16_t opcode, uint8_t status, struct net_buf *evt_buf)
{
	/* Original command buffer. */
	struct net_buf *buf = NULL;

	LOG_DBG("opcode 0x%04x status 0x%02x buf %p", opcode, status, evt_buf);

	/* Unsolicited cmd complete. This does not complete a command.
	 * The controller can send these for effect of the `ncmd` field.
	 */
	if (opcode == 0) {
		goto exit;
	}

	/* Take the original command buffer reference. */
	buf = atomic_ptr_clear((atomic_ptr_t *)&bt_dev.sent_cmd);

	if (!buf) {
		LOG_ERR("No command sent for cmd complete 0x%04x", opcode);
		goto exit;
	}

	if (cmd(buf)->opcode != opcode) {
		LOG_ERR("OpCode 0x%04x completed instead of expected 0x%04x", opcode,
			cmd(buf)->opcode);
		buf = atomic_ptr_set((atomic_ptr_t *)&bt_dev.sent_cmd, buf);
		__ASSERT_NO_MSG(!buf);
		goto exit;
	}

	/* Response data is to be delivered in the original command
	 * buffer.
	 */
	if (evt_buf != buf) {
		net_buf_reset(buf);
		bt_buf_set_type(buf, BT_BUF_EVT);
		net_buf_reserve(buf, BT_BUF_RESERVE);
		net_buf_add_mem(buf, evt_buf->data, evt_buf->len);
	}

	if (cmd(buf)->state && !status) {
		struct bt_hci_cmd_state_set *update = cmd(buf)->state;

		atomic_set_bit_to(update->target, update->bit, update->val);
	}

	/* If the command was synchronous wake up bt_hci_cmd_send_sync() */
	if (cmd(buf)->sync) {
		cmd(buf)->status = status;
		k_sem_give(cmd(buf)->sync);
	}

exit:
	if (buf) {
		net_buf_unref(buf);
	}
}

static void hci_cmd_complete(struct net_buf *buf)
{
	struct bt_hci_evt_cmd_complete *evt;
	uint8_t status, ncmd;
	uint16_t opcode;

	evt = net_buf_pull_mem(buf, sizeof(*evt));
	ncmd = evt->ncmd;
	opcode = sys_le16_to_cpu(evt->opcode);

	LOG_DBG("opcode 0x%04x", opcode);

	/* All command return parameters have a 1-byte status in the
	 * beginning, so we can safely make this generalization.
	 */
	status = buf->data[0];

	/* HOST_NUM_COMPLETED_PACKETS should not generate a response under normal operation.
	 * The generation of this command ignores `ncmd_sem`, so should not be given here.
	 */
	if (opcode == BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS) {
		LOG_WRN("Unexpected HOST_NUM_COMPLETED_PACKETS (status 0x%02x)", status);
		return;
	}

	hci_cmd_done(opcode, status, buf);

	/* Allow next command to be sent */
	if (ncmd) {
		k_sem_give(&bt_dev.ncmd_sem);
	}
}

static void hci_cmd_status(struct net_buf *buf)
{
	struct bt_hci_evt_cmd_status *evt;
	uint16_t opcode;
	uint8_t ncmd;

	evt = net_buf_pull_mem(buf, sizeof(*evt));
	opcode = sys_le16_to_cpu(evt->opcode);
	ncmd = evt->ncmd;

	LOG_DBG("opcode 0x%04x", opcode);

	hci_cmd_done(opcode, evt->status, buf);

	/* Allow next command to be sent */
	if (ncmd) {
		k_sem_give(&bt_dev.ncmd_sem);
	}
}

int bt_hci_get_conn_handle(const struct bt_conn *conn, uint16_t *conn_handle)
{
	if (conn->state != BT_CONN_CONNECTED) {
		return -ENOTCONN;
	}

	*conn_handle = conn->handle;
	return 0;
}

#if defined(CONFIG_BT_EXT_ADV)
int bt_hci_get_adv_handle(const struct bt_le_ext_adv *adv, uint8_t *adv_handle)
{
	if (!atomic_test_bit(adv->flags, BT_ADV_CREATED)) {
		return -EINVAL;
	}

	*adv_handle = adv->handle;
	return 0;
}
#endif /* CONFIG_BT_EXT_ADV */

#if defined(CONFIG_BT_HCI_VS_EVT_USER)
int bt_hci_register_vnd_evt_cb(bt_hci_vnd_evt_cb_t cb)
{
	hci_vnd_evt_cb = cb;
	return 0;
}
#endif /* CONFIG_BT_HCI_VS_EVT_USER */

#if defined(CONFIG_BT_TRANSMIT_POWER_CONTROL)
void bt_hci_le_transmit_power_report(struct net_buf *buf)
{
	struct bt_hci_evt_le_transmit_power_report *evt;
	struct bt_conn_le_tx_power_report report;
	struct bt_conn *conn;

	evt = net_buf_pull_mem(buf, sizeof(*evt));
	conn = bt_conn_lookup_handle(sys_le16_to_cpu(evt->handle), BT_CONN_TYPE_LE);
	if (!conn) {
		LOG_ERR("Unknown conn handle 0x%04X for transmit power report",
		       sys_le16_to_cpu(evt->handle));
		return;
	}

	report.reason = evt->reason;
	report.phy = evt->phy;
	report.tx_power_level = evt->tx_power_level;
	report.tx_power_level_flag = evt->tx_power_level_flag;
	report.delta = evt->delta;

	notify_tx_power_report(conn, report);

	bt_conn_unref(conn);
}
#endif /* CONFIG_BT_TRANSMIT_POWER_CONTROL */

static const struct event_handler vs_events[] = {
#if defined(CONFIG_BT_DF_VS_CL_IQ_REPORT_16_BITS_IQ_SAMPLES)
	EVENT_HANDLER(BT_HCI_EVT_VS_LE_CONNECTIONLESS_IQ_REPORT,
		      bt_hci_le_vs_df_connectionless_iq_report,
		      sizeof(struct bt_hci_evt_vs_le_connectionless_iq_report)),
#endif /* CONFIG_BT_DF_VS_CL_IQ_REPORT_16_BITS_IQ_SAMPLES */
#if defined(CONFIG_BT_DF_VS_CONN_IQ_REPORT_16_BITS_IQ_SAMPLES)
	EVENT_HANDLER(BT_HCI_EVT_VS_LE_CONNECTION_IQ_REPORT, bt_hci_le_vs_df_connection_iq_report,
		      sizeof(struct bt_hci_evt_vs_le_connection_iq_report)),
#endif /* CONFIG_BT_DF_VS_CONN_IQ_REPORT_16_BITS_IQ_SAMPLES */
};

static void hci_vendor_event(struct net_buf *buf)
{
	bool handled = false;

#if defined(CONFIG_BT_HCI_VS_EVT_USER)
	if (hci_vnd_evt_cb) {
		struct net_buf_simple_state state;

		net_buf_simple_save(&buf->b, &state);

		handled = hci_vnd_evt_cb(&buf->b);

		net_buf_simple_restore(&buf->b, &state);
	}
#endif /* CONFIG_BT_HCI_VS_EVT_USER */

	if (IS_ENABLED(CONFIG_BT_HCI_VS_EVT) && !handled) {
		struct bt_hci_evt_vs *evt;

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

		LOG_DBG("subevent 0x%02x", evt->subevent);

		handle_vs_event(evt->subevent, buf, vs_events, ARRAY_SIZE(vs_events));
	}
}

static const struct event_handler meta_events[] = {
#if defined(CONFIG_BT_OBSERVER)
	EVENT_HANDLER(BT_HCI_EVT_LE_ADVERTISING_REPORT, bt_hci_le_adv_report,
		      sizeof(struct bt_hci_evt_le_advertising_report)),
#endif /* CONFIG_BT_OBSERVER */
#if defined(CONFIG_BT_CONN)
	EVENT_HANDLER(BT_HCI_EVT_LE_CONN_COMPLETE, le_legacy_conn_complete,
		      sizeof(struct bt_hci_evt_le_conn_complete)),
	EVENT_HANDLER(BT_HCI_EVT_LE_ENH_CONN_COMPLETE, le_enh_conn_complete,
		      sizeof(struct bt_hci_evt_le_enh_conn_complete)),
	EVENT_HANDLER(BT_HCI_EVT_LE_CONN_UPDATE_COMPLETE,
		      le_conn_update_complete,
		      sizeof(struct bt_hci_evt_le_conn_update_complete)),
	EVENT_HANDLER(BT_HCI_EVT_LE_REMOTE_FEAT_COMPLETE,
		      le_remote_feat_complete,
		      sizeof(struct bt_hci_evt_le_remote_feat_complete)),
	EVENT_HANDLER(BT_HCI_EVT_LE_CONN_PARAM_REQ, le_conn_param_req,
		      sizeof(struct bt_hci_evt_le_conn_param_req)),
#if defined(CONFIG_BT_DATA_LEN_UPDATE)
	EVENT_HANDLER(BT_HCI_EVT_LE_DATA_LEN_CHANGE, le_data_len_change,
		      sizeof(struct bt_hci_evt_le_data_len_change)),
#endif /* CONFIG_BT_DATA_LEN_UPDATE */
#if defined(CONFIG_BT_PHY_UPDATE)
	EVENT_HANDLER(BT_HCI_EVT_LE_PHY_UPDATE_COMPLETE,
		      le_phy_update_complete,
		      sizeof(struct bt_hci_evt_le_phy_update_complete)),
#endif /* CONFIG_BT_PHY_UPDATE */
#endif /* CONFIG_BT_CONN */
#if defined(CONFIG_BT_SMP)
	EVENT_HANDLER(BT_HCI_EVT_LE_LTK_REQUEST, le_ltk_request,
		      sizeof(struct bt_hci_evt_le_ltk_request)),
#endif /* CONFIG_BT_SMP */
#if defined(CONFIG_BT_ECC)
	EVENT_HANDLER(BT_HCI_EVT_LE_P256_PUBLIC_KEY_COMPLETE,
		      bt_hci_evt_le_pkey_complete,
		      sizeof(struct bt_hci_evt_le_p256_public_key_complete)),
	EVENT_HANDLER(BT_HCI_EVT_LE_GENERATE_DHKEY_COMPLETE,
		      bt_hci_evt_le_dhkey_complete,
		      sizeof(struct bt_hci_evt_le_generate_dhkey_complete)),
#endif /* CONFIG_BT_SMP */
#if defined(CONFIG_BT_EXT_ADV)
#if defined(CONFIG_BT_BROADCASTER)
	EVENT_HANDLER(BT_HCI_EVT_LE_ADV_SET_TERMINATED, bt_hci_le_adv_set_terminated,
		      sizeof(struct bt_hci_evt_le_adv_set_terminated)),
	EVENT_HANDLER(BT_HCI_EVT_LE_SCAN_REQ_RECEIVED, bt_hci_le_scan_req_received,
		      sizeof(struct bt_hci_evt_le_scan_req_received)),
#endif
#if defined(CONFIG_BT_OBSERVER)
	EVENT_HANDLER(BT_HCI_EVT_LE_SCAN_TIMEOUT, bt_hci_le_scan_timeout,
		      0),
	EVENT_HANDLER(BT_HCI_EVT_LE_EXT_ADVERTISING_REPORT, bt_hci_le_adv_ext_report,
		      sizeof(struct bt_hci_evt_le_ext_advertising_report)),
#endif /* defined(CONFIG_BT_OBSERVER) */
#if defined(CONFIG_BT_PER_ADV_SYNC)
	EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADV_SYNC_ESTABLISHED,
		      bt_hci_le_per_adv_sync_established,
		      sizeof(struct bt_hci_evt_le_per_adv_sync_established)),
	EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADVERTISING_REPORT, bt_hci_le_per_adv_report,
		      sizeof(struct bt_hci_evt_le_per_advertising_report)),
	EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADV_SYNC_LOST, bt_hci_le_per_adv_sync_lost,
		      sizeof(struct bt_hci_evt_le_per_adv_sync_lost)),
#if defined(CONFIG_BT_CONN)
	EVENT_HANDLER(BT_HCI_EVT_LE_PAST_RECEIVED, bt_hci_le_past_received,
		      sizeof(struct bt_hci_evt_le_past_received)),
#endif /* CONFIG_BT_CONN */
#endif /* defined(CONFIG_BT_PER_ADV_SYNC) */
#endif /* defined(CONFIG_BT_EXT_ADV) */
#if defined(CONFIG_BT_ISO_UNICAST)
	EVENT_HANDLER(BT_HCI_EVT_LE_CIS_ESTABLISHED, hci_le_cis_established,
		      sizeof(struct bt_hci_evt_le_cis_established)),
#if defined(CONFIG_BT_ISO_PERIPHERAL)
	EVENT_HANDLER(BT_HCI_EVT_LE_CIS_REQ, hci_le_cis_req,
		      sizeof(struct bt_hci_evt_le_cis_req)),
#endif /* (CONFIG_BT_ISO_PERIPHERAL) */
#endif /* (CONFIG_BT_ISO_UNICAST) */
#if defined(CONFIG_BT_ISO_BROADCASTER)
	EVENT_HANDLER(BT_HCI_EVT_LE_BIG_COMPLETE,
		      hci_le_big_complete,
		      sizeof(struct bt_hci_evt_le_big_complete)),
	EVENT_HANDLER(BT_HCI_EVT_LE_BIG_TERMINATE,
		      hci_le_big_terminate,
		      sizeof(struct bt_hci_evt_le_big_terminate)),
#endif /* CONFIG_BT_ISO_BROADCASTER */
#if defined(CONFIG_BT_ISO_SYNC_RECEIVER)
	EVENT_HANDLER(BT_HCI_EVT_LE_BIG_SYNC_ESTABLISHED,
		      hci_le_big_sync_established,
		      sizeof(struct bt_hci_evt_le_big_sync_established)),
	EVENT_HANDLER(BT_HCI_EVT_LE_BIG_SYNC_LOST,
		      hci_le_big_sync_lost,
		      sizeof(struct bt_hci_evt_le_big_sync_lost)),
	EVENT_HANDLER(BT_HCI_EVT_LE_BIGINFO_ADV_REPORT,
		      bt_hci_le_biginfo_adv_report,
		      sizeof(struct bt_hci_evt_le_biginfo_adv_report)),
#endif /* CONFIG_BT_ISO_SYNC_RECEIVER */
#if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX)
	EVENT_HANDLER(BT_HCI_EVT_LE_CONNECTIONLESS_IQ_REPORT, bt_hci_le_df_connectionless_iq_report,
		      sizeof(struct bt_hci_evt_le_connectionless_iq_report)),
#endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX */
#if defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
	EVENT_HANDLER(BT_HCI_EVT_LE_CONNECTION_IQ_REPORT, bt_hci_le_df_connection_iq_report,
		      sizeof(struct bt_hci_evt_le_connection_iq_report)),
#endif /* CONFIG_BT_DF_CONNECTION_CTE_RX */
#if defined(CONFIG_BT_DF_CONNECTION_CTE_REQ)
	EVENT_HANDLER(BT_HCI_EVT_LE_CTE_REQUEST_FAILED, bt_hci_le_df_cte_req_failed,
		      sizeof(struct bt_hci_evt_le_cte_req_failed)),
#endif /* CONFIG_BT_DF_CONNECTION_CTE_REQ */
#if defined(CONFIG_BT_TRANSMIT_POWER_CONTROL)
	EVENT_HANDLER(BT_HCI_EVT_LE_TRANSMIT_POWER_REPORT, bt_hci_le_transmit_power_report,
		      sizeof(struct bt_hci_evt_le_transmit_power_report)),
#endif /* CONFIG_BT_TRANSMIT_POWER_CONTROL */
#if defined(CONFIG_BT_PER_ADV_SYNC_RSP)
	EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADVERTISING_REPORT_V2, bt_hci_le_per_adv_report_v2,
		      sizeof(struct bt_hci_evt_le_per_advertising_report_v2)),
	EVENT_HANDLER(BT_HCI_EVT_LE_PAST_RECEIVED_V2, bt_hci_le_past_received_v2,
		      sizeof(struct bt_hci_evt_le_past_received_v2)),
	EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADV_SYNC_ESTABLISHED_V2,
		      bt_hci_le_per_adv_sync_established_v2,
		      sizeof(struct bt_hci_evt_le_per_adv_sync_established_v2)),
#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */
#if defined(CONFIG_BT_PER_ADV_RSP)
	EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADV_SUBEVENT_DATA_REQUEST,
		      bt_hci_le_per_adv_subevent_data_request,
		      sizeof(struct bt_hci_evt_le_per_adv_subevent_data_request)),
	EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADV_RESPONSE_REPORT, bt_hci_le_per_adv_response_report,
		      sizeof(struct bt_hci_evt_le_per_adv_response_report)),
#endif /* CONFIG_BT_PER_ADV_RSP */
#if defined(CONFIG_BT_CONN)
#if defined(CONFIG_BT_PER_ADV_RSP) || defined(CONFIG_BT_PER_ADV_SYNC_RSP)
	EVENT_HANDLER(BT_HCI_EVT_LE_ENH_CONN_COMPLETE_V2, le_enh_conn_complete_v2,
		      sizeof(struct bt_hci_evt_le_enh_conn_complete_v2)),
#endif /* CONFIG_BT_PER_ADV_RSP || CONFIG_BT_PER_ADV_SYNC_RSP */
#endif /* CONFIG_BT_CONN */

};

static void hci_le_meta_event(struct net_buf *buf)
{
	struct bt_hci_evt_le_meta_event *evt;

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

	LOG_DBG("subevent 0x%02x", evt->subevent);

	handle_event(evt->subevent, buf, meta_events, ARRAY_SIZE(meta_events));
}

static const struct event_handler normal_events[] = {
	EVENT_HANDLER(BT_HCI_EVT_VENDOR, hci_vendor_event,
		      sizeof(struct bt_hci_evt_vs)),
	EVENT_HANDLER(BT_HCI_EVT_LE_META_EVENT, hci_le_meta_event,
		      sizeof(struct bt_hci_evt_le_meta_event)),
#if defined(CONFIG_BT_CLASSIC)
	EVENT_HANDLER(BT_HCI_EVT_CONN_REQUEST, bt_hci_conn_req,
		      sizeof(struct bt_hci_evt_conn_request)),
	EVENT_HANDLER(BT_HCI_EVT_CONN_COMPLETE, bt_hci_conn_complete,
		      sizeof(struct bt_hci_evt_conn_complete)),
	EVENT_HANDLER(BT_HCI_EVT_PIN_CODE_REQ, bt_hci_pin_code_req,
		      sizeof(struct bt_hci_evt_pin_code_req)),
	EVENT_HANDLER(BT_HCI_EVT_LINK_KEY_NOTIFY, bt_hci_link_key_notify,
		      sizeof(struct bt_hci_evt_link_key_notify)),
	EVENT_HANDLER(BT_HCI_EVT_LINK_KEY_REQ, bt_hci_link_key_req,
		      sizeof(struct bt_hci_evt_link_key_req)),
	EVENT_HANDLER(BT_HCI_EVT_IO_CAPA_RESP, bt_hci_io_capa_resp,
		      sizeof(struct bt_hci_evt_io_capa_resp)),
	EVENT_HANDLER(BT_HCI_EVT_IO_CAPA_REQ, bt_hci_io_capa_req,
		      sizeof(struct bt_hci_evt_io_capa_req)),
	EVENT_HANDLER(BT_HCI_EVT_SSP_COMPLETE, bt_hci_ssp_complete,
		      sizeof(struct bt_hci_evt_ssp_complete)),
	EVENT_HANDLER(BT_HCI_EVT_USER_CONFIRM_REQ, bt_hci_user_confirm_req,
		      sizeof(struct bt_hci_evt_user_confirm_req)),
	EVENT_HANDLER(BT_HCI_EVT_USER_PASSKEY_NOTIFY,
		      bt_hci_user_passkey_notify,
		      sizeof(struct bt_hci_evt_user_passkey_notify)),
	EVENT_HANDLER(BT_HCI_EVT_USER_PASSKEY_REQ, bt_hci_user_passkey_req,
		      sizeof(struct bt_hci_evt_user_passkey_req)),
	EVENT_HANDLER(BT_HCI_EVT_INQUIRY_COMPLETE, bt_hci_inquiry_complete,
		      sizeof(struct bt_hci_evt_inquiry_complete)),
	EVENT_HANDLER(BT_HCI_EVT_INQUIRY_RESULT_WITH_RSSI,
		      bt_hci_inquiry_result_with_rssi,
		      sizeof(struct bt_hci_evt_inquiry_result_with_rssi)),
	EVENT_HANDLER(BT_HCI_EVT_EXTENDED_INQUIRY_RESULT,
		      bt_hci_extended_inquiry_result,
		      sizeof(struct bt_hci_evt_extended_inquiry_result)),
	EVENT_HANDLER(BT_HCI_EVT_REMOTE_NAME_REQ_COMPLETE,
		      bt_hci_remote_name_request_complete,
		      sizeof(struct bt_hci_evt_remote_name_req_complete)),
	EVENT_HANDLER(BT_HCI_EVT_AUTH_COMPLETE, bt_hci_auth_complete,
		      sizeof(struct bt_hci_evt_auth_complete)),
	EVENT_HANDLER(BT_HCI_EVT_REMOTE_FEATURES,
		      bt_hci_read_remote_features_complete,
		      sizeof(struct bt_hci_evt_remote_features)),
	EVENT_HANDLER(BT_HCI_EVT_REMOTE_EXT_FEATURES,
		      bt_hci_read_remote_ext_features_complete,
		      sizeof(struct bt_hci_evt_remote_ext_features)),
	EVENT_HANDLER(BT_HCI_EVT_ROLE_CHANGE, bt_hci_role_change,
		      sizeof(struct bt_hci_evt_role_change)),
	EVENT_HANDLER(BT_HCI_EVT_SYNC_CONN_COMPLETE, bt_hci_synchronous_conn_complete,
		      sizeof(struct bt_hci_evt_sync_conn_complete)),
#endif /* CONFIG_BT_CLASSIC */
#if defined(CONFIG_BT_CONN)
	EVENT_HANDLER(BT_HCI_EVT_DISCONN_COMPLETE, hci_disconn_complete,
		      sizeof(struct bt_hci_evt_disconn_complete)),
#endif /* CONFIG_BT_CONN */
#if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_CLASSIC)
	EVENT_HANDLER(BT_HCI_EVT_ENCRYPT_CHANGE, hci_encrypt_change,
		      sizeof(struct bt_hci_evt_encrypt_change)),
	EVENT_HANDLER(BT_HCI_EVT_ENCRYPT_KEY_REFRESH_COMPLETE,
		      hci_encrypt_key_refresh_complete,
		      sizeof(struct bt_hci_evt_encrypt_key_refresh_complete)),
#endif /* CONFIG_BT_SMP || CONFIG_BT_CLASSIC */
#if defined(CONFIG_BT_REMOTE_VERSION)
	EVENT_HANDLER(BT_HCI_EVT_REMOTE_VERSION_INFO,
		      bt_hci_evt_read_remote_version_complete,
		      sizeof(struct bt_hci_evt_remote_version_info)),
#endif /* CONFIG_BT_REMOTE_VERSION */
	EVENT_HANDLER(BT_HCI_EVT_HARDWARE_ERROR, hci_hardware_error,
		      sizeof(struct bt_hci_evt_hardware_error)),
};


#define BT_HCI_EVT_FLAG_RECV_PRIO BIT(0)
#define BT_HCI_EVT_FLAG_RECV      BIT(1)

/** @brief Get HCI event flags.
 *
 * Helper for the HCI driver to get HCI event flags that describes rules that.
 * must be followed.
 *
 * @param evt HCI event code.
 *
 * @return HCI event flags for the specified event.
 */
static inline uint8_t bt_hci_evt_get_flags(uint8_t evt)
{
	switch (evt) {
	case BT_HCI_EVT_DISCONN_COMPLETE:
		return BT_HCI_EVT_FLAG_RECV | BT_HCI_EVT_FLAG_RECV_PRIO;
		/* fallthrough */
#if defined(CONFIG_BT_CONN) || defined(CONFIG_BT_ISO)
	case BT_HCI_EVT_NUM_COMPLETED_PACKETS:
#if defined(CONFIG_BT_CONN)
	case BT_HCI_EVT_DATA_BUF_OVERFLOW:
		__fallthrough;
#endif /* defined(CONFIG_BT_CONN) */
#endif /* CONFIG_BT_CONN ||  CONFIG_BT_ISO */
	case BT_HCI_EVT_CMD_COMPLETE:
	case BT_HCI_EVT_CMD_STATUS:
		return BT_HCI_EVT_FLAG_RECV_PRIO;
	default:
		return BT_HCI_EVT_FLAG_RECV;
	}
}

static void hci_event(struct net_buf *buf)
{
	struct bt_hci_evt_hdr *hdr;

	if (buf->len < sizeof(*hdr)) {
		LOG_ERR("Invalid HCI event size (%u)", buf->len);
		net_buf_unref(buf);
		return;
	}

	hdr = net_buf_pull_mem(buf, sizeof(*hdr));
	LOG_DBG("event 0x%02x", hdr->evt);
	BT_ASSERT(bt_hci_evt_get_flags(hdr->evt) & BT_HCI_EVT_FLAG_RECV);

	handle_event(hdr->evt, buf, normal_events, ARRAY_SIZE(normal_events));

	net_buf_unref(buf);
}

static void send_cmd(void)
{
	struct net_buf *buf;
	int err;

	/* Get next command */
	LOG_DBG("calling net_buf_get");
	buf = net_buf_get(&bt_dev.cmd_tx_queue, K_NO_WAIT);
	BT_ASSERT(buf);

	/* Wait until ncmd > 0 */
	LOG_DBG("calling sem_take_wait");
	k_sem_take(&bt_dev.ncmd_sem, K_FOREVER);

	/* Clear out any existing sent command */
	if (bt_dev.sent_cmd) {
		LOG_ERR("Uncleared pending sent_cmd");
		net_buf_unref(bt_dev.sent_cmd);
		bt_dev.sent_cmd = NULL;
	}

	bt_dev.sent_cmd = net_buf_ref(buf);

	LOG_DBG("Sending command 0x%04x (buf %p) to driver", cmd(buf)->opcode, buf);

	err = bt_send(buf);
	if (err) {
		LOG_ERR("Unable to send to driver (err %d)", err);
		k_sem_give(&bt_dev.ncmd_sem);
		hci_cmd_done(cmd(buf)->opcode, BT_HCI_ERR_UNSPECIFIED, buf);
		net_buf_unref(buf);
	}
}

static void process_events(struct k_poll_event *ev, int count)
{
	LOG_DBG("count %d", count);

	for (; count; ev++, count--) {
		LOG_DBG("ev->state %u", ev->state);

		switch (ev->state) {
		case K_POLL_STATE_SIGNALED:
			break;
		case K_POLL_STATE_SEM_AVAILABLE:
			/* After this fn is exec'd, `bt_conn_prepare_events()`
			 * will be called once again, and this time buffers will
			 * be available, so the FIFO will be added to the poll
			 * list instead of the ctlr buffers semaphore.
			 */
			break;
		case K_POLL_STATE_FIFO_DATA_AVAILABLE:
			if (ev->tag == BT_EVENT_CMD_TX) {
				send_cmd();
			} else if (IS_ENABLED(CONFIG_BT_CONN) ||
				   IS_ENABLED(CONFIG_BT_ISO)) {
				struct bt_conn *conn;

				if (ev->tag == BT_EVENT_CONN_TX_QUEUE) {
					conn = CONTAINER_OF(ev->fifo,
							    struct bt_conn,
							    tx_queue);
					bt_conn_process_tx(conn);
				}
			}
			break;
		case K_POLL_STATE_NOT_READY:
			break;
		default:
			LOG_WRN("Unexpected k_poll event state %u", ev->state);
			break;
		}
	}
}

#if defined(CONFIG_BT_CONN)
#if defined(CONFIG_BT_ISO)
/* command FIFO + conn_change signal + MAX_CONN + ISO_MAX_CHAN */
#define EV_COUNT (2 + CONFIG_BT_MAX_CONN + CONFIG_BT_ISO_MAX_CHAN)
#else
/* command FIFO + conn_change signal + MAX_CONN */
#define EV_COUNT (2 + CONFIG_BT_MAX_CONN)
#endif /* CONFIG_BT_ISO */
#else
#if defined(CONFIG_BT_ISO)
/* command FIFO + conn_change signal + ISO_MAX_CHAN */
#define EV_COUNT (2 + CONFIG_BT_ISO_MAX_CHAN)
#else
/* command FIFO */
#define EV_COUNT 1
#endif /* CONFIG_BT_ISO */
#endif /* CONFIG_BT_CONN */

static void hci_tx_thread(void *p1, void *p2, void *p3)
{
	static struct k_poll_event events[EV_COUNT] = {
		K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE,
						K_POLL_MODE_NOTIFY_ONLY,
						&bt_dev.cmd_tx_queue,
						BT_EVENT_CMD_TX),
	};

	LOG_DBG("Started");

	while (1) {
		int ev_count, err;

		events[0].state = K_POLL_STATE_NOT_READY;
		ev_count = 1;

		/* This adds the FIFO per-connection */
		if (IS_ENABLED(CONFIG_BT_CONN) || IS_ENABLED(CONFIG_BT_ISO)) {
			ev_count += bt_conn_prepare_events(&events[1]);
		}

		LOG_DBG("Calling k_poll with %d events", ev_count);

		err = k_poll(events, ev_count, K_FOREVER);
		BT_ASSERT(err == 0);

		process_events(events, ev_count);

		/* Make sure we don't hog the CPU if there's all the time
		 * some ready events.
		 */
		k_yield();
	}
}


static void read_local_ver_complete(struct net_buf *buf)
{
	struct bt_hci_rp_read_local_version_info *rp = (void *)buf->data;

	LOG_DBG("status 0x%02x", rp->status);

	bt_dev.hci_version = rp->hci_version;
	bt_dev.hci_revision = sys_le16_to_cpu(rp->hci_revision);
	bt_dev.lmp_version = rp->lmp_version;
	bt_dev.lmp_subversion = sys_le16_to_cpu(rp->lmp_subversion);
	bt_dev.manufacturer = sys_le16_to_cpu(rp->manufacturer);
}

static void read_le_features_complete(struct net_buf *buf)
{
	struct bt_hci_rp_le_read_local_features *rp = (void *)buf->data;

	LOG_DBG("status 0x%02x", rp->status);

	memcpy(bt_dev.le.features, rp->features, sizeof(bt_dev.le.features));
}

#if defined(CONFIG_BT_CONN)
#if !defined(CONFIG_BT_CLASSIC)
static void read_buffer_size_complete(struct net_buf *buf)
{
	struct bt_hci_rp_read_buffer_size *rp = (void *)buf->data;
	uint16_t pkts;

	LOG_DBG("status 0x%02x", rp->status);

	/* If LE-side has buffers we can ignore the BR/EDR values */
	if (bt_dev.le.acl_mtu) {
		return;
	}

	bt_dev.le.acl_mtu = sys_le16_to_cpu(rp->acl_max_len);
	pkts = sys_le16_to_cpu(rp->acl_max_num);

	LOG_DBG("ACL BR/EDR buffers: pkts %u mtu %u", pkts, bt_dev.le.acl_mtu);

	k_sem_init(&bt_dev.le.acl_pkts, pkts, pkts);
}
#endif /* !defined(CONFIG_BT_CLASSIC) */
#endif /* CONFIG_BT_CONN */

static void le_read_buffer_size_complete(struct net_buf *buf)
{
	struct bt_hci_rp_le_read_buffer_size *rp = (void *)buf->data;

	LOG_DBG("status 0x%02x", rp->status);

#if defined(CONFIG_BT_CONN)
	uint16_t acl_mtu = sys_le16_to_cpu(rp->le_max_len);

	if (!acl_mtu || !rp->le_max_num) {
		return;
	}

	bt_dev.le.acl_mtu = acl_mtu;

	LOG_DBG("ACL LE buffers: pkts %u mtu %u", rp->le_max_num, bt_dev.le.acl_mtu);

	k_sem_init(&bt_dev.le.acl_pkts, rp->le_max_num, rp->le_max_num);
#endif /* CONFIG_BT_CONN */
}

static void read_buffer_size_v2_complete(struct net_buf *buf)
{
#if defined(CONFIG_BT_ISO)
	struct bt_hci_rp_le_read_buffer_size_v2 *rp = (void *)buf->data;

	LOG_DBG("status %u", rp->status);

#if defined(CONFIG_BT_CONN)
	uint16_t acl_mtu = sys_le16_to_cpu(rp->acl_max_len);

	if (acl_mtu && rp->acl_max_num) {
		bt_dev.le.acl_mtu = acl_mtu;
		LOG_DBG("ACL LE buffers: pkts %u mtu %u", rp->acl_max_num, bt_dev.le.acl_mtu);

		k_sem_init(&bt_dev.le.acl_pkts, rp->acl_max_num, rp->acl_max_num);
	}
#endif /* CONFIG_BT_CONN */

	uint16_t iso_mtu = sys_le16_to_cpu(rp->iso_max_len);

	if (!iso_mtu || !rp->iso_max_num) {
		LOG_ERR("ISO buffer size not set");
		return;
	}

	bt_dev.le.iso_mtu = iso_mtu;

	LOG_DBG("ISO buffers: pkts %u mtu %u", rp->iso_max_num, bt_dev.le.iso_mtu);

	k_sem_init(&bt_dev.le.iso_pkts, rp->iso_max_num, rp->iso_max_num);
	bt_dev.le.iso_limit = rp->iso_max_num;
#endif /* CONFIG_BT_ISO */
}

static int le_set_host_feature(uint8_t bit_number, uint8_t bit_value)
{
	struct bt_hci_cp_le_set_host_feature *cp;
	struct net_buf *buf;

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_HOST_FEATURE, sizeof(*cp));
	if (!buf) {
		return -ENOBUFS;
	}

	cp = net_buf_add(buf, sizeof(*cp));
	cp->bit_number = bit_number;
	cp->bit_value = bit_value;

	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_HOST_FEATURE, buf, NULL);
}

static void read_supported_commands_complete(struct net_buf *buf)
{
	struct bt_hci_rp_read_supported_commands *rp = (void *)buf->data;

	LOG_DBG("status 0x%02x", rp->status);

	memcpy(bt_dev.supported_commands, rp->commands,
	       sizeof(bt_dev.supported_commands));

	/* Report additional HCI commands used for ECDH as
	 * supported if TinyCrypt ECC is used for emulation.
	 */
	if (IS_ENABLED(CONFIG_BT_TINYCRYPT_ECC)) {
		bt_hci_ecc_supported_commands(bt_dev.supported_commands);
	}
}

static void read_local_features_complete(struct net_buf *buf)
{
	struct bt_hci_rp_read_local_features *rp = (void *)buf->data;

	LOG_DBG("status 0x%02x", rp->status);

	memcpy(bt_dev.features[0], rp->features, sizeof(bt_dev.features[0]));
}

static void le_read_supp_states_complete(struct net_buf *buf)
{
	struct bt_hci_rp_le_read_supp_states *rp = (void *)buf->data;

	LOG_DBG("status 0x%02x", rp->status);

	bt_dev.le.states = sys_get_le64(rp->le_states);
}

#if defined(CONFIG_BT_SMP)
static void le_read_resolving_list_size_complete(struct net_buf *buf)
{
	struct bt_hci_rp_le_read_rl_size *rp = (void *)buf->data;

	LOG_DBG("Resolving List size %u", rp->rl_size);

	bt_dev.le.rl_size = rp->rl_size;
}
#endif /* defined(CONFIG_BT_SMP) */

static int common_init(void)
{
	struct net_buf *rsp;
	int err;

	if (!(bt_dev.drv->quirks & BT_QUIRK_NO_RESET)) {
		/* Send HCI_RESET */
		err = bt_hci_cmd_send_sync(BT_HCI_OP_RESET, NULL, &rsp);
		if (err) {
			return err;
		}
		hci_reset_complete(rsp);
		net_buf_unref(rsp);
	}

	/* Read Local Supported Features */
	err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_LOCAL_FEATURES, NULL, &rsp);
	if (err) {
		return err;
	}
	read_local_features_complete(rsp);
	net_buf_unref(rsp);

	/* Read Local Version Information */
	err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_LOCAL_VERSION_INFO, NULL,
				   &rsp);
	if (err) {
		return err;
	}
	read_local_ver_complete(rsp);
	net_buf_unref(rsp);

	/* Read Local Supported Commands */
	err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_SUPPORTED_COMMANDS, NULL,
				   &rsp);
	if (err) {
		return err;
	}
	read_supported_commands_complete(rsp);
	net_buf_unref(rsp);

	if (IS_ENABLED(CONFIG_BT_HOST_CRYPTO_PRNG)) {
		/* Initialize the PRNG so that it is safe to use it later
		 * on in the initialization process.
		 */
		err = prng_init();
		if (err) {
			return err;
		}
	}

#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
	err = set_flow_control();
	if (err) {
		return err;
	}
#endif /* CONFIG_BT_HCI_ACL_FLOW_CONTROL */

	return 0;
}

static int le_set_event_mask(void)
{
	struct bt_hci_cp_le_set_event_mask *cp_mask;
	struct net_buf *buf;
	uint64_t mask = 0U;

	/* Set LE event mask */
	buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_EVENT_MASK, sizeof(*cp_mask));
	if (!buf) {
		return -ENOBUFS;
	}

	cp_mask = net_buf_add(buf, sizeof(*cp_mask));

	mask |= BT_EVT_MASK_LE_ADVERTISING_REPORT;

	if (IS_ENABLED(CONFIG_BT_EXT_ADV) &&
	    BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features)) {
		mask |= BT_EVT_MASK_LE_ADV_SET_TERMINATED;
		mask |= BT_EVT_MASK_LE_SCAN_REQ_RECEIVED;
		mask |= BT_EVT_MASK_LE_EXT_ADVERTISING_REPORT;
		mask |= BT_EVT_MASK_LE_SCAN_TIMEOUT;
		if (IS_ENABLED(CONFIG_BT_PER_ADV_SYNC)) {
			mask |= BT_EVT_MASK_LE_PER_ADV_SYNC_ESTABLISHED;
			mask |= BT_EVT_MASK_LE_PER_ADVERTISING_REPORT;
			mask |= BT_EVT_MASK_LE_PER_ADV_SYNC_LOST;
			mask |= BT_EVT_MASK_LE_PAST_RECEIVED;
		}
	}

	if (IS_ENABLED(CONFIG_BT_CONN)) {
		if ((IS_ENABLED(CONFIG_BT_SMP) &&
		     BT_FEAT_LE_PRIVACY(bt_dev.le.features)) ||
		    (IS_ENABLED(CONFIG_BT_EXT_ADV) &&
		     BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features))) {
			/* C24:
			 * Mandatory if the LE Controller supports Connection
			 * State and either LE Feature (LL Privacy) or
			 * LE Feature (Extended Advertising) is supported, ...
			 */
			mask |= BT_EVT_MASK_LE_ENH_CONN_COMPLETE;
		} else {
			mask |= BT_EVT_MASK_LE_CONN_COMPLETE;
		}

		mask |= BT_EVT_MASK_LE_CONN_UPDATE_COMPLETE;
		mask |= BT_EVT_MASK_LE_REMOTE_FEAT_COMPLETE;

		if (BT_FEAT_LE_CONN_PARAM_REQ_PROC(bt_dev.le.features)) {
			mask |= BT_EVT_MASK_LE_CONN_PARAM_REQ;
		}

		if (IS_ENABLED(CONFIG_BT_DATA_LEN_UPDATE) &&
		    BT_FEAT_LE_DLE(bt_dev.le.features)) {
			mask |= BT_EVT_MASK_LE_DATA_LEN_CHANGE;
		}

		if (IS_ENABLED(CONFIG_BT_PHY_UPDATE) &&
		    (BT_FEAT_LE_PHY_2M(bt_dev.le.features) ||
		     BT_FEAT_LE_PHY_CODED(bt_dev.le.features))) {
			mask |= BT_EVT_MASK_LE_PHY_UPDATE_COMPLETE;
		}
		if (IS_ENABLED(CONFIG_BT_TRANSMIT_POWER_CONTROL)) {
			mask |= BT_EVT_MASK_LE_TRANSMIT_POWER_REPORTING;
		}
	}

	if (IS_ENABLED(CONFIG_BT_SMP) &&
	    BT_FEAT_LE_ENCR(bt_dev.le.features)) {
		mask |= BT_EVT_MASK_LE_LTK_REQUEST;
	}

	/*
	 * If "LE Read Local P-256 Public Key" and "LE Generate DH Key" are
	 * supported we need to enable events generated by those commands.
	 */
	if (IS_ENABLED(CONFIG_BT_ECC) &&
	    (BT_CMD_TEST(bt_dev.supported_commands, 34, 1)) &&
	    (BT_CMD_TEST(bt_dev.supported_commands, 34, 2))) {
		mask |= BT_EVT_MASK_LE_P256_PUBLIC_KEY_COMPLETE;
		mask |= BT_EVT_MASK_LE_GENERATE_DHKEY_COMPLETE;
	}

	/*
	 * Enable CIS events only if ISO connections are enabled and controller
	 * support them.
	 */
	if (IS_ENABLED(CONFIG_BT_ISO) &&
	    BT_FEAT_LE_CIS(bt_dev.le.features)) {
		mask |= BT_EVT_MASK_LE_CIS_ESTABLISHED;
		if (BT_FEAT_LE_CIS_PERIPHERAL(bt_dev.le.features)) {
			mask |= BT_EVT_MASK_LE_CIS_REQ;
		}
	}

	/* Enable BIS events for broadcaster and/or receiver */
	if (IS_ENABLED(CONFIG_BT_ISO) && BT_FEAT_LE_BIS(bt_dev.le.features)) {
		if (IS_ENABLED(CONFIG_BT_ISO_BROADCASTER) &&
		    BT_FEAT_LE_ISO_BROADCASTER(bt_dev.le.features)) {
			mask |= BT_EVT_MASK_LE_BIG_COMPLETE;
			mask |= BT_EVT_MASK_LE_BIG_TERMINATED;
		}
		if (IS_ENABLED(CONFIG_BT_ISO_SYNC_RECEIVER) &&
		    BT_FEAT_LE_SYNC_RECEIVER(bt_dev.le.features)) {
			mask |= BT_EVT_MASK_LE_BIG_SYNC_ESTABLISHED;
			mask |= BT_EVT_MASK_LE_BIG_SYNC_LOST;
			mask |= BT_EVT_MASK_LE_BIGINFO_ADV_REPORT;
		}
	}

	/* Enable IQ samples report events receiver */
	if (IS_ENABLED(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX)) {
		mask |= BT_EVT_MASK_LE_CONNECTIONLESS_IQ_REPORT;
	}

	if (IS_ENABLED(CONFIG_BT_DF_CONNECTION_CTE_RX)) {
		mask |= BT_EVT_MASK_LE_CONNECTION_IQ_REPORT;
		mask |= BT_EVT_MASK_LE_CTE_REQUEST_FAILED;
	}

	if (IS_ENABLED(CONFIG_BT_PER_ADV_RSP)) {
		mask |= BT_EVT_MASK_LE_PER_ADV_SUBEVENT_DATA_REQ;
		mask |= BT_EVT_MASK_LE_PER_ADV_RESPONSE_REPORT;
	}

	if (IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_RSP)) {
		mask |= BT_EVT_MASK_LE_PER_ADVERTISING_REPORT_V2;
		mask |= BT_EVT_MASK_LE_PER_ADV_SYNC_ESTABLISHED_V2;
		mask |= BT_EVT_MASK_LE_PAST_RECEIVED_V2;
	}

	if (IS_ENABLED(CONFIG_BT_CONN) &&
	    (IS_ENABLED(CONFIG_BT_PER_ADV_RSP) || IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_RSP))) {
		mask |= BT_EVT_MASK_LE_ENH_CONN_COMPLETE_V2;
	}

	sys_put_le64(mask, cp_mask->events);
	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_EVENT_MASK, buf, NULL);
}

static int le_init_iso(void)
{
	int err;
	struct net_buf *rsp;

	if (IS_ENABLED(CONFIG_BT_ISO_UNICAST)) {
		/* Set Connected Isochronous Streams - Host support */
		err = le_set_host_feature(BT_LE_FEAT_BIT_ISO_CHANNELS, 1);
		if (err) {
			return err;
		}
	}

	/* Octet 41, bit 5 is read buffer size V2 */
	if (BT_CMD_TEST(bt_dev.supported_commands, 41, 5)) {
		/* Read ISO Buffer Size V2 */
		err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_BUFFER_SIZE_V2,
					   NULL, &rsp);
		if (err) {
			return err;
		}

		read_buffer_size_v2_complete(rsp);

		net_buf_unref(rsp);
	} else if (IS_ENABLED(CONFIG_BT_CONN_TX)) {
		if (IS_ENABLED(CONFIG_BT_ISO_TX)) {
			LOG_WRN("Read Buffer Size V2 command is not supported. "
				"No ISO TX buffers will be available");
		}

		/* Read LE Buffer Size in the case that we support ACL without TX ISO (e.g. if we
		 * only support ISO sync receiver).
		 */
		err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_BUFFER_SIZE,
					   NULL, &rsp);
		if (err) {
			return err;
		}

		le_read_buffer_size_complete(rsp);

		net_buf_unref(rsp);
	}

	return 0;
}

static int le_init(void)
{
	struct bt_hci_cp_write_le_host_supp *cp_le;
	struct net_buf *buf, *rsp;
	int err;

	/* For now we only support LE capable controllers */
	if (!BT_FEAT_LE(bt_dev.features)) {
		LOG_ERR("Non-LE capable controller detected!");
		return -ENODEV;
	}

	/* Read Low Energy Supported Features */
	err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_LOCAL_FEATURES, NULL,
				   &rsp);
	if (err) {
		return err;
	}

	read_le_features_complete(rsp);
	net_buf_unref(rsp);

	if (IS_ENABLED(CONFIG_BT_ISO) &&
	    BT_FEAT_LE_ISO(bt_dev.le.features)) {
		err = le_init_iso();
		if (err) {
			return err;
		}
	} else if (IS_ENABLED(CONFIG_BT_CONN)) {
		/* Read LE Buffer Size */
		err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_BUFFER_SIZE,
					   NULL, &rsp);
		if (err) {
			return err;
		}

		le_read_buffer_size_complete(rsp);

		net_buf_unref(rsp);
	}

	if (BT_FEAT_BREDR(bt_dev.features)) {
		buf = bt_hci_cmd_create(BT_HCI_OP_LE_WRITE_LE_HOST_SUPP,
					sizeof(*cp_le));
		if (!buf) {
			return -ENOBUFS;
		}

		cp_le = net_buf_add(buf, sizeof(*cp_le));

		/* Explicitly enable LE for dual-mode controllers */
		cp_le->le = 0x01;
		cp_le->simul = 0x00;
		err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_WRITE_LE_HOST_SUPP, buf,
					   NULL);
		if (err) {
			return err;
		}
	}

	/* Read LE Supported States */
	if (BT_CMD_LE_STATES(bt_dev.supported_commands)) {
		err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_SUPP_STATES, NULL,
					   &rsp);
		if (err) {
			return err;
		}

		le_read_supp_states_complete(rsp);
		net_buf_unref(rsp);
	}

	if (IS_ENABLED(CONFIG_BT_CONN) &&
	    IS_ENABLED(CONFIG_BT_DATA_LEN_UPDATE) &&
	    IS_ENABLED(CONFIG_BT_AUTO_DATA_LEN_UPDATE) &&
	    BT_FEAT_LE_DLE(bt_dev.le.features)) {
		struct bt_hci_cp_le_write_default_data_len *cp;
		uint16_t tx_octets, tx_time;

		err = hci_le_read_max_data_len(&tx_octets, &tx_time);
		if (err) {
			return err;
		}

		buf = bt_hci_cmd_create(BT_HCI_OP_LE_WRITE_DEFAULT_DATA_LEN,
					sizeof(*cp));
		if (!buf) {
			return -ENOBUFS;
		}

		cp = net_buf_add(buf, sizeof(*cp));
		cp->max_tx_octets = sys_cpu_to_le16(tx_octets);
		cp->max_tx_time = sys_cpu_to_le16(tx_time);

		err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_WRITE_DEFAULT_DATA_LEN,
					   buf, NULL);
		if (err) {
			return err;
		}
	}

#if defined(CONFIG_BT_SMP)
	if (BT_FEAT_LE_PRIVACY(bt_dev.le.features)) {
#if defined(CONFIG_BT_PRIVACY)
		struct bt_hci_cp_le_set_rpa_timeout *cp;

		buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_RPA_TIMEOUT,
					sizeof(*cp));
		if (!buf) {
			return -ENOBUFS;
		}

		cp = net_buf_add(buf, sizeof(*cp));
		cp->rpa_timeout = sys_cpu_to_le16(bt_dev.rpa_timeout);
		err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_RPA_TIMEOUT, buf,
					   NULL);
		if (err) {
			return err;
		}
#endif /* defined(CONFIG_BT_PRIVACY) */

		err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_RL_SIZE, NULL,
					   &rsp);
		if (err) {
			return err;
		}
		le_read_resolving_list_size_complete(rsp);
		net_buf_unref(rsp);
	}
#endif

#if defined(CONFIG_BT_DF)
	if (BT_FEAT_LE_CONNECTIONLESS_CTE_TX(bt_dev.le.features) ||
	    BT_FEAT_LE_CONNECTIONLESS_CTE_RX(bt_dev.le.features) ||
	    BT_FEAT_LE_RX_CTE(bt_dev.le.features)) {
		err = le_df_init();
		if (err) {
			return err;
		}
	}
#endif /* CONFIG_BT_DF */

	return  le_set_event_mask();
}

#if !defined(CONFIG_BT_CLASSIC)
static int bt_br_init(void)
{
#if defined(CONFIG_BT_CONN)
	struct net_buf *rsp;
	int err;

	if (bt_dev.le.acl_mtu) {
		return 0;
	}

	/* Use BR/EDR buffer size if LE reports zero buffers */
	err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_BUFFER_SIZE, NULL, &rsp);
	if (err) {
		return err;
	}

	read_buffer_size_complete(rsp);
	net_buf_unref(rsp);
#endif /* CONFIG_BT_CONN */

	return 0;
}
#endif /* !defined(CONFIG_BT_CLASSIC) */

static int set_event_mask(void)
{
	struct bt_hci_cp_set_event_mask *ev;
	struct net_buf *buf;
	uint64_t mask = 0U;

	buf = bt_hci_cmd_create(BT_HCI_OP_SET_EVENT_MASK, sizeof(*ev));
	if (!buf) {
		return -ENOBUFS;
	}

	ev = net_buf_add(buf, sizeof(*ev));

	if (IS_ENABLED(CONFIG_BT_CLASSIC)) {
		/* Since we require LE support, we can count on a
		 * Bluetooth 4.0 feature set
		 */
		mask |= BT_EVT_MASK_INQUIRY_COMPLETE;
		mask |= BT_EVT_MASK_CONN_COMPLETE;
		mask |= BT_EVT_MASK_CONN_REQUEST;
		mask |= BT_EVT_MASK_AUTH_COMPLETE;
		mask |= BT_EVT_MASK_REMOTE_NAME_REQ_COMPLETE;
		mask |= BT_EVT_MASK_REMOTE_FEATURES;
		mask |= BT_EVT_MASK_ROLE_CHANGE;
		mask |= BT_EVT_MASK_PIN_CODE_REQ;
		mask |= BT_EVT_MASK_LINK_KEY_REQ;
		mask |= BT_EVT_MASK_LINK_KEY_NOTIFY;
		mask |= BT_EVT_MASK_INQUIRY_RESULT_WITH_RSSI;
		mask |= BT_EVT_MASK_REMOTE_EXT_FEATURES;
		mask |= BT_EVT_MASK_SYNC_CONN_COMPLETE;
		mask |= BT_EVT_MASK_EXTENDED_INQUIRY_RESULT;
		mask |= BT_EVT_MASK_IO_CAPA_REQ;
		mask |= BT_EVT_MASK_IO_CAPA_RESP;
		mask |= BT_EVT_MASK_USER_CONFIRM_REQ;
		mask |= BT_EVT_MASK_USER_PASSKEY_REQ;
		mask |= BT_EVT_MASK_SSP_COMPLETE;
		mask |= BT_EVT_MASK_USER_PASSKEY_NOTIFY;
	}

	mask |= BT_EVT_MASK_HARDWARE_ERROR;
	mask |= BT_EVT_MASK_DATA_BUFFER_OVERFLOW;
	mask |= BT_EVT_MASK_LE_META_EVENT;

	if (IS_ENABLED(CONFIG_BT_CONN)) {
		mask |= BT_EVT_MASK_DISCONN_COMPLETE;
		mask |= BT_EVT_MASK_REMOTE_VERSION_INFO;
	}

	if (IS_ENABLED(CONFIG_BT_SMP) &&
	    BT_FEAT_LE_ENCR(bt_dev.le.features)) {
		mask |= BT_EVT_MASK_ENCRYPT_CHANGE;
		mask |= BT_EVT_MASK_ENCRYPT_KEY_REFRESH_COMPLETE;
	}

	sys_put_le64(mask, ev->events);
	return bt_hci_cmd_send_sync(BT_HCI_OP_SET_EVENT_MASK, buf, NULL);
}

const char *bt_hci_get_ver_str(uint8_t core_version)
{
	const char * const str[] = {
		"1.0b", "1.1", "1.2", "2.0", "2.1", "3.0", "4.0", "4.1", "4.2",
		"5.0", "5.1", "5.2", "5.3", "5.4"
	};

	if (core_version < ARRAY_SIZE(str)) {
		return str[core_version];
	}

	return "unknown";
}

static void bt_dev_show_info(void)
{
	int i;

	LOG_INF("Identity%s: %s", bt_dev.id_count > 1 ? "[0]" : "",
		bt_addr_le_str(&bt_dev.id_addr[0]));

	if (IS_ENABLED(CONFIG_BT_LOG_SNIFFER_INFO)) {
#if defined(CONFIG_BT_PRIVACY)
		uint8_t irk[16];

		sys_memcpy_swap(irk, bt_dev.irk[0], 16);
		LOG_INF("IRK%s: 0x%s", bt_dev.id_count > 1 ? "[0]" : "", bt_hex(irk, 16));
#endif
	}

	for (i = 1; i < bt_dev.id_count; i++) {
		LOG_INF("Identity[%d]: %s", i, bt_addr_le_str(&bt_dev.id_addr[i]));

		if (IS_ENABLED(CONFIG_BT_LOG_SNIFFER_INFO)) {
#if defined(CONFIG_BT_PRIVACY)
			uint8_t irk[16];

			sys_memcpy_swap(irk, bt_dev.irk[i], 16);
			LOG_INF("IRK[%d]: 0x%s", i, bt_hex(irk, 16));
#endif
		}
	}

	if (IS_ENABLED(CONFIG_BT_SMP) &&
	    IS_ENABLED(CONFIG_BT_LOG_SNIFFER_INFO)) {
		bt_keys_foreach_type(BT_KEYS_ALL, bt_keys_show_sniffer_info, NULL);
	}

	LOG_INF("HCI: version %s (0x%02x) revision 0x%04x, manufacturer 0x%04x",
		bt_hci_get_ver_str(bt_dev.hci_version), bt_dev.hci_version, bt_dev.hci_revision,
		bt_dev.manufacturer);
	LOG_INF("LMP: version %s (0x%02x) subver 0x%04x", bt_hci_get_ver_str(bt_dev.lmp_version),
		bt_dev.lmp_version, bt_dev.lmp_subversion);
}

#if defined(CONFIG_BT_HCI_VS_EXT)
static const char *vs_hw_platform(uint16_t platform)
{
	static const char * const plat_str[] = {
		"reserved", "Intel Corporation", "Nordic Semiconductor",
		"NXP Semiconductors" };

	if (platform < ARRAY_SIZE(plat_str)) {
		return plat_str[platform];
	}

	return "unknown";
}

static const char *vs_hw_variant(uint16_t platform, uint16_t variant)
{
	static const char * const nordic_str[] = {
		"reserved", "nRF51x", "nRF52x", "nRF53x", "nRF54Hx", "nRF54Lx"
	};

	if (platform != BT_HCI_VS_HW_PLAT_NORDIC) {
		return "unknown";
	}

	if (variant < ARRAY_SIZE(nordic_str)) {
		return nordic_str[variant];
	}

	return "unknown";
}

static const char *vs_fw_variant(uint8_t variant)
{
	static const char * const var_str[] = {
		"Standard Bluetooth controller",
		"Vendor specific controller",
		"Firmware loader",
		"Rescue image",
	};

	if (variant < ARRAY_SIZE(var_str)) {
		return var_str[variant];
	}

	return "unknown";
}

static void hci_vs_init(void)
{
	union {
		struct bt_hci_rp_vs_read_version_info *info;
		struct bt_hci_rp_vs_read_supported_commands *cmds;
		struct bt_hci_rp_vs_read_supported_features *feat;
	} rp;
	struct net_buf *rsp;
	int err;

	/* If heuristics is enabled, try to guess HCI VS support by looking
	 * at the HCI version and identity address. We haven't set any addresses
	 * at this point. So we need to read the public address.
	 */
	if (IS_ENABLED(CONFIG_BT_HCI_VS_EXT_DETECT)) {
		bt_addr_le_t addr;

		if ((bt_dev.hci_version < BT_HCI_VERSION_5_0) ||
		    bt_id_read_public_addr(&addr)) {
			LOG_WRN("Controller doesn't seem to support "
				"Zephyr vendor HCI");
			return;
		}
	}

	err = bt_hci_cmd_send_sync(BT_HCI_OP_VS_READ_VERSION_INFO, NULL, &rsp);
	if (err) {
		LOG_WRN("Vendor HCI extensions not available");
		return;
	}

	if (IS_ENABLED(CONFIG_BT_HCI_VS_EXT_DETECT) &&
	    rsp->len != sizeof(struct bt_hci_rp_vs_read_version_info)) {
		LOG_WRN("Invalid Vendor HCI extensions");
		net_buf_unref(rsp);
		return;
	}

	rp.info = (void *)rsp->data;
	LOG_INF("HW Platform: %s (0x%04x)", vs_hw_platform(sys_le16_to_cpu(rp.info->hw_platform)),
		sys_le16_to_cpu(rp.info->hw_platform));
	LOG_INF("HW Variant: %s (0x%04x)",
		vs_hw_variant(sys_le16_to_cpu(rp.info->hw_platform),
			      sys_le16_to_cpu(rp.info->hw_variant)),
		sys_le16_to_cpu(rp.info->hw_variant));
	LOG_INF("Firmware: %s (0x%02x) Version %u.%u Build %u", vs_fw_variant(rp.info->fw_variant),
		rp.info->fw_variant, rp.info->fw_version, sys_le16_to_cpu(rp.info->fw_revision),
		sys_le32_to_cpu(rp.info->fw_build));

	net_buf_unref(rsp);

	err = bt_hci_cmd_send_sync(BT_HCI_OP_VS_READ_SUPPORTED_COMMANDS,
				   NULL, &rsp);
	if (err) {
		LOG_WRN("Failed to read supported vendor commands");
		return;
	}

	if (IS_ENABLED(CONFIG_BT_HCI_VS_EXT_DETECT) &&
	    rsp->len != sizeof(struct bt_hci_rp_vs_read_supported_commands)) {
		LOG_WRN("Invalid Vendor HCI extensions");
		net_buf_unref(rsp);
		return;
	}

	rp.cmds = (void *)rsp->data;
	memcpy(bt_dev.vs_commands, rp.cmds->commands, BT_DEV_VS_CMDS_MAX);
	net_buf_unref(rsp);

	if (BT_VS_CMD_SUP_FEAT(bt_dev.vs_commands)) {
		err = bt_hci_cmd_send_sync(BT_HCI_OP_VS_READ_SUPPORTED_FEATURES,
					   NULL, &rsp);
		if (err) {
			LOG_WRN("Failed to read supported vendor features");
			return;
		}

		if (IS_ENABLED(CONFIG_BT_HCI_VS_EXT_DETECT) &&
		    rsp->len !=
		    sizeof(struct bt_hci_rp_vs_read_supported_features)) {
			LOG_WRN("Invalid Vendor HCI extensions");
			net_buf_unref(rsp);
			return;
		}

		rp.feat = (void *)rsp->data;
		memcpy(bt_dev.vs_features, rp.feat->features,
		       BT_DEV_VS_FEAT_MAX);
		net_buf_unref(rsp);
	}
}
#endif /* CONFIG_BT_HCI_VS_EXT */

static int hci_init(void)
{
	int err;

#if defined(CONFIG_BT_HCI_SETUP)
	struct bt_hci_setup_params setup_params = { 0 };

	bt_addr_copy(&setup_params.public_addr, BT_ADDR_ANY);
#if defined(CONFIG_BT_HCI_SET_PUBLIC_ADDR)
	if (bt_dev.id_count > 0 && bt_dev.id_addr[BT_ID_DEFAULT].type == BT_ADDR_LE_PUBLIC) {
		bt_addr_copy(&setup_params.public_addr, &bt_dev.id_addr[BT_ID_DEFAULT].a);
	}
#endif /* defined(CONFIG_BT_HCI_SET_PUBLIC_ADDR) */

	if (bt_dev.drv->setup) {
		err = bt_dev.drv->setup(&setup_params);
		if (err) {
			return err;
		}
	}
#endif /* defined(CONFIG_BT_HCI_SETUP) */

	err = common_init();
	if (err) {
		return err;
	}

	err = le_init();
	if (err) {
		return err;
	}

	if (BT_FEAT_BREDR(bt_dev.features)) {
		err = bt_br_init();
		if (err) {
			return err;
		}
	} else if (IS_ENABLED(CONFIG_BT_CLASSIC)) {
		LOG_ERR("Non-BR/EDR controller detected");
		return -EIO;
	}
#if defined(CONFIG_BT_CONN)
	else if (!bt_dev.le.acl_mtu) {
		LOG_ERR("ACL BR/EDR buffers not initialized");
		return -EIO;
	}
#endif

	err = set_event_mask();
	if (err) {
		return err;
	}

#if defined(CONFIG_BT_HCI_VS_EXT)
	hci_vs_init();
#endif
	err = bt_id_init();
	if (err) {
		return err;
	}

	return 0;
}

int bt_send(struct net_buf *buf)
{
	LOG_DBG("buf %p len %u type %u", buf, buf->len, bt_buf_get_type(buf));

	bt_monitor_send(bt_monitor_opcode(buf), buf->data, buf->len);

	if (IS_ENABLED(CONFIG_BT_TINYCRYPT_ECC)) {
		return bt_hci_ecc_send(buf);
	}

	return bt_dev.drv->send(buf);
}

static const struct event_handler prio_events[] = {
	EVENT_HANDLER(BT_HCI_EVT_CMD_COMPLETE, hci_cmd_complete,
		      sizeof(struct bt_hci_evt_cmd_complete)),
	EVENT_HANDLER(BT_HCI_EVT_CMD_STATUS, hci_cmd_status,
		      sizeof(struct bt_hci_evt_cmd_status)),
#if defined(CONFIG_BT_CONN)
	EVENT_HANDLER(BT_HCI_EVT_DATA_BUF_OVERFLOW,
		      hci_data_buf_overflow,
		      sizeof(struct bt_hci_evt_data_buf_overflow)),
	EVENT_HANDLER(BT_HCI_EVT_DISCONN_COMPLETE, hci_disconn_complete_prio,
		      sizeof(struct bt_hci_evt_disconn_complete)),
#endif /* CONFIG_BT_CONN */
#if defined(CONFIG_BT_CONN_TX)
	EVENT_HANDLER(BT_HCI_EVT_NUM_COMPLETED_PACKETS,
		      hci_num_completed_packets,
		      sizeof(struct bt_hci_evt_num_completed_packets)),
#endif /* CONFIG_BT_CONN_TX */
};

void hci_event_prio(struct net_buf *buf)
{
	struct net_buf_simple_state state;
	struct bt_hci_evt_hdr *hdr;
	uint8_t evt_flags;

	net_buf_simple_save(&buf->b, &state);

	if (buf->len < sizeof(*hdr)) {
		LOG_ERR("Invalid HCI event size (%u)", buf->len);
		net_buf_unref(buf);
		return;
	}

	hdr = net_buf_pull_mem(buf, sizeof(*hdr));
	evt_flags = bt_hci_evt_get_flags(hdr->evt);
	BT_ASSERT(evt_flags & BT_HCI_EVT_FLAG_RECV_PRIO);

	handle_event(hdr->evt, buf, prio_events, ARRAY_SIZE(prio_events));

	if (evt_flags & BT_HCI_EVT_FLAG_RECV) {
		net_buf_simple_restore(&buf->b, &state);
	} else {
		net_buf_unref(buf);
	}
}

static void rx_queue_put(struct net_buf *buf)
{
	net_buf_slist_put(&bt_dev.rx_queue, buf);

#if defined(CONFIG_BT_RECV_WORKQ_SYS)
	const int err = k_work_submit(&rx_work);
#elif defined(CONFIG_BT_RECV_WORKQ_BT)
	const int err = k_work_submit_to_queue(&bt_workq, &rx_work);
#endif /* CONFIG_BT_RECV_WORKQ_SYS */
	if (err < 0) {
		LOG_ERR("Could not submit rx_work: %d", err);
	}
}

static int bt_recv_unsafe(struct net_buf *buf)
{
	bt_monitor_send(bt_monitor_opcode(buf), buf->data, buf->len);

	LOG_DBG("buf %p len %u", buf, buf->len);

	switch (bt_buf_get_type(buf)) {
#if defined(CONFIG_BT_CONN)
	case BT_BUF_ACL_IN:
		rx_queue_put(buf);
		return 0;
#endif /* BT_CONN */
	case BT_BUF_EVT:
	{
		struct bt_hci_evt_hdr *hdr = (void *)buf->data;
		uint8_t evt_flags = bt_hci_evt_get_flags(hdr->evt);

		if (evt_flags & BT_HCI_EVT_FLAG_RECV_PRIO) {
			hci_event_prio(buf);
		}

		if (evt_flags & BT_HCI_EVT_FLAG_RECV) {
			rx_queue_put(buf);
		}

		return 0;
	}
#if defined(CONFIG_BT_ISO)
	case BT_BUF_ISO_IN:
		rx_queue_put(buf);
		return 0;
#endif /* CONFIG_BT_ISO */
	default:
		LOG_ERR("Invalid buf type %u", bt_buf_get_type(buf));
		net_buf_unref(buf);
		return -EINVAL;
	}
}

int bt_recv(struct net_buf *buf)
{
	int err;

	k_sched_lock();
	err = bt_recv_unsafe(buf);
	k_sched_unlock();

	return err;
}

int bt_hci_driver_register(const struct bt_hci_driver *drv)
{
	if (bt_dev.drv) {
		return -EALREADY;
	}

	if (!drv->open || !drv->send) {
		return -EINVAL;
	}

	bt_dev.drv = drv;

	LOG_DBG("Registered %s", drv->name ? drv->name : "");

	bt_monitor_new_index(BT_MONITOR_TYPE_PRIMARY, drv->bus,
			     BT_ADDR_ANY, drv->name ? drv->name : "bt0");

	return 0;
}

void bt_finalize_init(void)
{
	atomic_set_bit(bt_dev.flags, BT_DEV_READY);

	if (IS_ENABLED(CONFIG_BT_OBSERVER)) {
		bt_le_scan_update(false);
	}

	bt_dev_show_info();
}

static int bt_init(void)
{
	int err;

	err = hci_init();
	if (err) {
		return err;
	}

	if (IS_ENABLED(CONFIG_BT_CONN)) {
		err = bt_conn_init();
		if (err) {
			return err;
		}
	}

	if (IS_ENABLED(CONFIG_BT_ISO)) {
		err = bt_conn_iso_init();
		if (err) {
			return err;
		}
	}

	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
		if (!bt_dev.id_count) {
			LOG_INF("No ID address. App must call settings_load()");
			return 0;
		}

		atomic_set_bit(bt_dev.flags, BT_DEV_PRESET_ID);
	}

	bt_finalize_init();
	return 0;
}

static void init_work(struct k_work *work)
{
	int err;

	err = bt_init();
	if (ready_cb) {
		ready_cb(err);
	}
}

static void rx_work_handler(struct k_work *work)
{
	int err;

	struct net_buf *buf;

	LOG_DBG("Getting net_buf from queue");
	buf = net_buf_slist_get(&bt_dev.rx_queue);
	if (!buf) {
		return;
	}

	LOG_DBG("buf %p type %u len %u", buf, bt_buf_get_type(buf), buf->len);

	switch (bt_buf_get_type(buf)) {
#if defined(CONFIG_BT_CONN)
	case BT_BUF_ACL_IN:
		hci_acl(buf);
		break;
#endif /* CONFIG_BT_CONN */
#if defined(CONFIG_BT_ISO)
	case BT_BUF_ISO_IN:
		hci_iso(buf);
		break;
#endif /* CONFIG_BT_ISO */
	case BT_BUF_EVT:
		hci_event(buf);
		break;
	default:
		LOG_ERR("Unknown buf type %u", bt_buf_get_type(buf));
		net_buf_unref(buf);
		break;
	}

	/* Schedule the work handler to be executed again if there are
	 * additional items in the queue. This allows for other users of the
	 * work queue to get a chance at running, which wouldn't be possible if
	 * we used a while() loop with a k_yield() statement.
	 */
	if (!sys_slist_is_empty(&bt_dev.rx_queue)) {

#if defined(CONFIG_BT_RECV_WORKQ_SYS)
		err = k_work_submit(&rx_work);
#elif defined(CONFIG_BT_RECV_WORKQ_BT)
		err = k_work_submit_to_queue(&bt_workq, &rx_work);
#endif
		if (err < 0) {
			LOG_ERR("Could not submit rx_work: %d", err);
		}
	}
}

#if defined(CONFIG_BT_TESTING)
k_tid_t bt_testing_tx_tid_get(void)
{
	return &tx_thread_data;
}
#endif

int bt_enable(bt_ready_cb_t cb)
{
	int err;

	if (!bt_dev.drv) {
		LOG_ERR("No HCI driver registered");
		return -ENODEV;
	}

	atomic_clear_bit(bt_dev.flags, BT_DEV_DISABLE);

	if (atomic_test_and_set_bit(bt_dev.flags, BT_DEV_ENABLE)) {
		return -EALREADY;
	}

	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
		err = bt_settings_init();
		if (err) {
			return err;
		}
	} else if (IS_ENABLED(CONFIG_BT_DEVICE_NAME_DYNAMIC)) {
		err = bt_set_name(CONFIG_BT_DEVICE_NAME);
		if (err) {
			LOG_WRN("Failed to set device name (%d)", err);
		}
	}

	ready_cb = cb;

	/* Give cmd_sem allowing to send first HCI_Reset cmd, the only
	 * exception is if the controller requests to wait for an
	 * initial Command Complete for NOP.
	 */
	if (!IS_ENABLED(CONFIG_BT_WAIT_NOP)) {
		k_sem_init(&bt_dev.ncmd_sem, 1, 1);
	} else {
		k_sem_init(&bt_dev.ncmd_sem, 0, 1);
	}
	k_fifo_init(&bt_dev.cmd_tx_queue);
	/* TX thread */
	k_thread_create(&tx_thread_data, tx_thread_stack,
			K_KERNEL_STACK_SIZEOF(tx_thread_stack),
			hci_tx_thread, NULL, NULL, NULL,
			K_PRIO_COOP(CONFIG_BT_HCI_TX_PRIO),
			0, K_NO_WAIT);
	k_thread_name_set(&tx_thread_data, "BT TX");

#if defined(CONFIG_BT_RECV_WORKQ_BT)
	/* RX thread */
	k_work_queue_init(&bt_workq);
	k_work_queue_start(&bt_workq, rx_thread_stack,
			   CONFIG_BT_RX_STACK_SIZE,
			   K_PRIO_COOP(CONFIG_BT_RX_PRIO), NULL);
	k_thread_name_set(&bt_workq.thread, "BT RX WQ");
#endif

	err = bt_dev.drv->open();
	if (err) {
		LOG_ERR("HCI driver open failed (%d)", err);
		return err;
	}

	bt_monitor_send(BT_MONITOR_OPEN_INDEX, NULL, 0);

	if (!cb) {
		return bt_init();
	}

	k_work_submit(&bt_dev.init);
	return 0;
}

int bt_disable(void)
{
	int err;

	if (!bt_dev.drv) {
		LOG_ERR("No HCI driver registered");
		return -ENODEV;
	}

	if (!bt_dev.drv->close) {
		return -ENOTSUP;
	}

	if (atomic_test_and_set_bit(bt_dev.flags, BT_DEV_DISABLE)) {
		return -EALREADY;
	}

	/* Clear BT_DEV_READY before disabling HCI link */
	atomic_clear_bit(bt_dev.flags, BT_DEV_READY);

	err = bt_dev.drv->close();
	if (err) {
		LOG_ERR("HCI driver close failed (%d)", err);

		/* Re-enable BT_DEV_READY to avoid inconsistent stack state */
		atomic_set_bit(bt_dev.flags, BT_DEV_READY);

		return err;
	}

	/* Some functions rely on checking this bitfield */
	memset(bt_dev.supported_commands, 0x00, sizeof(bt_dev.supported_commands));

	/* If random address was set up - clear it */
	bt_addr_le_copy(&bt_dev.random_addr, BT_ADDR_LE_ANY);

#if defined(CONFIG_BT_BROADCASTER)
	bt_adv_reset_adv_pool();
#endif /* CONFIG_BT_BROADCASTER */

#if defined(CONFIG_BT_PRIVACY)
	k_work_cancel_delayable(&bt_dev.rpa_update);
#endif /* CONFIG_BT_PRIVACY */

#if defined(CONFIG_BT_PER_ADV_SYNC)
	bt_periodic_sync_disable();
#endif /* CONFIG_BT_PER_ADV_SYNC */

#if defined(CONFIG_BT_CONN)
	if (IS_ENABLED(CONFIG_BT_SMP)) {
		bt_pub_key_hci_disrupted();
	}
	bt_conn_cleanup_all();
	disconnected_handles_reset();
#endif /* CONFIG_BT_CONN */

	/* Abort TX thread */
	k_thread_abort(&tx_thread_data);

#if defined(CONFIG_BT_RECV_WORKQ_BT)
	/* Abort RX thread */
	k_thread_abort(&bt_workq.thread);
#endif

	bt_monitor_send(BT_MONITOR_CLOSE_INDEX, NULL, 0);

	/* Clear BT_DEV_ENABLE here to prevent early bt_enable() calls, before disable is
	 * completed.
	 */
	atomic_clear_bit(bt_dev.flags, BT_DEV_ENABLE);

	return 0;
}

bool bt_is_ready(void)
{
	return atomic_test_bit(bt_dev.flags, BT_DEV_READY);
}

#define DEVICE_NAME_LEN (sizeof(CONFIG_BT_DEVICE_NAME) - 1)
#if defined(CONFIG_BT_DEVICE_NAME_DYNAMIC)
BUILD_ASSERT(DEVICE_NAME_LEN < CONFIG_BT_DEVICE_NAME_MAX);
#else
BUILD_ASSERT(DEVICE_NAME_LEN < 248);
#endif

int bt_set_name(const char *name)
{
#if defined(CONFIG_BT_DEVICE_NAME_DYNAMIC)
	size_t len = strlen(name);
	int err;

	if (len > CONFIG_BT_DEVICE_NAME_MAX) {
		return -ENOMEM;
	}

	if (!strcmp(bt_dev.name, name)) {
		return 0;
	}

	memcpy(bt_dev.name, name, len);
	bt_dev.name[len] = '\0';

	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
		err = bt_settings_store_name(bt_dev.name, len);
		if (err) {
			LOG_WRN("Unable to store name");
		}
	}

	return 0;
#else
	return -ENOMEM;
#endif
}

const char *bt_get_name(void)
{
#if defined(CONFIG_BT_DEVICE_NAME_DYNAMIC)
	return bt_dev.name;
#else
	return CONFIG_BT_DEVICE_NAME;
#endif
}

uint16_t bt_get_appearance(void)
{
#if defined(CONFIG_BT_DEVICE_APPEARANCE_DYNAMIC)
	return bt_dev.appearance;
#else
	return CONFIG_BT_DEVICE_APPEARANCE;
#endif
}

#if defined(CONFIG_BT_DEVICE_APPEARANCE_DYNAMIC)
int bt_set_appearance(uint16_t appearance)
{
	if (bt_dev.appearance != appearance) {
		if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
			int err = bt_settings_store_appearance(&appearance, sizeof(appearance));
			if (err) {
				LOG_ERR("Unable to save setting 'bt/appearance' (err %d).", err);
				return err;
			}
		}

		bt_dev.appearance = appearance;
	}

	return 0;
}
#endif

bool bt_addr_le_is_bonded(uint8_t id, const bt_addr_le_t *addr)
{
	if (IS_ENABLED(CONFIG_BT_SMP)) {
		struct bt_keys *keys = bt_keys_find_addr(id, addr);

		/* if there are any keys stored then device is bonded */
		return keys && keys->keys;
	} else {
		return false;
	}
}

#if defined(CONFIG_BT_FILTER_ACCEPT_LIST)
int bt_le_filter_accept_list_add(const bt_addr_le_t *addr)
{
	struct bt_hci_cp_le_add_dev_to_fal *cp;
	struct net_buf *buf;
	int err;

	if (!atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
		return -EAGAIN;
	}

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_ADD_DEV_TO_FAL, sizeof(*cp));
	if (!buf) {
		return -ENOBUFS;
	}

	cp = net_buf_add(buf, sizeof(*cp));
	bt_addr_le_copy(&cp->addr, addr);

	err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_ADD_DEV_TO_FAL, buf, NULL);
	if (err) {
		LOG_ERR("Failed to add device to filter accept list");

		return err;
	}

	return 0;
}

int bt_le_filter_accept_list_remove(const bt_addr_le_t *addr)
{
	struct bt_hci_cp_le_rem_dev_from_fal *cp;
	struct net_buf *buf;
	int err;

	if (!atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
		return -EAGAIN;
	}

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_REM_DEV_FROM_FAL, sizeof(*cp));
	if (!buf) {
		return -ENOBUFS;
	}

	cp = net_buf_add(buf, sizeof(*cp));
	bt_addr_le_copy(&cp->addr, addr);

	err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_REM_DEV_FROM_FAL, buf, NULL);
	if (err) {
		LOG_ERR("Failed to remove device from filter accept list");
		return err;
	}

	return 0;
}

int bt_le_filter_accept_list_clear(void)
{
	int err;

	if (!atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
		return -EAGAIN;
	}

	err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_CLEAR_FAL, NULL, NULL);
	if (err) {
		LOG_ERR("Failed to clear filter accept list");
		return err;
	}

	return 0;
}
#endif /* defined(CONFIG_BT_FILTER_ACCEPT_LIST) */

int bt_le_set_chan_map(uint8_t chan_map[5])
{
	struct bt_hci_cp_le_set_host_chan_classif *cp;
	struct net_buf *buf;

	if (!(IS_ENABLED(CONFIG_BT_CENTRAL) || IS_ENABLED(CONFIG_BT_BROADCASTER))) {
		return -ENOTSUP;
	}

	if (!BT_CMD_TEST(bt_dev.supported_commands, 27, 3)) {
		LOG_WRN("Set Host Channel Classification command is "
			"not supported");
		return -ENOTSUP;
	}

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_HOST_CHAN_CLASSIF,
				sizeof(*cp));
	if (!buf) {
		return -ENOBUFS;
	}

	cp = net_buf_add(buf, sizeof(*cp));

	memcpy(&cp->ch_map[0], &chan_map[0], 4);
	cp->ch_map[4] = chan_map[4] & BIT_MASK(5);

	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_HOST_CHAN_CLASSIF,
				    buf, NULL);
}

#if defined(CONFIG_BT_RPA_TIMEOUT_DYNAMIC)
int bt_le_set_rpa_timeout(uint16_t new_rpa_timeout)
{
	if ((new_rpa_timeout == 0) || (new_rpa_timeout > 3600)) {
		return -EINVAL;
	}

	if (new_rpa_timeout == bt_dev.rpa_timeout) {
		return 0;
	}

	bt_dev.rpa_timeout = new_rpa_timeout;
	atomic_set_bit(bt_dev.flags, BT_DEV_RPA_TIMEOUT_CHANGED);

	return 0;
}
#endif

int bt_configure_data_path(uint8_t dir, uint8_t id, uint8_t vs_config_len,
			   const uint8_t *vs_config)
{
	struct bt_hci_rp_configure_data_path *rp;
	struct bt_hci_cp_configure_data_path *cp;
	struct net_buf *rsp;
	struct net_buf *buf;
	int err;

	buf = bt_hci_cmd_create(BT_HCI_OP_CONFIGURE_DATA_PATH, sizeof(*cp) +
				vs_config_len);
	if (!buf) {
		return -ENOBUFS;
	}

	cp = net_buf_add(buf, sizeof(*cp));
	cp->data_path_dir = dir;
	cp->data_path_id  = id;
	cp->vs_config_len = vs_config_len;
	if (vs_config_len) {
		(void)memcpy(cp->vs_config, vs_config, vs_config_len);
	}

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

	rp = (void *)rsp->data;
	if (rp->status) {
		err = -EIO;
	}
	net_buf_unref(rsp);

	return err;
}
