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

#include <zephyr/sys/atomic.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/check.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/iso.h>
#include <zephyr/bluetooth/buf.h>
#include <zephyr/bluetooth/direction.h>
#include <zephyr/bluetooth/addr.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/hci_vs.h>

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

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

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

struct scanner_state {
	ATOMIC_DEFINE(scan_flags, BT_LE_SCAN_USER_NUM_FLAGS);
	struct bt_le_scan_param explicit_scan_param;
	struct bt_le_scan_param used_scan_param;
	struct k_mutex scan_update_mutex;
	struct k_mutex scan_explicit_params_mutex;
};

enum scan_action {
	SCAN_ACTION_NONE,
	SCAN_ACTION_START,
	SCAN_ACTION_STOP,
	SCAN_ACTION_UPDATE,
};

static bt_le_scan_cb_t *scan_dev_found_cb;
static sys_slist_t scan_cbs = SYS_SLIST_STATIC_INIT(&scan_cbs);

static struct scanner_state scan_state;

#if defined(CONFIG_BT_EXT_ADV)
/* A buffer used to reassemble advertisement data from the controller. */
NET_BUF_SIMPLE_DEFINE(ext_scan_buf, CONFIG_BT_EXT_SCAN_BUF_SIZE);

struct fragmented_advertiser {
	bt_addr_le_t addr;
	uint8_t sid;
	enum {
		FRAG_ADV_INACTIVE,
		FRAG_ADV_REASSEMBLING,
		FRAG_ADV_DISCARDING,
	} state;
};

static struct fragmented_advertiser reassembling_advertiser;

static bool fragmented_advertisers_equal(const struct fragmented_advertiser *a,
					 const bt_addr_le_t *addr, uint8_t sid)
{
	/* Two advertisers are equal if they are the same adv set from the same device */
	return a->sid == sid && bt_addr_le_eq(&a->addr, addr);
}

/* Sets the address and sid of the advertiser to be reassembled. */
static void init_reassembling_advertiser(const bt_addr_le_t *addr, uint8_t sid)
{
	bt_addr_le_copy(&reassembling_advertiser.addr, addr);
	reassembling_advertiser.sid = sid;
	reassembling_advertiser.state = FRAG_ADV_REASSEMBLING;
}

static void reset_reassembling_advertiser(void)
{
	net_buf_simple_reset(&ext_scan_buf);
	reassembling_advertiser.state = FRAG_ADV_INACTIVE;
}

#if defined(CONFIG_BT_PER_ADV_SYNC)
static struct bt_le_per_adv_sync *get_pending_per_adv_sync(void);
static struct bt_le_per_adv_sync per_adv_sync_pool[CONFIG_BT_PER_ADV_SYNC_MAX];
static sys_slist_t pa_sync_cbs = SYS_SLIST_STATIC_INIT(&pa_sync_cbs);
#endif /* defined(CONFIG_BT_PER_ADV_SYNC) */
#endif /* defined(CONFIG_BT_EXT_ADV) */

void bt_scan_softreset(void)
{
	scan_dev_found_cb = NULL;
#if defined(CONFIG_BT_EXT_ADV)
	reset_reassembling_advertiser();
#endif
}

void bt_scan_reset(void)
{
	memset(&scan_state, 0x0, sizeof(scan_state));
	k_mutex_init(&scan_state.scan_update_mutex);
	k_mutex_init(&scan_state.scan_explicit_params_mutex);
	bt_scan_softreset();
}

static int cmd_le_set_ext_scan_enable(bool enable, bool filter_duplicates, uint16_t duration)
{
	struct bt_hci_cp_le_set_ext_scan_enable *cp;
	struct bt_hci_cmd_state_set state;
	struct net_buf *buf;
	int err;

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

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

	cp->filter_dup = filter_duplicates;
	cp->enable = enable;
	cp->duration = sys_cpu_to_le16(duration);
	cp->period = 0;

	bt_hci_cmd_state_set_init(buf, &state, bt_dev.flags, BT_DEV_SCANNING,
				  enable == BT_HCI_LE_SCAN_ENABLE);

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

	return 0;
}

static int cmd_le_set_scan_enable_legacy(bool enable, bool filter_duplicates)
{
	struct bt_hci_cp_le_set_scan_enable *cp;
	struct bt_hci_cmd_state_set state;
	struct net_buf *buf;
	int err;

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

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

	cp->filter_dup = filter_duplicates;
	cp->enable = enable;

	bt_hci_cmd_state_set_init(buf, &state, bt_dev.flags, BT_DEV_SCANNING,
				  enable == BT_HCI_LE_SCAN_ENABLE);

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

	return 0;
}

static int cmd_le_set_scan_enable(bool enable, bool filter_duplicates)
{
	if (IS_ENABLED(CONFIG_BT_EXT_ADV) && BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features)) {
		return cmd_le_set_ext_scan_enable(enable, filter_duplicates, 0);
	}

	return cmd_le_set_scan_enable_legacy(enable, filter_duplicates);
}

int bt_le_scan_set_enable(uint8_t enable)
{
	return cmd_le_set_scan_enable(enable, scan_state.used_scan_param.options &
						      BT_LE_SCAN_OPT_FILTER_DUPLICATE);
}

static int start_le_scan_ext(struct bt_le_scan_param *scan_param)
{
	struct bt_hci_ext_scan_phy param_1m;
	struct bt_hci_ext_scan_phy param_coded;

	struct bt_hci_ext_scan_phy *phy_1m = NULL;
	struct bt_hci_ext_scan_phy *phy_coded = NULL;

	if (!(scan_param->options & BT_LE_SCAN_OPT_NO_1M)) {
		param_1m.type = scan_param->type;
		param_1m.interval = sys_cpu_to_le16(scan_param->interval);
		param_1m.window = sys_cpu_to_le16(scan_param->window);

		phy_1m = &param_1m;
	}

	if (scan_param->options & BT_LE_SCAN_OPT_CODED) {
		uint16_t interval = scan_param->interval_coded ? scan_param->interval_coded
							       : scan_param->interval;
		uint16_t window =
			scan_param->window_coded ? scan_param->window_coded : scan_param->window;

		param_coded.type = scan_param->type;
		param_coded.interval = sys_cpu_to_le16(interval);
		param_coded.window = sys_cpu_to_le16(window);
		phy_coded = &param_coded;
	}

	struct bt_hci_cp_le_set_ext_scan_param *set_param;
	struct net_buf *buf;
	uint8_t own_addr_type;
	bool active_scan;
	int err;

	active_scan = (phy_1m && phy_1m->type == BT_HCI_LE_SCAN_ACTIVE) ||
		      (phy_coded && phy_coded->type == BT_HCI_LE_SCAN_ACTIVE);

	if (scan_param->timeout > 0) {
		atomic_set_bit(bt_dev.flags, BT_DEV_SCAN_LIMITED);

		/* Allow bt_le_oob_get_local to be called directly before
		 * starting a scan limited by timeout.
		 */
		if (IS_ENABLED(CONFIG_BT_PRIVACY) && !bt_id_rpa_is_new()) {
			atomic_clear_bit(bt_dev.flags, BT_DEV_RPA_VALID);
		}
	}

	err = bt_id_set_scan_own_addr(active_scan, &own_addr_type);
	if (err) {
		return err;
	}

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_EXT_SCAN_PARAM,
				sizeof(*set_param) +
				(phy_1m ? sizeof(*phy_1m) : 0) +
				(phy_coded ? sizeof(*phy_coded) : 0));
	if (!buf) {
		return -ENOBUFS;
	}

	set_param = net_buf_add(buf, sizeof(*set_param));
	set_param->own_addr_type = own_addr_type;
	set_param->phys = 0;
	set_param->filter_policy = scan_param->options & BT_LE_SCAN_OPT_FILTER_ACCEPT_LIST
					   ? BT_HCI_LE_SCAN_FP_BASIC_FILTER
					   : BT_HCI_LE_SCAN_FP_BASIC_NO_FILTER;

	if (phy_1m) {
		set_param->phys |= BT_HCI_LE_EXT_SCAN_PHY_1M;
		net_buf_add_mem(buf, phy_1m, sizeof(*phy_1m));
	}

	if (phy_coded) {
		set_param->phys |= BT_HCI_LE_EXT_SCAN_PHY_CODED;
		net_buf_add_mem(buf, phy_coded, sizeof(*phy_coded));
	}

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

	err = cmd_le_set_ext_scan_enable(BT_HCI_LE_SCAN_ENABLE,
					 scan_param->options & BT_LE_SCAN_OPT_FILTER_DUPLICATE,
					 scan_param->timeout);
	if (err) {
		return err;
	}

	return 0;
}

static int start_le_scan_legacy(struct bt_le_scan_param *param)
{
	struct bt_hci_cp_le_set_scan_param set_param;
	struct net_buf *buf;
	int err;
	bool active_scan;

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

	set_param.scan_type = param->type;

	/* for the rest parameters apply default values according to
	 *  spec 4.2, vol2, part E, 7.8.10
	 */
	set_param.interval = sys_cpu_to_le16(param->interval);
	set_param.window = sys_cpu_to_le16(param->window);

	if (IS_ENABLED(CONFIG_BT_FILTER_ACCEPT_LIST) &&
	    param->options & BT_LE_SCAN_OPT_FILTER_ACCEPT_LIST) {
		set_param.filter_policy = BT_HCI_LE_SCAN_FP_BASIC_FILTER;
	} else {
		set_param.filter_policy = BT_HCI_LE_SCAN_FP_BASIC_NO_FILTER;
	}

	active_scan = param->type == BT_HCI_LE_SCAN_ACTIVE;
	err = bt_id_set_scan_own_addr(active_scan, &set_param.addr_type);
	if (err) {
		return err;
	}

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_SCAN_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_SCAN_PARAM, buf, NULL);
	if (err) {
		return err;
	}

	err = cmd_le_set_scan_enable(BT_HCI_LE_SCAN_ENABLE,
				     param->options & BT_LE_SCAN_OPT_FILTER_DUPLICATE);
	if (err) {
		return err;
	}

	return 0;
}

