/*
 * 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 <assert.h>
#include <string.h>
#include <errno.h>
#include "nimble/nimble_opt.h"
#include "host/ble_hs_adv.h"
#include "host/ble_hs_hci.h"
#include "ble_hs_priv.h"

#if MYNEWT
#include "bsp/bsp.h"
#else
#define bssnz_t
#endif

/**
 * GAP - Generic Access Profile.
 *
 * Design overview:
 *
 * GAP procedures are initiated by the application via function calls.  Such
 * functions return when either of the following happens:
 *
 * (1) The procedure completes (success or failure).
 * (2) The procedure cannot proceed until a BLE peer responds.
 *
 * For (1), the result of the procedure if fully indicated by the function
 * return code.
 * For (2), the procedure result is indicated by an application-configured
 * callback.  The callback is executed when the procedure completes.
 *
 * The GAP is always in one of two states:
 * 1. Free
 * 2. Preempted
 *
 * While GAP is in the free state, new procedures can be started at will.
 * While GAP is in the preempted state, no new procedures are allowed.  The
 * host sets GAP to the preempted state when it needs to ensure no ongoing
 * procedures, a condition required for some HCI commands to succeed.  The host
 * must take care to take GAP out of the preempted state as soon as possible.
 *
 * Notes on thread-safety:
 * 1. The ble_hs mutex must always be unlocked when an application callback is
 *    executed.  The purpose of this requirement is to allow callbacks to
 *    initiate additional host procedures, which may require locking of the
 *    mutex.
 * 2. Functions called directly by the application never call callbacks.
 *    Generally, these functions lock the ble_hs mutex at the start, and only
 *    unlock it at return.
 * 3. Functions which do call callbacks (receive handlers and timer
 *    expirations) generally only lock the mutex long enough to modify
 *    affected state and make copies of data needed for the callback.  A copy
 *    of various pieces of data is called a "snapshot" (struct
 *    ble_gap_snapshot).  The sole purpose of snapshots is to allow callbacks
 *    to be executed after unlocking the mutex.
 */

/** GAP procedure op codes. */
#define BLE_GAP_OP_NULL                         0
#define BLE_GAP_OP_M_DISC                       1
#define BLE_GAP_OP_M_CONN                       2
#define BLE_GAP_OP_S_ADV                        1

/**
 * If an attempt to cancel an active procedure fails, the attempt is retried
 * at this rate (ms).
 */
#define BLE_GAP_CANCEL_RETRY_TIMEOUT_MS         100 /* ms */

#define BLE_GAP_UPDATE_TIMEOUT_MS               40000 /* ms */

static const struct ble_gap_conn_params ble_gap_conn_params_dflt = {
    .scan_itvl = 0x0010,
    .scan_window = 0x0010,
    .itvl_min = BLE_GAP_INITIAL_CONN_ITVL_MIN,
    .itvl_max = BLE_GAP_INITIAL_CONN_ITVL_MAX,
    .latency = BLE_GAP_INITIAL_CONN_LATENCY,
    .supervision_timeout = BLE_GAP_INITIAL_SUPERVISION_TIMEOUT,
    .min_ce_len = BLE_GAP_INITIAL_CONN_MIN_CE_LEN,
    .max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN,
};

/**
 * The state of the in-progress master connection.  If no master connection is
 * currently in progress, then the op field is set to BLE_GAP_OP_NULL.
 */
struct ble_gap_master_state {
    uint8_t op;

    uint8_t exp_set:1;
    ble_npl_time_t exp_os_ticks;

    ble_gap_event_fn *cb;
    void *cb_arg;

    /**
     * Indicates the type of master procedure that was preempted, or
     * BLE_GAP_OP_NULL if no procedure was preempted.
     */
    uint8_t preempted_op;

    union {
        struct {
            uint8_t using_wl:1;
            uint8_t our_addr_type:2;
            uint8_t cancel:1;
        } conn;

        struct {
            uint8_t limited:1;
        } disc;
    };
};
static bssnz_t struct ble_gap_master_state ble_gap_master;

/**
 * The state of the in-progress slave connection.  If no slave connection is
 * currently in progress, then the op field is set to BLE_GAP_OP_NULL.
 */
struct ble_gap_slave_state {
    uint8_t op;

    unsigned int our_addr_type:2;
    unsigned int preempted:1;  /** Set to 1 if advertising was preempted. */
    unsigned int connectable:1;

#if MYNEWT_VAL(BLE_EXT_ADV)
    unsigned int configured:1; /** If instance is configured */
    unsigned int scannable:1;
    unsigned int directed:1;
    unsigned int legacy_pdu:1;
    unsigned int rnd_addr_set:1;
    uint8_t rnd_addr[6];
#else
/* timer is used only with legacy advertising */
    unsigned int exp_set:1;
    ble_npl_time_t exp_os_ticks;
#endif

    ble_gap_event_fn *cb;
    void *cb_arg;
};

static bssnz_t struct ble_gap_slave_state ble_gap_slave[BLE_ADV_INSTANCES];

struct ble_gap_update_entry {
    SLIST_ENTRY(ble_gap_update_entry) next;
    struct ble_gap_upd_params params;
    ble_npl_time_t exp_os_ticks;
    uint16_t conn_handle;
};
SLIST_HEAD(ble_gap_update_entry_list, ble_gap_update_entry);

struct ble_gap_snapshot {
    struct ble_gap_conn_desc *desc;
    ble_gap_event_fn *cb;
    void *cb_arg;
};

static SLIST_HEAD(ble_gap_hook_list, ble_gap_event_listener) ble_gap_event_listener_list;

static os_membuf_t ble_gap_update_entry_mem[
                        OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE),
                                        sizeof (struct ble_gap_update_entry))];
static struct os_mempool ble_gap_update_entry_pool;
static struct ble_gap_update_entry_list ble_gap_update_entries;

static void ble_gap_update_entry_free(struct ble_gap_update_entry *entry);
static struct ble_gap_update_entry *
ble_gap_update_entry_find(uint16_t conn_handle,
                          struct ble_gap_update_entry **out_prev);
static struct ble_gap_update_entry *
ble_gap_update_entry_remove(uint16_t conn_handle);
static void
ble_gap_update_l2cap_cb(uint16_t conn_handle, int status, void *arg);

static int ble_gap_adv_enable_tx(int enable);
static int ble_gap_conn_cancel_tx(void);

#if NIMBLE_BLE_SCAN && !MYNEWT_VAL(BLE_EXT_ADV)
static int ble_gap_disc_enable_tx(int enable, int filter_duplicates);
#endif

STATS_SECT_DECL(ble_gap_stats) ble_gap_stats;
STATS_NAME_START(ble_gap_stats)
    STATS_NAME(ble_gap_stats, wl_set)
    STATS_NAME(ble_gap_stats, wl_set_fail)
    STATS_NAME(ble_gap_stats, adv_stop)
    STATS_NAME(ble_gap_stats, adv_stop_fail)
    STATS_NAME(ble_gap_stats, adv_start)
    STATS_NAME(ble_gap_stats, adv_start_fail)
    STATS_NAME(ble_gap_stats, adv_set_data)
    STATS_NAME(ble_gap_stats, adv_set_data_fail)
    STATS_NAME(ble_gap_stats, adv_rsp_set_data)
    STATS_NAME(ble_gap_stats, adv_rsp_set_data_fail)
    STATS_NAME(ble_gap_stats, discover)
    STATS_NAME(ble_gap_stats, discover_fail)
    STATS_NAME(ble_gap_stats, initiate)
    STATS_NAME(ble_gap_stats, initiate_fail)
    STATS_NAME(ble_gap_stats, terminate)
    STATS_NAME(ble_gap_stats, terminate_fail)
    STATS_NAME(ble_gap_stats, cancel)
    STATS_NAME(ble_gap_stats, cancel_fail)
    STATS_NAME(ble_gap_stats, update)
    STATS_NAME(ble_gap_stats, update_fail)
    STATS_NAME(ble_gap_stats, connect_mst)
    STATS_NAME(ble_gap_stats, connect_slv)
    STATS_NAME(ble_gap_stats, disconnect)
    STATS_NAME(ble_gap_stats, rx_disconnect)
    STATS_NAME(ble_gap_stats, rx_update_complete)
    STATS_NAME(ble_gap_stats, rx_adv_report)
    STATS_NAME(ble_gap_stats, rx_conn_complete)
    STATS_NAME(ble_gap_stats, discover_cancel)
    STATS_NAME(ble_gap_stats, discover_cancel_fail)
    STATS_NAME(ble_gap_stats, security_initiate)
    STATS_NAME(ble_gap_stats, security_initiate_fail)
STATS_NAME_END(ble_gap_stats)

/*****************************************************************************
 * $debug                                                                    *
 *****************************************************************************/

#if MYNEWT_VAL(BLE_HS_DEBUG)
int
ble_gap_dbg_update_active(uint16_t conn_handle)
{
    const struct ble_gap_update_entry *entry;

    ble_hs_lock();
    entry = ble_gap_update_entry_find(conn_handle, NULL);
    ble_hs_unlock();

    return entry != NULL;
}
#endif

/*****************************************************************************
 * $log                                                                      *
 *****************************************************************************/

#if NIMBLE_BLE_SCAN && !MYNEWT_VAL(BLE_EXT_ADV)
static void
ble_gap_log_duration(int32_t duration_ms)
{
    if (duration_ms == BLE_HS_FOREVER) {
        BLE_HS_LOG(INFO, "duration=forever");
    } else {
        BLE_HS_LOG(INFO, "duration=%dms", duration_ms);
    }
}
#endif

#if !MYNEWT_VAL(BLE_EXT_ADV)
static void
ble_gap_log_conn(uint8_t own_addr_type, const ble_addr_t *peer_addr,
                 const struct ble_gap_conn_params *params)
{
    if (peer_addr != NULL) {
        BLE_HS_LOG(INFO, "peer_addr_type=%d peer_addr=", peer_addr->type);
        BLE_HS_LOG_ADDR(INFO, peer_addr->val);
    }

    BLE_HS_LOG(INFO, " scan_itvl=%d scan_window=%d itvl_min=%d itvl_max=%d "
                     "latency=%d supervision_timeout=%d min_ce_len=%d "
                     "max_ce_len=%d own_addr_type=%d",
               params->scan_itvl, params->scan_window, params->itvl_min,
               params->itvl_max, params->latency, params->supervision_timeout,
               params->min_ce_len, params->max_ce_len, own_addr_type);
}
#endif

#if NIMBLE_BLE_SCAN && !MYNEWT_VAL(BLE_EXT_ADV)
static void
ble_gap_log_disc(uint8_t own_addr_type, int32_t duration_ms,
                 const struct ble_gap_disc_params *disc_params)
{
    BLE_HS_LOG(INFO, "own_addr_type=%d filter_policy=%d passive=%d limited=%d "
                     "filter_duplicates=%d ",
               own_addr_type, disc_params->filter_policy, disc_params->passive,
               disc_params->limited, disc_params->filter_duplicates);
    ble_gap_log_duration(duration_ms);
}
#endif

static void
ble_gap_log_update(uint16_t conn_handle,
                   const struct ble_gap_upd_params *params)
{
    BLE_HS_LOG(INFO, "connection parameter update; "
                     "conn_handle=%d itvl_min=%d itvl_max=%d latency=%d "
                     "supervision_timeout=%d min_ce_len=%d max_ce_len=%d",
               conn_handle, params->itvl_min, params->itvl_max,
               params->latency, params->supervision_timeout,
               params->min_ce_len, params->max_ce_len);
}

static void
ble_gap_log_wl(const ble_addr_t *addr, uint8_t white_list_count)
{
    int i;

    BLE_HS_LOG(INFO, "count=%d ", white_list_count);

    for (i = 0; i < white_list_count; i++, addr++) {
        BLE_HS_LOG(INFO, "entry-%d={addr_type=%d addr=", i, addr->type);
        BLE_HS_LOG_ADDR(INFO, addr->val);
        BLE_HS_LOG(INFO, "} ");
    }
}

#if NIMBLE_BLE_ADVERTISE && !MYNEWT_VAL(BLE_EXT_ADV)
static void
ble_gap_log_adv(uint8_t own_addr_type, const ble_addr_t *direct_addr,
                const struct ble_gap_adv_params *adv_params)
{
    BLE_HS_LOG(INFO, "disc_mode=%d", adv_params->disc_mode);
    if (direct_addr) {
        BLE_HS_LOG(INFO, " direct_addr_type=%d direct_addr=",
                   direct_addr->type);
        BLE_HS_LOG_ADDR(INFO, direct_addr->val);
    }
    BLE_HS_LOG(INFO, " adv_channel_map=%d own_addr_type=%d "
                     "adv_filter_policy=%d adv_itvl_min=%d adv_itvl_max=%d",
               adv_params->channel_map,
               own_addr_type,
               adv_params->filter_policy,
               adv_params->itvl_min,
               adv_params->itvl_max);
}
#endif

/*****************************************************************************
 * $snapshot                                                                 *
 *****************************************************************************/

static void
ble_gap_fill_conn_desc(struct ble_hs_conn *conn,
                       struct ble_gap_conn_desc *desc)
{
    struct ble_hs_conn_addrs addrs;

    ble_hs_conn_addrs(conn, &addrs);

    desc->our_id_addr = addrs.our_id_addr;
    desc->peer_id_addr = addrs.peer_id_addr;
    desc->our_ota_addr = addrs.our_ota_addr;
    desc->peer_ota_addr = addrs.peer_ota_addr;

    desc->conn_handle = conn->bhc_handle;
    desc->conn_itvl = conn->bhc_itvl;
    desc->conn_latency = conn->bhc_latency;
    desc->supervision_timeout = conn->bhc_supervision_timeout;
    desc->master_clock_accuracy = conn->bhc_master_clock_accuracy;
    desc->sec_state = conn->bhc_sec_state;

    if (conn->bhc_flags & BLE_HS_CONN_F_MASTER) {
        desc->role = BLE_GAP_ROLE_MASTER;
    } else {
        desc->role = BLE_GAP_ROLE_SLAVE;
    }
}

static void
ble_gap_conn_to_snapshot(struct ble_hs_conn *conn,
                         struct ble_gap_snapshot *snap)
{
    ble_gap_fill_conn_desc(conn, snap->desc);
    snap->cb = conn->bhc_cb;
    snap->cb_arg = conn->bhc_cb_arg;
}

static int
ble_gap_find_snapshot(uint16_t handle, struct ble_gap_snapshot *snap)
{
    struct ble_hs_conn *conn;

    ble_hs_lock();

    conn = ble_hs_conn_find(handle);
    if (conn != NULL) {
        ble_gap_conn_to_snapshot(conn, snap);
    }

    ble_hs_unlock();

    if (conn == NULL) {
        return BLE_HS_ENOTCONN;
    } else {
        return 0;
    }
}

int
ble_gap_conn_find(uint16_t handle, struct ble_gap_conn_desc *out_desc)
{
    struct ble_hs_conn *conn;

    ble_hs_lock();

    conn = ble_hs_conn_find(handle);
    if (conn != NULL && out_desc != NULL) {
        ble_gap_fill_conn_desc(conn, out_desc);
    }

    ble_hs_unlock();

    if (conn == NULL) {
        return BLE_HS_ENOTCONN;
    } else {
        return 0;
    }
}

int
ble_gap_conn_find_by_addr(const ble_addr_t *addr,
                          struct ble_gap_conn_desc *out_desc)
{
	struct ble_hs_conn *conn;

	ble_hs_lock();

	conn = ble_hs_conn_find_by_addr(addr);
	if (conn != NULL && out_desc != NULL) {
		ble_gap_fill_conn_desc(conn, out_desc);
	}

	ble_hs_unlock();

	if (conn == NULL) {
		return BLE_HS_ENOTCONN;
	}

	return 0;
}

static int
ble_gap_extract_conn_cb(uint16_t conn_handle,
                        ble_gap_event_fn **out_cb, void **out_cb_arg)
{
    const struct ble_hs_conn *conn;

    BLE_HS_DBG_ASSERT(conn_handle <= BLE_HCI_LE_CONN_HANDLE_MAX);

    ble_hs_lock();

    conn = ble_hs_conn_find(conn_handle);
    if (conn != NULL) {
        *out_cb = conn->bhc_cb;
        *out_cb_arg = conn->bhc_cb_arg;
    } else {
        *out_cb = NULL;
        *out_cb_arg = NULL;
    }

    ble_hs_unlock();

    if (conn == NULL) {
        return BLE_HS_ENOTCONN;
    } else {
        return 0;
    }
}

int
ble_gap_set_priv_mode(const ble_addr_t *peer_addr, uint8_t priv_mode)
{
    return ble_hs_pvcy_set_mode(peer_addr, priv_mode);
}

int
ble_gap_read_le_phy(uint16_t conn_handle, uint8_t *tx_phy, uint8_t *rx_phy)
{
    struct ble_hs_conn *conn;
    uint8_t buf[BLE_HCI_LE_RD_PHY_LEN];
    uint8_t rspbuf[4];
    uint8_t rsplen;
    int rc;

    ble_hs_lock();
    conn = ble_hs_conn_find(conn_handle);
    ble_hs_unlock();

    if (conn == NULL) {
        return BLE_HS_ENOTCONN;
    }

    rc = ble_hs_hci_cmd_build_le_read_phy(conn_handle, buf, sizeof(buf));
    if (rc != 0) {
        return rc;
    }

    rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_PHY),
                           buf, sizeof(buf), rspbuf, sizeof(rspbuf), &rsplen);
    if (rc != 0) {
        return rc;
    }

    if (rsplen != sizeof(rspbuf)) {
        return BLE_HS_ECONTROLLER;
    }

    /* First two octets is conn_handle. We can ignore it */

    *tx_phy = rspbuf[2];
    *rx_phy = rspbuf[3];

    return 0;
}

