/*
 * 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 <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "syscfg/syscfg.h"
#include "nimble/ble.h"
#include "nimble/hci_common.h"
#include "controller/ble_ll.h"
#include "controller/ble_ll_hci.h"
#include "controller/ble_ll_ctrl.h"
#include "ble_ll_conn_priv.h"

#if (BLETEST_CONCURRENT_CONN_TEST == 1)
extern void bletest_ltk_req_reply(uint16_t handle);
#endif

/**
 * Send a data length change event for a connection to the host.
 *
 * @param connsm Pointer to connection state machine
 */
void
ble_ll_hci_ev_datalen_chg(struct ble_ll_conn_sm *connsm)
{
    struct ble_hci_ev_le_subev_data_len_chg *ev;
    struct ble_hci_ev *hci_ev;

    if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_DATA_LEN_CHG)) {
        hci_ev = ble_transport_alloc_evt(0);
        if (hci_ev) {
            hci_ev->opcode = BLE_HCI_EVCODE_LE_META;
            hci_ev->length = sizeof(*ev);
            ev = (void *) hci_ev->data;

            ev->subev_code = BLE_HCI_LE_SUBEV_DATA_LEN_CHG;
            ev->conn_handle = htole16(connsm->conn_handle);

            ev->max_tx_octets = htole16(connsm->eff_max_tx_octets);
            ev->max_tx_time = htole16(connsm->eff_max_tx_time);
            ev->max_rx_octets = htole16(connsm->eff_max_rx_octets);
            ev->max_rx_time = htole16(connsm->eff_max_rx_time);

            ble_ll_hci_event_send(hci_ev);
        }
    }
}

/**
 * Send a connection parameter request event for a connection to the host.
 *
 * @param connsm Pointer to connection state machine
 */
void
ble_ll_hci_ev_rem_conn_parm_req(struct ble_ll_conn_sm *connsm,
                                struct ble_ll_conn_params *cp)
{
    struct ble_hci_ev_le_subev_rem_conn_param_req *ev;
    struct ble_hci_ev *hci_ev;

    if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_REM_CONN_PARM_REQ)) {
        hci_ev = ble_transport_alloc_evt(0);
        if (hci_ev) {
            hci_ev->opcode = BLE_HCI_EVCODE_LE_META;
            hci_ev->length = sizeof(*ev);
            ev = (void *) hci_ev->data;

            ev->subev_code = BLE_HCI_LE_SUBEV_REM_CONN_PARM_REQ;
            ev->conn_handle = htole16(connsm->conn_handle);
            ev->min_interval = htole16(cp->interval_min);
            ev->max_interval = htole16(cp->interval_max);
            ev->latency = htole16(cp->latency);
            ev->timeout = htole16(cp->timeout);

            ble_ll_hci_event_send(hci_ev);
        }
    }
}

/**
 * Send a connection update event.
 *
 * @param connsm Pointer to connection state machine
 * @param status The error code.
 */
void
ble_ll_hci_ev_conn_update(struct ble_ll_conn_sm *connsm, uint8_t status)
{
    struct ble_hci_ev_le_subev_conn_upd_complete *ev;
    struct ble_hci_ev *hci_ev;

    if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_CONN_UPD_COMPLETE)) {
        hci_ev = ble_transport_alloc_evt(0);
        if (hci_ev) {
            hci_ev->opcode = BLE_HCI_EVCODE_LE_META;
            hci_ev->length = sizeof(*ev);
            ev = (void *) hci_ev->data;

            ev->subev_code = BLE_HCI_LE_SUBEV_CONN_UPD_COMPLETE;
            ev->status = status;
            ev->conn_handle = htole16(connsm->conn_handle);
            ev->conn_itvl = htole16(connsm->conn_itvl);
            ev->conn_latency = htole16(connsm->periph_latency);
            ev->supervision_timeout = htole16(connsm->supervision_tmo);

            ble_ll_hci_event_send(hci_ev);
        }
    }
}

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
void
ble_ll_hci_ev_encrypt_chg(struct ble_ll_conn_sm *connsm, uint8_t status)
{
    struct ble_hci_ev_enc_key_refresh *ev_key_refresh;
    struct ble_hci_ev_enrypt_chg *ev_enc_chf;
    struct ble_hci_ev *hci_ev;

    if (connsm->flags.encrypt_event_sent == 0) {
        if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_ENCRYPT_CHG)) {
            hci_ev = ble_transport_alloc_evt(0);
            if (hci_ev) {
                hci_ev->opcode = BLE_HCI_EVCODE_ENCRYPT_CHG;
                hci_ev->length = sizeof(*ev_enc_chf);
                ev_enc_chf = (void *) hci_ev->data;

                ev_enc_chf->status = status;
                ev_enc_chf->connection_handle = htole16(connsm->conn_handle);
                ev_enc_chf->enabled = (status == BLE_ERR_SUCCESS) ? 0x01 : 0x00;

                ble_ll_hci_event_send(hci_ev);
            }
        }

        connsm->flags.encrypt_event_sent = 1;
        return;
    }

    if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_ENC_KEY_REFRESH)) {
        hci_ev = ble_transport_alloc_evt(0);
        if (hci_ev) {
            hci_ev->opcode = BLE_HCI_EVCODE_ENC_KEY_REFRESH;
            hci_ev->length = sizeof(*ev_key_refresh);
            ev_key_refresh = (void *) hci_ev->data;

            ev_key_refresh->status = status;
            ev_key_refresh->conn_handle = htole16(connsm->conn_handle);

            ble_ll_hci_event_send(hci_ev);
        }
    }
}

