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

#include <stdbool.h>

#include <zephyr/settings/settings.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/check.h>

#include <zephyr/bluetooth/addr.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci_vs.h>
#include <zephyr/bluetooth/buf.h>
#include <zephyr/drivers/bluetooth/hci_driver.h>
#include <zephyr/sys/__assert.h>

#include "hci_core.h"
#include "id.h"
#include "scan.h"
#include "adv.h"
#include "smp.h"
#include "conn_internal.h"
#include "keys.h"
#include "common/rpa.h"

#include "settings.h"

#include <zephyr/bluetooth/hci.h>

#include "common/bt_str.h"

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

struct bt_adv_id_check_data {
	uint8_t id;
	bool adv_enabled;
};

#if defined(CONFIG_BT_OBSERVER) || defined(CONFIG_BT_BROADCASTER)
const bt_addr_le_t *bt_lookup_id_addr(uint8_t id, const bt_addr_le_t *addr)
{
	CHECKIF(id >= CONFIG_BT_ID_MAX || addr == NULL) {
		return NULL;
	}

	if (IS_ENABLED(CONFIG_BT_SMP)) {
		struct bt_keys *keys;

		keys = bt_keys_find_irk(id, addr);
		if (keys) {
			LOG_DBG("Identity %s matched RPA %s", bt_addr_le_str(&keys->addr),
				bt_addr_le_str(addr));
			return &keys->addr;
		}
	}

	return addr;
}
#endif /* CONFIG_BT_OBSERVER || CONFIG_BT_CONN */

static void adv_id_check_func(struct bt_le_ext_adv *adv, void *data)
{
	struct bt_adv_id_check_data *check_data = data;

	if (IS_ENABLED(CONFIG_BT_EXT_ADV)) {
		/* Only check if the ID is in use, as the advertiser can be
		 * started and stopped without reconfiguring parameters.
		 */
		if (check_data->id == adv->id) {
			check_data->adv_enabled = true;
		}
	} else {
		if (check_data->id == adv->id &&
		    atomic_test_bit(adv->flags, BT_ADV_ENABLED)) {
			check_data->adv_enabled = true;
		}
	}
}

static void adv_is_private_enabled(struct bt_le_ext_adv *adv, void *data)
{
	bool *adv_enabled = data;

	if (atomic_test_bit(adv->flags, BT_ADV_ENABLED) &&
	    !atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY)) {
		*adv_enabled = true;
	}
}

#if defined(CONFIG_BT_SMP)
static void adv_is_limited_enabled(struct bt_le_ext_adv *adv, void *data)
{
	bool *adv_enabled = data;

	if (atomic_test_bit(adv->flags, BT_ADV_ENABLED) &&
	    atomic_test_bit(adv->flags, BT_ADV_LIMITED)) {
		*adv_enabled = true;
	}
}

static void adv_pause_enabled(struct bt_le_ext_adv *adv, void *data)
{
	if (atomic_test_bit(adv->flags, BT_ADV_ENABLED)) {
		atomic_set_bit(adv->flags, BT_ADV_PAUSED);
		bt_le_adv_set_enable(adv, false);
	}
}

static void adv_unpause_enabled(struct bt_le_ext_adv *adv, void *data)
{
	if (atomic_test_and_clear_bit(adv->flags, BT_ADV_PAUSED)) {
		bt_le_adv_set_enable(adv, true);
	}
}
#endif /* defined(CONFIG_BT_SMP) */

static int set_random_address(const bt_addr_t *addr)
{
	struct net_buf *buf;
	int err;

	LOG_DBG("%s", bt_addr_str(addr));

	/* Do nothing if we already have the right address */
	if (bt_addr_eq(addr, &bt_dev.random_addr.a)) {
		return 0;
	}

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

	net_buf_add_mem(buf, addr, sizeof(*addr));

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

	bt_addr_copy(&bt_dev.random_addr.a, addr);
	bt_dev.random_addr.type = BT_ADDR_LE_RANDOM;
	return 0;
}

int bt_id_set_adv_random_addr(struct bt_le_ext_adv *adv,
			      const bt_addr_t *addr)
{
	struct bt_hci_cp_le_set_adv_set_random_addr *cp;
	struct net_buf *buf;
	int err;

	CHECKIF(adv == NULL || addr == NULL) {
		return -EINVAL;
	}

	if (!(IS_ENABLED(CONFIG_BT_EXT_ADV) &&
	      BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features))) {
		return set_random_address(addr);
	}

	LOG_DBG("%s", bt_addr_str(addr));

	if (!atomic_test_bit(adv->flags, BT_ADV_PARAMS_SET)) {
		bt_addr_copy(&adv->random_addr.a, addr);
		adv->random_addr.type = BT_ADDR_LE_RANDOM;
		atomic_set_bit(adv->flags, BT_ADV_RANDOM_ADDR_PENDING);
		return 0;
	}

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

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

	cp->handle = adv->handle;
	bt_addr_copy(&cp->bdaddr, addr);

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

	if (&adv->random_addr.a != addr) {
		bt_addr_copy(&adv->random_addr.a, addr);
	}
	adv->random_addr.type = BT_ADDR_LE_RANDOM;
	return 0;
}

/*	If rpa sharing is enabled, then rpa expired cb of adv-sets belonging
 *	to same id is verified to return true. If not, adv-sets will continue
 *	with old rpa through out the rpa rotations.
 */
static void adv_rpa_expired(struct bt_le_ext_adv *adv, void *data)
{
	bool rpa_invalid = true;
#if defined(CONFIG_BT_EXT_ADV) && defined(CONFIG_BT_PRIVACY)
	/* Notify the user about the RPA timeout and set the RPA validity. */
	if (atomic_test_bit(adv->flags, BT_ADV_RPA_VALID) &&
	    adv->cb && adv->cb->rpa_expired) {
		rpa_invalid = adv->cb->rpa_expired(adv);
	}
#endif

	if (IS_ENABLED(CONFIG_BT_RPA_SHARING)) {

		if (adv->id >= bt_dev.id_count) {
			return;
		}
		bool *rpa_invalid_set_ptr = data;

		if (!rpa_invalid) {
			rpa_invalid_set_ptr[adv->id] = false;
		}
	} else {
		if (rpa_invalid) {
			atomic_clear_bit(adv->flags, BT_ADV_RPA_VALID);
		}
	}
}

static void adv_rpa_invalidate(struct bt_le_ext_adv *adv, void *data)
{
	/* RPA of Advertisers limited by timeot or number of packets only expire
	 * when they are stopped.
	 */
	if (!atomic_test_bit(adv->flags, BT_ADV_LIMITED) &&
	    !atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY)) {
		adv_rpa_expired(adv, data);
	}
}

#if defined(CONFIG_BT_RPA_SHARING)
static void adv_rpa_clear_data(struct bt_le_ext_adv *adv, void *data)
{
	if (adv->id >= bt_dev.id_count) {
		return;
	}
	bool *rpa_invalid_set_ptr = data;

	if (rpa_invalid_set_ptr[adv->id]) {
		atomic_clear_bit(adv->flags, BT_ADV_RPA_VALID);
		bt_addr_copy(&bt_dev.rpa[adv->id], BT_ADDR_NONE);
	} else {
		LOG_WRN("Adv sets rpa expired cb with id %d returns false\n", adv->id);
	}
}
#endif

static void le_rpa_invalidate(void)
{
	/* Invalidate RPA */
	if (!(IS_ENABLED(CONFIG_BT_EXT_ADV) &&
	      atomic_test_bit(bt_dev.flags, BT_DEV_SCAN_LIMITED))) {
		atomic_clear_bit(bt_dev.flags, BT_DEV_RPA_VALID);
	}

	if (IS_ENABLED(CONFIG_BT_BROADCASTER)) {

		if (bt_dev.id_count == 0) {
			return;
		}
		bool rpa_expired_data[bt_dev.id_count];

		bt_le_ext_adv_foreach(adv_rpa_invalidate, &rpa_expired_data);
#if defined(CONFIG_BT_RPA_SHARING)
		/* rpa_expired data collected. now clear data based on data collected. */
		bt_le_ext_adv_foreach(adv_rpa_clear_data, &rpa_expired_data);
#endif
	}
}

#if defined(CONFIG_BT_PRIVACY)

