/*
 * QEMU Bluetooth HID Profile wrapper for USB HID.
 *
 * Copyright (C) 2007-2008 OpenMoko, Inc.
 * Written by Andrzej Zaborowski <andrew@openedhand.com>
 *
 * 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, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "qemu-common.h"
#include "usb.h"
#include "bt.h"

enum hid_transaction_req {
    BT_HANDSHAKE			= 0x0,
    BT_HID_CONTROL			= 0x1,
    BT_GET_REPORT			= 0x4,
    BT_SET_REPORT			= 0x5,
    BT_GET_PROTOCOL			= 0x6,
    BT_SET_PROTOCOL			= 0x7,
    BT_GET_IDLE				= 0x8,
    BT_SET_IDLE				= 0x9,
    BT_DATA				= 0xa,
    BT_DATC				= 0xb,
};

enum hid_transaction_handshake {
    BT_HS_SUCCESSFUL			= 0x0,
    BT_HS_NOT_READY			= 0x1,
    BT_HS_ERR_INVALID_REPORT_ID		= 0x2,
    BT_HS_ERR_UNSUPPORTED_REQUEST	= 0x3,
    BT_HS_ERR_INVALID_PARAMETER		= 0x4,
    BT_HS_ERR_UNKNOWN			= 0xe,
    BT_HS_ERR_FATAL			= 0xf,
};

enum hid_transaction_control {
    BT_HC_NOP				= 0x0,
    BT_HC_HARD_RESET			= 0x1,
    BT_HC_SOFT_RESET			= 0x2,
    BT_HC_SUSPEND			= 0x3,
    BT_HC_EXIT_SUSPEND			= 0x4,
    BT_HC_VIRTUAL_CABLE_UNPLUG		= 0x5,
};

enum hid_protocol {
    BT_HID_PROTO_BOOT			= 0,
    BT_HID_PROTO_REPORT			= 1,
};

enum hid_boot_reportid {
    BT_HID_BOOT_INVALID			= 0,
    BT_HID_BOOT_KEYBOARD,
    BT_HID_BOOT_MOUSE,
};

enum hid_data_pkt {
    BT_DATA_OTHER			= 0,
    BT_DATA_INPUT,
    BT_DATA_OUTPUT,
    BT_DATA_FEATURE,
};

#define BT_HID_MTU			48

/* HID interface requests */
#define GET_REPORT			0xa101
#define GET_IDLE			0xa102
#define GET_PROTOCOL			0xa103
#define SET_REPORT			0x2109
#define SET_IDLE			0x210a
#define SET_PROTOCOL			0x210b

struct bt_hid_device_s {
    struct bt_l2cap_device_s btdev;
    struct bt_l2cap_conn_params_s *control;
    struct bt_l2cap_conn_params_s *interrupt;
    USBDevice *usbdev;

    int proto;
    int connected;
    int data_type;
    int intr_state;
    struct {
        int len;
        uint8_t buffer[1024];
    } dataother, datain, dataout, feature, intrdataout;
    enum {
        bt_state_ready,
        bt_state_transaction,
        bt_state_suspend,
    } state;
};

static void bt_hid_reset(struct bt_hid_device_s *s)
{
    struct bt_scatternet_s *net = s->btdev.device.net;

    /* Go as far as... */
    bt_l2cap_device_done(&s->btdev);
    bt_l2cap_device_init(&s->btdev, net);

    s->usbdev->handle_reset(s->usbdev);
    s->proto = BT_HID_PROTO_REPORT;
    s->state = bt_state_ready;
    s->dataother.len = 0;
    s->datain.len = 0;
    s->dataout.len = 0;
    s->feature.len = 0;
    s->intrdataout.len = 0;
    s->intr_state = 0;
}

static int bt_hid_out(struct bt_hid_device_s *s)
{
    USBPacket p;

    if (s->data_type == BT_DATA_OUTPUT) {
        p.pid = USB_TOKEN_OUT;
        p.devep = 1;
        p.data = s->dataout.buffer;
        p.len = s->dataout.len;
        s->dataout.len = s->usbdev->handle_data(s->usbdev, &p);

        return s->dataout.len;
    }

    if (s->data_type == BT_DATA_FEATURE) {
        /* XXX:
         * does this send a USB_REQ_CLEAR_FEATURE/USB_REQ_SET_FEATURE
         * or a SET_REPORT? */
        p.devep = 0;
    }

    return -1;
}

static int bt_hid_in(struct bt_hid_device_s *s)
{
    USBPacket p;

    p.pid = USB_TOKEN_IN;
    p.devep = 1;
    p.data = s->datain.buffer;
    p.len = sizeof(s->datain.buffer);
    s->datain.len = s->usbdev->handle_data(s->usbdev, &p);

    return s->datain.len;
}

