/*
 * 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 <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include "os/os_mempool.h"
#include "nimble/ble.h"
#include "host/ble_uuid.h"
#include "ble_hs_priv.h"

/*****************************************************************************
 * $error response                                                           *
 *****************************************************************************/

int
ble_att_clt_rx_error(uint16_t conn_handle, struct os_mbuf **rxom)
{
    struct ble_att_error_rsp *rsp;
    int rc;

    rc = ble_hs_mbuf_pullup_base(rxom, sizeof(*rsp));
    if (rc != 0) {
        return rc;
    }

    rsp = (struct ble_att_error_rsp *)(*rxom)->om_data;

    BLE_ATT_LOG_CMD(0, "error rsp", conn_handle, ble_att_error_rsp_log, rsp);

    ble_gattc_rx_err(conn_handle, le16toh(rsp->baep_handle),
                     le16toh(rsp->baep_error_code));

    return 0;
}

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

int
ble_att_clt_tx_mtu(uint16_t conn_handle, uint16_t mtu)
{
    struct ble_att_mtu_cmd *req;
    struct ble_l2cap_chan *chan;
    struct ble_hs_conn *conn;
    struct os_mbuf *txom;
    int rc;

    if (mtu < BLE_ATT_MTU_DFLT) {
        return BLE_HS_EINVAL;
    }

    ble_hs_lock();

    rc = ble_att_conn_chan_find(conn_handle, &conn, &chan);
    if (rc != 0) {
        rc = BLE_HS_ENOTCONN;
    } else if (chan->flags & BLE_L2CAP_CHAN_F_TXED_MTU) {
        rc = BLE_HS_EALREADY;
    } else {
        rc = 0;
    }
    ble_hs_unlock();

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

    req = ble_att_cmd_get(BLE_ATT_OP_MTU_REQ, sizeof(*req), &txom);
    if (req == NULL) {
        return BLE_HS_ENOMEM;
    }

    req->bamc_mtu = htole16(mtu);

    rc = ble_att_tx(conn_handle, txom);
    if (rc != 0) {
        return rc;
    }

    BLE_ATT_LOG_CMD(1, "mtu req", conn_handle, ble_att_mtu_cmd_log, req);

    ble_hs_lock();

    rc = ble_att_conn_chan_find(conn_handle, &conn, &chan);
    if (rc == 0) {
        chan->flags |= BLE_L2CAP_CHAN_F_TXED_MTU;
    }

    ble_hs_unlock();

    return rc;
}

int
ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom)
{
    struct ble_att_mtu_cmd *cmd;
    struct ble_l2cap_chan *chan;
    uint16_t mtu;
    int rc;

    mtu = 0;

    rc = ble_hs_mbuf_pullup_base(rxom, sizeof(*cmd));
    if (rc == 0) {
        cmd = (struct ble_att_mtu_cmd *)(*rxom)->om_data;

        BLE_ATT_LOG_CMD(0, "mtu rsp", conn_handle, ble_att_mtu_cmd_log, cmd);

        ble_hs_lock();

        rc = ble_att_conn_chan_find(conn_handle, NULL, &chan);
        if (rc == 0) {
            ble_att_set_peer_mtu(chan, le16toh(cmd->bamc_mtu));
            mtu = ble_att_chan_mtu(chan);
        }

        ble_hs_unlock();

        if (rc == 0) {
            ble_gap_mtu_event(conn_handle, BLE_L2CAP_CID_ATT, mtu);
        }
    }

    ble_gattc_rx_mtu(conn_handle, rc, mtu);
    return rc;
}

/*****************************************************************************
 * $find information                                                         *
 *****************************************************************************/

int
ble_att_clt_tx_find_info(uint16_t conn_handle, uint16_t start_handle,
                         uint16_t end_handle)
{
#if !NIMBLE_BLE_ATT_CLT_FIND_INFO
    return BLE_HS_ENOTSUP;
#endif

    struct ble_att_find_info_req *req;
    struct os_mbuf *txom;

    if (start_handle == 0 || start_handle > end_handle) {
        return BLE_HS_EINVAL;
    }

    req = ble_att_cmd_get(BLE_ATT_OP_FIND_INFO_REQ, sizeof(*req), &txom);
    if (req == NULL) {
        return BLE_HS_ENOMEM;
    }

    req->bafq_start_handle = htole16(start_handle);
    req->bafq_end_handle = htole16(end_handle);

    BLE_ATT_LOG_CMD(1, "find info req", conn_handle,
                    ble_att_find_info_req_log, req);

    return ble_att_tx(conn_handle, txom);
}

