/*
 * 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 <stdint.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include "os/os.h"
#include "nimble/hci_common.h"
#include "nimble/ble_hci_trans.h"
#include "host/ble_gap.h"
#include "host/ble_monitor.h"
#include "ble_hs_priv.h"
#include "ble_hs_dbg_priv.h"

_Static_assert(sizeof (struct hci_data_hdr) == BLE_HCI_DATA_HDR_SZ,
               "struct hci_data_hdr must be 4 bytes");

typedef int ble_hs_hci_evt_fn(uint8_t event_code, uint8_t *data, int len);
static ble_hs_hci_evt_fn ble_hs_hci_evt_disconn_complete;
static ble_hs_hci_evt_fn ble_hs_hci_evt_encrypt_change;
static ble_hs_hci_evt_fn ble_hs_hci_evt_hw_error;
static ble_hs_hci_evt_fn ble_hs_hci_evt_num_completed_pkts;
static ble_hs_hci_evt_fn ble_hs_hci_evt_enc_key_refresh;
static ble_hs_hci_evt_fn ble_hs_hci_evt_le_meta;

typedef int ble_hs_hci_evt_le_fn(uint8_t subevent, uint8_t *data, int len);
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_conn_complete;
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_adv_rpt;
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_conn_upd_complete;
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_lt_key_req;
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_conn_parm_req;
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_dir_adv_rpt;
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_phy_update_complete;
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_ext_adv_rpt;
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_rd_rem_used_feat_complete;
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_scan_timeout;
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_adv_set_terminated;

/* Statistics */
struct host_hci_stats
{
    uint32_t events_rxd;
    uint32_t good_acks_rxd;
    uint32_t bad_acks_rxd;
    uint32_t unknown_events_rxd;
};

#define BLE_HS_HCI_EVT_TIMEOUT        50      /* Milliseconds. */

/** Dispatch table for incoming HCI events.  Sorted by event code field. */
struct ble_hs_hci_evt_dispatch_entry {
    uint8_t event_code;
    ble_hs_hci_evt_fn *cb;
};

static const struct ble_hs_hci_evt_dispatch_entry ble_hs_hci_evt_dispatch[] = {
    { BLE_HCI_EVCODE_DISCONN_CMP, ble_hs_hci_evt_disconn_complete },
    { BLE_HCI_EVCODE_ENCRYPT_CHG, ble_hs_hci_evt_encrypt_change },
    { BLE_HCI_EVCODE_HW_ERROR, ble_hs_hci_evt_hw_error },
    { BLE_HCI_EVCODE_NUM_COMP_PKTS, ble_hs_hci_evt_num_completed_pkts },
    { BLE_HCI_EVCODE_ENC_KEY_REFRESH, ble_hs_hci_evt_enc_key_refresh },
    { BLE_HCI_EVCODE_LE_META, ble_hs_hci_evt_le_meta },
};

#define BLE_HS_HCI_EVT_DISPATCH_SZ \
    (sizeof ble_hs_hci_evt_dispatch / sizeof ble_hs_hci_evt_dispatch[0])

/** Dispatch table for incoming LE meta events.  Sorted by subevent field. */
struct ble_hs_hci_evt_le_dispatch_entry {
    uint8_t subevent;
    ble_hs_hci_evt_le_fn *cb;
};

static const struct ble_hs_hci_evt_le_dispatch_entry
        ble_hs_hci_evt_le_dispatch[] = {
    { BLE_HCI_LE_SUBEV_CONN_COMPLETE, ble_hs_hci_evt_le_conn_complete },
    { BLE_HCI_LE_SUBEV_ADV_RPT, ble_hs_hci_evt_le_adv_rpt },
    { BLE_HCI_LE_SUBEV_CONN_UPD_COMPLETE,
          ble_hs_hci_evt_le_conn_upd_complete },
    { BLE_HCI_LE_SUBEV_LT_KEY_REQ, ble_hs_hci_evt_le_lt_key_req },
    { BLE_HCI_LE_SUBEV_REM_CONN_PARM_REQ, ble_hs_hci_evt_le_conn_parm_req },
    { BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE, ble_hs_hci_evt_le_conn_complete },
    { BLE_HCI_LE_SUBEV_DIRECT_ADV_RPT, ble_hs_hci_evt_le_dir_adv_rpt },
    { BLE_HCI_LE_SUBEV_PHY_UPDATE_COMPLETE,
        ble_hs_hci_evt_le_phy_update_complete },
    { BLE_HCI_LE_SUBEV_EXT_ADV_RPT, ble_hs_hci_evt_le_ext_adv_rpt },
    { BLE_HCI_LE_SUBEV_RD_REM_USED_FEAT,
            ble_hs_hci_evt_le_rd_rem_used_feat_complete },
    { BLE_HCI_LE_SUBEV_SCAN_TIMEOUT,
            ble_hs_hci_evt_le_scan_timeout },
    { BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED,
            ble_hs_hci_evt_le_adv_set_terminated },
};

