/[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 1496 - (hide annotations) (download)
Mon May 2 13:37:13 2005 UTC (8 years ago) by rousseau
File MIME type: text/plain
File size: 17066 byte(s)
typo in the data rates list
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     #ifdef DEBUG_LEVEL_COMM
203 rousseau 1047 char debug_header[] = "-> 123456 ";
204 rousseau 414
205 rousseau 1106 sprintf(debug_header, "-> %06X ", reader_index);
206 rousseau 414 #endif
207    
208     if (length > GEMPCTWIN_MAXBUF-3)
209     {
210 rousseau 608 DEBUG_CRITICAL3("command too long: %d for max %d",
211 rousseau 414 length, GEMPCTWIN_MAXBUF-3);
212     return STATUS_UNSUCCESSFUL;
213     }
214    
215     /* header */
216     low_level_buffer[0] = 0x03; /* SYNC */
217     low_level_buffer[1] = 0x06; /* ACK */
218    
219     /* CCID command */
220     memcpy(low_level_buffer+2, buffer, length);
221    
222     /* checksum */
223     lrc = 0;
224     for(i=0; i<length+2; i++)
225     lrc ^= low_level_buffer[i];
226     low_level_buffer[length+2] = lrc;
227    
228     #ifdef DEBUG_LEVEL_COMM
229     DEBUG_XXD(debug_header, low_level_buffer, length+3);
230     #endif
231    
232 rousseau 1106 if (write(serialDevice[reader_index].fd, low_level_buffer,
233 rousseau 453 length+3) != length+3)
234 rousseau 414 {
235 rousseau 608 DEBUG_CRITICAL2("write error: %s", strerror(errno));
236 rousseau 414 return STATUS_UNSUCCESSFUL;
237     }
238    
239     return STATUS_SUCCESS;
240     } /* WriteSerial */
241    
242    
243     /*****************************************************************************
244     *
245     * ReadSerial: Receive bytes from the card reader
246     *
247     *****************************************************************************/
248 rousseau 1106 status_t ReadSerial(unsigned int reader_index,
249     /*@unused@*/ unsigned int *length, unsigned char *buffer)
250 rousseau 414 {
251 rousseau 453 unsigned char c;
252     int rv;
253     int echo;
254     int to_read;
255     int i;
256 rousseau 414
257 rousseau 453 /* we get the echo first */
258     echo = TRUE;
259 rousseau 414
260 rousseau 453 start:
261 rousseau 462 DEBUG_COMM("start");
262 rousseau 1106 if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
263 rousseau 453 return rv;
264 rousseau 414
265 rousseau 453 if (c == RDR_to_PC_NotifySlotChange)
266     goto slot_change;
267 rousseau 414
268 rousseau 453 if (c == SYNC)
269     goto sync;
270 rousseau 414
271 rousseau 453 if (c >= 0x80)
272 rousseau 462 {
273     DEBUG_COMM2("time request: 0x%02X", c);
274 rousseau 453 goto start;
275 rousseau 462 }
276 rousseau 414
277 rousseau 453 DEBUG_CRITICAL2("Got 0x%02X", c);
278     return STATUS_COMM_ERROR;
279 rousseau 414
280 rousseau 453 slot_change:
281 rousseau 462 DEBUG_COMM("slot change");
282 rousseau 1106 if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
283 rousseau 453 return rv;
284 rousseau 414
285 rousseau 453 if (c == CARD_ABSENT)
286 rousseau 774 {
287 rousseau 453 DEBUG_COMM("Card removed");
288 rousseau 774 }
289 rousseau 453 else
290     if (c == CARD_PRESENT)
291 rousseau 774 {
292 rousseau 453 DEBUG_COMM("Card inserted");
293 rousseau 774 }
294 rousseau 453 else
295 rousseau 774 {
296 rousseau 1044 DEBUG_COMM2("Unknown card movement: %d", c);
297 rousseau 774 }
298 rousseau 453 goto start;
299 rousseau 414
300 rousseau 453 sync:
301 rousseau 462 DEBUG_COMM("sync");
302 rousseau 1106 if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
303 rousseau 453 return rv;
304 rousseau 414
305 rousseau 453 if (c == CTRL_ACK)
306     goto ack;
307 rousseau 414
308 rousseau 453 if (c == CTRL_NAK)
309     goto nak;
310 rousseau 414
311 rousseau 453 DEBUG_CRITICAL2("Got 0x%02X instead of ACK/NAK", c);
312     return STATUS_COMM_ERROR;
313 rousseau 414
314 rousseau 453 nak:
315 rousseau 462 DEBUG_COMM("nak");
316 rousseau 1106 if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
317 rousseau 453 return rv;
318 rousseau 414
319 rousseau 453 if (c != (SYNC ^ CTRL_NAK))
320 rousseau 414 {
321 rousseau 453 DEBUG_CRITICAL2("Wrong LRC: 0x%02X", c);
322     return STATUS_COMM_ERROR;
323 rousseau 414 }
324 rousseau 453 else
325 rousseau 1491 {
326     DEBUG_COMM("NAK requested");
327     return STATUS_COMM_NAK;
328     }
329 rousseau 414
330 rousseau 453 ack:
331 rousseau 462 DEBUG_COMM("ack");
332 rousseau 453 /* normal CCID frame */
333 rousseau 1106 if ((rv = get_bytes(reader_index, buffer, 5)) != STATUS_SUCCESS)
334 rousseau 453 return rv;
335 rousseau 414
336 rousseau 453 /* total frame size */
337     to_read = 10+dw2i(buffer, 1);
338 rousseau 414
339 rousseau 462 DEBUG_COMM2("frame size: %d", to_read);
340 rousseau 1106 if ((rv = get_bytes(reader_index, buffer+5, to_read-5)) != STATUS_SUCCESS)
341 rousseau 453 return rv;
342 rousseau 414
343 rousseau 462 #ifdef DEBUG_LEVEL_COMM
344     DEBUG_XXD("frame: ", buffer, to_read);
345     #endif
346    
347 rousseau 453 /* lrc */
348 rousseau 462 DEBUG_COMM("lrc");
349 rousseau 1106 if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
350 rousseau 453 return rv;
351    
352 rousseau 462 DEBUG_COMM2("lrc: 0x%02X", c);
353 rousseau 414 for (i=0; i<to_read; i++)
354 rousseau 453 c ^= buffer[i];
355 rousseau 414
356 rousseau 453 if (c != (SYNC ^ CTRL_ACK))
357     DEBUG_CRITICAL2("Wrong LRC: 0x%02X", c);
358 rousseau 414
359 rousseau 453 if (echo)
360     {
361     echo = FALSE;
362     goto start;
363     }
364 rousseau 414
365     return STATUS_SUCCESS;
366     } /* ReadSerial */
367    
368    
369     /*****************************************************************************
370     *
371 rousseau 453 * get_bytes: get n bytes
372 rousseau 414 *
373     *****************************************************************************/
374 rousseau 1106 int get_bytes(unsigned int reader_index, unsigned char *buffer, int length)
375 rousseau 414 {
376 rousseau 1106 int offset = serialDevice[reader_index].buffer_offset;
377     int offset_last = serialDevice[reader_index].buffer_offset_last;
378 rousseau 414
379 rousseau 608 DEBUG_COMM3("available: %d, needed: %d", offset_last-offset,
380 rousseau 462 length);
381 rousseau 453 /* enough data are available */
382     if (offset + length <= offset_last)
383 rousseau 414 {
384 rousseau 608 DEBUG_COMM("data available");
385 rousseau 1106 memcpy(buffer, serialDevice[reader_index].buffer + offset, length);
386     serialDevice[reader_index].buffer_offset += length;
387 rousseau 414 }
388 rousseau 453 else
389 rousseau 414 {
390 rousseau 453 int present, rv;
391 rousseau 414
392 rousseau 453 /* copy available data */
393     present = offset_last - offset;
394 rousseau 414
395 rousseau 453 if (present > 0)
396 rousseau 462 {
397 rousseau 608 DEBUG_COMM2("some data available: %d", present);
398 rousseau 1106 memcpy(buffer, serialDevice[reader_index].buffer + offset,
399 rousseau 462 present);
400     }
401 rousseau 414
402 rousseau 453 /* get fresh data */
403 rousseau 608 DEBUG_COMM2("get more data: %d", length - present);
404 rousseau 1106 rv = ReadChunk(reader_index, serialDevice[reader_index].buffer,
405     sizeof(serialDevice[reader_index].buffer), length - present);
406 rousseau 453 if (rv < 0)
407     return STATUS_COMM_ERROR;
408 rousseau 414
409 rousseau 453 /* fill the buffer */
410 rousseau 1106 memcpy(buffer + present, serialDevice[reader_index].buffer,
411 rousseau 453 length - present);
412 rousseau 1106 serialDevice[reader_index].buffer_offset = length - present;
413     serialDevice[reader_index].buffer_offset_last = rv;
414 rousseau 608 DEBUG_COMM3("offset: %d, last_offset: %d",
415 rousseau 1106 serialDevice[reader_index].buffer_offset,
416     serialDevice[reader_index].buffer_offset_last);
417 rousseau 414 }
418    
419 rousseau 453 return STATUS_SUCCESS;
420     } /* get_bytes */
421 rousseau 414
422 rousseau 453
423 rousseau 414 /*****************************************************************************
424     *
425     * ReadChunk: read a minimum number of bytes
426     *
427     *****************************************************************************/
428 rousseau 1106 static int ReadChunk(unsigned int reader_index, unsigned char *buffer,
429 rousseau 1050 int buffer_length, int min_length)
430 rousseau 414 {
431 rousseau 1106 int fd = serialDevice[reader_index].fd;
432 rousseau 1045 # ifndef S_SPLINT_S
433 rousseau 414 fd_set fdset;
434 rousseau 1045 # endif
435 rousseau 414 struct timeval t;
436 rousseau 462 int i, rv = 0;
437     int already_read;
438 rousseau 414 #ifdef DEBUG_LEVEL_COMM
439 rousseau 1047 char debug_header[] = "<- 123456 ";
440 rousseau 414
441 rousseau 1106 sprintf(debug_header, "<- %06X ", reader_index);
442 rousseau 414 #endif
443    
444 rousseau 462 already_read = 0;
445     while (already_read < min_length)
446     {
447     /* use select() to, eventually, timeout */
448     FD_ZERO(&fdset);
449     FD_SET(fd, &fdset);
450 rousseau 1453 t.tv_sec = serialDevice[reader_index].ccid.readTimeout;
451 rousseau 462 t.tv_usec = 0;
452 rousseau 414
453 rousseau 462 i = select(fd+1, &fdset, NULL, NULL, &t);
454     if (i == -1)
455 rousseau 414 {
456 rousseau 462 DEBUG_CRITICAL2("select: %s", strerror(errno));
457 rousseau 414 return -1;
458     }
459 rousseau 462 else
460     if (i == 0)
461     {
462 rousseau 1453 DEBUG_COMM2("Timeout! (%d sec)", serialDevice[reader_index].ccid.readTimeout);
463 rousseau 462 return -1;
464     }
465 rousseau 414
466 rousseau 462 rv = read(fd, buffer + already_read, buffer_length - already_read);
467     if (rv < 0)
468     {
469     DEBUG_COMM2("read error: %s", strerror(errno));
470     return -1;
471     }
472 rousseau 414
473 rousseau 453 #ifdef DEBUG_LEVEL_COMM
474 rousseau 462 DEBUG_XXD(debug_header, buffer + already_read, rv);
475 rousseau 453 #endif
476 rousseau 414
477 rousseau 462 already_read += rv;
478 rousseau 608 DEBUG_COMM3("read: %d, to read: %d", already_read,
479 rousseau 414 min_length);
480     }
481    
482 rousseau 462 return already_read;
483 rousseau 414 } /* ReadChunk */
484    
485    
486     /*****************************************************************************
487     *
488     * OpenSerial: open the port
489     *
490     *****************************************************************************/
491 rousseau 1106 status_t OpenSerial(unsigned int reader_index, int channel)
492 rousseau 414 {
493     char dev_name[FILENAME_MAX];
494    
495 rousseau 1106 DEBUG_COMM3("Reader index: %X, Channel: %d", reader_index, channel);
496 rousseau 414
497     /*
498     * Conversion of old-style ifd-hanler 1.0 CHANNELID
499     */
500     if (channel == 0x0103F8)
501     channel = 1;
502     else
503     if (channel == 0x0102F8)
504     channel = 2;
505     else
506     if (channel == 0x0103E8)
507     channel = 3;
508     else
509     if (channel == 0x0102E8)
510     channel = 4;
511    
512     if (channel < 0)
513     {
514     DEBUG_CRITICAL2("wrong port number: %d", (int) channel);
515     return STATUS_UNSUCCESSFUL;
516     }
517    
518     sprintf(dev_name, "/dev/pcsc/%d", (int) channel);
519    
520 rousseau 1106 return OpenSerialByName(reader_index, dev_name);
521 rousseau 649 } /* OpenSerial */
522    
523     /*****************************************************************************
524     *
525     * OpenSerialByName: open the port
526     *
527     *****************************************************************************/
528 rousseau 1106 status_t OpenSerialByName(unsigned int reader_index, char *dev_name)
529 rousseau 649 {
530     struct termios current_termios;
531     int i;
532 rousseau 1106 unsigned int reader = reader_index;
533 rousseau 649
534 rousseau 1292 DEBUG_COMM3("Reader index: %X, Device: %s", reader_index, dev_name);
535 rousseau 649
536 rousseau 414 /* check if the same channel is not already used */
537 rousseau 1077 for (i=0; i<CCID_DRIVER_MAX_READERS; i++)
538 rousseau 414 {
539 rousseau 649 if (serialDevice[i].device &&
540     strcmp(serialDevice[i].device, dev_name) == 0)
541 rousseau 414 {
542 rousseau 649 DEBUG_CRITICAL2("Device %s already in use", dev_name);
543 rousseau 414 return STATUS_UNSUCCESSFUL;
544     }
545     }
546    
547     serialDevice[reader].fd = open(dev_name, O_RDWR | O_NOCTTY);
548    
549 rousseau 892 if (-1 == serialDevice[reader].fd)
550 rousseau 414 {
551     DEBUG_CRITICAL3("open %s: %s", dev_name, strerror(errno));
552     return STATUS_UNSUCCESSFUL;
553     }
554    
555 rousseau 1472 /* Set RTS signal to low to prevent the smart card reader
556     * from sending its plug and play string. */
557     {
558     int flags;
559    
560     if (ioctl(serialDevice[reader].fd, TIOCMGET, &flags) < 0)
561     {
562     DEBUG_CRITICAL2("Get RS232 signals state failed: %s",
563     strerror(errno));
564     }
565     else
566     {
567     flags &= ~TIOCM_RTS;
568     if (ioctl(serialDevice[reader].fd, TIOCMSET, &flags) < 0)
569     {
570     DEBUG_CRITICAL2("Set RTS to low failed: %s", strerror(errno));
571     }
572     else
573     {
574     DEBUG_COMM("Plug-n-Play inhibition successful");
575     }
576     }
577     }
578    
579 rousseau 414 /* set channel used */
580 rousseau 649 serialDevice[reader].device = strdup(dev_name);
581 rousseau 414
582     /* empty in and out serial buffers */
583     if (tcflush(serialDevice[reader].fd, TCIOFLUSH))
584     DEBUG_INFO2("tcflush() function error: %s", strerror(errno));
585    
586     /* get config attributes */
587     if (tcgetattr(serialDevice[reader].fd, &current_termios) == -1)
588     {
589     DEBUG_INFO2("tcgetattr() function error: %s", strerror(errno));
590     close(serialDevice[reader].fd);
591     serialDevice[reader].fd = -1;
592    
593     return STATUS_UNSUCCESSFUL;
594     }
595    
596     /* IGNBRK: ignore BREAK condition on input
597     * IGNPAR: ignore framing errors and parity errors. */
598     current_termios.c_iflag = IGNBRK | IGNPAR;
599     current_termios.c_oflag = 0; /* Raw output modes */
600     /* CS8: 8-bits character size
601     * CSTOPB: set two stop bits
602     * CREAD: enable receiver
603     * CLOCAL: ignore modem control lines */
604     current_termios.c_cflag = CS8 | CSTOPB | CREAD | CLOCAL;
605    
606     /* Do not echo characters because if you connect to a host it or your modem
607     * will echo characters for you. Don't generate signals. */
608     current_termios.c_lflag = 0;
609    
610     /* set serial port speed to 115200 bauds */
611     cfsetspeed(&current_termios, B115200);
612    
613     DEBUG_INFO("Set serial port baudrate to 115200 and correct configuration");
614     if (tcsetattr(serialDevice[reader].fd, TCSANOW, &current_termios) == -1)
615     {
616     close(serialDevice[reader].fd);
617     serialDevice[reader].fd = -1;
618     DEBUG_INFO2("tcsetattr error: %s", strerror(errno));
619    
620     return STATUS_UNSUCCESSFUL;
621     }
622    
623 rousseau 1149 serialDevice[reader].ccid.real_bSeq = 0;
624     serialDevice[reader].ccid.pbSeq = &serialDevice[reader].ccid.real_bSeq;
625 rousseau 414 serialDevice[reader].ccid.readerID = GEMPCTWIN;
626     serialDevice[reader].ccid.dwMaxCCIDMessageLength = 271;
627 rousseau 672 serialDevice[reader].ccid.dwMaxIFSD = 254;
628 rousseau 414 serialDevice[reader].ccid.dwFeatures = 0x00010230;
629 rousseau 900 serialDevice[reader].ccid.bPINSupport = 0x0;
630 rousseau 694 serialDevice[reader].ccid.dwDefaultClock = 4000;
631 rousseau 1485 serialDevice[reader].ccid.dwMaxDataRate = 344086;
632 rousseau 1091 serialDevice[reader].ccid.bMaxSlotIndex = 0;
633     serialDevice[reader].ccid.bCurrentSlotIndex = 0;
634 rousseau 1447 serialDevice[reader].ccid.arrayOfSupportedDataRates = SerialDataRates;
635 rousseau 414
636 rousseau 453 serialDevice[reader].buffer_offset = 0;
637     serialDevice[reader].buffer_offset_last = 0;
638    
639 rousseau 1022 /* perform a command to be sure a GemPC Twin reader is connected
640     * get the reader firmware */
641     {
642 rousseau 1330 unsigned char tx_buffer[] = { 0x02 };
643 rousseau 1048 unsigned char rx_buffer[50];
644     unsigned int rx_length = sizeof(rx_buffer);
645 rousseau 1022
646 rousseau 1147 /* 2 seconds timeout to not wait too long if no reader is connected */
647 rousseau 1453 serialDevice[reader].ccid.readTimeout = 2;
648 rousseau 1147
649 rousseau 1106 if (IFD_SUCCESS != CmdEscape(reader_index, tx_buffer, sizeof(tx_buffer),
650 rousseau 1022 rx_buffer, &rx_length))
651     {
652 rousseau 1147 DEBUG_CRITICAL("Get firmware failed. Maybe the reader is not connected");
653 rousseau 1022 return STATUS_UNSUCCESSFUL;
654     }
655    
656 rousseau 1453 /* normal timeout: 2 seconds */
657     serialDevice[reader].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT ;
658 rousseau 1147
659 rousseau 1022 rx_buffer[rx_length] = '\0';
660     DEBUG_INFO2("Firmware: %s", rx_buffer);
661     }
662    
663 rousseau 1444 /* perform a command to configure GemPC Twin reader card movement
664     * notification to synchronous mode: the card movement is notified _after_
665     * the host command and _before_ the reader anwser */
666     {
667     unsigned char tx_buffer[] = { 0x01, 0x01, 0x01};
668     unsigned char rx_buffer[50];
669     unsigned int rx_length = sizeof(rx_buffer);
670    
671     if (IFD_SUCCESS != CmdEscape(reader_index, tx_buffer, sizeof(tx_buffer),
672     rx_buffer, &rx_length))
673     {
674     DEBUG_CRITICAL("Change card movement notification failed.");
675     return STATUS_UNSUCCESSFUL;
676     }
677     }
678    
679 rousseau 414 return STATUS_SUCCESS;
680 rousseau 649 } /* OpenSerialByName */
681 rousseau 414
682    
683     /*****************************************************************************
684     *
685     * CloseSerial: close the port
686     *
687     *****************************************************************************/
688 rousseau 1106 status_t CloseSerial(unsigned int reader_index)
689 rousseau 414 {
690 rousseau 1106 unsigned int reader = reader_index;
691 rousseau 414
692     close(serialDevice[reader].fd);
693     serialDevice[reader].fd = -1;
694    
695 rousseau 649 free(serialDevice[reader].device);
696     serialDevice[reader].device = NULL;
697    
698 rousseau 414 return STATUS_SUCCESS;
699     } /* CloseSerial */
700    
701    
702     /*****************************************************************************
703     *
704     * get_ccid_descriptor
705     *
706     ****************************************************************************/
707 rousseau 1106 _ccid_descriptor *get_ccid_descriptor(unsigned int reader_index)
708 rousseau 414 {
709 rousseau 1106 return &serialDevice[reader_index].ccid;
710 rousseau 414 } /* get_ccid_descriptor */
711    
712    

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5