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

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

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

revision 892 by rousseau, Mon May 24 12:58:43 2004 UTC revision 2804 by rousseau, Thu Feb 7 13:50:04 2008 UTC
# Line 1  Line 1 
1  /*  /*
2      ccid.c: CCID common code      ccid.c: CCID common code
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  /*  /*
# Line 22  Line 22 
22   */   */
23    
24  #include <stdio.h>  #include <stdio.h>
25    #include <stdlib.h>
26    #include <string.h>
27  #include <pcsclite.h>  #include <pcsclite.h>
28  #include <ifdhandler.h>  #include <ifdhandler.h>
29    
# Line 31  Line 33 
33  #include "defs.h"  #include "defs.h"
34  #include "ccid_ifdhandler.h"  #include "ccid_ifdhandler.h"
35  #include "commands.h"  #include "commands.h"
36    #include "ccid_usb.h"
37    
38  /*****************************************************************************  /*****************************************************************************
39   *   *
40   *                                      ccid_open_hack   *                                      ccid_open_hack
41   *   *
42   ****************************************************************************/   ****************************************************************************/
43  int ccid_open_hack(int lun)  int ccid_open_hack(unsigned int reader_index)
44  {  {
45          _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(lun);          _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
46    
47          switch (ccid_descriptor->readerID)          switch (ccid_descriptor->readerID)
48          {          {
# Line 49  int ccid_open_hack(int lun) Line 52  int ccid_open_hack(int lun)
52                          ccid_descriptor->dwFeatures |= CCID_CLASS_TPDU;                          ccid_descriptor->dwFeatures |= CCID_CLASS_TPDU;
53                          break;                          break;
54    
                         /*  
                          * Do not switch to APDU mode since it also swicth in EMV mode and  
                          * may not work with non EMV cards  
                          */  
55                  case GEMPCKEY:                  case GEMPCKEY:
56                  case GEMPCTWIN:                  case GEMPCTWIN:
57                          /* Reader announces TPDU but can do APDU */                          /* Reader announces TPDU but can do APDU */
58                          if (DriverOptions & DRIVER_OPTION_GEMPC_TWIN_KEY_APDU)                          if (DriverOptions & DRIVER_OPTION_GEMPC_TWIN_KEY_APDU)
59                          {                          {
60                                  unsigned char cmd[] = "\xA0\x02";                                  unsigned char cmd[] = { 0xA0, 0x02 };
61                                  unsigned char res[10];                                  unsigned char res[10];
62                                  unsigned int length_res = sizeof(res);                                  unsigned int length_res = sizeof(res);
63    
64                                  if (CmdEscape(lun, cmd, sizeof(cmd)-1, res, &length_res) == IFD_SUCCESS)                                  if (CmdEscape(reader_index, cmd, sizeof(cmd), res, &length_res) == IFD_SUCCESS)
65                                  {                                  {
66                                          ccid_descriptor->dwFeatures &= ~CCID_CLASS_EXCHANGE_MASK;                                          ccid_descriptor->dwFeatures &= ~CCID_CLASS_EXCHANGE_MASK;
67                                          ccid_descriptor->dwFeatures |= CCID_CLASS_SHORT_APDU;                                          ccid_descriptor->dwFeatures |= CCID_CLASS_SHORT_APDU;
68                                  }                                  }
69                          }                          }
70                          break;                          break;
71    
72                    case GEMPCPINPAD:
73                            /* load the l10n strings in the pinpad memory */
74                            {
75    #define L10N_HEADER_SIZE 5
76    #define L10N_STRING_MAX_SIZE 16
77    #define L10N_NB_STRING 10
78    
79                                    unsigned char cmd[L10N_HEADER_SIZE + L10N_NB_STRING * L10N_STRING_MAX_SIZE];
80                                    unsigned char res[20];
81                                    unsigned int length_res = sizeof(res);
82                                    int offset, i, j;
83    
84                                    const char *fr[] = {
85                                            "Entrer PIN",
86                                            "Nouveau PIN",
87                                            "Confirmer PIN",
88                                            "PIN correct",
89                                            "PIN Incorrect !",
90                                            "Delai depasse",
91                                            "* essai restant",
92                                            "Inserer carte",
93                                            "Erreur carte",
94                                            "PIN bloque" };
95    
96                                    const char *de[] = {
97                                            "PIN eingeben",
98                                            "Neue PIN",
99                                            "PIN bestatigen",
100                                            "PIN korrect",
101                                            "Falsche PIN !",
102                                            "Zeit abgelaufen",
103                                            "* Versuche ubrig",
104                                            "Karte einstecken",
105                                            "Fehler Karte",
106                                            "PIN blockiert" };
107    
108                                    const char *es[] = {
109                                            "Introducir PIN",
110                                            "Nuevo PIN",
111                                            "Confirmar PIN",
112                                            "PIN OK",
113                                            "PIN Incorrecto !",
114                                            "Tiempo Agotado",
115                                            "* ensayos quedan",
116                                            "Introducir Tarj.",
117                                            "Error en Tarjeta",
118                                            "PIN bloqueado" };
119    
120                                    const char *it[] = {
121                                            "Inserire PIN",
122                                            "Nuovo PIN",
123                                            "Confermare PIN",
124                                            "PIN Corretto",
125                                            "PIN Errato !",
126                                            "Tempo scaduto",
127                                            "* prove rimaste",
128                                            "Inserire Carta",
129                                            "Errore Carta",
130                                            "PIN ostruito"};
131    
132                                    const char *pt[] = {
133                                            "Insira PIN",
134                                            "Novo PIN",
135                                            "Conf. novo PIN",
136                                            "PIN OK",
137                                            "PIN falhou!",
138                                            "Tempo expirou",
139                                            "* tentiv. restam",
140                                            "Introduza cartao",
141                                            "Erro cartao",
142                                            "PIN bloqueado" };
143    
144                                    const char *nl[] = {
145                                            "Inbrengen code",
146                                            "Nieuwe code",
147                                            "Bevestig code",
148                                            "Code aanvaard",
149                                            "Foute code",
150                                            "Time out",
151                                            "* Nog Pogingen",
152                                            "Kaart inbrengen",
153                                            "Kaart fout",
154                                            "Kaart blok" };
155    
156                                    const char *tr[] = {
157                                            "PIN Giriniz",
158                                            "Yeni PIN",
159                                            "PIN Onayala",
160                                            "PIN OK",
161                                            "Yanlis PIN",
162                                            "Zaman Asimi",
163                                            "* deneme kaldi",
164                                            "Karti Takiniz",
165                                            "Kart Hatasi",
166                                            "Kart Kilitli" };
167    
168                                    const char *en[] = {
169                                            "Enter PIN",
170                                            "New PIN",
171                                            "Confirm PIN",
172                                            "PIN OK",
173                                            "Incorrect PIN!",
174                                            "Time Out",
175                                            "* retries left",
176                                            "Insert Card",
177                                            "Card Error",
178                                            "PIN blocked" };
179    
180                                    char *lang;
181                                    const char **l10n;
182    
183                                    lang = getenv("LANG");
184                                    if (NULL == lang)
185                                            l10n = en;
186                                    else
187                                    {
188                                            if (0 == strncmp(lang, "fr", 2))
189                                                    l10n = fr;
190                                            else if (0 == strncmp(lang, "de", 2))
191                                                    l10n = de;
192                                            else if (0 == strncmp(lang, "es", 2))
193                                                    l10n = es;
194                                            else if (0 == strncmp(lang, "it", 2))
195                                                    l10n = it;
196                                            else if (0 == strncmp(lang, "pt", 2))
197                                                    l10n = pt;
198                                            else if (0 == strncmp(lang, "nl", 2))
199                                                    l10n = nl;
200                                            else if (0 == strncmp(lang, "tr", 2))
201                                                    l10n = tr;
202                                            else
203                                                    l10n = en;
204                                    }
205    
206                                    offset = 0;
207                                    cmd[offset++] = 0xB2;   /* load strings */
208                                    cmd[offset++] = 0xA0;   /* address of the memory */
209                                    cmd[offset++] = 0x00;   /* address of the first byte */
210                                    cmd[offset++] = 0x4D;   /* magic value */
211                                    cmd[offset++] = 0x4C;   /* magic value */
212    
213                                    /* for each string */
214                                    for (i=0; i<L10N_NB_STRING; i++)
215                                    {
216                                            /* copy the string */
217                                            for (j=0; l10n[i][j]; j++)
218                                                    cmd[offset++] = l10n[i][j];
219    
220                                            /* pad with " " */
221                                            for (; j<L10N_STRING_MAX_SIZE; j++)
222                                                    cmd[offset++] = ' ';
223                                    }
224    
225                                    if (IFD_SUCCESS == CmdEscape(reader_index, cmd, sizeof(cmd), res, &length_res))
226                                    {
227                                            DEBUG_COMM("l10n string loaded successfully");
228                                    }
229                                    else
230                                    {
231                                            DEBUG_COMM("Failed to load l10n strings");
232                                    }
233                            }
234                            break;
235    
236                    /* SCM SCR331-DI contactless */
237                    case SCR331DI:
238                    /* SCM SCR331-DI-NTTCOM contactless */
239                    case SCR331DINTTCOM:
240                    /* SCM SDI010 contactless */
241                    case SDI010:
242                            /* the contactless reader is in the second slot */
243                            if (ccid_descriptor->bCurrentSlotIndex > 0)
244                            {
245                                    unsigned char cmd1[] = { 0x00 };
246                                    /*  command: 00 ??
247                                     * response: 06 10 03 03 00 00 00 01 FE FF FF FE 01 ?? */
248                                    unsigned char cmd2[] = { 0x02 };
249                                    /*  command: 02 ??
250                                     * response: 00 ?? */
251    
252                                    unsigned char res[20];
253                                    unsigned int length_res = sizeof(res);
254    
255                                    if ((IFD_SUCCESS == CmdEscape(reader_index, cmd1, sizeof(cmd1), res, &length_res))
256                                            && (IFD_SUCCESS == CmdEscape(reader_index, cmd2, sizeof(cmd2), res, &length_res)))
257                                    {
258                                            DEBUG_COMM("SCM SCR331-DI contactless detected");
259                                    }
260                                    else
261                                    {
262                                            DEBUG_COMM("SCM SCR331-DI contactless init failed");
263                                    }
264    
265                                    /* hack since the contactless reader do not share dwFeatures */
266                                    ccid_descriptor->dwFeatures &= ~CCID_CLASS_EXCHANGE_MASK;
267                                    ccid_descriptor->dwFeatures |= CCID_CLASS_SHORT_APDU;
268    
269                                    ccid_descriptor->dwFeatures |= CCID_CLASS_AUTO_IFSD;
270                            }
271                            break;
272    
273                    case MYSMARTPAD:
274                            ccid_descriptor->dwMaxIFSD = 254;
275                            break;
276    
277                    case CL1356D:
278                            /* the firmware needs some time to initialize */
279                            sleep(1);
280                            ccid_descriptor->readTimeout = 60; /* 60 seconds */
281                            break;
282    
283                    case SEG:
284                            InterruptRead(reader_index);
285                            break;
286            }
287    
288            /* ICCD type A */
289            if (ICCD_A == ccid_descriptor->bInterfaceProtocol)
290            {
291                    unsigned char tmp[MAX_ATR_SIZE];
292                    unsigned int n = sizeof(tmp);
293    
294                    DEBUG_COMM("ICCD type A");
295                    CmdPowerOff(reader_index);
296                    CmdPowerOn(reader_index, &n, tmp, CCID_CLASS_AUTO_VOLTAGE);
297                    CmdPowerOff(reader_index);
298            }
299    
300            /* ICCD type B */
301            if (ICCD_B == ccid_descriptor->bInterfaceProtocol)
302            {
303                    unsigned char tmp[MAX_ATR_SIZE];
304                    unsigned int n = sizeof(tmp);
305    
306                    DEBUG_COMM("ICCD type B");
307                    if (CCID_CLASS_SHORT_APDU ==
308                            (ccid_descriptor->dwFeatures & CCID_CLASS_EXCHANGE_MASK))
309                    {
310                            /* use the extended APDU comm alogorithm */
311                            ccid_descriptor->dwFeatures &= ~CCID_CLASS_EXCHANGE_MASK;
312                            ccid_descriptor->dwFeatures |= CCID_CLASS_EXTENDED_APDU;
313                    }
314    
315                    CmdPowerOff(reader_index);
316                    CmdPowerOn(reader_index, &n, tmp, CCID_CLASS_AUTO_VOLTAGE);
317                    CmdPowerOff(reader_index);
318          }          }
319    
320          return 0;          return 0;
# Line 79  int ccid_open_hack(int lun) Line 325  int ccid_open_hack(int lun)
325   *                                      ccid_error   *                                      ccid_error
326   *   *
327   ****************************************************************************/   ****************************************************************************/
328  void ccid_error(int error, char *file, int line)  void ccid_error(int error, const char *file, int line, const char *function)
329  {  {
330          char *text;          const char *text;
331            char var_text[30];
332    
333          switch (error)          switch (error)
334          {          {
# Line 168  void ccid_error(int error, char *file, i Line 415  void ccid_error(int error, char *file, i
415                  case 0xFB:                  case 0xFB:
416                          text = "Hardware error";                          text = "Hardware error";
417                          break;                          break;
418    
419                  case 0xFC:                  case 0xFC:
420                          text = "Overrun error";                          text = "Overrun error";
421                          break;                          break;
# Line 188  void ccid_error(int error, char *file, i Line 435  void ccid_error(int error, char *file, i
435                  default:                  default:
436                          if ((error >= 1) && (error <= 127))                          if ((error >= 1) && (error <= 127))
437                          {                          {
                                 char var_text[20];  
   
438                                  sprintf(var_text, "error on byte %d", error);                                  sprintf(var_text, "error on byte %d", error);
439                                  text = var_text;                                  text = var_text;
440                          }                          }
441                          else                          else
442                                  text = "Unknown CCID error";                                  sprintf(var_text, "Unknown CCID error: 0x%02X", error);
443                                    text = var_text;
444                          break;                          break;
445          }          }
446          debug_msg("%s:%d %s", file, line, text);          log_msg(PCSC_LOG_ERROR, "%s:%d:%s %s", file, line, function, text);
447    
448  } /* ccid_error */  } /* ccid_error */
449    

Legend:
Removed from v.892  
changed lines
  Added in v.2804

  ViewVC Help
Powered by ViewVC 1.1.5