/*
 * 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 <assert.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_monitor.h"
#include "ble_hs_dbg_priv.h"
#include "ble_hs_priv.h"
#include "ble_monitor_priv.h"

static int
ble_hs_hci_cmd_transport(uint8_t *cmdbuf)
{
    int rc;

#if BLE_MONITOR
    ble_monitor_send(BLE_MONITOR_OPCODE_COMMAND_PKT, cmdbuf,
                     cmdbuf[2] + BLE_HCI_CMD_HDR_LEN);
#endif

    rc = ble_hci_trans_hs_cmd_tx(cmdbuf);
    switch (rc) {
    case 0:
        return 0;

    case BLE_ERR_MEM_CAPACITY:
        return BLE_HS_ENOMEM_EVT;

    default:
        return BLE_HS_EUNKNOWN;
    }
}

void
ble_hs_hci_cmd_write_hdr(uint8_t ogf, uint16_t ocf, uint8_t len, void *buf)
{
    uint16_t opcode;
    uint8_t *u8ptr;

    u8ptr = buf;

    opcode = (ogf << 10) | ocf;
    put_le16(u8ptr, opcode);
    u8ptr[2] = len;
}

static int
ble_hs_hci_cmd_send(uint16_t opcode, uint8_t len, const void *cmddata)
{
    uint8_t *buf;
    int rc;

    buf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD);
    BLE_HS_DBG_ASSERT(buf != NULL);

    put_le16(buf, opcode);
    buf[2] = len;
    if (len != 0) {
        memcpy(buf + BLE_HCI_CMD_HDR_LEN, cmddata, len);
    }

#if !BLE_MONITOR
    BLE_HS_LOG(DEBUG, "ble_hs_hci_cmd_send: ogf=0x%02x ocf=0x%04x len=%d\n",
               BLE_HCI_OGF(opcode), BLE_HCI_OCF(opcode), len);
    ble_hs_log_flat_buf(buf, len + BLE_HCI_CMD_HDR_LEN);
    BLE_HS_LOG(DEBUG, "\n");
#endif

    rc = ble_hs_hci_cmd_transport(buf);

    if (rc == 0) {
        STATS_INC(ble_hs_stats, hci_cmd);
    } else {
        BLE_HS_LOG(DEBUG, "ble_hs_hci_cmd_send failure; rc=%d\n", rc);
    }

    return rc;
}

int
ble_hs_hci_cmd_send_buf(uint16_t opcode, void *buf, uint8_t buf_len)
{
    switch (ble_hs_sync_state) {
    case BLE_HS_SYNC_STATE_BAD:
        return BLE_HS_ENOTSYNCED;

    case BLE_HS_SYNC_STATE_BRINGUP:
        if (!ble_hs_is_parent_task()) {
            return BLE_HS_ENOTSYNCED;
        }
        break;

    case BLE_HS_SYNC_STATE_GOOD:
        break;

    default:
        BLE_HS_DBG_ASSERT(0);
        return BLE_HS_EUNKNOWN;
    }

    return ble_hs_hci_cmd_send(opcode, buf_len, buf);
}


/**
 * Send a LE command from the host to the controller.
 *
 * @param ocf
 * @param len
 * @param cmddata
 *
 * @return int
 */
static int
ble_hs_hci_cmd_le_send(uint16_t ocf, uint8_t len, void *cmddata)
{
    return ble_hs_hci_cmd_send(BLE_HCI_OP(BLE_HCI_OGF_LE, ocf), len, cmddata);
}

static int
ble_hs_hci_cmd_body_le_whitelist_chg(const uint8_t *addr, uint8_t addr_type,
                                     uint8_t *dst)
{
    if (addr_type > BLE_ADDR_RANDOM) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    dst[0] = addr_type;
    memcpy(dst + 1, addr, BLE_DEV_ADDR_LEN);

    return 0;
}

static int
ble_hs_hci_cmd_body_le_set_adv_params(const struct hci_adv_params *adv,
                                      uint8_t *dst)
{
    uint16_t itvl;

    BLE_HS_DBG_ASSERT(adv != NULL);

    /* Make sure parameters are valid */
    if ((adv->adv_itvl_min > adv->adv_itvl_max) ||
        (adv->own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) ||
        (adv->peer_addr_type > BLE_HCI_ADV_PEER_ADDR_MAX) ||
        (adv->adv_filter_policy > BLE_HCI_ADV_FILT_MAX) ||
        (adv->adv_type > BLE_HCI_ADV_TYPE_MAX) ||
        (adv->adv_channel_map == 0) ||
        ((adv->adv_channel_map & 0xF8) != 0)) {
        /* These parameters are not valid */
        return -1;
    }

/* When build with nimBLE controller we know it is BT5 compliant so no need
 * to limit non-connectable advertising interval
 */
#if MYNEWT_VAL(BLE_CONTROLLER)
    itvl = BLE_HCI_ADV_ITVL_MIN;
#else
    /* Make sure interval is valid for advertising type. */
    if (((adv->adv_type == BLE_HCI_ADV_TYPE_ADV_NONCONN_IND) ||
        (adv->adv_type == BLE_HCI_ADV_TYPE_ADV_SCAN_IND)) &&
        ble_hs_hci_get_hci_version() < BLE_HCI_VER_BCS_5_0) {
        itvl = BLE_HCI_ADV_ITVL_NONCONN_MIN;
    } else {
        itvl = BLE_HCI_ADV_ITVL_MIN;
    }
#endif

    /* Do not check if high duty-cycle directed */
    if (adv->adv_type != BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) {
        if ((adv->adv_itvl_min < itvl) ||
            (adv->adv_itvl_min > BLE_HCI_ADV_ITVL_MAX)) {
            return -1;
        }
    }

    put_le16(dst, adv->adv_itvl_min);
    put_le16(dst + 2, adv->adv_itvl_max);
    dst[4] = adv->adv_type;
    dst[5] = adv->own_addr_type;
    dst[6] = adv->peer_addr_type;
    memcpy(dst + 7, adv->peer_addr, BLE_DEV_ADDR_LEN);
    dst[13] = adv->adv_channel_map;
    dst[14] = adv->adv_filter_policy;

    return 0;
}

int
ble_hs_hci_cmd_build_le_set_adv_params(const struct hci_adv_params *adv,
                                       uint8_t *dst, int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_ADV_PARAM_LEN);

    return ble_hs_hci_cmd_body_le_set_adv_params(adv, dst);
}

/**
 * Set advertising data
 *
 * OGF = 0x08 (LE)
 * OCF = 0x0008
 *
 * @param data
 * @param len
 * @param dst
 *
 * @return int
 */
