/*
 * Copyright (c) 2017-2021 Nordic Semiconductor ASA
 * Copyright (c) 2015-2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <sys/types.h>

#include <zephyr/sys/byteorder.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/buf.h>

#include "addr_internal.h"
#include "hci_core.h"
#include "conn_internal.h"
#include "id.h"
#include "scan.h"

#include "common/bt_str.h"

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

enum adv_name_type {
	ADV_NAME_TYPE_NONE,
	ADV_NAME_TYPE_AD,
	ADV_NAME_TYPE_SD,
};

struct bt_ad {
	/* Pointer to an LTV structure */
	const struct bt_data *data;
	/* Number of elements in @p data */
	size_t len;
};

struct ad_stream {
	/* ad is a two dimensional array of struct bt_data elements. */
	const struct bt_ad *ad;
	/* The number of struct bt_ad elements. */
	size_t ad_len;

	/* The current index in the array of struct bt_ad elements */
	size_t ad_index;
	/* The current index in the array of ad.data elements */
	size_t data_index;

	/* Current LTV offset contains the data offset in the ad[x].data[y].data value array
	 * The length and type are included in this offset.
	 */
	uint16_t current_ltv_offset;

	/* The remaining size of total ad[i].data[j].data_len + 2 for LTV header */
	size_t remaining_size;
};

static int ad_stream_new(struct ad_stream *stream,
			 const struct bt_ad *ad, size_t ad_len)
{
	(void)memset(stream, 0, sizeof(*stream));
	stream->ad = ad;
	stream->ad_len = ad_len;

	for (size_t i = 0; i < ad_len; i++) {
		for (size_t j = 0; j < ad[i].len; j++) {
			/* LTV length + type + value */
			stream->remaining_size += ad[i].data[j].data_len + 2;

			if (stream->remaining_size > BT_GAP_ADV_MAX_EXT_ADV_DATA_LEN) {
				return -EINVAL;
			}
		}
	}

	return 0;
}

/**
 * @brief Returns true if the current stream is empty.
 *
 * @param stream AD stream, @ref ad_stream_new
 *
 * @returns true if the stream is now empty.
 */
static bool ad_stream_is_empty(const struct ad_stream *stream)
{
	return stream->remaining_size == 0;
}

/**
 * @brief Returns the bt_data structure that is currently being read
 *
 * If the structure has been fully read, the function iterates to the next
 *
 * @param stream AD stream, @ref ad_stream_new
 *
 * @returns The current LTV structure or NULL if there are no left.
 */
static const struct bt_data *ad_stream_current_ltv_update(struct ad_stream *stream)
{
	const struct bt_data *current_ltv = &stream->ad[stream->ad_index].data[stream->data_index];
	const bool done_reading_ltv = (stream->current_ltv_offset == current_ltv->data_len + 2);

	if (done_reading_ltv) {
		stream->current_ltv_offset = 0;

		if (stream->data_index + 1 == stream->ad[stream->ad_index].len) {
			stream->data_index = 0;
			stream->ad_index++;
		} else {
			stream->data_index++;
		}
	}

	if (stream->ad_index == stream->ad_len) {
		return NULL;
	} else {
		return &stream->ad[stream->ad_index].data[stream->data_index];
	}
}

/**
 * @brief Read at max buf_len data from the flattened AD stream.
 *
 * The read data can contain multiple LTV AD structures.
 *
 * @param stream  AD stream, @ref ad_stream_new
 * @param buf     Buffer where the data will be put
 * @param buf_len Buffer length
 *
 * @returns The number of bytes read from the stream written to the provided buffer
 */
static uint8_t ad_stream_read(struct ad_stream *stream, uint8_t *buf, uint8_t buf_len)
{
	uint8_t read_len = 0;

	while (read_len < buf_len) {
		const struct bt_data *current_ltv = ad_stream_current_ltv_update(stream);

		if (!current_ltv) {
			break;
		}

		if (stream->current_ltv_offset == 0) {
			buf[read_len] = current_ltv->data_len + 1;
			stream->current_ltv_offset++;
			read_len++;
		} else if (stream->current_ltv_offset == 1) {
			buf[read_len] = current_ltv->type;
			stream->current_ltv_offset++;
			read_len++;
		} else {
			const size_t remaining_data_len =
					current_ltv->data_len - stream->current_ltv_offset + 2;
			const size_t size_to_copy = MIN(buf_len - read_len, remaining_data_len);

			(void)memcpy(&buf[read_len],
				&current_ltv->data[stream->current_ltv_offset - 2],
				size_to_copy);
			stream->current_ltv_offset += size_to_copy;
			read_len += size_to_copy;
		}
	}

	__ASSERT_NO_MSG(stream->remaining_size >= read_len);
	stream->remaining_size -= read_len;

	return read_len;
}

enum adv_name_type get_adv_name_type(const struct bt_le_ext_adv *adv)
{
	if (atomic_test_bit(adv->flags, BT_ADV_INCLUDE_NAME_SD)) {
		return ADV_NAME_TYPE_SD;
	}

	if (atomic_test_bit(adv->flags, BT_ADV_INCLUDE_NAME_AD)) {
		return ADV_NAME_TYPE_AD;
	}

	return ADV_NAME_TYPE_NONE;
}

enum adv_name_type get_adv_name_type_param(const struct bt_le_adv_param *param)
{
	if (param->options & BT_LE_ADV_OPT_USE_NAME) {
		if (param->options & BT_LE_ADV_OPT_FORCE_NAME_IN_AD) {
			return ADV_NAME_TYPE_AD;
		}

		if ((param->options & BT_LE_ADV_OPT_EXT_ADV) &&
		    !(param->options & BT_LE_ADV_OPT_SCANNABLE)) {
			return ADV_NAME_TYPE_AD;
		}

		return ADV_NAME_TYPE_SD;
	}

	return ADV_NAME_TYPE_NONE;
}

#if defined(CONFIG_BT_EXT_ADV)
static struct bt_le_ext_adv adv_pool[CONFIG_BT_EXT_ADV_MAX_ADV_SET];
#endif /* defined(CONFIG_BT_EXT_ADV) */


#if defined(CONFIG_BT_EXT_ADV)
uint8_t bt_le_ext_adv_get_index(struct bt_le_ext_adv *adv)
{
	ptrdiff_t index = adv - adv_pool;

	__ASSERT(index >= 0 && index < ARRAY_SIZE(adv_pool),
		 "Invalid bt_adv pointer");
	return (uint8_t)index;
}

static struct bt_le_ext_adv *adv_new(void)
{
	struct bt_le_ext_adv *adv = NULL;
	int i;

	for (i = 0; i < ARRAY_SIZE(adv_pool); i++) {
		if (!atomic_test_bit(adv_pool[i].flags, BT_ADV_CREATED)) {
			adv = &adv_pool[i];
			break;
		}
	}

	if (!adv) {
		return NULL;
	}

	(void)memset(adv, 0, sizeof(*adv));
	atomic_set_bit(adv_pool[i].flags, BT_ADV_CREATED);
	adv->handle = i;

	return adv;
}

static void adv_delete(struct bt_le_ext_adv *adv)
{
	atomic_clear_bit(adv->flags, BT_ADV_CREATED);
}

#if defined(CONFIG_BT_BROADCASTER)
static struct bt_le_ext_adv *bt_adv_lookup_handle(uint8_t handle)
{
	if (handle < ARRAY_SIZE(adv_pool) &&
	    atomic_test_bit(adv_pool[handle].flags, BT_ADV_CREATED)) {
		return &adv_pool[handle];
	}

	return NULL;
}
#endif /* CONFIG_BT_BROADCASTER */
#endif /* defined(CONFIG_BT_EXT_ADV) */

void bt_le_ext_adv_foreach(void (*func)(struct bt_le_ext_adv *adv, void *data),
			   void *data)
{
#if defined(CONFIG_BT_EXT_ADV)
	for (size_t i = 0; i < ARRAY_SIZE(adv_pool); i++) {
		if (atomic_test_bit(adv_pool[i].flags, BT_ADV_CREATED)) {
			func(&adv_pool[i], data);
		}
	}
#else
	func(&bt_dev.adv, data);
#endif /* defined(CONFIG_BT_EXT_ADV) */
}

void bt_adv_reset_adv_pool(void)
{
#if defined(CONFIG_BT_EXT_ADV)
	(void)memset(&adv_pool, 0, sizeof(adv_pool));
#endif /* defined(CONFIG_BT_EXT_ADV) */

	(void)memset(&bt_dev.adv, 0, sizeof(bt_dev.adv));
}

static struct bt_le_ext_adv *adv_get_legacy(void)
{
#if defined(CONFIG_BT_EXT_ADV)
	if (bt_dev.adv) {
		return bt_dev.adv;
	}

	bt_dev.adv = adv_new();
	return bt_dev.adv;
#else
	return &bt_dev.adv;
#endif
}

void bt_le_adv_delete_legacy(void)
{
#if defined(CONFIG_BT_EXT_ADV)
	if (bt_dev.adv) {
		atomic_clear_bit(bt_dev.adv->flags, BT_ADV_CREATED);
		bt_dev.adv = NULL;
	}
#endif
}