int
ble_gap_set_prefered_default_le_phy(uint8_t tx_phys_mask, uint8_t rx_phys_mask)
{
    uint8_t buf[BLE_HCI_LE_SET_DEFAULT_PHY_LEN];
    int rc;

    rc = ble_hs_hci_cmd_build_le_set_default_phy(tx_phys_mask, rx_phys_mask,
                                                 buf, sizeof(buf));
    if (rc != 0) {
        return rc;
    }

    return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
                                        BLE_HCI_OCF_LE_SET_DEFAULT_PHY),
                            buf, sizeof(buf), NULL, 0, NULL);
}

int
ble_gap_set_prefered_le_phy(uint16_t conn_handle, uint8_t tx_phys_mask,
                   uint8_t rx_phys_mask, uint16_t phy_opts)
{
    struct ble_hs_conn *conn;
    uint8_t buf[BLE_HCI_LE_SET_PHY_LEN];
    int rc;

    ble_hs_lock();
    conn = ble_hs_conn_find(conn_handle);
    ble_hs_unlock();

    if (conn == NULL) {
        return BLE_HS_ENOTCONN;
    }

    rc = ble_hs_hci_cmd_build_le_set_phy(conn_handle, tx_phys_mask,
                                         rx_phys_mask, phy_opts, buf,
                                         sizeof(buf));
    if (rc != 0) {
        return rc;
    }

    return ble_hs_hci_cmd_tx(
        BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PHY),
        buf, sizeof(buf), NULL, 0, NULL);
}

/*****************************************************************************
 * $misc                                                                     *
 *****************************************************************************/

static int
ble_gap_event_listener_call(struct ble_gap_event *event);

static int
ble_gap_call_event_cb(struct ble_gap_event *event,
                      ble_gap_event_fn *cb, void *cb_arg)
{
    int rc;

    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());

    if (cb != NULL) {
        rc = cb(event, cb_arg);
    } else {
        if (event->type == BLE_GAP_EVENT_CONN_UPDATE_REQ) {
            /* Just copy peer parameters back into the reply. */
            *event->conn_update_req.self_params =
                *event->conn_update_req.peer_params;
        }
        rc = 0;
    }

    return rc;
}


static int
ble_gap_call_conn_event_cb(struct ble_gap_event *event, uint16_t conn_handle)
{
    ble_gap_event_fn *cb;
    void *cb_arg;
    int rc;

    rc = ble_gap_extract_conn_cb(conn_handle, &cb, &cb_arg);
    if (rc != 0) {
        return rc;
    }

    rc = ble_gap_call_event_cb(event, cb, cb_arg);
    if (rc != 0) {
        return rc;
    }

    return 0;
}

static bool
ble_gap_is_preempted(void)
{
    int i;

    BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());

    if (ble_gap_master.preempted_op != BLE_GAP_OP_NULL) {
        return true;
    }

    for (i = 0; i < BLE_ADV_INSTANCES; i++) {
        if (ble_gap_slave[i].preempted) {
            return true;
        }
    }

    return false;
}

static void
ble_gap_master_reset_state(void)
{
    ble_gap_master.op = BLE_GAP_OP_NULL;
    ble_gap_master.exp_set = 0;
    ble_gap_master.conn.cancel = 0;

    ble_hs_timer_resched();
}

static void
ble_gap_slave_reset_state(uint8_t instance)
{
    ble_gap_slave[instance].op = BLE_GAP_OP_NULL;

#if !MYNEWT_VAL(BLE_EXT_ADV)
    ble_gap_slave[instance].exp_set = 0;
    ble_hs_timer_resched();
#endif
}

static bool
ble_gap_has_client(struct ble_gap_master_state *out_state)
{
    if (!out_state) {
        return 0;
    }

    return out_state->cb;
}

static void
ble_gap_master_extract_state(struct ble_gap_master_state *out_state,
                             int reset_state)
{
    ble_hs_lock();

    *out_state = ble_gap_master;

    if (reset_state) {
        ble_gap_master_reset_state();
        ble_gap_master.preempted_op = BLE_GAP_OP_NULL;
    }

    ble_hs_unlock();
}

static void
ble_gap_slave_extract_cb(uint8_t instance,
                         ble_gap_event_fn **out_cb, void **out_cb_arg)
{
    ble_hs_lock();

    *out_cb = ble_gap_slave[instance].cb;
    *out_cb_arg = ble_gap_slave[instance].cb_arg;
    ble_gap_slave_reset_state(instance);

    ble_hs_unlock();
}

static void
ble_gap_adv_finished(uint8_t instance, int reason, uint16_t conn_handle,
                     uint8_t num_events)
{
    struct ble_gap_event event;
    ble_gap_event_fn *cb;
    void *cb_arg;

    ble_gap_slave_extract_cb(instance, &cb, &cb_arg);
    if (cb != NULL) {
        memset(&event, 0, sizeof event);
        event.type = BLE_GAP_EVENT_ADV_COMPLETE;
        event.adv_complete.reason = reason;
#if MYNEWT_VAL(BLE_EXT_ADV)
        event.adv_complete.instance = instance;
        event.adv_complete.conn_handle = conn_handle;
        event.adv_complete.num_ext_adv_events = num_events;
#endif
        cb(&event, cb_arg);
    }
}

static int
ble_gap_master_connect_failure(int status)
{
    struct ble_gap_master_state state;
    struct ble_gap_event event;
    int rc;

    ble_gap_master_extract_state(&state, 1);
    if (ble_gap_has_client(&state)) {
        memset(&event, 0, sizeof event);
        event.type = BLE_GAP_EVENT_CONNECT;
        event.connect.status = status;

        rc = state.cb(&event, state.cb_arg);
    } else {
        rc = 0;
    }

    return rc;
}

static void
ble_gap_master_connect_cancelled(void)
{
    struct ble_gap_master_state state;
    struct ble_gap_event event;

    ble_gap_master_extract_state(&state, 1);
    if (state.cb != NULL) {
        memset(&event, 0, sizeof event);
        event.type = BLE_GAP_EVENT_CONNECT;
        event.connect.conn_handle = BLE_HS_CONN_HANDLE_NONE;
        if (state.conn.cancel) {
            /* Connect procedure successfully cancelled. */
            event.connect.status = BLE_HS_EAPP;
        } else {
            /* Connect procedure timed out. */
            event.connect.status = BLE_HS_ETIMEOUT;
        }
        state.cb(&event, state.cb_arg);
    }
}

static void
ble_gap_disc_report(void *desc)
{
    struct ble_gap_master_state state;
    struct ble_gap_event event;

    memset(&event, 0, sizeof event);
#if MYNEWT_VAL(BLE_EXT_ADV)
    event.type = BLE_GAP_EVENT_EXT_DISC;
    event.ext_disc = *((struct ble_gap_ext_disc_desc *)desc);
#else
    event.type = BLE_GAP_EVENT_DISC;
    event.disc = *((struct ble_gap_disc_desc *)desc);
#endif

    ble_gap_master_extract_state(&state, 0);
    if (ble_gap_has_client(&state)) {
        state.cb(&event, state.cb_arg);
    }

    ble_gap_event_listener_call(&event);
}

#if NIMBLE_BLE_SCAN
static void
ble_gap_disc_complete(void)
{
    struct ble_gap_master_state state;
    struct ble_gap_event event;

    memset(&event, 0, sizeof event);
    event.type = BLE_GAP_EVENT_DISC_COMPLETE;
    event.disc_complete.reason = 0;

    ble_gap_master_extract_state(&state, 1);
    if (ble_gap_has_client(&state)) {
        ble_gap_call_event_cb(&event, state.cb, state.cb_arg);
    }

    ble_gap_event_listener_call(&event);
}
#endif

static void
ble_gap_update_notify(uint16_t conn_handle, int status)
{
    struct ble_gap_event event;

    memset(&event, 0, sizeof event);
    event.type = BLE_GAP_EVENT_CONN_UPDATE;
    event.conn_update.conn_handle = conn_handle;
    event.conn_update.status = status;

    ble_gap_event_listener_call(&event);
    ble_gap_call_conn_event_cb(&event, conn_handle);

    /* Terminate the connection on procedure timeout. */
    if (status == BLE_HS_ETIMEOUT) {
        ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);
    }
}

static uint32_t
ble_gap_master_ticks_until_exp(void)
{
    ble_npl_stime_t ticks;

    if (ble_gap_master.op == BLE_GAP_OP_NULL || !ble_gap_master.exp_set) {
        /* Timer not set; infinity ticks until next event. */
        return BLE_HS_FOREVER;
    }

    ticks = ble_gap_master.exp_os_ticks - ble_npl_time_get();
    if (ticks > 0) {
        /* Timer not expired yet. */
        return ticks;
    }

    /* Timer just expired. */
    return 0;
}

#if !MYNEWT_VAL(BLE_EXT_ADV)
static uint32_t
ble_gap_slave_ticks_until_exp(void)
{
    ble_npl_stime_t ticks;

    if (ble_gap_slave[0].op == BLE_GAP_OP_NULL || !ble_gap_slave[0].exp_set) {
        /* Timer not set; infinity ticks until next event. */
        return BLE_HS_FOREVER;
    }

    ticks = ble_gap_slave[0].exp_os_ticks - ble_npl_time_get();
    if (ticks > 0) {
        /* Timer not expired yet. */
        return ticks;
    }

    /* Timer just expired. */
    return 0;
}
#endif

/**
 * Finds the update procedure that expires soonest.
 *
 * @param out_ticks_from_now    On success, the ticks until the update
 *                                  procedure's expiry time gets written here.
 *
 * @return                      The connection handle of the update procedure
 *                                  that expires soonest, or
 *                                  BLE_HS_CONN_HANDLE_NONE if there are no
 *                                  active update procedures.
 */
static uint16_t
ble_gap_update_next_exp(int32_t *out_ticks_from_now)
{
    struct ble_gap_update_entry *entry;
    ble_npl_time_t now;
    uint16_t conn_handle;
    int32_t best_ticks;
    int32_t ticks;

    BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());

    conn_handle = BLE_HS_CONN_HANDLE_NONE;
    best_ticks = BLE_HS_FOREVER;
    now = ble_npl_time_get();

    SLIST_FOREACH(entry, &ble_gap_update_entries, next) {
        ticks = entry->exp_os_ticks - now;
        if (ticks <= 0) {
            ticks = 0;
        }

        if (ticks < best_ticks) {
            conn_handle = entry->conn_handle;
            best_ticks = ticks;
        }
    }

    if (out_ticks_from_now != NULL) {
        *out_ticks_from_now = best_ticks;
    }

    return conn_handle;

}

static void
ble_gap_master_set_timer(uint32_t ticks_from_now)
{
    ble_gap_master.exp_os_ticks = ble_npl_time_get() + ticks_from_now;
    ble_gap_master.exp_set = 1;

    ble_hs_timer_resched();
}

#if NIMBLE_BLE_ADVERTISE && !MYNEWT_VAL(BLE_EXT_ADV)
static void
ble_gap_slave_set_timer(uint32_t ticks_from_now)
{
    ble_gap_slave[0].exp_os_ticks = ble_npl_time_get() + ticks_from_now;
    ble_gap_slave[0].exp_set = 1;

    ble_hs_timer_resched();
}
#endif

/**
 * Called when an error is encountered while the master-connection-fsm is
 * active.
 */
static void
ble_gap_master_failed(int status)
{
    switch (ble_gap_master.op) {
    case BLE_GAP_OP_M_CONN:
        STATS_INC(ble_gap_stats, initiate_fail);
        ble_gap_master_connect_failure(status);
        break;

    default:
        BLE_HS_DBG_ASSERT(0);
        break;
    }
}

static void
ble_gap_update_failed(uint16_t conn_handle, int status)
{
    struct ble_gap_update_entry *entry;

    STATS_INC(ble_gap_stats, update_fail);

    ble_hs_lock();
    entry = ble_gap_update_entry_remove(conn_handle);
    ble_hs_unlock();

    ble_gap_update_entry_free(entry);

    ble_gap_update_notify(conn_handle, status);
}

void
ble_gap_conn_broken(uint16_t conn_handle, int reason)
{
    struct ble_gap_update_entry *entry;
    struct ble_gap_snapshot snap;
    struct ble_gap_event event;
    int rc;

    memset(&event, 0, sizeof event);
    snap.desc = &event.disconnect.conn;

    rc = ble_gap_find_snapshot(conn_handle, &snap);
    if (rc != 0) {
        /* No longer connected. */
        return;
    }

    /* If there was a connection update in progress, indicate to the
     * application that it did not complete.
     */
    ble_hs_lock();
    entry = ble_gap_update_entry_remove(conn_handle);
    ble_hs_unlock();

    if (entry != NULL) {
        ble_gap_update_notify(conn_handle, reason);
        ble_gap_update_entry_free(entry);
    }

    /* Indicate the connection termination to each module.  The order matters
     * here: gatts must come before gattc to ensure the application does not
     * get informed of spurious notify-tx events.
     */
    ble_l2cap_sig_conn_broken(conn_handle, reason);
    ble_sm_connection_broken(conn_handle);
    ble_gatts_connection_broken(conn_handle);
    ble_gattc_connection_broken(conn_handle);
    ble_hs_flow_connection_broken(conn_handle);;

    ble_hs_atomic_conn_delete(conn_handle);

    event.type = BLE_GAP_EVENT_DISCONNECT;
    event.disconnect.reason = reason;

    ble_gap_event_listener_call(&event);
    ble_gap_call_event_cb(&event, snap.cb, snap.cb_arg);

    STATS_INC(ble_gap_stats, disconnect);
}

static void
ble_gap_update_to_l2cap(const struct ble_gap_upd_params *params,
                        struct ble_l2cap_sig_update_params *l2cap_params)
{
    l2cap_params->itvl_min = params->itvl_min;
    l2cap_params->itvl_max = params->itvl_max;
    l2cap_params->slave_latency = params->latency;
    l2cap_params->timeout_multiplier = params->supervision_timeout;
}

void
ble_gap_rx_disconn_complete(struct hci_disconn_complete *evt)
{
#if !NIMBLE_BLE_CONNECT
    return;
#endif

    struct ble_gap_event event;

    STATS_INC(ble_gap_stats, rx_disconnect);

    if (evt->status == 0) {
        ble_gap_conn_broken(evt->connection_handle,
                            BLE_HS_HCI_ERR(evt->reason));
    } else {
        memset(&event, 0, sizeof event);
        event.type = BLE_GAP_EVENT_TERM_FAILURE;
        event.term_failure.conn_handle = evt->connection_handle;
        event.term_failure.status = BLE_HS_HCI_ERR(evt->status);

        ble_gap_event_listener_call(&event);
        ble_gap_call_conn_event_cb(&event, evt->connection_handle);
    }
}

void
ble_gap_rx_update_complete(struct hci_le_conn_upd_complete *evt)
{
#if !NIMBLE_BLE_CONNECT
    return;
#endif

    struct ble_gap_update_entry *entry;
    struct ble_l2cap_sig_update_params l2cap_params;
    struct ble_gap_event event;
    struct ble_hs_conn *conn;
    int cb_status;
    int call_cb;
    int rc;

    STATS_INC(ble_gap_stats, rx_update_complete);

    memset(&event, 0, sizeof event);
    memset(&l2cap_params, 0, sizeof l2cap_params);

    ble_hs_lock();

    conn = ble_hs_conn_find(evt->connection_handle);
    if (conn != NULL) {
        switch (evt->status) {
        case 0:
            /* Connection successfully updated. */
            conn->bhc_itvl = evt->conn_itvl;
            conn->bhc_latency = evt->conn_latency;
            conn->bhc_supervision_timeout = evt->supervision_timeout;
            break;

        case BLE_ERR_UNSUPP_REM_FEATURE:
            /* Peer reports that it doesn't support the procedure.  This should
             * only happen if our controller sent the 4.1 Connection Parameters
             * Request Procedure.  If we are the slave, fail over to the L2CAP
             * update procedure.
             */
            entry = ble_gap_update_entry_find(evt->connection_handle, NULL);
            if (entry != NULL && !(conn->bhc_flags & BLE_HS_CONN_F_MASTER)) {
                ble_gap_update_to_l2cap(&entry->params, &l2cap_params);
                entry->exp_os_ticks = ble_npl_time_get() +
                                      ble_npl_time_ms_to_ticks32(BLE_GAP_UPDATE_TIMEOUT_MS);
            }
            break;

        default:
            break;
        }
    }

    /* We aren't failing over to L2CAP, the update procedure is complete. */
    if (l2cap_params.itvl_min == 0) {
        entry = ble_gap_update_entry_remove(evt->connection_handle);
        ble_gap_update_entry_free(entry);
    }

    ble_hs_unlock();

    if (l2cap_params.itvl_min != 0) {
        rc = ble_l2cap_sig_update(evt->connection_handle,
                                  &l2cap_params,
                                  ble_gap_update_l2cap_cb, NULL);
        if (rc == 0) {
            call_cb = 0;
        } else {
            call_cb = 1;
            cb_status = rc;
        }
    } else {
        call_cb = 1;
        cb_status = BLE_HS_HCI_ERR(evt->status);
    }

    if (call_cb) {
        ble_gap_update_notify(evt->connection_handle, cb_status);
    }
}

/**
 * Tells you if there is an active central GAP procedure (connect or discover).
 */
int
ble_gap_master_in_progress(void)
{
    return ble_gap_master.op != BLE_GAP_OP_NULL;
}

static int
ble_gap_accept_master_conn(void)
{
    int rc;

    switch (ble_gap_master.op) {
    case BLE_GAP_OP_NULL:
    case BLE_GAP_OP_M_DISC:
        rc = BLE_HS_ENOENT;
        break;

    case BLE_GAP_OP_M_CONN:
        rc = 0;
        break;

    default:
        BLE_HS_DBG_ASSERT(0);
        rc = BLE_HS_ENOENT;
        break;
    }

    if (rc == 0) {
        STATS_INC(ble_gap_stats, connect_mst);
    }

    return rc;
}

static int
ble_gap_adv_active_instance(uint8_t instance)
{
    /* Assume read is atomic; mutex not necessary. */
    return ble_gap_slave[instance].op == BLE_GAP_OP_S_ADV;
}