/**
 * Send a long term key request event for a connection to the host.
 *
 * @param connsm Pointer to connection state machine
 */
int
ble_ll_hci_ev_ltk_req(struct ble_ll_conn_sm *connsm)
{
    struct ble_hci_ev_le_subev_lt_key_req *ev;
    struct ble_hci_ev *hci_ev;
    int rc;

    if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_LT_KEY_REQ)) {
        hci_ev = ble_transport_alloc_evt(0);
        if (hci_ev) {
            hci_ev->opcode = BLE_HCI_EVCODE_LE_META;
            hci_ev->length = sizeof(*ev);
            ev = (void *) hci_ev->data;

            ev->subev_code = BLE_HCI_LE_SUBEV_LT_KEY_REQ;
            ev->conn_handle = htole16(connsm->conn_handle);
            ev->rand = htole64(connsm->enc_data.host_rand_num);
            ev->div = htole16(connsm->enc_data.enc_div);

            ble_ll_hci_event_send(hci_ev);
        }
        rc = 0;
    } else {
        rc = -1;
    }

#if (BLETEST_CONCURRENT_CONN_TEST == 1)
    if (rc == 0) {
        bletest_ltk_req_reply(connsm->conn_handle);
    }
#endif
    return rc;
}
#endif

void
ble_ll_hci_ev_rd_rem_used_feat(struct ble_ll_conn_sm *connsm, uint8_t status)
{
    struct ble_hci_ev_le_subev_rd_rem_used_feat *ev;
    struct ble_hci_ev *hci_ev;

    if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_RD_REM_USED_FEAT)) {
        hci_ev = ble_transport_alloc_evt(0);
        if (hci_ev) {
            hci_ev->opcode = BLE_HCI_EVCODE_LE_META;
            hci_ev->length = sizeof(*ev);
            ev = (void *) hci_ev->data;

            ev->subev_code = BLE_HCI_LE_SUBEV_RD_REM_USED_FEAT;
            ev->status = status;
            ev->conn_handle = htole16(connsm->conn_handle);
            ev->features[0] = connsm->conn_features;
            memcpy(ev->features + 1, connsm->remote_features, 7);

            ble_ll_hci_event_send(hci_ev);
        }
    }
}

void
ble_ll_hci_ev_rd_rem_ver(struct ble_ll_conn_sm *connsm, uint8_t status)
{
    struct ble_hci_ev_rd_rem_ver_info_cmp *ev;
    struct ble_hci_ev *hci_ev;

    if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_RD_REM_VER_INFO_CMP)) {
        hci_ev = ble_transport_alloc_evt(0);
        if (hci_ev) {
            hci_ev->opcode = BLE_HCI_EVCODE_RD_REM_VER_INFO_CMP;
            hci_ev->length = sizeof(*ev);
            ev = (void *) hci_ev->data;

            ev->status = status;
            ev->conn_handle = htole16(connsm->conn_handle);
            ev->version = connsm->vers_nr;
            ev->manufacturer = htole16(connsm->comp_id);
            ev->subversion = htole16(connsm->sub_vers_nr);

            ble_ll_hci_event_send(hci_ev);
        }
    }
}

