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

#include <sys/byteorder.h>

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

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

#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_CORE)
#define LOG_MODULE_NAME bt_adv
#include "common/log.h"

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;
};

static void 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;
}

/**
 * @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)
{
	/* If ad_index == ad_len, then we are past the last element in the ad array */
	return stream->ad_index == stream->ad_len;
}

/**
 * @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 (ad_stream_is_empty(stream)) {
		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;
		}
	}

	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) */
}

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

	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 ? sys_cpu_to_le16(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_cmp(&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)) {
					BT_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,
				    const struct bt_ad *ad, size_t ad_len)
{
	struct bt_hci_cp_le_set_ext_adv_data *set_data;
	struct net_buf *buf;
	int err;
	uint8_t max_data_size;

	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));

	if (atomic_test_bit(adv->flags, BT_ADV_EXT_ADV)) {
		max_data_size = BT_HCI_LE_EXT_ADV_FRAG_MAX_LEN;
	} else {
		max_data_size = BT_GAP_ADV_MAX_ADV_DATA_LEN;
	}

	err = set_data_add_complete(set_data->data, max_data_size, 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)
{
	struct ad_stream stream;

	ad_stream_new(&stream, ad, ad_len);

	bool is_first_iteration = true;

	while (!ad_stream_is_empty(&stream)) {
		struct bt_hci_cp_le_set_ext_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));

		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, sizeof(set_data->data));

		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, 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)
{
	struct ad_stream stream;
	struct bt_ad d = { .data = ad, .len = ad_len };
	bool is_first_iteration = true;

	ad_stream_new(&stream, &d, 1);

	while (!ad_stream_is_empty(&stream)) {
		struct bt_hci_cp_le_set_per_adv_data *set_data;
		struct net_buf *buf;
		int err;

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

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

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

		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 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 (!bt_addr_le_cmp(&adv->target_addr, BT_ADDR_LE_ANY)) {
		/* Undirected advertising */
		conn = bt_conn_add_le(adv->id, BT_ADDR_LE_NONE);
		if (!conn) {
			return -ENOMEM;
		}

		bt_conn_set_state(conn, BT_CONN_CONNECT_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_CONNECT_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 (!bt_addr_le_cmp(&adv->target_addr, BT_ADDR_LE_ANY)) {
		conn = bt_conn_lookup_state_le(adv->id, BT_ADDR_LE_NONE,
					       BT_CONN_CONNECT_ADV);
	} else {
		conn = bt_conn_lookup_state_le(adv->id, &adv->target_addr,
					       BT_CONN_CONNECT_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);

	if (adv->id != param->id) {
		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) {
		BT_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;

	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));

	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) {
		if (param->options & BT_LE_ADV_OPT_NO_2M) {
			cp->sec_adv_phy = BT_HCI_LE_PHY_1M;
		} else {
			cp->sec_adv_phy = BT_HCI_LE_PHY_2M;
		}
	}

	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)) {
		cp->props |= BT_HCI_LE_ADV_PROP_LEGACY;
	}

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

	if (param->options & BT_LE_ADV_OPT_ANONYMOUS) {
		cp->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) {
		cp->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.
			 */
			cp->props |= BT_HCI_LE_ADV_PROP_SCAN;
		}
	}

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

	scannable = !!(cp->props & BT_HCI_LE_ADV_PROP_SCAN);

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

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

	cp->sid = param->sid;

	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) {
		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) {
		BT_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_new_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;

	(void)bt_le_lim_adv_cancel_timeout(adv);

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

	/* 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)
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) {
		BT_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) {
		BT_DBG("Host cannot resume connectable advertising (%d)", err);
		return;
	}

	BT_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);
	}

	err = bt_le_adv_set_enable(adv, true);
	if (err) {
		BT_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;

	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) {
		BT_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)) {
		atomic_clear_bit(adv->flags, BT_ADV_RPA_VALID);

#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);

	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) {
		BT_WARN("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
	BT_WARN("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)
{
	struct bt_hci_cp_le_set_per_adv_param *cp;
	struct net_buf *buf;
	int err;

	if (!BT_FEAT_LE_EXT_PER_ADV(bt_dev.le.features)) {
		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;
	}

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

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

	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) {
		cp->props |= BT_HCI_LE_ADV_PROP_TX_POWER;
	}

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

	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 || !ad) {
		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);
}

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;
	cp->enable = enable ? 1 : 0;

	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_CONN)
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_CONN */
#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;

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

	(void)bt_le_lim_adv_cancel_timeout(adv);
#if (CONFIG_BT_ID_MAX > 1) && (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 (atomic_test_bit(adv->flags, BT_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

	BT_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) {
		BT_ERR("No valid adv");
		return;
	}

	atomic_clear_bit(adv->flags, BT_ADV_ENABLED);

	if (evt->status && IS_ENABLED(CONFIG_BT_PERIPHERAL) &&
	    atomic_test_bit(adv->flags, BT_ADV_CONNECTABLE)) {
		/* Only set status for legacy advertising API.
		 * This will call connected callback for high duty cycle
		 * directed advertiser timeout.
		 */
		le_adv_stop_free_conn(adv, adv == bt_dev.adv ? evt->status : 0);
	}

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

		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_cmp(&conn->le.resp_addr.a,
						BT_ADDR_ANY) == 0) {
					bt_addr_copy(&conn->le.resp_addr.a,
						     &adv->random_addr.a);
				}
			} 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)) {
		atomic_clear_bit(adv->flags, BT_ADV_RPA_VALID);

#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 (!atomic_test_bit(adv->flags, BT_ADV_PERSIST) && adv == bt_dev.adv) {
		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);

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

	if (!adv) {
		BT_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 (evt->addr.type == BT_ADDR_LE_PUBLIC_ID ||
		    evt->addr.type == BT_ADDR_LE_RANDOM_ID) {
			bt_addr_le_copy(&id_addr, &evt->addr);
			id_addr.type -= BT_ADDR_LE_PUBLIC_ID;
		} 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) */
