/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "syscfg/syscfg.h"
#include "os/os.h"
#include "ble/xcvr.h"
#include "nimble/ble.h"
#include "nimble/nimble_opt.h"
#include "nimble/hci_common.h"
#include "controller/ble_phy.h"
#include "controller/ble_hw.h"
#include "controller/ble_ll.h"
#include "controller/ble_ll_pdu.h"
#include "controller/ble_ll_hci.h"
#include "controller/ble_ll_adv.h"
#include "controller/ble_ll_sched.h"
#include "controller/ble_ll_scan.h"
#include "controller/ble_ll_whitelist.h"
#include "controller/ble_ll_resolv.h"
#include "controller/ble_ll_tmr.h"
#include "controller/ble_ll_trace.h"
#include "controller/ble_ll_utils.h"
#include "controller/ble_ll_rfmgmt.h"
#include "controller/ble_ll_iso_big.h"
#include "ble_ll_conn_priv.h"
#include "ble_ll_priv.h"

#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER)

/* XXX: TODO
 * 1) Need to look at advertising and scan request PDUs. Do I allocate these
 * once? Do I use a different pool for smaller ones? Do I statically declare
 * them?
 * 3) How do features get supported? What happens if device does not support
 * advertising? (for example)
 * 4) How to determine the advertising interval we will actually use. As of
 * now, we set it to max.
 */

/* Scheduling data for secondary channel */
struct ble_ll_adv_aux {
    struct ble_ll_sched_item sch;
    uint32_t start_time;
    uint16_t data_offset;
    uint8_t chan;
    uint8_t ext_hdr_flags;
    uint8_t data_len;
    uint8_t payload_len;
    uint8_t auxptr_zero;
};

/* Scheduling data for sync PDUs */
struct ble_ll_adv_sync {
    struct ble_ll_sched_item sch;
    uint32_t start_time;
    uint16_t data_offset;
    uint8_t chan;
    uint8_t ext_hdr_flags;
    uint8_t data_len;
    uint8_t payload_len;
    uint8_t auxptr_zero;
#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
    struct ble_ll_iso_big *big;
#endif
};

/*
 * Advertising state machine
 *
 * The advertising state machine data structure.
 *
 *  adv_pdu_len
 *      The length of the advertising PDU that will be sent. This does not
 *      include the preamble, access address and CRC.
 *
 *  initiator_addr:
 *      This is the address that we send in directed advertisements (the
 *      INITA field). If we are using Privacy this is a RPA that we need to
 *      generate. We reserve space in the advsm to save time when creating
 *      the ADV_DIRECT_IND. If own address type is not 2 or 3, this is simply
 *      the peer address from the set advertising parameters.
 */
struct ble_ll_adv_sm
{
    uint8_t adv_enabled;
    uint8_t adv_instance;
    uint8_t adv_chanmask;
    uint8_t adv_filter_policy;
    uint8_t own_addr_type;
    uint8_t peer_addr_type;
    uint8_t adv_chan;
    uint8_t retry_event;
    uint8_t adv_pdu_len;
    int8_t adv_rpa_index;
    int8_t tx_power;
    uint16_t flags;
    uint16_t props;
    uint32_t adv_itvl_usecs;
    uint32_t adv_event_start_time;
    uint32_t adv_pdu_start_time;
    uint32_t adv_end_time;
    uint8_t adva[BLE_DEV_ADDR_LEN];
    uint8_t adv_rpa[BLE_DEV_ADDR_LEN];
    uint8_t peer_addr[BLE_DEV_ADDR_LEN];
    uint8_t initiator_addr[BLE_DEV_ADDR_LEN];
    struct os_mbuf *adv_data;
    struct os_mbuf *new_adv_data;
    struct os_mbuf *scan_rsp_data;
    struct os_mbuf *new_scan_rsp_data;
#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL)
    uint8_t *conn_comp_ev;
#endif
    struct ble_npl_event adv_txdone_ev;
    struct ble_ll_sched_item adv_sch;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2)
    uint16_t channel_id;
    uint16_t event_cntr;
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    uint8_t aux_active : 1;
    uint8_t aux_index : 1;
    uint8_t aux_first_pdu : 1;
    uint8_t aux_not_scanned : 1;
    uint8_t aux_dropped : 1;
    struct ble_mbuf_hdr *rx_ble_hdr;
    struct os_mbuf **aux_data;
    struct ble_ll_adv_aux aux[2];
    struct ble_npl_event adv_sec_txdone_ev;
    uint16_t duration;
    uint16_t adi;
    uint8_t adv_random_addr[BLE_DEV_ADDR_LEN];
    uint8_t events_max;
    uint8_t events;
    uint8_t pri_phy;
    uint8_t sec_phy;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV)
    struct os_mbuf *periodic_adv_data;
    struct os_mbuf *periodic_new_data;
    uint32_t periodic_crcinit; /* only 3 bytes are used */
    uint32_t periodic_access_addr;
    uint16_t periodic_adv_props;
    uint16_t periodic_channel_id;
    uint16_t periodic_event_cntr;
    uint16_t periodic_chain_event_cntr;
    uint8_t periodic_adv_enabled : 1;
    uint8_t periodic_adv_active : 1;
    uint8_t periodic_sync_active : 1;
    uint8_t periodic_sync_index : 1;
    uint8_t periodic_num_used_chans;
    uint8_t periodic_chanmap[BLE_LL_CHAN_MAP_LEN];
    uint16_t periodic_adv_itvl;
    uint32_t periodic_adv_itvl_ticks;
    uint8_t periodic_adv_itvl_rem_us;
    uint8_t periodic_adv_event_start_time_remainder;
    uint32_t periodic_adv_event_start_time;
    struct ble_ll_adv_sync periodic_sync[2];
    struct ble_npl_event adv_periodic_txdone_ev;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER)
    uint16_t periodic_event_cntr_last_sent;
#endif
#endif

#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
    struct ble_ll_iso_big *big;
#endif /* BLE_LL_ISO_BROADCASTER */

#endif
};

#define BLE_LL_ADV_SM_FLAG_TX_ADD                   0x0001
#define BLE_LL_ADV_SM_FLAG_RX_ADD                   0x0002
#define BLE_LL_ADV_SM_FLAG_SCAN_REQ_NOTIF           0x0004
#define BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD             0x0008
#define BLE_LL_ADV_SM_FLAG_ACTIVE_CHANSET_MASK      0x0030 /* use helpers! */
#define BLE_LL_ADV_SM_FLAG_ADV_DATA_INCOMPLETE      0x0040
#define BLE_LL_ADV_SM_FLAG_CONFIGURED               0x0080
#define BLE_LL_ADV_SM_FLAG_ADV_RPA_TMO              0x0100
#define BLE_LL_ADV_SM_FLAG_NEW_ADV_DATA             0x0200
#define BLE_LL_ADV_SM_FLAG_NEW_SCAN_RSP_DATA        0x0400
#define BLE_LL_ADV_SM_FLAG_PERIODIC_CONFIGURED      0x0800
#define BLE_LL_ADV_SM_FLAG_PERIODIC_DATA_INCOMPLETE 0x1000
#define BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING    0x2000
#define BLE_LL_ADV_SM_FLAG_PERIODIC_NEW_DATA        0x4000
#define BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD_ERR         0x8000

#define ADV_DATA_LEN(_advsm) \
    (((_advsm)->adv_data) ? OS_MBUF_PKTLEN((_advsm)->adv_data) : 0)
#define SCAN_RSP_DATA_LEN(_advsm) \
    (((_advsm)->scan_rsp_data) ? OS_MBUF_PKTLEN((_advsm)->scan_rsp_data) : 0)

#define AUX_CURRENT(_advsm) \
    (&((_advsm)->aux[(_advsm)->aux_index]))
#define AUX_NEXT(_advsm) \
    (&((_advsm)->aux[(_advsm)->aux_index ^ 1]))
#define AUX_DATA_LEN(_advsm) \
    (*((_advsm)->aux_data) ? OS_MBUF_PKTLEN(*(_advsm)->aux_data) : 0)

#define SYNC_CURRENT(_advsm) \
    (&((_advsm)->periodic_sync[(_advsm)->periodic_sync_index]))
#define SYNC_NEXT(_advsm) \
    (&((_advsm)->periodic_sync[(_advsm)->periodic_sync_index ^ 1]))
#define SYNC_DATA_LEN(_advsm) \
    ((_advsm)->periodic_adv_data ? OS_MBUF_PKTLEN((_advsm)->periodic_adv_data) : 0)

/* The advertising state machine global object */
struct ble_ll_adv_sm g_ble_ll_adv_sm[BLE_ADV_INSTANCES];
struct ble_ll_adv_sm *g_ble_ll_cur_adv_sm;

static void ble_ll_adv_drop_event(struct ble_ll_adv_sm *advsm, bool preempted);

static struct ble_ll_adv_sm *
ble_ll_adv_sm_find_configured(uint8_t instance)
{
    struct ble_ll_adv_sm *advsm;
    unsigned int i;

    /* in legacy mode we only allow instance 0 */
    if (!ble_ll_hci_adv_mode_ext()) {
        BLE_LL_ASSERT(instance == 0);
        return &g_ble_ll_adv_sm[0];
    }

    for (i = 0; i < ARRAY_SIZE(g_ble_ll_adv_sm); i++) {
        advsm = &g_ble_ll_adv_sm[i];

        if ((advsm->flags & BLE_LL_ADV_SM_FLAG_CONFIGURED) &&
                (advsm->adv_instance == instance)) {
            return advsm;
        }
    }

    return NULL;
}

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
static int
ble_ll_adv_active_chanset_is_pri(struct ble_ll_adv_sm *advsm)
{
    return (advsm->flags & BLE_LL_ADV_SM_FLAG_ACTIVE_CHANSET_MASK) == 0x10;
}

static int
ble_ll_adv_active_chanset_is_sec(struct ble_ll_adv_sm *advsm)
{
    return (advsm->flags & BLE_LL_ADV_SM_FLAG_ACTIVE_CHANSET_MASK) == 0x20;
}
#endif

static void
ble_ll_adv_active_chanset_clear(struct ble_ll_adv_sm *advsm)
{
    os_sr_t sr;

    OS_ENTER_CRITICAL(sr);
    advsm->flags &= ~BLE_LL_ADV_SM_FLAG_ACTIVE_CHANSET_MASK;
    OS_EXIT_CRITICAL(sr);
}

static void
ble_ll_adv_active_chanset_set_pri(struct ble_ll_adv_sm *advsm)
{
    os_sr_t sr;

    OS_ENTER_CRITICAL(sr);
    BLE_LL_ASSERT((advsm->flags & BLE_LL_ADV_SM_FLAG_ACTIVE_CHANSET_MASK) == 0);
    advsm->flags &= ~BLE_LL_ADV_SM_FLAG_ACTIVE_CHANSET_MASK;
    advsm->flags |= 0x10;
    OS_EXIT_CRITICAL(sr);
}

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
static void
ble_ll_adv_active_chanset_set_sec(struct ble_ll_adv_sm *advsm)
{
    os_sr_t sr;

    OS_ENTER_CRITICAL(sr);
    BLE_LL_ASSERT((advsm->flags & BLE_LL_ADV_SM_FLAG_ACTIVE_CHANSET_MASK) == 0);
    advsm->flags &= ~BLE_LL_ADV_SM_FLAG_ACTIVE_CHANSET_MASK;
    advsm->flags |= 0x20;
    OS_EXIT_CRITICAL(sr);
}
#endif

static void
ble_ll_adv_flags_set(struct ble_ll_adv_sm *advsm, uint16_t flags)
{
    os_sr_t sr;

    OS_ENTER_CRITICAL(sr);
    advsm->flags |= flags;
    OS_EXIT_CRITICAL(sr);
}

static void
ble_ll_adv_flags_clear(struct ble_ll_adv_sm *advsm, uint16_t flags)
{
    os_sr_t sr;

    OS_ENTER_CRITICAL(sr);
    advsm->flags &= ~flags;
    OS_EXIT_CRITICAL(sr);
}

static void ble_ll_adv_make_done(struct ble_ll_adv_sm *advsm, struct ble_mbuf_hdr *hdr);
static void ble_ll_adv_sm_init(struct ble_ll_adv_sm *advsm);
static void ble_ll_adv_sm_stop_timeout(struct ble_ll_adv_sm *advsm);

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
static void
ble_ll_adv_rpa_update(struct ble_ll_adv_sm *advsm)
{
    if (ble_ll_resolv_gen_rpa(advsm->peer_addr, advsm->peer_addr_type,
                              advsm->adva, 1) ||
        (ble_ll_resolv_local_rpa_get(advsm->own_addr_type & 1,
                                     advsm->adva) == 0)) {
        ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_TX_ADD);
    } else {
        if (advsm->own_addr_type & 1) {
            ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_TX_ADD);
        } else {
            ble_ll_adv_flags_clear(advsm, BLE_LL_ADV_SM_FLAG_TX_ADD);
        }
    }

    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED) {
        if (ble_ll_resolv_gen_rpa(advsm->peer_addr, advsm->peer_addr_type,
                              advsm->initiator_addr, 0)) {
            ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_RX_ADD);
        } else {
            if (advsm->peer_addr_type & 1) {
                ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_RX_ADD);
            } else {
                ble_ll_adv_flags_clear(advsm, BLE_LL_ADV_SM_FLAG_RX_ADD);
            }
        }
    }
}

/**
 * Called to change advertisers ADVA and INITA (for directed advertisements)
 * as an advertiser needs to adhere to the resolvable private address generation
 * timer.
 *
 * NOTE: the resolvable private address code uses its own timer to regenerate
 * local resolvable private addresses. The advertising code uses its own
 * timer to reset the INITA (for directed advertisements). This code also sets
 * the appropriate txadd and rxadd bits that will go into the advertisement.
 *
 * Another thing to note: it is possible that an IRK is all zeroes in the
 * resolving list. That is why we need to check if the generated address is
 * in fact a RPA as a resolving list entry with all zeroes will use the
 * identity address (which may be a private address or public).
 *
 * @param advsm
 */
void
ble_ll_adv_chk_rpa_timeout(struct ble_ll_adv_sm *advsm)
{
    if (advsm->own_addr_type < BLE_HCI_ADV_OWN_ADDR_PRIV_PUB) {
        return;
    }

    if (advsm->flags & BLE_LL_ADV_SM_FLAG_ADV_RPA_TMO) {
        ble_ll_adv_rpa_update(advsm);
        ble_ll_adv_flags_clear(advsm, BLE_LL_ADV_SM_FLAG_ADV_RPA_TMO);
    }
}

void
ble_ll_adv_rpa_timeout(void)
{
    struct ble_ll_adv_sm *advsm;
    int i;

    for (i = 0; i < BLE_ADV_INSTANCES; i++) {
        advsm = &g_ble_ll_adv_sm[i];

        if (advsm->adv_enabled &&
                advsm->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) {
            /* Mark RPA as timed out so we get a new RPA */
            ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_ADV_RPA_TMO);
        }
    }
}
#endif

/**
 * Calculate the first channel that we should advertise upon when we start
 * an advertising event.
 *
 * @param advsm
 *
 * @return uint8_t The number of the first channel usable for advertising.
 */
static uint8_t
ble_ll_adv_first_chan(struct ble_ll_adv_sm *advsm)
{
    uint8_t adv_chan;

    /* Set first advertising channel */
    if (advsm->adv_chanmask & 0x01) {
        adv_chan = BLE_PHY_ADV_CHAN_START;
    } else if (advsm->adv_chanmask & 0x02) {
        adv_chan = BLE_PHY_ADV_CHAN_START + 1;
    } else {
        adv_chan = BLE_PHY_ADV_CHAN_START + 2;
    }

    return adv_chan;
}

/**
 * Calculate the final channel that we should advertise upon when we start
 * an advertising event.
 *
 * @param advsm
 *
 * @return uint8_t The number of the final channel usable for advertising.
 */
static uint8_t
ble_ll_adv_final_chan(struct ble_ll_adv_sm *advsm)
{
    uint8_t adv_chan;

    if (advsm->adv_chanmask & 0x04) {
        adv_chan = BLE_PHY_ADV_CHAN_START + 2;
    } else if (advsm->adv_chanmask & 0x02) {
        adv_chan = BLE_PHY_ADV_CHAN_START + 1;
    } else {
        adv_chan = BLE_PHY_ADV_CHAN_START;
    }

    return adv_chan;
}

/**
 * Create the advertising legacy PDU
 *
 * @param advsm Pointer to advertisement state machine
 */
static uint8_t
ble_ll_adv_legacy_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte)
{
    struct ble_ll_adv_sm *advsm;
    uint8_t     adv_data_len;
    uint8_t     pdulen;
    uint8_t     pdu_type;

    advsm = pducb_arg;

    /* assume this is not a direct ind */
    adv_data_len = ADV_DATA_LEN(advsm);
    pdulen = BLE_DEV_ADDR_LEN + adv_data_len;

    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED) {
        pdu_type = BLE_ADV_PDU_TYPE_ADV_DIRECT_IND;

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2)
        pdu_type |= BLE_ADV_PDU_HDR_CHSEL;
#endif

        if (advsm->flags & BLE_LL_ADV_SM_FLAG_RX_ADD) {
            pdu_type |= BLE_ADV_PDU_HDR_RXADD_RAND;
        }

        adv_data_len = 0;
        pdulen = BLE_ADV_DIRECT_IND_LEN;
    } else if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE) {
        pdu_type = BLE_ADV_PDU_TYPE_ADV_IND;

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2)
        pdu_type |= BLE_ADV_PDU_HDR_CHSEL;
#endif
    } else if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE) {
        pdu_type = BLE_ADV_PDU_TYPE_ADV_SCAN_IND;
    } else {
        pdu_type = BLE_ADV_PDU_TYPE_ADV_NONCONN_IND;
    }

    /* An invalid advertising data length indicates a memory overwrite */
    BLE_LL_ASSERT(adv_data_len <= BLE_ADV_LEGACY_DATA_MAX_LEN);

    /* Set the PDU length in the state machine (includes header) */
    advsm->adv_pdu_len = pdulen + BLE_LL_PDU_HDR_LEN;

    /* Set TxAdd to random if needed. */
    if (advsm->flags & BLE_LL_ADV_SM_FLAG_TX_ADD) {
        pdu_type |= BLE_ADV_PDU_HDR_TXADD_RAND;
    }

    *hdr_byte = pdu_type;

    /* Construct advertisement */
    memcpy(dptr, advsm->adva, BLE_DEV_ADDR_LEN);
    dptr += BLE_DEV_ADDR_LEN;

    /* For ADV_DIRECT_IND add inita */
    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED) {
        memcpy(dptr, advsm->initiator_addr, BLE_DEV_ADDR_LEN);
    }

    /* Copy in advertising data, if any */
    if (adv_data_len != 0) {
        os_mbuf_copydata(advsm->adv_data, 0, adv_data_len, dptr);
    }

    return pdulen;
}

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
static void
ble_ll_adv_put_aux_ptr(uint8_t chan, uint8_t phy, uint32_t offset,
                       uint8_t *dptr)
{
    dptr[0] = chan;

    if (offset > 245700) {
        dptr[0] |= 0x80;
        offset = offset / 300;
    } else {
        offset = offset / 30;
    }

    if (offset > 0x1fff) {
        offset = 0;
    }

    /* offset is 13bits and PHY 3 bits */
    dptr[1] = (offset & 0x000000ff);
    dptr[2] = ((offset >> 8) & 0x0000001f) | (phy - 1) << 5;
}

/**
 * Create the advertising PDU
 */
static uint8_t
ble_ll_adv_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte)
{
    struct ble_ll_adv_sm *advsm;
    uint8_t pdu_type;
    uint8_t adv_mode;
    uint8_t ext_hdr_len;
    uint8_t ext_hdr_flags;
    uint32_t offset;

    advsm = pducb_arg;

    BLE_LL_ASSERT(ble_ll_adv_active_chanset_is_pri(advsm));
    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
        return ble_ll_adv_legacy_pdu_make(dptr, advsm, hdr_byte);
    }

    /* only ADV_EXT_IND goes on primary advertising channels */
    pdu_type = BLE_ADV_PDU_TYPE_ADV_EXT_IND;

    *hdr_byte = pdu_type;

    adv_mode = 0;
    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE) {
        adv_mode |= BLE_LL_EXT_ADV_MODE_CONN;
    }
    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE) {
        adv_mode |= BLE_LL_EXT_ADV_MODE_SCAN;
    }

    ext_hdr_len = BLE_LL_EXT_ADV_FLAGS_SIZE + BLE_LL_EXT_ADV_DATA_INFO_SIZE +
                  BLE_LL_EXT_ADV_AUX_PTR_SIZE;
    ext_hdr_flags = (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT) |
                    (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT);

    /* ext hdr len and adv mode */
    dptr[0] = ext_hdr_len | (adv_mode << 6);
    dptr += 1;

    /* ext hdr flags */
    dptr[0] = ext_hdr_flags;
    dptr += 1;

    /* ADI */
    dptr[0] = advsm->adi & 0x00ff;
    dptr[1] = advsm->adi >> 8;
    dptr += BLE_LL_EXT_ADV_DATA_INFO_SIZE;

    /* AuxPtr */
    if (AUX_CURRENT(advsm)->sch.enqueued) {
        offset = ble_ll_tmr_t2u(AUX_CURRENT(advsm)->start_time - advsm->adv_pdu_start_time);
    } else {
        offset = 0;
    }
    /* Always use channel from 1st AUX */
    ble_ll_adv_put_aux_ptr(AUX_CURRENT(advsm)->chan, advsm->sec_phy,
                           offset, dptr);

    return BLE_LL_EXT_ADV_HDR_LEN + ext_hdr_len;
}

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV)
static void
ble_ll_adv_put_syncinfo(struct ble_ll_adv_sm *advsm,
                        struct ble_ll_conn_sm *connsm, uint8_t *conn_event_cnt,
                        uint8_t *dptr)
{
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER)
    uint16_t conn_cnt;
#endif
    unsigned int event_cnt_off = 0;
    uint32_t offset = 0;
    uint32_t itvl_us;
    uint32_t anchor_ticks;
    uint8_t anchor_rem_us;
    uint8_t units;

    if (connsm) {
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER)
        anchor_ticks = connsm->anchor_point;
        anchor_rem_us = connsm->anchor_point_usecs;
        conn_cnt = connsm->event_cntr;

        /* get anchor for conn event that is before periodic_adv_event_start_time */
        while (LL_TMR_GT(anchor_ticks, advsm->periodic_adv_event_start_time)) {
            ble_ll_conn_get_anchor(connsm, --conn_cnt, &anchor_ticks, &anchor_rem_us);
        }

        offset = ble_ll_tmr_t2u(advsm->periodic_adv_event_start_time - anchor_ticks);
        offset -= anchor_rem_us;
        offset += advsm->periodic_adv_event_start_time_remainder;

        /* connEventCount */
        put_le16(conn_event_cnt, conn_cnt);
