/*
 * 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, if not, see <http://www.gnu.org/licenses/>.
 */

#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->info->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->info->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->info->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->info->handle_control(s->usbdev, NULL, 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->info->handle_control(s->usbdev, NULL, 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->info->handle_control(s->usbdev, NULL,
                        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;

    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->info->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->info->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->product_desc;
    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)
{
    USBDevice *dev = usb_create_simple(NULL /* FIXME */, "usb-kbd");
    return bt_hid_init(net, dev, class_keyboard);
}
