/*
 * 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;
    }
    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);
    }
    g_free(applet->aid);
    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);
    }
    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;
}

