[svn] GnuPG - r5075 - trunk/scd

svn author wk cvs at cvs.gnupg.org
Mon Jul 13 11:59:23 CEST 2009


Author: wk
Date: 2009-07-13 11:59:22 +0200 (Mon, 13 Jul 2009)
New Revision: 5075

Modified:
   trunk/scd/ChangeLog
   trunk/scd/apdu.c
   trunk/scd/app.c
   trunk/scd/ccid-driver.c
Log:
* ccid-driver.c (struct ccid_driver_s): Add fields last_progress,

progress_cb and progress_cb_arg.
(ccid_set_progress_cb): New.
(print_progress): New.
(ccid_transceive): Call print_progress for wait time extensions.
* apdu.c (struct reader_table_s): Add field set_progress_cb.
(new_reader_slot): Clear that field.
(open_ccid_reader): Set it to ..
(set_progress_cb_ccid_reader): ... new fucntion.
* app.c (print_progress_line): New.
(lock_reader): Add arg CTRL to set a progress callback and
change all callers to provide it.
(unlock_reader): Remove the progress callback.


Modified: trunk/scd/ChangeLog
===================================================================
--- trunk/scd/ChangeLog	2009-07-10 10:47:30 UTC (rev 5074)
+++ trunk/scd/ChangeLog	2009-07-13 09:59:22 UTC (rev 5075)
@@ -1,3 +1,19 @@
+2009-07-13  Werner Koch  <wk at g10code.com>
+
+	* ccid-driver.c (struct ccid_driver_s): Add fields last_progress,
+	progress_cb and progress_cb_arg.
+	(ccid_set_progress_cb): New.
+	(print_progress): New.
+	(ccid_transceive): Call print_progress for wait time extensions.
+	* apdu.c (struct reader_table_s): Add field set_progress_cb.
+	(new_reader_slot): Clear that field.
+	(open_ccid_reader): Set it to ..
+	(set_progress_cb_ccid_reader): ... new fucntion.
+	* app.c (print_progress_line): New.
+	(lock_reader): Add arg CTRL to set a progress callback and
+	change all callers to provide it.
+	(unlock_reader): Remove the progress callback.
+
 2009-07-10  Werner Koch  <wk at g10code.com>
 
 	* iso7816.c (iso7816_compute_ds): Add args EXTENDED_MODE and LE.

Modified: trunk/scd/apdu.c
===================================================================
--- trunk/scd/apdu.c	2009-07-10 10:47:30 UTC (rev 5074)
+++ trunk/scd/apdu.c	2009-07-13 09:59:22 UTC (rev 5075)
@@ -109,6 +109,7 @@
                           unsigned char *, size_t *, struct pininfo_s *);
   int (*check_keypad)(int, int, int, int, int, int);
   void (*dump_status_reader)(int);
+  int (*set_progress_cb)(int, gcry_handler_progress_t, void*);
 
   struct {
     ccid_driver_t handle;
@@ -339,6 +340,7 @@
   reader_table[reader].send_apdu_reader = NULL;
   reader_table[reader].check_keypad = NULL;
   reader_table[reader].dump_status_reader = NULL;
+  reader_table[reader].set_progress_cb = NULL;
 
   reader_table[reader].used = 1;  
   reader_table[reader].any_status = 0;
@@ -1835,6 +1837,15 @@
 
 
 static int
+set_progress_cb_ccid_reader (int slot, gcry_handler_progress_t cb, void *cb_arg)
+{
+  reader_table_t slotp = reader_table + slot;
+
+  return ccid_set_progress_cb (slotp->ccid.handle, cb, cb_arg);
+}
+
+
+static int
 get_status_ccid (int slot, unsigned int *status)
 {
   int rc;
@@ -1955,6 +1966,7 @@
   reader_table[slot].send_apdu_reader = send_apdu_ccid;
   reader_table[slot].check_keypad = check_ccid_keypad;
   reader_table[slot].dump_status_reader = dump_ccid_reader_status;
+  reader_table[slot].set_progress_cb = set_progress_cb_ccid_reader;
   /* Our CCID reader code does not support T=0 at all, thus reset the
      flag.  */
   reader_table[slot].is_t0 = 0;
@@ -2601,7 +2613,31 @@
 }
 
 
+/* Set the progress callback of SLOT to CB and its args to CB_ARG.  If
+   CB is NULL the progress callback is removed.  */
+int
+apdu_set_progress_cb (int slot, gcry_handler_progress_t cb, void *cb_arg)
+{
+  int sw;
 
+  if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
+    return SW_HOST_NO_DRIVER;
+
+  if (reader_table[slot].set_progress_cb)
+    {
+      sw = lock_slot (slot);
+      if (!sw)
+        {
+          sw = reader_table[slot].set_progress_cb (slot, cb, cb_arg);
+          unlock_slot (slot);
+        }
+    }
+  else
+    sw = 0;
+  return sw;
+}
+
+
 /* Do a reset for the card in reader at SLOT. */
 int
 apdu_reset (int slot)
@@ -2681,7 +2717,6 @@
 }
 
 
