event_thread(void *arg)

{

    unsigned char atr[MAX_ATR_LEN];

    int atr_len = MAX_ATR_LEN;

    VEvent *event = NULL;

    unsigned int reader_id;





    while (1) {

        const char *reader_name;



        event = vevent_wait_next_vevent();

        if (event == NULL) {

            break;

        }

        reader_id = vreader_get_id(event->reader);

        if (reader_id == VSCARD_UNDEFINED_READER_ID &&

            event->type != VEVENT_READER_INSERT) {

            /* ignore events from readers qemu has rejected */

            /* if qemu is still deciding on this reader, wait to see if need to

             * forward this event */

            qemu_mutex_lock(&pending_reader_lock);

            if (!pending_reader || (pending_reader != event->reader)) {

                /* wasn't for a pending reader, this reader has already been

                 * rejected by qemu */

                qemu_mutex_unlock(&pending_reader_lock);

                vevent_delete(event);

                continue;

            }

            /* this reader hasn't been told its status from qemu yet, wait for

             * that status */

            while (pending_reader != NULL) {

                qemu_cond_wait(&pending_reader_condition, &pending_reader_lock);

            }

            qemu_mutex_unlock(&pending_reader_lock);

            /* now recheck the id */

            reader_id = vreader_get_id(event->reader);

            if (reader_id == VSCARD_UNDEFINED_READER_ID) {

                /* this reader was rejected */

                vevent_delete(event);

                continue;

            }

            /* reader was accepted, now forward the event */

        }

        switch (event->type) {

        case VEVENT_READER_INSERT:

            /* tell qemu to insert a new CCID reader */

            /* wait until qemu has responded to our first reader insert

             * before we send a second. That way we won't confuse the responses

             * */

            qemu_mutex_lock(&pending_reader_lock);

            while (pending_reader != NULL) {

                qemu_cond_wait(&pending_reader_condition, &pending_reader_lock);

            }

            pending_reader = vreader_reference(event->reader);

            qemu_mutex_unlock(&pending_reader_lock);

            reader_name = vreader_get_name(event->reader);

            if (verbose > 10) {

                printf(" READER INSERT: %s\n", reader_name);

            }

            send_msg(VSC_ReaderAdd,

                reader_id, /* currerntly VSCARD_UNDEFINED_READER_ID */

                NULL, 0 /* TODO reader_name, strlen(reader_name) */);

            break;

        case VEVENT_READER_REMOVE:

            /* future, tell qemu that an old CCID reader has been removed */

            if (verbose > 10) {

                printf(" READER REMOVE: %u\n", reader_id);

            }

            send_msg(VSC_ReaderRemove, reader_id, NULL, 0);

            break;

        case VEVENT_CARD_INSERT:

            /* get the ATR (intended as a response to a power on from the

             * reader */

            atr_len = MAX_ATR_LEN;

            vreader_power_on(event->reader, atr, &atr_len);

            /* ATR call functions as a Card Insert event */

            if (verbose > 10) {

                printf(" CARD INSERT %u: ", reader_id);

                print_byte_array(atr, atr_len);

            }

            send_msg(VSC_ATR, reader_id, atr, atr_len);

            break;

        case VEVENT_CARD_REMOVE:

            /* Card removed */

            if (verbose > 10) {

                printf(" CARD REMOVE %u:\n", reader_id);

            }

            send_msg(VSC_CardRemove, reader_id, NULL, 0);

            break;

        default:

            break;

        }

        vevent_delete(event);

    }

    return NULL;

}

event_thread(void *arg)

{

    unsigned char atr[MAX_ATR_LEN];

    int atr_len = MAX_ATR_LEN;

    VEvent *event = NULL;

    unsigned int reader_id;





    while (1) {

        const char *reader_name;



        event = vevent_wait_next_vevent();

        if (event == NULL) {

            break;

        }

        reader_id = vreader_get_id(event->reader);

        if (reader_id == VSCARD_UNDEFINED_READER_ID &&

            event->type != VEVENT_READER_INSERT) {

            

            



            qemu_mutex_lock(&pending_reader_lock);

            if (!pending_reader || (pending_reader != event->reader)) {

                



                qemu_mutex_unlock(&pending_reader_lock);

                vevent_delete(event);

                continue;

            }

            



            while (pending_reader != NULL) {

                qemu_cond_wait(&pending_reader_condition, &pending_reader_lock);

            }

            qemu_mutex_unlock(&pending_reader_lock);

            

            reader_id = vreader_get_id(event->reader);

            if (reader_id == VSCARD_UNDEFINED_READER_ID) {

                

                vevent_delete(event);

                continue;

            }

            

        }

        switch (event->type) {

        case VEVENT_READER_INSERT:

            

            





            qemu_mutex_lock(&pending_reader_lock);

            while (pending_reader != NULL) {

                qemu_cond_wait(&pending_reader_condition, &pending_reader_lock);

            }

            pending_reader = vreader_reference(event->reader);

            qemu_mutex_unlock(&pending_reader_lock);

            reader_name = vreader_get_name(event->reader);

            if (verbose > 10) {

                printf(" READER INSERT: %s\n", reader_name);

            }

            send_msg(VSC_ReaderAdd,

                reader_id, 

                NULL, 0 );

            break;

        case VEVENT_READER_REMOVE:

            

            if (verbose > 10) {

                printf(" READER REMOVE: %u\n", reader_id);

            }

            send_msg(VSC_ReaderRemove, reader_id, NULL, 0);

            break;

        case VEVENT_CARD_INSERT:

            



            atr_len = MAX_ATR_LEN;

            vreader_power_on(event->reader, atr, &atr_len);

            

            if (verbose > 10) {

                printf(" CARD INSERT %u: ", reader_id);

                print_byte_array(atr, atr_len);

            }

            send_msg(VSC_ATR, reader_id, atr, atr_len);

            break;

        case VEVENT_CARD_REMOVE:

            

            if (verbose > 10) {

                printf(" CARD REMOVE %u:\n", reader_id);

            }

            send_msg(VSC_CardRemove, reader_id, NULL, 0);

            break;

        default:

            break;

        }

        vevent_delete(event);

    }

    return NULL;

}