bool bt_le_scan_active_scanner_running(void)
{
	return atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING) &&
	       scan_state.used_scan_param.type == BT_LE_SCAN_TYPE_ACTIVE;
}

static void select_scan_params(struct bt_le_scan_param *scan_param)
{
	/* From high priority to low priority: select parameters */
	/* 1. Priority: explicitly chosen parameters */
	if (atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_EXPLICIT_SCAN)) {
		memcpy(scan_param, &scan_state.explicit_scan_param, sizeof(*scan_param));
	}
	/* Below this, the scanner module chooses the parameters. */
	/* 2. Priority: reuse parameters from initiator */
	else if (atomic_test_bit(bt_dev.flags, BT_DEV_INITIATING)) {
		*scan_param = (struct bt_le_scan_param){
			.type = BT_LE_SCAN_TYPE_PASSIVE,
			.options = BT_LE_SCAN_OPT_FILTER_DUPLICATE,
			.interval = bt_dev.create_param.interval,
			.window = bt_dev.create_param.window,
			.timeout = 0,
			.interval_coded = bt_dev.create_param.interval_coded,
			.window_coded = bt_dev.create_param.window_coded,
		};
	}
	/* 3. Priority: choose custom parameters */
	else {
		*scan_param = (struct bt_le_scan_param){
			.type = BT_LE_SCAN_TYPE_PASSIVE,
			.options = BT_LE_SCAN_OPT_FILTER_DUPLICATE,
			.interval = CONFIG_BT_BACKGROUND_SCAN_INTERVAL,
			.window = CONFIG_BT_BACKGROUND_SCAN_WINDOW,
			.timeout = 0,
			.interval_coded = 0,
			.window_coded = 0,
		};

		if (BT_FEAT_LE_PHY_CODED(bt_dev.le.features)) {
			scan_param->options |= BT_LE_SCAN_OPT_CODED;
		}

		if (atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_PER_SYNC) ||
		    atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_CONN)) {
			scan_param->window = BT_GAP_SCAN_FAST_WINDOW;
			scan_param->interval = BT_GAP_SCAN_FAST_INTERVAL;
		}
	}
}

static int start_scan(struct bt_le_scan_param *scan_param)
{
	if (IS_ENABLED(CONFIG_BT_EXT_ADV) && BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features)) {
		return start_le_scan_ext(scan_param);
	}

	return start_le_scan_legacy(scan_param);
}

static bool is_already_using_same_params(struct bt_le_scan_param *scan_param)
{
	return !memcmp(scan_param, &scan_state.used_scan_param, sizeof(*scan_param));
}

static enum scan_action get_scan_action(struct bt_le_scan_param *scan_param)
{
	bool is_scanning = atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING);

	/* Check if there is reason to have the scanner running */
	if (atomic_get(scan_state.scan_flags) != 0) {
		if (is_scanning) {
			if (is_already_using_same_params(scan_param)) {
				/* Already scanning with the desired parameters */
				return SCAN_ACTION_NONE;
			} else {
				return SCAN_ACTION_UPDATE;
			}
		} else {
			return SCAN_ACTION_START;
		}
	} else {
		/* Scanner should not run */
		if (is_scanning) {
			return SCAN_ACTION_STOP;
		} else {
			return SCAN_ACTION_NONE;
		}
	}
}

static int scan_update(void)
{
	int32_t err;

	struct bt_le_scan_param scan_param;

	/* Prevent partial updates of the scanner state. */
	err = k_mutex_lock(&scan_state.scan_update_mutex, K_NO_WAIT);

	if (err) {
		return err;
	}

	select_scan_params(&scan_param);

	enum scan_action action = get_scan_action(&scan_param);

	/* start/stop/update if required and allowed */
	switch (action) {
	case SCAN_ACTION_NONE:
		break;
	case SCAN_ACTION_STOP:
		err = cmd_le_set_scan_enable(BT_HCI_LE_SCAN_DISABLE,
					     BT_HCI_LE_SCAN_FILTER_DUP_DISABLE);
		if (err) {
			LOG_DBG("Could not stop scanner: %d", err);
			break;
		}
		memset(&scan_state.used_scan_param, 0x0,
		       sizeof(scan_state.used_scan_param));
		break;
	case SCAN_ACTION_UPDATE:
		err = cmd_le_set_scan_enable(BT_HCI_LE_SCAN_DISABLE,
					     BT_HCI_LE_SCAN_FILTER_DUP_DISABLE);
		if (err) {
			LOG_DBG("Could not stop scanner to update: %d", err);
			break;
		}
		__fallthrough;
	case SCAN_ACTION_START:
		err = start_scan(&scan_param);
		if (err) {
			LOG_DBG("Could not start scanner: %d", err);
			break;
		}
		memcpy(&scan_state.used_scan_param, &scan_param, sizeof(scan_param));
		break;
	}

	k_mutex_unlock(&scan_state.scan_update_mutex);

	return err;
}

static int scan_check_if_state_allowed(enum bt_le_scan_user flag)
{
	/* check if state is already set */
	if (atomic_test_bit(scan_state.scan_flags, flag)) {
		return -EALREADY;
	}

	if (flag == BT_LE_SCAN_USER_EXPLICIT_SCAN && !BT_LE_STATES_SCAN_INIT(bt_dev.le.states) &&
	    atomic_test_bit(bt_dev.flags, BT_DEV_INITIATING)) {
		return -EPERM;
	}

	return 0;
}

int bt_le_scan_user_add(enum bt_le_scan_user flag)
{
	uint32_t err;

	if (flag == BT_LE_SCAN_USER_NONE) {
		/* Only check if the scanner parameters should be updated / the scanner should be
		 * started. This is mainly triggered once connections are established.
		 */
		return scan_update();
	}

	err = scan_check_if_state_allowed(flag);
	if (err) {
		return err;
	}

	atomic_set_bit(scan_state.scan_flags, flag);

	err = scan_update();
	if (err) {
		atomic_clear_bit(scan_state.scan_flags, flag);
	}

	return err;
}

int bt_le_scan_user_remove(enum bt_le_scan_user flag)
{
	if (flag == BT_LE_SCAN_USER_NONE) {
		/* Only check if the scanner parameters should be updated / the scanner should be
		 * started. This is mainly triggered once connections are established.
		 */
	} else {
		atomic_clear_bit(scan_state.scan_flags, flag);
	}

	return scan_update();
}

#if defined(CONFIG_BT_CENTRAL)
static void check_pending_conn(const bt_addr_le_t *id_addr,
			       const bt_addr_le_t *addr, uint8_t adv_props)
{
	struct bt_conn *conn;
	int err;

	/* No connections are allowed during explicit scanning
	 * when the controller does not support concurrent scanning and initiating.
	 */
	if (!BT_LE_STATES_SCAN_INIT(bt_dev.le.states) &&
	    atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_EXPLICIT_SCAN)) {
		return;
	}

	/* Return if event is not connectable */
	if (!(adv_props & BT_HCI_LE_ADV_EVT_TYPE_CONN)) {
		return;
	}

	conn = bt_conn_lookup_state_le(BT_ID_DEFAULT, id_addr,
				       BT_CONN_SCAN_BEFORE_INITIATING);
	if (!conn) {
		return;
	}

	/* Stop the scanner if there is no other reason to have it running.
	 * Ignore possible failures here, since the user is guaranteed to be removed
	 * and the scanner state is updated once the initiator starts / stops.
	 */
	err = bt_le_scan_user_remove(BT_LE_SCAN_USER_CONN);
	if (err) {
		LOG_DBG("Error while removing conn user from scanner (%d)", err);
	}

	bt_addr_le_copy(&conn->le.resp_addr, addr);
	if (bt_le_create_conn(conn)) {
		goto failed;
	}

	bt_conn_set_state(conn, BT_CONN_INITIATING);
	bt_conn_unref(conn);
	return;

failed:
	conn->err = BT_HCI_ERR_UNSPECIFIED;
	bt_conn_set_state(conn, BT_CONN_DISCONNECTED);
	bt_conn_unref(conn);
	/* Just a best-effort check if the scanner should be started. */
	err = bt_le_scan_user_remove(BT_LE_SCAN_USER_NONE);

	if (err) {
		LOG_WRN("Error while updating the scanner (%d)", err);
	}
}
#endif /* CONFIG_BT_CENTRAL */

/* Convert Legacy adv report evt_type field to adv props */
static uint8_t get_adv_props_legacy(uint8_t evt_type)
{
	switch (evt_type) {
	case BT_GAP_ADV_TYPE_ADV_IND:
		return BT_GAP_ADV_PROP_CONNECTABLE |
		       BT_GAP_ADV_PROP_SCANNABLE;

	case BT_GAP_ADV_TYPE_ADV_DIRECT_IND:
		return BT_GAP_ADV_PROP_CONNECTABLE |
		       BT_GAP_ADV_PROP_DIRECTED;

	case BT_GAP_ADV_TYPE_ADV_SCAN_IND:
		return BT_GAP_ADV_PROP_SCANNABLE;

	case BT_GAP_ADV_TYPE_ADV_NONCONN_IND:
		return 0;

	/* In legacy advertising report, we don't know if the scan
	 * response come from a connectable advertiser, so don't
	 * set connectable property bit.
	 */
	case BT_GAP_ADV_TYPE_SCAN_RSP:
		return BT_GAP_ADV_PROP_SCAN_RESPONSE |
		       BT_GAP_ADV_PROP_SCANNABLE;

	default:
		return 0;
	}
}

static void le_adv_recv(bt_addr_le_t *addr, struct bt_le_scan_recv_info *info,
			struct net_buf_simple *buf, uint16_t len)
{
	struct bt_le_scan_cb *listener, *next;
	struct net_buf_simple_state state;
	bt_addr_le_t id_addr;

	LOG_DBG("%s event %u, len %u, rssi %d dBm", bt_addr_le_str(addr), info->adv_type, len,
		info->rssi);

