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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1703 - (hide annotations) (download)
Mon Nov 7 15:46:03 2005 UTC (7 years, 6 months ago) by rousseau
File MIME type: text/plain
File size: 16910 byte(s)
remove #ifdef DEBUG_LEVEL_COMM since DEBUG_LEVEL_COMM is a numeric value
and not a compilation flag anymore. Debug is always active and filtered
by pcscd.
1 rousseau 414 /*
2     * ccid_serial.c: communicate with a GemPC Twin smart card reader
3 rousseau 1147 * Copyright (C) 2001-2004 Ludovic Rousseau <ludovic.rousseau@free.fr>
4 rousseau 414 *
5     * Thanks to Niki W. Waibel <niki.waibel@gmx.net> for a prototype version
6     *
7 rousseau 1399 This library is free software; you can redistribute it and/or
8     modify it under the terms of the GNU Lesser General Public
9     License as published by the Free Software Foundation; either
10     version 2.1 of the License, or (at your option) any later version.
11    
12     This library is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15     Lesser General Public License for more details.
16    
17     You should have received a copy of the GNU Lesser General Public
18     License along with this library; if not, write to the Free Software
19     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 rousseau 414 */
21    
22     /*
23     * $Id$
24     */
25    
26     #include <stdio.h>
27     #include <stdlib.h>
28     #include <fcntl.h>
29     #include <unistd.h>
30     #include <termios.h>
31     #include <string.h>
32     #include <errno.h>
33     #include <sys/time.h>
34     #include <sys/types.h>
35 rousseau 1472 #include <sys/ioctl.h>
36 rousseau 1022 #include <PCSC/ifdhandler.h>
37 rousseau 414
38 rousseau 877 #include "defs.h"
39     #include "ccid_ifdhandler.h"
40 rousseau 414 #include "config.h"
41     #include "debug.h"
42     #include "ccid.h"
43     #include "utils.h"
44 rousseau 1022 #include "commands.h"
45 rousseau 414
46     #define SYNC 0x03
47     #define CTRL_ACK 0x06
48     #define CTRL_NAK 0x15
49     #define RDR_to_PC_NotifySlotChange 0x50
50     #define CARD_ABSENT 0x02
51     #define CARD_PRESENT 0x03
52    
53     /*
54     * normal command:
55     * 1 : SYNC
56     * 1 : CTRL
57     * 10 +data length : CCID command
58     * 1 : LRC
59     *
60     * SYNC : 0x03
61     * CTRL : ACK (0x06) or NAK (0x15)
62     * CCID command : see USB CCID specs
63     * LRC : xor of all the previous byes
64     *
65     * Error message:
66     * 1 : SYNC (0x03)
67     * 1 : CTRL (NAK: 0x15)
68     * 1 : LRC (0x16)
69     *
70     * Card insertion/withdrawal
71     * 1 : RDR_to_PC_NotifySlotChange (0x50)
72     * 1 : bmSlotIccState
73     * 0x02 if card absent
74     * 0x03 is card present
75     *
76     * Time request
77     * T=1 : normal CCID command
78     * T=0 : 1 byte (value between 0x80 and 0xFF)
79     *
80     */
81    
82 rousseau 453 /*
83     * You may get read timeout after a card movement.
84     * This is because you will get the echo of the CCID command
85     * but not the result of the command.
86     *
87     * This is not an applicative issue since the card is either removed (and
88     * powered off) or just inserted (and not yet powered on).
89     */
90    
91     /* 271 = max size for short APDU
92     * 2 bytes for header
93     * 1 byte checksum
94     * doubled for echo
95     */
96     #define GEMPCTWIN_MAXBUF (271 +2 +1) * 2
97    
98 rousseau 414 typedef struct
99     {
100     /*
101     * File handle on the serial port
102     */
103     int fd;
104    
105     /*
106 rousseau 649 * device used ("/dev/ttyS?" under Linux)
107 rousseau 414 */
108 rousseau 1054 /*@null@*/ char *device;
109 rousseau 414
110     /*
111 rousseau 453 * serial communication buffer
112     */
113     unsigned char buffer[GEMPCTWIN_MAXBUF];
114    
115     /*
116     * next available byte
117     */
118     int buffer_offset;
119    
120     /*
121     * number of available bytes
122     */
123     int buffer_offset_last;
124    
125     /*
126 rousseau 414 * CCID infos common to USB and serial
127     */
128     _ccid_descriptor ccid;
129    
130     } _serialDevice;
131    
132     /* The _serialDevice structure must be defined before including ccid_serial.h */
133     #include "ccid_serial.h"
134    
135 rousseau 1458 unsigned int SerialDataRates[] = {
136 rousseau 1447 10753,
137     14337,
138     15625,
139     17204,
140     20833,
141     21505,
142     23438,
143     25806,
144     28674,
145     31250,
146     32258,
147     34409,
148     39063,
149     41667,
150     43011,
151     46875,
152     52083,
153     53763,
154     57348,
155     62500,
156     64516,
157     68817,
158     71685,
159     78125,
160     83333,
161     86022,
162     93750,
163 rousseau 1496 104167,
164 rousseau 1447 107527,
165     114695,
166     125000,
167     129032,
168     143369,
169     156250,
170     166667,
171     172043,
172     215054,
173     229391,
174     250000,
175     344086,
176     0
177     };
178    
179 rousseau 892 /* no need to initialize to 0 since it is static */
180 rousseau 1077 static _serialDevice serialDevice[CCID_DRIVER_MAX_READERS];
181 rousseau 414
182 rousseau 1050 /* unexported functions */
183 rousseau 1106 static int ReadChunk(unsigned int reader_index, unsigned char *buffer,
184     int buffer_length, int min_length);
185 rousseau 1050
186 rousseau 1106 static int get_bytes(unsigned int reader_index, unsigned char *buffer,
187     int length);
188 rousseau 1050
189    
190 rousseau 414 /*****************************************************************************
191     *
192     * WriteSerial: Send bytes to the card reader
193     *
194     *****************************************************************************/
195 rousseau 1106 status_t WriteSerial(unsigned int reader_index, unsigned int length,
196     unsigned char *buffer)
197 rousseau 414 {
198     int i;
199     unsigned char lrc;
200     unsigned char low_level_buffer[GEMPCTWIN_MAXBUF];
201    
202 rousseau 1047 char debug_header[] = "-> 123456 ";
203 rousseau 414
204 rousseau 1106 sprintf(debug_header, "-> %06X ", reader_index);
205 rousseau 414
206     if (length > GEMPCTWIN_MAXBUF-3)
207     {
208 rousseau 608 DEBUG_CRITICAL3("command too long: %d for max %d",
209 rousseau 414 length, GEMPCTWIN_MAXBUF-3);
210     return STATUS_UNSUCCESSFUL;
211     }
212    
213     /* header */
214     low_level_buffer[0] = 0x03; /* SYNC */
215     low_level_buffer[1] = 0x06; /* ACK */
216    
217     /* CCID command */
218     memcpy(low_level_buffer+2, buffer, length);
219    
220     /* checksum */
221     lrc = 0;
222     for(i=0; i<length+2; i++)
223     lrc ^= low_level_buffer[i];
224     low_level_buffer[length+2] = lrc;
225    
226     DEBUG_XXD(debug_header, low_level_buffer, length+3);
227    
228 rousseau 1106 if (write(serialDevice[reader_index].fd, low_level_buffer,
229 rousseau 453 length+3) != length+3)
230 rousseau 414 {
231 rousseau 608 DEBUG_CRITICAL2("write error: %s", strerror(errno));
232 rousseau 414 return STATUS_UNSUCCESSFUL;
233     }
234    
235     return STATUS_SUCCESS;
236     } /* WriteSerial */
237    
238    
239     /*****************************************************************************
240     *
241     * ReadSerial: Receive bytes from the card reader
242     *
243     *****************************************************************************/
244 rousseau 1106 status_t ReadSerial(unsigned int reader_index,
245     /*@unused@*/ unsigned int *length, unsigned char *buffer)
246 rousseau 414 {
247 rousseau 453 unsigned char c;
248     int rv;
249     int echo;
250     int to_read;
251     int i;
252 rousseau 414
253 rousseau 453 /* we get the echo first */
254     echo = TRUE;
255 rousseau 414
256 rousseau 453 start:
257 rousseau 462 DEBUG_COMM("start");
258 rousseau 1106 if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
259 rousseau 453 return rv;
260 rousseau 414
261 rousseau 453 if (c == RDR_to_PC_NotifySlotChange)
262     goto slot_change;
263 rousseau 414
264 rousseau 453 if (c == SYNC)
265     goto sync;
266 rousseau 414
267 rousseau 453 if (c >= 0x80)
268 rousseau 462 {
269     DEBUG_COMM2("time request: 0x%02X", c);
270 rousseau 453 goto start;
271 rousseau 462 }
272 rousseau 414
273 rousseau 453 DEBUG_CRITICAL2("Got 0x%02X", c);
274     return STATUS_COMM_ERROR;
275 rousseau 414
276 rousseau 453 slot_change:
277 rousseau 462 DEBUG_COMM("slot change");
278 rousseau 1106 if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
279 rousseau 453 return rv;
280 rousseau 414
281 rousseau 453 if (c == CARD_ABSENT)
282 rousseau 774 {
283 rousseau 453 DEBUG_COMM("Card removed");
284 rousseau 774 }
285 rousseau 453 else
286     if (c == CARD_PRESENT)
287 rousseau 774 {
288 rousseau 453 DEBUG_COMM("Card inserted");
289 rousseau 774 }
290 rousseau 453 else
291 rousseau 774 {
292 rousseau 1044 DEBUG_COMM2("Unknown card movement: %d", c);
293 rousseau 774 }
294 rousseau 453 goto start;
295 rousseau 414
296 rousseau 453 sync:
297 rousseau 462 DEBUG_COMM("sync");
298 rousseau 1106 if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
299 rousseau 453 return rv;
300 rousseau 414
301 rousseau 453 if (c == CTRL_ACK)
302     goto ack;
303 rousseau 414
304 rousseau 453 if (c == CTRL_NAK)
305     goto nak;
306 rousseau 414
307 rousseau 453 DEBUG_CRITICAL2("Got 0x%02X instead of ACK/NAK", c);
308     return STATUS_COMM_ERROR;
309 rousseau 414
310 rousseau 453 nak:
311 rousseau 462 DEBUG_COMM("nak");
312 rousseau 1106 if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
313 rousseau 453 return rv;
314 rousseau 414
315 rousseau 453 if (c != (SYNC ^ CTRL_NAK))
316 rousseau 414 {
317 rousseau 453 DEBUG_CRITICAL2("Wrong LRC: 0x%02X", c);
318     return STATUS_COMM_ERROR;
319 rousseau 414 }
320 rousseau 453 else
321 rousseau 1491 {
322     DEBUG_COMM("NAK requested");
323     return STATUS_COMM_NAK;
324     }
325 rousseau 414
326 rousseau 453 ack:
327 rousseau 462 DEBUG_COMM("ack");
328 rousseau 453 /* normal CCID frame */
329 rousseau 1106 if ((rv = get_bytes(reader_index, buffer, 5)) != STATUS_SUCCESS)
330 rousseau 453 return rv;
331 rousseau 414
332 rousseau 453 /* total frame size */
333     to_read = 10+dw2i(buffer, 1);
334 rousseau 414
335 rousseau 462 DEBUG_COMM2("frame size: %d", to_read);
336 rousseau 1106 if ((rv = get_bytes(reader_index, buffer+5, to_read-5)) != STATUS_SUCCESS)
337 rousseau 453 return rv;
338 rousseau 414
339 rousseau 1703 DEBUG_XXD("frame: ", buffer, to_read);
340 rousseau 462
341 rousseau 453 /* lrc */
342 rousseau 462 DEBUG_COMM("lrc");
343 rousseau 1106 if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
344 rousseau 453 return rv;
345    
346 rousseau 462 DEBUG_COMM2("lrc: 0x%02X", c);
347 rousseau 414 for (i=0; i<to_read; i++)
348 rousseau 453 c ^= buffer[i];
349 rousseau 414
350 rousseau 453 if (c != (SYNC ^ CTRL_ACK))
351     DEBUG_CRITICAL2("Wrong LRC: 0x%02X", c);
352 rousseau 414
353 rousseau 453 if (echo)
354     {
355     echo = FALSE;
356     goto start;
357     }
358 rousseau 414
359     return STATUS_SUCCESS;
360     } /* ReadSerial */
361    
362    
363     /*****************************************************************************
364     *
365 rousseau 453 * get_bytes: get n bytes
366 rousseau 414 *
367     *****************************************************************************/
368 rousseau 1106 int get_bytes(unsigned int reader_index, unsigned char *buffer, int length)
369 rousseau 414 {
370 rousseau 1106 int offset = serialDevice[reader_index].buffer_offset;
371     int offset_last = serialDevice[reader_index].buffer_offset_last;
372 rousseau 414
373 rousseau 608 DEBUG_COMM3("available: %d, needed: %d", offset_last-offset,
374 rousseau 462 length);
375 rousseau 453 /* enough data are available */
376     if (offset + length <= offset_last)
377 rousseau 414 {
378 rousseau 608 DEBUG_COMM("data available");
379 rousseau 1106 memcpy(buffer, serialDevice[reader_index].buffer + offset, length);
380     serialDevice[reader_index].buffer_offset += length;
381 rousseau 414 }
382 rousseau 453 else
383 rousseau 414 {
384 rousseau 453 int present, rv;
385 rousseau 414
386 rousseau 453 /* copy available data */
387     present = offset_last - offset;
388 rousseau 414
389 rousseau 453 if (present > 0)
390 rousseau 462 {
391 rousseau 608 DEBUG_COMM2("some data available: %d", present);
392 rousseau 1106 memcpy(buffer, serialDevice[reader_index].buffer + offset,
393 rousseau 462 present);
394     }
395 rousseau 414
396 rousseau 453 /* get fresh data */
397 rousseau 608 DEBUG_COMM2("get more data: %d", length - present);
398 rousseau 1106 rv = ReadChunk(reader_index, serialDevice[reader_index].buffer,
399     sizeof(serialDevice[reader_index].buffer), length - present);
400 rousseau 453 if (rv < 0)
401     return STATUS_COMM_ERROR;
402 rousseau 414
403 rousseau 453 /* fill the buffer */
404 rousseau 1106 memcpy(buffer + present, serialDevice[reader_index].buffer,
405 rousseau 453 length - present);
406 rousseau 1106 serialDevice[reader_index].buffer_offset = length - present;
407     serialDevice[reader_index].buffer_offset_last = rv;
408 rousseau 608 DEBUG_COMM3("offset: %d, last_offset: %d",
409 rousseau 1106 serialDevice[reader_index].buffer_offset,
410     serialDevice[reader_index].buffer_offset_last);
411 rousseau 414 }
412    
413 rousseau 453 return STATUS_SUCCESS;
414     } /* get_bytes */
415 rousseau 414
416 rousseau 453
417 rousseau 414 /*****************************************************************************
418     *
419     * ReadChunk: read a minimum number of bytes
420     *
421     *****************************************************************************/
422 rousseau 1106 static int ReadChunk(unsigned int reader_index, unsigned char *buffer,
423 rousseau 1050 int buffer_length, int min_length)
424 rousseau 414 {
425 rousseau 1106 int fd = serialDevice[reader_index].fd;
426 rousseau 1045 # ifndef S_SPLINT_S
427 rousseau 414 fd_set fdset;
428 rousseau 1045 # endif
429 rousseau 414 struct timeval t;
430 rousseau 462 int i, rv = 0;
431     int already_read;
432 rousseau 1047 char debug_header[] = "<- 123456 ";
433 rousseau 414
434 rousseau 1106 sprintf(debug_header, "<- %06X ", reader_index);
435 rousseau 414
436 rousseau 462 already_read = 0;
437     while (already_read < min_length)
438     {
439     /* use select() to, eventually, timeout */
440     FD_ZERO(&fdset);
441     FD_SET(fd, &fdset);
442 rousseau 1453 t.tv_sec = serialDevice[reader_index].ccid.readTimeout;
443 rousseau 462 t.tv_usec = 0;
444 rousseau 414
445 rousseau 462 i = select(fd+1, &fdset, NULL, NULL, &t);
446     if (i == -1)
447 rousseau 414 {
448 rousseau 462 DEBUG_CRITICAL2("select: %s", strerror(errno));
449 rousseau 414 return -1;
450     }
451 rousseau 462 else
452     if (i == 0)
453     {
454 rousseau 1453 DEBUG_COMM2("Timeout! (%d sec)", serialDevice[reader_index].ccid.readTimeout);
455 rousseau 462 return -1;
456     }
457 rousseau 414
458 rousseau 462 rv = read(fd, buffer + already_read, buffer_length - already_read);
459     if (rv < 0)
460     {
461     DEBUG_COMM2("read error: %s", strerror(errno));
462     return -1;
463     }
464 rousseau 414
465 rousseau 462 DEBUG_XXD(debug_header, buffer + already_read, rv);
466 rousseau 414
467 rousseau 462 already_read += rv;
468 rousseau 608 DEBUG_COMM3("read: %d, to read: %d", already_read,
469 rousseau 414 min_length);
470     }
471    
472 rousseau 462 return already_read;
473 rousseau 414 } /* ReadChunk */
474    
475    
476     /*****************************************************************************
477     *
478     * OpenSerial: open the port
479     *
480     *****************************************************************************/
481 rousseau 1106 status_t OpenSerial(unsigned int reader_index, int channel)
482 rousseau 414 {
483     char dev_name[FILENAME_MAX];
484    
485 rousseau 1106 DEBUG_COMM3("Reader index: %X, Channel: %d", reader_index, channel);
486 rousseau 414
487     /*
488     * Conversion of old-style ifd-hanler 1.0 CHANNELID
489     */
490     if (channel == 0x0103F8)
491     channel = 1;
492     else
493     if (channel == 0x0102F8)
494     channel = 2;
495     else
496     if (channel == 0x0103E8)
497     channel = 3;
498     else
499     if (channel == 0x0102E8)
500     channel = 4;
501    
502     if (channel < 0)
503     {
504     DEBUG_CRITICAL2("wrong port number: %d", (int) channel);
505     return STATUS_UNSUCCESSFUL;
506     }
507    
508     sprintf(dev_name, "/dev/pcsc/%d", (int) channel);
509    
510 rousseau 1106 return OpenSerialByName(reader_index, dev_name);
511 rousseau 649 } /* OpenSerial */
512    
513     /*****************************************************************************
514     *
515     * OpenSerialByName: open the port
516     *
517     *****************************************************************************/
518 rousseau 1106 status_t OpenSerialByName(unsigned int reader_index, char *dev_name)
519 rousseau 649 {
520     struct termios current_termios;
521     int i;
522 rousseau 1106 unsigned int reader = reader_index;
523 rousseau 649
524 rousseau 1292 DEBUG_COMM3("Reader index: %X, Device: %s", reader_index, dev_name);
525 rousseau 649
526 rousseau 414 /* check if the same channel is not already used */
527 rousseau 1077 for (i=0; i<CCID_DRIVER_MAX_READERS; i++)
528 rousseau 414 {
529 rousseau 649 if (serialDevice[i].device &&
530     strcmp(serialDevice[i].device, dev_name) == 0)
531 rousseau 414 {
532 rousseau 649 DEBUG_CRITICAL2("Device %s already in use", dev_name);
533 rousseau 414 return STATUS_UNSUCCESSFUL;
534     }
535     }
536    
537     serialDevice[reader].fd = open(dev_name, O_RDWR | O_NOCTTY);
538    
539 rousseau 892 if (-1 == serialDevice[reader].fd)
540 rousseau 414 {
541     DEBUG_CRITICAL3("open %s: %s", dev_name, strerror(errno));
542     return STATUS_UNSUCCESSFUL;
543     }
544    
545 rousseau 1472 /* Set RTS signal to low to prevent the smart card reader
546     * from sending its plug and play string. */
547     {
548     int flags;
549    
550     if (ioctl(serialDevice[reader].fd, TIOCMGET, &flags) < 0)
551     {
552     DEBUG_CRITICAL2("Get RS232 signals state failed: %s",
553     strerror(errno));
554     }
555     else
556     {
557     flags &= ~TIOCM_RTS;
558     if (ioctl(serialDevice[reader].fd, TIOCMSET, &flags) < 0)
559     {
560     DEBUG_CRITICAL2("Set RTS to low failed: %s", strerror(errno));
561     }
562     else
563     {
564     DEBUG_COMM("Plug-n-Play inhibition successful");
565     }
566     }
567     }
568    
569 rousseau 414 /* set channel used */
570 rousseau 649 serialDevice[reader].device = strdup(dev_name);
571 rousseau 414
572     /* empty in and out serial buffers */
573     if (tcflush(serialDevice[reader].fd, TCIOFLUSH))
574     DEBUG_INFO2("tcflush() function error: %s", strerror(errno));
575    
576     /* get config attributes */
577     if (tcgetattr(serialDevice[reader].fd, &current_termios) == -1)
578     {
579     DEBUG_INFO2("tcgetattr() function error: %s", strerror(errno));
580     close(serialDevice[reader].fd);
581     serialDevice[reader].fd = -1;
582    
583     return STATUS_UNSUCCESSFUL;
584     }
585    
586     /* IGNBRK: ignore BREAK condition on input
587     * IGNPAR: ignore framing errors and parity errors. */
588     current_termios.c_iflag = IGNBRK | IGNPAR;
589     current_termios.c_oflag = 0; /* Raw output modes */
590     /* CS8: 8-bits character size
591     * CSTOPB: set two stop bits
592     * CREAD: enable receiver
593     * CLOCAL: ignore modem control lines */
594     current_termios.c_cflag = CS8 | CSTOPB | CREAD | CLOCAL;
595    
596     /* Do not echo characters because if you connect to a host it or your modem
597     * will echo characters for you. Don't generate signals. */
598     current_termios.c_lflag = 0;
599    
600     /* set serial port speed to 115200 bauds */
601     cfsetspeed(&current_termios, B115200);
602    
603     DEBUG_INFO("Set serial port baudrate to 115200 and correct configuration");
604     if (tcsetattr(serialDevice[reader].fd, TCSANOW, &current_termios) == -1)
605     {
606     close(serialDevice[reader].fd);
607     serialDevice[reader].fd = -1;
608     DEBUG_INFO2("tcsetattr error: %s", strerror(errno));
609    
610     return STATUS_UNSUCCESSFUL;
611     }
612    
613 rousseau 1149 serialDevice[reader].ccid.real_bSeq = 0;
614     serialDevice[reader].ccid.pbSeq = &serialDevice[reader].ccid.real_bSeq;
615 rousseau 414 serialDevice[reader].ccid.readerID = GEMPCTWIN;
616     serialDevice[reader].ccid.dwMaxCCIDMessageLength = 271;
617 rousseau 672 serialDevice[reader].ccid.dwMaxIFSD = 254;
618 rousseau 414 serialDevice[reader].ccid.dwFeatures = 0x00010230;
619 rousseau 900 serialDevice[reader].ccid.bPINSupport = 0x0;
620 rousseau 694 serialDevice[reader].ccid.dwDefaultClock = 4000;
621 rousseau 1485 serialDevice[reader].ccid.dwMaxDataRate = 344086;
622 rousseau 1091 serialDevice[reader].ccid.bMaxSlotIndex = 0;
623     serialDevice[reader].ccid.bCurrentSlotIndex = 0;
624 rousseau 1447 serialDevice[reader].ccid.arrayOfSupportedDataRates = SerialDataRates;
625 rousseau 414
626 rousseau 453 serialDevice[reader].buffer_offset = 0;
627     serialDevice[reader].buffer_offset_last = 0;
628    
629 rousseau 1022 /* perform a command to be sure a GemPC Twin reader is connected
630     * get the reader firmware */
631     {
632 rousseau 1330 unsigned char tx_buffer[] = { 0x02 };
633 rousseau 1048 unsigned char rx_buffer[50];
634     unsigned int rx_length = sizeof(rx_buffer);
635 rousseau 1022
636 rousseau 1147 /* 2 seconds timeout to not wait too long if no reader is connected */
637 rousseau 1453 serialDevice[reader].ccid.readTimeout = 2;
638 rousseau 1147
639 rousseau 1106 if (IFD_SUCCESS != CmdEscape(reader_index, tx_buffer, sizeof(tx_buffer),
640 rousseau 1022 rx_buffer, &rx_length))
641     {
642 rousseau 1147 DEBUG_CRITICAL("Get firmware failed. Maybe the reader is not connected");
643 rousseau 1022 return STATUS_UNSUCCESSFUL;
644     }
645    
646 rousseau 1453 /* normal timeout: 2 seconds */
647     serialDevice[reader].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT ;
648 rousseau 1147
649 rousseau 1022 rx_buffer[rx_length] = '\0';
650     DEBUG_INFO2("Firmware: %s", rx_buffer);
651     }
652    
653 rousseau 1444 /* perform a command to configure GemPC Twin reader card movement
654     * notification to synchronous mode: the card movement is notified _after_
655     * the host command and _before_ the reader anwser */
656     {
657     unsigned char tx_buffer[] = { 0x01, 0x01, 0x01};
658     unsigned char rx_buffer[50];
659     unsigned int rx_length = sizeof(rx_buffer);
660    
661     if (IFD_SUCCESS != CmdEscape(reader_index, tx_buffer, sizeof(tx_buffer),
662     rx_buffer, &rx_length))
663     {
664     DEBUG_CRITICAL("Change card movement notification failed.");
665     return STATUS_UNSUCCESSFUL;
666     }
667     }
668    
669 rousseau 414 return STATUS_SUCCESS;
670 rousseau 649 } /* OpenSerialByName */
671 rousseau 414
672    
673     /*****************************************************************************
674     *
675     * CloseSerial: close the port
676     *
677     *****************************************************************************/
678 rousseau 1106 status_t CloseSerial(unsigned int reader_index)
679 rousseau 414 {
680 rousseau 1106 unsigned int reader = reader_index;
681 rousseau 414
682     close(serialDevice[reader].fd);
683     serialDevice[reader].fd = -1;
684    
685 rousseau 649 free(serialDevice[reader].device);
686     serialDevice[reader].device = NULL;
687    
688 rousseau 414 return STATUS_SUCCESS;
689     } /* CloseSerial */
690    
691    
692     /*****************************************************************************
693     *
694     * get_ccid_descriptor
695     *
696     ****************************************************************************/
697 rousseau 1106 _ccid_descriptor *get_ccid_descriptor(unsigned int reader_index)
698 rousseau 414 {
699 rousseau 1106 return &serialDevice[reader_index].ccid;
700 rousseau 414 } /* get_ccid_descriptor */
701    
702    

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5