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

#include <string.h>

#include <zephyr.h>
#include <soc.h>
#include <bluetooth/hci.h>
#include <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 "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"

#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

/* Hardware Filter Accept List */
static struct lll_filter fal_filter;
uint8_t fal_anon;

#define IRK_SIZE 16

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

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

static uint8_t rl_enable;

static struct lll_resolvelist rl[CONFIG_BT_CTLR_RL_SIZE];

#if defined(CONFIG_BT_CTLR_SW_DEFERRED_PRIVACY)
/* Cache of known unknown peer RPAs */
static uint8_t newest_prpa;
static struct prpa_cache_dev {
	uint8_t      taken:1;
	bt_addr_t rpa;
} 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, uint8_t *addr, uint8_t *free);
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 void filter_insert(struct lll_filter *filter, int index, uint8_t addr_type,
			   uint8_t *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 */

uint8_t ll_fal_size_get(void)
{
	return 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 */

	fal_anon = 0U;

	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) {
		fal_anon = 1U;
		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) {
		fal_anon = 0U;
		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;
	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) {
		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;
	}
	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) {
				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;
		}
		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) {
			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;
}

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)
		struct ll_adv_set *adv;

		/* TODO: foreach adv set */
		adv = ull_adv_is_enabled_get(0);
		if (adv) {
			rpa_adv_refresh(adv);
		}
#endif
	}
}

#if defined(CONFIG_BT_BROADCASTER)
const uint8_t *ull_filter_adva_get(struct ll_adv_set *adv)
{
	uint8_t idx = adv->lll.rl_idx;

	/* AdvA */
	if (idx < ARRAY_SIZE(rl) && rl[idx].lirk) {
		LL_ASSERT(rl[idx].rpas_ready);
		return rl[idx].local_rpa->val;
	}

	return NULL;
}

const uint8_t *ull_filter_tgta_get(struct ll_adv_set *adv)
{
	uint8_t idx = adv->lll.rl_idx;

	/* TargetA */
	if (idx < ARRAY_SIZE(rl) && rl[idx].pirk) {
		return 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)
{
	uint8_t i;

	if (free) {
		*free = 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 && !rl[i].taken && (*free == FILTER_IDX_NONE)) {
			*free = i;
		}
	}

	return FILTER_IDX_NONE;
}
#endif /* CONFIG_BT_CTLR_PRIVACY */

void ull_filter_reset(bool init)
{
	fal_anon = 0U;

#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);
	}
#else
	filter_clear(&fal_filter);
#endif /* CONFIG_BT_CTLR_PRIVACY */
}

#if defined(CONFIG_BT_CTLR_PRIVACY)
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;
}
#endif /* CONFIG_BT_CTLR_PRIVACY */

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
}

#if defined(CONFIG_BT_CTLR_PRIVACY)
struct lll_fal *ull_filter_lll_fal_get(void)
{
	return fal;
}

struct lll_resolvelist *ull_filter_lll_resolvelist_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, uint8_t *id_addr, uint8_t *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, 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 */
			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 */
			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 < 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, uint8_t *addr, uint8_t *free_idx)
{
	int i;

	if (free_idx) {
		*free_idx = FILTER_IDX_NONE;
	}

	for (i = 0; i < 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 < 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 pdu_adv *prev;
	struct pdu_adv *pdu;
	uint8_t idx;

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

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

	prev = lll_adv_data_peek(&adv->lll);
	pdu = lll_adv_data_alloc(&adv->lll, &idx);

	memcpy(pdu, prev, PDU_AC_LL_HEADER_SIZE + prev->len);
	ull_adv_pdu_update_addrs(adv, pdu);

	lll_adv_data_enqueue(&adv->lll, idx);
}
#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;

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

	index = FAL_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)) {
			filter->enable_bitmask &= ~BIT(index);
			filter->addr_type_bitmask &= ~BIT(index);
			return 0;
		}
	}

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

static void filter_insert(struct lll_filter *filter, int index, uint8_t addr_type,
			   uint8_t *bdaddr)
{
	filter->enable_bitmask |= BIT(index);
	filter->addr_type_bitmask |= ((addr_type & 0x01) << index);
	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;
}

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

	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;
}
#endif /* !CONFIG_BT_CTLR_SW_DEFERRED_PRIVACY */
