/[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 1352 by rousseau, Fri Feb 25 17:19:00 2005 UTC revision 1440 by rousseau, Tue Apr 26 12:07:44 2005 UTC
# Line 1  Line 1 
1  /*  /*
2      ifdhandler.c: IFDH API      ifdhandler.c: IFDH API
3      Copyright (C) 2003   Ludovic Rousseau      Copyright (C) 2003-2005   Ludovic Rousseau
4    
5      This program is free software; you can redistribute it and/or modify      This library is free software; you can redistribute it and/or
6      it under the terms of the GNU General Public License as published by      modify it under the terms of the GNU Lesser General Public
7      the Free Software Foundation; either version 2 of the License, or      License as published by the Free Software Foundation; either
8      (at your option) any later version.      version 2.1 of the License, or (at your option) any later version.
9    
10      This program is distributed in the hope that it will be useful,      This library is distributed in the hope that it will be useful,
11      but WITHOUT ANY WARRANTY; without even the implied warranty of      but WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      GNU General Public License for more details.      Lesser General Public License for more details.
14    
15      You should have received a copy of the GNU General Public License      You should have received a copy of the GNU Lesser General Public
16      along with this program; if not, write to the Free Software      License along with this library; if not, write to the Free Software
17      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
18  */  */
19    
20  /* $Id$ */  /* $Id$ */
# Line 54  static int DebugInitialized = FALSE; Line 54  static int DebugInitialized = FALSE;
54    
55  /* local functions */  /* local functions */
56  static void init_driver(void);  static void init_driver(void);
57    static void extra_egt(ATR_t *atr, _ccid_descriptor *ccid_desc, DWORD Protocol);
58    
59    
60  RESPONSECODE IFDHCreateChannelByName(DWORD Lun, LPTSTR lpcDevice)  RESPONSECODE IFDHCreateChannelByName(DWORD Lun, LPTSTR lpcDevice)
# Line 252  RESPONSECODE IFDHGetCapabilities(DWORD L Line 253  RESPONSECODE IFDHGetCapabilities(DWORD L
253                                  *Length : CcidSlots[reader_index].nATRLength;                                  *Length : CcidSlots[reader_index].nATRLength;
254    
255                          if (*Length)                          if (*Length)
256                                  memcpy(Value, CcidSlots[reader_index]                                  memcpy(Value, CcidSlots[reader_index].pcATRBuffer, *Length);
                                         .pcATRBuffer, *Length);  
257                          break;                          break;
258    
259  #ifdef HAVE_PTHREAD  #ifdef HAVE_PTHREAD
# Line 361  RESPONSECODE IFDHSetProtocolParameters(D Line 361  RESPONSECODE IFDHSetProtocolParameters(D
361           */           */
362    
363          BYTE pps[PPS_MAX_LENGTH];          BYTE pps[PPS_MAX_LENGTH];
364          ATR atr;          ATR_t atr;
365          unsigned int len;          unsigned int len;
366          int convention;          int convention;
367          int reader_index;          int reader_index;
# Line 383  RESPONSECODE IFDHSetProtocolParameters(D Line 383  RESPONSECODE IFDHSetProtocolParameters(D
383          ccid_slot = get_ccid_slot(reader_index);          ccid_slot = get_ccid_slot(reader_index);
384          ccid_desc = get_ccid_descriptor(reader_index);          ccid_desc = get_ccid_descriptor(reader_index);
385    
386            /* Do not send CCID command SetParameters or PPS to the CCID
387             * The CCID will do this himself */
388            if (ccid_desc->dwFeatures & CCID_CLASS_AUTO_PPS_PROP)
389                    return IFD_SUCCESS;
390    
391          /* Get ATR of the card */          /* Get ATR of the card */
392          ATR_InitFromArray(&atr, ccid_slot->pcATRBuffer, ccid_slot->nATRLength);          ATR_InitFromArray(&atr, ccid_slot->pcATRBuffer, ccid_slot->nATRLength);
393    
394            /* Apply Extra EGT patch for bogus cards */
395            extra_egt(&atr, ccid_desc, Protocol);
396    
397          if (SCARD_PROTOCOL_T0 == Protocol)          if (SCARD_PROTOCOL_T0 == Protocol)
398                  pps[1] |= ATR_PROTOCOL_TYPE_T0;                  pps[1] |= ATR_PROTOCOL_TYPE_T0;
399          else          else
# Line 529  RESPONSECODE IFDHSetProtocolParameters(D Line 537  RESPONSECODE IFDHSetProtocolParameters(D
537                          0x11,   /* Fi/Di                */                          0x11,   /* Fi/Di                */
538                          0x10,   /* TCCKS                */                          0x10,   /* TCCKS                */
539                          0x00,   /* GuardTime    */                          0x00,   /* GuardTime    */
540                          0x4D,   /* BWI/BCI              */                          0x4D,   /* BWI/CWI              */
541                          0x00,   /* ClockStop    */                          0x00,   /* ClockStop    */
542                          0x20,   /* IFSC                 */                          0x20,   /* IFSC                 */
543                          0x00    /* NADValue             */                          0x00    /* NADValue             */
# Line 541  RESPONSECODE IFDHSetProtocolParameters(D Line 549  RESPONSECODE IFDHSetProtocolParameters(D
549                  /* TA1 is not default */                  /* TA1 is not default */
550                  if (PPS_HAS_PPS1(pps))                  if (PPS_HAS_PPS1(pps))
551                          param[0] = pps[2];                          param[0] = pps[2];
552    
553                  /* CRC checksum? */                  /* CRC checksum? */
554                  if (2 == t1->rc_bytes)                  if (2 == t1->rc_bytes)
555                          param[1] |= 0x01;                          param[1] |= 0x01;
# Line 554  RESPONSECODE IFDHSetProtocolParameters(D Line 562  RESPONSECODE IFDHSetProtocolParameters(D
562                  if (atr.ib[0][ATR_INTERFACE_BYTE_TC].present)                  if (atr.ib[0][ATR_INTERFACE_BYTE_TC].present)
563                          param[2] = atr.ib[0][ATR_INTERFACE_BYTE_TC].value;                          param[2] = atr.ib[0][ATR_INTERFACE_BYTE_TC].value;
564    
565                  /* TBi (i>2) present? BWI/BCI */                  /* TBi (i>2) present? BWI/CWI */
566                  for (i=2; i<ATR_MAX_PROTOCOLS; i++)                  for (i=2; i<ATR_MAX_PROTOCOLS; i++)
567                          if (atr.ib[i][ATR_INTERFACE_BYTE_TB].present)                          if (atr.ib[i][ATR_INTERFACE_BYTE_TB].present)
568                          {                          {
569                                  DEBUG_COMM3("BWI/BCI (TB%d) present: %d", i+1,                                  DEBUG_COMM3("BWI/CWI (TB%d) present: 0x%02X", i+1,
570                                          atr.ib[i][ATR_INTERFACE_BYTE_TB].value);                                          atr.ib[i][ATR_INTERFACE_BYTE_TB].value);
571                                  param[3] = atr.ib[i][ATR_INTERFACE_BYTE_TB].value;                                  param[3] = atr.ib[i][ATR_INTERFACE_BYTE_TB].value;
572    
# Line 624  RESPONSECODE IFDHSetProtocolParameters(D Line 632  RESPONSECODE IFDHSetProtocolParameters(D
632                  /* IFSD not negociated by the reader? */                  /* IFSD not negociated by the reader? */
633                  if (! (ccid_desc->dwFeatures & CCID_CLASS_AUTO_IFSD))                  if (! (ccid_desc->dwFeatures & CCID_CLASS_AUTO_IFSD))
634                  {                  {
635                          DEBUG_COMM2("Negociate IFSD at %d",  ccid_desc -> dwMaxIFSD);                          DEBUG_COMM2("Negociate IFSD at %d", ccid_desc -> dwMaxIFSD);
636                          if (t1_negociate_ifsd(t1, 0, ccid_desc -> dwMaxIFSD) < 0)                          if (t1_negociate_ifsd(t1, 0, ccid_desc -> dwMaxIFSD) < 0)
637                                  return IFD_COMMUNICATION_ERROR;                                  return IFD_COMMUNICATION_ERROR;
638                  }                  }
# Line 697  RESPONSECODE IFDHPowerICC(DWORD Lun, DWO Line 705  RESPONSECODE IFDHPowerICC(DWORD Lun, DWO
705                          *CcidSlots[reader_index].pcATRBuffer = '\0';                          *CcidSlots[reader_index].pcATRBuffer = '\0';
706    
707                          /* Memorise the request */                          /* Memorise the request */
708                          CcidSlots[reader_index].bPowerFlags |=                          CcidSlots[reader_index].bPowerFlags |= MASK_POWERFLAGS_PDWN;
                                 MASK_POWERFLAGS_PDWN;  
709    
710                          /* send the command */                          /* send the command */
711                          if (IFD_SUCCESS != CmdPowerOff(reader_index))                          if (IFD_SUCCESS != CmdPowerOff(reader_index))
# Line 723  RESPONSECODE IFDHPowerICC(DWORD Lun, DWO Line 730  RESPONSECODE IFDHPowerICC(DWORD Lun, DWO
730                          }                          }
731    
732                          /* Power up successful, set state variable to memorise it */                          /* Power up successful, set state variable to memorise it */
733                          CcidSlots[reader_index].bPowerFlags |=                          CcidSlots[reader_index].bPowerFlags |= MASK_POWERFLAGS_PUP;
734                                  MASK_POWERFLAGS_PUP;                          CcidSlots[reader_index].bPowerFlags &= ~MASK_POWERFLAGS_PDWN;
                         CcidSlots[reader_index].bPowerFlags &=  
                                 ~MASK_POWERFLAGS_PDWN;  
735    
736                          /* Reset is returned, even if TCK is wrong */                          /* Reset is returned, even if TCK is wrong */
737                          CcidSlots[reader_index].nATRLength = *AtrLength =                          CcidSlots[reader_index].nATRLength = *AtrLength =
738                                  (nlength < MAX_ATR_SIZE) ? nlength : MAX_ATR_SIZE;                                  (nlength < MAX_ATR_SIZE) ? nlength : MAX_ATR_SIZE;
739                          memcpy(Atr, pcbuffer, *AtrLength);                          memcpy(Atr, pcbuffer, *AtrLength);
740                          memcpy(CcidSlots[reader_index].pcATRBuffer,                          memcpy(CcidSlots[reader_index].pcATRBuffer, pcbuffer, *AtrLength);
                                 pcbuffer, *AtrLength);  
741    
742                          /* initialise T=1 context */                          /* initialise T=1 context */
743                          t1_init(&(get_ccid_slot(reader_index) -> t1), reader_index);                          t1_init(&(get_ccid_slot(reader_index) -> t1), reader_index);
# Line 990  void init_driver(void) Line 994  void init_driver(void)
994                  LogLevel = strtoul(keyValue, NULL, 0);                  LogLevel = strtoul(keyValue, NULL, 0);
995    
996                  /* print the log level used */                  /* print the log level used */
997                  debug_msg("%s:%d:%s LogLevel: 0x%.4X", __FILE__, __LINE__, __FUNCTION__,                  DEBUG_INFO2("LogLevel: 0x%.4X", LogLevel);
                         LogLevel);  
998          }          }
999    
1000          /* Driver options */          /* Driver options */
# Line 1001  void init_driver(void) Line 1004  void init_driver(void)
1004                  DriverOptions = strtoul(keyValue, NULL, 0);                  DriverOptions = strtoul(keyValue, NULL, 0);
1005    
1006                  /* print the log level used */                  /* print the log level used */
1007                  debug_msg("%s:%d:%s DriverOptions: 0x%.4X", __FILE__, __LINE__,                  DEBUG_INFO2("DriverOptions: 0x%.4X", DriverOptions);
                         __FUNCTION__, DriverOptions);  