	if (!IS_ENABLED(CONFIG_BT_PRIVACY) && !IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY) &&
	    atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_EXPLICIT_SCAN) &&
	    (info->adv_props & BT_HCI_LE_ADV_PROP_DIRECT)) {
		LOG_DBG("Dropped direct adv report");
		return;
	}

	if (bt_addr_le_is_resolved(addr)) {
		bt_addr_le_copy_resolved(&id_addr, addr);
	} else if (addr->type == BT_HCI_PEER_ADDR_ANONYMOUS) {
		bt_addr_le_copy(&id_addr, BT_ADDR_LE_ANY);
	} else {
		bt_addr_le_copy(&id_addr,
				bt_lookup_id_addr(BT_ID_DEFAULT, addr));
	}

	if (scan_dev_found_cb) {
		net_buf_simple_save(buf, &state);

		buf->len = len;
		scan_dev_found_cb(&id_addr, info->rssi, info->adv_type, buf);

		net_buf_simple_restore(buf, &state);
	}

	info->addr = &id_addr;

	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&scan_cbs, listener, next, node) {
		if (listener->recv) {
			net_buf_simple_save(buf, &state);

			buf->len = len;
			listener->recv(info, buf);

			net_buf_simple_restore(buf, &state);
		}
	}

	/* Clear pointer to this stack frame before returning to calling function */
	info->addr = NULL;

#if defined(CONFIG_BT_CENTRAL)
	check_pending_conn(&id_addr, addr, info->adv_props);
#endif /* CONFIG_BT_CENTRAL */
}

#if defined(CONFIG_BT_EXT_ADV)
void bt_hci_le_scan_timeout(struct net_buf *buf)
{
	struct bt_le_scan_cb *listener, *next;

	int err = bt_le_scan_user_remove(BT_LE_SCAN_USER_EXPLICIT_SCAN);

	if (err) {
		k_yield();
		err = bt_le_scan_user_remove(BT_LE_SCAN_USER_EXPLICIT_SCAN);
	}

	if (err) {
		LOG_WRN("Could not stop the explicit scanner (%d)", err);
	}

	atomic_clear_bit(bt_dev.flags, BT_DEV_SCAN_LIMITED);
	atomic_clear_bit(bt_dev.flags, BT_DEV_RPA_VALID);

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

	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&scan_cbs, listener, next, node) {
		if (listener->timeout) {
			listener->timeout();
		}
	}
}

/* Convert Extended adv report evt_type field into adv type */
static uint8_t get_adv_type(uint8_t evt_type)
{
	switch (evt_type) {
	case (BT_HCI_LE_ADV_EVT_TYPE_CONN |
	      BT_HCI_LE_ADV_EVT_TYPE_SCAN |
	      BT_HCI_LE_ADV_EVT_TYPE_LEGACY):
		return BT_GAP_ADV_TYPE_ADV_IND;

	case (BT_HCI_LE_ADV_EVT_TYPE_CONN |
	      BT_HCI_LE_ADV_EVT_TYPE_DIRECT |
	      BT_HCI_LE_ADV_EVT_TYPE_LEGACY):
		return BT_GAP_ADV_TYPE_ADV_DIRECT_IND;

	case (BT_HCI_LE_ADV_EVT_TYPE_SCAN |
	      BT_HCI_LE_ADV_EVT_TYPE_LEGACY):
		return BT_GAP_ADV_TYPE_ADV_SCAN_IND;

	case BT_HCI_LE_ADV_EVT_TYPE_LEGACY:
		return BT_GAP_ADV_TYPE_ADV_NONCONN_IND;

	case (BT_HCI_LE_ADV_EVT_TYPE_SCAN_RSP |
	      BT_HCI_LE_ADV_EVT_TYPE_CONN |
	      BT_HCI_LE_ADV_EVT_TYPE_SCAN |
	      BT_HCI_LE_ADV_EVT_TYPE_LEGACY):
	case (BT_HCI_LE_ADV_EVT_TYPE_SCAN_RSP |
	      BT_HCI_LE_ADV_EVT_TYPE_SCAN |
	      BT_HCI_LE_ADV_EVT_TYPE_LEGACY):
		/* Scan response from connectable or non-connectable advertiser.
		 */
		return BT_GAP_ADV_TYPE_SCAN_RSP;

	default:
		return BT_GAP_ADV_TYPE_EXT_ADV;
	}
}

/* Convert Extended adv report PHY to GAP PHY */
static uint8_t get_ext_adv_coding_sel_phy(uint8_t hci_phy)
{
	/* Converts from Extended adv report PHY to BT_GAP_LE_PHY_*
	 * When Advertising Coding Selection (Host Support) is enabled
	 * the controller will return the advertising coding scheme which
	 * can be S=2 or S=8 data coding.
	 */
	switch (hci_phy) {
	case BT_HCI_LE_ADV_EVT_PHY_1M:
		return BT_GAP_LE_PHY_1M;
	case BT_HCI_LE_ADV_EVT_PHY_2M:
		return BT_GAP_LE_PHY_2M;
	case BT_HCI_LE_ADV_EVT_PHY_CODED_S8:
		return BT_GAP_LE_PHY_CODED_S8;
	case BT_HCI_LE_ADV_EVT_PHY_CODED_S2:
		return BT_GAP_LE_PHY_CODED_S2;
	default:
		return 0;
	}
}

/* Convert extended adv report evt_type field to adv props */
static uint16_t get_adv_props_extended(uint16_t evt_type)
{
	/* Converts from BT_HCI_LE_ADV_EVT_TYPE_* to BT_GAP_ADV_PROP_*
	 * The first 4 bits are the same (conn, scan, direct, scan_rsp).
	 * Bit 4 must be flipped as the meaning of 1 is opposite (legacy -> extended)
	 * The rest of the bits are zeroed out.
	 */
	return (evt_type ^ BT_HCI_LE_ADV_EVT_TYPE_LEGACY) & BIT_MASK(5);
}

static void create_ext_adv_info(struct bt_hci_evt_le_ext_advertising_info const *const evt,
				struct bt_le_scan_recv_info *const scan_info)
{
	if (IS_ENABLED(CONFIG_BT_EXT_ADV_CODING_SELECTION) &&
	    BT_FEAT_LE_ADV_CODING_SEL(bt_dev.le.features)) {
		scan_info->primary_phy = get_ext_adv_coding_sel_phy(evt->prim_phy);
		scan_info->secondary_phy = get_ext_adv_coding_sel_phy(evt->sec_phy);
	} else {
		scan_info->primary_phy = bt_get_phy(evt->prim_phy);
		scan_info->secondary_phy = bt_get_phy(evt->sec_phy);
	}

	scan_info->tx_power = evt->tx_power;
	scan_info->rssi = evt->rssi;
	scan_info->sid = evt->sid;
	scan_info->interval = sys_le16_to_cpu(evt->interval);
	scan_info->adv_type = get_adv_type(sys_le16_to_cpu(evt->evt_type));
	scan_info->adv_props = get_adv_props_extended(sys_le16_to_cpu(evt->evt_type));
}

void bt_hci_le_adv_ext_report(struct net_buf *buf)
{
	uint8_t num_reports = net_buf_pull_u8(buf);

	LOG_DBG("Adv number of reports %u", num_reports);

	while (num_reports--) {
		struct bt_hci_evt_le_ext_advertising_info *evt;
		struct bt_le_scan_recv_info scan_info;
		uint16_t data_status;
		uint16_t evt_type;
		bool is_report_complete;
		bool more_to_come;
		bool is_new_advertiser;

		if (!atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_EXPLICIT_SCAN)) {
			/* The application has not requested explicit scan, so it is not expecting
			 * advertising reports. Discard, and reset the reassembler if not inactive
			 * This is done in the loop as this flag can change between each iteration,
			 * and it is not uncommon that scanning is disabled in the callback called
			 * from le_adv_recv
			 */

			if (reassembling_advertiser.state != FRAG_ADV_INACTIVE) {
				reset_reassembling_advertiser();
			}

			break;
		}

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

		evt = net_buf_pull_mem(buf, sizeof(*evt));
		evt_type = sys_le16_to_cpu(evt->evt_type);
		data_status = BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS(evt_type);
		is_report_complete = data_status == BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_COMPLETE;
		more_to_come = data_status == BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_PARTIAL;

		if (evt->length > buf->len) {
			LOG_WRN("Adv report corrupted (wants %u out of %u)", evt->length, buf->len);

			net_buf_reset(buf);

			if (evt_type & BT_HCI_LE_ADV_EVT_TYPE_LEGACY) {
				return;
			}

			/* Start discarding irrespective of the `more_to_come` flag. We
			 * assume we may have lost a partial adv report in the truncated
			 * data.
			 */
			reassembling_advertiser.state = FRAG_ADV_DISCARDING;

			return;
		}

		if (evt_type & BT_HCI_LE_ADV_EVT_TYPE_LEGACY) {
			/* Legacy advertising reports are complete.
			 * Create event immediately.
			 */
			create_ext_adv_info(evt, &scan_info);
			le_adv_recv(&evt->addr, &scan_info, &buf->b, evt->length);
			goto cont;
		}

		is_new_advertiser = reassembling_advertiser.state == FRAG_ADV_INACTIVE ||
				    !fragmented_advertisers_equal(&reassembling_advertiser,
								  &evt->addr, evt->sid);

		if (is_new_advertiser && is_report_complete) {
			/* Only advertising report from this advertiser.
			 * Create event immediately.
			 */
			create_ext_adv_info(evt, &scan_info);
			le_adv_recv(&evt->addr, &scan_info, &buf->b, evt->length);
			goto cont;
		}

		if (is_new_advertiser && reassembling_advertiser.state == FRAG_ADV_REASSEMBLING) {
			LOG_WRN("Received an incomplete advertising report while reassembling "
				"advertising reports from a different advertiser. The advertising "
				"report is discarded and future scan results may be incomplete. "
				"Interleaving of fragmented advertising reports from different "
				"advertisers is not yet supported.");
			goto cont;
		}

		if (data_status == BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_INCOMPLETE) {
			/* Got HCI_LE_Extended_Advertising_Report: Incomplete, data truncated, no
			 * more to come. This means the Controller is aborting the reassembly. We
			 * discard the partially received report, and the application is not
			 * notified.
			 *
			 * See the Controller's documentation for possible reasons for aborting.
			 * Hint: CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX.
			 */
			LOG_DBG("Discarding incomplete advertisement.");
			reset_reassembling_advertiser();
			goto cont;
		}

		if (is_new_advertiser) {
			/* We are not reassembling reports from an advertiser and
			 * this is the first report from the new advertiser.
			 * Initialize the new advertiser.
			 */
			__ASSERT_NO_MSG(reassembling_advertiser.state == FRAG_ADV_INACTIVE);
			init_reassembling_advertiser(&evt->addr, evt->sid);
		}

		if (evt->length + ext_scan_buf.len > ext_scan_buf.size) {
			/* The report does not fit in the reassemby buffer
			 * Discard this and future reports from the advertiser.
			 */
			reassembling_advertiser.state = FRAG_ADV_DISCARDING;
		}

		if (reassembling_advertiser.state == FRAG_ADV_DISCARDING) {
			if (!more_to_come) {
				/* We do no longer need to keep track of this advertiser as
				 * all the expected data is received.
				 */
				reset_reassembling_advertiser();
			}
			goto cont;
		}

		net_buf_simple_add_mem(&ext_scan_buf, buf->data, evt->length);
		if (more_to_come) {
			/* The controller will send additional reports to be reassembled */
			continue;
		}

		/* No more data coming from the controller.
		 * Create event.
		 */
		__ASSERT_NO_MSG(is_report_complete);
		create_ext_adv_info(evt, &scan_info);
		le_adv_recv(&evt->addr, &scan_info, &ext_scan_buf, ext_scan_buf.len);

		/* We do no longer need to keep track of this advertiser. */
		reset_reassembling_advertiser();

cont:
		net_buf_pull(buf, evt->length);
	}
}