struct bt_le_ext_adv *bt_le_adv_lookup_legacy(void)
{
#if defined(CONFIG_BT_EXT_ADV)
	return bt_dev.adv;
#else
	return &bt_dev.adv;
#endif
}

int bt_le_adv_set_enable_legacy(struct bt_le_ext_adv *adv, bool enable)
{
	struct net_buf *buf;
	struct bt_hci_cmd_state_set state;
	int err;

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

	if (enable) {
		net_buf_add_u8(buf, BT_HCI_LE_ADV_ENABLE);
	} else {
		net_buf_add_u8(buf, BT_HCI_LE_ADV_DISABLE);
	}

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

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

	return 0;
}

int bt_le_adv_set_enable_ext(struct bt_le_ext_adv *adv,
			 bool enable,
			 const struct bt_le_ext_adv_start_param *param)
{
	struct net_buf *buf;
	struct bt_hci_cmd_state_set state;
	int err;

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_EXT_ADV_ENABLE, 6);
	if (!buf) {
		return -ENOBUFS;
	}

	if (enable) {
		net_buf_add_u8(buf, BT_HCI_LE_ADV_ENABLE);
	} else {
		net_buf_add_u8(buf, BT_HCI_LE_ADV_DISABLE);
	}

	net_buf_add_u8(buf, 1);

	net_buf_add_u8(buf, adv->handle);
	net_buf_add_le16(buf, param ? param->timeout : 0);
	net_buf_add_u8(buf, param ? param->num_events : 0);

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

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

	return 0;
}

int bt_le_adv_set_enable(struct bt_le_ext_adv *adv, bool enable)
{
	if (IS_ENABLED(CONFIG_BT_EXT_ADV) &&
	    BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features)) {
		return bt_le_adv_set_enable_ext(adv, enable, NULL);
	}

	return bt_le_adv_set_enable_legacy(adv, enable);
}

static bool valid_adv_ext_param(const struct bt_le_adv_param *param)
{
	if (IS_ENABLED(CONFIG_BT_EXT_ADV) &&
	    BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features)) {
		if (param->peer &&
		    !(param->options & BT_LE_ADV_OPT_EXT_ADV) &&
		    !(param->options & BT_LE_ADV_OPT_CONNECTABLE)) {
			/* Cannot do directed non-connectable advertising
			 * without extended advertising.
			 */
			return false;
		}

		if (param->peer &&
		    (param->options & BT_LE_ADV_OPT_EXT_ADV) &&
		    !(param->options & BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY)) {
			/* High duty cycle directed connectable advertising
			 * shall not be used with Extended Advertising.
			 */
			return false;
		}

		if (!(param->options & BT_LE_ADV_OPT_EXT_ADV) &&
		    param->options & (BT_LE_ADV_OPT_EXT_ADV |
				      BT_LE_ADV_OPT_NO_2M |
				      BT_LE_ADV_OPT_CODED |
				      BT_LE_ADV_OPT_ANONYMOUS |
				      BT_LE_ADV_OPT_USE_TX_POWER)) {
			/* Extended options require extended advertising. */
			return false;
		}

		if ((param->options & BT_LE_ADV_OPT_EXT_ADV) &&
		    (param->options & BT_LE_ADV_OPT_SCANNABLE) &&
		    (param->options & BT_LE_ADV_OPT_FORCE_NAME_IN_AD)) {
			/* Advertising data is not permitted for an extended
			 * scannable advertiser.
			 */
			return false;
		}
	}

	if (IS_ENABLED(CONFIG_BT_PRIVACY) &&
	    param->peer &&
	    (param->options & BT_LE_ADV_OPT_USE_IDENTITY) &&
	    (param->options & BT_LE_ADV_OPT_DIR_ADDR_RPA)) {
		/* own addr type used for both RPAs in directed advertising. */
		return false;
	}

	if (param->id >= bt_dev.id_count ||
	    bt_addr_le_eq(&bt_dev.id_addr[param->id], BT_ADDR_LE_ANY)) {
		return false;
	}

	if (!(param->options & BT_LE_ADV_OPT_CONNECTABLE)) {
		/*
		 * BT Core 4.2 [Vol 2, Part E, 7.8.5]
		 * The Advertising_Interval_Min and Advertising_Interval_Max
		 * shall not be set to less than 0x00A0 (100 ms) if the
		 * Advertising_Type is set to ADV_SCAN_IND or ADV_NONCONN_IND.
		 */
		if (bt_dev.hci_version < BT_HCI_VERSION_5_0 &&
		    param->interval_min < 0x00a0) {
			return false;
		}
	}

	if ((param->options & (BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY |
			       BT_LE_ADV_OPT_DIR_ADDR_RPA)) &&
	    !param->peer) {
		return false;
	}

	if ((param->options & BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY) ||
	    !param->peer) {
		if (param->interval_min > param->interval_max ||
		    param->interval_min < 0x0020 ||
		    param->interval_max > 0x4000) {
			return false;
		}
	}

	if ((param->options & BT_LE_ADV_OPT_DISABLE_CHAN_37) &&
	    (param->options & BT_LE_ADV_OPT_DISABLE_CHAN_38) &&
	    (param->options & BT_LE_ADV_OPT_DISABLE_CHAN_39)) {
		return false;
	}

	return true;
}

static bool valid_adv_param(const struct bt_le_adv_param *param)
{
	if (param->options & BT_LE_ADV_OPT_EXT_ADV) {
		return false;
	}

	if (param->peer && !(param->options & BT_LE_ADV_OPT_CONNECTABLE)) {
		return false;
	}

	return valid_adv_ext_param(param);
}

static int set_data_add_complete(uint8_t *set_data, uint8_t set_data_len_max,
			const struct bt_ad *ad, size_t ad_len, uint8_t *data_len)
{
	uint8_t set_data_len = 0;

	for (size_t i = 0; i < ad_len; i++) {
		const struct bt_data *data = ad[i].data;

		for (size_t j = 0; j < ad[i].len; j++) {
			size_t len = data[j].data_len;
			uint8_t type = data[j].type;

			/* Check if ad fit in the remaining buffer */
			if ((set_data_len + len + 2) > set_data_len_max) {
				ssize_t shortened_len = set_data_len_max -
							(set_data_len + 2);

				if (!(type == BT_DATA_NAME_COMPLETE &&
				      shortened_len > 0)) {
					LOG_ERR("Too big advertising data");
					return -EINVAL;
				}

				type = BT_DATA_NAME_SHORTENED;
				len = shortened_len;
			}

			set_data[set_data_len++] = len + 1;
			set_data[set_data_len++] = type;

			memcpy(&set_data[set_data_len], data[j].data, len);
			set_data_len += len;
		}
	}

	*data_len = set_data_len;
	return 0;
}

static int hci_set_ad(uint16_t hci_op, const struct bt_ad *ad, size_t ad_len)
{
	struct bt_hci_cp_le_set_adv_data *set_data;
	struct net_buf *buf;
	int err;

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

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

	err = set_data_add_complete(set_data->data, BT_GAP_ADV_MAX_ADV_DATA_LEN,
				    ad, ad_len, &set_data->len);
	if (err) {
		net_buf_unref(buf);
		return err;
	}

	return bt_hci_cmd_send_sync(hci_op, buf, NULL);
}

static int hci_set_adv_ext_complete(struct bt_le_ext_adv *adv, uint16_t hci_op,
				    size_t total_data_len, const struct bt_ad *ad, size_t ad_len)
{
	struct bt_hci_cp_le_set_ext_adv_data *set_data;
	struct net_buf *buf;
	size_t cmd_size;
	int err;

	/* Provide the opportunity to truncate the complete name */
	if (!atomic_test_bit(adv->flags, BT_ADV_EXT_ADV) &&
	    total_data_len > BT_GAP_ADV_MAX_ADV_DATA_LEN) {
		total_data_len = BT_GAP_ADV_MAX_ADV_DATA_LEN;
	}

	cmd_size = sizeof(*set_data) + total_data_len;

	buf = bt_hci_cmd_create(hci_op, cmd_size);
	if (!buf) {
		return -ENOBUFS;
	}

	set_data = net_buf_add(buf, cmd_size);
	(void)memset(set_data, 0, cmd_size);

	err = set_data_add_complete(set_data->data, total_data_len,
				    ad, ad_len, &set_data->len);
	if (err) {
		net_buf_unref(buf);
		return err;
	}

	set_data->handle = adv->handle;
	set_data->op = BT_HCI_LE_EXT_ADV_OP_COMPLETE_DATA;
	set_data->frag_pref = BT_HCI_LE_EXT_ADV_FRAG_DISABLED;

	return bt_hci_cmd_send_sync(hci_op, buf, NULL);
}