static int
ble_att_clt_parse_find_info_entry(struct os_mbuf **rxom, uint8_t rsp_format,
                                  struct ble_att_find_info_idata *idata)
{
    int entry_len;
    int rc;

    switch (rsp_format) {
    case BLE_ATT_FIND_INFO_RSP_FORMAT_16BIT:
        entry_len = 2 + 2;
        break;

    case BLE_ATT_FIND_INFO_RSP_FORMAT_128BIT:
        entry_len = 2 + 16;
        break;

    default:
        return BLE_HS_EBADDATA;
    }

    rc = ble_hs_mbuf_pullup_base(rxom, entry_len);
    if (rc != 0) {
        return rc;
    }

    idata->attr_handle = get_le16((*rxom)->om_data);

    switch (rsp_format) {
    case BLE_ATT_FIND_INFO_RSP_FORMAT_16BIT:
        rc = ble_uuid_init_from_att_mbuf(&idata->uuid, *rxom, 2, 2);
        if (rc != 0) {
            return BLE_HS_EBADDATA;
        }
        break;

    case BLE_ATT_FIND_INFO_RSP_FORMAT_128BIT:
        rc = ble_uuid_init_from_att_mbuf(&idata->uuid, *rxom, 2, 16);
        if (rc != 0) {
            return BLE_HS_EBADDATA;
        }
        break;

    default:
        BLE_HS_DBG_ASSERT(0);
        break;
    }

    os_mbuf_adj(*rxom, entry_len);
    return 0;
}

int
ble_att_clt_rx_find_info(uint16_t conn_handle, struct os_mbuf **om)
{
#if !NIMBLE_BLE_ATT_CLT_FIND_INFO
    return BLE_HS_ENOTSUP;
#endif

    struct ble_att_find_info_idata idata;
    struct ble_att_find_info_rsp *rsp;
    int rc;

    rc = ble_hs_mbuf_pullup_base(om, sizeof(*rsp));
    if (rc != 0) {
        goto done;
    }

    rsp = (struct ble_att_find_info_rsp *)(*om)->om_data;

    BLE_ATT_LOG_CMD(0, "find info rsp", conn_handle, ble_att_find_info_rsp_log,
                    rsp);

    /* Strip the response base from the front of the mbuf. */
    os_mbuf_adj((*om), sizeof(*rsp));

    while (OS_MBUF_PKTLEN(*om) > 0) {
        rc = ble_att_clt_parse_find_info_entry(om, rsp->bafp_format, &idata);
        if (rc != 0) {
            goto done;
        }

        /* Hand find-info entry to GATT. */
        ble_gattc_rx_find_info_idata(conn_handle, &idata);
    }

    rc = 0;

done:
    /* Notify GATT that response processing is done. */
    ble_gattc_rx_find_info_complete(conn_handle, rc);
    return rc;
}

/*****************************************************************************
 * $find by type value                                                       *
 *****************************************************************************/

/*
 * TODO consider this to accept UUID instead of value, it is used only for this
 * anyway
 */
int
ble_att_clt_tx_find_type_value(uint16_t conn_handle, uint16_t start_handle,
                               uint16_t end_handle, uint16_t attribute_type,
                               const void *attribute_value, int value_len)
{
#if !NIMBLE_BLE_ATT_CLT_FIND_TYPE
    return BLE_HS_ENOTSUP;
#endif

    struct ble_att_find_type_value_req *req;
    struct os_mbuf *txom;

    if (start_handle == 0 || start_handle > end_handle) {
        return BLE_HS_EINVAL;
    }

    req = ble_att_cmd_get(BLE_ATT_OP_FIND_TYPE_VALUE_REQ, sizeof(*req) + value_len,
                          &txom);
    if (req == NULL) {
        return BLE_HS_ENOMEM;
    }

    req->bavq_start_handle = htole16(start_handle);
    req->bavq_end_handle = htole16(end_handle);
    req->bavq_attr_type = htole16(attribute_type);
    memcpy(req->bavq_value, attribute_value, value_len);

    BLE_ATT_LOG_CMD(1, "find type value req", conn_handle,
                    ble_att_find_type_value_req_log, req);

    return ble_att_tx(conn_handle, txom);
}