#if defined(CONFIG_BT_PER_ADV_SYNC)
static void per_adv_sync_delete(struct bt_le_per_adv_sync *per_adv_sync)
{
	atomic_clear(per_adv_sync->flags);
}

static struct bt_le_per_adv_sync *per_adv_sync_new(void)
{
	struct bt_le_per_adv_sync *per_adv_sync = NULL;

	for (int i = 0; i < ARRAY_SIZE(per_adv_sync_pool); i++) {
		if (!atomic_test_bit(per_adv_sync_pool[i].flags,
				     BT_PER_ADV_SYNC_CREATED)) {
			per_adv_sync = &per_adv_sync_pool[i];
			break;
		}
	}

	if (!per_adv_sync) {
		return NULL;
	}

	(void)memset(per_adv_sync, 0, sizeof(*per_adv_sync));
	atomic_set_bit(per_adv_sync->flags, BT_PER_ADV_SYNC_CREATED);

#if CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0
	net_buf_simple_init_with_data(&per_adv_sync->reassembly,
				      per_adv_sync->reassembly_data,
				      CONFIG_BT_PER_ADV_SYNC_BUF_SIZE);
	net_buf_simple_reset(&per_adv_sync->reassembly);
#endif /* CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0 */

	return per_adv_sync;
}

static struct bt_le_per_adv_sync *get_pending_per_adv_sync(void)
{
	for (int i = 0; i < ARRAY_SIZE(per_adv_sync_pool); i++) {
		if (atomic_test_bit(per_adv_sync_pool[i].flags,
				    BT_PER_ADV_SYNC_SYNCING)) {
			return &per_adv_sync_pool[i];
		}
	}

	return NULL;
}

void bt_periodic_sync_disable(void)
{
	for (size_t i = 0; i < ARRAY_SIZE(per_adv_sync_pool); i++) {
		per_adv_sync_delete(&per_adv_sync_pool[i]);
	}
}

struct bt_le_per_adv_sync *bt_hci_per_adv_sync_lookup_handle(uint16_t handle)
{
	for (int i = 0; i < ARRAY_SIZE(per_adv_sync_pool); i++) {
		if (per_adv_sync_pool[i].handle == handle &&
		    atomic_test_bit(per_adv_sync_pool[i].flags,
				    BT_PER_ADV_SYNC_SYNCED)) {
			return &per_adv_sync_pool[i];
		}
	}

	return NULL;
}

void bt_hci_le_per_adv_report_recv(struct bt_le_per_adv_sync *per_adv_sync,
				   struct net_buf_simple *buf,
				   const struct bt_le_per_adv_sync_recv_info *info)
{
	struct net_buf_simple_state state;
	struct bt_le_per_adv_sync_cb *listener;

	SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) {
		if (listener->recv) {
			net_buf_simple_save(buf, &state);
			listener->recv(per_adv_sync, info, buf);
			net_buf_simple_restore(buf, &state);
		}
	}
}

#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) && (CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0)
static void bt_hci_le_per_adv_report_recv_failure(struct bt_le_per_adv_sync *per_adv_sync,
				   const struct bt_le_per_adv_sync_recv_info *info)
{
	struct bt_le_per_adv_sync_cb *listener;

	SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) {
		if (listener->recv) {
			listener->recv(per_adv_sync, info, NULL);
		}
	}
}
#endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) && (CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0) */

static void bt_hci_le_per_adv_report_common(struct net_buf *buf)
{
#if defined(CONFIG_BT_PER_ADV_SYNC_RSP)
	struct bt_hci_evt_le_per_advertising_report_v2 *evt;
#else
	struct bt_hci_evt_le_per_advertising_report *evt;
#endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) */

	struct bt_le_per_adv_sync *per_adv_sync;
	struct bt_le_per_adv_sync_recv_info info;

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

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

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

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

	if (atomic_test_bit(per_adv_sync->flags,
			    BT_PER_ADV_SYNC_RECV_DISABLED)) {
		LOG_ERR("Received PA adv report when receive disabled");
		return;
	}

	info.tx_power = evt->tx_power;
	info.rssi = evt->rssi;
	info.cte_type = bt_get_df_cte_type(evt->cte_type);
	info.addr = &per_adv_sync->addr;
	info.sid = per_adv_sync->sid;

#if defined(CONFIG_BT_PER_ADV_SYNC_RSP)
	info.periodic_event_counter = sys_le16_to_cpu(evt->periodic_event_counter);
	info.subevent = evt->subevent;
#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */

	if (!per_adv_sync->report_truncated) {
#if CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0
		if (net_buf_simple_tailroom(&per_adv_sync->reassembly) < evt->length) {
			/* The buffer is too small for the entire report. Drop it */
			LOG_WRN("Buffer is too small to reassemble the report. "
				"Use CONFIG_BT_PER_ADV_SYNC_BUF_SIZE to change "
				"the buffer size.");

			per_adv_sync->report_truncated = true;
			net_buf_simple_reset(&per_adv_sync->reassembly);
			return;
		}

		if (evt->data_status == BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_COMPLETE) {
			if (per_adv_sync->reassembly.len == 0) {
				/* We have not received any partial data before.
				 * This buffer can be forwarded without an extra copy.
				 */
				bt_hci_le_per_adv_report_recv(per_adv_sync, &buf->b, &info);
			} else {
				net_buf_simple_add_mem(&per_adv_sync->reassembly,
						       buf->data, evt->length);
				bt_hci_le_per_adv_report_recv(per_adv_sync,
							      &per_adv_sync->reassembly, &info);
				net_buf_simple_reset(&per_adv_sync->reassembly);
			}
		} else if (evt->data_status == BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_INCOMPLETE) {
			LOG_DBG("Received incomplete advertising data. "
				"Advertising report dropped.");

			net_buf_simple_reset(&per_adv_sync->reassembly);

		} else if (evt->data_status == BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_PARTIAL) {
			net_buf_simple_add_mem(&per_adv_sync->reassembly, buf->data, evt->length);
#if defined(CONFIG_BT_PER_ADV_SYNC_RSP)
		} else if (evt->data_status == BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_RX_FAILED &&
			   per_adv_sync->num_subevents) {
			bt_hci_le_per_adv_report_recv_failure(per_adv_sync, &info);
#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */
		} else {
			__ASSERT(false, "Invalid data status 0x%02X", evt->data_status);
		}
#else /* CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0 */
		if (evt->data_status == BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_COMPLETE) {
			bt_hci_le_per_adv_report_recv(per_adv_sync, &buf->b, &info);
		} else {
			per_adv_sync->report_truncated = true;
		}
#endif /* CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0 */
	} else if (evt->data_status == BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_COMPLETE) {
		per_adv_sync->report_truncated = false;
	}
}

void bt_hci_le_per_adv_report(struct net_buf *buf)
{
	if (IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_RSP)) {
		LOG_ERR("The controller shall raise the latest unmasked version of the event");

		return;
	}

	bt_hci_le_per_adv_report_common(buf);
}

static int per_adv_sync_terminate(uint16_t handle)
{
	struct bt_hci_cp_le_per_adv_terminate_sync *cp;
	struct net_buf *buf;

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

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

	cp->handle = sys_cpu_to_le16(handle);

	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_PER_ADV_TERMINATE_SYNC, buf,
				    NULL);
}

static void per_adv_sync_terminated(struct bt_le_per_adv_sync *per_adv_sync,
				    uint8_t reason)
{
	/* Terminate the PA sync and notify app */
	const struct bt_le_per_adv_sync_term_info term_info = {
		.addr = &per_adv_sync->addr,
		.sid = per_adv_sync->sid,
		.reason = reason,
	};
	struct bt_le_per_adv_sync_cb *listener;

	/* Deleting before callback, so the caller will be able
	 * to restart sync in the callback.
	 */
	per_adv_sync_delete(per_adv_sync);

	SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) {
		if (listener->term) {
			listener->term(per_adv_sync, &term_info);
		}
	}
}