static int
ble_gap_accept_slave_conn(uint8_t instance)
{
    int rc;

    if (instance >= BLE_ADV_INSTANCES) {
       rc = BLE_HS_ENOENT;
    } else if (!ble_gap_adv_active_instance(instance)) {
        rc = BLE_HS_ENOENT;
    } else {
        if (ble_gap_slave[instance].connectable) {
            rc = 0;
        } else {
            rc = BLE_HS_ENOENT;
        }
    }

    if (rc == 0) {
        STATS_INC(ble_gap_stats, connect_slv);
    }

    return rc;
}

static int
ble_gap_rx_adv_report_sanity_check(uint8_t *adv_data, uint8_t adv_data_len)
{
    const struct ble_hs_adv_field *flags;
    int rc;

    STATS_INC(ble_gap_stats, rx_adv_report);

    if (ble_gap_master.op != BLE_GAP_OP_M_DISC) {
        return -1;
    }

    /* If a limited discovery procedure is active, discard non-limited
     * advertisements.
     */
    if (ble_gap_master.disc.limited) {
        rc = ble_hs_adv_find_field(BLE_HS_ADV_TYPE_FLAGS, adv_data,
                                   adv_data_len, &flags);
        if ((rc == 0) && (flags->length == 2) &&
            !(flags->value[0] & BLE_HS_ADV_F_DISC_LTD)) {
            return -1;
        }
    }

    return 0;
}

void
ble_gap_rx_adv_report(struct ble_gap_disc_desc *desc)
{
#if !NIMBLE_BLE_SCAN
    return;
#endif

    if (ble_gap_rx_adv_report_sanity_check(desc->data, desc->length_data)) {
        return;
    }

    ble_gap_disc_report(desc);
}

#if MYNEWT_VAL(BLE_EXT_ADV) && NIMBLE_BLE_SCAN
void
ble_gap_rx_le_scan_timeout(void)
{
    ble_gap_disc_complete();
}
#endif

#if MYNEWT_VAL(BLE_EXT_ADV)
void
ble_gap_rx_ext_adv_report(struct ble_gap_ext_disc_desc *desc)
{
    if (ble_gap_rx_adv_report_sanity_check(desc->data, desc->length_data)) {
        return;
    }

    ble_gap_disc_report(desc);
}

void
ble_gap_rx_adv_set_terminated(struct hci_le_adv_set_terminated *evt)
{
    uint16_t conn_handle;
    int reason;

    /* Currently spec allows only 0x3c and 0x43 when advertising was stopped
     * due to timeout or events limit, mp this for timeout error for now */
    if (evt->status) {
        reason = BLE_HS_ETIMEOUT;
        conn_handle = 0;
    } else {
        reason = 0;
        conn_handle = evt->conn_handle;
    }

    ble_gap_adv_finished(evt->adv_handle, reason, conn_handle,
                         evt->completed_events);
}
#endif

static int
ble_gap_rd_rem_sup_feat_tx(uint16_t handle)
{
    uint8_t buf[BLE_HCI_CONN_RD_REM_FEAT_LEN];
    int rc;

    rc = ble_hs_hci_cmd_build_le_read_remote_feat(handle, buf, sizeof buf);
    if (rc != 0) {
        return BLE_HS_EUNKNOWN;
    }

    rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE,
                                                BLE_HCI_OCF_LE_RD_REM_FEAT),
                                     buf, sizeof(buf));
    if (rc != 0) {
        return rc;
    }

    return 0;
}

/**
 * Processes an incoming connection-complete HCI event.
 * instance parameter is valid only for slave connection.
 */
int
ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt, uint8_t instance)
{
#if !NIMBLE_BLE_CONNECT
    return BLE_HS_ENOTSUP;
#endif

    struct ble_gap_event event;
    struct ble_hs_conn *conn;
    int rc;

    STATS_INC(ble_gap_stats, rx_conn_complete);

    /* in that case *only* status field is valid so we determine role
     * based on error code
     */
    if (evt->status != BLE_ERR_SUCCESS) {
        switch (evt->status) {
        case BLE_ERR_DIR_ADV_TMO:
            /* slave role (HD directed advertising)
             *
             * with ext advertising this is send from set terminated event
             */
#if !MYNEWT_VAL(BLE_EXT_ADV)
            if (ble_gap_adv_active()) {
                ble_gap_adv_finished(0, 0, 0, 0);
            }
#endif
            break;
        case BLE_ERR_UNK_CONN_ID:
            /* master role */
            if (ble_gap_master_in_progress()) {
                /* Connect procedure successfully cancelled. */
                if (ble_gap_master.preempted_op == BLE_GAP_OP_M_CONN) {
                    ble_gap_master_failed(BLE_HS_EPREEMPTED);
                } else {
                    ble_gap_master_connect_cancelled();
                }
            }
            break;
        default:
            /* this should never happen, unless controller is broken */
            BLE_HS_LOG(INFO, "controller reported invalid error code in conn"
                             "complete event: %u", evt->status);
            assert(0);
            break;
        }
        return 0;
    }

    /* Apply the event to the existing connection if it exists. */
    if (ble_hs_atomic_conn_flags(evt->connection_handle, NULL) == 0) {
        /* XXX: Does this ever happen? */
        return 0;
    }

    /* This event refers to a new connection. */

    switch (evt->role) {
    case BLE_HCI_LE_CONN_COMPLETE_ROLE_MASTER:
        rc = ble_gap_accept_master_conn();
        if (rc != 0) {
            return rc;
        }
        break;

    case BLE_HCI_LE_CONN_COMPLETE_ROLE_SLAVE:
        rc = ble_gap_accept_slave_conn(instance);
        if (rc != 0) {
            return rc;
        }
        break;

    default:
        BLE_HS_DBG_ASSERT(0);
        break;
    }

    /* We verified that there is a free connection when the procedure began. */
    conn = ble_hs_conn_alloc(evt->connection_handle);
    BLE_HS_DBG_ASSERT(conn != NULL);

    conn->bhc_itvl = evt->conn_itvl;
    conn->bhc_latency = evt->conn_latency;
    conn->bhc_supervision_timeout = evt->supervision_timeout;
    conn->bhc_master_clock_accuracy = evt->master_clk_acc;
    if (evt->role == BLE_HCI_LE_CONN_COMPLETE_ROLE_MASTER) {
        conn->bhc_cb = ble_gap_master.cb;
        conn->bhc_cb_arg = ble_gap_master.cb_arg;
        conn->bhc_flags |= BLE_HS_CONN_F_MASTER;
        conn->bhc_our_addr_type = ble_gap_master.conn.our_addr_type;
        ble_gap_master_reset_state();
    } else {
        conn->bhc_cb = ble_gap_slave[instance].cb;
        conn->bhc_cb_arg = ble_gap_slave[instance].cb_arg;
        conn->bhc_our_addr_type = ble_gap_slave[instance].our_addr_type;
#if MYNEWT_VAL(BLE_EXT_ADV)
        memcpy(conn->bhc_our_rnd_addr, ble_gap_slave[instance].rnd_addr, 6);
#endif
        ble_gap_slave_reset_state(instance);
    }

    conn->bhc_peer_addr.type = evt->peer_addr_type;
    memcpy(conn->bhc_peer_addr.val, evt->peer_addr, 6);

    conn->bhc_our_rpa_addr.type = BLE_ADDR_RANDOM;
    memcpy(conn->bhc_our_rpa_addr.val, evt->local_rpa, 6);

    /* If peer RPA is not set in the event and peer address
     * is RPA then store the peer RPA address so when the peer
     * address is resolved, the RPA is not forgotten.
     */
    if (memcmp(BLE_ADDR_ANY->val, evt->peer_rpa, 6) == 0) {
        if (BLE_ADDR_IS_RPA(&conn->bhc_peer_addr)) {
            conn->bhc_peer_rpa_addr = conn->bhc_peer_addr;
        }
    } else {
        conn->bhc_peer_rpa_addr.type = BLE_ADDR_RANDOM;
        memcpy(conn->bhc_peer_rpa_addr.val, evt->peer_rpa, 6);
    }

    ble_hs_lock();

    memset(&event, 0, sizeof event);
    ble_hs_conn_insert(conn);

    ble_hs_unlock();

    event.type = BLE_GAP_EVENT_CONNECT;
    event.connect.conn_handle = evt->connection_handle;
    event.connect.status = 0;

    ble_gap_event_listener_call(&event);
    ble_gap_call_conn_event_cb(&event, evt->connection_handle);

    ble_gap_rd_rem_sup_feat_tx(evt->connection_handle);

    return 0;
}

void
ble_gap_rx_rd_rem_sup_feat_complete(
    struct hci_le_rd_rem_supp_feat_complete *evt)
{
#if !NIMBLE_BLE_CONNECT
    return;
#endif

    struct ble_hs_conn *conn;

    ble_hs_lock();

    conn = ble_hs_conn_find(evt->connection_handle);
    if (conn != NULL && evt->status == 0) {
            conn->supported_feat = get_le32(evt->features);
    }

    ble_hs_unlock();
}

int
ble_gap_rx_l2cap_update_req(uint16_t conn_handle,
                            struct ble_gap_upd_params *params)
{
    struct ble_gap_event event;
    int rc;

    memset(&event, 0, sizeof event);
    event.type = BLE_GAP_EVENT_L2CAP_UPDATE_REQ;
    event.conn_update_req.conn_handle = conn_handle;
    event.conn_update_req.peer_params = params;

    rc = ble_gap_call_conn_event_cb(&event, conn_handle);
    return rc;
}

void
ble_gap_rx_phy_update_complete(struct hci_le_phy_upd_complete *evt)
{
    struct ble_gap_event event;

    memset(&event, 0, sizeof event);
    event.type = BLE_GAP_EVENT_PHY_UPDATE_COMPLETE;
    event.phy_updated.status = evt->status;
    event.phy_updated.conn_handle = evt->connection_handle;
    event.phy_updated.tx_phy = evt->tx_phy;
    event.phy_updated.rx_phy = evt->rx_phy;

    ble_gap_event_listener_call(&event);
    ble_gap_call_conn_event_cb(&event, evt->connection_handle);
}

static int32_t
ble_gap_master_timer(void)
{
    uint32_t ticks_until_exp;
    int rc;

    ticks_until_exp = ble_gap_master_ticks_until_exp();
    if (ticks_until_exp != 0) {
        /* Timer not expired yet. */
        return ticks_until_exp;
    }

    /*** Timer expired; process event. */

    switch (ble_gap_master.op) {
    case BLE_GAP_OP_M_CONN:
        rc = ble_gap_conn_cancel_tx();
        if (rc != 0) {
            /* Failed to stop connecting; try again in 100 ms. */
            return ble_npl_time_ms_to_ticks32(BLE_GAP_CANCEL_RETRY_TIMEOUT_MS);
        } else {
            /* Stop the timer now that the cancel command has been acked. */
            ble_gap_master.exp_set = 0;

            /* Timeout gets reported when we receive a connection complete
             * event indicating the connect procedure has been cancelled.
             */
            /* XXX: Set a timer to reset the controller if a connection
             * complete event isn't received within a reasonable interval.
             */
        }
        break;

    case BLE_GAP_OP_M_DISC:
#if NIMBLE_BLE_SCAN && !MYNEWT_VAL(BLE_EXT_ADV)
        /* When a discovery procedure times out, it is not a failure. */
        rc = ble_gap_disc_enable_tx(0, 0);
        if (rc != 0) {
            /* Failed to stop discovery; try again in 100 ms. */
            return ble_npl_time_ms_to_ticks32(BLE_GAP_CANCEL_RETRY_TIMEOUT_MS);
        }

        ble_gap_disc_complete();
#else
        assert(0);
#endif
        break;

    default:
        BLE_HS_DBG_ASSERT(0);
        break;
    }

    return BLE_HS_FOREVER;
}

#if !MYNEWT_VAL(BLE_EXT_ADV)
static int32_t
ble_gap_slave_timer(void)
{
    uint32_t ticks_until_exp;
    int rc;

    ticks_until_exp = ble_gap_slave_ticks_until_exp();
    if (ticks_until_exp != 0) {
        /* Timer not expired yet. */
        return ticks_until_exp;
    }

    /*** Timer expired; process event. */

    /* Stop advertising. */
    rc = ble_gap_adv_enable_tx(0);
    if (rc != 0) {
        /* Failed to stop advertising; try again in 100 ms. */
        return 100;
    }

    /* Clear the timer and cancel the current procedure. */
    ble_gap_slave_reset_state(0);

    /* Indicate to application that advertising has stopped. */
    ble_gap_adv_finished(0, BLE_HS_ETIMEOUT, 0, 0);

    return BLE_HS_FOREVER;
}
#endif

static int32_t
ble_gap_update_timer(void)
{
    struct ble_gap_update_entry *entry;
    int32_t ticks_until_exp;
    uint16_t conn_handle;

    do {
        ble_hs_lock();

        conn_handle = ble_gap_update_next_exp(&ticks_until_exp);
        if (ticks_until_exp == 0) {
            entry = ble_gap_update_entry_remove(conn_handle);
        } else {
            entry = NULL;
        }

        ble_hs_unlock();

        if (entry != NULL) {
            ble_gap_update_notify(conn_handle, BLE_HS_ETIMEOUT);
            ble_gap_update_entry_free(entry);
        }
    } while (entry != NULL);

    return ticks_until_exp;
}

int
ble_gap_set_event_cb(uint16_t conn_handle, ble_gap_event_fn *cb, void *cb_arg)
{
    struct ble_hs_conn *conn;

    ble_hs_lock();

    conn = ble_hs_conn_find(conn_handle);
    if (conn != NULL) {
        conn->bhc_cb = cb;
        conn->bhc_cb_arg = cb_arg;
    }

    ble_hs_unlock();

    if (conn == NULL) {
        return BLE_HS_ENOTCONN;
    }

    return 0;
}

/**
 * Handles timed-out GAP procedures.
 *
 * @return                      The number of ticks until this function should
 *                                  be called again.
 */
int32_t
ble_gap_timer(void)
{
    int32_t update_ticks;
    int32_t master_ticks;
    int32_t min_ticks;

    master_ticks = ble_gap_master_timer();
    update_ticks = ble_gap_update_timer();

    min_ticks = min(master_ticks, update_ticks);

#if !MYNEWT_VAL(BLE_EXT_ADV)
    min_ticks = min(min_ticks, ble_gap_slave_timer());
#endif

    return min_ticks;
}

/*****************************************************************************
 * $white list                                                               *
 *****************************************************************************/

static int
ble_gap_wl_busy(void)
{
#if !MYNEWT_VAL(BLE_WHITELIST)
    return BLE_HS_ENOTSUP;
#endif

    /* Check if an auto or selective connection establishment procedure is in
     * progress.
     */
    return ble_gap_master.op == BLE_GAP_OP_M_CONN &&
           ble_gap_master.conn.using_wl;
}

static int
ble_gap_wl_tx_add(const ble_addr_t *addr)
{
    uint8_t buf[BLE_HCI_ADD_WHITE_LIST_LEN];
    int rc;

    rc = ble_hs_hci_cmd_build_le_add_to_whitelist(addr->val, addr->type,
                                                  buf, sizeof buf);
    if (rc != 0) {
        return rc;
    }

    rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE,
                                                BLE_HCI_OCF_LE_ADD_WHITE_LIST),
                                     buf, sizeof(buf));
    if (rc != 0) {
        return rc;
    }

    return 0;
}

static int
ble_gap_wl_tx_clear(void)
{
    int rc;

    rc = ble_hs_hci_cmd_tx_empty_ack(
        BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_CLEAR_WHITE_LIST),
        NULL, 0);
    if (rc != 0) {
        return rc;
    }

    return 0;
}

int
ble_gap_wl_set(const ble_addr_t *addrs, uint8_t white_list_count)
{
#if !MYNEWT_VAL(BLE_WHITELIST)
    return BLE_HS_ENOTSUP;
#endif

    int rc;
    int i;

    STATS_INC(ble_gap_stats, wl_set);

    ble_hs_lock();

    if (white_list_count == 0) {
        rc = BLE_HS_EINVAL;
        goto done;
    }

    for (i = 0; i < white_list_count; i++) {
        if (addrs[i].type != BLE_ADDR_PUBLIC &&
            addrs[i].type != BLE_ADDR_RANDOM) {

            rc = BLE_HS_EINVAL;
            goto done;
        }
    }

    if (ble_gap_wl_busy()) {
        rc = BLE_HS_EBUSY;
        goto done;
    }

    BLE_HS_LOG(INFO, "GAP procedure initiated: set whitelist; ");
    ble_gap_log_wl(addrs, white_list_count);
    BLE_HS_LOG(INFO, "\n");

    rc = ble_gap_wl_tx_clear();
    if (rc != 0) {
        goto done;
    }

    for (i = 0; i < white_list_count; i++) {
        rc = ble_gap_wl_tx_add(addrs + i);
        if (rc != 0) {
            goto done;
        }
    }

    rc = 0;

done:
    ble_hs_unlock();

    if (rc != 0) {
        STATS_INC(ble_gap_stats, wl_set_fail);
    }
    return rc;
}

/*****************************************************************************
 * $stop advertise                                                           *
 *****************************************************************************/

static int
ble_gap_adv_enable_tx(int enable)
{
    uint8_t buf[BLE_HCI_SET_ADV_ENABLE_LEN];
    uint16_t opcode;
    int rc;

    opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_ADV_ENABLE);
    ble_hs_hci_cmd_build_le_set_adv_enable(!!enable, buf, sizeof buf);

    rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf));
    if (rc != 0) {
        return rc;
    }

    return 0;
}

static int
ble_gap_adv_stop_no_lock(void)
{
#if !NIMBLE_BLE_ADVERTISE
    return BLE_HS_ENOTSUP;
#endif

    bool active;
    int rc;

    BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());

    STATS_INC(ble_gap_stats, adv_stop);

    active = ble_gap_adv_active();

    BLE_HS_LOG(INFO, "GAP procedure initiated: stop advertising.\n");

    rc = ble_gap_adv_enable_tx(0);
    if (rc != 0) {
        goto done;
    }

    ble_gap_slave_reset_state(0);

    if (!active) {
        rc = BLE_HS_EALREADY;
    } else {
        rc = 0;
    }

