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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2804 - (hide annotations) (download)
Thu Feb 7 13:50:04 2008 UTC (5 years, 4 months ago) by rousseau
File MIME type: text/plain
File size: 10146 byte(s)
#include "ccid_usb.h" to get the declaration of InterruptRead()
1 rousseau 413 /*
2     ccid.c: CCID common code
3 rousseau 1411 Copyright (C) 2003-2005 Ludovic Rousseau
4 rousseau 413
5 rousseau 1399 This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9 rousseau 413
10 rousseau 1399 This library is distributed in the hope that it will be useful,
11 rousseau 413 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 rousseau 1399 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13     Lesser General Public License for more details.
14 rousseau 413
15 rousseau 1399 You should have received a copy of the GNU Lesser General Public
16     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
18 rousseau 413 */
19    
20     /*
21     * $Id$
22     */
23    
24 rousseau 879 #include <stdio.h>
25 rousseau 1796 #include <stdlib.h>
26     #include <string.h>
27 rousseau 1771 #include <pcsclite.h>
28     #include <ifdhandler.h>
29 rousseau 879
30 rousseau 413 #include "config.h"
31     #include "debug.h"
32 rousseau 879 #include "ccid.h"
33 rousseau 611 #include "defs.h"
34 rousseau 879 #include "ccid_ifdhandler.h"
35 rousseau 413 #include "commands.h"
36 rousseau 2804 #include "ccid_usb.h"
37 rousseau 413
38     /*****************************************************************************
39     *
40     * ccid_open_hack
41     *
42     ****************************************************************************/
43 rousseau 1106 int ccid_open_hack(unsigned int reader_index)
44 rousseau 413 {
45 rousseau 1106 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
46 rousseau 413
47     switch (ccid_descriptor->readerID)
48     {
49     case CARDMAN3121+1:
50     /* Reader announces APDU but is in fact TPDU */
51     ccid_descriptor->dwFeatures &= ~CCID_CLASS_EXCHANGE_MASK;
52     ccid_descriptor->dwFeatures |= CCID_CLASS_TPDU;
53     break;
54    
55     case GEMPCKEY:
56     case GEMPCTWIN:
57     /* Reader announces TPDU but can do APDU */
58 rousseau 879 if (DriverOptions & DRIVER_OPTION_GEMPC_TWIN_KEY_APDU)
59 rousseau 413 {
60 rousseau 1228 unsigned char cmd[] = { 0xA0, 0x02 };
61 rousseau 879 unsigned char res[10];
62 rousseau 892 unsigned int length_res = sizeof(res);
63 rousseau 879
64 rousseau 1228 if (CmdEscape(reader_index, cmd, sizeof(cmd), res, &length_res) == IFD_SUCCESS)
65 rousseau 879 {
66     ccid_descriptor->dwFeatures &= ~CCID_CLASS_EXCHANGE_MASK;
67     ccid_descriptor->dwFeatures |= CCID_CLASS_SHORT_APDU;
68     }
69 rousseau 413 }
70     break;
71 rousseau 1093
72 rousseau 1796 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 rousseau 2366 #define L10N_NB_STRING 10
78 rousseau 1796
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 rousseau 2254 const char *fr[] = {
85 rousseau 1796 "Entrer PIN",
86     "Nouveau PIN",
87     "Confirmer PIN",
88     "PIN correct",
89     "PIN Incorrect !",
90     "Delai depasse",
91     "* essai restant",
92     "Inserer carte",
93 rousseau 2366 "Erreur carte",
94     "PIN bloque" };
95 rousseau 1796
96 rousseau 2254 const char *de[] = {
97 rousseau 1796 "PIN eingeben",
98     "Neue PIN",
99     "PIN bestatigen",
100     "PIN korrect",
101     "Falsche PIN !",
102     "Zeit abgelaufen",
103     "* Versuche ubrig",
104     "Karte einstecken",
105 rousseau 2366 "Fehler Karte",
106     "PIN blockiert" };
107 rousseau 1796
108 rousseau 2254 const char *es[] = {
109 rousseau 1796 "Introducir PIN",
110     "Nuevo PIN",
111     "Confirmar PIN",
112     "PIN OK",
113     "PIN Incorrecto !",
114     "Tiempo Agotado",
115 rousseau 1805 "* ensayos quedan",
116 rousseau 1796 "Introducir Tarj.",
117 rousseau 2366 "Error en Tarjeta",
118     "PIN bloqueado" };
119 rousseau 1796
120 rousseau 2254 const char *it[] = {
121 rousseau 1796 "Inserire PIN",
122     "Nuovo PIN",
123     "Confermare PIN",
124     "PIN Corretto",
125     "PIN Errato !",
126     "Tempo scaduto",
127     "* prove rimaste",
128     "Inserire Carta",
129 rousseau 2366 "Errore Carta",
130     "PIN ostruito"};
131 rousseau 1796
132 rousseau 2365 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 rousseau 2366 "Erro cartao",
142     "PIN bloqueado" };
143 rousseau 2365
144 rousseau 2489 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 rousseau 2254 const char *en[] = {
169 rousseau 1796 "Enter PIN",
170     "New PIN",
171     "Confirm PIN",
172     "PIN OK",
173     "Incorrect PIN!",
174     "Time Out",
175     "* retries left",
176     "Insert Card",
177 rousseau 2366 "Card Error",
178     "PIN blocked" };
179 rousseau 1796
180     char *lang;
181 rousseau 2254 const char **l10n;
182 rousseau 1796
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 rousseau 2365 else if (0 == strncmp(lang, "pt", 2))
197     l10n = pt;
198 rousseau 2489 else if (0 == strncmp(lang, "nl", 2))
199     l10n = nl;
200     else if (0 == strncmp(lang, "tr", 2))
201     l10n = tr;
202 rousseau 1796 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 rousseau 1799 {
227 rousseau 1796 DEBUG_COMM("l10n string loaded successfully");
228 rousseau 1799 }
229 rousseau 1796 else
230 rousseau 1799 {
231 rousseau 1796 DEBUG_COMM("Failed to load l10n strings");
232 rousseau 1799 }
233 rousseau 1796 }
234     break;
235    
236 rousseau 1093 /* SCM SCR331-DI contactless */
237     case SCR331DI:
238 rousseau 2035 /* SCM SCR331-DI-NTTCOM contactless */
239     case SCR331DINTTCOM:
240 rousseau 1950 /* SCM SDI010 contactless */
241     case SDI010:
242 rousseau 1093 /* the contactless reader is in the second slot */
243 rousseau 1157 if (ccid_descriptor->bCurrentSlotIndex > 0)
244 rousseau 1093 {
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 rousseau 1106 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 rousseau 1093 {
258     DEBUG_COMM("SCM SCR331-DI contactless detected");
259     }
260     else
261     {
262     DEBUG_COMM("SCM SCR331-DI contactless init failed");
263 rousseau 1157 }
264 rousseau 1093
265 rousseau 1157 /* 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 rousseau 1093 }
271     break;
272 rousseau 1832
273     case MYSMARTPAD:
274     ccid_descriptor->dwMaxIFSD = 254;
275     break;
276 rousseau 2085
277     case CL1356D:
278     /* the firmware needs some time to initialize */
279     sleep(1);
280     ccid_descriptor->readTimeout = 60; /* 60 seconds */
281     break;
282 rousseau 2782
283     case SEG:
284     InterruptRead(reader_index);
285     break;
286 rousseau 413 }
287    
288 rousseau 2470 /* 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 rousseau 413 return 0;
321     } /* ccid_open_hack */
322    
323     /*****************************************************************************
324     *
325     * ccid_error
326     *
327     ****************************************************************************/
328 rousseau 2255 void ccid_error(int error, const char *file, int line, const char *function)
329 rousseau 413 {
330 rousseau 2254 const char *text;
331 rousseau 2596 char var_text[30];
332 rousseau 413
333     switch (error)
334     {
335     case 0x00:
336     text = "Command not supported or not allowed";
337     break;
338    
339     case 0x01:
340     text = "Wrong command length";
341     break;
342    
343     case 0x05:
344 rousseau 890 text = "Invalid slot number";
345 rousseau 413 break;
346    
347     case 0xA2:
348     text = "Card short-circuiting. Card powered off";
349     break;
350    
351     case 0xA3:
352     text = "ATR too long (> 33)";
353     break;
354    
355 rousseau 890 case 0xAB:
356     text = "No data exchanged";
357     break;
358    
359 rousseau 413 case 0xB0:
360     text = "Reader in EMV mode and T=1 message too long";
361     break;
362    
363     case 0xBB:
364     text = "Protocol error in EMV mode";
365     break;
366    
367     case 0xBD:
368     text = "Card error during T=1 exchange";
369     break;
370    
371     case 0xBE:
372     text = "Wrong APDU command length";
373     break;
374    
375 rousseau 890 case 0xE0:
376     text = "Slot busy";
377     break;
378    
379     case 0xEF:
380     text = "PIN cancelled";
381     break;
382    
383     case 0xF0:
384     text = "PIN timeout";
385     break;
386    
387     case 0xF2:
388     text = "Busy with autosequence";
389     break;
390    
391     case 0xF3:
392     text = "Deactivated protocol";
393     break;
394    
395 rousseau 413 case 0xF4:
396     text = "Procedure byte conflict";
397     break;
398    
399 rousseau 890 case 0xF5:
400     text = "Class not supported";
401     break;
402    
403     case 0xF6:
404     text = "Protocol not supported";
405     break;
406    
407 rousseau 413 case 0xF7:
408     text = "Invalid ATR checksum byte (TCK)";
409     break;
410    
411     case 0xF8:
412     text = "Invalid ATR first byte";
413     break;
414    
415 rousseau 890 case 0xFB:
416     text = "Hardware error";
417     break;
418 rousseau 2152
419 rousseau 890 case 0xFC:
420     text = "Overrun error";
421     break;
422    
423 rousseau 413 case 0xFD:
424     text = "Parity error during exchange";
425     break;
426    
427     case 0xFE:
428     text = "Card absent or mute";
429     break;
430    
431 rousseau 890 case 0xFF:
432     text = "Activity aborted by Host";
433     break;
434    
435 rousseau 413 default:
436 rousseau 890 if ((error >= 1) && (error <= 127))
437     {
438     sprintf(var_text, "error on byte %d", error);
439     text = var_text;
440     }
441     else
442 rousseau 2082 sprintf(var_text, "Unknown CCID error: 0x%02X", error);
443     text = var_text;
444 rousseau 413 break;
445     }
446 rousseau 1411 log_msg(PCSC_LOG_ERROR, "%s:%d:%s %s", file, line, function, text);
447 rousseau 413
448     } /* ccid_error */
449    

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.5