/*
 * CCID Passthru Card Device emulation
 *
 * Copyright (c) 2011 Red Hat.
 * Written by Alon Levy.
 *
 * This work is licensed under the terms of the GNU GPL, version 2.1 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu-char.h"
#include "qemu_socket.h"
#include "monitor.h"
#include "hw/ccid.h"
#include "libcacard/vscard_common.h"

#define DPRINTF(card, lvl, fmt, ...)                    \
do {                                                    \
    if (lvl <= card->debug) {                           \
        printf("ccid-card-passthru: " fmt , ## __VA_ARGS__);     \
    }                                                   \
} while (0)

#define D_WARN 1
#define D_INFO 2
#define D_MORE_INFO 3
#define D_VERBOSE 4

/* TODO: do we still need this? */
uint8_t DEFAULT_ATR[] = {
/*
 * From some example somewhere
 * 0x3B, 0xB0, 0x18, 0x00, 0xD1, 0x81, 0x05, 0xB1, 0x40, 0x38, 0x1F, 0x03, 0x28
 */

/* From an Athena smart card */
 0x3B, 0xD5, 0x18, 0xFF, 0x80, 0x91, 0xFE, 0x1F, 0xC3, 0x80, 0x73, 0xC8, 0x21,
 0x13, 0x08
};


#define PASSTHRU_DEV_NAME "ccid-card-passthru"
#define VSCARD_IN_SIZE 65536

/* maximum size of ATR - from 7816-3 */
#define MAX_ATR_SIZE        40

typedef struct PassthruState PassthruState;

struct PassthruState {
    CCIDCardState base;
    CharDriverState *cs;
    uint8_t  vscard_in_data[VSCARD_IN_SIZE];
    uint32_t vscard_in_pos;
    uint32_t vscard_in_hdr;
    uint8_t  atr[MAX_ATR_SIZE];
    uint8_t  atr_length;
    uint8_t  debug;
};

/*
 * VSCard protocol over chardev
 * This code should not depend on the card type.
 */

static void ccid_card_vscard_send_msg(PassthruState *s,
        VSCMsgType type, uint32_t reader_id,
        const uint8_t *payload, uint32_t length)
{
    VSCMsgHeader scr_msg_header;

    scr_msg_header.type = htonl(type);
    scr_msg_header.reader_id = htonl(reader_id);
    scr_msg_header.length = htonl(length);
    qemu_chr_fe_write(s->cs, (uint8_t *)&scr_msg_header, sizeof(VSCMsgHeader));
    qemu_chr_fe_write(s->cs, payload, length);
}

static void ccid_card_vscard_send_apdu(PassthruState *s,
    const uint8_t *apdu, uint32_t length)
{
    ccid_card_vscard_send_msg(
        s, VSC_APDU, VSCARD_MINIMAL_READER_ID, apdu, length);
}

static void ccid_card_vscard_send_error(PassthruState *s,
                    uint32_t reader_id, VSCErrorCode code)
{
    VSCMsgError msg = {.code = htonl(code)};

    ccid_card_vscard_send_msg(
        s, VSC_Error, reader_id, (uint8_t *)&msg, sizeof(msg));
}

static void ccid_card_vscard_send_init(PassthruState *s)
{
    VSCMsgInit msg = {
        .version = htonl(VSCARD_VERSION),
        .magic = VSCARD_MAGIC,
        .capabilities = {0}
    };

    ccid_card_vscard_send_msg(s, VSC_Init, VSCARD_UNDEFINED_READER_ID,
                         (uint8_t *)&msg, sizeof(msg));
}

static int ccid_card_vscard_can_read(void *opaque)
{
    PassthruState *card = opaque;

    return VSCARD_IN_SIZE >= card->vscard_in_pos ?
           VSCARD_IN_SIZE - card->vscard_in_pos : 0;
}