static int
ble_hs_hci_cmd_body_le_set_adv_data(const uint8_t *data, uint8_t len,
                                    uint8_t *dst)
{
    /* Check for valid parameters */
    if (((data == NULL) && (len != 0)) || (len > BLE_HCI_MAX_ADV_DATA_LEN)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    memset(dst, 0, BLE_HCI_SET_ADV_DATA_LEN);
    dst[0] = len;
    memcpy(dst + 1, data, len);

    return 0;
}

/**
 * Set advertising data
 *
 * OGF = 0x08 (LE)
 * OCF = 0x0008
 *
 * @param data
 * @param len
 * @param dst
 *
 * @return int
 */
int
ble_hs_hci_cmd_build_le_set_adv_data(const uint8_t *data, uint8_t len,
                                     uint8_t *dst, int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_ADV_DATA_LEN);

    return ble_hs_hci_cmd_body_le_set_adv_data(data, len, dst);
}

static int
ble_hs_hci_cmd_body_le_set_scan_rsp_data(const uint8_t *data, uint8_t len,
                                         uint8_t *dst)
{
    /* Check for valid parameters */
    if (((data == NULL) && (len != 0)) ||
         (len > BLE_HCI_MAX_SCAN_RSP_DATA_LEN)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    memset(dst, 0, BLE_HCI_SET_SCAN_RSP_DATA_LEN);
    dst[0] = len;
    memcpy(dst + 1, data, len);

    return 0;
}

int
ble_hs_hci_cmd_build_le_set_scan_rsp_data(const uint8_t *data, uint8_t len,
                                          uint8_t *dst, int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_SCAN_RSP_DATA_LEN);

    return ble_hs_hci_cmd_body_le_set_scan_rsp_data(data, len, dst);
}

static void
ble_hs_hci_cmd_body_set_event_mask(uint64_t event_mask, uint8_t *dst)
{
    put_le64(dst, event_mask);
}

void
ble_hs_hci_cmd_build_set_event_mask(uint64_t event_mask,
                                    uint8_t *dst, int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_EVENT_MASK_LEN);

    ble_hs_hci_cmd_body_set_event_mask(event_mask, dst);
}

void
ble_hs_hci_cmd_build_set_event_mask2(uint64_t event_mask,
                                     uint8_t *dst, int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_EVENT_MASK_LEN);

    ble_hs_hci_cmd_body_set_event_mask(event_mask, dst);
}

static void
ble_hs_hci_cmd_body_disconnect(uint16_t handle, uint8_t reason, uint8_t *dst)
{
    put_le16(dst + 0, handle);
    dst[2] = reason;
}

void
ble_hs_hci_cmd_build_disconnect(uint16_t handle, uint8_t reason,
                                uint8_t *dst, int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_DISCONNECT_CMD_LEN);

    ble_hs_hci_cmd_body_disconnect(handle, reason, dst);
}

static void
ble_hs_hci_cmd_body_le_set_event_mask(uint64_t event_mask, uint8_t *dst)
{
    put_le64(dst, event_mask);
}

void
ble_hs_hci_cmd_build_le_set_event_mask(uint64_t event_mask,
                                       uint8_t *dst, int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_LE_EVENT_MASK_LEN);

    ble_hs_hci_cmd_body_le_set_event_mask(event_mask, dst);
}

static void
ble_hs_hci_cmd_body_le_set_adv_enable(uint8_t enable, uint8_t *dst)
{
    dst[0] = enable;
}

void
ble_hs_hci_cmd_build_le_set_adv_enable(uint8_t enable, uint8_t *dst,
                                       int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_ADV_ENABLE_LEN);

    ble_hs_hci_cmd_body_le_set_adv_enable(enable, dst);
}

