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

#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <limits.h>

#include <zephyr/bluetooth/hci_types.h>
#include <zephyr/sys/byteorder.h>

#include "hal/ccm.h"
#include "hal/radio.h"
#include "hal/ticker.h"

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

#include "ticker/ticker.h"

#include "pdu_vendor.h"
#include "pdu.h"

#include "lll.h"
#include "lll_vendor.h"
#include "lll_clock.h"
#include "lll_scan.h"
#include "lll_df_types.h"
#include "lll_conn.h"
#include "lll_chan.h"
#include "lll_filter.h"

#include "lll_internal.h"
#include "lll_tim_internal.h"
#include "lll_prof_internal.h"

#include <soc.h>
#include "hal/debug.h"

static int init_reset(void);
static int prepare_cb(struct lll_prepare_param *prepare_param);
static int is_abort_cb(void *next, void *curr, lll_prepare_cb_t *resume_cb);
static void abort_cb(struct lll_prepare_param *prepare_param, void *param);
static void ticker_stop_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
			   uint32_t remainder, uint16_t lazy, uint8_t force,
			   void *param);
static void ticker_op_start_cb(uint32_t status, void *param);
static void isr_rx(void *param);
static void isr_tx(void *param);
static void isr_done(void *param);
static void isr_window(void *param);
static void isr_abort(void *param);
static void isr_cleanup(void *param);
static void isr_race(void *param);

static inline bool isr_rx_scan_check(struct lll_scan *lll, uint8_t irkmatch_ok,
				     uint8_t devmatch_ok, uint8_t rl_idx);
static inline uint32_t isr_rx_pdu(struct lll_scan *lll, uint8_t devmatch_ok,
			       uint8_t devmatch_id, uint8_t irkmatch_ok,
			       uint8_t irkmatch_id, uint8_t rl_idx, uint8_t rssi_ready);
#if defined(CONFIG_BT_CENTRAL)
static inline bool isr_scan_init_check(struct lll_scan *lll,
				       struct pdu_adv *pdu, uint8_t rl_idx);
static inline bool isr_scan_init_adva_check(struct lll_scan *lll,
					    struct pdu_adv *pdu, uint8_t rl_idx);
#endif /* CONFIG_BT_CENTRAL */
static inline bool isr_scan_tgta_check(struct lll_scan *lll, bool init,
				       struct pdu_adv *pdu, uint8_t rl_idx,
				       bool *dir_report);
static inline bool isr_scan_tgta_rpa_check(struct lll_scan *lll,
					   struct pdu_adv *pdu,
					   bool *dir_report);
static inline bool isr_scan_rsp_adva_matches(struct pdu_adv *srsp);
static uint32_t isr_rx_scan_report(struct lll_scan *lll, uint8_t rssi_ready,
				uint8_t rl_idx, bool dir_report);


int lll_scan_init(void)
{
	int err;

	err = init_reset();
	if (err) {
		return err;
	}

	return 0;
}

int lll_scan_reset(void)
{
	int err;

	err = init_reset();
	if (err) {
		return err;
	}

	return 0;
}

void lll_scan_prepare(void *param)
{
	struct lll_prepare_param *p = param;
	int err;

	err = lll_clk_on();
	LL_ASSERT(!err || err == -EINPROGRESS);

	err = lll_prepare(is_abort_cb, abort_cb, prepare_cb, 0, p);
	LL_ASSERT(!err || err == -EINPROGRESS);
}

static int init_reset(void)
{
	return 0;
}