/**
 * Send a HW error to the host.
 *
 * @param hw_err
 *
 * @return int 0: event masked or event sent, -1 otherwise
 */
int
ble_ll_hci_ev_hw_err(uint8_t hw_err)
{
    struct ble_hci_ev_hw_error *ev;
    struct ble_hci_ev *hci_ev;
    int rc;

    rc = 0;
    if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_HW_ERROR)) {
        hci_ev = ble_transport_alloc_evt(0);
        if (hci_ev) {
            hci_ev->opcode = BLE_HCI_EVCODE_HW_ERROR;
            hci_ev->length = sizeof(*ev);
            ev = (void *) hci_ev->data;

            ev->hw_code = hw_err;

            ble_ll_hci_event_send(hci_ev);
        } else {
            rc = -1;
        }
    }
    return rc;
}

void
ble_ll_hci_ev_databuf_overflow(void)
{
    struct ble_hci_ev_data_buf_overflow *ev;
    struct ble_hci_ev *hci_ev;

    if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_DATA_BUF_OVERFLOW)) {
        hci_ev = ble_transport_alloc_evt(0);
        if (hci_ev) {
            hci_ev->opcode = BLE_HCI_EVCODE_DATA_BUF_OVERFLOW;
            hci_ev->length = sizeof(*ev);
            ev = (void *) hci_ev->data;

            ev->link_type = BLE_HCI_EVENT_ACL_BUF_OVERFLOW;

            ble_ll_hci_event_send(hci_ev);
        }
    }
}

/**
 * Send a LE Channel Selection Algorithm event.
 *
 * @param connsm Pointer to connection state machine
 */
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2)
void
ble_ll_hci_ev_le_csa(struct ble_ll_conn_sm *connsm)
{
    struct ble_hci_ev_le_subev_chan_sel_alg *ev;
    struct ble_hci_ev *hci_ev;

    if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_CHAN_SEL_ALG)) {
        hci_ev = ble_transport_alloc_evt(0);
        if (hci_ev) {
            hci_ev->opcode = BLE_HCI_EVCODE_LE_META;
            hci_ev->length = sizeof(*ev);
            ev = (void *) hci_ev->data;

            ev->subev_code = BLE_HCI_LE_SUBEV_CHAN_SEL_ALG;
            ev->conn_handle = htole16(connsm->conn_handle);
            ev->csa = connsm->flags.csa2 ? 0x01 : 0x00;

            ble_ll_hci_event_send(hci_ev);
        }
    }
}
#endif

/**
 * Sends the LE Scan Request Received event
 *
 */
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
void
ble_ll_hci_ev_send_scan_req_recv(uint8_t adv_handle, const uint8_t *peer,
                                 uint8_t peer_addr_type)
{
    struct ble_hci_ev_le_subev_scan_req_rcvd *ev;
    struct ble_hci_ev *hci_ev;

    if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_SCAN_REQ_RCVD)) {
        hci_ev = ble_transport_alloc_evt(0);
        if (hci_ev) {
            hci_ev->opcode = BLE_HCI_EVCODE_LE_META;
            hci_ev->length = sizeof(*ev);
            ev = (void *) hci_ev->data;

            ev->subev_code = BLE_HCI_LE_SUBEV_SCAN_REQ_RCVD;
            ev->adv_handle = adv_handle;
            ev->peer_addr_type = peer_addr_type;
            memcpy(ev->peer_addr, peer, BLE_DEV_ADDR_LEN);

            ble_ll_hci_event_send(hci_ev);
        }
    }
}
#endif

/**
 * Sends the  LE Scan Timeout Event
 *
 */
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
void
ble_ll_hci_ev_send_scan_timeout(void)
{
    struct ble_hci_ev_le_subev_scan_timeout *ev;
    struct ble_hci_ev *hci_ev;

    if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_SCAN_TIMEOUT)) {
        hci_ev = ble_transport_alloc_evt(0);
        if (hci_ev) {
            hci_ev->opcode = BLE_HCI_EVCODE_LE_META;
            hci_ev->length = sizeof(*ev);
            ev = (void *) hci_ev->data;

            ev->subev_code = BLE_HCI_LE_SUBEV_SCAN_TIMEOUT;

            ble_ll_hci_event_send(hci_ev);
        }
    }
}
#endif