#endif
    } else {
        anchor_ticks = advsm->periodic_adv_event_start_time;
        anchor_rem_us = advsm->periodic_adv_event_start_time_remainder;
        itvl_us = advsm->periodic_adv_itvl * BLE_LL_ADV_PERIODIC_ITVL;

        /* Get periodic event that is past AUX start time (so that we always
         * provide valid offset if it is not too far in future). This can
         * happen if advertising event is interleaved with periodic advertising
         * event (when chaining).
         */
        while (LL_TMR_GEQ(AUX_CURRENT(advsm)->start_time, anchor_ticks)) {
            ble_ll_tmr_add(&anchor_ticks, &anchor_rem_us, itvl_us);
            event_cnt_off++;
        }

        /* We always schedule aux with 0 rem_us so no need to include it here */
        offset = ble_ll_tmr_t2u(anchor_ticks - AUX_CURRENT(advsm)->start_time);
        offset += anchor_rem_us;
    }

    /* Sync Packet Offset (13 bits), Offset Units (1 bit), Offset Adjust (1 bit),
     * RFU (1 bit)
     */
    if (offset > 245700) {
        units = 0x20;
        offset = offset / 300;

        if (offset >= 0x2000) {
            if (connsm) {
                offset -= 0x2000;
                units |= 0x40;
            } else {
                /* not able to represent time in offset */
                offset = 0;
                units = 0x00;
                event_cnt_off = 0;
            }
        }

    } else {
        units = 0x00;
        offset = offset / 30;
    }

    dptr[0] = (offset & 0x000000ff);
    dptr[1] = ((offset >> 8) & 0x0000001f) | units;

    /* Interval (2 bytes) */
    put_le16(&dptr[2], advsm->periodic_adv_itvl);

    /* Channels Mask (37 bits) */
    dptr[4] = advsm->periodic_chanmap[0];
    dptr[5] = advsm->periodic_chanmap[1];
    dptr[6] = advsm->periodic_chanmap[2];
    dptr[7] = advsm->periodic_chanmap[3];
    dptr[8] = advsm->periodic_chanmap[4] & 0x1f;

    /* SCA (3 bits) */
    dptr[8] |= BLE_LL_SCA_ENUM << 5;

    /* AA (4 bytes) */
    put_le32(&dptr[9], advsm->periodic_access_addr);

    /* CRCInit (3 bytes) */
    dptr[13] = (uint8_t)advsm->periodic_crcinit;
    dptr[14] = (uint8_t)(advsm->periodic_crcinit >> 8);
    dptr[15] = (uint8_t)(advsm->periodic_crcinit >> 16);

    /* Event Counter (2 bytes) */
    put_le16(&dptr[16], advsm->periodic_event_cntr + event_cnt_off);
}
#endif

/**
 * Create the AUX PDU
 */
static uint8_t
ble_ll_adv_aux_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte)
{
    struct ble_ll_adv_sm *advsm;
    struct ble_ll_adv_aux *aux;
    uint8_t adv_mode;
    uint8_t pdu_type;
    uint8_t ext_hdr_len;
    uint32_t offset;

    advsm = pducb_arg;
    aux = AUX_CURRENT(advsm);

    BLE_LL_ASSERT(!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY));
    BLE_LL_ASSERT(ble_ll_adv_active_chanset_is_sec(advsm));

    /* It's the same for AUX_ADV_IND and AUX_CHAIN_IND */
    pdu_type = BLE_ADV_PDU_TYPE_AUX_ADV_IND;

    /* We do not create scannable PDUs here - this is handled separately */
    adv_mode = 0;
    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE) {
        adv_mode |= BLE_LL_EXT_ADV_MODE_CONN;
    }

    ext_hdr_len = aux->payload_len - BLE_LL_EXT_ADV_HDR_LEN - aux->data_len;
    dptr[0] = (adv_mode << 6) | ext_hdr_len;
    dptr += 1;

    /* only put flags if needed */
    if (aux->ext_hdr_flags) {
        dptr[0] = aux->ext_hdr_flags;
        dptr += 1;
    }

    if (aux->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_ADVA_BIT)) {

        /* Set TxAdd to random if needed. */
        if (advsm->flags & BLE_LL_ADV_SM_FLAG_TX_ADD) {
            pdu_type |= BLE_ADV_PDU_HDR_TXADD_RAND;
        }

        memcpy(dptr, advsm->adva, BLE_LL_EXT_ADV_ADVA_SIZE);
        dptr += BLE_LL_EXT_ADV_ADVA_SIZE;
    }

    if (aux->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_TARGETA_BIT)) {
        memcpy(dptr, advsm->initiator_addr, BLE_LL_EXT_ADV_TARGETA_SIZE);
        dptr += BLE_LL_EXT_ADV_TARGETA_SIZE;

        /* Set RxAdd to random if needed. */
        if (advsm->flags & BLE_LL_ADV_SM_FLAG_RX_ADD) {
            pdu_type |= BLE_ADV_PDU_HDR_RXADD_RAND;
        }
    }

    if (aux->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT)) {
        dptr[0] = advsm->adi & 0x00ff;
        dptr[1] = advsm->adi >> 8;
        dptr += BLE_LL_EXT_ADV_DATA_INFO_SIZE;
    }

    if (aux->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)) {
        if (!AUX_NEXT(advsm)->sch.enqueued) {
            /*
             * Trim data here in case we do not have next aux scheduled. This
             * can happen if next aux was outside advertising set period and
             * was removed from scheduler.
             */
            offset = 0;
        } else if (advsm->rx_ble_hdr) {
            offset = ble_ll_tmr_t2u(AUX_NEXT(advsm)->start_time - advsm->rx_ble_hdr->beg_cputime);
            offset -= (advsm->rx_ble_hdr->rem_usecs + ble_ll_pdu_us(12, advsm->sec_phy) + BLE_LL_IFS);
        } else {
            offset = ble_ll_tmr_t2u(AUX_NEXT(advsm)->start_time - aux->start_time);
        }

        aux->auxptr_zero = offset == 0;

        ble_ll_adv_put_aux_ptr(AUX_NEXT(advsm)->chan, advsm->sec_phy,
                               offset, dptr);

        dptr += BLE_LL_EXT_ADV_AUX_PTR_SIZE;
    }

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV)
    if (aux->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_SYNC_INFO_BIT)) {
        ble_ll_adv_put_syncinfo(advsm, NULL, NULL, dptr);
        dptr += BLE_LL_EXT_ADV_SYNC_INFO_SIZE;
    }
#endif

    if (aux->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_TX_POWER_BIT)) {
        dptr[0] = advsm->tx_power + g_ble_ll_tx_power_compensation;
        dptr += BLE_LL_EXT_ADV_TX_POWER_SIZE;
    }

    if (aux->data_len) {
        os_mbuf_copydata(*advsm->aux_data, aux->data_offset,
                         aux->data_len, dptr);
    }

    *hdr_byte = pdu_type;

    return aux->payload_len;
}

static uint8_t
ble_ll_adv_aux_scannable_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte)
{
    struct ble_ll_adv_sm *advsm;
    uint8_t pdu_type;
    uint8_t *ext_hdr_len;
    uint8_t *ext_hdr;
    uint8_t pdulen;

    advsm = pducb_arg;

    BLE_LL_ASSERT(!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY));
    BLE_LL_ASSERT(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE);
    BLE_LL_ASSERT(advsm->aux_first_pdu);
    BLE_LL_ASSERT(ble_ll_adv_active_chanset_is_sec(advsm));

    pdu_type = BLE_ADV_PDU_TYPE_AUX_ADV_IND;

    ext_hdr_len = &dptr[0];
    ext_hdr = &dptr[1];
    dptr += 2;

    /* Flags always */
    *ext_hdr_len = BLE_LL_EXT_ADV_FLAGS_SIZE;
    *ext_hdr = 0;

    /* AdvA when non anonymous */
    if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV)) {
        /* Set TxAdd to random if needed. */
        if (advsm->flags & BLE_LL_ADV_SM_FLAG_TX_ADD) {
            pdu_type |= BLE_ADV_PDU_HDR_TXADD_RAND;
        }

        *ext_hdr_len += BLE_LL_EXT_ADV_ADVA_SIZE;
        *ext_hdr |= (1 << BLE_LL_EXT_ADV_ADVA_BIT);
        memcpy(dptr, advsm->adva, BLE_LL_EXT_ADV_ADVA_SIZE);
        dptr += BLE_LL_EXT_ADV_ADVA_SIZE;
    }

    /* TargetA only for directed */
    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED) {
        *ext_hdr_len += BLE_LL_EXT_ADV_TARGETA_SIZE;
        *ext_hdr |= (1 << BLE_LL_EXT_ADV_TARGETA_BIT);
        memcpy(dptr, advsm->initiator_addr, BLE_LL_EXT_ADV_TARGETA_SIZE);
        dptr += BLE_LL_EXT_ADV_TARGETA_SIZE;

        /* Set RxAdd to random if needed. */
        if (advsm->flags & BLE_LL_ADV_SM_FLAG_RX_ADD) {
            pdu_type |= BLE_ADV_PDU_HDR_RXADD_RAND;
        }
    }

    /* ADI always */
    *ext_hdr_len += BLE_LL_EXT_ADV_DATA_INFO_SIZE;
    *ext_hdr |= (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT);
    dptr[0] = advsm->adi & 0x00ff;
    dptr[1] = advsm->adi >> 8;
    dptr += BLE_LL_EXT_ADV_DATA_INFO_SIZE;

    /* TxPower if configured */
    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_INC_TX_PWR) {
        *ext_hdr_len += BLE_LL_EXT_ADV_TX_POWER_SIZE;
        *ext_hdr |= (1 << BLE_LL_EXT_ADV_TX_POWER_BIT);
        dptr[0] = advsm->tx_power + g_ble_ll_tx_power_compensation;
        dptr += BLE_LL_EXT_ADV_TX_POWER_SIZE;
    }

    pdulen = BLE_LL_EXT_ADV_HDR_LEN + *ext_hdr_len;

    *hdr_byte = pdu_type;
    *ext_hdr_len |= (BLE_LL_EXT_ADV_MODE_SCAN << 6);

    return pdulen;
}
#endif

static uint8_t
ble_ll_adv_scan_rsp_legacy_pdu_make(uint8_t *dptr, void *pducb_arg,
                                    uint8_t *hdr_byte)
{
    struct ble_ll_adv_sm *advsm;
    uint8_t     scan_rsp_len;
    uint8_t     pdulen;
    uint8_t     hdr;

    advsm = pducb_arg;

    /* Make sure that the length is valid */
    scan_rsp_len = SCAN_RSP_DATA_LEN(advsm);
    BLE_LL_ASSERT(scan_rsp_len <= BLE_SCAN_RSP_LEGACY_DATA_MAX_LEN);

    /* Set BLE transmit header */
    pdulen = BLE_DEV_ADDR_LEN + scan_rsp_len;
    hdr = BLE_ADV_PDU_TYPE_SCAN_RSP;
    if (advsm->flags & BLE_LL_ADV_SM_FLAG_TX_ADD) {
        hdr |= BLE_ADV_PDU_HDR_TXADD_RAND;
    }

    *hdr_byte = hdr;

    /*
     * The adva in this packet will be the same one that was being advertised
     * and is based on the peer identity address in the set advertising
     * parameters. If a different peer sends us a scan request (for some reason)
     * we will reply with an adva that was not generated based on the local irk
     * of the peer sending the scan request.
     */

    /* Construct scan response */
    memcpy(dptr, advsm->adva, BLE_DEV_ADDR_LEN);
    if (scan_rsp_len != 0) {
        os_mbuf_copydata(advsm->scan_rsp_data, 0, scan_rsp_len,
                         dptr + BLE_DEV_ADDR_LEN);
    }

    return pdulen;
}

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
/**
 * Create a scan response PDU
 *
 * @param advsm
 */
static uint8_t
ble_ll_adv_scan_rsp_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte)
{
    struct ble_ll_adv_sm *advsm;

    advsm = pducb_arg;

    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
        return ble_ll_adv_scan_rsp_legacy_pdu_make(dptr, pducb_arg, hdr_byte);
    }

    return ble_ll_adv_aux_pdu_make(dptr, pducb_arg, hdr_byte);
}

struct aux_conn_rsp_data {
    struct ble_ll_adv_sm *advsm;
    uint8_t *peer;
    uint8_t rxadd;
};

/**
 * Create a AUX connect response PDU
 *
 * @param advsm
 */
#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL)
static uint8_t
ble_ll_adv_aux_conn_rsp_pdu_make(uint8_t *dptr, void *pducb_arg,
                                 uint8_t *hdr_byte)
{
    struct aux_conn_rsp_data *rsp_data;
    uint8_t     pdulen;
    uint8_t     ext_hdr_len;
    uint8_t     ext_hdr_flags;
    uint8_t     hdr;

    rsp_data = pducb_arg;

    /* flags,AdvA and TargetA */
    ext_hdr_len = BLE_LL_EXT_ADV_FLAGS_SIZE + BLE_LL_EXT_ADV_ADVA_SIZE +
                  BLE_LL_EXT_ADV_TARGETA_SIZE;
    ext_hdr_flags = (1 << BLE_LL_EXT_ADV_ADVA_BIT);
    ext_hdr_flags |= (1 << BLE_LL_EXT_ADV_TARGETA_BIT);

    pdulen = BLE_LL_EXT_ADV_HDR_LEN + ext_hdr_len;

    /* Set BLE transmit header */
    hdr = BLE_ADV_PDU_TYPE_AUX_CONNECT_RSP;
    if (rsp_data->rxadd) {
        hdr |= BLE_ADV_PDU_HDR_RXADD_MASK;
    }
    if (rsp_data->advsm->flags & BLE_LL_ADV_SM_FLAG_TX_ADD) {
        hdr |= BLE_ADV_PDU_HDR_TXADD_MASK;
    }

    *hdr_byte = hdr;

    /* ext hdr len and adv mode (00b) */
    dptr[0] = ext_hdr_len;
    dptr += 1;

    /* ext hdr flags */
    dptr[0] = ext_hdr_flags;
    dptr += 1;

    memcpy(dptr, rsp_data->advsm->adva, BLE_LL_EXT_ADV_ADVA_SIZE);
    dptr += BLE_LL_EXT_ADV_ADVA_SIZE;

    memcpy(dptr, rsp_data->peer, BLE_LL_EXT_ADV_TARGETA_SIZE);
    dptr += BLE_LL_EXT_ADV_ADVA_SIZE;

    return pdulen;
}
#endif
#endif

/**
 * Called to indicate the advertising event is over.
 *
 * Context: Interrupt
 *
 * @param advsm
 *
 */
static void
ble_ll_adv_tx_done(void *arg)
{
    struct ble_ll_adv_sm *advsm;

    advsm = (struct ble_ll_adv_sm *)arg;

    ble_ll_trace_u32x2(BLE_LL_TRACE_ID_ADV_TXDONE, advsm->adv_instance,
                       advsm->flags & BLE_LL_ADV_SM_FLAG_ACTIVE_CHANSET_MASK);

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    if (ble_ll_adv_active_chanset_is_pri(advsm)) {
        ble_ll_event_add(&advsm->adv_txdone_ev);
    } else if (ble_ll_adv_active_chanset_is_sec(advsm)) {
        ble_ll_event_add(&advsm->adv_sec_txdone_ev);
    } else {
        BLE_LL_ASSERT(0);
    }
#else
    ble_ll_event_add(&advsm->adv_txdone_ev);
#endif

    ble_ll_state_set(BLE_LL_STATE_STANDBY);

    ble_ll_adv_active_chanset_clear(advsm);

    /* We no longer have a current state machine */
    g_ble_ll_cur_adv_sm = NULL;
}

void
ble_ll_adv_preempted(struct ble_ll_adv_sm *advsm)
{
    ble_ll_adv_drop_event(advsm, 1);
}

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV)
/*
 * Called when a periodic event has been removed from the scheduler
 * without being run.
 */
void
ble_ll_adv_periodic_rmvd_from_sched(struct ble_ll_adv_sm *advsm)
{
    ble_ll_event_add(&advsm->adv_periodic_txdone_ev);
}
#endif

/**
 * This is the scheduler callback (called from interrupt context) which
 * transmits an advertisement.
 *
 * Context: Interrupt (scheduler)
 *
 * @param sch
 *
 * @return int
 */
static int
ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch)
{
    int rc;
    uint8_t end_trans;
    uint32_t txstart;
    struct ble_ll_adv_sm *advsm;

    /* Get the state machine for the event */
    advsm = (struct ble_ll_adv_sm *)sch->cb_arg;

    /* Set the current advertiser */
    g_ble_ll_cur_adv_sm = advsm;

    ble_ll_adv_active_chanset_set_pri(advsm);

    if ((advsm->flags & BLE_LL_ADV_SM_FLAG_NEW_ADV_DATA) ||
        (advsm->flags & BLE_LL_ADV_SM_FLAG_NEW_SCAN_RSP_DATA)) {
        goto adv_tx_done;
    }

    /* Set channel */
    rc = ble_phy_setchan(advsm->adv_chan, BLE_ACCESS_ADDR_ADV, BLE_LL_CRCINIT_ADV);
    BLE_LL_ASSERT(rc == 0);

#if MYNEWT_VAL(BLE_LL_PHY)
    /* Set phy mode */
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
        ble_phy_mode_set(BLE_PHY_MODE_1M, BLE_PHY_MODE_1M);
    } else {
        ble_phy_mode_set(advsm->pri_phy, advsm->pri_phy);
    }
#else
    ble_phy_mode_set(BLE_PHY_MODE_1M, BLE_PHY_MODE_1M);
#endif
#endif

    /* Set the power */
    ble_ll_tx_power_set(advsm->tx_power);

    /* Set transmit start time. */
    txstart = sch->start_time + g_ble_ll_sched_offset_ticks;
    rc = ble_phy_tx_set_start_time(txstart, sch->remainder);
    if (rc) {
        STATS_INC(ble_ll_stats, adv_late_starts);
        goto adv_tx_done;
    }

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
    ble_phy_encrypt_disable();
#endif

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
    advsm->adv_rpa_index = -1;
    if (ble_ll_resolv_enabled()) {
        ble_phy_resolv_list_enable();
    } else {
        ble_phy_resolv_list_disable();
    }
#endif

    /* We switch to RX after connectable or scannable legacy packets. */
    if ((advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) &&
            ((advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE) ||
             (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE))) {
        end_trans = BLE_PHY_TRANSITION_TX_RX;
        ble_phy_set_txend_cb(NULL, NULL);
    } else {
        end_trans = BLE_PHY_TRANSITION_NONE;
        ble_phy_set_txend_cb(ble_ll_adv_tx_done, advsm);
    }

    /* Transmit advertisement */
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    rc = ble_phy_tx(ble_ll_adv_pdu_make, advsm, end_trans);
#else
    rc = ble_phy_tx(ble_ll_adv_legacy_pdu_make, advsm, end_trans);
#endif
    if (rc) {
        goto adv_tx_done;
    }

    /* Enable/disable whitelisting based on filter policy */
    if (advsm->adv_filter_policy != BLE_HCI_ADV_FILT_NONE) {
        ble_ll_whitelist_enable();
    } else {
        ble_ll_whitelist_disable();
    }

    /* Set link layer state to advertising */
    ble_ll_state_set(BLE_LL_STATE_ADV);

    /* Count # of adv. sent */
    STATS_INC(ble_ll_stats, adv_txg);

    return BLE_LL_SCHED_STATE_RUNNING;

adv_tx_done:
    ble_ll_adv_tx_done(advsm);
    return BLE_LL_SCHED_STATE_DONE;
}

static void
ble_ll_adv_set_sched(struct ble_ll_adv_sm *advsm)
{
    uint32_t max_usecs;
    struct ble_ll_sched_item *sch;

    sch = &advsm->adv_sch;
    sch->cb_arg = advsm;
    sch->sched_cb = ble_ll_adv_tx_start_cb;
    sch->sched_type = BLE_LL_SCHED_TYPE_ADV;

    /* Set end time to maximum time this schedule item may take */
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
        max_usecs = ble_ll_pdu_us(advsm->adv_pdu_len, BLE_PHY_MODE_1M);

        if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED) {
            max_usecs += BLE_LL_SCHED_DIRECT_ADV_MAX_USECS;
        } else if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE) {
            max_usecs += BLE_LL_SCHED_ADV_MAX_USECS;
        }
    } else {
        /*
         * In ADV_EXT_IND we always set only ADI and AUX so the payload length
         * is always 7 bytes.
         */
        max_usecs = ble_ll_pdu_us(7, advsm->pri_phy);
    }
#else
    max_usecs = ble_ll_pdu_us(advsm->adv_pdu_len, BLE_PHY_MODE_1M);

    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED) {
        max_usecs += BLE_LL_SCHED_DIRECT_ADV_MAX_USECS;
    } else if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE) {
        max_usecs += BLE_LL_SCHED_ADV_MAX_USECS;
    }
