source: branches/monitor-improvement/csctapi/atr.c@ 1228

Last change on this file since 1228 was 1228, checked in by alno, 13 years ago

WebIf:

  • Command: Merging revisions 1212-1227 of trunk
File size: 13.0 KB
Line 
1/*
2 atr.c
3 ISO 7816 ICC's answer to reset abstract data type implementation
4
5 This file is part of the Unix driver for Towitoko smartcard readers
6 Copyright (C) 2000 Carlos Prados <cprados@yahoo.com>
7
8 This version is modified by doz21 to work in a special manner ;)
9
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 2 of the License, or (at your option) any later version.
14
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
19
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25#include "defines.h"
26#include "atr.h"
27#include <stdlib.h>
28#include <string.h>
29
30/*
31 * Not exported variables definition
32 */
33
34unsigned long atr_fs_table[16] = {4000000L, 5000000L, 6000000L, 8000000L, 12000000L, 16000000L, 20000000L, 0, 0, 5000000L, 7500000L, 10000000L, 15000000L, 20000000L, 0, 0};
35
36static unsigned atr_num_ib_table[16] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
37
38/*
39 * Exported variables definition
40 */
41
42unsigned atr_f_table[16] = {372, 372, 558, 744, 1116, 1488, 1860, 0, 0, 512, 768, 1024, 1536, 2048, 0, 0};
43
44double atr_d_table[16] = {0, 1, 2, 4, 8, 16, 32, 64, 12, 20, 0.5, 0.25, 0.125, 0.0625, 0.03125, 0.015625};
45//old table has 0 for RFU:
46//double atr_d_table[16] = {0, 1, 2, 4, 8, 16, 0, 0, 0, 0, 0.5, 0.25, 125, 0.0625, 0.03125, 0.015625};
47
48unsigned atr_i_table[4] = {25, 50, 100, 0};
49
50/*
51 * Not exported functions declaration
52 */
53
54static bool ATR_GetNextByte (unsigned timeout, BYTE * b, bool invert);
55
56/*
57 * Exported funcions definition
58 */
59
60ATR * ATR_New (void)
61{
62 ATR *atr;
63
64 /* Allocate memory */
65 atr = (ATR *) malloc (sizeof (ATR));
66
67 return atr;
68}
69
70int ATR_InitFromArray (ATR * atr, BYTE atr_buffer[ATR_MAX_SIZE], unsigned length)
71{
72 BYTE TDi;
73 BYTE buffer[ATR_MAX_SIZE];
74 unsigned pointer = 0, pn = 0;
75
76 /* Check size of buffer */
77 if (length < 2)
78 return (ATR_MALFORMED);
79
80 /* Check if ATR is from a inverse convention card */
81 if (atr_buffer[0] == 0x03)
82 {
83 for (pointer = 0; pointer < length; pointer++)
84 buffer[pointer] = ~(INVERT_BYTE (atr_buffer[pointer]));
85 }
86 else
87 {
88 memcpy (buffer, atr_buffer, length);
89 }
90
91 /* Store T0 and TS */
92 atr->TS = buffer[0];
93
94 atr->T0 = TDi = buffer[1];
95 pointer = 1;
96
97 /* Store number of historical bytes */
98 atr->hbn = TDi & 0x0F;
99
100 /* TCK is not present by default */
101 (atr->TCK).present = FALSE;
102
103 /* Extract interface bytes */
104 while (pointer < length)
105 {
106 /* Check buffer is long enought */
107 if (pointer + atr_num_ib_table[(0xF0 & TDi) >> 4] >= length)
108 {
109 return (ATR_MALFORMED);
110 }
111
112 /* Check TAi is present */
113 if ((TDi | 0xEF) == 0xFF)
114 {
115 pointer++;
116 atr->ib[pn][ATR_INTERFACE_BYTE_TA].value = buffer[pointer];
117 atr->ib[pn][ATR_INTERFACE_BYTE_TA].present = TRUE;
118 }
119 else
120 {
121 atr->ib[pn][ATR_INTERFACE_BYTE_TA].present = FALSE;
122 }
123
124 /* Check TBi is present */
125 if ((TDi | 0xDF) == 0xFF)
126 {
127 pointer++;
128 atr->ib[pn][ATR_INTERFACE_BYTE_TB].value = buffer[pointer];
129 atr->ib[pn][ATR_INTERFACE_BYTE_TB].present = TRUE;
130 }
131 else
132 {
133 atr->ib[pn][ATR_INTERFACE_BYTE_TB].present = FALSE;
134 }
135
136 /* Check TCi is present */
137 if ((TDi | 0xBF) == 0xFF)
138 {
139 pointer++;
140 atr->ib[pn][ATR_INTERFACE_BYTE_TC].value = buffer[pointer];
141 atr->ib[pn][ATR_INTERFACE_BYTE_TC].present = TRUE;
142 }
143 else
144 {
145 atr->ib[pn][ATR_INTERFACE_BYTE_TC].present = FALSE;
146 }
147
148 /* Read TDi if present */
149 if ((TDi | 0x7F) == 0xFF)
150 {
151 pointer++;
152 TDi = atr->ib[pn][ATR_INTERFACE_BYTE_TD].value = buffer[pointer];
153 atr->ib[pn][ATR_INTERFACE_BYTE_TD].present = TRUE;
154 (atr->TCK).present = ((TDi & 0x0F) != ATR_PROTOCOL_TYPE_T0);
155 if (pn >= ATR_MAX_PROTOCOLS)
156 return (ATR_MALFORMED);
157 pn++;
158 }
159 else
160 {
161 atr->ib[pn][ATR_INTERFACE_BYTE_TD].present = FALSE;
162 break;
163 }
164 }
165
166 /* Store number of protocols */
167 atr->pn = pn + 1;
168
169 /* Store historical bytes */
170 if (pointer + atr->hbn >= length) {
171 cs_log("ATR is malformed, it reports %i historical bytes but there are only %i",atr->hbn, length-pointer-2);
172 if (length-pointer >= 2)
173 atr->hbn = length-pointer-2;
174 else {
175 atr->hbn = 0;
176 atr->length = pointer + 1;
177 return (ATR_MALFORMED);
178 }
179
180 }
181
182 memcpy (atr->hb, buffer + pointer + 1, atr->hbn);
183 pointer += (atr->hbn);
184
185 /* Store TCK */
186 if ((atr->TCK).present)
187 {
188 if (pointer + 1 >= length)
189 return (ATR_MALFORMED);
190
191 pointer++;
192
193 (atr->TCK).value = buffer[pointer];
194 }
195
196 atr->length = pointer + 1;
197 return (ATR_OK);
198}
199
200int ATR_InitFromStream (ATR * atr, unsigned timeout)
201{
202 BYTE TDi;
203 unsigned pointer = 0, pn = 0, i;
204 bool invert;
205
206 invert = FALSE;
207
208 /* Store T0 and TS */
209 if (!ATR_GetNextByte (timeout, &(atr->TS), invert))
210 return ATR_IO_ERROR;
211
212 if (atr->TS == 0x03)
213 {
214 atr->TS = 0x3F;
215 invert = TRUE;
216 }
217
218 if ((atr->TS != 0x3B) && (atr->TS != 0x3F))
219 return ATR_MALFORMED;
220
221 if (!ATR_GetNextByte (timeout, &(atr->T0), invert))
222 return ATR_MALFORMED;
223
224 TDi = atr->T0;
225 pointer = 1;
226
227 /* Store number of historical bytes */
228 atr->hbn = TDi & 0x0F;
229
230 /* TCK is not present by default */
231 (atr->TCK).present = FALSE;
232
233 /* Extract interface bytes */
234 while (TRUE)
235 {
236 /* Check TAi is present */
237 if ((TDi | 0xEF) == 0xFF)
238 {
239 pointer++;
240 if (!ATR_GetNextByte(timeout, &(atr->ib[pn][ATR_INTERFACE_BYTE_TA].value),invert))
241 return ATR_MALFORMED;
242 atr->ib[pn][ATR_INTERFACE_BYTE_TA].present = TRUE;
243 }
244 else
245 {
246 atr->ib[pn][ATR_INTERFACE_BYTE_TA].present = FALSE;
247 }
248
249 /* Check TBi is present */
250 if ((TDi | 0xDF) == 0xFF)
251 {
252 pointer++;
253 if (!ATR_GetNextByte(timeout, &(atr->ib[pn][ATR_INTERFACE_BYTE_TB].value),invert))
254 return ATR_MALFORMED;
255 atr->ib[pn][ATR_INTERFACE_BYTE_TB].present = TRUE;
256 }
257 else
258 {
259 atr->ib[pn][ATR_INTERFACE_BYTE_TB].present = FALSE;
260 }
261
262 /* Check TCi is present */
263 if ((TDi | 0xBF) == 0xFF)
264 {
265 pointer++;
266 if (!ATR_GetNextByte(timeout, &(atr->ib[pn][ATR_INTERFACE_BYTE_TC].value), invert))
267 return ATR_MALFORMED;
268 atr->ib[pn][ATR_INTERFACE_BYTE_TC].present = TRUE;
269 }
270 else
271 {
272 atr->ib[pn][ATR_INTERFACE_BYTE_TC].present = FALSE;
273 }
274
275 /* Read TDi if present */
276 if ((TDi | 0x7F) == 0xFF)
277 {
278 pointer++;
279 if (!ATR_GetNextByte(timeout, &(atr->ib[pn][ATR_INTERFACE_BYTE_TD].value), invert))
280 return ATR_MALFORMED;
281 TDi = atr->ib[pn][ATR_INTERFACE_BYTE_TD].value;
282 atr->ib[pn][ATR_INTERFACE_BYTE_TD].present = TRUE;
283 (atr->TCK).present = ((TDi & 0x0F) != ATR_PROTOCOL_TYPE_T0);
284 if (pn >= ATR_MAX_PROTOCOLS)
285 return (ATR_MALFORMED);
286 pn++;
287 }
288 else
289 {
290 atr->ib[pn][ATR_INTERFACE_BYTE_TD].present = FALSE;
291 break;
292 }
293 }
294
295 /* Store number of protocols */
296 atr->pn = pn + 1;
297
298 /* Store historical bytes */
299 for (i = 0; i < (atr->hbn); i++)
300 {
301 if (!ATR_GetNextByte (timeout, &(atr->hb[i]), invert))
302 return ATR_MALFORMED;
303 }
304
305 pointer += (atr->hbn);
306
307 /* Store TCK */
308 if ((atr->TCK).present)
309 {
310 pointer++;
311
312 if (!ATR_GetNextByte (timeout, (&((atr->TCK).value)), invert))
313 return ATR_MALFORMED;
314 }
315
316 atr->length = pointer + 1;
317 return (ATR_OK);
318
319}
320
321void ATR_Delete (ATR * atr)
322{
323 free (atr);
324}
325
326int ATR_GetConvention (ATR * atr, int *convention)
327{
328 if (atr->TS == 0x3B)
329 (*convention) = ATR_CONVENTION_DIRECT;
330 else if (atr->TS == 0x3F)
331 (*convention) = ATR_CONVENTION_INVERSE;
332 else
333 return (ATR_MALFORMED);
334
335 return (ATR_OK);
336}
337
338int ATR_GetSize (ATR * atr, unsigned *size)
339{
340 (*size) = atr->length;
341 return (ATR_OK);
342}
343
344int ATR_GetNumberOfProtocols (ATR * atr, unsigned *number_protocols)
345{
346 (*number_protocols) = atr->pn;
347 return (ATR_OK);
348}
349
350int ATR_GetProtocolType (ATR * atr, unsigned number_protocol, BYTE *protocol_type)
351{
352 if ((number_protocol > atr->pn) || number_protocol < 1)
353 return ATR_NOT_FOUND;
354
355 if (atr->ib[number_protocol - 1][ATR_INTERFACE_BYTE_TD].present)
356 (*protocol_type) = (atr->ib[number_protocol - 1][ATR_INTERFACE_BYTE_TD].value & 0x0F);
357 else
358 (*protocol_type) = ATR_PROTOCOL_TYPE_T0;
359
360 return (ATR_OK);
361}
362
363int ATR_GetInterfaceByte (ATR * atr, unsigned number, int character, BYTE * value)
364{
365 if (number > atr->pn || number < 1)
366 return (ATR_NOT_FOUND);
367
368 if (atr->ib[number - 1][character].present && (character == ATR_INTERFACE_BYTE_TA || character == ATR_INTERFACE_BYTE_TB || character == ATR_INTERFACE_BYTE_TC || character == ATR_INTERFACE_BYTE_TD))
369 (*value) = atr->ib[number - 1][character].value;
370 else
371 return (ATR_NOT_FOUND);
372
373 return (ATR_OK);
374}
375
376int ATR_GetIntegerValue (ATR * atr, int name, BYTE * value)
377{
378 int ret;
379
380 if (name == ATR_INTEGER_VALUE_FI)
381 {
382 if (atr->ib[0][ATR_INTERFACE_BYTE_TA].present)
383 {
384 (*value) = (atr->ib[0][ATR_INTERFACE_BYTE_TA].value & 0xF0) >> 4;
385 ret = ATR_OK;
386 }
387 else
388 {
389 ret = ATR_NOT_FOUND;
390 }
391 }
392 else if (name == ATR_INTEGER_VALUE_DI)
393 {
394 if (atr->ib[0][ATR_INTERFACE_BYTE_TA].present)
395 {
396 (*value) = (atr->ib[0][ATR_INTERFACE_BYTE_TA].value & 0x0F);
397 ret = ATR_OK;
398 }
399 else
400 {
401 ret = ATR_NOT_FOUND;
402 }
403 }
404 else if (name == ATR_INTEGER_VALUE_II)
405 {
406 if (atr->ib[0][ATR_INTERFACE_BYTE_TB].present)
407 {
408 (*value) = (atr->ib[0][ATR_INTERFACE_BYTE_TB].value & 0x60) >> 5;
409 ret = ATR_OK;
410 }
411 else
412 {
413 ret = ATR_NOT_FOUND;
414 }
415 }
416 else if (name == ATR_INTEGER_VALUE_PI1)
417 {
418 if (atr->ib[0][ATR_INTERFACE_BYTE_TB].present)
419 {
420 (*value) = (atr->ib[0][ATR_INTERFACE_BYTE_TB].value & 0x1F);
421 ret = ATR_OK;
422 }
423 else
424 {
425 ret = ATR_NOT_FOUND;
426 }
427 }
428 else if (name == ATR_INTEGER_VALUE_PI2)
429 {
430 if (atr->ib[1][ATR_INTERFACE_BYTE_TB].present)
431 {
432 (*value) = atr->ib[1][ATR_INTERFACE_BYTE_TB].value;
433 ret = ATR_OK;
434 }
435 else
436 {
437 ret = ATR_NOT_FOUND;
438 }
439 }
440 else if (name == ATR_INTEGER_VALUE_N)
441 {
442 if (atr->ib[0][ATR_INTERFACE_BYTE_TC].present)
443 {
444 (*value) = atr->ib[0][ATR_INTERFACE_BYTE_TC].value;
445 ret = ATR_OK;
446 }
447 else
448 {
449 ret = ATR_NOT_FOUND;
450 }
451 }
452 else
453 {
454 ret = ATR_NOT_FOUND;
455 }
456
457 return ret;
458}
459
460int ATR_GetParameter (ATR * atr, int name, double *parameter)
461{
462 BYTE FI, DI, II, PI1, PI2, N;
463
464 if (name == ATR_PARAMETER_F)
465 {
466 if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_FI, &FI) != ATR_OK)
467 FI = ATR_DEFAULT_FI;
468 (*parameter) = (double) (atr_f_table[FI]);
469 return (ATR_OK);
470 }
471 else if (name == ATR_PARAMETER_D)
472 {
473 if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_DI, &DI) == ATR_OK)
474 (*parameter) = (double) (atr_d_table[DI]);
475 else
476 (*parameter) = (double) ATR_DEFAULT_D;
477 return (ATR_OK);
478 }
479 else if (name == ATR_PARAMETER_I)
480 {
481 if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_II, &II) == ATR_OK)
482 (*parameter) = (double) (atr_i_table[II]);
483 else
484 (*parameter) = ATR_DEFAULT_I;
485 return (ATR_OK);
486 }
487 else if (name == ATR_PARAMETER_P)
488 {
489 if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_PI2, &PI2) == ATR_OK)
490 (*parameter) = (double) PI2;
491 else if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_PI1, &PI1) == ATR_OK)
492 (*parameter) = (double) PI1;
493 else
494 (*parameter) = (double) ATR_DEFAULT_P;
495 return (ATR_OK);
496 }
497 else if (name == ATR_PARAMETER_N)
498 {
499 if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_N, &N) == ATR_OK)
500 (*parameter) = (double) N;
501 else
502 (*parameter) = (double) ATR_DEFAULT_N;
503 return (ATR_OK);
504 }
505
506 return (ATR_NOT_FOUND);
507}
508
509int ATR_GetHistoricalBytes (ATR * atr, BYTE hist[ATR_MAX_HISTORICAL], unsigned *length)
510{
511 if (atr->hbn == 0)
512 return (ATR_NOT_FOUND);
513
514 (*length) = atr->hbn;
515 memcpy (hist, atr->hb, atr->hbn);
516 return (ATR_OK);
517}
518
519int ATR_GetRaw (ATR * atr, BYTE buffer[ATR_MAX_SIZE], unsigned *length)
520{
521 unsigned i, j;
522
523 buffer[0] = atr->TS;
524 buffer[1] = atr->T0;
525
526 j = 2;
527
528 for (i = 0; i < atr->pn; i++)
529 {
530 if (atr->ib[i][ATR_INTERFACE_BYTE_TA].present)
531 buffer[j++] = atr->ib[i][ATR_INTERFACE_BYTE_TA].value;
532
533 if (atr->ib[i][ATR_INTERFACE_BYTE_TB].present)
534 buffer[j++] = atr->ib[i][ATR_INTERFACE_BYTE_TB].value;
535
536 if (atr->ib[i][ATR_INTERFACE_BYTE_TC].present)
537 buffer[j++] = atr->ib[i][ATR_INTERFACE_BYTE_TC].value;
538
539 if (atr->ib[i][ATR_INTERFACE_BYTE_TD].present)
540 buffer[j++] = atr->ib[i][ATR_INTERFACE_BYTE_TD].value;
541 }
542
543 if (atr->hbn > 0)
544 {
545 memcpy (&(buffer[j]), atr->hb, atr->hbn);
546 j += atr->hbn;
547 }
548
549 if ((atr->TCK).present)
550 buffer[j++] = (atr->TCK).value;
551
552 (*length) = j;
553
554 return ATR_OK;
555}
556
557int ATR_GetCheckByte (ATR * atr, BYTE * check_byte)
558{
559 if (!((atr->TCK).present))
560 return (ATR_NOT_FOUND);
561
562 (*check_byte) = (atr->TCK).value;
563 return (ATR_OK);
564}
565
566int ATR_GetFsMax (ATR * atr, unsigned long *fsmax)
567{
568 BYTE FI;
569
570 if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_FI, &FI) == ATR_OK)
571 (*fsmax) = atr_fs_table[FI];
572 else
573 (*fsmax) = atr_fs_table[1];
574
575 return (ATR_OK);
576}
577
578/*
579 * Not exported functions definition
580 */
581
582static bool ATR_GetNextByte (unsigned timeout, BYTE * byte, bool invert)
583{
584 bool ret;
585 ret = IO_Serial_Read (timeout, 1, byte);
586 /* Para tarjetas inversas quiza */
587 if (invert)
588 (*byte) = ~(INVERT_BYTE (*byte));
589
590 return ret;
591}
Note: See TracBrowser for help on using the repository browser.