/*
 * Copyright (c) 2017-2019 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <string.h>

#include <zephyr/kernel.h>
#include <soc.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/sys/byteorder.h>

#include "hal/cpu.h"
#include "hal/ccm.h"

#include "util/util.h"
#include "util/mem.h"
#include "util/memq.h"
#include "util/mayfly.h"
#include "util/dbuf.h"

#include "pdu.h"

#include "lll.h"
#include "lll/lll_adv_types.h"
#include "lll_adv.h"
#include "lll/lll_adv_pdu.h"
#include "lll_scan.h"
#include "lll/lll_df_types.h"
#include "lll_conn.h"
#include "lll_filter.h"

#if (!defined(CONFIG_BT_LL_SW_LLCP_LEGACY))
#include "ll_sw/ull_tx_queue.h"
#endif

#include "ull_adv_types.h"
#include "ull_scan_types.h"
#include "ull_conn_types.h"
#include "ull_filter.h"

#include "ull_internal.h"
#include "ull_adv_internal.h"
#include "ull_scan_internal.h"
#include "ull_conn_internal.h"

#include "ll.h"

#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
#define LOG_MODULE_NAME bt_ctlr_ull_filter
#include "common/log.h"
#include "hal/debug.h"

#define ADDR_TYPE_ANON 0xFF

#if defined(CONFIG_BT_CTLR_FILTER_ACCEPT_LIST)
/* Hardware Filter Accept List */
static struct lll_filter fal_filter;

#if defined(CONFIG_BT_CTLR_PRIVACY)
#include "common/rpa.h"

/* Filter Accept List peer list */
static struct lll_fal fal[CONFIG_BT_CTLR_FAL_SIZE];

/* Resolving list */
static struct lll_resolve_list rl[CONFIG_BT_CTLR_RL_SIZE];
static uint8_t rl_enable;

#if defined(CONFIG_BT_CTLR_SW_DEFERRED_PRIVACY)
/* Cache of known unknown peer RPAs */
static uint8_t newest_prpa;
static struct lll_prpa_cache prpa_cache[CONFIG_BT_CTLR_RPA_CACHE_SIZE];

struct prpa_resolve_work {
	struct k_work prpa_work;
	bt_addr_t     rpa;
	resolve_callback_t cb;
};

struct target_resolve_work {
	struct k_work target_work;
	bt_addr_t rpa;
	uint8_t      idx;
	resolve_callback_t cb;
};
#endif /* CONFIG_BT_CTLR_SW_DEFERRED_PRIVACY */

static uint8_t peer_irks[CONFIG_BT_CTLR_RL_SIZE][IRK_SIZE];
static uint8_t peer_irk_rl_ids[CONFIG_BT_CTLR_RL_SIZE];
static uint8_t peer_irk_count;

static bt_addr_t local_rpas[CONFIG_BT_CTLR_RL_SIZE];

#if defined(CONFIG_BT_CTLR_SW_DEFERRED_PRIVACY)
static struct prpa_resolve_work resolve_work;
static struct target_resolve_work t_work;

BUILD_ASSERT(ARRAY_SIZE(prpa_cache) < FILTER_IDX_NONE);
#endif /* CONFIG_BT_CTLR_SW_DEFERRED_PRIVACY */
BUILD_ASSERT(ARRAY_SIZE(fal) < FILTER_IDX_NONE);
BUILD_ASSERT(ARRAY_SIZE(rl) < FILTER_IDX_NONE);

/* Hardware filter for the resolving list */
static struct lll_filter rl_filter;

#define DEFAULT_RPA_TIMEOUT_MS (900 * 1000)
static uint32_t rpa_timeout_ms;
static int64_t rpa_last_ms;

static struct k_work_delayable rpa_work;

#define LIST_MATCH(list, i, type, addr) (list[i].taken && \
		    (list[i].id_addr_type == (type & 0x1)) && \
		    !memcmp(list[i].id_addr.val, addr, BDADDR_SIZE))

static void fal_clear(void);
static uint8_t fal_find(uint8_t addr_type, const uint8_t *const addr,
			uint8_t *const free_idx);
static uint32_t fal_add(bt_addr_le_t *id_addr);
static uint32_t fal_remove(bt_addr_le_t *id_addr);
static void fal_update(void);

static void rl_clear(void);
static void rl_update(void);
static int rl_access_check(bool check_ar);

#if defined(CONFIG_BT_BROADCASTER)
static void rpa_adv_refresh(struct ll_adv_set *adv);
#endif
static void rpa_timeout(struct k_work *work);
static void rpa_refresh_start(void);
static void rpa_refresh_stop(void);
#else /* !CONFIG_BT_CTLR_PRIVACY */
static uint32_t filter_add(struct lll_filter *filter, uint8_t addr_type,
			uint8_t *bdaddr);
static uint32_t filter_remove(struct lll_filter *filter, uint8_t addr_type,
			   uint8_t *bdaddr);
#endif /* !CONFIG_BT_CTLR_PRIVACY */

static uint32_t filter_find(const struct lll_filter *const filter,
			    uint8_t addr_type, const uint8_t *const bdaddr);
static void filter_insert(struct lll_filter *const filter, int index,
			  uint8_t addr_type, const uint8_t *const bdaddr);
static void filter_clear(struct lll_filter *filter);

#if defined(CONFIG_BT_CTLR_PRIVACY) && \
	defined(CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN)
static void conn_rpa_update(uint8_t rl_idx);
#endif /* CONFIG_BT_CTLR_PRIVACY && CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN */

#if defined(CONFIG_BT_CTLR_SW_DEFERRED_PRIVACY)
static void prpa_cache_clear(void);
static uint8_t prpa_cache_find(bt_addr_t *prpa_cache_addr);
static void prpa_cache_add(bt_addr_t *prpa_cache_addr);
static uint8_t prpa_cache_try_resolve(bt_addr_t *rpa);
static void prpa_cache_resolve(struct k_work *work);
static void target_resolve(struct k_work *work);
#endif /* CONFIG_BT_CTLR_SW_DEFERRED_PRIVACY */
#endif /* CONFIG_BT_CTLR_FILTER_ACCEPT_LIST */

#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST)
#define PAL_ADDR_MATCH(type, addr) \
		(pal[i].taken && \
		 (pal[i].id_addr_type == (type & 0x1)) && \
		 !memcmp(pal[i].id_addr.val, addr, BDADDR_SIZE))

#define PAL_MATCH(type, addr, sid) \
		(PAL_ADDR_MATCH(type, addr) && \
		 (pal[i].sid == sid))