FUNC_0(void *VAR_0)

{

    unsigned char VAR_1[MAX_ATR_LEN];

    int VAR_2 = MAX_ATR_LEN;

    VEvent *event = NULL;

    unsigned int VAR_3;





    while (1) {

        const char *VAR_4;



        event = vevent_wait_next_vevent();

        if (event == NULL) {

            break;

        }

        VAR_3 = vreader_get_id(event->reader);

        if (VAR_3 == VSCARD_UNDEFINED_READER_ID &&

            event->type != VEVENT_READER_INSERT) {

            

            



            qemu_mutex_lock(&pending_reader_lock);

            if (!pending_reader || (pending_reader != event->reader)) {

                



                qemu_mutex_unlock(&pending_reader_lock);

                vevent_delete(event);

                continue;

            }

            



            while (pending_reader != NULL) {

                qemu_cond_wait(&pending_reader_condition, &pending_reader_lock);

            }

            qemu_mutex_unlock(&pending_reader_lock);

            

            VAR_3 = vreader_get_id(event->reader);

            if (VAR_3 == VSCARD_UNDEFINED_READER_ID) {

                

                vevent_delete(event);

                continue;

            }

            

        }

        switch (event->type) {

        case VEVENT_READER_INSERT:

            

            





            qemu_mutex_lock(&pending_reader_lock);

            while (pending_reader != NULL) {

                qemu_cond_wait(&pending_reader_condition, &pending_reader_lock);

            }

            pending_reader = vreader_reference(event->reader);

            qemu_mutex_unlock(&pending_reader_lock);

            VAR_4 = vreader_get_name(event->reader);

            if (verbose > 10) {

                printf(" READER INSERT: %s\n", VAR_4);

            }

            send_msg(VSC_ReaderAdd,

                VAR_3, 

                NULL, 0 );

            break;

        case VEVENT_READER_REMOVE:

            

            if (verbose > 10) {

                printf(" READER REMOVE: %u\n", VAR_3);

            }

            send_msg(VSC_ReaderRemove, VAR_3, NULL, 0);

            break;

        case VEVENT_CARD_INSERT:

            



            VAR_2 = MAX_ATR_LEN;

            vreader_power_on(event->reader, VAR_1, &VAR_2);

            

            if (verbose > 10) {

                printf(" CARD INSERT %u: ", VAR_3);

                print_byte_array(VAR_1, VAR_2);

            }

            send_msg(VSC_ATR, VAR_3, VAR_1, VAR_2);

            break;

        case VEVENT_CARD_REMOVE:

            

            if (verbose > 10) {

                printf(" CARD REMOVE %u:\n", VAR_3);

            }

            send_msg(VSC_CardRemove, VAR_3, NULL, 0);

            break;

        default:

            break;

        }

        vevent_delete(event);

    }

    return NULL;

}

FUNC_0(void *VAR_0)
{ unsigned char VAR_1[MAX_ATR_LEN]; int VAR_2 = MAX_ATR_LEN; VEvent *event = NULL; unsigned int VAR_3; while (1) { const char *VAR_4; event = vevent_wait_next_vevent(); if (event == NULL) { break; } VAR_3 = vreader_get_id(event->reader); if (VAR_3 == VSCARD_UNDEFINED_READER_ID &&
event->type != VEVENT_READER_INSERT) { qemu_mutex_lock(&pending_reader_lock); if (!pending_reader || (pending_reader != event->reader)) { qemu_mutex_unlock(&pending_reader_lock); vevent_delete(event); continue; } while (pending_reader != NULL) { qemu_cond_wait(&pending_reader_condition, &pending_reader_lock); } qemu_mutex_unlock(&pending_reader_lock); VAR_3 = vreader_get_id(event->reader); if (VAR_3 == VSCARD_UNDEFINED_READER_ID) { vevent_delete(event); continue; } } switch (event->type) { case VEVENT_READER_INSERT:
qemu_mutex_lock(&pending_reader_lock); while (pending_reader != NULL) { qemu_cond_wait(&pending_reader_condition, &pending_reader_lock); } pending_reader = vreader_reference(event->reader); qemu_mutex_unlock(&pending_reader_lock); VAR_4 = vreader_get_name(event->reader); if (verbose > 10) { printf(" READER INSERT: %s\n", VAR_4); } send_msg(VSC_ReaderAdd,
VAR_3,
NULL, 0 ); break; case VEVENT_READER_REMOVE:
if (verbose > 10) { printf(" READER REMOVE: %u\n", VAR_3); } send_msg(VSC_ReaderRemove, VAR_3, NULL, 0); break; case VEVENT_CARD_INSERT:
VAR_2 = MAX_ATR_LEN; vreader_power_on(event->reader, VAR_1, &VAR_2); if (verbose > 10) { printf(" CARD INSERT %u: ", VAR_3); print_byte_array(VAR_1, VAR_2); } send_msg(VSC_ATR, VAR_3, VAR_1, VAR_2); break; case VEVENT_CARD_REMOVE:
if (verbose > 10) { printf(" CARD REMOVE %u:\n", VAR_3); } send_msg(VSC_CardRemove, VAR_3, NULL, 0); break; default:
break; } vevent_delete(event); } return NULL; }