#define BLE_HS_HCI_EVT_LE_DISPATCH_SZ \
    (sizeof ble_hs_hci_evt_le_dispatch / sizeof ble_hs_hci_evt_le_dispatch[0])

static const struct ble_hs_hci_evt_dispatch_entry *
ble_hs_hci_evt_dispatch_find(uint8_t event_code)
{
    const struct ble_hs_hci_evt_dispatch_entry *entry;
    int i;

    for (i = 0; i < BLE_HS_HCI_EVT_DISPATCH_SZ; i++) {
        entry = ble_hs_hci_evt_dispatch + i;
        if (entry->event_code == event_code) {
            return entry;
        }
    }

    return NULL;
}

static const struct ble_hs_hci_evt_le_dispatch_entry *
ble_hs_hci_evt_le_dispatch_find(uint8_t event_code)
{
    const struct ble_hs_hci_evt_le_dispatch_entry *entry;
    int i;

    for (i = 0; i < BLE_HS_HCI_EVT_LE_DISPATCH_SZ; i++) {
        entry = ble_hs_hci_evt_le_dispatch + i;
        if (entry->subevent == event_code) {
            return entry;
        }
    }

    return NULL;
}

static int
ble_hs_hci_evt_disconn_complete(uint8_t event_code, uint8_t *data, int len)
{
    struct hci_disconn_complete evt;
    const struct ble_hs_conn *conn;

    if (len < BLE_HCI_EVENT_DISCONN_COMPLETE_LEN) {
        return BLE_HS_ECONTROLLER;
    }

    evt.status = data[2];
    evt.connection_handle = get_le16(data + 3);
    evt.reason = data[5];

    ble_hs_lock();
    conn = ble_hs_conn_find(evt.connection_handle);
    if (conn != NULL) {
        ble_hs_hci_add_avail_pkts(conn->bhc_outstanding_pkts);
    }
    ble_hs_unlock();

    ble_gap_rx_disconn_complete(&evt);

    /* The connection termination may have freed up some capacity in the
     * controller for additional ACL data packets.  Wake up any stalled
     * connections.
     */
    ble_hs_wakeup_tx();

    return 0;
}

static int
ble_hs_hci_evt_encrypt_change(uint8_t event_code, uint8_t *data, int len)
{
    struct hci_encrypt_change evt;

    if (len < BLE_HCI_EVENT_ENCRYPT_CHG_LEN) {
        return BLE_HS_ECONTROLLER;
    }

    evt.status = data[2];
    evt.connection_handle = get_le16(data + 3);
    evt.encryption_enabled = data[5];

    ble_sm_enc_change_rx(&evt);

    return 0;
}

static int
ble_hs_hci_evt_hw_error(uint8_t event_code, uint8_t *data, int len)
{
    uint8_t hw_code;

    if (len < BLE_HCI_EVENT_HW_ERROR_LEN) {
        return BLE_HS_ECONTROLLER;
    }

    hw_code = data[0];
    ble_hs_hw_error(hw_code);

    return 0;
}

static int
ble_hs_hci_evt_enc_key_refresh(uint8_t event_code, uint8_t *data, int len)
{
    struct hci_encrypt_key_refresh evt;

    if (len < BLE_HCI_EVENT_ENC_KEY_REFRESH_LEN) {
        return BLE_HS_ECONTROLLER;
    }

    evt.status = data[2];
    evt.connection_handle = get_le16(data + 3);

    ble_sm_enc_key_refresh_rx(&evt);

    return 0;
}