static int prepare_cb(struct lll_prepare_param *prepare_param)
{
	struct lll_scan *lll = prepare_param->param;
	uint32_t aa = sys_cpu_to_le32(PDU_AC_ACCESS_ADDR);
	uint32_t ticks_at_event, ticks_at_start;
	struct node_rx_pdu *node_rx;
	uint32_t remainder_us;
	struct ull_hdr *ull;
	uint32_t remainder;

	DEBUG_RADIO_START_O(1);

#if defined(CONFIG_BT_CENTRAL)
	/* Check if stopped (on connection establishment race between LLL and
	 * ULL.
	 */
	if (unlikely(lll->conn && lll->conn->central.initiated)) {
		int err;

		err = lll_clk_off();
		LL_ASSERT(!err || err == -EBUSY);

		lll_done(NULL);

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

	radio_reset();
	/* TODO: other Tx Power settings */
	radio_tx_power_set(RADIO_TXP_DEFAULT);

#if defined(CONFIG_BT_CTLR_ADV_EXT)
	/* TODO: if coded we use S8? */
	radio_phy_set(lll->phy, 1);
	radio_pkt_configure(8, PDU_AC_LEG_PAYLOAD_SIZE_MAX, (lll->phy << 1));
#else /* !CONFIG_BT_CTLR_ADV_EXT */
	radio_phy_set(0, 0);
	radio_pkt_configure(8, PDU_AC_LEG_PAYLOAD_SIZE_MAX, 0);
#endif /* !CONFIG_BT_CTLR_ADV_EXT */

	node_rx = ull_pdu_rx_alloc_peek(1);
	LL_ASSERT(node_rx);
	radio_pkt_rx_set(node_rx->pdu);

	radio_aa_set((uint8_t *)&aa);
	radio_crc_configure(((0x5bUL) | ((0x06UL) << 8) | ((0x00UL) << 16)),
			    0x555555);

	lll_chan_set(37 + lll->chan);

	radio_isr_set(isr_rx, lll);

	/* setup tIFS switching */
	radio_tmr_tifs_set(EVENT_IFS_US);
	radio_switch_complete_and_tx(0, 0, 0, 0);

#if defined(CONFIG_BT_CTLR_PRIVACY)
	if (ull_filter_lll_rl_enabled()) {
		struct lll_filter *filter =
			ull_filter_lll_get((lll->filter_policy &
					    SCAN_FP_FILTER) != 0U);
		uint8_t count, *irks = ull_filter_lll_irks_get(&count);

		radio_filter_configure(filter->enable_bitmask,
				       filter->addr_type_bitmask,
				       (uint8_t *)filter->bdaddr);

		radio_ar_configure(count, irks);
	} else
#endif /* CONFIG_BT_CTLR_PRIVACY */

		if (IS_ENABLED(CONFIG_BT_CTLR_FILTER_ACCEPT_LIST) && lll->filter_policy) {
			/* Setup Radio Filter */
			struct lll_filter *fal = ull_filter_lll_get(true);

			radio_filter_configure(fal->enable_bitmask,
					       fal->addr_type_bitmask,
					       (uint8_t *)fal->bdaddr);
		}

	ticks_at_event = prepare_param->ticks_at_expire;
	ull = HDR_LLL2ULL(lll);
	ticks_at_event += lll_event_offset_get(ull);

	ticks_at_start = ticks_at_event;
	ticks_at_start += HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);

	remainder = prepare_param->remainder;
	remainder_us = radio_tmr_start(0, ticks_at_start, remainder);

	/* capture end of Rx-ed PDU, for initiator to calculate first
	 * central event.
	 */
	radio_tmr_end_capture();

	/* scanner always measures RSSI */
	radio_rssi_measure();

#if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
	radio_gpio_lna_setup();
	radio_gpio_pa_lna_enable(remainder_us +
				 radio_rx_ready_delay_get(0, 0) -
				 HAL_RADIO_GPIO_LNA_OFFSET);
#else /* !HAL_RADIO_GPIO_HAVE_LNA_PIN */
	ARG_UNUSED(remainder_us);
#endif /* !HAL_RADIO_GPIO_HAVE_LNA_PIN */

#if defined(CONFIG_BT_CTLR_XTAL_ADVANCED) && \
	(EVENT_OVERHEAD_PREEMPT_US <= EVENT_OVERHEAD_PREEMPT_MIN_US)
	/* check if preempt to start has changed */
	if (lll_preempt_calc(ull, (TICKER_ID_SCAN_BASE +
				   ull_scan_lll_handle_get(lll)),
			     ticks_at_event)) {
		radio_isr_set(isr_abort, lll);
		radio_disable();
	} else
#endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */
	{
		uint32_t ret;

		if (lll->ticks_window) {
			/* start window close timeout */
			ret = ticker_start(TICKER_INSTANCE_ID_CTLR,
					   TICKER_USER_ID_LLL,
					   TICKER_ID_SCAN_STOP,
					   ticks_at_event, lll->ticks_window,
					   TICKER_NULL_PERIOD,
					   TICKER_NULL_REMAINDER,
					   TICKER_NULL_LAZY, TICKER_NULL_SLOT,
					   ticker_stop_cb, lll,
					   ticker_op_start_cb,
					   (void *)__LINE__);
			LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
				  (ret == TICKER_STATUS_BUSY));
		}

		ret = lll_prepare_done(lll);
		LL_ASSERT(!ret);
	}

	DEBUG_RADIO_START_O(1);

	return 0;
}

static int resume_prepare_cb(struct lll_prepare_param *p)
{
	struct ull_hdr *ull = HDR_LLL2ULL(p->param);

	p->ticks_at_expire = ticker_ticks_now_get() - lll_event_offset_get(ull);
	p->remainder = 0;
	p->lazy = 0;

	return prepare_cb(p);
}

static int is_abort_cb(void *next, void *curr, lll_prepare_cb_t *resume_cb)
{
	struct lll_scan *lll = curr;

	/* TODO: check prio */
	if (next != curr) {
		int err;

		/* wrap back after the pre-empter */
		*resume_cb = resume_prepare_cb;

		/* Retain HF clk */
		err = lll_clk_on();
		LL_ASSERT(!err || err == -EINPROGRESS);

		return -EAGAIN;
	}

	radio_isr_set(isr_window, lll);
	radio_disable();

	if (++lll->chan == 3U) {
		lll->chan = 0U;
	}

	lll_chan_set(37 + lll->chan);

	return 0;
}

static void abort_cb(struct lll_prepare_param *prepare_param, void *param)
{
	int err;

	/* NOTE: This is not a prepare being cancelled */
	if (!prepare_param) {
		/* Perform event abort here.
		 * After event has been cleanly aborted, clean up resources
		 * and dispatch event done.
		 */
		radio_isr_set(isr_abort, param);
		radio_disable();
		return;
	}

	/* NOTE: Else clean the top half preparations of the aborted event
	 * currently in preparation pipeline.
	 */
	err = lll_clk_off();
	LL_ASSERT(!err || err == -EBUSY);

	lll_done(param);
}