done:
    if (rc != 0) {
        STATS_INC(ble_gap_stats, adv_stop_fail);
    }

    return rc;
}

int
ble_gap_adv_stop(void)
{
#if !NIMBLE_BLE_ADVERTISE || MYNEWT_VAL(BLE_EXT_ADV)
    return BLE_HS_ENOTSUP;
#endif

    int rc;

    ble_hs_lock();
    rc = ble_gap_adv_stop_no_lock();
    ble_hs_unlock();

    return rc;
}

/*****************************************************************************
 * $advertise                                                                *
 *****************************************************************************/
#if NIMBLE_BLE_ADVERTISE && !MYNEWT_VAL(BLE_EXT_ADV)
static int
ble_gap_adv_type(const struct ble_gap_adv_params *adv_params)
{
    switch (adv_params->conn_mode) {
    case BLE_GAP_CONN_MODE_NON:
        if (adv_params->disc_mode == BLE_GAP_DISC_MODE_NON) {
            return BLE_HCI_ADV_TYPE_ADV_NONCONN_IND;
        } else {
            return BLE_HCI_ADV_TYPE_ADV_SCAN_IND;
        }

    case BLE_GAP_CONN_MODE_UND:
        return BLE_HCI_ADV_TYPE_ADV_IND;

    case BLE_GAP_CONN_MODE_DIR:
        if (adv_params->high_duty_cycle) {
            return BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD;
        } else {
            return BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD;
        }

    default:
        BLE_HS_DBG_ASSERT(0);
        return BLE_HCI_ADV_TYPE_ADV_IND;
    }
}

static void
ble_gap_adv_dflt_itvls(uint8_t conn_mode,
                       uint16_t *out_itvl_min, uint16_t *out_itvl_max)
{
    switch (conn_mode) {
    case BLE_GAP_CONN_MODE_NON:
        *out_itvl_min = BLE_GAP_ADV_FAST_INTERVAL2_MIN;
        *out_itvl_max = BLE_GAP_ADV_FAST_INTERVAL2_MAX;
        break;

    case BLE_GAP_CONN_MODE_UND:
        *out_itvl_min = BLE_GAP_ADV_FAST_INTERVAL1_MIN;
        *out_itvl_max = BLE_GAP_ADV_FAST_INTERVAL1_MAX;
        break;

    case BLE_GAP_CONN_MODE_DIR:
        *out_itvl_min = BLE_GAP_ADV_FAST_INTERVAL1_MIN;
        *out_itvl_max = BLE_GAP_ADV_FAST_INTERVAL1_MAX;
        break;

    default:
        BLE_HS_DBG_ASSERT(0);
        break;
    }
}

static int
ble_gap_adv_params_tx(uint8_t own_addr_type, const ble_addr_t *peer_addr,
                      const struct ble_gap_adv_params *adv_params)

{
    const ble_addr_t *peer_any = BLE_ADDR_ANY;
    struct hci_adv_params hci_adv_params;
    uint8_t buf[BLE_HCI_SET_ADV_PARAM_LEN];
    int rc;

    if (peer_addr == NULL) {
        peer_addr = peer_any;
    }

    hci_adv_params.own_addr_type = own_addr_type;
    hci_adv_params.peer_addr_type = peer_addr->type;
    memcpy(hci_adv_params.peer_addr, peer_addr->val,
           sizeof hci_adv_params.peer_addr);

    /* Fill optional fields if application did not specify them. */
    if (adv_params->itvl_min == 0 && adv_params->itvl_max == 0) {
        ble_gap_adv_dflt_itvls(adv_params->conn_mode,
                               &hci_adv_params.adv_itvl_min,
                               &hci_adv_params.adv_itvl_max);
    } else {
        hci_adv_params.adv_itvl_min = adv_params->itvl_min;
        hci_adv_params.adv_itvl_max = adv_params->itvl_max;
    }
    if (adv_params->channel_map == 0) {
        hci_adv_params.adv_channel_map = BLE_GAP_ADV_DFLT_CHANNEL_MAP;
    } else {
        hci_adv_params.adv_channel_map = adv_params->channel_map;
    }

    /* Zero is the default value for filter policy and high duty cycle */
    hci_adv_params.adv_filter_policy = adv_params->filter_policy;

    hci_adv_params.adv_type = ble_gap_adv_type(adv_params);
    rc = ble_hs_hci_cmd_build_le_set_adv_params(&hci_adv_params,
                                                buf, sizeof buf);
    if (rc != 0) {
        return BLE_HS_EINVAL;
    }

    rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE,
                                                BLE_HCI_OCF_LE_SET_ADV_PARAMS),
                                     buf, sizeof(buf));
    if (rc != 0) {
        return rc;
    }

    return 0;
}

static int
ble_gap_adv_validate(uint8_t own_addr_type, const ble_addr_t *peer_addr,
                     const struct ble_gap_adv_params *adv_params)
{
    if (adv_params == NULL) {
        return BLE_HS_EINVAL;
    }

    if (own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) {
        return BLE_HS_EINVAL;
    }

    if (adv_params->disc_mode >= BLE_GAP_DISC_MODE_MAX) {
        return BLE_HS_EINVAL;
    }

    if (ble_gap_slave[0].op != BLE_GAP_OP_NULL) {
        return BLE_HS_EALREADY;
    }

    switch (adv_params->conn_mode) {
    case BLE_GAP_CONN_MODE_NON:
        /* High duty cycle only allowed for directed advertising. */
        if (adv_params->high_duty_cycle) {
            return BLE_HS_EINVAL;
        }
        break;

    case BLE_GAP_CONN_MODE_UND:
        /* High duty cycle only allowed for directed advertising. */
        if (adv_params->high_duty_cycle) {
            return BLE_HS_EINVAL;
        }

        /* Don't allow connectable advertising if we won't be able to allocate
         * a new connection.
         */
        if (!ble_hs_conn_can_alloc()) {
            return BLE_HS_ENOMEM;
        }
        break;

    case BLE_GAP_CONN_MODE_DIR:
        if (peer_addr == NULL) {
            return BLE_HS_EINVAL;
        }

        if (peer_addr->type != BLE_ADDR_PUBLIC &&
            peer_addr->type != BLE_ADDR_RANDOM &&
            peer_addr->type != BLE_ADDR_PUBLIC_ID &&
            peer_addr->type != BLE_ADDR_RANDOM_ID) {

            return BLE_HS_EINVAL;
        }

        /* Don't allow connectable advertising if we won't be able to allocate
         * a new connection.
         */
        if (!ble_hs_conn_can_alloc()) {
            return BLE_HS_ENOMEM;
        }
        break;

    default:
        return BLE_HS_EINVAL;
    }

    return 0;
}
#endif

int
ble_gap_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr,
                  int32_t duration_ms,
                  const struct ble_gap_adv_params *adv_params,
                  ble_gap_event_fn *cb, void *cb_arg)
{
#if !NIMBLE_BLE_ADVERTISE || MYNEWT_VAL(BLE_EXT_ADV)
    return BLE_HS_ENOTSUP;
#else
    uint32_t duration_ticks;
    int rc;

    STATS_INC(ble_gap_stats, adv_start);

    ble_hs_lock();

    rc = ble_gap_adv_validate(own_addr_type, direct_addr, adv_params);
    if (rc != 0) {
        goto done;
    }

    if (duration_ms != BLE_HS_FOREVER) {
        rc = ble_npl_time_ms_to_ticks(duration_ms, &duration_ticks);
        if (rc != 0) {
            /* Duration too great. */
            rc = BLE_HS_EINVAL;
            goto done;
        }
    }

    if (!ble_hs_is_enabled()) {
        rc = BLE_HS_EDISABLED;
        goto done;
    }

    if (ble_gap_is_preempted()) {
        rc = BLE_HS_EPREEMPTED;
        goto done;
    }

    rc = ble_hs_id_use_addr(own_addr_type);
    if (rc != 0) {
        goto done;
    }

    BLE_HS_LOG(INFO, "GAP procedure initiated: advertise; ");
    ble_gap_log_adv(own_addr_type, direct_addr, adv_params);
    BLE_HS_LOG(INFO, "\n");

    ble_gap_slave[0].cb = cb;
    ble_gap_slave[0].cb_arg = cb_arg;
    ble_gap_slave[0].our_addr_type = own_addr_type;

    if (adv_params->conn_mode != BLE_GAP_CONN_MODE_NON) {
        ble_gap_slave[0].connectable = 1;
    } else {
        ble_gap_slave[0].connectable = 0;
    }

    rc = ble_gap_adv_params_tx(own_addr_type, direct_addr, adv_params);
    if (rc != 0) {
        goto done;
    }

    ble_gap_slave[0].op = BLE_GAP_OP_S_ADV;

    rc = ble_gap_adv_enable_tx(1);
    if (rc != 0) {
        ble_gap_slave_reset_state(0);
        goto done;
    }

    if (duration_ms != BLE_HS_FOREVER) {
        ble_gap_slave_set_timer(duration_ticks);
    }

    rc = 0;

done:
    ble_hs_unlock();

    if (rc != 0) {
        STATS_INC(ble_gap_stats, adv_start_fail);
    }
    return rc;
#endif
}

int
ble_gap_adv_set_data(const uint8_t *data, int data_len)
{
#if !NIMBLE_BLE_ADVERTISE || MYNEWT_VAL(BLE_EXT_ADV)
    return BLE_HS_ENOTSUP;
#endif

    uint8_t buf[BLE_HCI_SET_ADV_DATA_LEN];
    uint16_t opcode;
    int rc;

    STATS_INC(ble_gap_stats, adv_set_data);

    ble_hs_lock();

    opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_ADV_DATA);
    rc = ble_hs_hci_cmd_build_le_set_adv_data(data, data_len, buf,
                                              sizeof(buf));
    if (rc != 0) {
        goto done;
    }

    rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf));
    if (rc != 0) {
        goto done;
    }

    rc = 0;

done:
    ble_hs_unlock();
    return rc;
}

int
ble_gap_adv_rsp_set_data(const uint8_t *data, int data_len)
{
#if !NIMBLE_BLE_ADVERTISE || MYNEWT_VAL(BLE_EXT_ADV)
    return BLE_HS_ENOTSUP;
#endif

    uint8_t buf[BLE_HCI_SET_SCAN_RSP_DATA_LEN];
    uint16_t opcode;
    int rc;

    ble_hs_lock();

    opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_SCAN_RSP_DATA);
    rc = ble_hs_hci_cmd_build_le_set_scan_rsp_data(data, data_len,
                                                   buf, sizeof(buf));
    if (rc != 0) {
        rc = BLE_HS_HCI_ERR(rc);
        goto done;
    }

    rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf));
    if (rc != 0) {
        goto done;
    }

    rc = 0;

done:
    ble_hs_unlock();
    return rc;
}

int
ble_gap_adv_set_fields(const struct ble_hs_adv_fields *adv_fields)
{
#if !NIMBLE_BLE_ADVERTISE || MYNEWT_VAL(BLE_EXT_ADV)
    return BLE_HS_ENOTSUP;
#endif

    uint8_t buf[BLE_HS_ADV_MAX_SZ];
    uint8_t buf_sz;
    int rc;

    rc = ble_hs_adv_set_fields(adv_fields, buf, &buf_sz, sizeof buf);
    if (rc != 0) {
        return rc;
    }

    rc = ble_gap_adv_set_data(buf, buf_sz);
    if (rc != 0) {
        return rc;
    }

    return 0;
}

int
ble_gap_adv_rsp_set_fields(const struct ble_hs_adv_fields *rsp_fields)
{
#if !NIMBLE_BLE_ADVERTISE || MYNEWT_VAL(BLE_EXT_ADV)
    return BLE_HS_ENOTSUP;
#endif

    uint8_t buf[BLE_HS_ADV_MAX_SZ];
    uint8_t buf_sz;
    int rc;

    rc = ble_hs_adv_set_fields(rsp_fields, buf, &buf_sz, sizeof buf);
    if (rc != 0) {
        return rc;
    }

    rc = ble_gap_adv_rsp_set_data(buf, buf_sz);
    if (rc != 0) {
        return rc;
    }

    return 0;
}

int
ble_gap_adv_active(void)
{
    return ble_gap_adv_active_instance(0);
}

#if MYNEWT_VAL(BLE_EXT_ADV)
static int
ble_gap_ext_adv_params_tx(uint8_t instance,
                          const struct ble_gap_ext_adv_params *params,
                          int8_t *selected_tx_power)

{
    struct hci_ext_adv_params hci_adv_params;
    uint8_t buf[BLE_HCI_LE_SET_EXT_ADV_PARAM_LEN];
    uint8_t rsp;
    int rc;

    memset(&hci_adv_params, 0, sizeof(hci_adv_params));

    if (params->connectable) {
        hci_adv_params.properties |= BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE;
    }
    if (params->scannable) {
        hci_adv_params.properties |= BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE;
    }
    if (params->directed) {
        hci_adv_params.properties |= BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED;
        hci_adv_params.peer_addr_type = params->peer.type;
        memcpy(hci_adv_params.peer_addr, params->peer.val, 6);
    }
    if (params->high_duty_directed) {
        hci_adv_params.properties |= BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED;
    }
    if (params->legacy_pdu) {
        hci_adv_params.properties |= BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY;
    }
    if (params->anonymous) {
        hci_adv_params.properties |= BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV;
    }
    if (params->include_tx_power) {
        hci_adv_params.properties |= BLE_HCI_LE_SET_EXT_ADV_PROP_INC_TX_PWR;
    }

    /* Fill optional fields if application did not specify them. */
    if (params->itvl_min == 0 && params->itvl_max == 0) {
        /* TODO for now limited to legacy values*/
        hci_adv_params.min_interval = BLE_GAP_ADV_FAST_INTERVAL1_MIN;
        hci_adv_params.max_interval = BLE_GAP_ADV_FAST_INTERVAL2_MAX;

    } else {
        hci_adv_params.min_interval = params->itvl_min;
        hci_adv_params.max_interval = params->itvl_max;
    }

    if (params->channel_map == 0) {
        hci_adv_params.chan_map = BLE_GAP_ADV_DFLT_CHANNEL_MAP;
    } else {
        hci_adv_params.chan_map = params->channel_map;
    }

    /* Zero is the default value for filter policy and high duty cycle */
    hci_adv_params.filter_policy = params->filter_policy;
    hci_adv_params.tx_power = params->tx_power;

    if (params->legacy_pdu) {
        hci_adv_params.primary_phy = BLE_HCI_LE_PHY_1M;
        hci_adv_params.secondary_phy = BLE_HCI_LE_PHY_1M;
    } else {
        hci_adv_params.primary_phy = params->primary_phy;
        hci_adv_params.secondary_phy = params->secondary_phy;
    }

    hci_adv_params.own_addr_type = params->own_addr_type;
    hci_adv_params.max_skip = 0;
    hci_adv_params.sid = params->sid;
    hci_adv_params.scan_req_notif = params->scan_req_notif;

    rc = ble_hs_hci_cmd_build_le_ext_adv_params(instance, &hci_adv_params,
                                                buf, sizeof(buf));
    if (rc != 0) {
        return rc;
    }

    rc = ble_hs_hci_cmd_tx(
            BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_EXT_ADV_PARAM),
            buf, sizeof(buf), &rsp, 1, NULL);

    if (rc != 0) {
        return rc;
    }

    if (selected_tx_power) {
        *selected_tx_power = rsp;
    }

    return 0;
}

static int
ble_gap_ext_adv_params_validate(const struct ble_gap_ext_adv_params *params)
{
    if (!params) {
        return BLE_HS_EINVAL;
    }

    if (params->own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) {
        return BLE_HS_EINVAL;
    }

    /* Don't allow connectable advertising if we won't be able to allocate
     * a new connection.
     */
    if (params->connectable && !ble_hs_conn_can_alloc()) {
        return BLE_HS_ENOMEM;
    }

    if (params->legacy_pdu) {
        /* not allowed for legacy PDUs */
        if (params->anonymous || params->include_tx_power) {
            return BLE_HS_EINVAL;
        }
    }

    if (params->directed) {
        if (params->scannable && params->connectable) {
            return BLE_HS_EINVAL;
        }
    }

    if (!params->legacy_pdu) {
        /* not allowed for extended advertising PDUs */
        if (params->connectable && params->scannable) {
            return BLE_HS_EINVAL;
        }

        /* HD directed advertising allowed only for legacy PDUs */
        if (params->high_duty_directed) {
            return BLE_HS_EINVAL;
        }
    }

    return 0;
}

int
ble_gap_ext_adv_configure(uint8_t instance,
                          const struct ble_gap_ext_adv_params *params,
                          int8_t *selected_tx_power,
                          ble_gap_event_fn *cb, void *cb_arg)
{
    int rc;

    if (instance >= BLE_ADV_INSTANCES) {
        return EINVAL;
    }

    rc = ble_gap_ext_adv_params_validate(params);
    if (rc) {
        return rc;
    }

    ble_hs_lock();

    /* TODO should we allow to reconfigure existing instance? */
    if (ble_gap_slave[instance].configured) {
        ble_hs_unlock();
        return ENOMEM;
    }

    rc = ble_gap_ext_adv_params_tx(instance, params, selected_tx_power);
    if (rc) {
        ble_hs_unlock();
        return rc;
    }

    ble_gap_slave[instance].configured = 1;
    ble_gap_slave[instance].cb = cb;
    ble_gap_slave[instance].cb_arg = cb_arg;
    ble_gap_slave[instance].our_addr_type = params->own_addr_type;

    ble_gap_slave[instance].connectable = params->connectable;
    ble_gap_slave[instance].scannable = params->scannable;
    ble_gap_slave[instance].directed = params->directed;
    ble_gap_slave[instance].legacy_pdu = params->legacy_pdu;

    ble_hs_unlock();
    return 0;
}

