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

#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 "hal/ticker.h"

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

#include "ticker/ticker.h"

#include "pdu_df.h"
#include "lll/pdu_vendor.h"
#include "pdu.h"

#include "lll.h"
#include "lll_clock.h"
#include "lll/lll_vendor.h"
#include "lll/lll_adv_types.h"
#include "lll_adv.h"
#include "lll/lll_adv_pdu.h"
#include "lll_adv_sync.h"
#include "lll/lll_df_types.h"
#include "lll_conn.h"
#include "lll_chan.h"

#include "ull_adv_types.h"

#include "ull_internal.h"
#include "ull_chan_internal.h"
#include "ull_sched_internal.h"
#include "ull_adv_internal.h"

#include "ll.h"

#include "hal/debug.h"

static int init_reset(void);
static uint8_t adv_type_check(struct ll_adv_set *adv);
static inline struct ll_adv_sync_set *sync_acquire(void);
static inline void sync_release(struct ll_adv_sync_set *sync);
static inline uint16_t sync_handle_get(const struct ll_adv_sync_set *sync);
static uint32_t sync_time_get(const struct ll_adv_sync_set *sync,
			      const struct pdu_adv *pdu);
static inline uint8_t sync_remove(struct ll_adv_sync_set *sync,
				  struct ll_adv_set *adv, uint8_t enable);
static uint8_t sync_chm_update(uint8_t handle);

#if defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
static void sync_info_offset_fill(struct pdu_adv_sync_info *si, uint32_t offs);

#else /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
static void mfy_sync_offset_get(void *param);
static void sync_info_offset_fill(struct pdu_adv_sync_info *si,
				  uint32_t ticks_offset,
				  uint32_t remainder_us,
				  uint32_t start_us);
static void ticker_op_cb(uint32_t status, void *param);
#endif /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */

static struct pdu_adv_sync_info *sync_info_get(struct pdu_adv *pdu);
static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
		      uint32_t remainder, uint16_t lazy, uint8_t force,
		      void *param);

#if defined(CONFIG_BT_CTLR_ADV_ISO) && defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
static void ticker_update_op_cb(uint32_t status, void *param);

static struct ticker_ext ll_adv_sync_ticker_ext[CONFIG_BT_CTLR_ADV_SYNC_SET];
#endif /* !CONFIG_BT_CTLR_ADV_ISO  && CONFIG_BT_TICKER_EXT_EXPIRE_INFO */

static struct ll_adv_sync_set ll_adv_sync_pool[CONFIG_BT_CTLR_ADV_SYNC_SET];
static void *adv_sync_free;

uint8_t ll_adv_sync_param_set(uint8_t handle, uint16_t interval, uint16_t flags)
{
	void *extra_data_prev, *extra_data;
	struct pdu_adv *pdu_prev, *pdu;
	struct lll_adv_sync *lll_sync;
	struct ll_adv_sync_set *sync;
	struct ll_adv_set *adv;
	uint8_t err, ter_idx;

	adv = ull_adv_is_created_get(handle);
	if (!adv) {
		return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
	}

	if (IS_ENABLED(CONFIG_BT_CTLR_PARAM_CHECK)) {
		uint8_t err;

		err = adv_type_check(adv);
		if (err) {
			return err;
		}
	}

	lll_sync = adv->lll.sync;
	if (!lll_sync) {
		struct pdu_adv *ter_pdu;
		struct lll_adv *lll;
		uint8_t chm_last;
		int err;

		sync = sync_acquire();
		if (!sync) {
			return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
		}

		lll = &adv->lll;
		lll_sync = &sync->lll;
		lll->sync = lll_sync;
		lll_sync->adv = lll;

		lll_adv_data_reset(&lll_sync->data);
		err = lll_adv_sync_data_init(&lll_sync->data);
		if (err) {
			return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
		}

		/* NOTE: ull_hdr_init(&sync->ull); is done on start */
		lll_hdr_init(lll_sync, sync);

		err = util_aa_le32(lll_sync->access_addr);
		LL_ASSERT(!err);

		lll_sync->data_chan_id = lll_chan_id(lll_sync->access_addr);
		chm_last = lll_sync->chm_first;
		lll_sync->chm_last = chm_last;
		lll_sync->chm[chm_last].data_chan_count =
			ull_chan_map_get(lll_sync->chm[chm_last].data_chan_map);

		lll_csrand_get(lll_sync->crc_init, sizeof(lll_sync->crc_init));

		lll_sync->latency_prepare = 0;
		lll_sync->latency_event = 0;
		lll_sync->event_counter = 0;

		sync->is_enabled = 0U;
		sync->is_started = 0U;

		ter_pdu = lll_adv_sync_data_peek(lll_sync, NULL);
		ull_adv_sync_pdu_init(ter_pdu, 0U, 0U, 0U, NULL);
	} else {
		sync = HDR_LLL2ULL(lll_sync);
	}

	/* Periodic Advertising is already started */
	if (sync->is_started) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}

	sync->interval = interval;

	err = ull_adv_sync_pdu_alloc(adv, ULL_ADV_PDU_EXTRA_DATA_ALLOC_IF_EXIST, &pdu_prev, &pdu,
				     &extra_data_prev, &extra_data, &ter_idx);
	if (err) {
		return err;
	}

#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
	if (extra_data) {
		ull_adv_sync_extra_data_set_clear(extra_data_prev, extra_data,
						  0U, 0U, NULL);
	}
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */

#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK)
	/* Duplicate chain PDUs */
	do {
		struct pdu_adv *pdu_chain;

#endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK */
		err = ull_adv_sync_pdu_set_clear(lll_sync, pdu_prev, pdu,
						 0U, 0U, NULL);
		if (err) {
			return err;
		}

#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK)
		pdu_prev = lll_adv_pdu_linked_next_get(pdu_prev);
		pdu_chain = lll_adv_pdu_linked_next_get(pdu);

		/* Allocate new chain PDU if required */
		if (pdu_prev) {
			/* Prior PDU chain allocation valid */
			if (pdu_chain) {
				pdu = pdu_chain;

				continue;
			}

			/* Get a new chain PDU */
			pdu_chain = lll_adv_pdu_alloc_pdu_adv();
			if (!pdu_chain) {
				return BT_HCI_ERR_INSUFFICIENT_RESOURCES;
			}

			/* Link the chain PDU to parent PDU */
			lll_adv_pdu_linked_append(pdu_chain, pdu);

			/* continue back to update the new PDU */
			pdu = pdu_chain;
		}
	} while (pdu_prev);
#endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK */

	lll_adv_sync_data_enqueue(lll_sync, ter_idx);

	sync->is_data_cmplt = 1U;

	return 0;
}

#if defined(CONFIG_BT_CTLR_ADV_ISO) && defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
void ull_adv_iso_created(struct ll_adv_sync_set *sync)
{
	if (sync->lll.iso && sync->is_started) {
		uint8_t iso_handle = sync->lll.iso->handle;
		uint8_t handle = sync_handle_get(sync);

		ticker_update_ext(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_THREAD,
			   (TICKER_ID_ADV_SYNC_BASE + handle), 0, 0, 0, 0, 0, 0,
			   ticker_update_op_cb, sync, 0, TICKER_ID_ADV_ISO_BASE + iso_handle);
	}
}
#endif /* CONFIG_BT_CTLR_ADV_ISO && CONFIG_BT_TICKER_EXT_EXPIRE_INFO */

uint8_t ll_adv_sync_ad_data_set(uint8_t handle, uint8_t op, uint8_t len,
				uint8_t const *const data)
{
	uint8_t hdr_data[ULL_ADV_HDR_DATA_LEN_SIZE +
			 ULL_ADV_HDR_DATA_DATA_PTR_SIZE +
			 ULL_ADV_HDR_DATA_LEN_SIZE +
			 ULL_ADV_HDR_DATA_AUX_PTR_PTR_SIZE +
			 ULL_ADV_HDR_DATA_LEN_SIZE];
	void *extra_data_prev, *extra_data;
	struct pdu_adv *pdu_prev, *pdu;
	struct lll_adv_sync *lll_sync;
	struct ll_adv_sync_set *sync;
	struct ll_adv_set *adv;
	uint8_t *val_ptr;
	uint8_t ter_idx;
	uint8_t err;

#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK)
	uint8_t ad_len_overflow;
	uint8_t ad_len_chain;
#endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK */

	/* Check for valid advertising set */
	adv =  ull_adv_is_created_get(handle);
	if (!adv) {
		return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
	}

	/* Check for advertising set type */
	if (IS_ENABLED(CONFIG_BT_CTLR_PARAM_CHECK)) {
		uint8_t err;

		err = adv_type_check(adv);
		if (err) {
			return err;
		}
	}

	/* Check if periodic advertising is associated with advertising set */
	lll_sync = adv->lll.sync;
	if (!lll_sync) {
		return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
	}

	sync = HDR_LLL2ULL(lll_sync);

	/* Reject setting fragment when periodic advertising is enabled */
	if (sync->is_enabled && (op <= BT_HCI_LE_EXT_ADV_OP_LAST_FRAG)) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}

	/* Reject intermediate op before first op */
	if (sync->is_data_cmplt &&
	    ((op == BT_HCI_LE_EXT_ADV_OP_INTERM_FRAG) ||
	     (op == BT_HCI_LE_EXT_ADV_OP_LAST_FRAG))) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}

	/* Reject unchanged op before complete status */
	if (!sync->is_data_cmplt &&
	    (op == BT_HCI_LE_EXT_ADV_OP_UNCHANGED_DATA)) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}

	/* Reject first, intermediate, last operation and len > 191 bytes if
	 * chain PDUs unsupported.
	 */
	if (!IS_ENABLED(CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK) &&
	    ((op < BT_HCI_LE_EXT_ADV_OP_COMPLETE_DATA) ||
	     (len > PDU_AC_EXT_AD_DATA_LEN_MAX))) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}

	/* Allocate new PDU buffer at latest double buffer index */
	err = ull_adv_sync_pdu_alloc(adv, ULL_ADV_PDU_EXTRA_DATA_ALLOC_IF_EXIST,
				     &pdu_prev, &pdu, &extra_data_prev,
				     &extra_data, &ter_idx);
	if (err) {
		return err;
	}