static void bt_hci_le_per_adv_sync_established_common(struct net_buf *buf)
{
#if defined(CONFIG_BT_PER_ADV_SYNC_RSP)
	struct bt_hci_evt_le_per_adv_sync_established_v2 *evt =
		(struct bt_hci_evt_le_per_adv_sync_established_v2 *)buf->data;
#else
	struct bt_hci_evt_le_per_adv_sync_established *evt =
		(struct bt_hci_evt_le_per_adv_sync_established *)buf->data;
#endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) */

	struct bt_le_per_adv_sync_synced_info sync_info;
	struct bt_le_per_adv_sync *pending_per_adv_sync;
	struct bt_le_per_adv_sync_cb *listener;
	bt_addr_le_t id_addr;
	bool unexpected_evt;
	int err;

	pending_per_adv_sync = get_pending_per_adv_sync();

	if (pending_per_adv_sync) {
		atomic_clear_bit(pending_per_adv_sync->flags, BT_PER_ADV_SYNC_SYNCING);
		err = bt_le_scan_user_remove(BT_LE_SCAN_USER_PER_SYNC);

		if (err) {
			LOG_ERR("Could not update scan (%d)", err);
		}
	}

	if (evt->status == BT_HCI_ERR_OP_CANCELLED_BY_HOST) {
		/* Cancelled locally, don't call CB */
		if (pending_per_adv_sync) {
			per_adv_sync_delete(pending_per_adv_sync);
		} else {
			LOG_ERR("Unexpected per adv sync cancelled event");
		}

		return;
	}

	if (bt_addr_le_is_resolved(&evt->adv_addr)) {
		bt_addr_le_copy_resolved(&id_addr, &evt->adv_addr);
	} else {
		bt_addr_le_copy(&id_addr,
				bt_lookup_id_addr(BT_ID_DEFAULT,
						  &evt->adv_addr));
	}

	if (!pending_per_adv_sync ||
	    (!atomic_test_bit(pending_per_adv_sync->flags,
			      BT_PER_ADV_SYNC_SYNCING_USE_LIST) &&
	     ((pending_per_adv_sync->sid != evt->sid) ||
	      !bt_addr_le_eq(&pending_per_adv_sync->addr, &id_addr)))) {
		LOG_ERR("Unexpected per adv sync established event");
		/* Request terminate of pending periodic advertising in controller */
		per_adv_sync_terminate(sys_le16_to_cpu(evt->handle));

		unexpected_evt = true;
	} else {
		unexpected_evt = false;
	}

	if (unexpected_evt || evt->status != BT_HCI_ERR_SUCCESS) {
		if (pending_per_adv_sync) {
			const uint8_t reason = unexpected_evt ? BT_HCI_ERR_UNSPECIFIED
							      : evt->status;

			if (atomic_test_bit(pending_per_adv_sync->flags,
					    BT_PER_ADV_SYNC_SYNCING_USE_LIST)) {
				/* Update the addr and sid for the callback
				 * Already set if not using the sync list
				 */
				bt_addr_le_copy(&pending_per_adv_sync->addr,
						&id_addr);
				pending_per_adv_sync->sid = evt->sid;
			}

			per_adv_sync_terminated(pending_per_adv_sync, reason);
		}
		return;
	}

	pending_per_adv_sync->report_truncated = false;

	atomic_set_bit(pending_per_adv_sync->flags, BT_PER_ADV_SYNC_SYNCED);

	pending_per_adv_sync->handle = sys_le16_to_cpu(evt->handle);
	pending_per_adv_sync->interval = sys_le16_to_cpu(evt->interval);
	pending_per_adv_sync->clock_accuracy =
		sys_le16_to_cpu(evt->clock_accuracy);
	pending_per_adv_sync->phy = bt_get_phy(evt->phy);

	memset(&sync_info, 0, sizeof(sync_info));
	sync_info.interval = pending_per_adv_sync->interval;
	sync_info.phy = pending_per_adv_sync->phy;

	if (atomic_test_bit(pending_per_adv_sync->flags,
			    BT_PER_ADV_SYNC_SYNCING_USE_LIST)) {
		/* Now we know which address and SID we synchronized to. */
		pending_per_adv_sync->sid = evt->sid;

		if (bt_addr_le_is_resolved(&pending_per_adv_sync->addr)) {
			bt_addr_le_copy_resolved(&pending_per_adv_sync->addr,
						 &id_addr);
		} else {
			bt_addr_le_copy(&pending_per_adv_sync->addr, &id_addr);
		}
	}

	sync_info.addr = &pending_per_adv_sync->addr;
	sync_info.sid = pending_per_adv_sync->sid;
#if defined(CONFIG_BT_PER_ADV_SYNC_RSP)
	sync_info.num_subevents = evt->num_subevents;
	sync_info.subevent_interval = evt->subevent_interval;
	sync_info.response_slot_delay = evt->response_slot_delay;
	sync_info.response_slot_spacing = evt->response_slot_spacing;

	pending_per_adv_sync->num_subevents = evt->num_subevents;
	pending_per_adv_sync->subevent_interval = evt->subevent_interval;
	pending_per_adv_sync->response_slot_delay = evt->response_slot_delay;
	pending_per_adv_sync->response_slot_spacing = evt->response_slot_spacing;
#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */

	sync_info.recv_enabled =
		!atomic_test_bit(pending_per_adv_sync->flags,
				 BT_PER_ADV_SYNC_RECV_DISABLED);

	SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) {
		if (listener->synced) {
			listener->synced(pending_per_adv_sync, &sync_info);
		}
	}
}

void bt_hci_le_per_adv_sync_established(struct net_buf *buf)
{
	if (IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_RSP)) {
		LOG_ERR("The controller shall raise the latest unmasked version of the event");

		return;
	}

	bt_hci_le_per_adv_sync_established_common(buf);
}

#if defined(CONFIG_BT_PER_ADV_SYNC_RSP)
int bt_le_per_adv_sync_subevent(struct bt_le_per_adv_sync *per_adv_sync,
				struct bt_le_per_adv_sync_subevent_params *params)
{
	struct bt_hci_cp_le_set_pawr_sync_subevent *cp;
	struct net_buf *buf;

	if (params->num_subevents > BT_HCI_PAWR_SUBEVENT_MAX) {
		return -EINVAL;
	}

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_PER_ADV_SYNC_SUBEVENT,
				sizeof(*cp) + params->num_subevents);

	if (!buf) {
		return -ENOBUFS;
	}

	cp = net_buf_add(buf, sizeof(*cp));
	(void)memset(cp, 0, sizeof(*cp));
	cp->sync_handle = sys_cpu_to_le16(per_adv_sync->handle);
	cp->periodic_adv_properties = sys_cpu_to_le16(params->properties);
	cp->num_subevents = params->num_subevents;
	net_buf_add_mem(buf, params->subevents, cp->num_subevents);

	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_PER_ADV_SYNC_SUBEVENT, buf, NULL);
}

int bt_le_per_adv_set_response_data(struct bt_le_per_adv_sync *per_adv_sync,
				    const struct bt_le_per_adv_response_params *param,
				    const struct net_buf_simple *data)
{
	struct bt_hci_cp_le_set_pawr_response_data *cp;
	struct net_buf *buf;

	if (per_adv_sync->num_subevents == 0) {
		return -EINVAL;
	}

	if (param->request_subevent >= per_adv_sync->num_subevents) {
		return -EINVAL;
	}

	if (param->response_subevent >= per_adv_sync->num_subevents) {
		return -EINVAL;
	}

	if (data->len > 247) {
		return -EINVAL;
	}

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_PER_ADV_RESPONSE_DATA,
				sizeof(*cp) + data->len);

	if (!buf) {
		return -ENOBUFS;
	}

	cp = net_buf_add(buf, sizeof(*cp));
	(void)memset(cp, 0, sizeof(*cp));
	cp->sync_handle = sys_cpu_to_le16(per_adv_sync->handle);
	cp->request_event = sys_cpu_to_le16(param->request_event);
	cp->request_subevent = param->request_subevent;
	cp->response_subevent = param->response_subevent;
	cp->response_slot = param->response_slot;
	cp->response_data_length = data->len;

	net_buf_add_mem(buf, data->data, cp->response_data_length);

	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_PER_ADV_RESPONSE_DATA, buf, NULL);
}
#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */

void bt_hci_le_per_adv_sync_lost(struct net_buf *buf)
{
	struct bt_hci_evt_le_per_adv_sync_lost *evt =
		(struct bt_hci_evt_le_per_adv_sync_lost *)buf->data;
	struct bt_le_per_adv_sync *per_adv_sync;

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

	if (!per_adv_sync) {
		LOG_ERR("Unknown handle 0x%04Xfor periodic adv sync lost",
			sys_le16_to_cpu(evt->handle));
		return;
	}

	/* There is no status in the per. adv. sync lost event */
	per_adv_sync_terminated(per_adv_sync, BT_HCI_ERR_UNSPECIFIED);
}

#if defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER)
static uint8_t conn_past_modes[CONFIG_BT_MAX_CONN];
static uint8_t default_past_mode;

static void past_disconnected_cb(struct bt_conn *conn, uint8_t reason)
{
	/* The core spec does not explicit state that the mode of a connection handle is cleared on
	 * disconnect, but let's assume it is.
	 */
	conn_past_modes[bt_conn_index(conn)] = BT_HCI_LE_PAST_MODE_NO_SYNC;
}

BT_CONN_CB_DEFINE(past_conn_callbacks) = {
	.disconnected = past_disconnected_cb,
};