static int
ble_att_clt_parse_find_type_value_hinfo(
    struct os_mbuf **om, struct ble_att_find_type_value_hinfo *dst)
{
    struct ble_att_handle_group *group;
    int rc;

    rc = ble_hs_mbuf_pullup_base(om, sizeof(*group));
    if (rc != 0) {
        return BLE_HS_EBADDATA;
    }

    group = (struct ble_att_handle_group *)(*om)->om_data;

    dst->attr_handle = le16toh(group->attr_handle);
    dst->group_end_handle = le16toh(group->group_end_handle);

    os_mbuf_adj((*om), sizeof(*group));

    return 0;
}

int
ble_att_clt_rx_find_type_value(uint16_t conn_handle, struct os_mbuf **rxom)
{
#if !NIMBLE_BLE_ATT_CLT_FIND_TYPE
    return BLE_HS_ENOTSUP;
#endif

    struct ble_att_find_type_value_hinfo hinfo;
    int rc;

    BLE_ATT_LOG_EMPTY_CMD(0, "find type value rsp", conn_handle);

    /* Parse the Handles-Information-List field, passing each entry to GATT. */
    rc = 0;
    while (OS_MBUF_PKTLEN(*rxom) > 0) {
        rc = ble_att_clt_parse_find_type_value_hinfo(rxom, &hinfo);
        if (rc != 0) {
            break;
        }

        ble_gattc_rx_find_type_value_hinfo(conn_handle, &hinfo);
    }

    /* Notify GATT client that the full response has been parsed. */
    ble_gattc_rx_find_type_value_complete(conn_handle, rc);

    return 0;
}

/*****************************************************************************
 * $read by type                                                             *
 *****************************************************************************/

int
ble_att_clt_tx_read_type(uint16_t conn_handle, uint16_t start_handle,
                         uint16_t end_handle, const ble_uuid_t *uuid)
{
#if !NIMBLE_BLE_ATT_CLT_READ_TYPE
    return BLE_HS_ENOTSUP;
#endif

    struct ble_att_read_type_req *req;
    struct os_mbuf *txom;

    if (start_handle == 0 || start_handle > end_handle) {
        return BLE_HS_EINVAL;
    }

    req = ble_att_cmd_get(BLE_ATT_OP_READ_TYPE_REQ,
                          sizeof(*req) + ble_uuid_length(uuid), &txom);
    if (req == NULL) {
        return BLE_HS_ENOMEM;
    }

    req->batq_start_handle = htole16(start_handle);
    req->batq_end_handle = htole16(end_handle);

    ble_uuid_flat(uuid, req->uuid);

    BLE_ATT_LOG_CMD(1, "read type req", conn_handle,
                    ble_att_read_type_req_log, req);

    return ble_att_tx(conn_handle, txom);
}

int
ble_att_clt_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom)
{
#if !NIMBLE_BLE_ATT_CLT_READ_TYPE
    return BLE_HS_ENOTSUP;
#endif

    struct ble_att_read_type_adata adata;
    struct ble_att_attr_data_list *data;
    struct ble_att_read_type_rsp *rsp;
    uint8_t data_len;
    int rc;

    rc = ble_hs_mbuf_pullup_base(rxom, sizeof(*rsp));
    if (rc != 0) {
        goto done;
    }

    rsp = (struct ble_att_read_type_rsp *)(*rxom)->om_data;

    BLE_ATT_LOG_CMD(0, "read type rsp", conn_handle, ble_att_read_type_rsp_log,
                    rsp);

    data_len = rsp->batp_length;

    /* Strip the response base from the front of the mbuf. */
    os_mbuf_adj(*rxom, sizeof(*rsp));

    if (data_len < sizeof(*data)) {
        rc = BLE_HS_EBADDATA;
        goto done;
    }

    /* Parse the Attribute Data List field, passing each entry to the GATT. */
    while (OS_MBUF_PKTLEN(*rxom) > 0) {
        rc = ble_hs_mbuf_pullup_base(rxom, data_len);
        if (rc != 0) {
            break;
        }

        data = (struct ble_att_attr_data_list *)(*rxom)->om_data;

        adata.att_handle = le16toh(data->handle);
        adata.value_len = data_len - sizeof(*data);
        adata.value = data->value;

        ble_gattc_rx_read_type_adata(conn_handle, &adata);
        os_mbuf_adj(*rxom, data_len);
    }

done:
    /* Notify GATT that the response is done being parsed. */
    ble_gattc_rx_read_type_complete(conn_handle, rc);
    return rc;

}