#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
	if (extra_data) {
		ull_adv_sync_extra_data_set_clear(extra_data_prev, extra_data,
						  0U, 0U, NULL);
	}
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */

	/* Prepare the AD data as parameter to update in PDU */
	/* Use length = 0 and NULL pointer to retain old data in the PDU.
	 * Use length = 0 and valid pointer of `data` (auto/local variable) to
	 * remove old data.
	 * User length > 0 and valid pointer of `data` (auto/local variable) to
	 * set new data.
	 */
	val_ptr = hdr_data;
	if (op == BT_HCI_LE_EXT_ADV_OP_INTERM_FRAG ||
	    op == BT_HCI_LE_EXT_ADV_OP_LAST_FRAG ||
	    op == BT_HCI_LE_EXT_ADV_OP_UNCHANGED_DATA) {
		*val_ptr++ = 0U;
		(void)memset((void *)val_ptr, 0U,
			     ULL_ADV_HDR_DATA_DATA_PTR_SIZE);
	} else {
		*val_ptr++ = len;
		(void)memcpy(val_ptr, &data, sizeof(data));
	}

	if (!IS_ENABLED(CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK) ||
	    (op == BT_HCI_LE_EXT_ADV_OP_UNCHANGED_DATA)) {
		err = ull_adv_sync_pdu_set_clear(lll_sync, pdu_prev, pdu,
						 ULL_ADV_PDU_HDR_FIELD_AD_DATA,
						 0U, hdr_data);
#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK)
		/* No AD data overflow */
		ad_len_overflow = 0U;
#endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK */
	} else if (!IS_ENABLED(CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK) ||
		   (op == BT_HCI_LE_EXT_ADV_OP_FIRST_FRAG ||
		    op == BT_HCI_LE_EXT_ADV_OP_COMPLETE_DATA)) {
		/* Add AD Data and remove any prior presence of Aux Ptr */
		err = ull_adv_sync_pdu_set_clear(lll_sync, pdu_prev, pdu,
						 ULL_ADV_PDU_HDR_FIELD_AD_DATA,
						 ULL_ADV_PDU_HDR_FIELD_AUX_PTR,
						 hdr_data);
#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK)
		if (!err) {
			/* Fragment into chain PDU if len > 191 bytes */
			if (len > PDU_AC_EXT_AD_DATA_LEN_MAX) {
				/* Prepare the AD data as parameter to update in
				 * PDU
				 */
				val_ptr = hdr_data;
				*val_ptr++ = PDU_AC_EXT_AD_DATA_LEN_MAX;
				(void)memcpy(val_ptr, &data, sizeof(data));

				/* Traverse to next set clear hdr data
				 * parameter, as aux ptr reference to be
				 * returned, hence second parameter will be for
				 * AD data field.
				 */
				val_ptr += sizeof(data);

				*val_ptr = PDU_AC_EXT_AD_DATA_LEN_MAX;
				(void)memcpy(&val_ptr[ULL_ADV_HDR_DATA_DATA_PTR_OFFSET],
					     &data, sizeof(data));

				/* Calculate the overflow chain PDU's AD data
				 * length
				 */
				ad_len_overflow =
					len - PDU_AC_EXT_AD_DATA_LEN_MAX;

				/* No AD data in chain PDU besides the
				 * overflow
				 */
				ad_len_chain = 0U;
			} else {
				struct pdu_adv *pdu_chain;

				/* Remove/Release any previous chain PDU
				 * allocations
				 */
				pdu_chain = lll_adv_pdu_linked_next_get(pdu);
				if (pdu_chain) {
					lll_adv_pdu_linked_append(NULL, pdu);
					lll_adv_pdu_linked_release_all(pdu_chain);
				}

				/* No AD data overflow */
				ad_len_overflow = 0U;
			}
		}
	} else {
		struct pdu_adv *pdu_chain_prev;
		struct pdu_adv *pdu_chain;
		uint16_t ad_len_total;
		uint8_t ad_len_prev;

		/* Traverse to next set clear hdr data parameter */
		val_ptr += sizeof(data);

		/* Traverse to the last chain PDU */
		ad_len_total = 0U;
		pdu_chain_prev = pdu_prev;
		pdu_chain = pdu;
		do {
			/* Prepare for aux ptr field reference to be returned, hence
			 * second parameter will be for AD data field.
			 */
			*val_ptr = 0U;
			(void)memset((void *)&val_ptr[ULL_ADV_HDR_DATA_DATA_PTR_OFFSET],
				     0U, ULL_ADV_HDR_DATA_DATA_PTR_SIZE);

			pdu_prev = pdu_chain_prev;
			pdu = pdu_chain;

			/* Add Aux Ptr field if not already present */
			err = ull_adv_sync_pdu_set_clear(lll_sync, pdu_prev,
					pdu, (ULL_ADV_PDU_HDR_FIELD_AD_DATA |
					      ULL_ADV_PDU_HDR_FIELD_AUX_PTR),
					0, hdr_data);
			LL_ASSERT(!err || (err == BT_HCI_ERR_PACKET_TOO_LONG));

			/* Get PDUs previous AD data length */
			ad_len_prev =
				hdr_data[ULL_ADV_HDR_DATA_AUX_PTR_PTR_OFFSET +
					 ULL_ADV_HDR_DATA_AUX_PTR_PTR_SIZE];

			/* Check of max supported AD data len */
			ad_len_total += ad_len_prev;
			if ((ad_len_total + len) >
			    CONFIG_BT_CTLR_ADV_DATA_LEN_MAX) {
				/* NOTE: latest PDU was not consumed by LLL and
				 * as ull_adv_sync_pdu_alloc() has reverted back
				 * the double buffer with the first PDU, and
				 * returned the latest PDU as the new PDU, we
				 * need to enqueue back the new PDU which is
				 * infact the latest PDU.
				 */
				if (pdu_prev == pdu) {
					lll_adv_sync_data_enqueue(lll_sync, ter_idx);
				}

				return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
			}

			pdu_chain_prev = lll_adv_pdu_linked_next_get(pdu_prev);
			pdu_chain = lll_adv_pdu_linked_next_get(pdu);
			LL_ASSERT((pdu_chain_prev && pdu_chain) ||
				  (!pdu_chain_prev && !pdu_chain));
		} while (pdu_chain_prev);

		if (err == BT_HCI_ERR_PACKET_TOO_LONG) {
			ad_len_overflow =
				hdr_data[ULL_ADV_HDR_DATA_AUX_PTR_PTR_OFFSET +
					 ULL_ADV_HDR_DATA_AUX_PTR_PTR_SIZE +
					 ULL_ADV_HDR_DATA_DATA_PTR_OFFSET +
					 ULL_ADV_HDR_DATA_DATA_PTR_SIZE];

			/* Prepare for aux ptr field reference to be returned,
			 * hence second parameter will be for AD data field.
			 * Fill it with reduced AD data length.
			 */
			*val_ptr = ad_len_prev - ad_len_overflow;

			/* AD data len in chain PDU */
			ad_len_chain = len;

			/* Proceed to add chain PDU */
			err = 0U;
		} else {
			ad_len_overflow = 0U;
		}
#endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK */
	}
	if (err) {
		return err;
	}

	/* Parameter validation, if operation is 0x04 (unchanged data)
	 * - periodic advertising is disabled, or
	 * - periodic advertising contains no data, or
	 * - Advertising Data Length is not zero
	 */
	if (IS_ENABLED(CONFIG_BT_CTLR_PARAM_CHECK) &&
	    (op == BT_HCI_LE_EXT_ADV_OP_UNCHANGED_DATA) &&
	    ((!sync->is_enabled) ||
	     (hdr_data[ULL_ADV_HDR_DATA_LEN_OFFSET] == 0U) ||
	     (len != 0U))) {
		/* NOTE: latest PDU was not consumed by LLL and as
		 * ull_adv_sync_pdu_alloc() has reverted back the double buffer
		 * with the first PDU, and returned the latest PDU as the new
		 * PDU, we need to enqueue back the new PDU which is infact
		 * the latest PDU.
		 */
		if (pdu_prev == pdu) {
			lll_adv_sync_data_enqueue(lll_sync, ter_idx);
		}

		return BT_HCI_ERR_INVALID_PARAM;
	}

#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK)
	if ((op == BT_HCI_LE_EXT_ADV_OP_INTERM_FRAG) ||
	    (op == BT_HCI_LE_EXT_ADV_OP_LAST_FRAG) ||
	    ad_len_overflow) {
		struct pdu_adv_com_ext_adv *com_hdr_chain;
		struct pdu_adv_com_ext_adv *com_hdr;
		struct pdu_adv_ext_hdr *hdr_chain;
		struct pdu_adv_aux_ptr *aux_ptr;
		struct pdu_adv *pdu_chain_prev;
		struct pdu_adv_ext_hdr hdr;
		struct pdu_adv *pdu_chain;
		uint8_t *dptr_chain;
		uint32_t offs_us;
		uint16_t ter_len;
		uint8_t *dptr;

		/* Get reference to flags in superior PDU */
		com_hdr = &pdu->adv_ext_ind;
		if (com_hdr->ext_hdr_len) {
			hdr = com_hdr->ext_hdr;
		} else {
			*(uint8_t *)&hdr = 0U;
		}
		dptr = com_hdr->ext_hdr.data;

		/* Allocate new PDU */
		pdu_chain = lll_adv_pdu_alloc_pdu_adv();
		LL_ASSERT(pdu_chain);

		/* Populate the appended chain PDU */
		pdu_chain->type = PDU_ADV_TYPE_AUX_CHAIN_IND;
		pdu_chain->rfu = 0U;
		pdu_chain->chan_sel = 0U;
		pdu_chain->tx_addr = 0U;
		pdu_chain->rx_addr = 0U;
		pdu_chain->len = 0U;

		com_hdr_chain = &pdu_chain->adv_ext_ind;
		hdr_chain = (void *)&com_hdr_chain->ext_hdr_adv_data[0];
		dptr_chain = (void *)hdr_chain;

		/* Initialize Flags */
		*dptr_chain = 0U;

		/* No CTE Info.
		 * CTE count is given by HCI LE Set Connectionless CTE Transmit
		 * Parameters, hence it is not altered due to change on PDUs
		 * count in Periodic Advertising chain.
		 */

		/* ADI flag, mandatory if superior PDU has it */
		if (hdr.adi) {
			hdr_chain->adi = 1U;
		}

		/* Proceed to next byte if any flags present */
		if (*dptr_chain) {
			dptr_chain++;
		}

		/* Start adding fields corresponding to flags here, if any */

		/* No AdvA */
		/* No TgtA */
		/* No CTEInfo */

		/* ADI flag */
		if (hdr_chain->adi) {
			(void)memcpy(dptr_chain, dptr,
				     sizeof(struct pdu_adv_adi));

			dptr += sizeof(struct pdu_adv_adi);
			dptr_chain += sizeof(struct pdu_adv_adi);
		}

		/* non-connectable non-scannable chain pdu */
		com_hdr_chain->adv_mode = 0;

		/* Calc current chain PDU len */
		ter_len = ull_adv_aux_hdr_len_calc(com_hdr_chain, &dptr_chain);

		/* Prefix overflowed data to chain PDU and reduce the AD data in
		 * in the current PDU.
		 */
		if (ad_len_overflow) {
			uint8_t *ad_overflow;

			/* Copy overflowed AD data from previous PDU into
			 * new chain PDU
			 */
			(void)memcpy(&ad_overflow,
				     &val_ptr[ULL_ADV_HDR_DATA_DATA_PTR_OFFSET],
				     sizeof(ad_overflow));
			ad_overflow += *val_ptr;
			(void)memcpy(dptr_chain, ad_overflow, ad_len_overflow);
			dptr_chain += ad_len_overflow;

			/* Reduce the AD data in the current PDU that will
			 * become the current parent PDU for the new chain PDU.
			 */
			err = ull_adv_sync_pdu_set_clear(lll_sync, pdu_prev, pdu,
							 (ULL_ADV_PDU_HDR_FIELD_AD_DATA |
							  ULL_ADV_PDU_HDR_FIELD_AUX_PTR),
							 0, hdr_data);
			if (err) {
				/* NOTE: latest PDU was not consumed by LLL and
				 * as ull_adv_sync_pdu_alloc() has reverted back
				 * the double buffer with the first PDU, and
				 * returned the latest PDU as the new PDU, we
				 * need to enqueue back the new PDU which is
				 * infact the latest PDU.
				 */
				if (pdu_prev == pdu) {
					lll_adv_sync_data_enqueue(lll_sync, ter_idx);
				}

				return err;
			}

			/* AD data len in chain PDU besides the overflow */
			len = ad_len_chain;
		}

		/* Check AdvData overflow */
		if ((ter_len + ad_len_overflow + len) >
		    PDU_AC_PAYLOAD_SIZE_MAX) {
			/* NOTE: latest PDU was not consumed by LLL and
			 * as ull_adv_sync_pdu_alloc() has reverted back
			 * the double buffer with the first PDU, and
			 * returned the latest PDU as the new PDU, we
			 * need to enqueue back the new PDU which is
			 * infact the latest PDU.
			 */
			if (pdu_prev == pdu) {
				lll_adv_sync_data_enqueue(lll_sync, ter_idx);
			}

			return BT_HCI_ERR_PACKET_TOO_LONG;
		}

		/* Fill the chain PDU length */
		ull_adv_aux_hdr_len_fill(com_hdr_chain, ter_len);
		pdu_chain->len = ter_len + ad_len_overflow + len;

		/* Fill AD Data in chain PDU */
		(void)memcpy(dptr_chain, data, len);

		/* Get reference to aux ptr in superior PDU */
		(void)memcpy(&aux_ptr,
			     &hdr_data[ULL_ADV_HDR_DATA_AUX_PTR_PTR_OFFSET],
			     sizeof(aux_ptr));

		/* Fill the aux offset in the previous AUX_SYNC_IND PDU */
		offs_us = PDU_AC_US(pdu->len, adv->lll.phy_s,
				    adv->lll.phy_flags) +
			  EVENT_SYNC_B2B_MAFS_US;
		ull_adv_aux_ptr_fill(aux_ptr, offs_us, adv->lll.phy_s);

		/* Remove/Release any previous chain PDUs */
		pdu_chain_prev = lll_adv_pdu_linked_next_get(pdu);
		if (pdu_chain_prev) {
			lll_adv_pdu_linked_append(NULL, pdu);
			lll_adv_pdu_linked_release_all(pdu_chain_prev);
		}

		/* Chain the PDU */
		lll_adv_pdu_linked_append(pdu_chain, pdu);
	}
#endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK */

	/* Update time reservation if Periodic Advertising events are active */
	if (sync->is_started) {
		err = ull_adv_sync_time_update(sync, pdu);
		if (err) {
			return err;
		}
	}

	/* Commit the updated Periodic Advertising Data */
	lll_adv_sync_data_enqueue(lll_sync, ter_idx);

	/* Check if Periodic Advertising Data is complete */
	sync->is_data_cmplt = (op >= BT_HCI_LE_EXT_ADV_OP_LAST_FRAG);

	return 0;
}

uint8_t ll_adv_sync_enable(uint8_t handle, uint8_t enable)
{
	struct pdu_adv *ter_pdu = NULL;
	struct lll_adv_sync *lll_sync;
	struct ll_adv_sync_set *sync;
	uint8_t sync_got_enabled;
	struct ll_adv_set *adv;
	uint8_t ter_idx;
	uint8_t err;

	/* Check for valid advertising set */
	adv = ull_adv_is_created_get(handle);
	if (!adv) {
		return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
	}

	/* Check if periodic advertising is associated with advertising set */
	lll_sync = adv->lll.sync;
	if (!lll_sync) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}

	/* Check for invalid enable bit fields */
	if ((enable > (BT_HCI_LE_SET_PER_ADV_ENABLE_ENABLE |
		       BT_HCI_LE_SET_PER_ADV_ENABLE_ADI)) ||
	    (!IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT) &&
	     (enable > BT_HCI_LE_SET_PER_ADV_ENABLE_ENABLE))) {
		return BT_HCI_ERR_UNSUPP_FEATURE_PARAM_VAL;
	}

	sync = HDR_LLL2ULL(lll_sync);

	/* Handle periodic advertising being disable */
	if (!(enable & BT_HCI_LE_SET_PER_ADV_ENABLE_ENABLE)) {
		if (!sync->is_enabled) {
			return BT_HCI_ERR_CMD_DISALLOWED;
		}

		if (!sync->is_started) {
			sync->is_enabled = 0U;

			return 0;
		}

		err = sync_remove(sync, adv, 0U);
		return err;
	}

	/* Check for advertising set type */
	if (IS_ENABLED(CONFIG_BT_CTLR_PARAM_CHECK)) {
		uint8_t err;

		err = adv_type_check(adv);
		if (err) {
			return BT_HCI_ERR_CMD_DISALLOWED;
		}
	}

	/* Check for periodic data being complete */
	if (!sync->is_data_cmplt) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}

	/* TODO: Check packet too long */

	/* Check for already enabled periodic advertising set */
	sync_got_enabled = 0U;
	if (sync->is_enabled) {
		/* TODO: Enabling an already enabled advertising changes its
		 * random address.
		 */
	} else {
		sync_got_enabled = 1U;
	}

	/* Add/Remove ADI */
	if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT)) {
		uint8_t hdr_data[ULL_ADV_HDR_DATA_LEN_SIZE +
				 ULL_ADV_HDR_DATA_ADI_PTR_SIZE] = {0, };
		void *extra_data_prev, *extra_data;
		struct pdu_adv *pdu_prev, *pdu;
		uint16_t hdr_add_fields;
		uint16_t hdr_rem_fields;

		if (enable & BT_HCI_LE_SET_PER_ADV_ENABLE_ADI) {
			hdr_add_fields = ULL_ADV_PDU_HDR_FIELD_ADI;
			hdr_rem_fields = 0U;
		} else {
			hdr_add_fields = 0U;
			hdr_rem_fields = ULL_ADV_PDU_HDR_FIELD_ADI;
		}

		err = ull_adv_sync_pdu_alloc(adv, ULL_ADV_PDU_EXTRA_DATA_ALLOC_IF_EXIST,
					     &pdu_prev, &pdu, &extra_data_prev,
					     &extra_data, &ter_idx);
		if (err) {
			return err;
		}

		/* Use PDU to calculate time reservation */
		ter_pdu = pdu;

#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
		if (extra_data) {
			ull_adv_sync_extra_data_set_clear(extra_data_prev,
							  extra_data, 0U, 0U,
							  NULL);
		}
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */

#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK)
		/* Update ADI while duplicating chain PDUs */
		do {
			struct pdu_adv *pdu_chain;

#endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK */
			err = ull_adv_sync_pdu_set_clear(lll_sync, pdu_prev,
							 pdu, hdr_add_fields,
							 hdr_rem_fields,
							 hdr_data);
			if (err) {
				return err;
			}

#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK)
			pdu_prev = lll_adv_pdu_linked_next_get(pdu_prev);
			pdu_chain = lll_adv_pdu_linked_next_get(pdu);

			/* Allocate new chain PDU if required */
			if (pdu_prev) {
				/* Prior PDU chain allocation valid */
				if (pdu_chain) {
					pdu = pdu_chain;

					continue;
				}

				/* Get a new chain PDU */
				pdu_chain = lll_adv_pdu_alloc_pdu_adv();
				if (!pdu_chain) {
					return BT_HCI_ERR_INSUFFICIENT_RESOURCES;
				}

				/* Link the chain PDU to parent PDU */
				lll_adv_pdu_linked_append(pdu_chain, pdu);

				/* continue back to update the new PDU */
				pdu = pdu_chain;
			}
		} while (pdu_prev);
#endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK */
	}

	/* Start Periodic Advertising events if Extended Advertising events are
	 * active.
	 */
	if (adv->is_enabled && !sync->is_started) {
		struct pdu_adv_sync_info *sync_info;
		uint8_t value[1 + sizeof(sync_info)];
		uint32_t ticks_slot_overhead_aux;
		uint32_t ticks_slot_overhead;
		struct lll_adv_aux *lll_aux;
		struct ll_adv_aux_set *aux;
		uint32_t ticks_anchor_sync;
		uint32_t ticks_anchor_aux;
		uint8_t pri_idx, sec_idx;
		uint32_t ret;

		lll_aux = adv->lll.aux;

		/* Add sync_info into auxiliary PDU */
		err = ull_adv_aux_hdr_set_clear(adv,
						ULL_ADV_PDU_HDR_FIELD_SYNC_INFO,
						0U, value, &pri_idx, &sec_idx);
		if (err) {
			return err;
		}

		/* First byte in the length-value encoded parameter is size of
		 * sync_info structure, followed by pointer to sync_info in the
		 * PDU.
		 */
		(void)memcpy(&sync_info, &value[1], sizeof(sync_info));
		ull_adv_sync_info_fill(sync, sync_info);

		/* Calculate the ticks_slot and return slot overhead */
		ticks_slot_overhead = ull_adv_sync_evt_init(adv, sync, ter_pdu);

		/* If Auxiliary PDU already active, find and schedule Periodic
		 * advertising follow it.
		 */
		if (lll_aux) {
			/* Auxiliary set already active (due to other fields
			 * being already present or being started prior).
			 */
			aux = NULL;
			ticks_anchor_aux = 0U; /* unused in this path */
			ticks_slot_overhead_aux = 0U; /* unused in this path */

			/* Find the anchor after the group of active auxiliary
			 * sets such that Periodic Advertising events are placed
			 * in non-overlapping timeline when auxiliary and
			 * Periodic Advertising have similar event interval.
			 */
			ticks_anchor_sync = ticker_ticks_now_get() +
				HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);

#if defined(CONFIG_BT_CTLR_SCHED_ADVANCED)
			err = ull_sched_adv_aux_sync_free_anchor_get(sync->ull.ticks_slot,
								     &ticks_anchor_sync);
			if (!err) {
				ticks_anchor_sync += HAL_TICKER_US_TO_TICKS(
					MAX(EVENT_MAFS_US,
					    EVENT_OVERHEAD_START_US) -
					EVENT_OVERHEAD_START_US +
					(EVENT_TICKER_RES_MARGIN_US << 1));
			}
#endif /* CONFIG_BT_CTLR_SCHED_ADVANCED */

		} else {
			/* Auxiliary set will be started due to inclusion of
			 * sync info field.
			 */
			lll_aux = adv->lll.aux;
			aux = HDR_LLL2ULL(lll_aux);
			ticks_anchor_aux = ticker_ticks_now_get() +
				HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);
			ticks_slot_overhead_aux =
				ull_adv_aux_evt_init(aux, &ticks_anchor_aux);

#if !defined(CONFIG_BT_CTLR_ADV_AUX_SYNC_OFFSET) || \
	(CONFIG_BT_CTLR_ADV_AUX_SYNC_OFFSET == 0)
			ticks_anchor_sync = ticks_anchor_aux +
				ticks_slot_overhead_aux + aux->ull.ticks_slot +
				HAL_TICKER_US_TO_TICKS(
					MAX(EVENT_MAFS_US,
					    EVENT_OVERHEAD_START_US) -
					EVENT_OVERHEAD_START_US +
					(EVENT_TICKER_RES_MARGIN_US << 1));

#else /* CONFIG_BT_CTLR_ADV_AUX_SYNC_OFFSET */
			ticks_anchor_sync = ticks_anchor_aux +
				HAL_TICKER_US_TO_TICKS(
					CONFIG_BT_CTLR_ADV_AUX_SYNC_OFFSET);

