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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5