static int
ble_gap_ext_adv_set_addr_no_lock(uint8_t instance, const uint8_t *addr)
{
    uint8_t buf[BLE_HCI_LE_SET_ADV_SET_RND_ADDR_LEN];
    int rc;

    rc = ble_hs_hci_cmd_build_le_ext_adv_set_random_addr(instance, addr, buf,
                                                         sizeof(buf));
    if (rc != 0) {
        return rc;
    }

    rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE,
                                     BLE_HCI_OCF_LE_SET_ADV_SET_RND_ADDR),
                                     buf, sizeof(buf));
    if (rc != 0) {
        return rc;
    }

    ble_gap_slave[instance].rnd_addr_set = 1;
    memcpy(ble_gap_slave[instance].rnd_addr, addr, 6);

    return 0;
}

int
ble_gap_ext_adv_set_addr(uint8_t instance, const ble_addr_t *addr)
{
    int rc;

    if (instance >= BLE_ADV_INSTANCES || addr->type != BLE_ADDR_RANDOM) {
        return BLE_HS_EINVAL;
    }

    ble_hs_lock();
    rc = ble_gap_ext_adv_set_addr_no_lock(instance, addr->val);
    ble_hs_unlock();

    return rc;
}

int
ble_gap_ext_adv_start(uint8_t instance, int duration, int max_events)
{
    const uint8_t *rnd_addr;
    uint8_t buf[6];
    struct hci_ext_adv_set set;
    uint16_t opcode;
    int rc;

    if (instance >= BLE_ADV_INSTANCES) {
        return BLE_HS_EINVAL;
    }

    ble_hs_lock();
    if (!ble_gap_slave[instance].configured) {
        ble_hs_unlock();
        return BLE_HS_EINVAL;
    }

    if (ble_gap_slave[instance].op != BLE_GAP_OP_NULL) {
        ble_hs_unlock();
        return  BLE_HS_EALREADY;
    }

    if (ble_gap_slave[instance].directed && duration > 1280) {
        ble_hs_unlock();
        return BLE_HS_EINVAL;
    }

    /* verify own address type if random address for instance wasn't explicitly
     * set
     */
    switch (ble_gap_slave[instance].our_addr_type) {
    case BLE_OWN_ADDR_RANDOM:
    case BLE_OWN_ADDR_RPA_RANDOM_DEFAULT:
        if (ble_gap_slave[instance].rnd_addr_set) {
            break;
        }
        /* fall through */
    case BLE_OWN_ADDR_PUBLIC:
    case BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT:
    default:
        rc = ble_hs_id_use_addr(ble_gap_slave[instance].our_addr_type);
        if (rc) {
            ble_hs_unlock();
            return BLE_HS_EINVAL;
        }
        break;
    }

    /* fallback to ID static random address if using random address and instance
     * wasn't configured with own address
     */
    if (!ble_gap_slave[instance].rnd_addr_set) {
        switch (ble_gap_slave[instance].our_addr_type) {
        case BLE_OWN_ADDR_RANDOM:
        case BLE_OWN_ADDR_RPA_RANDOM_DEFAULT:
            rc = ble_hs_id_addr(BLE_ADDR_RANDOM, &rnd_addr, NULL);
            if (rc != 0) {
                ble_hs_unlock();
                return rc;
            }

            rc = ble_gap_ext_adv_set_addr_no_lock(instance, rnd_addr);
            if (rc != 0) {
                ble_hs_unlock();
                return rc;
            }
            break;
        default:
            break;
        }
    }

    opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_EXT_ADV_ENABLE);

    set.handle = instance;
    set.duration = duration;
    set.events = max_events;

    rc = ble_hs_hci_cmd_build_le_ext_adv_enable(1, 1, &set, buf, sizeof(buf));
    if (rc != 0) {
        ble_hs_unlock();
        return rc;
    }

    rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf));
    if (rc != 0) {
        ble_hs_unlock();
        return rc;
    }

    ble_gap_slave[instance].op = BLE_GAP_OP_S_ADV;

    ble_hs_unlock();
    return 0;
}

static int
ble_gap_ext_adv_stop_no_lock(uint8_t instance)
{
    uint8_t buf[6];
    struct hci_ext_adv_set set;
    uint16_t opcode;
    bool active;
    int rc;

    if (!ble_gap_slave[instance].configured) {
        return BLE_HS_EINVAL;
    }

    active = ble_gap_adv_active_instance(instance);

    opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_EXT_ADV_ENABLE);

    set.handle = instance;
    set.duration = 0;
    set.events = 0;

    rc = ble_hs_hci_cmd_build_le_ext_adv_enable(0, 1, &set, buf, sizeof(buf));
    if (rc != 0) {
        return rc;
    }

    rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf));
    if (rc != 0) {
        return rc;
    }

    ble_gap_slave[instance].op = BLE_GAP_OP_NULL;

    if (!active) {
        return BLE_HS_EALREADY;
    } else {
        return 0;
    }
}

int
ble_gap_ext_adv_stop(uint8_t instance)
{
    int rc;

    if (instance >= BLE_ADV_INSTANCES) {
        return BLE_HS_EINVAL;
    }

    ble_hs_lock();
    rc = ble_gap_ext_adv_stop_no_lock(instance);
    ble_hs_unlock();

    return rc;
}


static int
ble_gap_ext_adv_set_data_validate(uint8_t instance, struct os_mbuf *data)
{
    uint16_t len = OS_MBUF_PKTLEN(data);

    if (!ble_gap_slave[instance].configured) {
        return BLE_HS_EINVAL;
    }

    /* not allowed with directed advertising for legacy*/
    if (ble_gap_slave[instance].legacy_pdu && ble_gap_slave[instance].directed) {
        return BLE_HS_EINVAL;
    }

    /* always allowed with legacy PDU but limited to legacy length */
    if (ble_gap_slave[instance].legacy_pdu) {
        if (len > BLE_HS_ADV_MAX_SZ) {
            return BLE_HS_EINVAL;
        }

        return 0;
    }

    /* if already advertising, data must fit in single HCI command
     * as per BT 5.0 Vol 2, Part E, 7.8.54. Don't bother Controller with such
     * a request.
     */
    if (ble_gap_slave[instance].op == BLE_GAP_OP_S_ADV) {
        if (len > min(MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE), 251)) {
            return BLE_HS_EINVAL;
        }
    }

    /* not allowed with scannable advertising */
    if (ble_gap_slave[instance].scannable) {
        return BLE_HS_EINVAL;
    }

    return 0;
}

static int
ble_gap_ext_adv_set(uint8_t instance, uint16_t opcode, struct os_mbuf **data)
{
    /* in that case we always fit all data in single HCI command */
#if MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE) <= BLE_HCI_MAX_EXT_ADV_DATA_LEN
    static uint8_t buf[BLE_HCI_SET_EXT_ADV_DATA_HDR_LEN + \
                       MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE)];
    uint16_t len = OS_MBUF_PKTLEN(*data);
    int rc;

    opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, opcode);

    rc = ble_hs_hci_cmd_build_le_ext_adv_data(instance,
                                    BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_COMPLETE,
                                    0, *data, len, buf, sizeof(buf));
    if (rc) {
        return rc;
    }

    os_mbuf_adj(*data, MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE));
    *data = os_mbuf_trim_front(*data);

    return ble_hs_hci_cmd_tx_empty_ack(opcode, buf,
                                       BLE_HCI_SET_EXT_ADV_DATA_HDR_LEN + len);
#else
    static uint8_t buf[BLE_HCI_SET_EXT_ADV_DATA_HDR_LEN + \
                       BLE_HCI_MAX_EXT_ADV_DATA_LEN];
    uint16_t len = OS_MBUF_PKTLEN(*data);
    uint8_t op;
    int rc;

    opcode =  BLE_HCI_OP(BLE_HCI_OGF_LE, opcode);

    /* complete data */
    if (len <= BLE_HCI_MAX_EXT_ADV_DATA_LEN) {
        rc = ble_hs_hci_cmd_build_le_ext_adv_data(instance,
                                    BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_COMPLETE,
                                    0, *data, len, buf,sizeof(buf));
        if (rc) {
            return rc;
        }

        os_mbuf_adj(*data, len);
        *data = os_mbuf_trim_front(*data);

        return ble_hs_hci_cmd_tx_empty_ack(opcode, buf,
                                        BLE_HCI_SET_EXT_ADV_DATA_HDR_LEN + len);
    }

    /* first fragment  */
    op = BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_FIRST;

    do {
        rc = ble_hs_hci_cmd_build_le_ext_adv_data(instance, op, 0, *data,
                                                  BLE_HCI_MAX_EXT_ADV_DATA_LEN,
                                                  buf, sizeof(buf));
        if (rc) {
            return rc;
        }

        os_mbuf_adj(*data, BLE_HCI_MAX_EXT_ADV_DATA_LEN);
        *data = os_mbuf_trim_front(*data);

        rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf));
        if (rc) {
            return rc;
        }

        len -= BLE_HCI_MAX_EXT_ADV_DATA_LEN;
        op = BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_INT;
    } while (len > BLE_HCI_MAX_EXT_ADV_DATA_LEN);

    /* last fragment */
    rc = ble_hs_hci_cmd_build_le_ext_adv_data(instance,
                                        BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_LAST,
                                        0, *data, len, buf, sizeof(buf));
    if (rc) {
        return rc;
    }

    os_mbuf_adj(*data, len);
    *data = os_mbuf_trim_front(*data);

    return ble_hs_hci_cmd_tx_empty_ack(opcode, buf,
                                       BLE_HCI_SET_EXT_ADV_DATA_HDR_LEN + len);
#endif
}

int
ble_gap_ext_adv_set_data(uint8_t instance, struct os_mbuf *data)
{
    int rc;

    if (instance >= BLE_ADV_INSTANCES) {
        rc = BLE_HS_EINVAL;
        goto done;
    }

    ble_hs_lock();
    rc = ble_gap_ext_adv_set_data_validate(instance, data);
    if (rc != 0) {
        ble_hs_unlock();
        goto done;
    }

    rc = ble_gap_ext_adv_set(instance, BLE_HCI_OCF_LE_SET_EXT_ADV_DATA, &data);

    ble_hs_unlock();

done:
    os_mbuf_free_chain(data);
    return rc;
}

static int
ble_gap_ext_adv_rsp_set_validate(uint8_t instance,  struct os_mbuf *data)
{
    uint16_t len = OS_MBUF_PKTLEN(data);

    if (!ble_gap_slave[instance].configured) {
        return BLE_HS_EINVAL;
    }

    /* not allowed with directed advertising */
    if (ble_gap_slave[instance].directed && ble_gap_slave[instance].connectable) {
        return BLE_HS_EINVAL;
    }

    /* only allowed with scannable advertising */
    if (!ble_gap_slave[instance].scannable) {
        return BLE_HS_EINVAL;
    }

    /* with legacy PDU limited to legacy length */
    if (ble_gap_slave[instance].legacy_pdu) {
        if (len > BLE_HS_ADV_MAX_SZ) {
            return BLE_HS_EINVAL;
        }

        return 0;
    }

    /* if already advertising, data must fit in single HCI command
     * as per BT 5.0 Vol 2, Part E, 7.8.55. Don't bother Controller with such
     * a request.
     */
    if (ble_gap_slave[instance].op == BLE_GAP_OP_S_ADV) {
        if (len > min(MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE), 251)) {
            return BLE_HS_EINVAL;
        }
    }

    return 0;
}

int
ble_gap_ext_adv_rsp_set_data(uint8_t instance, struct os_mbuf *data)
{
    int rc;

    if (instance >= BLE_ADV_INSTANCES) {
        rc = BLE_HS_EINVAL;
        goto done;
    }

    ble_hs_lock();
    rc = ble_gap_ext_adv_rsp_set_validate(instance, data);
    if (rc != 0) {
        ble_hs_unlock();
        goto done;
    }

    rc = ble_gap_ext_adv_set(instance, BLE_HCI_OCF_LE_SET_EXT_SCAN_RSP_DATA,
                             &data);

    ble_hs_unlock();

done:
    os_mbuf_free_chain(data);
    return rc;
}

int
ble_gap_ext_adv_remove(uint8_t instance)
{
    uint8_t buf[BLE_HCI_LE_REMOVE_ADV_SET_LEN];
    uint16_t opcode;
    int rc;

    if (instance >= BLE_ADV_INSTANCES) {
        return BLE_HS_EINVAL;
    }

    ble_hs_lock();
    if (!ble_gap_slave[instance].configured) {
        ble_hs_unlock();
        return BLE_HS_EALREADY;
    }

    if (ble_gap_slave[instance].op == BLE_GAP_OP_S_ADV) {
        ble_hs_unlock();
        return BLE_HS_EBUSY;
    }

    opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_REMOVE_ADV_SET);

    rc = ble_hs_hci_cmd_build_le_ext_adv_remove(instance, buf, sizeof(buf));
    if (rc != 0) {
        ble_hs_unlock();
        return rc;
    }

    rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf));
    if (rc != 0) {
        ble_hs_unlock();
        return rc;
    }

    memset(&ble_gap_slave[instance], 0, sizeof(struct ble_gap_slave_state));
    ble_hs_unlock();

    return 0;
}

#endif

/*****************************************************************************
 * $discovery procedures                                                     *
 *****************************************************************************/

#if MYNEWT_VAL(BLE_EXT_ADV) && NIMBLE_BLE_SCAN
static int
ble_gap_ext_disc_tx_params(uint8_t own_addr_type, uint8_t filter_policy,
                       const struct ble_hs_hci_ext_scan_param *uncoded_params,
                       const struct ble_hs_hci_ext_scan_param *coded_params)
{
    uint8_t buf[BLE_HCI_LE_EXT_SCAN_BASE_LEN +
                2 * BLE_HCI_LE_EXT_SCAN_SINGLE_PARAM_LEN];
    uint8_t phy_mask = 0;
    struct ble_hs_hci_ext_scan_param param[2] = {{0}};
    struct ble_hs_hci_ext_scan_param *p = param;
    int phy_count = 0;
    uint8_t len;
    int rc;

    if (uncoded_params) {
        phy_mask |= BLE_HCI_LE_PHY_1M_PREF_MASK;
        memcpy(&param[phy_count], uncoded_params, sizeof(*uncoded_params));
        phy_count++;
    }

    if (coded_params) {
        phy_mask |= BLE_HCI_LE_PHY_CODED_PREF_MASK;
        memcpy(&param[phy_count], coded_params, sizeof(*coded_params));
        phy_count++;
    }

    rc = ble_hs_hci_cmd_build_le_set_ext_scan_params(own_addr_type,
                                                     filter_policy,
                                                     phy_mask,
                                                     phy_count,
                                                     &p, buf, sizeof(buf));

    if (rc != 0) {
        return BLE_HS_EINVAL;
    }

    len = BLE_HCI_LE_EXT_SCAN_BASE_LEN +
          BLE_HCI_LE_EXT_SCAN_SINGLE_PARAM_LEN * phy_count;

    return ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE,
                                            BLE_HCI_OCF_LE_SET_EXT_SCAN_PARAM),
                                       buf, len);
}

static int
ble_gap_ext_disc_enable_tx(uint8_t enable, uint8_t filter_duplicates,
                           uint16_t duration, uint16_t period)
{
    uint8_t buf[BLE_HCI_LE_SET_EXT_SCAN_ENABLE_LEN];

    ble_hs_hci_cmd_build_le_set_ext_scan_enable(enable, filter_duplicates,
                                                duration, period,
                                                buf, sizeof buf);

    return ble_hs_hci_cmd_tx_empty_ack(
        BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_EXT_SCAN_ENABLE),
        buf, sizeof(buf));
}
#endif

#if NIMBLE_BLE_SCAN
#if !MYNEWT_VAL(BLE_EXT_ADV)
static int
ble_gap_disc_enable_tx(int enable, int filter_duplicates)
{
    uint8_t buf[BLE_HCI_SET_SCAN_ENABLE_LEN];
    int rc;

    ble_hs_hci_cmd_build_le_set_scan_enable(!!enable, !!filter_duplicates,
                                            buf, sizeof buf);
    rc = ble_hs_hci_cmd_tx_empty_ack(
        BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_SCAN_ENABLE),
        buf, sizeof(buf));
    if (rc != 0) {
        return rc;
    }

    return 0;
}

static int
ble_gap_disc_tx_params(uint8_t own_addr_type,
                       const struct ble_gap_disc_params *disc_params)
{
    uint8_t buf[BLE_HCI_SET_SCAN_PARAM_LEN];
    uint8_t scan_type;
    int rc;

    if (disc_params->passive) {
        scan_type = BLE_HCI_SCAN_TYPE_PASSIVE;
    } else {
        scan_type = BLE_HCI_SCAN_TYPE_ACTIVE;
    }

    rc = ble_hs_hci_cmd_build_le_set_scan_params(scan_type,
                                                 disc_params->itvl,
                                                 disc_params->window,
                                                 own_addr_type,
                                                 disc_params->filter_policy,
                                                 buf, sizeof buf);
    if (rc != 0) {
        return BLE_HS_EINVAL;
    }

    rc = ble_hs_hci_cmd_tx_empty_ack(
        BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_SCAN_PARAMS),
        buf, sizeof(buf));
    if (rc != 0) {
        return rc;
    }

    return 0;
}
#endif

static int
ble_gap_disc_disable_tx(void)
{
#if MYNEWT_VAL(BLE_EXT_ADV)
    return ble_gap_ext_disc_enable_tx(0, 0, 0, 0);
#else
    return ble_gap_disc_enable_tx(0, 0);
#endif
}

static int
ble_gap_disc_cancel_no_lock(void)
{
    int rc;

    STATS_INC(ble_gap_stats, discover_cancel);

    if (!ble_gap_disc_active()) {
        rc = BLE_HS_EALREADY;
        goto done;
    }

    rc = ble_gap_disc_disable_tx();
    if (rc != 0) {
        goto done;
    }

    ble_gap_master_reset_state();

done:
    if (rc != 0) {
        STATS_INC(ble_gap_stats, discover_cancel_fail);
    }

    return rc;
}
#endif

