static void *handle_apdu_thread(void* arg)

{

    EmulatedState *card = arg;

    uint8_t recv_data[APDU_BUF_SIZE];

    int recv_len;

    VReaderStatus reader_status;

    EmulEvent *event;



    while (1) {

        qemu_mutex_lock(&card->handle_apdu_mutex);

        qemu_cond_wait(&card->handle_apdu_cond, &card->handle_apdu_mutex);

        qemu_mutex_unlock(&card->handle_apdu_mutex);

        if (card->quit_apdu_thread) {

            card->quit_apdu_thread = 0; /* debugging */

            break;

        }

        qemu_mutex_lock(&card->vreader_mutex);

        while (!QSIMPLEQ_EMPTY(&card->guest_apdu_list)) {

            event = QSIMPLEQ_FIRST(&card->guest_apdu_list);

            assert((unsigned long)event > 1000);

            QSIMPLEQ_REMOVE_HEAD(&card->guest_apdu_list, entry);

            if (event->p.data.type != EMUL_GUEST_APDU) {

                DPRINTF(card, 1, "unexpected message in handle_apdu_thread\n");

                g_free(event);

                continue;

            }

            if (card->reader == NULL) {

                DPRINTF(card, 1, "reader is NULL\n");

                g_free(event);

                continue;

            }

            recv_len = sizeof(recv_data);

            reader_status = vreader_xfr_bytes(card->reader,

                    event->p.data.data, event->p.data.len,

                    recv_data, &recv_len);

            DPRINTF(card, 2, "got back apdu of length %d\n", recv_len);

            if (reader_status == VREADER_OK) {

                emulated_push_response_apdu(card, recv_data, recv_len);

            } else {

                emulated_push_error(card, reader_status);

            }

            g_free(event);

        }

        qemu_mutex_unlock(&card->vreader_mutex);

    }

    qemu_mutex_lock(&card->apdu_thread_quit_mutex);

    qemu_cond_signal(&card->apdu_thread_quit_cond);

    qemu_mutex_unlock(&card->apdu_thread_quit_mutex);

    return NULL;

}

static void *handle_apdu_thread(void* arg)

{

    EmulatedState *card = arg;

    uint8_t recv_data[APDU_BUF_SIZE];

    int recv_len;

    VReaderStatus reader_status;

    EmulEvent *event;



    while (1) {

        qemu_mutex_lock(&card->handle_apdu_mutex);

        qemu_cond_wait(&card->handle_apdu_cond, &card->handle_apdu_mutex);

        qemu_mutex_unlock(&card->handle_apdu_mutex);

        if (card->quit_apdu_thread) {

            card->quit_apdu_thread = 0; 

            break;

        }

        qemu_mutex_lock(&card->vreader_mutex);

        while (!QSIMPLEQ_EMPTY(&card->guest_apdu_list)) {

            event = QSIMPLEQ_FIRST(&card->guest_apdu_list);

            assert((unsigned long)event > 1000);

            QSIMPLEQ_REMOVE_HEAD(&card->guest_apdu_list, entry);

            if (event->p.data.type != EMUL_GUEST_APDU) {

                DPRINTF(card, 1, "unexpected message in handle_apdu_thread\n");

                g_free(event);

                continue;

            }

            if (card->reader == NULL) {

                DPRINTF(card, 1, "reader is NULL\n");

                g_free(event);

                continue;

            }

            recv_len = sizeof(recv_data);

            reader_status = vreader_xfr_bytes(card->reader,

                    event->p.data.data, event->p.data.len,

                    recv_data, &recv_len);

            DPRINTF(card, 2, "got back apdu of length %d\n", recv_len);

            if (reader_status == VREADER_OK) {

                emulated_push_response_apdu(card, recv_data, recv_len);

            } else {

                emulated_push_error(card, reader_status);

            }

            g_free(event);

        }

        qemu_mutex_unlock(&card->vreader_mutex);

    }

    qemu_mutex_lock(&card->apdu_thread_quit_mutex);

    qemu_cond_signal(&card->apdu_thread_quit_cond);

    qemu_mutex_unlock(&card->apdu_thread_quit_mutex);

    return NULL;

}

    qemu_mutex_lock(&card->apdu_thread_quit_mutex);     qemu_cond_signal(&card->apdu_thread_quit_cond);     qemu_mutex_unlock(&card->apdu_thread_quit_mutex);     qemu_mutex_lock(&card->apdu_thread_quit_mutex);