#if defined(CONFIG_BT_RPA_TIMEOUT_DYNAMIC)
static void le_rpa_timeout_update(void)
{
	int err = 0;

	if (atomic_test_and_clear_bit(bt_dev.flags, BT_DEV_RPA_TIMEOUT_CHANGED)) {
		struct net_buf *buf;
		struct bt_hci_cp_le_set_rpa_timeout *cp;

		buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_RPA_TIMEOUT,
					sizeof(*cp));
		if (!buf) {
			LOG_ERR("Failed to create HCI RPA timeout command");
			err = -ENOBUFS;
			goto submit;
		}

		cp = net_buf_add(buf, sizeof(*cp));
		cp->rpa_timeout = sys_cpu_to_le16(bt_dev.rpa_timeout);
		err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_RPA_TIMEOUT, buf, NULL);
		if (err) {
			LOG_ERR("Failed to send HCI RPA timeout command");
			goto submit;
		}
	}

submit:
	if (err) {
		atomic_set_bit(bt_dev.flags, BT_DEV_RPA_TIMEOUT_CHANGED);
	}
}
#endif

static void le_rpa_timeout_submit(void)
{
#if defined(CONFIG_BT_RPA_TIMEOUT_DYNAMIC)
	le_rpa_timeout_update();
#endif

	(void)k_work_schedule(&bt_dev.rpa_update, K_SECONDS(bt_dev.rpa_timeout));
}

/* this function sets new RPA only if current one is no longer valid */
int bt_id_set_private_addr(uint8_t id)
{
	bt_addr_t rpa;
	int err;

	CHECKIF(id >= CONFIG_BT_ID_MAX) {
		return -EINVAL;
	}

	/* check if RPA is valid */
	if (atomic_test_bit(bt_dev.flags, BT_DEV_RPA_VALID)) {
		return 0;
	}

	err = bt_rpa_create(bt_dev.irk[id], &rpa);
	if (!err) {
		err = set_random_address(&rpa);
		if (!err) {
			atomic_set_bit(bt_dev.flags, BT_DEV_RPA_VALID);
		}
	}

	le_rpa_timeout_submit();

	if (err) {
		return err;
	}

	if (IS_ENABLED(CONFIG_BT_LOG_SNIFFER_INFO)) {
		LOG_INF("RPA: %s", bt_addr_str(&rpa));
	}

	return 0;
}

#if defined(CONFIG_BT_RPA_SHARING)
static int adv_rpa_get(struct bt_le_ext_adv *adv, bt_addr_t *rpa)
{
	int err;

	if (bt_addr_eq(&bt_dev.rpa[adv->id], BT_ADDR_NONE)) {
		err = bt_rpa_create(bt_dev.irk[adv->id], &bt_dev.rpa[adv->id]);
		if (err) {
			return err;
		}
	}

	bt_addr_copy(rpa, &bt_dev.rpa[adv->id]);

	return 0;
}
#else
static int adv_rpa_get(struct bt_le_ext_adv *adv, bt_addr_t *rpa)
{
	int err;

	err = bt_rpa_create(bt_dev.irk[adv->id], rpa);
	if (err) {
		return err;
	}

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

int bt_id_set_adv_private_addr(struct bt_le_ext_adv *adv)
{
	bt_addr_t rpa;
	int err;

	CHECKIF(adv == NULL) {
		return -EINVAL;
	}

	if (IS_ENABLED(CONFIG_BT_PRIVACY) &&
	    (adv->options & BT_LE_ADV_OPT_USE_NRPA)) {
		/* The host doesn't support setting NRPAs when BT_PRIVACY=y.
		 * In that case you probably want to use an RPA anyway.
		 */
		LOG_ERR("NRPA not supported when BT_PRIVACY=y");

		return -ENOSYS;
	}

	if (!(IS_ENABLED(CONFIG_BT_EXT_ADV) &&
	      BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features))) {
		return bt_id_set_private_addr(adv->id);
	}

	/* check if RPA is valid */
	if (atomic_test_bit(adv->flags, BT_ADV_RPA_VALID)) {
		/* Schedule the RPA timer if it is not running.
		 * The RPA may be valid without the timer running.
		 */
		if (!atomic_test_bit(adv->flags, BT_ADV_LIMITED)) {
			le_rpa_timeout_submit();
		}

		return 0;
	}

	if (adv == bt_le_adv_lookup_legacy() && adv->id == BT_ID_DEFAULT) {
		/* Make sure that a Legacy advertiser using default ID has same
		 * RPA address as scanner roles.
		 */
		err = bt_id_set_private_addr(BT_ID_DEFAULT);
		if (err) {
			return err;
		}

		err = bt_id_set_adv_random_addr(adv, &bt_dev.random_addr.a);
		if (!err) {
			atomic_set_bit(adv->flags, BT_ADV_RPA_VALID);
		}

		return 0;
	}

	err = adv_rpa_get(adv, &rpa);
	if (!err) {
		err = bt_id_set_adv_random_addr(adv, &rpa);
		if (!err) {
			atomic_set_bit(adv->flags, BT_ADV_RPA_VALID);
		}
	}

	if (!atomic_test_bit(adv->flags, BT_ADV_LIMITED)) {
		le_rpa_timeout_submit();
	}

	if (err) {
		return err;
	}

	if (IS_ENABLED(CONFIG_BT_LOG_SNIFFER_INFO)) {
		LOG_INF("RPA: %s", bt_addr_str(&rpa));
	}

	return 0;
}
#else
int bt_id_set_private_addr(uint8_t id)
{
	bt_addr_t nrpa;
	int err;

	CHECKIF(id >= CONFIG_BT_ID_MAX) {
		return -EINVAL;
	}

	err = bt_rand(nrpa.val, sizeof(nrpa.val));
	if (err) {
		return err;
	}

	BT_ADDR_SET_NRPA(&nrpa);

	err = set_random_address(&nrpa);
	if (err)  {
		return err;
	}

	if (IS_ENABLED(CONFIG_BT_LOG_SNIFFER_INFO)) {
		LOG_INF("NRPA: %s", bt_addr_str(&nrpa));
	}

	return 0;
}

int bt_id_set_adv_private_addr(struct bt_le_ext_adv *adv)
{
	bt_addr_t nrpa;
	int err;

	CHECKIF(adv == NULL) {
		return -EINVAL;
	}

	err = bt_rand(nrpa.val, sizeof(nrpa.val));
	if (err) {
		return err;
	}

	BT_ADDR_SET_NRPA(&nrpa);

	err = bt_id_set_adv_random_addr(adv, &nrpa);
	if (err) {
		return err;
	}

	if (IS_ENABLED(CONFIG_BT_LOG_SNIFFER_INFO)) {
		LOG_INF("NRPA: %s", bt_addr_str(&nrpa));
	}

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

static void adv_pause_rpa(struct bt_le_ext_adv *adv, void *data)
{
	bool *adv_enabled = data;

	/* Disable advertising sets to prepare them for RPA update. */
	if (atomic_test_bit(adv->flags, BT_ADV_ENABLED) &&
	    !atomic_test_bit(adv->flags, BT_ADV_LIMITED) &&
	    !atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY)) {
		int err;

		err = bt_le_adv_set_enable_ext(adv, false, NULL);
		if (err) {
			LOG_ERR("Failed to disable advertising (err %d)", err);
		}

		atomic_set_bit(adv->flags, BT_ADV_RPA_UPDATE);
		*adv_enabled = true;
	}
}

static bool le_adv_rpa_timeout(void)
{
	bool adv_enabled = false;

	if (IS_ENABLED(CONFIG_BT_BROADCASTER)) {
		if (IS_ENABLED(CONFIG_BT_EXT_ADV) &&
		    BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features)) {
			/* Pause all advertising sets using RPAs */
			bt_le_ext_adv_foreach(adv_pause_rpa, &adv_enabled);
		} else {
			/* Check if advertising set is enabled */
			bt_le_ext_adv_foreach(adv_is_private_enabled, &adv_enabled);
		}
	}

	return adv_enabled;
}

static void adv_enable_rpa(struct bt_le_ext_adv *adv, void *data)
{
	if (atomic_test_and_clear_bit(adv->flags, BT_ADV_RPA_UPDATE)) {
		int err;

		err = bt_id_set_adv_private_addr(adv);
		if (err) {
			LOG_WRN("Failed to update advertiser RPA address (%d)", err);
		}

		err = bt_le_adv_set_enable_ext(adv, true, NULL);
		if (err) {
			LOG_ERR("Failed to enable advertising (err %d)", err);
		}
	}
}