static void ticker_stop_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
			   uint32_t remainder, uint16_t lazy, uint8_t force,
			   void *param)
{
	radio_isr_set(isr_cleanup, param);
	radio_disable();
}

static void ticker_op_start_cb(uint32_t status, void *param)
{
	ARG_UNUSED(param);

	LL_ASSERT(status == TICKER_STATUS_SUCCESS);
}

static void isr_rx(void *param)
{
	struct lll_scan *lll = (void *)param;
	uint8_t trx_done;
	uint8_t crc_ok;
	uint8_t devmatch_ok;
	uint8_t devmatch_id;
	uint8_t irkmatch_ok;
	uint8_t irkmatch_id;
	uint8_t rssi_ready;
	uint8_t rl_idx;

	if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
		lll_prof_latency_capture();
	}

	/* Read radio status and events */
	trx_done = radio_is_done();
	if (trx_done) {
		crc_ok = radio_crc_is_valid();
		devmatch_ok = radio_filter_has_match();
		devmatch_id = radio_filter_match_get();
		if (IS_ENABLED(CONFIG_BT_CTLR_PRIVACY)) {
			irkmatch_ok = radio_ar_has_match();
			irkmatch_id = radio_ar_match_get();
		} else {
			irkmatch_ok = 0U;
			irkmatch_id = FILTER_IDX_NONE;
		}
		rssi_ready = radio_rssi_is_ready();
	} else {
		crc_ok = devmatch_ok = irkmatch_ok = rssi_ready = 0U;
		devmatch_id = irkmatch_id = FILTER_IDX_NONE;
	}

	/* Clear radio status and events */
	lll_isr_status_reset();

	if (IS_ENABLED(HAL_RADIO_GPIO_HAVE_PA_PIN) ||
	    IS_ENABLED(HAL_RADIO_GPIO_HAVE_LNA_PIN)) {
		radio_gpio_pa_lna_disable();
	}

	if (!trx_done) {
		goto isr_rx_do_close;
	}

#if defined(CONFIG_BT_CTLR_PRIVACY)
	rl_idx = devmatch_ok ?
		 ull_filter_lll_rl_idx(((lll->filter_policy &
					 SCAN_FP_FILTER) != 0U),
				       devmatch_id) :
		 irkmatch_ok ? ull_filter_lll_rl_irk_idx(irkmatch_id) :
			       FILTER_IDX_NONE;
#else
	rl_idx = FILTER_IDX_NONE;
#endif
	if (crc_ok && isr_rx_scan_check(lll, irkmatch_ok, devmatch_ok,
					rl_idx)) {
		uint32_t err;

		err = isr_rx_pdu(lll, devmatch_ok, devmatch_id, irkmatch_ok,
				 irkmatch_id, rl_idx, rssi_ready);
		if (!err) {
			if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
				lll_prof_send();
			}

			return;
		}
	}

isr_rx_do_close:
	radio_isr_set(isr_done, lll);
	radio_disable();
}

static void isr_tx(void *param)
{
	struct node_rx_pdu *node_rx;
	uint32_t hcto;

	/* TODO: MOVE to a common interface, isr_lll_radio_status? */
	/* Clear radio status and events */
	radio_status_reset();
	radio_tmr_status_reset();

	if (IS_ENABLED(HAL_RADIO_GPIO_HAVE_PA_PIN) ||
	    IS_ENABLED(HAL_RADIO_GPIO_HAVE_LNA_PIN)) {
		radio_gpio_pa_lna_disable();
	}
	/* TODO: MOVE ^^ */

	/* setup tIFS switching */
	radio_tmr_tifs_set(EVENT_IFS_US);
	radio_switch_complete_and_tx(0, 0, 0, 0);

	node_rx = ull_pdu_rx_alloc_peek(1);
	LL_ASSERT(node_rx);
	radio_pkt_rx_set(node_rx->pdu);

	/* assert if radio packet ptr is not set and radio started rx */
	LL_ASSERT(!radio_is_ready());

#if defined(CONFIG_BT_CTLR_PRIVACY)
	if (ull_filter_lll_rl_enabled()) {
		uint8_t count, *irks = ull_filter_lll_irks_get(&count);

		radio_ar_configure(count, irks);
	}
#endif /* CONFIG_BT_CTLR_PRIVACY */

	/* +/- 2us active clock jitter, +1 us hcto compensation */
	hcto = radio_tmr_tifs_base_get() + EVENT_IFS_US + 4 + 1;
	hcto += radio_rx_chain_delay_get(0, 0);
	hcto += addr_us_get(0);
	hcto -= radio_tx_chain_delay_get(0, 0);

	radio_tmr_hcto_configure(hcto);

	radio_rssi_measure();

#if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
	radio_gpio_lna_setup();
	radio_gpio_pa_lna_enable(radio_tmr_tifs_base_get() + EVENT_IFS_US - 4 -
				 radio_tx_chain_delay_get(0, 0) -
				 HAL_RADIO_GPIO_LNA_OFFSET);
#endif /* HAL_RADIO_GPIO_HAVE_LNA_PIN */

	radio_isr_set(isr_rx, param);
}

