/[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 3424 - (hide annotations) (download)
Fri Apr 10 07:43:30 2009 UTC (4 years, 1 month ago) by rousseau
File MIME type: text/plain
File size: 11340 byte(s)
ccid_open_hack_pre(): empty the interrupt end point (card movements)
before trying to talk to the device for the GemProx DU/SU
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 2974 You should have received a copy of the GNU Lesser General Public License
16     along with this library; if not, write to the Free Software Foundation,
17     Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 rousseau 3403 * ccid_open_hack_pre
41 rousseau 413 *
42     ****************************************************************************/
43 rousseau 3403 int ccid_open_hack_pre(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 rousseau 3404 case MYSMARTPAD:
56     ccid_descriptor->dwMaxIFSD = 254;
57     break;
58    
59     case CL1356D:
60     /* the firmware needs some time to initialize */
61     (void)sleep(1);
62     ccid_descriptor->readTimeout = 60; /* 60 seconds */
63     break;
64    
65     case SEG:
66 rousseau 3424 case GEMALTOPROXDU:
67     case GEMALTOPROXSU:
68 rousseau 3404 #ifndef TWIN_SERIAL
69     (void)InterruptRead(reader_index);
70     #endif
71     break;
72     }
73    
74     /* ICCD type A */
75     if (ICCD_A == ccid_descriptor->bInterfaceProtocol)
76     {
77     unsigned char tmp[MAX_ATR_SIZE];
78     unsigned int n = sizeof(tmp);
79    
80     DEBUG_COMM("ICCD type A");
81     (void)CmdPowerOff(reader_index);
82     (void)CmdPowerOn(reader_index, &n, tmp, CCID_CLASS_AUTO_VOLTAGE);
83     (void)CmdPowerOff(reader_index);
84     }
85    
86     /* ICCD type B */
87     if (ICCD_B == ccid_descriptor->bInterfaceProtocol)
88     {
89     unsigned char tmp[MAX_ATR_SIZE];
90     unsigned int n = sizeof(tmp);
91    
92     DEBUG_COMM("ICCD type B");
93     if (CCID_CLASS_SHORT_APDU ==
94     (ccid_descriptor->dwFeatures & CCID_CLASS_EXCHANGE_MASK))
95     {
96     /* use the extended APDU comm alogorithm */
97     ccid_descriptor->dwFeatures &= ~CCID_CLASS_EXCHANGE_MASK;
98     ccid_descriptor->dwFeatures |= CCID_CLASS_EXTENDED_APDU;
99     }
100    
101     (void)CmdPowerOff(reader_index);
102     (void)CmdPowerOn(reader_index, &n, tmp, CCID_CLASS_AUTO_VOLTAGE);
103     (void)CmdPowerOff(reader_index);
104     }
105    
106     return 0;
107     } /* ccid_open_hack_pre */
108    
109     /*****************************************************************************
110     *
111     * ccid_open_hack_post
112     *
113     ****************************************************************************/
114     int ccid_open_hack_post(unsigned int reader_index)
115     {
116     _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
117    
118     switch (ccid_descriptor->readerID)
119     {
120 rousseau 413 case GEMPCKEY:
121     case GEMPCTWIN:
122     /* Reader announces TPDU but can do APDU */
123 rousseau 879 if (DriverOptions & DRIVER_OPTION_GEMPC_TWIN_KEY_APDU)
124 rousseau 413 {
125 rousseau 1228 unsigned char cmd[] = { 0xA0, 0x02 };
126 rousseau 879 unsigned char res[10];
127 rousseau 892 unsigned int length_res = sizeof(res);
128 rousseau 879
129 rousseau 1228 if (CmdEscape(reader_index, cmd, sizeof(cmd), res, &length_res) == IFD_SUCCESS)
130 rousseau 879 {
131     ccid_descriptor->dwFeatures &= ~CCID_CLASS_EXCHANGE_MASK;
132     ccid_descriptor->dwFeatures |= CCID_CLASS_SHORT_APDU;
133     }
134 rousseau 413 }
135     break;
136 rousseau 1093
137 rousseau 1796 case GEMPCPINPAD:
138     /* load the l10n strings in the pinpad memory */
139     {
140     #define L10N_HEADER_SIZE 5
141     #define L10N_STRING_MAX_SIZE 16
142 rousseau 2366 #define L10N_NB_STRING 10
143 rousseau 1796
144     unsigned char cmd[L10N_HEADER_SIZE + L10N_NB_STRING * L10N_STRING_MAX_SIZE];
145     unsigned char res[20];
146     unsigned int length_res = sizeof(res);
147     int offset, i, j;
148    
149 rousseau 2254 const char *fr[] = {
150 rousseau 1796 "Entrer PIN",
151     "Nouveau PIN",
152     "Confirmer PIN",
153     "PIN correct",
154     "PIN Incorrect !",
155     "Delai depasse",
156     "* essai restant",
157     "Inserer carte",
158 rousseau 2366 "Erreur carte",
159     "PIN bloque" };
160 rousseau 1796
161 rousseau 2254 const char *de[] = {
162 rousseau 1796 "PIN eingeben",
163     "Neue PIN",
164     "PIN bestatigen",
165     "PIN korrect",
166     "Falsche PIN !",
167     "Zeit abgelaufen",
168     "* Versuche ubrig",
169     "Karte einstecken",
170 rousseau 2366 "Fehler Karte",
171     "PIN blockiert" };
172 rousseau 1796
173 rousseau 2254 const char *es[] = {
174 rousseau 1796 "Introducir PIN",
175     "Nuevo PIN",
176     "Confirmar PIN",
177     "PIN OK",
178     "PIN Incorrecto !",
179     "Tiempo Agotado",
180 rousseau 1805 "* ensayos quedan",
181 rousseau 1796 "Introducir Tarj.",
182 rousseau 2366 "Error en Tarjeta",
183     "PIN bloqueado" };
184 rousseau 1796
185 rousseau 2254 const char *it[] = {
186 rousseau 1796 "Inserire PIN",
187     "Nuovo PIN",
188     "Confermare PIN",
189     "PIN Corretto",
190     "PIN Errato !",
191     "Tempo scaduto",
192     "* prove rimaste",
193     "Inserire Carta",
194 rousseau 2366 "Errore Carta",
195     "PIN ostruito"};
196 rousseau 1796
197 rousseau 2365 const char *pt[] = {
198     "Insira PIN",
199     "Novo PIN",
200     "Conf. novo PIN",
201     "PIN OK",
202     "PIN falhou!",
203     "Tempo expirou",
204     "* tentiv. restam",
205     "Introduza cartao",
206 rousseau 2366 "Erro cartao",
207     "PIN bloqueado" };
208 rousseau 2365
209 rousseau 2489 const char *nl[] = {
210     "Inbrengen code",
211     "Nieuwe code",
212     "Bevestig code",
213     "Code aanvaard",
214     "Foute code",
215     "Time out",
216     "* Nog Pogingen",
217     "Kaart inbrengen",
218     "Kaart fout",
219     "Kaart blok" };
220    
221     const char *tr[] = {
222     "PIN Giriniz",
223     "Yeni PIN",
224     "PIN Onayala",
225     "PIN OK",
226     "Yanlis PIN",
227     "Zaman Asimi",
228     "* deneme kaldi",
229     "Karti Takiniz",
230     "Kart Hatasi",
231     "Kart Kilitli" };
232    
233 rousseau 2254 const char *en[] = {
234 rousseau 1796 "Enter PIN",
235     "New PIN",
236     "Confirm PIN",
237     "PIN OK",
238     "Incorrect PIN!",
239     "Time Out",
240     "* retries left",
241     "Insert Card",
242 rousseau 2366 "Card Error",
243     "PIN blocked" };
244 rousseau 1796
245     char *lang;
246 rousseau 2254 const char **l10n;
247 rousseau 1796
248     lang = getenv("LANG");
249     if (NULL == lang)
250     l10n = en;
251     else
252     {
253     if (0 == strncmp(lang, "fr", 2))
254     l10n = fr;
255     else if (0 == strncmp(lang, "de", 2))
256     l10n = de;
257     else if (0 == strncmp(lang, "es", 2))
258     l10n = es;
259     else if (0 == strncmp(lang, "it", 2))
260     l10n = it;
261 rousseau 2365 else if (0 == strncmp(lang, "pt", 2))
262     l10n = pt;
263 rousseau 2489 else if (0 == strncmp(lang, "nl", 2))
264     l10n = nl;
265     else if (0 == strncmp(lang, "tr", 2))
266     l10n = tr;
267 rousseau 1796 else
268     l10n = en;
269     }
270    
271     offset = 0;
272     cmd[offset++] = 0xB2; /* load strings */
273     cmd[offset++] = 0xA0; /* address of the memory */
274     cmd[offset++] = 0x00; /* address of the first byte */
275     cmd[offset++] = 0x4D; /* magic value */
276     cmd[offset++] = 0x4C; /* magic value */
277    
278     /* for each string */
279     for (i=0; i<L10N_NB_STRING; i++)
280     {
281     /* copy the string */
282     for (j=0; l10n[i][j]; j++)
283     cmd[offset++] = l10n[i][j];
284    
285     /* pad with " " */
286     for (; j<L10N_STRING_MAX_SIZE; j++)
287     cmd[offset++] = ' ';
288     }
289    
290 rousseau 3268 (void)sleep(1);
291 rousseau 1796 if (IFD_SUCCESS == CmdEscape(reader_index, cmd, sizeof(cmd), res, &length_res))
292 rousseau 1799 {
293 rousseau 1796 DEBUG_COMM("l10n string loaded successfully");
294 rousseau 1799 }
295 rousseau 1796 else
296 rousseau 1799 {
297 rousseau 1796 DEBUG_COMM("Failed to load l10n strings");
298 rousseau 1799 }
299 rousseau 1796 }
300     break;
301    
302 rousseau 3280 #if 0
303 rousseau 1093 /* SCM SCR331-DI contactless */
304     case SCR331DI:
305 rousseau 2035 /* SCM SCR331-DI-NTTCOM contactless */
306     case SCR331DINTTCOM:
307 rousseau 1950 /* SCM SDI010 contactless */
308     case SDI010:
309 rousseau 1093 /* the contactless reader is in the second slot */
310 rousseau 1157 if (ccid_descriptor->bCurrentSlotIndex > 0)
311 rousseau 1093 {
312     unsigned char cmd1[] = { 0x00 };
313     /* command: 00 ??
314     * response: 06 10 03 03 00 00 00 01 FE FF FF FE 01 ?? */
315     unsigned char cmd2[] = { 0x02 };
316     /* command: 02 ??
317     * response: 00 ?? */
318    
319     unsigned char res[20];
320     unsigned int length_res = sizeof(res);
321    
322 rousseau 1106 if ((IFD_SUCCESS == CmdEscape(reader_index, cmd1, sizeof(cmd1), res, &length_res))
323     && (IFD_SUCCESS == CmdEscape(reader_index, cmd2, sizeof(cmd2), res, &length_res)))
324 rousseau 1093 {
325     DEBUG_COMM("SCM SCR331-DI contactless detected");
326     }
327     else
328     {
329     DEBUG_COMM("SCM SCR331-DI contactless init failed");
330 rousseau 1157 }
331 rousseau 1093
332 rousseau 1157 /* hack since the contactless reader do not share dwFeatures */
333     ccid_descriptor->dwFeatures &= ~CCID_CLASS_EXCHANGE_MASK;
334     ccid_descriptor->dwFeatures |= CCID_CLASS_SHORT_APDU;
335    
336     ccid_descriptor->dwFeatures |= CCID_CLASS_AUTO_IFSD;
337 rousseau 1093 }
338     break;
339 rousseau 3280 #endif
340 rousseau 1832
341 rousseau 3378 #ifndef USE_USB_INTERRUPT
342     /* only if we do not use USB interrupts */
343     case GEMALTOPROXDU:
344     case GEMALTOPROXSU:
345     {
346     /* disable card movements notification
347     * with RDR_to_PC_NotifySlotChange */
348     unsigned char cmd[] = { 0x42, 0x00 /* disable */};
349     unsigned char res[10];
350     unsigned int length_res = sizeof(res);
351    
352     if (CmdEscape(reader_index, cmd, sizeof(cmd), res, &length_res) == IFD_SUCCESS)
353     {
354     DEBUG_COMM("NotifySlotChange disabled");
355     }
356     else
357     {
358     DEBUG_CRITICAL("NotifySlotChange disabling failed");
359     }
360     }
361     break;
362     #endif
363 rousseau 413 }
364    
365     return 0;
366 rousseau 3403 } /* ccid_open_hack_post */
367    
368     /*****************************************************************************
369     *
370 rousseau 413 * ccid_error
371     *
372     ****************************************************************************/
373 rousseau 2255 void ccid_error(int error, const char *file, int line, const char *function)
374 rousseau 413 {
375 rousseau 2254 const char *text;
376 rousseau 2596 char var_text[30];
377 rousseau 413
378     switch (error)
379     {
380     case 0x00:
381     text = "Command not supported or not allowed";
382     break;
383    
384     case 0x01:
385     text = "Wrong command length";
386     break;
387    
388     case 0x05:
389 rousseau 890 text = "Invalid slot number";
390 rousseau 413 break;
391    
392     case 0xA2:
393     text = "Card short-circuiting. Card powered off";
394     break;
395    
396     case 0xA3:
397     text = "ATR too long (> 33)";
398     break;
399    
400 rousseau 890 case 0xAB:
401     text = "No data exchanged";
402     break;
403    
404 rousseau 413 case 0xB0:
405     text = "Reader in EMV mode and T=1 message too long";
406     break;
407    
408     case 0xBB:
409     text = "Protocol error in EMV mode";
410     break;
411    
412     case 0xBD:
413     text = "Card error during T=1 exchange";
414     break;
415    
416     case 0xBE:
417     text = "Wrong APDU command length";
418     break;
419    
420 rousseau 890 case 0xE0:
421     text = "Slot busy";
422     break;
423    
424     case 0xEF:
425     text = "PIN cancelled";
426     break;
427    
428     case 0xF0:
429     text = "PIN timeout";
430     break;
431    
432     case 0xF2:
433     text = "Busy with autosequence";
434     break;
435    
436     case 0xF3:
437     text = "Deactivated protocol";
438     break;
439    
440 rousseau 413 case 0xF4:
441     text = "Procedure byte conflict";
442     break;
443    
444 rousseau 890 case 0xF5:
445     text = "Class not supported";
446     break;
447    
448     case 0xF6:
449     text = "Protocol not supported";
450     break;
451    
452 rousseau 413 case 0xF7:
453     text = "Invalid ATR checksum byte (TCK)";
454     break;
455    
456     case 0xF8:
457     text = "Invalid ATR first byte";
458     break;
459    
460 rousseau 890 case 0xFB:
461     text = "Hardware error";
462     break;
463 rousseau 2152
464 rousseau 890 case 0xFC:
465     text = "Overrun error";
466     break;
467    
468 rousseau 413 case 0xFD:
469     text = "Parity error during exchange";
470     break;
471    
472     case 0xFE:
473     text = "Card absent or mute";
474     break;
475    
476 rousseau 890 case 0xFF:
477     text = "Activity aborted by Host";
478     break;
479    
480 rousseau 413 default:
481 rousseau 890 if ((error >= 1) && (error <= 127))
482     {
483 rousseau 3269 (void)snprintf(var_text, sizeof(var_text), "error on byte %d",
484     error);
485 rousseau 890 text = var_text;
486     }
487     else
488 rousseau 3269 (void)snprintf(var_text, sizeof(var_text),
489     "Unknown CCID error: 0x%02X", error);
490 rousseau 2082 text = var_text;
491 rousseau 413 break;
492     }
493 rousseau 1411 log_msg(PCSC_LOG_ERROR, "%s:%d:%s %s", file, line, function, text);
494 rousseau 413
495     } /* ccid_error */
496    

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5