static void *FUNC_0(void* VAR_0)

{

    EmulatedState *card = VAR_0;

    uint8_t recv_data[APDU_BUF_SIZE];

    int VAR_1;

    VReaderStatus reader_status;

    EmulEvent *event;



    while (1) {

        qemu_mutex_lock(&card->handle_apdu_mutex);

        qemu_cond_wait(&card->handle_apdu_cond, &card->handle_apdu_mutex);

        qemu_mutex_unlock(&card->handle_apdu_mutex);

        if (card->quit_apdu_thread) {

            card->quit_apdu_thread = 0; 

            break;

        }

        qemu_mutex_lock(&card->vreader_mutex);

        while (!QSIMPLEQ_EMPTY(&card->guest_apdu_list)) {

            event = QSIMPLEQ_FIRST(&card->guest_apdu_list);

            assert((unsigned long)event > 1000);

            QSIMPLEQ_REMOVE_HEAD(&card->guest_apdu_list, entry);

            if (event->p.data.type != EMUL_GUEST_APDU) {

                DPRINTF(card, 1, "unexpected message in FUNC_0\n");

                g_free(event);

                continue;

            }

            if (card->reader == NULL) {

                DPRINTF(card, 1, "reader is NULL\n");

                g_free(event);

                continue;

            }

            VAR_1 = sizeof(recv_data);

            reader_status = vreader_xfr_bytes(card->reader,

                    event->p.data.data, event->p.data.len,

                    recv_data, &VAR_1);

            DPRINTF(card, 2, "got back apdu of length %d\n", VAR_1);

            if (reader_status == VREADER_OK) {

                emulated_push_response_apdu(card, recv_data, VAR_1);

            } else {

                emulated_push_error(card, reader_status);

            }

            g_free(event);

        }

        qemu_mutex_unlock(&card->vreader_mutex);

    }

    qemu_mutex_lock(&card->apdu_thread_quit_mutex);

    qemu_cond_signal(&card->apdu_thread_quit_cond);

    qemu_mutex_unlock(&card->apdu_thread_quit_mutex);

    return NULL;

}

static void *FUNC_0(void* VAR_0)
{ EmulatedState *card = VAR_0; uint8_t recv_data[APDU_BUF_SIZE]; int VAR_1; VReaderStatus reader_status; EmulEvent *event; while (1) { qemu_mutex_lock(&card->handle_apdu_mutex); qemu_cond_wait(&card->handle_apdu_cond, &card->handle_apdu_mutex); qemu_mutex_unlock(&card->handle_apdu_mutex); if (card->quit_apdu_thread) { card->quit_apdu_thread = 0; break; } qemu_mutex_lock(&card->vreader_mutex); while (!QSIMPLEQ_EMPTY(&card->guest_apdu_list)) { event = QSIMPLEQ_FIRST(&card->guest_apdu_list); assert((unsigned long)event > 1000); QSIMPLEQ_REMOVE_HEAD(&card->guest_apdu_list, entry); if (event->p.data.type != EMUL_GUEST_APDU) { DPRINTF(card, 1, "unexpected message in FUNC_0\n"); g_free(event); continue; } if (card->reader == NULL) { DPRINTF(card, 1, "reader is NULL\n"); g_free(event); continue; } VAR_1 = sizeof(recv_data); reader_status = vreader_xfr_bytes(card->reader,
event->p.data.data, event->p.data.len,
recv_data, &VAR_1); DPRINTF(card, 2, "got back apdu of length %d\n", VAR_1); if (reader_status == VREADER_OK) { emulated_push_response_apdu(card, recv_data, VAR_1); } else { emulated_push_error(card, reader_status); } g_free(event); } qemu_mutex_unlock(&card->vreader_mutex); } qemu_mutex_lock(&card->apdu_thread_quit_mutex); qemu_cond_signal(&card->apdu_thread_quit_cond); qemu_mutex_unlock(&card->apdu_thread_quit_mutex); return NULL; }