/*
 * implement the Java card standard.
 *
 * 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 "vcard.h"
#include "vcard_emul.h"
#include "card_7816t.h"

struct VCardAppletStruct {
    VCardApplet   *next;
    VCardProcessAPDU process_apdu;
    VCardResetApplet reset_applet;
    unsigned char *aid;
    int aid_len;
    void *applet_private;
    VCardAppletPrivateFree applet_private_free;
};

struct VCardStruct {
    int reference_count;
    VCardApplet *applet_list;
    VCardApplet *current_applet[MAX_CHANNEL];
    VCardBufferResponse *vcard_buffer_response;
    VCardType type;
    VCardEmul *vcard_private;
    VCardEmulFree vcard_private_free;
    VCardGetAtr vcard_get_atr;
};

VCardBufferResponse *
vcard_buffer_response_new(unsigned char *buffer, int size)
{
    VCardBufferResponse *new_buffer;

    new_buffer = g_new(VCardBufferResponse, 1);
    new_buffer->buffer = (unsigned char *)g_memdup(buffer, size);
    new_buffer->buffer_len = size;
    new_buffer->current = new_buffer->buffer;
    new_buffer->len = size;
    return new_buffer;
}

void
vcard_buffer_response_delete(VCardBufferResponse *buffer_response)
{
    if (buffer_response == NULL) {
        return;
    }
    if (buffer_response->buffer) {
        g_free(buffer_response->buffer);
    }
    g_free(buffer_response);
}


/*
 * clean up state after a reset
 */
void
vcard_reset(VCard *card, VCardPower power)
{
    int i;
    VCardApplet *applet = NULL;

    if (card->type ==  VCARD_DIRECT) {
        /* select the last applet */
        VCardApplet *current_applet = NULL;
        for (current_applet = card->applet_list; current_applet;
                                       current_applet = current_applet->next) {
            applet = current_applet;
        }
    }
    for (i = 0; i < MAX_CHANNEL; i++) {
        card->current_applet[i] = applet;
    }
    if (card->vcard_buffer_response) {
        vcard_buffer_response_delete(card->vcard_buffer_response);
        card->vcard_buffer_response = NULL;
    }
    vcard_emul_reset(card, power);
    if (applet) {
        applet->reset_applet(card, 0);
    }
}

/* applet utilities */

/*
 * applet utilities
 */
/* constructor */
VCardApplet *
vcard_new_applet(VCardProcessAPDU applet_process_function,
                 VCardResetApplet applet_reset_function,
                 unsigned char *aid, int aid_len)
{
    VCardApplet *applet;

    applet = g_new0(VCardApplet, 1);
    applet->process_apdu = applet_process_function;
    applet->reset_applet = applet_reset_function;

    applet->aid = g_memdup(aid, aid_len);
    applet->aid_len = aid_len;
    return applet;
}

/* destructor */
void
vcard_delete_applet(VCardApplet *applet)
{
    if (applet == NULL) {
        return;
    }
    if (applet->applet_private_free) {
        applet->applet_private_free(applet->applet_private);
        applet->applet_private = NULL;
    }
    if (applet->aid) {
        g_free(applet->aid);
        applet->aid = NULL;
    }
    g_free(applet);
}

/* accessor */
void
vcard_set_applet_private(VCardApplet *applet, VCardAppletPrivate *private,
                         VCardAppletPrivateFree private_free)
{
    if (applet->applet_private_free) {
        applet->applet_private_free(applet->applet_private);
    }
    applet->applet_private = private;
    applet->applet_private_free = private_free;
}

VCard *
vcard_new(VCardEmul *private, VCardEmulFree private_free)
{
    VCard *new_card;

    new_card = g_new0(VCard, 1);
    new_card->type = VCARD_VM;
    new_card->vcard_private = private;
    new_card->vcard_private_free = private_free;
    new_card->reference_count = 1;
    return new_card;
}

