/[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 1799 - (show annotations) (download)
Thu Jan 12 21:51:25 2006 UTC (7 years, 4 months ago) by rousseau
File MIME type: text/plain
File size: 7812 byte(s)
ccid_open_hack(): use { } around DEBUG_COMM() in an if-else since
DEBUG_COMM() is not a function but an multi-instruction macro
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 "quedan * ensayos",
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 /* the contactless reader is in the second slot */
191 if (ccid_descriptor->bCurrentSlotIndex > 0)
192 {
193 unsigned char cmd1[] = { 0x00 };
194 /* command: 00 ??
195 * response: 06 10 03 03 00 00 00 01 FE FF FF FE 01 ?? */
196 unsigned char cmd2[] = { 0x02 };
197 /* command: 02 ??
198 * response: 00 ?? */
199
200 unsigned char res[20];
201 unsigned int length_res = sizeof(res);
202
203 if ((IFD_SUCCESS == CmdEscape(reader_index, cmd1, sizeof(cmd1), res, &length_res))
204 && (IFD_SUCCESS == CmdEscape(reader_index, cmd2, sizeof(cmd2), res, &length_res)))
205 {
206 DEBUG_COMM("SCM SCR331-DI contactless detected");
207 }
208 else
209 {
210 DEBUG_COMM("SCM SCR331-DI contactless init failed");
211 }
212
213 /* hack since the contactless reader do not share dwFeatures */
214 ccid_descriptor->dwFeatures &= ~CCID_CLASS_EXCHANGE_MASK;
215 ccid_descriptor->dwFeatures |= CCID_CLASS_SHORT_APDU;
216
217 ccid_descriptor->dwFeatures |= CCID_CLASS_AUTO_IFSD;
218 }
219 break;
220 }
221
222 return 0;
223 } /* ccid_open_hack */
224
225 /*****************************************************************************
226 *
227 * ccid_error
228 *
229 ****************************************************************************/
230 void ccid_error(int error, char *file, int line, const char *function)
231 {
232 char *text;
233 char var_text[20];
234
235 switch (error)
236 {
237 case 0x00:
238 text = "Command not supported or not allowed";
239 break;
240
241 case 0x01:
242 text = "Wrong command length";
243 break;
244
245 case 0x05:
246 text = "Invalid slot number";
247 break;
248
249 case 0xA2:
250 text = "Card short-circuiting. Card powered off";
251 break;
252
253 case 0xA3:
254 text = "ATR too long (> 33)";
255 break;
256
257 case 0xAB:
258 text = "No data exchanged";
259 break;
260
261 case 0xB0:
262 text = "Reader in EMV mode and T=1 message too long";
263 break;
264
265 case 0xBB:
266 text = "Protocol error in EMV mode";
267 break;
268
269 case 0xBD:
270 text = "Card error during T=1 exchange";
271 break;
272
273 case 0xBE:
274 text = "Wrong APDU command length";
275 break;
276
277 case 0xE0:
278 text = "Slot busy";
279 break;
280
281 case 0xEF:
282 text = "PIN cancelled";
283 break;
284
285 case 0xF0:
286 text = "PIN timeout";
287 break;
288
289 case 0xF2:
290 text = "Busy with autosequence";
291 break;
292
293 case 0xF3:
294 text = "Deactivated protocol";
295 break;
296
297 case 0xF4:
298 text = "Procedure byte conflict";
299 break;
300
301 case 0xF5:
302 text = "Class not supported";
303 break;
304
305 case 0xF6:
306 text = "Protocol not supported";
307 break;
308
309 case 0xF7:
310 text = "Invalid ATR checksum byte (TCK)";
311 break;
312
313 case 0xF8:
314 text = "Invalid ATR first byte";
315 break;
316
317 case 0xFB:
318 text = "Hardware error";
319 break;
320
321 case 0xFC:
322 text = "Overrun error";
323 break;
324
325 case 0xFD:
326 text = "Parity error during exchange";
327 break;
328
329 case 0xFE:
330 text = "Card absent or mute";
331 break;
332
333 case 0xFF:
334 text = "Activity aborted by Host";
335 break;
336
337 default:
338 if ((error >= 1) && (error <= 127))
339 {
340 sprintf(var_text, "error on byte %d", error);
341 text = var_text;
342 }
343 else
344 text = "Unknown CCID error";
345 break;
346 }
347 log_msg(PCSC_LOG_ERROR, "%s:%d:%s %s", file, line, function, text);
348
349 } /* ccid_error */
350

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5