/*****************************************************************************
 * $read                                                                     *
 *****************************************************************************/

int
ble_att_clt_tx_read(uint16_t conn_handle, uint16_t handle)
{
#if !NIMBLE_BLE_ATT_CLT_READ
    return BLE_HS_ENOTSUP;
#endif

    struct ble_att_read_req *req;
    struct os_mbuf *txom;
    int rc;

    if (handle == 0) {
        return BLE_HS_EINVAL;
    }

    req = ble_att_cmd_get(BLE_ATT_OP_READ_REQ, sizeof(*req), &txom);
    if (req == NULL) {
        return BLE_HS_ENOMEM;
    }

    req->barq_handle = htole16(handle);

    rc = ble_att_tx(conn_handle, txom);
    if (rc != 0) {
        return rc;
    }

    BLE_ATT_LOG_CMD(1, "read req", conn_handle, ble_att_read_req_log, req);

    return 0;
}

int
ble_att_clt_rx_read(uint16_t conn_handle, struct os_mbuf **rxom)
{
#if !NIMBLE_BLE_ATT_CLT_READ
    return BLE_HS_ENOTSUP;
#endif

    BLE_ATT_LOG_EMPTY_CMD(0, "read rsp", conn_handle);

    /* Pass the Attribute Value field to GATT. */
    ble_gattc_rx_read_rsp(conn_handle, 0, rxom);
    return 0;
}

/*****************************************************************************
 * $read blob                                                                *
 *****************************************************************************/

int
ble_att_clt_tx_read_blob(uint16_t conn_handle, uint16_t handle, uint16_t offset)
{
#if !NIMBLE_BLE_ATT_CLT_READ_BLOB
    return BLE_HS_ENOTSUP;
#endif

    struct ble_att_read_blob_req *req;
    struct os_mbuf *txom;
    int rc;

    if (handle == 0) {
        return BLE_HS_EINVAL;
    }

    req = ble_att_cmd_get(BLE_ATT_OP_READ_BLOB_REQ, sizeof(*req), &txom);
    if (req == NULL) {
        return BLE_HS_ENOMEM;
    }

    req->babq_handle = htole16(handle);
    req->babq_offset = htole16(offset);

    rc = ble_att_tx(conn_handle, txom);
    if (rc != 0) {
        return rc;
    }

    BLE_ATT_LOG_CMD(1, "read blob req", conn_handle,
                    ble_att_read_blob_req_log, req);

    return 0;
}

int
ble_att_clt_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom)
{
#if !NIMBLE_BLE_ATT_CLT_READ_BLOB
    return BLE_HS_ENOTSUP;
#endif

    BLE_ATT_LOG_EMPTY_CMD(0, "read blob rsp", conn_handle);

    /* Pass the Attribute Value field to GATT. */
    ble_gattc_rx_read_blob_rsp(conn_handle, 0, rxom);
    return 0;
}

/*****************************************************************************
 * $read multiple                                                            *
 *****************************************************************************/
int
ble_att_clt_tx_read_mult(uint16_t conn_handle, const uint16_t *handles,
                         int num_handles)
{
#if !NIMBLE_BLE_ATT_CLT_READ_MULT
    return BLE_HS_ENOTSUP;
#endif

    struct ble_att_read_mult_req *req;
    struct os_mbuf *txom;
    int i;

    BLE_ATT_LOG_EMPTY_CMD(1, "reqd mult req", conn_handle);

    if (num_handles < 1) {
        return BLE_HS_EINVAL;
    }

    req = ble_att_cmd_get(BLE_ATT_OP_READ_MULT_REQ,
                          sizeof(req->handles[0]) * num_handles,
                          &txom);
    if (req == NULL) {
        return BLE_HS_ENOMEM;
    }

    for(i = 0; i < num_handles; i++) {
        req->handles[i] = htole16(handles[i]);
    }

    return ble_att_tx(conn_handle, txom);
}

int
ble_att_clt_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom)
{
#if !NIMBLE_BLE_ATT_CLT_READ_MULT
    return BLE_HS_ENOTSUP;
#endif

    BLE_ATT_LOG_EMPTY_CMD(0, "read mult rsp", conn_handle);

    /* Pass the Attribute Value field to GATT. */
    ble_gattc_rx_read_mult_rsp(conn_handle, 0, rxom);
    return 0;
}