static int hci_set_adv_ext_fragmented(struct bt_le_ext_adv *adv, uint16_t hci_op,
				      const struct bt_ad *ad, size_t ad_len)
{
	int err;
	struct ad_stream stream;
	bool is_first_iteration = true;

	err = ad_stream_new(&stream, ad, ad_len);
	if (err) {
		return err;
	}

	while (!ad_stream_is_empty(&stream)) {
		struct bt_hci_cp_le_set_ext_adv_data *set_data;
		struct net_buf *buf;
		const size_t data_len = MIN(BT_HCI_LE_EXT_ADV_FRAG_MAX_LEN, stream.remaining_size);
		const size_t cmd_size = sizeof(*set_data) + data_len;

		buf = bt_hci_cmd_create(hci_op, cmd_size);
		if (!buf) {
			return -ENOBUFS;
		}

		set_data = net_buf_add(buf, cmd_size);

		set_data->handle = adv->handle;
		set_data->frag_pref = BT_HCI_LE_EXT_ADV_FRAG_ENABLED;
		set_data->len = ad_stream_read(&stream, set_data->data, data_len);

		if (is_first_iteration && ad_stream_is_empty(&stream)) {
			set_data->op = BT_HCI_LE_EXT_ADV_OP_COMPLETE_DATA;
		} else if (is_first_iteration) {
			set_data->op = BT_HCI_LE_EXT_ADV_OP_FIRST_FRAG;
		} else if (ad_stream_is_empty(&stream)) {
			set_data->op = BT_HCI_LE_EXT_ADV_OP_LAST_FRAG;
		} else {
			set_data->op = BT_HCI_LE_EXT_ADV_OP_INTERM_FRAG;
		}

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

		is_first_iteration = false;
	}

	return 0;
}

static int hci_set_ad_ext(struct bt_le_ext_adv *adv, uint16_t hci_op,
			  const struct bt_ad *ad, size_t ad_len)
{
	size_t total_len_bytes = 0;

	for (size_t i = 0; i < ad_len; i++) {
		for (size_t j = 0; j < ad[i].len; j++) {
			total_len_bytes += ad[i].data[j].data_len + 2;
		}
	}

	if ((total_len_bytes > BT_HCI_LE_EXT_ADV_FRAG_MAX_LEN) &&
	    atomic_test_bit(adv->flags, BT_ADV_ENABLED)) {
		/* It is not allowed to set advertising data in multiple
		 * operations while the advertiser is running.
		 */
		return -EAGAIN;
	}

	if (total_len_bytes <= BT_HCI_LE_EXT_ADV_FRAG_MAX_LEN) {
		/* If possible, set all data at once.
		 * This allows us to update advertising data while advertising.
		 */
		return hci_set_adv_ext_complete(adv, hci_op, total_len_bytes, ad, ad_len);
	} else {
		return hci_set_adv_ext_fragmented(adv, hci_op, ad, ad_len);
	}

	return 0;
}

static int set_ad(struct bt_le_ext_adv *adv, const struct bt_ad *ad,
		  size_t ad_len)
{
	if (IS_ENABLED(CONFIG_BT_EXT_ADV) &&
	    BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features)) {
		return hci_set_ad_ext(adv, BT_HCI_OP_LE_SET_EXT_ADV_DATA,
				      ad, ad_len);
	}

	return hci_set_ad(BT_HCI_OP_LE_SET_ADV_DATA, ad, ad_len);
}

static int set_sd(struct bt_le_ext_adv *adv, const struct bt_ad *sd,
		  size_t sd_len)
{
	if (IS_ENABLED(CONFIG_BT_EXT_ADV) &&
	    BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features)) {
		return hci_set_ad_ext(adv, BT_HCI_OP_LE_SET_EXT_SCAN_RSP_DATA,
				      sd, sd_len);
	}

	return hci_set_ad(BT_HCI_OP_LE_SET_SCAN_RSP_DATA, sd, sd_len);
}

#if defined(CONFIG_BT_PER_ADV)
static int hci_set_per_adv_data(const struct bt_le_ext_adv *adv,
				const struct bt_data *ad, size_t ad_len)
{
	int err;
	struct ad_stream stream;
	struct bt_ad d = { .data = ad, .len = ad_len };
	bool is_first_iteration = true;

	err = ad_stream_new(&stream, &d, 1);
	if (err) {
		return err;
	}

	while (!ad_stream_is_empty(&stream)) {
		struct bt_hci_cp_le_set_per_adv_data *set_data;
		struct net_buf *buf;
		const size_t data_len = MIN(BT_HCI_LE_PER_ADV_FRAG_MAX_LEN, stream.remaining_size);
		const size_t cmd_size = sizeof(*set_data) + data_len;

		buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_PER_ADV_DATA, cmd_size);
		if (!buf) {
			return -ENOBUFS;
		}

		set_data = net_buf_add(buf, cmd_size);
		(void)memset(set_data, 0, cmd_size);

		set_data->handle = adv->handle;
		set_data->len = ad_stream_read(&stream, set_data->data, data_len);

		if (is_first_iteration && ad_stream_is_empty(&stream)) {
			set_data->op = BT_HCI_LE_EXT_ADV_OP_COMPLETE_DATA;
		} else if (is_first_iteration) {
			set_data->op = BT_HCI_LE_EXT_ADV_OP_FIRST_FRAG;
		} else if (ad_stream_is_empty(&stream)) {
			set_data->op = BT_HCI_LE_EXT_ADV_OP_LAST_FRAG;
		} else {
			set_data->op = BT_HCI_LE_EXT_ADV_OP_INTERM_FRAG;
		}

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

		is_first_iteration = false;
	}

	return 0;
}
#endif /* CONFIG_BT_PER_ADV */

static inline bool ad_has_name(const struct bt_data *ad, size_t ad_len)
{
	size_t i;

	for (i = 0; i < ad_len; i++) {
		if (ad[i].type == BT_DATA_NAME_COMPLETE ||
		    ad[i].type == BT_DATA_NAME_SHORTENED) {
			return true;
		}
	}

	return false;
}

static bool ad_is_limited(const struct bt_data *ad, size_t ad_len)
{
	size_t i;

	for (i = 0; i < ad_len; i++) {
		if (ad[i].type == BT_DATA_FLAGS &&
		    ad[i].data_len == sizeof(uint8_t) &&
		    ad[i].data != NULL) {
			if (ad[i].data[0] & BT_LE_AD_LIMITED) {
				return true;
			}
		}
	}

	return false;
}

static int le_adv_update(struct bt_le_ext_adv *adv,
			 const struct bt_data *ad, size_t ad_len,
			 const struct bt_data *sd, size_t sd_len,
			 bool ext_adv, bool scannable,
			 enum adv_name_type name_type)
{
	struct bt_ad d[2] = {};
	struct bt_data data;
	size_t d_len;
	int err;

	if (name_type != ADV_NAME_TYPE_NONE) {
		const char *name = bt_get_name();

		if ((ad && ad_has_name(ad, ad_len)) ||
		    (sd && ad_has_name(sd, sd_len))) {
			/* Cannot use name if name is already set */
			return -EINVAL;
		}

		data = (struct bt_data)BT_DATA(
			BT_DATA_NAME_COMPLETE,
			name, strlen(name));
	}

	if (!(ext_adv && scannable)) {
		d_len = 1;
		d[0].data = ad;
		d[0].len = ad_len;

		if (name_type == ADV_NAME_TYPE_AD) {
			d[1].data = &data;
			d[1].len = 1;
			d_len = 2;
		}

		err = set_ad(adv, d, d_len);
		if (err) {
			return err;
		}
	}

	if (scannable) {
		d_len = 1;
		d[0].data = sd;
		d[0].len = sd_len;

		if (name_type == ADV_NAME_TYPE_SD) {
			d[1].data = &data;
			d[1].len = 1;
			d_len = 2;
		}

		err = set_sd(adv, d, d_len);
		if (err) {
			return err;
		}
	}

	atomic_set_bit(adv->flags, BT_ADV_DATA_SET);
	return 0;
}

int bt_le_adv_update_data(const struct bt_data *ad, size_t ad_len,
			  const struct bt_data *sd, size_t sd_len)
{
	struct bt_le_ext_adv *adv = bt_le_adv_lookup_legacy();
	bool scannable;

	if (!adv) {
		return -EINVAL;
	}

	if (!atomic_test_bit(adv->flags, BT_ADV_ENABLED)) {
		return -EAGAIN;
	}

	scannable = atomic_test_bit(adv->flags, BT_ADV_SCANNABLE);

	return le_adv_update(adv, ad, ad_len, sd, sd_len, false, scannable,
			     get_adv_name_type(adv));
}

static uint8_t get_filter_policy(uint32_t options)
{
	if (!IS_ENABLED(CONFIG_BT_FILTER_ACCEPT_LIST)) {
		return BT_LE_ADV_FP_NO_FILTER;
	} else if ((options & BT_LE_ADV_OPT_FILTER_SCAN_REQ) &&
		   (options & BT_LE_ADV_OPT_FILTER_CONN)) {
		return BT_LE_ADV_FP_FILTER_BOTH;
	} else if (options & BT_LE_ADV_OPT_FILTER_SCAN_REQ) {
		return BT_LE_ADV_FP_FILTER_SCAN_REQ;
	} else if (options & BT_LE_ADV_OPT_FILTER_CONN) {
		return BT_LE_ADV_FP_FILTER_CONN_IND;
	} else {
		return BT_LE_ADV_FP_NO_FILTER;
	}
}