/* Periodic Advertising Accept List */
#define PAL_SIZE CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST_SIZE
static struct lll_pal pal[PAL_SIZE];

static void pal_clear(void);
#if defined(CONFIG_BT_CTLR_PRIVACY)
static uint8_t pal_addr_find(const uint8_t addr_type,
			     const uint8_t *const addr);
#endif /* CONFIG_BT_CTLR_PRIVACY */
static uint8_t pal_find(const uint8_t addr_type, const uint8_t *const addr,
			const uint8_t sid, uint8_t *const free_idx);
static uint32_t pal_add(const bt_addr_le_t *const id_addr, const uint8_t sid);
static uint32_t pal_remove(const bt_addr_le_t *const id_addr,
			   const uint8_t sid);
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST */

#if defined(CONFIG_BT_CTLR_FILTER_ACCEPT_LIST)
uint8_t ll_fal_size_get(void)
{
	return CONFIG_BT_CTLR_FAL_SIZE;
}

uint8_t ll_fal_clear(void)
{
#if defined(CONFIG_BT_BROADCASTER)
	if (ull_adv_filter_pol_get(0)) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}
#endif /* CONFIG_BT_BROADCASTER */

#if defined(CONFIG_BT_OBSERVER)
	if (ull_scan_filter_pol_get(0) & 0x1) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}
#endif /* CONFIG_BT_OBSERVER */

#if defined(CONFIG_BT_CTLR_PRIVACY)
	fal_clear();
#else
	filter_clear(&fal_filter);
#endif /* CONFIG_BT_CTLR_PRIVACY */

	return 0;
}

uint8_t ll_fal_add(bt_addr_le_t *addr)
{
#if defined(CONFIG_BT_BROADCASTER)
	if (ull_adv_filter_pol_get(0)) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}
#endif /* CONFIG_BT_BROADCASTER */

#if defined(CONFIG_BT_OBSERVER)
	if (ull_scan_filter_pol_get(0) & 0x1) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}
#endif /* CONFIG_BT_OBSERVER */

	if (addr->type == ADDR_TYPE_ANON) {
		return 0;
	}

#if defined(CONFIG_BT_CTLR_PRIVACY)
	return fal_add(addr);
#else
	return filter_add(&fal_filter, addr->type, addr->a.val);
#endif /* CONFIG_BT_CTLR_PRIVACY */
}

uint8_t ll_fal_remove(bt_addr_le_t *addr)
{
#if defined(CONFIG_BT_BROADCASTER)
	if (ull_adv_filter_pol_get(0)) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}
#endif /* CONFIG_BT_BROADCASTER */

#if defined(CONFIG_BT_OBSERVER)
	if (ull_scan_filter_pol_get(0) & 0x1) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}
#endif /* CONFIG_BT_OBSERVER */

	if (addr->type == ADDR_TYPE_ANON) {
		return 0;
	}

#if defined(CONFIG_BT_CTLR_PRIVACY)
	return fal_remove(addr);
#else
	return filter_remove(&fal_filter, addr->type, addr->a.val);
#endif /* CONFIG_BT_CTLR_PRIVACY */
}

#if defined(CONFIG_BT_CTLR_PRIVACY)
void ll_rl_id_addr_get(uint8_t rl_idx, uint8_t *id_addr_type, uint8_t *id_addr)
{
	LL_ASSERT(rl_idx < CONFIG_BT_CTLR_RL_SIZE);
	LL_ASSERT(rl[rl_idx].taken);

	*id_addr_type = rl[rl_idx].id_addr_type;
	(void)memcpy(id_addr, rl[rl_idx].id_addr.val, BDADDR_SIZE);
}

uint8_t ll_rl_size_get(void)
{
	return CONFIG_BT_CTLR_RL_SIZE;
}

uint8_t ll_rl_clear(void)
{
	if (!rl_access_check(false)) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}

	rl_clear();

	return 0;
}

uint8_t ll_rl_add(bt_addr_le_t *id_addr, const uint8_t pirk[IRK_SIZE],
	       const uint8_t lirk[IRK_SIZE])
{
	uint8_t i, j;

	if (!rl_access_check(false)) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}

	i = ull_filter_rl_find(id_addr->type, id_addr->a.val, &j);

	/* Duplicate check */
	if (i < ARRAY_SIZE(rl)) {
		return BT_HCI_ERR_INVALID_PARAM;
	} else if (j >= ARRAY_SIZE(rl)) {
		return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
	}

	/* Device not found but empty slot found */
	i = j;

	bt_addr_copy(&rl[i].id_addr, &id_addr->a);
	rl[i].id_addr_type = id_addr->type & 0x1;
	rl[i].pirk = mem_nz((uint8_t *)pirk, IRK_SIZE);
	rl[i].lirk = mem_nz((uint8_t *)lirk, IRK_SIZE);
	if (rl[i].pirk) {
		/* cross-reference */
		rl[i].pirk_idx = peer_irk_count;
		peer_irk_rl_ids[peer_irk_count] = i;
		/* AAR requires big-endian IRKs */
		sys_memcpy_swap(peer_irks[peer_irk_count++], pirk, IRK_SIZE);
#if defined(CONFIG_BT_CTLR_SW_DEFERRED_PRIVACY)
		/* a new key was added, invalidate the known/unknown list */
		prpa_cache_clear();
#endif
	}
	if (rl[i].lirk) {
		(void)memcpy(rl[i].local_irk, lirk, IRK_SIZE);
		rl[i].local_rpa = NULL;
	}
	memset(rl[i].curr_rpa.val, 0x00, sizeof(rl[i].curr_rpa));
	rl[i].rpas_ready = 0U;
#if defined(CONFIG_BT_CTLR_SW_DEFERRED_PRIVACY)
	memset(rl[i].target_rpa.val, 0x00, sizeof(rl[i].target_rpa));
#endif
	/* Default to Network Privacy */
	rl[i].dev = 0U;
	/* Add reference to  a Filter Accept List entry */
	j = fal_find(id_addr->type, id_addr->a.val, NULL);
	if (j < ARRAY_SIZE(fal)) {
		fal[j].rl_idx = i;
		rl[i].fal = 1U;
	} else {
		rl[i].fal = 0U;
	}

#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST)
	/* Add reference to a periodic list entry */
	j = pal_addr_find(id_addr->type, id_addr->a.val);
	if (j < ARRAY_SIZE(pal)) {
		pal[j].rl_idx = i;
		rl[i].pal = j + 1U;
	} else {
		rl[i].pal = 0U;
	}
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST */

	rl[i].taken = 1U;

	return 0;
}

