/*
 * emulate the reader
 *
 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
 * See the COPYING.LIB file in the top-level directory.
 */

#include "qemu-common.h"
#include "qemu/thread.h"

#include "vcard.h"
#include "vcard_emul.h"
#include "card_7816.h"
#include "vreader.h"
#include "vevent.h"

struct VReaderStruct {
    int    reference_count;
    VCard *card;
    char *name;
    vreader_id_t id;
    QemuMutex lock;
    VReaderEmul  *reader_private;
    VReaderEmulFree reader_private_free;
};

/* manage locking */
static inline void
vreader_lock(VReader *reader)
{
    qemu_mutex_lock(&reader->lock);
}

static inline void
vreader_unlock(VReader *reader)
{
    qemu_mutex_unlock(&reader->lock);
}

/*
 * vreader constructor
 */
VReader *
vreader_new(const char *name, VReaderEmul *private,
            VReaderEmulFree private_free)
{
    VReader *reader;

    reader = (VReader *)g_malloc(sizeof(VReader));
    qemu_mutex_init(&reader->lock);
    reader->reference_count = 1;
    reader->name = name ? strdup(name) : NULL;
    reader->card = NULL;
    reader->id = (vreader_id_t)-1;
    reader->reader_private = private;
    reader->reader_private_free = private_free;
    return reader;
}

/* get a reference */
VReader*
vreader_reference(VReader *reader)
{
    if (reader == NULL) {
        return NULL;
    }
    vreader_lock(reader);
    reader->reference_count++;
    vreader_unlock(reader);
    return reader;
}

/* free a reference */
void
vreader_free(VReader *reader)
{
    if (reader == NULL) {
        return;
    }
    vreader_lock(reader);
    if (reader->reference_count-- > 1) {
        vreader_unlock(reader);
        return;
    }
    vreader_unlock(reader);
    if (reader->card) {
        vcard_free(reader->card);
    }
    if (reader->name) {
        g_free(reader->name);
    }
    if (reader->reader_private_free) {
        reader->reader_private_free(reader->reader_private);
    }
    g_free(reader);
}

static VCard *
vreader_get_card(VReader *reader)
{
    VCard *card;

    vreader_lock(reader);
    card = vcard_reference(reader->card);
    vreader_unlock(reader);
    return card;
}

VReaderStatus
vreader_card_is_present(VReader *reader)
{
    VCard *card = vreader_get_card(reader);

    if (card == NULL) {
        return VREADER_NO_CARD;
    }
    vcard_free(card);
    return VREADER_OK;
}

vreader_id_t
vreader_get_id(VReader *reader)
{
    if (reader == NULL) {
        return (vreader_id_t)-1;
    }
    return reader->id;
}

VReaderStatus
vreader_set_id(VReader *reader, vreader_id_t id)
{
    if (reader == NULL) {
        return VREADER_NO_CARD;
    }
    reader->id = id;
    return VREADER_OK;
}

const char *
vreader_get_name(VReader *reader)
{
    if (reader == NULL) {
        return NULL;
    }
    return reader->name;
}

VReaderEmul *
vreader_get_private(VReader *reader)
{
    return reader->reader_private;
}

static VReaderStatus
vreader_reset(VReader *reader, VCardPower power, unsigned char *atr, int *len)
{
    VCard *card = vreader_get_card(reader);

    if (card == NULL) {
        return VREADER_NO_CARD;
    }
    /*
     * clean up our state
     */
    vcard_reset(card, power);
    if (atr) {
        vcard_get_atr(card, atr, len);
    }
    vcard_free(card); /* free our reference */
    return VREADER_OK;
}

VReaderStatus
vreader_power_on(VReader *reader, unsigned char *atr, int *len)
{
    return vreader_reset(reader, VCARD_POWER_ON, atr, len);
}

VReaderStatus
vreader_power_off(VReader *reader)
{
    return vreader_reset(reader, VCARD_POWER_OFF, NULL, 0);
}