static int
ble_hs_hci_cmd_body_le_set_scan_params(
    uint8_t scan_type, uint16_t scan_itvl, uint16_t scan_window,
    uint8_t own_addr_type, uint8_t filter_policy, uint8_t *dst) {

    /* Make sure parameters are valid */
    if ((scan_type != BLE_HCI_SCAN_TYPE_PASSIVE) &&
        (scan_type != BLE_HCI_SCAN_TYPE_ACTIVE)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* Check interval and window */
    if ((scan_itvl < BLE_HCI_SCAN_ITVL_MIN) ||
        (scan_itvl > BLE_HCI_SCAN_ITVL_MAX) ||
        (scan_window < BLE_HCI_SCAN_WINDOW_MIN) ||
        (scan_window > BLE_HCI_SCAN_WINDOW_MAX) ||
        (scan_itvl < scan_window)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* Check own addr type */
    if (own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* Check scanner filter policy */
    if (filter_policy > BLE_HCI_SCAN_FILT_MAX) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    dst[0] = scan_type;
    put_le16(dst + 1, scan_itvl);
    put_le16(dst + 3, scan_window);
    dst[5] = own_addr_type;
    dst[6] = filter_policy;

    return 0;
}

int
ble_hs_hci_cmd_build_le_set_scan_params(uint8_t scan_type,
                                        uint16_t scan_itvl,
                                        uint16_t scan_window,
                                        uint8_t own_addr_type,
                                        uint8_t filter_policy,
                                        uint8_t *dst, int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_SCAN_PARAM_LEN);

    return ble_hs_hci_cmd_body_le_set_scan_params(scan_type, scan_itvl,
                                              scan_window, own_addr_type,
                                              filter_policy, dst);
}

static void
ble_hs_hci_cmd_body_le_set_scan_enable(uint8_t enable, uint8_t filter_dups,
                                       uint8_t *dst)
{
    dst[0] = enable;
    dst[1] = filter_dups;
}

void
ble_hs_hci_cmd_build_le_set_scan_enable(uint8_t enable, uint8_t filter_dups,
                                        uint8_t *dst, uint8_t dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_SCAN_ENABLE_LEN);

    ble_hs_hci_cmd_body_le_set_scan_enable(enable, filter_dups, dst);
}

static int
ble_hs_hci_cmd_body_le_create_connection(const struct hci_create_conn *hcc,
                                         uint8_t *cmd)
{
    /* Check scan interval and scan window */
    if ((hcc->scan_itvl < BLE_HCI_SCAN_ITVL_MIN) ||
        (hcc->scan_itvl > BLE_HCI_SCAN_ITVL_MAX) ||
        (hcc->scan_window < BLE_HCI_SCAN_WINDOW_MIN) ||
        (hcc->scan_window > BLE_HCI_SCAN_WINDOW_MAX) ||
        (hcc->scan_itvl < hcc->scan_window)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* Check initiator filter policy */
    if (hcc->filter_policy > BLE_HCI_CONN_FILT_MAX) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* Check peer addr type */
    if (hcc->peer_addr_type > BLE_HCI_CONN_PEER_ADDR_MAX) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* Check own addr type */
    if (hcc->own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* Check connection interval min */
    if ((hcc->conn_itvl_min < BLE_HCI_CONN_ITVL_MIN) ||
        (hcc->conn_itvl_min > BLE_HCI_CONN_ITVL_MAX)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* Check connection interval max */
    if ((hcc->conn_itvl_max < BLE_HCI_CONN_ITVL_MIN) ||
        (hcc->conn_itvl_max > BLE_HCI_CONN_ITVL_MAX) ||
        (hcc->conn_itvl_max < hcc->conn_itvl_min)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* Check connection latency */
    if ((hcc->conn_latency < BLE_HCI_CONN_LATENCY_MIN) ||
        (hcc->conn_latency > BLE_HCI_CONN_LATENCY_MAX)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* Check supervision timeout */
    if ((hcc->supervision_timeout < BLE_HCI_CONN_SPVN_TIMEOUT_MIN) ||
        (hcc->supervision_timeout > BLE_HCI_CONN_SPVN_TIMEOUT_MAX)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* Check connection event length */
    if (hcc->min_ce_len > hcc->max_ce_len) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    put_le16(cmd + 0, hcc->scan_itvl);
    put_le16(cmd + 2, hcc->scan_window);
    cmd[4] = hcc->filter_policy;
    cmd[5] = hcc->peer_addr_type;
    memcpy(cmd + 6, hcc->peer_addr, BLE_DEV_ADDR_LEN);
    cmd[12] = hcc->own_addr_type;
    put_le16(cmd + 13, hcc->conn_itvl_min);
    put_le16(cmd + 15, hcc->conn_itvl_max);
    put_le16(cmd + 17, hcc->conn_latency);
    put_le16(cmd + 19, hcc->supervision_timeout);
    put_le16(cmd + 21, hcc->min_ce_len);
    put_le16(cmd + 23, hcc->max_ce_len);

    return 0;
}

int
ble_hs_hci_cmd_build_le_create_connection(const struct hci_create_conn *hcc,
                                          uint8_t *cmd, int cmd_len)
{
    BLE_HS_DBG_ASSERT(cmd_len >= BLE_HCI_CREATE_CONN_LEN);

    return ble_hs_hci_cmd_body_le_create_connection(hcc, cmd);
}

int
ble_hs_hci_cmd_build_le_add_to_whitelist(const uint8_t *addr,
                                         uint8_t addr_type,
                                         uint8_t *dst, int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_ADD_WHITE_LIST_LEN);

    return ble_hs_hci_cmd_body_le_whitelist_chg(addr, addr_type, dst);
}

/**
 * Reset the controller and link manager.
 *
 * @return int
 */
int
ble_hs_hci_cmd_reset(void)
{
    return ble_hs_hci_cmd_send(BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND,
                                          BLE_HCI_OCF_CB_RESET),
                               0, NULL);
}

/** Set controller to host flow control (OGF 0x03, OCF 0x0031). */
int
ble_hs_hci_cmd_tx_set_ctlr_to_host_fc(uint8_t fc_enable)
{
    if (fc_enable > BLE_HCI_CTLR_TO_HOST_FC_BOTH) {
        return BLE_HS_EINVAL;
    }

    return ble_hs_hci_cmd_tx_empty_ack(
        BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND,
                   BLE_HCI_OCF_CB_SET_CTLR_TO_HOST_FC),
        &fc_enable, 1);
}

/* Host buffer size (OGF 0x03, OCF 0x0033). */
int
ble_hs_hci_cmd_tx_host_buf_size(const struct hci_host_buf_size *cmd)
{
    uint8_t buf[BLE_HCI_HOST_BUF_SIZE_LEN];

    put_le16(buf + 0, cmd->acl_pkt_len);
    buf[2] = cmd->sync_pkt_len;
    put_le16(buf + 3, cmd->num_acl_pkts);
    put_le16(buf + 5, cmd->num_sync_pkts);

    return ble_hs_hci_cmd_tx_empty_ack(
        BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, BLE_HCI_OCF_CB_HOST_BUF_SIZE),
        buf, sizeof buf);
}

/* Host number of completed packets (OGF 0x03, OCF 0x0035). */
int
ble_hs_hci_cmd_build_host_num_comp_pkts_entry(
    const struct hci_host_num_comp_pkts_entry *entry,
    uint8_t *dst, int dst_len)
{
    if (dst_len < BLE_HCI_HOST_NUM_COMP_PKTS_ENT_LEN) {
        return BLE_HS_EMSGSIZE;
    }

    put_le16(dst + 0, entry->conn_handle);
    put_le16(dst + 2, entry->num_pkts);

    return 0;
}

/**
 * Read the transmit power level used for LE advertising channel packets.
 *
 * @return int
 */
int
ble_hs_hci_cmd_read_adv_pwr(void)
{
    return ble_hs_hci_cmd_send(BLE_HCI_OP(BLE_HCI_OGF_LE,
                                          BLE_HCI_OCF_LE_RD_ADV_CHAN_TXPWR),
                               0, NULL);
}

int
ble_hs_hci_cmd_le_create_conn_cancel(void)
{
    return ble_hs_hci_cmd_send(BLE_HCI_OP(BLE_HCI_OGF_LE,
                                          BLE_HCI_OCF_LE_CREATE_CONN_CANCEL),
                               0, NULL);
}

static int
ble_hs_hci_cmd_body_le_conn_update(const struct hci_conn_update *hcu,
                                   uint8_t *dst)
{
    /* XXX: add parameter checking later */
    put_le16(dst + 0, hcu->handle);
    put_le16(dst + 2, hcu->conn_itvl_min);
    put_le16(dst + 4, hcu->conn_itvl_max);
    put_le16(dst + 6, hcu->conn_latency);
    put_le16(dst + 8, hcu->supervision_timeout);
    put_le16(dst + 10, hcu->min_ce_len);
    put_le16(dst + 12, hcu->max_ce_len);

    return 0;
}

int
ble_hs_hci_cmd_build_le_conn_update(const struct hci_conn_update *hcu,
                                    uint8_t *dst, int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_CONN_UPDATE_LEN);

    return ble_hs_hci_cmd_body_le_conn_update(hcu, dst);
}

int
ble_hs_hci_cmd_le_conn_update(const struct hci_conn_update *hcu)
{
    uint8_t cmd[BLE_HCI_CONN_UPDATE_LEN];
    int rc;

    rc = ble_hs_hci_cmd_body_le_conn_update(hcu, cmd);
    if (rc != 0) {
        return rc;
    }

    return ble_hs_hci_cmd_le_send(BLE_HCI_OCF_LE_CONN_UPDATE,
                              BLE_HCI_CONN_UPDATE_LEN, cmd);
}

static void
ble_hs_hci_cmd_body_le_lt_key_req_reply(const struct hci_lt_key_req_reply *hkr,
                                        uint8_t *dst)
{
    put_le16(dst + 0, hkr->conn_handle);
    memcpy(dst + 2, hkr->long_term_key, sizeof hkr->long_term_key);
}

/**
 * Sends the long-term key (LTK) to the controller.
 *
 * Note: This function expects the 128-bit key to be in little-endian byte
 * order.
 *
 * OGF = 0x08 (LE)
 * OCF = 0x001a
 *
 * @param key
 * @param pt
 *
 * @return int
 */
void
ble_hs_hci_cmd_build_le_lt_key_req_reply(
    const struct hci_lt_key_req_reply *hkr, uint8_t *dst, int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_LT_KEY_REQ_REPLY_LEN);

    ble_hs_hci_cmd_body_le_lt_key_req_reply(hkr, dst);
}

void
ble_hs_hci_cmd_build_le_lt_key_req_neg_reply(uint16_t conn_handle,
                                             uint8_t *dst, int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_LT_KEY_REQ_NEG_REPLY_LEN);

    put_le16(dst, conn_handle);
}

