1 | /* |
---|
2 | icc_async.c |
---|
3 | Asynchronous ICC's handling functions |
---|
4 | |
---|
5 | This file is part of the Unix driver for Towitoko smartcard readers |
---|
6 | Copyright (C) 2000 2001 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 <stdlib.h> |
---|
26 | #include <stdio.h> |
---|
27 | #include <string.h> |
---|
28 | #include "../globals.h" |
---|
29 | #include "defines.h" |
---|
30 | #include "icc_async.h" |
---|
31 | #include "ifd.h" |
---|
32 | #include "mc_global.h" |
---|
33 | #include "apdu.h" |
---|
34 | #include "protocol_t0.h" |
---|
35 | #include "protocol_t1.h" |
---|
36 | |
---|
37 | // Default T0/T14 settings |
---|
38 | #define DEFAULT_WI 10 |
---|
39 | // Default T1 settings |
---|
40 | #define DEFAULT_IFSC 32 |
---|
41 | #define MAX_IFSC 251 /* Cannot send > 255 buffer */ |
---|
42 | #define DEFAULT_CWI 13 |
---|
43 | #define DEFAULT_BWI 4 |
---|
44 | #define EDC_LRC 0 |
---|
45 | |
---|
46 | #define PPS_MAX_LENGTH 6 |
---|
47 | #define PPS_HAS_PPS1(block) ((block[1] & 0x10) == 0x10) |
---|
48 | #define PPS_HAS_PPS2(block) ((block[1] & 0x20) == 0x20) |
---|
49 | #define PPS_HAS_PPS3(block) ((block[1] & 0x40) == 0x40) |
---|
50 | |
---|
51 | |
---|
52 | /* |
---|
53 | * Not exported functions declaration |
---|
54 | */ |
---|
55 | |
---|
56 | static void ICC_Async_InvertBuffer (unsigned size, BYTE * buffer); |
---|
57 | static int Parse_ATR (ATR * atr, unsigned short deprecated); |
---|
58 | static int PPS_Exchange (BYTE * params, unsigned *length); |
---|
59 | static unsigned PPS_GetLength (BYTE * block); |
---|
60 | static int InitCard (ATR * atr, BYTE FI, double d, double n, unsigned short deprecated); |
---|
61 | static unsigned int ETU_to_ms(unsigned long WWT); |
---|
62 | static BYTE PPS_GetPCK (BYTE * block, unsigned length); |
---|
63 | static int Protocol_Command (unsigned char * command, unsigned long command_len, APDU_Rsp ** rsp); |
---|
64 | static int SetRightParity (void); |
---|
65 | |
---|
66 | int fdmc=(-1); |
---|
67 | |
---|
68 | /* |
---|
69 | * Exported functions definition |
---|
70 | */ |
---|
71 | |
---|
72 | int ICC_Async_Device_Init () |
---|
73 | { |
---|
74 | cs_debug_mask (D_IFD, "IFD: Opening device %s\n", reader[ridx].device); |
---|
75 | |
---|
76 | wr = 0; |
---|
77 | |
---|
78 | switch(reader[ridx].typ) { |
---|
79 | case R_MOUSE: |
---|
80 | reader[ridx].handle = open (reader[ridx].device, O_RDWR | O_NOCTTY| O_NONBLOCK); |
---|
81 | if (reader[ridx].handle < 0) { |
---|
82 | cs_log("ERROR opening device %s",reader[ridx].device); |
---|
83 | return ERROR; |
---|
84 | } |
---|
85 | break; |
---|
86 | #if defined(TUXBOX) && defined(PPC) |
---|
87 | case R_DB2COM1: |
---|
88 | case R_DB2COM2: |
---|
89 | reader[ridx].handle = open (reader[ridx].device, O_RDWR | O_NOCTTY| O_SYNC); |
---|
90 | if (reader[ridx].handle < 0) { |
---|
91 | cs_log("ERROR opening device %s",reader[ridx].device); |
---|
92 | return ERROR; |
---|
93 | } |
---|
94 | if ((fdmc = open(DEV_MULTICAM, O_RDWR)) < 0) { |
---|
95 | close(reader[ridx].handle); |
---|
96 | cs_log("ERROR opening device %s",DEV_MULTICAM); |
---|
97 | return ERROR; |
---|
98 | } |
---|
99 | break; |
---|
100 | #endif |
---|
101 | case R_SMART: |
---|
102 | #if defined(LIBUSB) |
---|
103 | call (SR_Init(&reader[ridx])); |
---|
104 | break; |
---|
105 | #else |
---|
106 | cs_log("ERROR, you have specified 'protocol = smartreader' in oscam.server,"); |
---|
107 | cs_log("recompile with SmartReader support."); |
---|
108 | return ERROR; |
---|
109 | #endif |
---|
110 | case R_INTERNAL: |
---|
111 | #ifdef COOL |
---|
112 | return Cool_Init(); |
---|
113 | #elif SCI_DEV |
---|
114 | #if defined(SH4) || defined(STB04SCI) |
---|
115 | reader[ridx].handle = open (reader[ridx].device, O_RDWR|O_NONBLOCK|O_NOCTTY); |
---|
116 | #else |
---|
117 | reader[ridx].handle = open (reader[ridx].device, O_RDWR); |
---|
118 | #endif |
---|
119 | if (reader[ridx].handle < 0) { |
---|
120 | cs_log("ERROR opening device %s",reader[ridx].device); |
---|
121 | return ERROR; |
---|
122 | } |
---|
123 | #else//SCI_DEV |
---|
124 | cs_log("ERROR, you have specified 'protocol = internal' in oscam.server,"); |
---|
125 | cs_log("recompile with internal reader support."); |
---|
126 | return ERROR; |
---|
127 | #endif//SCI_DEV |
---|
128 | break; |
---|
129 | default: |
---|
130 | cs_log("ERROR ICC_Device_Init: unknow reader type %i",reader[ridx].typ); |
---|
131 | return ERROR; |
---|
132 | } |
---|
133 | |
---|
134 | if (reader[ridx].typ <= R_MOUSE) |
---|
135 | if (Phoenix_Init()) { |
---|
136 | cs_log("ERROR: Phoenix_Init returns error"); |
---|
137 | Phoenix_Close (); |
---|
138 | return ERROR; |
---|
139 | } |
---|
140 | cs_debug_mask (D_IFD, "IFD: Device %s succesfully opened\n", reader[ridx].device); |
---|
141 | return OK; |
---|
142 | } |
---|
143 | |
---|
144 | int ICC_Async_GetStatus (int * card) |
---|
145 | { |
---|
146 | int in; |
---|
147 | |
---|
148 | // printf("\n%08X\n", (int)ifd->io); |
---|
149 | |
---|
150 | switch(reader[ridx].typ) { |
---|
151 | case R_DB2COM1: |
---|
152 | case R_DB2COM2: |
---|
153 | #if defined(TUXBOX) && defined(PPC) |
---|
154 | { |
---|
155 | ushort msr=1; |
---|
156 | extern int fdmc; |
---|
157 | IO_Serial_Ioctl_Lock(1); |
---|
158 | ioctl(fdmc, GET_PCDAT, &msr); |
---|
159 | if (reader[ridx].typ == R_DB2COM2) |
---|
160 | in=(!(msr & 1)); |
---|
161 | else |
---|
162 | in=((msr & 0x0f00) == 0x0f00); |
---|
163 | IO_Serial_Ioctl_Lock(0); |
---|
164 | } |
---|
165 | break; |
---|
166 | #endif |
---|
167 | case R_MOUSE: |
---|
168 | call (Phoenix_GetStatus(&in)); |
---|
169 | break; |
---|
170 | #if defined(LIBUSB) |
---|
171 | case R_SMART: |
---|
172 | call (SR_GetStatus(&reader[ridx],&in)); |
---|
173 | break; |
---|
174 | #endif |
---|
175 | case R_INTERNAL: |
---|
176 | #ifdef SCI_DEV |
---|
177 | call (Sci_GetStatus(reader[ridx].handle, &in)); |
---|
178 | #elif COOL |
---|
179 | call (Cool_GetStatus(&in)); |
---|
180 | #endif |
---|
181 | break; |
---|
182 | default: |
---|
183 | cs_log("ERROR ICC_Device_Init: unknow reader type %i",reader[ridx].typ); |
---|
184 | return ERROR; |
---|
185 | } |
---|
186 | |
---|
187 | if (in) |
---|
188 | *card = TRUE; |
---|
189 | else |
---|
190 | *card = FALSE; |
---|
191 | |
---|
192 | //cs_debug_mask (D_TRACE, "IFD: Status = %s", in ? "card": "no card"); |
---|
193 | |
---|
194 | return OK; |
---|
195 | } |
---|
196 | |
---|
197 | int ICC_Async_Activate (ATR * atr, unsigned short deprecated) |
---|
198 | { |
---|
199 | cs_debug_mask (D_IFD, "IFD: Activating card in reader %s\n", reader[ridx].label); |
---|
200 | int card; |
---|
201 | |
---|
202 | call (ICC_Async_GetStatus (&card)); |
---|
203 | if (card == 0) { |
---|
204 | cs_log("ERROR: Trying to activate card but no card inside"); |
---|
205 | return ERROR; |
---|
206 | } |
---|
207 | |
---|
208 | current_baudrate = DEFAULT_BAUDRATE; //this is needed for all readers to calculate work_etu for timings |
---|
209 | switch(reader[ridx].typ) { |
---|
210 | case R_DB2COM1: |
---|
211 | case R_DB2COM2: |
---|
212 | case R_MOUSE: |
---|
213 | call (Phoenix_Reset(atr)); |
---|
214 | break; |
---|
215 | #if defined(LIBUSB) |
---|
216 | case R_SMART: |
---|
217 | call (SR_Reset(&reader[ridx],atr)); |
---|
218 | break; |
---|
219 | #endif |
---|
220 | case R_INTERNAL: |
---|
221 | #ifdef SCI_DEV |
---|
222 | call (Sci_Activate()); |
---|
223 | call (Sci_Reset(atr)); |
---|
224 | #elif COOL |
---|
225 | call (Cool_Reset(atr)); |
---|
226 | #endif |
---|
227 | break; |
---|
228 | default: |
---|
229 | cs_log("ERROR ICC_Async_Activate: unknow reader type %i",reader[ridx].typ); |
---|
230 | return ERROR; |
---|
231 | } |
---|
232 | |
---|
233 | unsigned char atrarr[64]; |
---|
234 | unsigned int atr_size; |
---|
235 | ATR_GetRaw(atr, atrarr, &atr_size); |
---|
236 | cs_ri_log("ATR: %s", cs_hexdump(1, atrarr, atr_size)); |
---|
237 | |
---|
238 | /* Get ICC convention */ |
---|
239 | if (ATR_GetConvention (atr, &(convention)) != ATR_OK) { |
---|
240 | cs_log("ERROR: Could not read convention"); |
---|
241 | convention = 0; |
---|
242 | protocol_type = 0; |
---|
243 | return ERROR; |
---|
244 | } |
---|
245 | |
---|
246 | protocol_type = ATR_PROTOCOL_TYPE_T0; |
---|
247 | |
---|
248 | unsigned short cs_ptyp_orig=cs_ptyp; |
---|
249 | cs_ptyp=D_ATR; |
---|
250 | int ret = Parse_ATR(atr, deprecated); |
---|
251 | if (ret) |
---|
252 | cs_log("ERROR: Parse_ATR returned error"); |
---|
253 | cs_ptyp=cs_ptyp_orig; |
---|
254 | if (ret) |
---|
255 | return ERROR; |
---|
256 | cs_debug_mask (D_IFD, "IFD: Card in reader %s succesfully activated\n", reader[ridx].label); |
---|
257 | return OK; |
---|
258 | } |
---|
259 | |
---|
260 | int ICC_Async_CardWrite (unsigned char *cmd, unsigned short lc, unsigned char *rsp, unsigned short *lr) |
---|
261 | { |
---|
262 | APDU_Rsp *apdu_rsp = NULL; |
---|
263 | int remain; |
---|
264 | bool err = FALSE; |
---|
265 | |
---|
266 | call (Protocol_Command (cmd, lc, &apdu_rsp)); |
---|
267 | { |
---|
268 | if (apdu_rsp != NULL) { |
---|
269 | /* Copy APDU data to rsp */ |
---|
270 | remain = MAX ((short)APDU_Rsp_RawLen(apdu_rsp) - (*lr),0); |
---|
271 | if (remain > 0) { |
---|
272 | cs_log("MEMORY ERROR"); |
---|
273 | err = TRUE; //FIXME do I need this? |
---|
274 | } |
---|
275 | (*lr) = MIN ((*lr), (short)APDU_Rsp_RawLen (apdu_rsp)); |
---|
276 | memcpy (rsp, APDU_Rsp_Raw (apdu_rsp) + remain, (*lr)); |
---|
277 | APDU_Rsp_Delete (apdu_rsp); |
---|
278 | } |
---|
279 | else |
---|
280 | (*lr) = 0; |
---|
281 | } |
---|
282 | |
---|
283 | if (err) { |
---|
284 | cs_log("ERROR creating APDU response"); |
---|
285 | return ERROR; |
---|
286 | } |
---|
287 | |
---|
288 | return OK; |
---|
289 | } |
---|
290 | |
---|
291 | int Protocol_Command (unsigned char * command, unsigned long command_len, APDU_Rsp ** rsp) |
---|
292 | { |
---|
293 | switch (protocol_type) { |
---|
294 | case ATR_PROTOCOL_TYPE_T0: |
---|
295 | call (Protocol_T0_Command (command, command_len, rsp)); |
---|
296 | break; |
---|
297 | case ATR_PROTOCOL_TYPE_T1: |
---|
298 | { |
---|
299 | int try = 1; |
---|
300 | do { |
---|
301 | if (Protocol_T1_Command (command, command_len, rsp) == OK) |
---|
302 | break; |
---|
303 | try++; |
---|
304 | //try to resync |
---|
305 | APDU_Rsp ** rsp; |
---|
306 | unsigned char resync[] = { 0x21, 0xC0, 0x00, 0xE1 }; |
---|
307 | Protocol_T1_Command (resync, sizeof(resync), rsp); |
---|
308 | ifsc = DEFAULT_IFSC; |
---|
309 | } while (try <= 3); |
---|
310 | break; |
---|
311 | } |
---|
312 | case ATR_PROTOCOL_TYPE_T14: |
---|
313 | call (Protocol_T14_ExchangeTPDU (command, command_len, rsp)); |
---|
314 | break; |
---|
315 | default: |
---|
316 | cs_log("Error, unknown protocol type %i",protocol_type); |
---|
317 | return ERROR; |
---|
318 | } |
---|
319 | return OK; |
---|
320 | } |
---|
321 | |
---|
322 | int ICC_Async_SetTimings (unsigned wait_etu) |
---|
323 | { |
---|
324 | read_timeout = ETU_to_ms(wait_etu); |
---|
325 | cs_debug_mask(D_IFD, "Setting timeout to %i", wait_etu); |
---|
326 | return OK; |
---|
327 | } |
---|
328 | |
---|
329 | int ICC_Async_Transmit (unsigned size, BYTE * data) |
---|
330 | { |
---|
331 | cs_ddump_mask(D_IFD, data, size, "IFD Transmit: "); |
---|
332 | BYTE *buffer = NULL, *sent; |
---|
333 | |
---|
334 | if (convention == ATR_CONVENTION_INVERSE && reader[ridx].typ <= R_MOUSE) { |
---|
335 | buffer = (BYTE *) calloc(sizeof (BYTE), size); |
---|
336 | memcpy (buffer, data, size); |
---|
337 | ICC_Async_InvertBuffer (size, buffer); |
---|
338 | sent = buffer; |
---|
339 | } |
---|
340 | else |
---|
341 | sent = data; |
---|
342 | |
---|
343 | switch(reader[ridx].typ) { |
---|
344 | case R_DB2COM1: |
---|
345 | case R_DB2COM2: |
---|
346 | case R_MOUSE: |
---|
347 | call (Phoenix_Transmit (sent, size, icc_timings.block_delay, icc_timings.char_delay)); |
---|
348 | break; |
---|
349 | #if defined(LIBUSB) |
---|
350 | case R_SMART: |
---|
351 | call (SR_Transmit(&reader[ridx], sent, size)); |
---|
352 | break; |
---|
353 | #endif |
---|
354 | case R_INTERNAL: |
---|
355 | #ifdef COOL |
---|
356 | call (Cool_Transmit(sent, size)); |
---|
357 | #elif SCI_DEV |
---|
358 | call (Phoenix_Transmit (sent, size, 0, 0)); //the internal reader will provide the delay |
---|
359 | #endif |
---|
360 | break; |
---|
361 | default: |
---|
362 | cs_log("ERROR ICC_Async_Transmit: unknow reader type %i",reader[ridx].typ); |
---|
363 | return ERROR; |
---|
364 | } |
---|
365 | |
---|
366 | if (convention == ATR_CONVENTION_INVERSE && reader[ridx].typ <= R_MOUSE) |
---|
367 | free (buffer); |
---|
368 | cs_debug_mask(D_IFD, "IFD Transmit succesful"); |
---|
369 | return OK; |
---|
370 | } |
---|
371 | |
---|
372 | int ICC_Async_Receive (unsigned size, BYTE * data) |
---|
373 | { |
---|
374 | switch(reader[ridx].typ) { |
---|
375 | case R_DB2COM1: |
---|
376 | case R_DB2COM2: |
---|
377 | case R_MOUSE: |
---|
378 | call (Phoenix_Receive (data, size, read_timeout)); |
---|
379 | break; |
---|
380 | #if defined(LIBUSB) |
---|
381 | case R_SMART: |
---|
382 | call (SR_Receive(&reader[ridx], data, size)); |
---|
383 | break; |
---|
384 | #endif |
---|
385 | case R_INTERNAL: |
---|
386 | #ifdef COOL |
---|
387 | call (Cool_Receive(data, size)); |
---|
388 | #elif SCI_DEV |
---|
389 | call (Phoenix_Receive (data, size, read_timeout)); |
---|
390 | #endif |
---|
391 | break; |
---|
392 | default: |
---|
393 | cs_log("ERROR ICC_Async_Receive: unknow reader type %i",reader[ridx].typ); |
---|
394 | return ERROR; |
---|
395 | } |
---|
396 | |
---|
397 | if (convention == ATR_CONVENTION_INVERSE && reader[ridx].typ <= R_MOUSE) |
---|
398 | ICC_Async_InvertBuffer (size, data); |
---|
399 | |
---|
400 | cs_ddump_mask(D_IFD, data, size, "IFD Received: "); |
---|
401 | return OK; |
---|
402 | } |
---|
403 | |
---|
404 | int ICC_Async_Close () |
---|
405 | { //FIXME this routine is never called! |
---|
406 | cs_debug_mask (D_IFD, "IFD: Closing device %s", reader[ridx].device); |
---|
407 | |
---|
408 | switch(reader[ridx].typ) { |
---|
409 | case R_DB2COM1: |
---|
410 | case R_DB2COM2: |
---|
411 | case R_MOUSE: |
---|
412 | call (Phoenix_Close()); |
---|
413 | break; |
---|
414 | #if defined(LIBUSB) |
---|
415 | case R_SMART: |
---|
416 | call (SR_Close(&reader[ridx])); |
---|
417 | break; |
---|
418 | #endif |
---|
419 | case R_INTERNAL: |
---|
420 | #ifdef SCI_DEV |
---|
421 | /* Dectivate ICC */ |
---|
422 | call (Sci_Deactivate()); |
---|
423 | call (Phoenix_Close()); |
---|
424 | #endif |
---|
425 | break; |
---|
426 | default: |
---|
427 | cs_log("ERROR ICC_Async_Close: unknow reader type %i",reader[ridx].typ); |
---|
428 | return ERROR; |
---|
429 | } |
---|
430 | |
---|
431 | cs_debug_mask (D_IFD, "IFD: Device %s succesfully closed", reader[ridx].device); |
---|
432 | return OK; |
---|
433 | } |
---|
434 | |
---|
435 | unsigned long ICC_Async_GetClockRate () |
---|
436 | { |
---|
437 | switch (reader[ridx].cardmhz) { |
---|
438 | case 357: |
---|
439 | case 358: |
---|
440 | return (372L * 9600L); |
---|
441 | case 368: |
---|
442 | return (384L * 9600L); |
---|
443 | default: |
---|
444 | return reader[ridx].cardmhz * 10000L; |
---|
445 | } |
---|
446 | } |
---|
447 | |
---|
448 | static void ICC_Async_InvertBuffer (unsigned size, BYTE * buffer) |
---|
449 | { |
---|
450 | uint i; |
---|
451 | |
---|
452 | for (i = 0; i < size; i++) |
---|
453 | buffer[i] = ~(INVERT_BYTE (buffer[i])); |
---|
454 | } |
---|
455 | |
---|
456 | static int Parse_ATR (ATR * atr, unsigned short deprecated) |
---|
457 | { |
---|
458 | BYTE FI = ATR_DEFAULT_FI; |
---|
459 | //BYTE t = ATR_PROTOCOL_TYPE_T0; |
---|
460 | double d = ATR_DEFAULT_D; |
---|
461 | double n = ATR_DEFAULT_N; |
---|
462 | int ret; |
---|
463 | |
---|
464 | int numprot = atr->pn; |
---|
465 | //if there is a trailing TD, this number is one too high |
---|
466 | BYTE tx; |
---|
467 | if (ATR_GetInterfaceByte (atr, numprot-1, ATR_INTERFACE_BYTE_TD, &tx) == ATR_OK) |
---|
468 | if ((tx & 0xF0) == 0) |
---|
469 | numprot--; |
---|
470 | int i,point; |
---|
471 | char txt[50]; |
---|
472 | bool OffersT[3]; //T14 stored as T2 |
---|
473 | for (i = 0; i <= 2; i++) |
---|
474 | OffersT[i] = FALSE; |
---|
475 | for (i=1; i<= numprot; i++) { |
---|
476 | point = 0; |
---|
477 | if (ATR_GetInterfaceByte (atr, i, ATR_INTERFACE_BYTE_TA, &tx) == ATR_OK) { |
---|
478 | sprintf((char *)txt+point,"TA%i=%02X ",i,tx); |
---|
479 | point +=7; |
---|
480 | } |
---|
481 | if (ATR_GetInterfaceByte (atr, i, ATR_INTERFACE_BYTE_TB, &tx) == ATR_OK) { |
---|
482 | sprintf((char *)txt+point,"TB%i=%02X ",i,tx); |
---|
483 | point +=7; |
---|
484 | } |
---|
485 | if (ATR_GetInterfaceByte (atr, i, ATR_INTERFACE_BYTE_TC, &tx) == ATR_OK) { |
---|
486 | sprintf((char *)txt+point,"TC%i=%02X ",i,tx); |
---|
487 | point +=7; |
---|
488 | } |
---|
489 | if (ATR_GetInterfaceByte (atr, i, ATR_INTERFACE_BYTE_TD, &tx) == ATR_OK) { |
---|
490 | sprintf((char *)txt+point,"TD%i=%02X ",i,tx); |
---|
491 | point +=7; |
---|
492 | tx &= 0X0F; |
---|
493 | sprintf((char *)txt+point,"(T%i)",tx); |
---|
494 | if (tx == 14) |
---|
495 | OffersT[2] = TRUE; |
---|
496 | else |
---|
497 | OffersT[tx] = TRUE; |
---|
498 | } |
---|
499 | else { |
---|
500 | sprintf((char *)txt+point,"no TD%i means T0",i); |
---|
501 | OffersT[0] = TRUE; |
---|
502 | } |
---|
503 | cs_debug("%s",txt); |
---|
504 | } |
---|
505 | |
---|
506 | int numprottype = 0; |
---|
507 | for (i = 0; i <= 2; i++) |
---|
508 | if (OffersT[i]) |
---|
509 | numprottype ++; |
---|
510 | cs_debug("%i protocol types detected. Historical bytes: %s",numprottype, cs_hexdump(1,atr->hb,atr->hbn)); |
---|
511 | |
---|
512 | ATR_GetParameter (atr, ATR_PARAMETER_N, &(n)); |
---|
513 | ATR_GetProtocolType(atr,1,&(protocol_type)); //get protocol from TD1 |
---|
514 | BYTE TA2; |
---|
515 | bool SpecificMode = (ATR_GetInterfaceByte (atr, 2, ATR_INTERFACE_BYTE_TA, &TA2) == ATR_OK); //if TA2 present, specific mode, else negotiable mode |
---|
516 | if (SpecificMode) { |
---|
517 | protocol_type = TA2 & 0x0F; |
---|
518 | if ((TA2 & 0x10) != 0x10) { //bit 5 set to 0 means F and D explicitly defined in interface characters |
---|
519 | BYTE TA1; |
---|
520 | if (ATR_GetInterfaceByte (atr, 1 , ATR_INTERFACE_BYTE_TA, &TA1) == ATR_OK) { |
---|
521 | FI = TA1 >> 4; |
---|
522 | ATR_GetParameter (atr, ATR_PARAMETER_D, &(d)); |
---|
523 | } |
---|
524 | else { |
---|
525 | FI = ATR_DEFAULT_FI; |
---|
526 | d = ATR_DEFAULT_D; |
---|
527 | } |
---|
528 | } |
---|
529 | else { |
---|
530 | cs_log("Specific mode: speed 'implicitly defined', not sure how to proceed, assuming default values"); |
---|
531 | FI = ATR_DEFAULT_FI; |
---|
532 | d = ATR_DEFAULT_D; |
---|
533 | } |
---|
534 | cs_debug("Specific mode: T%i, F=%.0f, D=%.6f, N=%.0f\n", protocol_type, (double) atr_f_table[FI], d, n); |
---|
535 | } |
---|
536 | else { //negotiable mode |
---|
537 | |
---|
538 | bool PPS_success = FALSE; |
---|
539 | bool NeedsPTS = ((protocol_type != ATR_PROTOCOL_TYPE_T14) && (numprottype > 1 || (atr->ib[0][ATR_INTERFACE_BYTE_TA].present == TRUE && atr->ib[0][ATR_INTERFACE_BYTE_TA].value != 0x11) || n == 255)); //needs PTS according to old ISO 7816 |
---|
540 | if (NeedsPTS && deprecated == 0) { |
---|
541 | // PTSS PTS0 PTS1 PCK |
---|
542 | BYTE req[] = { 0xFF, 0x10, 0x00, 0x00 }; //we currently do not support PTS2, standard guardtimes |
---|
543 | req[1]=0x10 | protocol_type; //PTS0 always flags PTS1 to be sent always |
---|
544 | if (ATR_GetInterfaceByte (atr, 1, ATR_INTERFACE_BYTE_TA, &req[2]) != ATR_OK) //PTS1 |
---|
545 | req[2] = 0x11; //defaults FI and DI to 1 |
---|
546 | unsigned int len = sizeof(req); |
---|
547 | ret = PPS_Exchange (req, &len); |
---|
548 | if (ret == OK) { |
---|
549 | FI = req[2] >> 4; |
---|
550 | BYTE DI = req[2] & 0x0F; |
---|
551 | d = (double) (atr_d_table[DI]); |
---|
552 | PPS_success = TRUE; |
---|
553 | cs_debug("PTS Succesfull, selected protocol: T%i, F=%.0f, D=%.6f, N=%.0f\n", protocol_type, (double) atr_f_table[FI], d, n); |
---|
554 | } |
---|
555 | else |
---|
556 | cs_ddump(req,4,"PTS Failure, response:"); |
---|
557 | } |
---|
558 | |
---|
559 | //When for SCI, T14 protocol, TA1 is obeyed, this goes OK for mosts devices, but somehow on DM7025 Sky S02 card goes wrong when setting ETU (ok on DM800/DM8000) |
---|
560 | if (!PPS_success) {//last PPS not succesfull |
---|
561 | BYTE TA1; |
---|
562 | if (ATR_GetInterfaceByte (atr, 1 , ATR_INTERFACE_BYTE_TA, &TA1) == ATR_OK) { |
---|
563 | FI = TA1 >> 4; |
---|
564 | ATR_GetParameter (atr, ATR_PARAMETER_D, &(d)); |
---|
565 | } |
---|
566 | else { //do not obey TA1 |
---|
567 | FI = ATR_DEFAULT_FI; |
---|
568 | d = ATR_DEFAULT_D; |
---|
569 | } |
---|
570 | if (NeedsPTS) { |
---|
571 | if ((d == 32) || (d == 12) || (d == 20)) //those values were RFU in old table |
---|
572 | d = 0; // viaccess cards that fail PTS need this |
---|
573 | } |
---|
574 | |
---|
575 | cs_debug("No PTS %s, selected protocol T%i, F=%.0f, D=%.6f, N=%.0f\n", NeedsPTS?"happened":"needed", protocol_type, (double) atr_f_table[FI], d, n); |
---|
576 | } |
---|
577 | }//end negotiable mode |
---|
578 | |
---|
579 | //make sure no zero values |
---|
580 | double F = (double) atr_f_table[FI]; |
---|
581 | if (!F) { |
---|
582 | FI = ATR_DEFAULT_FI; |
---|
583 | cs_log("Warning: F=0 is invalid, forcing FI=%d", FI); |
---|
584 | } |
---|
585 | if (!d) { |
---|
586 | d = ATR_DEFAULT_D; |
---|
587 | cs_log("Warning: D=0 is invalid, forcing D=%.0f",d); |
---|
588 | } |
---|
589 | |
---|
590 | if (deprecated == 0) |
---|
591 | return InitCard (atr, FI, d, n, deprecated); |
---|
592 | else |
---|
593 | return InitCard (atr, ATR_DEFAULT_FI, ATR_DEFAULT_D, n, deprecated); |
---|
594 | } |
---|
595 | |
---|
596 | static int PPS_Exchange (BYTE * params, unsigned *length) |
---|
597 | { |
---|
598 | BYTE confirm[PPS_MAX_LENGTH]; |
---|
599 | unsigned len_request, len_confirm; |
---|
600 | int ret; |
---|
601 | |
---|
602 | len_request = PPS_GetLength (params); |
---|
603 | params[len_request - 1] = PPS_GetPCK(params, len_request - 1); |
---|
604 | cs_debug_mask (D_IFD,"PTS: Sending request: %s", cs_hexdump(1, params, len_request)); |
---|
605 | |
---|
606 | /* Send PPS request */ |
---|
607 | call (ICC_Async_Transmit (len_request, params)); |
---|
608 | |
---|
609 | /* Get PPS confirm */ |
---|
610 | call (ICC_Async_Receive (2, confirm)); |
---|
611 | len_confirm = PPS_GetLength (confirm); |
---|
612 | call (ICC_Async_Receive (len_confirm - 2, confirm + 2)); |
---|
613 | |
---|
614 | cs_debug_mask(D_IFD, "PTS: Receiving confirm: %s", cs_hexdump(1, confirm, len_confirm)); |
---|
615 | if ((len_request != len_confirm) || (memcmp (params, confirm, len_request))) |
---|
616 | ret = ERROR; |
---|
617 | else |
---|
618 | ret = OK; |
---|
619 | |
---|
620 | /* Copy PPS handsake */ |
---|
621 | memcpy (params, confirm, len_confirm); |
---|
622 | (*length) = len_confirm; |
---|
623 | return ret; |
---|
624 | } |
---|
625 | |
---|
626 | static unsigned PPS_GetLength (BYTE * block) |
---|
627 | { |
---|
628 | unsigned length = 3; |
---|
629 | |
---|
630 | if (PPS_HAS_PPS1 (block)) |
---|
631 | length++; |
---|
632 | |
---|
633 | if (PPS_HAS_PPS2 (block)) |
---|
634 | length++; |
---|
635 | |
---|
636 | if (PPS_HAS_PPS3 (block)) |
---|
637 | length++; |
---|
638 | |
---|
639 | return length; |
---|
640 | } |
---|
641 | |
---|
642 | static unsigned int ETU_to_ms(unsigned long WWT) |
---|
643 | { |
---|
644 | #define CHAR_LEN 10L //character length in ETU, perhaps should be 9 when parity = none? |
---|
645 | if (WWT > CHAR_LEN) |
---|
646 | WWT -= CHAR_LEN; |
---|
647 | else |
---|
648 | WWT = 0; |
---|
649 | double work_etu = 1000 / (double)current_baudrate;//FIXME sometimes work_etu should be used, sometimes initial etu |
---|
650 | return (unsigned int) WWT * work_etu * reader[ridx].cardmhz / reader[ridx].mhz; |
---|
651 | } |
---|
652 | |
---|
653 | static int ICC_Async_SetParity (unsigned short parity) |
---|
654 | { |
---|
655 | switch(reader[ridx].typ) { |
---|
656 | case R_DB2COM1: |
---|
657 | case R_DB2COM2: |
---|
658 | case R_MOUSE: |
---|
659 | call (IO_Serial_SetParity (parity)); |
---|
660 | break; |
---|
661 | #if defined(LIBUSB) |
---|
662 | case R_SMART: |
---|
663 | call (SR_SetParity(&reader[ridx], parity)); |
---|
664 | break; |
---|
665 | #endif |
---|
666 | case R_INTERNAL: |
---|
667 | return OK; |
---|
668 | default: |
---|
669 | cs_log("ERROR ICC_Async_SetParity: unknow reader type %i",reader[ridx].typ); |
---|
670 | return ERROR; |
---|
671 | } |
---|
672 | return OK; |
---|
673 | } |
---|
674 | |
---|
675 | static int SetRightParity (void) |
---|
676 | { |
---|
677 | //set right parity |
---|
678 | unsigned short parity = PARITY_EVEN; |
---|
679 | if (convention == ATR_CONVENTION_INVERSE) |
---|
680 | parity = PARITY_ODD; |
---|
681 | else if(protocol_type == ATR_PROTOCOL_TYPE_T14) |
---|
682 | parity = PARITY_NONE; |
---|
683 | |
---|
684 | call (ICC_Async_SetParity(parity)); |
---|
685 | |
---|
686 | #ifdef COOL |
---|
687 | if (reader[ridx].typ != R_INTERNAL) |
---|
688 | #endif |
---|
689 | #if defined(LIBUSB) |
---|
690 | if (reader[ridx].typ != R_SMART) |
---|
691 | #endif |
---|
692 | IO_Serial_Flush(); |
---|
693 | return OK; |
---|
694 | } |
---|
695 | |
---|
696 | static int InitCard (ATR * atr, BYTE FI, double d, double n, unsigned short deprecated) |
---|
697 | { |
---|
698 | double P,I; |
---|
699 | double F; |
---|
700 | unsigned long BGT, edc, EGT, CGT, WWT = 0; |
---|
701 | unsigned int GT; |
---|
702 | unsigned long gt_ms; |
---|
703 | current_baudrate = DEFAULT_BAUDRATE; |
---|
704 | |
---|
705 | //set the amps and the volts according to ATR |
---|
706 | if (ATR_GetParameter(atr, ATR_PARAMETER_P, &P) != ATR_OK) |
---|
707 | P = 0; |
---|
708 | if (ATR_GetParameter(atr, ATR_PARAMETER_I, &I) != ATR_OK) |
---|
709 | I = 0; |
---|
710 | |
---|
711 | //set clock speed to max if internal reader |
---|
712 | if(reader[ridx].typ > R_MOUSE) |
---|
713 | if (reader[ridx].mhz == 357 || reader[ridx].mhz == 358) //no overclocking |
---|
714 | reader[ridx].mhz = atr_fs_table[FI] / 10000; //we are going to clock the card to this nominal frequency |
---|
715 | |
---|
716 | //set clock speed/baudrate must be done before timings |
---|
717 | //because current_baudrate is used in calculation of timings |
---|
718 | F = (double) atr_f_table[FI]; |
---|
719 | |
---|
720 | if (deprecated == 0) |
---|
721 | if (protocol_type != ATR_PROTOCOL_TYPE_T14) { //dont switch for T14 |
---|
722 | unsigned long baud_temp = d * ICC_Async_GetClockRate () / F; |
---|
723 | if (reader[ridx].typ <= R_MOUSE) |
---|
724 | call (Phoenix_SetBaudrate (baud_temp)); |
---|
725 | cs_debug_mask(D_IFD, "Setting baudrate to %lu", baud_temp); |
---|
726 | current_baudrate = baud_temp; //this is needed for all readers to calculate work_etu for timings |
---|
727 | } |
---|
728 | |
---|
729 | //set timings according to ATR |
---|
730 | read_timeout = 0; |
---|
731 | icc_timings.block_delay = 0; |
---|
732 | icc_timings.char_delay = 0; |
---|
733 | |
---|
734 | if (n == 255) //Extra Guard Time |
---|
735 | EGT = 0; |
---|
736 | else |
---|
737 | EGT = n; |
---|
738 | GT = EGT + 12; //Guard Time in ETU |
---|
739 | gt_ms = ETU_to_ms(GT); |
---|
740 | |
---|
741 | switch (protocol_type) { |
---|
742 | case ATR_PROTOCOL_TYPE_T0: |
---|
743 | case ATR_PROTOCOL_TYPE_T14: |
---|
744 | { |
---|
745 | BYTE wi; |
---|
746 | /* Integer value WI = TC2, by default 10 */ |
---|
747 | #ifndef PROTOCOL_T0_USE_DEFAULT_TIMINGS |
---|
748 | if (ATR_GetInterfaceByte (atr, 2, ATR_INTERFACE_BYTE_TC, &(wi)) != ATR_OK) |
---|
749 | #endif |
---|
750 | wi = DEFAULT_WI; |
---|
751 | |
---|
752 | // WWT = 960 * WI * (Fi / f) * 1000 milliseconds |
---|
753 | WWT = (unsigned long) 960 * wi; //in ETU |
---|
754 | if (protocol_type == ATR_PROTOCOL_TYPE_T14) |
---|
755 | WWT >>= 1; //is this correct? |
---|
756 | |
---|
757 | read_timeout = ETU_to_ms(WWT); |
---|
758 | icc_timings.block_delay = gt_ms; |
---|
759 | icc_timings.char_delay = gt_ms; |
---|
760 | cs_debug("Setting timings: timeout=%u ms, block_delay=%u ms, char_delay=%u ms", read_timeout, icc_timings.block_delay, icc_timings.char_delay); |
---|
761 | cs_debug_mask (D_IFD,"Protocol: T=%i: WWT=%d, Clockrate=%lu\n", protocol_type, (int)(WWT), ICC_Async_GetClockRate()); |
---|
762 | } |
---|
763 | break; |
---|
764 | case ATR_PROTOCOL_TYPE_T1: |
---|
765 | { |
---|
766 | BYTE ta, tb, tc, cwi, bwi; |
---|
767 | |
---|
768 | // Set IFSC |
---|
769 | if (ATR_GetInterfaceByte (atr, 3, ATR_INTERFACE_BYTE_TA, &ta) == ATR_NOT_FOUND) |
---|
770 | ifsc = DEFAULT_IFSC; |
---|
771 | else if ((ta != 0x00) && (ta != 0xFF)) |
---|
772 | ifsc = ta; |
---|
773 | else |
---|
774 | ifsc = DEFAULT_IFSC; |
---|
775 | |
---|
776 | // Towitoko does not allow IFSC > 251 //FIXME not sure whether this limitation still exists |
---|
777 | // ifsc = MIN (ifsc, MAX_IFSC); |
---|
778 | |
---|
779 | ifsc = MIN (ifsc, MAX_IFSC); |
---|
780 | |
---|
781 | #ifndef PROTOCOL_T1_USE_DEFAULT_TIMINGS |
---|
782 | // Calculate CWI and BWI |
---|
783 | if (ATR_GetInterfaceByte (atr, 3, ATR_INTERFACE_BYTE_TB, &tb) == ATR_NOT_FOUND) |
---|
784 | { |
---|
785 | #endif |
---|
786 | cwi = DEFAULT_CWI; |
---|
787 | bwi = DEFAULT_BWI; |
---|
788 | #ifndef PROTOCOL_T1_USE_DEFAULT_TIMINGS |
---|
789 | } |
---|
790 | else |
---|
791 | { |
---|
792 | cwi = tb & 0x0F; |
---|
793 | bwi = tb >> 4; |
---|
794 | } |
---|
795 | #endif |
---|
796 | |
---|
797 | // Set CWT = (2^CWI + 11) work etu |
---|
798 | CWT = (unsigned short) (((1<<cwi) + 11)); // in ETU |
---|
799 | |
---|
800 | // Set BWT = (2^BWI * 960 + 11) work etu |
---|
801 | BWT = (unsigned short)((1<<bwi) * 960 * 372 * 9600 / ICC_Async_GetClockRate() ) + 11 ; |
---|
802 | |
---|
803 | // Set BGT = 22 * work etu |
---|
804 | BGT = 22L; //in ETU |
---|
805 | |
---|
806 | if (n == 255) |
---|
807 | CGT = 11L; //in ETU |
---|
808 | else |
---|
809 | CGT = GT; |
---|
810 | |
---|
811 | // Set the error detection code type |
---|
812 | if (ATR_GetInterfaceByte (atr, 3, ATR_INTERFACE_BYTE_TC, &tc) == ATR_NOT_FOUND) |
---|
813 | edc = EDC_LRC; |
---|
814 | else |
---|
815 | edc = tc & 0x01; |
---|
816 | |
---|
817 | // Set initial send sequence (NS) |
---|
818 | ns = 1; |
---|
819 | |
---|
820 | cs_debug ("Protocol: T=1: IFSC=%d, CWT=%d etu, BWT=%d etu, BGT=%d etu, EDC=%s\n", ifsc, CWT, BWT, BGT, (edc == EDC_LRC) ? "LRC" : "CRC"); |
---|
821 | |
---|
822 | read_timeout = ETU_to_ms(BWT); |
---|
823 | icc_timings.block_delay = ETU_to_ms(BGT); |
---|
824 | icc_timings.char_delay = ETU_to_ms(CGT); |
---|
825 | cs_debug("Setting timings: timeout=%u ms, block_delay=%u ms, char_delay=%u ms", read_timeout, icc_timings.block_delay, icc_timings.char_delay); |
---|
826 | } |
---|
827 | break; |
---|
828 | default: |
---|
829 | return ERROR; |
---|
830 | break; |
---|
831 | }//switch |
---|
832 | |
---|
833 | call (SetRightParity ()); |
---|
834 | |
---|
835 | //write settings to internal device |
---|
836 | if(reader[ridx].typ == R_INTERNAL) { |
---|
837 | #ifdef SCI_DEV |
---|
838 | double F = (double) atr_f_table[FI]; |
---|
839 | unsigned long ETU = 0; |
---|
840 | //for Irdeto T14 cards, do not set ETU |
---|
841 | if (!(atr->hbn >= 6 && !memcmp(atr->hb, "IRDETO", 6) && protocol_type == ATR_PROTOCOL_TYPE_T14)) |
---|
842 | ETU = F / d; |
---|
843 | call (Sci_WriteSettings (protocol_type, reader[ridx].mhz / 100, ETU, WWT, BWT, CWT, EGT, (unsigned char)P, (unsigned char)I)); |
---|
844 | #elif COOL |
---|
845 | call (Cool_SetClockrate(reader[ridx].mhz)); |
---|
846 | call (Cool_WriteSettings (BWT, CWT, EGT, BGT)); |
---|
847 | #endif //COOL |
---|
848 | } |
---|
849 | #if defined(LIBUSB) |
---|
850 | if (reader[ridx].typ == R_SMART) |
---|
851 | SR_WriteSettings(&reader[ridx], (unsigned short) atr_f_table[FI], (BYTE)d, (BYTE)EGT, (BYTE)protocol_type, convention); |
---|
852 | #endif |
---|
853 | cs_log("Maximum frequency for this card is formally %i Mhz, clocking it to %.2f Mhz", atr_fs_table[FI] / 1000000, (float) reader[ridx].mhz / 100); |
---|
854 | |
---|
855 | //IFS setting in case of T1 |
---|
856 | if ((protocol_type == ATR_PROTOCOL_TYPE_T1) && (ifsc != DEFAULT_IFSC)) { |
---|
857 | APDU_Rsp ** rsp; |
---|
858 | unsigned char tmp[] = { 0x21, 0xC1, 0x01, 0x00, 0x00 }; |
---|
859 | tmp[3] = ifsc; // Information Field size |
---|
860 | tmp[4] = ifsc ^ 0xE1; |
---|
861 | Protocol_T1_Command (tmp, sizeof(tmp), rsp); |
---|
862 | } |
---|
863 | return OK; |
---|
864 | } |
---|
865 | |
---|
866 | static BYTE PPS_GetPCK (BYTE * block, unsigned length) |
---|
867 | { |
---|
868 | BYTE pck; |
---|
869 | unsigned i; |
---|
870 | |
---|
871 | pck = block[0]; |
---|
872 | for (i = 1; i < length; i++) |
---|
873 | pck ^= block[i]; |
---|
874 | |
---|
875 | return pck; |
---|
876 | } |
---|