static void le_update_private_addr(void)
{
	struct bt_le_ext_adv *adv = NULL;
	bool adv_enabled = false;
	uint8_t id = BT_ID_DEFAULT;
	int err;

#if defined(CONFIG_BT_OBSERVER)
	bool scan_enabled = false;

	if (atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING) &&
	    !(IS_ENABLED(CONFIG_BT_EXT_ADV) &&
	      atomic_test_bit(bt_dev.flags, BT_DEV_SCAN_LIMITED))) {
		bt_le_scan_set_enable(BT_HCI_LE_SCAN_DISABLE);
		scan_enabled = true;
	}
#endif
	if (IS_ENABLED(CONFIG_BT_CENTRAL) &&
	    IS_ENABLED(CONFIG_BT_FILTER_ACCEPT_LIST) &&
	    atomic_test_bit(bt_dev.flags, BT_DEV_INITIATING)) {
		/* Canceled initiating procedure will be restarted by
		 * connection complete event.
		 */
		bt_le_create_conn_cancel();
	}

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

		if (adv &&
		    atomic_test_bit(adv->flags, BT_ADV_ENABLED) &&
		    !atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY)) {
			adv_enabled = true;
			id = adv->id;
			bt_le_adv_set_enable_legacy(adv, false);
		}
	}

	/* If both advertiser and scanner is running then the advertiser
	 * ID must be BT_ID_DEFAULT, this will update the RPA address
	 * for both roles.
	 */
	err = bt_id_set_private_addr(id);
	if (err) {
		LOG_WRN("Failed to update RPA address (%d)", err);
		return;
	}

	if (IS_ENABLED(CONFIG_BT_BROADCASTER) &&
	    IS_ENABLED(CONFIG_BT_EXT_ADV) &&
	    BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features)) {
		bt_le_ext_adv_foreach(adv_enable_rpa, NULL);
	}

	if (IS_ENABLED(CONFIG_BT_BROADCASTER) &&
	    adv && adv_enabled) {
		bt_le_adv_set_enable_legacy(adv, true);
	}

#if defined(CONFIG_BT_OBSERVER)
	if (scan_enabled) {
		bt_le_scan_set_enable(BT_HCI_LE_SCAN_ENABLE);
	}
#endif
}

static void le_force_rpa_timeout(void)
{
#if defined(CONFIG_BT_PRIVACY)
	struct k_work_sync sync;

	k_work_cancel_delayable_sync(&bt_dev.rpa_update, &sync);
#endif
	(void)le_adv_rpa_timeout();
	le_rpa_invalidate();
	le_update_private_addr();
}

#if defined(CONFIG_BT_PRIVACY)
static void rpa_timeout(struct k_work *work)
{
	bool adv_enabled;

	LOG_DBG("");

	if (IS_ENABLED(CONFIG_BT_CENTRAL)) {
		struct bt_conn *conn =
			bt_conn_lookup_state_le(BT_ID_DEFAULT, NULL,
						BT_CONN_SCAN_BEFORE_INITIATING);

		if (conn) {
			bt_conn_unref(conn);
			bt_le_create_conn_cancel();
		}
	}

	adv_enabled = le_adv_rpa_timeout();
	le_rpa_invalidate();

	/* IF no roles using the RPA is running we can stop the RPA timer */
	if (!(adv_enabled ||
	      atomic_test_bit(bt_dev.flags, BT_DEV_INITIATING) ||
	      (atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING) &&
	       atomic_test_bit(bt_dev.flags, BT_DEV_ACTIVE_SCAN)))) {
		return;
	}

	le_update_private_addr();
}
#endif /* CONFIG_BT_PRIVACY */

bool bt_id_scan_random_addr_check(void)
{
	struct bt_le_ext_adv *adv;

	if (!IS_ENABLED(CONFIG_BT_BROADCASTER) ||
	    (IS_ENABLED(CONFIG_BT_EXT_ADV) &&
	     BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features))) {
		/* Advertiser is not enabled or advertiser and scanner are using
		 * a different random address.
		 */
		return true;
	}

	adv = bt_le_adv_lookup_legacy();
	if (!adv) {
		return true;
	}

	/* If the advertiser is not active there is no issue */
	if (!atomic_test_bit(adv->flags, BT_ADV_ENABLED)) {
		return true;
	}

	/* When privacy is enabled the random address will not be set
	 * immediately before starting the role, because the RPA might still be
	 * valid and only updated on RPA timeout.
	 */
	if (IS_ENABLED(CONFIG_BT_PRIVACY)) {
		/* Cannot start scanner or initiator if the random address is
		 * used by the advertiser for an RPA with a different identity
		 * or for a random static identity address.
		 */
		if ((atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY) &&
		     bt_dev.id_addr[adv->id].type == BT_ADDR_LE_RANDOM) ||
		    adv->id != BT_ID_DEFAULT) {
			return false;
		}
	}

	/* If privacy is not enabled then the random address will be attempted
	 * to be set before enabling the role. If another role is already using
	 * the random address then this command will fail, and should return
	 * the error code to the application.
	 */
	return true;
}

bool bt_id_adv_random_addr_check(const struct bt_le_adv_param *param)
{
	CHECKIF(param == NULL) {
		return false;
	}

	if (!IS_ENABLED(CONFIG_BT_OBSERVER) ||
	    (IS_ENABLED(CONFIG_BT_EXT_ADV) &&
	     BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features))) {
		/* If scanner roles are not enabled or advertiser and scanner
		 * are using a different random address.
		 */
		return true;
	}

	/* If scanner roles are not active there is no issue. */
	if (!(atomic_test_bit(bt_dev.flags, BT_DEV_INITIATING) ||
	      atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING))) {
		return true;
	}

	/* When privacy is enabled the random address will not be set
	 * immediately before starting the role, because the RPA might still be
	 * valid and only updated on RPA timeout.
	 */
	if (IS_ENABLED(CONFIG_BT_PRIVACY)) {
		/* Cannot start an advertiser with random static identity or
		 * using an RPA generated for a different identity than scanner
		 * roles.
		 */
		if (((param->options & BT_LE_ADV_OPT_USE_IDENTITY) &&
		     bt_dev.id_addr[param->id].type == BT_ADDR_LE_RANDOM) ||
		    param->id != BT_ID_DEFAULT) {
			return false;
		}
	} else if (IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY) &&
		   atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING) &&
		   bt_dev.id_addr[BT_ID_DEFAULT].type == BT_ADDR_LE_RANDOM) {
		/* Scanning with random static identity. Stop the advertiser
		 * from overwriting the passive scanner identity address.
		 * In this case the LE Set Random Address command does not
		 * protect us in the case of a passive scanner.
		 * Explicitly stop it here.
		 */

		if (!(param->options & BT_LE_ADV_OPT_CONNECTABLE) &&
		     (param->options & BT_LE_ADV_OPT_USE_IDENTITY)) {
			/* Attempt to set non-connectable NRPA */
			return false;
		} else if (bt_dev.id_addr[param->id].type ==
			   BT_ADDR_LE_RANDOM &&
			   param->id != BT_ID_DEFAULT) {
			/* Attempt to set connectable, or non-connectable with
			 * identity different than scanner.
			 */
			return false;
		}
	}

	/* If privacy is not enabled then the random address will be attempted
	 * to be set before enabling the role. If another role is already using
	 * the random address then this command will fail, and should return
	 * the error code to the application.
	 */
	return true;
}

void bt_id_adv_limited_stopped(struct bt_le_ext_adv *adv)
{
	adv_rpa_expired(adv, NULL);
}

#if defined(CONFIG_BT_SMP)
static int le_set_privacy_mode(const bt_addr_le_t *addr, uint8_t mode)
{
	struct bt_hci_cp_le_set_privacy_mode cp;
	struct net_buf *buf;
	int err;

	/* Check if set privacy mode command is supported */
	if (!BT_CMD_TEST(bt_dev.supported_commands, 39, 2)) {
		LOG_WRN("Set privacy mode command is not supported");
		return 0;
	}

	LOG_DBG("addr %s mode 0x%02x", bt_addr_le_str(addr), mode);

	bt_addr_le_copy(&cp.id_addr, addr);
	cp.mode = mode;

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

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

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

	return 0;
}

static int addr_res_enable(uint8_t enable)
{
	struct net_buf *buf;

	LOG_DBG("%s", enable ? "enabled" : "disabled");

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

	net_buf_add_u8(buf, enable);

	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_ADDR_RES_ENABLE,
				    buf, NULL);
}

