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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 414 by rousseau, Wed Sep 10 09:17:43 2003 UTC revision 1496 by rousseau, Mon May 2 13:37:13 2005 UTC
# Line 1  Line 1 
1  /*  /*
2   * ccid_serial.c: communicate with a GemPC Twin smart card reader   * ccid_serial.c: communicate with a GemPC Twin smart card reader
3   * Copyright (C) 2001-2003 Ludovic Rousseau <ludovic.rousseau@free.fr>   * Copyright (C) 2001-2004 Ludovic Rousseau <ludovic.rousseau@free.fr>
4   *   *
5   * Thanks to Niki W. Waibel <niki.waibel@gmx.net> for a prototype version   * Thanks to Niki W. Waibel <niki.waibel@gmx.net> for a prototype version
6   *   *
7   * This program is free software; you can redistribute it and/or modify it      This library is free software; you can redistribute it and/or
8   * under the terms of the GNU General Public License as published by the      modify it under the terms of the GNU Lesser General Public
9   * Free Software Foundation; either version 2 of the License, or (at your      License as published by the Free Software Foundation; either
10   * option) any later version.      version 2.1 of the License, or (at your option) any later version.
11   *  
12   * This program is distributed in the hope that it will be useful, but      This library is distributed in the hope that it will be useful,
13   * WITHOUT ANY WARRANTY; without even the implied warranty of      but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15   * General Public License for more details.      Lesser General Public License for more details.
16   *  
17   * You should have received a copy of the GNU General Public License along      You should have received a copy of the GNU Lesser General Public
18   * with this program; if not, write to the Free Software Foundation, Inc.,      License along with this library; if not, write to the Free Software
19   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
20   */   */
21    
22  /*  /*
# Line 32  Line 32 
32  #include <errno.h>  #include <errno.h>
33  #include <sys/time.h>  #include <sys/time.h>
34  #include <sys/types.h>  #include <sys/types.h>
35    #include <sys/ioctl.h>
36    #include <PCSC/ifdhandler.h>
37    
38  #include "pcscdefines.h"  #include "defs.h"
39    #include "ccid_ifdhandler.h"
40  #include "config.h"  #include "config.h"
41  #include "debug.h"  #include "debug.h"
42  #include "ccid.h"  #include "ccid.h"
43  #include "utils.h"  #include "utils.h"
44    #include "commands.h"
 /* communication timeout in seconds */  
 #define SERIAL_TIMEOUT 10  
45    
46  #define SYNC 0x03  #define SYNC 0x03
47  #define CTRL_ACK 0x06  #define CTRL_ACK 0x06
# Line 67  Line 68 
68   * 1 : LRC (0x16)   * 1 : LRC (0x16)
69   *   *
70   * Card insertion/withdrawal   * Card insertion/withdrawal
  * 1 : SYNC  
  * 1 : CTRL  
71   * 1 : RDR_to_PC_NotifySlotChange (0x50)   * 1 : RDR_to_PC_NotifySlotChange (0x50)
72   * 1 : bmSlotIccState   * 1 : bmSlotIccState
73   *     0x02 if card absent   *     0x02 if card absent
74   *     0x03 is card present   *     0x03 is card present
  * 1 : LRC  