#endif

    sch->start_time = advsm->adv_pdu_start_time - g_ble_ll_sched_offset_ticks;
    sch->remainder = 0;
    sch->end_time = advsm->adv_pdu_start_time + ble_ll_tmr_u2t_up(max_usecs);
}

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
static int
ble_ll_adv_secondary_tx_start_cb(struct ble_ll_sched_item *sch)
{
    int rc;
    uint8_t end_trans;
    uint32_t txstart;
    struct ble_ll_adv_sm *advsm;
    ble_phy_tx_pducb_t pducb;
    struct ble_ll_adv_aux *aux;

    /* Get the state machine for the event */
    advsm = (struct ble_ll_adv_sm *)sch->cb_arg;

    /* Set the current advertiser */
    g_ble_ll_cur_adv_sm = advsm;

    ble_ll_adv_active_chanset_set_sec(advsm);

    /* Set channel */
    aux = AUX_CURRENT(advsm);
    rc = ble_phy_setchan(aux->chan, BLE_ACCESS_ADDR_ADV,
                         BLE_LL_CRCINIT_ADV);
    BLE_LL_ASSERT(rc == 0);

#if MYNEWT_VAL(BLE_LL_PHY)
    /* Set phy mode */
     ble_phy_mode_set(advsm->sec_phy, advsm->sec_phy);
#endif

    /* Set the power */
    ble_ll_tx_power_set(advsm->tx_power);

    /* Set transmit start time. */
    txstart = sch->start_time + g_ble_ll_sched_offset_ticks;
    rc = ble_phy_tx_set_start_time(txstart, sch->remainder);
    if (rc) {
        STATS_INC(ble_ll_stats, adv_late_starts);
        goto adv_aux_dropped;
    }

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
    ble_phy_encrypt_disable();
#endif

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
    advsm->adv_rpa_index = -1;
    if (ble_ll_resolv_enabled()) {
        ble_phy_resolv_list_enable();
    } else {
        ble_phy_resolv_list_disable();
    }
#endif

    /* Set phy mode based on type of advertisement */
    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE) {
        end_trans = BLE_PHY_TRANSITION_TX_RX;
        ble_phy_set_txend_cb(NULL, NULL);
        pducb = ble_ll_adv_aux_pdu_make;
    } else if ((advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE) &&
               advsm->aux_first_pdu) {
        end_trans = BLE_PHY_TRANSITION_TX_RX;
        ble_phy_set_txend_cb(NULL, NULL);
        pducb = ble_ll_adv_aux_scannable_pdu_make;
    } else {
        end_trans = BLE_PHY_TRANSITION_NONE;
        ble_phy_set_txend_cb(ble_ll_adv_tx_done, advsm);
        pducb = ble_ll_adv_aux_pdu_make;
    }

    /* Transmit advertisement */
    rc = ble_phy_tx(pducb, advsm, end_trans);
    if (rc) {
        goto adv_aux_dropped;
    }

    /* Enable/disable whitelisting based on filter policy */
    if (advsm->adv_filter_policy != BLE_HCI_ADV_FILT_NONE) {
        ble_ll_whitelist_enable();
    } else {
        ble_ll_whitelist_disable();
    }

    /* Set link layer state to advertising */
    ble_ll_state_set(BLE_LL_STATE_ADV);

    /* Count # of adv. sent */
    STATS_INC(ble_ll_stats, adv_txg);

    return BLE_LL_SCHED_STATE_RUNNING;

adv_aux_dropped:
    advsm->aux_dropped = 1;
    ble_ll_adv_tx_done(advsm);
    return BLE_LL_SCHED_STATE_DONE;
}

static uint8_t
ble_ll_adv_aux_scannable_pdu_payload_len(struct ble_ll_adv_sm *advsm)
{
    uint8_t len;

    /* Flags, ADI always */
    len = BLE_LL_EXT_ADV_HDR_LEN + BLE_LL_EXT_ADV_FLAGS_SIZE
            + BLE_LL_EXT_ADV_DATA_INFO_SIZE;

    /* AdvA if not anonymous */
    if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV)) {
        len += BLE_LL_EXT_ADV_ADVA_SIZE;
    }

    /* TargetA only for directed */
    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED) {
        len += BLE_LL_EXT_ADV_TARGETA_SIZE;
    }

    /* TxPower if configured */
    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_INC_TX_PWR) {
        len += BLE_LL_EXT_ADV_TX_POWER_SIZE;
    }

    return len;
}

static uint16_t
ble_ll_adv_aux_calculate_payload(struct ble_ll_adv_sm *advsm, uint16_t props,
                                 struct os_mbuf *data, uint32_t data_offset,
                                 uint8_t *data_len_o, uint8_t *ext_hdr_flags_o)
{
    uint16_t rem_data_len;
    uint8_t data_len;
    uint8_t ext_hdr_flags;
    uint8_t ext_hdr_len;
    bool chainable;
    bool first_pdu;

    /* Note: advsm shall only be used to check if periodic advertising is
     *       enabled, other parameters in advsm may have different values than
     *       those we want to check (e.g. when reconfiguring instance).
     */

    rem_data_len = (data ? OS_MBUF_PKTLEN(data) : 0) - data_offset;
    BLE_LL_ASSERT((int16_t)rem_data_len >= 0);

    first_pdu = (data_offset == 0);
    chainable = !(props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE);

    ext_hdr_flags = 0;
    ext_hdr_len = BLE_LL_EXT_ADV_HDR_LEN;

    /* ADI for anything but scannable */
    if (!(props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE)) {
        ext_hdr_flags |= (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT);
        ext_hdr_len += BLE_LL_EXT_ADV_DATA_INFO_SIZE;
    }

    /* AdvA in 1st PDU, except for anonymous */
    if (first_pdu &&
        !(props & BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV)) {
        ext_hdr_flags |= (1 << BLE_LL_EXT_ADV_ADVA_BIT);
        ext_hdr_len += BLE_LL_EXT_ADV_ADVA_SIZE;
    }

    /* TargetA in 1st PDU, if directed
     *
     * Note that for scannable this calculates AUX_SCAN_RSP which shall not
     * include TargetA (see: Core 5.3, Vol 6, Part B, 2.3.2.3). For scannable
     * TargetA is included in AUX_ADV_IND which is in that case calculated in
     * ble_ll_adv_aux_schedule_first().
     */
    if (first_pdu &&
        (props & BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED) &&
        !(props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE)) {
        ext_hdr_flags |= (1 << BLE_LL_EXT_ADV_TARGETA_BIT);
        ext_hdr_len += BLE_LL_EXT_ADV_TARGETA_SIZE;
    }

    /* TxPower in 1st PDU, if configured */
    if (first_pdu &&
        (props & BLE_HCI_LE_SET_EXT_ADV_PROP_INC_TX_PWR)) {
        ext_hdr_flags |= (1 << BLE_LL_EXT_ADV_TX_POWER_BIT);
        ext_hdr_len += BLE_LL_EXT_ADV_TX_POWER_SIZE;
    }

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV)
    /* SyncInfo in 1st PDU, if periodic advertising is enabled */
    if (first_pdu && advsm->periodic_adv_active) {
        ext_hdr_flags |= (1 << BLE_LL_EXT_ADV_SYNC_INFO_BIT);
        ext_hdr_len += BLE_LL_EXT_ADV_SYNC_INFO_SIZE;
    }
#endif

    /* Flags, if any field is present in header
     *
     * Note that this does not account for AuxPtr which is added later if
     * remaining data does not fit in single PDU.
     */
    if (ext_hdr_flags) {
        ext_hdr_len += BLE_LL_EXT_ADV_FLAGS_SIZE;
    }

    /* AdvData */
    data_len = MIN(BLE_LL_MAX_PAYLOAD_LEN - ext_hdr_len, rem_data_len);

    /* AuxPtr if there are more AdvData remaining that we can fit here */
    if (chainable && (rem_data_len > data_len)) {
        /* Add flags if not already added */
        if (!ext_hdr_flags) {
            ext_hdr_len += BLE_LL_EXT_ADV_FLAGS_SIZE;
            data_len -= BLE_LL_EXT_ADV_FLAGS_SIZE;
        }

        ext_hdr_flags |= (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT);
        ext_hdr_len += BLE_LL_EXT_ADV_AUX_PTR_SIZE;

        data_len -= BLE_LL_EXT_ADV_AUX_PTR_SIZE;

        /* PDU payload should be full if adding AuxPtr */
        BLE_LL_ASSERT(ext_hdr_len + data_len == BLE_LL_MAX_PAYLOAD_LEN);
    }

    *data_len_o = data_len;
    *ext_hdr_flags_o = ext_hdr_flags;

    return ext_hdr_len + data_len;
}

static void
ble_ll_adv_aux_calculate(struct ble_ll_adv_sm *advsm,
                         struct ble_ll_adv_aux *aux, uint16_t data_offset)
{
    BLE_LL_ASSERT(!aux->sch.enqueued);
    BLE_LL_ASSERT((AUX_DATA_LEN(advsm) > data_offset) ||
                  (AUX_DATA_LEN(advsm) == 0 && data_offset == 0));

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2)
    aux->chan = ble_ll_utils_dci_csa2(advsm->event_cntr++,
                                      advsm->channel_id,
                                      g_ble_ll_data.chan_map_used,
                                      g_ble_ll_data.chan_map);
#else
    aux->chan = ble_ll_utils_remapped_channel(ble_ll_rand() % BLE_PHY_NUM_DATA_CHANS,
                                              g_ble_ll_data.chan_map);
#endif

    aux->data_offset = data_offset;
    aux->payload_len = ble_ll_adv_aux_calculate_payload(advsm, advsm->props,
                                                        *advsm->aux_data,
                                                        data_offset,
                                                        &aux->data_len,
                                                        &aux->ext_hdr_flags);
}

static bool
ble_ll_adv_aux_check_data_itvl(struct ble_ll_adv_sm *advsm, uint16_t props,
                               uint8_t pri_phy, uint8_t sec_phy,
                               struct os_mbuf *data, uint32_t interval_us)
{
    uint32_t max_usecs;
    uint16_t data_offset;
    uint16_t pdu_len;
    uint8_t data_len;
    uint8_t ext_hdr_flags;

    /* FIXME:
     * We should include PDUs on primary channel when calculating advertising
     * event duration, but the actual time varies a bit in our case due to
     * scheduling. For now let's assume we always schedule all PDUs 300us apart
     * and we use shortest possible payload (ADI+AuxPtr, no AdvA).
     *
     * Note that calculations below do not take channel map and max skip into
     * account, but we do not support max skip anyway for now.
     */

    max_usecs = 3 * (ble_ll_pdu_us(7, pri_phy) + 300) +
                BLE_LL_MAFS + MYNEWT_VAL(BLE_LL_SCHED_AUX_MAFS_DELAY);

    data_offset = 0;

    do {
        pdu_len = ble_ll_adv_aux_calculate_payload(advsm, props, data, data_offset,
                                                   &data_len, &ext_hdr_flags);

        max_usecs += ble_ll_pdu_us(pdu_len, sec_phy);
        max_usecs += BLE_LL_MAFS + MYNEWT_VAL(BLE_LL_SCHED_AUX_CHAIN_MAFS_DELAY);

        data_offset += data_len;

    } while (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT));

    return max_usecs < interval_us;
}

static void
ble_ll_adv_aux_scheduled(struct ble_ll_adv_sm *advsm, uint32_t sch_start,
                         void *arg)
{
    struct ble_ll_adv_aux *aux = arg;

    aux->start_time = sch_start + g_ble_ll_sched_offset_ticks;
}

static void
ble_ll_adv_aux_schedule_next(struct ble_ll_adv_sm *advsm)
{
    struct ble_ll_adv_aux *aux;
    struct ble_ll_adv_aux *aux_next;
    struct ble_ll_sched_item *sch;
    uint16_t rem_data_len;
    uint16_t next_data_offset;
    uint32_t max_usecs;

    BLE_LL_ASSERT(advsm->aux_active);

    aux = AUX_CURRENT(advsm);
    aux_next = AUX_NEXT(advsm);

    BLE_LL_ASSERT(!aux_next->sch.enqueued);

    /*
     * Do not schedule next aux if current aux is no longer scheduled since we
     * do not have reference time for scheduling.
     */
    if (!aux->sch.enqueued) {
        return;
    }

    /*
     * Do not schedule next aux if current aux does not have AuxPtr in extended
     * header as this means we do not need subsequent ADV_CHAIN_IND to be sent.
     */
    if (!(aux->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT))) {
        return;
    }

    next_data_offset = aux->data_offset + aux->data_len;

    BLE_LL_ASSERT(AUX_DATA_LEN(advsm) >= next_data_offset);

    rem_data_len = AUX_DATA_LEN(advsm) - next_data_offset;
    BLE_LL_ASSERT(rem_data_len > 0);

    ble_ll_adv_aux_calculate(advsm, aux_next, next_data_offset);
    max_usecs = ble_ll_pdu_us(aux_next->payload_len, advsm->sec_phy);

    aux_next->start_time = aux->sch.end_time +
                           ble_ll_tmr_u2t_up(BLE_LL_MAFS +
                                             MYNEWT_VAL(BLE_LL_SCHED_AUX_CHAIN_MAFS_DELAY));

    sch = &aux_next->sch;
    sch->start_time = aux_next->start_time - g_ble_ll_sched_offset_ticks;
    sch->remainder = 0;
    sch->end_time = aux_next->start_time + ble_ll_tmr_u2t_up(max_usecs);
    ble_ll_sched_adv_new(&aux_next->sch, ble_ll_adv_aux_scheduled, aux_next);

    /* Remove aux if previous one was already sent with zero offset or new one
     * is scheduled past advertising duration (if set).
     */
    if (aux->auxptr_zero ||
        (advsm->duration && LL_TMR_GT(aux_next->sch.end_time,
                                      advsm->adv_end_time))) {
        ble_ll_sched_rmv_elem(&aux_next->sch);
    }
}

static void
ble_ll_adv_aux_schedule_first(struct ble_ll_adv_sm *advsm)
{
    struct ble_ll_adv_aux *aux;
    struct ble_ll_sched_item *sch;
    uint32_t max_usecs;

    BLE_LL_ASSERT(!advsm->aux_active);
    BLE_LL_ASSERT(!advsm->aux[0].sch.enqueued);
    BLE_LL_ASSERT(!advsm->aux[1].sch.enqueued);

    advsm->aux_active = 1;
    advsm->aux_index = 0;
    advsm->aux_first_pdu = 1;
    advsm->aux_not_scanned = 0;
    advsm->aux_dropped = 0;

    aux = AUX_CURRENT(advsm);
    aux->auxptr_zero = 0;
    ble_ll_adv_aux_calculate(advsm, aux, 0);

    /* Set end time to maximum time this schedule item may take */
    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE) {
        max_usecs = ble_ll_pdu_us(aux->payload_len, advsm->sec_phy) +
                    BLE_LL_IFS +
                    /* AUX_CONN_REQ */
                    ble_ll_pdu_us(34 + 14, advsm->sec_phy)  +
                    BLE_LL_IFS +
                    /* AUX_CONN_RSP */
                    ble_ll_pdu_us(14, advsm->sec_phy);
    } else if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE) {
        /* For scannable advertising we need to calculate how much time we
         * need for AUX_ADV_IND along with AUX_SCAN_REQ, AUX_SCAN_RSP and
         * IFS in between.
         *
         * Note:
         *  1. aux->payload_len, which calculated by above ble_ll_adv_aux_calulcate(),
         * contains AUX_SCAN_RSP length.
         *  2. length of AUX_ADV_IND is calculated by special function:
         *      ble_ll_adv_aux_scannable_pdu_payload_len()
         */
        max_usecs = ble_ll_pdu_us(ble_ll_adv_aux_scannable_pdu_payload_len(advsm),
                                           advsm->sec_phy) +
                    BLE_LL_IFS +
                    /* AUX_SCAN_REQ */
                    ble_ll_pdu_us(12, advsm->sec_phy)  +
                    BLE_LL_IFS +
                    /* AUX_SCAN_RSP */
                    ble_ll_pdu_us(aux->payload_len, advsm->sec_phy);
    } else {
        max_usecs = ble_ll_pdu_us(aux->payload_len, advsm->sec_phy);
    }

    sch = &aux->sch;
    sch->start_time = aux->start_time - g_ble_ll_sched_offset_ticks;
    sch->remainder = 0;
    sch->end_time = aux->start_time + ble_ll_tmr_u2t_up(max_usecs);
    ble_ll_sched_adv_new(sch, ble_ll_adv_aux_scheduled, aux);
}

static void
ble_ll_adv_aux_set_start_time(struct ble_ll_adv_sm *advsm)
{
    static const uint8_t bits[8] = {0, 1, 1, 2, 1, 2, 2, 3};
    struct ble_ll_sched_item *sched = &advsm->adv_sch;
    uint32_t adv_pdu_dur;
    uint32_t adv_event_dur;
    uint8_t chans;

    BLE_LL_ASSERT(!advsm->aux_active);
    BLE_LL_ASSERT(!advsm->aux[0].sch.enqueued);
    BLE_LL_ASSERT(!advsm->aux[1].sch.enqueued);

    assert(advsm->adv_chanmask > 0 &&
           advsm->adv_chanmask <= BLE_HCI_ADV_CHANMASK_DEF);

    chans = bits[advsm->adv_chanmask];

    adv_pdu_dur = (int32_t)(sched->end_time - sched->start_time) -
                  g_ble_ll_sched_offset_ticks;

    /* The interval between advertising PDUs may vary due to scheduling, but in
     * general we reserve 3 ticks for end-to-schedule time and add scheduler
     * offset. That should be more that enough to make sure there's at least
     * T_mafs delay between last advertising PDU and auxiliary PDU.
     *
     * TODO we can make this much more efficient with TX-TX transition
     */
    adv_event_dur = (adv_pdu_dur * chans) +
                    ((3 + g_ble_ll_sched_offset_ticks) * (chans - 1));

    advsm->aux[0].start_time = advsm->adv_event_start_time + adv_event_dur +
                               ble_ll_tmr_u2t_up(BLE_LL_MAFS +
                                                 MYNEWT_VAL(BLE_LL_SCHED_AUX_MAFS_DELAY));
}

static void
ble_ll_adv_aux_schedule(struct ble_ll_adv_sm *advsm)
{
    /*
     * For secondary channel we always start by scheduling two consecutive
     * auxiliary packets at once. Then, after sending one packet we try to
     * schedule another one as long as there are some data left to send. This
     * is to make sure we can always calculate AuxPtr to subsequent packet
     * without need to scheduled it in an interrupt.
     */

    ble_ll_adv_aux_set_start_time(advsm);
    ble_ll_adv_aux_schedule_first(advsm);
    ble_ll_adv_aux_schedule_next(advsm);

    /*
     * In case duration is set for advertising set we need to check if at least
     * 1st aux will fit inside duration. If not, stop advertising now so we do
     * not start extended advertising event which we cannot finish in time.
     */
    if (advsm->duration &&
        LL_TMR_GT(AUX_CURRENT(advsm)->sch.end_time, advsm->adv_end_time)) {
        ble_ll_adv_sm_stop_timeout(advsm);
    }
}
#endif

/**
 * Called when advertising need to be halted. This normally should not be called
 * and is only called when a scheduled item executes but advertising is still
 * running.
 *
 * Context: Interrupt
 */
void
ble_ll_adv_halt(void)
{
    struct ble_ll_adv_sm *advsm;

    if (g_ble_ll_cur_adv_sm != NULL) {
        advsm = g_ble_ll_cur_adv_sm;

        ble_ll_trace_u32(BLE_LL_TRACE_ID_ADV_HALT, advsm->adv_instance);

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV)
        if (advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING) {
            ble_ll_adv_flags_clear(advsm,
                                   BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING);
            ble_ll_event_add(&advsm->adv_periodic_txdone_ev);
            ble_ll_state_set(BLE_LL_STATE_STANDBY);
            g_ble_ll_cur_adv_sm = NULL;
            return;
        }
#endif

        ble_ll_event_add(&advsm->adv_txdone_ev);
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
        if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY)) {
            ble_ll_event_add(&advsm->adv_sec_txdone_ev);
        }
#endif

        ble_ll_state_set(BLE_LL_STATE_STANDBY);
        ble_ll_adv_active_chanset_clear(g_ble_ll_cur_adv_sm);
        g_ble_ll_cur_adv_sm = NULL;
    } else {
        ble_ll_trace_u32(BLE_LL_TRACE_ID_ADV_HALT, UINT32_MAX);
    }
}

/**
 * Called by the HCI command parser when a set advertising parameters command
 * has been received.
 *
 * Context: Link Layer task (HCI command parser)
 *
 * @param cmd
 *
 * @return int
 */