#endif /* CONFIG_BT_CTLR_ADV_AUX_SYNC_OFFSET */
		}

		ret = ull_adv_sync_start(adv, sync, ticks_anchor_sync,
					 ticks_slot_overhead);
		if (ret) {
			sync_remove(sync, adv, 1U);

			return BT_HCI_ERR_INSUFFICIENT_RESOURCES;
		}

		sync->is_started = 1U;

		lll_adv_aux_data_enqueue(lll_aux, sec_idx);
		lll_adv_data_enqueue(&adv->lll, pri_idx);

		if (aux) {
			/* Keep aux interval equal or higher than primary PDU
			 * interval.
			 */
			aux->interval = adv->interval +
					(HAL_TICKER_TICKS_TO_US(
						ULL_ADV_RANDOM_DELAY) /
						ADV_INT_UNIT_US);

			ret = ull_adv_aux_start(aux, ticks_anchor_aux,
						ticks_slot_overhead_aux);
			if (ret) {
				sync_remove(sync, adv, 1U);

				return BT_HCI_ERR_INSUFFICIENT_RESOURCES;
			}

			aux->is_started = 1U;

		} else if (IS_ENABLED(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)) {
			/* notify the auxiliary set */
			ull_adv_sync_started_stopped(HDR_LLL2ULL(lll_aux));
		}
	}

	/* Commit the Periodic Advertising data if ADI supported and has been
	 * updated.
	 */
	if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT)) {
		lll_adv_sync_data_enqueue(lll_sync, ter_idx);
	}

	if (sync_got_enabled) {
		sync->is_enabled = sync_got_enabled;
	}

	return 0;
}

int ull_adv_sync_init(void)
{
	int err;

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

	return 0;
}

int ull_adv_sync_reset(void)
{
	struct lll_adv_sync *lll_sync;
	struct ll_adv_sync_set *sync;
	struct ll_adv_set *adv;
	uint8_t handle;
	int err;

	for (handle = 0U; handle < BT_CTLR_ADV_SET; handle++) {
		adv = ull_adv_is_created_get(handle);
		if (!adv) {
			continue;
		}

		lll_sync = adv->lll.sync;
		if (!lll_sync) {
			continue;
		}

		sync = HDR_LLL2ULL(lll_sync);

		if (!sync->is_started) {
			sync->is_enabled = 0U;

			continue;
		}

		err = sync_remove(sync, adv, 0U);
		if (err) {
			return err;
		}
	}

	return 0;
}

int ull_adv_sync_reset_finalize(void)
{
	int err;

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

	return 0;
}

struct ll_adv_sync_set *ull_adv_sync_get(uint8_t handle)
{
	if (handle >= CONFIG_BT_CTLR_ADV_SYNC_SET) {
		return NULL;
	}

	return &ll_adv_sync_pool[handle];
}

uint16_t ull_adv_sync_handle_get(const struct ll_adv_sync_set *sync)
{
	return sync_handle_get(sync);
}

uint16_t ull_adv_sync_lll_handle_get(const struct lll_adv_sync *lll)
{
	return sync_handle_get((void *)lll->hdr.parent);
}

void ull_adv_sync_release(struct ll_adv_sync_set *sync)
{
	lll_adv_sync_data_release(&sync->lll);
	sync_release(sync);
}

uint32_t ull_adv_sync_time_get(const struct ll_adv_sync_set *sync,
			       uint8_t pdu_len)
{
	const struct lll_adv_sync *lll_sync = &sync->lll;
	const struct lll_adv *lll = lll_sync->adv;
	uint32_t time_us;

	/* NOTE: 16-bit values are sufficient for minimum radio event time
	 *       reservation, 32-bit are used here so that reservations for
	 *       whole back-to-back chaining of PDUs can be accommodated where
	 *       the required microseconds could overflow 16-bits, example,
	 *       back-to-back chained Coded PHY PDUs.
	 */

	time_us = PDU_AC_US(pdu_len, lll->phy_s, lll->phy_flags) +
		  EVENT_OVERHEAD_START_US + EVENT_OVERHEAD_END_US;

#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
	struct ll_adv_set *adv = HDR_LLL2ULL(lll);
	struct lll_df_adv_cfg *df_cfg = adv->df_cfg;

	if (df_cfg && df_cfg->is_enabled) {
		time_us += CTE_LEN_US(df_cfg->cte_length);
	}
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */

	return time_us;
}

uint32_t ull_adv_sync_evt_init(struct ll_adv_set *adv,
			       struct ll_adv_sync_set *sync,
			       struct pdu_adv *pdu)
{
	uint32_t ticks_slot_overhead;
	uint32_t ticks_slot_offset;
	uint32_t time_us;

	ull_hdr_init(&sync->ull);

	if (!pdu) {
		pdu = lll_adv_sync_data_peek(&sync->lll, NULL);
	}

	time_us = sync_time_get(sync, pdu);

	/* TODO: active_to_start feature port */
	sync->ull.ticks_active_to_start = 0U;
	sync->ull.ticks_prepare_to_start =
		HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US);
	sync->ull.ticks_preempt_to_start =
		HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US);
	sync->ull.ticks_slot = HAL_TICKER_US_TO_TICKS(time_us);

	ticks_slot_offset = MAX(sync->ull.ticks_active_to_start,
				sync->ull.ticks_prepare_to_start);
	if (IS_ENABLED(CONFIG_BT_CTLR_LOW_LAT)) {
		ticks_slot_overhead = ticks_slot_offset;
	} else {
		ticks_slot_overhead = 0U;
	}

	return ticks_slot_overhead;
}

uint32_t ull_adv_sync_start(struct ll_adv_set *adv,
			    struct ll_adv_sync_set *sync,
			    uint32_t ticks_anchor,
			    uint32_t ticks_slot_overhead)
{
	uint32_t volatile ret_cb;
	uint32_t interval_us;
	uint8_t sync_handle;
	uint32_t ret;

	interval_us = (uint32_t)sync->interval * PERIODIC_INT_UNIT_US;

	sync_handle = sync_handle_get(sync);

#if defined(CONFIG_BT_CTLR_ADV_ISO) && \
	defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
	if (sync->lll.iso) {
		ll_adv_sync_ticker_ext[sync_handle].expire_info_id =
			TICKER_ID_ADV_ISO_BASE + sync->lll.iso->handle;
	} else {
		ll_adv_sync_ticker_ext[sync_handle].expire_info_id = TICKER_NULL;
	}

	ll_adv_sync_ticker_ext[sync_handle].ext_timeout_func = ticker_cb;

	ret_cb = TICKER_STATUS_BUSY;
	ret = ticker_start_ext(
#else /* !CONFIG_BT_CTLR_ADV_ISO || !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */

	ret_cb = TICKER_STATUS_BUSY;
	ret = ticker_start(
#endif /* !CONFIG_BT_CTLR_ADV_ISO || !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
			   TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_THREAD,
			   (TICKER_ID_ADV_SYNC_BASE + sync_handle),
			   ticks_anchor, 0U,
			   HAL_TICKER_US_TO_TICKS(interval_us),
			   HAL_TICKER_REMAINDER(interval_us), TICKER_NULL_LAZY,
			   (sync->ull.ticks_slot + ticks_slot_overhead),
			   ticker_cb, sync,
			   ull_ticker_status_give, (void *)&ret_cb
#if defined(CONFIG_BT_CTLR_ADV_ISO) && \
	defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
			   ,
			   &ll_adv_sync_ticker_ext[sync_handle]
#endif /* !CONFIG_BT_CTLR_ADV_ISO || !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
			   );
	ret = ull_ticker_status_take(ret, &ret_cb);

	return ret;
}

uint8_t ull_adv_sync_time_update(struct ll_adv_sync_set *sync,
				 struct pdu_adv *pdu)
{
	uint32_t volatile ret_cb;
	uint32_t ticks_minus;
	uint32_t ticks_plus;
	uint32_t time_ticks;
	uint32_t time_us;
	uint32_t ret;

	time_us = sync_time_get(sync, pdu);
	time_ticks = HAL_TICKER_US_TO_TICKS(time_us);
	if (sync->ull.ticks_slot > time_ticks) {
		ticks_minus = sync->ull.ticks_slot - time_ticks;
		ticks_plus = 0U;
	} else if (sync->ull.ticks_slot < time_ticks) {
		ticks_minus = 0U;
		ticks_plus = time_ticks - sync->ull.ticks_slot;
	} else {
		return BT_HCI_ERR_SUCCESS;
	}

	ret_cb = TICKER_STATUS_BUSY;
	ret = ticker_update(TICKER_INSTANCE_ID_CTLR,
			    TICKER_USER_ID_THREAD,
			    (TICKER_ID_ADV_SYNC_BASE + sync_handle_get(sync)),
			    0, 0, ticks_plus, ticks_minus, 0, 0,
			    ull_ticker_status_give, (void *)&ret_cb);
	ret = ull_ticker_status_take(ret, &ret_cb);
	if (ret != TICKER_STATUS_SUCCESS) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}

	sync->ull.ticks_slot = time_ticks;

	return BT_HCI_ERR_SUCCESS;
}

uint8_t ull_adv_sync_chm_update(void)
{
	uint8_t handle;

	handle = CONFIG_BT_CTLR_ADV_SYNC_SET;
	while (handle--) {
		(void)sync_chm_update(handle);
	}

	/* TODO: Should failure due to Channel Map Update being already in
	 *       progress be returned to caller?
	 */
	return 0;
}

void ull_adv_sync_chm_complete(struct node_rx_hdr *rx)
{
	uint8_t hdr_data[ULL_ADV_HDR_DATA_LEN_SIZE +
			 ULL_ADV_HDR_DATA_ACAD_PTR_SIZE];
	struct lll_adv_sync *lll_sync;
	struct pdu_adv *pdu_prev;
	struct ll_adv_set *adv;
	struct pdu_adv *pdu;
	uint8_t others_len;
	uint8_t acad_len;
	uint8_t *others;
	uint8_t ter_idx;
	uint8_t ad_len;
	uint8_t *acad;
	uint8_t *ad;
	uint8_t len;
	uint8_t err;

	/* Allocate next Sync PDU */
	pdu_prev = NULL;
	pdu = NULL;
	lll_sync = rx->rx_ftr.param;
	adv = HDR_LLL2ULL(lll_sync->adv);
	err = ull_adv_sync_pdu_alloc(adv, ULL_ADV_PDU_EXTRA_DATA_ALLOC_IF_EXIST,
				     &pdu_prev, &pdu, NULL, NULL, &ter_idx);
	LL_ASSERT(!err);

	/* Get the size of current ACAD, first octet returns the old length and
	 * followed by pointer to previous offset to ACAD in the PDU.
	 */
	hdr_data[ULL_ADV_HDR_DATA_LEN_OFFSET] = 0U;
	err = ull_adv_sync_pdu_set_clear(lll_sync, pdu_prev, pdu,
					 ULL_ADV_PDU_HDR_FIELD_ACAD, 0U,
					 &hdr_data);
	LL_ASSERT(!err);

	/* Dev assert if ACAD empty */
	LL_ASSERT(hdr_data[ULL_ADV_HDR_DATA_LEN_OFFSET]);

	/* Get the pointer, prev content and size of current ACAD */
	err = ull_adv_sync_pdu_set_clear(lll_sync, pdu_prev, pdu,
					 ULL_ADV_PDU_HDR_FIELD_ACAD, 0U,
					 &hdr_data);
	LL_ASSERT(!err);

	/* Find the Channel Map Update Indication */
	acad_len = hdr_data[ULL_ADV_HDR_DATA_LEN_OFFSET];
	len = acad_len;
	(void)memcpy(&acad, &hdr_data[ULL_ADV_HDR_DATA_ACAD_PTR_OFFSET],
		     sizeof(acad));
	ad = acad;
	do {
		ad_len = ad[PDU_ADV_DATA_HEADER_LEN_OFFSET];
		if (ad_len &&
		    (ad[PDU_ADV_DATA_HEADER_TYPE_OFFSET] ==
		     BT_DATA_CHANNEL_MAP_UPDATE_IND)) {
			break;
		}

		ad_len += 1U;

		LL_ASSERT(ad_len <= len);

		ad += ad_len;
		len -= ad_len;
	} while (len);
	LL_ASSERT(len);

	/* Remove Channel Map Update Indication by moving other AD types that
	 * are after it.
	 */
	ad_len += 1U;
	others = ad + ad_len;
	acad_len -= ad_len;
	others_len = acad_len - (ad - acad);
	(void)memmove(ad, others, others_len);

	/* Adjust the next PDU for ACAD length, this is done by using the next
	 * PDU to copy ACAD into same next PDU.
	 */
	hdr_data[ULL_ADV_HDR_DATA_LEN_OFFSET] = acad_len;
	err = ull_adv_sync_pdu_set_clear(lll_sync, pdu, pdu,
					 ULL_ADV_PDU_HDR_FIELD_ACAD, 0U,
					 &hdr_data);
	LL_ASSERT(!err);

	lll_adv_sync_data_enqueue(lll_sync, ter_idx);
}