static void bt_hid_send_handshake(struct bt_hid_device_s *s, int result)
{
    *s->control->sdu_out(s->control, 1) =
            (BT_HANDSHAKE << 4) | result;
    s->control->sdu_submit(s->control);
}

static void bt_hid_send_control(struct bt_hid_device_s *s, int operation)
{
    *s->control->sdu_out(s->control, 1) =
            (BT_HID_CONTROL << 4) | operation;
    s->control->sdu_submit(s->control);
}

static void bt_hid_disconnect(struct bt_hid_device_s *s)
{
    /* Disconnect s->control and s->interrupt */
}

static void bt_hid_send_data(struct bt_l2cap_conn_params_s *ch, int type,
                const uint8_t *data, int len)
{
    uint8_t *pkt, hdr = (BT_DATA << 4) | type;
    int plen;

    do {
        plen = MIN(len, ch->remote_mtu - 1);
        pkt = ch->sdu_out(ch, plen + 1);

        pkt[0] = hdr;
        if (plen)
            memcpy(pkt + 1, data, plen);
        ch->sdu_submit(ch);

        len -= plen;
        data += plen;
        hdr = (BT_DATC << 4) | type;
    } while (plen == ch->remote_mtu - 1);
}

static void bt_hid_control_transaction(struct bt_hid_device_s *s,
                const uint8_t *data, int len)
{
    uint8_t type, parameter;
    int rlen, ret = -1;
    if (len < 1)
        return;

    type = data[0] >> 4;
    parameter = data[0] & 0xf;

    switch (type) {
    case BT_HANDSHAKE:
    case BT_DATA:
        switch (parameter) {
        default:
            /* These are not expected to be sent this direction.  */
            ret = BT_HS_ERR_INVALID_PARAMETER;
        }
        break;

    case BT_HID_CONTROL:
        if (len != 1 || (parameter != BT_HC_VIRTUAL_CABLE_UNPLUG &&
                                s->state == bt_state_transaction)) {
            ret = BT_HS_ERR_INVALID_PARAMETER;
            break;
        }
        switch (parameter) {
        case BT_HC_NOP:
            break;
        case BT_HC_HARD_RESET:
        case BT_HC_SOFT_RESET:
            bt_hid_reset(s);
            break;
        case BT_HC_SUSPEND:
            if (s->state == bt_state_ready)
                s->state = bt_state_suspend;
            else
                ret = BT_HS_ERR_INVALID_PARAMETER;
            break;
        case BT_HC_EXIT_SUSPEND:
            if (s->state == bt_state_suspend)
                s->state = bt_state_ready;
            else
                ret = BT_HS_ERR_INVALID_PARAMETER;
            break;
        case BT_HC_VIRTUAL_CABLE_UNPLUG:
            bt_hid_disconnect(s);
            break;
        default:
            ret = BT_HS_ERR_INVALID_PARAMETER;
        }
        break;

    case BT_GET_REPORT:
        /* No ReportIDs declared.  */
        if (((parameter & 8) && len != 3) ||
                        (!(parameter & 8) && len != 1) ||
                        s->state != bt_state_ready) {
            ret = BT_HS_ERR_INVALID_PARAMETER;
            break;
        }
        if (parameter & 8)
            rlen = data[2] | (data[3] << 8);
        else
            rlen = INT_MAX;
        switch (parameter & 3) {
        case BT_DATA_OTHER:
            ret = BT_HS_ERR_INVALID_PARAMETER;
            break;
        case BT_DATA_INPUT:
            /* Here we can as well poll s->usbdev */
            bt_hid_send_data(s->control, BT_DATA_INPUT,
                            s->datain.buffer, MIN(rlen, s->datain.len));
            break;
        case BT_DATA_OUTPUT:
            bt_hid_send_data(s->control, BT_DATA_OUTPUT,
                            s->dataout.buffer, MIN(rlen, s->dataout.len));
            break;
        case BT_DATA_FEATURE:
            bt_hid_send_data(s->control, BT_DATA_FEATURE,
                            s->feature.buffer, MIN(rlen, s->feature.len));
            break;
        }
        break;

    case BT_SET_REPORT:
        if (len < 2 || len > BT_HID_MTU || s->state != bt_state_ready ||
                        (parameter & 3) == BT_DATA_OTHER ||
                        (parameter & 3) == BT_DATA_INPUT) {
            ret = BT_HS_ERR_INVALID_PARAMETER;
            break;
        }
        s->data_type = parameter & 3;
        if (s->data_type == BT_DATA_OUTPUT) {
            s->dataout.len = len - 1;
            memcpy(s->dataout.buffer, data + 1, s->dataout.len);
        } else {
            s->feature.len = len - 1;
            memcpy(s->feature.buffer, data + 1, s->feature.len);
        }
        if (len == BT_HID_MTU)
            s->state = bt_state_transaction;
        else
            bt_hid_out(s);
        break;

    case BT_GET_PROTOCOL:
        if (len != 1 || s->state == bt_state_transaction) {
            ret = BT_HS_ERR_INVALID_PARAMETER;
            break;
        }
        *s->control->sdu_out(s->control, 1) = s->proto;
        s->control->sdu_submit(s->control);
        break;

    case BT_SET_PROTOCOL:
        if (len != 1 || s->state == bt_state_transaction ||
                        (parameter != BT_HID_PROTO_BOOT &&
                         parameter != BT_HID_PROTO_REPORT)) {
            ret = BT_HS_ERR_INVALID_PARAMETER;
            break;
        }
        s->proto = parameter;
        s->usbdev->handle_control(s->usbdev, SET_PROTOCOL, s->proto, 0, 0,
                                  NULL);
        ret = BT_HS_SUCCESSFUL;
        break;

    case BT_GET_IDLE:
        if (len != 1 || s->state == bt_state_transaction) {
            ret = BT_HS_ERR_INVALID_PARAMETER;
            break;
        }
        s->usbdev->handle_control(s->usbdev, GET_IDLE, 0, 0, 1,
                        s->control->sdu_out(s->control, 1));
        s->control->sdu_submit(s->control);
        break;

    case BT_SET_IDLE:
        if (len != 2 || s->state == bt_state_transaction) {
            ret = BT_HS_ERR_INVALID_PARAMETER;
            break;
        }

        /* We don't need to know about the Idle Rate here really,
         * so just pass it on to the device.  */
        ret = s->usbdev->handle_control(s->usbdev,
                        SET_IDLE, data[1], 0, 0, NULL) ?
                BT_HS_SUCCESSFUL : BT_HS_ERR_INVALID_PARAMETER;
        /* XXX: Does this generate a handshake? */
        break;

    case BT_DATC:
        if (len > BT_HID_MTU || s->state != bt_state_transaction) {
            ret = BT_HS_ERR_INVALID_PARAMETER;
            break;
        }
        if (s->data_type == BT_DATA_OUTPUT) {
            memcpy(s->dataout.buffer + s->dataout.len, data + 1, len - 1);
            s->dataout.len += len - 1;
        } else {
            memcpy(s->feature.buffer + s->feature.len, data + 1, len - 1);
            s->feature.len += len - 1;
        }
        if (len < BT_HID_MTU) {
            bt_hid_out(s);
            s->state = bt_state_ready;
        }
        break;

    default:
        ret = BT_HS_ERR_UNSUPPORTED_REQUEST;
    }

    if (ret != -1)
        bt_hid_send_handshake(s, ret);
}