static int
ble_hs_hci_evt_num_completed_pkts(uint8_t event_code, uint8_t *data, int len)
{
    struct ble_hs_conn *conn;
    uint16_t num_pkts;
    uint16_t handle;
    uint8_t num_handles;
    int off;
    int i;

    if (len < BLE_HCI_EVENT_HDR_LEN + BLE_HCI_EVENT_NUM_COMP_PKTS_HDR_LEN) {
        return BLE_HS_ECONTROLLER;
    }

    off = BLE_HCI_EVENT_HDR_LEN;
    num_handles = data[off];
    if (len < BLE_HCI_EVENT_NUM_COMP_PKTS_HDR_LEN +
              num_handles * BLE_HCI_EVENT_NUM_COMP_PKTS_ENT_LEN) {
        return BLE_HS_ECONTROLLER;
    }
    off++;

    for (i = 0; i < num_handles; i++) {
        handle = get_le16(data + off);
        num_pkts = get_le16(data + off + 2);
        off += (2 * sizeof(uint16_t));

        if (num_pkts > 0) {
            ble_hs_lock();
            conn = ble_hs_conn_find(handle);
            if (conn != NULL) {
                if (conn->bhc_outstanding_pkts < num_pkts) {
                    ble_hs_sched_reset(BLE_HS_ECONTROLLER);
                } else {
                    conn->bhc_outstanding_pkts -= num_pkts;
                }

                ble_hs_hci_add_avail_pkts(num_pkts);
            }
            ble_hs_unlock();
        }
    }

    /* If any transmissions have stalled, wake them up now. */
    ble_hs_wakeup_tx();

    return 0;
}

static int
ble_hs_hci_evt_le_meta(uint8_t event_code, uint8_t *data, int len)
{
    const struct ble_hs_hci_evt_le_dispatch_entry *entry;
    uint8_t subevent;
    int rc;

    if (len < BLE_HCI_EVENT_HDR_LEN + BLE_HCI_LE_MIN_LEN) {
        return BLE_HS_ECONTROLLER;
    }

    subevent = data[2];
    entry = ble_hs_hci_evt_le_dispatch_find(subevent);
    if (entry != NULL) {
        rc = entry->cb(subevent, data + BLE_HCI_EVENT_HDR_LEN,
                           len - BLE_HCI_EVENT_HDR_LEN);
        if (rc != 0) {
            return rc;
        }
    }

    return 0;
}

#if MYNEWT_VAL(BLE_EXT_ADV)
static struct hci_le_conn_complete pend_conn_complete;
#endif

static int
ble_hs_hci_evt_le_conn_complete(uint8_t subevent, uint8_t *data, int len)
{
    struct hci_le_conn_complete evt;
    int extended_offset = 0;

    if (len < BLE_HCI_LE_CONN_COMPLETE_LEN) {
        return BLE_HS_ECONTROLLER;
    }

    /* this code processes two different events that are really similar */
    if ((subevent == BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE) &&
        ( len < BLE_HCI_LE_ENH_CONN_COMPLETE_LEN)) {
        return BLE_HS_ECONTROLLER;
    }

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

    evt.subevent_code = data[0];
    evt.status = data[1];

    if (evt.status == BLE_ERR_SUCCESS) {
        evt.connection_handle = get_le16(data + 2);
        evt.role = data[4];
        evt.peer_addr_type = data[5];
        memcpy(evt.peer_addr, data + 6, BLE_DEV_ADDR_LEN);

        /* enhanced connection event has the same information with these
         * extra fields stuffed into the middle */
        if (subevent == BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE) {
            memcpy(evt.local_rpa, data + 12, BLE_DEV_ADDR_LEN);
            memcpy(evt.peer_rpa, data + 18, BLE_DEV_ADDR_LEN);
            extended_offset = 12;
        } else {
            memset(evt.local_rpa, 0, BLE_DEV_ADDR_LEN);
            memset(evt.peer_rpa, 0, BLE_DEV_ADDR_LEN);
        }

        evt.conn_itvl = get_le16(data + 12 + extended_offset);
        evt.conn_latency = get_le16(data + 14 + extended_offset);
        evt.supervision_timeout = get_le16(data + 16 + extended_offset);
        evt.master_clk_acc = data[18 + extended_offset];
    } else {
#if MYNEWT_VAL(BLE_HS_DEBUG)
        evt.connection_handle = BLE_HS_CONN_HANDLE_NONE;
#endif
    }

#if MYNEWT_VAL(BLE_EXT_ADV)
    if (evt.status == BLE_ERR_DIR_ADV_TMO ||
                            evt.role == BLE_HCI_LE_CONN_COMPLETE_ROLE_SLAVE) {
    /* store this until we get set terminated event with adv handle */
        memcpy(&pend_conn_complete, &evt, sizeof(evt));
        return 0;
    }
#endif
    return ble_gap_rx_conn_complete(&evt, 0);
}