1008          }          }
1009    
1010          /* initialise the Lun to reader_index mapping */          /* initialise the Lun to reader_index mapping */
# Line 1011  void init_driver(void) Line 1013  void init_driver(void)
1013          DebugInitialized = TRUE;          DebugInitialized = TRUE;
1014  } /* init_driver */  } /* init_driver */
1015    
1016    
1017    void extra_egt(ATR_t *atr, _ccid_descriptor *ccid_desc, DWORD Protocol)
1018    {
1019            /*
1020             * This function apply an extra EGT value for card who comply
1021             * with followings criterias.
1022             * If the extra EGT are not apply to the reader, the communication
1023             * with the smart card will be impossible.
1024             * It is a smart card bug wich are not compatible with ISO 7816-3
1025             * standard.
1026             */
1027    
1028            int card_baudrate;
1029            int default_baudrate;
1030            int i;
1031            double f, d;
1032    
1033            /* if TA1 not present */
1034            if (! atr->ib[0][ATR_INTERFACE_BYTE_TA].present)
1035                    return;
1036    
1037            ATR_GetParameter(atr, ATR_PARAMETER_D, &d);
1038            ATR_GetParameter(atr, ATR_PARAMETER_F, &f);
1039    
1040            /* Baudrate = f x D/F */
1041            card_baudrate = 1000 * ccid_desc->dwDefaultClock * d / f;
1042    
1043            default_baudrate = 1000 * ccid_desc->dwDefaultClock
1044                    * ATR_DEFAULT_D / ATR_DEFAULT_F;
1045    
1046            /* TA1 > 11? */
1047            if (card_baudrate <= default_baudrate)
1048                    return;
1049    
1050            /* Current EGT = 0 or FF? */
1051            if (atr->ib[0][ATR_INTERFACE_BYTE_TC].present &&
1052                    ((0x00 == atr->ib[0][ATR_INTERFACE_BYTE_TC].value) ||
1053                    (0xFF == atr->ib[0][ATR_INTERFACE_BYTE_TC].value)))
1054            {
1055                    if (SCARD_PROTOCOL_T0 == Protocol)
1056                    {
1057                            /* Init TC1 */
1058                            atr->ib[0][ATR_INTERFACE_BYTE_TC].present = TRUE;
1059                            atr->ib[0][ATR_INTERFACE_BYTE_TC].value = 2;
1060                            DEBUG_INFO("Extra EGT patch applied");
1061                    }
1062    
1063                    if (SCARD_PROTOCOL_T1 == Protocol)
1064                    {
1065                            /* TBi (i>2) present? BWI/CWI */
1066                            for (i=2; i<ATR_MAX_PROTOCOLS; i++)
1067                            {
1068                                    /* CWI >= 2 ? */
1069                                    if (atr->ib[i][ATR_INTERFACE_BYTE_TB].present &&
1070                                            ((atr->ib[i][ATR_INTERFACE_BYTE_TB].value & 0x0F) >= 2))
1071                                    {
1072                                            /* Init TC1 */
1073                                            atr->ib[0][ATR_INTERFACE_BYTE_TC].present = TRUE;
1074                                            atr->ib[0][ATR_INTERFACE_BYTE_TC].value = 2;
1075                                            DEBUG_INFO("Extra EGT patch applied");
1076    
1077                                            /* only the first TBi (i>2) must be used */
1078                                            break;
1079                                    }
1080                            }
1081                    }
1082            }
1083    } /* extra_egt */
1084    

Legend:
Removed from v.1352  
changed lines
  Added in v.1440

  ViewVC Help
Powered by ViewVC 1.1.5