static uint8_t get_adv_channel_map(uint32_t options)
{
	uint8_t channel_map = 0x07;

	if (options & BT_LE_ADV_OPT_DISABLE_CHAN_37) {
		channel_map &= ~0x01;
	}

	if (options & BT_LE_ADV_OPT_DISABLE_CHAN_38) {
		channel_map &= ~0x02;
	}

	if (options & BT_LE_ADV_OPT_DISABLE_CHAN_39) {
		channel_map &= ~0x04;
	}

	return channel_map;
}

static inline bool adv_is_directed(const struct bt_le_ext_adv *adv)
{
	/* The advertiser is assumed to be directed when the peer address has
	 * been set.
	 */
	return !bt_addr_le_eq(&adv->target_addr, BT_ADDR_LE_ANY);
}

static int le_adv_start_add_conn(const struct bt_le_ext_adv *adv,
				 struct bt_conn **out_conn)
{
	struct bt_conn *conn;

	bt_dev.adv_conn_id = adv->id;

	if (!adv_is_directed(adv)) {
		/* Undirected advertising */
		conn = bt_conn_add_le(adv->id, BT_ADDR_LE_NONE);
		if (!conn) {
			return -ENOMEM;
		}

		bt_conn_set_state(conn, BT_CONN_CONNECTING_ADV);
		*out_conn = conn;
		return 0;
	}

	if (bt_conn_exists_le(adv->id, &adv->target_addr)) {
		return -EINVAL;
	}

	conn = bt_conn_add_le(adv->id, &adv->target_addr);
	if (!conn) {
		return -ENOMEM;
	}

	bt_conn_set_state(conn, BT_CONN_CONNECTING_DIR_ADV);
	*out_conn = conn;
	return 0;
}

static void le_adv_stop_free_conn(const struct bt_le_ext_adv *adv, uint8_t status)
{
	struct bt_conn *conn;

	if (!adv_is_directed(adv)) {
		conn = bt_conn_lookup_state_le(adv->id, BT_ADDR_LE_NONE,
					       BT_CONN_CONNECTING_ADV);
	} else {
		conn = bt_conn_lookup_state_le(adv->id, &adv->target_addr,
					       BT_CONN_CONNECTING_DIR_ADV);
	}

	if (conn) {
		conn->err = status;
		bt_conn_set_state(conn, BT_CONN_DISCONNECTED);
		bt_conn_unref(conn);
	}
}

int bt_le_adv_start_legacy(struct bt_le_ext_adv *adv,
			   const struct bt_le_adv_param *param,
			   const struct bt_data *ad, size_t ad_len,
			   const struct bt_data *sd, size_t sd_len)
{
	struct bt_hci_cp_le_set_adv_param set_param;
	struct bt_conn *conn = NULL;
	struct net_buf *buf;
	bool dir_adv = (param->peer != NULL), scannable = false;
	enum adv_name_type name_type;

	int err;

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

	if (!valid_adv_param(param)) {
		return -EINVAL;
	}

	if (!bt_id_adv_random_addr_check(param)) {
		return -EINVAL;
	}

	if (atomic_test_bit(adv->flags, BT_ADV_ENABLED)) {
		return -EALREADY;
	}

	(void)memset(&set_param, 0, sizeof(set_param));

	set_param.min_interval = sys_cpu_to_le16(param->interval_min);
	set_param.max_interval = sys_cpu_to_le16(param->interval_max);
	set_param.channel_map  = get_adv_channel_map(param->options);
	set_param.filter_policy = get_filter_policy(param->options);

	atomic_clear_bit(bt_dev.flags, BT_DEV_RPA_VALID);

	adv->id = param->id;
	bt_dev.adv_conn_id = adv->id;

	err = bt_id_set_adv_own_addr(adv, param->options, dir_adv,
				     &set_param.own_addr_type);
	if (err) {
		return err;
	}

	if (dir_adv) {
		bt_addr_le_copy(&adv->target_addr, param->peer);
	} else {
		bt_addr_le_copy(&adv->target_addr, BT_ADDR_LE_ANY);
	}

	name_type = get_adv_name_type_param(param);

	if (param->options & BT_LE_ADV_OPT_CONNECTABLE) {
		if (dir_adv) {
			if (param->options & BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY) {
				set_param.type = BT_HCI_ADV_DIRECT_IND_LOW_DUTY;
			} else {
				set_param.type = BT_HCI_ADV_DIRECT_IND;
			}

			bt_addr_le_copy(&set_param.direct_addr, param->peer);
		} else {
			scannable = true;
			set_param.type = BT_HCI_ADV_IND;
		}
	} else if ((param->options & BT_LE_ADV_OPT_SCANNABLE) || sd ||
		   (name_type == ADV_NAME_TYPE_SD)) {
		scannable = true;
		set_param.type = BT_HCI_ADV_SCAN_IND;
	} else {
		set_param.type = BT_HCI_ADV_NONCONN_IND;
	}

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_ADV_PARAM, sizeof(set_param));
	if (!buf) {
		return -ENOBUFS;
	}

	net_buf_add_mem(buf, &set_param, sizeof(set_param));

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

	if (!dir_adv) {
		err = le_adv_update(adv, ad, ad_len, sd, sd_len, false,
				    scannable, name_type);
		if (err) {
			return err;
		}
	}

	if (IS_ENABLED(CONFIG_BT_PERIPHERAL) &&
	    (param->options & BT_LE_ADV_OPT_CONNECTABLE)) {
		err = le_adv_start_add_conn(adv, &conn);
		if (err) {
			if (err == -ENOMEM && !dir_adv &&
			    !(param->options & BT_LE_ADV_OPT_ONE_TIME)) {
				goto set_adv_state;
			}

			return err;
		}
	}

	err = bt_le_adv_set_enable(adv, true);
	if (err) {
		LOG_ERR("Failed to start advertiser");
		if (IS_ENABLED(CONFIG_BT_PERIPHERAL) && conn) {
			bt_conn_set_state(conn, BT_CONN_DISCONNECTED);
			bt_conn_unref(conn);
		}

		return err;
	}

	if (IS_ENABLED(CONFIG_BT_PERIPHERAL) && conn) {
		/* If undirected connectable advertiser we have created a
		 * connection object that we don't yet give to the application.
		 * Since we don't give the application a reference to manage in
		 * this case, we need to release this reference here
		 */
		bt_conn_unref(conn);
	}

set_adv_state:
	atomic_set_bit_to(adv->flags, BT_ADV_PERSIST, !dir_adv &&
			  !(param->options & BT_LE_ADV_OPT_ONE_TIME));

	atomic_set_bit_to(adv->flags, BT_ADV_INCLUDE_NAME_AD,
			  name_type == ADV_NAME_TYPE_AD);

	atomic_set_bit_to(adv->flags, BT_ADV_INCLUDE_NAME_SD,
			  name_type == ADV_NAME_TYPE_SD);

	atomic_set_bit_to(adv->flags, BT_ADV_CONNECTABLE,
			  param->options & BT_LE_ADV_OPT_CONNECTABLE);

	atomic_set_bit_to(adv->flags, BT_ADV_SCANNABLE, scannable);

	atomic_set_bit_to(adv->flags, BT_ADV_USE_IDENTITY,
			  param->options & BT_LE_ADV_OPT_USE_IDENTITY);

	return 0;
}