static void ccid_card_vscard_handle_init(
    PassthruState *card, VSCMsgHeader *hdr, VSCMsgInit *init)
{
    uint32_t *capabilities;
    int num_capabilities;
    int i;

    capabilities = init->capabilities;
    num_capabilities =
        1 + ((hdr->length - sizeof(VSCMsgInit)) / sizeof(uint32_t));
    init->version = ntohl(init->version);
    for (i = 0 ; i < num_capabilities; ++i) {
        capabilities[i] = ntohl(capabilities[i]);
    }
    if (init->magic != VSCARD_MAGIC) {
        error_report("wrong magic");
        /* we can't disconnect the chardev */
    }
    if (init->version != VSCARD_VERSION) {
        DPRINTF(card, D_WARN,
            "got version %d, have %d", init->version, VSCARD_VERSION);
    }
    /* future handling of capabilities, none exist atm */
    ccid_card_vscard_send_init(card);
}

static void ccid_card_vscard_handle_message(PassthruState *card,
    VSCMsgHeader *scr_msg_header)
{
    uint8_t *data = (uint8_t *)&scr_msg_header[1];

    switch (scr_msg_header->type) {
    case VSC_ATR:
        DPRINTF(card, D_INFO, "VSC_ATR %d\n", scr_msg_header->length);
        if (scr_msg_header->length > MAX_ATR_SIZE) {
            error_report("ATR size exceeds spec, ignoring");
            ccid_card_vscard_send_error(card, scr_msg_header->reader_id,
                                        VSC_GENERAL_ERROR);
            break;
        }
        memcpy(card->atr, data, scr_msg_header->length);
        card->atr_length = scr_msg_header->length;
        ccid_card_card_inserted(&card->base);
        ccid_card_vscard_send_error(card, scr_msg_header->reader_id,
                                    VSC_SUCCESS);
        break;
    case VSC_APDU:
        ccid_card_send_apdu_to_guest(
            &card->base, data, scr_msg_header->length);
        break;
    case VSC_CardRemove:
        DPRINTF(card, D_INFO, "VSC_CardRemove\n");
        ccid_card_card_removed(&card->base);
        ccid_card_vscard_send_error(card,
            scr_msg_header->reader_id, VSC_SUCCESS);
        break;
    case VSC_Init:
        ccid_card_vscard_handle_init(
            card, scr_msg_header, (VSCMsgInit *)data);
        break;
    case VSC_Error:
        ccid_card_card_error(&card->base, *(uint32_t *)data);
        break;
    case VSC_ReaderAdd:
        if (ccid_card_ccid_attach(&card->base) < 0) {
            ccid_card_vscard_send_error(card, VSCARD_UNDEFINED_READER_ID,
                                      VSC_CANNOT_ADD_MORE_READERS);
        } else {
            ccid_card_vscard_send_error(card, VSCARD_MINIMAL_READER_ID,
                                        VSC_SUCCESS);
        }
        break;
    case VSC_ReaderRemove:
        ccid_card_ccid_detach(&card->base);
        ccid_card_vscard_send_error(card,
            scr_msg_header->reader_id, VSC_SUCCESS);
        break;
    default:
        printf("usb-ccid: chardev: unexpected message of type %X\n",
               scr_msg_header->type);
        ccid_card_vscard_send_error(card, scr_msg_header->reader_id,
            VSC_GENERAL_ERROR);
    }
}

static void ccid_card_vscard_drop_connection(PassthruState *card)
{
    qemu_chr_delete(card->cs);
    card->vscard_in_pos = card->vscard_in_hdr = 0;
}

static void ccid_card_vscard_read(void *opaque, const uint8_t *buf, int size)
{
    PassthruState *card = opaque;
    VSCMsgHeader *hdr;

    if (card->vscard_in_pos + size > VSCARD_IN_SIZE) {
        error_report(
            "no room for data: pos %d +  size %d > %d. dropping connection.",
            card->vscard_in_pos, size, VSCARD_IN_SIZE);
        ccid_card_vscard_drop_connection(card);
        return;
    }
    assert(card->vscard_in_pos < VSCARD_IN_SIZE);
    assert(card->vscard_in_hdr < VSCARD_IN_SIZE);
    memcpy(card->vscard_in_data + card->vscard_in_pos, buf, size);
    card->vscard_in_pos += size;
    hdr = (VSCMsgHeader *)(card->vscard_in_data + card->vscard_in_hdr);

    while ((card->vscard_in_pos - card->vscard_in_hdr >= sizeof(VSCMsgHeader))
         &&(card->vscard_in_pos - card->vscard_in_hdr >=
                                  sizeof(VSCMsgHeader) + ntohl(hdr->length))) {
        hdr->reader_id = ntohl(hdr->reader_id);
        hdr->length = ntohl(hdr->length);
        hdr->type = ntohl(hdr->type);
        ccid_card_vscard_handle_message(card, hdr);
        card->vscard_in_hdr += hdr->length + sizeof(VSCMsgHeader);
        hdr = (VSCMsgHeader *)(card->vscard_in_data + card->vscard_in_hdr);
    }
    if (card->vscard_in_hdr == card->vscard_in_pos) {
        card->vscard_in_pos = card->vscard_in_hdr = 0;
    }
}