int
ble_ll_adv_set_adv_params(const uint8_t *cmdbuf, uint8_t len)
{
    const struct ble_hci_le_set_adv_params_cp *cmd = (const void *) cmdbuf;
    struct ble_ll_adv_sm *advsm;
    uint8_t adv_filter_policy;
    uint16_t adv_itvl_min;
    uint16_t adv_itvl_max;
    uint32_t adv_itvl_usecs;
    uint16_t props;

    if (len != sizeof(*cmd)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    advsm = &g_ble_ll_adv_sm[0];
    if (advsm->adv_enabled) {
        return BLE_ERR_CMD_DISALLOWED;
    }

    /* Make sure intervals are OK (along with advertising type */
    adv_itvl_min = le16toh(cmd->min_interval);
    adv_itvl_max = le16toh(cmd->max_interval);

    /*
     * Get the filter policy now since we will ignore it if we are doing
     * directed advertising
     */
    adv_filter_policy = cmd->filter_policy;

    switch (cmd->type) {
#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL)
    case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD:
        adv_filter_policy = BLE_HCI_ADV_FILT_NONE;
        memcpy(advsm->peer_addr, cmd->peer_addr, BLE_DEV_ADDR_LEN);

        /* Ignore min/max interval */
        adv_itvl_min = 0;
        adv_itvl_max = 0;

        props = BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_HD_DIR ;
        break;
    case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD:
        adv_filter_policy = BLE_HCI_ADV_FILT_NONE;
        memcpy(advsm->peer_addr, cmd->peer_addr, BLE_DEV_ADDR_LEN);

        props = BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_LD_DIR ;
        break;
    case BLE_HCI_ADV_TYPE_ADV_IND:
        props = BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_IND;
        break;
#endif
    case BLE_HCI_ADV_TYPE_ADV_NONCONN_IND:
        props = BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_NONCONN;
        break;
    case BLE_HCI_ADV_TYPE_ADV_SCAN_IND:
        props = BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_SCAN;
        break;
    default:
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* Make sure intervals values are valid
     * (HD directed advertising ignores those parameters)
     */
    if (!(props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED)) {
        if ((adv_itvl_min > adv_itvl_max) ||
                (adv_itvl_min < BLE_HCI_ADV_ITVL_MIN) ||
                (adv_itvl_min > BLE_HCI_ADV_ITVL_MAX) ||
                (adv_itvl_max < BLE_HCI_ADV_ITVL_MIN) ||
                (adv_itvl_max > BLE_HCI_ADV_ITVL_MAX)) {
            return BLE_ERR_INV_HCI_CMD_PARMS;
        }
    }

    if ((cmd->own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) ||
        (cmd->peer_addr_type > BLE_HCI_ADV_PEER_ADDR_MAX)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    advsm->tx_power = ble_ll_tx_power_round(g_ble_ll_tx_power - g_ble_ll_tx_power_compensation);

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
    if (cmd->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) {
        /* Copy peer address */
        memcpy(advsm->peer_addr, cmd->peer_addr, BLE_DEV_ADDR_LEN);
    }
#else
    /* If we dont support privacy some address types wont work */
    if (cmd->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) {
        return BLE_ERR_UNSUPPORTED;
    }
#endif

    /* There are only three adv channels, so check for any outside the range */
    if (((cmd->chan_map & 0xF8) != 0) || (cmd->chan_map == 0)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* Check for valid filter policy */
    if (adv_filter_policy > BLE_HCI_ADV_FILT_MAX) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* Determine the advertising interval we will use */
    if (props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) {
        /* Set it to max. allowed for high duty cycle advertising */
        adv_itvl_usecs = BLE_LL_ADV_PDU_ITVL_HD_MS_MAX;
    } else {
        adv_itvl_usecs = adv_itvl_max * BLE_LL_ADV_ITVL;
    }

    /* Fill out rest of advertising state machine */
    advsm->own_addr_type = cmd->own_addr_type;
    advsm->peer_addr_type = cmd->peer_addr_type;
    advsm->adv_filter_policy = adv_filter_policy;
    advsm->adv_chanmask = cmd->chan_map;
    advsm->adv_itvl_usecs = adv_itvl_usecs;
    advsm->props = props;

    return 0;
}

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
static void
ble_ll_adv_update_did(struct ble_ll_adv_sm *advsm)
{
    uint16_t old_adi = advsm->adi;

    /*
     * The Advertising DID for a given advertising set shall be initialized
     * with a randomly chosen value. Whenever the Host provides new advertising
     * data or scan response data for a given advertising set (whether it is the
     * same as the previous data or not), the Advertising DID shall be updated.
     * The new value shall be a randomly chosen value that is not the same as
     * the previously used value.
     */
    do {
        advsm->adi = (advsm->adi & 0xf000) | (ble_ll_rand() & 0x0fff);
    } while (old_adi == advsm->adi);
}
#endif

static void
ble_ll_adv_update_adv_scan_rsp_data(struct ble_ll_adv_sm *advsm)
{
    if (!(advsm->flags & BLE_LL_ADV_SM_FLAG_NEW_ADV_DATA) &&
                    !(advsm->flags & BLE_LL_ADV_SM_FLAG_NEW_SCAN_RSP_DATA)) {
        return;
    }

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    if (advsm->aux_active) {
        return;
    }
#endif

    if (advsm->flags & BLE_LL_ADV_SM_FLAG_NEW_ADV_DATA) {
        if (advsm->new_adv_data) {
            os_mbuf_free_chain(advsm->adv_data);
            advsm->adv_data = advsm->new_adv_data;
            advsm->new_adv_data = NULL;
        }
        ble_ll_adv_flags_clear(advsm, BLE_LL_ADV_SM_FLAG_NEW_ADV_DATA);
    } else if (advsm->flags & BLE_LL_ADV_SM_FLAG_NEW_SCAN_RSP_DATA) {
        os_mbuf_free_chain(advsm->scan_rsp_data);
        advsm->scan_rsp_data = advsm->new_scan_rsp_data;
        advsm->new_scan_rsp_data = NULL;
        ble_ll_adv_flags_clear(advsm, BLE_LL_ADV_SM_FLAG_NEW_SCAN_RSP_DATA);
    }

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    /* DID shall be updated when host provides new advertising data */
    ble_ll_adv_update_did(advsm);
#endif
}

/**
 * Stop advertising state machine
 *
 * Context: Link Layer task.
 *
 * @param advsm
 */
static void
ble_ll_adv_sm_stop(struct ble_ll_adv_sm *advsm)
{
    os_sr_t sr;

    if (advsm->adv_enabled) {
        ble_ll_rfmgmt_release();

        /* Remove any scheduled advertising items */
        ble_ll_sched_rmv_elem(&advsm->adv_sch);
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
        advsm->aux_active = 0;
        ble_ll_sched_rmv_elem(&advsm->aux[0].sch);
        ble_ll_sched_rmv_elem(&advsm->aux[1].sch);
#endif

        /* Set to standby if we are no longer advertising */
        OS_ENTER_CRITICAL(sr);
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
        if ((g_ble_ll_cur_adv_sm == advsm) &&
               !(advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING)) {
            ble_phy_disable();
            ble_ll_state_set(BLE_LL_STATE_STANDBY);
            g_ble_ll_cur_adv_sm = NULL;
            ble_ll_scan_chk_resume();
        }
#else
        if (ble_ll_state_get() == BLE_LL_STATE_ADV) {
            ble_phy_disable();
            ble_ll_state_set(BLE_LL_STATE_STANDBY);
            g_ble_ll_cur_adv_sm = NULL;
            ble_ll_scan_chk_resume();
        }
#endif
        OS_EXIT_CRITICAL(sr);

        ble_ll_event_remove(&advsm->adv_txdone_ev);
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
        ble_ll_event_remove(&advsm->adv_sec_txdone_ev);
#endif

#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL)
        /* If there is an event buf we need to free it */
        if (advsm->conn_comp_ev) {
            ble_transport_free(advsm->conn_comp_ev);
            advsm->conn_comp_ev = NULL;
        }
#endif

        ble_ll_adv_active_chanset_clear(advsm);

        /* Disable advertising */
        advsm->adv_enabled = 0;

        /* Check if there is outstanding update */
        ble_ll_adv_update_adv_scan_rsp_data(advsm);
    }
}

static void
ble_ll_adv_sm_stop_timeout(struct ble_ll_adv_sm *advsm)
{
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    if (ble_ll_hci_adv_mode_ext()) {
        ble_ll_hci_ev_send_adv_set_terminated(BLE_ERR_DIR_ADV_TMO,
                                                        advsm->adv_instance, 0,
                                                        advsm->events);
    }
#endif

#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL)
    /*
     * For high duty directed advertising we need to send connection
     * complete event with proper status
     */
    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) {
        ble_ll_conn_comp_event_send(NULL, BLE_ERR_DIR_ADV_TMO,
                                    advsm->conn_comp_ev, advsm);
        advsm->conn_comp_ev = NULL;
    }
#endif

    /* Disable advertising */
    ble_ll_adv_sm_stop(advsm);
}

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
static void
ble_ll_adv_sm_stop_limit_reached(struct ble_ll_adv_sm *advsm)
{
    ble_ll_hci_ev_send_adv_set_terminated(BLE_ERR_LIMIT_REACHED,
                                          advsm->adv_instance, 0,
                                          advsm->events);

    /*
     * For high duty directed advertising we need to send connection
     * complete event with proper status
     *
     * Spec is a bit unambiguous here since it doesn't define what code should
     * be used if HD directed advertising was terminated before timeout due to
     * events count limit. For now just use same code as with duration timeout.
     */
#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL)
    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) {
        ble_ll_conn_comp_event_send(NULL, BLE_ERR_DIR_ADV_TMO,
                                    advsm->conn_comp_ev, advsm);
        advsm->conn_comp_ev = NULL;
    }
#endif

    /* Disable advertising */
    ble_ll_adv_sm_stop(advsm);
}
#endif

static void
ble_ll_adv_scheduled(struct ble_ll_adv_sm *advsm, uint32_t sch_start, void *arg)
{
    /* The event start time is when we start transmission of the adv PDU */
    advsm->adv_event_start_time = sch_start + g_ble_ll_sched_offset_ticks;
    advsm->adv_pdu_start_time = advsm->adv_event_start_time;

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    /* this is validated for HD adv so no need to do additional checks here
     * duration is in 10ms units
     */
    if (advsm->duration) {
        advsm->adv_end_time = advsm->adv_event_start_time +
                             ble_ll_tmr_u2t(advsm->duration * 10000);
    }
#else
    /* Set the time at which we must end directed, high-duty cycle advertising.
     */
    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) {
        advsm->adv_end_time = advsm->adv_event_start_time +
                     ble_ll_tmr_u2t(BLE_LL_ADV_STATE_HD_MAX * 1000);
    }
#endif
}

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV)
static uint8_t
ble_ll_adv_sync_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte)
{
    struct ble_ll_adv_sm *advsm;
    struct ble_ll_adv_sync *sync;
    uint8_t adv_mode;
    uint8_t pdu_type;
    uint8_t ext_hdr_len;
#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
    uint8_t biginfo_len;
#endif
    uint32_t offset;

    advsm = pducb_arg;
    sync = SYNC_CURRENT(advsm);

    BLE_LL_ASSERT(!ble_ll_adv_active_chanset_is_sec(advsm));
    BLE_LL_ASSERT(advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING);

    /* It's the same for AUX_SYNC_IND and AUX_CHAIN_IND */
    pdu_type = BLE_ADV_PDU_TYPE_AUX_SYNC_IND;

    /* non-connectable and non-scannable */
    adv_mode = 0;

    ext_hdr_len = sync->payload_len - BLE_LL_EXT_ADV_HDR_LEN - sync->data_len;
    dptr[0] = (adv_mode << 6) | ext_hdr_len;
    dptr += 1;

    /* only put flags if needed */
#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
    if (sync->ext_hdr_flags || sync->big) {
        dptr[0] = sync->ext_hdr_flags;
        dptr += 1;
    }
#else
    if (sync->ext_hdr_flags) {
        dptr[0] = sync->ext_hdr_flags;
        dptr += 1;
    }
#endif

    if (sync->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)) {
        if (!SYNC_NEXT(advsm)->sch.enqueued) {
            /*
             * Trim data here in case we do not have next sync scheduled. This
             * can happen if next sync was outside advertising set period and
             * was removed from scheduler.
             */
            offset = 0;
        } else {
            offset = ble_ll_tmr_t2u(SYNC_NEXT(advsm)->start_time -
                                    sync->start_time);
        }

        sync->auxptr_zero = offset == 0;

        ble_ll_adv_put_aux_ptr(SYNC_NEXT(advsm)->chan, advsm->sec_phy,
                               offset, dptr);

        dptr += BLE_LL_EXT_ADV_AUX_PTR_SIZE;
    }

    if (sync->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_TX_POWER_BIT)) {
        dptr[0] = advsm->tx_power + g_ble_ll_tx_power_compensation;
        dptr += BLE_LL_EXT_ADV_TX_POWER_SIZE;
    }

#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
    if (advsm->big) {
        biginfo_len = ble_ll_iso_big_biginfo_copy(advsm->big, dptr,
                                                  sync->sch.start_time +
                                                  g_ble_ll_sched_offset_ticks,
                                                  sync->sch.remainder);
        BLE_LL_ASSERT(biginfo_len > 0);

        dptr += biginfo_len;
    }
#endif

    if (sync->data_len) {
        os_mbuf_copydata(advsm->periodic_adv_data, sync->data_offset,
                         sync->data_len, dptr);
    }

    *hdr_byte = pdu_type;

    return sync->payload_len;
}


static void
ble_ll_adv_sync_tx_done(struct ble_ll_adv_sm *advsm)
{
    /* for sync we trace a no pri nor sec set */
    ble_ll_trace_u32x2(BLE_LL_TRACE_ID_ADV_TXDONE, advsm->adv_instance, 0);

    BLE_LL_ASSERT(advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING);
    BLE_LL_ASSERT(!ble_ll_adv_active_chanset_is_sec(advsm));

    ble_ll_event_add(&advsm->adv_periodic_txdone_ev);

    ble_ll_state_set(BLE_LL_STATE_STANDBY);
    ble_ll_adv_flags_clear(advsm, BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING);

    /* We no longer have a current state machine */
    g_ble_ll_cur_adv_sm = NULL;
}

/**
 * Called to indicate the advertising sync event is over.
 *
 * Context: Interrupt
 *
 * @param advsm
 *
 */
static void
ble_ll_adv_sync_tx_end(void *arg)
{
    struct ble_ll_adv_sm *advsm = arg;

    ble_ll_adv_sync_tx_done(advsm);

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER)
    /* store last sent periodic counter */
    advsm->periodic_event_cntr_last_sent = advsm->periodic_event_cntr;
#endif
}

static int
ble_ll_adv_sync_tx_start_cb(struct ble_ll_sched_item *sch)
{
    int rc;
    uint32_t txstart;
    struct ble_ll_adv_sm *advsm;
    struct ble_ll_adv_sync *sync;

    /* Get the state machine for the event */
    advsm = (struct ble_ll_adv_sm *)sch->cb_arg;

    /* Set the current advertiser */
    g_ble_ll_cur_adv_sm = advsm;

    ble_ll_adv_active_chanset_clear(advsm);
    ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING);

    /* Set channel */
    sync = SYNC_CURRENT(advsm);
    rc = ble_phy_setchan(sync->chan, advsm->periodic_access_addr,
                         advsm->periodic_crcinit);

    BLE_LL_ASSERT(rc == 0);

#if MYNEWT_VAL(BLE_LL_PHY)
    /* Set phy mode */
     ble_phy_mode_set(advsm->sec_phy, advsm->sec_phy);
#endif

    /* Set the power */
    ble_ll_tx_power_set(advsm->tx_power);

    /* Set transmit start time. */
    txstart = sch->start_time + g_ble_ll_sched_offset_ticks;
    rc = ble_phy_tx_set_start_time(txstart, sch->remainder);
    if (rc) {
        STATS_INC(ble_ll_stats, adv_late_starts);
        goto adv_tx_done;
    }

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
    ble_phy_encrypt_disable();
#endif

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
    ble_phy_resolv_list_disable();
#endif

    /* Transmit advertisement */
    ble_phy_set_txend_cb(ble_ll_adv_sync_tx_end, advsm);
    rc = ble_phy_tx(ble_ll_adv_sync_pdu_make, advsm, BLE_PHY_TRANSITION_NONE);
    if (rc) {
        goto adv_tx_done;
    }

    /* disable whitelisting, we are always non-connectable non-scannable */
    ble_ll_whitelist_disable();

    /* Set link layer state to advertising */
    ble_ll_state_set(BLE_LL_STATE_ADV);

    /* Count # of adv. sent */
    STATS_INC(ble_ll_stats, adv_txg);

    return BLE_LL_SCHED_STATE_RUNNING;

adv_tx_done:
    ble_ll_adv_sync_tx_done(advsm);
    return BLE_LL_SCHED_STATE_DONE;
}

static void
ble_ll_adv_sync_calculate(struct ble_ll_adv_sm *advsm,
                          struct ble_ll_adv_sync *sync, uint16_t data_offset,
                          uint8_t chan)
{
    uint16_t rem_data_len;
    uint8_t ext_hdr_len;

    BLE_LL_ASSERT(!sync->sch.enqueued);
    BLE_LL_ASSERT((SYNC_DATA_LEN(advsm) > data_offset) ||
                  (SYNC_DATA_LEN(advsm) == 0 && data_offset == 0));

    sync->data_offset = data_offset;
    sync->data_len = 0;
    sync->payload_len = 0;
    sync->ext_hdr_flags = 0;
    sync->chan = chan;

    rem_data_len = SYNC_DATA_LEN(advsm) - data_offset;

    ext_hdr_len = BLE_LL_EXT_ADV_HDR_LEN;

    /* TxPower if configured
     * Note: TxPower shall not be present in chain PDU for SYNC
     */
    if (data_offset == 0 &&
        (advsm->periodic_adv_props & BLE_HCI_LE_SET_PERIODIC_ADV_PROP_INC_TX_PWR)) {
        sync->ext_hdr_flags |= (1 << BLE_LL_EXT_ADV_TX_POWER_BIT);
        ext_hdr_len += BLE_LL_EXT_ADV_TX_POWER_SIZE;
    }

    /* if we have any fields in ext header we need to add flags, note that Aux
     * PTR is handled later and it will account for flags if needed
     *
     * This could be handled inside TxPower but lets keep code consistent with
     * how Aux calculate works and this also make it easier to add more fields
     * into flags if needed in future
     */
#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
    sync->big = advsm->big;
    /* If BIG is present flags will always be also present even if none is set
     * to indicate ACAD is present.
     */
    if (sync->ext_hdr_flags || sync->big) {
        ext_hdr_len += BLE_LL_EXT_ADV_FLAGS_SIZE;
    }
#else
    if (sync->ext_hdr_flags) {
        ext_hdr_len += BLE_LL_EXT_ADV_FLAGS_SIZE;
    }
#endif

#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
    if (advsm->big) {
        ext_hdr_len += ble_ll_iso_big_biginfo_len(advsm->big);
    }
#endif

    /* AdvData always */
    sync->data_len = MIN(BLE_LL_MAX_PAYLOAD_LEN - ext_hdr_len, rem_data_len);

    /* AuxPtr if there are more AdvData remaining that we can fit here */
    if ((rem_data_len > sync->data_len)) {
        /* adjust for flags that needs to be added if AuxPtr is only field
         * in Extended Header
         */
        if (!sync->ext_hdr_flags) {
            ext_hdr_len += BLE_LL_EXT_ADV_FLAGS_SIZE;
            sync->data_len -= BLE_LL_EXT_ADV_FLAGS_SIZE;
        }

        sync->ext_hdr_flags |= (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT);
        ext_hdr_len += BLE_LL_EXT_ADV_AUX_PTR_SIZE;
        sync->data_len -= BLE_LL_EXT_ADV_AUX_PTR_SIZE;

        /* PDU payload should be full if chained */
        BLE_LL_ASSERT(ext_hdr_len + sync->data_len == BLE_LL_MAX_PAYLOAD_LEN);
    }

    sync->payload_len = ext_hdr_len + sync->data_len;
}

static void
ble_ll_adv_periodic_schedule_first(struct ble_ll_adv_sm *advsm,
                                   bool first_pdu)
{
    struct ble_ll_adv_sync *sync;
    struct ble_ll_sched_item *sch;
    uint32_t max_usecs;
    uint8_t chan;
    int rc;

    BLE_LL_ASSERT(!advsm->periodic_sync_active);
    BLE_LL_ASSERT(!advsm->periodic_sync[0].sch.enqueued);
    BLE_LL_ASSERT(!advsm->periodic_sync[1].sch.enqueued);

    advsm->periodic_sync_active = 1;
    advsm->periodic_sync_index = 0;

    sync = SYNC_CURRENT(advsm);
    sync->auxptr_zero = 0;

    /* For first SYNC packet in chain we use separate CSA#2 state to maintain
     * freq hopping as advertised in SyncInfo
     *
     * Preincrement event counter as we later send this in PDU so make sure
     * same values are used
     */
    chan = ble_ll_utils_dci_csa2(++advsm->periodic_event_cntr,
                                 advsm->periodic_channel_id,
                                 advsm->periodic_num_used_chans,
                                 advsm->periodic_chanmap);

    ble_ll_adv_sync_calculate(advsm, sync, 0, chan);

    /* sync is always non-connectable and non-scannable*/
    max_usecs = ble_ll_pdu_us(sync->payload_len, advsm->sec_phy);

    sch = &sync->sch;

    ble_ll_tmr_add_u(&advsm->periodic_adv_event_start_time,
                     &advsm->periodic_adv_event_start_time_remainder,
                     advsm->periodic_adv_itvl_rem_us);

    sch->start_time = advsm->periodic_adv_event_start_time;
    sch->remainder = advsm->periodic_adv_event_start_time_remainder;
    sch->end_time = sch->start_time + ble_ll_tmr_u2t_up(max_usecs);
    sch->start_time -= g_ble_ll_sched_offset_ticks;

    rc = ble_ll_sched_periodic_adv(sch, first_pdu);
    if (rc) {
        STATS_INC(ble_ll_stats, periodic_adv_drop_event);
        ble_ll_event_add(&advsm->adv_periodic_txdone_ev);
        return;
    }

    sync->start_time = sch->start_time + g_ble_ll_sched_offset_ticks;

    assert(first_pdu ||
           (sync->start_time == advsm->periodic_adv_event_start_time));

    /* The event start time is when we start transmission of the SYNC PDU */
    advsm->periodic_adv_event_start_time = sync->start_time;
}

static void
ble_ll_adv_sync_next_scheduled(struct ble_ll_adv_sm *advsm, uint32_t sch_start,
                         void *arg)
{
    struct ble_ll_adv_sync *sync = arg;

    sync->start_time = sch_start + g_ble_ll_sched_offset_ticks;
}

static void
ble_ll_adv_periodic_schedule_next(struct ble_ll_adv_sm *advsm)
{
    struct ble_ll_adv_sync *sync;
    struct ble_ll_adv_sync *sync_next;
    struct ble_ll_sched_item *sch;
    uint16_t rem_data_len;
    uint16_t next_data_offset;
    uint32_t max_usecs;
    uint8_t chan;

    BLE_LL_ASSERT(advsm->periodic_sync_active);

    sync = SYNC_CURRENT(advsm);
    sync_next = SYNC_NEXT(advsm);

    BLE_LL_ASSERT(!sync_next->sch.enqueued);

    /*
     * Do not schedule next sync if current sync is no longer scheduled since we
     * do not have reference time for scheduling.
     */
    if (!sync->sch.enqueued) {
        return;
    }

    /*
     * Do not schedule next sync if current sync does not have AuxPtr in extended
     * header as this means we do not need subsequent ADV_CHAIN_IND to be sent.
     */
    if (!(sync->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT))) {
        return;
    }

    next_data_offset = sync->data_offset + sync->data_len;

    BLE_LL_ASSERT(SYNC_DATA_LEN(advsm) >= next_data_offset);

    rem_data_len = SYNC_DATA_LEN(advsm) - next_data_offset;
    BLE_LL_ASSERT(rem_data_len > 0);

    /* we use separate counter for chaining */
    chan = ble_ll_utils_dci_csa2(advsm->periodic_chain_event_cntr++,
                                 advsm->periodic_channel_id,
                                 advsm->periodic_num_used_chans,
                                 advsm->periodic_chanmap);

    ble_ll_adv_sync_calculate(advsm, sync_next, next_data_offset, chan);
    max_usecs = ble_ll_pdu_us(sync_next->payload_len, advsm->sec_phy);

    sync_next->start_time = sync->sch.end_time +
                            ble_ll_tmr_u2t_up(BLE_LL_MAFS +
                                              MYNEWT_VAL(BLE_LL_SCHED_AUX_CHAIN_MAFS_DELAY));

    sch = &sync_next->sch;
    sch->start_time = sync_next->start_time - g_ble_ll_sched_offset_ticks;

    /* adjust for previous packets remainder */
    sch->remainder = sync->sch.remainder;
    sch->end_time = sync_next->start_time + ble_ll_tmr_u2t_up(max_usecs);

    /* here we can use ble_ll_sched_adv_new as we don't care about timing */
    ble_ll_sched_adv_new(&sync_next->sch, ble_ll_adv_sync_next_scheduled,
                         sync_next);

    /* Remove aux if previous one was already sent with zero offset or new one
     * is scheduled past advertising interval.
     */
    if (sync->auxptr_zero ||
        (LL_TMR_GT(sch->end_time, advsm->periodic_adv_event_start_time +
                                  advsm->periodic_adv_itvl_ticks))) {
        STATS_INC(ble_ll_stats, periodic_chain_drop_event);
        ble_ll_sched_rmv_elem(&sync->sch);
    }
}