static int hci_id_add(uint8_t id, const bt_addr_le_t *addr, uint8_t peer_irk[16])
{
	struct bt_hci_cp_le_add_dev_to_rl *cp;
	struct net_buf *buf;

	if (id >= CONFIG_BT_ID_MAX) {
		return -EINVAL;
	}

	LOG_DBG("addr %s", bt_addr_le_str(addr));

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

	cp = net_buf_add(buf, sizeof(*cp));
	bt_addr_le_copy(&cp->peer_id_addr, addr);
	memcpy(cp->peer_irk, peer_irk, 16);

#if defined(CONFIG_BT_PRIVACY)
	(void)memcpy(cp->local_irk, &bt_dev.irk[id], 16);
#else
	(void)memset(cp->local_irk, 0, 16);
#endif

	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_ADD_DEV_TO_RL, buf, NULL);
}

static void pending_id_update(struct bt_keys *keys, void *data)
{
	if (keys->state & BT_KEYS_ID_PENDING_ADD) {
		keys->state &= ~BT_KEYS_ID_PENDING_ADD;
		bt_id_add(keys);
		return;
	}

	if (keys->state & BT_KEYS_ID_PENDING_DEL) {
		keys->state &= ~BT_KEYS_ID_PENDING_DEL;
		bt_id_del(keys);
		return;
	}
}

static void bt_id_pending_keys_update_set(struct bt_keys *keys, uint8_t flag)
{
	atomic_set_bit(bt_dev.flags, BT_DEV_ID_PENDING);
	keys->state |= flag;
}

void bt_id_pending_keys_update(void)
{
	if (atomic_test_and_clear_bit(bt_dev.flags, BT_DEV_ID_PENDING)) {
		if (IS_ENABLED(CONFIG_BT_CENTRAL) &&
		    IS_ENABLED(CONFIG_BT_PRIVACY)) {
			bt_keys_foreach_type(BT_KEYS_ALL, pending_id_update, NULL);
		} else {
			bt_keys_foreach_type(BT_KEYS_IRK, pending_id_update, NULL);
		}
	}
}

struct bt_id_conflict {
	struct bt_keys *candidate;
	struct bt_keys *found;
};

/* The Controller Resolve List is constrained by 7.8.38 "LE Add Device To
 * Resolving List command". The Host is designed with the assumption that all
 * local bonds can be put in the resolve list if there is room. Therefore we
 * must refuse bonds that conflict in the resolve list. Notably, this prevents
 * multiple local identities to bond with the same remote identity.
 */
void find_rl_conflict(struct bt_keys *resident, void *user_data)
{
	struct bt_id_conflict *conflict = user_data;
	bool addr_conflict;
	bool irk_conflict;

	__ASSERT_NO_MSG(conflict != NULL);
	__ASSERT_NO_MSG(conflict->candidate != NULL);
	__ASSERT_NO_MSG(resident != NULL);
	/* Only uncommitted bonds can be in conflict with committed bonds. */
	__ASSERT_NO_MSG((conflict->candidate->state & BT_KEYS_ID_ADDED) == 0);

	if (conflict->found) {
		return;
	}

	/* Test against committed bonds only. */
	if ((resident->state & BT_KEYS_ID_ADDED) == 0) {
		return;
	}

	addr_conflict = bt_addr_le_eq(&conflict->candidate->addr, &resident->addr);

	/* All-zero IRK is "no IRK", and does not conflict with other Zero-IRKs. */
	irk_conflict = (!bt_irk_eq(&conflict->candidate->irk, &(struct bt_irk){}) &&
			bt_irk_eq(&conflict->candidate->irk, &resident->irk));

	if (addr_conflict || irk_conflict) {
		conflict->found = resident;
	}
}

struct bt_keys *bt_id_find_conflict(struct bt_keys *candidate)
{
	struct bt_id_conflict conflict = {
		.candidate = candidate,
	};

	bt_keys_foreach_type(BT_KEYS_IRK, find_rl_conflict, &conflict);

	return conflict.found;
}

void bt_id_add(struct bt_keys *keys)
{
	CHECKIF(keys == NULL) {
		return;
	}

	struct bt_conn *conn;
	int err;

	LOG_DBG("addr %s", bt_addr_le_str(&keys->addr));

	__ASSERT_NO_MSG(keys != NULL);
	/* We assume (and could assert) !bt_id_find_conflict(keys) here. */

	/* Nothing to be done if host-side resolving is used */
	if (!bt_dev.le.rl_size || bt_dev.le.rl_entries > bt_dev.le.rl_size) {
		bt_dev.le.rl_entries++;
		keys->state |= BT_KEYS_ID_ADDED;
		return;
	}

	conn = bt_conn_lookup_state_le(BT_ID_DEFAULT, NULL, BT_CONN_INITIATING);
	if (conn) {
		bt_id_pending_keys_update_set(keys, BT_KEYS_ID_PENDING_ADD);
		bt_conn_unref(conn);
		return;
	}

	if (IS_ENABLED(CONFIG_BT_BROADCASTER) &&
	    IS_ENABLED(CONFIG_BT_EXT_ADV)) {
		bool adv_enabled = false;

		bt_le_ext_adv_foreach(adv_is_limited_enabled, &adv_enabled);
		if (adv_enabled) {
			bt_id_pending_keys_update_set(keys,
						   BT_KEYS_ID_PENDING_ADD);
			return;
		}
	}

#if defined(CONFIG_BT_OBSERVER)
	bool scan_enabled = atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING);

	if (IS_ENABLED(CONFIG_BT_EXT_ADV) && scan_enabled &&
	    atomic_test_bit(bt_dev.flags, BT_DEV_SCAN_LIMITED)) {
		bt_id_pending_keys_update_set(keys, BT_KEYS_ID_PENDING_ADD);
	}
#endif

	if (IS_ENABLED(CONFIG_BT_BROADCASTER)) {
		bt_le_ext_adv_foreach(adv_pause_enabled, NULL);
	}

#if defined(CONFIG_BT_OBSERVER)
	if (scan_enabled) {
		bt_le_scan_set_enable(BT_HCI_LE_SCAN_DISABLE);
	}
#endif /* CONFIG_BT_OBSERVER */

	/* If there are any existing entries address resolution will be on */
	if (bt_dev.le.rl_entries) {
		err = addr_res_enable(BT_HCI_ADDR_RES_DISABLE);
		if (err) {
			LOG_WRN("Failed to disable address resolution");
			goto done;
		}
	}

	if (bt_dev.le.rl_entries == bt_dev.le.rl_size) {
		LOG_WRN("Resolving list size exceeded. Switching to host.");

		err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_CLEAR_RL, NULL, NULL);
		if (err) {
			LOG_ERR("Failed to clear resolution list");
			goto done;
		}

		bt_dev.le.rl_entries++;
		keys->state |= BT_KEYS_ID_ADDED;

		goto done;
	}

	err = hci_id_add(keys->id, &keys->addr, keys->irk.val);
	if (err) {
		LOG_ERR("Failed to add IRK to controller");
		goto done;
	}

	bt_dev.le.rl_entries++;
	keys->state |= BT_KEYS_ID_ADDED;

	/*
	 * According to Core Spec. 5.0 Vol 1, Part A 5.4.5 Privacy Feature
	 *
	 * By default, network privacy mode is used when private addresses are
	 * resolved and generated by the Controller, so advertising packets from
	 * peer devices that contain private addresses will only be accepted.
	 * By changing to the device privacy mode device is only concerned about
	 * its privacy and will accept advertising packets from peer devices
	 * that contain their identity address as well as ones that contain
	 * a private address, even if the peer device has distributed its IRK in
	 * the past.
	 */
	err = le_set_privacy_mode(&keys->addr, BT_HCI_LE_PRIVACY_MODE_DEVICE);
	if (err) {
		LOG_ERR("Failed to set privacy mode");
		goto done;
	}

done:
	addr_res_enable(BT_HCI_ADDR_RES_ENABLE);

#if defined(CONFIG_BT_OBSERVER)
	if (scan_enabled) {
		bt_le_scan_set_enable(BT_HCI_LE_SCAN_ENABLE);
	}
#endif /* CONFIG_BT_OBSERVER */

	if (IS_ENABLED(CONFIG_BT_BROADCASTER)) {
		bt_le_ext_adv_foreach(adv_unpause_enabled, NULL);
	}
}