uint8_t ll_rl_remove(bt_addr_le_t *id_addr)
{
	uint8_t i;

	if (!rl_access_check(false)) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}

	/* find the device and mark it as empty */
	i = ull_filter_rl_find(id_addr->type, id_addr->a.val, NULL);
	if (i < ARRAY_SIZE(rl)) {
		uint8_t j, k;

		if (rl[i].pirk) {
			/* Swap with last item */
			uint8_t pi = rl[i].pirk_idx, pj = peer_irk_count - 1;

			if (pj && pi != pj) {
				(void)memcpy(peer_irks[pi], peer_irks[pj],
					     IRK_SIZE);
				for (k = 0U;
				     k < CONFIG_BT_CTLR_RL_SIZE;
				     k++) {

					if (rl[k].taken && rl[k].pirk &&
					    rl[k].pirk_idx == pj) {
						rl[k].pirk_idx = pi;
						peer_irk_rl_ids[pi] = k;
						break;
					}
				}
			}
			peer_irk_count--;
		}

		/* Check if referenced by a Filter Accept List entry */
		j = fal_find(id_addr->type, id_addr->a.val, NULL);
		if (j < ARRAY_SIZE(fal)) {
			fal[j].rl_idx = FILTER_IDX_NONE;
		}

#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST)
		/* Check if referenced by a periodic list entry */
		j = pal_addr_find(id_addr->type, id_addr->a.val);
		if (j < ARRAY_SIZE(pal)) {
			pal[j].rl_idx = FILTER_IDX_NONE;
		}
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST */

		rl[i].taken = 0U;

		return 0;
	}

	return BT_HCI_ERR_UNKNOWN_CONN_ID;
}

void ll_rl_crpa_set(uint8_t id_addr_type, uint8_t *id_addr, uint8_t rl_idx,
		    uint8_t *crpa)
{
	if ((crpa[5] & 0xc0) == 0x40) {

		if (id_addr) {
			/* find the device and return its RPA */
			rl_idx = ull_filter_rl_find(id_addr_type, id_addr,
						    NULL);
		}

		if (rl_idx < ARRAY_SIZE(rl) && rl[rl_idx].taken) {
			(void)memcpy(rl[rl_idx].curr_rpa.val, crpa,
				     sizeof(bt_addr_t));
#if defined(CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN)
			conn_rpa_update(rl_idx);
#endif /* CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN) */
		}
	}
}

uint8_t ll_rl_crpa_get(bt_addr_le_t *id_addr, bt_addr_t *crpa)
{
	uint8_t i;

	/* find the device and return its RPA */
	i = ull_filter_rl_find(id_addr->type, id_addr->a.val, NULL);
	if (i < ARRAY_SIZE(rl) &&
	    mem_nz(rl[i].curr_rpa.val, sizeof(rl[i].curr_rpa.val))) {
		bt_addr_copy(crpa, &rl[i].curr_rpa);
		return 0;
	}

	return BT_HCI_ERR_UNKNOWN_CONN_ID;
}

uint8_t ll_rl_lrpa_get(bt_addr_le_t *id_addr, bt_addr_t *lrpa)
{
	uint8_t i;

	/* find the device and return the local RPA */
	i = ull_filter_rl_find(id_addr->type, id_addr->a.val, NULL);
	if (i < ARRAY_SIZE(rl)) {
		bt_addr_copy(lrpa, rl[i].local_rpa);
		return 0;
	}

	return BT_HCI_ERR_UNKNOWN_CONN_ID;
}

uint8_t ll_rl_enable(uint8_t enable)
{
	if (!rl_access_check(false)) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}

	switch (enable) {
	case BT_HCI_ADDR_RES_DISABLE:
		rl_enable = 0U;
		break;
	case BT_HCI_ADDR_RES_ENABLE:
		rl_enable = 1U;
		break;
	default:
		return BT_HCI_ERR_INVALID_PARAM;
	}

	return 0;
}

void ll_rl_timeout_set(uint16_t timeout)
{
	rpa_timeout_ms = timeout * 1000U;
}

uint8_t ll_priv_mode_set(bt_addr_le_t *id_addr, uint8_t mode)
{
	uint8_t i;

	if (!rl_access_check(false)) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}

	/* find the device and mark it as empty */
	i = ull_filter_rl_find(id_addr->type, id_addr->a.val, NULL);
	if (i < ARRAY_SIZE(rl)) {
		switch (mode) {
		case BT_HCI_LE_PRIVACY_MODE_NETWORK:
			rl[i].dev = 0U;
			break;
		case BT_HCI_LE_PRIVACY_MODE_DEVICE:
			rl[i].dev = 1U;
			break;
		default:
			return BT_HCI_ERR_INVALID_PARAM;
		}
	} else {
		return BT_HCI_ERR_UNKNOWN_CONN_ID;
	}

	return 0;
}
#endif /* CONFIG_BT_CTLR_PRIVACY */
#endif /* CONFIG_BT_CTLR_FILTER_ACCEPT_LIST */

#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST)
uint8_t ll_pal_size_get(void)
{
	return PAL_SIZE;
}

uint8_t ll_pal_clear(void)
{
	/* FIXME: Check and fail if Periodic Advertising Create Sync is pending.
	 */

	pal_clear();

	return 0;
}

uint8_t ll_pal_add(const bt_addr_le_t *const addr, const uint8_t sid)
{
	/* FIXME: Check and fail if Periodic Advertising Create Sync is pending.
	 */

	if (addr->type == ADDR_TYPE_ANON) {
		return 0;
	}

	return pal_add(addr, sid);
}

uint8_t ll_pal_remove(const bt_addr_le_t *const addr, const uint8_t sid)
{
	/* FIXME: Check and fail if Periodic Advertising Create Sync is pending.
	 */

	if (addr->type == ADDR_TYPE_ANON) {
		return 0;
	}

	return pal_remove(addr, sid);
}

bool ull_filter_ull_pal_addr_match(const uint8_t addr_type,
				   const uint8_t *const addr)
{
	for (int i = 0; i < PAL_SIZE; i++) {
		if (PAL_ADDR_MATCH(addr_type, addr)) {
			return true;
		}
	}

	return false;
}

bool ull_filter_ull_pal_match(const uint8_t addr_type,
			      const uint8_t *const addr, const uint8_t sid)
{
	for (int i = 0; i < PAL_SIZE; i++) {
		if (PAL_MATCH(addr_type, addr, sid)) {
			return true;
		}
	}

	return false;
}