/**
 * Sends the LE Advertising Set Terminated event
 *
 */
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
void
ble_ll_hci_ev_send_adv_set_terminated(uint8_t status, uint8_t adv_handle,
                                      uint16_t conn_handle, uint8_t events)
{
    struct ble_hci_ev_le_subev_adv_set_terminated *ev;
    struct ble_hci_ev *hci_ev;

    if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED)) {
        hci_ev = ble_transport_alloc_evt(0);
        if (hci_ev) {
            hci_ev->opcode = BLE_HCI_EVCODE_LE_META;
            hci_ev->length = sizeof(*ev);
            ev = (void *) hci_ev->data;

            ev->subev_code = BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED;
            ev->status = status;
            ev->adv_handle = adv_handle;
            ev->conn_handle = htole16(conn_handle);
            ev->num_events = events;

            ble_ll_hci_event_send(hci_ev);
        }
    }
}
#endif

/**
 * Send a PHY update complete event
 *
 * @param connsm Pointer to connection state machine
 * @param status error status of event
 */
#if MYNEWT_VAL(BLE_LL_PHY)
int
ble_ll_hci_ev_phy_update(struct ble_ll_conn_sm *connsm, uint8_t status)
{
    struct ble_hci_ev_le_subev_phy_update_complete *ev;
    struct ble_hci_ev *hci_ev;
    int rc;

    rc = 0;
    if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_PHY_UPDATE_COMPLETE)) {
        hci_ev = ble_transport_alloc_evt(0);
        if (hci_ev) {
            hci_ev->opcode = BLE_HCI_EVCODE_LE_META;
            hci_ev->length = sizeof(*ev);
            ev = (void *) hci_ev->data;

            ev->subev_code = BLE_HCI_LE_SUBEV_PHY_UPDATE_COMPLETE;
            ev->status = status;
            ev->conn_handle = htole16(connsm->conn_handle);
            ev->tx_phy = connsm->phy_data.cur_tx_phy;
            ev->rx_phy = connsm->phy_data.cur_rx_phy;

            ble_ll_hci_event_send(hci_ev);
        } else {
            rc = BLE_ERR_MEM_CAPACITY;
        }
    }
    return rc;
}
#endif

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE)
void
ble_ll_hci_ev_sca_update(struct ble_ll_conn_sm *connsm, uint8_t status,
                         uint8_t peer_sca)
{
    struct ble_hci_ev_le_subev_peer_sca_complete *ev;
    struct ble_hci_ev *hci_ev;

    if (!ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_REQ_PEER_SCA_COMP)) {
        return;
    }

    hci_ev = ble_transport_alloc_evt(0);
    if (!hci_ev) {
        return;
    }

    hci_ev->opcode = BLE_HCI_EVCODE_LE_META;
    hci_ev->length = sizeof(*ev);
    ev = (void *) hci_ev->data;

    ev->subev_code = BLE_HCI_LE_SUBEV_REQ_PEER_SCA_COMP;
    ev->status = status;
    ev->conn_handle = htole16(connsm->conn_handle);
    ev->sca = peer_sca;

    ble_ll_hci_event_send(hci_ev);
}

#endif

#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE)
void
ble_ll_hci_ev_subrate_change(struct ble_ll_conn_sm *connsm, uint8_t status)
{
    struct ble_hci_ev_le_subev_subrate_change *ev;
    struct ble_hci_ev *hci_ev;

    if (!ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_SUBRATE_CHANGE)) {
        return;
    }

    hci_ev = ble_transport_alloc_evt(0);
    if (!hci_ev) {
        return;
    }

    hci_ev->opcode = BLE_HCI_EVCODE_LE_META;
    hci_ev->length = sizeof(*ev);
    ev = (void *)hci_ev->data;

    ev->subev_code = BLE_HCI_LE_SUBEV_SUBRATE_CHANGE;
    ev->status = status;
    ev->conn_handle = htole16(connsm->conn_handle);
    ev->subrate_factor = htole16(connsm->subrate_factor);
    ev->periph_latency = htole16(connsm->periph_latency);
    ev->cont_num = htole16(connsm->cont_num);
    ev->supervision_tmo = htole16(connsm->supervision_tmo);

    ble_ll_hci_event_send(hci_ev);
}
#endif

