qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Alon Levy <alevy@redhat.com>
To: qemu-devel@nongnu.org
Cc: mlureau@redhat.com
Subject: [Qemu-devel] [PATCH 09/26] libcacard: split vscclient main() from socket reading
Date: Mon, 18 Mar 2013 15:10:55 +0200	[thread overview]
Message-ID: <1363612272-13713-10-git-send-email-alevy@redhat.com> (raw)
In-Reply-To: <1363612272-13713-1-git-send-email-alevy@redhat.com>

From: Marc-André Lureau <marcandre.lureau@redhat.com>

---
 libcacard/vscclient.c | 314 ++++++++++++++++++++++++++------------------------
 1 file changed, 162 insertions(+), 152 deletions(-)

diff --git a/libcacard/vscclient.c b/libcacard/vscclient.c
index 9b744f2..5e00db3 100644
--- a/libcacard/vscclient.c
+++ b/libcacard/vscclient.c
@@ -211,6 +211,166 @@ get_id_from_string(char *string, unsigned int default_id)
     return id;
 }
 
+static int
+on_host_init(VSCMsgHeader *mhHeader, VSCMsgInit *incoming)
+{
+    uint32_t *capabilities = (incoming->capabilities);
+    int num_capabilities =
+        1 + ((mhHeader->length - sizeof(VSCMsgInit)) / sizeof(uint32_t));
+    int i;
+    int rv;
+    pthread_t thread_id;
+
+    incoming->version = ntohl(incoming->version);
+    if (incoming->version != VSCARD_VERSION) {
+        if (verbose > 0) {
+            printf("warning: host has version %d, we have %d\n",
+                verbose, VSCARD_VERSION);
+        }
+    }
+    if (incoming->magic != VSCARD_MAGIC) {
+        printf("unexpected magic: got %d, expected %d\n",
+            incoming->magic, VSCARD_MAGIC);
+        return -1;
+    }
+    for (i = 0 ; i < num_capabilities; ++i) {
+        capabilities[i] = ntohl(capabilities[i]);
+    }
+    /* Future: check capabilities */
+    /* remove whatever reader might be left in qemu,
+     * in case of an unclean previous exit. */
+    send_msg(VSC_ReaderRemove, VSCARD_MINIMAL_READER_ID, NULL, 0);
+    /* launch the event_thread. This will trigger reader adds for all the
+     * existing readers */
+    rv = pthread_create(&thread_id, NULL, event_thread, NULL);
+    if (rv < 0) {
+        perror("pthread_create");
+        return rv;
+    }
+    return 0;
+}
+
+#define APDUBufSize 270
+
+static int
+do_socket_read(void)
+{
+    int rv;
+    int dwSendLength;
+    int dwRecvLength;
+    uint8_t pbRecvBuffer[APDUBufSize];
+    uint8_t pbSendBuffer[APDUBufSize];
+    VReaderStatus reader_status;
+    VReader *reader = NULL;
+    VSCMsgHeader mhHeader;
+    VSCMsgError *error_msg;
+
+    rv = read(sock, &mhHeader, sizeof(mhHeader));
+    if (rv < sizeof(mhHeader)) {
+        /* Error */
+        if (rv < 0) {
+            perror("header read error\n");
+        } else {
+            fprintf(stderr, "header short read %d\n", rv);
+        }
+        return -1;
+    }
+    mhHeader.type = ntohl(mhHeader.type);
+    mhHeader.reader_id = ntohl(mhHeader.reader_id);
+    mhHeader.length = ntohl(mhHeader.length);
+    if (verbose) {
+        printf("Header: type=%d, reader_id=%u length=%d (0x%x)\n",
+               mhHeader.type, mhHeader.reader_id, mhHeader.length,
+               mhHeader.length);
+    }
+    switch (mhHeader.type) {
+    case VSC_APDU:
+    case VSC_Flush:
+    case VSC_Error:
+    case VSC_Init:
+        rv = read(sock, pbSendBuffer, mhHeader.length);
+        break;
+    default:
+        fprintf(stderr, "Unexpected message of type 0x%X\n", mhHeader.type);
+        return -1;
+    }
+    switch (mhHeader.type) {
+    case VSC_APDU:
+        if (rv < 0) {
+            /* Error */
+            fprintf(stderr, "read error\n");
+            close(sock);
+            return -1;
+        }
+        if (verbose) {
+            printf(" recv APDU: ");
+            print_byte_array(pbSendBuffer, mhHeader.length);
+        }
+        /* Transmit received APDU */
+        dwSendLength = mhHeader.length;
+        dwRecvLength = sizeof(pbRecvBuffer);
+        reader = vreader_get_reader_by_id(mhHeader.reader_id);
+        reader_status = vreader_xfr_bytes(reader,
+                                          pbSendBuffer, dwSendLength,
+                                          pbRecvBuffer, &dwRecvLength);
+        if (reader_status == VREADER_OK) {
+            mhHeader.length = dwRecvLength;
+            if (verbose) {
+                printf(" send response: ");
+                print_byte_array(pbRecvBuffer, mhHeader.length);
+            }
+            send_msg(VSC_APDU, mhHeader.reader_id,
+                     pbRecvBuffer, dwRecvLength);
+        } else {
+            rv = reader_status; /* warning: not meaningful */
+            send_msg(VSC_Error, mhHeader.reader_id, &rv, sizeof(uint32_t));
+        }
+        vreader_free(reader);
+        reader = NULL; /* we've freed it, don't use it by accident
+                          again */
+        break;
+    case VSC_Flush:
+        /* TODO: actually flush */
+        send_msg(VSC_FlushComplete, mhHeader.reader_id, NULL, 0);
+        break;
+    case VSC_Error:
+        error_msg = (VSCMsgError *) pbSendBuffer;
+        if (error_msg->code == VSC_SUCCESS) {
+            qemu_mutex_lock(&pending_reader_lock);
+            if (pending_reader) {
+                vreader_set_id(pending_reader, mhHeader.reader_id);
+                vreader_free(pending_reader);
+                pending_reader = NULL;
+                qemu_cond_signal(&pending_reader_condition);
+            }
+            qemu_mutex_unlock(&pending_reader_lock);
+            break;
+        }
+        printf("warning: qemu refused to add reader\n");
+        if (error_msg->code == VSC_CANNOT_ADD_MORE_READERS) {
+            /* clear pending reader, qemu can't handle any more */
+            qemu_mutex_lock(&pending_reader_lock);
+            if (pending_reader) {
+                pending_reader = NULL;
+                /* make sure the event loop doesn't hang */
+                qemu_cond_signal(&pending_reader_condition);
+            }
+            qemu_mutex_unlock(&pending_reader_lock);
+        }
+        break;
+    case VSC_Init:
+        if (on_host_init(&mhHeader, (VSCMsgInit *)pbSendBuffer) < 0) {
+            return -1;
+        }
+        break;
+    default:
+        printf("Default\n");
+        return -1;
+    }
+
+    return 0;
+}
+
 static void
 do_command(void)
 {
@@ -339,8 +499,6 @@ do_command(void)
 }
 
 