static int le_ext_adv_param_set(struct bt_le_ext_adv *adv,
				const struct bt_le_adv_param *param,
				bool  has_scan_data)
{
	struct bt_hci_cp_le_set_ext_adv_param *cp;
	bool dir_adv = param->peer != NULL, scannable;
	struct net_buf *buf, *rsp;
	int err;
	enum adv_name_type name_type;
	uint16_t props = 0;

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

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

	adv->options = param->options;

	err = bt_id_set_adv_own_addr(adv, param->options, dir_adv,
				     &cp->own_addr_type);
	if (err) {
		return err;
	}

	if (dir_adv) {
		bt_addr_le_copy(&adv->target_addr, param->peer);
	} else {
		bt_addr_le_copy(&adv->target_addr, BT_ADDR_LE_ANY);
	}

	name_type = get_adv_name_type_param(param);

	cp->handle = adv->handle;
	sys_put_le24(param->interval_min, cp->prim_min_interval);
	sys_put_le24(param->interval_max, cp->prim_max_interval);
	cp->prim_channel_map = get_adv_channel_map(param->options);
	cp->filter_policy = get_filter_policy(param->options);
	cp->tx_power = BT_HCI_LE_ADV_TX_POWER_NO_PREF;

	cp->prim_adv_phy = BT_HCI_LE_PHY_1M;
	if ((param->options & BT_LE_ADV_OPT_EXT_ADV) &&
	    !(param->options & BT_LE_ADV_OPT_NO_2M)) {
		cp->sec_adv_phy = BT_HCI_LE_PHY_2M;
	} else {
		cp->sec_adv_phy = BT_HCI_LE_PHY_1M;
	}

	if (param->options & BT_LE_ADV_OPT_CODED) {
		cp->prim_adv_phy = BT_HCI_LE_PHY_CODED;
		cp->sec_adv_phy = BT_HCI_LE_PHY_CODED;
	}

	if (!(param->options & BT_LE_ADV_OPT_EXT_ADV)) {
		props |= BT_HCI_LE_ADV_PROP_LEGACY;
	}

	if (param->options & BT_LE_ADV_OPT_USE_TX_POWER) {
		props |= BT_HCI_LE_ADV_PROP_TX_POWER;
	}

	if (param->options & BT_LE_ADV_OPT_ANONYMOUS) {
		props |= BT_HCI_LE_ADV_PROP_ANON;
	}

	if (param->options & BT_LE_ADV_OPT_NOTIFY_SCAN_REQ) {
		cp->scan_req_notify_enable = BT_HCI_LE_ADV_SCAN_REQ_ENABLE;
	}

	if (param->options & BT_LE_ADV_OPT_CONNECTABLE) {
		props |= BT_HCI_LE_ADV_PROP_CONN;
		if (!dir_adv && !(param->options & BT_LE_ADV_OPT_EXT_ADV)) {
			/* When using non-extended adv packets then undirected
			 * advertising has to be scannable as well.
			 * We didn't require this option to be set before, so
			 * it is implicitly set instead in this case.
			 */
			props |= BT_HCI_LE_ADV_PROP_SCAN;
		}
	}

	if ((param->options & BT_LE_ADV_OPT_SCANNABLE) || has_scan_data ||
	    (name_type == ADV_NAME_TYPE_SD)) {
		props |= BT_HCI_LE_ADV_PROP_SCAN;
	}

	scannable = !!(props & BT_HCI_LE_ADV_PROP_SCAN);

	if (dir_adv) {
		props |= BT_HCI_LE_ADV_PROP_DIRECT;
		if (!(param->options & BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY)) {
			props |= BT_HCI_LE_ADV_PROP_HI_DC_CONN;
		}

		bt_addr_le_copy(&cp->peer_addr, param->peer);
	}

	cp->sid = param->sid;

	cp->props = sys_cpu_to_le16(props);
	err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_EXT_ADV_PARAM, buf, &rsp);
	if (err) {
		return err;
	}

#if defined(CONFIG_BT_EXT_ADV)
	struct bt_hci_rp_le_set_ext_adv_param *rp = (void *)rsp->data;

	adv->tx_power = rp->tx_power;
#endif /* defined(CONFIG_BT_EXT_ADV) */

	net_buf_unref(rsp);

	atomic_set_bit(adv->flags, BT_ADV_PARAMS_SET);

	if (atomic_test_and_clear_bit(adv->flags, BT_ADV_RANDOM_ADDR_PENDING)) {
		err = bt_id_set_adv_random_addr(adv, &adv->random_addr.a);
		if (err) {
			return err;
		}
	}

	/* Flag only used by bt_le_adv_start API. */
	atomic_set_bit_to(adv->flags, BT_ADV_PERSIST, false);

	atomic_set_bit_to(adv->flags, BT_ADV_INCLUDE_NAME_AD,
			  name_type == ADV_NAME_TYPE_AD);

	atomic_set_bit_to(adv->flags, BT_ADV_INCLUDE_NAME_SD,
			  name_type == ADV_NAME_TYPE_SD);

	atomic_set_bit_to(adv->flags, BT_ADV_CONNECTABLE,
			  param->options & BT_LE_ADV_OPT_CONNECTABLE);

	atomic_set_bit_to(adv->flags, BT_ADV_SCANNABLE, scannable);

	atomic_set_bit_to(adv->flags, BT_ADV_USE_IDENTITY,
			  param->options & BT_LE_ADV_OPT_USE_IDENTITY);

	atomic_set_bit_to(adv->flags, BT_ADV_EXT_ADV,
			  param->options & BT_LE_ADV_OPT_EXT_ADV);

	return 0;
}

int bt_le_adv_start_ext(struct bt_le_ext_adv *adv,
			const struct bt_le_adv_param *param,
			const struct bt_data *ad, size_t ad_len,
			const struct bt_data *sd, size_t sd_len)
{
	struct bt_le_ext_adv_start_param start_param = {
		.timeout = 0,
		.num_events = 0,
	};
	bool dir_adv = (param->peer != NULL);
	struct bt_conn *conn = NULL;
	int err;

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

	if (!valid_adv_param(param)) {
		return -EINVAL;
	}

	if (atomic_test_bit(adv->flags, BT_ADV_ENABLED)) {
		return -EALREADY;
	}

	adv->id = param->id;
	err = le_ext_adv_param_set(adv, param, sd != NULL);
	if (err) {
		return err;
	}

	if (!dir_adv) {
		if (IS_ENABLED(CONFIG_BT_EXT_ADV)) {
			err = bt_le_ext_adv_set_data(adv, ad, ad_len, sd, sd_len);
			if (err) {
				return err;
			}
		}
	} else {
		if (!(param->options & BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY)) {
			start_param.timeout =
				BT_GAP_ADV_HIGH_DUTY_CYCLE_MAX_TIMEOUT;
			atomic_set_bit(adv->flags, BT_ADV_LIMITED);
		}
	}

	if (IS_ENABLED(CONFIG_BT_PERIPHERAL) &&
	    (param->options & BT_LE_ADV_OPT_CONNECTABLE)) {
		err = le_adv_start_add_conn(adv, &conn);
		if (err) {
			if (err == -ENOMEM && !dir_adv &&
			    !(param->options & BT_LE_ADV_OPT_ONE_TIME)) {
				goto set_adv_state;
			}

			return err;
		}
	}

	err = bt_le_adv_set_enable_ext(adv, true, &start_param);
	if (err) {
		LOG_ERR("Failed to start advertiser");
		if (IS_ENABLED(CONFIG_BT_PERIPHERAL) && conn) {
			bt_conn_set_state(conn, BT_CONN_DISCONNECTED);
			bt_conn_unref(conn);
		}

		return err;
	}

	if (IS_ENABLED(CONFIG_BT_PERIPHERAL) && conn) {
		/* If undirected connectable advertiser we have created a
		 * connection object that we don't yet give to the application.
		 * Since we don't give the application a reference to manage in
		 * this case, we need to release this reference here
		 */
		bt_conn_unref(conn);
	}

set_adv_state:
	/* Flag always set to false by le_ext_adv_param_set */
	atomic_set_bit_to(adv->flags, BT_ADV_PERSIST, !dir_adv &&
			  !(param->options & BT_LE_ADV_OPT_ONE_TIME));

	return 0;
}

static void adv_timeout(struct k_work *work);

int bt_le_lim_adv_cancel_timeout(struct bt_le_ext_adv *adv)
{
	return k_work_cancel_delayable(&adv->lim_adv_timeout_work);
}

int bt_le_adv_start(const struct bt_le_adv_param *param,
		    const struct bt_data *ad, size_t ad_len,
		    const struct bt_data *sd, size_t sd_len)
{
	struct bt_le_ext_adv *adv = adv_get_legacy();
	int err;

	if (!adv) {
		return -ENOMEM;
	}

	if (IS_ENABLED(CONFIG_BT_EXT_ADV) &&
	    BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features)) {
		err = bt_le_adv_start_ext(adv, param, ad, ad_len, sd, sd_len);
	} else {
		err = bt_le_adv_start_legacy(adv, param, ad, ad_len, sd, sd_len);
	}

	if (err) {
		bt_le_adv_delete_legacy();
	}

	if (ad_is_limited(ad, ad_len)) {
		k_work_init_delayable(&adv->lim_adv_timeout_work, adv_timeout);
		k_work_reschedule(&adv->lim_adv_timeout_work,
				  K_SECONDS(CONFIG_BT_LIM_ADV_TIMEOUT));
	}

	return err;
}

int bt_le_adv_stop(void)
{
	struct bt_le_ext_adv *adv = bt_le_adv_lookup_legacy();
	int err;

	if (!adv) {
		LOG_ERR("No valid legacy adv");
		return 0;
	}

	(void)bt_le_lim_adv_cancel_timeout(adv);

	/* Make sure advertising is not re-enabled later even if it's not
	 * currently enabled (i.e. BT_DEV_ADVERTISING is not set).
	 */
	atomic_clear_bit(adv->flags, BT_ADV_PERSIST);

	if (!atomic_test_bit(adv->flags, BT_ADV_ENABLED)) {
		/* Legacy advertiser exists, but is not currently advertising.
		 * This happens when keep advertising behavior is active but
		 * no conn object is available to do connectable advertising.
		 */
		bt_le_adv_delete_legacy();
		return 0;
	}

	if (IS_ENABLED(CONFIG_BT_PERIPHERAL) &&
	    atomic_test_bit(adv->flags, BT_ADV_CONNECTABLE)) {
		le_adv_stop_free_conn(adv, 0);
	}

	if (IS_ENABLED(CONFIG_BT_EXT_ADV) &&
	    BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features)) {
		err = bt_le_adv_set_enable_ext(adv, false, NULL);
		if (err) {
			return err;
		}
	} else {
		err = bt_le_adv_set_enable_legacy(adv, false);
		if (err) {
			return err;
		}
	}

	bt_le_adv_delete_legacy();