static void
ble_hs_hci_cmd_body_le_conn_param_reply(const struct hci_conn_param_reply *hcr,
                                        uint8_t *dst)
{
    put_le16(dst + 0, hcr->handle);
    put_le16(dst + 2, hcr->conn_itvl_min);
    put_le16(dst + 4, hcr->conn_itvl_max);
    put_le16(dst + 6, hcr->conn_latency);
    put_le16(dst + 8, hcr->supervision_timeout);
    put_le16(dst + 10, hcr->min_ce_len);
    put_le16(dst + 12, hcr->max_ce_len);
}

void
ble_hs_hci_cmd_build_le_conn_param_reply(
    const struct hci_conn_param_reply *hcr, uint8_t *dst, int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_CONN_PARAM_REPLY_LEN);

    ble_hs_hci_cmd_body_le_conn_param_reply(hcr, dst);
}

int
ble_hs_hci_cmd_le_conn_param_reply(const struct hci_conn_param_reply *hcr)
{
    uint8_t cmd[BLE_HCI_CONN_PARAM_REPLY_LEN];

    put_le16(cmd + 0, hcr->handle);
    put_le16(cmd + 2, hcr->conn_itvl_min);
    put_le16(cmd + 4, hcr->conn_itvl_max);
    put_le16(cmd + 6, hcr->conn_latency);
    put_le16(cmd + 8, hcr->supervision_timeout);
    put_le16(cmd + 10, hcr->min_ce_len);
    put_le16(cmd + 12, hcr->max_ce_len);

    return ble_hs_hci_cmd_le_send(BLE_HCI_OCF_LE_REM_CONN_PARAM_RR,
                              BLE_HCI_CONN_PARAM_REPLY_LEN, cmd);
}

static void
ble_hs_hci_cmd_body_le_conn_param_neg_reply(
    const struct hci_conn_param_neg_reply *hcn, uint8_t *dst)
{
    put_le16(dst + 0, hcn->handle);
    dst[2] = hcn->reason;
}


void
ble_hs_hci_cmd_build_le_conn_param_neg_reply(
    const struct hci_conn_param_neg_reply *hcn, uint8_t *dst, int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_CONN_PARAM_NEG_REPLY_LEN);

    ble_hs_hci_cmd_body_le_conn_param_neg_reply(hcn, dst);
}

int
ble_hs_hci_cmd_le_conn_param_neg_reply(
    const struct hci_conn_param_neg_reply *hcn)
{
    uint8_t cmd[BLE_HCI_CONN_PARAM_NEG_REPLY_LEN];

    ble_hs_hci_cmd_body_le_conn_param_neg_reply(hcn, cmd);

    return ble_hs_hci_cmd_le_send(BLE_HCI_OCF_LE_REM_CONN_PARAM_NRR,
                              BLE_HCI_CONN_PARAM_NEG_REPLY_LEN, cmd);
}

static void
ble_hs_hci_cmd_body_le_start_encrypt(const struct hci_start_encrypt *cmd,
                                     uint8_t *dst)
{
    put_le16(dst + 0, cmd->connection_handle);
    put_le64(dst + 2, cmd->random_number);
    put_le16(dst + 10, cmd->encrypted_diversifier);
    memcpy(dst + 12, cmd->long_term_key, sizeof cmd->long_term_key);
}

/*
 * OGF=0x08 OCF=0x0019
 */
void
ble_hs_hci_cmd_build_le_start_encrypt(const struct hci_start_encrypt *cmd,
                                      uint8_t *dst, int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_LE_START_ENCRYPT_LEN);

    ble_hs_hci_cmd_body_le_start_encrypt(cmd, dst);
}

/**
 * Read the RSSI for a given connection handle
 *
 * NOTE: OGF=0x05 OCF=0x0005
 *
 * @param handle
 *
 * @return int
 */
static void
ble_hs_hci_cmd_body_read_rssi(uint16_t handle, uint8_t *dst)
{
    put_le16(dst, handle);
}

void
ble_hs_hci_cmd_build_read_rssi(uint16_t handle, uint8_t *dst, int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_READ_RSSI_LEN);

    ble_hs_hci_cmd_body_read_rssi(handle, dst);
}

/**
 * LE Set Host Channel Classification
 *
 * OGF = 0x08 (LE)
 * OCF = 0x0014
 */
void
ble_hs_hci_cmd_build_le_set_host_chan_class(const uint8_t *chan_map,
                                            uint8_t *dst, int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_HOST_CHAN_CLASS_LEN);

    memcpy(dst, chan_map, BLE_HCI_SET_HOST_CHAN_CLASS_LEN);
}

/**
 * LE Read Channel Map
 *
 * OGF = 0x08 (LE)
 * OCF = 0x0015
 */
void
ble_hs_hci_cmd_build_le_read_chan_map(uint16_t conn_handle,
                                      uint8_t *dst, int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_RD_CHANMAP_LEN);

    put_le16(dst + 0, conn_handle);
}

static int
ble_hs_hci_cmd_body_set_data_len(uint16_t connection_handle,
                                 uint16_t tx_octets,
                                 uint16_t tx_time, uint8_t *dst)
{

    if (tx_octets < BLE_HCI_SET_DATALEN_TX_OCTETS_MIN ||
        tx_octets > BLE_HCI_SET_DATALEN_TX_OCTETS_MAX) {

        return BLE_HS_EINVAL;
    }

    if (tx_time < BLE_HCI_SET_DATALEN_TX_TIME_MIN ||
        tx_time > BLE_HCI_SET_DATALEN_TX_TIME_MAX) {

        return BLE_HS_EINVAL;
    }

    put_le16(dst + 0, connection_handle);
    put_le16(dst + 2, tx_octets);
    put_le16(dst + 4, tx_time);

    return 0;
}