static void
ble_ll_adv_sync_schedule(struct ble_ll_adv_sm *advsm, bool first_pdu)
{
    /*
     * For secondary channel we always start by scheduling two consecutive
     * auxiliary packets at once. Then, after sending one packet we try to
     * schedule another one as long as there are some data left to send. This
     * is to make sure we can always calculate AuxPtr to subsequent packet
     * without need to scheduled it in an interrupt.
     */

    ble_ll_adv_periodic_schedule_first(advsm, first_pdu);
    ble_ll_adv_periodic_schedule_next(advsm);
}

static void
ble_ll_adv_reschedule_periodic_event(struct ble_ll_adv_sm *advsm)
{
    advsm->periodic_adv_event_start_time += advsm->periodic_adv_itvl_ticks;
    ble_ll_adv_sync_schedule(advsm, false);
}

static void
ble_ll_adv_update_periodic_data(struct ble_ll_adv_sm *advsm)
{
    if (!(advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_NEW_DATA)) {
        return;
    }

    if (advsm->periodic_sync_active) {
        return;
    }

    if (advsm->periodic_new_data) {
        os_mbuf_free_chain(advsm->periodic_adv_data);
        advsm->periodic_adv_data = advsm->periodic_new_data;
        advsm->periodic_new_data = NULL;
    }

    ble_ll_adv_flags_clear(advsm, BLE_LL_ADV_SM_FLAG_PERIODIC_NEW_DATA);
}

/**
 * Called when periodic packet is txd on secondary channel
 *
 * Context: Link Layer task.
 *
 * @param ev
 */
static void
ble_ll_adv_periodic_done(struct ble_ll_adv_sm *advsm)
{
    struct ble_ll_adv_sync *sync;
    struct ble_ll_adv_sync *sync_next;

    BLE_LL_ASSERT(advsm->periodic_adv_enabled);
    BLE_LL_ASSERT(advsm->periodic_adv_active);
    BLE_LL_ASSERT(advsm->periodic_sync_active);

    ble_ll_rfmgmt_release();

    sync = SYNC_CURRENT(advsm);
    sync_next = SYNC_NEXT(advsm);

    /* Remove anything else scheduled for periodic */
    ble_ll_sched_rmv_elem(&sync->sch);
    ble_ll_event_remove(&advsm->adv_periodic_txdone_ev);

    /* If we have next SYNC scheduled, try to schedule another one */
    if (sync_next->sch.enqueued) {
        advsm->periodic_sync_index ^= 1;
        ble_ll_adv_periodic_schedule_next(advsm);
        return;
    }

    /* Check if we need to resume scanning */
    ble_ll_scan_chk_resume();

    advsm->periodic_sync_active = 0;
    ble_ll_adv_update_periodic_data(advsm);
    ble_ll_adv_reschedule_periodic_event(advsm);
}

static void
ble_ll_adv_periodic_event_done(struct ble_npl_event *ev)
{
    ble_ll_adv_periodic_done(ble_npl_event_get_arg(ev));
}

static void
ble_ll_adv_sm_start_periodic(struct ble_ll_adv_sm *advsm)
{
    uint32_t usecs;

    /*
     * The Advertising DID is not required to change when a SyncInfo field is
     * added to or removed from an advertising set. However, if it does not
     * change, then scanners may fail to synchronize to periodic advertising
     * because entries in the Advertising DID cache (see Section 4.3.3) mean
     * they ignore the advertisements containing the SyncInfo field. Therefore,
     * advertisers should update the Advertising DID when a periodic advertising
     * train is enabled.
     */
    ble_ll_adv_update_did(advsm);

    advsm->periodic_adv_active = 1;

    /* keep channel map since we cannot change it later on */
    memcpy(advsm->periodic_chanmap, g_ble_ll_data.chan_map, BLE_LL_CHAN_MAP_LEN);
    advsm->periodic_num_used_chans = g_ble_ll_data.chan_map_used;
    advsm->periodic_event_cntr = 0;
    /* for chaining we start with random counter as we share access addr */
    advsm->periodic_chain_event_cntr = ble_ll_rand();
    advsm->periodic_access_addr = ble_ll_utils_calc_aa();
    advsm->periodic_channel_id = ((advsm->periodic_access_addr & 0xffff0000) >> 16) ^
                                 (advsm->periodic_access_addr & 0x0000ffff);
    advsm->periodic_crcinit = ble_ll_rand() & 0xffffff;

    usecs = (uint32_t)advsm->periodic_adv_itvl * BLE_LL_ADV_PERIODIC_ITVL;
    advsm->periodic_adv_itvl_ticks = ble_ll_tmr_u2t_r(usecs,
                                                      &advsm->periodic_adv_itvl_rem_us);

    /* There is no point in starting periodic advertising until next advertising
     * event since SyncInfo is needed for synchronization
     */
    advsm->periodic_adv_event_start_time_remainder = 0;
    advsm->periodic_adv_event_start_time = advsm->adv_pdu_start_time +
                      ble_ll_tmr_u2t(advsm->adv_itvl_usecs + 5000);

    ble_ll_adv_sync_schedule(advsm, true);
}

static void
ble_ll_adv_sm_stop_periodic(struct ble_ll_adv_sm *advsm)
{
    os_sr_t sr;

    ble_ll_rfmgmt_release();

    if (!advsm->periodic_adv_active) {
        return;
    }

    /*
     * The Advertising DID is not required to change when a SyncInfo field is
     * added to or removed from an advertising set. However, if it does not
     * change, then scanners may unnecessary try to synchronize to instance that
     * no longer has periodic advertising enabled  because entries in the
     * Advertising DID cache (see Section 4.3.3) mean they ignore the
     * advertisements no longer containing the SyncInfo field. Therefore,
     * advertisers should update the Advertising DID when a periodic advertising
     * train is disabled.
     */
    ble_ll_adv_update_did(advsm);

    /* Remove any scheduled advertising items */
    advsm->periodic_adv_active = 0;
    advsm->periodic_sync_active = 0;
    ble_ll_sched_rmv_elem(&advsm->periodic_sync[0].sch);
    ble_ll_sched_rmv_elem(&advsm->periodic_sync[1].sch);

    /* Set to standby if we are no longer advertising */
    OS_ENTER_CRITICAL(sr);
    if ((g_ble_ll_cur_adv_sm == advsm) &&
            (advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING)) {
        ble_phy_disable();
        ble_ll_state_set(BLE_LL_STATE_STANDBY);
        g_ble_ll_cur_adv_sm = NULL;
        ble_ll_scan_chk_resume();
    }
    OS_EXIT_CRITICAL(sr);

    ble_ll_adv_flags_clear(advsm, BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING);

    ble_ll_event_remove(&advsm->adv_periodic_txdone_ev);

    ble_ll_adv_update_periodic_data(advsm);
}
#endif

/**
 * Start the advertising state machine. This is called when the host sends
 * the "enable advertising" command and is not called again while in the
 * advertising state.
 *
 * Context: Link-layer task.
 *
 * @param advsm Pointer to advertising state machine
 *
 * @return int
 */
static int
ble_ll_adv_sm_start(struct ble_ll_adv_sm *advsm)
{
    uint8_t adv_chan;
    uint8_t *addr;
    uint32_t start_delay_us;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2)
    uint32_t access_addr;
#endif
    const uint8_t *random_addr;
    uint32_t earliest_start_time;
    int32_t delta;

    /* only clear flags that are not set from HCI */
    ble_ll_adv_flags_clear(advsm, BLE_LL_ADV_SM_FLAG_TX_ADD |
                                  BLE_LL_ADV_SM_FLAG_RX_ADD |
                                  BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD);

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    random_addr = advsm->adv_random_addr;
#else
    random_addr = g_random_addr;
#endif

    if (!ble_ll_is_valid_own_addr_type(advsm->own_addr_type, random_addr)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /*
     * Get an event with which to send the connection complete event if
     * this is connectable
     */
#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL)
    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE) {
        /* We expect this to be NULL but if not we wont allocate one... */
        if (advsm->conn_comp_ev == NULL) {
            advsm->conn_comp_ev = ble_transport_alloc_evt(0);
            if (!advsm->conn_comp_ev) {
                return BLE_ERR_MEM_CAPACITY;
            }
        }
    }
#endif

    /* Set advertising address */
    if ((advsm->own_addr_type & 1) == 0) {
        addr = g_dev_addr;
    } else {
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
        addr = advsm->adv_random_addr;
#else
        addr = g_random_addr;
#endif
        advsm->flags |= BLE_LL_ADV_SM_FLAG_TX_ADD;
    }
    memcpy(advsm->adva, addr, BLE_DEV_ADDR_LEN);

    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED) {
        memcpy(advsm->initiator_addr, advsm->peer_addr, BLE_DEV_ADDR_LEN);
        if (advsm->peer_addr_type & 1) {
            advsm->flags |= BLE_LL_ADV_SM_FLAG_RX_ADD;
        }
    }

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
    /* This will generate an RPA for both initiator addr and adva */
    if (advsm->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) {
        ble_ll_adv_rpa_update(advsm);
    }
#endif

    /* Set flag telling us that advertising is enabled */
    advsm->adv_enabled = 1;

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2)
    advsm->event_cntr = 0;
    access_addr = ble_ll_utils_calc_aa();
    advsm->channel_id = ((access_addr & 0xffff0000) >> 16) ^
                         (access_addr & 0x0000ffff);
#endif

    /* Set first advertising channel */
    adv_chan = ble_ll_adv_first_chan(advsm);
    advsm->adv_chan = adv_chan;

    /*
     * Scheduling 1st PDU is a bit tricky.
     * Earliest possible start time is after RF is enabled so just force RF to
     * start here to see when if will be fully enabled - it will be too early,
     * but this is the only reliable way to have it enabled on time.
     * Next we calculate expected start time (randomize it a bit) and this is
     * used to setup start time for scheduler item.
     * Then we check if start time for scheduler item (which includes scheduler
     * overhead) is no earlier than calculated earliest possible start time and
     * adjust scheduler item if necessary.
     */
    earliest_start_time = ble_ll_rfmgmt_enable_now();

    start_delay_us = ble_ll_rand() % (BLE_LL_ADV_DELAY_MS_MAX * 1000);
    advsm->adv_pdu_start_time = ble_ll_tmr_get() +
                                ble_ll_tmr_u2t(start_delay_us);

    ble_ll_adv_set_sched(advsm);

    delta = (int32_t)(advsm->adv_sch.start_time - earliest_start_time);
    if (delta < 0) {
        advsm->adv_sch.start_time -= delta;
        advsm->adv_sch.end_time -= delta;
    }

    /* This does actual scheduling */
    ble_ll_sched_adv_new(&advsm->adv_sch, ble_ll_adv_scheduled, NULL);

    /* we start periodic before AE since we need PDU start time in SyncInfo */
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV)
    if (advsm->periodic_adv_enabled && !advsm->periodic_adv_active) {
        ble_ll_adv_sm_start_periodic(advsm);
    }
#endif

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY)) {
        ble_ll_adv_aux_schedule(advsm);
    }
#endif

    return BLE_ERR_SUCCESS;
}

/**
 * Called when the LE HCI command read advertising channel tx power command
 * has been received. Returns the current advertising transmit power.
 *
 * Context: Link Layer task (HCI command parser)
 *
 * @return int
 */
int
ble_ll_adv_read_txpwr(uint8_t *rspbuf, uint8_t *rsplen)
{
    struct ble_hci_le_rd_adv_chan_txpwr_rp *rsp = (void *) rspbuf;

    rsp->power_level = g_ble_ll_tx_power;

    *rsplen = sizeof(*rsp);
    return BLE_ERR_SUCCESS;
}

/**
 * Turn advertising on/off.
 *
 * Context: Link Layer task
 *
 * @param cmd
 *
 * @return int
 */
static int
ble_ll_adv_set_enable(uint8_t instance, uint8_t enable, int duration,
                      uint8_t events)
{
    int rc;
    struct ble_ll_adv_sm *advsm;

    advsm = ble_ll_adv_sm_find_configured(instance);
    if (!advsm) {
        return BLE_ERR_UNK_ADV_INDENT;
    }

    rc = BLE_ERR_SUCCESS;
    if (enable == 1) {
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
        if (advsm->flags & BLE_LL_ADV_SM_FLAG_ADV_DATA_INCOMPLETE) {
            return BLE_ERR_CMD_DISALLOWED;
        }

        if (ble_ll_hci_adv_mode_ext() &&
                (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE) &&
                !(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) &&
                SCAN_RSP_DATA_LEN(advsm) == 0) {
            return BLE_ERR_CMD_DISALLOWED;
        }

        /* handle specifics of HD dir adv enabled in legacy way */
        if (duration < 0) {
            if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) {
                duration = BLE_LL_ADV_STATE_HD_MAX / 10;
            } else {
                duration = 0;
            }
        }
        advsm->duration = duration;
        advsm->events_max = events;
        advsm->events = 0;
#endif

        /* If already enabled, do nothing */
        if (!advsm->adv_enabled) {
            /* Start the advertising state machine */
            rc = ble_ll_adv_sm_start(advsm);
        }
    } else if (enable == 0) {
        ble_ll_adv_sm_stop(advsm);
    } else {
        rc = BLE_ERR_INV_HCI_CMD_PARMS;
    }

    return rc;
}

int
ble_ll_hci_adv_set_enable(const uint8_t *cmdbuf, uint8_t len)
{
    const struct ble_hci_le_set_adv_enable_cp *cmd = (const void *) cmdbuf;

    if (len != sizeof(*cmd)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    return ble_ll_adv_set_enable(0, cmd->enable, -1, 0);
}

static void
ble_ll_adv_update_data_mbuf(struct os_mbuf **omp, bool new_data, uint16_t maxlen,
                            const void *data, uint16_t datalen)
{
    struct os_mbuf *om;
    int ret;

    om = *omp;

    if (new_data) {
        if (om) {
            os_mbuf_free_chain(om);
        }

        om = os_msys_get_pkthdr(datalen, 0);
        if (!om) {
            goto done;
        }
    }

    BLE_LL_ASSERT(om);

    if (OS_MBUF_PKTLEN(om) + datalen > maxlen) {
        os_mbuf_free_chain(om);
        om = NULL;
        goto done;
    }

    ret = os_mbuf_append(om, data, datalen);
    if (ret) {
        os_mbuf_free_chain(om);
        om = NULL;
    }

done:
    *omp = om;
}

/**
 * Set the scan response data that the controller will send.
 *
 * @param cmd
 * @param len
 *
 * @return int
 */
static int
ble_ll_adv_set_scan_rsp_data(const uint8_t *data, uint8_t datalen,
                             uint8_t instance, uint8_t operation)
{
    struct ble_ll_adv_sm *advsm;
    bool new_data;

    advsm = ble_ll_adv_sm_find_configured(instance);
    if (!advsm) {
        return BLE_ERR_UNK_ADV_INDENT;
    }

    /* check if type of advertising support scan rsp */
    if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE)) {
        if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY)) {
            return BLE_ERR_INV_HCI_CMD_PARMS;
        }
    }

    switch (operation) {
    case BLE_HCI_LE_SET_DATA_OPER_COMPLETE:
        if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
            if (datalen > BLE_SCAN_RSP_LEGACY_DATA_MAX_LEN) {
                return BLE_ERR_INV_HCI_CMD_PARMS;
            }
        }

        break;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    case BLE_HCI_LE_SET_DATA_OPER_LAST:
        /* TODO mark scan rsp as complete? */
        /* fall through */
    case BLE_HCI_LE_SET_DATA_OPER_INT:
        if (!advsm->scan_rsp_data) {
            return BLE_ERR_INV_HCI_CMD_PARMS;
        }

        if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
            return BLE_ERR_INV_HCI_CMD_PARMS;
        }

        if (advsm->adv_enabled) {
            return BLE_ERR_CMD_DISALLOWED;
        }

        if (!datalen) {
            return BLE_ERR_INV_HCI_CMD_PARMS;
        }
        break;
    case BLE_HCI_LE_SET_DATA_OPER_FIRST:
        if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
            return BLE_ERR_INV_HCI_CMD_PARMS;
        }

        if (advsm->adv_enabled) {
            return BLE_ERR_CMD_DISALLOWED;
        }

        if (!datalen) {
            return BLE_ERR_INV_HCI_CMD_PARMS;
        }

        break;
#endif
    default:
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    new_data = (operation == BLE_HCI_LE_SET_DATA_OPER_COMPLETE) ||
               (operation == BLE_HCI_LE_SET_DATA_OPER_FIRST);

    if (advsm->adv_enabled) {
        if (advsm->new_scan_rsp_data) {
            ble_ll_adv_flags_clear(advsm, BLE_LL_ADV_SM_FLAG_NEW_SCAN_RSP_DATA);
            os_mbuf_free_chain(advsm->new_scan_rsp_data);
            advsm->new_scan_rsp_data = NULL;
        }

        ble_ll_adv_update_data_mbuf(&advsm->new_scan_rsp_data, new_data,
                                    BLE_ADV_DATA_MAX_LEN, data, datalen);
        if (!advsm->new_scan_rsp_data) {
            return BLE_ERR_MEM_CAPACITY;
        }

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
        if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) &&
            !ble_ll_adv_aux_check_data_itvl(advsm, advsm->props, advsm->pri_phy,
                                            advsm->sec_phy,
                                            advsm->new_scan_rsp_data,
                                            advsm->adv_itvl_usecs)) {
            os_mbuf_free_chain(advsm->new_scan_rsp_data);
            advsm->new_scan_rsp_data = NULL;
            return BLE_ERR_PACKET_TOO_LONG;
        }
#endif

        ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_NEW_SCAN_RSP_DATA);
    } else {
        ble_ll_adv_update_data_mbuf(&advsm->scan_rsp_data, new_data,
                                    BLE_SCAN_RSP_DATA_MAX_LEN, data, datalen);
        if (!advsm->scan_rsp_data) {
            return BLE_ERR_MEM_CAPACITY;
        }

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
        if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) &&
            !ble_ll_adv_aux_check_data_itvl(advsm, advsm->props, advsm->pri_phy,
                                            advsm->sec_phy,
                                            advsm->scan_rsp_data,
                                            advsm->adv_itvl_usecs)) {
            os_mbuf_free_chain(advsm->scan_rsp_data);
            advsm->scan_rsp_data = NULL;
            return BLE_ERR_PACKET_TOO_LONG;
        }

        /* DID shall be updated when host provides new scan response data */
        ble_ll_adv_update_did(advsm);
#endif
    }

    return BLE_ERR_SUCCESS;
}

int
ble_ll_hci_set_scan_rsp_data(const uint8_t *cmdbuf, uint8_t len)
{
    const struct ble_hci_le_set_scan_rsp_data_cp *cmd = (const void *) cmdbuf;

    if ((len != sizeof(*cmd)) || (cmd->scan_rsp_len > sizeof(cmd->scan_rsp))) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    return ble_ll_adv_set_scan_rsp_data(cmd->scan_rsp, cmd->scan_rsp_len, 0,
                                        BLE_HCI_LE_SET_DATA_OPER_COMPLETE);
}
/**
 * Called by the LL HCI command parser when a set advertising
 * data command has been sent from the host to the controller.
 *
 * @param cmd Pointer to command data
 * @param len Length of command data
 *
 * @return int 0: success; BLE_ERR_INV_HCI_CMD_PARMS otherwise.
 */
static int
ble_ll_adv_set_adv_data(const uint8_t *data, uint8_t datalen, uint8_t instance,
                        uint8_t operation)
{
    struct ble_ll_adv_sm *advsm;
    bool new_data;

    advsm = ble_ll_adv_sm_find_configured(instance);
    if (!advsm) {
        return BLE_ERR_UNK_ADV_INDENT;
    }

    /* check if type of advertising support adv data */
    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
        if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED) {
            if (ble_ll_hci_adv_mode_ext()) {
                return BLE_ERR_INV_HCI_CMD_PARMS;
            }
        }
    } else {
        if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE) {
            return BLE_ERR_INV_HCI_CMD_PARMS;
        }
    }

    switch (operation) {
    case BLE_HCI_LE_SET_DATA_OPER_COMPLETE:
        if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
            if (datalen > BLE_ADV_LEGACY_DATA_MAX_LEN) {
                return BLE_ERR_INV_HCI_CMD_PARMS;
            }
        }

        ble_ll_adv_flags_clear(advsm, BLE_LL_ADV_SM_FLAG_ADV_DATA_INCOMPLETE);

        break;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    case BLE_HCI_LE_SET_DATA_OPER_UNCHANGED:
        if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
            return BLE_ERR_INV_HCI_CMD_PARMS;
        }

        if (!advsm->adv_enabled || !ADV_DATA_LEN(advsm) || datalen) {
            return BLE_ERR_INV_HCI_CMD_PARMS;
        }

        /* update DID only */
        ble_ll_adv_update_did(advsm);
        return BLE_ERR_SUCCESS;
    case BLE_HCI_LE_SET_DATA_OPER_LAST:
        ble_ll_adv_flags_clear(advsm, BLE_LL_ADV_SM_FLAG_ADV_DATA_INCOMPLETE);
        /* fall through */
    case BLE_HCI_LE_SET_DATA_OPER_INT:
        if (!advsm->adv_data) {
            return BLE_ERR_INV_HCI_CMD_PARMS;
        }

        if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
            return BLE_ERR_INV_HCI_CMD_PARMS;
        }

        if (!datalen) {
            return BLE_ERR_INV_HCI_CMD_PARMS;
        }

        if (advsm->adv_enabled) {
            return BLE_ERR_CMD_DISALLOWED;
        }
        break;
    case BLE_HCI_LE_SET_DATA_OPER_FIRST:
        if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
            return BLE_ERR_INV_HCI_CMD_PARMS;
        }

        if (advsm->adv_enabled) {
            return BLE_ERR_CMD_DISALLOWED;
        }

        if (!datalen) {
            return BLE_ERR_INV_HCI_CMD_PARMS;
        }

        ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_ADV_DATA_INCOMPLETE);
        break;