static void isr_common_done(void *param)
{
	struct node_rx_pdu *node_rx;

	/* TODO: MOVE to a common interface, isr_lll_radio_status? */
	/* Clear radio status and events */
	lll_isr_status_reset();

	if (IS_ENABLED(HAL_RADIO_GPIO_HAVE_PA_PIN) ||
	    IS_ENABLED(HAL_RADIO_GPIO_HAVE_LNA_PIN)) {
		radio_gpio_pa_lna_disable();
	}
	/* TODO: MOVE ^^ */

	/* setup tIFS switching */
	radio_tmr_tifs_set(EVENT_IFS_US);
	radio_switch_complete_and_tx(0, 0, 0, 0);

	node_rx = ull_pdu_rx_alloc_peek(1);
	LL_ASSERT(node_rx);
	radio_pkt_rx_set(node_rx->pdu);

#if defined(CONFIG_BT_CTLR_PRIVACY)
	if (ull_filter_lll_rl_enabled()) {
		uint8_t count, *irks = ull_filter_lll_irks_get(&count);

		radio_ar_configure(count, irks);
	}
#endif /* CONFIG_BT_CTLR_PRIVACY */

	radio_rssi_measure();

	radio_isr_set(isr_rx, param);
}

static void isr_done(void *param)
{
	uint32_t start_us;

	isr_common_done(param);

#if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
	start_us = radio_tmr_start_now(0);

	radio_gpio_lna_setup();
	radio_gpio_pa_lna_enable(start_us +
				 radio_rx_ready_delay_get(0, 0) -
				 HAL_RADIO_GPIO_LNA_OFFSET);
#else /* !HAL_RADIO_GPIO_HAVE_LNA_PIN */
	ARG_UNUSED(start_us);

	radio_rx_enable();
#endif /* !HAL_RADIO_GPIO_HAVE_LNA_PIN */

	/* capture end of Rx-ed PDU, for initiator to calculate first
	 * central event.
	 */
	radio_tmr_end_capture();
}

static void isr_window(void *param)
{
	uint32_t ticks_at_start, remainder_us;

	isr_common_done(param);

	ticks_at_start = ticker_ticks_now_get() +
			 HAL_TICKER_CNTR_CMP_OFFSET_MIN;
	remainder_us = radio_tmr_start_tick(0, ticks_at_start);

	/* capture end of Rx-ed PDU, for initiator to calculate first
	 * central event.
	 */
	radio_tmr_end_capture();

#if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
	radio_gpio_lna_setup();
	radio_gpio_pa_lna_enable(remainder_us +
				 radio_rx_ready_delay_get(0, 0) -
				 HAL_RADIO_GPIO_LNA_OFFSET);
#else /* !HAL_RADIO_GPIO_HAVE_LNA_PIN */
	ARG_UNUSED(remainder_us);
#endif /* !HAL_RADIO_GPIO_HAVE_LNA_PIN */
}

static void isr_abort(void *param)
{
	/* Clear radio status and events */
	lll_isr_status_reset();

	if (IS_ENABLED(HAL_RADIO_GPIO_HAVE_PA_PIN) ||
	    IS_ENABLED(HAL_RADIO_GPIO_HAVE_LNA_PIN)) {
		radio_gpio_pa_lna_disable();
	}

	/* Scanner stop can expire while here in this ISR.
	 * Deferred attempt to stop can fail as it would have
	 * expired, hence ignore failure.
	 */
	(void)ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_LLL,
			  TICKER_ID_SCAN_STOP, NULL, NULL);

	/* Under race conditions, radio could get started while entering ISR */
	radio_disable();

	isr_cleanup(param);
}

static void isr_cleanup(void *param)
{
	struct lll_scan *lll = param;
	struct node_rx_hdr *node_rx;
	int err;

	if (lll_is_done(param)) {
		return;
	}

	radio_filter_disable();

	if (++lll->chan == 3U) {
		lll->chan = 0U;
	}

#if defined(CONFIG_BT_HCI_MESH_EXT)
	if (_radio.advertiser.is_enabled && _radio.advertiser.is_mesh &&
	    !_radio.advertiser.retry) {
		mayfly_mesh_stop(NULL);
	}
#endif /* CONFIG_BT_HCI_MESH_EXT */

#if defined(CONFIG_BT_CTLR_SCAN_INDICATION)
	node_rx = ull_pdu_rx_alloc_peek(3);
	if (node_rx) {
		ull_pdu_rx_alloc();

		/* TODO: add other info by defining a payload struct */
		node_rx->type = NODE_RX_TYPE_SCAN_INDICATION;

		ull_rx_put_sched(node_rx->link, node_rx);
	}
#else /* !CONFIG_BT_CTLR_SCAN_INDICATION */
	ARG_UNUSED(node_rx);
#endif /* !CONFIG_BT_CTLR_SCAN_INDICATION */

	radio_isr_set(isr_race, param);
	radio_tmr_stop();

	err = lll_clk_off();
	LL_ASSERT(!err || err == -EBUSY);

	lll_done(NULL);
}

static void isr_race(void *param)
{
	/* NOTE: lll_disable could have a race with ... */
	radio_status_reset();
}

