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