VCard *
vcard_reference(VCard *vcard)
{
    if (vcard == NULL) {
        return NULL;
    }
    vcard->reference_count++;
    return vcard;
}

void
vcard_free(VCard *vcard)
{
    VCardApplet *current_applet;
    VCardApplet *next_applet;

    if (vcard == NULL) {
        return;
    }
    vcard->reference_count--;
    if (vcard->reference_count != 0) {
        return;
    }
    if (vcard->vcard_private_free) {
        (*vcard->vcard_private_free)(vcard->vcard_private);
        vcard->vcard_private_free = 0;
        vcard->vcard_private = 0;
    }
    for (current_applet = vcard->applet_list; current_applet;
                                        current_applet = next_applet) {
        next_applet = current_applet->next;
        vcard_delete_applet(current_applet);
    }
    vcard_buffer_response_delete(vcard->vcard_buffer_response);
    g_free(vcard);
}

void
vcard_get_atr(VCard *vcard, unsigned char *atr, int *atr_len)
{
    if (vcard->vcard_get_atr) {
        (*vcard->vcard_get_atr)(vcard, atr, atr_len);
        return;
    }
    vcard_emul_get_atr(vcard, atr, atr_len);
}

void
vcard_set_atr_func(VCard *card, VCardGetAtr vcard_get_atr)
{
    card->vcard_get_atr = vcard_get_atr;
}


VCardStatus
vcard_add_applet(VCard *card, VCardApplet *applet)
{
    applet->next = card->applet_list;
    card->applet_list = applet;
    /* if our card-type is direct, always call the applet */
    if (card->type ==  VCARD_DIRECT) {
        int i;

        for (i = 0; i < MAX_CHANNEL; i++) {
            card->current_applet[i] = applet;
        }
    }
    return VCARD_DONE;
}

/*
 * manage applets
 */
VCardApplet *
vcard_find_applet(VCard *card, unsigned char *aid, int aid_len)
{
    VCardApplet *current_applet;

    for (current_applet = card->applet_list; current_applet;
                                        current_applet = current_applet->next) {
        if (current_applet->aid_len != aid_len) {
            continue;
        }
        if (memcmp(current_applet->aid, aid, aid_len) == 0) {
            break;
        }
    }
    return current_applet;
}

unsigned char *
vcard_applet_get_aid(VCardApplet *applet, int *aid_len)
{
    if (applet == NULL) {
        return NULL;
    }
    *aid_len = applet->aid_len;
    return applet->aid;
}


void
vcard_select_applet(VCard *card, int channel, VCardApplet *applet)
{
    assert(channel < MAX_CHANNEL);
    card->current_applet[channel] = applet;
    /* reset the applet */
    if (applet && applet->reset_applet) {
        applet->reset_applet(card, channel);
    }
}

VCardAppletPrivate *
vcard_get_current_applet_private(VCard *card, int channel)
{
    VCardApplet *applet = card->current_applet[channel];

    if (applet == NULL) {
        return NULL;
    }
    return applet->applet_private;
}

VCardStatus
vcard_process_applet_apdu(VCard *card, VCardAPDU *apdu,
                          VCardResponse **response)
{
    if (card->current_applet[apdu->a_channel]) {
        return card->current_applet[apdu->a_channel]->process_apdu(
                                                        card, apdu, response);
    }
    return VCARD_NEXT;
}

/*
 * Accessor functions
 */
/* accessor functions for the response buffer */
VCardBufferResponse *
vcard_get_buffer_response(VCard *card)
{
    return card->vcard_buffer_response;
}

void
vcard_set_buffer_response(VCard *card, VCardBufferResponse *buffer)
{
    card->vcard_buffer_response = buffer;
}


/* accessor functions for the type */
VCardType
vcard_get_type(VCard *card)
{
    return card->type;
}

void
vcard_set_type(VCard *card, VCardType type)
{
    card->type = type;
}

/* accessor for private data */
VCardEmul *
vcard_get_private(VCard *vcard)
{
    return vcard->vcard_private;
}