static inline bool isr_rx_scan_check(struct lll_scan *lll, uint8_t irkmatch_ok,
				     uint8_t devmatch_ok, uint8_t rl_idx)
{
#if defined(CONFIG_BT_CTLR_PRIVACY)
	return (((lll->filter_policy & SCAN_FP_FILTER) == 0U) &&
		 (!devmatch_ok || ull_filter_lll_rl_idx_allowed(irkmatch_ok,
								rl_idx))) ||
		(((lll->filter_policy & SCAN_FP_FILTER) != 0U) &&
		 (devmatch_ok || ull_filter_lll_irk_in_fal(rl_idx)));
#else
	return ((lll->filter_policy & SCAN_FP_FILTER) == 0U) ||
		devmatch_ok;
#endif /* CONFIG_BT_CTLR_PRIVACY */
}

static inline uint32_t isr_rx_pdu(struct lll_scan *lll, uint8_t devmatch_ok,
			       uint8_t devmatch_id, uint8_t irkmatch_ok,
			       uint8_t irkmatch_id, uint8_t rl_idx, uint8_t rssi_ready)
{
	struct node_rx_pdu *node_rx;
	struct pdu_adv *pdu_adv_rx;
	bool dir_report = false;

	node_rx = ull_pdu_rx_alloc_peek(1);
	LL_ASSERT(node_rx);

	pdu_adv_rx = (void *)node_rx->pdu;

	if (0) {
#if defined(CONFIG_BT_CENTRAL)
	/* Initiator */
	} else if (lll->conn &&
		   isr_scan_init_check(lll, pdu_adv_rx, rl_idx)) {
		struct lll_conn *lll_conn;
		struct node_rx_ftr *ftr;
		struct node_rx_pdu *rx;
		struct pdu_adv *pdu_tx;
		uint32_t conn_interval_us;
		uint32_t conn_offset_us;
		uint32_t conn_space_us;
		struct ull_hdr *ull;
		uint32_t pdu_end_us;
#if defined(CONFIG_BT_CTLR_PRIVACY)
		bt_addr_t *lrpa;
#endif /* CONFIG_BT_CTLR_PRIVACY */

		if (IS_ENABLED(CONFIG_BT_CTLR_CHAN_SEL_2)) {
			rx = ull_pdu_rx_alloc_peek(4);
		} else {
			rx = ull_pdu_rx_alloc_peek(3);
		}

		if (!rx) {
			return -ENOBUFS;
		}

		pdu_end_us = radio_tmr_end_get();
		if (!lll->ticks_window) {
			uint32_t scan_interval_us;

			/* FIXME: is this correct for continuous scanning? */
			scan_interval_us = lll->interval * SCAN_INT_UNIT_US;
			pdu_end_us %= scan_interval_us;
		}
		ull = HDR_LLL2ULL(lll);
		if (pdu_end_us > (HAL_TICKER_TICKS_TO_US(ull->ticks_slot) -
				  EVENT_IFS_US - 352 - EVENT_OVERHEAD_START_US -
				  EVENT_TICKER_RES_MARGIN_US)) {
			return -ETIME;
		}

		radio_switch_complete_and_disable();

		/* Acquire the connection context */
		lll_conn = lll->conn;

		/* Tx the connect request packet */
		pdu_tx = (void *)radio_pkt_scratch_get();
		pdu_tx->type = PDU_ADV_TYPE_CONNECT_IND;

		if (IS_ENABLED(CONFIG_BT_CTLR_CHAN_SEL_2)) {
			pdu_tx->chan_sel = 1;
		} else {
			pdu_tx->chan_sel = 0;
		}

		pdu_tx->rx_addr = pdu_adv_rx->tx_addr;
		pdu_tx->len = sizeof(struct pdu_adv_connect_ind);
#if defined(CONFIG_BT_CTLR_PRIVACY)
		lrpa = ull_filter_lll_lrpa_get(rl_idx);
		if (lll->rpa_gen && lrpa) {
			pdu_tx->tx_addr = 1;
			memcpy(&pdu_tx->connect_ind.init_addr[0], lrpa->val,
			       BDADDR_SIZE);
		} else {
#else
		if (1) {
#endif /* CONFIG_BT_CTLR_PRIVACY */
			pdu_tx->tx_addr = lll->init_addr_type;
			memcpy(&pdu_tx->connect_ind.init_addr[0],
			       &lll->init_addr[0], BDADDR_SIZE);
		}
		memcpy(&pdu_tx->connect_ind.adv_addr[0],
		       &pdu_adv_rx->adv_ind.addr[0], BDADDR_SIZE);
		memcpy(&pdu_tx->connect_ind.access_addr[0],
		       &lll_conn->access_addr[0], 4);
		memcpy(&pdu_tx->connect_ind.crc_init[0],
		       &lll_conn->crc_init[0], 3);
		pdu_tx->connect_ind.win_size = 1;

		conn_interval_us = (uint32_t)lll_conn->interval *
			CONN_INT_UNIT_US;
		conn_offset_us = radio_tmr_end_get() + 502 +
			CONN_INT_UNIT_US;

		if (!IS_ENABLED(CONFIG_BT_CTLR_SCHED_ADVANCED) ||
		    lll->conn_win_offset_us == 0U) {
			conn_space_us = conn_offset_us;
			pdu_tx->connect_ind.win_offset = sys_cpu_to_le16(0);
		} else {
			conn_space_us = lll->conn_win_offset_us;
			while ((conn_space_us & ((uint32_t)1 << 31)) ||
			       (conn_space_us < conn_offset_us)) {
				conn_space_us += conn_interval_us;
			}
			pdu_tx->connect_ind.win_offset =
				sys_cpu_to_le16((conn_space_us -
						 conn_offset_us) /
					CONN_INT_UNIT_US);
			pdu_tx->connect_ind.win_size++;
		}

		pdu_tx->connect_ind.interval =
			sys_cpu_to_le16(lll_conn->interval);
		pdu_tx->connect_ind.latency =
			sys_cpu_to_le16(lll_conn->latency);
		pdu_tx->connect_ind.timeout =
			sys_cpu_to_le16(lll->conn_timeout);
		memcpy(&pdu_tx->connect_ind.chan_map[0],
		       &lll_conn->data_chan_map[0],
		       sizeof(pdu_tx->connect_ind.chan_map));
		pdu_tx->connect_ind.hop = lll_conn->data_chan_hop;
		pdu_tx->connect_ind.sca = lll_clock_sca_local_get();

		radio_pkt_tx_set(pdu_tx);

		/* assert if radio packet ptr is not set and radio started tx */
		LL_ASSERT(!radio_is_ready());

		if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
			lll_prof_cputime_capture();
		}

		radio_isr_set(isr_cleanup, lll);

#if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
		if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
			/* PA/LNA enable is overwriting packet end
			 * used in ISR profiling, hence back it up
			 * for later use.
			 */
			lll_prof_radio_end_backup();
		}
		radio_gpio_pa_setup();
		radio_gpio_pa_lna_enable(radio_tmr_tifs_base_get() +
					 EVENT_IFS_US -
					 radio_rx_chain_delay_get(0, 0) -
					 HAL_RADIO_GPIO_PA_OFFSET);
#endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */

#if defined(CONFIG_BT_CTLR_CONN_RSSI)
		if (rssi_ready) {
			lll_conn->rssi_latest =  radio_rssi_get();
		}
#endif /* CONFIG_BT_CTLR_CONN_RSSI */

		/* block CPU so that there is no CRC error on pdu tx,
		 * this is only needed if we want the CPU to sleep.
		 * while(!radio_has_disabled())
		 * {cpu_sleep();}
		 * radio_status_reset();
		 */

		/* Stop further LLL radio events */
		lll->conn->central.initiated = 1;

		rx = ull_pdu_rx_alloc();

		rx->hdr.type = NODE_RX_TYPE_CONNECTION;
		rx->hdr.handle = 0xffff;

		uint8_t pdu_adv_rx_chan_sel = pdu_adv_rx->chan_sel;

		memcpy(rx->pdu, pdu_tx, (offsetof(struct pdu_adv, connect_ind) +
					  sizeof(struct pdu_adv_connect_ind)));

		/*
		 * Overwrite the sent chan sel with received chan sel, when
		 * giving this PDU to the higher layer.
		 */
		pdu_adv_rx = (void *)rx->pdu;
		pdu_adv_rx->chan_sel = pdu_adv_rx_chan_sel;

		ftr = &(rx->hdr.rx_ftr);

		ftr->param = lll;
		ftr->ticks_anchor = radio_tmr_start_get();
		ftr->radio_end_us = conn_space_us -
				    radio_tx_chain_delay_get(0, 0);

#if defined(CONFIG_BT_CTLR_PRIVACY)
		ftr->rl_idx = irkmatch_ok ? rl_idx : FILTER_IDX_NONE;
#endif /* CONFIG_BT_CTLR_PRIVACY */

		if (IS_ENABLED(CONFIG_BT_CTLR_CHAN_SEL_2)) {
			ftr->extra = ull_pdu_rx_alloc();
		}

		ull_rx_put_sched(rx->hdr.link, rx);

		return 0;
#endif /* CONFIG_BT_CENTRAL */

	/* Active scanner */
	} else if (((pdu_adv_rx->type == PDU_ADV_TYPE_ADV_IND) ||
		    (pdu_adv_rx->type == PDU_ADV_TYPE_SCAN_IND)) &&
		   (pdu_adv_rx->len <= sizeof(struct pdu_adv_adv_ind)) &&
		   lll->type &&
#if defined(CONFIG_BT_CENTRAL)
		   !lll->conn) {
#else /* !CONFIG_BT_CENTRAL */
		   1) {
#endif /* !CONFIG_BT_CENTRAL */
		struct pdu_adv *pdu_tx;
#if defined(CONFIG_BT_CTLR_PRIVACY)
		bt_addr_t *lrpa;
#endif /* CONFIG_BT_CTLR_PRIVACY */
		uint32_t err;

		/* setup tIFS switching */
		radio_tmr_tifs_set(EVENT_IFS_US);
		radio_switch_complete_and_rx(0);

		/* save the adv packet */
		err = isr_rx_scan_report(lll, rssi_ready,
					 irkmatch_ok ? rl_idx : FILTER_IDX_NONE,
					 false);
		if (err) {
			return err;
		}

		/* prepare the scan request packet */
		pdu_tx = (void *)radio_pkt_scratch_get();
		pdu_tx->type = PDU_ADV_TYPE_SCAN_REQ;
		pdu_tx->rx_addr = pdu_adv_rx->tx_addr;
		pdu_tx->len = sizeof(struct pdu_adv_scan_req);
#if defined(CONFIG_BT_CTLR_PRIVACY)
		lrpa = ull_filter_lll_lrpa_get(rl_idx);
		if (lll->rpa_gen && lrpa) {
			pdu_tx->tx_addr = 1;
			memcpy(&pdu_tx->scan_req.scan_addr[0], lrpa->val,
			       BDADDR_SIZE);
		} else {
#else
		if (1) {
#endif /* CONFIG_BT_CTLR_PRIVACY */
			pdu_tx->tx_addr = lll->init_addr_type;
			memcpy(&pdu_tx->scan_req.scan_addr[0],
			       &lll->init_addr[0], BDADDR_SIZE);
		}
		memcpy(&pdu_tx->scan_req.adv_addr[0],
		       &pdu_adv_rx->adv_ind.addr[0], BDADDR_SIZE);

		radio_pkt_tx_set(pdu_tx);

		/* assert if radio packet ptr is not set and radio started tx */
		LL_ASSERT(!radio_is_ready());

		if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
			lll_prof_cputime_capture();

		}

		/* capture end of Tx-ed PDU, used to calculate HCTO. */
		radio_tmr_end_capture();

#if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
		if (IS_ENABLED(CONFIG_BT_CTLR_PROFILE_ISR)) {
			/* PA/LNA enable is overwriting packet end
			 * used in ISR profiling, hence back it up
			 * for later use.
			 */
			lll_prof_radio_end_backup();
		}

		radio_gpio_pa_setup();
		radio_gpio_pa_lna_enable(radio_tmr_tifs_base_get() +
					 EVENT_IFS_US -
					 radio_rx_chain_delay_get(0, 0) -
					 HAL_RADIO_GPIO_PA_OFFSET);
#endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */

		/* switch scanner state to active */
		lll->state = 1U;
		radio_isr_set(isr_tx, lll);

		return 0;
	}
	/* Passive scanner or scan responses */
	else if (((((pdu_adv_rx->type == PDU_ADV_TYPE_ADV_IND) ||
		    (pdu_adv_rx->type == PDU_ADV_TYPE_NONCONN_IND) ||
		    (pdu_adv_rx->type == PDU_ADV_TYPE_SCAN_IND)) &&
		   (pdu_adv_rx->len <= sizeof(struct pdu_adv_adv_ind))) ||
		  ((pdu_adv_rx->type == PDU_ADV_TYPE_DIRECT_IND) &&
		   (pdu_adv_rx->len == sizeof(struct pdu_adv_direct_ind)) &&
		   (/* allow directed adv packets addressed to this device */
		    isr_scan_tgta_check(lll, false, pdu_adv_rx, rl_idx,
					&dir_report))) ||
#if defined(CONFIG_BT_CTLR_ADV_EXT)
		  ((pdu_adv_rx->type == PDU_ADV_TYPE_EXT_IND) &&
		   (lll->phy)) ||
#endif /* CONFIG_BT_CTLR_ADV_EXT */
		  ((pdu_adv_rx->type == PDU_ADV_TYPE_SCAN_RSP) &&
		   (pdu_adv_rx->len <= sizeof(struct pdu_adv_scan_rsp)) &&
		   (lll->state != 0U) &&
		   isr_scan_rsp_adva_matches(pdu_adv_rx))) &&
		 (pdu_adv_rx->len != 0) &&
#if defined(CONFIG_BT_CENTRAL)
		   !lll->conn) {
#else /* !CONFIG_BT_CENTRAL */
		   1) {
#endif /* !CONFIG_BT_CENTRAL */
		uint32_t err;

		/* save the scan response packet */
		err = isr_rx_scan_report(lll, rssi_ready,
					 irkmatch_ok ? rl_idx :
						       FILTER_IDX_NONE,
					 dir_report);
		if (err) {
			return err;
		}
	}
	/* invalid PDU */
	else {
		/* ignore and close this rx/tx chain ( code below ) */
		return 1;
	}

	return 1;
}