#if defined(CONFIG_BT_CTLR_PRIVACY)
bool ull_filter_ull_pal_listed(const uint8_t rl_idx, uint8_t *const addr_type,
			      uint8_t *const addr)
{
	if (rl_idx >= ARRAY_SIZE(rl)) {
		return false;
	}

	LL_ASSERT(rl[rl_idx].taken);

	if (rl[rl_idx].pal) {
		uint8_t pal_idx = rl[rl_idx].pal - 1;

		*addr_type = pal[pal_idx].id_addr_type;
		(void)memcpy(addr, pal[pal_idx].id_addr.val, BDADDR_SIZE);

		return true;
	}

	return false;
}
#endif /* CONFIG_BT_CTLR_PRIVACY */
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST */

void ull_filter_reset(bool init)
{
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST)
	pal_clear();
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST */

#if defined(CONFIG_BT_CTLR_PRIVACY)
	fal_clear();

	rl_enable = 0U;
	rpa_timeout_ms = DEFAULT_RPA_TIMEOUT_MS;
	rpa_last_ms = -1;
	rl_clear();
#if defined(CONFIG_BT_CTLR_SW_DEFERRED_PRIVACY)
	prpa_cache_clear();
#endif
	if (init) {
		k_work_init_delayable(&rpa_work, rpa_timeout);
#if defined(CONFIG_BT_CTLR_SW_DEFERRED_PRIVACY)
		k_work_init(&(resolve_work.prpa_work), prpa_cache_resolve);
		k_work_init(&(t_work.target_work), target_resolve);
#endif
	} else {
		k_work_cancel_delayable(&rpa_work);
	}
#elif defined(CONFIG_BT_CTLR_FILTER_ACCEPT_LIST)
	filter_clear(&fal_filter);
#endif /* CONFIG_BT_CTLR_FILTER_ACCEPT_LIST */
}

#if defined(CONFIG_BT_CTLR_FILTER_ACCEPT_LIST)
struct lll_filter *ull_filter_lll_get(bool filter)
{
#if defined(CONFIG_BT_CTLR_PRIVACY)
	if (filter) {
		return &fal_filter;
	}
	return &rl_filter;
#else
	LL_ASSERT(filter);
	return &fal_filter;
#endif
}

uint8_t ull_filter_lll_fal_match(const struct lll_filter *const filter,
				 uint8_t addr_type, const uint8_t *const addr,
				 uint8_t *devmatch_id)
{
	*devmatch_id = filter_find(filter, addr_type, addr);

	return (*devmatch_id) == FILTER_IDX_NONE ? 0U : 1U;
}

#if defined(CONFIG_BT_CTLR_PRIVACY)
void ull_filter_adv_scan_state_cb(uint8_t bm)
{
	if (bm) {
		rpa_refresh_start();
	} else {
		rpa_refresh_stop();
	}
}

void ull_filter_adv_update(uint8_t adv_fp)
{
	/* Clear before populating filter */
	filter_clear(&fal_filter);

	/* enabling advertising */
	if (adv_fp &&
	    (!IS_ENABLED(CONFIG_BT_OBSERVER) ||
	     !(ull_scan_filter_pol_get(0) & 0x1))) {
		/* filter accept list not in use, update FAL */
		fal_update();
	}

	/* Clear before populating rl filter */
	filter_clear(&rl_filter);

	if (rl_enable &&
	    (!IS_ENABLED(CONFIG_BT_OBSERVER) || !ull_scan_is_enabled(0))) {
		/* rl not in use, update resolving list LUT */
		rl_update();
	}
}

void ull_filter_scan_update(uint8_t scan_fp)
{
	/* Clear before populating filter */
	filter_clear(&fal_filter);

	/* enabling advertising */
	if ((scan_fp & 0x1) &&
	    (!IS_ENABLED(CONFIG_BT_BROADCASTER) ||
	     !ull_adv_filter_pol_get(0))) {
		/* Filter Accept List not in use, update FAL */
		fal_update();
	}

	/* Clear before populating rl filter */
	filter_clear(&rl_filter);

	if (rl_enable &&
	    (!IS_ENABLED(CONFIG_BT_BROADCASTER) || !ull_adv_is_enabled(0))) {
		/* rl not in use, update resolving list LUT */
		rl_update();
	}
}

void ull_filter_rpa_update(bool timeout)
{
	uint8_t i;
	int err;
	int64_t now = k_uptime_get();
	bool all = timeout || (rpa_last_ms == -1) ||
		   (now - rpa_last_ms >= rpa_timeout_ms);
	BT_DBG("");

	for (i = 0U; i < CONFIG_BT_CTLR_RL_SIZE; i++) {
		if ((rl[i].taken) && (all || !rl[i].rpas_ready)) {

			if (rl[i].pirk) {
				uint8_t irk[IRK_SIZE];

				/* TODO: move this swap to the driver level */
				sys_memcpy_swap(irk, peer_irks[rl[i].pirk_idx],
						IRK_SIZE);
				err = bt_rpa_create(irk, &rl[i].peer_rpa);
				LL_ASSERT(!err);
#if defined(CONFIG_BT_CTLR_SW_DEFERRED_PRIVACY)
				/* a new key was added,
				 * invalidate the known/unknown peer RPA cache
				 */
				prpa_cache_clear();
#endif
			}

			if (rl[i].lirk) {
				bt_addr_t rpa;

				err = bt_rpa_create(rl[i].local_irk, &rpa);
				LL_ASSERT(!err);
				/* pointer read/write assumed to be atomic
				 * so that if ISR fires the local_rpa pointer
				 * will always point to a valid full RPA
				 */
				rl[i].local_rpa = &rpa;
				bt_addr_copy(&local_rpas[i], &rpa);
				rl[i].local_rpa = &local_rpas[i];
			}

			rl[i].rpas_ready = 1U;
		}
	}

	if (all) {
		rpa_last_ms = now;
	}

	if (timeout) {
#if defined(CONFIG_BT_BROADCASTER)
		uint8_t handle;

		for (handle = 0U; handle < BT_CTLR_ADV_SET; handle++) {
			struct ll_adv_set *adv;

			adv = ull_adv_is_enabled_get(handle);
			if (adv) {
				rpa_adv_refresh(adv);
			}
		}
#endif
	}
}

#if defined(CONFIG_BT_BROADCASTER)
const uint8_t *ull_filter_adva_get(uint8_t rl_idx)
{
	/* AdvA */
	if (rl_idx < ARRAY_SIZE(rl) && rl[rl_idx].lirk) {
		LL_ASSERT(rl[rl_idx].rpas_ready);
		return rl[rl_idx].local_rpa->val;
	}

	return NULL;
}

