/*
 * 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 = (VCardBufferResponse *)g_malloc(sizeof(VCardBufferResponse));
    new_buffer->buffer = (unsigned char *)g_malloc(size);
    memcpy(new_buffer->buffer, 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 = (VCardApplet *)g_malloc(sizeof(VCardApplet));
    applet->next = NULL;
    applet->applet_private = NULL;
    applet->applet_private_free = NULL;
    applet->process_apdu = applet_process_function;
    applet->reset_applet = applet_reset_function;

    applet->aid = g_malloc(aid_len);
    memcpy(applet->aid, 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;
    int i;

    new_card = (VCard *)g_malloc(sizeof(VCard));
    new_card->applet_list = NULL;
    for (i = 0; i < MAX_CHANNEL; i++) {
        new_card->current_applet[i] = NULL;
    }
    new_card->vcard_buffer_response = NULL;
    new_card->type = VCARD_VM;
    new_card->vcard_private = private;
    new_card->vcard_private_free = private_free;
    new_card->vcard_get_atr = NULL;
    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 = NULL;
    VCardApplet *next_applet = NULL;

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