#if defined(CONFIG_BT_CENTRAL)
static inline bool isr_scan_init_check(struct lll_scan *lll,
				       struct pdu_adv *pdu, uint8_t rl_idx)
{
	return ((((lll->filter_policy & SCAN_FP_FILTER) != 0U) ||
		 isr_scan_init_adva_check(lll, pdu, rl_idx)) &&
		(((pdu->type == PDU_ADV_TYPE_ADV_IND) &&
		  (pdu->len <= sizeof(struct pdu_adv_adv_ind))) ||
		 ((pdu->type == PDU_ADV_TYPE_DIRECT_IND) &&
		  (pdu->len == sizeof(struct pdu_adv_direct_ind)) &&
		  (/* allow directed adv packets addressed to this device */
		   isr_scan_tgta_check(lll, true, pdu, rl_idx, NULL)))));
}

static inline bool isr_scan_init_adva_check(struct lll_scan *lll,
					    struct pdu_adv *pdu, uint8_t rl_idx)
{
#if defined(CONFIG_BT_CTLR_PRIVACY)
	/* Only applies to initiator with no filter accept list */
	if (rl_idx != FILTER_IDX_NONE) {
		return (rl_idx == lll->rl_idx);
	} else if (!ull_filter_lll_rl_addr_allowed(pdu->tx_addr,
						   pdu->adv_ind.addr,
						   &rl_idx)) {
		return false;
	}
#endif /* CONFIG_BT_CTLR_PRIVACY */
	return ((lll->adv_addr_type == pdu->tx_addr) &&
		!memcmp(lll->adv_addr, &pdu->adv_ind.addr[0], BDADDR_SIZE));
}
#endif /* CONFIG_BT_CENTRAL */