/*****************************************************************************
 * $read by group type                                                       *
 *****************************************************************************/

int
ble_att_clt_tx_read_group_type(uint16_t conn_handle,
                               uint16_t start_handle, uint16_t end_handle,
                               const ble_uuid_t *uuid)
{
#if !NIMBLE_BLE_ATT_CLT_READ_GROUP_TYPE
    return BLE_HS_ENOTSUP;
#endif

    struct ble_att_read_group_type_req *req;
    struct os_mbuf *txom;

    if (start_handle == 0 || start_handle > end_handle) {
        return BLE_HS_EINVAL;
    }

    req = ble_att_cmd_get(BLE_ATT_OP_READ_GROUP_TYPE_REQ,
                          sizeof(*req) + ble_uuid_length(uuid), &txom);
    if (req == NULL) {
        return BLE_HS_ENOMEM;
    }

    req->bagq_start_handle = htole16(start_handle);
    req->bagq_end_handle = htole16(end_handle);
    ble_uuid_flat(uuid, req->uuid);

    BLE_ATT_LOG_CMD(1, "read group type req", conn_handle,
                    ble_att_read_group_type_req_log, req);

    return ble_att_tx(conn_handle, txom);
}

static int
ble_att_clt_parse_read_group_type_adata(
    struct os_mbuf **om, int data_len,
    struct ble_att_read_group_type_adata *adata)
{
    int rc;

    if (data_len < BLE_ATT_READ_GROUP_TYPE_ADATA_BASE_SZ + 1) {
        return BLE_HS_EMSGSIZE;
    }

    rc = ble_hs_mbuf_pullup_base(om, data_len);
    if (rc != 0) {
        return rc;
    }

    adata->att_handle = get_le16((*om)->om_data + 0);
    adata->end_group_handle = get_le16((*om)->om_data + 2);
    adata->value_len = data_len - BLE_ATT_READ_GROUP_TYPE_ADATA_BASE_SZ;
    adata->value = (*om)->om_data + BLE_ATT_READ_GROUP_TYPE_ADATA_BASE_SZ;

    return 0;
}

int
ble_att_clt_rx_read_group_type(uint16_t conn_handle, struct os_mbuf **rxom)
{
#if !NIMBLE_BLE_ATT_CLT_READ_GROUP_TYPE
    return BLE_HS_ENOTSUP;
#endif

    struct ble_att_read_group_type_adata adata;
    struct ble_att_read_group_type_rsp *rsp;
    uint8_t len;
    int rc;

    rc = ble_hs_mbuf_pullup_base(rxom, sizeof(*rsp));
    if (rc != 0) {
        goto done;
    }

    rsp = (struct ble_att_read_group_type_rsp *)(*rxom)->om_data;

    BLE_ATT_LOG_CMD(0, "read group type rsp", conn_handle,
                    ble_att_read_group_type_rsp_log, rsp);

    len = rsp->bagp_length;

    /* Strip the base from the front of the response. */
    os_mbuf_adj(*rxom, sizeof(*rsp));

    /* Parse the Attribute Data List field, passing each entry to GATT. */
    while (OS_MBUF_PKTLEN(*rxom) > 0) {
        rc = ble_att_clt_parse_read_group_type_adata(rxom, len, &adata);
        if (rc != 0) {
            goto done;
        }

        ble_gattc_rx_read_group_type_adata(conn_handle, &adata);
        os_mbuf_adj(*rxom, len);
    }

done:
    /* Notify GATT that the response is done being parsed. */
    ble_gattc_rx_read_group_type_complete(conn_handle, rc);
    return rc;
}

/*****************************************************************************
 * $write                                                                    *
 *****************************************************************************/

int
ble_att_clt_tx_write_req(uint16_t conn_handle, uint16_t handle,
                         struct os_mbuf *txom)
{
#if !NIMBLE_BLE_ATT_CLT_WRITE
    return BLE_HS_ENOTSUP;
#endif

    struct ble_att_write_req *req;
    struct os_mbuf *txom2;

    req = ble_att_cmd_get(BLE_ATT_OP_WRITE_REQ, sizeof(*req), &txom2);
    if (req == NULL) {
        os_mbuf_free_chain(txom);
        return BLE_HS_ENOMEM;
    }