static void bt_hid_control_sdu(void *opaque, const uint8_t *data, int len)
{
    struct bt_hid_device_s *hid = opaque;

    return bt_hid_control_transaction(hid, data, len);
}

static void bt_hid_datain(void *opaque)
{
    struct bt_hid_device_s *hid = opaque;

    /* If suspended, wake-up and send a wake-up event first.  We might
     * want to also inspect the input report and ignore event like
     * mouse movements until a button event occurs.  */
    if (hid->state == bt_state_suspend) {
        hid->state = bt_state_ready;
    }

    if (bt_hid_in(hid) > 0)
        /* TODO: when in boot-mode precede any Input reports with the ReportID
         * byte, here and in GetReport/SetReport on the Control channel.  */
        bt_hid_send_data(hid->interrupt, BT_DATA_INPUT,
                        hid->datain.buffer, hid->datain.len);
}

static void bt_hid_interrupt_sdu(void *opaque, const uint8_t *data, int len)
{
    struct bt_hid_device_s *hid = opaque;

    if (len > BT_HID_MTU || len < 1)
        goto bad;
    if ((data[0] & 3) != BT_DATA_OUTPUT)
        goto bad;
    if ((data[0] >> 4) == BT_DATA) {
        if (hid->intr_state)
            goto bad;

        hid->data_type = BT_DATA_OUTPUT;
        hid->intrdataout.len = 0;
    } else if ((data[0] >> 4) == BT_DATC) {
        if (!hid->intr_state)
            goto bad;
    } else
        goto bad;

    memcpy(hid->intrdataout.buffer + hid->intrdataout.len, data + 1, len - 1);
    hid->intrdataout.len += len - 1;
    hid->intr_state = (len == BT_HID_MTU);
    if (!hid->intr_state) {
        memcpy(hid->dataout.buffer, hid->intrdataout.buffer,
                        hid->dataout.len = hid->intrdataout.len);
        bt_hid_out(hid);
    }

    return;
bad:
    fprintf(stderr, "%s: bad transaction on Interrupt channel.\n",
                    __FUNCTION__);
}