const uint8_t *ull_filter_tgta_get(uint8_t rl_idx)
{
	/* TargetA */
	if (rl_idx < ARRAY_SIZE(rl) && rl[rl_idx].pirk) {
		return rl[rl_idx].peer_rpa.val;
	}

	return NULL;
}
#endif /* CONFIG_BT_BROADCASTER */

uint8_t ull_filter_rl_find(uint8_t id_addr_type, uint8_t const *const id_addr,
			   uint8_t *const free_idx)
{
	uint8_t i;

	if (free_idx) {
		*free_idx = FILTER_IDX_NONE;
	}

	for (i = 0U; i < CONFIG_BT_CTLR_RL_SIZE; i++) {
		if (LIST_MATCH(rl, i, id_addr_type, id_addr)) {
			return i;
		} else if (free_idx && !rl[i].taken &&
			   (*free_idx == FILTER_IDX_NONE)) {
			*free_idx = i;
		}
	}

	return FILTER_IDX_NONE;
}

bool ull_filter_lll_lrpa_used(uint8_t rl_idx)
{
	return rl_idx < ARRAY_SIZE(rl) && rl[rl_idx].lirk;
}

bt_addr_t *ull_filter_lll_lrpa_get(uint8_t rl_idx)
{
	if ((rl_idx >= ARRAY_SIZE(rl)) || !rl[rl_idx].lirk ||
	    !rl[rl_idx].rpas_ready) {
		return NULL;
	}

	return rl[rl_idx].local_rpa;
}

uint8_t *ull_filter_lll_irks_get(uint8_t *count)
{
	*count = peer_irk_count;
	return (uint8_t *)peer_irks;
}

uint8_t ull_filter_lll_rl_idx(bool filter, uint8_t devmatch_id)
{
	uint8_t i;

	if (filter) {
		LL_ASSERT(devmatch_id < ARRAY_SIZE(fal));
		LL_ASSERT(fal[devmatch_id].taken);
		i = fal[devmatch_id].rl_idx;
	} else {
		LL_ASSERT(devmatch_id < ARRAY_SIZE(rl));
		i = devmatch_id;
		LL_ASSERT(rl[i].taken);
	}

	return i;
}

uint8_t ull_filter_lll_rl_irk_idx(uint8_t irkmatch_id)
{
	uint8_t i;

	LL_ASSERT(irkmatch_id < peer_irk_count);
	i = peer_irk_rl_ids[irkmatch_id];
	LL_ASSERT(i < CONFIG_BT_CTLR_RL_SIZE);
	LL_ASSERT(rl[i].taken);

	return i;
}

bool ull_filter_lll_irk_in_fal(uint8_t rl_idx)
{
	if (rl_idx >= ARRAY_SIZE(rl)) {
		return false;
	}

	LL_ASSERT(rl[rl_idx].taken);

	return rl[rl_idx].fal;
}

struct lll_fal *ull_filter_lll_fal_get(void)
{
	return fal;
}

struct lll_resolve_list *ull_filter_lll_resolve_list_get(void)
{
	return rl;
}

bool ull_filter_lll_rl_idx_allowed(uint8_t irkmatch_ok, uint8_t rl_idx)
{
	/* If AR is disabled or we don't know the device or we matched an IRK
	 * then we're all set.
	 */
	if (!rl_enable || rl_idx >= ARRAY_SIZE(rl) || irkmatch_ok) {
		return true;
	}

	LL_ASSERT(rl_idx < CONFIG_BT_CTLR_RL_SIZE);
	LL_ASSERT(rl[rl_idx].taken);

	return !rl[rl_idx].pirk || rl[rl_idx].dev;
}

bool ull_filter_lll_rl_addr_allowed(uint8_t id_addr_type,
				    const uint8_t *id_addr,
				    uint8_t *const rl_idx)
{
	uint8_t i, j;

	/* We matched an IRK then we're all set. No hw
	 * filters are used in this case.
	 */
	if (*rl_idx != FILTER_IDX_NONE) {
		return true;
	}

	for (i = 0U; i < CONFIG_BT_CTLR_RL_SIZE; i++) {
		if (rl[i].taken && (rl[i].id_addr_type == id_addr_type)) {
			uint8_t *addr = rl[i].id_addr.val;

			for (j = 0U; j < BDADDR_SIZE; j++) {
				if (addr[j] != id_addr[j]) {
					break;
				}
			}

			if (j == BDADDR_SIZE) {
				*rl_idx = i;
				return !rl[i].pirk || rl[i].dev;
			}
		}
	}

	return true;
}

bool ull_filter_lll_rl_addr_resolve(uint8_t id_addr_type,
				    const uint8_t *id_addr, uint8_t rl_idx)
{
	/* Unable to resolve if AR is disabled, no RL entry or no local IRK */
	if (!rl_enable || rl_idx >= ARRAY_SIZE(rl) || !rl[rl_idx].lirk) {
		return false;
	}

	if ((id_addr_type != 0U) && ((id_addr[5] & 0xc0) == 0x40)) {
		return bt_rpa_irk_matches(rl[rl_idx].local_irk,
					  (bt_addr_t *)id_addr);
	}

	return false;
}

bool ull_filter_lll_rl_enabled(void)
{
	return rl_enable;
}

#if defined(CONFIG_BT_CTLR_SW_DEFERRED_PRIVACY)
uint8_t ull_filter_deferred_resolve(bt_addr_t *rpa, resolve_callback_t cb)
{
	if (rl_enable) {
		if (!k_work_is_pending(&(resolve_work.prpa_work))) {
			/* copy input param to work variable */
			(void)memcpy(resolve_work.rpa.val, rpa->val,
				     sizeof(bt_addr_t));
			resolve_work.cb = cb;

			k_work_submit(&(resolve_work.prpa_work));

			return 1;
		}
	}

	return 0;
}

uint8_t ull_filter_deferred_targeta_resolve(bt_addr_t *rpa, uint8_t rl_idx,
					 resolve_callback_t cb)
{
	if (rl_enable) {
		if (!k_work_is_pending(&(t_work.target_work))) {
			/* copy input param to work variable */
			(void)memcpy(t_work.rpa.val, rpa->val,
				     sizeof(bt_addr_t));
			t_work.cb = cb;
			t_work.idx = rl_idx;

			k_work_submit(&(t_work.target_work));

			return 1;
		}
	}
	return 0;
}
#endif /* CONFIG_BT_CTLR_SW_DEFERRED_PRIVACY */

static void fal_clear(void)
{
	for (int i = 0; i < CONFIG_BT_CTLR_FAL_SIZE; i++) {
		uint8_t j = fal[i].rl_idx;

		if (j < ARRAY_SIZE(rl)) {
			rl[j].fal = 0U;
		}
		fal[i].taken = 0U;
	}
}