#endif
    default:
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    new_data = (operation == BLE_HCI_LE_SET_DATA_OPER_COMPLETE) ||
               (operation == BLE_HCI_LE_SET_DATA_OPER_FIRST);

    if (advsm->adv_enabled) {
        if (advsm->new_adv_data) {
            ble_ll_adv_flags_clear(advsm, BLE_LL_ADV_SM_FLAG_NEW_ADV_DATA);
            os_mbuf_free_chain(advsm->new_adv_data);
            advsm->new_adv_data = NULL;
        }

        ble_ll_adv_update_data_mbuf(&advsm->new_adv_data, new_data,
                                    BLE_ADV_DATA_MAX_LEN, data, datalen);
        if (!advsm->new_adv_data) {
            return BLE_ERR_MEM_CAPACITY;
        }

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
        if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) &&
            !ble_ll_adv_aux_check_data_itvl(advsm, advsm->props, advsm->pri_phy,
                                            advsm->sec_phy, advsm->new_adv_data,
                                            advsm->adv_itvl_usecs)) {
            os_mbuf_free_chain(advsm->new_adv_data);
            advsm->new_adv_data = NULL;
            return BLE_ERR_PACKET_TOO_LONG;
        }
#endif

        ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_NEW_ADV_DATA);
    } else {
        ble_ll_adv_update_data_mbuf(&advsm->adv_data, new_data,
                                    BLE_ADV_DATA_MAX_LEN, data, datalen);
        if (!advsm->adv_data) {
            return BLE_ERR_MEM_CAPACITY;
        }

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
        if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) &&
            !ble_ll_adv_aux_check_data_itvl(advsm, advsm->props, advsm->pri_phy,
                                            advsm->sec_phy, advsm->adv_data,
                                            advsm->adv_itvl_usecs)) {
            os_mbuf_free_chain(advsm->adv_data);
            advsm->adv_data = NULL;
            return BLE_ERR_PACKET_TOO_LONG;
        }

        /* DID shall be updated when host provides new advertising data */
        ble_ll_adv_update_did(advsm);
#endif
        }

    return BLE_ERR_SUCCESS;
}

int
ble_ll_hci_set_adv_data(const uint8_t *cmdbuf, uint8_t len)
{
    const struct ble_hci_le_set_adv_data_cp *cmd = (const void *) cmdbuf;

    if ((len != sizeof(*cmd)) || (cmd->adv_data_len > sizeof(cmd->adv_data))) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    return ble_ll_adv_set_adv_data(cmd->adv_data, cmd->adv_data_len, 0,
                                   BLE_HCI_LE_SET_DATA_OPER_COMPLETE);
}

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
static bool
pri_phy_valid(uint8_t phy)
{
    switch (phy) {
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)
    case BLE_HCI_LE_PHY_CODED:
#endif
    case BLE_HCI_LE_PHY_1M:
        return true;
    default:
        return false;
    }
}

static bool
sec_phy_valid(uint8_t phy)
{
    switch (phy) {
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)
    case BLE_HCI_LE_PHY_CODED:
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY)
    case BLE_HCI_LE_PHY_2M:
#endif
    case BLE_HCI_LE_PHY_1M:
        return true;
    default:
        return false;
    }
}

static struct ble_ll_adv_sm *
ble_ll_adv_sm_get(uint8_t instance)
{
    struct ble_ll_adv_sm *advsm;
    unsigned int i;

    advsm = ble_ll_adv_sm_find_configured(instance);
    if (advsm) {
        return advsm;
    }

    for (i = 0; i < ARRAY_SIZE(g_ble_ll_adv_sm); i++) {
        advsm = &g_ble_ll_adv_sm[i];

        if (!(advsm->flags & BLE_LL_ADV_SM_FLAG_CONFIGURED)) {
            ble_ll_adv_sm_init(advsm);

           /* configured flag is set by caller on success config */
           advsm->adv_instance = instance;
           return advsm;
        }
    }

    return NULL;
}

int
ble_ll_adv_ext_set_param(const uint8_t *cmdbuf, uint8_t len,
                         uint8_t *rspbuf, uint8_t *rsplen)
{
    const struct ble_hci_le_set_ext_adv_params_cp *cmd = (const void *) cmdbuf;
    struct ble_hci_le_set_ext_adv_params_rp *rsp = (void *) rspbuf;
    struct ble_ll_adv_sm *advsm;
    uint32_t adv_itvl_min;
    uint32_t adv_itvl_max;
    uint32_t adv_itvl_usecs;
    uint16_t props;
    int rc;

    if (len != sizeof(*cmd )) {
        rc = BLE_ERR_INV_HCI_CMD_PARMS;
        goto done;
    }

    advsm = ble_ll_adv_sm_get(cmd->adv_handle);
    if (!advsm) {
        rc = BLE_ERR_MEM_CAPACITY;
        goto done;
    }

    if (advsm->adv_enabled) {
        rc = BLE_ERR_CMD_DISALLOWED;
        goto done;
    }

    props = le16toh(cmd->props);

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV)
    /* If the Host issues this command when periodic advertising is enabled for
     * the specified advertising set and connectable, scannable, legacy, or
     * anonymous advertising is specified, the Controller shall return the
     * error code Invalid HCI Command Parameters (0x12).
     */
    if (advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_CONFIGURED) {
        if (advsm->periodic_adv_enabled) {
            if (props & (BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE |
                         BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE |
                         BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY |
                         BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV)) {
                rc = BLE_ERR_INV_HCI_CMD_PARMS;
                goto done;
            }
        }
    }
#endif

    adv_itvl_min = cmd->pri_itvl_min[2] << 16 | cmd->pri_itvl_min[1] << 8 |
                   cmd->pri_itvl_min[0];
    adv_itvl_max = cmd->pri_itvl_max[2] << 16 | cmd->pri_itvl_max[1] << 8 |
                   cmd->pri_itvl_max[0];

    if (props & ~BLE_HCI_LE_SET_EXT_ADV_PROP_MASK) {
        rc = BLE_ERR_INV_HCI_CMD_PARMS;
        goto done;
    }

    if (props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
        if (ADV_DATA_LEN(advsm) > BLE_ADV_LEGACY_DATA_MAX_LEN ||
            SCAN_RSP_DATA_LEN(advsm) > BLE_SCAN_RSP_LEGACY_DATA_MAX_LEN) {
            rc = BLE_ERR_INV_HCI_CMD_PARMS;
            goto done;
        }

        /* if legacy bit is set possible values are limited */
        switch (props) {
#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL)
        case BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_IND:
        case BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_LD_DIR:
        case BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_HD_DIR:
#endif
        case BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_SCAN:
        case BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_NONCONN:
            break;
        default:
            rc = BLE_ERR_INV_HCI_CMD_PARMS;
            goto done;
        }
    } else {
#if !MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL)
        if (props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE) {
            rc = BLE_ERR_INV_HCI_CMD_PARMS;
            goto done;
        }
#endif
        /* HD directed advertising allowed only on legacy PDUs */
        if (props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) {
            rc = BLE_ERR_INV_HCI_CMD_PARMS;
            goto done;
        }

        /* if ext advertising PDUs are used then it shall not be both
         * connectable and scanable
         */
        if ((props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE) &&
            (props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE)) {
            rc = BLE_ERR_INV_HCI_CMD_PARMS;
            goto done;
        }
    }

    /* High Duty Directed advertising is special */
    if (props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) {
        if (ADV_DATA_LEN(advsm) || SCAN_RSP_DATA_LEN(advsm)) {
            rc = BLE_ERR_INV_HCI_CMD_PARMS;
            goto done;
        }

        /* Ignore min/max interval */
        adv_itvl_min = 0;
        adv_itvl_max = 0;
    } else {
        /* validate intervals for non HD-directed advertising */
        if ((adv_itvl_min > adv_itvl_max) ||
                (adv_itvl_min < BLE_HCI_ADV_ITVL_MIN) ||
                (adv_itvl_max < BLE_HCI_ADV_ITVL_MIN)) {
            rc = BLE_ERR_INV_HCI_CMD_PARMS;
            goto done;
        }

        /* TODO for now limit those to values from legacy advertising
         *
         * If the primary advertising interval range is outside the advertising
         * interval range supported by the Controller, then the Controller shall
         * return the error code Unsupported Feature or Parameter Value (0x11).
         */
        if ((adv_itvl_min > BLE_HCI_ADV_ITVL_MAX) ||
                (adv_itvl_max > BLE_HCI_ADV_ITVL_MAX)) {
            rc = BLE_ERR_UNSUPPORTED;
            goto done;
        }
    }

    /* There are only three adv channels, so check for any outside the range */
    if (((cmd->pri_chan_map & 0xF8) != 0) || (cmd->pri_chan_map == 0)) {
        rc = BLE_ERR_INV_HCI_CMD_PARMS;
        goto done;
    }

    if (cmd->own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) {
        rc = BLE_ERR_INV_HCI_CMD_PARMS;
        goto done;
    }

#if !MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
    /* If we dont support privacy some address types wont work */
    if (cmd->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) {
        rc = BLE_ERR_UNSUPPORTED;
        goto done;
    }
#endif

    /* peer address type is only valid for directed */
    if ((props & BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED) &&
            (cmd->peer_addr_type > BLE_HCI_ADV_PEER_ADDR_MAX)) {
        rc = BLE_ERR_INV_HCI_CMD_PARMS;
        goto done;
    }

    /* Check filter policy (valid only for undirected) */
    if (!(props & BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED) &&
         cmd->filter_policy > BLE_HCI_ADV_FILT_MAX) {
        rc = BLE_ERR_INV_HCI_CMD_PARMS;
        goto done;
    }

    if (!pri_phy_valid(cmd->pri_phy)) {
        rc = BLE_ERR_INV_HCI_CMD_PARMS;
        goto done;
    }

    /* check secondary phy only if not using legacy PDUs */
    if (!(props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) &&
            !sec_phy_valid(cmd->sec_phy)) {
        rc = BLE_ERR_INV_HCI_CMD_PARMS;
        goto done;
    }

    if (cmd->sid > 0x0f) {
        rc = BLE_ERR_INV_HCI_CMD_PARMS;
        goto done;
    }

    if (cmd->scan_req_notif > 0x01) {
        rc = BLE_ERR_INV_HCI_CMD_PARMS;
        goto done;
    }

    /* Determine the advertising interval we will use */
    if (props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) {
        /* Set it to max. allowed for high duty cycle advertising */
        adv_itvl_usecs = BLE_LL_ADV_PDU_ITVL_HD_MS_MAX;
    } else {
        adv_itvl_usecs = adv_itvl_max * BLE_LL_ADV_ITVL;
    }

    if (!ble_ll_adv_aux_check_data_itvl(advsm, props, cmd->pri_phy, cmd->sec_phy,
                                        advsm->adv_data, adv_itvl_usecs) ||
        !ble_ll_adv_aux_check_data_itvl(advsm, props, cmd->pri_phy, cmd->sec_phy,
                                        advsm->scan_rsp_data, adv_itvl_usecs)) {
        return BLE_ERR_PACKET_TOO_LONG;
    }

    rc = BLE_ERR_SUCCESS;

    if (cmd->tx_power == 127) {
        /* no preference */
        advsm->tx_power = ble_ll_tx_power_round(g_ble_ll_tx_power - g_ble_ll_tx_power_compensation);
    } else {
        advsm->tx_power = ble_ll_tx_power_round(MIN(cmd->tx_power, MYNEWT_VAL(BLE_LL_TX_PWR_MAX_DBM)) -
                                                g_ble_ll_tx_power_compensation);
    }

    /* we can always store as those are validated and used only when needed */
    advsm->peer_addr_type = cmd->peer_addr_type;
    memcpy(advsm->peer_addr, cmd->peer_addr, BLE_DEV_ADDR_LEN);
    advsm->own_addr_type = cmd->own_addr_type;
    advsm->adv_filter_policy = cmd->filter_policy;
    advsm->adv_chanmask = cmd->pri_chan_map;
    advsm->adv_itvl_usecs = adv_itvl_usecs;
    advsm->pri_phy = cmd->pri_phy;
    advsm->sec_phy = cmd->sec_phy;
    /* Update SID only */
    advsm->adi = (advsm->adi & 0x0fff) | ((cmd->sid << 12));

    advsm->props = props;

    /* Set proper mbuf chain for aux data */
    if (props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
        advsm->aux_data = NULL;
    } else if (props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE) {
        advsm->aux_data = &advsm->scan_rsp_data;
    } else {
        advsm->aux_data = &advsm->adv_data;
    }

    if (cmd->scan_req_notif) {
        ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_SCAN_REQ_NOTIF);
    } else {
        ble_ll_adv_flags_clear(advsm, BLE_LL_ADV_SM_FLAG_SCAN_REQ_NOTIF);
    }

    ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_CONFIGURED);

done:
    /* Update TX power */
    rsp->tx_power = rc ? 0 : (advsm->tx_power + g_ble_ll_tx_power_compensation);

    *rsplen = sizeof(*rsp);
    return rc;
}