-
 unsigned char *
 apdu_get_atr (int slot, size_t *atrlen)
 {

Modified: trunk/scd/app.c
===================================================================
--- trunk/scd/app.c	2009-07-10 10:47:30 UTC (rev 5074)
+++ trunk/scd/app.c	2009-07-13 09:59:22 UTC (rev 5075)
@@ -48,6 +48,20 @@
 
 
 
+static void
+print_progress_line (void *opaque, const char *what, int pc, int cur, int tot)
+{
+  ctrl_t ctrl = opaque;
+  char line[100];
+
+  if (ctrl)
+    {
+      snprintf (line, sizeof line, "%s %c %d %d", what, pc, cur, tot);
+      send_status_direct (ctrl, "PROGRESS", line);
+    }
+}
+
+
 /* Lock the reader SLOT.  This function shall be used right before
    calling any of the actual application functions to serialize access
    to the reader.  We do this always even if the reader is not
@@ -56,7 +70,7 @@
    success; only then the unlock_reader function must be called after
    returning from the handler. */
 static gpg_error_t 
-lock_reader (int slot)
+lock_reader (int slot, ctrl_t ctrl)
 {
   gpg_error_t err;
 
@@ -84,6 +98,8 @@
       return err;
     }
 
+  apdu_set_progress_cb (slot, print_progress_line, ctrl);
+
   return 0;
 }
 
@@ -95,10 +111,11 @@
       || !lock_table[slot].initialized)
     log_bug ("unlock_reader called for invalid slot %d\n", slot);
 
+  apdu_set_progress_cb (slot, NULL, NULL);
+
   if (!pth_mutex_release (&lock_table[slot].lock))
     log_error ("failed to release APP lock for slot %d: %s\n",
                slot, strerror (errno));
-
 }
 
 
@@ -171,7 +188,7 @@
     return;
 
   /* FIXME: We are ignoring any error value here.  */
-  lock_reader (slot); 
+  lock_reader (slot, NULL); 
 
   /* Mark application as non-reusable.  */
   if (lock_table[slot].app)
@@ -229,7 +246,7 @@
 
   *r_app = NULL;
 
-  err = lock_reader (slot);
+  err = lock_reader (slot, ctrl);
   if (err)
     return err;
 
@@ -461,7 +478,7 @@
   /* Move the reference to the application in the lock table. */
   slot = app->slot;
   /* FIXME: We are ignoring any error value.  */