static uint8_t fal_find(uint8_t addr_type, const uint8_t *const addr,
			uint8_t *const free_idx)
{
	int i;

	if (free_idx) {
		*free_idx = FILTER_IDX_NONE;
	}

	for (i = 0; i < CONFIG_BT_CTLR_FAL_SIZE; i++) {
		if (LIST_MATCH(fal, i, addr_type, addr)) {
			return i;
		} else if (free_idx && !fal[i].taken &&
			   (*free_idx == FILTER_IDX_NONE)) {
			*free_idx = i;
		}
	}

	return FILTER_IDX_NONE;
}

static uint32_t fal_add(bt_addr_le_t *id_addr)
{
	uint8_t i, j;

	i = fal_find(id_addr->type, id_addr->a.val, &j);

	/* Duplicate  check */
	if (i < ARRAY_SIZE(fal)) {
		return 0;
	} else if (j >= ARRAY_SIZE(fal)) {
		return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
	}

	i = j;

	fal[i].id_addr_type = id_addr->type & 0x1;
	bt_addr_copy(&fal[i].id_addr, &id_addr->a);
	/* Get index to Resolving List if applicable */
	j = ull_filter_rl_find(id_addr->type, id_addr->a.val, NULL);
	if (j < ARRAY_SIZE(rl)) {
		fal[i].rl_idx = j;
		rl[j].fal = 1U;
	} else {
		fal[i].rl_idx = FILTER_IDX_NONE;
	}
	fal[i].taken = 1U;

	return 0;
}

static uint32_t fal_remove(bt_addr_le_t *id_addr)
{
	/* find the device and mark it as empty */
	uint8_t i = fal_find(id_addr->type, id_addr->a.val, NULL);

	if (i < ARRAY_SIZE(fal)) {
		uint8_t j = fal[i].rl_idx;

		if (j < ARRAY_SIZE(rl)) {
			rl[j].fal = 0U;
		}
		fal[i].taken = 0U;

		return 0;
	}

	return BT_HCI_ERR_UNKNOWN_CONN_ID;
}

static void fal_update(void)
{
	uint8_t i;

	/* Populate filter from fal peers */
	for (i = 0U; i < CONFIG_BT_CTLR_FAL_SIZE; i++) {
		uint8_t j;

		if (!fal[i].taken) {
			continue;
		}

		j = fal[i].rl_idx;

		if (!rl_enable || j >= ARRAY_SIZE(rl) || !rl[j].pirk ||
		    rl[j].dev) {
			filter_insert(&fal_filter, i, fal[i].id_addr_type,
				      fal[i].id_addr.val);
		}
	}
}

static void rl_update(void)
{
	uint8_t i;

	/* Populate filter from rl peers */
	for (i = 0U; i < CONFIG_BT_CTLR_RL_SIZE; i++) {
		if (rl[i].taken) {
			filter_insert(&rl_filter, i, rl[i].id_addr_type,
				      rl[i].id_addr.val);
		}
	}
}

#if defined(CONFIG_BT_BROADCASTER)
static void rpa_adv_refresh(struct ll_adv_set *adv)
{
	struct lll_adv_aux *lll_aux;
	struct pdu_adv *prev;
	struct lll_adv *lll;
	struct pdu_adv *pdu;
	uint8_t pri_idx;

#if defined(CONFIG_BT_CTLR_ADV_EXT)
	uint8_t sec_idx;
#endif /* CONFIG_BT_CTLR_ADV_EXT */

	if (adv->own_addr_type != BT_ADDR_LE_PUBLIC_ID &&
	    adv->own_addr_type != BT_ADDR_LE_RANDOM_ID) {
		return;
	}

	lll = &adv->lll;
	if (lll->rl_idx >= ARRAY_SIZE(rl)) {
		return;
	}


	pri_idx = UINT8_MAX;
	lll_aux = NULL;
	pdu = NULL;
	prev = lll_adv_data_peek(lll);

	if (false) {

#if defined(CONFIG_BT_CTLR_ADV_EXT)
	} else if (prev->type == PDU_ADV_TYPE_EXT_IND) {
		struct pdu_adv_com_ext_adv *pri_com_hdr;
		struct pdu_adv_ext_hdr pri_hdr_flags;
		struct pdu_adv_ext_hdr *pri_hdr;

		/* Pick the primary PDU header flags */
		pri_com_hdr = (void *)&prev->adv_ext_ind;
		pri_hdr = (void *)pri_com_hdr->ext_hdr_adv_data;
		if (pri_com_hdr->ext_hdr_len) {
			pri_hdr_flags = *pri_hdr;
		} else {
			*(uint8_t *)&pri_hdr_flags = 0U;
		}

		/* AdvA, in primary or auxiliary PDU */
		if (pri_hdr_flags.adv_addr) {
			pdu = lll_adv_data_alloc(lll, &pri_idx);
			(void)memcpy(pdu, prev, (PDU_AC_LL_HEADER_SIZE +
						 prev->len));

#if (CONFIG_BT_CTLR_ADV_AUX_SET > 0)
		} else if (pri_hdr_flags.aux_ptr) {
			struct pdu_adv_com_ext_adv *sec_com_hdr;
			struct pdu_adv_ext_hdr sec_hdr_flags;
			struct pdu_adv_ext_hdr *sec_hdr;
			struct pdu_adv *sec_pdu;

			lll_aux = lll->aux;
			sec_pdu = lll_adv_aux_data_peek(lll_aux);

			sec_com_hdr = (void *)&sec_pdu->adv_ext_ind;
			sec_hdr = (void *)sec_com_hdr->ext_hdr_adv_data;
			if (sec_com_hdr->ext_hdr_len) {
				sec_hdr_flags = *sec_hdr;
			} else {
				*(uint8_t *)&sec_hdr_flags = 0U;
			}

			if (sec_hdr_flags.adv_addr) {
				pdu = lll_adv_aux_data_alloc(lll_aux, &sec_idx);
				(void)memcpy(pdu, sec_pdu,
					     (PDU_AC_LL_HEADER_SIZE +
					      sec_pdu->len));
			}
#endif /* (CONFIG_BT_CTLR_ADV_AUX_SET > 0) */
		}
#endif /* CONFIG_BT_CTLR_ADV_EXT */

	} else {
		pdu = lll_adv_data_alloc(lll, &pri_idx);
		(void)memcpy(pdu, prev, (PDU_AC_LL_HEADER_SIZE + prev->len));
	}

	if (pdu) {
		ull_adv_pdu_update_addrs(adv, pdu);

		if (pri_idx != UINT8_MAX) {
			lll_adv_data_enqueue(lll, pri_idx);

#if defined(CONFIG_BT_CTLR_ADV_EXT)
		} else {
			lll_adv_aux_data_enqueue(lll_aux, sec_idx);
#endif /* CONFIG_BT_CTLR_ADV_EXT */

		}
	}
}
#endif /* CONFIG_BT_BROADCASTER */