static int
ble_hs_hci_evt_le_adv_rpt_first_pass(uint8_t *data, int len)
{
    uint8_t num_reports;
    int off;
    int i;

    if (len < BLE_HCI_LE_ADV_RPT_MIN_LEN) {
        return BLE_HS_ECONTROLLER;
    }

    num_reports = data[1];
    if (num_reports < BLE_HCI_LE_ADV_RPT_NUM_RPTS_MIN ||
        num_reports > BLE_HCI_LE_ADV_RPT_NUM_RPTS_MAX) {
        return BLE_HS_EBADDATA;
    }

    off = 2; /* Subevent code and num reports. */
    for (i = 0; i < num_reports; i++) {
        /* Move past event type (1), address type (1) and address (6) */
        off += 8;

        /* Add advertising data length (N), length (1) and rssi (1) */
        off += data[off];
        off += 2;

        /* Make sure we are not past length */
        if (off > len) {
            return BLE_HS_ECONTROLLER;
        }
    }

    /* Make sure length was correct */
    if (off != len) {
        return BLE_HS_ECONTROLLER;
    }

    return 0;
}

static int
ble_hs_hci_evt_le_adv_rpt(uint8_t subevent, uint8_t *data, int len)
{
    struct ble_gap_disc_desc desc = {0};
    uint8_t num_reports;
    int off;
    int rc;
    int i;

    /* Validate the event is formatted correctly */
    rc = ble_hs_hci_evt_le_adv_rpt_first_pass(data, len);
    if (rc != 0) {
        return rc;
    }

    desc.direct_addr = *BLE_ADDR_ANY;

    off = 2; /* skip sub-event and num reports */
    num_reports = data[1];
    for (i = 0; i < num_reports; i++) {
        desc.event_type = data[off];
        ++off;

        desc.addr.type = data[off];
        ++off;

        memcpy(desc.addr.val, data + off, 6);
        off += 6;

        desc.length_data = data[off];
        ++off;

        desc.data = data + off;
        off += desc.length_data;

        desc.rssi = data[off];
        ++off;

        ble_gap_rx_adv_report(&desc);
    }

    return 0;
}

static int
ble_hs_hci_evt_le_dir_adv_rpt(uint8_t subevent, uint8_t *data, int len)
{
    struct ble_gap_disc_desc desc = {0};
    uint8_t num_reports;
    int suboff;
    int off;
    int i;

    if (len < BLE_HCI_LE_ADV_DIRECT_RPT_LEN) {
        return BLE_HS_ECONTROLLER;
    }

    num_reports = data[1];
    if (len != 2 + num_reports * BLE_HCI_LE_ADV_DIRECT_RPT_SUB_LEN) {
        return BLE_HS_ECONTROLLER;
    }

    /* Data fields not present in a direct advertising report. */
    desc.data = NULL;
    desc.length_data = 0;

    for (i = 0; i < num_reports; i++) {
        suboff = 0;

        off = 2 + suboff * num_reports + i;
        desc.event_type = data[off];
        suboff++;

        off = 2 + suboff * num_reports + i;
        desc.addr.type = data[off];
        suboff++;

        off = 2 + suboff * num_reports + i * 6;
        memcpy(desc.addr.val, data + off, 6);
        suboff += 6;

        off = 2 + suboff * num_reports + i;
        desc.direct_addr.type = data[off];
        suboff++;

        off = 2 + suboff * num_reports + i * 6;
        memcpy(desc.direct_addr.val, data + off, 6);
        suboff += 6;

        off = 2 + suboff * num_reports + i;
        desc.rssi = data[off];
        suboff++;

        ble_gap_rx_adv_report(&desc);
    }

    return 0;
}

static int
ble_hs_hci_evt_le_rd_rem_used_feat_complete(uint8_t subevent, uint8_t *data,
                                                                        int len)
{
    struct hci_le_rd_rem_supp_feat_complete evt;

    if (len < BLE_HCI_LE_RD_REM_USED_FEAT_LEN) {
        return BLE_HS_ECONTROLLER;
    }

    evt.subevent_code = data[0];
    evt.status = data[1];
    evt.connection_handle = get_le16(data + 2);
    memcpy(evt.features, data + 4, 8);

    ble_gap_rx_rd_rem_sup_feat_complete(&evt);

    return 0;
}