/* "Virtual cable" plug/unplug event.  */
static void bt_hid_connected_update(struct bt_hid_device_s *hid)
{
    int prev = hid->connected;

    hid->connected = hid->control && hid->interrupt;

    /* Stop page-/inquiry-scanning when a host is connected.  */
    hid->btdev.device.page_scan = !hid->connected;
    hid->btdev.device.inquiry_scan = !hid->connected;

    if (hid->connected && !prev) {
        hid->usbdev->handle_reset(hid->usbdev);
        hid->proto = BT_HID_PROTO_REPORT;
    }

    /* Should set HIDVirtualCable in SDP (possibly need to check that SDP
     * isn't destroyed yet, in case we're being called from handle_destroy) */
}

static void bt_hid_close_control(void *opaque)
{
    struct bt_hid_device_s *hid = opaque;

    hid->control = NULL;
    bt_hid_connected_update(hid);
}

static void bt_hid_close_interrupt(void *opaque)
{
    struct bt_hid_device_s *hid = opaque;

    hid->interrupt = NULL;
    bt_hid_connected_update(hid);
}

static int bt_hid_new_control_ch(struct bt_l2cap_device_s *dev,
                struct bt_l2cap_conn_params_s *params)
{
    struct bt_hid_device_s *hid = (struct bt_hid_device_s *) dev;

    if (hid->control)
        return 1;

    hid->control = params;
    hid->control->opaque = hid;
    hid->control->close = bt_hid_close_control;
    hid->control->sdu_in = bt_hid_control_sdu;

    bt_hid_connected_update(hid);

    return 0;
}

static int bt_hid_new_interrupt_ch(struct bt_l2cap_device_s *dev,
                struct bt_l2cap_conn_params_s *params)
{
    struct bt_hid_device_s *hid = (struct bt_hid_device_s *) dev;

    if (hid->interrupt)
        return 1;

    hid->interrupt = params;
    hid->interrupt->opaque = hid;
    hid->interrupt->close = bt_hid_close_interrupt;
    hid->interrupt->sdu_in = bt_hid_interrupt_sdu;

    bt_hid_connected_update(hid);

    return 0;
}

static void bt_hid_destroy(struct bt_device_s *dev)
{
    struct bt_hid_device_s *hid = (struct bt_hid_device_s *) dev;

    if (hid->connected)
        bt_hid_send_control(hid, BT_HC_VIRTUAL_CABLE_UNPLUG);
    bt_l2cap_device_done(&hid->btdev);

    hid->usbdev->handle_destroy(hid->usbdev);

    qemu_free(hid);
}

enum peripheral_minor_class {
    class_other		= 0 << 4,
    class_keyboard	= 1 << 4,
    class_pointing	= 2 << 4,
    class_combo		= 3 << 4,
};

static struct bt_device_s *bt_hid_init(struct bt_scatternet_s *net,
                USBDevice *dev, enum peripheral_minor_class minor)
{
    struct bt_hid_device_s *s = qemu_mallocz(sizeof(*s));
    uint32_t class =
            /* Format type */
            (0 << 0) |
            /* Device class */
            (minor << 2) |
            (5 << 8) |  /* "Peripheral" */
            /* Service classes */
            (1 << 13) | /* Limited discoverable mode */
            (1 << 19);  /* Capturing device (?) */

    bt_l2cap_device_init(&s->btdev, net);
    bt_l2cap_sdp_init(&s->btdev);
    bt_l2cap_psm_register(&s->btdev, BT_PSM_HID_CTRL,
                    BT_HID_MTU, bt_hid_new_control_ch);
    bt_l2cap_psm_register(&s->btdev, BT_PSM_HID_INTR,
                    BT_HID_MTU, bt_hid_new_interrupt_ch);

    s->usbdev = dev;
    s->btdev.device.lmp_name = s->usbdev->devname;
    usb_hid_datain_cb(s->usbdev, s, bt_hid_datain);

    s->btdev.device.handle_destroy = bt_hid_destroy;

    s->btdev.device.class[0] = (class >>  0) & 0xff;
    s->btdev.device.class[1] = (class >>  8) & 0xff;
    s->btdev.device.class[2] = (class >> 16) & 0xff;

    return &s->btdev.device;
}

struct bt_device_s *bt_keyboard_init(struct bt_scatternet_s *net)
{
    return bt_hid_init(net, usb_keyboard_init(), class_keyboard);
}
