/[pcsclite]/trunk/Drivers/ccid/src/commands.c
ViewVC logotype

Contents of /trunk/Drivers/ccid/src/commands.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3004 - (show annotations) (download)
Mon Jun 16 08:35:10 2008 UTC (4 years, 11 months ago) by rousseau
File MIME type: text/plain
File size: 53995 byte(s)
CCID_Receive(): do not crash if the reader firmware is bogus and does
not support chaining for extended APDU.

This is the case for Kobil readers
1 /*
2 commands.c: Commands sent to the card
3 Copyright (C) 2003-2004 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 License
16 along with this library; if not, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 /*
21 * $Id$
22 */
23
24 #include <string.h>
25 #include <stdlib.h>
26 #include <errno.h>
27 #include <pcsclite.h>
28 #include <ifdhandler.h>
29 #include <reader.h>
30
31 #include "misc.h"
32 #include "commands.h"
33 #include "openct/proto-t1.h"
34 #include "ccid.h"
35 #include "defs.h"
36 #include "ccid_ifdhandler.h"
37 #include "config.h"
38 #include "debug.h"
39 #include "ccid_usb.h"
40
41 /* All the pinpad readers I used are more or less bogus
42 * I use code to change the user command and make the firmware happy */
43 #define BOGUS_PINPAD_FIRMWARE
44
45 /* The firmware of SCM readers reports dwMaxCCIDMessageLength = 263
46 * instead of 270 so this prevents from sending a full length APDU
47 * of 260 bytes since the driver check this value */
48 #define BOGUS_SCM_FIRMWARE_FOR_dwMaxCCIDMessageLength
49
50 #define max( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )
51 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
52 #define IFD_ERROR_INSUFFICIENT_BUFFER 700
53
54 /* internal functions */
55 static RESPONSECODE CmdXfrBlockAPDU_extended(unsigned int reader_index,
56 unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length,
57 unsigned char rx_buffer[]);
58
59 static RESPONSECODE CmdXfrBlockTPDU_T0(unsigned int reader_index,
60 unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length,
61 unsigned char rx_buffer[]);
62
63 static RESPONSECODE CmdXfrBlockCHAR_T0(unsigned int reader_index, unsigned int
64 tx_length, unsigned char tx_buffer[], unsigned int *rx_length, unsigned
65 char rx_buffer[]);
66
67 static RESPONSECODE CmdXfrBlockTPDU_T1(unsigned int reader_index,
68 unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length,
69 unsigned char rx_buffer[]);
70
71 static void i2dw(int value, unsigned char *buffer);
72
73
74 /*****************************************************************************
75 *
76 * CmdPowerOn
77 *
78 ****************************************************************************/
79 RESPONSECODE CmdPowerOn(unsigned int reader_index, unsigned int * nlength,
80 unsigned char buffer[], int voltage)
81 {
82 unsigned char cmd[10];
83 status_t res;
84 int length, count = 1;
85 unsigned int atr_len;
86 RESPONSECODE return_value = IFD_SUCCESS;
87 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
88
89 #ifndef TWIN_SERIAL
90 if (ICCD_A == ccid_descriptor->bInterfaceProtocol)
91 {
92 int r;
93 unsigned char pcbuffer[SIZE_GET_SLOT_STATUS];
94
95 /* first power off to reset the ICC state machine */
96 r = CmdPowerOff(reader_index);
97 if (r != IFD_SUCCESS)
98 return r;
99
100 /* wait for ready */
101 r = CmdGetSlotStatus(reader_index, pcbuffer);
102 if (r != IFD_SUCCESS)
103 return r;
104
105 /* Power On */
106 r = ControlUSB(reader_index, 0xA1, 0x62, 0, buffer, *nlength);
107
108 /* we got an error? */
109 if (r < 0)
110 {
111 DEBUG_INFO2("ICC Power On failed: %s", strerror(errno));
112 return IFD_COMMUNICATION_ERROR;
113 }
114
115 *nlength = r;
116
117 return IFD_SUCCESS;
118 }
119
120 if (ICCD_B == ccid_descriptor->bInterfaceProtocol)
121 {
122 int r;
123 unsigned char tmp[MAX_ATR_SIZE+1];
124
125 /* first power off to reset the ICC state machine */
126 r = CmdPowerOff(reader_index);
127 if (r != IFD_SUCCESS)
128 return r;
129
130 /* Power On */
131 r = ControlUSB(reader_index, 0x21, 0x62, 1, NULL, 0);
132
133 /* we got an error? */
134 if (r < 0)
135 {
136 DEBUG_INFO2("ICC Power On failed: %s", strerror(errno));
137 return IFD_COMMUNICATION_ERROR;
138 }
139
140 /* Data Block */
141 r = ControlUSB(reader_index, 0xA1, 0x6F, 0, tmp, sizeof(tmp));
142
143 /* we got an error? */
144 if (r < 0)
145 {
146 DEBUG_INFO2("ICC Data Block failed: %s", strerror(errno));
147 return IFD_COMMUNICATION_ERROR;
148 }
149
150 if (tmp[0] != 0x00)
151 {
152 DEBUG_CRITICAL2("bResponseType: 0x%02X", tmp[0]);
153
154 /* Status Information? */
155 if (0x40 == tmp[0])
156 ccid_error(tmp[2], __FILE__, __LINE__, __FUNCTION__);
157 return IFD_COMMUNICATION_ERROR;
158 }
159
160 DEBUG_INFO_XXD("Data Block: ", tmp, r);
161 if (*nlength > r-1)
162 *nlength = r-1;
163 memcpy(buffer, tmp+1, *nlength);
164
165 return IFD_SUCCESS;
166 }
167 #endif
168
169 /* store length of buffer[] */
170 length = *nlength;
171
172 if (ccid_descriptor->dwFeatures & CCID_CLASS_AUTO_VOLTAGE)
173 voltage = 0; /* automatic voltage selection */
174
175 again:
176 cmd[0] = 0x62; /* IccPowerOn */
177 cmd[1] = cmd[2] = cmd[3] = cmd[4] = 0; /* dwLength */
178 cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
179 cmd[6] = (*ccid_descriptor->pbSeq)++;
180 cmd[7] = voltage;
181 cmd[8] = cmd[9] = 0; /* RFU */
182
183 res = WritePort(reader_index, sizeof(cmd), cmd);
184 if (res != STATUS_SUCCESS)
185 return IFD_COMMUNICATION_ERROR;
186
187 /* reset available buffer size */
188 /* needed if we go back after a switch to ISO mode */
189 *nlength = length;
190
191 res = ReadPort(reader_index, nlength, buffer);
192 if (res != STATUS_SUCCESS)
193 return IFD_COMMUNICATION_ERROR;
194
195 if (*nlength < STATUS_OFFSET+1)
196 {
197 DEBUG_CRITICAL2("Not enough data received: %d bytes", *nlength);
198 return IFD_COMMUNICATION_ERROR;
199 }
200
201 if (buffer[STATUS_OFFSET] & CCID_COMMAND_FAILED)
202 {
203 ccid_error(buffer[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__); /* bError */
204
205 if (0xBB == buffer[ERROR_OFFSET] && /* Protocol error in EMV mode */
206 ((GEMPC433 == ccid_descriptor->readerID)
207 || (CHERRYXX33 == ccid_descriptor->readerID)))
208 {
209 unsigned char cmd_tmp[] = {0x1F, 0x01};
210 unsigned char res_tmp[1];
211 unsigned int res_length = sizeof(res_tmp);
212
213 if ((return_value = CmdEscape(reader_index, cmd_tmp,
214 sizeof(cmd_tmp), res_tmp, &res_length)) != IFD_SUCCESS)
215 return return_value;
216
217 /* avoid looping if we can't switch mode */
218 if (count--)
219 goto again;
220 else
221 DEBUG_CRITICAL("Can't set reader in ISO mode");
222 }
223
224 /* continue with 3 volts and 5 volts */
225 if (voltage > 1)
226 {
227 const char *voltage_code[] = { "auto", "5V", "3V", "1.8V" };
228
229 DEBUG_INFO3("Power up with %s failed. Try with %s.",
230 voltage_code[voltage], voltage_code[voltage-1]);
231 voltage--;
232 goto again;
233 }
234
235 return IFD_COMMUNICATION_ERROR;
236 }
237
238 /* extract the ATR */
239 atr_len = dw2i(buffer, 1); /* ATR length */
240 if (atr_len > *nlength)
241 atr_len = *nlength;
242 else
243 *nlength = atr_len;
244
245 memmove(buffer, buffer+10, atr_len);
246
247 return return_value;
248 } /* CmdPowerOn */
249
250
251 /*****************************************************************************
252 *
253 * SecurePINVerify
254 *
255 ****************************************************************************/
256 RESPONSECODE SecurePINVerify(unsigned int reader_index,
257 unsigned char TxBuffer[], unsigned int TxLength,
258 unsigned char RxBuffer[], unsigned int *RxLength)
259 {
260 unsigned char cmd[11+14+CMD_BUF_SIZE];
261 unsigned int a, b;
262 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
263 int old_read_timeout;
264 RESPONSECODE ret;
265
266 cmd[0] = 0x69; /* Secure */
267 cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
268 cmd[6] = (*ccid_descriptor->pbSeq)++;
269 cmd[7] = 0; /* bBWI */
270 cmd[8] = 0; /* wLevelParameter */
271 cmd[9] = 0;
272 cmd[10] = 0; /* bPINOperation: PIN Verification */
273
274 /* 19 is the size of the PCSCv2 PIN verify structure
275 * The equivalent CCID structure is only 14-bytes long */
276 if (TxLength > 19+CMD_BUF_SIZE) /* command too large? */
277 {
278 DEBUG_INFO3("Command too long: %d > %d", TxLength, 19+CMD_BUF_SIZE);
279 return IFD_NOT_SUPPORTED;
280 }
281
282 if (TxLength < 19+4 /* 4 = APDU size */) /* command too short? */
283 {
284 DEBUG_INFO3("Command too short: %d < %d", TxLength, 19+4);
285 return IFD_NOT_SUPPORTED;
286 }
287
288 if (dw2i(TxBuffer, 15) + 19 != TxLength) /* ulDataLength field coherency */
289 {
290 DEBUG_INFO3("Wrong lengths: %d %d", dw2i(TxBuffer, 15) + 19, TxLength);
291 return IFD_NOT_SUPPORTED;
292 }
293
294 /* make sure bEntryValidationCondition is valid
295 * The Cherry XX44 reader crashes with a wrong value */
296 if ((0x00 == TxBuffer[7]) || (TxBuffer[7] > 0x07))
297 {
298 DEBUG_INFO2("Correct bEntryValidationCondition (was 0x%02X)",
299 TxBuffer[7]);
300 TxBuffer[7] = 0x02;
301 }
302
303 #ifdef BOGUS_PINPAD_FIRMWARE
304 /* bug circumvention for the GemPC Pinpad */
305 if (GEMPCPINPAD == ccid_descriptor->readerID)
306 {
307 /* the firmware reject the cases: 00h No string and FFh default
308 * CCID message. The only value supported is 01h (display 1 message) */
309 if (0x01 != TxBuffer[8])
310 {
311 DEBUG_INFO2("Correct bNumberMessage for GemPC Pinpad (was %d)",
312 TxBuffer[8]);
313 TxBuffer[8] = 0x01;
314 }
315
316 /* The reader does not support, and actively reject, "max size reached"
317 * and "timeout occured" validation conditions */
318 if (0x02 != TxBuffer[7])
319 {
320 DEBUG_INFO2("Correct bEntryValidationCondition for GemPC Pinpad (was %d)",
321 TxBuffer[7]);
322 TxBuffer[7] = 0x02; /* validation key pressed */
323 }
324
325 }
326 #endif
327
328 /* T=1 Protocol Management for a TPDU reader */
329 if ((SCARD_PROTOCOL_T1 == ccid_descriptor->cardProtocol)
330 && (CCID_CLASS_TPDU == (ccid_descriptor->dwFeatures & CCID_CLASS_EXCHANGE_MASK)))
331 {
332 ct_buf_t sbuf;
333 unsigned char sdata[T1_BUFFER_SIZE];
334
335 /* Initialize send buffer with the APDU */
336 ct_buf_set(&sbuf,
337 (void *)(TxBuffer + offsetof(PIN_VERIFY_STRUCTURE, abData)),
338 TxLength - offsetof(PIN_VERIFY_STRUCTURE, abData));
339
340 /* Create T=1 block */
341 ret = t1_build(&((get_ccid_slot(reader_index))->t1),
342 sdata, 0, T1_I_BLOCK, &sbuf, NULL);
343
344 /* Increment the sequence numbers */
345 get_ccid_slot(reader_index)->t1.ns ^= 1;
346 get_ccid_slot(reader_index)->t1.nr ^= 1;
347
348 /* Copy the generated T=1 block prologue into the teoprologue
349 * of the CCID command */
350 memcpy(TxBuffer + offsetof(PIN_VERIFY_STRUCTURE, bTeoPrologue),
351 sdata, 3);
352 }
353
354 /* Build a CCID block from a PC/SC V2.1.2 Part 10 block */
355 for (a = 11, b = 0; b < TxLength; b++)
356 {
357 if (1 == b) /* bTimeOut2 field */
358 /* Ignore the second timeout as there's nothing we can do with
359 * it currently */
360 continue;
361
362 if ((b >= 15) && (b <= 18)) /* ulDataLength field (4 bytes) */
363 /* the ulDataLength field is not present in the CCID frame
364 * so do not copy */
365 continue;
366
367 /* copy the CCID block 'verbatim' */
368 cmd[a] = TxBuffer[b];
369 a++;
370 }
371
372 /* SPR532 and Case 1 APDU */
373 if ((SPR532 == ccid_descriptor->readerID) && (TxBuffer[15] == 4))
374 {
375 RESPONSECODE return_value;
376 unsigned char cmd_tmp[] = { 0x80, 0x02, 0x00 };
377 unsigned char res_tmp[1];
378 unsigned int res_length = sizeof(res_tmp);
379
380 /* the SPR532 will append the PIN code without any padding */
381 return_value = CmdEscape(reader_index, cmd_tmp, sizeof(cmd_tmp),
382 res_tmp, &res_length);
383 if (return_value != IFD_SUCCESS)
384 return return_value;
385 }
386
387 i2dw(a - 10, cmd + 1); /* CCID message length */
388
389 old_read_timeout = ccid_descriptor -> readTimeout;
390 ccid_descriptor -> readTimeout = max(30, TxBuffer[0]+10); /* at least 30 seconds */
391
392 if (WritePort(reader_index, a, cmd) != STATUS_SUCCESS)
393 return IFD_COMMUNICATION_ERROR;
394
395 ret = CCID_Receive(reader_index, RxLength, RxBuffer, NULL);
396
397 /* T=1 Protocol Management for a TPDU reader */
398 if ((IFD_SUCCESS == ret)
399 && (SCARD_PROTOCOL_T1 == ccid_descriptor->cardProtocol)
400 && (CCID_CLASS_TPDU == (ccid_descriptor->dwFeatures & CCID_CLASS_EXCHANGE_MASK)))
401 {
402 /* timeout and cancel cases are faked by CCID_Receive() */
403 if (2 == *RxLength)
404 {
405 /* Decrement the sequence numbers since no TPDU was sent */
406 get_ccid_slot(reader_index)->t1.ns ^= 1;
407 get_ccid_slot(reader_index)->t1.nr ^= 1;
408 }
409 else
410 {
411 /* get only the T=1 data */
412 /* FIXME: manage T=1 error blocks */
413 memmove(RxBuffer, RxBuffer+3, *RxLength -4);
414 *RxLength -= 4; /* remove NAD, PCB, LEN and CRC */
415 }
416 }
417
418 ccid_descriptor -> readTimeout = old_read_timeout;
419 return ret;
420 } /* SecurePINVerify */
421
422
423 /*****************************************************************************
424 *
425 * SecurePINModify
426 *
427 ****************************************************************************/
428 RESPONSECODE SecurePINModify(unsigned int reader_index,
429 unsigned char TxBuffer[], unsigned int TxLength,
430 unsigned char RxBuffer[], unsigned int *RxLength)
431 {
432 unsigned char cmd[11+19+CMD_BUF_SIZE];
433 unsigned int a, b;
434 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
435 int old_read_timeout;
436 RESPONSECODE ret;
437 #ifdef BOGUS_PINPAD_FIRMWARE
438 int bNumberMessages = 0; /* for GemPC Pinpad */
439 #endif
440
441 cmd[0] = 0x69; /* Secure */
442 cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
443 cmd[6] = (*ccid_descriptor->pbSeq)++;
444 cmd[7] = 0; /* bBWI */
445 cmd[8] = 0; /* wLevelParameter */
446 cmd[9] = 0;
447 cmd[10] = 1; /* bPINOperation: PIN Modification */
448
449 /* 24 is the size of the PCSC PIN modify structure
450 * The equivalent CCID structure is only 18 or 19-bytes long */
451 if (TxLength > 24+CMD_BUF_SIZE) /* command too large? */
452 {
453 DEBUG_INFO3("Command too long: %d > %d", TxLength, 24+CMD_BUF_SIZE);
454 return IFD_NOT_SUPPORTED;
455 }
456
457 if (TxLength < 24+4 /* 4 = APDU size */) /* command too short? */
458 {
459 DEBUG_INFO3("Command too short: %d < %d", TxLength, 24+4);
460 return IFD_NOT_SUPPORTED;
461 }
462
463 if (dw2i(TxBuffer, 20) + 24 != TxLength) /* ulDataLength field coherency */
464 {
465 DEBUG_INFO3("Wrong lengths: %d %d", dw2i(TxBuffer, 20) + 24, TxLength);
466 return IFD_NOT_SUPPORTED;
467 }
468
469 /* Make sure in the beginning if bNumberMessage is valid or not */
470 if (TxBuffer[11] > 3)
471 {
472 DEBUG_INFO2("Wrong bNumberMessage: %d", TxBuffer[11]);
473 return IFD_NOT_SUPPORTED;
474 }
475
476 /* Make sure bEntryValidationCondition is valid
477 * The Cherry XX44 reader crashes with a wrong value */
478 if ((0x00 == TxBuffer[10]) || (TxBuffer[10] > 0x07))
479 {
480 DEBUG_INFO2("Correct bEntryValidationCondition (was 0x%02X)",
481 TxBuffer[10]);
482 TxBuffer[10] = 0x02;
483 }
484
485 #ifdef BOGUS_PINPAD_FIRMWARE
486 /* some firmwares are buggy so we try to "correct" the frame */
487 /*
488 * SPR 532 and Cherry ST 2000C has no display but requires _all_
489 * bMsgIndex fields with bNumberMessage set to 0.
490 */
491 if ((SPR532 == ccid_descriptor->readerID)
492 || (CHERRYST2000 == ccid_descriptor->readerID))
493 {
494 TxBuffer[11] = 0x03; /* set bNumberMessages to 3 so that
495 all bMsgIndex123 are filled */
496 TxBuffer[14] = TxBuffer[15] = TxBuffer[16] = 0; /* bMsgIndex123 */
497 }
498
499 /* the bug is a bit different than for the Cherry ST 2000C
500 * with bNumberMessages < 3 the command seems to be accepted
501 * and the card sends 6B 80 */
502 if (CHERRYXX44 == ccid_descriptor->readerID)
503 {
504 TxBuffer[11] = 0x03; /* set bNumberMessages to 3 so that
505 all bMsgIndex123 are filled */
506 }
507
508 /* bug circumvention for the GemPC Pinpad */
509 if (GEMPCPINPAD == ccid_descriptor->readerID)
510 {
511 /* The reader does not support, and actively reject, "max size reached"
512 * and "timeout occured" validation conditions */
513 if (0x02 != TxBuffer[10])
514 {
515 DEBUG_INFO2("Correct bEntryValidationCondition for GemPC Pinpad (was %d)",
516 TxBuffer[10]);
517 TxBuffer[10] = 0x02; /* validation key pressed */
518 }
519
520 /* the reader does not support any other value than 3 for the number
521 * of messages */
522 bNumberMessages = TxBuffer[11];
523 if (0x03 != TxBuffer[11])
524 {
525 DEBUG_INFO2("Correct bNumberMessages for GemPC Pinpad (was %d)",
526 TxBuffer[11]);
527 TxBuffer[11] = 0x03; /* 3 messages */
528 }
529 }
530 #endif
531
532 /* T=1 Protocol Management for a TPDU reader */
533 if ((SCARD_PROTOCOL_T1 == ccid_descriptor->cardProtocol)
534 && (CCID_CLASS_TPDU == (ccid_descriptor->dwFeatures & CCID_CLASS_EXCHANGE_MASK)))
535 {
536 ct_buf_t sbuf;
537 unsigned char sdata[T1_BUFFER_SIZE];
538
539 /* Initialize send buffer with the APDU */
540 ct_buf_set(&sbuf,
541 (void *)(TxBuffer + offsetof(PIN_MODIFY_STRUCTURE, abData)),
542 TxLength - offsetof(PIN_MODIFY_STRUCTURE, abData));
543
544 /* Create T=1 block */
545 ret = t1_build(&((get_ccid_slot(reader_index))->t1),
546 sdata, 0, T1_I_BLOCK, &sbuf, NULL);
547
548 /* Increment the sequence numbers */
549 get_ccid_slot(reader_index)->t1.ns ^= 1;
550 get_ccid_slot(reader_index)->t1.nr ^= 1;
551
552 /* Copy the generated T=1 block prologue into the teoprologue
553 * of the CCID command */
554 memcpy(TxBuffer + offsetof(PIN_MODIFY_STRUCTURE, bTeoPrologue),
555 sdata, 3);
556 }
557
558 /* Build a CCID block from a PC/SC V2.1.2 Part 10 block */
559
560 /* Do adjustments as needed - CCID spec is not exact with some
561 * details in the format of the structure, per-reader adaptions
562 * might be needed.
563 */
564 for (a = 11, b = 0; b < TxLength; b++)
565 {
566 if (1 == b) /* bTimeOut2 */
567 /* Ignore the second timeout as there's nothing we can do with it
568 * currently */
569 continue;
570
571 if (15 == b) /* bMsgIndex2 */
572 {
573 /* in CCID the bMsgIndex2 is present only if bNumberMessage != 0 */
574 if (0 == TxBuffer[11])
575 continue;
576 }
577
578 if (16 == b) /* bMsgIndex3 */
579 {
580 /* in CCID the bMsgIndex3 is present only if bNumberMessage == 3 */
581 if (TxBuffer[11] < 3)
582 continue;
583 }
584
585 if ((b >= 20) && (b <= 23)) /* ulDataLength field (4 bytes) */
586 /* the ulDataLength field is not present in the CCID frame
587 * so do not copy */
588 continue;
589
590 /* copy to the CCID block 'verbatim' */
591 cmd[a] = TxBuffer[b];
592 a++;
593 }
594
595 #ifdef BOGUS_PINPAD_FIRMWARE
596 if ((SPR532 == ccid_descriptor->readerID)
597 || (CHERRYST2000 == ccid_descriptor->readerID))
598 {
599 cmd[21] = 0x00; /* set bNumberMessages to 0 */
600 }
601
602 if (GEMPCPINPAD == ccid_descriptor->readerID)
603 cmd[21] = bNumberMessages; /* restore the real value */
604 #endif
605
606 /* We know the size of the CCID message now */
607 i2dw(a - 10, cmd + 1); /* command length (includes bPINOperation) */
608
609 old_read_timeout = ccid_descriptor -> readTimeout;
610 ccid_descriptor -> readTimeout = max(30, TxBuffer[0]+10); /* at least 30 seconds */
611
612 if (WritePort(reader_index, a, cmd) != STATUS_SUCCESS)
613 return IFD_COMMUNICATION_ERROR;
614
615 ret = CCID_Receive(reader_index, RxLength, RxBuffer, NULL);
616
617 /* T=1 Protocol Management for a TPDU reader */
618 if ((IFD_SUCCESS == ret)
619 && (SCARD_PROTOCOL_T1 == ccid_descriptor->cardProtocol)
620 && (CCID_CLASS_TPDU == (ccid_descriptor->dwFeatures & CCID_CLASS_EXCHANGE_MASK)))
621 {
622 /* timeout and cancel cases are faked by CCID_Receive() */
623 if (2 == *RxLength)
624 {
625 /* Decrement the sequence numbers since no TPDU was sent */
626 get_ccid_slot(reader_index)->t1.ns ^= 1;
627 get_ccid_slot(reader_index)->t1.nr ^= 1;
628 }
629 else
630 {
631 /* get only the T=1 data */
632 /* FIXME: manage T=1 error blocks */
633 memmove(RxBuffer, RxBuffer+3, *RxLength -4);
634 *RxLength -= 4; /* remove NAD, PCB, LEN and CRC */
635 }
636 }
637
638 ccid_descriptor -> readTimeout = old_read_timeout;
639 return ret;
640 } /* SecurePINModify */
641
642
643 /*****************************************************************************
644 *
645 * Escape
646 *
647 ****************************************************************************/
648 RESPONSECODE CmdEscape(unsigned int reader_index,
649 const unsigned char TxBuffer[], unsigned int TxLength,
650 unsigned char RxBuffer[], unsigned int *RxLength)
651 {
652 unsigned char *cmd_in, *cmd_out;
653 status_t res;
654 unsigned int length_in, length_out;
655 RESPONSECODE return_value = IFD_SUCCESS;
656 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
657
658 again:
659 /* allocate buffers */
660 length_in = 10 + TxLength;
661 if (NULL == (cmd_in = malloc(length_in)))
662 return IFD_COMMUNICATION_ERROR;
663
664 length_out = 10 + *RxLength;
665 if (NULL == (cmd_out = malloc(length_out)))
666 {
667 free(cmd_in);
668 return IFD_COMMUNICATION_ERROR;
669 }
670
671 cmd_in[0] = 0x6B; /* PC_to_RDR_Escape */
672 i2dw(length_in - 10, cmd_in+1); /* dwLength */
673 cmd_in[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
674 cmd_in[6] = (*ccid_descriptor->pbSeq)++;
675 cmd_in[7] = cmd_in[8] = cmd_in[9] = 0; /* RFU */
676
677 /* copy the command */
678 memcpy(&cmd_in[10], TxBuffer, TxLength);
679
680 res = WritePort(reader_index, length_in, cmd_in);
681 free(cmd_in);
682 if (res != STATUS_SUCCESS)
683 {
684 free(cmd_out);
685 return IFD_COMMUNICATION_ERROR;
686 }
687
688 res = ReadPort(reader_index, &length_out, cmd_out);
689
690 /* replay the command if NAK
691 * This (generally) happens only for the first command sent to the reader
692 * with the serial protocol so it is not really needed for all the other
693 * ReadPort() calls */
694 if (STATUS_COMM_NAK == res)
695 {
696 free(cmd_out);
697 goto again;
698 }
699
700 if (res != STATUS_SUCCESS)
701 {
702 free(cmd_out);
703 return IFD_COMMUNICATION_ERROR;
704 }
705
706 if (length_out < STATUS_OFFSET+1)
707 {
708 DEBUG_CRITICAL2("Not enough data received: %d bytes", length_out);
709 return IFD_COMMUNICATION_ERROR;
710 }
711
712 if (cmd_out[STATUS_OFFSET] & CCID_COMMAND_FAILED)
713 {
714 ccid_error(cmd_out[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__); /* bError */
715 return_value = IFD_COMMUNICATION_ERROR;
716 }
717
718 /* copy the response */
719 length_out = dw2i(cmd_out, 1);
720 if (length_out > *RxLength)
721 length_out = *RxLength;
722 *RxLength = length_out;
723 memcpy(RxBuffer, &cmd_out[10], length_out);
724
725 free(cmd_out);
726
727 return return_value;
728 } /* Escape */
729
730
731 /*****************************************************************************
732 *
733 * CmdPowerOff
734 *
735 ****************************************************************************/
736 RESPONSECODE CmdPowerOff(unsigned int reader_index)
737 {
738 unsigned char cmd[10];
739 status_t res;
740 unsigned int length;
741 RESPONSECODE return_value = IFD_SUCCESS;
742 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
743
744 #ifndef TWIN_SERIAL
745 if (ICCD_A == ccid_descriptor->bInterfaceProtocol)
746 {
747 int r;
748
749 /* PowerOff */
750 r = ControlUSB(reader_index, 0x21, 0x63, 0, NULL, 0);
751
752 /* we got an error? */
753 if (r < 0)
754 {
755 DEBUG_INFO2("ICC Power Off failed: %s", strerror(errno));
756 return IFD_COMMUNICATION_ERROR;
757 }
758
759 return IFD_SUCCESS;
760 }
761
762 if (ICCD_B == ccid_descriptor->bInterfaceProtocol)
763 {
764 int r;
765 unsigned char buffer[3];
766
767 /* PowerOff */
768 r = ControlUSB(reader_index, 0x21, 0x63, 0, NULL, 0);
769
770 /* we got an error? */
771 if (r < 0)
772 {
773 DEBUG_INFO2("ICC Power Off failed: %s", strerror(errno));
774 return IFD_COMMUNICATION_ERROR;
775 }
776
777 /* SlotStatus */
778 r = ControlUSB(reader_index, 0xA1, 0x81, 0, buffer, sizeof(buffer));
779
780 /* we got an error? */
781 if (r < 0)
782 {
783 DEBUG_INFO2("ICC SlotStatus failed: %s", strerror(errno));
784 return IFD_COMMUNICATION_ERROR;
785 }
786
787 return IFD_SUCCESS;
788 }
789 #endif
790
791 cmd[0] = 0x63; /* IccPowerOff */
792 cmd[1] = cmd[2] = cmd[3] = cmd[4] = 0; /* dwLength */
793 cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
794 cmd[6] = (*ccid_descriptor->pbSeq)++;
795 cmd[7] = cmd[8] = cmd[9] = 0; /* RFU */
796
797 res = WritePort(reader_index, sizeof(cmd), cmd);
798 if (res != STATUS_SUCCESS)
799 return IFD_COMMUNICATION_ERROR;
800
801 length = sizeof(cmd);
802 res = ReadPort(reader_index, &length, cmd);
803 if (res != STATUS_SUCCESS)
804 return IFD_COMMUNICATION_ERROR;
805
806 if (length < STATUS_OFFSET+1)
807 {
808 DEBUG_CRITICAL2("Not enough data received: %d bytes", length);
809 return IFD_COMMUNICATION_ERROR;
810 }
811
812 if (cmd[STATUS_OFFSET] & CCID_COMMAND_FAILED)
813 {
814 ccid_error(cmd[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__); /* bError */
815 return_value = IFD_COMMUNICATION_ERROR;
816 }
817
818 return return_value;
819 } /* CmdPowerOff */
820
821
822 /*****************************************************************************
823 *
824 * CmdGetSlotStatus
825 *
826 ****************************************************************************/
827 RESPONSECODE CmdGetSlotStatus(unsigned int reader_index, unsigned char buffer[])
828 {
829 unsigned char cmd[10];
830 status_t res;
831 unsigned int length;
832 RESPONSECODE return_value = IFD_SUCCESS;
833 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
834
835 #ifndef TWIN_SERIAL
836 if (ICCD_A == ccid_descriptor->bInterfaceProtocol)
837 {
838 int r;
839 unsigned char status[1];
840
841 again_status:
842 /* SlotStatus */
843 r = ControlUSB(reader_index, 0xA1, 0xA0, 0, status, sizeof(status));
844
845 /* we got an error? */
846 if (r < 0)
847 {
848 DEBUG_INFO2("ICC Slot Status failed: %s", strerror(errno));
849 if (ENODEV == errno)
850 return IFD_NO_SUCH_DEVICE;
851 return IFD_COMMUNICATION_ERROR;
852 }
853
854 /* busy */
855 if (status[0] & 0x40)
856 {
857 DEBUG_INFO2("Busy: 0x%02X", status[0]);
858 usleep(1000 * 10);
859 goto again_status;
860 }
861
862 /* simulate a CCID bStatus */
863 /* present and active by default */
864 buffer[7] = CCID_ICC_PRESENT_ACTIVE;
865
866 /* mute */
867 if (0x80 == status[0])
868 buffer[7] = CCID_ICC_ABSENT;
869
870 /* store the status for CmdXfrBlockCHAR_T0() */
871 buffer[0] = status[0];
872
873 return IFD_SUCCESS;
874 }
875
876 if (ICCD_B == ccid_descriptor->bInterfaceProtocol)
877 {
878 int r;
879 unsigned char buffer_tmp[3];
880
881 /* SlotStatus */
882 r = ControlUSB(reader_index, 0xA1, 0x81, 0, buffer_tmp,
883 sizeof(buffer_tmp));
884
885 /* we got an error? */
886 if (r < 0)
887 {
888 DEBUG_INFO2("ICC Slot Status failed: %s", strerror(errno));
889 if (ENODEV == errno)
890 return IFD_NO_SUCH_DEVICE;
891 return IFD_COMMUNICATION_ERROR;
892 }
893
894 /* simulate a CCID bStatus */
895 switch (buffer_tmp[1] & 0x03)
896 {
897 case 0:
898 buffer[7] = CCID_ICC_PRESENT_ACTIVE;
899 break;
900 case 1:
901 buffer[7] = CCID_ICC_PRESENT_INACTIVE;
902 break;
903 case 2:
904 case 3:
905 buffer[7] = CCID_ICC_ABSENT;
906 }
907 return IFD_SUCCESS;
908 }
909 #endif
910
911 cmd[0] = 0x65; /* GetSlotStatus */
912 cmd[1] = cmd[2] = cmd[3] = cmd[4] = 0; /* dwLength */
913 cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
914 cmd[6] = (*ccid_descriptor->pbSeq)++;
915 cmd[7] = cmd[8] = cmd[9] = 0; /* RFU */
916
917 res = WritePort(reader_index, sizeof(cmd), cmd);
918 if (res != STATUS_SUCCESS)
919 {
920 if (STATUS_NO_SUCH_DEVICE == res)
921 return IFD_NO_SUCH_DEVICE;
922 return IFD_COMMUNICATION_ERROR;
923 }
924
925 length = SIZE_GET_SLOT_STATUS;
926 res = ReadPort(reader_index, &length, buffer);
927 if (res != STATUS_SUCCESS)
928 return IFD_COMMUNICATION_ERROR;
929
930 if (length < STATUS_OFFSET+1)
931 {
932 DEBUG_CRITICAL2("Not enough data received: %d bytes", length);
933 return IFD_COMMUNICATION_ERROR;
934 }
935
936 if (buffer[STATUS_OFFSET] & CCID_COMMAND_FAILED)
937 {
938 #ifdef O2MICRO_OZ776_PATCH
939 /* the O2MICRO OZ 776 reader sends card absent or mute errors
940 * when no card is inserted */
941 if (! (((OZ776 == ccid_descriptor->readerID)
942 || (OZ776_7772 == ccid_descriptor->readerID))
943 && (buffer[ERROR_OFFSET] == 0xFE)))
944 #endif
945 ccid_error(buffer[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__); /* bError */
946
947 /* card absent or mute is not an communication error */
948 if (buffer[ERROR_OFFSET] != 0xFE)
949 return_value = IFD_COMMUNICATION_ERROR;
950 }
951
952 return return_value;
953 } /* CmdGetSlotStatus */
954
955
956 /*****************************************************************************
957 *
958 * CmdXfrBlock
959 *
960 ****************************************************************************/
961 RESPONSECODE CmdXfrBlock(unsigned int reader_index, unsigned int tx_length,
962 unsigned char tx_buffer[], unsigned int *rx_length,
963 unsigned char rx_buffer[], int protocol)
964 {
965 RESPONSECODE return_value = IFD_SUCCESS;
966 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
967
968 /* APDU or TPDU? */
969 switch (ccid_descriptor->dwFeatures & CCID_CLASS_EXCHANGE_MASK)
970 {
971 case CCID_CLASS_TPDU:
972 if (protocol == T_0)
973 return_value = CmdXfrBlockTPDU_T0(reader_index,
974 tx_length, tx_buffer, rx_length, rx_buffer);
975 else
976 if (protocol == T_1)
977 return_value = CmdXfrBlockTPDU_T1(reader_index, tx_length,
978 tx_buffer, rx_length, rx_buffer);
979 else
980 return_value = IFD_PROTOCOL_NOT_SUPPORTED;
981 break;
982
983 case CCID_CLASS_SHORT_APDU:
984 return_value = CmdXfrBlockTPDU_T0(reader_index,
985 tx_length, tx_buffer, rx_length, rx_buffer);
986 break;
987
988 case CCID_CLASS_EXTENDED_APDU:
989 return_value = CmdXfrBlockAPDU_extended(reader_index,
990 tx_length, tx_buffer, rx_length, rx_buffer);
991 break;
992
993 case CCID_CLASS_CHARACTER:
994 if (protocol == T_0)
995 return_value = CmdXfrBlockCHAR_T0(reader_index, tx_length,
996 tx_buffer, rx_length, rx_buffer);
997 else
998 if (protocol == T_1)
999 return_value = CmdXfrBlockTPDU_T1(reader_index, tx_length,
1000 tx_buffer, rx_length, rx_buffer);
1001 else
1002 return_value = IFD_PROTOCOL_NOT_SUPPORTED;
1003 break;
1004
1005 default:
1006 return_value = IFD_COMMUNICATION_ERROR;
1007 }
1008
1009 return return_value;
1010 } /* CmdXfrBlock */
1011
1012
1013 /*****************************************************************************
1014 *
1015 * CCID_Transmit
1016 *
1017 ****************************************************************************/
1018 RESPONSECODE CCID_Transmit(unsigned int reader_index, unsigned int tx_length,
1019 const unsigned char tx_buffer[], unsigned short rx_length, unsigned char bBWI)
1020 {
1021 unsigned char cmd[10+CMD_BUF_SIZE]; /* CCID + APDU buffer */
1022 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
1023 status_t ret;
1024
1025 #ifndef TWIN_SERIAL
1026 if (ICCD_A == ccid_descriptor->bInterfaceProtocol)
1027 {
1028 int r;
1029
1030 /* Xfr Block */
1031 r = ControlUSB(reader_index, 0x21, 0x65, 0, tx_buffer, tx_length);
1032
1033 /* we got an error? */
1034 if (r < 0)
1035 {
1036 DEBUG_INFO2("ICC Xfr Block failed: %s", strerror(errno));
1037 return IFD_COMMUNICATION_ERROR;
1038 }
1039
1040 return IFD_SUCCESS;
1041 }
1042
1043 if (ICCD_B == ccid_descriptor->bInterfaceProtocol)
1044 {
1045 int r;
1046
1047 /* nul block so we are chaining */
1048 if (NULL == tx_buffer)
1049 rx_length = 0x10; /* bLevelParameter */
1050
1051 /* Xfr Block */
1052 DEBUG_COMM2("chain parameter: %d", rx_length);
1053 r = ControlUSB(reader_index, 0x21, 0x65, rx_length << 8, tx_buffer,
1054 tx_length);
1055
1056 /* we got an error? */
1057 if (r < 0)
1058 {
1059 DEBUG_INFO2("ICC Xfr Block failed: %s", strerror(errno));
1060 return IFD_COMMUNICATION_ERROR;
1061 }
1062
1063 return IFD_SUCCESS;
1064 }
1065 #endif
1066
1067 cmd[0] = 0x6F; /* XfrBlock */
1068 i2dw(tx_length, cmd+1); /* APDU length */
1069 cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
1070 cmd[6] = (*ccid_descriptor->pbSeq)++;
1071 cmd[7] = bBWI; /* extend block waiting timeout */
1072 cmd[8] = rx_length & 0xFF; /* Expected length, in character mode only */
1073 cmd[9] = (rx_length >> 8) & 0xFF;
1074
1075 /* check that the command is not too large */
1076 if (tx_length > CMD_BUF_SIZE)
1077 {
1078 DEBUG_CRITICAL2("TX Length too big: %d", tx_length);
1079 return IFD_NOT_SUPPORTED;
1080 }
1081
1082 memcpy(cmd+10, tx_buffer, tx_length);
1083
1084 ret = WritePort(reader_index, 10+tx_length, cmd);
1085 if (STATUS_NO_SUCH_DEVICE == ret)
1086 return IFD_NO_SUCH_DEVICE;
1087 if (ret != STATUS_SUCCESS)
1088 return IFD_COMMUNICATION_ERROR;
1089
1090 return IFD_SUCCESS;
1091 } /* CCID_Transmit */
1092
1093
1094 /*****************************************************************************
1095 *
1096 * CCID_Receive
1097 *
1098 ****************************************************************************/
1099 RESPONSECODE CCID_Receive(unsigned int reader_index, unsigned int *rx_length,
1100 unsigned char rx_buffer[], unsigned char *chain_parameter)
1101 {
1102 unsigned char cmd[10+CMD_BUF_SIZE]; /* CCID + APDU buffer */
1103 unsigned int length;
1104 RESPONSECODE return_value = IFD_SUCCESS;
1105 status_t ret;
1106
1107 #ifndef TWIN_SERIAL
1108 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
1109
1110 if (ICCD_A == ccid_descriptor->bInterfaceProtocol)
1111 {
1112 int r;
1113
1114 /* Data Block */
1115 r = ControlUSB(reader_index, 0xA1, 0x6F, 0, rx_buffer, *rx_length);
1116
1117 /* we got an error? */
1118 if (r < 0)
1119 {
1120 DEBUG_INFO2("ICC Data Block failed: %s", strerror(errno));
1121 return IFD_COMMUNICATION_ERROR;
1122 }
1123
1124 return IFD_SUCCESS;
1125 }
1126
1127 if (ICCD_B == ccid_descriptor->bInterfaceProtocol)
1128 {
1129 int r;
1130 unsigned char rx_tmp[4];
1131 unsigned char *old_rx_buffer = NULL;
1132 int old_rx_length = 0;
1133
1134 /* read a nul block. buffer need to be at least 4-bytes */
1135 if (NULL == rx_buffer)
1136 {
1137 rx_buffer = rx_tmp;
1138 *rx_length = sizeof(rx_tmp);
1139 }
1140
1141 /* the buffer must be 4 bytes minimum for ICCD-B */
1142 if (*rx_length < 4)
1143 {
1144 old_rx_buffer = rx_buffer;
1145 old_rx_length = *rx_length;
1146 rx_buffer = rx_tmp;
1147 *rx_length = sizeof(rx_tmp);
1148 }
1149
1150 time_request_ICCD_B:
1151 /* Data Block */
1152 r = ControlUSB(reader_index, 0xA1, 0x6F, 0, rx_buffer, *rx_length);
1153
1154 /* we got an error? */
1155 if (r < 0)
1156 {
1157 DEBUG_INFO2("ICC Data Block failed: %s", strerror(errno));
1158 return IFD_COMMUNICATION_ERROR;
1159 }
1160
1161 /* copy from the 4 bytes buffer if used */
1162 if (old_rx_buffer)
1163 {
1164 memcpy(old_rx_buffer, rx_buffer, min(r, old_rx_length));
1165 rx_buffer = old_rx_buffer;
1166 }
1167
1168 /* bResponseType */
1169 switch (rx_buffer[0])
1170 {
1171 case 0x00:
1172 /* the abData field contains the information created by the
1173 * preceding request */
1174 break;
1175
1176 case 0x40:
1177 /* Status Information */
1178 ccid_error(rx_buffer[2], __FILE__, __LINE__, __FUNCTION__);
1179 return IFD_COMMUNICATION_ERROR;
1180
1181 case 0x80:
1182 /* Polling */
1183 {
1184 int delay;
1185
1186 delay = (rx_buffer[2] << 8) + rx_buffer[1];
1187 DEBUG_COMM2("Pooling delay: %d", delay);
1188
1189 if (0 == delay)
1190 /* host select the delay */
1191 delay = 1;
1192 usleep(delay * 1000 * 10);
1193 goto time_request_ICCD_B;
1194 }
1195
1196 case 0x01:
1197 case 0x02:
1198 case 0x03:
1199 case 0x10:
1200 /* Extended case
1201 * Only valid for Data Block frames */
1202 if (chain_parameter)
1203 *chain_parameter = rx_buffer[0];
1204 break;
1205
1206 default:
1207 DEBUG_CRITICAL2("Unknown bResponseType: 0x%02X", rx_buffer[0]);
1208 return IFD_COMMUNICATION_ERROR;
1209 }
1210
1211 memmove(rx_buffer, rx_buffer+1, r-1);
1212 *rx_length = r-1;
1213
1214 return IFD_SUCCESS;
1215 }
1216 #endif
1217
1218 time_request:
1219 length = sizeof(cmd);
1220 ret = ReadPort(reader_index, &length, cmd);
1221 if (ret != STATUS_SUCCESS)
1222 {
1223 if (STATUS_NO_SUCH_DEVICE == ret)
1224 return IFD_NO_SUCH_DEVICE;
1225 return IFD_COMMUNICATION_ERROR;
1226 }
1227
1228 if (length < STATUS_OFFSET+1)
1229 {
1230 DEBUG_CRITICAL2("Not enough data received: %d bytes", length);
1231 return IFD_COMMUNICATION_ERROR;
1232 }
1233
1234 if (cmd[STATUS_OFFSET] & CCID_COMMAND_FAILED)
1235 {
1236 ccid_error(cmd[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__); /* bError */
1237 switch (cmd[ERROR_OFFSET])
1238 {
1239 case 0xEF: /* cancel */
1240 if (*rx_length < 2)
1241 return IFD_COMMUNICATION_ERROR;
1242 rx_buffer[0]= 0x64;
1243 rx_buffer[1]= 0x01;
1244 *rx_length = 2;
1245 return IFD_SUCCESS;
1246
1247 case 0xF0: /* timeout */
1248 if (*rx_length < 2)
1249 return IFD_COMMUNICATION_ERROR;
1250 rx_buffer[0]= 0x64;
1251 rx_buffer[1]= 0x00;
1252 *rx_length = 2;
1253 return IFD_SUCCESS;
1254
1255 case 0xFD: /* Parity error during exchange */
1256 return IFD_PARITY_ERROR;
1257
1258 default:
1259 return IFD_COMMUNICATION_ERROR;
1260 }
1261 }
1262
1263 if (cmd[STATUS_OFFSET] & CCID_TIME_EXTENSION)
1264 {
1265 DEBUG_COMM2("Time extension requested: 0x%02X", cmd[ERROR_OFFSET]);
1266 goto time_request;
1267 }
1268
1269 /* we have read less (or more) data than the CCID frame says to contain */
1270 if (length-10 != dw2i(cmd, 1))
1271 {
1272 DEBUG_CRITICAL3("Can't read all data (%d out of %d expected)",
1273 length-10, dw2i(cmd, 1));
1274 return_value = IFD_COMMUNICATION_ERROR;
1275 }
1276
1277 length = dw2i(cmd, 1);
1278 if (length <= *rx_length)
1279 *rx_length = length;
1280 else
1281 {
1282 DEBUG_CRITICAL2("overrun by %d bytes", length - *rx_length);
1283 length = *rx_length;
1284 return_value = IFD_ERROR_INSUFFICIENT_BUFFER;
1285 }
1286
1287 /* Kobil firmware bug. No support for chaining */
1288 if (length && (NULL == rx_buffer))
1289 {
1290 DEBUG_CRITICAL2("Nul block expected but got %d bytes", length);
1291 return_value = IFD_COMMUNICATION_ERROR;
1292 }
1293 else
1294 memcpy(rx_buffer, cmd+10, length);
1295
1296 /* Extended case?
1297 * Only valid for RDR_to_PC_DataBlock frames */
1298 if (chain_parameter)
1299 *chain_parameter = cmd[CHAIN_PARAMETER_OFFSET];
1300
1301 return return_value;
1302 } /* CCID_Receive */
1303
1304
1305 /*****************************************************************************
1306 *
1307 * CmdXfrBlockAPDU_extended
1308 *
1309 ****************************************************************************/
1310 static RESPONSECODE CmdXfrBlockAPDU_extended(unsigned int reader_index,
1311 unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length,
1312 unsigned char rx_buffer[])
1313 {
1314 RESPONSECODE return_value;
1315 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
1316 unsigned char chain_parameter;
1317 unsigned int local_tx_length, sent_length;
1318 unsigned int local_rx_length, received_length;
1319 int buffer_overflow = 0;
1320
1321 if (ICCD_B == ccid_descriptor->bInterfaceProtocol)
1322 {
1323 /* length is on 16-bits only
1324 * if a size > 0x1000 is used then usb_control_msg() fails with
1325 * "Invalid argument" */
1326 if (*rx_length > 0x1000)
1327 *rx_length = 0x1000;
1328 }
1329
1330 DEBUG_COMM2("T=0 (extended): %d bytes", tx_length);
1331
1332 /* send the APDU */
1333 sent_length = 0;
1334
1335 /* we suppose one command is enough */
1336 chain_parameter = 0x00;
1337
1338 local_tx_length = tx_length - sent_length;
1339 if (local_tx_length > CMD_BUF_SIZE)
1340 {
1341 local_tx_length = CMD_BUF_SIZE;
1342 /* the command APDU begins with this command, and continue in the next
1343 * PC_to_RDR_XfrBlock */
1344 chain_parameter = 0x01;
1345 }
1346 if (local_tx_length > ccid_descriptor->dwMaxCCIDMessageLength-10)
1347 {
1348 local_tx_length = ccid_descriptor->dwMaxCCIDMessageLength-10;
1349 chain_parameter = 0x01;
1350 }
1351
1352 send_next_block:
1353 return_value = CCID_Transmit(reader_index, local_tx_length, tx_buffer,
1354 chain_parameter, 0);
1355 if (return_value != IFD_SUCCESS)
1356 return return_value;
1357
1358 sent_length += local_tx_length;
1359 tx_buffer += local_tx_length;
1360
1361 /* we just sent the last block (0x02) or only one block was needded (0x00) */
1362 if ((0x02 == chain_parameter) || (0x00 == chain_parameter))
1363 goto receive_block;
1364
1365 /* read a nul block */
1366 return_value = CCID_Receive(reader_index, &local_rx_length, NULL, NULL);
1367 if (return_value != IFD_SUCCESS)
1368 return return_value;
1369
1370 /* size of the next block */
1371 if (tx_length - sent_length > local_tx_length)
1372 {
1373 /* the abData field continues a command APDU and
1374 * another block is to follow */
1375 chain_parameter = 0x03;
1376 }
1377 else
1378 {
1379 /* this abData field continues a command APDU and ends
1380 * the APDU command */
1381 chain_parameter = 0x02;
1382
1383 /* last (smaller) block */
1384 local_tx_length = tx_length - sent_length;
1385 }
1386
1387 goto send_next_block;
1388
1389 receive_block:
1390 /* receive the APDU */
1391 received_length = 0;
1392
1393 receive_next_block:
1394 local_rx_length = *rx_length - received_length;
1395 return_value = CCID_Receive(reader_index, &local_rx_length, rx_buffer,
1396 &chain_parameter);
1397 if (IFD_ERROR_INSUFFICIENT_BUFFER == return_value)
1398 {
1399 buffer_overflow = 1;
1400
1401 /* we continue to read all the response APDU */
1402 return_value = IFD_SUCCESS;
1403 }
1404
1405 if (return_value != IFD_SUCCESS)
1406 return return_value;
1407
1408 /* advance in the reiceiving buffer */
1409 rx_buffer += local_rx_length;
1410 received_length += local_rx_length;
1411
1412 switch (chain_parameter)
1413 {
1414 /* the response APDU begins and ends in this command */
1415 case 0x00:
1416 /* this abData field continues the response APDU and ends the response
1417 * APDU */
1418 case 0x02:
1419 break;
1420
1421 /* the response APDU begins with this command and is to continue */
1422 case 0x01:
1423 /* this abData field continues the response APDU and another block is
1424 * to follow */
1425 case 0x03:
1426 /* empty abData field, continuation of the command APDU is expected in
1427 * next PC_to_RDR_XfrBlock command */
1428 case 0x10:
1429 /* send a nul block */
1430 return_value = CCID_Transmit(reader_index, 0, NULL, 0, 0);
1431 if (return_value != IFD_SUCCESS)
1432 return return_value;
1433
1434 goto receive_next_block;
1435 }
1436
1437 *rx_length = received_length;
1438
1439 /* generate an overflow detected by pcscd */
1440 if (buffer_overflow)
1441 (*rx_length)++;
1442
1443 return IFD_SUCCESS;
1444 } /* CmdXfrBlockAPDU_extended */
1445
1446
1447 /*****************************************************************************
1448 *
1449 * CmdXfrBlockTPDU_T0
1450 *
1451 ****************************************************************************/
1452 static RESPONSECODE CmdXfrBlockTPDU_T0(unsigned int reader_index,
1453 unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length,
1454 unsigned char rx_buffer[])
1455 {
1456 RESPONSECODE return_value = IFD_SUCCESS;
1457 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
1458
1459 DEBUG_COMM2("T=0: %d bytes", tx_length);
1460
1461 /* command length too big for CCID reader? */
1462 if (tx_length > ccid_descriptor->dwMaxCCIDMessageLength-10)
1463 {
1464 #ifdef BOGUS_SCM_FIRMWARE_FOR_dwMaxCCIDMessageLength
1465 if (263 == ccid_descriptor->dwMaxCCIDMessageLength)
1466 {
1467 DEBUG_INFO3("Command too long (%d bytes) for max: %d bytes."
1468 " SCM reader with bogus firmware?",
1469 tx_length, ccid_descriptor->dwMaxCCIDMessageLength-10);
1470 }
1471 else
1472 #endif
1473 {
1474 DEBUG_CRITICAL3("Command too long (%d bytes) for max: %d bytes",
1475 tx_length, ccid_descriptor->dwMaxCCIDMessageLength-10);
1476 return IFD_COMMUNICATION_ERROR;
1477 }
1478 }
1479
1480 /* command length too big for CCID driver? */
1481 if (tx_length > CMD_BUF_SIZE)
1482 {
1483 DEBUG_CRITICAL3("Command too long (%d bytes) for max: %d bytes",
1484 tx_length, CMD_BUF_SIZE);
1485 return IFD_COMMUNICATION_ERROR;
1486 }
1487
1488 return_value = CCID_Transmit(reader_index, tx_length, tx_buffer, 0, 0);
1489 if (return_value != IFD_SUCCESS)
1490 return return_value;
1491
1492 return CCID_Receive(reader_index, rx_length, rx_buffer, NULL);
1493 } /* CmdXfrBlockTPDU_T0 */
1494
1495
1496 /*****************************************************************************
1497 *
1498 * T0CmdParsing
1499 *
1500 ****************************************************************************/
1501 static RESPONSECODE T0CmdParsing(unsigned char *cmd, unsigned int cmd_len,
1502 unsigned int *exp_len)
1503 {
1504 *exp_len = 0;
1505
1506 /* Ref: 7816-4 Annex A */
1507 switch (cmd_len)
1508 {
1509 case 4: /* Case 1 */
1510 *exp_len = 2; /* SW1 and SW2 only */
1511 break;
1512
1513 case 5: /* Case 2 */
1514 if (cmd[4] != 0)
1515 *exp_len = cmd[4] + 2;
1516 else
1517 *exp_len = 256 + 2;
1518 break;
1519
1520 default: /* Case 3 */
1521 if (cmd_len > 5 && cmd_len == (unsigned int)(cmd[4] + 5))
1522 *exp_len = 2; /* SW1 and SW2 only */
1523 else
1524 return IFD_COMMUNICATION_ERROR; /* situation not supported */
1525 break;
1526 }
1527
1528 return IFD_SUCCESS;
1529 } /* T0CmdParsing */
1530
1531
1532 /*****************************************************************************
1533 *
1534 * T0ProcACK
1535 *
1536 ****************************************************************************/
1537 static RESPONSECODE T0ProcACK(unsigned int reader_index,
1538 unsigned char **snd_buf, unsigned int *snd_len,
1539 unsigned char **rcv_buf, unsigned int *rcv_len,
1540 unsigned char **in_buf, unsigned int *in_len,
1541 unsigned int proc_len, int is_rcv)
1542 {
1543 RESPONSECODE return_value;
1544 unsigned int remain_len;
1545 unsigned char tmp_buf[512];
1546 unsigned int ret_len;
1547
1548 DEBUG_COMM2("Enter, is_rcv = %d", is_rcv);
1549
1550 if (is_rcv == 1)
1551 { /* Receiving mode */
1552 if (*in_len > 0)
1553 { /* There are still available data in our buffer */
1554 if (*in_len >= proc_len)
1555 {
1556 /* We only need to get the data from our buffer */
1557 memcpy(*rcv_buf, *in_buf, proc_len);
1558 *rcv_buf += proc_len;
1559 *in_buf += proc_len;
1560 *rcv_len += proc_len;
1561 *in_len -= proc_len;
1562
1563 return IFD_SUCCESS;
1564 }
1565 else
1566 {
1567 /* Move all data in the input buffer to the reply buffer */
1568 remain_len = proc_len - *in_len;
1569 memcpy(*rcv_buf, *in_buf, *in_len);
1570 *rcv_buf += *in_len;
1571 *in_buf += *in_len;
1572 *rcv_len += *in_len;
1573 *in_len = 0;
1574 }
1575 }
1576 else
1577 /* There is no data in our tmp_buf,
1578 * we have to read all data we needed */
1579 remain_len = proc_len;
1580
1581 /* Read the expected data from the smartcard */
1582 if (*in_len != 0)
1583 {
1584 DEBUG_CRITICAL("*in_len != 0");
1585 return IFD_COMMUNICATION_ERROR;
1586 }
1587
1588 memset(tmp_buf, 0, sizeof(tmp_buf));
1589
1590 #ifdef O2MICRO_OZ776_PATCH
1591 if((0 != remain_len) && (0 == (remain_len + 10) % 64))
1592 {
1593 /* special hack to avoid a command of size modulo 64
1594 * we send two commands instead */
1595 ret_len = 1;
1596 return_value = CCID_Transmit(reader_index, 0, *snd_buf, ret_len, 0);
1597 if (return_value != IFD_SUCCESS)
1598 return return_value;
1599 return_value = CCID_Receive(reader_index, &ret_len, tmp_buf, NULL);
1600 if (return_value != IFD_SUCCESS)
1601 return return_value;
1602
1603 ret_len = remain_len - 1;
1604 return_value = CCID_Transmit(reader_index, 0, *snd_buf, ret_len, 0);
1605 if (return_value != IFD_SUCCESS)
1606 return return_value;
1607 return_value = CCID_Receive(reader_index, &ret_len, &tmp_buf[1],
1608 NULL);
1609 if (return_value != IFD_SUCCESS)
1610 return return_value;
1611
1612 ret_len += 1;
1613 }
1614 else
1615 #endif
1616 {
1617 ret_len = remain_len;
1618 return_value = CCID_Transmit(reader_index, 0, *snd_buf, ret_len, 0);
1619 if (return_value != IFD_SUCCESS)
1620 return return_value;
1621
1622 return_value = CCID_Receive(reader_index, &ret_len, tmp_buf, NULL);
1623 if (return_value != IFD_SUCCESS)
1624 return return_value;
1625 }
1626 memcpy(*rcv_buf, tmp_buf, remain_len);
1627 *rcv_buf += remain_len, *rcv_len += remain_len;
1628
1629 /* If ret_len != remain_len, our logic is erroneous */
1630 if (ret_len != remain_len)
1631 {
1632 DEBUG_CRITICAL("ret_len != remain_len");
1633 return IFD_COMMUNICATION_ERROR;
1634 }
1635 }
1636 else
1637 { /* Sending mode */
1638
1639 return_value = CCID_Transmit(reader_index, proc_len, *snd_buf, 1, 0);
1640 if (return_value != IFD_SUCCESS)
1641 return return_value;
1642
1643 *snd_len -= proc_len;
1644 *snd_buf += proc_len;
1645 }
1646
1647 DEBUG_COMM("Exit");
1648
1649 return IFD_SUCCESS;
1650 } /* T0ProcACK */
1651
1652
1653 /*****************************************************************************
1654 *
1655 * T0ProcSW1
1656 *
1657 ****************************************************************************/
1658 static RESPONSECODE T0ProcSW1(unsigned int reader_index,
1659 unsigned char *rcv_buf, unsigned int *rcv_len,
1660 unsigned char *in_buf, unsigned int in_len)
1661 {
1662 RESPONSECODE return_value = IFD_SUCCESS;
1663 UCHAR tmp_buf[512];
1664 unsigned char *rcv_buf_tmp = rcv_buf;
1665 const unsigned int rcv_len_tmp = *rcv_len;
1666 unsigned char sw1, sw2;
1667
1668 /* store the SW1 */
1669 sw1 = *rcv_buf = *in_buf;
1670 rcv_buf++;
1671 in_buf++;
1672 in_len--;
1673 (*rcv_len)++;
1674
1675 /* store the SW2 */
1676 if (0 == in_len)
1677 {
1678 return_value = CCID_Transmit(reader_index, 0, rcv_buf, 1, 0);
1679 if (return_value != IFD_SUCCESS)
1680 return return_value;
1681
1682 in_len = 1;
1683
1684 return_value = CCID_Receive(reader_index, &in_len, tmp_buf, NULL);
1685 if (return_value != IFD_SUCCESS)
1686 return return_value;
1687
1688 in_buf = tmp_buf;
1689 }
1690 sw2 = *rcv_buf = *in_buf;
1691 rcv_buf++;
1692 in_buf++;
1693 in_len--;
1694 (*rcv_len)++;
1695
1696 if (return_value != IFD_SUCCESS)
1697 {
1698 rcv_buf_tmp[0] = rcv_buf_tmp[1] = 0;
1699 *rcv_len = rcv_len_tmp;
1700 }
1701
1702 DEBUG_COMM3("Exit: SW=%02X %02X", sw1, sw2);
1703
1704 return return_value;
1705 } /* T0ProcSW1 */
1706
1707
1708 /*****************************************************************************
1709 *
1710 * CmdXfrBlockCHAR_T0
1711 *
1712 ****************************************************************************/
1713 static RESPONSECODE CmdXfrBlockCHAR_T0(unsigned int reader_index,
1714 unsigned int snd_len, unsigned char snd_buf[], unsigned int *rcv_len,
1715 unsigned char rcv_buf[])
1716 {
1717 int is_rcv;
1718 unsigned char cmd[5];
1719 unsigned char tmp_buf[512];
1720 unsigned int exp_len, in_len;
1721 unsigned char ins, *in_buf;
1722 RESPONSECODE return_value = IFD_SUCCESS;
1723 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
1724
1725 DEBUG_COMM2("T=0: %d bytes", snd_len);
1726
1727 if (ICCD_A == ccid_descriptor->bInterfaceProtocol)
1728 {
1729 unsigned char pcbuffer[SIZE_GET_SLOT_STATUS];
1730
1731 /* Command to send to the smart card (must be 5 bytes) */
1732 memset(cmd, 0, sizeof(cmd));
1733 if (snd_len == 4)
1734 {
1735 memcpy(cmd, snd_buf, 4);
1736 snd_buf += 4;
1737 snd_len -= 4;
1738 }
1739 else
1740 {
1741 memcpy(cmd, snd_buf, 5);
1742 snd_buf += 5;
1743 snd_len -= 5;
1744 }
1745
1746 /* at most 5 bytes */
1747 return_value = CCID_Transmit(reader_index, 5, cmd, 0, 0);
1748 if (return_value != IFD_SUCCESS)
1749 return return_value;
1750
1751 /* wait for ready */
1752 return_value = CmdGetSlotStatus(reader_index, pcbuffer);
1753 if (return_value != IFD_SUCCESS)
1754 return return_value;
1755
1756 if ((0x20 != pcbuffer[0]) && (snd_len > 0))
1757 {
1758 /* continue sending the APDU */
1759 return_value = CCID_Transmit(reader_index, snd_len, snd_buf, 0, 0);
1760 if (return_value != IFD_SUCCESS)
1761 return return_value;
1762 }
1763 else
1764 {
1765 if ((0x20 == pcbuffer[0]) && (*rcv_len > 2))
1766 /* we will just read SW1-SW2 */
1767 *rcv_len = 2;
1768
1769 return_value = CCID_Receive(reader_index, rcv_len, rcv_buf, NULL);
1770 if (return_value != IFD_SUCCESS)
1771 DEBUG_CRITICAL("CCID_Receive failed");
1772
1773 return return_value;
1774 }
1775
1776 /* wait for ready */
1777 return_value = CmdGetSlotStatus(reader_index, pcbuffer);
1778 if (return_value != IFD_SUCCESS)
1779 return return_value;
1780
1781 if ((0x20 == pcbuffer[0]) && (*rcv_len > 2))
1782 /* we will just read SW1-SW2 */
1783 *rcv_len = 2;
1784
1785 /* read SW1-SW2 */
1786 return_value = CCID_Receive(reader_index, rcv_len, rcv_buf, NULL);
1787 if (return_value != IFD_SUCCESS)
1788 DEBUG_CRITICAL("CCID_Receive failed");
1789
1790 return return_value;
1791 }
1792
1793 in_buf = tmp_buf;
1794 in_len = 0;
1795 *rcv_len = 0;
1796
1797 return_value = T0CmdParsing(snd_buf, snd_len, &exp_len);
1798 if (return_value != IFD_SUCCESS)
1799 {
1800 DEBUG_CRITICAL("T0CmdParsing failed");
1801 return IFD_COMMUNICATION_ERROR;
1802 }
1803
1804 if (snd_len == 5 || snd_len == 4)
1805 is_rcv = 1;
1806 else
1807 is_rcv = 0;
1808
1809 /* Command to send to the smart card (must be 5 bytes, from 7816 p.15) */
1810 memset(cmd, 0, sizeof(cmd));
1811 if (snd_len == 4)
1812 {
1813 memcpy(cmd, snd_buf, 4);
1814 snd_buf += 4;
1815 snd_len -= 4;
1816 }
1817 else
1818 {
1819 memcpy(cmd, snd_buf, 5);
1820 snd_buf += 5;
1821 snd_len -= 5;
1822 }
1823
1824 /* Make sure this is a valid command by checking the INS field */
1825 ins = cmd[1];
1826 if ((ins & 0xF0) == 0x60 || /* 7816-3 8.3.2 */
1827 (ins & 0xF0) == 0x90)
1828 {
1829 DEBUG_CRITICAL2("fatal: INS (0x%02X) = 0x6X or 0x9X", ins);
1830 return IFD_COMMUNICATION_ERROR;
1831 }
1832
1833 return_value = CCID_Transmit(reader_index, 5, cmd, 1, 0);
1834 if (return_value != IFD_SUCCESS)
1835 return return_value;
1836
1837 while (1)
1838 {
1839 if (in_len == 0)
1840 {
1841 in_len = 1;
1842 return_value = CCID_Receive(reader_index, &in_len, tmp_buf, NULL);
1843 if (return_value != IFD_SUCCESS)
1844 {
1845 DEBUG_CRITICAL("CCID_Receive failed");
1846 return return_value;
1847 }
1848 in_buf = tmp_buf;
1849 }
1850 if (in_len == 0)
1851 {
1852 /* Suppose we should be able to get data.
1853 * If not, error. Set the time-out error */
1854 DEBUG_CRITICAL("error: in_len = 0");
1855 return IFD_RESPONSE_TIMEOUT;
1856 }
1857
1858 /* Start to process the procedure bytes */
1859 if (*in_buf == 0x60)
1860 {
1861 in_len = 0;
1862 return_value = CCID_Transmit(reader_index, 0, cmd, 1, 0);
1863
1864 if (return_value != IFD_SUCCESS)
1865 return return_value;
1866
1867 continue;
1868 }
1869 else if (*in_buf == ins || *in_buf == (ins ^ 0x01))
1870 {
1871 /* ACK => To transfer all remaining data bytes */
1872 in_buf++, in_len--;
1873 if (is_rcv)
1874 return_value = T0ProcACK(reader_index, &snd_buf, &snd_len,
1875 &rcv_buf, rcv_len, &in_buf, &in_len, exp_len - *rcv_len, 1);
1876 else
1877 return_value = T0ProcACK(reader_index, &snd_buf, &snd_len,
1878 &rcv_buf, rcv_len, &in_buf, &in_len, snd_len, 0);
1879
1880 if (*rcv_len == exp_len)
1881 return return_value;
1882
1883 continue;
1884 }
1885 else if (*in_buf == (ins ^ 0xFF) || *in_buf == (ins ^ 0xFE))
1886 {
1887 /* ACK => To transfer 1 remaining bytes */
1888 in_buf++, in_len--;
1889 return_value = T0ProcACK(reader_index, &snd_buf, &snd_len,
1890 &rcv_buf, rcv_len, &in_buf, &in_len, 1, is_rcv);
1891
1892 if (return_value != IFD_SUCCESS)
1893 return return_value;
1894
1895 continue;
1896 }
1897 else if ((*in_buf & 0xF0) == 0x60 || (*in_buf & 0xF0) == 0x90)
1898 /* SW1 */
1899 return T0ProcSW1(reader_index, rcv_buf, rcv_len, in_buf, in_len);
1900
1901 /* Error, unrecognized situation found */
1902 DEBUG_CRITICAL2("Unrecognized Procedure byte (0x%02X) found!", *in_buf);
1903 return return_value;
1904 }
1905
1906 return return_value;
1907 } /* CmdXfrBlockCHAR_T0 */
1908
1909
1910 /*****************************************************************************
1911 *
1912 * CmdXfrBlockTPDU_T1
1913 *
1914 ****************************************************************************/
1915 static RESPONSECODE CmdXfrBlockTPDU_T1(unsigned int reader_index,
1916 unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length,
1917 unsigned char rx_buffer[])
1918 {
1919 RESPONSECODE return_value = IFD_SUCCESS;
1920 int ret;
1921
1922 DEBUG_COMM3("T=1: %d and %d bytes", tx_length, *rx_length);
1923
1924 ret = t1_transceive(&((get_ccid_slot(reader_index)) -> t1), 0,
1925 tx_buffer, tx_length, rx_buffer, *rx_length);
1926
1927 if (ret < 0)
1928 return_value = IFD_COMMUNICATION_ERROR;
1929 else
1930 *rx_length = ret;
1931
1932 return return_value;
1933 } /* CmdXfrBlockTPDU_T1 */
1934
1935
1936 /*****************************************************************************
1937 *
1938 * SetParameters
1939 *
1940 ****************************************************************************/
1941 RESPONSECODE SetParameters(unsigned int reader_index, char protocol,
1942 unsigned int length, unsigned char buffer[])
1943 {
1944 unsigned char cmd[10+CMD_BUF_SIZE]; /* CCID + APDU buffer */
1945 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
1946
1947 DEBUG_COMM2("length: %d bytes", length);
1948
1949 cmd[0] = 0x61; /* SetParameters */
1950 i2dw(length, cmd+1); /* APDU length */
1951 cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
1952 cmd[6] = (*ccid_descriptor->pbSeq)++;
1953 cmd[7] = protocol; /* bProtocolNum */
1954 cmd[8] = cmd[9] = 0; /* RFU */
1955
1956 /* check that the command is not too large */
1957 if (length > CMD_BUF_SIZE)
1958 return IFD_NOT_SUPPORTED;
1959
1960 memcpy(cmd+10, buffer, length);
1961
1962 if (WritePort(reader_index, 10+length, cmd) != STATUS_SUCCESS)
1963 return IFD_COMMUNICATION_ERROR;
1964
1965 length = sizeof(cmd);
1966 if (ReadPort(reader_index, &length, cmd) != STATUS_SUCCESS)
1967 return IFD_COMMUNICATION_ERROR;
1968
1969 if (length < STATUS_OFFSET+1)
1970 {
1971 DEBUG_CRITICAL2("Not enough data received: %d bytes", length);
1972 return IFD_COMMUNICATION_ERROR;
1973 }
1974
1975 if (cmd[STATUS_OFFSET] & CCID_COMMAND_FAILED)
1976 {
1977 ccid_error(cmd[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__); /* bError */
1978 if (0x00 == cmd[ERROR_OFFSET]) /* command not supported */
1979 return IFD_NOT_SUPPORTED;
1980 else
1981 if ((cmd[ERROR_OFFSET] >= 1) && (cmd[ERROR_OFFSET] <= 127))
1982 /* a parameter is not changeable */
1983 return IFD_SUCCESS;
1984 else
1985 return IFD_COMMUNICATION_ERROR;
1986 }
1987
1988 return IFD_SUCCESS;
1989 } /* SetParameters */
1990
1991
1992 /*****************************************************************************
1993 *
1994 * isCharLevel
1995 *
1996 ****************************************************************************/
1997 int isCharLevel(int reader_index)
1998 {
1999 return CCID_CLASS_CHARACTER == (get_ccid_descriptor(reader_index)->dwFeatures & CCID_CLASS_EXCHANGE_MASK);
2000 } /* isCharLevel */
2001
2002
2003 /*****************************************************************************
2004 *
2005 * i2dw
2006 *
2007 ****************************************************************************/
2008 static void i2dw(int value, unsigned char buffer[])
2009 {
2010 buffer[0] = value & 0xFF;
2011 buffer[1] = (value >> 8) & 0xFF;
2012 buffer[2] = (value >> 16) & 0xFF;
2013 buffer[3] = (value >> 24) & 0xFF;
2014 } /* i2dw */
2015

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5