static void ccid_card_vscard_event(void *opaque, int event)
{
    PassthruState *card = opaque;

    switch (event) {
    case CHR_EVENT_BREAK:
        card->vscard_in_pos = card->vscard_in_hdr = 0;
        break;
    case CHR_EVENT_FOCUS:
        break;
    case CHR_EVENT_OPENED:
        DPRINTF(card, D_INFO, "%s: CHR_EVENT_OPENED\n", __func__);
        break;
    }
}

/* End VSCard handling */

static void passthru_apdu_from_guest(
    CCIDCardState *base, const uint8_t *apdu, uint32_t len)
{
    PassthruState *card = DO_UPCAST(PassthruState, base, base);

    if (!card->cs) {
        printf("ccid-passthru: no chardev, discarding apdu length %d\n", len);
        return;
    }
    ccid_card_vscard_send_apdu(card, apdu, len);
}

static const uint8_t *passthru_get_atr(CCIDCardState *base, uint32_t *len)
{
    PassthruState *card = DO_UPCAST(PassthruState, base, base);

    *len = card->atr_length;
    return card->atr;
}

static int passthru_initfn(CCIDCardState *base)
{
    PassthruState *card = DO_UPCAST(PassthruState, base, base);

    card->vscard_in_pos = 0;
    card->vscard_in_hdr = 0;
    if (card->cs) {
        DPRINTF(card, D_INFO, "initing chardev\n");
        qemu_chr_add_handlers(card->cs,
            ccid_card_vscard_can_read,
            ccid_card_vscard_read,
            ccid_card_vscard_event, card);
        ccid_card_vscard_send_init(card);
    } else {
        error_report("missing chardev");
        return -1;
    }
    assert(sizeof(DEFAULT_ATR) <= MAX_ATR_SIZE);
    memcpy(card->atr, DEFAULT_ATR, sizeof(DEFAULT_ATR));
    card->atr_length = sizeof(DEFAULT_ATR);
    return 0;
}

static int passthru_exitfn(CCIDCardState *base)
{
    return 0;
}

static VMStateDescription passthru_vmstate = {
    .name = PASSTHRU_DEV_NAME,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_BUFFER(vscard_in_data, PassthruState),
        VMSTATE_UINT32(vscard_in_pos, PassthruState),
        VMSTATE_UINT32(vscard_in_hdr, PassthruState),
        VMSTATE_BUFFER(atr, PassthruState),
        VMSTATE_UINT8(atr_length, PassthruState),
        VMSTATE_END_OF_LIST()
    }
};

static Property passthru_card_properties[] = {
    DEFINE_PROP_CHR("chardev", PassthruState, cs),
    DEFINE_PROP_UINT8("debug", PassthruState, debug, 0),
    DEFINE_PROP_END_OF_LIST(),
};

static void passthru_class_initfn(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    CCIDCardClass *cc = CCID_CARD_CLASS(klass);

    cc->initfn = passthru_initfn;
    cc->exitfn = passthru_exitfn;
    cc->get_atr = passthru_get_atr;
    cc->apdu_from_guest = passthru_apdu_from_guest;
    dc->desc = "passthrough smartcard";
    dc->vmsd = &passthru_vmstate;
    dc->props = passthru_card_properties;
}

static TypeInfo passthru_card_info = {
    .name          = PASSTHRU_DEV_NAME,
    .parent        = TYPE_CCID_CARD,
    .instance_size = sizeof(PassthruState),
    .class_init    = passthru_class_initfn,
};

static void ccid_card_passthru_register_types(void)
{
    type_register_static(&passthru_card_info);
}

type_init(ccid_card_passthru_register_types)