static void bt_hci_le_past_received_common(struct net_buf *buf)
{
#if defined(CONFIG_BT_PER_ADV_SYNC_RSP)
	struct bt_hci_evt_le_past_received_v2 *evt =
		(struct bt_hci_evt_le_past_received_v2 *)buf->data;
#else
	struct bt_hci_evt_le_past_received *evt =
		(struct bt_hci_evt_le_past_received *)buf->data;
#endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) */

	struct bt_le_per_adv_sync_synced_info sync_info;
	struct bt_le_per_adv_sync_cb *listener;
	struct bt_le_per_adv_sync *per_adv_sync;
	bt_addr_le_t id_addr;

	if (evt->status) {
		/* No sync created, don't notify app */
		LOG_DBG("PAST receive failed with status 0x%02X %s",
			evt->status, bt_hci_err_to_str(evt->status));
		return;
	}

	sync_info.conn = bt_conn_lookup_handle(
				sys_le16_to_cpu(evt->conn_handle),
				BT_CONN_TYPE_LE);

	if (!sync_info.conn) {
		LOG_ERR("Could not lookup connection handle from PAST");
		per_adv_sync_terminate(sys_le16_to_cpu(evt->sync_handle));
		return;
	}

	per_adv_sync = per_adv_sync_new();
	if (!per_adv_sync) {
		LOG_WRN("Could not allocate new PA sync from PAST");
		per_adv_sync_terminate(sys_le16_to_cpu(evt->sync_handle));
		bt_conn_unref(sync_info.conn);
		return;
	}

	atomic_set_bit(per_adv_sync->flags, BT_PER_ADV_SYNC_SYNCED);

	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(BT_ID_DEFAULT, &evt->addr));
	}

	per_adv_sync->handle = sys_le16_to_cpu(evt->sync_handle);
	per_adv_sync->interval = sys_le16_to_cpu(evt->interval);
	per_adv_sync->clock_accuracy = sys_le16_to_cpu(evt->clock_accuracy);
	per_adv_sync->phy = bt_get_phy(evt->phy);
	bt_addr_le_copy(&per_adv_sync->addr, &id_addr);
	per_adv_sync->sid = evt->adv_sid;

#if defined(CONFIG_BT_PER_ADV_SYNC_RSP)
	per_adv_sync->num_subevents = evt->num_subevents;
	per_adv_sync->subevent_interval = evt->subevent_interval;
	per_adv_sync->response_slot_delay = evt->response_slot_delay;
	per_adv_sync->response_slot_spacing = evt->response_slot_spacing;
#endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) */

	sync_info.interval = per_adv_sync->interval;
	sync_info.phy = per_adv_sync->phy;
	sync_info.addr = &per_adv_sync->addr;
	sync_info.sid = per_adv_sync->sid;
	sync_info.service_data = sys_le16_to_cpu(evt->service_data);

	const uint8_t mode = conn_past_modes[bt_conn_index(sync_info.conn)];

	if (mode == BT_HCI_LE_PAST_MODE_NO_SYNC) {
		/* Use the default parameter mode as the conn specific mode is not set */
		sync_info.recv_enabled =
			default_past_mode == BT_HCI_LE_PAST_MODE_SYNC ||
			default_past_mode == BT_HCI_LE_PAST_MODE_SYNC_FILTER_DUPLICATES;
	} else {
		sync_info.recv_enabled = mode == BT_HCI_LE_PAST_MODE_SYNC ||
					 mode == BT_HCI_LE_PAST_MODE_SYNC_FILTER_DUPLICATES;
	}

#if defined(CONFIG_BT_PER_ADV_SYNC_RSP)
	sync_info.num_subevents =  per_adv_sync->num_subevents;
	sync_info.subevent_interval =  per_adv_sync->subevent_interval;
	sync_info.response_slot_delay =  per_adv_sync->response_slot_delay;
	sync_info.response_slot_spacing =  per_adv_sync->response_slot_spacing;
#endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) */

	SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) {
		if (listener->synced) {
			listener->synced(per_adv_sync, &sync_info);
		}
	}

	bt_conn_unref(sync_info.conn);
}

void bt_hci_le_past_received(struct net_buf *buf)
{
	if (IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_RSP)) {
		LOG_ERR("The controller shall raise the latest unmasked version of the event");

		return;
	}

	bt_hci_le_past_received_common(buf);
}

#if defined(CONFIG_BT_PER_ADV_SYNC_RSP)
void bt_hci_le_past_received_v2(struct net_buf *buf)
{
	bt_hci_le_past_received_common(buf);
}
#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */
#endif /* CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER */

#if defined(CONFIG_BT_PER_ADV_SYNC_RSP)
void bt_hci_le_per_adv_sync_established_v2(struct net_buf *buf)
{
	bt_hci_le_per_adv_sync_established_common(buf);
}

void bt_hci_le_per_adv_report_v2(struct net_buf *buf)
{
	bt_hci_le_per_adv_report_common(buf);
}
#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */

#if defined(CONFIG_BT_ISO_BROADCAST)
void bt_hci_le_biginfo_adv_report(struct net_buf *buf)
{
	struct bt_hci_evt_le_biginfo_adv_report *evt;
	struct bt_le_per_adv_sync *per_adv_sync;
	struct bt_le_per_adv_sync_cb *listener;
	struct bt_iso_biginfo biginfo;

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

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

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

	biginfo.addr = &per_adv_sync->addr;
	biginfo.sid = per_adv_sync->sid;
	biginfo.num_bis = evt->num_bis;
	biginfo.sub_evt_count = evt->nse;
	biginfo.iso_interval = sys_le16_to_cpu(evt->iso_interval);
	biginfo.burst_number = evt->bn;
	biginfo.offset = evt->pto;
	biginfo.rep_count = evt->irc;
	biginfo.max_pdu = sys_le16_to_cpu(evt->max_pdu);
	biginfo.sdu_interval = sys_get_le24(evt->sdu_interval);
	biginfo.max_sdu = sys_le16_to_cpu(evt->max_sdu);
	biginfo.phy = bt_get_phy(evt->phy);
	biginfo.framing = evt->framing;
	biginfo.encryption = evt->encryption ? true : false;

	SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) {
		if (listener->biginfo) {
			listener->biginfo(per_adv_sync, &biginfo);
		}
	}
}
#endif /* CONFIG_BT_ISO_BROADCAST */
#if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX)
static void bt_hci_le_df_connectionless_iq_report_common(uint8_t event, struct net_buf *buf)
{
	int err;

	struct bt_df_per_adv_sync_iq_samples_report cte_report;
	struct bt_le_per_adv_sync *per_adv_sync;
	struct bt_le_per_adv_sync_cb *listener;

	if (event == BT_HCI_EVT_LE_CONNECTIONLESS_IQ_REPORT) {
		err = hci_df_prepare_connectionless_iq_report(buf, &cte_report, &per_adv_sync);
		if (err) {
			LOG_ERR("Prepare CTE conn IQ report failed %d", err);
			return;
		}
	} else if (IS_ENABLED(CONFIG_BT_DF_VS_CL_IQ_REPORT_16_BITS_IQ_SAMPLES) &&
		   event == BT_HCI_EVT_VS_LE_CONNECTIONLESS_IQ_REPORT) {
		err = hci_df_vs_prepare_connectionless_iq_report(buf, &cte_report, &per_adv_sync);
		if (err) {
			LOG_ERR("Prepare CTE conn IQ report failed %d", err);
			return;
		}
	} else {
		LOG_ERR("Unhandled VS connectionless IQ report");
		return;
	}

	SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) {
		if (listener->cte_report_cb) {
			listener->cte_report_cb(per_adv_sync, &cte_report);
		}
	}
}

void bt_hci_le_df_connectionless_iq_report(struct net_buf *buf)
{
	bt_hci_le_df_connectionless_iq_report_common(BT_HCI_EVT_LE_CONNECTIONLESS_IQ_REPORT, buf);
}

#if defined(CONFIG_BT_DF_VS_CL_IQ_REPORT_16_BITS_IQ_SAMPLES)
void bt_hci_le_vs_df_connectionless_iq_report(struct net_buf *buf)
{
	bt_hci_le_df_connectionless_iq_report_common(BT_HCI_EVT_VS_LE_CONNECTIONLESS_IQ_REPORT,
						     buf);
}
#endif /* CONFIG_BT_DF_VS_CL_IQ_REPORT_16_BITS_IQ_SAMPLES */
#endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX */
#endif /* defined(CONFIG_BT_PER_ADV_SYNC) */
#endif /* defined(CONFIG_BT_EXT_ADV) */

void bt_hci_le_adv_report(struct net_buf *buf)
{
	uint8_t num_reports = net_buf_pull_u8(buf);
	struct bt_hci_evt_le_advertising_info *evt;

	LOG_DBG("Adv number of reports %u",  num_reports);

	while (num_reports--) {
		struct bt_le_scan_recv_info adv_info;

		if (!atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_EXPLICIT_SCAN)) {
			/* The application has not requested explicit scan, so it is not expecting
			 * advertising reports. Discard.
			 * This is done in the loop as this flag can change between each iteration,
			 * and it is not uncommon that scanning is disabled in the callback called
			 * from le_adv_recv
			 */

			break;
		}

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

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

		if (buf->len < evt->length + sizeof(adv_info.rssi)) {
			LOG_ERR("Unexpected end of buffer");
			break;
		}

		adv_info.primary_phy = BT_GAP_LE_PHY_1M;
		adv_info.secondary_phy = 0;
		adv_info.tx_power = BT_GAP_TX_POWER_INVALID;
		adv_info.rssi = evt->data[evt->length];
		adv_info.sid = BT_GAP_SID_INVALID;
		adv_info.interval = 0U;

		adv_info.adv_type = evt->evt_type;
		adv_info.adv_props = get_adv_props_legacy(evt->evt_type);

		le_adv_recv(&evt->addr, &adv_info, &buf->b, evt->length);

		net_buf_pull(buf, evt->length + sizeof(adv_info.rssi));
	}
}

