/*
 * Support for host VHCIs inside qemu scatternets.
 *
 * Copyright (C) 2008 Andrzej Zaborowski  <balrog@zabor.org>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 or
 * (at your option) version 3 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu-common.h"
#include "sysemu/bt.h"
#include "hw/bt.h"
#include "qemu/main-loop.h"

#define VHCI_DEV	"/dev/vhci"
#define VHCI_UDEV	"/dev/hci_vhci"

struct bt_vhci_s {
    int fd;
    struct HCIInfo *info;

    uint8_t hdr[4096];
    int len;
};

static void vhci_read(void *opaque)
{
    struct bt_vhci_s *s = (struct bt_vhci_s *) opaque;
    uint8_t *pkt;
    int pktlen;

    /* Seems that we can't read only the header first and then the amount
     * of data indicated in the header because Linux will discard everything
     * that's not been read in one go.  */
    s->len = read(s->fd, s->hdr, sizeof(s->hdr));

    if (s->len < 0) {
        fprintf(stderr, "qemu: error %i reading the PDU\n", errno);
        return;
    }

    pkt = s->hdr;
    while (s->len --)
        switch (*pkt ++) {
        case HCI_COMMAND_PKT:
            if (s->len < 3)
                goto bad_pkt;

            pktlen = MIN(pkt[2] + 3, s->len);
            s->info->cmd_send(s->info, pkt, pktlen);
            s->len -= pktlen;
            pkt += pktlen;
            break;

        case HCI_ACLDATA_PKT:
            if (s->len < 4)
                goto bad_pkt;

            pktlen = MIN(((pkt[3] << 8) | pkt[2]) + 4, s->len);
            s->info->acl_send(s->info, pkt, pktlen);
            s->len -= pktlen;
            pkt += pktlen;
            break;

        case HCI_SCODATA_PKT:
            if (s->len < 3)
                goto bad_pkt;

            pktlen = MIN(pkt[2] + 3, s->len);
            s->info->sco_send(s->info, pkt, pktlen);
            s->len -= pktlen;
            pkt += pktlen;
            break;

        default:
        bad_pkt:
            fprintf(stderr, "qemu: bad HCI packet type %02x\n", pkt[-1]);
        }
}

static void vhci_host_send(void *opaque,
                int type, const uint8_t *data, int len)
{
    struct bt_vhci_s *s = (struct bt_vhci_s *) opaque;
#if 0
    uint8_t pkt = type;
    struct iovec iv[2];

    iv[0].iov_base = &pkt;
    iv[0].iov_len  = 1;
    iv[1].iov_base = (void *) data;
    iv[1].iov_len  = len;

    while (writev(s->fd, iv, 2) < 0)
        if (errno != EAGAIN && errno != EINTR) {
            fprintf(stderr, "qemu: error %i writing bluetooth packet.\n",
                            errno);
            return;
        }
#else
    /* Apparently VHCI wants us to write everything in one chunk :-(  */
    static uint8_t buf[4096];

    buf[0] = type;
    memcpy(buf + 1, data, len);

    while (write(s->fd, buf, len + 1) < 0)
        if (errno != EAGAIN && errno != EINTR) {
            fprintf(stderr, "qemu: error %i writing bluetooth packet.\n",
                            errno);
            return;
        }
#endif
}

static void vhci_out_hci_packet_event(void *opaque,
                const uint8_t *data, int len)
{
    vhci_host_send(opaque, HCI_EVENT_PKT, data, len);
}

static void vhci_out_hci_packet_acl(void *opaque,
                const uint8_t *data, int len)
{
    vhci_host_send(opaque, HCI_ACLDATA_PKT, data, len);
}

void bt_vhci_init(struct HCIInfo *info)
{
    struct bt_vhci_s *s;
    int err[2];
    int fd;

    fd = open(VHCI_DEV, O_RDWR);
    err[0] = errno;
    if (fd < 0) {
        fd = open(VHCI_UDEV, O_RDWR);
        err[1] = errno;
    }

    if (fd < 0) {
        fprintf(stderr, "qemu: Can't open `%s': %s (%i)\n",
                        VHCI_DEV, strerror(err[0]), err[0]);
        fprintf(stderr, "qemu: Can't open `%s': %s (%i)\n",
                        VHCI_UDEV, strerror(err[1]), err[1]);
        exit(-1);
    }

    s = g_malloc0(sizeof(struct bt_vhci_s));
    s->fd = fd;
    s->info = info ?: qemu_next_hci();
    s->info->opaque = s;
    s->info->evt_recv = vhci_out_hci_packet_event;
    s->info->acl_recv = vhci_out_hci_packet_acl;

    qemu_set_fd_handler(s->fd, vhci_read, NULL, s);
}