#if MYNEWT_VAL(BLE_EXT_ADV)
static int
ble_hs_hci_decode_legacy_type(uint16_t evt_type)
{
     switch (evt_type) {
     case BLE_HCI_LEGACY_ADV_EVTYPE_ADV_IND:
         return BLE_HCI_ADV_RPT_EVTYPE_ADV_IND;
     case BLE_HCI_LEGACY_ADV_EVTYPE_ADV_DIRECT_IND:
         return BLE_HCI_ADV_RPT_EVTYPE_DIR_IND;
     case BLE_HCI_LEGACY_ADV_EVTYPE_ADV_SCAN_IND:
         return BLE_HCI_ADV_RPT_EVTYPE_SCAN_IND;
     case BLE_HCI_LEGACY_ADV_EVTYPE_ADV_NONCON_IND:
         return BLE_HCI_ADV_RPT_EVTYPE_NONCONN_IND;
     case BLE_HCI_LEGACY_ADV_EVTYPE_SCAN_RSP_ADV_IND:
         return BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP;
     default:
         return -1;
     }
}
#endif

static int
ble_hs_hci_evt_le_ext_adv_rpt(uint8_t subevent, uint8_t *data, int len)
{
#if MYNEWT_VAL(BLE_EXT_ADV)
    struct ble_gap_ext_disc_desc desc;
    struct hci_ext_adv_report *ext_adv;
    struct hci_ext_adv_report_param *params;
    int num_reports;
    int i;
    int legacy_event_type;

    if (len < sizeof(*ext_adv)) {
        return BLE_HS_EBADDATA;
    }

    ext_adv = (struct hci_ext_adv_report *) data;
    num_reports = ext_adv->num_reports;
    if (num_reports < BLE_HCI_LE_ADV_RPT_NUM_RPTS_MIN ||
        num_reports > BLE_HCI_LE_ADV_RPT_NUM_RPTS_MAX) {

        return BLE_HS_EBADDATA;
    }

    if (len < (sizeof(*ext_adv) + ext_adv->num_reports * sizeof(*params))) {
        return BLE_HS_ECONTROLLER;
    }

    params = &ext_adv->params[0];
    for (i = 0; i < num_reports; i++) {
        memset(&desc, 0, sizeof(desc));

        desc.props = (params->evt_type) & 0x1F;
        if (desc.props & BLE_HCI_ADV_LEGACY_MASK) {
            legacy_event_type = ble_hs_hci_decode_legacy_type(params->evt_type);
            if (legacy_event_type < 0) {
                params += 1;
                continue;
            }
            desc.legacy_event_type = legacy_event_type;
            desc.data_status = BLE_GAP_EXT_ADV_DATA_STATUS_COMPLETE;
        } else {
            switch(params->evt_type & BLE_HCI_ADV_DATA_STATUS_MASK) {
            case BLE_HCI_ADV_DATA_STATUS_COMPLETE:
                desc.data_status = BLE_GAP_EXT_ADV_DATA_STATUS_COMPLETE;
                break;
            case BLE_HCI_ADV_DATA_STATUS_INCOMPLETE:
                desc.data_status = BLE_GAP_EXT_ADV_DATA_STATUS_INCOMPLETE;
                break;
            case BLE_HCI_ADV_DATA_STATUS_TRUNCATED:
                desc.data_status = BLE_GAP_EXT_ADV_DATA_STATUS_TRUNCATED;
                break;
            default:
                assert(false);
            }
        }
        desc.addr.type = params->addr_type;
        memcpy(desc.addr.val, params->addr, 6);
        desc.length_data = params->adv_data_len;
        desc.data = params->adv_data;
        desc.rssi = params->rssi;
        desc.tx_power = params->tx_power;
        memcpy(desc.direct_addr.val, params->dir_addr, 6);
        desc.direct_addr.type = params->dir_addr_type;
        desc.sid = params->sid;
        desc.prim_phy = params->prim_phy;
        desc.sec_phy = params->sec_phy;
        ble_gap_rx_ext_adv_report(&desc);
        params += 1;
    }
#endif
    return 0;
}