-  lock_reader (slot);
+  lock_reader (slot, NULL);
   if (lock_table[slot].app != app)
     {
       unlock_reader (slot);
@@ -579,7 +596,7 @@
   if (app->apptype && !(flags & 1))
     send_status_info (ctrl, "APPTYPE",
                       app->apptype, strlen (app->apptype), NULL, 0);
-  err = lock_reader (app->slot);
+  err = lock_reader (app->slot, ctrl);
   if (err)
     return err;
   err = app->fnc.learn_status (app, ctrl, flags);
@@ -604,7 +621,7 @@
     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
   if (!app->fnc.readcert)
     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
-  err = lock_reader (app->slot);
+  err = lock_reader (app->slot, NULL/* FIXME*/);
   if (err)
     return err;
   err = app->fnc.readcert (app, certid, cert, certlen);
@@ -636,7 +653,7 @@
     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
   if (!app->fnc.readkey)
     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
-  err = lock_reader (app->slot);
+  err = lock_reader (app->slot, NULL /*FIXME*/);
   if (err)
     return err;
   err= app->fnc.readkey (app, keyid, pk, pklen);
@@ -678,7 +695,7 @@
 
   if (!app->fnc.getattr)
     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
-  err = lock_reader (app->slot);
+  err = lock_reader (app->slot, ctrl);
   if (err)
     return err;
   err =  app->fnc.getattr (app, ctrl, name);
@@ -701,7 +718,7 @@
     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
   if (!app->fnc.setattr)
     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
-  err = lock_reader (app->slot);
+  err = lock_reader (app->slot, NULL /*FIXME*/);
   if (err)
     return err;
   err = app->fnc.setattr (app, name, pincb, pincb_arg, value, valuelen);
@@ -727,7 +744,7 @@
     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
   if (!app->fnc.sign)
     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
-  err = lock_reader (app->slot);
+  err = lock_reader (app->slot, NULL /*FIXME*/);
   if (err)
     return err;
   err = app->fnc.sign (app, keyidstr, hashalgo,
@@ -759,7 +776,7 @@
     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
   if (!app->fnc.auth)
     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
-  err = lock_reader (app->slot);
+  err = lock_reader (app->slot, NULL /*FIXME*/);
   if (err)
     return err;
   err = app->fnc.auth (app, keyidstr,
@@ -791,7 +808,7 @@
     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
   if (!app->fnc.decipher)
     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
-  err = lock_reader (app->slot);
+  err = lock_reader (app->slot, NULL /*FIXME*/);
   if (err)
     return err;
   err = app->fnc.decipher (app, keyidstr,
@@ -821,7 +838,7 @@
     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
   if (!app->fnc.writecert)
     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
-  err = lock_reader (app->slot);
+  err = lock_reader (app->slot, ctrl);
   if (err)
     return err;
   err = app->fnc.writecert (app, ctrl, certidstr,
@@ -849,7 +866,7 @@
     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
   if (!app->fnc.writekey)
     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
-  err = lock_reader (app->slot);
+  err = lock_reader (app->slot, ctrl);
   if (err)
     return err;
   err = app->fnc.writekey (app, ctrl, keyidstr, flags,
@@ -876,7 +893,7 @@
     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
   if (!app->fnc.genkey)
     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
-  err = lock_reader (app->slot);
+  err = lock_reader (app->slot, ctrl);
   if (err)
     return err;
   err = app->fnc.genkey (app, ctrl, keynostr, flags, 
@@ -900,7 +917,7 @@
     return gpg_error (GPG_ERR_INV_VALUE);
   if (!app->ref_count)
     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
-  err = lock_reader (app->slot);
+  err = lock_reader (app->slot, NULL /*FIXME*/);
   if (err)
     return err;
   err = iso7816_get_challenge (app->slot, nbytes, buffer);
@@ -924,7 +941,7 @@
     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
   if (!app->fnc.change_pin)
     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
-  err = lock_reader (app->slot);
+  err = lock_reader (app->slot, ctrl);
   if (err)
     return err;
   err = app->fnc.change_pin (app, ctrl, chvnostr, reset_mode,
@@ -952,7 +969,7 @@
     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
   if (!app->fnc.check_pin)
     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
-  err = lock_reader (app->slot);
+  err = lock_reader (app->slot, NULL /*FIXME*/);
   if (err)
     return err;
   err = app->fnc.check_pin (app, keyidstr, pincb, pincb_arg);

Modified: trunk/scd/ccid-driver.c
===================================================================
--- trunk/scd/ccid-driver.c	2009-07-10 10:47:30 UTC (rev 5074)
+++ trunk/scd/ccid-driver.c	2009-07-13 09:59:22 UTC (rev 5075)
@@ -254,6 +254,12 @@
   int apdu_level;     /* Reader supports short APDU level exchange.
                          With a value of 2 short and extended level is
                          supported.*/
+  time_t last_progress; /* Last time we sent progress line.  */
+
+  /* The progress callback and its first arg as supplied to
+     ccid_set_progress_cb.  */
+  void (*progress_cb)(void *, const char *, int, int, int);
+  void *progress_cb_arg;
 };
 
 
@@ -302,6 +308,23 @@
 }
 
 
+static void
+print_progress (ccid_driver_t handle)
+{
+  time_t ct = time (NULL);
+
+  /* We don't want to print progress lines too often. */
+  if (ct == handle->last_progress)
+    return;
+
+  if (handle->progress_cb)
+    handle->progress_cb (handle->progress_cb_arg, "card_busy", 'w', 0, 0);
+
+  handle->last_progress = ct;
+}
+
+
+
 /* Pint an error message for a failed CCID command including a textual
    error code.  MSG shall be the CCID message at a minimum of 10 bytes. */
 static void
@@ -1670,6 +1693,20 @@
 }
 
 
+int 
+ccid_set_progress_cb (ccid_driver_t handle, 
+                      void (*cb)(void *, const char *, int, int, int),
+                      void *cb_arg)
+{
+  if (!handle || !handle->rid)
+    return CCID_DRIVER_ERR_INV_VALUE;
+
+  handle->progress_cb = cb;
+  handle->progress_cb_arg = cb_arg;
+  return 0;
+}
+
+
 /* Close the reader HANDLE. */
 int 
 ccid_close_reader (ccid_driver_t handle)
@@ -2894,6 +2931,7 @@
                 tpdu[tpdulen++] = (edc >> 8);
               tpdu[tpdulen++] = edc;
               DEBUGOUT_1 ("T=1: waittime extension of bwi=%d\n", bwi);
+              print_progress (handle);
             }
           else if ( (tpdu[1] & 0x20) && (tpdu[1] & 0x1f) == 0 && !tpdu[2])
             {




More information about the Gnupg-commits mailing list