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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5