int
ble_ll_adv_ext_set_adv_data(const uint8_t *cmdbuf, uint8_t cmdlen)
{
    const struct ble_hci_le_set_ext_adv_data_cp *cmd = (const void *) cmdbuf;

    if (cmdlen < sizeof(*cmd )) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    if (cmd->adv_data_len > BLE_HCI_MAX_EXT_ADV_DATA_LEN ||
            cmd->adv_data_len > cmdlen - sizeof(*cmd)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* TODO fragment preference ignored for now */

    return ble_ll_adv_set_adv_data(cmd->adv_data, cmd->adv_data_len,
                                   cmd->adv_handle, cmd->operation);
}

int
ble_ll_adv_ext_set_scan_rsp(const uint8_t *cmdbuf, uint8_t cmdlen)
{
    const struct ble_hci_le_set_ext_scan_rsp_data_cp *cmd = (const void *) cmdbuf;

    if (cmdlen < sizeof(*cmd )) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    if (cmd->scan_rsp_len > BLE_HCI_MAX_EXT_ADV_DATA_LEN ||
            cmd->scan_rsp_len > cmdlen - sizeof(*cmd)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* TODO fragment preference ignored for now */

    return ble_ll_adv_set_scan_rsp_data(cmd->scan_rsp, cmd->scan_rsp_len,
                                        cmd->adv_handle, cmd->operation);
}

/**
 * HCI LE extended advertising enable command
 *
 * @param cmd Pointer to command data
 * @param len Command data length
 *
 * @return int BLE error code
 */
int
ble_ll_adv_ext_set_enable(const uint8_t *cmdbuf, uint8_t len)
{
    const struct ble_hci_le_set_ext_adv_enable_cp *cmd = (const void *) cmdbuf;
    struct ble_ll_adv_sm *advsm;
    int i, j, rc;

    if (len < sizeof(*cmd)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* check if length is correct */
    if (len != 2 + (cmd->num_sets * sizeof(cmd->sets[0]))) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    if (cmd->num_sets > BLE_ADV_INSTANCES) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    if (cmd->num_sets == 0) {
        if (cmd->enable) {
            return BLE_ERR_INV_HCI_CMD_PARMS;
        }

        /* disable all instances */
        for (i = 0; i < BLE_ADV_INSTANCES; i++) {
            ble_ll_adv_set_enable(i, 0, 0, 0);
        }

        return BLE_ERR_SUCCESS;
    }

    /* validate instances */
    for (i = 0; i < cmd->num_sets; i++) {
        /* validate duplicated sets */
        for (j = i + 1; j < cmd->num_sets; j++) {
            if (cmd->sets[i].adv_handle == cmd->sets[j].adv_handle) {
                return BLE_ERR_INV_HCI_CMD_PARMS;
            }
        }

        advsm = ble_ll_adv_sm_find_configured(cmd->sets[i].adv_handle);
        if (!advsm) {
            return BLE_ERR_UNK_ADV_INDENT;
        }

        if (cmd->enable) {
            if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) {
                if (cmd->sets[i].duration == 0 ||
                        le16toh(cmd->sets[i].duration) > 128) {
                    return BLE_ERR_INV_HCI_CMD_PARMS;
                }
            }
        }
    }

    for (i = 0; i < cmd->num_sets; i++) {
        rc = ble_ll_adv_set_enable(cmd->sets[i].adv_handle, cmd->enable,
                                   le16toh(cmd->sets[i].duration),
                                   cmd->sets[i].max_events);
        if (rc) {
            return rc;
        }
    }

    return BLE_ERR_SUCCESS;
}

int
ble_ll_adv_set_random_addr(const uint8_t *addr, uint8_t instance)
{
    struct ble_ll_adv_sm *advsm;

    advsm = ble_ll_adv_sm_find_configured(instance);
    if (!advsm) {
        return BLE_ERR_UNK_ADV_INDENT;
    }

    /*
     * Reject if connectable advertising is on
     * Core Spec Vol. 2 Part E 7.8.52
     */
    if (advsm->adv_enabled &&
            (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE)) {
        return BLE_ERR_CMD_DISALLOWED;
    }

    memcpy(advsm->adv_random_addr, addr, BLE_DEV_ADDR_LEN);
    return BLE_ERR_SUCCESS;
}

int
ble_ll_adv_hci_set_random_addr(const uint8_t *cmdbuf, uint8_t len)
{
    const struct ble_hci_le_set_adv_set_rnd_addr_cp *cmd = (const void *) cmdbuf;

    if (len != sizeof(*cmd)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    return ble_ll_adv_set_random_addr(cmd->addr, cmd->adv_handle);
}

/**
 * HCI LE extended advertising remove command
 *
 * @return int BLE error code
 */
int
ble_ll_adv_remove(const uint8_t *cmdbuf, uint8_t len)
{
    const struct ble_hci_le_remove_adv_set_cp *cmd = (const void *) cmdbuf;
    struct ble_ll_adv_sm *advsm;

    if (len != sizeof(*cmd)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    advsm = ble_ll_adv_sm_find_configured(cmd->adv_handle);
    if (!advsm) {
        return BLE_ERR_UNK_ADV_INDENT;
    }

    if (advsm->adv_enabled) {
        return BLE_ERR_CMD_DISALLOWED;
    }

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV)
    if (advsm->periodic_adv_enabled) {
        return BLE_ERR_CMD_DISALLOWED;
    }

    if (advsm->periodic_adv_data) {
        os_mbuf_free_chain(advsm->periodic_adv_data);
    }
#endif

    if (advsm->adv_data) {
        os_mbuf_free_chain(advsm->adv_data);
    }
    if (advsm->scan_rsp_data) {
        os_mbuf_free_chain(advsm->scan_rsp_data);
    }

    ble_ll_adv_sm_init(advsm);

    return BLE_ERR_SUCCESS;
}

/**
 * HCI LE extended advertising clear command
 *
 * @return int BLE error code
 */
int
ble_ll_adv_clear_all(void)
{
    int i;

    for (i = 0; i < BLE_ADV_INSTANCES; i++) {
        if (g_ble_ll_adv_sm[i].adv_enabled) {
            return BLE_ERR_CMD_DISALLOWED;
        }

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV)
    if (g_ble_ll_adv_sm[i].periodic_adv_enabled) {
        return BLE_ERR_CMD_DISALLOWED;
    }
#endif
    }

    ble_ll_adv_reset();

    return BLE_ERR_SUCCESS;
}

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV)
static uint16_t
ble_ll_adv_sync_get_pdu_len(uint16_t data_len, uint16_t *data_offset,
                            uint16_t props)
{
    uint16_t rem_data_len = data_len - *data_offset;
    uint8_t hdr_len = BLE_LL_EXT_ADV_HDR_LEN;
    uint8_t ext_hdr = 0;

    /* TxPower if configured
     * Note: TxPower shall not be present in chain PDU for SYNC
     */
    if (*data_offset == 0 &&
        (props & BLE_HCI_LE_SET_PERIODIC_ADV_PROP_INC_TX_PWR)) {
        ext_hdr |= (1 << BLE_LL_EXT_ADV_TX_POWER_BIT);
        hdr_len += BLE_LL_EXT_ADV_TX_POWER_SIZE;
    }

    /* if we have any fields in ext header we need to add flags, note that Aux
     * PTR is handled later and it will account for flags if needed
     *
     * This could be handled inside TxPower but lets keep code consistent with
     * how Aux calculate works and this also make it easier to add more fields
     * into flags if needed in future
     */
    if (ext_hdr) {
        hdr_len += BLE_LL_EXT_ADV_FLAGS_SIZE;
    }

    /* AdvData always */
    data_len = MIN(BLE_LL_MAX_PAYLOAD_LEN - hdr_len, rem_data_len);

    /* AuxPtr if there are more AdvData remaining that we can fit here */
    if (rem_data_len > data_len) {
            /* adjust for flags that needs to be added if AuxPtr is only field
             * in Extended Header
             */
            if (!ext_hdr) {
                hdr_len += BLE_LL_EXT_ADV_FLAGS_SIZE;
                data_len -= BLE_LL_EXT_ADV_FLAGS_SIZE;
            }

            hdr_len += BLE_LL_EXT_ADV_AUX_PTR_SIZE;
            data_len -= BLE_LL_EXT_ADV_AUX_PTR_SIZE;

            /* PDU payload should be full if chained */
            BLE_LL_ASSERT(hdr_len + data_len == BLE_LL_MAX_PAYLOAD_LEN);
    }

    *data_offset += data_len;

    return hdr_len + data_len;
}

static bool
ble_ll_adv_periodic_check_data_itvl(uint16_t payload_len, uint16_t props,
                                    uint16_t itvl, uint8_t phy)
{
    uint32_t max_usecs = 0;
    uint32_t itvl_usecs;
    uint16_t offset = 0;
    uint16_t pdu_len;

    while (offset < payload_len) {
        pdu_len = ble_ll_adv_sync_get_pdu_len(payload_len, &offset, props);

        max_usecs += ble_ll_pdu_us(pdu_len, phy);
        max_usecs += BLE_LL_MAFS + MYNEWT_VAL(BLE_LL_SCHED_AUX_CHAIN_MAFS_DELAY);
    }

    itvl_usecs = (uint32_t)itvl * BLE_LL_ADV_PERIODIC_ITVL;

    return max_usecs < itvl_usecs;
}

int
ble_ll_adv_periodic_set_param(const uint8_t *cmdbuf, uint8_t len)
{
    const struct ble_hci_le_set_periodic_adv_params_cp *cmd = (const void *) cmdbuf;
    struct ble_ll_adv_sm *advsm;
    uint16_t adv_itvl_min;
    uint16_t adv_itvl_max;
    uint16_t props;

    if (len != sizeof(*cmd)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    adv_itvl_min = le16toh(cmd->min_itvl);
    adv_itvl_max = le16toh(cmd->max_itvl);
    props = le16toh(cmd->props);

    advsm = ble_ll_adv_sm_find_configured(cmd->adv_handle);
    if (!advsm) {
        return BLE_ERR_UNK_ADV_INDENT;
    }

    /* If the advertising set identified by the Advertising_Handle specified
     * scannable, connectable, legacy, or anonymous advertising, the Controller
     * shall return the error code Invalid HCI Command Parameters (0x12).
     */
    if (advsm->props & (BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV |
                        BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE |
                        BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE |
                        BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* If the Host issues this command when periodic advertising is enabled for
     * the specified advertising set, the Controller shall return the error code
     * Command Disallowed (0x0C).
     */
    if (advsm->periodic_adv_enabled) {
        return BLE_ERR_CMD_DISALLOWED;
    }

    /* validate intervals */
    if ((adv_itvl_min < 0x0006) || (adv_itvl_max < 0x006) ||
            (adv_itvl_min > adv_itvl_max)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* validate properties */
    if (props & ~BLE_HCI_LE_SET_PERIODIC_ADV_PROP_MASK) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* If the advertising set already contains periodic advertising data and the
     * length of the data is greater than the maximum that the Controller can
     * transmit within a periodic advertising interval of
     * Periodic_Advertising_Interval_Max, the Controller shall return the error
     * code Packet Too Long (0x45).
     */
    if (!ble_ll_adv_periodic_check_data_itvl(SYNC_DATA_LEN(advsm), props,
                                             adv_itvl_max, advsm->sec_phy)) {
        return BLE_ERR_PACKET_TOO_LONG;
    }

    advsm->periodic_adv_itvl = adv_itvl_max;
    advsm->periodic_adv_props = props;

    ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_PERIODIC_CONFIGURED);

    return BLE_ERR_SUCCESS;
}

int
ble_ll_adv_periodic_set_data(const uint8_t *cmdbuf, uint8_t len)
{
    const struct ble_hci_le_set_periodic_adv_data_cp *cmd = (const void *) cmdbuf;
    struct ble_ll_adv_sm *advsm;
    uint16_t payload_total_len;
    bool new_data = false;

    if (len < sizeof(*cmd)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    if (cmd->adv_data_len > BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN ||
            cmd->adv_data_len != len - sizeof(*cmd)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    advsm = ble_ll_adv_sm_find_configured(cmd->adv_handle);
    if (!advsm) {
        return BLE_ERR_UNK_ADV_INDENT;
    }

    if (!(advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_CONFIGURED)) {
        return BLE_ERR_CMD_DISALLOWED;
    }

    switch (cmd->operation) {
    case BLE_HCI_LE_SET_DATA_OPER_LAST:
    case BLE_HCI_LE_SET_DATA_OPER_INT:
        if (advsm->periodic_adv_enabled) {
            return BLE_ERR_CMD_DISALLOWED;
        }

        if (!(advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_DATA_INCOMPLETE)) {
            return BLE_ERR_INV_HCI_CMD_PARMS;
        }

        if (!advsm->periodic_adv_data || !cmd->adv_data_len) {
            return BLE_ERR_INV_HCI_CMD_PARMS;
        }
        break;
    case BLE_HCI_LE_SET_DATA_OPER_FIRST:
        if (advsm->periodic_adv_enabled) {
            return BLE_ERR_CMD_DISALLOWED;
        }

        if (!cmd->adv_data_len) {
            return BLE_ERR_INV_HCI_CMD_PARMS;
        }
        new_data = true;
        break;
    case BLE_HCI_LE_SET_DATA_OPER_COMPLETE:
        new_data = true;
        break;
    default:
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    payload_total_len = cmd->adv_data_len;
    if (!new_data) {
        payload_total_len += SYNC_DATA_LEN(advsm);
    }

    /* If the combined length of the data is greater than the maximum that the
     * Controller can transmit within the current periodic advertising interval
     * (if periodic advertising is currently enabled) or the
     * Periodic_Advertising_Interval_Max for the advertising set (if currently
     * disabled), all the data shall be discarded and the Controller shall
     * return the error code Packet Too Long (0x45).
     */
    if (!ble_ll_adv_periodic_check_data_itvl(payload_total_len,
                                             advsm->periodic_adv_props,
                                             advsm->periodic_adv_itvl,
                                             advsm->sec_phy)) {
        return BLE_ERR_PACKET_TOO_LONG;
    }

    if (advsm->periodic_adv_active) {
        ble_ll_adv_flags_clear(advsm, BLE_LL_ADV_SM_FLAG_PERIODIC_NEW_DATA);

        ble_ll_adv_update_data_mbuf(&advsm->periodic_new_data, true,
                                    BLE_ADV_DATA_MAX_LEN,
                                    cmd->adv_data, cmd->adv_data_len);
        if (!advsm->periodic_new_data) {
            return BLE_ERR_MEM_CAPACITY;
        }

        ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_PERIODIC_NEW_DATA);
    } else {
        ble_ll_adv_update_data_mbuf(&advsm->periodic_adv_data, new_data,
                                    BLE_ADV_DATA_MAX_LEN, cmd->adv_data,
                                    cmd->adv_data_len);
        if (!advsm->periodic_adv_data) {
            return BLE_ERR_MEM_CAPACITY;
        }
    }

    /* set/clear incomplete data flag only on success */
    switch (cmd->operation) {
    case BLE_HCI_LE_SET_DATA_OPER_LAST:
    case BLE_HCI_LE_SET_DATA_OPER_COMPLETE:
        ble_ll_adv_flags_clear(advsm,
                               BLE_LL_ADV_SM_FLAG_PERIODIC_DATA_INCOMPLETE);
        break;
    case BLE_HCI_LE_SET_DATA_OPER_INT:
    case BLE_HCI_LE_SET_DATA_OPER_FIRST:
    default:
        ble_ll_adv_flags_set(advsm,
                             BLE_LL_ADV_SM_FLAG_PERIODIC_DATA_INCOMPLETE);
        break;
    }

    return BLE_ERR_SUCCESS;
}

int
ble_ll_adv_periodic_enable(const uint8_t *cmdbuf, uint8_t len)
{
    const struct ble_hci_le_set_periodic_adv_enable_cp *cmd = (const void *)cmdbuf;
    struct ble_ll_adv_sm *advsm;

    if (len != sizeof(*cmd)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    advsm = ble_ll_adv_sm_find_configured(cmd->adv_handle);
    if (!advsm) {
        return BLE_ERR_UNK_ADV_INDENT;
    }

#if MYNEWT_VAL(BLE_VERSION) >= 53
    if (cmd->enable & 0x02) {
        return BLE_ERR_UNSUPPORTED;
    } else if (cmd->enable & 0xfc) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }
#else
    if (cmd->enable & 0xfe) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }
#endif

    if (cmd->enable) {
        if (advsm->props & (BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV |
                            BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE |
                            BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE |
                            BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY)) {
            return BLE_ERR_CMD_DISALLOWED;
        }

        if (advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_DATA_INCOMPLETE) {
            return BLE_ERR_CMD_DISALLOWED;
        }

        if (!(advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_CONFIGURED)) {
            return BLE_ERR_CMD_DISALLOWED;
        }

        /* If Enable is set to 0x01 and the length of the periodic advertising
         * data is greater than the maximum that the Controller can transmit
         * within the chosen periodicadvertising interval, the Controller shall
         * return the error code Packet Too Long (0x45).
         */
        if (!ble_ll_adv_periodic_check_data_itvl(SYNC_DATA_LEN(advsm),
                                                 advsm->periodic_adv_props,
                                                 advsm->periodic_adv_itvl,
                                                 advsm->sec_phy)) {
            return BLE_ERR_PACKET_TOO_LONG;
        }

        /* If the advertising set is not currently enabled (see the
         * LE_Set_Extended_Advertising_Enable command), the periodic advertising
         * is not started until the advertising set is enabled.
         */
        if (advsm->adv_enabled && !advsm->periodic_adv_active) {
            /* Start the periodic advertising state machine */
            ble_ll_adv_sm_start_periodic(advsm);
        }
    } else {
        /* Stop the periodic advertising state machine */
        ble_ll_adv_sm_stop_periodic(advsm);
    }

    advsm->periodic_adv_enabled = cmd->enable;

    return BLE_ERR_SUCCESS;
}

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER)
static int
ble_ll_adv_periodic_send_sync_ind(struct ble_ll_adv_sm *advsm,
                                  struct ble_ll_conn_sm *connsm,
                                  uint16_t service_data)
{
    struct os_mbuf *om;
    uint8_t *sync_ind;

    om = os_msys_get_pkthdr(BLE_LL_CTRL_MAX_PDU_LEN,
                            sizeof(struct ble_mbuf_hdr));
    if (!om) {
        return BLE_ERR_MEM_CAPACITY;
    }

    om->om_data[0] = BLE_LL_CTRL_PERIODIC_SYNC_IND;

    sync_ind = om->om_data + 1;

    /* ID (service_data), already in LE order */
    memcpy(sync_ind, &service_data, sizeof(service_data));

    /* fill in syncinfo */
    ble_ll_adv_put_syncinfo(advsm, connsm, sync_ind + 20, sync_ind + 2);

    /* lastPaEventCounter */
    put_le16(sync_ind + 22, advsm->periodic_event_cntr_last_sent);

    /* SID, AType, SCA */
    sync_ind[24] = (advsm->adi >> 12);
    sync_ind[24] |= !!(advsm->flags & BLE_LL_ADV_SM_FLAG_TX_ADD) << 4;
    sync_ind[24] |= BLE_LL_SCA_ENUM << 5;

    /* PHY */
    sync_ind[25] = (0x01 << (advsm->sec_phy - 1));

    /* AdvA */
    memcpy(sync_ind + 26, advsm->adva, BLE_DEV_ADDR_LEN);

    /* syncConnEventCount */
    put_le16(sync_ind + 32, connsm->event_cntr);

    ble_ll_conn_enqueue_pkt(connsm, om, BLE_LL_LLID_CTRL,
                            BLE_LL_CTRL_PERIODIC_SYNC_IND_LEN + 1);

    return BLE_ERR_SUCCESS;
}

int
ble_ll_adv_periodic_set_info_transfer(const uint8_t *cmdbuf, uint8_t len,
                                      uint8_t *rspbuf, uint8_t *rsplen)
{
    const struct ble_hci_le_periodic_adv_set_info_transfer_cp *cmd = (const void *)cmdbuf;
     struct ble_hci_le_periodic_adv_set_info_transfer_rp *rsp = (void *) rspbuf;
     struct ble_ll_conn_sm *connsm;
     struct ble_ll_adv_sm *advsm;
     uint16_t handle;
     int rc;

     if (len != sizeof(*cmd)) {
         rc = BLE_ERR_INV_HCI_CMD_PARMS;
         goto done;
     }

     advsm = ble_ll_adv_sm_find_configured(cmd->adv_handle);
     if (!advsm) {
         rc = BLE_ERR_UNK_ADV_INDENT;
         goto done;
     }

     if (!advsm->periodic_adv_active) {
         rc = BLE_ERR_CMD_DISALLOWED;
         goto done;
     }

     handle = le16toh(cmd->conn_handle);
     if (handle > 0xeff) {
         rc = BLE_ERR_INV_HCI_CMD_PARMS;
         goto done;
     }

     connsm = ble_ll_conn_find_by_handle(handle);
     if (!connsm) {
         rc = BLE_ERR_UNK_CONN_ID;
         goto done;
     }

     /* TODO should not need to shift
      * byte 3 (0 byte is conn_feature) , bit 1
      *
      * Allow initiate LL procedure only if remote supports it.
      */
     if (!ble_ll_conn_rem_feature_check(connsm, BLE_LL_FEAT_SYNC_TRANS_RECV)) {
         rc = BLE_ERR_UNSUPP_REM_FEATURE;
         goto done;
     }

     rc = ble_ll_adv_periodic_send_sync_ind(advsm, connsm, cmd->service_data);
 done:
     rsp->conn_handle = cmd->conn_handle;
     *rsplen = sizeof(*rsp);
     return rc;
}
#endif
#endif
#endif

/**
 * Called when the LL receives a scan request or connection request
 *
 * Context: Called from interrupt context.
 *
 * @param rxbuf
 *
 * @return -1: request not for us or is a connect request.
 *          0: request (scan) is for us and we successfully went from rx to tx.
 *        > 0: PHY error attempting to go from rx to tx.
 */
static int
ble_ll_adv_rx_req(uint8_t pdu_type, struct os_mbuf *rxpdu)
{
    int rc;
    int resolved;
    uint8_t chk_wl;
    uint8_t txadd;
    uint8_t peer_addr_type;
    uint8_t *rxbuf;
    uint8_t *adva;
    uint8_t *peer;
    struct ble_mbuf_hdr *ble_hdr;
    struct ble_ll_adv_sm *advsm;
#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL)
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    struct aux_conn_rsp_data rsp_data;
#endif
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
    struct ble_ll_resolv_entry *rl;
#endif

    /* See if adva in the request (scan or connect) matches what we sent */
    advsm = g_ble_ll_cur_adv_sm;
    rxbuf = rxpdu->om_data;
    adva = rxbuf + BLE_LL_PDU_HDR_LEN + BLE_DEV_ADDR_LEN;
    if (memcmp(advsm->adva, adva, BLE_DEV_ADDR_LEN)) {
        return -1;
    }

    /* Set device match bit if we are whitelisting */
    if (pdu_type == BLE_ADV_PDU_TYPE_SCAN_REQ) {
        chk_wl = advsm->adv_filter_policy & 1;
    } else {
        chk_wl = advsm->adv_filter_policy & 2;
    }

    /* Get the peer address type */
    if (rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK) {
        txadd = BLE_ADDR_RANDOM;
    } else {
        txadd = BLE_ADDR_PUBLIC;
    }

    ble_hdr = BLE_MBUF_HDR_PTR(rxpdu);
    peer = rxbuf + BLE_LL_PDU_HDR_LEN;
    peer_addr_type = txadd;
    resolved = 0;

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
    rl = NULL;
    if (ble_ll_resolv_enabled()) {
        if (ble_ll_is_rpa(peer, txadd)) {
            advsm->adv_rpa_index = ble_hw_resolv_list_match();
            if (advsm->adv_rpa_index >= 0) {
                ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_RESOLVED;
                rl = &g_ble_ll_resolv_list[advsm->adv_rpa_index];
                if (chk_wl) {
                    peer = rl->rl_identity_addr;
                    peer_addr_type = rl->rl_addr_type;
                    resolved = 1;
                }
            } else {
                if (chk_wl) {
                    return -1;
                }
            }
        } else {
            /* Verify privacy mode */
            rl = ble_ll_resolv_list_find(peer, peer_addr_type);
            if (rl && (rl->rl_priv_mode == BLE_HCI_PRIVACY_NETWORK) &&
                rl->rl_has_peer) {
                return -1;
            }
        }
    }
#endif

    /* Set device match bit if we are whitelisting */
    if (chk_wl && !ble_ll_whitelist_match(peer, peer_addr_type, resolved)) {
        return -1;
    }

    /*
     * We set the device match bit to tell the upper layer that we will
     * accept the request
     */
    ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_DEVMATCH;

    /* Setup to transmit the scan response if appropriate */
    rc = -1;

    if (pdu_type == BLE_ADV_PDU_TYPE_SCAN_REQ) {
        /* PHY used for scan requests shall be the same as the PHY used for the
         * PDU that they reply to so no need to change PHY mode.
         */
        ble_phy_set_txend_cb(ble_ll_adv_tx_done, advsm);

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
        if (advsm->flags & BLE_LL_ADV_SM_FLAG_SCAN_REQ_NOTIF) {
            ble_ll_hci_ev_send_scan_req_recv(advsm->adv_instance, peer,
                                             peer_addr_type);
        }

        /*
         * We need to store current rxed packet header temporarily so AuxPtr
         * can be calculated (if necessary) relative to AUX_SCAN_RSP instead of
         * AUX_ADV_IND.
         */

        advsm->rx_ble_hdr = ble_hdr;
        rc = ble_phy_tx(ble_ll_adv_scan_rsp_pdu_make, advsm,
                        BLE_PHY_TRANSITION_NONE);
        advsm->rx_ble_hdr = NULL;
#else
        rc = ble_phy_tx(ble_ll_adv_scan_rsp_legacy_pdu_make, advsm,
                        BLE_PHY_TRANSITION_NONE);
#endif

        if (!rc) {
            ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_SCAN_RSP_TXD;
            STATS_INC(ble_ll_stats, scan_rsp_txg);
        }
    } else if (pdu_type == BLE_ADV_PDU_TYPE_AUX_CONNECT_REQ) {
#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL)
        /* See if the device is already connected */
        if (ble_ll_conn_find_by_peer_addr(peer, peer_addr_type)) {
            return -1;
        }

        /*
         * Only accept connect requests from the desired address if we
         * are doing directed advertising
         */
        if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED) {
            if (memcmp(advsm->initiator_addr, peer, BLE_DEV_ADDR_LEN)) {
                return -1;
            }
        }

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
        if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
            return -1;
        }

        /* use remote address used over the air */
        rsp_data.advsm = advsm;
        rsp_data.peer = rxbuf + BLE_LL_PDU_HDR_LEN;
        rsp_data.rxadd = rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK;

        ble_phy_set_txend_cb(ble_ll_adv_tx_done, advsm);
        rc = ble_phy_tx(ble_ll_adv_aux_conn_rsp_pdu_make, &rsp_data,
                        BLE_PHY_TRANSITION_NONE);
        if (!rc) {
            ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD);
            STATS_INC(ble_ll_stats, aux_conn_rsp_tx);
        }
#endif
#endif
    }

    return rc;
}

/**
 * Called when a connect request has been received.
 *
 * Context: Link Layer
 *
 * @param rxbuf
 * @param flags
 *
 * @return 0: no connection started. 1: connection started
 */
#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL)
static int
ble_ll_adv_conn_req_rxd(uint8_t *rxbuf, struct ble_mbuf_hdr *hdr,
                        struct ble_ll_adv_sm *advsm)
{
    int valid;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
    uint8_t resolved;
#endif
    uint8_t addr_type;
    uint8_t *inita;
    uint8_t *ident_addr;

    /* Don't create connection if AUX_CONNECT_RSP was not send */
    if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY)) {
        if (!(advsm->flags & BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD)) {
            return 0;
        }
    }

    /* Check filter policy. */
    valid = 0;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
    resolved = BLE_MBUF_HDR_RESOLVED(hdr);
#endif
    inita = rxbuf + BLE_LL_PDU_HDR_LEN;
    if (hdr->rxinfo.flags & BLE_MBUF_HDR_F_DEVMATCH) {

        valid = 1;
        if (rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK) {
            addr_type = BLE_ADDR_RANDOM;
        } else {
            addr_type = BLE_ADDR_PUBLIC;
        }

        /*
         * Only accept connect requests from the desired address if we
         * are doing directed advertising
         */
        if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED) {
            ident_addr = inita;

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
            if (resolved) {
                ident_addr = g_ble_ll_resolv_list[advsm->adv_rpa_index].rl_identity_addr;
                addr_type = g_ble_ll_resolv_list[advsm->adv_rpa_index].rl_addr_type;
            }
#endif
            if ((addr_type != advsm->peer_addr_type) ||
                memcmp(advsm->peer_addr, ident_addr, BLE_DEV_ADDR_LEN)) {
                valid = 0;
            }
        }
    }

    if (valid) {
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
        if (resolved) {
            /* Retain the resolvable private address that we received. */
            memcpy(advsm->adv_rpa, inita, BLE_DEV_ADDR_LEN);

            /* Update resolving list with current peer RPA */
            ble_ll_resolv_set_peer_rpa(advsm->adv_rpa_index, inita);

            /*
             * Overwrite received inita with identity address since that
             * is used from now on.
             */
            memcpy(inita,
                   g_ble_ll_resolv_list[advsm->adv_rpa_index].rl_identity_addr,
                   BLE_DEV_ADDR_LEN);

            /* Peer address type is an identity address */
            addr_type = g_ble_ll_resolv_list[advsm->adv_rpa_index].rl_addr_type;
            addr_type += 2;
        }
#endif

        /* Try to start peripheral connection. If successful, stop advertising */
        valid = ble_ll_conn_periph_start(rxbuf, addr_type, hdr,
                                         !(advsm->props &
                                           BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY));
        if (valid) {
            /* stop advertising only if not transmitting connection response */
            if (!(advsm->flags & BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD)) {
                ble_ll_adv_sm_stop(advsm);
            }
        } else if (advsm->flags & BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD) {
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
            ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD_ERR);
            valid = 1;
#endif
        }
    }

    return valid;
}
#endif

/**
 * Called on phy rx pdu end when in advertising state.
 *
 * There are only two pdu types we care about in this state: scan requests
 * and connection requests. When we receive a scan request we must determine if
 * we need to send a scan response and that needs to be acted on within T_IFS.
 *
 * When we receive a connection request, we need to determine if we will allow
 * this device to start a connection with us. However, no immediate response is
 * sent so we handle this at the link layer task.
 *
 * Context: Interrupt
 *
 * @param pdu_type Type of pdu received.
 * @param rxpdu Pointer to received PDU
 *
 * @return int
 *       < 0: Disable the phy after reception.
 *      == 0: Do not disable the PHY
 *       > 0: Do not disable PHY as that has already been done.
 */
int
ble_ll_adv_rx_isr_end(uint8_t pdu_type, struct os_mbuf *rxpdu, int crcok)
{
    int rc;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    struct ble_mbuf_hdr *rxhdr;
#endif

    rc = -1;
    if (rxpdu == NULL) {
        ble_ll_adv_tx_done(g_ble_ll_cur_adv_sm);
    } else {
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
        rxhdr = BLE_MBUF_HDR_PTR(rxpdu);
        rxhdr->rxinfo.user_data = g_ble_ll_cur_adv_sm;
        if (ble_ll_adv_active_chanset_is_sec(g_ble_ll_cur_adv_sm)) {
            rxhdr->rxinfo.flags |= BLE_MBUF_HDR_F_EXT_ADV_SEC;
        } else {
            BLE_LL_ASSERT(ble_ll_adv_active_chanset_is_pri(g_ble_ll_cur_adv_sm));
        }
#endif
        if (crcok) {
            if ((pdu_type == BLE_ADV_PDU_TYPE_SCAN_REQ) ||
                (pdu_type == BLE_ADV_PDU_TYPE_CONNECT_IND)) {
                /* Process request */
                rc = ble_ll_adv_rx_req(pdu_type, rxpdu);
            }
        }

        if (rc) {
            /* We no longer have a current state machine */
            g_ble_ll_cur_adv_sm = NULL;
        }
    }

    if (rc) {
        ble_ll_state_set(BLE_LL_STATE_STANDBY);
    }

    return rc;
}

