/[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 2085 - (show annotations) (download)
Mon Jul 3 12:57:50 2006 UTC (6 years, 10 months ago) by rousseau
File MIME type: text/plain
File size: 8184 byte(s)
ccid_open_hack(): the CL1356D firmware needs some time to initialize.
Wait 1 second here
1 /*
2 ccid.c: CCID common code
3 Copyright (C) 2003-2005 Ludovic Rousseau
4
5 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
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 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 */
19
20 /*
21 * $Id$
22 */
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <pcsclite.h>
28 #include <ifdhandler.h>
29
30 #include "config.h"
31 #include "debug.h"
32 #include "ccid.h"
33 #include "defs.h"
34 #include "ccid_ifdhandler.h"
35 #include "commands.h"
36
37 /*****************************************************************************
38 *
39 * ccid_open_hack
40 *
41 ****************************************************************************/
42 int ccid_open_hack(unsigned int reader_index)
43 {
44 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
45
46 switch (ccid_descriptor->readerID)
47 {
48 case CARDMAN3121+1:
49 /* Reader announces APDU but is in fact TPDU */
50 ccid_descriptor->dwFeatures &= ~CCID_CLASS_EXCHANGE_MASK;
51 ccid_descriptor->dwFeatures |= CCID_CLASS_TPDU;
52 break;
53
54 case GEMPCKEY:
55 case GEMPCTWIN:
56 /* Reader announces TPDU but can do APDU */
57 if (DriverOptions & DRIVER_OPTION_GEMPC_TWIN_KEY_APDU)
58 {
59 unsigned char cmd[] = { 0xA0, 0x02 };
60 unsigned char res[10];
61 unsigned int length_res = sizeof(res);
62
63 if (CmdEscape(reader_index, cmd, sizeof(cmd), res, &length_res) == IFD_SUCCESS)
64 {
65 ccid_descriptor->dwFeatures &= ~CCID_CLASS_EXCHANGE_MASK;
66 ccid_descriptor->dwFeatures |= CCID_CLASS_SHORT_APDU;
67 }
68 }
69 break;
70
71 case GEMPCPINPAD:
72 /* load the l10n strings in the pinpad memory */
73 {
74 #define L10N_HEADER_SIZE 5
75 #define L10N_STRING_MAX_SIZE 16
76 #define L10N_NB_STRING 9
77
78 unsigned char cmd[L10N_HEADER_SIZE + L10N_NB_STRING * L10N_STRING_MAX_SIZE];
79 unsigned char res[20];
80 unsigned int length_res = sizeof(res);
81 int offset, i, j;
82
83 char *fr[] = {
84 "Entrer PIN",
85 "Nouveau PIN",
86 "Confirmer PIN",
87 "PIN correct",
88 "PIN Incorrect !",
89 "Delai depasse",
90 "* essai restant",
91 "Inserer carte",
92 "Erreur carte" };
93
94 char *de[] = {
95 "PIN eingeben",
96 "Neue PIN",
97 "PIN bestatigen",
98 "PIN korrect",
99 "Falsche PIN !",
100 "Zeit abgelaufen",
101 "* Versuche ubrig",
102 "Karte einstecken",
103 "Fehler Karte" };
104
105 char *es[] = {
106 "Introducir PIN",
107 "Nuevo PIN",
108 "Confirmar PIN",
109 "PIN OK",
110 "PIN Incorrecto !",
111 "Tiempo Agotado",
112 "* ensayos quedan",
113 "Introducir Tarj.",
114 "Error en Tarjeta" };
115
116 char *it[] = {
117 "Inserire PIN",
118 "Nuovo PIN",
119 "Confermare PIN",
120 "PIN Corretto",
121 "PIN Errato !",
122 "Tempo scaduto",
123 "* prove rimaste",
124 "Inserire Carta",
125 "Errore Carta" };
126
127 char *en[] = {
128 "Enter PIN",
129 "New PIN",
130 "Confirm PIN",
131 "PIN OK",
132 "Incorrect PIN!",
133 "Time Out",
134 "* retries left",
135 "Insert Card",
136 "Card Error" };
137
138 char *lang;
139 char **l10n;
140
141 lang = getenv("LANG");
142 if (NULL == lang)
143 l10n = en;
144 else
145 {
146 if (0 == strncmp(lang, "fr", 2))
147 l10n = fr;
148 else if (0 == strncmp(lang, "de", 2))
149 l10n = de;
150 else if (0 == strncmp(lang, "es", 2))
151 l10n = es;
152 else if (0 == strncmp(lang, "it", 2))
153 l10n = it;
154 else
155 l10n = en;
156 }
157
158 offset = 0;
159 cmd[offset++] = 0xB2; /* load strings */
160 cmd[offset++] = 0xA0; /* address of the memory */
161 cmd[offset++] = 0x00; /* address of the first byte */
162 cmd[offset++] = 0x4D; /* magic value */
163 cmd[offset++] = 0x4C; /* magic value */
164
165 /* for each string */
166 for (i=0; i<L10N_NB_STRING; i++)
167 {
168 /* copy the string */
169 for (j=0; l10n[i][j]; j++)
170 cmd[offset++] = l10n[i][j];
171
172 /* pad with " " */
173 for (; j<L10N_STRING_MAX_SIZE; j++)
174 cmd[offset++] = ' ';
175 }
176
177 if (IFD_SUCCESS == CmdEscape(reader_index, cmd, sizeof(cmd), res, &length_res))
178 {
179 DEBUG_COMM("l10n string loaded successfully");
180 }
181 else
182 {
183 DEBUG_COMM("Failed to load l10n strings");
184 }
185 }
186 break;
187
188 /* SCM SCR331-DI contactless */
189 case SCR331DI:
190 /* SCM SCR331-DI-NTTCOM contactless */
191 case SCR331DINTTCOM:
192 /* SCM SDI010 contactless */
193 case SDI010:
194 /* the contactless reader is in the second slot */
195 if (ccid_descriptor->bCurrentSlotIndex > 0)
196 {
197 unsigned char cmd1[] = { 0x00 };
198 /* command: 00 ??
199 * response: 06 10 03 03 00 00 00 01 FE FF FF FE 01 ?? */
200 unsigned char cmd2[] = { 0x02 };
201 /* command: 02 ??
202 * response: 00 ?? */
203
204 unsigned char res[20];
205 unsigned int length_res = sizeof(res);
206
207 if ((IFD_SUCCESS == CmdEscape(reader_index, cmd1, sizeof(cmd1), res, &length_res))
208 && (IFD_SUCCESS == CmdEscape(reader_index, cmd2, sizeof(cmd2), res, &length_res)))
209 {
210 DEBUG_COMM("SCM SCR331-DI contactless detected");
211 }
212 else
213 {
214 DEBUG_COMM("SCM SCR331-DI contactless init failed");
215 }
216
217 /* hack since the contactless reader do not share dwFeatures */
218 ccid_descriptor->dwFeatures &= ~CCID_CLASS_EXCHANGE_MASK;
219 ccid_descriptor->dwFeatures |= CCID_CLASS_SHORT_APDU;
220
221 ccid_descriptor->dwFeatures |= CCID_CLASS_AUTO_IFSD;
222 }
223 break;
224
225 case MYSMARTPAD:
226 ccid_descriptor->dwMaxIFSD = 254;
227 break;
228
229 case CL1356D:
230 /* the firmware needs some time to initialize */
231 sleep(1);
232 ccid_descriptor->readTimeout = 60; /* 60 seconds */
233 break;
234 }
235
236 return 0;
237 } /* ccid_open_hack */
238
239 /*****************************************************************************
240 *
241 * ccid_error
242 *
243 ****************************************************************************/
244 void ccid_error(int error, char *file, int line, const char *function)
245 {
246 char *text;
247 char var_text[20];
248
249 switch (error)
250 {
251 case 0x00:
252 text = "Command not supported or not allowed";
253 break;
254
255 case 0x01:
256 text = "Wrong command length";
257 break;
258
259 case 0x05:
260 text = "Invalid slot number";
261 break;
262
263 case 0xA2:
264 text = "Card short-circuiting. Card powered off";
265 break;
266
267 case 0xA3:
268 text = "ATR too long (> 33)";
269 break;
270
271 case 0xAB:
272 text = "No data exchanged";
273 break;
274
275 case 0xB0:
276 text = "Reader in EMV mode and T=1 message too long";
277 break;
278
279 case 0xBB:
280 text = "Protocol error in EMV mode";
281 break;
282
283 case 0xBD:
284 text = "Card error during T=1 exchange";
285 break;
286
287 case 0xBE:
288 text = "Wrong APDU command length";
289 break;
290
291 case 0xE0:
292 text = "Slot busy";
293 break;
294
295 case 0xEF:
296 text = "PIN cancelled";
297 break;
298
299 case 0xF0:
300 text = "PIN timeout";
301 break;
302
303 case 0xF2:
304 text = "Busy with autosequence";
305 break;
306
307 case 0xF3:
308 text = "Deactivated protocol";
309 break;
310
311 case 0xF4:
312 text = "Procedure byte conflict";
313 break;
314
315 case 0xF5:
316 text = "Class not supported";
317 break;
318
319 case 0xF6:
320 text = "Protocol not supported";
321 break;
322
323 case 0xF7:
324 text = "Invalid ATR checksum byte (TCK)";
325 break;
326
327 case 0xF8:
328 text = "Invalid ATR first byte";
329 break;
330
331 case 0xFB:
332 text = "Hardware error";
333 break;
334
335 case 0xFC:
336 text = "Overrun error";
337 break;
338
339 case 0xFD:
340 text = "Parity error during exchange";
341 break;
342
343 case 0xFE:
344 text = "Card absent or mute";
345 break;
346
347 case 0xFF:
348 text = "Activity aborted by Host";
349 break;
350
351 default:
352 if ((error >= 1) && (error <= 127))
353 {
354 sprintf(var_text, "error on byte %d", error);
355 text = var_text;
356 }
357 else
358 sprintf(var_text, "Unknown CCID error: 0x%02X", error);
359 text = var_text;
360 break;
361 }
362 log_msg(PCSC_LOG_ERROR, "%s:%d:%s %s", file, line, function, text);
363
364 } /* ccid_error */
365

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5