diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2013-03-01 13:59:19 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2013-04-08 18:13:12 +0200 |
commit | 49ab747f668f421138d5b40d83fa279c4c5e278d (patch) | |
tree | 943225a04eac885aed038731adf058f2250a2f40 /hw/ccid-card-passthru.c | |
parent | ce3b494cb504f96992f2d37ebc8f56deed202b06 (diff) |
hw: move target-independent files to subdirectories
This patch tackles all files that are compiled once, moving
them to subdirectories of hw/.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'hw/ccid-card-passthru.c')
-rw-r--r-- | hw/ccid-card-passthru.c | 351 |
1 files changed, 0 insertions, 351 deletions
diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c deleted file mode 100644 index 984bd0bf4c..0000000000 --- a/hw/ccid-card-passthru.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * 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 "char/char.h" -#include "qemu/sockets.h" -#include "monitor/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 const 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) |