#if defined(CONFIG_BT_OBSERVER)
	if (!(IS_ENABLED(CONFIG_BT_EXT_ADV) &&
	      BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features)) &&
	    !IS_ENABLED(CONFIG_BT_PRIVACY) &&
	    !IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY)) {
		/* If scan is ongoing set back NRPA */
		if (atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING)) {
			bt_le_scan_set_enable(BT_HCI_LE_SCAN_DISABLE);
			bt_id_set_private_addr(BT_ID_DEFAULT);
			bt_le_scan_set_enable(BT_HCI_LE_SCAN_ENABLE);
		}
	}
#endif /* defined(CONFIG_BT_OBSERVER) */

	return 0;
}

#if defined(CONFIG_BT_PERIPHERAL)
static uint32_t adv_get_options(const struct bt_le_ext_adv *adv)
{
	uint32_t options = 0;

	if (!atomic_test_bit(adv->flags, BT_ADV_PERSIST)) {
		options |= BT_LE_ADV_OPT_ONE_TIME;
	}

	if (atomic_test_bit(adv->flags, BT_ADV_CONNECTABLE)) {
		options |= BT_LE_ADV_OPT_CONNECTABLE;
	}

	if (atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY)) {
		options |= BT_LE_ADV_OPT_USE_IDENTITY;
	}

	return options;
}

void bt_le_adv_resume(void)
{
	struct bt_le_ext_adv *adv = bt_le_adv_lookup_legacy();
	struct bt_conn *conn;
	bool persist_paused = false;
	int err;

	if (!adv) {
		LOG_DBG("No valid legacy adv");
		return;
	}

	if (!(atomic_test_bit(adv->flags, BT_ADV_PERSIST) &&
	      !atomic_test_bit(adv->flags, BT_ADV_ENABLED))) {
		return;
	}

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

	err = le_adv_start_add_conn(adv, &conn);
	if (err) {
		LOG_DBG("Host cannot resume connectable advertising (%d)", err);
		return;
	}

	LOG_DBG("Resuming connectable advertising");

	if (IS_ENABLED(CONFIG_BT_PRIVACY) &&
	    !atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY)) {
		bt_id_set_adv_private_addr(adv);
	} else {
		uint8_t own_addr_type;
		bool dir_adv = adv_is_directed(adv);
		uint32_t options = adv_get_options(adv);

		/* Always set the address. Don't assume it has not changed. */
		err = bt_id_set_adv_own_addr(adv, options, dir_adv, &own_addr_type);
		if (err) {
			LOG_ERR("Controller cannot resume connectable advertising (%d)", err);
			return;
		}
	}

	err = bt_le_adv_set_enable(adv, true);
	if (err) {
		LOG_DBG("Controller cannot resume connectable advertising (%d)", err);
		bt_conn_set_state(conn, BT_CONN_DISCONNECTED);

		/* Temporarily clear persist flag to avoid recursion in
		 * bt_conn_unref if the flag is still set.
		 */
		persist_paused = atomic_test_and_clear_bit(adv->flags,
							   BT_ADV_PERSIST);
	}

	/* Since we don't give the application a reference to manage in
	 * this case, we need to release this reference here.
	 */
	bt_conn_unref(conn);
	if (persist_paused) {
		atomic_set_bit(adv->flags, BT_ADV_PERSIST);
	}
}
#endif /* defined(CONFIG_BT_PERIPHERAL) */

#if defined(CONFIG_BT_EXT_ADV)
int bt_le_ext_adv_get_info(const struct bt_le_ext_adv *adv,
			   struct bt_le_ext_adv_info *info)
{
	info->id = adv->id;
	info->tx_power = adv->tx_power;
	info->addr = &adv->random_addr;

	return 0;
}

int bt_le_ext_adv_create(const struct bt_le_adv_param *param,
			 const struct bt_le_ext_adv_cb *cb,
			 struct bt_le_ext_adv **out_adv)
{
	struct bt_le_ext_adv *adv;
	int err;

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

	if (!valid_adv_ext_param(param)) {
		return -EINVAL;
	}

	adv = adv_new();
	if (!adv) {
		return -ENOMEM;
	}

	adv->id = param->id;
	adv->cb = cb;

	err = le_ext_adv_param_set(adv, param, false);
	if (err) {
		adv_delete(adv);
		return err;
	}

	*out_adv = adv;
	return 0;
}

int bt_le_ext_adv_update_param(struct bt_le_ext_adv *adv,
			       const struct bt_le_adv_param *param)
{
	if (!valid_adv_ext_param(param)) {
		return -EINVAL;
	}

	if (IS_ENABLED(CONFIG_BT_PER_ADV) &&
	    atomic_test_bit(adv->flags, BT_PER_ADV_PARAMS_SET)) {
		/* If params for per adv has been set, do not allow setting
		 * connectable, scanable or use legacy adv
		 */
		if (param->options & BT_LE_ADV_OPT_CONNECTABLE ||
		    param->options & BT_LE_ADV_OPT_SCANNABLE ||
		    !(param->options & BT_LE_ADV_OPT_EXT_ADV) ||
		    param->options & BT_LE_ADV_OPT_ANONYMOUS) {
			return -EINVAL;
		}
	}

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

	if (param->id != adv->id) {
		atomic_clear_bit(adv->flags, BT_ADV_RPA_VALID);
	}

	return le_ext_adv_param_set(adv, param, false);
}

int bt_le_ext_adv_start(struct bt_le_ext_adv *adv,
			struct bt_le_ext_adv_start_param *param)
{
	struct bt_conn *conn = NULL;
	int err;

	if (atomic_test_bit(adv->flags, BT_ADV_ENABLED)) {
		return -EALREADY;
	}

	if (IS_ENABLED(CONFIG_BT_PERIPHERAL) &&
	    atomic_test_bit(adv->flags, BT_ADV_CONNECTABLE)) {
		err = le_adv_start_add_conn(adv, &conn);
		if (err) {
			return err;
		}
	}

	atomic_set_bit_to(adv->flags, BT_ADV_LIMITED, param &&
			  (param->timeout > 0 || param->num_events > 0));

	if (atomic_test_bit(adv->flags, BT_ADV_CONNECTABLE)) {
		if (IS_ENABLED(CONFIG_BT_PRIVACY) &&
		    !atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY)) {
			bt_id_set_adv_private_addr(adv);
		}
	} else {
		if (!atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY)) {
			bt_id_set_adv_private_addr(adv);
		}
	}

	if (get_adv_name_type(adv) != ADV_NAME_TYPE_NONE &&
	    !atomic_test_bit(adv->flags, BT_ADV_DATA_SET)) {
		/* Set the advertiser name */
		bt_le_ext_adv_set_data(adv, NULL, 0, NULL, 0);
	}

	err = bt_le_adv_set_enable_ext(adv, true, param);
	if (err) {
		LOG_ERR("Failed to start advertiser");
		if (IS_ENABLED(CONFIG_BT_PERIPHERAL) && conn) {
			bt_conn_set_state(conn, BT_CONN_DISCONNECTED);
			bt_conn_unref(conn);
		}

		return err;
	}

	if (IS_ENABLED(CONFIG_BT_PERIPHERAL) && conn) {
		/* If undirected connectable advertiser we have created a
		 * connection object that we don't yet give to the application.
		 * Since we don't give the application a reference to manage in
		 * this case, we need to release this reference here
		 */
		bt_conn_unref(conn);
	}

	return 0;
}