static void keys_add_id(struct bt_keys *keys, void *data)
{
	if (keys->state & BT_KEYS_ID_ADDED) {
		hci_id_add(keys->id, &keys->addr, keys->irk.val);
	}
}

static int hci_id_del(const bt_addr_le_t *addr)
{
	struct bt_hci_cp_le_rem_dev_from_rl *cp;
	struct net_buf *buf;

	LOG_DBG("addr %s", bt_addr_le_str(addr));

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

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

	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_REM_DEV_FROM_RL, buf, NULL);
}

void bt_id_del(struct bt_keys *keys)
{
	struct bt_conn *conn;
	int err;

	CHECKIF(keys == NULL) {
		return;
	}

	LOG_DBG("addr %s", bt_addr_le_str(&keys->addr));

	if (!bt_dev.le.rl_size ||
	    bt_dev.le.rl_entries > bt_dev.le.rl_size + 1) {
		__ASSERT_NO_MSG(bt_dev.le.rl_entries > 0);
		if (bt_dev.le.rl_entries > 0) {
			bt_dev.le.rl_entries--;
		}
		keys->state &= ~BT_KEYS_ID_ADDED;
		return;
	}

	conn = bt_conn_lookup_state_le(BT_ID_DEFAULT, NULL, BT_CONN_INITIATING);
	if (conn) {
		bt_id_pending_keys_update_set(keys, BT_KEYS_ID_PENDING_DEL);
		bt_conn_unref(conn);
		return;
	}

	if (IS_ENABLED(CONFIG_BT_BROADCASTER) &&
	    IS_ENABLED(CONFIG_BT_EXT_ADV)) {
		bool adv_enabled = false;

		bt_le_ext_adv_foreach(adv_is_limited_enabled, &adv_enabled);
		if (adv_enabled) {
			bt_id_pending_keys_update_set(keys, BT_KEYS_ID_PENDING_DEL);
			return;
		}
	}

#if defined(CONFIG_BT_OBSERVER)
	bool scan_enabled = atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING);

	if (IS_ENABLED(CONFIG_BT_EXT_ADV) && scan_enabled &&
	    atomic_test_bit(bt_dev.flags, BT_DEV_SCAN_LIMITED)) {
		bt_id_pending_keys_update_set(keys, BT_KEYS_ID_PENDING_DEL);
	}
#endif /* CONFIG_BT_OBSERVER */

	if (IS_ENABLED(CONFIG_BT_BROADCASTER)) {
		bt_le_ext_adv_foreach(adv_pause_enabled, NULL);
	}

#if defined(CONFIG_BT_OBSERVER)
	if (scan_enabled) {
		bt_le_scan_set_enable(BT_HCI_LE_SCAN_DISABLE);
	}
#endif /* CONFIG_BT_OBSERVER */

	err = addr_res_enable(BT_HCI_ADDR_RES_DISABLE);
	if (err) {
		LOG_ERR("Disabling address resolution failed (err %d)", err);
		goto done;
	}

	/* We checked size + 1 earlier, so here we know we can fit again */
	if (bt_dev.le.rl_entries > bt_dev.le.rl_size) {
		bt_dev.le.rl_entries--;
		keys->state &= ~BT_KEYS_ID_ADDED;
		if (IS_ENABLED(CONFIG_BT_CENTRAL) &&
		    IS_ENABLED(CONFIG_BT_PRIVACY)) {
			bt_keys_foreach_type(BT_KEYS_ALL, keys_add_id, NULL);
		} else {
			bt_keys_foreach_type(BT_KEYS_IRK, keys_add_id, NULL);
		}
		goto done;
	}

	err = hci_id_del(&keys->addr);
	if (err) {
		LOG_ERR("Failed to remove IRK from controller");
		goto done;
	}

	bt_dev.le.rl_entries--;
	keys->state &= ~BT_KEYS_ID_ADDED;

done:
	/* Only re-enable if there are entries to do resolving with */
	if (bt_dev.le.rl_entries) {
		addr_res_enable(BT_HCI_ADDR_RES_ENABLE);
	}

#if defined(CONFIG_BT_OBSERVER)
	if (scan_enabled) {
		bt_le_scan_set_enable(BT_HCI_LE_SCAN_ENABLE);
	}
#endif /* CONFIG_BT_OBSERVER */

	if (IS_ENABLED(CONFIG_BT_BROADCASTER)) {
		bt_le_ext_adv_foreach(adv_unpause_enabled, NULL);
	}
}
#endif /* defined(CONFIG_BT_SMP) */

void bt_id_get(bt_addr_le_t *addrs, size_t *count)
{
	if (addrs) {
		size_t to_copy = MIN(*count, bt_dev.id_count);

		memcpy(addrs, bt_dev.id_addr, to_copy * sizeof(bt_addr_le_t));
		*count = to_copy;
	} else {
		*count = bt_dev.id_count;
	}
}

static int id_find(const bt_addr_le_t *addr)
{
	uint8_t id;

	for (id = 0U; id < bt_dev.id_count; id++) {
		if (bt_addr_le_eq(addr, &bt_dev.id_addr[id])) {
			return id;
		}
	}

	return -ENOENT;
}

static int id_create(uint8_t id, bt_addr_le_t *addr, uint8_t *irk)
{
	if (addr && !bt_addr_le_eq(addr, BT_ADDR_LE_ANY)) {
		bt_addr_le_copy(&bt_dev.id_addr[id], addr);
	} else {
		bt_addr_le_t new_addr;

		do {
			int err;

			err = bt_addr_le_create_static(&new_addr);
			if (err) {
				return err;
			}
			/* Make sure we didn't generate a duplicate */
		} while (id_find(&new_addr) >= 0);

		bt_addr_le_copy(&bt_dev.id_addr[id], &new_addr);

		if (addr) {
			bt_addr_le_copy(addr, &bt_dev.id_addr[id]);
		}
	}

#if defined(CONFIG_BT_PRIVACY)
	{
		uint8_t zero_irk[16] = { 0 };

		if (irk && memcmp(irk, zero_irk, 16)) {
			memcpy(&bt_dev.irk[id], irk, 16);
		} else {
			int err;

			err = bt_rand(&bt_dev.irk[id], 16);
			if (err) {
				return err;
			}

			if (irk) {
				memcpy(irk, &bt_dev.irk[id], 16);
			}
		}

#if defined(CONFIG_BT_RPA_SHARING)
		bt_addr_copy(&bt_dev.rpa[id], BT_ADDR_NONE);
#endif
	}
#endif
	/* Only store if stack was already initialized. Before initialization
	 * we don't know the flash content, so it's potentially harmful to
	 * try to write anything there.
	 */
	if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
	    atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
		(void)bt_settings_store_id();
		(void)bt_settings_store_irk();
	}

	return 0;
}

int bt_id_create(bt_addr_le_t *addr, uint8_t *irk)
{
	int new_id, err;

	if (!IS_ENABLED(CONFIG_BT_PRIVACY) && irk) {
		return -EINVAL;
	}

	if (addr && !bt_addr_le_eq(addr, BT_ADDR_LE_ANY)) {
		if (id_find(addr) >= 0) {
			return -EALREADY;
		}

		if (addr->type == BT_ADDR_LE_PUBLIC && IS_ENABLED(CONFIG_BT_HCI_SET_PUBLIC_ADDR)) {
			/* set the single public address */
			if (bt_dev.id_count != 0) {
				return -EALREADY;
			}
			bt_addr_le_copy(&bt_dev.id_addr[BT_ID_DEFAULT], addr);
			bt_dev.id_count++;
			return BT_ID_DEFAULT;
		} else if (addr->type != BT_ADDR_LE_RANDOM || !BT_ADDR_IS_STATIC(&addr->a)) {
			LOG_ERR("Only random static identity address supported");
			return -EINVAL;
		}
	}

	if (bt_dev.id_count == ARRAY_SIZE(bt_dev.id_addr)) {
		return -ENOMEM;
	}

	/* bt_rand is not available before Bluetooth enable has been called */
	if (!atomic_test_bit(bt_dev.flags, BT_DEV_ENABLE)) {
		uint8_t zero_irk[16] = { 0 };

		if (!(addr && !bt_addr_le_eq(addr, BT_ADDR_LE_ANY))) {
			return -EINVAL;
		}

		if (IS_ENABLED(CONFIG_BT_PRIVACY) &&
		    !(irk && memcmp(irk, zero_irk, 16))) {
			return -EINVAL;
		}
	}

	new_id = bt_dev.id_count++;
	err = id_create(new_id, addr, irk);
	if (err) {
		bt_dev.id_count--;
		return err;
	}

	return new_id;
}