    req->bawq_handle = htole16(handle);
    os_mbuf_concat(txom2, txom);

    BLE_ATT_LOG_CMD(1, "write req", conn_handle, ble_att_write_req_log, req);

    return ble_att_tx(conn_handle, txom2);
}

int
ble_att_clt_tx_write_cmd(uint16_t conn_handle, uint16_t handle,
                         struct os_mbuf *txom)
{
#if !NIMBLE_BLE_ATT_CLT_WRITE_NO_RSP
    return BLE_HS_ENOTSUP;
#endif

    struct ble_att_write_cmd *cmd;
    struct os_mbuf *txom2;
    uint8_t b;
    int rc;
    int i;

    BLE_HS_LOG(DEBUG, "ble_att_clt_tx_write_cmd(): ");
    for (i = 0; i < OS_MBUF_PKTLEN(txom); i++) {
        if (i != 0) {
            BLE_HS_LOG(DEBUG, ":");
        }
        rc = os_mbuf_copydata(txom, i, 1, &b);
        assert(rc == 0);
        BLE_HS_LOG(DEBUG, "0x%02x", b);
    }


    cmd = ble_att_cmd_get(BLE_ATT_OP_WRITE_CMD, sizeof(*cmd), &txom2);
    if (cmd == NULL) {
        os_mbuf_free_chain(txom);
        return BLE_HS_ENOMEM;
    }

    cmd->handle = htole16(handle);
    os_mbuf_concat(txom2, txom);

    BLE_ATT_LOG_CMD(1, "write cmd", conn_handle, ble_att_write_cmd_log, cmd);

    return ble_att_tx(conn_handle, txom2);
}

int
ble_att_clt_rx_write(uint16_t conn_handle, struct os_mbuf **rxom)
{
#if !NIMBLE_BLE_ATT_CLT_WRITE
    return BLE_HS_ENOTSUP;
#endif

    BLE_ATT_LOG_EMPTY_CMD(0, "write rsp", conn_handle);

    /* No payload. */
    ble_gattc_rx_write_rsp(conn_handle);
    return 0;
}

/*****************************************************************************
 * $prepare write request                                                    *
 *****************************************************************************/

int
ble_att_clt_tx_prep_write(uint16_t conn_handle, uint16_t handle,
                          uint16_t offset, struct os_mbuf *txom)
{
#if !NIMBLE_BLE_ATT_CLT_PREP_WRITE
    return BLE_HS_ENOTSUP;
#endif

    struct ble_att_prep_write_cmd *req;
    struct os_mbuf *txom2;
    int rc;

    if (handle == 0) {
        rc = BLE_HS_EINVAL;
        goto err;
    }

    if (offset + OS_MBUF_PKTLEN(txom) > BLE_ATT_ATTR_MAX_LEN) {
        rc = BLE_HS_EINVAL;
        goto err;
    }

    if (OS_MBUF_PKTLEN(txom) >
        ble_att_mtu(conn_handle) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ) {
        rc = BLE_HS_EINVAL;
        goto err;
    }

    req = ble_att_cmd_get(BLE_ATT_OP_PREP_WRITE_REQ, sizeof(*req), &txom2);
    if (req == NULL) {
        rc = BLE_HS_ENOMEM;
        goto err;
    }

    req->bapc_handle = htole16(handle);
    req->bapc_offset = htole16(offset);
    os_mbuf_concat(txom2, txom);

    BLE_ATT_LOG_CMD(1, "prep write req", conn_handle,
                    ble_att_prep_write_cmd_log, req);

    return ble_att_tx(conn_handle, txom2);

err:
    os_mbuf_free_chain(txom);
    return rc;
}

int
ble_att_clt_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom)
{
#if !NIMBLE_BLE_ATT_CLT_PREP_WRITE
    return BLE_HS_ENOTSUP;
#endif

    struct ble_att_prep_write_cmd *rsp;
    uint16_t handle, offset;
    int rc;

    /* Initialize some values in case of early error. */
    handle = 0;
    offset = 0;

    rc = ble_hs_mbuf_pullup_base(rxom, sizeof(*rsp));
    if (rc != 0) {
        goto done;
    }

    rsp = (struct ble_att_prep_write_cmd *)(*rxom)->om_data;
    BLE_ATT_LOG_CMD(0, "prep write rsp", conn_handle,
                    ble_att_prep_write_cmd_log, rsp);

    handle = le16toh(rsp->bapc_handle);
    offset = le16toh(rsp->bapc_offset);

    /* Strip the base from the front of the response. */
    os_mbuf_adj(*rxom, sizeof(*rsp));

done:
    /* Notify GATT client that the full response has been parsed. */
    ble_gattc_rx_prep_write_rsp(conn_handle, rc, handle, offset, rxom);
    return rc;
}