static void rl_clear(void)
{
	for (uint8_t i = 0; i < CONFIG_BT_CTLR_RL_SIZE; i++) {
		rl[i].taken = 0U;
	}

	peer_irk_count = 0U;
}

static int rl_access_check(bool check_ar)
{
	if (check_ar) {
		/* If address resolution is disabled, allow immediately */
		if (!rl_enable) {
			return -1;
		}
	}

	/* NOTE: Allowed when passive scanning, otherwise deny if advertising,
	 *       active scanning, initiating or periodic sync create is active.
	 */
	return ((IS_ENABLED(CONFIG_BT_BROADCASTER) && ull_adv_is_enabled(0)) ||
		(IS_ENABLED(CONFIG_BT_OBSERVER) &&
		 (ull_scan_is_enabled(0) & ~ULL_SCAN_IS_PASSIVE)))
		? 0 : 1;
}

static void rpa_timeout(struct k_work *work)
{
	ull_filter_rpa_update(true);
	k_work_schedule(&rpa_work, K_MSEC(rpa_timeout_ms));
}

static void rpa_refresh_start(void)
{
	BT_DBG("");
	k_work_schedule(&rpa_work, K_MSEC(rpa_timeout_ms));
}

static void rpa_refresh_stop(void)
{
	k_work_cancel_delayable(&rpa_work);
}

#else /* !CONFIG_BT_CTLR_PRIVACY */

static uint32_t filter_add(struct lll_filter *filter, uint8_t addr_type,
			uint8_t *bdaddr)
{
	int index;

	if (filter->enable_bitmask == LLL_FILTER_BITMASK_ALL) {
		return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
	}

	for (index = 0;
	     (filter->enable_bitmask & BIT(index));
	     index++) {
	}

	filter_insert(filter, index, addr_type, bdaddr);
	return 0;
}

static uint32_t filter_remove(struct lll_filter *filter, uint8_t addr_type,
			   uint8_t *bdaddr)
{
	int index;

	index = filter_find(filter, addr_type, bdaddr);
	if (index == FILTER_IDX_NONE) {
		return BT_HCI_ERR_INVALID_PARAM;
	}

	filter->enable_bitmask &= ~BIT(index);
	filter->addr_type_bitmask &= ~BIT(index);

	return 0;
}
#endif /* !CONFIG_BT_CTLR_PRIVACY */

static uint32_t filter_find(const struct lll_filter *const filter,
			    uint8_t addr_type, const uint8_t *const bdaddr)
{
	int index;

	if (!filter->enable_bitmask) {
		return FILTER_IDX_NONE;
	}

	index = LLL_FILTER_SIZE;
	while (index--) {
		if ((filter->enable_bitmask & BIT(index)) &&
		    (((filter->addr_type_bitmask >> index) & 0x01) ==
		     (addr_type & 0x01)) &&
		    !memcmp(filter->bdaddr[index], bdaddr, BDADDR_SIZE)) {
			return index;
		}
	}

	return FILTER_IDX_NONE;
}

static void filter_insert(struct lll_filter *const filter, int index,
			  uint8_t addr_type, const uint8_t *const bdaddr)
{
	filter->enable_bitmask |= BIT(index);
	filter->addr_type_bitmask |= ((addr_type & 0x01) << index);
	(void)memcpy(&filter->bdaddr[index][0], bdaddr, BDADDR_SIZE);
}

static void filter_clear(struct lll_filter *filter)
{
	filter->enable_bitmask = 0;
	filter->addr_type_bitmask = 0;
}
#endif /* CONFIG_BT_CTLR_FILTER_ACCEPT_LIST */

#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST)
static void pal_clear(void)
{
	for (int i = 0; i < PAL_SIZE; i++) {

#if defined(CONFIG_BT_CTLR_PRIVACY)
		uint8_t j = pal[i].rl_idx;

		if (j < ARRAY_SIZE(pal)) {
			rl[j].pal = 0U;
		}
#endif /* CONFIG_BT_CTLR_PRIVACY */

		pal[i].taken = 0U;
	}
}

#if defined(CONFIG_BT_CTLR_PRIVACY)
static uint8_t pal_addr_find(const uint8_t addr_type, const uint8_t *const addr)
{
	for (int i = 0; i < PAL_SIZE; i++) {
		if (PAL_ADDR_MATCH(addr_type, addr)) {
			return i;
		}
	}

	return FILTER_IDX_NONE;
}
#endif /* CONFIG_BT_CTLR_PRIVACY */

static uint8_t pal_find(const uint8_t addr_type, const uint8_t *const addr,
			const uint8_t sid, uint8_t *const free_idx)
{
	int i;

	if (free_idx) {
		*free_idx = FILTER_IDX_NONE;
	}

	for (i = 0; i < PAL_SIZE; i++) {
		if (PAL_MATCH(addr_type, addr, sid)) {
			return i;
		} else if (free_idx && !pal[i].taken &&
			   (*free_idx == FILTER_IDX_NONE)) {
			*free_idx = i;
		}
	}

	return FILTER_IDX_NONE;
}

static uint32_t pal_add(const bt_addr_le_t *const id_addr, const uint8_t sid)
{
	uint8_t i, j;

	i = pal_find(id_addr->type, id_addr->a.val, sid, &j);

	/* Duplicate  check */
	if (i < PAL_SIZE) {
		return BT_HCI_ERR_INVALID_PARAM;
	} else if (j >= PAL_SIZE) {
		return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
	}

	i = j;

	pal[i].id_addr_type = id_addr->type & 0x1;
	bt_addr_copy(&pal[i].id_addr, &id_addr->a);
	pal[i].sid = sid;

#if defined(CONFIG_BT_CTLR_PRIVACY)
	/* Get index to Resolving List if applicable */
	j = ull_filter_rl_find(id_addr->type, id_addr->a.val, NULL);
	if (j < ARRAY_SIZE(rl)) {
		pal[i].rl_idx = j;
		rl[j].pal = i + 1U;
	} else {
		pal[i].rl_idx = FILTER_IDX_NONE;
	}
#endif /* CONFIG_BT_CTLR_PRIVACY */

	pal[i].taken = 1U;

	return 0;
}