int bt_id_reset(uint8_t id, bt_addr_le_t *addr, uint8_t *irk)
{
	int err;

	if (addr && !bt_addr_le_eq(addr, BT_ADDR_LE_ANY)) {
		if (addr->type != BT_ADDR_LE_RANDOM ||
		    !BT_ADDR_IS_STATIC(&addr->a)) {
			LOG_ERR("Only static random identity address supported");
			return -EINVAL;
		}

		if (id_find(addr) >= 0) {
			return -EALREADY;
		}
	}

	if (!IS_ENABLED(CONFIG_BT_PRIVACY) && irk) {
		return -EINVAL;
	}

	if (id == BT_ID_DEFAULT || id >= bt_dev.id_count) {
		return -EINVAL;
	}

	if (IS_ENABLED(CONFIG_BT_BROADCASTER)) {
		struct bt_adv_id_check_data check_data = {
			.id = id,
			.adv_enabled = false,
		};

		bt_le_ext_adv_foreach(adv_id_check_func, &check_data);
		if (check_data.adv_enabled) {
			return -EBUSY;
		}
	}

	if (IS_ENABLED(CONFIG_BT_CONN) &&
	    !bt_addr_le_eq(&bt_dev.id_addr[id], BT_ADDR_LE_ANY)) {
		err = bt_unpair(id, NULL);
		if (err) {
			return err;
		}
	}

	err = id_create(id, addr, irk);
	if (err) {
		return err;
	}

	return id;
}

int bt_id_delete(uint8_t id)
{
	if (id == BT_ID_DEFAULT || id >= bt_dev.id_count) {
		return -EINVAL;
	}

	if (bt_addr_le_eq(&bt_dev.id_addr[id], BT_ADDR_LE_ANY)) {
		return -EALREADY;
	}

	if (IS_ENABLED(CONFIG_BT_BROADCASTER)) {
		struct bt_adv_id_check_data check_data = {
			.id = id,
			.adv_enabled = false,
		};

		bt_le_ext_adv_foreach(adv_id_check_func, &check_data);
		if (check_data.adv_enabled) {
			return -EBUSY;
		}
	}

	if (IS_ENABLED(CONFIG_BT_CONN)) {
		int err;

		err = bt_unpair(id, NULL);
		if (err) {
			return err;
		}
	}

#if defined(CONFIG_BT_PRIVACY)
	(void)memset(bt_dev.irk[id], 0, 16);
#endif
	bt_addr_le_copy(&bt_dev.id_addr[id], BT_ADDR_LE_ANY);

	if (id == bt_dev.id_count - 1) {
		bt_dev.id_count--;
	}

	if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
	    atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
		(void)bt_settings_store_id();
		(void)bt_settings_store_irk();
	}

	return 0;
}

#if defined(CONFIG_BT_PRIVACY)
static void bt_read_identity_root(uint8_t *ir)
{
	/* Invalid IR */
	memset(ir, 0, 16);

#if defined(CONFIG_BT_HCI_VS_EXT)
	struct bt_hci_rp_vs_read_key_hierarchy_roots *rp;
	struct net_buf *rsp;
	int err;

	if (!BT_VS_CMD_READ_KEY_ROOTS(bt_dev.vs_commands)) {
		return;
	}

	err = bt_hci_cmd_send_sync(BT_HCI_OP_VS_READ_KEY_HIERARCHY_ROOTS, NULL,
				   &rsp);
	if (err) {
		LOG_WRN("Failed to read identity root");
		return;
	}

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

	rp = (void *)rsp->data;
	memcpy(ir, rp->ir, 16);

	net_buf_unref(rsp);
#endif /* defined(CONFIG_BT_HCI_VS_EXT) */
}
#endif /* defined(CONFIG_BT_PRIVACY) */

uint8_t bt_id_read_public_addr(bt_addr_le_t *addr)
{
	struct bt_hci_rp_read_bd_addr *rp;
	struct net_buf *rsp;
	int err;

	CHECKIF(addr == NULL) {
		LOG_WRN("Invalid input parameters");
		return 0U;
	}

	/* Read Bluetooth Address */
	err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_BD_ADDR, NULL, &rsp);
	if (err) {
		LOG_WRN("Failed to read public address");
		return 0U;
	}

	rp = (void *)rsp->data;

	if (bt_addr_eq(&rp->bdaddr, BT_ADDR_ANY) ||
	    bt_addr_eq(&rp->bdaddr, BT_ADDR_NONE)) {
		LOG_DBG("Controller has no public address");
		net_buf_unref(rsp);
		return 0U;
	}

	bt_addr_copy(&addr->a, &rp->bdaddr);
	addr->type = BT_ADDR_LE_PUBLIC;

	net_buf_unref(rsp);
	return 1U;
}

int bt_setup_public_id_addr(void)
{
	bt_addr_le_t addr;
	uint8_t *irk = NULL;

	bt_dev.id_count = bt_id_read_public_addr(&addr);

	if (!bt_dev.id_count) {
		return 0;
	}

#if defined(CONFIG_BT_PRIVACY)
	uint8_t ir_irk[16];
	uint8_t ir[16];

	bt_read_identity_root(ir);

	if (!IS_ENABLED(CONFIG_BT_PRIVACY_RANDOMIZE_IR)) {
		if (!bt_smp_irk_get(ir, ir_irk)) {
			irk = ir_irk;
		}
	}
#endif /* defined(CONFIG_BT_PRIVACY) */

	/* If true, `id_create` will randomize the IRK. */
	if (!irk && IS_ENABLED(CONFIG_BT_PRIVACY)) {
		/* `id_create` will not store the id when called before BT_DEV_READY.
		 * But since part of the id will be randomized, it needs to be stored.
		 */
		if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
			atomic_set_bit(bt_dev.flags, BT_DEV_STORE_ID);
		}
	}

	return id_create(BT_ID_DEFAULT, &addr, irk);
}

#if defined(CONFIG_BT_HCI_VS_EXT)
uint8_t bt_read_static_addr(struct bt_hci_vs_static_addr addrs[], uint8_t size)
{
	struct bt_hci_rp_vs_read_static_addrs *rp;
	struct net_buf *rsp;
	int err, i;
	uint8_t cnt;

	if (!BT_VS_CMD_READ_STATIC_ADDRS(bt_dev.vs_commands)) {
		LOG_WRN("Read Static Addresses command not available");
		return 0;
	}

	err = bt_hci_cmd_send_sync(BT_HCI_OP_VS_READ_STATIC_ADDRS, NULL, &rsp);
	if (err) {
		LOG_WRN("Failed to read static addresses");
		return 0;
	}

	if (IS_ENABLED(CONFIG_BT_HCI_VS_EXT_DETECT) &&
	    rsp->len < sizeof(struct bt_hci_rp_vs_read_static_addrs)) {
		LOG_WRN("Invalid Vendor HCI extensions");
		net_buf_unref(rsp);
		return 0;
	}

	rp = (void *)rsp->data;
	cnt = MIN(rp->num_addrs, size);

	if (IS_ENABLED(CONFIG_BT_HCI_VS_EXT_DETECT) &&
	    rsp->len != (sizeof(struct bt_hci_rp_vs_read_static_addrs) +
			 rp->num_addrs *
			 sizeof(struct bt_hci_vs_static_addr))) {
		LOG_WRN("Invalid Vendor HCI extensions");
		net_buf_unref(rsp);
		return 0;
	}

	for (i = 0; i < cnt; i++) {
		memcpy(&addrs[i], &rp->a[i], sizeof(struct bt_hci_vs_static_addr));
	}

	net_buf_unref(rsp);
	if (!cnt) {
		LOG_WRN("No static addresses stored in controller");
	}

	return cnt;
}
#endif /* CONFIG_BT_HCI_VS_EXT */

