* cardglue.c (card_close): New.
authorWerner Koch <wk@gnupg.org>
Fri, 10 Oct 2003 15:12:02 +0000 (15:12 +0000)
committerWerner Koch <wk@gnupg.org>
Fri, 10 Oct 2003 15:12:02 +0000 (15:12 +0000)
* ccid-driver.c (ccid_close_reader): New.
* apdu.c (close_ccid_reader, close_ct_reader, close_csc_reader)
(close_osc_reader, apdu_close_reader): New.  Not all are properly
implemented yet.
* g10.c (g10_exit): Use close_card.

g10/ChangeLog
g10/apdu.c
g10/apdu.h
g10/cardglue.c
g10/cardglue.h
g10/ccid-driver.c
g10/ccid-driver.h
g10/g10.c

index 9cfc794..f96e831 100644 (file)
@@ -1,3 +1,12 @@
+2003-10-10  Werner Koch  <wk@gnupg.org>
+
+       * cardglue.c (card_close): New.
+       * ccid-driver.c (ccid_close_reader): New.
+       * apdu.c (close_ccid_reader, close_ct_reader, close_csc_reader)
+       (close_osc_reader, apdu_close_reader): New.  Not all are properly
+       implemented yet.
+       * g10.c (g10_exit): Use close_card.
+
 2003-10-09  David Shaw  <dshaw@jabberwocky.com>
 
        * g10.c (main): Give a deprecated option warning for
index d5b93de..1587bfe 100644 (file)
@@ -347,6 +347,14 @@ open_ct_reader (int port)
   return reader;
 }
 
+static int
+close_ct_reader (int slot)
+{
+  /* FIXME: Implement. */
+  reader_table[slot].used = 0;
+  return 0;
+}
+
 
 /* Actually send the APDU of length APDULEN to SLOT and return a
    maximum of *BUFLEN data in BUFFER, the actual retruned size will be
@@ -570,6 +578,17 @@ pcsc_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
   return err? -1:0; /* FIXME: Return appropriate error code. */
 }
 
+static int
+close_pcsc_reader (int slot)
+{
+  /* FIXME: Implement. */
+  reader_table[slot].used = 0;
+  return 0;
+}
+
+
+
+
 \f
 #ifdef HAVE_LIBUSB
 /* 
@@ -609,6 +628,15 @@ open_ccid_reader (void)
   return slot;
 }
 
+static int
+close_ccid_reader (int slot)
+{
+  ccid_close_reader (reader_table[slot].ccid.handle);
+  reader_table[slot].used = 0;
+  return 0;
+}                       
+  
+
 
 /* Actually send the APDU of length APDULEN to SLOT and return a
    maximum of *BUFLEN data in BUFFER, the actual returned size will be
@@ -738,6 +766,16 @@ open_osc_reader (int portno)
 }
 
 
+static int
+close_osc_reader (int slot)
+{
+  /* FIXME: Implement. */
+  reader_table[slot].used = 0;
+  return 0;
+}
+
+
+
 /* Actually send the APDU of length APDULEN to SLOT and return a
    maximum of *BUFLEN data in BUFFER, the actual returned size will be
    set to BUFLEN.  Returns: OpenSC error code. */
@@ -940,6 +978,26 @@ apdu_open_reader (const char *portstr)
 }
 
 