static int
ble_hs_hci_evt_le_scan_timeout(uint8_t subevent, uint8_t *data, int len)
{
#if MYNEWT_VAL(BLE_EXT_ADV) && NIMBLE_BLE_SCAN
        ble_gap_rx_le_scan_timeout();
#endif
        return 0;
}

static int
ble_hs_hci_evt_le_adv_set_terminated(uint8_t subevent, uint8_t *data, int len)
{
#if MYNEWT_VAL(BLE_EXT_ADV)
    struct hci_le_adv_set_terminated evt;

    if (len < BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED_LEN) {
        return BLE_HS_ECONTROLLER;
    }

    evt.subevent_code = data[0];
    evt.status = data[1];
    evt.adv_handle = data[2];
    evt.conn_handle = get_le16(data + 3);
    evt.completed_events = data[5];

    if (evt.status == 0) {
        /* ignore return code as we need to terminate advertising set anyway */
        ble_gap_rx_conn_complete(&pend_conn_complete, evt.adv_handle);
    }
    ble_gap_rx_adv_set_terminated(&evt);
#endif

    return 0;
}

static int
ble_hs_hci_evt_le_conn_upd_complete(uint8_t subevent, uint8_t *data, int len)
{
    struct hci_le_conn_upd_complete evt;

    if (len < BLE_HCI_LE_CONN_UPD_LEN) {
        return BLE_HS_ECONTROLLER;
    }

    evt.subevent_code = data[0];
    evt.status = data[1];
    evt.connection_handle = get_le16(data + 2);
    evt.conn_itvl = get_le16(data + 4);
    evt.conn_latency = get_le16(data + 6);
    evt.supervision_timeout = get_le16(data + 8);

    if (evt.status == 0) {
        if (evt.conn_itvl < BLE_HCI_CONN_ITVL_MIN ||
            evt.conn_itvl > BLE_HCI_CONN_ITVL_MAX) {

            return BLE_HS_EBADDATA;
        }
        if (evt.conn_latency < BLE_HCI_CONN_LATENCY_MIN ||
            evt.conn_latency > BLE_HCI_CONN_LATENCY_MAX) {

            return BLE_HS_EBADDATA;
        }
        if (evt.supervision_timeout < BLE_HCI_CONN_SPVN_TIMEOUT_MIN ||
            evt.supervision_timeout > BLE_HCI_CONN_SPVN_TIMEOUT_MAX) {

            return BLE_HS_EBADDATA;
        }
    }

    ble_gap_rx_update_complete(&evt);

    return 0;
}

static int
ble_hs_hci_evt_le_lt_key_req(uint8_t subevent, uint8_t *data, int len)
{
    struct hci_le_lt_key_req evt;

    if (len < BLE_HCI_LE_LT_KEY_REQ_LEN) {
        return BLE_HS_ECONTROLLER;
    }

    evt.subevent_code = data[0];
    evt.connection_handle = get_le16(data + 1);
    evt.random_number = get_le64(data + 3);
    evt.encrypted_diversifier = get_le16(data + 11);

    ble_sm_ltk_req_rx(&evt);

    return 0;
}

static int
ble_hs_hci_evt_le_conn_parm_req(uint8_t subevent, uint8_t *data, int len)
{
    struct hci_le_conn_param_req evt;

    if (len < BLE_HCI_LE_REM_CONN_PARM_REQ_LEN) {
        return BLE_HS_ECONTROLLER;
    }

    evt.subevent_code = data[0];
    evt.connection_handle = get_le16(data + 1);
    evt.itvl_min = get_le16(data + 3);
    evt.itvl_max = get_le16(data + 5);
    evt.latency = get_le16(data + 7);
    evt.timeout = get_le16(data + 9);

    if (evt.itvl_min < BLE_HCI_CONN_ITVL_MIN ||
        evt.itvl_max > BLE_HCI_CONN_ITVL_MAX ||
        evt.itvl_min > evt.itvl_max) {

        return BLE_HS_EBADDATA;
    }
    if (evt.latency < BLE_HCI_CONN_LATENCY_MIN ||
        evt.latency > BLE_HCI_CONN_LATENCY_MAX) {

        return BLE_HS_EBADDATA;
    }
    if (evt.timeout < BLE_HCI_CONN_SPVN_TIMEOUT_MIN ||
        evt.timeout > BLE_HCI_CONN_SPVN_TIMEOUT_MAX) {

        return BLE_HS_EBADDATA;
    }

    ble_gap_rx_param_req(&evt);

    return 0;
}

