mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-02 12:01:32 +01:00
* 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.
This commit is contained in:
parent
806b0acad7
commit
d0d4931e00
@ -1,3 +1,19 @@
|
||||
2009-07-13 Werner Koch <wk@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@g10code.com>
|
||||
|
||||
* iso7816.c (iso7816_compute_ds): Add args EXTENDED_MODE and LE.
|
||||
|
37
scd/apdu.c
37
scd/apdu.c
@ -109,6 +109,7 @@ struct reader_table_s {
|
||||
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 @@ new_reader_slot (void)
|
||||
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;
|
||||
@ -1834,6 +1836,15 @@ reset_ccid_reader (int slot)
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
@ -1955,6 +1966,7 @@ open_ccid_reader (const char *portstr)
|
||||
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,6 +2613,30 @@ apdu_disconnect (int slot)
|
||||
}
|
||||
|
||||
|
||||
/* 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
|
||||
@ -2681,7 +2717,6 @@ apdu_activate (int slot)
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned char *
|
||||
apdu_get_atr (int slot, size_t *atrlen)
|
||||
{
|
||||
|
55
scd/app.c
55
scd/app.c
@ -48,6 +48,20 @@ static void deallocate_app (app_t app);
|
||||
|
||||
|
||||
|
||||
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 @@ static void deallocate_app (app_t app);
|
||||
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 @@ lock_reader (int slot)
|
||||
return err;
|
||||
}
|
||||
|
||||
apdu_set_progress_cb (slot, print_progress_line, ctrl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -95,10 +111,11 @@ unlock_reader (int slot)
|
||||
|| !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 @@ application_notify_card_reset (int slot)
|
||||
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 @@ select_application (ctrl_t ctrl, int slot, const char *name, app_t *r_app)
|
||||
|
||||
*r_app = NULL;
|
||||
|
||||
err = lock_reader (slot);
|
||||
err = lock_reader (slot, ctrl);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -461,7 +478,7 @@ release_application (app_t app)
|
||||
/* 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 @@ app_write_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
|
||||
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 @@ app_readcert (app_t app, const char *certid,
|
||||
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 @@ app_readkey (app_t app, const char *keyid, unsigned char **pk, size_t *pklen)
|
||||
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 @@ app_getattr (app_t app, ctrl_t ctrl, const char *name)
|
||||
|
||||
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 @@ app_setattr (app_t app, const char *name,
|
||||
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 @@ app_sign (app_t app, const char *keyidstr, int hashalgo,
|
||||
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 @@ app_auth (app_t app, const char *keyidstr,
|
||||
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 @@ app_decipher (app_t app, const char *keyidstr,
|
||||
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 @@ app_writecert (app_t app, ctrl_t ctrl,
|
||||
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 @@ app_writekey (app_t app, ctrl_t ctrl,
|
||||
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 @@ app_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags,
|
||||
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 @@ app_get_challenge (app_t app, size_t nbytes, unsigned char *buffer)
|
||||
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 @@ app_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, int reset_mode,
|
||||
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 @@ app_check_pin (app_t app, const char *keyidstr,
|
||||
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);
|
||||
|
@ -254,6 +254,12 @@ struct ccid_driver_s
|
||||
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 @@ set_msg_len (unsigned char *msg, unsigned int length)
|
||||
}
|
||||
|
||||
|
||||
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 @@ ccid_shutdown_reader (ccid_driver_t handle)
|
||||
}
|
||||
|
||||
|
||||
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 @@ ccid_transceive (ccid_driver_t handle,
|
||||
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])
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user