static bool valid_le_scan_param(const struct bt_le_scan_param *param)
{
	if (IS_ENABLED(CONFIG_BT_PRIVACY) &&
	    param->type == BT_LE_SCAN_TYPE_ACTIVE &&
	    param->timeout != 0) {
		/* This is marked as not supported as a stopgap until the (scan,
		 * adv, init) roles are reworked into proper state machines.
		 *
		 * Having proper state machines is necessary to be able to
		 * suspend all roles that use the (resolvable) private address,
		 * update the RPA and resume them again with the right
		 * parameters.
		 *
		 * Else we lower the privacy of the device as either the RPA
		 * update will fail or the scanner will not use the newly
		 * generated RPA.
		 */
		return false;
	}

	if (param->type != BT_LE_SCAN_TYPE_PASSIVE &&
	    param->type != BT_LE_SCAN_TYPE_ACTIVE) {
		return false;
	}

	if (param->options & ~(BT_LE_SCAN_OPT_FILTER_DUPLICATE |
			       BT_LE_SCAN_OPT_FILTER_ACCEPT_LIST |
			       BT_LE_SCAN_OPT_CODED |
			       BT_LE_SCAN_OPT_NO_1M)) {
		return false;
	}

	if (param->interval < 0x0004 || param->interval > 0x4000) {
		return false;
	}

	if (param->window < 0x0004 || param->window > 0x4000) {
		return false;
	}

	if (param->window > param->interval) {
		return false;
	}

	return true;
}

int bt_le_scan_start(const struct bt_le_scan_param *param, bt_le_scan_cb_t cb)
{
	int err;

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

	/* Check that the parameters have valid values */
	if (!valid_le_scan_param(param)) {
		return -EINVAL;
	}

	if (param->type && !bt_id_scan_random_addr_check()) {
		return -EINVAL;
	}

	/* Prevent multiple threads to try to enable explicit scanning at the same time.
	 * That could lead to unwanted overwriting of scan_state.explicit_scan_param.
	 */
	err = k_mutex_lock(&scan_state.scan_explicit_params_mutex, K_NO_WAIT);

	if (err) {
		return err;
	}

	err = scan_check_if_state_allowed(BT_LE_SCAN_USER_EXPLICIT_SCAN);

	if (err) {
		k_mutex_unlock(&scan_state.scan_explicit_params_mutex);
		return err;
	}

	/* store the parameters that were used to start the scanner */
	memcpy(&scan_state.explicit_scan_param, param,
	       sizeof(scan_state.explicit_scan_param));

	scan_dev_found_cb = cb;
	err = bt_le_scan_user_add(BT_LE_SCAN_USER_EXPLICIT_SCAN);
	k_mutex_unlock(&scan_state.scan_explicit_params_mutex);

	return err;
}

int bt_le_scan_stop(void)
{
	bt_scan_softreset();
	scan_dev_found_cb = NULL;

	if (IS_ENABLED(CONFIG_BT_EXT_ADV) &&
	    atomic_test_and_clear_bit(bt_dev.flags, BT_DEV_SCAN_LIMITED)) {
		atomic_clear_bit(bt_dev.flags, BT_DEV_RPA_VALID);

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

	return bt_le_scan_user_remove(BT_LE_SCAN_USER_EXPLICIT_SCAN);
}

int bt_le_scan_cb_register(struct bt_le_scan_cb *cb)
{
	if (sys_slist_find(&scan_cbs, &cb->node, NULL)) {
		return -EEXIST;
	}

	sys_slist_append(&scan_cbs, &cb->node);

	return 0;
}

void bt_le_scan_cb_unregister(struct bt_le_scan_cb *cb)
{
	sys_slist_find_and_remove(&scan_cbs, &cb->node);
}

#if defined(CONFIG_BT_PER_ADV_SYNC)
uint8_t bt_le_per_adv_sync_get_index(struct bt_le_per_adv_sync *per_adv_sync)
{
	ptrdiff_t index = per_adv_sync - per_adv_sync_pool;

	__ASSERT(index >= 0 && ARRAY_SIZE(per_adv_sync_pool) > index,
		 "Invalid per_adv_sync pointer");
	return (uint8_t)index;
}

struct bt_le_per_adv_sync *bt_le_per_adv_sync_lookup_index(uint8_t index)
{
	if (index >= ARRAY_SIZE(per_adv_sync_pool)) {
		return NULL;
	}

	return &per_adv_sync_pool[index];
}

int bt_le_per_adv_sync_get_info(struct bt_le_per_adv_sync *per_adv_sync,
				struct bt_le_per_adv_sync_info *info)
{
	CHECKIF(per_adv_sync == NULL || info == NULL) {
		return -EINVAL;
	}

	bt_addr_le_copy(&info->addr, &per_adv_sync->addr);
	info->sid = per_adv_sync->sid;
	info->phy = per_adv_sync->phy;
	info->interval = per_adv_sync->interval;

	return 0;
}

struct bt_le_per_adv_sync *bt_le_per_adv_sync_lookup_addr(const bt_addr_le_t *adv_addr,
							  uint8_t sid)
{
	for (int i = 0; i < ARRAY_SIZE(per_adv_sync_pool); i++) {
		struct bt_le_per_adv_sync *sync = &per_adv_sync_pool[i];

		if (!atomic_test_bit(per_adv_sync_pool[i].flags,
				     BT_PER_ADV_SYNC_CREATED)) {
			continue;
		}

		if (bt_addr_le_eq(&sync->addr, adv_addr) && sync->sid == sid) {
			return sync;
		}
	}

	return NULL;
}

int bt_le_per_adv_sync_create(const struct bt_le_per_adv_sync_param *param,
			      struct bt_le_per_adv_sync **out_sync)
{
	struct bt_hci_cp_le_per_adv_create_sync *cp;
	struct net_buf *buf;
	struct bt_le_per_adv_sync *per_adv_sync;
	int err;

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

	if (get_pending_per_adv_sync()) {
		return -EBUSY;
	}

	if (param->sid > BT_GAP_SID_MAX ||
		   param->skip > BT_GAP_PER_ADV_MAX_SKIP ||
		   param->timeout > BT_GAP_PER_ADV_MAX_TIMEOUT ||
		   param->timeout < BT_GAP_PER_ADV_MIN_TIMEOUT) {
		return -EINVAL;
	}

	per_adv_sync = per_adv_sync_new();
	if (!per_adv_sync) {
		return -ENOMEM;
	}

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

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

	if (param->options & BT_LE_PER_ADV_SYNC_OPT_USE_PER_ADV_LIST) {
		atomic_set_bit(per_adv_sync->flags,
			       BT_PER_ADV_SYNC_SYNCING_USE_LIST);

		cp->options |= BT_HCI_LE_PER_ADV_CREATE_SYNC_FP_USE_LIST;
	} else {
		/* If BT_LE_PER_ADV_SYNC_OPT_USE_PER_ADV_LIST is set, then the
		 * address and SID are ignored by the controller, so we only
		 * copy/assign them in case that the periodic advertising list
		 * is not used.
		 */
		bt_addr_le_copy(&cp->addr, &param->addr);
		cp->sid = param->sid;
	}

	if (param->options &
	    BT_LE_PER_ADV_SYNC_OPT_REPORTING_INITIALLY_DISABLED) {
		cp->options |=
			BT_HCI_LE_PER_ADV_CREATE_SYNC_FP_REPORTS_DISABLED;

		atomic_set_bit(per_adv_sync->flags,
			       BT_PER_ADV_SYNC_RECV_DISABLED);
	}

	if (param->options & BT_LE_PER_ADV_SYNC_OPT_FILTER_DUPLICATE) {
		cp->options |=
			BT_HCI_LE_PER_ADV_CREATE_SYNC_FP_FILTER_DUPLICATE;
	}

	if (param->options & BT_LE_PER_ADV_SYNC_OPT_DONT_SYNC_AOA) {
		cp->cte_type |= BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_AOA;
	}

	if (param->options & BT_LE_PER_ADV_SYNC_OPT_DONT_SYNC_AOD_1US) {
		cp->cte_type |=
			BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_AOD_1US;
	}

	if (param->options & BT_LE_PER_ADV_SYNC_OPT_DONT_SYNC_AOD_2US) {
		cp->cte_type |=
			BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_AOD_2US;
	}

	if (param->options & BT_LE_PER_ADV_SYNC_OPT_SYNC_ONLY_CONST_TONE_EXT) {
		cp->cte_type |= BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_ONLY_CTE;
	}

	cp->skip = sys_cpu_to_le16(param->skip);
	cp->sync_timeout = sys_cpu_to_le16(param->timeout);

	err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_PER_ADV_CREATE_SYNC, buf, NULL);
	if (err) {
		per_adv_sync_delete(per_adv_sync);
		return err;
	}

	atomic_set_bit(per_adv_sync->flags, BT_PER_ADV_SYNC_SYNCING);

	/* Syncing requires that scan is enabled. If the caller doesn't enable
	 * scan first, we enable it here, and disable it once the sync has been
	 * established. We don't need to use any callbacks since we rely on
	 * the advertiser address in the sync params.
	 */
	err = bt_le_scan_user_add(BT_LE_SCAN_USER_PER_SYNC);
	if (err) {
		int per_sync_remove_err = bt_le_scan_user_remove(BT_LE_SCAN_USER_PER_SYNC);

		if (per_sync_remove_err) {
			LOG_WRN("Error while updating the scanner (%d)", per_sync_remove_err);
		}

		bt_le_per_adv_sync_delete(per_adv_sync);
		return err;
	}

	*out_sync = per_adv_sync;
	bt_addr_le_copy(&per_adv_sync->addr, &param->addr);
	per_adv_sync->sid = param->sid;

	return 0;
}

static int bt_le_per_adv_sync_create_cancel(
	struct bt_le_per_adv_sync *per_adv_sync)
{
	struct net_buf *buf;
	int err;

	if (get_pending_per_adv_sync() != per_adv_sync) {
		return -EINVAL;
	}

	err = bt_le_scan_user_remove(BT_LE_SCAN_USER_PER_SYNC);

	if (err) {
		return err;
	}

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

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

	return 0;
}

static int bt_le_per_adv_sync_terminate(struct bt_le_per_adv_sync *per_adv_sync)
{
	int err;

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

	err = per_adv_sync_terminate(per_adv_sync->handle);

	if (err) {
		return err;
	}

	return 0;
}