VReaderStatus
vreader_xfr_bytes(VReader *reader,
                  unsigned char *send_buf, int send_buf_len,
                  unsigned char *receive_buf, int *receive_buf_len)
{
    VCardAPDU *apdu;
    VCardResponse *response = NULL;
    VCardStatus card_status;
    unsigned short status;
    VCard *card = vreader_get_card(reader);

    if (card == NULL) {
        return VREADER_NO_CARD;
    }

    apdu = vcard_apdu_new(send_buf, send_buf_len, &status);
    if (apdu == NULL) {
        response = vcard_make_response(status);
        card_status = VCARD_DONE;
    } else {
        card_status = vcard_process_apdu(card, apdu, &response);
    }
    assert(card_status == VCARD_DONE);
    if (card_status == VCARD_DONE) {
        int size = MIN(*receive_buf_len, response->b_total_len);
        memcpy(receive_buf, response->b_data, size);
        *receive_buf_len = size;
    }
    vcard_response_delete(response);
    vcard_apdu_delete(apdu);
    vcard_free(card); /* free our reference */
    return VREADER_OK;
}

struct VReaderListStruct {
    VReaderListEntry *head;
    VReaderListEntry *tail;
};

struct VReaderListEntryStruct {
    VReaderListEntry *next;
    VReaderListEntry *prev;
    VReader *reader;
};


static VReaderListEntry *
vreader_list_entry_new(VReader *reader)
{
    VReaderListEntry *new_reader_list_entry;

    new_reader_list_entry = (VReaderListEntry *)
                               g_malloc(sizeof(VReaderListEntry));
    new_reader_list_entry->next = NULL;
    new_reader_list_entry->prev = NULL;
    new_reader_list_entry->reader = vreader_reference(reader);
    return new_reader_list_entry;
}

static void
vreader_list_entry_delete(VReaderListEntry *entry)
{
    if (entry == NULL) {
        return;
    }
    vreader_free(entry->reader);
    g_free(entry);
}


static VReaderList *
vreader_list_new(void)
{
    VReaderList *new_reader_list;

    new_reader_list = (VReaderList *)g_malloc(sizeof(VReaderList));
    new_reader_list->head = NULL;
    new_reader_list->tail = NULL;
    return new_reader_list;
}

void
vreader_list_delete(VReaderList *list)
{
    VReaderListEntry *current_entry;
    VReaderListEntry *next_entry = NULL;
    for (current_entry = vreader_list_get_first(list); current_entry;
         current_entry = next_entry) {
        next_entry = vreader_list_get_next(current_entry);
        vreader_list_entry_delete(current_entry);
    }
    list->head = NULL;
    list->tail = NULL;
    g_free(list);
}


VReaderListEntry *
vreader_list_get_first(VReaderList *list)
{
    return list ? list->head : NULL;
}

VReaderListEntry *
vreader_list_get_next(VReaderListEntry *current)
{
    return current ? current->next : NULL;
}

VReader *
vreader_list_get_reader(VReaderListEntry *entry)
{
    return entry ? vreader_reference(entry->reader) : NULL;
}

static void
vreader_queue(VReaderList *list, VReaderListEntry *entry)
{
    if (entry == NULL) {
        return;
    }
    entry->next = NULL;
    entry->prev = list->tail;
    if (list->head) {
        list->tail->next = entry;
    } else {
        list->head = entry;
    }
    list->tail = entry;
}

static void
vreader_dequeue(VReaderList *list, VReaderListEntry *entry)
{
    if (entry == NULL) {
        return;
    }
    if (entry->next == NULL) {
        list->tail = entry->prev;
    } else if (entry->prev == NULL) {
        list->head = entry->next;
    } else {
        entry->prev->next = entry->next;
        entry->next->prev = entry->prev;
    }
    if ((list->tail == NULL) || (list->head == NULL)) {
        list->head = list->tail = NULL;
    }
    entry->next = entry->prev = NULL;
}

static VReaderList *vreader_list;
static QemuMutex vreader_list_mutex;

static void
vreader_list_init(void)
{
    vreader_list = vreader_list_new();
    qemu_mutex_init(&vreader_list_mutex);
}

static void
vreader_list_lock(void)
{
    qemu_mutex_lock(&vreader_list_mutex);
}

static void
vreader_list_unlock(void)
{
    qemu_mutex_unlock(&vreader_list_mutex);
}