/*
 * OGF=0x08 OCF=0x0022
 */
int
ble_hs_hci_cmd_build_set_data_len(uint16_t connection_handle,
                                  uint16_t tx_octets, uint16_t tx_time,
                                  uint8_t *dst, int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_DATALEN_LEN);

    return ble_hs_hci_cmd_body_set_data_len(connection_handle, tx_octets,
                                          tx_time, dst);
}

/**
 * IRKs are in little endian.
 */
static int
ble_hs_hci_cmd_body_add_to_resolv_list(uint8_t addr_type, const uint8_t *addr,
                                       const uint8_t *peer_irk,
                                       const uint8_t *local_irk,
                                       uint8_t *dst)
{
    if (addr_type > BLE_ADDR_RANDOM) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    dst[0] = addr_type;
    memcpy(dst + 1, addr, BLE_DEV_ADDR_LEN);
    memcpy(dst + 1 + 6, peer_irk , 16);
    memcpy(dst + 1 + 6 + 16, local_irk , 16);
    /* 16 + 16 + 6 + 1 == 39 */
    return 0;
}

/**
 * OGF=0x08 OCF=0x0027
 *
 * IRKs are in little endian.
 */
int
ble_hs_hci_cmd_build_add_to_resolv_list(
    const struct hci_add_dev_to_resolving_list *padd,
    uint8_t *dst,
    int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_ADD_TO_RESOLV_LIST_LEN);

    return ble_hs_hci_cmd_body_add_to_resolv_list(
            padd->addr_type, padd->addr, padd->peer_irk, padd->local_irk, dst);
}

static int
ble_hs_hci_cmd_body_remove_from_resolv_list(uint8_t addr_type,
                                            const uint8_t *addr,
                                            uint8_t *dst)
{
    if (addr_type > BLE_ADDR_RANDOM) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    dst[0] = addr_type;
    memcpy(dst + 1, addr, BLE_DEV_ADDR_LEN);
    return 0;
}


int
ble_hs_hci_cmd_build_remove_from_resolv_list(uint8_t addr_type,
                                             const uint8_t *addr,
                                             uint8_t *dst, int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_RMV_FROM_RESOLV_LIST_LEN);

    return ble_hs_hci_cmd_body_remove_from_resolv_list(addr_type, addr, dst);
}

static int
ble_hs_hci_cmd_body_read_peer_resolv_addr(uint8_t peer_identity_addr_type,
                                          const uint8_t *peer_identity_addr,
                                          uint8_t *dst)
{
    if (peer_identity_addr_type > BLE_ADDR_RANDOM) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    dst[0] = peer_identity_addr_type;
    memcpy(dst + 1, peer_identity_addr, BLE_DEV_ADDR_LEN);
    return 0;
}

int
ble_hs_hci_cmd_build_read_peer_resolv_addr(uint8_t peer_identity_addr_type,
                                           const uint8_t *peer_identity_addr,
                                           uint8_t *dst,
                                           int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_RD_PEER_RESOLV_ADDR_LEN);

    return ble_hs_hci_cmd_body_read_peer_resolv_addr(peer_identity_addr_type,
                                                   peer_identity_addr, dst);
}

static int
ble_hs_hci_cmd_body_read_lcl_resolv_addr(
    uint8_t local_identity_addr_type,
    const uint8_t *local_identity_addr,
    uint8_t *dst)
{
    if (local_identity_addr_type > BLE_ADDR_RANDOM) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    dst[0] = local_identity_addr_type;
    memcpy(dst + 1, local_identity_addr, BLE_DEV_ADDR_LEN);
    return 0;
}

/*
 * OGF=0x08 OCF=0x002c
 */
int
ble_hs_hci_cmd_build_read_lcl_resolv_addr(uint8_t local_identity_addr_type,
                                          const uint8_t *local_identity_addr,
                                          uint8_t *dst,
                                          int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_RD_LOC_RESOLV_ADDR_LEN);

    return ble_hs_hci_cmd_body_read_lcl_resolv_addr(local_identity_addr_type,
                                                  local_identity_addr, dst);
}

static int
ble_hs_hci_cmd_body_set_addr_res_en(uint8_t enable, uint8_t *dst)
{
    if (enable > 1) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    dst[0] = enable;
    return 0;
}

/*
 * OGF=0x08 OCF=0x002d
 */
int
ble_hs_hci_cmd_build_set_addr_res_en(uint8_t enable, uint8_t *dst, int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_ADDR_RESOL_ENA_LEN);

    return ble_hs_hci_cmd_body_set_addr_res_en(enable, dst);
}

static int
ble_hs_hci_cmd_body_set_resolv_priv_addr_timeout(uint16_t timeout,
                                                 uint8_t *dst)
{
    if (timeout == 0 || timeout > 0xA1B8) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    put_le16(dst, timeout);
    return 0;
}

/*
 * OGF=0x08 OCF=0x002e
 */
int
ble_hs_hci_cmd_build_set_resolv_priv_addr_timeout(
    uint16_t timeout, uint8_t *dst, int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_RESOLV_PRIV_ADDR_TO_LEN);

    return ble_hs_hci_cmd_body_set_resolv_priv_addr_timeout(timeout, dst);
}

/*
 * OGF=0x08 OCF=0x0030
 */
int
ble_hs_hci_cmd_build_le_read_phy(uint16_t conn_handle, uint8_t *dst, int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_LE_RD_PHY_LEN);

    put_le16(dst, conn_handle);

    return 0;
}