static int
ble_hs_hci_evt_le_phy_update_complete(uint8_t subevent, uint8_t *data, int len)
{
    struct hci_le_phy_upd_complete evt;

    if (len < BLE_HCI_LE_PHY_UPD_LEN) {
        return BLE_HS_ECONTROLLER;
    }

    evt.subevent_code = data[0];
    evt.status = data[1];
    evt.connection_handle = get_le16(data + 2);
    evt.tx_phy = data[4];
    evt.rx_phy = data[5];

    ble_gap_rx_phy_update_complete(&evt);

    return 0;
}

int
ble_hs_hci_evt_process(uint8_t *data)
{
    const struct ble_hs_hci_evt_dispatch_entry *entry;
    uint8_t event_code;
    uint8_t param_len;
    int event_len;
    int rc;

    /* Count events received */
    STATS_INC(ble_hs_stats, hci_event);

    /* Display to console */
    ble_hs_dbg_event_disp(data);

    /* Process the event */
    event_code = data[0];
    param_len = data[1];

    event_len = param_len + 2;

    entry = ble_hs_hci_evt_dispatch_find(event_code);
    if (entry == NULL) {
        STATS_INC(ble_hs_stats, hci_unknown_event);
        rc = BLE_HS_ENOTSUP;
    } else {
        rc = entry->cb(event_code, data, event_len);
    }

    ble_hci_trans_buf_free(data);

    return rc;
}

/**
 * Called when a data packet is received from the controller.  This function
 * consumes the supplied mbuf, regardless of the outcome.
 *
 * @param om                    The incoming data packet, beginning with the
 *                                  HCI ACL data header.
 *
 * @return                      0 on success; nonzero on failure.
 */
int
ble_hs_hci_evt_acl_process(struct os_mbuf *om)
{
    struct hci_data_hdr hci_hdr;
    struct ble_hs_conn *conn;
    ble_l2cap_rx_fn *rx_cb;
    uint16_t conn_handle;
    int reject_cid;
    int rc;

    rc = ble_hs_hci_util_data_hdr_strip(om, &hci_hdr);
    if (rc != 0) {
        goto err;
    }

#if (BLETEST_THROUGHPUT_TEST == 0)
#if !BLE_MONITOR
    BLE_HS_LOG(DEBUG, "ble_hs_hci_evt_acl_process(): conn_handle=%u pb=%x "
                      "len=%u data=",
               BLE_HCI_DATA_HANDLE(hci_hdr.hdh_handle_pb_bc),
               BLE_HCI_DATA_PB(hci_hdr.hdh_handle_pb_bc),
               hci_hdr.hdh_len);
    ble_hs_log_mbuf(om);
    BLE_HS_LOG(DEBUG, "\n");
#endif
#endif

    if (hci_hdr.hdh_len != OS_MBUF_PKTHDR(om)->omp_len) {
        rc = BLE_HS_EBADDATA;
        goto err;
    }

    conn_handle = BLE_HCI_DATA_HANDLE(hci_hdr.hdh_handle_pb_bc);

    ble_hs_lock();

    conn = ble_hs_conn_find(conn_handle);
    if (conn == NULL) {
        /* Peer not connected; quietly discard packet. */
        rc = BLE_HS_ENOTCONN;
        reject_cid = -1;
    } else {
        /* Forward ACL data to L2CAP. */
        rc = ble_l2cap_rx(conn, &hci_hdr, om, &rx_cb, &reject_cid);
        om = NULL;
    }

    ble_hs_unlock();

    switch (rc) {
    case 0:
        /* Final fragment received. */
        BLE_HS_DBG_ASSERT(rx_cb != NULL);
        rc = rx_cb(conn->bhc_rx_chan);
        ble_l2cap_remove_rx(conn, conn->bhc_rx_chan);
        break;

    case BLE_HS_EAGAIN:
        /* More fragments on the way. */
        break;

    default:
        if (reject_cid != -1) {
            ble_l2cap_sig_reject_invalid_cid_tx(conn_handle, 0, 0, reject_cid);
        }
        goto err;
    }

    return 0;

err:
    os_mbuf_free_chain(om);
    return rc;
}