static VReaderList *
vreader_copy_list(VReaderList *list)
{
    VReaderList *new_list = NULL;
    VReaderListEntry *current_entry = NULL;

    new_list = vreader_list_new();
    if (new_list == NULL) {
        return NULL;
    }
    for (current_entry = vreader_list_get_first(list); current_entry;
         current_entry = vreader_list_get_next(current_entry)) {
        VReader *reader = vreader_list_get_reader(current_entry);
        VReaderListEntry *new_entry = vreader_list_entry_new(reader);

        vreader_free(reader);
        vreader_queue(new_list, new_entry);
    }
    return new_list;
}

VReaderList *
vreader_get_reader_list(void)
{
    VReaderList *new_reader_list;

    vreader_list_lock();
    new_reader_list = vreader_copy_list(vreader_list);
    vreader_list_unlock();
    return new_reader_list;
}

VReader *
vreader_get_reader_by_id(vreader_id_t id)
{
    VReader *reader = NULL;
    VReaderListEntry *current_entry = NULL;

    if (id == (vreader_id_t) -1) {
        return NULL;
    }

    vreader_list_lock();
    for (current_entry = vreader_list_get_first(vreader_list); current_entry;
            current_entry = vreader_list_get_next(current_entry)) {
        VReader *creader = vreader_list_get_reader(current_entry);
        if (creader->id == id) {
            reader = creader;
            break;
        }
        vreader_free(creader);
    }
    vreader_list_unlock();
    return reader;
}

VReader *
vreader_get_reader_by_name(const char *name)
{
    VReader *reader = NULL;
    VReaderListEntry *current_entry = NULL;

    vreader_list_lock();
    for (current_entry = vreader_list_get_first(vreader_list); current_entry;
            current_entry = vreader_list_get_next(current_entry)) {
        VReader *creader = vreader_list_get_reader(current_entry);
        if (strcmp(creader->name, name) == 0) {
            reader = creader;
            break;
        }
        vreader_free(creader);
    }
    vreader_list_unlock();
    return reader;
}

/* called from card_emul to initialize the readers */
VReaderStatus
vreader_add_reader(VReader *reader)
{
    VReaderListEntry *reader_entry;

    reader_entry = vreader_list_entry_new(reader);
    if (reader_entry == NULL) {
        return VREADER_OUT_OF_MEMORY;
    }
    vreader_list_lock();
    vreader_queue(vreader_list, reader_entry);
    vreader_list_unlock();
    vevent_queue_vevent(vevent_new(VEVENT_READER_INSERT, reader, NULL));
    return VREADER_OK;
}


VReaderStatus
vreader_remove_reader(VReader *reader)
{
    VReaderListEntry *current_entry;

    vreader_list_lock();
    for (current_entry = vreader_list_get_first(vreader_list); current_entry;
         current_entry = vreader_list_get_next(current_entry)) {
        if (current_entry->reader == reader) {
            break;
        }
    }
    vreader_dequeue(vreader_list, current_entry);
    vreader_list_unlock();
    vreader_list_entry_delete(current_entry);
    vevent_queue_vevent(vevent_new(VEVENT_READER_REMOVE, reader, NULL));
    return VREADER_OK;
}

/*
 * Generate VEVENT_CARD_INSERT or VEVENT_CARD_REMOVE based on vreader
 * state. Separated from vreader_insert_card to allow replaying events
 * for a given state.
 */
void
vreader_queue_card_event(VReader *reader)
{
    vevent_queue_vevent(vevent_new(
        reader->card ? VEVENT_CARD_INSERT : VEVENT_CARD_REMOVE, reader,
        reader->card));
}

/*
 * insert/remove a new card. for removal, card == NULL
 */
VReaderStatus
vreader_insert_card(VReader *reader, VCard *card)
{
    vreader_lock(reader);
    if (reader->card) {
        /* decrement reference count */
        vcard_free(reader->card);
        reader->card = NULL;
    }
    reader->card = vcard_reference(card);
    vreader_unlock(reader);
    vreader_queue_card_event(reader);
    return VREADER_OK;
}

/*
 * initialize all the static reader structures
 */
void
vreader_init(void)
{
    vreader_list_init();
}