int bt_setup_random_id_addr(void)
{
#if defined(CONFIG_BT_HCI_VS_EXT) || defined(CONFIG_BT_CTLR)
	/* Only read the addresses if the user has not already configured one or
	 * more identities (!bt_dev.id_count).
	 */
	if (!bt_dev.id_count) {
		struct bt_hci_vs_static_addr addrs[CONFIG_BT_ID_MAX];

		bt_dev.id_count = bt_read_static_addr(addrs, CONFIG_BT_ID_MAX);

		if (bt_dev.id_count) {
			for (uint8_t i = 0; i < bt_dev.id_count; i++) {
				int err;
				bt_addr_le_t addr;
				uint8_t *irk = NULL;
#if defined(CONFIG_BT_PRIVACY)
				uint8_t ir_irk[16];

				if (!IS_ENABLED(CONFIG_BT_PRIVACY_RANDOMIZE_IR)) {
					if (!bt_smp_irk_get(addrs[i].ir, ir_irk)) {
						irk = ir_irk;
					}
				}
#endif /* CONFIG_BT_PRIVACY */

				/* If true, `id_create` will randomize the IRK. */
				if (!irk && IS_ENABLED(CONFIG_BT_PRIVACY)) {
					/* `id_create` will not store the id when called before
					 * BT_DEV_READY. But since part of the id will be
					 * randomized, it needs to be stored.
					 */
					if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
						atomic_set_bit(bt_dev.flags, BT_DEV_STORE_ID);
					}
				}

				bt_addr_copy(&addr.a, &addrs[i].bdaddr);
				addr.type = BT_ADDR_LE_RANDOM;

				err = id_create(i, &addr, irk);
				if (err) {
					return err;
				}
			}

			return 0;
		}
	}
#endif /* defined(CONFIG_BT_HCI_VS_EXT) || defined(CONFIG_BT_CTLR) */

	if (IS_ENABLED(CONFIG_BT_PRIVACY) && IS_ENABLED(CONFIG_BT_SETTINGS)) {
		atomic_set_bit(bt_dev.flags, BT_DEV_STORE_ID);
	}

	return bt_id_create(NULL, NULL);
}

#if defined(CONFIG_BT_CENTRAL)
static inline bool rpa_timeout_valid_check(void)
{
#if defined(CONFIG_BT_PRIVACY)
	uint32_t remaining_ms = k_ticks_to_ms_floor32(
		k_work_delayable_remaining_get(&bt_dev.rpa_update));
	/* Check if create conn timeout will happen before RPA timeout. */
	return remaining_ms > (10 * bt_dev.create_param.timeout);
#else
	return true;
#endif
}

int bt_id_set_create_conn_own_addr(bool use_filter, uint8_t *own_addr_type)
{
	int err;

	CHECKIF(own_addr_type == NULL) {
		return -EINVAL;
	}

	if (IS_ENABLED(CONFIG_BT_PRIVACY)) {
		if (use_filter || rpa_timeout_valid_check()) {
			err = bt_id_set_private_addr(BT_ID_DEFAULT);
			if (err) {
				return err;
			}
		} else {
			/* Force new RPA timeout so that RPA timeout is not
			 * triggered while direct initiator is active.
			 */
			le_force_rpa_timeout();
		}

		if (BT_FEAT_LE_PRIVACY(bt_dev.le.features)) {
			*own_addr_type = BT_HCI_OWN_ADDR_RPA_OR_RANDOM;
		} else {
			*own_addr_type = BT_ADDR_LE_RANDOM;
		}
	} else {
		const bt_addr_le_t *addr = &bt_dev.id_addr[BT_ID_DEFAULT];

		/* If Static Random address is used as Identity address we
		 * need to restore it before creating connection. Otherwise
		 * NRPA used for active scan could be used for connection.
		 */
		if (addr->type == BT_ADDR_LE_RANDOM) {
			err = set_random_address(&addr->a);
			if (err) {
				return err;
			}
		}

		*own_addr_type = addr->type;
	}

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

#if defined(CONFIG_BT_OBSERVER)
static bool is_adv_using_rand_addr(void)
{
	struct bt_le_ext_adv *adv;

	if (!IS_ENABLED(CONFIG_BT_BROADCASTER) ||
	    (IS_ENABLED(CONFIG_BT_EXT_ADV) &&
	     BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features))) {
		/* When advertising is not enabled or is using extended
		 * advertising HCI commands then only the scanner uses the set
		 * random address command.
		 */
		return false;
	}

	adv = bt_le_adv_lookup_legacy();

	return adv && atomic_test_bit(adv->flags, BT_ADV_ENABLED);
}

int bt_id_set_scan_own_addr(bool active_scan, uint8_t *own_addr_type)
{
	int err;

	CHECKIF(own_addr_type == NULL) {
		return -EINVAL;
	}

	if (IS_ENABLED(CONFIG_BT_PRIVACY)) {
		err = bt_id_set_private_addr(BT_ID_DEFAULT);
		if (err) {
			return err;
		}

		if (BT_FEAT_LE_PRIVACY(bt_dev.le.features)) {
			*own_addr_type = BT_HCI_OWN_ADDR_RPA_OR_RANDOM;
		} else {
			*own_addr_type = BT_ADDR_LE_RANDOM;
		}
	} else {
		*own_addr_type = bt_dev.id_addr[0].type;

		/* Use NRPA unless identity has been explicitly requested
		 * (through Kconfig).
		 * Use same RPA as legacy advertiser if advertising.
		 */
		if (!IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY) &&
		    !is_adv_using_rand_addr()) {
			err = bt_id_set_private_addr(BT_ID_DEFAULT);
			if (err) {
				if (active_scan || !is_adv_using_rand_addr()) {
					return err;
				}

				LOG_WRN("Ignoring failure to set address for passive scan (%d)",
					err);
			}

			*own_addr_type = BT_ADDR_LE_RANDOM;
		} else if (IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY) &&
			   *own_addr_type == BT_ADDR_LE_RANDOM) {
			/* If scanning with Identity Address we must set the
			 * random identity address for both active and passive
			 * scanner in order to receive adv reports that are
			 * directed towards this identity.
			 */
			err = set_random_address(&bt_dev.id_addr[0].a);
			if (err) {
				return err;
			}
		} else {
			LOG_DBG("Not changing the address");
		}
	}

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

int bt_id_set_adv_own_addr(struct bt_le_ext_adv *adv, uint32_t options,
			   bool dir_adv, uint8_t *own_addr_type)
{
	const bt_addr_le_t *id_addr;
	int err = 0;

	CHECKIF(adv == NULL || own_addr_type == NULL) {
		return -EINVAL;
	}

	/* Set which local identity address we're advertising with */
	id_addr = &bt_dev.id_addr[adv->id];

	/* Short-circuit to force NRPA usage */
	if (options & BT_LE_ADV_OPT_USE_NRPA) {
		if (options & BT_LE_ADV_OPT_USE_IDENTITY) {
			LOG_ERR("Can't set both IDENTITY & NRPA");

			return -EINVAL;
		}

		err = bt_id_set_adv_private_addr(adv);
		if (err) {
			return err;
		}
		*own_addr_type = BT_ADDR_LE_RANDOM;

		return 0;
	}

	if (options & BT_LE_ADV_OPT_CONNECTABLE) {
		if (dir_adv && (options & BT_LE_ADV_OPT_DIR_ADDR_RPA) &&
		    !BT_FEAT_LE_PRIVACY(bt_dev.le.features)) {
			return -ENOTSUP;
		}

		if (IS_ENABLED(CONFIG_BT_PRIVACY) &&
		    !(options & BT_LE_ADV_OPT_USE_IDENTITY)) {
			err = bt_id_set_adv_private_addr(adv);
			if (err) {
				return err;
			}

			if (dir_adv && (options & BT_LE_ADV_OPT_DIR_ADDR_RPA)) {
				*own_addr_type = BT_HCI_OWN_ADDR_RPA_OR_RANDOM;
			} else {
				*own_addr_type = BT_ADDR_LE_RANDOM;
			}
		} else {
			/*
			 * If Static Random address is used as Identity
			 * address we need to restore it before advertising
			 * is enabled. Otherwise NRPA used for active scan
			 * could be used for advertising.
			 */
			if (id_addr->type == BT_ADDR_LE_RANDOM) {
				err = bt_id_set_adv_random_addr(adv, &id_addr->a);
				if (err) {
					return err;
				}
			}

			*own_addr_type = id_addr->type;

			if (dir_adv && (options & BT_LE_ADV_OPT_DIR_ADDR_RPA)) {
				*own_addr_type |= BT_HCI_OWN_ADDR_RPA_MASK;
			}
		}
	} else {
		if (options & BT_LE_ADV_OPT_USE_IDENTITY) {
			if (id_addr->type == BT_ADDR_LE_RANDOM) {
				err = bt_id_set_adv_random_addr(adv, &id_addr->a);
			}

			*own_addr_type = id_addr->type;
		} else if (!(IS_ENABLED(CONFIG_BT_EXT_ADV) &&
			     BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features))) {
			/* In case advertising set random address is not
			 * available we must handle the shared random address
			 * problem.
			 */
#if defined(CONFIG_BT_OBSERVER)
			bool scan_enabled = false;

			/* If active scan with NRPA is ongoing refresh NRPA */
			if (!IS_ENABLED(CONFIG_BT_PRIVACY) &&
			    !IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY) &&
			    atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING)) {
				scan_enabled = true;
				bt_le_scan_set_enable(BT_HCI_LE_SCAN_DISABLE);
			}