int bt_le_per_adv_sync_delete(struct bt_le_per_adv_sync *per_adv_sync)
{
	int err = 0;

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

	if (atomic_test_bit(per_adv_sync->flags, BT_PER_ADV_SYNC_SYNCED)) {
		err = bt_le_per_adv_sync_terminate(per_adv_sync);

		if (!err) {
			per_adv_sync_terminated(per_adv_sync,
						BT_HCI_ERR_LOCALHOST_TERM_CONN);
		}
	} else if (get_pending_per_adv_sync() == per_adv_sync) {
		err = bt_le_per_adv_sync_create_cancel(per_adv_sync);
		/* Delete of the per_adv_sync will be done in the event
		 * handler when cancelling.
		 */
	}

	return err;
}

int bt_le_per_adv_sync_cb_register(struct bt_le_per_adv_sync_cb *cb)
{
	if (sys_slist_find(&pa_sync_cbs, &cb->node, NULL)) {
		return -EEXIST;
	}

	sys_slist_append(&pa_sync_cbs, &cb->node);

	return 0;
}

static int bt_le_set_per_adv_recv_enable(
	struct bt_le_per_adv_sync *per_adv_sync, bool enable)
{
	struct bt_hci_cp_le_set_per_adv_recv_enable *cp;
	struct bt_le_per_adv_sync_cb *listener;
	struct bt_le_per_adv_sync_state_info info;
	struct net_buf *buf;
	struct bt_hci_cmd_state_set state;
	int err;

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

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

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

	if ((enable && !atomic_test_bit(per_adv_sync->flags,
					BT_PER_ADV_SYNC_RECV_DISABLED)) ||
	    (!enable && atomic_test_bit(per_adv_sync->flags,
					BT_PER_ADV_SYNC_RECV_DISABLED))) {
		return -EALREADY;
	}

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

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

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

	bt_hci_cmd_state_set_init(buf, &state, per_adv_sync->flags,
				  BT_PER_ADV_SYNC_RECV_DISABLED, !enable);

	err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_PER_ADV_RECV_ENABLE,
				   buf, NULL);

	if (err) {
		return err;
	}

	info.recv_enabled = !atomic_test_bit(per_adv_sync->flags,
					     BT_PER_ADV_SYNC_RECV_DISABLED);

	SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) {
		if (listener->state_changed) {
			listener->state_changed(per_adv_sync, &info);
		}
	}

	return 0;
}

int bt_le_per_adv_sync_recv_enable(struct bt_le_per_adv_sync *per_adv_sync)
{
	return bt_le_set_per_adv_recv_enable(per_adv_sync, true);
}

int bt_le_per_adv_sync_recv_disable(struct bt_le_per_adv_sync *per_adv_sync)
{
	return bt_le_set_per_adv_recv_enable(per_adv_sync, false);
}

#if defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER)
int bt_le_per_adv_sync_transfer(const struct bt_le_per_adv_sync *per_adv_sync,
				const struct bt_conn *conn,
				uint16_t service_data)
{
	struct bt_hci_cp_le_per_adv_sync_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_SYNC_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->sync_handle = sys_cpu_to_le16(per_adv_sync->handle);
	cp->service_data = sys_cpu_to_le16(service_data);

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

#if defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER)
static bool valid_past_param(
	const struct bt_le_per_adv_sync_transfer_param *param)
{
	if (param->skip > 0x01f3 ||
	    param->timeout < 0x000A ||
	    param->timeout > 0x4000) {
		return false;
	}
	if ((param->options & BT_LE_PER_ADV_SYNC_TRANSFER_OPT_REPORTING_INITIALLY_DISABLED) &&
	    (param->options & BT_LE_PER_ADV_SYNC_TRANSFER_OPT_FILTER_DUPLICATES)) {
		return false;
	}

	return true;
}

static int past_param_set(const struct bt_conn *conn, uint8_t mode,
			  uint16_t skip, uint16_t timeout, uint8_t cte_type)
{
	struct bt_hci_cp_le_past_param *cp;
	struct net_buf *buf;

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_PAST_PARAM, 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->mode = mode;
	cp->skip = sys_cpu_to_le16(skip);
	cp->timeout = sys_cpu_to_le16(timeout);
	cp->cte_type = cte_type;

	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_PAST_PARAM, buf, NULL);
}

static int default_past_param_set(uint8_t mode, uint16_t skip, uint16_t timeout,
				  uint8_t cte_type)
{
	struct bt_hci_cp_le_default_past_param *cp;
	struct net_buf *buf;

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

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

	cp->mode = mode;
	cp->skip = sys_cpu_to_le16(skip);
	cp->timeout = sys_cpu_to_le16(timeout);
	cp->cte_type = cte_type;

	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_DEFAULT_PAST_PARAM, buf, NULL);
}

int bt_le_per_adv_sync_transfer_subscribe(
	const struct bt_conn *conn,
	const struct bt_le_per_adv_sync_transfer_param *param)
{
	uint8_t cte_type = 0;
	uint8_t mode = BT_HCI_LE_PAST_MODE_SYNC;
	int err;

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

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

	if (param->options & BT_LE_PER_ADV_SYNC_TRANSFER_OPT_SYNC_NO_AOA) {
		cte_type |= BT_HCI_LE_PAST_CTE_TYPE_NO_AOA;
	}

	if (param->options & BT_LE_PER_ADV_SYNC_TRANSFER_OPT_SYNC_NO_AOD_1US) {
		cte_type |= BT_HCI_LE_PAST_CTE_TYPE_NO_AOD_1US;
	}

	if (param->options & BT_LE_PER_ADV_SYNC_TRANSFER_OPT_SYNC_NO_AOD_2US) {
		cte_type |= BT_HCI_LE_PAST_CTE_TYPE_NO_AOD_2US;
	}

	if (param->options & BT_LE_PER_ADV_SYNC_TRANSFER_OPT_SYNC_ONLY_CTE) {
		cte_type |= BT_HCI_LE_PAST_CTE_TYPE_ONLY_CTE;
	}

	if (param->options & BT_LE_PER_ADV_SYNC_TRANSFER_OPT_REPORTING_INITIALLY_DISABLED) {
		mode = BT_HCI_LE_PAST_MODE_NO_REPORTS;
	} else if (param->options & BT_LE_PER_ADV_SYNC_TRANSFER_OPT_FILTER_DUPLICATES) {
		mode = BT_HCI_LE_PAST_MODE_SYNC_FILTER_DUPLICATES;
	}

	if (conn) {
		const uint8_t conn_idx = bt_conn_index(conn);
		const uint8_t old_mode = conn_past_modes[conn_idx];

		conn_past_modes[conn_idx] = mode;

		err = past_param_set(conn, mode, param->skip, param->timeout, cte_type);
		if (err != 0) {
			/* Restore old mode */
			conn_past_modes[conn_idx] = old_mode;
		}
	} else {
		const uint8_t old_mode = default_past_mode;

		default_past_mode = mode;

		err = default_past_param_set(mode, param->skip, param->timeout, cte_type);
		if (err != 0) {
			/* Restore old mode */
			default_past_mode = old_mode;
		}
	}

	return err;
}

int bt_le_per_adv_sync_transfer_unsubscribe(const struct bt_conn *conn)
{
	int err;

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

	if (conn) {
		const uint8_t conn_idx = bt_conn_index(conn);
		const uint8_t old_mode = conn_past_modes[conn_idx];

		conn_past_modes[conn_idx] = BT_HCI_LE_PAST_MODE_NO_SYNC;

		err = past_param_set(conn, BT_HCI_LE_PAST_MODE_NO_SYNC, 0, 0x0a, 0);
		if (err != 0) {
			/* Restore old mode */
			conn_past_modes[conn_idx] = old_mode;
		}
	} else {
		const uint8_t old_mode = default_past_mode;

		default_past_mode = BT_HCI_LE_PAST_MODE_NO_SYNC;
		err = default_past_param_set(BT_HCI_LE_PAST_MODE_NO_SYNC, 0, 0x0a, 0);
		if (err != 0) {
			/* Restore old mode */
			default_past_mode = old_mode;
		}
	}

	return err;
}
#endif /* CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER */

int bt_le_per_adv_list_add(const bt_addr_le_t *addr, uint8_t sid)
{
	struct bt_hci_cp_le_add_dev_to_per_adv_list *cp;
	struct net_buf *buf;
	int err;

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

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

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

	err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_ADD_DEV_TO_PER_ADV_LIST, buf,
				   NULL);
	if (err) {
		LOG_ERR("Failed to add device to periodic advertiser list");

		return err;
	}

	return 0;
}

int bt_le_per_adv_list_remove(const bt_addr_le_t *addr, uint8_t sid)
{
	struct bt_hci_cp_le_rem_dev_from_per_adv_list *cp;
	struct net_buf *buf;
	int err;

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

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

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

	err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_REM_DEV_FROM_PER_ADV_LIST, buf,
				   NULL);
	if (err) {
		LOG_ERR("Failed to remove device from periodic advertiser list");
		return err;
	}

	return 0;
}

int bt_le_per_adv_list_clear(void)
{
	int err;

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

	err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_CLEAR_PER_ADV_LIST, NULL, NULL);
	if (err) {
		LOG_ERR("Failed to clear periodic advertiser list");
		return err;
	}

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

bool bt_le_explicit_scanner_running(void)
{
	return atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_EXPLICIT_SCAN);
}

bool bt_le_explicit_scanner_uses_same_params(const struct bt_conn_le_create_param *create_param)
{
	if (scan_state.explicit_scan_param.window != create_param->window ||
	    scan_state.explicit_scan_param.interval != create_param->interval){
		return false;
	}

	if (scan_state.explicit_scan_param.options & BT_LE_SCAN_OPT_CODED) {
		if (scan_state.explicit_scan_param.window_coded != create_param->window_coded ||
		    scan_state.explicit_scan_param.interval_coded != create_param->interval_coded){
			return false;
		}
	}

	return true;
}