static inline bool isr_scan_tgta_check(struct lll_scan *lll, bool init,
				       struct pdu_adv *pdu, uint8_t rl_idx,
				       bool *dir_report)
{
#if defined(CONFIG_BT_CTLR_PRIVACY)
	if (ull_filter_lll_rl_addr_resolve(pdu->rx_addr,
					   pdu->direct_ind.tgt_addr, rl_idx)) {
		return true;
	} else if (init && lll->rpa_gen &&
		   ull_filter_lll_lrpa_get(rl_idx)) {
		/* Initiator generating RPAs, and could not resolve TargetA:
		 * discard
		 */
		return false;
	}
#endif /* CONFIG_BT_CTLR_PRIVACY */

	return (((lll->init_addr_type == pdu->rx_addr) &&
		!memcmp(lll->init_addr, pdu->direct_ind.tgt_addr,
			BDADDR_SIZE))) ||
		  /* allow directed adv packets where TargetA address
		   * is resolvable private address (scanner only)
		   */
	       isr_scan_tgta_rpa_check(lll, pdu, dir_report);
}

static inline bool isr_scan_tgta_rpa_check(struct lll_scan *lll,
					   struct pdu_adv *pdu,
					   bool *dir_report)
{
	if (((lll->filter_policy & SCAN_FP_EXT) != 0U) &&
	    (pdu->rx_addr != 0) &&
	    ((pdu->direct_ind.tgt_addr[5] & 0xc0) == 0x40)) {

		if (dir_report) {
			*dir_report = true;
		}

		return true;
	}

	return false;
}