void ull_adv_sync_info_fill(struct ll_adv_sync_set *sync,
			    struct pdu_adv_sync_info *si)
{
	struct lll_adv_sync *lll_sync;

	/* NOTE: sync offset and offset unit filled by secondary prepare.
	 *
	 * If sync_info is part of ADV PDU the offs_adjust field
	 * is always set to 0.
	 */
	si->offs_units = OFFS_UNIT_VALUE_30_US;
	si->offs_adjust = 0U;
	si->offs = 0U;

	/* Fill the interval, access address and CRC init */
	si->interval = sys_cpu_to_le16(sync->interval);
	lll_sync = &sync->lll;
	(void)memcpy(&si->aa, lll_sync->access_addr, sizeof(si->aa));
	(void)memcpy(si->crc_init, lll_sync->crc_init, sizeof(si->crc_init));

	/* NOTE: Filled by secondary prepare */
	si->evt_cntr = 0U;
}

#if !defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
void ull_adv_sync_offset_get(struct ll_adv_set *adv)
{
	static memq_link_t link;
	static struct mayfly mfy = {0, 0, &link, NULL, mfy_sync_offset_get};
	uint32_t ret;

	mfy.param = adv;
	ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH, TICKER_USER_ID_ULL_LOW, 1,
			     &mfy);
	LL_ASSERT(!ret);
}
#endif /* CONFIG_BT_TICKER_EXT_EXPIRE_INFO */

void ull_adv_sync_pdu_init(struct pdu_adv *pdu, uint8_t ext_hdr_flags,
			   uint8_t phy_s, uint8_t phy_flags,
			   struct pdu_cte_info *cte_info)
{
	struct pdu_adv_com_ext_adv *com_hdr;
	struct pdu_adv_ext_hdr *ext_hdr;
	struct pdu_adv_aux_ptr *aux_ptr;
	uint32_t cte_len_us;
	uint8_t *dptr;
	uint8_t len;

	pdu->type = PDU_ADV_TYPE_AUX_SYNC_IND;
	pdu->rfu = 0U;
	pdu->chan_sel = 0U;

	pdu->tx_addr = 0U;
	pdu->rx_addr = 0U;

	com_hdr = &pdu->adv_ext_ind;
	/* Non-connectable and Non-scannable adv mode */
	com_hdr->adv_mode = 0U;

	ext_hdr = &com_hdr->ext_hdr;
	*(uint8_t *)ext_hdr = ext_hdr_flags;
	dptr = ext_hdr->data;

	LL_ASSERT(!(ext_hdr_flags & (ULL_ADV_PDU_HDR_FIELD_ADVA | ULL_ADV_PDU_HDR_FIELD_TARGETA |
#if !defined(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT)
				     ULL_ADV_PDU_HDR_FIELD_ADI |
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT */
				     ULL_ADV_PDU_HDR_FIELD_SYNC_INFO)));

	if (IS_ENABLED(CONFIG_BT_CTLR_DF_ADV_CTE_TX) &&
	    (ext_hdr_flags & ULL_ADV_PDU_HDR_FIELD_CTE_INFO)) {
		(void)memcpy(dptr, cte_info, sizeof(*cte_info));
		cte_len_us = CTE_LEN_US(cte_info->time);
		dptr += sizeof(struct pdu_cte_info);
	} else {
		cte_len_us = 0U;
	}
	if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC_ADI_SUPPORT) &&
	    (ext_hdr_flags & ULL_ADV_PDU_HDR_FIELD_ADI)) {
		dptr += sizeof(struct pdu_adv_adi);
	}
	if (IS_ENABLED(CONFIG_BT_CTLR_ADV_SYNC_PDU_LINK) &&
	    (ext_hdr_flags & ULL_ADV_PDU_HDR_FIELD_AUX_PTR)) {
		aux_ptr = (void *)dptr;
		dptr += sizeof(struct pdu_adv_aux_ptr);
	}
	if (ext_hdr_flags & ULL_ADV_PDU_HDR_FIELD_TX_POWER) {
		dptr += sizeof(uint8_t);
	}

	/* Calc tertiary PDU len */
	len = ull_adv_aux_hdr_len_calc(com_hdr, &dptr);
	ull_adv_aux_hdr_len_fill(com_hdr, len);

	pdu->len = len;

#if defined(CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK)
	/* Fill aux offset in aux pointer field */
	if (ext_hdr_flags & ULL_ADV_PDU_HDR_FIELD_AUX_PTR) {
		uint32_t offs_us;

		offs_us = PDU_AC_US(pdu->len, phy_s, phy_flags) +
			  EVENT_SYNC_B2B_MAFS_US;
		offs_us += cte_len_us;
		ull_adv_aux_ptr_fill(aux_ptr, offs_us, phy_s);
	}
#endif /* CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK */
}

