/[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 1146 by rousseau, Wed Aug 4 21:30:14 2004 UTC
# 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 <PCSC/ifdhandler.h>
36    
37  #include "pcscdefines.h"  #include "defs.h"
38    #include "ccid_ifdhandler.h"
39  #include "config.h"  #include "config.h"
40  #include "debug.h"  #include "debug.h"
41  #include "ccid.h"  #include "ccid.h"
42  #include "utils.h"  #include "utils.h"
43    #include "commands.h"
44    
45  /* communication timeout in seconds */  /* communication timeout in seconds */
46  #define SERIAL_TIMEOUT 10  #define SERIAL_TIMEOUT 2
47    
48  #define SYNC 0x03  #define SYNC 0x03
49  #define CTRL_ACK 0x06  #define CTRL_ACK 0x06
# Line 67  Line 70 
70   * 1 : LRC (0x16)   * 1 : LRC (0x16)
71   *   *
72   * Card insertion/withdrawal   * Card insertion/withdrawal
  * 1 : SYNC  
  * 1 : CTRL  
73   * 1 : RDR_to_PC_NotifySlotChange (0x50)   * 1 : RDR_to_PC_NotifySlotChange (0x50)
74   * 1 : bmSlotIccState   * 1 : bmSlotIccState
75   *     0x02 if card absent   *     0x02 if card absent
76   *     0x03 is card present   *     0x03 is card present
  * 1 : LRC  
77   *   *
78   * Time request   * Time request
79   * T=1 : normal CCID command   * T=1 : normal CCID command
# Line 81  Line 81 
81   *   *
82   */   */
83    
84    /*
85     * You may get read timeout after a card movement.
86     * This is because you will get the echo of the CCID command
87     * but not the result of the command.
88     *
89     * This is not an applicative issue since the card is either removed (and
90     * powered off) or just inserted (and not yet powered on).
91     */
92    
93    /* 271 = max size for short APDU
94     * 2 bytes for header
95     * 1 byte checksum
96     * doubled for echo
97     */
98    #define GEMPCTWIN_MAXBUF (271 +2 +1) * 2
99    
100  typedef struct  typedef struct
101  {  {
102          /*          /*
# Line 89  typedef struct Line 105  typedef struct
105          int fd;          int fd;
106    
107          /*          /*
108           * channel used (1..4)           * device used ("/dev/ttyS?" under Linux)
109             */
110            /*@null@*/ char *device;
111    
112            /*
113             * serial communication buffer
114           */           */
115          int channel;          unsigned char buffer[GEMPCTWIN_MAXBUF];
116    
117            /*
118             * next available byte
119             */
120            int buffer_offset;
121    
122            /*
123             * number of available bytes
124             */
125            int buffer_offset_last;
126    
127          /*          /*
128           * CCID infos common to USB and serial           * CCID infos common to USB and serial
# Line 103  typedef struct Line 134  typedef struct
134  /* The _serialDevice structure must be defined before including ccid_serial.h */  /* The _serialDevice structure must be defined before including ccid_serial.h */
135  #include "ccid_serial.h"  #include "ccid_serial.h"
136    
137  static _serialDevice serialDevice[PCSCLITE_MAX_READERS] = {  /* no need to initialize to 0 since it is static */
138          [ 0 ... (PCSCLITE_MAX_READERS-1) ] = { -1, -1 }  static _serialDevice serialDevice[CCID_DRIVER_MAX_READERS];
139  };  
140    /* unexported functions */
141    static int ReadChunk(unsigned int reader_index, unsigned char *buffer,
142            int buffer_length, int min_length);
143    
144    static int get_bytes(unsigned int reader_index, unsigned char *buffer,
145            int length);
146    
 /* 271 = max size for short APDU  
  * 2 bytes for header  
  * 1 byte checksum  
  * doubled for echo */  
 #define GEMPCTWIN_MAXBUF (271 +2 +1) *2  
147    
148  /*****************************************************************************  /*****************************************************************************
149   *   *
150   *                              WriteSerial: Send bytes to the card reader   *                              WriteSerial: Send bytes to the card reader
151   *   *
152   *****************************************************************************/   *****************************************************************************/
153  status_t WriteSerial(int lun, int length, unsigned char *buffer)  status_t WriteSerial(unsigned int reader_index, unsigned int length,
154            unsigned char *buffer)
155  {  {
156          int i;          int i;
         int reader = LunToReaderIndex(lun);  
157          unsigned char lrc;          unsigned char lrc;
158          unsigned char low_level_buffer[GEMPCTWIN_MAXBUF];          unsigned char low_level_buffer[GEMPCTWIN_MAXBUF];
159    
160  #ifdef DEBUG_LEVEL_COMM  #ifdef DEBUG_LEVEL_COMM
161          char debug_header[] = "-> 121234 ";          char debug_header[] = "-> 123456 ";
162    
163          sprintf(debug_header, "-> %06X ", (int)lun);          sprintf(debug_header, "-> %06X ", reader_index);
164  #endif  #endif
165    
166          if (length > GEMPCTWIN_MAXBUF-3)          if (length > GEMPCTWIN_MAXBUF-3)
167          {          {
168                  DEBUG_CRITICAL3("WriteSerial: command too long: %d for max %d",                  DEBUG_CRITICAL3("command too long: %d for max %d",
169                          length, GEMPCTWIN_MAXBUF-3);                          length, GEMPCTWIN_MAXBUF-3);
170                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
171          }          }
# Line 155  status_t WriteSerial(int lun, int length Line 187  status_t WriteSerial(int lun, int length
187          DEBUG_XXD(debug_header, low_level_buffer, length+3);          DEBUG_XXD(debug_header, low_level_buffer, length+3);
188  #endif  #endif
189    
190          if (write(serialDevice[reader].fd, low_level_buffer, length+3) != length+3)          if (write(serialDevice[reader_index].fd, low_level_buffer,
191                    length+3) != length+3)
192          {          {
193                  DEBUG_CRITICAL2("WriteSerial: write error: %s", strerror(errno));                  DEBUG_CRITICAL2("write error: %s", strerror(errno));
194                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
195          }          }
196    
# Line 170  status_t WriteSerial(int lun, int length Line 203  status_t WriteSerial(int lun, int length
203   *                              ReadSerial: Receive bytes from the card reader   *                              ReadSerial: Receive bytes from the card reader
204   *   *
205   *****************************************************************************/   *****************************************************************************/
206  status_t ReadSerial(int lun, int *length, unsigned char *buffer)  status_t ReadSerial(unsigned int reader_index,
207            /*@unused@*/ unsigned int *length, unsigned char *buffer)
208  {  {
209          int fd = serialDevice[LunToReaderIndex(lun)].fd;          unsigned char c;
210          static unsigned char low_level_buffer[GEMPCTWIN_MAXBUF];          int rv;
211          int buffer_size, len, rv, already_read, to_read;          int echo;
212          unsigned char *reader_to_pc;          int to_read;
213          unsigned char lrc;          int i;
         int skipped, i;  
 #ifdef DEBUG_LEVEL_COMM  
         char debug_header[] = "<- 121234 ";  
   
         sprintf(debug_header, "<- %06X ", (int)lun);  
 #endif  
   
         buffer_size = *length;  
214    
215          /* error by default (zero length) */          /* we get the echo first */
216          *length = 0;          echo = TRUE;
217    
218          rv = ReadChunk(fd, low_level_buffer, sizeof(low_level_buffer), 3, lun);  start:
219          if (rv < 0)          DEBUG_COMM("start");
220                  return STATUS_UNSUCCESSFUL;          if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
221                    return rv;
222    
223          /* Nb of bytes already read */          if (c == RDR_to_PC_NotifySlotChange)
224          already_read = rv;                  goto slot_change;
225    
226  #ifdef DEBUG_LEVEL_COMM          if (c == SYNC)
227          DEBUG_XXD(debug_header, low_level_buffer, rv);                  goto sync;
 #endif  
228    
229          /* skip the echo of the previous command */          if (c >= 0x80)
230          skipped = skip_echo(low_level_buffer, sizeof(low_level_buffer));          {
231          if (skipped == 0)                  DEBUG_COMM2("time request: 0x%02X", c);
232                  return STATUS_UNSUCCESSFUL;                  goto start;
233            }
234    
235          /* Nb of bytes until the end of the buffer */          DEBUG_CRITICAL2("Got 0x%02X", c);
236          len = sizeof(low_level_buffer) - skipped;          return STATUS_COMM_ERROR;
         already_read -= skipped;  
         reader_to_pc = low_level_buffer + skipped;  
237    
238          to_read = 2 +1; /* minimal frame size */  slot_change:
239            DEBUG_COMM("slot change");
240            if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
241                    return rv;
242    
243          while (already_read < to_read)          if (c == CARD_ABSENT)
244          {          {
245                  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;  
246          }          }
247            else
248                    if (c == CARD_PRESENT)
249                    {
250                            DEBUG_COMM("Card inserted");
251                    }
252                    else
253                    {
254                            DEBUG_COMM2("Unknown card movement: %d", c);
255                    }
256            goto start;
257    
258          if (reader_to_pc[0] != SYNC)  sync:
259          {          DEBUG_COMM("sync");
260                  DEBUG_CRITICAL2("No SYNC byte found: 0x%02X", buffer[0]);          if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
261                  return STATUS_UNSUCCESSFUL;                  return rv;
         }  
262    
263          if (reader_to_pc[1] != CTRL_ACK)          if (c == CTRL_ACK)
264          {                  goto ack;
                 DEBUG_CRITICAL2("No ACK byte found: 0x%02X", buffer[0]);  
                 return 0;  
         }  
265    
266          /* read up to CCID frame length */          if (c == CTRL_NAK)
267          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;  
268    
269                  already_read += rv;          DEBUG_CRITICAL2("Got 0x%02X instead of ACK/NAK", c);
270                  len -= rv;          return STATUS_COMM_ERROR;
         }  
271    
272          /* normal CCID command */  nak:
273          to_read = 10+3+dw2i(reader_to_pc, 3);          DEBUG_COMM("nak");
274            if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
275                    return rv;
276    
277          while (already_read < to_read)          if (c != (SYNC ^ CTRL_NAK))
278          {          {
279                  rv = ReadChunk(fd, reader_to_pc + already_read, len, 1, lun);                  DEBUG_CRITICAL2("Wrong LRC: 0x%02X", c);
280                  if (rv < 0)                  return STATUS_COMM_ERROR;
                         return STATUS_UNSUCCESSFUL;  
   
                 already_read += rv;  
                 len -= rv;  
281          }          }
282            else
283                    goto start;
284    
285          lrc = 0;  ack:
286          for (i=0; i<to_read; i++)          DEBUG_COMM("ack");
287                  lrc ^= reader_to_pc[i];          /* normal CCID frame */
288            if ((rv = get_bytes(reader_index, buffer, 5)) != STATUS_SUCCESS)
289          if (lrc != 0)                  return rv;
290                  DEBUG_CRITICAL2("Wrong lrc: 0x%02X", lrc);  
291            /* total frame size */
292            to_read = 10+dw2i(buffer, 1);
293    
294            DEBUG_COMM2("frame size: %d", to_read);
295            if ((rv = get_bytes(reader_index, buffer+5, to_read-5)) != STATUS_SUCCESS)
296                    return rv;
297    
298  #ifdef DEBUG_LEVEL_COMM  #ifdef DEBUG_LEVEL_COMM
299          DEBUG_XXD(debug_header, reader_to_pc, to_read);                  DEBUG_XXD("frame: ", buffer, to_read);
300  #endif  #endif
301    
302          /* copy up to buffer_size bytes */          /* lrc */
303          *length = to_read-3;          DEBUG_COMM("lrc");
304            if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
305                    return rv;
306    
307            DEBUG_COMM2("lrc: 0x%02X", c);
308            for (i=0; i<to_read; i++)
309                    c ^= buffer[i];
310    
311          memcpy(buffer, reader_to_pc+2, *length);          if (c != (SYNC ^ CTRL_ACK))
312                    DEBUG_CRITICAL2("Wrong LRC: 0x%02X", c);
313    
314            if (echo)
315            {
316                    echo = FALSE;
317                    goto start;
318            }
319    
320          return STATUS_SUCCESS;          return STATUS_SUCCESS;
321  } /* ReadSerial */  } /* ReadSerial */
# Line 281  status_t ReadSerial(int lun, int *length Line 323  status_t ReadSerial(int lun, int *length
323    
324  /*****************************************************************************  /*****************************************************************************
325   *   *
326   *                              skip_echo: skip the echo of the previous command   *                              get_bytes: get n bytes
327   *   *
328   *****************************************************************************/   *****************************************************************************/
329  int skip_echo(unsigned char *buffer, int buffer_length)  int get_bytes(unsigned int reader_index, unsigned char *buffer, int length)
330  {  {
331          unsigned char lrc;          int offset = serialDevice[reader_index].buffer_offset;
332          int i;          int offset_last = serialDevice[reader_index].buffer_offset_last;
333    
334          if (buffer[0] != SYNC)          DEBUG_COMM3("available: %d, needed: %d", offset_last-offset,
335          {                  length);
336                  DEBUG_CRITICAL2("No SYNC byte found: 0x%02X", buffer[0]);          /* enough data are available */
337                  return 0;          if (offset + length <= offset_last)
338            {
339                    DEBUG_COMM("data available");
340                    memcpy(buffer, serialDevice[reader_index].buffer + offset, length);
341                    serialDevice[reader_index].buffer_offset += length;
342          }          }
343            else
         if (buffer[1] != CTRL_ACK)  
344          {          {
345                  DEBUG_CRITICAL2("No ACK byte found: 0x%02X", buffer[0]);                  int present, rv;
                 return 0;  
         }  
346    
347          if (buffer[2] == RDR_to_PC_NotifySlotChange)                  /* copy available data */
348          {                  present = offset_last - offset;
349                  switch (buffer[3])  
350                    if (present > 0)
351                  {                  {
352                          case CARD_PRESENT:                          DEBUG_COMM2("some data available: %d", present);
353                                  DEBUG_INFO("Card inserted");                          memcpy(buffer, serialDevice[reader_index].buffer + offset,
354                                  break;                                  present);
   
                         case CARD_ABSENT:  
                                 DEBUG_INFO("Card removed");  
                                 break;  
   
                         default:  
                                 DEBUG_INFO2("Unknown card movement: %d", buffer[3]);  
                                 break;  
355                  }                  }
   
                 lrc = 0;  
                 for (i=0; i<5; i++)  
                         lrc ^= buffer[i];  
356    
357                  if (lrc != 0)                  /* get fresh data */
358                          DEBUG_CRITICAL2("Wrong lrc: 0x%02", lrc);                  DEBUG_COMM2("get more data: %d", length - present);
359                    rv = ReadChunk(reader_index, serialDevice[reader_index].buffer,
360                            sizeof(serialDevice[reader_index].buffer), length - present);
361                    if (rv < 0)
362                            return STATUS_COMM_ERROR;
363    
364                  /* Card insertion/withdrawal */                  /* fill the buffer */
365                  return 5;                  memcpy(buffer + present, serialDevice[reader_index].buffer,
366                            length - present);
367                    serialDevice[reader_index].buffer_offset = length - present;
368                    serialDevice[reader_index].buffer_offset_last = rv;
369                    DEBUG_COMM3("offset: %d, last_offset: %d",
370                            serialDevice[reader_index].buffer_offset,
371                            serialDevice[reader_index].buffer_offset_last);
372          }          }
373    
374          /* normal CCID command, 2 for SYNC CTRL, 1 for length offset in CCID cmd */          return STATUS_SUCCESS;
375          return 2 + 10 + dw2i(buffer, 2 +1) +1;  } /* get_bytes */
 } /* skip_echo */  
376    
377    
378  /*****************************************************************************  /*****************************************************************************
# Line 339  int skip_echo(unsigned char *buffer, int Line 380  int skip_echo(unsigned char *buffer, int
380   *                              ReadChunk: read a minimum number of bytes   *                              ReadChunk: read a minimum number of bytes
381   *   *
382   *****************************************************************************/   *****************************************************************************/
383  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,
384            int buffer_length, int min_length)
385  {  {
386            int fd = serialDevice[reader_index].fd;
387    # ifndef S_SPLINT_S
388          fd_set fdset;          fd_set fdset;
389    # endif
390          struct timeval t;          struct timeval t;
391          int i, rv;          int i, rv = 0;
392            int already_read;
393  #ifdef DEBUG_LEVEL_COMM  #ifdef DEBUG_LEVEL_COMM
394          char debug_header[] = "<- 121234 ";          char debug_header[] = "<- 123456 ";
395    
396          sprintf(debug_header, "<- %06X ", (int)lun);          sprintf(debug_header, "<- %06X ", reader_index);
397  #endif  #endif
398    
399  time_request:          already_read = 0;
400          /* 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)  
401          {          {
402                  DEBUG_CRITICAL2("select: %s", strerror(errno));                  /* use select() to, eventually, timeout */
403                  return -1;                  FD_ZERO(&fdset);
404          }                  FD_SET(fd, &fdset);
405          else                  t.tv_sec = SERIAL_TIMEOUT;
406                  if (i == 0)                  t.tv_usec = 0;
407    
408                    i = select(fd+1, &fdset, NULL, NULL, &t);
409                    if (i == -1)
410                  {                  {
411                          DEBUG_COMM2("Timeout! (%d sec)", SERIAL_TIMEOUT);                          DEBUG_CRITICAL2("select: %s", strerror(errno));
412                          return -1;                          return -1;
413                  }                  }
414                    else
415                            if (i == 0)
416                            {
417                                    DEBUG_COMM2("Timeout! (%d sec)", SERIAL_TIMEOUT);
418                                    return -1;
419                            }
420    
421          rv = read(fd, buffer, buffer_length);                  rv = read(fd, buffer + already_read, buffer_length - already_read);
422          if (rv < 0)                  if (rv < 0)
423          {                  {
424                  DEBUG_COMM2("read error: %s", strerror(errno));                          DEBUG_COMM2("read error: %s", strerror(errno));
425                  return -1;                          return -1;
426          }                  }
   
         if ((rv == 1) && (buffer[0] >= 0x80))  
         {  
                 DEBUG_COMM2("Time request: 0x%02X", buffer[0]);  
                 goto time_request;  
         }  
427    
         /* too short */  
         if (rv < min_length)  
         {  
428  #ifdef DEBUG_LEVEL_COMM  #ifdef DEBUG_LEVEL_COMM
429                  DEBUG_XXD(debug_header, buffer, rv);                  DEBUG_XXD(debug_header, buffer + already_read, rv);
430  #endif  #endif
                 DEBUG_COMM3("ReadSerial: only %d byte(s) read, needed %d", rv,  
                         min_length);  
431    
432                  return -1;                  already_read += rv;
433                    DEBUG_COMM3("read: %d, to read: %d", already_read,
434                            min_length);
435          }          }
436    
437          return rv;          return already_read;
438  } /* ReadChunk */  } /* ReadChunk */
439    
440    
# Line 404  time_request: Line 443  time_request:
443   *                              OpenSerial: open the port   *                              OpenSerial: open the port
444   *   *
445   *****************************************************************************/   *****************************************************************************/
446  status_t OpenSerial(int lun, int channel)  status_t OpenSerial(unsigned int reader_index, int channel)
447  {  {
448          char dev_name[FILENAME_MAX];          char dev_name[FILENAME_MAX];
         struct termios current_termios;  
         int i;  
         int reader = LunToReaderIndex(lun);  
449    
450          DEBUG_COMM3("OpenSerial: Lun: %X, Channel: %d", lun, channel);          DEBUG_COMM3("Reader index: %X, Channel: %d", reader_index, channel);
451    
452          /*          /*
453           * 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 472  status_t OpenSerial(int lun, int channel
472    
473          sprintf(dev_name, "/dev/pcsc/%d", (int) channel);          sprintf(dev_name, "/dev/pcsc/%d", (int) channel);
474    
475            return OpenSerialByName(reader_index, dev_name);
476    } /* OpenSerial */
477    
478    /*****************************************************************************
479     *
480     *                              OpenSerialByName: open the port
481     *
482     *****************************************************************************/
483    status_t OpenSerialByName(unsigned int reader_index, char *dev_name)
484    {
485            struct termios current_termios;
486            int i;
487            unsigned int reader = reader_index;
488    
489            DEBUG_COMM3("Reader index: %X, Device: %d", reader_index, dev_name);
490    
491          /* check if the same channel is not already used */          /* check if the same channel is not already used */
492          for (i=0; i<PCSCLITE_MAX_READERS; i++)          for (i=0; i<CCID_DRIVER_MAX_READERS; i++)
493          {          {
494                  if (serialDevice[i].channel == channel)                  if (serialDevice[i].device &&
495                            strcmp(serialDevice[i].device, dev_name) == 0)
496                  {                  {
497                          DEBUG_CRITICAL2("Channel %s already in use", dev_name);                          DEBUG_CRITICAL2("Device %s already in use", dev_name);
498                          return STATUS_UNSUCCESSFUL;                          return STATUS_UNSUCCESSFUL;
499                  }                  }
500          }          }
501    
502          serialDevice[reader].fd = open(dev_name, O_RDWR | O_NOCTTY);          serialDevice[reader].fd = open(dev_name, O_RDWR | O_NOCTTY);
503    
504          if (serialDevice[reader].fd <= 0)          if (-1 == serialDevice[reader].fd)
505          {          {
506                  DEBUG_CRITICAL3("open %s: %s", dev_name, strerror(errno));                  DEBUG_CRITICAL3("open %s: %s", dev_name, strerror(errno));
507                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
508          }          }
509    
510          /* set channel used */          /* set channel used */
511          serialDevice[reader].channel = channel;          serialDevice[reader].device = strdup(dev_name);
512    
513          /* empty in and out serial buffers */          /* empty in and out serial buffers */
514          if (tcflush(serialDevice[reader].fd, TCIOFLUSH))          if (tcflush(serialDevice[reader].fd, TCIOFLUSH))
# Line 501  status_t OpenSerial(int lun, int channel Line 554  status_t OpenSerial(int lun, int channel
554          serialDevice[reader].ccid.bSeq = 0;          serialDevice[reader].ccid.bSeq = 0;
555          serialDevice[reader].ccid.readerID = GEMPCTWIN;          serialDevice[reader].ccid.readerID = GEMPCTWIN;
556          serialDevice[reader].ccid.dwMaxCCIDMessageLength = 271;          serialDevice[reader].ccid.dwMaxCCIDMessageLength = 271;
557            serialDevice[reader].ccid.dwMaxIFSD = 254;
558          serialDevice[reader].ccid.dwFeatures = 0x00010230;          serialDevice[reader].ccid.dwFeatures = 0x00010230;
559            serialDevice[reader].ccid.bPINSupport = 0x0;
560            serialDevice[reader].ccid.dwDefaultClock = 4000;
561            serialDevice[reader].ccid.dwMaxDataRate = 344086;
562            serialDevice[reader].ccid.bMaxSlotIndex = 0;
563            serialDevice[reader].ccid.bCurrentSlotIndex = 0;
564    
565            serialDevice[reader].buffer_offset = 0;
566            serialDevice[reader].buffer_offset_last = 0;
567    
568            /* perform a command to be sure a GemPC Twin reader is connected
569             * get the reader firmware */
570            {
571                    unsigned char tx_buffer[] = "\x02";
572                    unsigned char rx_buffer[50];
573                    unsigned int rx_length = sizeof(rx_buffer);
574    
575                    if (IFD_SUCCESS != CmdEscape(reader_index, tx_buffer, sizeof(tx_buffer),
576                            rx_buffer, &rx_length))
577                    {
578                            DEBUG_CRITICAL("Get firmware failed. Maybe the reader is not co,,ected");
579                            return STATUS_UNSUCCESSFUL;
580                    }
581    
582          ccid_open_hack(lun);                  rx_buffer[rx_length] = '\0';
583                    DEBUG_INFO2("Firmware: %s", rx_buffer);
584            }
585    
586          return STATUS_SUCCESS;          return STATUS_SUCCESS;
587  } /* OpenSerial */  } /* OpenSerialByName */
588    
589    
590  /*****************************************************************************  /*****************************************************************************
# Line 514  status_t OpenSerial(int lun, int channel Line 592  status_t OpenSerial(int lun, int channel
592   *                              CloseSerial: close the port   *                              CloseSerial: close the port
593   *   *
594   *****************************************************************************/   *****************************************************************************/
595  status_t CloseSerial(int lun)  status_t CloseSerial(unsigned int reader_index)
596  {  {
597          int reader = LunToReaderIndex(lun);          unsigned int reader = reader_index;
598    
599          close(serialDevice[reader].fd);          close(serialDevice[reader].fd);
   
600          serialDevice[reader].fd = -1;          serialDevice[reader].fd = -1;
601          serialDevice[reader].channel = -1;  
602            free(serialDevice[reader].device);
603            serialDevice[reader].device = NULL;
604    
605          return STATUS_SUCCESS;          return STATUS_SUCCESS;
606  } /* CloseSerial */  } /* CloseSerial */
# Line 532  status_t CloseSerial(int lun) Line 611  status_t CloseSerial(int lun)
611   *                                      get_ccid_descriptor   *                                      get_ccid_descriptor
612   *   *
613   ****************************************************************************/   ****************************************************************************/
614  _ccid_descriptor *get_ccid_descriptor(int lun)  _ccid_descriptor *get_ccid_descriptor(unsigned int reader_index)
615  {  {
616          return &serialDevice[LunToReaderIndex(lun)].ccid;          return &serialDevice[reader_index].ccid;
617  } /* get_ccid_descriptor */  } /* get_ccid_descriptor */
618    
619    

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

  ViewVC Help
Powered by ViewVC 1.1.5