/[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 1227 - (hide annotations) (download)
Wed Sep 8 20:45:19 2004 UTC (8 years, 8 months ago) by rousseau
File MIME type: text/plain
File size: 17119 byte(s)
CmdPowerOn(): do not use a null terminated C string for the EMV->ISO
switch command since the command is NOT a C string
1 rousseau 269 /*
2     commands.c: Commands sent to the card
3     Copyright (C) 2003 Ludovic Rousseau
4    
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9    
10     This program 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
13     GNU General Public License for more details.
14    
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18     */
19    
20     /*
21     * $Id$
22     */
23    
24     #include <string.h>
25 rousseau 614 #include <stdlib.h>
26 rousseau 990 #include <PCSC/pcsclite.h>
27     #include <PCSC/ifdhandler.h>
28 rousseau 269
29     #include "commands.h"
30 rousseau 990 #include "openct/proto-t1.h"
31 rousseau 407 #include "ccid.h"
32 rousseau 269 #include "defs.h"
33 rousseau 879 #include "ccid_ifdhandler.h"
34 rousseau 269 #include "config.h"
35     #include "debug.h"
36    
37 rousseau 991 /*
38     * Possible values :
39     * 3 -> 1.8V, 3V, 5V
40     * 2 -> 3V, 5V
41     * 1 -> 5V only
42     */
43     /*
44     * To be safe we only use 5V
45     * otherwise we would have to parse the ATR and get the value of TAi (i>2) when
46     * in T=15
47     */
48     #define DEFAULT_VOLTAGE 1 /* start with 5 volts */
49 rousseau 269
50 rousseau 1066 /* internal functions */
51 rousseau 1106 static RESPONSECODE CmdXfrBlockTPDU_T0(unsigned int reader_index,
52     unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length,
53 rousseau 1066 unsigned char rx_buffer[]);
54    
55 rousseau 1106 static RESPONSECODE CmdXfrBlockTPDU_T1(unsigned int reader_index,
56     unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length,
57 rousseau 1066 unsigned char rx_buffer[]);
58    
59 rousseau 1068 static void i2dw(int value, unsigned char *buffer);
60 rousseau 1066
61 rousseau 1068
62 rousseau 407 /*****************************************************************************
63     *
64     * CmdPowerOn
65     *
66     ****************************************************************************/
67 rousseau 1106 RESPONSECODE CmdPowerOn(unsigned int reader_index, unsigned int * nlength,
68 rousseau 1043 unsigned char buffer[])
69 rousseau 269 {
70     unsigned char cmd[10];
71     status_t res;
72     int atr_len, length, count = 1;
73     RESPONSECODE return_value = IFD_SUCCESS;
74 rousseau 1106 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
75 rousseau 991 char voltage;
76 rousseau 269
77     /* store length of buffer[] */
78     length = *nlength;
79 rousseau 991
80     if (ccid_descriptor->dwFeatures & CCID_CLASS_AUTO_VOLTAGE)
81     voltage = 0; /* automatic voltage selection */
82     else
83     voltage = DEFAULT_VOLTAGE;
84    
85 rousseau 269 again:
86     cmd[0] = 0x62; /* IccPowerOn */
87     cmd[1] = cmd[2] = cmd[3] = cmd[4] = 0; /* dwLength */
88 rousseau 1092 cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
89 rousseau 1150 cmd[6] = (*ccid_descriptor->pbSeq)++;
90 rousseau 991 cmd[7] = voltage;
91 rousseau 269 cmd[8] = cmd[9] = 0; /* RFU */
92    
93 rousseau 1106 res = WritePort(reader_index, sizeof(cmd), cmd);
94 rousseau 269 if (res != STATUS_SUCCESS)
95     return IFD_COMMUNICATION_ERROR;
96    
97     /* reset available buffer size */
98     /* needed if we go back after a switch to ISO mode */
99     *nlength = length;
100    
101 rousseau 1106 res = ReadPort(reader_index, nlength, buffer);
102 rousseau 269 if (res != STATUS_SUCCESS)
103     return IFD_COMMUNICATION_ERROR;
104    
105 rousseau 407 if (buffer[STATUS_OFFSET] & CCID_COMMAND_FAILED)
106 rousseau 269 {
107 rousseau 990 ccid_error(buffer[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__); /* bError */
108 rousseau 269
109 rousseau 1226 if (0xBB == buffer[ERROR_OFFSET] && /* Protocol error in EMV mode */
110     ((GEMPC433 == ccid_descriptor->readerID)
111     || (CHERRYXX33 == ccid_descriptor->readerID)))
112 rousseau 269 {
113 rousseau 1227 unsigned char cmd[] = {0x1F, 0x01};
114 rousseau 879 unsigned char res[1];
115 rousseau 892 unsigned int res_length = sizeof(res);
116 rousseau 879
117 rousseau 1227 if ((return_value = CmdEscape(reader_index, cmd, sizeof(cmd), res,
118 rousseau 879 &res_length)) != IFD_SUCCESS)
119 rousseau 269 return return_value;
120    
121     /* avoid looping if we can't switch mode */
122     if (count--)
123     goto again;
124     else
125     DEBUG_CRITICAL("Can't set reader in ISO mode");
126     }
127    
128 rousseau 991 /* continue with 3 volts and 5 volts */
129     if (voltage > 1)
130     {
131     voltage--;
132     goto again;
133     }
134    
135 rousseau 269 return IFD_COMMUNICATION_ERROR;
136     }
137    
138     /* extract the ATR */
139     atr_len = dw2i(buffer, 1); /* ATR length */
140     if (atr_len > *nlength)
141     atr_len = *nlength;
142     else
143     *nlength = atr_len;
144    
145 rousseau 1076 memmove(buffer, buffer+10, atr_len);
146 rousseau 269
147     return return_value;
148     } /* CmdPowerOn */
149    
150 rousseau 407
151     /*****************************************************************************
152     *
153 rousseau 891 * SecurePIN
154     *
155     ****************************************************************************/
156 rousseau 1106 RESPONSECODE SecurePIN(unsigned int reader_index,
157     const unsigned char TxBuffer[], unsigned int TxLength,
158     unsigned char RxBuffer[], unsigned int *RxLength)
159    
160 rousseau 891 {
161     unsigned char cmd[11+14+CMD_BUF_SIZE];
162 rousseau 1106 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
163 rousseau 891 int length = 0;
164    
165 rousseau 904 /* PIN verification data structure WITHOUT TeoPrologue */
166 rousseau 891 if (TxBuffer[4] /* Lc */
167     + 5 /* CLA, INS, P1, P2, Lc */
168     + 11 /* CCID PIN verification data structure */ == TxLength)
169     {
170     i2dw(TxLength+3+1, cmd+1); /* command length */
171    
172     /* copy the CCID data structure */
173     memcpy(cmd +11, TxBuffer + TxBuffer[4] + 5, 11);
174    
175     /* TeoPrologue not used */
176 rousseau 904 memset(cmd +11 +11, 0, 3);
177 rousseau 891
178     /* copy the APDU */
179     memcpy(cmd +11 +14, TxBuffer, TxLength-11);
180    
181     length = 14 + TxLength;
182     }
183 rousseau 904 /* PIN verification data structure WITH TeoPrologue */
184 rousseau 891 else if (TxBuffer[4] /* Lc */
185     + 5 /* CLA, INS, P1, P2, Lc */
186 rousseau 904 + 14 /* CCID PIN verification data structure */ == TxLength)
187 rousseau 891 {
188 rousseau 904 i2dw(TxLength+1, cmd+1); /* command length */
189 rousseau 891
190     /* copy the CCID data structure */
191 rousseau 904 memcpy(cmd +11, TxBuffer + TxBuffer[4] + 5, 14);
192 rousseau 891
193     /* copy the APDU */
194 rousseau 904 memcpy(cmd +11 +14, TxBuffer, TxLength-14);
195 rousseau 891
196 rousseau 904 length = 11 + TxLength;
197 rousseau 891 }
198     else
199     {
200     *RxLength = 0;
201     return IFD_COMMUNICATION_ERROR;
202     }
203    
204     cmd[0] = 0x69; /* Secure */
205 rousseau 1092 cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
206 rousseau 1150 cmd[6] = (*ccid_descriptor->pbSeq)++;
207 rousseau 891 cmd[7] = 0; /* bBWI */
208     cmd[8] = 0; /* wLevelParameter */
209     cmd[9] = 0;
210     cmd[10] = 0; /* bPINOperation: PIN Verification */
211    
212 rousseau 1106 if (WritePort(reader_index, length, cmd) != STATUS_SUCCESS)
213 rousseau 891 return IFD_COMMUNICATION_ERROR;
214    
215 rousseau 1106 return CCID_Receive(reader_index, RxLength, RxBuffer);
216 rousseau 891 } /* SecurePIN */
217    
218    
219     /*****************************************************************************
220     *
221 rousseau 407 * Escape
222     *
223     ****************************************************************************/
224 rousseau 1106 RESPONSECODE CmdEscape(unsigned int reader_index,
225     const unsigned char TxBuffer[], unsigned int TxLength,
226     unsigned char RxBuffer[], unsigned int *RxLength)
227 rousseau 269 {
228 rousseau 879 unsigned char *cmd_in, *cmd_out;
229 rousseau 269 status_t res;
230 rousseau 892 unsigned int length_in, length_out;
231 rousseau 269 RESPONSECODE return_value = IFD_SUCCESS;
232 rousseau 1106 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
233 rousseau 269
234 rousseau 879 /* allocate buffers */
235     length_in = 10 + TxLength;
236     if (NULL == (cmd_in = malloc(length_in)))
237     return IFD_COMMUNICATION_ERROR;
238 rousseau 269
239 rousseau 879 length_out = 10 + *RxLength;
240     if (NULL == (cmd_out = malloc(length_out)))
241 rousseau 269 {
242 rousseau 879 free(cmd_in);
243     return IFD_COMMUNICATION_ERROR;
244     }
245 rousseau 269
246 rousseau 879 cmd_in[0] = 0x6B; /* PC_to_RDR_Escape */
247     i2dw(length_in - 10, cmd_in+1); /* dwLength */
248 rousseau 1092 cmd_in[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
249 rousseau 1150 cmd_in[6] = (*ccid_descriptor->pbSeq)++;
250 rousseau 879 cmd_in[7] = cmd_in[8] = cmd_in[9] = 0; /* RFU */
251 rousseau 407
252 rousseau 879 /* copy the command */
253     memcpy(&cmd_in[10], TxBuffer, TxLength);
254 rousseau 269
255 rousseau 1106 res = WritePort(reader_index, length_in, cmd_in);
256 rousseau 879 free(cmd_in);
257 rousseau 269 if (res != STATUS_SUCCESS)
258 rousseau 879 {
259     free(cmd_out);
260 rousseau 269 return IFD_COMMUNICATION_ERROR;
261 rousseau 879 }
262 rousseau 269
263 rousseau 1106 res = ReadPort(reader_index, &length_out, cmd_out);
264 rousseau 269 if (res != STATUS_SUCCESS)
265 rousseau 879 {
266     free(cmd_out);
267 rousseau 269 return IFD_COMMUNICATION_ERROR;
268 rousseau 879 }
269 rousseau 269
270 rousseau 879 if (cmd_out[STATUS_OFFSET] & CCID_COMMAND_FAILED)
271 rousseau 269 {
272 rousseau 990 ccid_error(cmd_out[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__); /* bError */
273 rousseau 269 return_value = IFD_COMMUNICATION_ERROR;
274     }
275    
276 rousseau 879 /* copy the response */
277     length_out = dw2i(cmd_out, 1);
278     if (length_out > *RxLength)
279     length_out = *RxLength;
280     *RxLength = length_out;
281     memcpy(RxBuffer, &cmd_out[10], length_out);
282    
283     free(cmd_out);
284    
285 rousseau 269 return return_value;
286     } /* Escape */
287    
288 rousseau 407
289     /*****************************************************************************
290     *
291     * CmdPowerOff
292     *
293     ****************************************************************************/
294 rousseau 1106 RESPONSECODE CmdPowerOff(unsigned int reader_index)
295 rousseau 269 {
296     unsigned char cmd[10];
297     status_t res;
298 rousseau 892 unsigned int length;
299 rousseau 269 RESPONSECODE return_value = IFD_SUCCESS;
300 rousseau 1106 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
301 rousseau 269
302     cmd[0] = 0x63; /* IccPowerOff */
303     cmd[1] = cmd[2] = cmd[3] = cmd[4] = 0; /* dwLength */
304 rousseau 1092 cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
305 rousseau 1150 cmd[6] = (*ccid_descriptor->pbSeq)++;
306 rousseau 269 cmd[7] = cmd[8] = cmd[9] = 0; /* RFU */
307    
308 rousseau 1106 res = WritePort(reader_index, sizeof(cmd), cmd);
309 rousseau 269 if (res != STATUS_SUCCESS)
310     return IFD_COMMUNICATION_ERROR;
311    
312     length = sizeof(cmd);
313 rousseau 1106 res = ReadPort(reader_index, &length, cmd);
314 rousseau 269 if (res != STATUS_SUCCESS)
315     return IFD_COMMUNICATION_ERROR;
316    
317 rousseau 407 if (cmd[STATUS_OFFSET] & CCID_COMMAND_FAILED)
318 rousseau 269 {
319 rousseau 990 ccid_error(cmd[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__); /* bError */
320 rousseau 269 return_value = IFD_COMMUNICATION_ERROR;
321     }
322    
323     return return_value;
324     } /* CmdPowerOff */
325    
326 rousseau 407
327     /*****************************************************************************
328     *
329     * CmdGetSlotStatus
330     *
331     ****************************************************************************/
332 rousseau 1106 RESPONSECODE CmdGetSlotStatus(unsigned int reader_index, unsigned char buffer[])
333 rousseau 269 {
334     unsigned char cmd[10];
335     status_t res;
336 rousseau 892 unsigned int length;
337 rousseau 269 RESPONSECODE return_value = IFD_SUCCESS;
338 rousseau 1106 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
339 rousseau 269
340     cmd[0] = 0x65; /* GetSlotStatus */
341     cmd[1] = cmd[2] = cmd[3] = cmd[4] = 0; /* dwLength */
342 rousseau 1092 cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
343 rousseau 1150 cmd[6] = (*ccid_descriptor->pbSeq)++;
344 rousseau 269 cmd[7] = cmd[8] = cmd[9] = 0; /* RFU */
345    
346 rousseau 1106 res = WritePort(reader_index, sizeof(cmd), cmd);
347 rousseau 269 if (res != STATUS_SUCCESS)
348     return IFD_COMMUNICATION_ERROR;
349    
350     length = SIZE_GET_SLOT_STATUS;
351 rousseau 1106 res = ReadPort(reader_index, &length, buffer);
352 rousseau 269 if (res != STATUS_SUCCESS)
353     return IFD_COMMUNICATION_ERROR;
354    
355 rousseau 407 if (buffer[STATUS_OFFSET] & CCID_COMMAND_FAILED)
356 rousseau 269 {
357 rousseau 990 ccid_error(buffer[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__); /* bError */
358 rousseau 269 return_value = IFD_COMMUNICATION_ERROR;
359     }
360    
361     return return_value;
362     } /* CmdGetSlotStatus */
363    
364 rousseau 407
365     /*****************************************************************************
366     *
367     * CmdXfrBlock
368     *
369     ****************************************************************************/
370 rousseau 1106 RESPONSECODE CmdXfrBlock(unsigned int reader_index, unsigned int tx_length,
371 rousseau 892 unsigned char tx_buffer[], unsigned int *rx_length,
372     unsigned char rx_buffer[], int protocol)
373 rousseau 269 {
374 rousseau 407 RESPONSECODE return_value = IFD_SUCCESS;
375 rousseau 1106 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
376 rousseau 407
377     /* command length too big for CCID reader? */
378     if (tx_length > ccid_descriptor->dwMaxCCIDMessageLength)
379     {
380     DEBUG_CRITICAL3("Command too long (%d bytes) for max: %d bytes",
381     tx_length, ccid_descriptor->dwMaxCCIDMessageLength);
382     return_value = IFD_COMMUNICATION_ERROR;
383     goto clean_up_and_return;
384     }
385    
386     /* command length too big for CCID driver? */
387     if (tx_length > CMD_BUF_SIZE)
388     {
389     DEBUG_CRITICAL3("Command too long (%d bytes) for max: %d bytes",
390     tx_length, CMD_BUF_SIZE);
391     return_value = IFD_COMMUNICATION_ERROR;
392     goto clean_up_and_return;
393     }
394    
395     /* APDU or TPDU? */
396     switch (ccid_descriptor->dwFeatures & CCID_CLASS_EXCHANGE_MASK)
397     {
398     case CCID_CLASS_TPDU:
399 rousseau 614 if (protocol == T_0)
400 rousseau 1106 return_value = CmdXfrBlockTPDU_T0(reader_index,
401     tx_length, tx_buffer, rx_length, rx_buffer);
402 rousseau 614 else
403     if (protocol == T_1)
404 rousseau 1106 return_value = CmdXfrBlockTPDU_T1(reader_index, tx_length,
405 rousseau 614 tx_buffer, rx_length, rx_buffer);
406     else
407     return_value = IFD_PROTOCOL_NOT_SUPPORTED;
408 rousseau 407 break;
409    
410     case CCID_CLASS_SHORT_APDU:
411     case CCID_CLASS_EXTENDED_APDU:
412     /* We only support extended APDU if the reader can support the
413     * command length. See test above */
414 rousseau 1106 return_value = CmdXfrBlockTPDU_T0(reader_index,
415     tx_length, tx_buffer, rx_length, rx_buffer);
416 rousseau 407 break;
417    
418     default:
419 rousseau 614 *rx_length = 0;
420 rousseau 407 return_value = IFD_COMMUNICATION_ERROR;
421     }
422    
423     clean_up_and_return:
424     return return_value;
425     } /* CmdXfrBlock */
426    
427    
428     /*****************************************************************************
429     *
430 rousseau 613 * CCID_Transmit
431 rousseau 407 *
432     ****************************************************************************/
433 rousseau 1106 RESPONSECODE CCID_Transmit(unsigned int reader_index, unsigned int tx_length,
434 rousseau 992 const unsigned char tx_buffer[], unsigned char bBWI)
435 rousseau 407 {
436 rousseau 269 unsigned char cmd[10+CMD_BUF_SIZE]; /* CCID + APDU buffer */
437 rousseau 1106 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
438 rousseau 269
439 rousseau 613 cmd[0] = 0x6F; /* XfrBlock */
440 rousseau 269 i2dw(tx_length, cmd+1); /* APDU length */
441 rousseau 1092 cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
442 rousseau 1150 cmd[6] = (*ccid_descriptor->pbSeq)++;
443 rousseau 992 cmd[7] = bBWI; /* extend block waiting timeout */
444     cmd[8] = cmd[9] = 0; /* RFU */
445 rousseau 269 memcpy(cmd+10, tx_buffer, tx_length);
446    
447 rousseau 1106 if (WritePort(reader_index, 10+tx_length, cmd) != STATUS_SUCCESS)
448 rousseau 269 return IFD_COMMUNICATION_ERROR;
449    
450 rousseau 613 return IFD_SUCCESS;
451     } /* CCID_Transmit */
452    
453    
454     /*****************************************************************************
455     *
456     * CCID_Receive
457     *
458     ****************************************************************************/
459 rousseau 1106 RESPONSECODE CCID_Receive(unsigned int reader_index, unsigned int *rx_length,
460 rousseau 892 unsigned char rx_buffer[])
461 rousseau 613 {
462     unsigned char cmd[10+CMD_BUF_SIZE]; /* CCID + APDU buffer */
463 rousseau 892 unsigned int length;
464 rousseau 613
465 rousseau 407 time_request:
466 rousseau 269 length = sizeof(cmd);
467 rousseau 1106 if (ReadPort(reader_index, &length, cmd) != STATUS_SUCCESS)
468 rousseau 905 {
469     *rx_length = 0;
470 rousseau 269 return IFD_COMMUNICATION_ERROR;
471 rousseau 905 }
472 rousseau 269
473 rousseau 407 if (cmd[STATUS_OFFSET] & CCID_COMMAND_FAILED)
474 rousseau 269 {
475 rousseau 990 ccid_error(cmd[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__); /* bError */
476 rousseau 269 *rx_length = 0; /* nothing received */
477 rousseau 993 if (0xFD == cmd[ERROR_OFFSET]) /* Parity error during exchange */
478     return IFD_PARITY_ERROR;
479     else
480     return IFD_COMMUNICATION_ERROR;
481 rousseau 269 }
482    
483 rousseau 407 if (cmd[STATUS_OFFSET] & CCID_TIME_EXTENSION)
484     {
485     DEBUG_CRITICAL2("Time extension requested: 0x%02X", cmd[ERROR_OFFSET]);
486     goto time_request;
487     }
488    
489 rousseau 269 length = dw2i(cmd, 1);
490     if (length < *rx_length)
491     *rx_length = length;
492     else
493     length = *rx_length;
494     memcpy(rx_buffer, cmd+10, length);
495    
496 rousseau 658 return IFD_SUCCESS;
497 rousseau 613 } /* CCID_Receive */
498 rousseau 269
499 rousseau 407
500     /*****************************************************************************
501     *
502 rousseau 614 * CmdXfrBlockTPDU_T0
503 rousseau 407 *
504     ****************************************************************************/
505 rousseau 1106 static RESPONSECODE CmdXfrBlockTPDU_T0(unsigned int reader_index,
506     unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length,
507 rousseau 892 unsigned char rx_buffer[])
508 rousseau 407 {
509     RESPONSECODE return_value = IFD_SUCCESS;
510    
511 rousseau 614 DEBUG_COMM2("T=0: %d bytes", tx_length);
512 rousseau 407
513 rousseau 1106 return_value = CCID_Transmit(reader_index, tx_length, tx_buffer, 0);
514 rousseau 613 if (return_value != IFD_SUCCESS)
515     return return_value;
516    
517 rousseau 1106 return CCID_Receive(reader_index, rx_length, rx_buffer);
518 rousseau 614 } /* CmdXfrBlockTPDU_T0 */
519 rousseau 407
520    
521     /*****************************************************************************
522     *
523 rousseau 614 * CmdXfrBlockTPDU_T1
524     *
525     ****************************************************************************/
526 rousseau 1106 static RESPONSECODE CmdXfrBlockTPDU_T1(unsigned int reader_index,
527     unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length,
528 rousseau 892 unsigned char rx_buffer[])
529 rousseau 614 {
530 rousseau 994 RESPONSECODE return_value = IFD_SUCCESS;
531 rousseau 1073 int ret;
532 rousseau 614
533     DEBUG_COMM2("T=1: %d bytes", tx_length);
534    
535 rousseau 1106 ret = t1_transceive(&((get_ccid_slot(reader_index)) -> t1), 0,
536     tx_buffer, tx_length, rx_buffer, *rx_length);
537 rousseau 614
538 rousseau 1073 if (ret < 0)
539 rousseau 614 {
540 rousseau 659 *rx_length = 0;
541 rousseau 614 return_value = IFD_COMMUNICATION_ERROR;
542 rousseau 659 }
543 rousseau 1073 else
544     *rx_length = ret;
545 rousseau 614
546     return return_value;
547     } /* CmdXfrBlockTPDU_T1 */
548    
549    
550     /*****************************************************************************
551     *
552 rousseau 617 * SetParameters
553     *
554     ****************************************************************************/
555 rousseau 1106 RESPONSECODE SetParameters(unsigned int reader_index, char protocol,
556     unsigned int length, unsigned char buffer[])
557 rousseau 617 {
558     unsigned char cmd[10+CMD_BUF_SIZE]; /* CCID + APDU buffer */
559 rousseau 1106 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
560 rousseau 617
561     DEBUG_COMM2("length: %d bytes", length);
562    
563     cmd[0] = 0x61; /* SetParameters */
564     i2dw(length, cmd+1); /* APDU length */
565 rousseau 1092 cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
566 rousseau 1150 cmd[6] = (*ccid_descriptor->pbSeq)++;
567 rousseau 617 cmd[7] = protocol; /* bProtocolNum */
568     cmd[8] = cmd[9] = 0; /* RFU */
569     memcpy(cmd+10, buffer, length);
570    
571 rousseau 1106 if (WritePort(reader_index, 10+length, cmd) != STATUS_SUCCESS)
572 rousseau 617 return IFD_COMMUNICATION_ERROR;
573    
574     length = sizeof(cmd);
575 rousseau 1106 if (ReadPort(reader_index, &length, cmd) != STATUS_SUCCESS)
576 rousseau 617 return IFD_COMMUNICATION_ERROR;
577    
578     if (cmd[STATUS_OFFSET] & CCID_COMMAND_FAILED)
579     {
580 rousseau 990 ccid_error(cmd[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__); /* bError */
581 rousseau 1212 if (0x00 == cmd[ERROR_OFFSET]) /* command not supported */
582     return IFD_NOT_SUPPORTED;
583     else
584     return IFD_COMMUNICATION_ERROR;
585 rousseau 617 }
586    
587     return IFD_SUCCESS;
588     } /* SetParameters */
589    
590    
591     /*****************************************************************************
592     *
593 rousseau 407 * i2dw
594     *
595     ****************************************************************************/
596 rousseau 1068 static void i2dw(int value, unsigned char buffer[])
597 rousseau 269 {
598     buffer[0] = value & 0xFF;
599     buffer[1] = (value >> 8) & 0xFF;
600     buffer[2] = (value >> 16) & 0xFF;
601     buffer[3] = (value >> 24) & 0xFF;
602     } /* i2dw */
603    

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5