uint8_t ull_adv_sync_pdu_alloc(struct ll_adv_set *adv,
			       enum ull_adv_pdu_extra_data_flag extra_data_flag,
			       struct pdu_adv **ter_pdu_prev, struct pdu_adv **ter_pdu_new,
			       void **extra_data_prev, void **extra_data_new, uint8_t *ter_idx)
{
	struct pdu_adv *pdu_prev, *pdu_new;
	struct lll_adv_sync *lll_sync;
	void *ed_prev;
#if defined(CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY)
	void *ed_new;
#endif

	lll_sync = adv->lll.sync;
	if (!lll_sync) {
		return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
	}

	/* Get reference to previous periodic advertising PDU data */
	pdu_prev = lll_adv_sync_data_peek(lll_sync, &ed_prev);

#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
	/* Get reference to new periodic advertising PDU data buffer */
	if (extra_data_flag == ULL_ADV_PDU_EXTRA_DATA_ALLOC_ALWAYS ||
	    (extra_data_flag == ULL_ADV_PDU_EXTRA_DATA_ALLOC_IF_EXIST && ed_prev)) {
		/* If there was an extra data in past PDU data or it is required
		 * by the hdr_add_fields then allocate memmory for it.
		 */
		pdu_new = lll_adv_sync_data_alloc(lll_sync, &ed_new,
						  ter_idx);
		if (!pdu_new) {
			return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
		}
	} else {
		ed_new = NULL;
#else
	{
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
		pdu_new = lll_adv_sync_data_alloc(lll_sync, NULL, ter_idx);
		if (!pdu_new) {
			return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
		}
	}

#if defined(CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY)
	if (extra_data_prev) {
		*extra_data_prev = ed_prev;
	}
	if (extra_data_new) {
		*extra_data_new = ed_new;
	}
#endif /* CONFIG_BT_CTLR_ADV_EXT_PDU_EXTRA_DATA_MEMORY */

	*ter_pdu_prev = pdu_prev;
	*ter_pdu_new = pdu_new;

	return 0;
}

/* @brief Set or clear fields in extended advertising header and store
 *        extra_data if requested.
 *
 * @param[in]  lll_sync         Reference to periodic advertising sync.
 * @param[in]  ter_pdu_prev     Pointer to previous PDU.
 * @param[in]  ter_pdu_         Pointer to PDU to fill fields.
 * @param[in]  hdr_add_fields   Flag with information which fields add.
 * @param[in]  hdr_rem_fields   Flag with information which fields remove.
 * @param[in]  hdr_data         Pointer to data to be added to header. Content
 *                              depends on the value of @p hdr_add_fields.
 *
 * @Note
 * @p hdr_data content depends on the flag provided by @p hdr_add_fields:
 * - ULL_ADV_PDU_HDR_FIELD_CTE_INFO:
 *   # @p hdr_data points to single byte with CTEInfo field
 * - ULL_ADV_PDU_HDR_FIELD_ADI:
 *   # @p hdr_data points to memory where first byte is size of ADI structure,
 *     following bytes are the pointer reference to the new ADI structure to be
 *     updated in the PDU.
 *     In return, the first byte returns the size of ADI structure, following
 *     bytes returns the pointer reference to ADI structure offset inside the
 *     updated current PDU.
 * - ULL_ADV_PDU_HDR_FIELD_AD_DATA:
 *   # @p hdr_data points to memory where first byte
 *     is size of advertising data, following byte is a pointer to actual
 *     advertising data.
 * - ULL_ADV_PDU_HDR_FIELD_AUX_PTR:
 *   # @p hdr_data points to memory where first byte is size of aux ptr
 *     structure, following bytes are the pointer reference to the new aux ptr
 *     structure to be updated in the PDU.
 *     In return, the first byte returns the size of aux ptr structure,
 *     following bytes returns the pointer reference to aux ptr structure offset
 *     inside the updated current PDU.
 * - ULL_ADV_PDU_HDR_FIELD_ACAD:
 *   # @p hdr_data points to memory where first byte is size of ACAD, second
 *     byte is used to return offset to ACAD field.
 *   # @p hdr_data memory returns previous ACAD length back in the first byte
 *     and offset to new ACAD in the next PDU.
 *
 * @return Zero in case of success, other value in case of failure.
 */
uint8_t ull_adv_sync_pdu_set_clear(struct lll_adv_sync *lll_sync,
				   struct pdu_adv *ter_pdu_prev,
				   struct pdu_adv *ter_pdu,
				   uint16_t hdr_add_fields,
				   uint16_t hdr_rem_fields,
				   void *hdr_data)
{
	struct pdu_adv_com_ext_adv *ter_com_hdr, *ter_com_hdr_prev;
	struct pdu_adv_ext_hdr ter_hdr = { 0 }, ter_hdr_prev = { 0 };
	struct pdu_adv_aux_ptr *aux_ptr, *aux_ptr_prev;
	uint8_t *ter_dptr, *ter_dptr_prev;
	struct pdu_adv_adi *adi;
	uint8_t acad_len_prev;
	uint8_t ter_len_prev;
	uint8_t hdr_buf_len;
	uint16_t ter_len;
	uint8_t *ad_data;
	uint8_t acad_len;
#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
	uint8_t cte_info;
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
	uint8_t ad_len;

	/* Get common pointers from reference to previous tertiary PDU data */
	ter_com_hdr_prev = (void *)&ter_pdu_prev->adv_ext_ind;
	if (ter_com_hdr_prev->ext_hdr_len != 0) {
		ter_hdr_prev = ter_com_hdr_prev->ext_hdr;
	}
	ter_dptr_prev = ter_com_hdr_prev->ext_hdr.data;

	/* Set common fields in reference to new tertiary PDU data buffer */
	ter_pdu->type = ter_pdu_prev->type;
	ter_pdu->rfu = 0U;
	ter_pdu->chan_sel = 0U;

	ter_pdu->tx_addr = ter_pdu_prev->tx_addr;
	ter_pdu->rx_addr = ter_pdu_prev->rx_addr;

	/* Get common pointers from current tertiary PDU data.
	 * It is possible that the current tertiary is the same as
	 * previous one. It may happen if update periodic advertising
	 * chain in place.
	 */
	ter_com_hdr = (void *)&ter_pdu->adv_ext_ind;
	ter_com_hdr->adv_mode = ter_com_hdr_prev->adv_mode;
	ter_dptr = ter_com_hdr->ext_hdr.data;

	/* No AdvA in AUX_SYNC_IND */
	/* No TargetA in AUX_SYNC_IND */

#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
	/* If requested add or update CTEInfo */
	if (hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_CTE_INFO) {
		ter_hdr.cte_info = 1;
		cte_info = *(uint8_t *)hdr_data;
		hdr_data = (uint8_t *)hdr_data + 1;
		ter_dptr += sizeof(struct pdu_cte_info);
	/* If CTEInfo exists in prev and is not requested to be removed */
	} else if (!(hdr_rem_fields & ULL_ADV_PDU_HDR_FIELD_CTE_INFO) &&
		   ter_hdr_prev.cte_info) {
		ter_hdr.cte_info = 1;
		cte_info = 0U; /* value not used, will be read from prev PDU */
		ter_dptr += sizeof(struct pdu_cte_info);
	} else {
		cte_info = 0U; /* value not used */
	}

	/* If CTEInfo exists in prev PDU */
	if (ter_hdr_prev.cte_info) {
		ter_dptr_prev += sizeof(struct pdu_cte_info);
	}
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */

	/* ADI */
	if (hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_ADI) {
		ter_hdr.adi = 1U;
		/* return the size of ADI structure */
		*(uint8_t *)hdr_data = sizeof(struct pdu_adv_adi);
		hdr_data = (uint8_t *)hdr_data + sizeof(uint8_t);
		/* pick the reference to ADI param */
		(void)memcpy(&adi, hdr_data, sizeof(struct pdu_adv_adi *));
		/* return the pointer to ADI struct inside the PDU */
		(void)memcpy(hdr_data, &ter_dptr, sizeof(ter_dptr));
		hdr_data = (uint8_t *)hdr_data + sizeof(ter_dptr);
		ter_dptr += sizeof(struct pdu_adv_adi);
	} else if (!(hdr_rem_fields & ULL_ADV_PDU_HDR_FIELD_ADI) &&
		   ter_hdr_prev.adi) {
		ter_hdr.adi = 1U;
		adi = NULL;
		ter_dptr += sizeof(struct pdu_adv_adi);
	} else {
		adi = NULL;
	}
	if (ter_hdr_prev.adi) {
		ter_dptr_prev += sizeof(struct pdu_adv_adi);
	}

	/* AuxPtr - will be added if AUX_CHAIN_IND is required */
	if (hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_AUX_PTR) {
		ter_hdr.aux_ptr = 1;
		aux_ptr_prev = NULL;
		aux_ptr = (void *)ter_dptr;

		/* return the size of aux pointer structure */
		*(uint8_t *)hdr_data = sizeof(struct pdu_adv_aux_ptr);
		hdr_data = (uint8_t *)hdr_data + sizeof(uint8_t);

		/* return the pointer to aux pointer struct inside the PDU
		 * buffer
		 */
		(void)memcpy(hdr_data, &ter_dptr, sizeof(ter_dptr));
		hdr_data = (uint8_t *)hdr_data + sizeof(ter_dptr);
	} else if (!(hdr_rem_fields & ULL_ADV_PDU_HDR_FIELD_AUX_PTR) &&
		   ter_hdr_prev.aux_ptr) {
		ter_hdr.aux_ptr = 1;
		aux_ptr_prev = (void *)ter_dptr_prev;
		aux_ptr = (void *)ter_dptr;
	} else {
		aux_ptr_prev = NULL;
		aux_ptr = NULL;
	}
	if (ter_hdr_prev.aux_ptr) {
		ter_dptr_prev += sizeof(struct pdu_adv_aux_ptr);
	}
	if (ter_hdr.aux_ptr) {
		ter_dptr += sizeof(struct pdu_adv_aux_ptr);
	}

	/* No SyncInfo in AUX_SYNC_IND */

	/* Tx Power flag */
	if (ter_hdr_prev.tx_pwr) {
		ter_dptr_prev++;

		ter_hdr.tx_pwr = 1;
		ter_dptr++;
	}

	/* Calc previous ACAD len and update PDU len */
	ter_len_prev = ter_dptr_prev - (uint8_t *)ter_com_hdr_prev;
	hdr_buf_len = ter_com_hdr_prev->ext_hdr_len +
		      PDU_AC_EXT_HEADER_SIZE_MIN;
	if (ter_len_prev <= hdr_buf_len) {
		/* There are some data, except ACAD, in extended header if ter_len_prev
		 * equals to hdr_buf_len. There is ACAD if the size of ter_len_prev
		 * is smaller than hdr_buf_len.
		 */
		acad_len_prev = hdr_buf_len - ter_len_prev;
		ter_len_prev += acad_len_prev;
		ter_dptr_prev += acad_len_prev;
	} else {
		/* There are no data in extended header, all flags are zeros. */
		acad_len_prev = 0;
		/* NOTE: If no flags are set then extended header length will be
		 *       zero. Under this condition the current ter_len_prev
		 *       value will be greater than extended header length,
		 *       hence set ter_len_prev to size of the length/mode
		 *       field.
		 */
		ter_len_prev = PDU_AC_EXT_HEADER_SIZE_MIN;
		ter_dptr_prev = (uint8_t *)ter_com_hdr_prev + ter_len_prev;
	}

	/* Did we parse beyond PDU length? */
	if (ter_len_prev > ter_pdu_prev->len) {
		/* we should not encounter invalid length */
		return BT_HCI_ERR_UNSPECIFIED;
	}

	/* Add/Retain/Remove ACAD */
	if (hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_ACAD) {
		acad_len = *(uint8_t *)hdr_data;
		/* If zero length ACAD then do not reduce ACAD but return
		 * return previous ACAD length.
		 */
		if (!acad_len) {
			acad_len = acad_len_prev;
		}
		/* return prev ACAD length */
		*(uint8_t *)hdr_data = acad_len_prev;
		hdr_data = (uint8_t *)hdr_data + 1;
		/* return the pointer to ACAD offset */
		(void)memcpy(hdr_data, &ter_dptr, sizeof(ter_dptr));
		hdr_data = (uint8_t *)hdr_data + sizeof(ter_dptr);
		ter_dptr += acad_len;
	} else if (!(hdr_rem_fields & ULL_ADV_PDU_HDR_FIELD_ACAD)) {
		acad_len = acad_len_prev;
		ter_dptr += acad_len_prev;
	} else {
		acad_len = 0U;
	}

	/* Calc current tertiary PDU len so far without AD data added */
	ter_len = ull_adv_aux_hdr_len_calc(ter_com_hdr, &ter_dptr);

	/* Get Adv data from function parameters */
	if (hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_AD_DATA) {
		uint8_t ad_len_prev;

		/* remember the new ad data len */
		ad_len = *(uint8_t *)hdr_data;

		/* return prev ad data length */
		ad_len_prev = ter_pdu_prev->len - ter_len_prev;
		*(uint8_t *)hdr_data = ad_len_prev;
		hdr_data = (uint8_t *)hdr_data + sizeof(ad_len);

		/* remember the reference to new ad data */
		(void)memcpy(&ad_data, hdr_data, sizeof(ad_data));

		/* return the reference to prev ad data */
		(void)memcpy(hdr_data, &ter_dptr_prev, sizeof(ter_dptr_prev));
		hdr_data = (uint8_t *)hdr_data + sizeof(ter_dptr_prev);

		/* unchanged data */
		if (!ad_len && !ad_data) {
			ad_len = ad_len_prev;
			ad_data = ter_dptr_prev;
		}
	} else if (!(hdr_rem_fields & ULL_ADV_PDU_HDR_FIELD_AD_DATA)) {
		ad_len = ter_pdu_prev->len - ter_len_prev;
		ad_data = ter_dptr_prev;
	} else {
		ad_len = 0;
		ad_data = NULL;
	}

	/* Check Max Advertising Data Length */
	if (ad_len > CONFIG_BT_CTLR_ADV_DATA_LEN_MAX) {
		return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
	}

	/* Check AdvData overflow */
	if ((ter_len + ad_len) > PDU_AC_PAYLOAD_SIZE_MAX) {
		/* return excess length */
		*(uint8_t *)hdr_data = ter_len + ad_len -
				       PDU_AC_PAYLOAD_SIZE_MAX;

		/* Will use packet too long error to determine fragmenting
		 * long data
		 */
		return BT_HCI_ERR_PACKET_TOO_LONG;
	}

	/* set the tertiary extended header and PDU length */
	ull_adv_aux_hdr_len_fill(ter_com_hdr, ter_len);
	ter_pdu->len = ter_len + ad_len;

	/* Start filling tertiary PDU payload based on flags from here
	 * ==============================================================
	 */

	/* Fill AdvData in tertiary PDU */
	(void)memmove(ter_dptr, ad_data, ad_len);

	/* Early exit if no flags set */
	if (!ter_com_hdr->ext_hdr_len) {
		return 0;
	}

	/* Retain ACAD in tertiary PDU */
	ter_dptr_prev -= acad_len_prev;
	if (acad_len) {
		ter_dptr -= acad_len;
		(void)memmove(ter_dptr, ter_dptr_prev, acad_len_prev);
	}

	/* Tx Power */
	if (ter_hdr.tx_pwr) {
		*--ter_dptr = *--ter_dptr_prev;
	}

	/* No SyncInfo in AUX_SYNC_IND */

	/* AuxPtr */
	if (ter_hdr_prev.aux_ptr) {
		ter_dptr_prev -= sizeof(struct pdu_adv_aux_ptr);
	}
	if (ter_hdr.aux_ptr) {
		ter_dptr -= sizeof(struct pdu_adv_aux_ptr);
	}
	if (aux_ptr_prev) {
		(void)memmove(ter_dptr, aux_ptr_prev, sizeof(*aux_ptr_prev));
	}

	/* ADI */
	if (ter_hdr_prev.adi) {
		ter_dptr_prev -= sizeof(struct pdu_adv_adi);
	}
	if (ter_hdr.adi) {
		struct pdu_adv_adi *adi_pdu;

		ter_dptr -= sizeof(struct pdu_adv_adi);
		adi_pdu = (void *)ter_dptr;

		if (!adi) {
			struct ll_adv_set *adv;

			adv = HDR_LLL2ULL(lll_sync->adv);

			/* The DID for a specific SID shall be unique.
			 */
			const uint16_t did =
				sys_cpu_to_le16(ull_adv_aux_did_next_unique_get(adv->sid));
			PDU_ADV_ADI_DID_SID_SET(adi_pdu, did, adv->sid);
		} else {
			adi_pdu->did_sid_packed[0] = adi->did_sid_packed[0];
			adi_pdu->did_sid_packed[1] = adi->did_sid_packed[1];
		}
	}

#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
	if (ter_hdr.cte_info) {
		if (hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_CTE_INFO) {
			*--ter_dptr = cte_info;
		} else {
			*--ter_dptr = *--ter_dptr_prev;
		}
	}
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */

	/* No TargetA in AUX_SYNC_IND */
	/* No AdvA in AUX_SYNC_IND */

	if (ter_com_hdr->ext_hdr_len != 0) {
		ter_com_hdr->ext_hdr = ter_hdr;
	}

	return 0;
}

#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
/* @brief Set or clear fields in extended advertising header and store
 *        extra_data if requested.
 *
 * @param[in]  extra_data_prev  Pointer to previous content of extra_data.
 * @param[in]  hdr_add_fields   Flag with information which fields add.
 * @param[in]  hdr_rem_fields   Flag with information which fields remove.
 * @param[in]  data             Pointer to data to be stored in extra_data.
 *                              Content depends on the data depends on
 *                              @p hdr_add_fields.
 *
 * @Note
 * @p data depends on the flag provided by @p hdr_add_fields.
 * Information about content of value may be found in description of
 * @ref ull_adv_sync_pdu_set_clear.
 *
 * @return Zero in case of success, other value in case of failure.
 */
void ull_adv_sync_extra_data_set_clear(void *extra_data_prev,
				       void *extra_data_new,
				       uint16_t hdr_add_fields,
				       uint16_t hdr_rem_fields,
				       void *data)
{
	/* Currently only CTE enable requires extra_data. Due to that fact
	 * CTE additional data are just copied to extra_data memory.
	 */
	if (hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_CTE_INFO) {
		(void)memcpy(extra_data_new, data, sizeof(struct lll_df_adv_cfg));
	} else if (!(hdr_rem_fields & ULL_ADV_PDU_HDR_FIELD_CTE_INFO) ||
		   extra_data_prev) {
		(void)memmove(extra_data_new, extra_data_prev,
			      sizeof(struct lll_df_adv_cfg));
	}
}
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */

static int init_reset(void)
{
	/* Initialize adv sync pool. */
	mem_init(ll_adv_sync_pool, sizeof(struct ll_adv_sync_set),
		 sizeof(ll_adv_sync_pool) / sizeof(struct ll_adv_sync_set),
		 &adv_sync_free);

	return 0;
}

static uint8_t adv_type_check(struct ll_adv_set *adv)
{
	struct pdu_adv_com_ext_adv *pri_com_hdr;
	struct pdu_adv_ext_hdr *pri_hdr;
	struct pdu_adv *pri_pdu;

	pri_pdu = lll_adv_data_latest_peek(&adv->lll);
	if (pri_pdu->type != PDU_ADV_TYPE_EXT_IND) {
		return BT_HCI_ERR_INVALID_PARAM;
	}

	pri_com_hdr = (void *)&pri_pdu->adv_ext_ind;
	if (pri_com_hdr->adv_mode != 0U) {
		return BT_HCI_ERR_INVALID_PARAM;
	}

	pri_hdr = (void *)pri_com_hdr->ext_hdr_adv_data;
	if (pri_hdr->aux_ptr) {
		struct pdu_adv_com_ext_adv *sec_com_hdr;
		struct pdu_adv_ext_hdr *sec_hdr;
		struct pdu_adv *sec_pdu;

		sec_pdu = lll_adv_aux_data_latest_peek(adv->lll.aux);
		sec_com_hdr = (void *)&sec_pdu->adv_ext_ind;
		sec_hdr = (void *)sec_com_hdr->ext_hdr_adv_data;
		if (!pri_hdr->adv_addr && !sec_hdr->adv_addr) {
			return BT_HCI_ERR_INVALID_PARAM;
		}
	} else if (!pri_hdr->adv_addr) {
		return BT_HCI_ERR_INVALID_PARAM;
	}

	return 0;
}

static inline struct ll_adv_sync_set *sync_acquire(void)
{
	return mem_acquire(&adv_sync_free);
}

static inline void sync_release(struct ll_adv_sync_set *sync)
{
	mem_release(sync, &adv_sync_free);
}

static inline uint16_t sync_handle_get(const struct ll_adv_sync_set *sync)
{
	return mem_index_get(sync, ll_adv_sync_pool,
			     sizeof(struct ll_adv_sync_set));
}

static uint32_t sync_time_get(const struct ll_adv_sync_set *sync,
			      const struct pdu_adv *pdu)
{
	uint8_t len;

	/* Calculate the PDU Tx Time and hence the radio event length,
	 * Always use maximum length for common extended header format so that
	 * ACAD could be update when periodic advertising is active and the
	 * time reservation need not be updated everytime avoiding overlapping
	 * with other active states/roles.
	 */
	len = pdu->len - pdu->adv_ext_ind.ext_hdr_len -
	      PDU_AC_EXT_HEADER_SIZE_MIN + PDU_AC_EXT_HEADER_SIZE_MAX;

	return ull_adv_sync_time_get(sync, len);
}

static uint8_t sync_stop(struct ll_adv_sync_set *sync)
{
	uint8_t sync_handle;
	int err;

	sync_handle = sync_handle_get(sync);

	err = ull_ticker_stop_with_mark(TICKER_ID_ADV_SYNC_BASE + sync_handle,
					sync, &sync->lll);
	LL_ASSERT(err == 0 || err == -EALREADY);
	if (err) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}

	return 0;
}