int bt_le_ext_adv_stop(struct bt_le_ext_adv *adv)
{
	(void)bt_le_lim_adv_cancel_timeout(adv);

	atomic_clear_bit(adv->flags, BT_ADV_PERSIST);

	if (!atomic_test_bit(adv->flags, BT_ADV_ENABLED)) {
		return 0;
	}

	if (atomic_test_and_clear_bit(adv->flags, BT_ADV_LIMITED)) {
		bt_id_adv_limited_stopped(adv);

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

	if (IS_ENABLED(CONFIG_BT_PERIPHERAL) &&
	    atomic_test_bit(adv->flags, BT_ADV_CONNECTABLE)) {
		le_adv_stop_free_conn(adv, 0);
	}

	return bt_le_adv_set_enable_ext(adv, false, NULL);
}

int bt_le_ext_adv_set_data(struct bt_le_ext_adv *adv,
			   const struct bt_data *ad, size_t ad_len,
			   const struct bt_data *sd, size_t sd_len)
{
	bool ext_adv, scannable;

	ext_adv = atomic_test_bit(adv->flags, BT_ADV_EXT_ADV);
	scannable = atomic_test_bit(adv->flags, BT_ADV_SCANNABLE);

	if (ext_adv) {
		if ((scannable && ad_len) ||
		    (!scannable && sd_len)) {
			return -ENOTSUP;
		}
	}

	return le_adv_update(adv, ad, ad_len, sd, sd_len, ext_adv, scannable,
			     get_adv_name_type(adv));
}

int bt_le_ext_adv_delete(struct bt_le_ext_adv *adv)
{
	struct bt_hci_cp_le_remove_adv_set *cp;
	struct net_buf *buf;
	int err;

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

	/* Advertising set should be stopped first */
	if (atomic_test_bit(adv->flags, BT_ADV_ENABLED)) {
		return -EINVAL;
	}

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_REMOVE_ADV_SET, sizeof(*cp));
	if (!buf) {
		LOG_WRN("No HCI buffers");
		return -ENOBUFS;
	}

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

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

	adv_delete(adv);

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


static void adv_timeout(struct k_work *work)
{
	int err = 0;
	struct k_work_delayable *dwork;
	struct bt_le_ext_adv *adv;

	dwork = k_work_delayable_from_work(work);
	adv = CONTAINER_OF(dwork, struct bt_le_ext_adv, lim_adv_timeout_work);

#if defined(CONFIG_BT_EXT_ADV)
	if (adv == bt_dev.adv) {
		err = bt_le_adv_stop();
	} else {
		err = bt_le_ext_adv_stop(adv);
	}
#else
	err = bt_le_adv_stop();
#endif
	if (err) {
		LOG_WRN("Failed to stop advertising: %d", err);
	}
}

#if defined(CONFIG_BT_PER_ADV)
int bt_le_per_adv_set_param(struct bt_le_ext_adv *adv,
			    const struct bt_le_per_adv_param *param)
{
#if defined(CONFIG_BT_PER_ADV_RSP)
	/* The v2 struct can be used even if we end up sending a v1 command
	 * because they have the same layout for the common fields.
	 * V2 simply adds fields at the end of the v1 command.
	 */
	struct bt_hci_cp_le_set_per_adv_param_v2 *cp;
#else
	struct bt_hci_cp_le_set_per_adv_param *cp;
#endif /* CONFIG_BT_PER_ADV_RSP */

	uint16_t opcode;
	uint16_t size;
	struct net_buf *buf;
	int err;
	uint16_t props = 0;

	if (IS_ENABLED(CONFIG_BT_PER_ADV_RSP) && BT_FEAT_LE_PAWR_ADVERTISER(bt_dev.le.features)) {
		opcode = BT_HCI_OP_LE_SET_PER_ADV_PARAM_V2;
		size = sizeof(struct bt_hci_cp_le_set_per_adv_param_v2);
	} else if (BT_FEAT_LE_EXT_PER_ADV(bt_dev.le.features)) {
		opcode = BT_HCI_OP_LE_SET_PER_ADV_PARAM;
		size = sizeof(struct bt_hci_cp_le_set_per_adv_param);
	} else {
		return -ENOTSUP;
	}

	if (atomic_test_bit(adv->flags, BT_ADV_SCANNABLE)) {
		return -EINVAL;
	} else if (atomic_test_bit(adv->flags, BT_ADV_CONNECTABLE)) {
		return -EINVAL;
	} else if (!atomic_test_bit(adv->flags, BT_ADV_EXT_ADV)) {
		return -EINVAL;
	}

	if (param->interval_min < BT_GAP_PER_ADV_MIN_INTERVAL ||
	    param->interval_max > BT_GAP_PER_ADV_MAX_INTERVAL ||
	    param->interval_min > param->interval_max) {
		return -EINVAL;
	}

	if (!BT_FEAT_LE_PER_ADV_ADI_SUPP(bt_dev.le.features) &&
	    (param->options & BT_LE_PER_ADV_OPT_INCLUDE_ADI)) {
		return -ENOTSUP;
	}

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

	cp = net_buf_add(buf, size);
	(void)memset(cp, 0, size);

	cp->handle = adv->handle;
	cp->min_interval = sys_cpu_to_le16(param->interval_min);
	cp->max_interval = sys_cpu_to_le16(param->interval_max);

	if (param->options & BT_LE_PER_ADV_OPT_USE_TX_POWER) {
		props |= BT_HCI_LE_ADV_PROP_TX_POWER;
	}

	cp->props = sys_cpu_to_le16(props);

#if defined(CONFIG_BT_PER_ADV_RSP)
	if (opcode == BT_HCI_OP_LE_SET_PER_ADV_PARAM_V2) {
		cp->num_subevents = param->num_subevents;
		cp->subevent_interval = param->subevent_interval;
		cp->response_slot_delay = param->response_slot_delay;
		cp->response_slot_spacing = param->response_slot_spacing;
		cp->num_response_slots = param->num_response_slots;
	}
#endif /* CONFIG_BT_PER_ADV_RSP */

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

	if (param->options & BT_LE_PER_ADV_OPT_INCLUDE_ADI) {
		atomic_set_bit(adv->flags, BT_PER_ADV_INCLUDE_ADI);
	} else {
		atomic_clear_bit(adv->flags, BT_PER_ADV_INCLUDE_ADI);
	}

	atomic_set_bit(adv->flags, BT_PER_ADV_PARAMS_SET);

	return 0;
}

int bt_le_per_adv_set_data(const struct bt_le_ext_adv *adv,
			   const struct bt_data *ad, size_t ad_len)
{
	size_t total_len_bytes = 0;

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

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

	if (ad_len != 0 && ad == NULL) {
		return -EINVAL;
	}

	for (size_t i = 0; i < ad_len; i++) {
		total_len_bytes += ad[i].data_len + 2;
	}

	if ((total_len_bytes > BT_HCI_LE_PER_ADV_FRAG_MAX_LEN) &&
	    atomic_test_bit(adv->flags, BT_PER_ADV_ENABLED)) {
		/* It is not allowed to set periodic advertising data
		 * in multiple operations while it is running.
		 */
		return -EINVAL;
	}

	return hci_set_per_adv_data(adv, ad, ad_len);
}

int bt_le_per_adv_set_subevent_data(const struct bt_le_ext_adv *adv, uint8_t num_subevents,
				    const struct bt_le_per_adv_subevent_data_params *params)
{
	struct bt_hci_cp_le_set_pawr_subevent_data *cp;
	struct bt_hci_cp_le_set_pawr_subevent_data_element *element;
	struct net_buf *buf;
	size_t cmd_length = sizeof(*cp);

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

	for (size_t i = 0; i < num_subevents; i++) {
		cmd_length += sizeof(struct bt_hci_cp_le_set_pawr_subevent_data_element);
		cmd_length += params[i].data->len;
	}

	if (cmd_length > 0xFF) {
		return -EINVAL;
	}

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_PER_ADV_SUBEVENT_DATA, (uint8_t)cmd_length);
	if (!buf) {
		return -ENOBUFS;
	}

	cp = net_buf_add(buf, sizeof(*cp));
	cp->adv_handle = adv->handle;
	cp->num_subevents = num_subevents;

	for (size_t i = 0; i < num_subevents; i++) {
		element = net_buf_add(buf, sizeof(*element));
		element->subevent = params[i].subevent;
		element->response_slot_start = params[i].response_slot_start;
		element->response_slot_count = params[i].response_slot_count;
		element->subevent_data_length = params[i].data->len;
		net_buf_add_mem(buf, params[i].data->data, params[i].data->len);
	}

	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_PER_ADV_SUBEVENT_DATA, buf, NULL);
}

static int bt_le_per_adv_enable(struct bt_le_ext_adv *adv, bool enable)
{
	struct bt_hci_cp_le_set_per_adv_enable *cp;
	struct net_buf *buf;
	struct bt_hci_cmd_state_set state;
	int err;

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

	/* TODO: We could setup some default ext adv params if not already set*/
	if (!atomic_test_bit(adv->flags, BT_PER_ADV_PARAMS_SET)) {
		return -EINVAL;
	}

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

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

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

	cp->handle = adv->handle;

	if (enable) {
		cp->enable = BT_HCI_LE_SET_PER_ADV_ENABLE_ENABLE;

		if (atomic_test_bit(adv->flags, BT_PER_ADV_INCLUDE_ADI)) {
			cp->enable |= BT_HCI_LE_SET_PER_ADV_ENABLE_ADI;
		}
	} else {
		cp->enable = 0U;
	}

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

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

	return 0;
}

int bt_le_per_adv_start(struct bt_le_ext_adv *adv)
{
	return bt_le_per_adv_enable(adv, true);
}

int bt_le_per_adv_stop(struct bt_le_ext_adv *adv)
{
	return bt_le_per_adv_enable(adv, false);
}

#if defined(CONFIG_BT_PER_ADV_RSP)
void bt_hci_le_per_adv_subevent_data_request(struct net_buf *buf)
{
	struct bt_hci_evt_le_per_adv_subevent_data_request *evt;
	struct bt_le_per_adv_data_request request;
	struct bt_le_ext_adv *adv;

	if (buf->len < sizeof(struct bt_hci_evt_le_per_adv_subevent_data_request)) {
		LOG_ERR("Invalid data request");

		return;
	}

	evt = net_buf_pull_mem(buf, sizeof(struct bt_hci_evt_le_per_adv_subevent_data_request));
	adv = bt_adv_lookup_handle(evt->adv_handle);
	if (!adv) {
		LOG_ERR("Unknown advertising handle %d", evt->adv_handle);

		return;
	}

	request.start = evt->subevent_start;
	request.count = evt->subevent_data_count;

	if (adv->cb && adv->cb->pawr_data_request) {
		adv->cb->pawr_data_request(adv, &request);
	}
}