75   *   *
76   * Time request   * Time request
77   * T=1 : normal CCID command   * T=1 : normal CCID command
# Line 81  Line 79 
79   *   *
80   */   */
81    
82    /*
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  typedef struct  typedef struct
99  {  {
100          /*          /*
# Line 89  typedef struct Line 103  typedef struct
103          int fd;          int fd;
104    
105          /*          /*
106           * channel used (1..4)           * device used ("/dev/ttyS?" under Linux)
107             */
108            /*@null@*/ char *device;
109    
110            /*
111             * serial communication buffer
112           */           */
113          int channel;          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           * CCID infos common to USB and serial           * CCID infos common to USB and serial
# Line 103  typedef struct Line 132  typedef struct
132  /* The _serialDevice structure must be defined before including ccid_serial.h */  /* The _serialDevice structure must be defined before including ccid_serial.h */
133  #include "ccid_serial.h"  #include "ccid_serial.h"
134    
135  static _serialDevice serialDevice[PCSCLITE_MAX_READERS] = {  unsigned int SerialDataRates[] = {
136          [ 0 ... (PCSCLITE_MAX_READERS-1) ] = { -1, -1 }                  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                    104167,
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    /* no need to initialize to 0 since it is static */
180    static _serialDevice serialDevice[CCID_DRIVER_MAX_READERS];
181    
182    /* unexported functions */
183    static int ReadChunk(unsigned int reader_index, unsigned char *buffer,
184            int buffer_length, int min_length);
185    
186    static int get_bytes(unsigned int reader_index, unsigned char *buffer,
187            int length);
188    
 /* 271 = max size for short APDU  
  * 2 bytes for header  
  * 1 byte checksum  
  * doubled for echo */  
 #define GEMPCTWIN_MAXBUF (271 +2 +1) *2  
189    
190  /*****************************************************************************  /*****************************************************************************
191   *   *
192   *                              WriteSerial: Send bytes to the card reader   *                              WriteSerial: Send bytes to the card reader
193   *   *
194   *****************************************************************************/   *****************************************************************************/
195  status_t WriteSerial(int lun, int length, unsigned char *buffer)  status_t WriteSerial(unsigned int reader_index, unsigned int length,
196            unsigned char *buffer)
197  {  {
198          int i;          int i;
         int reader = LunToReaderIndex(lun);  
199          unsigned char lrc;          unsigned char lrc;
200          unsigned char low_level_buffer[GEMPCTWIN_MAXBUF];          unsigned char low_level_buffer[GEMPCTWIN_MAXBUF];
201    
202  #ifdef DEBUG_LEVEL_COMM  #ifdef DEBUG_LEVEL_COMM
203          char debug_header[] = "-> 121234 ";          char debug_header[] = "-> 123456 ";
204    
205          sprintf(debug_header, "-> %06X ", (int)lun);          sprintf(debug_header, "-> %06X ", reader_index);
206  #endif  #endif
207    
208          if (length > GEMPCTWIN_MAXBUF-3)          if (length > GEMPCTWIN_MAXBUF-3)
209          {          {
210                  DEBUG_CRITICAL3("WriteSerial: command too long: %d for max %d",                  DEBUG_CRITICAL3("command too long: %d for max %d",
211                          length, GEMPCTWIN_MAXBUF-3);                          length, GEMPCTWIN_MAXBUF-3);
212                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
213          }          }
# Line 155  status_t WriteSerial(int lun, int length Line 229  status_t WriteSerial(int lun, int length
229          DEBUG_XXD(debug_header, low_level_buffer, length+3);          DEBUG_XXD(debug_header, low_level_buffer, length+3);
230  #endif  #endif
231    
232          if (write(serialDevice[reader].fd, low_level_buffer, length+3) != length+3)          if (write(serialDevice[reader_index].fd, low_level_buffer,
233                    length+3) != length+3)
234          {          {
235                  DEBUG_CRITICAL2("WriteSerial: write error: %s", strerror(errno));                  DEBUG_CRITICAL2("write error: %s", strerror(errno));
236                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
237          }          }
238    
# Line 170  status_t WriteSerial(int lun, int length Line 245  status_t WriteSerial(int lun, int length
245   *                              ReadSerial: Receive bytes from the card reader   *                              ReadSerial: Receive bytes from the card reader
246   *   *
247   *****************************************************************************/   *****************************************************************************/
248  status_t ReadSerial(int lun, int *length, unsigned char *buffer)  status_t ReadSerial(unsigned int reader_index,
249            /*@unused@*/ unsigned int *length, unsigned char *buffer)
250  {  {
251          int fd = serialDevice[LunToReaderIndex(lun)].fd;          unsigned char c;
252          static unsigned char low_level_buffer[GEMPCTWIN_MAXBUF];          int rv;
253          int buffer_size, len, rv, already_read, to_read;          int echo;
254          unsigned char *reader_to_pc;          int to_read;
255          unsigned char lrc;          int i;
         int skipped, i;  
 #ifdef DEBUG_LEVEL_COMM  
         char debug_header[] = "<- 121234 ";  
   
         sprintf(debug_header, "<- %06X ", (int)lun);  
 #endif  
256    
257          buffer_size = *length;          /* we get the echo first */
258            echo = TRUE;
259    
260          /* error by default (zero length) */  start:
261          *length = 0;          DEBUG_COMM("start");
262            if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
263                    return rv;
264    
265          rv = ReadChunk(fd, low_level_buffer, sizeof(low_level_buffer), 3, lun);          if (c == RDR_to_PC_NotifySlotChange)
266          if (rv < 0)                  goto slot_change;
                 return STATUS_UNSUCCESSFUL;  
267    
268          /* Nb of bytes already read */          if (c == SYNC)
269          already_read = rv;                  goto sync;
270    
271  #ifdef DEBUG_LEVEL_COMM          if (c >= 0x80)
272          DEBUG_XXD(debug_header, low_level_buffer, rv);          {
273  #endif                  DEBUG_COMM2("time request: 0x%02X", c);
274                    goto start;
275          /* skip the echo of the previous command */          }
         skipped = skip_echo(low_level_buffer, sizeof(low_level_buffer));  
         if (skipped == 0)  
                 return STATUS_UNSUCCESSFUL;  
276    
277          /* Nb of bytes until the end of the buffer */          DEBUG_CRITICAL2("Got 0x%02X", c);
278          len = sizeof(low_level_buffer) - skipped;          return STATUS_COMM_ERROR;
         already_read -= skipped;  
         reader_to_pc = low_level_buffer + skipped;  
279    
280          to_read = 2 +1; /* minimal frame size */  slot_change:
281            DEBUG_COMM("slot change");
282            if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
283                    return rv;
284    
285          while (already_read < to_read)          if (c == CARD_ABSENT)
286          {          {
287                  rv = ReadChunk(fd, reader_to_pc + already_read, len, 1, lun);                  DEBUG_COMM("Card removed");
                 if (rv < 0)  
                         return STATUS_UNSUCCESSFUL;  
   
                 already_read += rv;  
                 len -= rv;  
288          }          }
289            else
290                    if (c == CARD_PRESENT)
291                    {
292                            DEBUG_COMM("Card inserted");
293                    }
294                    else
295                    {
296                            DEBUG_COMM2("Unknown card movement: %d", c);
297                    }
298            goto start;
299    
300          if (reader_to_pc[0] != SYNC)  sync:
301          {          DEBUG_COMM("sync");
302                  DEBUG_CRITICAL2("No SYNC byte found: 0x%02X", buffer[0]);          if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
303                  return STATUS_UNSUCCESSFUL;                  return rv;
         }  
304    
305          if (reader_to_pc[1] != CTRL_ACK)          if (c == CTRL_ACK)
306          {                  goto ack;
                 DEBUG_CRITICAL2("No ACK byte found: 0x%02X", buffer[0]);  
                 return 0;  
         }  
307    
308          /* read up to CCID frame length */          if (c == CTRL_NAK)
309          to_read = 5; /* bMessageType + dwLength */                  goto nak;
         while (already_read < to_read)  
         {  
                 rv = ReadChunk(fd, reader_to_pc + already_read, len, 1, lun);  
                 if (rv < 0)  
                         return STATUS_UNSUCCESSFUL;  
310    
311                  already_read += rv;          DEBUG_CRITICAL2("Got 0x%02X instead of ACK/NAK", c);
312                  len -= rv;          return STATUS_COMM_ERROR;
         }  
313    
314          /* normal CCID command */  nak:
315          to_read = 10+3+dw2i(reader_to_pc, 3);          DEBUG_COMM("nak");
316            if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
317                    return rv;
318    
319          while (already_read < to_read)          if (c != (SYNC ^ CTRL_NAK))
320          {          {
321                  rv = ReadChunk(fd, reader_to_pc + already_read, len, 1, lun);                  DEBUG_CRITICAL2("Wrong LRC: 0x%02X", c);
322                  if (rv < 0)                  return STATUS_COMM_ERROR;
323                          return STATUS_UNSUCCESSFUL;          }
324            else
325                  already_read += rv;          {
326                  len -= rv;                  DEBUG_COMM("NAK requested");
327                    return STATUS_COMM_NAK;
328          }          }
329    
330          lrc = 0;  ack:
331          for (i=0; i<to_read; i++)          DEBUG_COMM("ack");
332                  lrc ^= reader_to_pc[i];          /* normal CCID frame */
333            if ((rv = get_bytes(reader_index, buffer, 5)) != STATUS_SUCCESS)
334          if (lrc != 0)                  return rv;
335                  DEBUG_CRITICAL2("Wrong lrc: 0x%02X", lrc);  
336            /* total frame size */
337            to_read = 10+dw2i(buffer, 1);
338    
339            DEBUG_COMM2("frame size: %d", to_read);
340            if ((rv = get_bytes(reader_index, buffer+5, to_read-5)) != STATUS_SUCCESS)
341                    return rv;
342    
343  #ifdef DEBUG_LEVEL_COMM  #ifdef DEBUG_LEVEL_COMM
344          DEBUG_XXD(debug_header, reader_to_pc, to_read);                  DEBUG_XXD("frame: ", buffer, to_read);
345  #endif  #endif
346    
347          /* copy up to buffer_size bytes */          /* lrc */
348          *length = to_read-3;          DEBUG_COMM("lrc");
349            if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
350                    return rv;
351    
352            DEBUG_COMM2("lrc: 0x%02X", c);
353            for (i=0; i<to_read; i++)
354                    c ^= buffer[i];
355    
356            if (c != (SYNC ^ CTRL_ACK))
357                    DEBUG_CRITICAL2("Wrong LRC: 0x%02X", c);
358    
359          memcpy(buffer, reader_to_pc+2, *length);          if (echo)
360            {
361                    echo = FALSE;
362                    goto start;
363            }
364    
365          return STATUS_SUCCESS;          return STATUS_SUCCESS;
366  } /* ReadSerial */  } /* ReadSerial */
# Line 281  status_t ReadSerial(int lun, int *length Line 368  status_t ReadSerial(int lun, int *length
368    
369  /*****************************************************************************  /*****************************************************************************
370   *   *
371   *                              skip_echo: skip the echo of the previous command   *                              get_bytes: get n bytes
372   *   *
373   *****************************************************************************/   *****************************************************************************/
374  int skip_echo(unsigned char *buffer, int buffer_length)  int get_bytes(unsigned int reader_index, unsigned char *buffer, int length)
375  {  {
376          unsigned char lrc;          int offset = serialDevice[reader_index].buffer_offset;
377          int i;          int offset_last = serialDevice[reader_index].buffer_offset_last;
378    
379          if (buffer[0] != SYNC)          DEBUG_COMM3("available: %d, needed: %d", offset_last-offset,
380          {                  length);
381                  DEBUG_CRITICAL2("No SYNC byte found: 0x%02X", buffer[0]);          /* enough data are available */
382                  return 0;          if (offset + length <= offset_last)
383            {
384                    DEBUG_COMM("data available");
385                    memcpy(buffer, serialDevice[reader_index].buffer + offset, length);
386                    serialDevice[reader_index].buffer_offset += length;
387          }          }
388            else
         if (buffer[1] != CTRL_ACK)  
389          {          {
390                  DEBUG_CRITICAL2("No ACK byte found: 0x%02X", buffer[0]);                  int present, rv;
                 return 0;  
         }  
391    
392          if (buffer[2] == RDR_to_PC_NotifySlotChange)                  /* copy available data */
393          {                  present = offset_last - offset;
394                  switch (buffer[3])  
395                    if (present > 0)
396                  {                  {
397                          case CARD_PRESENT:                          DEBUG_COMM2("some data available: %d", present);
398                                  DEBUG_INFO("Card inserted");                          memcpy(buffer, serialDevice[reader_index].buffer + offset,
399                                  break;                                  present);
   
                         case CARD_ABSENT:  
                                 DEBUG_INFO("Card removed");  
                                 break;  
   
                         default:  
                                 DEBUG_INFO2("Unknown card movement: %d", buffer[3]);  
                                 break;  
400                  }                  }
   
                 lrc = 0;  
                 for (i=0; i<5; i++)  
                         lrc ^= buffer[i];  
401    
402                  if (lrc != 0)                  /* get fresh data */
403                          DEBUG_CRITICAL2("Wrong lrc: 0x%02", lrc);                  DEBUG_COMM2("get more data: %d", length - present);
404                    rv = ReadChunk(reader_index, serialDevice[reader_index].buffer,
405                            sizeof(serialDevice[reader_index].buffer), length - present);
406                    if (rv < 0)
407                            return STATUS_COMM_ERROR;
408    
409                  /* Card insertion/withdrawal */                  /* fill the buffer */
410                  return 5;                  memcpy(buffer + present, serialDevice[reader_index].buffer,
411                            length - present);
412                    serialDevice[reader_index].buffer_offset = length - present;
413                    serialDevice[reader_index].buffer_offset_last = rv;
414                    DEBUG_COMM3("offset: %d, last_offset: %d",
415                            serialDevice[reader_index].buffer_offset,
416                            serialDevice[reader_index].buffer_offset_last);
417          }          }
418    
419          /* normal CCID command, 2 for SYNC CTRL, 1 for length offset in CCID cmd */          return STATUS_SUCCESS;
420          return 2 + 10 + dw2i(buffer, 2 +1) +1;  } /* get_bytes */
 } /* skip_echo */  
421    
422    
423  /*****************************************************************************  /*****************************************************************************
# Line 339  int skip_echo(unsigned char *buffer, int Line 425  int skip_echo(unsigned char *buffer, int
425   *                              ReadChunk: read a minimum number of bytes   *                              ReadChunk: read a minimum number of bytes
426   *   *
427   *****************************************************************************/   *****************************************************************************/
428  int ReadChunk(int fd, unsigned char *buffer, int buffer_length, int min_length, int lun)  static int ReadChunk(unsigned int reader_index, unsigned char *buffer,
429            int buffer_length, int min_length)
430  {  {
431            int fd = serialDevice[reader_index].fd;
432    # ifndef S_SPLINT_S
433          fd_set fdset;          fd_set fdset;
434    # endif
435          struct timeval t;          struct timeval t;
436          int i, rv;          int i, rv = 0;
437            int already_read;
438  #ifdef DEBUG_LEVEL_COMM  #ifdef DEBUG_LEVEL_COMM
439          char debug_header[] = "<- 121234 ";          char debug_header[] = "<- 123456 ";
440    
441          sprintf(debug_header, "<- %06X ", (int)lun);          sprintf(debug_header, "<- %06X ", reader_index);
442  #endif  #endif
443    
444  time_request:          already_read = 0;
445          /* use select() to, eventually, timeout */          while (already_read < min_length)
         FD_ZERO(&fdset);  
         FD_SET(fd, &fdset);  
         t.tv_sec = SERIAL_TIMEOUT;  
         t.tv_usec = 0;  
   
         i = select(fd+1, &fdset, NULL, NULL, &t);  
         if (i == -1)  
446          {          {
447                  DEBUG_CRITICAL2("select: %s", strerror(errno));                  /* use select() to, eventually, timeout */
448                  return -1;                  FD_ZERO(&fdset);
449          }                  FD_SET(fd, &fdset);
450          else                  t.tv_sec = serialDevice[reader_index].ccid.readTimeout;
451                  if (i == 0)                  t.tv_usec = 0;
452    
453                    i = select(fd+1, &fdset, NULL, NULL, &t);
454                    if (i == -1)
455                  {                  {
456                          DEBUG_COMM2("Timeout! (%d sec)", SERIAL_TIMEOUT);                          DEBUG_CRITICAL2("select: %s", strerror(errno));
457                          return -1;                          return -1;
458                  }                  }
459                    else
460                            if (i == 0)
461                            {
462                                    DEBUG_COMM2("Timeout! (%d sec)", serialDevice[reader_index].ccid.readTimeout);
463                                    return -1;
464                            }
465    
466          rv = read(fd, buffer, buffer_length);                  rv = read(fd, buffer + already_read, buffer_length - already_read);
467          if (rv < 0)                  if (rv < 0)
468          {                  {
469                  DEBUG_COMM2("read error: %s", strerror(errno));                          DEBUG_COMM2("read error: %s", strerror(errno));
470                  return -1;                          return -1;
471          }                  }
   
         if ((rv == 1) && (buffer[0] >= 0x80))  
         {  
                 DEBUG_COMM2("Time request: 0x%02X", buffer[0]);  
                 goto time_request;  
         }  
472    
         /* too short */  
         if (rv < min_length)  
         {  
473  #ifdef DEBUG_LEVEL_COMM  #ifdef DEBUG_LEVEL_COMM
474                  DEBUG_XXD(debug_header, buffer, rv);                  DEBUG_XXD(debug_header, buffer + already_read, rv);
475  #endif  #endif
                 DEBUG_COMM3("ReadSerial: only %d byte(s) read, needed %d", rv,  
                         min_length);  
476    
477                  return -1;                  already_read += rv;
478                    DEBUG_COMM3("read: %d, to read: %d", already_read,
479                            min_length);
480          }          }
481    
482          return rv;          return already_read;
483  } /* ReadChunk */  } /* ReadChunk */
484    
485    
# Line 404  time_request: Line 488  time_request:
488   *                              OpenSerial: open the port   *                              OpenSerial: open the port
489   *   *
490   *****************************************************************************/   *****************************************************************************/
491  status_t OpenSerial(int lun, int channel)  status_t OpenSerial(unsigned int reader_index, int channel)
492  {  {
493          char dev_name[FILENAME_MAX];          char dev_name[FILENAME_MAX];
         struct termios current_termios;  
         int i;  
         int reader = LunToReaderIndex(lun);  
494    
495          DEBUG_COMM3("OpenSerial: Lun: %X, Channel: %d", lun, channel);          DEBUG_COMM3("Reader index: %X, Channel: %d", reader_index, channel);
496    
497          /*          /*
498           * Conversion of old-style ifd-hanler 1.0 CHANNELID           * Conversion of old-style ifd-hanler 1.0 CHANNELID
# Line 436  status_t OpenSerial(int lun, int channel Line 517  status_t OpenSerial(int lun, int channel
517    
518          sprintf(dev_name, "/dev/pcsc/%d", (int) channel);          sprintf(dev_name, "/dev/pcsc/%d", (int) channel);
519    
520            return OpenSerialByName(reader_index, dev_name);
521    } /* OpenSerial */
522    
523    /*****************************************************************************
524     *
525     *                              OpenSerialByName: open the port
526     *
527     *****************************************************************************/
528    status_t OpenSerialByName(unsigned int reader_index, char *dev_name)
529    {
530            struct termios current_termios;
531            int i;
532            unsigned int reader = reader_index;
533    
534            DEBUG_COMM3("Reader index: %X, Device: %s", reader_index, dev_name);
535    
536          /* check if the same channel is not already used */          /* check if the same channel is not already used */
537          for (i=0; i<PCSCLITE_MAX_READERS; i++)          for (i=0; i<CCID_DRIVER_MAX_READERS; i++)
538          {          {
539                  if (serialDevice[i].channel == channel)                  if (serialDevice[i].device &&
540                            strcmp(serialDevice[i].device, dev_name) == 0)
541                  {                  {
542                          DEBUG_CRITICAL2("Channel %s already in use", dev_name);                          DEBUG_CRITICAL2("Device %s already in use", dev_name);
543                          return STATUS_UNSUCCESSFUL;                          return STATUS_UNSUCCESSFUL;
544                  }                  }
545          }          }
546    
547          serialDevice[reader].fd = open(dev_name, O_RDWR | O_NOCTTY);          serialDevice[reader].fd = open(dev_name, O_RDWR | O_NOCTTY);
548    
549          if (serialDevice[reader].fd <= 0)          if (-1 == serialDevice[reader].fd)
550          {          {
551                  DEBUG_CRITICAL3("open %s: %s", dev_name, strerror(errno));                  DEBUG_CRITICAL3("open %s: %s", dev_name, strerror(errno));
552                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
553          }          }
554    
555            /* 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          /* set channel used */          /* set channel used */
580          serialDevice[reader].channel = channel;          serialDevice[reader].device = strdup(dev_name);
581    
582          /* empty in and out serial buffers */          /* empty in and out serial buffers */
583          if (tcflush(serialDevice[reader].fd, TCIOFLUSH))          if (tcflush(serialDevice[reader].fd, TCIOFLUSH))
# Line 498  status_t OpenSerial(int lun, int channel Line 620  status_t OpenSerial(int lun, int channel
620                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
621          }          }
622    
623          serialDevice[reader].ccid.bSeq = 0;          serialDevice[reader].ccid.real_bSeq = 0;
624            serialDevice[reader].ccid.pbSeq = &serialDevice[reader].ccid.real_bSeq;
625          serialDevice[reader].ccid.readerID = GEMPCTWIN;          serialDevice[reader].ccid.readerID = GEMPCTWIN;
626          serialDevice[reader].ccid.dwMaxCCIDMessageLength = 271;          serialDevice[reader].ccid.dwMaxCCIDMessageLength = 271;
627            serialDevice[reader].ccid.dwMaxIFSD = 254;
628          serialDevice[reader].ccid.dwFeatures = 0x00010230;          serialDevice[reader].ccid.dwFeatures = 0x00010230;
629            serialDevice[reader].ccid.bPINSupport = 0x0;
630            serialDevice[reader].ccid.dwDefaultClock = 4000;
631            serialDevice[reader].ccid.dwMaxDataRate = 344086;
632            serialDevice[reader].ccid.bMaxSlotIndex = 0;
633            serialDevice[reader].ccid.bCurrentSlotIndex = 0;
634            serialDevice[reader].ccid.arrayOfSupportedDataRates = SerialDataRates;
635    
636            serialDevice[reader].buffer_offset = 0;
637            serialDevice[reader].buffer_offset_last = 0;
638    
639            /* perform a command to be sure a GemPC Twin reader is connected
640             * get the reader firmware */
641            {
642                    unsigned char tx_buffer[] = { 0x02 };
643                    unsigned char rx_buffer[50];
644                    unsigned int rx_length = sizeof(rx_buffer);
645    
646          ccid_open_hack(lun);                  /* 2 seconds timeout to not wait too long if no reader is connected */
647                    serialDevice[reader].ccid.readTimeout = 2;
648    
649                    if (IFD_SUCCESS != CmdEscape(reader_index, tx_buffer, sizeof(tx_buffer),
650                            rx_buffer, &rx_length))
651                    {
652                            DEBUG_CRITICAL("Get firmware failed. Maybe the reader is not connected");
653                            return STATUS_UNSUCCESSFUL;
654                    }
655    
656                    /* normal timeout: 2 seconds */
657                    serialDevice[reader].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT ;
658    
659                    rx_buffer[rx_length] = '\0';
660                    DEBUG_INFO2("Firmware: %s", rx_buffer);
661            }
662    
663            /* 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          return STATUS_SUCCESS;          return STATUS_SUCCESS;
680  } /* OpenSerial */  } /* OpenSerialByName */
681    
682    
683  /*****************************************************************************  /*****************************************************************************
# Line 514  status_t OpenSerial(int lun, int channel Line 685  status_t OpenSerial(int lun, int channel
685   *                              CloseSerial: close the port   *                              CloseSerial: close the port
686   *   *
687   *****************************************************************************/   *****************************************************************************/
688  status_t CloseSerial(int lun)  status_t CloseSerial(unsigned int reader_index)
689  {  {
690          int reader = LunToReaderIndex(lun);          unsigned int reader = reader_index;
691    
692          close(serialDevice[reader].fd);          close(serialDevice[reader].fd);
   
693          serialDevice[reader].fd = -1;          serialDevice[reader].fd = -1;
694          serialDevice[reader].channel = -1;  
695            free(serialDevice[reader].device);
696            serialDevice[reader].device = NULL;
697    
698          return STATUS_SUCCESS;          return STATUS_SUCCESS;
699  } /* CloseSerial */  } /* CloseSerial */
# Line 532  status_t CloseSerial(int lun) Line 704  status_t CloseSerial(int lun)
704   *                                      get_ccid_descriptor   *                                      get_ccid_descriptor
705   *   *
706   ****************************************************************************/   ****************************************************************************/
707  _ccid_descriptor *get_ccid_descriptor(int lun)  _ccid_descriptor *get_ccid_descriptor(unsigned int reader_index)
708  {  {
709          return &serialDevice[LunToReaderIndex(lun)].ccid;          return &serialDevice[reader_index].ccid;
710  } /* get_ccid_descriptor */  } /* get_ccid_descriptor */
711    
712    

Legend:
Removed from v.414  
changed lines
  Added in v.1496

  ViewVC Help
Powered by ViewVC 1.1.5