static inline uint8_t sync_remove(struct ll_adv_sync_set *sync,
				  struct ll_adv_set *adv, uint8_t enable)
{
	uint8_t pri_idx;
	uint8_t sec_idx;
	uint8_t err;

	/* Remove sync_info from auxiliary PDU */
	err = ull_adv_aux_hdr_set_clear(adv, 0U,
					ULL_ADV_PDU_HDR_FIELD_SYNC_INFO, NULL,
					&pri_idx, &sec_idx);
	if (err) {
		return err;
	}

	lll_adv_aux_data_enqueue(adv->lll.aux, sec_idx);
	lll_adv_data_enqueue(&adv->lll, pri_idx);

	if (sync->is_started) {
		/* TODO: we removed sync info, but if sync_stop() fails, what do
		 * we do?
		 */
		err = sync_stop(sync);
		if (err) {
			return err;
		}

		sync->is_started = 0U;

#if defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
		if (adv->lll.aux) {
			/* notify the auxiliary set */
			ull_adv_sync_started_stopped(HDR_LLL2ULL(adv->lll.aux));
		}
#endif /* CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
	}

	if (!enable) {
		sync->is_enabled = 0U;
	}

	return 0U;
}

static uint8_t sync_chm_update(uint8_t handle)
{
	uint8_t hdr_data[ULL_ADV_HDR_DATA_LEN_SIZE +
			 ULL_ADV_HDR_DATA_ACAD_PTR_SIZE];
	struct pdu_adv_sync_chm_upd_ind *chm_upd_ind;
	struct lll_adv_sync *lll_sync;
	struct pdu_adv *pdu_prev;
	struct ll_adv_set *adv;
	uint8_t acad_len_prev;
	struct pdu_adv *pdu;
	uint16_t instant;
	uint8_t chm_last;
	uint8_t ter_idx;
	uint8_t *acad;
	uint8_t err;

	/* Check for valid advertising instance */
	adv = ull_adv_is_created_get(handle);
	if (!adv) {
		return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
	}

	/* Check for valid periodic advertising */
	lll_sync = adv->lll.sync;
	if (!lll_sync) {
		return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
	}

	/* Fail if already in progress */
	if (lll_sync->chm_last != lll_sync->chm_first) {
		return BT_HCI_ERR_CMD_DISALLOWED;
	}

	/* Allocate next Sync PDU */
	err = ull_adv_sync_pdu_alloc(adv, ULL_ADV_PDU_EXTRA_DATA_ALLOC_IF_EXIST,
				     &pdu_prev, &pdu, NULL, NULL, &ter_idx);
	if (err) {
		return err;
	}

	/* Try to allocate ACAD for channel map update indication, previous
	 * ACAD length with be returned back.
	 */
	hdr_data[ULL_ADV_HDR_DATA_LEN_OFFSET] = sizeof(*chm_upd_ind) + 2U;
	err = ull_adv_sync_pdu_set_clear(lll_sync, pdu_prev, pdu,
					 ULL_ADV_PDU_HDR_FIELD_ACAD, 0U,
					 &hdr_data);
	if (err) {
		return err;
	}

	/* Check if there are other ACAD data previously */
	acad_len_prev = hdr_data[ULL_ADV_HDR_DATA_LEN_OFFSET];
	if (acad_len_prev) {
		/* Append to end of other ACAD already present */
		hdr_data[ULL_ADV_HDR_DATA_LEN_OFFSET] = acad_len_prev +
							sizeof(*chm_upd_ind) +
							2U;

		err = ull_adv_sync_pdu_set_clear(lll_sync, pdu_prev, pdu,
						 ULL_ADV_PDU_HDR_FIELD_ACAD, 0U,
						 &hdr_data);
		if (err) {
			return err;
		}
	}

	/* Populate the AD data length and opcode */
	(void)memcpy(&acad, &hdr_data[ULL_ADV_HDR_DATA_ACAD_PTR_OFFSET],
		     sizeof(acad));
	acad += acad_len_prev;
	acad[PDU_ADV_DATA_HEADER_LEN_OFFSET] = sizeof(*chm_upd_ind) + 1U;
	acad[PDU_ADV_DATA_HEADER_TYPE_OFFSET] = BT_DATA_CHANNEL_MAP_UPDATE_IND;

	/* Populate the Channel Map Indication structure */
	chm_upd_ind = (void *)&acad[PDU_ADV_DATA_HEADER_DATA_OFFSET];
	(void)ull_chan_map_get(chm_upd_ind->chm);
	instant = lll_sync->event_counter + 6U;
	chm_upd_ind->instant = sys_cpu_to_le16(instant);

	/* Update the LLL to reflect the Channel Map and Instant to use */
	chm_last = lll_sync->chm_last + 1;
	if (chm_last == DOUBLE_BUFFER_SIZE) {
		chm_last = 0U;
	}
	lll_sync->chm[chm_last].data_chan_count =
		ull_chan_map_get(lll_sync->chm[chm_last].data_chan_map);
	lll_sync->chm_instant = instant;

	/* Commit the Channel Map Indication in the ACAD field of Periodic
	 * Advertising
	 */
	lll_adv_sync_data_enqueue(lll_sync, ter_idx);

	/* Initiate the Channel Map Indication */
	lll_sync->chm_last = chm_last;

#if defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
	struct ll_adv_sync_set *sync = HDR_LLL2ULL(lll_sync);

	if (!sync->is_started) {
		/* Sync not started yet, apply new channel map now */
		lll_sync->chm_first = lll_sync->chm_last;
	}
#endif /* CONFIG_BT_TICKER_EXT_EXPIRE_INFO */

	return 0;
}

