/*
 * 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/osdep.h"
#include "qemu/timer.h"
#include "ui/console.h"
#include "hw/input/hid.h"
#include "hw/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;
    HIDState hid;

    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);

    hid_reset(&s->hid);
    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)
{
    if (s->data_type == BT_DATA_OUTPUT) {
        /* nothing */
        ;
    }

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

    return -1;
}

static int bt_hid_in(struct bt_hid_device_s *s)
{
    s->datain.len = hid_keyboard_poll(&s->hid, s->datain.buffer,
                                      sizeof(s->datain.buffer));
    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->hid.protocol = parameter;
        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->control->sdu_out(s->control, 1) = s->hid.idle;
        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;
        }

        s->hid.idle = data[1];
        /* 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(HIDState *hs)
{
    struct bt_hid_device_s *hid =
        container_of(hs, struct bt_hid_device_s, hid);

    /* 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:
    error_report("%s: bad transaction on Interrupt channel.",
                    __func__);
}

/* "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_reset(&hid->hid);
        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_free(&hid->hid);

    g_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,
                                       enum peripheral_minor_class minor)
{
    struct bt_hid_device_s *s = g_malloc0(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);

    hid_init(&s->hid, HID_KEYBOARD, bt_hid_datain);
    s->btdev.device.lmp_name = "BT Keyboard";

    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, class_keyboard);
}