-#define APDUBufSize 270
-
 /* just for ease of parsing command line arguments. */
 #define MAX_CERTS 100
 
@@ -385,44 +543,6 @@ connect_to_qemu(
     return sock;
 }
 
-static int on_host_init(VSCMsgHeader *mhHeader, VSCMsgInit *incoming)
-{
-    uint32_t *capabilities = (incoming->capabilities);
-    int num_capabilities =
-        1 + ((mhHeader->length - sizeof(VSCMsgInit)) / sizeof(uint32_t));
-    int i;
-    int rv;
-    pthread_t thread_id;
-
-    incoming->version = ntohl(incoming->version);
-    if (incoming->version != VSCARD_VERSION) {
-        if (verbose > 0) {
-            printf("warning: host has version %d, we have %d\n",
-                verbose, VSCARD_VERSION);
-        }
-    }
-    if (incoming->magic != VSCARD_MAGIC) {
-        printf("unexpected magic: got %d, expected %d\n",
-            incoming->magic, VSCARD_MAGIC);
-        return -1;
-    }
-    for (i = 0 ; i < num_capabilities; ++i) {
-        capabilities[i] = ntohl(capabilities[i]);
-    }
-    /* Future: check capabilities */
-    /* remove whatever reader might be left in qemu,
-     * in case of an unclean previous exit. */
-    send_msg(VSC_ReaderRemove, VSCARD_MINIMAL_READER_ID, NULL, 0);
-    /* launch the event_thread. This will trigger reader adds for all the
-     * existing readers */
-    rv = pthread_create(&thread_id, NULL, event_thread, NULL);
-    if (rv < 0) {
-        perror("pthread_create");
-        return rv;
-    }
-    return 0;
-}
-
 int
 main(
     int argc,
@@ -431,21 +551,13 @@ main(
     char *qemu_host;
     char *qemu_port;
     VSCMsgHeader mhHeader;
-    VSCMsgError *error_msg;
 
-    int rv;
-    int dwSendLength;
-    int dwRecvLength;
-    uint8_t pbRecvBuffer[APDUBufSize];
-    uint8_t pbSendBuffer[APDUBufSize];
-     VReaderStatus reader_status;
-    VReader *reader = NULL;
     VCardEmulOptions *command_line_options = NULL;
 
     char *cert_names[MAX_CERTS];
     char *emul_args = NULL;
     int cert_count = 0;
-    int c;
+    int c, rv;
 
     while ((c = getopt(argc, argv, "c:e:pd:")) != -1) {
         switch (c) {
@@ -548,109 +660,7 @@ main(
         if (!FD_ISSET(sock, &fds)) {
             continue;
         }
-
-        rv = read(sock, &mhHeader, sizeof(mhHeader));
-        if (rv < sizeof(mhHeader)) {
-            /* Error */
-            if (rv < 0) {
-                perror("header read error\n");
-            } else {
-                fprintf(stderr, "header short read %d\n", rv);
-            }
-            return 8;
-        }
-        mhHeader.type = ntohl(mhHeader.type);
-        mhHeader.reader_id = ntohl(mhHeader.reader_id);
-        mhHeader.length = ntohl(mhHeader.length);
-        if (verbose) {
-            printf("Header: type=%d, reader_id=%u length=%d (0x%x)\n",
-                    mhHeader.type, mhHeader.reader_id, mhHeader.length,
-                                               mhHeader.length);
-        }
-        switch (mhHeader.type) {
-        case VSC_APDU:
-        case VSC_Flush:
-        case VSC_Error:
-        case VSC_Init:
-            rv = read(sock, pbSendBuffer, mhHeader.length);
-            break;
-        default:
-            fprintf(stderr, "Unexpected message of type 0x%X\n", mhHeader.type);
-            return 0;
-        }
-        switch (mhHeader.type) {
-        case VSC_APDU:
-            if (rv < 0) {
-                /* Error */
-                fprintf(stderr, "read error\n");
-                close(sock);
-                return 8;
-            }
-            if (verbose) {
-                printf(" recv APDU: ");
-                print_byte_array(pbSendBuffer, mhHeader.length);
-            }
-            /* Transmit received APDU */
-            dwSendLength = mhHeader.length;
-            dwRecvLength = sizeof(pbRecvBuffer);
-            reader = vreader_get_reader_by_id(mhHeader.reader_id);
-            reader_status = vreader_xfr_bytes(reader,
-                pbSendBuffer, dwSendLength,
-                pbRecvBuffer, &dwRecvLength);
-            if (reader_status == VREADER_OK) {
-                mhHeader.length = dwRecvLength;
-                if (verbose) {
-                    printf(" send response: ");
-                    print_byte_array(pbRecvBuffer, mhHeader.length);
-                }
-                send_msg(VSC_APDU, mhHeader.reader_id,
-                         pbRecvBuffer, dwRecvLength);
-            } else {
-                rv = reader_status; /* warning: not meaningful */
-                send_msg(VSC_Error, mhHeader.reader_id, &rv, sizeof(uint32_t));
-            }
-            vreader_free(reader);
-            reader = NULL; /* we've freed it, don't use it by accident
-                              again */
-            break;
-        case VSC_Flush:
-            /* TODO: actually flush */
-            send_msg(VSC_FlushComplete, mhHeader.reader_id, NULL, 0);
-            break;
-        case VSC_Error:
-            error_msg = (VSCMsgError *) pbSendBuffer;
-            if (error_msg->code == VSC_SUCCESS) {
-                qemu_mutex_lock(&pending_reader_lock);
-                if (pending_reader) {
-                    vreader_set_id(pending_reader, mhHeader.reader_id);
-                    vreader_free(pending_reader);
-                    pending_reader = NULL;
-                    qemu_cond_signal(&pending_reader_condition);
-                }
-                qemu_mutex_unlock(&pending_reader_lock);
-                break;
-            }
-            printf("warning: qemu refused to add reader\n");
-            if (error_msg->code == VSC_CANNOT_ADD_MORE_READERS) {
-                /* clear pending reader, qemu can't handle any more */
-                qemu_mutex_lock(&pending_reader_lock);
-                if (pending_reader) {
-                    pending_reader = NULL;
-                    /* make sure the event loop doesn't hang */
-                    qemu_cond_signal(&pending_reader_condition);
-                }
-                qemu_mutex_unlock(&pending_reader_lock);
-            }
-            break;
-        case VSC_Init:
-            if (on_host_init(&mhHeader, (VSCMsgInit *)pbSendBuffer) < 0) {
-                return -1;
-            }
-            break;
-        default:
-            printf("Default\n");
-            return 0;
-        }
+        rv = do_socket_read();
     } while (rv >= 0);
 
     return 0;
-- 
1.8.1.4

  parent reply	other threads:[~2013-03-18 13:11 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-18 13:10 [Qemu-devel] [PATCH 00/26] ccid and libcacard fixes for windows/mingw Alon Levy
2013-03-18 13:10 ` [Qemu-devel] [PATCH 01/26] libcacard: correct T0 historical bytes size Alon Levy
2013-03-18 13:10 ` [Qemu-devel] [PATCH 02/26] ccid-card-emul: do not crash if backend is not provided Alon Levy
2013-03-18 13:10 ` [Qemu-devel] [PATCH 03/26] ccid: make backend_enum_table "static const" and adjust users Alon Levy
2013-03-18 13:10 ` [Qemu-devel] [PATCH 04/26] ccid: declare DEFAULT_ATR table to be "static const" Alon Levy
2013-03-18 13:10 ` [Qemu-devel] [PATCH 05/26] libcacard: use system config directory for nss db on win32 Alon Levy
2013-03-18 13:10 ` [Qemu-devel] [PATCH 06/26] util: move socket_init() to osdep.c Alon Levy
2013-03-18 13:10 ` [Qemu-devel] [PATCH 07/26] build-sys: must link with -fstack-protector Alon Levy
2013-03-22 17:18   ` Paolo Bonzini
2013-03-18 13:10 ` [Qemu-devel] [PATCH 08/26] libcacard: fix mingw64 cross-compilation Alon Levy
2013-03-18 14:54   ` Paolo Bonzini
2013-03-18 13:10 ` Alon Levy [this message]
2013-03-18 13:10 ` [Qemu-devel] [PATCH 10/26] libcacard: vscclient to use QemuThread for portability Alon Levy
2013-03-18 13:10 ` [Qemu-devel] [PATCH 11/26] libcacard: teach vscclient to use GMainLoop " Alon Levy
2013-03-18 13:10 ` [Qemu-devel] [PATCH 12/26] hw/ccid-card-passthru.c: add atr check Alon Levy
2013-03-22 14:23   ` Marc-André Lureau
2013-03-22 19:31     ` Alon Levy
2013-03-18 13:10 ` [Qemu-devel] [PATCH 13/26] ccid-card-passthru, dev-smartcard-reader: add debug environment variables Alon Levy
2013-03-22 14:23   ` Marc-André Lureau
2013-03-18 13:11 ` [Qemu-devel] [PATCH 14/26] hw/usb/dev-smartcard-reader.c: white space fixes Alon Levy
2013-03-22 14:23   ` Marc-André Lureau
2013-03-18 13:11 ` [Qemu-devel] [PATCH 15/26] hw/usb/dev-smartcard-reader.c: nicer debug messages Alon Levy
2013-03-22 14:23   ` Marc-André Lureau
2013-03-18 13:11 ` [Qemu-devel] [PATCH 16/26] hw/usb/dev-smartcard-reader.c: remove aborts (never triggered, but just in case) Alon Levy
2013-03-22 14:23   ` Marc-André Lureau
2013-03-18 13:11 ` [Qemu-devel] [PATCH 17/26] hw/usb/dev-smartcard-reader.c: define structs for CCID_Parameter internals Alon Levy
2013-03-22 14:23   ` Marc-André Lureau
2013-03-18 13:11 ` [Qemu-devel] [PATCH 18/26] hw/usb/dev-smartcard-reader.c: copy atr's protocol to ccid's parameters (adds todo's) Alon Levy
2013-03-22 14:23   ` Marc-André Lureau
2013-03-27 15:06     ` Alon Levy
2013-03-18 13:11 ` [Qemu-devel] [PATCH 19/26] hw/usb/dev-smartcard-reader.c: dwFeadvertise support for T=0 only Alon Levy
2013-03-22 14:23   ` Marc-André Lureau
2013-03-18 13:11 ` [Qemu-devel] [PATCH 20/26] hw/usb/dev-smartcard-reader: support windows guest Alon Levy
2013-03-22 14:23   ` Marc-André Lureau
2013-03-18 13:11 ` [Qemu-devel] [PATCH 21/26] dev-smartcard-reader: reuse usb.h definitions Alon Levy
2013-03-22 14:22   ` Marc-André Lureau
2013-03-18 13:11 ` [Qemu-devel] [PATCH 22/26] libcacard/vreader: add debugging messages for apdu Alon Levy
2013-03-22 14:22   ` Marc-André Lureau
2013-03-18 13:11 ` [Qemu-devel] [PATCH 23/26] libcacard: change default ATR Alon Levy
2013-03-22 14:22   ` Marc-André Lureau
2013-03-18 13:11 ` [Qemu-devel] [PATCH 24/26] libcacard: move atr setting from macro to function Alon Levy
2013-03-22 14:22   ` Marc-André Lureau
2013-03-22 19:33     ` Alon Levy
2013-03-18 13:11 ` [Qemu-devel] [PATCH 25/26] dev-smartcard-reader: empty implementation for Mechanical (fail correctly) Alon Levy
2013-03-22 14:22   ` Marc-André Lureau
2013-03-18 13:11 ` [Qemu-devel] [PATCH 26/26] libcacard/cac.c: questionable change to single return of big switch functions Alon Levy
2013-03-22 14:22   ` Marc-André Lureau
2013-03-18 13:15 ` [Qemu-devel] [PATCH 00/26] ccid and libcacard fixes for windows/mingw Alon Levy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1363612272-13713-10-git-send-email-alevy@redhat.com \
    --to=alevy@redhat.com \
    --cc=mlureau@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).