static int
ble_hs_hci_verify_le_phy_params(uint8_t tx_phys_mask, uint8_t rx_phys_mask,
                                uint16_t phy_opts)
{
    if (tx_phys_mask > (BLE_HCI_LE_PHY_1M_PREF_MASK |
                        BLE_HCI_LE_PHY_2M_PREF_MASK |
                        BLE_HCI_LE_PHY_CODED_PREF_MASK)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    if (rx_phys_mask > (BLE_HCI_LE_PHY_1M_PREF_MASK |
                        BLE_HCI_LE_PHY_2M_PREF_MASK |
                        BLE_HCI_LE_PHY_CODED_PREF_MASK)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    if (phy_opts > BLE_HCI_LE_PHY_CODED_S8_PREF) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    return 0;
}

static int
ble_hs_hci_cmd_body_le_set_default_phy(uint8_t tx_phys_mask,
                                       uint8_t rx_phys_mask, uint8_t *dst)
{
    int rc;

    rc = ble_hs_hci_verify_le_phy_params(tx_phys_mask, rx_phys_mask, 0);
    if (rc !=0 ) {
        return rc;
    }

    if (tx_phys_mask == 0) {
        dst[0] |= BLE_HCI_LE_PHY_NO_TX_PREF_MASK;
    } else {
        dst[1] = tx_phys_mask;
    }

    if (rx_phys_mask == 0){
        dst[0] |= BLE_HCI_LE_PHY_NO_RX_PREF_MASK;
    } else {
        dst[2] = rx_phys_mask;
    }

    return 0;
}

/*
 * OGF=0x08 OCF=0x0031
 */
int
ble_hs_hci_cmd_build_le_set_default_phy(uint8_t tx_phys_mask, uint8_t rx_phys_mask,
                                        uint8_t *dst, int dst_len)
{

    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_LE_SET_DEFAULT_PHY_LEN);

    memset(dst, 0, dst_len);

    return ble_hs_hci_cmd_body_le_set_default_phy(tx_phys_mask, rx_phys_mask,
                                                  dst);
}

static int
ble_hs_hci_cmd_body_le_set_phy(uint16_t conn_handle, uint8_t tx_phys_mask,
                               uint8_t rx_phys_mask, uint16_t phy_opts,
                               uint8_t *dst)
{
    int rc;

    rc = ble_hs_hci_verify_le_phy_params(tx_phys_mask, rx_phys_mask, phy_opts);
    if (rc != 0) {
        return rc;
    }

    put_le16(dst, conn_handle);

    if (tx_phys_mask == 0) {
        dst[2] |= BLE_HCI_LE_PHY_NO_TX_PREF_MASK;
    } else {
        dst[3] = tx_phys_mask;
    }

    if (rx_phys_mask == 0){
        dst[2] |= BLE_HCI_LE_PHY_NO_RX_PREF_MASK;
    } else {
        dst[4] = rx_phys_mask;
    }

    put_le16(dst + 5, phy_opts);

    return 0;
}

/*
 * OGF=0x08 OCF=0x0032
 */
int
ble_hs_hci_cmd_build_le_set_phy(uint16_t conn_handle, uint8_t tx_phys_mask,
                                uint8_t rx_phys_mask, uint16_t phy_opts,
                                uint8_t *dst, int dst_len)
{

    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_LE_SET_PHY_LEN);

    memset(dst, 0, dst_len);

    return ble_hs_hci_cmd_body_le_set_phy(conn_handle, tx_phys_mask,
                                          rx_phys_mask, phy_opts, dst);
}

static int
ble_hs_hci_cmd_body_le_enhanced_recv_test(uint8_t chan, uint8_t phy,
                                          uint8_t mod_idx, uint8_t *dst)
{
    /* Parameters check according to Bluetooth 5.0 Vol 2, Part E
     * 7.8.50 LE Enhanced Receiver Test Command
     */
    if (phy > BLE_HCI_LE_PHY_CODED || chan > 0x27 || mod_idx > 1) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    dst[0] = chan;
    dst[1] = phy;
    dst[2] = mod_idx;

    return 0;
}

/*
 * OGF=0x08 OCF=0x0033
 */
int
ble_hs_hci_cmd_build_le_enh_recv_test(uint8_t rx_chan, uint8_t phy,
                                      uint8_t mod_idx,
                                      uint8_t *dst, uint16_t dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_LE_ENH_RX_TEST_LEN);

    return ble_hs_hci_cmd_body_le_enhanced_recv_test(rx_chan, phy, mod_idx, dst);
}

static int
ble_hs_hci_cmd_body_le_enhanced_trans_test(uint8_t chan, uint8_t test_data_len,
                                           uint8_t packet_payload_idx,
                                           uint8_t phy,
                                           uint8_t *dst)
{
    /* Parameters check according to Bluetooth 5.0 Vol 2, Part E
     * 7.8.51 LE Enhanced Transmitter Test Command
     */
    if (phy > BLE_HCI_LE_PHY_CODED_S2 || chan > 0x27 ||
            packet_payload_idx > 0x07) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    dst[0] = chan;
    dst[1] = test_data_len;
    dst[2] = packet_payload_idx;
    dst[3] = phy;

    return 0;
}

/*
 * OGF=0x08 OCF=0x0034
 */
int
ble_hs_hci_cmd_build_le_enh_trans_test(uint8_t tx_chan, uint8_t test_data_len,
                                       uint8_t packet_payload_idx, uint8_t phy,
                                       uint8_t *dst, uint16_t dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_LE_ENH_TX_TEST_LEN);

    return ble_hs_hci_cmd_body_le_enhanced_trans_test(tx_chan, test_data_len,
                                                      packet_payload_idx,
                                                      phy, dst);
}