int
ble_gap_disc_cancel(void)
{
#if !NIMBLE_BLE_SCAN
    return BLE_HS_ENOTSUP;
#else

    int rc;

    ble_hs_lock();
    rc = ble_gap_disc_cancel_no_lock();
    ble_hs_unlock();

    return rc;
#endif
}

#if NIMBLE_BLE_SCAN
static int
ble_gap_disc_ext_validate(uint8_t own_addr_type)
{
    if (own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) {
        return BLE_HS_EINVAL;
    }

    if (ble_gap_conn_active()) {
        return BLE_HS_EBUSY;
    }

    if (ble_gap_disc_active()) {
        return BLE_HS_EALREADY;
    }

    if (!ble_hs_is_enabled()) {
        return BLE_HS_EDISABLED;
    }

    if (ble_gap_is_preempted()) {
        return BLE_HS_EPREEMPTED;
    }

    return 0;
}
#endif

#if MYNEWT_VAL(BLE_EXT_ADV) && NIMBLE_BLE_SCAN
static void
ble_gap_ext_disc_fill_dflts(uint8_t limited,
                            struct ble_hs_hci_ext_scan_param *disc_params)
{
   if (disc_params->scan_itvl == 0) {
        if (limited) {
            disc_params->scan_itvl = BLE_GAP_LIM_DISC_SCAN_INT;
        } else {
            disc_params->scan_itvl = BLE_GAP_SCAN_FAST_INTERVAL_MIN;
        }
    }

    if (disc_params->scan_window == 0) {
        if (limited) {
            disc_params->scan_window = BLE_GAP_LIM_DISC_SCAN_WINDOW;
        } else {
            disc_params->scan_window = BLE_GAP_SCAN_FAST_WINDOW;
        }
    }
}

static void
ble_gap_ext_scan_params_to_hci(const struct ble_gap_ext_disc_params *params,
                               struct ble_hs_hci_ext_scan_param *hci_params)
{

    memset(hci_params, 0, sizeof(*hci_params));

    if (params->passive) {
        hci_params->scan_type =  BLE_HCI_SCAN_TYPE_PASSIVE;
    } else {
        hci_params->scan_type = BLE_HCI_SCAN_TYPE_ACTIVE;
    }

    hci_params->scan_itvl = params->itvl;
    hci_params->scan_window = params->window;
}
#endif

int
ble_gap_ext_disc(uint8_t own_addr_type, uint16_t duration, uint16_t period,
                 uint8_t filter_duplicates, uint8_t filter_policy,
                 uint8_t limited,
                 const struct ble_gap_ext_disc_params *uncoded_params,
                 const struct ble_gap_ext_disc_params *coded_params,
                 ble_gap_event_fn *cb, void *cb_arg)
{
#if !NIMBLE_BLE_SCAN || !MYNEWT_VAL(BLE_EXT_ADV)
    return BLE_HS_ENOTSUP;
#else

    struct ble_hs_hci_ext_scan_param ucp;
    struct ble_hs_hci_ext_scan_param cp;
    int rc;

    STATS_INC(ble_gap_stats, discover);

    ble_hs_lock();

    rc = ble_gap_disc_ext_validate(own_addr_type);
    if (rc != 0) {
        goto done;
    }

    /* Make a copy of the parameter structure and fill unspecified values with
     * defaults.
     */

    if (uncoded_params) {
        ble_gap_ext_scan_params_to_hci(uncoded_params, &ucp);
        ble_gap_ext_disc_fill_dflts(limited, &ucp);

        /* XXX: We should do it only once */
        if (!uncoded_params->passive) {
            rc = ble_hs_id_use_addr(own_addr_type);
            if (rc != 0) {
                goto done;
            }
        }
    }

    if (coded_params) {
        ble_gap_ext_scan_params_to_hci(coded_params, &cp);
        ble_gap_ext_disc_fill_dflts(limited, &cp);

        /* XXX: We should do it only once */
        if (!coded_params->passive) {
            rc = ble_hs_id_use_addr(own_addr_type);
            if (rc != 0) {
                goto done;
            }
        }
    }

    ble_gap_master.disc.limited = limited;
    ble_gap_master.cb = cb;
    ble_gap_master.cb_arg = cb_arg;

    rc = ble_gap_ext_disc_tx_params(own_addr_type, filter_policy,
                                    uncoded_params ? &ucp : NULL,
                                    coded_params ? &cp : NULL);
    if (rc != 0) {
        goto done;
    }

    ble_gap_master.op = BLE_GAP_OP_M_DISC;

    rc = ble_gap_ext_disc_enable_tx(1, filter_duplicates, duration, period);
    if (rc != 0) {
        ble_gap_master_reset_state();
        goto done;
    }

    rc = 0;

done:
    ble_hs_unlock();

    if (rc != 0) {
        STATS_INC(ble_gap_stats, discover_fail);
    }
    return rc;
#endif
}

#if NIMBLE_BLE_SCAN && !MYNEWT_VAL(BLE_EXT_ADV)
static void
ble_gap_disc_fill_dflts(struct ble_gap_disc_params *disc_params)
{
   if (disc_params->itvl == 0) {
        if (disc_params->limited) {
            disc_params->itvl = BLE_GAP_LIM_DISC_SCAN_INT;
        } else {
            disc_params->itvl = BLE_GAP_SCAN_FAST_INTERVAL_MIN;
        }
    }

    if (disc_params->window == 0) {
        if (disc_params->limited) {
            disc_params->window = BLE_GAP_LIM_DISC_SCAN_WINDOW;
        } else {
            disc_params->window = BLE_GAP_SCAN_FAST_WINDOW;
        }
    }
}

static int
ble_gap_disc_validate(uint8_t own_addr_type,
                      const struct ble_gap_disc_params *disc_params)
{
    if (disc_params == NULL) {
        return BLE_HS_EINVAL;
    }

    return ble_gap_disc_ext_validate(own_addr_type);
}
#endif

int
ble_gap_disc(uint8_t own_addr_type, int32_t duration_ms,
             const struct ble_gap_disc_params *disc_params,
             ble_gap_event_fn *cb, void *cb_arg)
{
#if !NIMBLE_BLE_SCAN
    return BLE_HS_ENOTSUP;
#else

#if MYNEWT_VAL(BLE_EXT_ADV)
    struct ble_gap_ext_disc_params p = {0};

    p.itvl = disc_params->itvl;
    p.passive = disc_params->passive;
    p.window = disc_params->window;

    return ble_gap_ext_disc(own_addr_type, duration_ms/10, 0,
                          disc_params->filter_duplicates,
                          disc_params->filter_policy, disc_params->limited,
                          &p, NULL, cb, cb_arg);
#else
    struct ble_gap_disc_params params;
    uint32_t duration_ticks = 0;
    int rc;

    STATS_INC(ble_gap_stats, discover);

    ble_hs_lock();

    /* Make a copy of the parameter strcuture and fill unspecified values with
     * defaults.
     */
    params = *disc_params;
    ble_gap_disc_fill_dflts(&params);

    rc = ble_gap_disc_validate(own_addr_type, &params);
    if (rc != 0) {
        goto done;
    }

    if (duration_ms == 0) {
        duration_ms = BLE_GAP_DISC_DUR_DFLT;
    }

    if (duration_ms != BLE_HS_FOREVER) {
        rc = ble_npl_time_ms_to_ticks(duration_ms, &duration_ticks);
        if (rc != 0) {
            /* Duration too great. */
            rc = BLE_HS_EINVAL;
            goto done;
        }
    }

    if (!params.passive) {
        rc = ble_hs_id_use_addr(own_addr_type);
        if (rc != 0) {
            goto done;
        }
    }

    ble_gap_master.disc.limited = params.limited;
    ble_gap_master.cb = cb;
    ble_gap_master.cb_arg = cb_arg;

    BLE_HS_LOG(INFO, "GAP procedure initiated: discovery; ");
    ble_gap_log_disc(own_addr_type, duration_ms, &params);
    BLE_HS_LOG(INFO, "\n");

    rc = ble_gap_disc_tx_params(own_addr_type, &params);
    if (rc != 0) {
        goto done;
    }

    ble_gap_master.op = BLE_GAP_OP_M_DISC;

    rc = ble_gap_disc_enable_tx(1, params.filter_duplicates);
    if (rc != 0) {
        ble_gap_master_reset_state();
        goto done;
    }

    if (duration_ms != BLE_HS_FOREVER) {
        ble_gap_master_set_timer(duration_ticks);
    }

    rc = 0;

done:
    ble_hs_unlock();

    if (rc != 0) {
        STATS_INC(ble_gap_stats, discover_fail);
    }
    return rc;
#endif
#endif
}

int
ble_gap_disc_active(void)
{
    /* Assume read is atomic; mutex not necessary. */
    return ble_gap_master.op == BLE_GAP_OP_M_DISC;
}

#if !MYNEWT_VAL(BLE_EXT_ADV)
/*****************************************************************************
 * $connection establishment procedures                                      *
 *****************************************************************************/

static int
ble_gap_conn_create_tx(uint8_t own_addr_type, const ble_addr_t *peer_addr,
                       const struct ble_gap_conn_params *params)
{
    uint8_t buf[BLE_HCI_CREATE_CONN_LEN];
    struct hci_create_conn hcc;
    int rc;

    hcc.scan_itvl = params->scan_itvl;
    hcc.scan_window = params->scan_window;

    if (peer_addr == NULL) {
        /* Application wants to connect to any device in the white list.  The
         * peer address type and peer address fields are ignored by the
         * controller; fill them with dummy values.
         */
        hcc.filter_policy = BLE_HCI_CONN_FILT_USE_WL;
        hcc.peer_addr_type = 0;
        memset(hcc.peer_addr, 0, sizeof hcc.peer_addr);
    } else {
        hcc.filter_policy = BLE_HCI_CONN_FILT_NO_WL;
        hcc.peer_addr_type = peer_addr->type;
        memcpy(hcc.peer_addr, peer_addr->val, sizeof hcc.peer_addr);
    }

    hcc.own_addr_type = own_addr_type;
    hcc.conn_itvl_min = params->itvl_min;
    hcc.conn_itvl_max = params->itvl_max;
    hcc.conn_latency = params->latency;
    hcc.supervision_timeout = params->supervision_timeout;
    hcc.min_ce_len = params->min_ce_len;
    hcc.max_ce_len = params->max_ce_len;

    rc = ble_hs_hci_cmd_build_le_create_connection(&hcc, buf, sizeof buf);
    if (rc != 0) {
        return BLE_HS_EUNKNOWN;
    }

    rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE,
                                                BLE_HCI_OCF_LE_CREATE_CONN),
                                     buf, sizeof(buf));
    if (rc != 0) {
        return rc;
    }

    return 0;
}
#endif

#if MYNEWT_VAL(BLE_EXT_ADV)
static void
ble_gap_copy_params(struct hci_ext_conn_params *hcc_params,
                    const struct ble_gap_conn_params *gap_params)
{
    hcc_params->scan_itvl = gap_params->scan_itvl;
    hcc_params->scan_window = gap_params->scan_window;
    hcc_params->conn_itvl_max = gap_params->itvl_max;
    hcc_params->conn_itvl_min = gap_params->itvl_min;
    hcc_params->max_ce_len = gap_params->max_ce_len;
    hcc_params->min_ce_len = gap_params->min_ce_len;
    hcc_params->conn_latency = gap_params->latency;
    hcc_params->supervision_timeout = gap_params->supervision_timeout;
}

static int
ble_gap_ext_conn_create_tx(
    uint8_t own_addr_type, const ble_addr_t *peer_addr, uint8_t phy_mask,
    const struct ble_gap_conn_params *phy_1m_conn_params,
    const struct ble_gap_conn_params *phy_2m_conn_params,
    const struct ble_gap_conn_params *phy_coded_conn_params)
{
    uint8_t buf[sizeof(struct hci_ext_create_conn)];
    struct hci_ext_create_conn hcc = {0};
    int rc;

    if (peer_addr == NULL) {
        /* Application wants to connect to any device in the white list.  The
         * peer address type and peer address fields are ignored by the
         * controller; fill them with dummy values.
         */
        hcc.filter_policy = BLE_HCI_CONN_FILT_USE_WL;
        hcc.peer_addr_type = 0;
        memset(hcc.peer_addr, 0, sizeof hcc.peer_addr);
    } else {
        hcc.filter_policy = BLE_HCI_CONN_FILT_NO_WL;
        hcc.peer_addr_type = peer_addr->type;;
        memcpy(hcc.peer_addr, peer_addr->val, sizeof hcc.peer_addr);
    }

    hcc.own_addr_type = own_addr_type;

    hcc.init_phy_mask = phy_mask;

    if (phy_mask & BLE_GAP_LE_PHY_1M_MASK) {
        /* XXX same structs */
        ble_gap_copy_params(&hcc.params[0], phy_1m_conn_params);
    }

    if (phy_mask & BLE_GAP_LE_PHY_2M_MASK) {
        /* XXX same structs */
        ble_gap_copy_params(&hcc.params[1], phy_2m_conn_params);
    }

    if (phy_mask & BLE_GAP_LE_PHY_CODED_MASK) {
        /* XXX same structs */
        ble_gap_copy_params(&hcc.params[2], phy_coded_conn_params);
    }

    rc = ble_hs_hci_cmd_build_le_ext_create_conn(&hcc, buf, sizeof buf);
    if (rc != 0) {
        return BLE_HS_EUNKNOWN;
    }

    rc = ble_hs_hci_cmd_tx_empty_ack(
        BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_EXT_CREATE_CONN),
        buf, sizeof(buf));
    if (rc != 0) {
        return rc;
    }

    return 0;
}

/**
 * Initiates a connect procedure.
 *
 * @param own_addr_type         The type of address the stack should use for
 *                                  itself during connection establishment.
 *                                      o BLE_OWN_ADDR_PUBLIC
 *                                      o BLE_OWN_ADDR_RANDOM
 *                                      o BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT
 *                                      o BLE_OWN_ADDR_RPA_RANDOM_DEFAULT
 * @param peer_addr             The address of the peer to connect to.
 *                                  If this parameter is NULL, the white list
 *                                  is used.
 * @param duration_ms           The duration of the discovery procedure.
 *                                  On expiration, the procedure ends and a
 *                                  BLE_GAP_EVENT_DISC_COMPLETE event is
 *                                  reported.  Units are milliseconds.
 * @param phy_mask              Define on which PHYs connection attempt should
 *                                  be done
 * @param phy_1m_conn_params     Additional arguments specifying the
 *                                  particulars of the connect procedure. When
 *                                  BLE_GAP_LE_PHY_1M_MASK is set in phy_mask
 *                                  this parameter can be specify to null for
 *                                  default values.
 * @param phy_2m_conn_params     Additional arguments specifying the
 *                                  particulars of the connect procedure. When
 *                                  BLE_GAP_LE_PHY_2M_MASK is set in phy_mask
 *                                  this parameter can be specify to null for
 *                                  default values.
 * @param phy_coded_conn_params  Additional arguments specifying the
 *                                  particulars of the connect procedure. When
 *                                  BLE_GAP_LE_PHY_CODED_MASK is set in
 *                                  phy_mask this parameter can be specify to
 *                                  null for default values.
 * @param cb                    The callback to associate with this connect
 *                                  procedure.  When the connect procedure
 *                                  completes, the result is reported through
 *                                  this callback.  If the connect procedure
 *                                  succeeds, the connection inherits this
 *                                  callback as its event-reporting mechanism.
 * @param cb_arg                The optional argument to pass to the callback
 *                                  function.
 *
 * @return                      0 on success;
 *                              BLE_HS_EALREADY if a connection attempt is
 *                                  already in progress;
 *                              BLE_HS_EBUSY if initiating a connection is not
 *                                  possible because scanning is in progress;
 *                              BLE_HS_EDONE if the specified peer is already
 *                                  connected;
 *                              Other nonzero on error.
 */
int
ble_gap_ext_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr,
                int32_t duration_ms, uint8_t phy_mask,
                const struct ble_gap_conn_params *phy_1m_conn_params,
                const struct ble_gap_conn_params *phy_2m_conn_params,
                const struct ble_gap_conn_params *phy_coded_conn_params,
                ble_gap_event_fn *cb, void *cb_arg)
{
#if !MYNEWT_VAL(BLE_ROLE_CENTRAL)
    return BLE_HS_ENOTSUP;
#endif

    ble_npl_time_t duration_ticks;
    int rc;

    STATS_INC(ble_gap_stats, initiate);

    ble_hs_lock();

    if (ble_gap_conn_active()) {
        rc = BLE_HS_EALREADY;
        goto done;
    }

    if (ble_gap_disc_active()) {
        rc = BLE_HS_EBUSY;
        goto done;
    }

    if (!ble_hs_is_enabled()) {
        return BLE_HS_EDISABLED;
    }

    if (ble_gap_is_preempted()) {
        rc = BLE_HS_EPREEMPTED;
        goto done;
    }

    if (!ble_hs_conn_can_alloc()) {
        rc = BLE_HS_ENOMEM;
        goto done;
    }

    if (peer_addr &&
        peer_addr->type != BLE_ADDR_PUBLIC &&
        peer_addr->type != BLE_ADDR_RANDOM &&
        peer_addr->type != BLE_ADDR_PUBLIC_ID &&
        peer_addr->type != BLE_ADDR_RANDOM_ID) {

        rc = BLE_HS_EINVAL;
        goto done;
    }

    if ((phy_mask & BLE_GAP_LE_PHY_1M_MASK) && phy_1m_conn_params == NULL) {
        phy_1m_conn_params = &ble_gap_conn_params_dflt;
    }

    if ((phy_mask & BLE_GAP_LE_PHY_2M_MASK) && phy_2m_conn_params == NULL) {
        phy_2m_conn_params = &ble_gap_conn_params_dflt;
    }

    if ((phy_mask & BLE_GAP_LE_PHY_CODED_MASK) &&
        phy_coded_conn_params == NULL) {

        phy_coded_conn_params = &ble_gap_conn_params_dflt;
    }

    if (duration_ms == 0) {
        duration_ms = BLE_GAP_CONN_DUR_DFLT;
    }

    if (duration_ms != BLE_HS_FOREVER) {
        rc = ble_npl_time_ms_to_ticks(duration_ms, &duration_ticks);
        if (rc != 0) {
            /* Duration too great. */
            rc = BLE_HS_EINVAL;
            goto done;
        }
    }

    /* Verify peer not already connected. */
    if (ble_hs_conn_find_by_addr(peer_addr) != NULL) {
        rc = BLE_HS_EDONE;
        goto done;
    }

    /* XXX: Verify conn_params. */

    rc = ble_hs_id_use_addr(own_addr_type);
    if (rc != 0) {
        goto done;
    }

    ble_gap_master.cb = cb;
    ble_gap_master.cb_arg = cb_arg;
    ble_gap_master.conn.using_wl = peer_addr == NULL;
    ble_gap_master.conn.our_addr_type = own_addr_type;

    ble_gap_master.op = BLE_GAP_OP_M_CONN;

    rc = ble_gap_ext_conn_create_tx(own_addr_type, peer_addr, phy_mask,
                                    phy_1m_conn_params, phy_2m_conn_params,
                                    phy_coded_conn_params);
    if (rc != 0) {
        ble_gap_master_reset_state();
        goto done;
    }

    if (duration_ms != BLE_HS_FOREVER) {
        ble_gap_master_set_timer(duration_ticks);
    }

    rc = 0;

done:
    ble_hs_unlock();

    if (rc != 0) {
        STATS_INC(ble_gap_stats, initiate_fail);
    }
    return rc;
}
#endif