void bt_hci_le_per_adv_response_report(struct net_buf *buf)
{
	struct bt_hci_evt_le_per_adv_response_report *evt;
	struct bt_hci_evt_le_per_adv_response *response;
	struct bt_le_ext_adv *adv;
	struct bt_le_per_adv_response_info info;
	struct net_buf_simple data;

	if (buf->len < sizeof(struct bt_hci_evt_le_per_adv_response_report)) {
		LOG_ERR("Invalid response report");

		return;
	}

	evt = net_buf_pull_mem(buf, sizeof(struct bt_hci_evt_le_per_adv_response_report));
	adv = bt_adv_lookup_handle(evt->adv_handle);
	if (!adv) {
		LOG_ERR("Unknown advertising handle %d", evt->adv_handle);

		return;
	}

	info.subevent = evt->subevent;
	info.tx_status = evt->tx_status;

	for (uint8_t i = 0; i < evt->num_responses; i++) {
		if (buf->len < sizeof(struct bt_hci_evt_le_per_adv_response)) {
			LOG_ERR("Invalid response report");

			return;
		}

		response = net_buf_pull_mem(buf, sizeof(struct bt_hci_evt_le_per_adv_response));
		info.tx_power = response->tx_power;
		info.rssi = response->rssi;
		info.cte_type = bt_get_df_cte_type(response->cte_type);
		info.response_slot = response->response_slot;

		if (buf->len < response->data_length) {
			LOG_ERR("Invalid response report");

			return;
		}

		if (response->data_status == BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_PARTIAL) {
			LOG_WRN("Incomplete response report received, discarding");
			(void)net_buf_pull_mem(buf, response->data_length);
		} else if (response->data_status == BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_RX_FAILED) {
			(void)net_buf_pull_mem(buf, response->data_length);

			if (adv->cb && adv->cb->pawr_response) {
				adv->cb->pawr_response(adv, &info, NULL);
			}
		} else if (response->data_status == BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_COMPLETE) {
			net_buf_simple_init_with_data(&data,
						      net_buf_pull_mem(buf, response->data_length),
						      response->data_length);

			if (adv->cb && adv->cb->pawr_response) {
				adv->cb->pawr_response(adv, &info, &data);
			}
		} else {
			LOG_ERR("Invalid data status %d", response->data_status);
			(void)net_buf_pull_mem(buf, response->data_length);
		}
	}
}
#endif /* CONFIG_BT_PER_ADV_RSP */

#if defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER)
int bt_le_per_adv_set_info_transfer(const struct bt_le_ext_adv *adv,
				    const struct bt_conn *conn,
				    uint16_t service_data)
{
	struct bt_hci_cp_le_per_adv_set_info_transfer *cp;
	struct net_buf *buf;


	if (!BT_FEAT_LE_EXT_PER_ADV(bt_dev.le.features)) {
		return -ENOTSUP;
	} else if (!BT_FEAT_LE_PAST_SEND(bt_dev.le.features)) {
		return -ENOTSUP;
	}

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

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

	cp->conn_handle = sys_cpu_to_le16(conn->handle);
	cp->adv_handle = adv->handle;
	cp->service_data = sys_cpu_to_le16(service_data);

	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_PER_ADV_SET_INFO_TRANSFER, buf,
				    NULL);
}
#endif /* CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER */
#endif /* CONFIG_BT_PER_ADV */

#if defined(CONFIG_BT_EXT_ADV)
#if defined(CONFIG_BT_BROADCASTER)
void bt_hci_le_adv_set_terminated(struct net_buf *buf)
{
	struct bt_hci_evt_le_adv_set_terminated *evt;
	struct bt_le_ext_adv *adv;
	uint16_t conn_handle;
#if defined(CONFIG_BT_CONN) && (CONFIG_BT_EXT_ADV_MAX_ADV_SET > 1)
	bool was_adv_enabled;
#endif

	evt = (void *)buf->data;
	adv = bt_adv_lookup_handle(evt->adv_handle);
	conn_handle = sys_le16_to_cpu(evt->conn_handle);

	LOG_DBG("status 0x%02x adv_handle %u conn_handle 0x%02x num %u", evt->status,
		evt->adv_handle, conn_handle, evt->num_completed_ext_adv_evts);

	if (!adv) {
		LOG_ERR("No valid adv");
		return;
	}

	(void)bt_le_lim_adv_cancel_timeout(adv);

#if defined(CONFIG_BT_CONN) && (CONFIG_BT_EXT_ADV_MAX_ADV_SET > 1)
	was_adv_enabled = atomic_test_bit(adv->flags, BT_ADV_ENABLED);
#endif

	atomic_clear_bit(adv->flags, BT_ADV_ENABLED);

#if defined(CONFIG_BT_CONN) && (CONFIG_BT_EXT_ADV_MAX_ADV_SET > 1)
	bt_dev.adv_conn_id = adv->id;
	for (int i = 0; i < ARRAY_SIZE(bt_dev.cached_conn_complete); i++) {
		if (bt_dev.cached_conn_complete[i].valid &&
		    bt_dev.cached_conn_complete[i].evt.handle == evt->conn_handle) {
			if (was_adv_enabled) {
				/* Process the cached connection complete event
				 * now that the corresponding advertising set is known.
				 *
				 * If the advertiser has been stopped before the connection
				 * complete event has been raised to the application, we
				 * discard the event.
				 */
				bt_hci_le_enh_conn_complete(&bt_dev.cached_conn_complete[i].evt);
			}
			bt_dev.cached_conn_complete[i].valid = false;
		}
	}
#endif

	if (evt->status && IS_ENABLED(CONFIG_BT_PERIPHERAL) &&
	    atomic_test_bit(adv->flags, BT_ADV_CONNECTABLE)) {
		/* This will call connected callback for high duty cycle
		 * directed advertiser timeout.
		 */
		le_adv_stop_free_conn(adv, evt->status);
	}

	if (IS_ENABLED(CONFIG_BT_CONN) && !evt->status) {
		struct bt_conn *conn = bt_conn_lookup_handle(conn_handle, BT_CONN_TYPE_LE);

		if (conn) {
			if (IS_ENABLED(CONFIG_BT_PRIVACY) &&
			    !atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY)) {
				/* Set Responder address unless already set */
				conn->le.resp_addr.type = BT_ADDR_LE_RANDOM;
				if (bt_addr_eq(&conn->le.resp_addr.a, BT_ADDR_ANY)) {
					bt_addr_copy(&conn->le.resp_addr.a,
						     &adv->random_addr.a);
				}
			} else if (adv->options & BT_LE_ADV_OPT_USE_NRPA) {
				bt_addr_le_copy(&conn->le.resp_addr,
						&adv->random_addr);
			} else {
				bt_addr_le_copy(&conn->le.resp_addr,
					&bt_dev.id_addr[conn->id]);
			}

			if (adv->cb && adv->cb->connected) {
				struct bt_le_ext_adv_connected_info info = {
					.conn = conn,
				};

				adv->cb->connected(adv, &info);
			}

			bt_conn_unref(conn);
		}
	}

	if (atomic_test_and_clear_bit(adv->flags, BT_ADV_LIMITED)) {
		bt_id_adv_limited_stopped(adv);

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

		if (adv->cb && adv->cb->sent) {
			struct bt_le_ext_adv_sent_info info = {
				.num_sent = evt->num_completed_ext_adv_evts,
			};

			adv->cb->sent(adv, &info);
		}
	}

	if (adv == bt_dev.adv) {
		if (atomic_test_bit(adv->flags, BT_ADV_PERSIST)) {
#if defined(CONFIG_BT_PERIPHERAL)
			bt_le_adv_resume();
#endif
		} else {
			bt_le_adv_delete_legacy();
		}
	}
}

void bt_hci_le_scan_req_received(struct net_buf *buf)
{
	struct bt_hci_evt_le_scan_req_received *evt;
	struct bt_le_ext_adv *adv;

	evt = (void *)buf->data;
	adv = bt_adv_lookup_handle(evt->handle);

	LOG_DBG("handle %u peer %s", evt->handle, bt_addr_le_str(&evt->addr));

	if (!adv) {
		LOG_ERR("No valid adv");
		return;
	}

	if (adv->cb && adv->cb->scanned) {
		struct bt_le_ext_adv_scanned_info info;
		bt_addr_le_t id_addr;

		if (bt_addr_le_is_resolved(&evt->addr)) {
			bt_addr_le_copy_resolved(&id_addr, &evt->addr);
		} else {
			bt_addr_le_copy(&id_addr,
					bt_lookup_id_addr(adv->id, &evt->addr));
		}

		info.addr = &id_addr;
		adv->cb->scanned(adv, &info);
	}
}
#endif /* defined(CONFIG_BT_BROADCASTER) */
#endif /* defined(CONFIG_BT_EXT_ADV) */