+int
+apdu_close_reader (int slot)
+{
+  if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
+    return SW_HOST_NO_DRIVER;
+  if (reader_table[slot].is_ctapi)
+    return close_ct_reader (slot);
+#ifdef HAVE_LIBUSB
+  else if (reader_table[slot].is_ccid)
+    return close_ccid_reader (slot);
+#endif
+#ifdef HAVE_OPENSC
+  else if (reader_table[slot].is_osc)
+    return close_osc_reader (slot);
+#endif
+  else
+    return close_pcsc_reader (slot);
+}
+
+
 unsigned char *
 apdu_get_atr (int slot, size_t *atrlen)
 {
index 6e4244b..21e2b98 100644 (file)
@@ -54,6 +54,7 @@ enum {
 
 /* Note , that apdu_open_reader returns no status word but -1 on error. */
 int apdu_open_reader (const char *portstr);
+int apdu_close_reader (int slot);
 unsigned char *apdu_get_atr (int slot, size_t *atrlen);
 
 
index 91637a7..1bd36b3 100644 (file)
@@ -249,7 +249,7 @@ open_card (void)
   int rc;
   APP app;
 
-  current_app = NULL;/* FIXME: Release it first.*/
+  card_close ();
   slot = apdu_open_reader (default_reader_port);
   if (slot == -1)
     {
@@ -262,7 +262,7 @@ open_card (void)
   rc = app_select_openpgp (app, &app->serialno, &app->serialnolen);
   if (rc)
     {
-/*        apdu_close_reader (slot); */
+      apdu_close_reader (slot);
       log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc));
       xfree (app);
       return NULL;
@@ -273,6 +273,18 @@ open_card (void)
   return app;
 }
 
+void
+card_close (void)
+{
+  if (current_app)
+    {
+      APP app = current_app;
+      current_app = NULL;
+
+      apdu_close_reader (app->slot);
+      xfree (app);
+    }
+}
 
 
 /* Return a new malloced string by unescaping the string S.  Escaping
index fcd3726..b0ad8aa 100644 (file)
@@ -122,6 +122,8 @@ void log_printhex (const char *text, const void *buffer, size_t length);
 #define GCRY_MD_SHA1 DIGEST_ALGO_SHA1
 #define GCRY_MD_RMD160 DIGEST_ALGO_RMD160
 
+void card_close (void);
+
 
 /* Release the card info structure. */
 void agent_release_card_info (struct agent_card_info_s *info);
index 35f0329..f14600c 100644 (file)
@@ -174,6 +174,12 @@ struct ccid_driver_s {
 };
 
 
+static int bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen);
+static int bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length,
+                    size_t *nread, int expected_type, int seqno);
+
+
+
 /* Convert a little endian stored 4 byte value into an unsigned
    integer. */
 static unsigned int 
@@ -182,6 +188,16 @@ convert_le_u32 (const unsigned char *buf)
   return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); 
 }
 
+static void
+set_msg_len (unsigned char *msg, unsigned int length)
+{
+  msg[1] = length;
+  msg[2] = length >> 8;
+  msg[3] = length >> 16;
+  msg[4] = length >> 24;
+}
+
+
 
 
 /* Parse a CCID descriptor, optionally print all available features
@@ -482,22 +498,47 @@ ccid_open_reader (ccid_driver_t *handle, int readerno)
 }
 
 
-/* Return False if a card is present and powered. */
-int
-ccid_check_card_presence (ccid_driver_t handle)
+/* Close the reader HANDLE. */
+int 
+ccid_close_reader (ccid_driver_t handle)
 {
+  if (!handle || !handle->idev)
+    return 0;
 
-  return -1;
+   {
+     int rc;
+     unsigned char msg[100];
+     size_t msglen;
+     unsigned char seqno;
+   
+     msg[0] = PC_to_RDR_IccPowerOff;
+     msg[5] = 0; /* slot */
+     msg[6] = seqno = handle->seqno++;
+     msg[7] = 0; /* RFU */
+     msg[8] = 0; /* RFU */
+     msg[9] = 0; /* RFU */
+     set_msg_len (msg, 0);
+     msglen = 10;
+   
+     rc = bulk_out (handle, msg, msglen);
+     if (!rc)
+        bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_SlotStatus, seqno);
+   }
+   
+  usb_release_interface (handle->idev, 0);
+  usb_close (handle->idev);
+  handle->idev = NULL;
+  free (handle);
+  return 0;
 }
 
 
-static void
-set_msg_len (unsigned char *msg, unsigned int length)
+/* Return False if a card is present and powered. */
+int
+ccid_check_card_presence (ccid_driver_t handle)
 {
-  msg[1] = length;
-  msg[2] = length >> 8;
-  msg[3] = length >> 16;
-  msg[4] = length >> 24;
+
+  return -1;
 }
 
 
index 4d12d88..e33be55 100644 (file)
@@ -60,6 +60,7 @@ struct ccid_driver_s;
 typedef struct ccid_driver_s *ccid_driver_t;
 
 int ccid_open_reader (ccid_driver_t *handle, int readerno);
+int ccid_close_reader (ccid_driver_t handle);
 int ccid_get_atr (ccid_driver_t handle,
                   unsigned char *atr, size_t maxatrlen, size_t *atrlen);
 int ccid_transceive (ccid_driver_t handle,
index 34c8076..5dff576 100644 (file)
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -2980,6 +2980,9 @@ main( int argc, char **argv )
 void
 g10_exit( int rc )
 {
+#ifdef ENABLE_CARD_SUPPORT
+    card_close ();
+#endif
     update_random_seed_file();
     if( opt.debug & DBG_MEMSTAT_VALUE ) {
        m_print_stats("on exit");