/**
 * Process a received packet at the link layer task when in the advertising
 * state
 *
 * Context: Link Layer
 *
 *
 * @param ptype
 * @param rxbuf
 * @param hdr
 *
 * @return int
 */
void
ble_ll_adv_rx_pkt_in(uint8_t ptype, uint8_t *rxbuf, struct ble_mbuf_hdr *hdr)
{
    int adv_event_over;
    struct ble_ll_adv_sm *advsm;

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    advsm = (struct ble_ll_adv_sm *)hdr->rxinfo.user_data;
#else
    advsm = &g_ble_ll_adv_sm[0];
#endif

    /*
     * It is possible that advertising was stopped and a packet placed on the
     * LL receive packet queue. In this case, just ignore the received packet
     * as the advertising state machine is no longer "valid"
     */
    if (!advsm->adv_enabled) {
        return;
    }

    /*
     * If we have received a scan request and we are transmitting a response
     * or we have received a valid connect request, dont "end" the advertising
     * event. In the case of a connect request we will stop advertising. In
     * the case of the scan response transmission we will get a transmit
     * end callback.
     */
    adv_event_over = 1;
    if (BLE_MBUF_HDR_CRC_OK(hdr)) {
        if (ptype == BLE_ADV_PDU_TYPE_CONNECT_IND) {
#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL)
            if (ble_ll_adv_conn_req_rxd(rxbuf, hdr, advsm)) {
                adv_event_over = 0;
            }
#endif
        } else {
            if ((ptype == BLE_ADV_PDU_TYPE_SCAN_REQ) &&
                (hdr->rxinfo.flags & BLE_MBUF_HDR_F_SCAN_RSP_TXD)) {
                adv_event_over = 0;
            }
        }
    }

    if (adv_event_over) {
        ble_ll_adv_make_done(advsm, hdr);
    }
}

/**
 * Called when a receive PDU has started and we are advertising.
 *
 * Context: interrupt
 *
 * @param pdu_type
 * @param rxpdu
 *
 * @return int
 *   < 0: A frame we dont want to receive.
 *   = 0: Continue to receive frame. Dont go from rx to tx
 *   > 0: Continue to receive frame and go from rx to tx when done
 */
int
ble_ll_adv_rx_isr_start(uint8_t pdu_type)
{
    int rc;
    struct ble_ll_adv_sm *advsm;

    /* Assume we will abort the frame */
    rc = -1;

    /* If we get a scan request we must tell the phy to go from rx to tx */
    advsm = g_ble_ll_cur_adv_sm;
    if (pdu_type == BLE_ADV_PDU_TYPE_SCAN_REQ) {
        /* Only accept scan requests if we are indirect adv or scan adv */
        if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE) {
            rc = 1;
        }
    } else {
        /* Only accept connect requests if connectable advertising event */
        if (pdu_type == BLE_ADV_PDU_TYPE_CONNECT_IND) {
            if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE) {
                /* Need transition to TX if extended adv */
                rc = !(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY);
            }
        }
    }

    /*
     * If we abort the frame, we need to post the LL task to check if the
     * advertising event is over.
     */
    if (rc < 0) {
        ble_ll_adv_tx_done(advsm);
    }

    return rc;
}

static void
ble_ll_adv_drop_event(struct ble_ll_adv_sm *advsm, bool preempted)
{
    os_sr_t sr;

    STATS_INC(ble_ll_stats, adv_drop_event);

    ble_ll_sched_rmv_elem(&advsm->adv_sch);
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    ble_ll_sched_rmv_elem(&advsm->aux[0].sch);
    ble_ll_sched_rmv_elem(&advsm->aux[1].sch);

    ble_ll_event_remove(&advsm->adv_sec_txdone_ev);
    advsm->aux_active = 0;
#endif

    if (preempted) {
        OS_ENTER_CRITICAL(sr);
        advsm->retry_event = !(advsm->flags & BLE_LL_ADV_SM_FLAG_ACTIVE_CHANSET_MASK);
        OS_EXIT_CRITICAL(sr);
    }

    advsm->adv_chan = ble_ll_adv_final_chan(advsm);
    ble_ll_event_add(&advsm->adv_txdone_ev);
}

static void
ble_ll_adv_reschedule_event(struct ble_ll_adv_sm *advsm)
{
    struct ble_ll_sched_item *sch;
    uint32_t max_delay_ticks;
    int rc;

    BLE_LL_ASSERT(advsm->adv_enabled);

    sch = &advsm->adv_sch;

    if (!sch->enqueued) {
        if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) {
            max_delay_ticks = 0;
        } else {
            max_delay_ticks = ble_ll_tmr_u2t(BLE_LL_ADV_DELAY_MS_MAX * 1000);
        }

        rc = ble_ll_sched_adv_reschedule(sch, max_delay_ticks);
        if (rc) {
            ble_ll_adv_drop_event(advsm, 0);
            return;
        }

        advsm->adv_event_start_time = sch->start_time +
                                      g_ble_ll_sched_offset_ticks;
        advsm->adv_pdu_start_time = advsm->adv_event_start_time;
    }

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) &&
                                                        !advsm->aux_active) {
        ble_ll_adv_aux_schedule(advsm);
    }
#endif
}

/**
 * Called when an advertising event is over.
 *
 * Context: Link Layer task.
 *
 * @param arg Pointer to advertising state machine.
 */
static void
ble_ll_adv_done(struct ble_ll_adv_sm *advsm)

{
    int rc;
    int resched_pdu;
    uint8_t mask;
    uint8_t final_adv_chan;
    int32_t delta_t;
    uint32_t itvl;
    uint32_t tick_itvl;
    uint32_t start_time;

    BLE_LL_ASSERT(advsm->adv_enabled);

    ble_ll_rfmgmt_release();

    ble_ll_adv_update_adv_scan_rsp_data(advsm);

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
        /* stop advertising this was due to transmitting connection response */
        if (advsm->flags & BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD) {
            ble_ll_adv_sm_stop(advsm);
            return;
        }
    }
#endif

    /* Remove the element from the schedule if it is still there. */
    ble_ll_sched_rmv_elem(&advsm->adv_sch);

    ble_ll_event_remove(&advsm->adv_txdone_ev);

    /*
     * Check if we have ended our advertising event. If our last advertising
     * packet was sent on the last channel, it means we are done with this
     * event.
     */
    final_adv_chan = ble_ll_adv_final_chan(advsm);

    if (advsm->adv_chan == final_adv_chan) {
        ble_ll_scan_chk_resume();

        /* This event is over. Set adv channel to first one */
        advsm->adv_chan = ble_ll_adv_first_chan(advsm);

        itvl = advsm->adv_itvl_usecs;
        tick_itvl = ble_ll_tmr_u2t(itvl);

        /* do not calculate new event time if current event should be retried;
         * this happens if event was preempted, so we just try to schedule one
         * more time with the same start time
         */

        if (!advsm->retry_event) {
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
            if (advsm->events_max) {
                advsm->events++;
            }
#endif

            /*
             * Calculate start time of next advertising event. NOTE: we do not
             * add the random advDelay as the scheduling code will do that.
             */
            advsm->adv_event_start_time += tick_itvl;
            advsm->adv_pdu_start_time = advsm->adv_event_start_time;
        } else {
            advsm->retry_event = 0;
        }

        /*
         * The scheduled time better be in the future! If it is not, we will
         * just keep advancing until we the time is in the future
         */
        start_time = advsm->adv_pdu_start_time - g_ble_ll_sched_offset_ticks;

        delta_t = (int32_t)(start_time - ble_ll_tmr_get());
        if (delta_t < 0) {
            /*
             * NOTE: we just the same interval that we calculated earlier.
             * No real need to keep recalculating a new interval.
             */
            while (delta_t < 0) {
                advsm->adv_event_start_time += tick_itvl;
                advsm->adv_pdu_start_time = advsm->adv_event_start_time;
                delta_t += (int32_t)tick_itvl;
            }
        }
        resched_pdu = 0;
    } else {
        /*
         * Move to next advertising channel. If not in the mask, just
         * increment by 1. We can do this because we already checked if we
         * just transmitted on the last advertising channel
         */
        ++advsm->adv_chan;
        mask = 1 << (advsm->adv_chan - BLE_PHY_ADV_CHAN_START);
        if ((mask & advsm->adv_chanmask) == 0) {
            ++advsm->adv_chan;
        }

        /* We want to send next PDU right away so start time is set to "now"
         * plus scheduling offset. Add an extra tick since LL timer may tick
         * when we calculate other things in the meantime.
         */
        advsm->adv_pdu_start_time = ble_ll_tmr_get() +
                                    g_ble_ll_sched_offset_ticks + 1;

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
        /* If we're past aux (unlikely, but can happen), just drop an event */
        if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) &&
                advsm->aux_active &&
                LL_TMR_GT(advsm->adv_pdu_start_time,
                           AUX_CURRENT(advsm)->start_time)) {
            ble_ll_adv_drop_event(advsm, 0);
            return;
        }
#endif

        resched_pdu = 1;
    }

    /* check if advertising timed out */
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    if (advsm->duration &&
        LL_TMR_GEQ(advsm->adv_pdu_start_time, advsm->adv_end_time)) {
        /* Legacy PDUs need to be stop here.
         * For ext adv it will be stopped when AUX is done (unless it was
         * dropped so check if AUX is active here as well).
         */
        if ((advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) ||
                !advsm->aux_active) {
            ble_ll_adv_sm_stop_timeout(advsm);
        }

        return;
    }
#else
    if ((advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) &&
        LL_TMR_GEQ(advsm->adv_pdu_start_time, advsm->adv_end_time)) {
        ble_ll_adv_sm_stop_timeout(advsm);
        return;
    }
#endif

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    if (advsm->events_max && (advsm->events >= advsm->events_max)) {
        /* Legacy PDUs need to be stop here.
         * For ext adv it will be stopped when AUX is done (unless it was
         * dropped so check if AUX is active here as well).
         */
        if ((advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) ||
                !advsm->aux_active) {
            ble_ll_adv_sm_stop_limit_reached(advsm);
        }

        return;
    }
#endif

    /* We need to regenerate our RPA's if we have passed timeout */
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
    ble_ll_adv_chk_rpa_timeout(advsm);
#endif

    /* Schedule advertising transmit */
    ble_ll_adv_set_sched(advsm);

    if (!resched_pdu) {
        ble_ll_adv_reschedule_event(advsm);
        return;
    }

    /*
     * In the unlikely event we can't reschedule this, just post a done event
     * and we will reschedule the next advertising PDU.
     */
    rc = ble_ll_sched_adv_resched_pdu(&advsm->adv_sch);
    if (rc) {
        STATS_INC(ble_ll_stats, adv_resched_pdu_fail);
        ble_ll_event_add(&advsm->adv_txdone_ev);
    }
}

static void
ble_ll_adv_event_done(struct ble_npl_event *ev)
{
    ble_ll_adv_done(ble_npl_event_get_arg(ev));
}

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
/**
 * Called when auxiliary packet is txd on secondary channel
 *
 * Context: Link Layer task.
 *
 * @param ev
 */
static void
ble_ll_adv_sec_done(struct ble_ll_adv_sm *advsm)
{
    struct ble_ll_adv_aux *aux;
    struct ble_ll_adv_aux *aux_next;

    BLE_LL_ASSERT(advsm->adv_enabled);
    BLE_LL_ASSERT(advsm->aux_active);

    aux = AUX_CURRENT(advsm);
    aux_next = AUX_NEXT(advsm);

    /* We don't need RF anymore */
    ble_ll_rfmgmt_release();

    if (advsm->aux_dropped) {
        ble_ll_adv_drop_event(advsm, 0);
        return;
    }

    if (advsm->aux_not_scanned) {
        ble_ll_sched_rmv_elem(&aux_next->sch);
    }

    /* Remove anything else scheduled for secondary channel */
    ble_ll_sched_rmv_elem(&aux->sch);
    ble_ll_event_remove(&advsm->adv_sec_txdone_ev);

    /* Stop advertising due to transmitting connection response */
    if (advsm->flags & BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD) {
        if (!(advsm->flags & BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD_ERR)) {
            ble_ll_adv_sm_stop(advsm);
            return;
        } else {
            ble_ll_adv_flags_clear(advsm, BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD |
                                          BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD_ERR);
        }
    }

    /* If we have next AUX scheduled, try to schedule another one */
    if (aux_next->sch.enqueued) {
        advsm->aux_index ^= 1;
        advsm->aux_first_pdu = 0;
        ble_ll_adv_aux_schedule_next(advsm);
        return;
    }

    ble_ll_scan_chk_resume();

    /* Check if advertising timed out */
    if (advsm->duration &&
        LL_TMR_GEQ(advsm->adv_pdu_start_time, advsm->adv_end_time)) {
        ble_ll_adv_sm_stop_timeout(advsm);
        return;
    }

    if (advsm->events_max && (advsm->events >= advsm->events_max)) {
        ble_ll_adv_sm_stop_limit_reached(advsm);
        return;
    }

    advsm->aux_active = 0;
    ble_ll_adv_update_adv_scan_rsp_data(advsm);
    ble_ll_adv_reschedule_event(advsm);
}

static void
ble_ll_adv_sec_event_done(struct ble_npl_event *ev)
{
    ble_ll_adv_sec_done(ble_npl_event_get_arg(ev));
}
#endif

static void
ble_ll_adv_make_done(struct ble_ll_adv_sm *advsm, struct ble_mbuf_hdr *hdr)
{
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    if (BLE_MBUF_HDR_EXT_ADV_SEC(hdr)) {
        BLE_LL_ASSERT(!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY));
        BLE_LL_ASSERT(ble_ll_adv_active_chanset_is_sec(advsm));
        ble_ll_adv_active_chanset_clear(advsm);
        ble_ll_adv_sec_done(advsm);
    } else {
        BLE_LL_ASSERT(ble_ll_adv_active_chanset_is_pri(advsm));
        ble_ll_adv_active_chanset_clear(advsm);
        ble_ll_adv_done(advsm);
    }
#else
    ble_ll_adv_active_chanset_clear(advsm);
    ble_ll_adv_done(advsm);
#endif
}

/**
 * Checks if the controller can change the whitelist. If advertising is enabled
 * and is using the whitelist the controller is not allowed to change the
 * whitelist.
 *
 * @return int 0: not allowed to change whitelist; 1: change allowed.
 */
int
ble_ll_adv_can_chg_whitelist(void)
{
    struct ble_ll_adv_sm *advsm;
    int rc;
    int i;

    rc = 1;
    for (i = 0; i < BLE_ADV_INSTANCES; ++i) {
        advsm = &g_ble_ll_adv_sm[i];
        if (advsm->adv_enabled &&
            (advsm->adv_filter_policy != BLE_HCI_ADV_FILT_NONE)) {
            rc = 0;
            break;
        }
    }

    return rc;
}

/**
 * Sends the connection complete event when advertising a connection starts.
 *
 * @return uint8_t* Pointer to event buffer
 */
#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL)
void
ble_ll_adv_send_conn_comp_ev(struct ble_ll_conn_sm *connsm,
                             struct ble_mbuf_hdr *rxhdr)
{
    struct ble_ll_adv_sm *advsm;

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    advsm = (struct ble_ll_adv_sm *)rxhdr->rxinfo.user_data;
#else
    advsm = &g_ble_ll_adv_sm[0];
#endif

    BLE_LL_ASSERT(advsm->conn_comp_ev != NULL);
    ble_ll_conn_comp_event_send(connsm, BLE_ERR_SUCCESS, advsm->conn_comp_ev,
                                advsm);
    advsm->conn_comp_ev = NULL;

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2)
    ble_ll_hci_ev_le_csa(connsm);
#endif

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    if (ble_ll_hci_adv_mode_ext()) {
        ble_ll_hci_ev_send_adv_set_terminated(0, advsm->adv_instance,
                                          connsm->conn_handle, advsm->events);
    }
#endif
}
#endif

/**
 * Returns the local resolvable private address currently being using by
 * the advertiser
 *
 * @return uint8_t*
 */
uint8_t *
ble_ll_adv_get_local_rpa(struct ble_ll_adv_sm *advsm)
{
    uint8_t *rpa = NULL;

    if (advsm->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) {
        if ((advsm->flags & BLE_LL_ADV_SM_FLAG_TX_ADD) &&
                                    ble_ll_is_rpa(advsm->adva, 1)) {
            rpa = advsm->adva;
        }
    }

    return rpa;
}

/**
 * Returns the peer resolvable private address of last device connecting to us
 *
 * @return uint8_t*
 */
uint8_t *
ble_ll_adv_get_peer_rpa(struct ble_ll_adv_sm *advsm)
{
    /* XXX: should this go into IRK list or connection? */
    return advsm->adv_rpa;
}

/**
 * Called when the LL wait for response timer expires while in the advertising
 * state. Disables the phy and
 *
 */
void
ble_ll_adv_wfr_timer_exp(void)
{
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    g_ble_ll_cur_adv_sm->aux_not_scanned = 1;
#endif

    ble_phy_disable();
    ble_ll_adv_tx_done(g_ble_ll_cur_adv_sm);
}

/**
 * Reset the advertising state machine.
 *
 * Context: Link Layer task
 *
 */
void
ble_ll_adv_reset(void)
{
    int i;
    struct ble_ll_adv_sm *advsm;

    for (i = 0; i < BLE_ADV_INSTANCES; ++i) {
        advsm = &g_ble_ll_adv_sm[i];

        /* Stop advertising state machine */
        ble_ll_adv_sm_stop(advsm);

        /* clear any data present */
        os_mbuf_free_chain(advsm->adv_data);
        os_mbuf_free_chain(advsm->scan_rsp_data);

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV)
        /* Stop periodic advertising state machine */
        ble_ll_adv_sm_stop_periodic(advsm);

        /* clear any periodic data present */
        os_mbuf_free_chain(advsm->periodic_adv_data);
#endif

        /* re-initialize the advertiser state machine */
        ble_ll_adv_sm_init(advsm);
    }
}

/* Called to determine if advertising is enabled.
 */
uint8_t
ble_ll_adv_enabled(void)
{
    int i;

    for (i = 0; i < BLE_ADV_INSTANCES; i++) {
        if (g_ble_ll_adv_sm[i].adv_enabled) {
            return 1;
        }
    }

    return 0;
}

static void
ble_ll_adv_sm_init(struct ble_ll_adv_sm *advsm)
{
    memset(advsm, 0, sizeof(struct ble_ll_adv_sm));

    advsm->adv_chanmask = BLE_HCI_ADV_CHANMASK_DEF;

    /* Initialize advertising tx done event */
    ble_npl_event_init(&advsm->adv_txdone_ev, ble_ll_adv_event_done, advsm);
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    ble_npl_event_init(&advsm->adv_sec_txdone_ev, ble_ll_adv_sec_event_done, advsm);
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV)
    ble_npl_event_init(&advsm->adv_periodic_txdone_ev,
                       ble_ll_adv_periodic_event_done, advsm);
#endif

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
    /* Initialize aux schedulers */
    advsm->aux_active = 0;
    advsm->aux[0].sch.cb_arg = advsm;
    advsm->aux[0].sch.sched_cb = ble_ll_adv_secondary_tx_start_cb;
    advsm->aux[0].sch.sched_type = BLE_LL_SCHED_TYPE_ADV;
    advsm->aux[1].sch.cb_arg = advsm;
    advsm->aux[1].sch.sched_cb = ble_ll_adv_secondary_tx_start_cb;
    advsm->aux[1].sch.sched_type = BLE_LL_SCHED_TYPE_ADV;

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV)
    /* Initialize sync schedulers */
    advsm->periodic_sync_active = 0;
    advsm->periodic_sync[0].sch.cb_arg = advsm;
    advsm->periodic_sync[0].sch.sched_cb = ble_ll_adv_sync_tx_start_cb;
    advsm->periodic_sync[0].sch.sched_type = BLE_LL_SCHED_TYPE_PERIODIC;
    advsm->periodic_sync[1].sch.cb_arg = advsm;
    advsm->periodic_sync[1].sch.sched_cb = ble_ll_adv_sync_tx_start_cb;
    advsm->periodic_sync[1].sch.sched_type = BLE_LL_SCHED_TYPE_PERIODIC;
#endif
#endif

    /* Configure instances to be legacy on start */
    advsm->props |= BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE;
    advsm->props |= BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY;
}

#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
struct ble_ll_adv_sm *
ble_ll_adv_sync_get(uint8_t handle)
{
    struct ble_ll_adv_sm *advsm;

    advsm = ble_ll_adv_sm_find_configured(handle);
    if (!advsm) {
        return NULL;
    }

    if (!(advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_CONFIGURED)) {
        return NULL;
    }

    return advsm;
}

int
ble_ll_adv_sync_sched_get(struct ble_ll_adv_sm *advsm, uint32_t *start_time,
                          uint32_t *end_time)
{
    struct ble_ll_adv_sync *sync;

    if (!advsm || !advsm->periodic_adv_active) {
        return -EIO;
    }

    sync = SYNC_CURRENT(advsm);

    *start_time = sync->sch.start_time + g_ble_ll_sched_offset_ticks;
    *end_time = sync->sch.end_time;

    return 0;
}

int
ble_ll_adv_sync_big_add(struct ble_ll_adv_sm *advsm,
                        struct ble_ll_iso_big *big)
{
    if (!(advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_CONFIGURED)) {
        return -EINVAL;
    }

    if (advsm->big && (advsm->big != big)) {
        return -EBUSY;
    }

    advsm->big = big;

    return 0;
}

int
ble_ll_adv_sync_big_remove(struct ble_ll_adv_sm *advsm,
                           struct ble_ll_iso_big *big)
{
    if (advsm->big != big) {
        return -EINVAL;
    }

    advsm->big = NULL;

    return 0;
}
#endif /* BLE_LL_ISO_BROADCASTER */

/**
 * Initialize the advertising functionality of a BLE device. This should
 * be called once on initialization
 */
void
ble_ll_adv_init(void)
{
    int i;

    /* Set default advertising parameters */
    for (i = 0; i < BLE_ADV_INSTANCES; ++i) {
        ble_ll_adv_sm_init(&g_ble_ll_adv_sm[i]);
    }
}

#endif