static uint32_t pal_remove(const bt_addr_le_t *const id_addr, const uint8_t sid)
{
	/* find the device and mark it as empty */
	uint8_t i = pal_find(id_addr->type, id_addr->a.val, sid, NULL);

	if (i < PAL_SIZE) {

#if defined(CONFIG_BT_CTLR_PRIVACY)
		uint8_t j = pal[i].rl_idx;

		if (j < ARRAY_SIZE(rl)) {
			rl[j].pal = 0U;
		}
#endif /* CONFIG_BT_CTLR_PRIVACY */

		pal[i].taken = 0U;

		return 0;
	}

	return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
}
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST */

#if defined(CONFIG_BT_CTLR_PRIVACY) && \
	defined(CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN)
static void conn_rpa_update(uint8_t rl_idx)
{
	uint16_t handle;

	for (handle = 0U; handle < CONFIG_BT_MAX_CONN; handle++) {
		struct ll_conn *conn = ll_connected_get(handle);

		/* The RPA of the connection matches the RPA that was just
		 * resolved
		 */
		if (conn && !memcmp(conn->peer_id_addr, rl[rl_idx].curr_rpa.val,
				    BDADDR_SIZE)) {
			(void)memcpy(conn->peer_id_addr, rl[rl_idx].id_addr.val,
				     BDADDR_SIZE);
			break;
		}
	}
}
#endif /* CONFIG_BT_CTLR_PRIVACY && CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN */

#if defined(CONFIG_BT_CTLR_SW_DEFERRED_PRIVACY)
static void target_resolve(struct k_work *work)
{
	uint8_t j, idx;
	bt_addr_t *search_rpa;
	struct target_resolve_work *twork;
	static memq_link_t link;
	static struct mayfly mfy = {0, 0, &link, 0, NULL};

	twork = CONTAINER_OF(work, struct target_resolve_work, target_work);
	idx = twork->idx;
	search_rpa = &(twork->rpa);

	if (rl[idx].taken && !bt_addr_cmp(&(rl[idx].target_rpa), search_rpa)) {
		j = idx;
	} else {
		/* No match - so not in list Need to see if we can resolve */
		if (bt_rpa_irk_matches(rl[idx].local_irk, search_rpa)) {
			/* Could resolve, store RPA */
			(void)memcpy(rl[idx].target_rpa.val, search_rpa->val,
				     sizeof(bt_addr_t));
			j = idx;
		} else {
			/* Could not resolve, and not in table */
			j = FILTER_IDX_NONE;
		}
	}

	/* Kick the callback in LLL (using the mayfly, tailchain it)
	 * Pass param FILTER_IDX_NONE if RPA can not be resolved,
	 * or index in cache if it can be resolved
	 */
	if (twork->cb) {
		mfy.fp = twork->cb;
		mfy.param = (void *) ((unsigned int) j);
		(void)mayfly_enqueue(TICKER_USER_ID_THREAD,
				     TICKER_USER_ID_LLL, 1, &mfy);
	}
}

static uint8_t prpa_cache_try_resolve(bt_addr_t *rpa)
{
	uint8_t pi;
	uint8_t lpirk[IRK_SIZE];

	for (uint8_t i = 0U; i < CONFIG_BT_CTLR_RL_SIZE; i++) {
		if (rl[i].taken && rl[i].pirk) {
			pi = rl[i].pirk_idx;
			sys_memcpy_swap(lpirk, peer_irks[pi], IRK_SIZE);
			if (bt_rpa_irk_matches(lpirk, rpa)) {
				return i;
			}
		}
	}

	return FILTER_IDX_NONE;
}

static void prpa_cache_resolve(struct k_work *work)
{
	uint8_t i, j;
	bt_addr_t *search_rpa;
	struct prpa_resolve_work *rwork;
	static memq_link_t link;
	static struct mayfly mfy = {0, 0, &link, 0, NULL};

	rwork = CONTAINER_OF(work, struct prpa_resolve_work, prpa_work);
	search_rpa = &(rwork->rpa);

	i = prpa_cache_find(search_rpa);

	if (i == FILTER_IDX_NONE) {
		/* No match - so not in known unknown list
		 * Need to see if we can resolve
		 */
		j = prpa_cache_try_resolve(search_rpa);

		if (j == FILTER_IDX_NONE) {
			/* No match - thus cannot resolve, we have an unknown
			 * so insert in known unkonown list
			 */
			prpa_cache_add(search_rpa);
		} else {
			/* Address could be resolved, so update current RPA
			 * in list
			 */
			(void)memcpy(rl[j].curr_rpa.val, search_rpa->val,
				     sizeof(bt_addr_t));
#if defined(CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN)
			conn_rpa_update(j);
#endif /* CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN */
		}

	} else {
		/* Found a known unknown - do nothing */
		j = FILTER_IDX_NONE;
	}

	/* Kick the callback in LLL (using the mayfly, tailchain it)
	 * Pass param FILTER_IDX_NONE if RPA can not be resolved,
	 * or index in cache if it can be resolved
	 */
	if (rwork->cb) {
		mfy.fp = rwork->cb;
		mfy.param = (void *) ((unsigned int) j);
		(void)mayfly_enqueue(TICKER_USER_ID_THREAD,
				     TICKER_USER_ID_LLL, 1, &mfy);
	}
}

static void prpa_cache_clear(void)
{
	/* Note the first element will not be in use before wrap around
	 * is reached.
	 * The first element in actual use will be at index 1.
	 * There is no element waisted with this implementation, as
	 * element 0 will eventually be allocated.
	 */
	newest_prpa = 0U;

	for (uint8_t i = 0; i < CONFIG_BT_CTLR_RPA_CACHE_SIZE; i++) {
		prpa_cache[i].taken = 0U;
	}
}

static void prpa_cache_add(bt_addr_t *rpa)
{
	newest_prpa = (newest_prpa + 1) % CONFIG_BT_CTLR_RPA_CACHE_SIZE;

	(void)memcpy(prpa_cache[newest_prpa].rpa.val, rpa->val,
		     sizeof(bt_addr_t));
	prpa_cache[newest_prpa].taken = 1U;
}

static uint8_t prpa_cache_find(bt_addr_t *rpa)
{
	for (uint8_t i = 0; i < CONFIG_BT_CTLR_RPA_CACHE_SIZE; i++) {
		if (prpa_cache[i].taken &&
		    !bt_addr_cmp(&(prpa_cache[i].rpa), rpa)) {
			return i;
		}
	}
	return FILTER_IDX_NONE;
}

const struct lll_prpa_cache *ull_filter_lll_prpa_cache_get(void)
{
	return prpa_cache;
}
#endif /* !CONFIG_BT_CTLR_SW_DEFERRED_PRIVACY */