#if MYNEWT_VAL(BLE_EXT_ADV)
static int
ble_hs_hci_check_scan_params(uint16_t scan_itvl, uint16_t scan_window)
{
    /* Check interval and window */
    if ((scan_itvl < BLE_HCI_SCAN_ITVL_MIN) ||
        (scan_itvl > BLE_HCI_SCAN_ITVL_MAX) ||
        (scan_window < BLE_HCI_SCAN_WINDOW_MIN) ||
        (scan_window > BLE_HCI_SCAN_WINDOW_MAX) ||
        (scan_itvl < scan_window)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    return 0;
}

static int
ble_hs_hci_cmd_body_le_set_ext_scan_param(uint8_t own_addr_type,
                                          uint8_t filter_policy,
                                          uint8_t phy_mask,
                                          uint8_t phy_count,
                                          struct ble_hs_hci_ext_scan_param *params[],
                                          uint8_t *dst)
{
    int i;
    int rc;
    uint8_t *dst_params;
    struct ble_hs_hci_ext_scan_param *p;

    if (phy_mask >
            (BLE_HCI_LE_PHY_1M_PREF_MASK | BLE_HCI_LE_PHY_CODED_PREF_MASK)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* Check own addr type */
    if (own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* Check scanner filter policy */
    if (filter_policy > BLE_HCI_SCAN_FILT_MAX) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    dst[0] = own_addr_type;
    dst[1] = filter_policy;
    dst[2] = phy_mask;
    dst_params = &dst[3];

    for (i = 0; i < phy_count; i++) {
        p = (*params) + i;
        rc = ble_hs_hci_check_scan_params(p->scan_itvl, p->scan_window);
        if (rc) {
            return rc;
        }

        dst_params[0] = p->scan_type;
        put_le16(dst_params + 1, p->scan_itvl);
        put_le16(dst_params + 3, p->scan_window);

        dst_params += BLE_HCI_LE_EXT_SCAN_SINGLE_PARAM_LEN;
    }

    return 0;
}

/*
 *  OGF=0x08 OCF=0x0041
 */
int
ble_hs_hci_cmd_build_le_set_ext_scan_params(uint8_t own_addr_type,
                                            uint8_t filter_policy,
                                            uint8_t phy_mask,
                                            uint8_t phy_count,
                                            struct ble_hs_hci_ext_scan_param *params[],
                                            uint8_t *dst, uint16_t dst_len)
{
    if (phy_count == 0) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_LE_EXT_SCAN_BASE_LEN +
                              BLE_HCI_LE_EXT_SCAN_SINGLE_PARAM_LEN * phy_count);

    return ble_hs_hci_cmd_body_le_set_ext_scan_param(own_addr_type,
                                                     filter_policy,
                                                     phy_mask,
                                                     phy_count,
                                                     params,
                                                     dst);
}

static int
ble_hs_hci_cmd_body_le_set_ext_scan_enable(uint8_t enable, uint8_t filter_dups,
                                           uint16_t duration, uint16_t period,
                                           uint8_t *dst)
{
    if (enable > 0x01 || filter_dups > 0x03) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    dst[0] = enable;
    dst[1] = filter_dups;
    put_le16(dst + 2, duration);
    put_le16(dst + 4, period);

    return 0;
}

/*
 *  OGF=0x08 OCF=0x0042
 */
int
ble_hs_hci_cmd_build_le_set_ext_scan_enable(uint8_t enable,
                                            uint8_t filter_dups,
                                            uint16_t duration,
                                            uint16_t period,
                                            uint8_t *dst, uint16_t dst_len)
{

    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_LE_SET_EXT_SCAN_ENABLE_LEN);

    return ble_hs_hci_cmd_body_le_set_ext_scan_enable(enable, filter_dups,
                                                      duration, period, dst);
}

static int
ble_hs_hci_check_conn_params(uint8_t phy,
                             const struct hci_ext_conn_params *params)
{
    if (phy != BLE_HCI_LE_PHY_2M) {
        if (ble_hs_hci_check_scan_params(params->scan_itvl, params->scan_window)) {
            return BLE_ERR_INV_HCI_CMD_PARMS;
        }
    }
        /* Check connection interval min */
    if ((params->conn_itvl_min < BLE_HCI_CONN_ITVL_MIN) ||
        (params->conn_itvl_min > BLE_HCI_CONN_ITVL_MAX)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }
    /* Check connection interval max */
    if ((params->conn_itvl_max < BLE_HCI_CONN_ITVL_MIN) ||
        (params->conn_itvl_max > BLE_HCI_CONN_ITVL_MAX) ||
        (params->conn_itvl_max < params->conn_itvl_min)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* Check connection latency */
    if ((params->conn_latency < BLE_HCI_CONN_LATENCY_MIN) ||
        (params->conn_latency > BLE_HCI_CONN_LATENCY_MAX)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* Check supervision timeout */
    if ((params->supervision_timeout < BLE_HCI_CONN_SPVN_TIMEOUT_MIN) ||
        (params->supervision_timeout > BLE_HCI_CONN_SPVN_TIMEOUT_MAX)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    /* Check connection event length */
    if (params->min_ce_len > params->max_ce_len) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    return 0;
}

static int
ble_hs_hci_cmd_body_le_ext_create_conn(const struct hci_ext_create_conn *hcc,
                                       uint8_t *cmd)
{
    int iter = 0;
    const struct hci_ext_conn_params *params;

    /* Check initiator filter policy */
    if (hcc->filter_policy > BLE_HCI_CONN_FILT_MAX) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }
    cmd[iter] = hcc->filter_policy;
    iter++;
    /* Check own addr type */
    if (hcc->own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }
    cmd[iter] = hcc->own_addr_type;
    iter++;

    /* Check peer addr type */
    if (hcc->peer_addr_type > BLE_HCI_CONN_PEER_ADDR_MAX) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }
    cmd[iter] = hcc->peer_addr_type;
    iter++;

    memcpy(cmd + iter, hcc->peer_addr, BLE_DEV_ADDR_LEN);
    iter += BLE_DEV_ADDR_LEN;

    if (hcc->init_phy_mask > (BLE_HCI_LE_PHY_1M_PREF_MASK |
                                BLE_HCI_LE_PHY_2M_PREF_MASK |
                                BLE_HCI_LE_PHY_CODED_PREF_MASK)) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }
    cmd[iter] = hcc->init_phy_mask;
    iter++;

    if (hcc->init_phy_mask & BLE_HCI_LE_PHY_1M_PREF_MASK) {
        params = &hcc->params[0];
        if (ble_hs_hci_check_conn_params(BLE_HCI_LE_PHY_1M, params)) {
            return BLE_ERR_INV_HCI_CMD_PARMS;
        }
        put_le16(cmd + iter, params->scan_itvl);
        put_le16(cmd + iter + 2, params->scan_window);
        put_le16(cmd + iter + 4, params->conn_itvl_min);
        put_le16(cmd + iter + 6, params->conn_itvl_max);
        put_le16(cmd + iter + 8, params->conn_latency);
        put_le16(cmd + iter + 10, params->supervision_timeout);
        put_le16(cmd + iter + 12, params->min_ce_len);
        put_le16(cmd + iter + 14, params->max_ce_len);
        iter += 16;
    }

    if (hcc->init_phy_mask & BLE_HCI_LE_PHY_2M_PREF_MASK) {
        params = &hcc->params[1];
        if (ble_hs_hci_check_conn_params(BLE_HCI_LE_PHY_2M, params)) {
            return BLE_ERR_INV_HCI_CMD_PARMS;
        }
        put_le16(cmd + iter, 0);
        put_le16(cmd + iter + 2, 0);
        put_le16(cmd + iter + 4, params->conn_itvl_min);
        put_le16(cmd + iter + 6, params->conn_itvl_max);
        put_le16(cmd + iter + 8, params->conn_latency);
        put_le16(cmd + iter + 10, params->supervision_timeout);
        put_le16(cmd + iter + 12, params->min_ce_len);
        put_le16(cmd + iter + 14, params->max_ce_len);
        iter += 16;
    }

    if (hcc->init_phy_mask & BLE_HCI_LE_PHY_CODED_PREF_MASK) {
        params = &hcc->params[2];
        if (ble_hs_hci_check_conn_params(BLE_HCI_LE_PHY_CODED, params)) {
            return BLE_ERR_INV_HCI_CMD_PARMS;
        }
        put_le16(cmd + iter, params->scan_itvl);
        put_le16(cmd + iter + 2, params->scan_window);
        put_le16(cmd + iter + 4, params->conn_itvl_min);
        put_le16(cmd + iter + 6, params->conn_itvl_max);
        put_le16(cmd + iter + 8, params->conn_latency);
        put_le16(cmd + iter + 10, params->supervision_timeout);
        put_le16(cmd + iter + 12, params->min_ce_len);
        put_le16(cmd + iter + 14, params->max_ce_len);
        iter += 16;
    }

    return 0;
}

int
ble_hs_hci_cmd_build_le_ext_create_conn(const struct hci_ext_create_conn *hcc,
                                        uint8_t *cmd, int cmd_len)
{
    uint8_t size;

    size = BLE_HCI_LE_EXT_CREATE_CONN_BASE_LEN;
    if (hcc->init_phy_mask & BLE_HCI_LE_PHY_1M_PREF_MASK) {
        size += sizeof(struct hci_ext_conn_params);
    }

    if (hcc->init_phy_mask & BLE_HCI_LE_PHY_2M_PREF_MASK) {
        size += sizeof(struct hci_ext_conn_params);
    }

    if (hcc->init_phy_mask & BLE_HCI_LE_PHY_CODED_PREF_MASK) {
        size += sizeof(struct hci_ext_conn_params);
    }

    BLE_HS_DBG_ASSERT(cmd_len >= size);

    return ble_hs_hci_cmd_body_le_ext_create_conn(hcc, cmd);
}

int
ble_hs_hci_cmd_build_le_ext_adv_set_random_addr(uint8_t handle,
                                                const uint8_t *addr,
                                                uint8_t *cmd, int cmd_len)
{
    BLE_HS_DBG_ASSERT(cmd_len >= BLE_HCI_LE_SET_ADV_SET_RND_ADDR_LEN);

    cmd[0] = handle;
    memcpy(cmd + 1, addr, BLE_DEV_ADDR_LEN);

    return 0;
}

int
ble_hs_hci_cmd_build_le_ext_adv_data(uint8_t handle, uint8_t operation,
                                     uint8_t frag_pref, struct os_mbuf *data,
                                     uint8_t data_len,
                                     uint8_t *cmd, int cmd_len)
{
    BLE_HS_DBG_ASSERT(cmd_len >= 4 + data_len);

    cmd[0] = handle;
    cmd[1] = operation;
    cmd[2] = frag_pref;
    cmd[3] = data_len;
    os_mbuf_copydata(data, 0, data_len, cmd + 4);

    return 0;
}

int
ble_hs_hci_cmd_build_le_ext_adv_enable(uint8_t enable, uint8_t sets_num,
                                       const struct hci_ext_adv_set *sets,
                                       uint8_t *cmd, int cmd_len)
{
    int i;

    BLE_HS_DBG_ASSERT(cmd_len >= 2 + (sets_num * 4));

    cmd[0] = enable;
    cmd[1] = sets_num;

    cmd += 2;

    for (i = 0; i < sets_num; i++) {
        cmd[0] = sets[i].handle;
        put_le16(&cmd[1], sets[i].duration);
        cmd[3] = sets[i].events;

        cmd += 4;
    }

    return 0;
}

int
ble_hs_hci_cmd_build_le_ext_adv_params(uint8_t handle,
                                       const struct hci_ext_adv_params *params,
                                       uint8_t *cmd, int cmd_len)
{
    uint32_t tmp;

    BLE_HS_DBG_ASSERT(cmd_len >= BLE_HCI_LE_SET_EXT_ADV_PARAM_LEN);

    cmd[0] = handle;
    put_le16(&cmd[1], params->properties);

    tmp = htole32(params->min_interval);
    memcpy(&cmd[3], &tmp, 3);

    tmp = htole32(params->max_interval);
    memcpy(&cmd[6], &tmp, 3);

    cmd[9] = params->chan_map;
    cmd[10] = params->own_addr_type;
    cmd[11] = params->peer_addr_type;
    memcpy(&cmd[12], params->peer_addr, BLE_DEV_ADDR_LEN);
    cmd[18] = params->filter_policy;
    cmd[19] = params->tx_power;
    cmd[20] = params->primary_phy;
    cmd[21] = params->max_skip;
    cmd[22] = params->secondary_phy;
    cmd[23] = params->sid;
    cmd[24] = params->scan_req_notif;

    return 0;
}
int
ble_hs_hci_cmd_build_le_ext_adv_remove(uint8_t handle,
                                       uint8_t *cmd, int cmd_len)
{
    BLE_HS_DBG_ASSERT(cmd_len >= BLE_HCI_LE_REMOVE_ADV_SET_LEN);

    cmd[0] = handle;

    return 0;
}
#endif

static int
ble_hs_hci_cmd_body_le_set_priv_mode(const uint8_t *addr, uint8_t addr_type,
                                     uint8_t priv_mode, uint8_t *dst)
{
    /* In this command addr type can be either:
     *  - public identity (0x00)
     *  - random (static) identity (0x01)
     */
    if (addr_type > BLE_ADDR_RANDOM) {
        return BLE_ERR_INV_HCI_CMD_PARMS;
    }

    dst[0] = addr_type;
    memcpy(dst + 1, addr, BLE_DEV_ADDR_LEN);
    dst[7] = priv_mode;

    return 0;
}

/*
 *  OGF=0x08 OCF=0x004e
 */
int
ble_hs_hci_cmd_build_le_set_priv_mode(const uint8_t *addr, uint8_t addr_type,
                                      uint8_t priv_mode, uint8_t *dst,
                                      uint16_t dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_LE_SET_PRIVACY_MODE_LEN);

    return ble_hs_hci_cmd_body_le_set_priv_mode(addr, addr_type, priv_mode, dst);
}

static int
ble_hs_hci_cmd_body_set_random_addr(const struct hci_rand_addr *paddr,
                                    uint8_t *dst)
{
    memcpy(dst, paddr->addr, BLE_DEV_ADDR_LEN);
    return 0;
}

int
ble_hs_hci_cmd_build_set_random_addr(const uint8_t *addr,
                                     uint8_t *dst, int dst_len)
{
    struct hci_rand_addr r_addr;

    memcpy(r_addr.addr, addr, sizeof(r_addr.addr));

    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_SET_RAND_ADDR_LEN);

    return ble_hs_hci_cmd_body_set_random_addr(&r_addr, dst);
}

static void
ble_hs_hci_cmd_body_le_read_remote_feat(uint16_t handle, uint8_t *dst)
{
    put_le16(dst, handle);
}

int
ble_hs_hci_cmd_build_le_read_remote_feat(uint16_t handle, uint8_t *dst,
                                                                 int dst_len)
{
    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_CONN_RD_REM_FEAT_LEN);

    ble_hs_hci_cmd_body_le_read_remote_feat(handle, dst);

    return 0;
}