#endif /* defined(CONFIG_BT_OBSERVER) */
			err = bt_id_set_adv_private_addr(adv);
			*own_addr_type = BT_ADDR_LE_RANDOM;

#if defined(CONFIG_BT_OBSERVER)
			if (scan_enabled) {
				bt_le_scan_set_enable(BT_HCI_LE_SCAN_ENABLE);
			}
#endif /* defined(CONFIG_BT_OBSERVER) */
		} else {
			err = bt_id_set_adv_private_addr(adv);
			*own_addr_type = BT_ADDR_LE_RANDOM;
		}

		if (err) {
			return err;
		}
	}

	return 0;
}

#if defined(CONFIG_BT_CLASSIC)
int bt_br_oob_get_local(struct bt_br_oob *oob)
{
	CHECKIF(oob == NULL) {
		return -EINVAL;
	}

	bt_addr_copy(&oob->addr, &bt_dev.id_addr[0].a);

	return 0;
}
#endif /* CONFIG_BT_CLASSIC */

int bt_le_oob_get_local(uint8_t id, struct bt_le_oob *oob)
{
	struct bt_le_ext_adv *adv = NULL;
	int err;

	CHECKIF(oob == NULL) {
		return -EINVAL;
	}

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

	if (id >= CONFIG_BT_ID_MAX) {
		return -EINVAL;
	}

	if (IS_ENABLED(CONFIG_BT_BROADCASTER)) {
		adv = bt_le_adv_lookup_legacy();
	}

	if (IS_ENABLED(CONFIG_BT_PRIVACY) &&
	    !(adv && adv->id == id &&
	      atomic_test_bit(adv->flags, BT_ADV_ENABLED) &&
	      atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY) &&
	      bt_dev.id_addr[id].type == BT_ADDR_LE_RANDOM)) {
		if (IS_ENABLED(CONFIG_BT_CENTRAL) &&
		    atomic_test_bit(bt_dev.flags, BT_DEV_INITIATING)) {
			struct bt_conn *conn;

			conn = bt_conn_lookup_state_le(BT_ID_DEFAULT, NULL,
						       BT_CONN_SCAN_BEFORE_INITIATING);
			if (conn) {
				/* Cannot set new RPA while creating
				 * connections.
				 */
				bt_conn_unref(conn);
				return -EINVAL;
			}
		}

		if (adv &&
		    atomic_test_bit(adv->flags, BT_ADV_ENABLED) &&
		    atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY) &&
		    (bt_dev.id_addr[id].type == BT_ADDR_LE_RANDOM)) {
			/* Cannot set a new RPA address while advertising with
			 * random static identity address for a different
			 * identity.
			 */
			return -EINVAL;
		}

		if (IS_ENABLED(CONFIG_BT_OBSERVER) &&
		    CONFIG_BT_ID_MAX > 1 &&
		    id != BT_ID_DEFAULT &&
		    (atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING) ||
		     atomic_test_bit(bt_dev.flags, BT_DEV_INITIATING))) {
			/* Cannot switch identity of scanner or initiator */
			return -EINVAL;
		}

		le_force_rpa_timeout();

		bt_addr_le_copy(&oob->addr, &bt_dev.random_addr);
	} else {
		bt_addr_le_copy(&oob->addr, &bt_dev.id_addr[id]);
	}

	if (IS_ENABLED(CONFIG_BT_SMP)) {
		err = bt_smp_le_oob_generate_sc_data(&oob->le_sc_data);
		if (err && err != -ENOTSUP) {
			return err;
		}
	}

	return 0;
}

#if defined(CONFIG_BT_EXT_ADV)
int bt_le_ext_adv_oob_get_local(struct bt_le_ext_adv *adv,
				struct bt_le_oob *oob)
{
	int err;

	CHECKIF(adv == NULL || oob == NULL) {
		return -EINVAL;
	}

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

	if (IS_ENABLED(CONFIG_BT_PRIVACY) &&
	    !atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY)) {
		/* Don't refresh RPA addresses if the RPA is new.
		 * This allows back to back calls to this function or
		 * bt_le_oob_get_local to not invalidate the previously set
		 * RPAs.
		 */
		if (!atomic_test_bit(adv->flags, BT_ADV_LIMITED) &&
		    !bt_id_rpa_is_new()) {
			if (IS_ENABLED(CONFIG_BT_CENTRAL) &&
			    atomic_test_bit(bt_dev.flags, BT_DEV_INITIATING)) {
				struct bt_conn *conn;

				conn = bt_conn_lookup_state_le(
					BT_ID_DEFAULT, NULL,
					BT_CONN_SCAN_BEFORE_INITIATING);

				if (conn) {
					/* Cannot set new RPA while creating
					 * connections.
					 */
					bt_conn_unref(conn);
					return -EINVAL;
				}
			}

			le_force_rpa_timeout();
		}

		bt_addr_le_copy(&oob->addr, &adv->random_addr);
	} else {
		bt_addr_le_copy(&oob->addr, &bt_dev.id_addr[adv->id]);
	}

	if (IS_ENABLED(CONFIG_BT_SMP)) {
		err = bt_smp_le_oob_generate_sc_data(&oob->le_sc_data);
		if (err && err != -ENOTSUP) {
			return err;
		}
	}

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

#if defined(CONFIG_BT_SMP)
#if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
int bt_le_oob_set_legacy_tk(struct bt_conn *conn, const uint8_t *tk)
{
	CHECKIF(conn == NULL || tk == NULL) {
		return -EINVAL;
	}

	return bt_smp_le_oob_set_tk(conn, tk);
}
#endif /* !defined(CONFIG_BT_SMP_SC_PAIR_ONLY) */

#if !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
int bt_le_oob_set_sc_data(struct bt_conn *conn,
			  const struct bt_le_oob_sc_data *oobd_local,
			  const struct bt_le_oob_sc_data *oobd_remote)
{
	CHECKIF(conn == NULL) {
		return -EINVAL;
	}

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

	return bt_smp_le_oob_set_sc_data(conn, oobd_local, oobd_remote);
}

int bt_le_oob_get_sc_data(struct bt_conn *conn,
			  const struct bt_le_oob_sc_data **oobd_local,
			  const struct bt_le_oob_sc_data **oobd_remote)
{
	CHECKIF(conn == NULL) {
		return -EINVAL;
	}

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

	return bt_smp_le_oob_get_sc_data(conn, oobd_local, oobd_remote);
}
#endif /* !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY) */
#endif /* defined(CONFIG_BT_SMP) */

int bt_id_init(void)
{
	int err;

#if defined(CONFIG_BT_PRIVACY)
	k_work_init_delayable(&bt_dev.rpa_update, rpa_timeout);
#if defined(CONFIG_BT_RPA_SHARING)
	for (uint8_t id = 0U; id < ARRAY_SIZE(bt_dev.rpa); id++) {
		bt_addr_copy(&bt_dev.rpa[id], BT_ADDR_NONE);
	}
#endif
#endif

	if (!IS_ENABLED(CONFIG_BT_SETTINGS) && !bt_dev.id_count) {
		LOG_DBG("No user identity. Trying to set public.");

		err = bt_setup_public_id_addr();
		if (err) {
			LOG_ERR("Unable to set identity address");
			return err;
		}
	}

	if (!IS_ENABLED(CONFIG_BT_SETTINGS) && !bt_dev.id_count) {
		LOG_DBG("No public address. Trying to set static random.");

		err = bt_setup_random_id_addr();
		if (err) {
			LOG_ERR("Unable to set identity address");
			return err;
		}

		/* The passive scanner just sends a dummy address type in the
		 * command. If the first activity does this, and the dummy type
		 * is a random address, it needs a valid value, even though it's
		 * not actually used.
		 */
		err = set_random_address(&bt_dev.id_addr[0].a);
		if (err) {
			LOG_ERR("Unable to set random address");
			return err;
		}
	}

	return 0;
}