int
ble_gap_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr,
                int32_t duration_ms,
                const struct ble_gap_conn_params *conn_params,
                ble_gap_event_fn *cb, void *cb_arg)
{
#if !MYNEWT_VAL(BLE_ROLE_CENTRAL)
    return BLE_HS_ENOTSUP;
#endif

#if MYNEWT_VAL(BLE_EXT_ADV)
    return ble_gap_ext_connect(own_addr_type, peer_addr, duration_ms,
                               BLE_GAP_LE_PHY_1M_MASK,
                               conn_params, NULL, NULL, cb, cb_arg);
#else
    uint32_t duration_ticks;
    int rc;

    STATS_INC(ble_gap_stats, initiate);

    ble_hs_lock();

    if (ble_gap_conn_active()) {
        rc = BLE_HS_EALREADY;
        goto done;
    }

    if (ble_gap_disc_active()) {
        rc = BLE_HS_EBUSY;
        goto done;
    }

    if (!ble_hs_is_enabled()) {
        rc = BLE_HS_EDISABLED;
        goto done;
    }

    if (ble_gap_is_preempted()) {
        rc = BLE_HS_EPREEMPTED;
        goto done;
    }

    if (!ble_hs_conn_can_alloc()) {
        rc = BLE_HS_ENOMEM;
        goto done;
    }

    if (peer_addr &&
        peer_addr->type != BLE_ADDR_PUBLIC &&
        peer_addr->type != BLE_ADDR_RANDOM &&
        peer_addr->type != BLE_ADDR_PUBLIC_ID &&
        peer_addr->type != BLE_ADDR_RANDOM_ID) {

        rc = BLE_HS_EINVAL;
        goto done;
    }

    if (conn_params == NULL) {
        conn_params = &ble_gap_conn_params_dflt;
    }

    if (duration_ms == 0) {
        duration_ms = BLE_GAP_CONN_DUR_DFLT;
    }

    if (duration_ms != BLE_HS_FOREVER) {
        rc = ble_npl_time_ms_to_ticks(duration_ms, &duration_ticks);
        if (rc != 0) {
            /* Duration too great. */
            rc = BLE_HS_EINVAL;
            goto done;
        }
    }

    /* Verify peer not already connected. */
    if (ble_hs_conn_find_by_addr(peer_addr) != NULL) {
        rc = BLE_HS_EDONE;
        goto done;
    }

    /* XXX: Verify conn_params. */

    rc = ble_hs_id_use_addr(own_addr_type);
    if (rc != 0) {
        goto done;
    }

    BLE_HS_LOG(INFO, "GAP procedure initiated: connect; ");
    ble_gap_log_conn(own_addr_type, peer_addr, conn_params);
    BLE_HS_LOG(INFO, "\n");

    ble_gap_master.cb = cb;
    ble_gap_master.cb_arg = cb_arg;
    ble_gap_master.conn.using_wl = peer_addr == NULL;
    ble_gap_master.conn.our_addr_type = own_addr_type;

    ble_gap_master.op = BLE_GAP_OP_M_CONN;

    rc = ble_gap_conn_create_tx(own_addr_type, peer_addr,
                                conn_params);
    if (rc != 0) {
        ble_gap_master_reset_state();
        goto done;
    }

    if (duration_ms != BLE_HS_FOREVER) {
        ble_gap_master_set_timer(duration_ticks);
    }

    rc = 0;

done:
    ble_hs_unlock();

    if (rc != 0) {
        STATS_INC(ble_gap_stats, initiate_fail);
    }
    return rc;
#endif
}

int
ble_gap_conn_active(void)
{
    /* Assume read is atomic; mutex not necessary. */
    return ble_gap_master.op == BLE_GAP_OP_M_CONN;
}

/*****************************************************************************
 * $terminate connection procedure                                           *
 *****************************************************************************/

int
ble_gap_terminate(uint16_t conn_handle, uint8_t hci_reason)
{
    uint8_t buf[BLE_HCI_DISCONNECT_CMD_LEN];
    struct ble_hs_conn *conn;
    int rc;

    STATS_INC(ble_gap_stats, terminate);

    ble_hs_lock();

    conn = ble_hs_conn_find(conn_handle);
    if (conn == NULL) {
        rc = BLE_HS_ENOTCONN;
        goto done;
    }

    if (conn->bhc_flags & BLE_HS_CONN_F_TERMINATING) {
        rc = BLE_HS_EALREADY;
        goto done;
    }

    BLE_HS_LOG(INFO, "GAP procedure initiated: terminate connection; "
                     "conn_handle=%d hci_reason=%d\n",
               conn_handle, hci_reason);

    ble_hs_hci_cmd_build_disconnect(conn_handle, hci_reason,
                                    buf, sizeof buf);
    rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LINK_CTRL,
                                                BLE_HCI_OCF_DISCONNECT_CMD),
                                     buf, sizeof(buf));
    if (rc != 0) {
        goto done;
    }

    conn->bhc_flags |= BLE_HS_CONN_F_TERMINATING;
    rc = 0;

done:
    ble_hs_unlock();

    if (rc != 0) {
        STATS_INC(ble_gap_stats, terminate_fail);
    }
    return rc;
}

/*****************************************************************************
 * $cancel                                                                   *
 *****************************************************************************/

static int
ble_gap_conn_cancel_tx(void)
{
    int rc;

    rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE,
                                            BLE_HCI_OCF_LE_CREATE_CONN_CANCEL),
                                     NULL, 0);
    if (rc != 0) {
        return rc;
    }

    return 0;
}

static int
ble_gap_conn_cancel_no_lock(void)
{
#if !MYNEWT_VAL(BLE_ROLE_CENTRAL)
    return BLE_HS_ENOTSUP;
#endif

    int rc;

    STATS_INC(ble_gap_stats, cancel);

    if (!ble_gap_conn_active()) {
        rc = BLE_HS_EALREADY;
        goto done;
    }

    BLE_HS_LOG(INFO, "GAP procedure initiated: cancel connection\n");

    rc = ble_gap_conn_cancel_tx();
    if (rc != 0) {
        goto done;
    }

    ble_gap_master.conn.cancel = 1;
    rc = 0;

done:
    if (rc != 0) {
        STATS_INC(ble_gap_stats, cancel_fail);
    }

    return rc;
}

int
ble_gap_conn_cancel(void)
{
#if !MYNEWT_VAL(BLE_ROLE_CENTRAL)
    return BLE_HS_ENOTSUP;
#endif

    int rc;

    ble_hs_lock();
    rc = ble_gap_conn_cancel_no_lock();
    ble_hs_unlock();

    return rc;
}

/*****************************************************************************
 * $update connection parameters                                             *
 *****************************************************************************/

static struct ble_gap_update_entry *
ble_gap_update_entry_alloc(void)
{
    struct ble_gap_update_entry *entry;

    entry = os_memblock_get(&ble_gap_update_entry_pool);
    if (entry != NULL) {
        memset(entry, 0, sizeof *entry);
    }

    return entry;
}

static void
ble_gap_update_entry_free(struct ble_gap_update_entry *entry)
{
    int rc;

    if (entry != NULL) {
#if MYNEWT_VAL(BLE_HS_DEBUG)
        memset(entry, 0xff, sizeof *entry);
#endif
        rc = os_memblock_put(&ble_gap_update_entry_pool, entry);
        BLE_HS_DBG_ASSERT_EVAL(rc == 0);
    }
}

static struct ble_gap_update_entry *
ble_gap_update_entry_find(uint16_t conn_handle,
                          struct ble_gap_update_entry **out_prev)
{
    struct ble_gap_update_entry *entry;
    struct ble_gap_update_entry *prev;

    BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());

    prev = NULL;
    SLIST_FOREACH(entry, &ble_gap_update_entries, next) {
        if (entry->conn_handle == conn_handle) {
            break;
        }

        prev = entry;
    }

    if (out_prev != NULL) {
        *out_prev = prev;
    }

    return entry;
}

static struct ble_gap_update_entry *
ble_gap_update_entry_remove(uint16_t conn_handle)
{
    struct ble_gap_update_entry *entry;
    struct ble_gap_update_entry *prev;

    entry = ble_gap_update_entry_find(conn_handle, &prev);
    if (entry != NULL) {
        if (prev == NULL) {
            SLIST_REMOVE_HEAD(&ble_gap_update_entries, next);
        } else {
            SLIST_NEXT(prev, next) = SLIST_NEXT(entry, next);
        }
        ble_hs_timer_resched();
    }

    return entry;
}

static void
ble_gap_update_l2cap_cb(uint16_t conn_handle, int status, void *arg)
{
    struct ble_gap_update_entry *entry;

    /* Report failures and rejections.  Success gets reported when the
     * controller sends the connection update complete event.
     */

    ble_hs_lock();
    entry = ble_gap_update_entry_remove(conn_handle);
    ble_hs_unlock();

    if (entry != NULL) {
        ble_gap_update_entry_free(entry);
        if (status != 0) {
            ble_gap_update_notify(conn_handle, status);
        }
        /* On success let's wait for the controller to notify about update */
    }
}

static int
ble_gap_tx_param_pos_reply(uint16_t conn_handle,
                           struct ble_gap_upd_params *params)
{
    uint8_t buf[BLE_HCI_CONN_PARAM_REPLY_LEN];
    struct hci_conn_param_reply pos_reply;
    int rc;

    pos_reply.handle = conn_handle;
    pos_reply.conn_itvl_min = params->itvl_min;
    pos_reply.conn_itvl_max = params->itvl_max;
    pos_reply.conn_latency = params->latency;
    pos_reply.supervision_timeout = params->supervision_timeout;
    pos_reply.min_ce_len = params->min_ce_len;
    pos_reply.max_ce_len = params->max_ce_len;

    ble_hs_hci_cmd_build_le_conn_param_reply(&pos_reply, buf, sizeof buf);
    rc = ble_hs_hci_cmd_tx_empty_ack(
        BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_REM_CONN_PARAM_RR),
        buf, sizeof(buf));
    if (rc != 0) {
        return rc;
    }

    return 0;
}

static int
ble_gap_tx_param_neg_reply(uint16_t conn_handle, uint8_t reject_reason)
{
    uint8_t buf[BLE_HCI_CONN_PARAM_NEG_REPLY_LEN];
    struct hci_conn_param_neg_reply neg_reply;
    int rc;

    neg_reply.handle = conn_handle;
    neg_reply.reason = reject_reason;

    ble_hs_hci_cmd_build_le_conn_param_neg_reply(&neg_reply, buf, sizeof buf);
    rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE,
                                         BLE_HCI_OCF_LE_REM_CONN_PARAM_NRR),
                                     buf, sizeof(buf));
    if (rc != 0) {
        return rc;
    }

    return 0;
}

void
ble_gap_rx_param_req(struct hci_le_conn_param_req *evt)
{
#if !NIMBLE_BLE_CONNECT
    return;
#endif

    struct ble_gap_upd_params peer_params;
    struct ble_gap_upd_params self_params;
    struct ble_gap_event event;
    uint8_t reject_reason;
    int rc;

    reject_reason = 0; /* Silence warning. */

    memset(&event, 0, sizeof event);

    peer_params.itvl_min = evt->itvl_min;
    peer_params.itvl_max = evt->itvl_max;
    peer_params.latency = evt->latency;
    peer_params.supervision_timeout = evt->timeout;
    peer_params.min_ce_len = 0;
    peer_params.max_ce_len = 0;

    /* Copy the peer params into the self params to make it easy on the
     * application.  The application callback will change only the fields which
     * it finds unsuitable.
     */
    self_params = peer_params;

    memset(&event, 0, sizeof event);
    event.type = BLE_GAP_EVENT_CONN_UPDATE_REQ;
    event.conn_update_req.conn_handle = evt->connection_handle;
    event.conn_update_req.self_params = &self_params;
    event.conn_update_req.peer_params = &peer_params;
    rc = ble_gap_call_conn_event_cb(&event, evt->connection_handle);
    if (rc != 0) {
        reject_reason = rc;
    }

    if (rc == 0) {
        rc = ble_gap_tx_param_pos_reply(evt->connection_handle, &self_params);
        if (rc != 0) {
            ble_gap_update_failed(evt->connection_handle, rc);
        }
    } else {
        ble_gap_tx_param_neg_reply(evt->connection_handle, reject_reason);
    }
}

static int
ble_gap_update_tx(uint16_t conn_handle,
                  const struct ble_gap_upd_params *params)
{
    uint8_t buf[BLE_HCI_CONN_UPDATE_LEN];
    struct hci_conn_update cmd;
    int rc;

    cmd.handle = conn_handle;
    cmd.conn_itvl_min = params->itvl_min;
    cmd.conn_itvl_max = params->itvl_max;
    cmd.conn_latency = params->latency;
    cmd.supervision_timeout = params->supervision_timeout;
    cmd.min_ce_len = params->min_ce_len;
    cmd.max_ce_len = params->max_ce_len;

    rc = ble_hs_hci_cmd_build_le_conn_update(&cmd, buf, sizeof buf);
    if (rc != 0) {
        return rc;
    }

    rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE,
                                                BLE_HCI_OCF_LE_CONN_UPDATE),
                                     buf, sizeof(buf));
    if (rc != 0) {
        return rc;
    }

    return 0;
}

static bool
ble_gap_validate_conn_params(const struct ble_gap_upd_params *params)
{

    /* Requirements from Bluetooth spec. v4.2 [Vol 2, Part E], 7.8.18 */
    if (params->itvl_min > params->itvl_max) {
        return false;
    }

    if (params->itvl_min < 0x0006 || params->itvl_max > 0x0C80) {
        return false;
    }

    if (params->latency > 0x01F3) {
        return false;
    }

    /* According to specification mentioned above we should make sure that:
     * supervision_timeout_ms > (1 + latency) * 2 * max_interval_ms
     *    =>
     * supervision_timeout * 10 ms > (1 + latency) * 2 * itvl_max * 1.25ms
     */
    if (params->supervision_timeout <=
                   (((1 + params->latency) * params->itvl_max) / 4)) {
        return false;
    }

    return true;
}

int
ble_gap_update_params(uint16_t conn_handle,
                      const struct ble_gap_upd_params *params)
{
#if !NIMBLE_BLE_CONNECT
    return BLE_HS_ENOTSUP;
#endif

    struct ble_l2cap_sig_update_params l2cap_params;
    struct ble_gap_update_entry *entry;
    struct ble_gap_update_entry *dup;
    struct ble_hs_conn *conn;
    int l2cap_update;
    int rc;

    l2cap_update = 0;

    /* Validate parameters with a spec */
    if (!ble_gap_validate_conn_params(params)) {
        return BLE_HS_EINVAL;
    }

    STATS_INC(ble_gap_stats, update);
    memset(&l2cap_params, 0, sizeof l2cap_params);
    entry = NULL;

    ble_hs_lock();

    conn = ble_hs_conn_find(conn_handle);
    if (conn == NULL) {
        rc = BLE_HS_ENOTCONN;
        goto done;
    }

    /* Don't allow two concurrent updates to the same connection. */
    dup = ble_gap_update_entry_find(conn_handle, NULL);
    if (dup != NULL) {
        rc = BLE_HS_EALREADY;
        goto done;
    }

    entry = ble_gap_update_entry_alloc();
    if (entry == NULL) {
        rc = BLE_HS_ENOMEM;
        goto done;
    }

    entry->conn_handle = conn_handle;
    entry->params = *params;

    entry->exp_os_ticks = ble_npl_time_get() +
                          ble_npl_time_ms_to_ticks32(BLE_GAP_UPDATE_TIMEOUT_MS);

    BLE_HS_LOG(INFO, "GAP procedure initiated: ");
    ble_gap_log_update(conn_handle, params);
    BLE_HS_LOG(INFO, "\n");

    /*
     * If LL update procedure is not supported on this connection and we are
     * the slave, fail over to the L2CAP update procedure.
     */
    if ((conn->supported_feat & BLE_HS_HCI_LE_FEAT_CONN_PARAM_REQUEST) == 0 &&
            !(conn->bhc_flags & BLE_HS_CONN_F_MASTER)) {
        l2cap_update = 1;
        rc = 0;
    } else {
        rc = ble_gap_update_tx(conn_handle, params);
    }

done:
    ble_hs_unlock();

    if (!l2cap_update) {
        ble_hs_timer_resched();
    } else {
        ble_gap_update_to_l2cap(params, &l2cap_params);

        rc = ble_l2cap_sig_update(conn_handle, &l2cap_params,
                                              ble_gap_update_l2cap_cb, NULL);
    }

    ble_hs_lock();
    if (rc == 0) {
        SLIST_INSERT_HEAD(&ble_gap_update_entries, entry, next);
    } else {
        ble_gap_update_entry_free(entry);
        STATS_INC(ble_gap_stats, update_fail);
    }
    ble_hs_unlock();

    return rc;
}