/*****************************************************************************
 * $execute write request                                                    *
 *****************************************************************************/

int
ble_att_clt_tx_exec_write(uint16_t conn_handle, uint8_t flags)
{
#if !NIMBLE_BLE_ATT_CLT_EXEC_WRITE
    return BLE_HS_ENOTSUP;
#endif

    struct ble_att_exec_write_req *req;
    struct os_mbuf *txom;
    int rc;

    req = ble_att_cmd_get(BLE_ATT_OP_EXEC_WRITE_REQ, sizeof(*req), &txom);
    if (req == NULL) {
        return BLE_HS_ENOMEM;
    }

    req->baeq_flags = flags;

    rc = ble_att_tx(conn_handle, txom);
    if (rc != 0) {
        return rc;
    }

    BLE_ATT_LOG_CMD(1, "exec write req", conn_handle,
                    ble_att_exec_write_req_log, req);

    return 0;
}

int
ble_att_clt_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom)
{
#if !NIMBLE_BLE_ATT_CLT_EXEC_WRITE
    return BLE_HS_ENOTSUP;
#endif

    BLE_ATT_LOG_EMPTY_CMD(0, "exec write rsp", conn_handle);

    ble_gattc_rx_exec_write_rsp(conn_handle, 0);
    return 0;
}

/*****************************************************************************
 * $handle value notification                                                *
 *****************************************************************************/

int
ble_att_clt_tx_notify(uint16_t conn_handle, uint16_t handle,
                      struct os_mbuf *txom)
{
#if !NIMBLE_BLE_ATT_CLT_NOTIFY
    return BLE_HS_ENOTSUP;
#endif

    struct ble_att_notify_req *req;
    struct os_mbuf *txom2;
    int rc;

    if (handle == 0) {
        rc = BLE_HS_EINVAL;
        goto err;
    }

    req = ble_att_cmd_get(BLE_ATT_OP_NOTIFY_REQ, sizeof(*req), &txom2);
    if (req == NULL) {
        rc = BLE_HS_ENOMEM;
        goto err;
    }

    req->banq_handle = htole16(handle);
    os_mbuf_concat(txom2, txom);

    BLE_ATT_LOG_CMD(1, "notify req", conn_handle, ble_att_notify_req_log, req);

    return ble_att_tx(conn_handle, txom2);

err:
    os_mbuf_free_chain(txom);
    return rc;
}

/*****************************************************************************
 * $handle value indication                                                  *
 *****************************************************************************/

int
ble_att_clt_tx_indicate(uint16_t conn_handle, uint16_t handle,
                        struct os_mbuf *txom)
{
#if !NIMBLE_BLE_ATT_CLT_INDICATE
    return BLE_HS_ENOTSUP;
#endif

    struct ble_att_indicate_req *req;
    struct os_mbuf *txom2;
    int rc;

    if (handle == 0) {
        rc = BLE_HS_EINVAL;
        goto err;
    }

    req = ble_att_cmd_get(BLE_ATT_OP_INDICATE_REQ, sizeof(*req), &txom2);
    if (req == NULL) {
        rc = BLE_HS_ENOMEM;
        goto err;
    }

    req->baiq_handle = htole16(handle);
    os_mbuf_concat(txom2, txom);

    BLE_ATT_LOG_CMD(1, "indicate req", conn_handle, ble_att_indicate_req_log,
                    req);

    return ble_att_tx(conn_handle, txom2);

err:
    os_mbuf_free_chain(txom);
    return rc;
}

int
ble_att_clt_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom)
{
#if !NIMBLE_BLE_ATT_CLT_INDICATE
    return BLE_HS_ENOTSUP;
#endif

    BLE_ATT_LOG_EMPTY_CMD(0, "indicate rsp", conn_handle);

    /* No payload. */
    ble_gattc_rx_indicate_rsp(conn_handle);
    return 0;
}
