/[pcsclite]/trunk/Drivers/ccid/src/ifdhandler.c
ViewVC logotype

Diff of /trunk/Drivers/ccid/src/ifdhandler.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2109 by rousseau, Wed Jul 12 08:30:26 2006 UTC revision 2197 by rousseau, Wed Nov 15 10:04:18 2006 UTC
# Line 22  Line 22 
22  #include <stdio.h>  #include <stdio.h>
23  #include <string.h>  #include <string.h>
24  #include <stdlib.h>  #include <stdlib.h>
25    #include <arpa/inet.h>
26  #include "misc.h"  #include "misc.h"
27  #include <pcsclite.h>  #include <pcsclite.h>
28  #include <ifdhandler.h>  #include <ifdhandler.h>
# Line 59  static int DebugInitialized = FALSE; Line 60  static int DebugInitialized = FALSE;
60  static void init_driver(void);  static void init_driver(void);
61  static void extra_egt(ATR_t *atr, _ccid_descriptor *ccid_desc, DWORD Protocol);  static void extra_egt(ATR_t *atr, _ccid_descriptor *ccid_desc, DWORD Protocol);
62  static char find_baud_rate(unsigned int baudrate, unsigned int *list);  static char find_baud_rate(unsigned int baudrate, unsigned int *list);
63  static unsigned int T0_card_timeout(double f, double d, int TC1, int TC2,  static unsigned int T0_card_timeout(double f, double d, int TC1, int TC2,
64          int clock_frequency);          int clock_frequency);
65  static unsigned int T1_card_timeout(double f, double d, int TC1, int BWI,  static unsigned int T1_card_timeout(double f, double d, int TC1, int BWI,
66          int CWI, int clock_frequency);          int CWI, int clock_frequency);
# Line 98  EXTERNAL RESPONSECODE IFDHCreateChannelB Line 99  EXTERNAL RESPONSECODE IFDHCreateChannelB
99                  ReleaseReaderIndex(reader_index);                  ReleaseReaderIndex(reader_index);
100          }          }
101          else          else
102            {
103                  /* Maybe we have a special treatment for this reader */                  /* Maybe we have a special treatment for this reader */
104                  ccid_open_hack(reader_index);                  ccid_open_hack(reader_index);
105    
106                    /* Try to access the reader */
107                    /* This "warm up" sequence is sometimes needed when pcscd is
108                     * restarted with the reader already connected. We get some
109                     * "usb_bulk_read: Resource temporarily unavailable" on the first
110                     * few tries. It is an empirical hack */
111                    if ((IFD_COMMUNICATION_ERROR == IFDHICCPresence(Lun))
112                            && (IFD_COMMUNICATION_ERROR == IFDHICCPresence(Lun))
113                            && (IFD_COMMUNICATION_ERROR == IFDHICCPresence(Lun)))
114                    {
115                            DEBUG_CRITICAL("failed");
116                            return_value = IFD_COMMUNICATION_ERROR;
117    
118                            /* release the allocated reader_index */
119                            ReleaseReaderIndex(reader_index);
120                    }
121            }
122    
123  #ifdef HAVE_PTHREAD  #ifdef HAVE_PTHREAD
124          pthread_mutex_unlock(&ifdh_context_mutex);          pthread_mutex_unlock(&ifdh_context_mutex);
125  #endif  #endif
# Line 303  EXTERNAL RESPONSECODE IFDHGetCapabilitie Line 322  EXTERNAL RESPONSECODE IFDHGetCapabilitie
322                          }                          }
323                          break;                          break;
324    
325                    case SCARD_ATTR_VENDOR_IFD_VERSION:
326                            /* Vendor-supplied interface device version (DWORD in the form
327                             * 0xMMmmbbbb where MM = major version, mm = minor version, and
328                             * bbbb = build number). */
329                            *Length = sizeof(DWORD);
330                            if (Value)
331                                    *(DWORD *)Value = CCID_VERSION;
332                            break;
333    
334                    case SCARD_ATTR_VENDOR_NAME:
335    #define VENDOR_NAME "Ludovic Rousseau"
336                            *Length = sizeof(VENDOR_NAME);
337                            if (Value)
338                                    memcpy(Value, VENDOR_NAME, sizeof(VENDOR_NAME));
339                            break;
340    
341                    case SCARD_ATTR_MAXINPUT:
342                            *Length = sizeof(uint32_t);
343                            if (Value)
344                                    *(uint32_t *)Value = get_ccid_descriptor(reader_index) -> dwMaxCCIDMessageLength -10;
345                            break;
346    
347                  default:                  default:
348                          return IFD_ERROR_TAG;                          return IFD_ERROR_TAG;
349          }          }
# Line 783  EXTERNAL RESPONSECODE IFDHPowerICC(DWORD Line 824  EXTERNAL RESPONSECODE IFDHPowerICC(DWORD
824          RESPONSECODE return_value = IFD_SUCCESS;          RESPONSECODE return_value = IFD_SUCCESS;
825          unsigned char pcbuffer[RESP_BUF_SIZE];          unsigned char pcbuffer[RESP_BUF_SIZE];
826          int reader_index;          int reader_index;
827            char *actions[] = { "PowerUp", "PowerDown", "Reset" };
828    
829          DEBUG_INFO2("lun: %X", Lun);          DEBUG_INFO3("lun: %X, action: %s", Lun, actions[Action-IFD_POWER_UP]);
830    
831          /* By default, assume it won't work :) */          /* By default, assume it won't work :) */
832          *AtrLength = 0;          *AtrLength = 0;
# Line 907  EXTERNAL RESPONSECODE IFDHTransmitToICC( Line 949  EXTERNAL RESPONSECODE IFDHTransmitToICC(
949    
950  EXTERNAL RESPONSECODE IFDHControl(DWORD Lun, DWORD dwControlCode,  EXTERNAL RESPONSECODE IFDHControl(DWORD Lun, DWORD dwControlCode,
951          PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, DWORD RxLength,          PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, DWORD RxLength,
952          PDWORD pdwBytesReturned)          PDWORD pdwBytesReturned)
953  {  {
954          /*          /*
955           * This function performs a data exchange with the reader (not the           * This function performs a data exchange with the reader (not the
# Line 954  EXTERNAL RESPONSECODE IFDHControl(DWORD Line 996  EXTERNAL RESPONSECODE IFDHControl(DWORD
996          }          }
997    
998          /* Implement the PC/SC v2.1.2 Part 10 IOCTL mechanism */          /* Implement the PC/SC v2.1.2 Part 10 IOCTL mechanism */
999    
1000          /* Query for features */          /* Query for features */
1001          if (CM_IOCTL_GET_FEATURE_REQUEST == dwControlCode)          if (CM_IOCTL_GET_FEATURE_REQUEST == dwControlCode)
1002          {          {
# Line 971  EXTERNAL RESPONSECODE IFDHControl(DWORD Line 1013  EXTERNAL RESPONSECODE IFDHControl(DWORD
1013                  {                  {
1014                          pcsc_tlv -> tag = FEATURE_VERIFY_PIN_DIRECT;                          pcsc_tlv -> tag = FEATURE_VERIFY_PIN_DIRECT;
1015                          pcsc_tlv -> length = 0x04; /* always 0x04 */                          pcsc_tlv -> length = 0x04; /* always 0x04 */
1016                          pcsc_tlv -> value = IOCTL_FEATURE_VERIFY_PIN_DIRECT;                          pcsc_tlv -> value = htonl(IOCTL_FEATURE_VERIFY_PIN_DIRECT);
1017    
1018                          pcsc_tlv++;                          pcsc_tlv++;
1019                          iBytesReturned += sizeof(PCSC_TLV_STRUCTURE);                          iBytesReturned += sizeof(PCSC_TLV_STRUCTURE);
1020                  }                  }
1021    
1022                  if (get_ccid_descriptor(reader_index) -> bPINSupport                  if (get_ccid_descriptor(reader_index) -> bPINSupport
1023                          & CCID_CLASS_PIN_MODIFY)                          & CCID_CLASS_PIN_MODIFY)
1024                  {                  {
1025                          pcsc_tlv -> tag = FEATURE_MODIFY_PIN_DIRECT;                          pcsc_tlv -> tag = FEATURE_MODIFY_PIN_DIRECT;
1026                          pcsc_tlv -> length = 0x04; /* always 0x04 */                          pcsc_tlv -> length = 0x04; /* always 0x04 */
1027                          pcsc_tlv -> value = IOCTL_FEATURE_MODIFY_PIN_DIRECT;                          pcsc_tlv -> value = htonl(IOCTL_FEATURE_MODIFY_PIN_DIRECT);
1028    
1029                          pcsc_tlv++;                          pcsc_tlv++;
1030                          iBytesReturned += sizeof(PCSC_TLV_STRUCTURE);                          iBytesReturned += sizeof(PCSC_TLV_STRUCTURE);
# Line 1067  EXTERNAL RESPONSECODE IFDHICCPresence(DW Line 1109  EXTERNAL RESPONSECODE IFDHICCPresence(DW
1109          switch (pcbuffer[7] & CCID_ICC_STATUS_MASK)     /* bStatus */          switch (pcbuffer[7] & CCID_ICC_STATUS_MASK)     /* bStatus */
1110          {          {
1111                  case CCID_ICC_PRESENT_ACTIVE:                  case CCID_ICC_PRESENT_ACTIVE:
                 case CCID_ICC_PRESENT_INACTIVE:  
1112                          return_value = IFD_ICC_PRESENT;                          return_value = IFD_ICC_PRESENT;
1113                          /* use default slot */                          /* use default slot */
1114                          break;                          break;
1115    
1116                    case CCID_ICC_PRESENT_INACTIVE:
1117                            if ((CcidSlots[reader_index].bPowerFlags == POWERFLAGS_RAZ)
1118                                    || (CcidSlots[reader_index].bPowerFlags & MASK_POWERFLAGS_PDWN))
1119                                    /* the card was previously absent */
1120                                    return_value = IFD_ICC_PRESENT;
1121                            else
1122                            {
1123                                    /* the card was previously present but has been
1124                                     * removed and inserted between two consecutive
1125                                     * IFDHICCPresence() calls */
1126                                    CcidSlots[reader_index].bPowerFlags = POWERFLAGS_RAZ;
1127                                    return_value = IFD_ICC_NOT_PRESENT;
1128                            }
1129                            break;
1130    
1131                  case CCID_ICC_ABSENT:                  case CCID_ICC_ABSENT:
1132                          /* Reset ATR buffer */                          /* Reset ATR buffer */
1133                          CcidSlots[reader_index].nATRLength = 0;                          CcidSlots[reader_index].nATRLength = 0;
# Line 1097  EXTERNAL RESPONSECODE IFDHICCPresence(DW Line 1153  EXTERNAL RESPONSECODE IFDHICCPresence(DW
1153    
1154                  unsigned char res[10];                  unsigned char res[10];
1155                  unsigned int length_res = sizeof(res);                  unsigned int length_res = sizeof(res);
1156                    RESPONSECODE ret;
1157    
1158                  /* if DEBUG_LEVEL_PERIODIC is not set we remove DEBUG_LEVEL_COMM */                  /* if DEBUG_LEVEL_PERIODIC is not set we remove DEBUG_LEVEL_COMM */
1159                  oldLogLevel = LogLevel;                  oldLogLevel = LogLevel;
1160                  if (! (LogLevel & DEBUG_LEVEL_PERIODIC))                  if (! (LogLevel & DEBUG_LEVEL_PERIODIC))
1161                          LogLevel &= ~DEBUG_LEVEL_COMM;                          LogLevel &= ~DEBUG_LEVEL_COMM;
1162    
1163                  CmdEscape(reader_index, cmd, sizeof(cmd), res, &length_res);                  ret = CmdEscape(reader_index, cmd, sizeof(cmd), res, &length_res);
1164    
1165                  /* set back the old LogLevel */                  /* set back the old LogLevel */
1166                  LogLevel = oldLogLevel;                  LogLevel = oldLogLevel;
1167    
1168                    if (ret != IFD_SUCCESS)
1169                    {
1170                            DEBUG_INFO("CmdEscape failed");
1171                            /* simulate a card absent */
1172                            res[0] = 0;
1173                    }
1174    
1175                  if (0x01 == res[0])                  if (0x01 == res[0])
1176                          return_value = IFD_ICC_PRESENT;                          return_value = IFD_ICC_PRESENT;
1177                  else                  else
# Line 1251  void extra_egt(ATR_t *atr, _ccid_descrip Line 1315  void extra_egt(ATR_t *atr, _ccid_descrip
1315                          for (i=2; i<ATR_MAX_PROTOCOLS; i++)                          for (i=2; i<ATR_MAX_PROTOCOLS; i++)
1316                          {                          {
1317                                  /* CWI >= 2 ? */                                  /* CWI >= 2 ? */
1318                                  if (atr->ib[i][ATR_INTERFACE_BYTE_TB].present &&                                  if (atr->ib[i][ATR_INTERFACE_BYTE_TB].present &&
1319                                          ((atr->ib[i][ATR_INTERFACE_BYTE_TB].value & 0x0F) >= 2))                                          ((atr->ib[i][ATR_INTERFACE_BYTE_TB].value & 0x0F) >= 2))
1320                                  {                                  {
1321                                          /* Init TC1 */                                          /* Init TC1 */
# Line 1316  static unsigned int T0_card_timeout(doub Line 1380  static unsigned int T0_card_timeout(doub
1380           * Terminal:                    Smart card:           * Terminal:                    Smart card:
1381           * 5 bytes header cmd  ->           * 5 bytes header cmd  ->
1382           *                                        <-        Procedure byte + 256 data bytes + SW1-SW2           *                                        <-        Procedure byte + 256 data bytes + SW1-SW2
1383           * = 5 EGT          + 1 WWT     + 259 WWT           * = 5 EGT          + 1 WWT     + 259 WWT
1384           */           */
1385    
1386          /* clock_frequency is in kHz so the times are in milliseconds and not          /* clock_frequency is in kHz so the times are in milliseconds and not
# Line 1362  static unsigned int T1_card_timeout(doub Line 1426  static unsigned int T1_card_timeout(doub
1426          /* Timeout applied on ISO in + ISO out card exchange          /* Timeout applied on ISO in + ISO out card exchange
1427           *           *
1428       * Timeout is the sum of:       * Timeout is the sum of:
1429           * - ISO in delay between leading edge of the first character sent by the           * - ISO in delay between leading edge of the first character sent by the
1430           *   interface device and the last one (NAD PCB LN APDU CKS) = 260 EGT,           *   interface device and the last one (NAD PCB LN APDU CKS) = 260 EGT,
1431           * - delay between ISO in and ISO out = BWT,           * - delay between ISO in and ISO out = BWT,
1432           * - ISO out delay between leading edge of the first character sent by the           * - ISO out delay between leading edge of the first character sent by the
1433           *   card and the last one (NAD PCB LN DATAS CKS) = 260 CWT.           *   card and the last one (NAD PCB LN DATAS CKS) = 260 CWT.
1434           */           */
1435    
1436          /* clock_frequency is in kHz so the times are in milliseconds and not          /* clock_frequency is in kHz so the times are in milliseconds and not

Legend:
Removed from v.2109  
changed lines
  Added in v.2197

  ViewVC Help
Powered by ViewVC 1.1.5