/*****************************************************************************
 * $security                                                                 *
 *****************************************************************************/
int
ble_gap_security_initiate(uint16_t conn_handle)
{
#if !NIMBLE_BLE_SM
    return BLE_HS_ENOTSUP;
#endif

    struct ble_store_value_sec value_sec;
    struct ble_store_key_sec key_sec;
    struct ble_hs_conn_addrs addrs;
    ble_hs_conn_flags_t conn_flags;
    struct ble_hs_conn *conn;
    int rc;

    STATS_INC(ble_gap_stats, security_initiate);

    ble_hs_lock();
    conn = ble_hs_conn_find(conn_handle);
    if (conn != NULL) {
        conn_flags = conn->bhc_flags;
        ble_hs_conn_addrs(conn, &addrs);

        memset(&key_sec, 0, sizeof key_sec);
        key_sec.peer_addr = addrs.peer_id_addr;
    }
    ble_hs_unlock();

    if (conn == NULL) {
        rc = BLE_HS_ENOTCONN;
        goto done;
    }

    if (conn_flags & BLE_HS_CONN_F_MASTER) {
        /* Search the security database for an LTK for this peer.  If one
         * is found, perform the encryption procedure rather than the pairing
         * procedure.
         */
        rc = ble_store_read_peer_sec(&key_sec, &value_sec);
        if (rc == 0 && value_sec.ltk_present) {
            rc = ble_sm_enc_initiate(conn_handle, value_sec.key_size,
                                     value_sec.ltk, value_sec.ediv,
                                     value_sec.rand_num,
                                     value_sec.authenticated);
            if (rc != 0) {
                goto done;
            }
        } else {
            rc = ble_sm_pair_initiate(conn_handle);
            if (rc != 0) {
                goto done;
            }
        }
    } else {
        rc = ble_sm_slave_initiate(conn_handle);
        if (rc != 0) {
            goto done;
        }
    }

    rc = 0;

done:
    if (rc != 0) {
        STATS_INC(ble_gap_stats, security_initiate_fail);
    }

    return rc;
}

int
ble_gap_pair_initiate(uint16_t conn_handle)
{
    int rc;

    rc = ble_sm_pair_initiate(conn_handle);

    return rc;
}

int
ble_gap_encryption_initiate(uint16_t conn_handle,
                            uint8_t key_size,
                            const uint8_t *ltk,
                            uint16_t ediv,
                            uint64_t rand_val,
                            int auth)
{
#if !NIMBLE_BLE_SM
    return BLE_HS_ENOTSUP;
#endif

    ble_hs_conn_flags_t conn_flags;
    int rc;

    rc = ble_hs_atomic_conn_flags(conn_handle, &conn_flags);
    if (rc != 0) {
        return rc;
    }

    if (!(conn_flags & BLE_HS_CONN_F_MASTER)) {
        return BLE_HS_EROLE;
    }

    rc = ble_sm_enc_initiate(conn_handle, key_size, ltk,
                             ediv, rand_val, auth);
    return rc;
}

int
ble_gap_unpair(const ble_addr_t *peer_addr)
{
    struct ble_hs_conn *conn;
    int rc;

    if (ble_addr_cmp(peer_addr, BLE_ADDR_ANY) == 0) {
        return BLE_HS_EINVAL;
    }

    conn = ble_hs_conn_find_by_addr(peer_addr);
    if (conn != NULL) {
        rc = ble_gap_terminate(conn->bhc_handle, BLE_ERR_REM_USER_CONN_TERM);
        if ((rc != BLE_HS_EALREADY) && (rc != BLE_HS_ENOTCONN)) {
            return rc;
        }
    }

    rc = ble_hs_pvcy_remove_entry(peer_addr->type,
                                  peer_addr->val);
    if (rc != 0) {
        return rc;
    }

    return ble_store_util_delete_peer(peer_addr);
}

int
ble_gap_unpair_oldest_peer(void)
{
    ble_addr_t oldest_peer_id_addr;
    int num_peers;
    int rc;

    rc = ble_store_util_bonded_peers(
            &oldest_peer_id_addr, &num_peers, 1);
    if (rc != 0) {
        return rc;
    }

    if (num_peers == 0) {
        return 0;
    }

    rc = ble_gap_unpair(&oldest_peer_id_addr);
    if (rc != 0) {
        return rc;
    }

    return 0;
}

void
ble_gap_passkey_event(uint16_t conn_handle,
                      struct ble_gap_passkey_params *passkey_params)
{
#if !NIMBLE_BLE_SM
    return;
#endif

    struct ble_gap_event event;

    BLE_HS_LOG(DEBUG, "send passkey action request %d\n",
               passkey_params->action);

    memset(&event, 0, sizeof event);
    event.type = BLE_GAP_EVENT_PASSKEY_ACTION;
    event.passkey.conn_handle = conn_handle;
    event.passkey.params = *passkey_params;
    ble_gap_call_conn_event_cb(&event, conn_handle);
}

void
ble_gap_enc_event(uint16_t conn_handle, int status, int security_restored)
{
#if !NIMBLE_BLE_SM
    return;
#endif

    struct ble_gap_event event;

    memset(&event, 0, sizeof event);
    event.type = BLE_GAP_EVENT_ENC_CHANGE;
    event.enc_change.conn_handle = conn_handle;
    event.enc_change.status = status;

    ble_gap_event_listener_call(&event);
    ble_gap_call_conn_event_cb(&event, conn_handle);

    if (status == 0) {
        if (security_restored) {
            ble_gatts_bonding_restored(conn_handle);
        } else {
            ble_gatts_bonding_established(conn_handle);
        }
    }
}

void
ble_gap_identity_event(uint16_t conn_handle)
{
#if !NIMBLE_BLE_SM
    return;
#endif

    struct ble_gap_event event;

    BLE_HS_LOG(DEBUG, "send identity changed");

    memset(&event, 0, sizeof event);
    event.type = BLE_GAP_EVENT_IDENTITY_RESOLVED;
    event.identity_resolved.conn_handle = conn_handle;
    ble_gap_call_conn_event_cb(&event, conn_handle);
}

int
ble_gap_repeat_pairing_event(const struct ble_gap_repeat_pairing *rp)
{
#if !NIMBLE_BLE_SM
    return 0;
#endif

    struct ble_gap_event event;
    int rc;

    memset(&event, 0, sizeof event);
    event.type = BLE_GAP_EVENT_REPEAT_PAIRING;
    event.repeat_pairing = *rp;
    rc = ble_gap_call_conn_event_cb(&event, rp->conn_handle);
    return rc;
}

/*****************************************************************************
 * $rssi                                                                     *
 *****************************************************************************/

int
ble_gap_conn_rssi(uint16_t conn_handle, int8_t *out_rssi)
{
    int rc;

    rc = ble_hs_hci_util_read_rssi(conn_handle, out_rssi);
    return rc;
}

/*****************************************************************************
 * $notify                                                                   *
 *****************************************************************************/

void
ble_gap_notify_rx_event(uint16_t conn_handle, uint16_t attr_handle,
                        struct os_mbuf *om, int is_indication)
{
#if !MYNEWT_VAL(BLE_GATT_NOTIFY) && !MYNEWT_VAL(BLE_GATT_INDICATE)
    return;
#endif

    struct ble_gap_event event;

    memset(&event, 0, sizeof event);
    event.type = BLE_GAP_EVENT_NOTIFY_RX;
    event.notify_rx.conn_handle = conn_handle;
    event.notify_rx.attr_handle = attr_handle;
    event.notify_rx.om = om;
    event.notify_rx.indication = is_indication;
    ble_gap_call_conn_event_cb(&event, conn_handle);

    os_mbuf_free_chain(event.notify_rx.om);
}

void
ble_gap_notify_tx_event(int status, uint16_t conn_handle, uint16_t attr_handle,
                        int is_indication)
{
#if !MYNEWT_VAL(BLE_GATT_NOTIFY) && !MYNEWT_VAL(BLE_GATT_INDICATE)
    return;
#endif

    struct ble_gap_event event;

    memset(&event, 0, sizeof event);
    event.type = BLE_GAP_EVENT_NOTIFY_TX;
    event.notify_tx.conn_handle = conn_handle;
    event.notify_tx.status = status;
    event.notify_tx.attr_handle = attr_handle;
    event.notify_tx.indication = is_indication;
    ble_gap_call_conn_event_cb(&event, conn_handle);
}

/*****************************************************************************
 * $subscribe                                                                *
 *****************************************************************************/

void
ble_gap_subscribe_event(uint16_t conn_handle, uint16_t attr_handle,
                        uint8_t reason,
                        uint8_t prev_notify, uint8_t cur_notify,
                        uint8_t prev_indicate, uint8_t cur_indicate)
{
    struct ble_gap_event event;

    BLE_HS_DBG_ASSERT(prev_notify != cur_notify ||
                      prev_indicate != cur_indicate);
    BLE_HS_DBG_ASSERT(reason == BLE_GAP_SUBSCRIBE_REASON_WRITE ||
                      reason == BLE_GAP_SUBSCRIBE_REASON_TERM  ||
                      reason == BLE_GAP_SUBSCRIBE_REASON_RESTORE);

    memset(&event, 0, sizeof event);
    event.type = BLE_GAP_EVENT_SUBSCRIBE;
    event.subscribe.conn_handle = conn_handle;
    event.subscribe.attr_handle = attr_handle;
    event.subscribe.reason = reason;
    event.subscribe.prev_notify = !!prev_notify;
    event.subscribe.cur_notify = !!cur_notify;
    event.subscribe.prev_indicate = !!prev_indicate;
    event.subscribe.cur_indicate = !!cur_indicate;

    ble_gap_event_listener_call(&event);
    ble_gap_call_conn_event_cb(&event, conn_handle);
}

/*****************************************************************************
 * $mtu                                                                      *
 *****************************************************************************/

void
ble_gap_mtu_event(uint16_t conn_handle, uint16_t cid, uint16_t mtu)
{
    struct ble_gap_event event;

    memset(&event, 0, sizeof event);
    event.type = BLE_GAP_EVENT_MTU;
    event.mtu.conn_handle = conn_handle;
    event.mtu.channel_id = cid;
    event.mtu.value = mtu;

    ble_gap_event_listener_call(&event);
    ble_gap_call_conn_event_cb(&event, conn_handle);
}

/*****************************************************************************
 * $preempt                                                                  *
 *****************************************************************************/

void
ble_gap_preempt_no_lock(void)
{
    int rc;
    int i;

    (void)rc;
    (void)i;

#if NIMBLE_BLE_ADVERTISE
#if MYNEWT_VAL(BLE_EXT_ADV)
    for (i = 0; i < BLE_ADV_INSTANCES; i++) {
        rc = ble_gap_ext_adv_stop_no_lock(i);
        if (rc == 0) {
            ble_gap_slave[i].preempted = 1;
        }
    }
#else
    rc = ble_gap_adv_stop_no_lock();
    if (rc == 0) {
        ble_gap_slave[0].preempted = 1;
    }
#endif
#endif

#if NIMBLE_BLE_CONNECT
    rc = ble_gap_conn_cancel_no_lock();
    if (rc == 0) {
        ble_gap_master.preempted_op = BLE_GAP_OP_M_CONN;
    }
#endif

#if NIMBLE_BLE_SCAN
    rc = ble_gap_disc_cancel_no_lock();
    if (rc == 0) {
        ble_gap_master.preempted_op = BLE_GAP_OP_M_DISC;
    }
#endif
}

/**
 * @brief Preempts the GAP if it is not already preempted.
 *
 * Aborts all active GAP procedures and prevents new ones from being started.
 * This function is used to ensure an idle GAP so that the controller's
 * resolving list can be modified.  When done accessing the resolving list, the
 * caller must call `ble_gap_preempt_done()` to permit new GAP procedures.
 *
 * On preemption, all aborted GAP procedures are reported with a status or
 * reason code of BLE_HS_EPREEMPTED.  An attempt to initiate a new GAP
 * procedure during preemption fails with a return code of BLE_HS_EPREEMPTED.
 */
void
ble_gap_preempt(void)
{
    ble_hs_lock();

    if (!ble_gap_is_preempted()) {
        ble_gap_preempt_no_lock();
    }

    ble_hs_unlock();
}

/**
 * Takes GAP out of the preempted state, allowing new GAP procedures to be
 * initiated.  This function should only be called after a call to
 * `ble_gap_preempt()`.
 */

static struct ble_npl_mutex preempt_done_mutex;

void
ble_gap_preempt_done(void)
{
    struct ble_gap_event event;
    ble_gap_event_fn *master_cb;
    void *master_arg;
    int disc_preempted;
    int i;
    static struct {
        ble_gap_event_fn *cb;
        void *arg;
    } slaves[BLE_ADV_INSTANCES];

    disc_preempted = 0;

    /* protects slaves from accessing by multiple threads */
    ble_npl_mutex_pend(&preempt_done_mutex, 0xFFFFFFFF);
    memset(slaves, 0, sizeof(slaves));

    ble_hs_lock();

    for (i = 0; i < BLE_ADV_INSTANCES; i++) {
        if (ble_gap_slave[i].preempted) {
            ble_gap_slave[i].preempted = 0;
            slaves[i].cb = ble_gap_slave[i].cb;
            slaves[i].arg = ble_gap_slave[i].cb_arg;
        }
    }

    if (ble_gap_master.preempted_op == BLE_GAP_OP_M_DISC) {
        ble_gap_master.preempted_op = BLE_GAP_OP_NULL;
        disc_preempted = 1;
        master_cb = ble_gap_master.cb;
        master_arg = ble_gap_master.cb_arg;
    }

    ble_hs_unlock();

    event.type = BLE_GAP_EVENT_ADV_COMPLETE;
    event.adv_complete.reason = BLE_HS_EPREEMPTED;

    for (i = 0; i < BLE_ADV_INSTANCES; i++) {
        if (slaves[i].cb) {
#if MYNEWT_VAL(BLE_EXT_ADV)
            event.adv_complete.instance = i;
            event.adv_complete.conn_handle = i;
#endif
            ble_gap_call_event_cb(&event, slaves[i].cb, slaves[i].arg);
        }
    }
    ble_npl_mutex_release(&preempt_done_mutex);

    if (disc_preempted) {
        event.type = BLE_GAP_EVENT_DISC_COMPLETE;
        event.disc_complete.reason = BLE_HS_EPREEMPTED;
        ble_gap_call_event_cb(&event, master_cb, master_arg);
    }
}

int
ble_gap_event_listener_register(struct ble_gap_event_listener *listener,
                                ble_gap_event_fn *fn, void *arg)
{
    struct ble_gap_event_listener *evl = NULL;
    int rc;

    SLIST_FOREACH(evl, &ble_gap_event_listener_list, link) {
        if (evl == listener) {
            break;
        }
    }

    if (!evl) {
        if (fn) {
            memset(listener, 0, sizeof(*listener));
            listener->fn = fn;
            listener->arg = arg;
            SLIST_INSERT_HEAD(&ble_gap_event_listener_list, listener, link);
            rc = 0;
        } else {
            rc = BLE_HS_EINVAL;
        }
    } else {
        rc = BLE_HS_EALREADY;
    }

    return rc;
}

int
ble_gap_event_listener_unregister(struct ble_gap_event_listener *listener)
{
    struct ble_gap_event_listener *evl = NULL;
    int rc;

    /*
     * We check if element exists on the list only for sanity to let caller
     * know whether it registered its listener before.
     */

    SLIST_FOREACH(evl, &ble_gap_event_listener_list, link) {
        if (evl == listener) {
            break;
        }
    }

    if (!evl) {
        rc = BLE_HS_ENOENT;
    } else {
        SLIST_REMOVE(&ble_gap_event_listener_list, listener,
                     ble_gap_event_listener, link);
        rc = 0;
    }

    return rc;
}

static int
ble_gap_event_listener_call(struct ble_gap_event *event)
{
    struct ble_gap_event_listener *evl = NULL;

    SLIST_FOREACH(evl, &ble_gap_event_listener_list, link) {
        evl->fn(event, evl->arg);
    }

    return 0;
}

/*****************************************************************************
 * $init                                                                     *
 *****************************************************************************/

int
ble_gap_init(void)
{
    int rc;

    memset(&ble_gap_master, 0, sizeof ble_gap_master);
    memset(ble_gap_slave, 0, sizeof ble_gap_slave);

    ble_npl_mutex_init(&preempt_done_mutex);

    SLIST_INIT(&ble_gap_update_entries);
    SLIST_INIT(&ble_gap_event_listener_list);

    rc = os_mempool_init(&ble_gap_update_entry_pool,
                         MYNEWT_VAL(BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE),
                         sizeof (struct ble_gap_update_entry),
                         ble_gap_update_entry_mem,
                         "ble_gap_update");
    switch (rc) {
    case 0:
        break;
    case OS_ENOMEM:
        rc = BLE_HS_ENOMEM;
        goto err;
    default:
        rc = BLE_HS_EOS;
        goto err;
    }

    rc = stats_init_and_reg(
        STATS_HDR(ble_gap_stats), STATS_SIZE_INIT_PARMS(ble_gap_stats,
        STATS_SIZE_32), STATS_NAME_INIT_PARMS(ble_gap_stats), "ble_gap");
    if (rc != 0) {
        goto err;
    }

    return 0;

err:
    return rc;
}