static inline bool isr_scan_rsp_adva_matches(struct pdu_adv *srsp)
{
	struct pdu_adv *sreq = (void *)radio_pkt_scratch_get();

	return ((sreq->rx_addr == srsp->tx_addr) &&
		(memcmp(&sreq->scan_req.adv_addr[0],
			&srsp->scan_rsp.addr[0], BDADDR_SIZE) == 0));
}

static uint32_t isr_rx_scan_report(struct lll_scan *lll, uint8_t rssi_ready,
				uint8_t rl_idx, bool dir_report)
{
	struct node_rx_pdu *node_rx;
	struct pdu_adv *pdu_adv_rx;

	node_rx = ull_pdu_rx_alloc_peek(3);
	if (!node_rx) {
		return 1;
	}
	ull_pdu_rx_alloc();

	/* Prepare the report (adv or scan resp) */
	node_rx->hdr.handle = 0xffff;
	if (0) {

#if defined(CONFIG_BT_HCI_MESH_EXT)
	} else if (_radio.advertiser.is_enabled &&
		   _radio.advertiser.is_mesh) {
		node_rx->hdr.type = NODE_RX_TYPE_MESH_REPORT;
#endif /* CONFIG_BT_HCI_MESH_EXT */

#if defined(CONFIG_BT_CTLR_ADV_EXT)
	} else if (lll->phy) {
		switch (lll->phy) {
		case PHY_1M:
			node_rx->hdr.type = NODE_RX_TYPE_EXT_1M_REPORT;
			break;

		case PHY_CODED:
			node_rx->hdr.type = NODE_RX_TYPE_EXT_CODED_REPORT;
			break;

		default:
			LL_ASSERT(0);
			break;
		}
#endif /* CONFIG_BT_CTLR_ADV_EXT */
	} else {
		node_rx->hdr.type = NODE_RX_TYPE_REPORT;
	}

	pdu_adv_rx = (void *)node_rx->pdu;

	node_rx->hdr.rx_ftr.rssi = (rssi_ready) ?
				   (radio_rssi_get() & 0x7f)
				   : 0x7f;
#if defined(CONFIG_BT_CTLR_PRIVACY)
	/* save the resolving list index. */
	node_rx->hdr.rx_ftr.rl_idx = rl_idx;
#endif /* CONFIG_BT_CTLR_PRIVACY */
#if defined(CONFIG_BT_CTLR_EXT_SCAN_FP)
	/* save the directed adv report flag */
	node_rx->hdr.rx_ftr.direct = dir_report;
#endif /* CONFIG_BT_CTLR_EXT_SCAN_FP */
#if defined(CONFIG_BT_HCI_MESH_EXT)
	if (node_rx->hdr.type == NODE_RX_TYPE_MESH_REPORT) {
		/* save channel and anchor point ticks. */
		node_rx->hdr.rx_ftr.chan = _radio.scanner.chan - 1;
		node_rx->hdr.rx_ftr.ticks_anchor = _radio.ticks_anchor;
	}
#endif /* CONFIG_BT_CTLR_EXT_SCAN_FP */

	ull_rx_put_sched(node_rx->hdr.link, node_rx);

	return 0;
}