#if defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
void ull_adv_sync_lll_syncinfo_fill(struct pdu_adv *pdu, struct lll_adv_aux *lll_aux)
{
	struct lll_adv_sync *lll_sync;
	struct pdu_adv_sync_info *si;
	uint8_t chm_first;

	lll_sync = lll_aux->adv->sync;

	si = sync_info_get(pdu);
	sync_info_offset_fill(si, lll_sync->us_adv_sync_pdu_offset);
	si->evt_cntr = lll_sync->event_counter + lll_sync->latency_prepare +
		       lll_sync->sync_lazy;

	/* Fill the correct channel map to use if at or past the instant */
	if (lll_sync->chm_first != lll_sync->chm_last) {
		uint16_t instant_latency;

		instant_latency = (si->evt_cntr - lll_sync->chm_instant) &
				  EVENT_INSTANT_MAX;
		if (instant_latency <= EVENT_INSTANT_LATENCY_MAX) {
			chm_first = lll_sync->chm_last;
		} else {
			chm_first = lll_sync->chm_first;
		}
	} else {
		chm_first = lll_sync->chm_first;
	}
	(void)memcpy(si->sca_chm, lll_sync->chm[chm_first].data_chan_map,
		     sizeof(si->sca_chm));
	si->sca_chm[PDU_SYNC_INFO_SCA_CHM_SCA_BYTE_OFFSET] &=
		~PDU_SYNC_INFO_SCA_CHM_SCA_BIT_MASK;
	si->sca_chm[PDU_SYNC_INFO_SCA_CHM_SCA_BYTE_OFFSET] |=
		((lll_clock_sca_local_get() <<
		  PDU_SYNC_INFO_SCA_CHM_SCA_BIT_POS) &
		 PDU_SYNC_INFO_SCA_CHM_SCA_BIT_MASK);
}

static void sync_info_offset_fill(struct pdu_adv_sync_info *si, uint32_t offs)
{
	if (offs >= OFFS_ADJUST_US) {
		offs -= OFFS_ADJUST_US;
		si->offs_adjust = 1U;
	}

	offs = offs / OFFS_UNIT_30_US;
	if (!!(offs >> OFFS_UNIT_BITS)) {
		si->offs = sys_cpu_to_le16(offs / (OFFS_UNIT_300_US / OFFS_UNIT_30_US));
		si->offs_units = OFFS_UNIT_VALUE_300_US;
	} else {
		si->offs = sys_cpu_to_le16(offs);
		si->offs_units = OFFS_UNIT_VALUE_30_US;
	}
}

#else /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
static void mfy_sync_offset_get(void *param)
{
	struct ll_adv_set *adv = param;
	struct lll_adv_sync *lll_sync;
	struct ll_adv_sync_set *sync;
	struct pdu_adv_sync_info *si;
	uint32_t sync_remainder_us;
	uint32_t aux_remainder_us;
	uint32_t ticks_to_expire;
	uint32_t ticks_current;
	struct pdu_adv *pdu;
	uint32_t remainder;
	uint8_t chm_first;
	uint8_t ticker_id;
	uint16_t lazy;
	uint8_t retry;
	uint8_t id;

	lll_sync = adv->lll.sync;
	sync = HDR_LLL2ULL(lll_sync);
	ticker_id = TICKER_ID_ADV_SYNC_BASE + sync_handle_get(sync);

	id = TICKER_NULL;
	ticks_to_expire = 0U;
	ticks_current = 0U;
	retry = 4U;
	do {
		uint32_t volatile ret_cb;
		uint32_t ticks_previous;
		uint32_t ret;
		bool success;

		ticks_previous = ticks_current;

		ret_cb = TICKER_STATUS_BUSY;
		ret = ticker_next_slot_get_ext(TICKER_INSTANCE_ID_CTLR,
					       TICKER_USER_ID_ULL_LOW,
					       &id, &ticks_current,
					       &ticks_to_expire, &remainder,
					       &lazy, NULL, NULL,
					       ticker_op_cb, (void *)&ret_cb);
		if (ret == TICKER_STATUS_BUSY) {
			while (ret_cb == TICKER_STATUS_BUSY) {
				ticker_job_sched(TICKER_INSTANCE_ID_CTLR,
						 TICKER_USER_ID_ULL_LOW);
			}
		}

		success = (ret_cb == TICKER_STATUS_SUCCESS);
		LL_ASSERT(success);

		LL_ASSERT((ticks_current == ticks_previous) || retry--);

		LL_ASSERT(id != TICKER_NULL);
	} while (id != ticker_id);

	/* Reduced a tick for negative remainder and return positive remainder
	 * value.
	 */
	hal_ticker_remove_jitter(&ticks_to_expire, &remainder);
	sync_remainder_us = remainder;

	/* Add a tick for negative remainder and return positive remainder
	 * value.
	 */
	remainder = sync->aux_remainder;
	hal_ticker_add_jitter(&ticks_to_expire, &remainder);
	aux_remainder_us = remainder;

	pdu = lll_adv_aux_data_latest_peek(adv->lll.aux);
	si = sync_info_get(pdu);
	sync_info_offset_fill(si, ticks_to_expire, sync_remainder_us,
			      aux_remainder_us);
	si->evt_cntr = lll_sync->event_counter + lll_sync->latency_prepare +
		       lazy;

	/* Fill the correct channel map to use if at or past the instant */
	if (lll_sync->chm_first != lll_sync->chm_last) {
		uint16_t instant_latency;

		instant_latency = (si->evt_cntr - lll_sync->chm_instant) &
				  EVENT_INSTANT_MAX;
		if (instant_latency <= EVENT_INSTANT_LATENCY_MAX) {
			chm_first = lll_sync->chm_last;
		} else {
			chm_first = lll_sync->chm_first;
		}
	} else {
		chm_first = lll_sync->chm_first;
	}
	(void)memcpy(si->sca_chm, lll_sync->chm[chm_first].data_chan_map,
		     sizeof(si->sca_chm));
	si->sca_chm[PDU_SYNC_INFO_SCA_CHM_SCA_BYTE_OFFSET] &=
		~PDU_SYNC_INFO_SCA_CHM_SCA_BIT_MASK;
	si->sca_chm[PDU_SYNC_INFO_SCA_CHM_SCA_BYTE_OFFSET] |=
		((lll_clock_sca_local_get() <<
		  PDU_SYNC_INFO_SCA_CHM_SCA_BIT_POS) &
		 PDU_SYNC_INFO_SCA_CHM_SCA_BIT_MASK);
}

static void sync_info_offset_fill(struct pdu_adv_sync_info *si,
				  uint32_t ticks_offset,
				  uint32_t remainder_us,
				  uint32_t start_us)
{
	uint32_t offs;

	offs = HAL_TICKER_TICKS_TO_US(ticks_offset) + remainder_us - start_us;

	if (offs >= OFFS_ADJUST_US) {
		offs -= OFFS_ADJUST_US;
		si->offs_adjust = 1U;
	}

	offs = offs / OFFS_UNIT_30_US;
	if (!!(offs >> OFFS_UNIT_BITS)) {
		si->offs = sys_cpu_to_le16(offs / (OFFS_UNIT_300_US / OFFS_UNIT_30_US));
		si->offs_units = OFFS_UNIT_VALUE_300_US;
	} else {
		si->offs = sys_cpu_to_le16(offs);
		si->offs_units = OFFS_UNIT_VALUE_30_US;
	}
}

static void ticker_op_cb(uint32_t status, void *param)
{
	*((uint32_t volatile *)param) = status;
}
#endif /* !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */

static struct pdu_adv_sync_info *sync_info_get(struct pdu_adv *pdu)
{
	struct pdu_adv_com_ext_adv *p;
	struct pdu_adv_ext_hdr *h;
	uint8_t *ptr;

	p = (void *)&pdu->adv_ext_ind;
	h = (void *)p->ext_hdr_adv_data;
	ptr = h->data;

	/* traverse through adv_addr, if present */
	if (h->adv_addr) {
		ptr += BDADDR_SIZE;
	}

	/* traverse through tgt_addr, if present */
	if (h->tgt_addr) {
		ptr += BDADDR_SIZE;
	}

	/* No CTEInfo flag in primary and secondary channel PDU */

	/* traverse through adi, if present */
	if (h->adi) {
		ptr += sizeof(struct pdu_adv_adi);
	}

	/* traverse through aux ptr, if present */
	if (h->aux_ptr) {
		ptr += sizeof(struct pdu_adv_aux_ptr);
	}

	/* return pointer offset to sync_info */
	return (void *)ptr;
}

static void ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift,
		      uint32_t remainder, uint16_t lazy, uint8_t force,
		      void *param)
{
	static memq_link_t link;
	static struct mayfly mfy = {0, 0, &link, NULL, lll_adv_sync_prepare};
	static struct lll_prepare_param p;
#if defined(CONFIG_BT_CTLR_ADV_ISO) && \
	defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
	struct ticker_ext_context *context = param;
	struct ll_adv_sync_set *sync = context->context;
#else /* !CONFIG_BT_CTLR_ADV_ISO || !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
	struct ll_adv_sync_set *sync = param;
#endif /* !CONFIG_BT_CTLR_ADV_ISO || !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
	struct lll_adv_sync *lll;
	uint32_t ret;
	uint8_t ref;

	DEBUG_RADIO_PREPARE_A(1);

	lll = &sync->lll;

	/* Increment prepare reference count */
	ref = ull_ref_inc(&sync->ull);
	LL_ASSERT(ref);

#if defined(CONFIG_BT_CTLR_ADV_ISO) && \
	defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
	if (lll->iso) {
		struct lll_adv_iso *lll_iso = lll->iso;

		LL_ASSERT(context->other_expire_info);

		/* Check: No need for remainder in this case? */
		lll_iso->ticks_sync_pdu_offset = context->other_expire_info->ticks_to_expire;
		lll_iso->iso_lazy = context->other_expire_info->lazy;
	}
#endif /* CONFIG_BT_CTLR_ADV_ISO && CONFIG_BT_TICKER_EXT_EXPIRE_INFO */

	/* Append timing parameters */
	p.ticks_at_expire = ticks_at_expire;
	p.remainder = remainder;
	p.lazy = lazy;
	p.force = force;
	p.param = lll;
	mfy.param = &p;

	/* Kick LLL prepare */
	ret = mayfly_enqueue(TICKER_USER_ID_ULL_HIGH,
			     TICKER_USER_ID_LLL, 0, &mfy);
	LL_ASSERT(!ret);

#if defined(CONFIG_BT_CTLR_ADV_ISO) && \
	!defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
	if (lll->iso) {
		ull_adv_iso_offset_get(sync);
	}
#endif /* CONFIG_BT_CTLR_ADV_ISO && !CONFIG_BT_TICKER_EXT_EXPIRE_INFO */

	DEBUG_RADIO_PREPARE_A(1);
}

#if defined(CONFIG_BT_CTLR_ADV_ISO) && \
	defined(CONFIG_BT_TICKER_EXT_EXPIRE_INFO)
static void ticker_update_op_cb(uint32_t status, void *param)
{
	LL_ASSERT(status == TICKER_STATUS_SUCCESS ||
		  param == ull_disable_mark_get());
}
#endif /* !CONFIG_BT_CTLR_ADV_ISO && CONFIG_BT_TICKER_EXT_EXPIRE_INFO */