#if MYNEWT_VAL(BLE_LL_HCI_VS_CONN_STRICT_SCHED)
void
ble_ll_hci_ev_send_vs_css_slot_changed(uint16_t conn_handle, uint16_t slot_idx)
{
    struct ble_hci_ev_vs_css_slot_changed *ev;
    struct ble_hci_ev_vs *ev_vs;
    struct ble_hci_ev *hci_ev;

    hci_ev = ble_transport_alloc_evt(0);
    if (!hci_ev) {
        return;

    }

    hci_ev->opcode = BLE_HCI_EVCODE_VS;
    hci_ev->length = sizeof(*ev_vs) + sizeof(*ev);
    ev_vs = (void *)hci_ev->data;
    ev_vs->id = BLE_HCI_VS_SUBEV_ID_CSS_SLOT_CHANGED;
    ev = (void *)ev_vs->data;
    ev->conn_handle = htole16(conn_handle);
    ev->slot_idx = htole16(slot_idx);

    ble_ll_hci_event_send(hci_ev);
}
#endif

void
ble_ll_hci_ev_send_vs_assert(const char *file, uint32_t line)
{
    struct ble_hci_ev_vs *ev;
    struct ble_hci_ev *hci_ev;
    unsigned int str_len;
    bool skip = true;
    uint8_t digit;
    int max_len;
    int i;

    /* 6 is for line number ":00000" , we assume files have no more than 64k of
     * lines
     */
    max_len = BLE_HCI_MAX_DATA_LEN - sizeof(*ev) - 6;

    hci_ev = ble_transport_alloc_evt(0);
    if (hci_ev) {
        hci_ev->opcode = BLE_HCI_EVCODE_VS;
        hci_ev->length = sizeof(*ev);
        ev = (void *) hci_ev->data;

        /* Debug id for future use */
        ev->id = BLE_HCI_VS_SUBEV_ID_ASSERT;

        /* snprintf would be nicer but this is heavy on flash
         * len = snprintf((char *) ev->data, max_len, "%s:%u", file, line);
         * if (len < 0) {
         *     len = 0;
         * } else if (len > max_len) {
         *     len = max_len;
         * }
         *
         *  hci_ev->length += len;
         */
        str_len = strlen(file);
        if (str_len > (unsigned int)max_len) {
            str_len = max_len;
        }

        memcpy(ev->data, file, str_len);
        ev->data[str_len++] = ':';

        for (i = 100000; i >= 10; i /= 10) {
            digit = (line % i) / (i/10);

            if (!digit && skip) {
                continue;
            }

            skip = false;
            ev->data[str_len++] = '0' + digit;
        }

        hci_ev->length += str_len;

        ble_ll_hci_event_send(hci_ev);
    }
}

void
ble_ll_hci_ev_send_vs_printf(uint8_t id, const char *fmt, ...)
{
    struct ble_hci_ev_vs *ev;
    struct ble_hci_ev *hci_ev;
    va_list ap;

    hci_ev = ble_transport_alloc_evt(1);
    if (!hci_ev) {
        return;
    }

    hci_ev->opcode = BLE_HCI_EVCODE_VS;
    hci_ev->length = sizeof(*ev);

    ev = (void *) hci_ev->data;
    ev->id = id;

    va_start(ap, fmt);
    hci_ev->length += vsnprintf((void *)ev->data,
                                BLE_HCI_MAX_DATA_LEN - sizeof(*ev), fmt, ap);
    va_end(ap);

    ble_ll_hci_event_send(hci_ev);
}

#if MYNEWT_VAL(BLE_LL_HCI_LLCP_TRACE)
void
ble_ll_hci_ev_send_vs_llcp_trace(uint8_t type, uint16_t handle, uint16_t count,
                                 void *pdu, size_t length)
{
    struct ble_hci_ev_vs *ev;
    struct ble_hci_ev *hci_ev;

    hci_ev = ble_transport_alloc_evt(1);
    if (hci_ev) {
        hci_ev->opcode = BLE_HCI_EVCODE_VS;
        hci_ev->length = sizeof(*ev) + 8 + length;
        ev = (void *) hci_ev->data;

        ev->id = BLE_HCI_VS_SUBEV_ID_LLCP_TRACE;
        ev->data[0] = type;
        put_le16(&ev->data[1], handle);
        put_le16(&ev->data[3], count);
        ev->data[5] = 0;
        ev->data[6] = 0;
        ev->data[7] = 0;
        memcpy(&ev->data[8], pdu, length);

        ble_ll_hci_event_send(hci_ev);
    }
}
#endif
