/[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 877 by rousseau, Mon May 17 14:35:51 2004 UTC revision 1447 by rousseau, Tue Apr 26 13:44:08 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 <PCSC/ifdhandler.h>
36    
37  #include "defs.h"  #include "defs.h"
38  #include "ccid_ifdhandler.h"  #include "ccid_ifdhandler.h"
# Line 39  Line 40 
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 2   * the value is set at the end of OpenSerialByName() */
47    int SerialTimeout;
48    
49  #define SYNC 0x03  #define SYNC 0x03
50  #define CTRL_ACK 0x06  #define CTRL_ACK 0x06
# Line 105  typedef struct Line 108  typedef struct
108          /*          /*
109           * device used ("/dev/ttyS?" under Linux)           * device used ("/dev/ttyS?" under Linux)
110           */           */
111          char *device;          /*@null@*/ char *device;
112    
113          /*          /*
114           * serial communication buffer           * serial communication buffer
# Line 132  typedef struct Line 135  typedef struct
135  /* The _serialDevice structure must be defined before including ccid_serial.h */  /* The _serialDevice structure must be defined before including ccid_serial.h */
136  #include "ccid_serial.h"  #include "ccid_serial.h"
137    
138  static _serialDevice serialDevice[PCSCLITE_MAX_READERS] = {  int SerialDataRates[] = {
139          [ 0 ... (PCSCLITE_MAX_READERS-1) ] = { -1, NULL }                  10753,
140  };                  14337,
141                    15625,
142                    17204,
143                    20833,
144                    21505,
145                    23438,
146                    25806,
147                    28674,
148                    31250,
149                    32258,
150                    34409,
151                    39063,
152                    41667,
153                    43011,
154                    46875,
155                    52083,
156                    53763,
157                    57348,
158                    62500,
159                    64516,
160                    68817,
161                    71685,
162                    78125,
163                    83333,
164                    86022,
165                    93750,
166                    104667,
167                    107527,
168                    114695,
169                    125000,
170                    129032,
171                    143369,
172                    156250,
173                    166667,
174                    172043,
175                    215054,
176                    229391,
177                    250000,
178                    344086,
179                    0
180            };
181    
182    /* no need to initialize to 0 since it is static */
183    static _serialDevice serialDevice[CCID_DRIVER_MAX_READERS];
184    
185    /* unexported functions */
186    static int ReadChunk(unsigned int reader_index, unsigned char *buffer,
187            int buffer_length, int min_length);
188    
189    static int get_bytes(unsigned int reader_index, unsigned char *buffer,
190            int length);
191    
192    
193  /*****************************************************************************  /*****************************************************************************
194   *   *
195   *                              WriteSerial: Send bytes to the card reader   *                              WriteSerial: Send bytes to the card reader
196   *   *
197   *****************************************************************************/   *****************************************************************************/
198  status_t WriteSerial(int lun, int length, unsigned char *buffer)  status_t WriteSerial(unsigned int reader_index, unsigned int length,
199            unsigned char *buffer)
200  {  {
201          int i;          int i;
202          unsigned char lrc;          unsigned char lrc;
203          unsigned char low_level_buffer[GEMPCTWIN_MAXBUF];          unsigned char low_level_buffer[GEMPCTWIN_MAXBUF];
204    
205  #ifdef DEBUG_LEVEL_COMM  #ifdef DEBUG_LEVEL_COMM
206          char debug_header[] = "-> 121234 ";          char debug_header[] = "-> 123456 ";
207    
208          sprintf(debug_header, "-> %06X ", (int)lun);          sprintf(debug_header, "-> %06X ", reader_index);
209  #endif  #endif
210    
211          if (length > GEMPCTWIN_MAXBUF-3)          if (length > GEMPCTWIN_MAXBUF-3)
# Line 177  status_t WriteSerial(int lun, int length Line 232  status_t WriteSerial(int lun, int length
232          DEBUG_XXD(debug_header, low_level_buffer, length+3);          DEBUG_XXD(debug_header, low_level_buffer, length+3);
233  #endif  #endif
234    
235          if (write(serialDevice[LunToReaderIndex(lun)].fd, low_level_buffer,          if (write(serialDevice[reader_index].fd, low_level_buffer,
236                  length+3) != length+3)                  length+3) != length+3)
237          {          {
238                  DEBUG_CRITICAL2("write error: %s", strerror(errno));                  DEBUG_CRITICAL2("write error: %s", strerror(errno));
# Line 193  status_t WriteSerial(int lun, int length Line 248  status_t WriteSerial(int lun, int length
248   *                              ReadSerial: Receive bytes from the card reader   *                              ReadSerial: Receive bytes from the card reader
249   *   *
250   *****************************************************************************/   *****************************************************************************/
251  status_t ReadSerial(int lun, int *length, unsigned char *buffer)  status_t ReadSerial(unsigned int reader_index,
252            /*@unused@*/ unsigned int *length, unsigned char *buffer)
253  {  {
254          unsigned char c;          unsigned char c;
255          int rv;          int rv;
# Line 206  status_t ReadSerial(int lun, int *length Line 262  status_t ReadSerial(int lun, int *length
262    
263  start:  start:
264          DEBUG_COMM("start");          DEBUG_COMM("start");
265          if ((rv = get_bytes(lun, &c, 1)) != STATUS_SUCCESS)          if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
266                  return rv;                  return rv;
267    
268          if (c == RDR_to_PC_NotifySlotChange)          if (c == RDR_to_PC_NotifySlotChange)
# Line 226  start: Line 282  start:
282    
283  slot_change:  slot_change:
284          DEBUG_COMM("slot change");          DEBUG_COMM("slot change");
285          if ((rv = get_bytes(lun, &c, 1)) != STATUS_SUCCESS)          if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
286                  return rv;                  return rv;
287    
288          if (c == CARD_ABSENT)          if (c == CARD_ABSENT)
# Line 240  slot_change: Line 296  slot_change:
296                  }                  }
297                  else                  else
298                  {                  {
299                          DEBUG_COMM2("Unknown card movement: %d", buffer[3]);                          DEBUG_COMM2("Unknown card movement: %d", c);
300                  }                  }
301          goto start;          goto start;
302    
303  sync:  sync:
304          DEBUG_COMM("sync");          DEBUG_COMM("sync");
305          if ((rv = get_bytes(lun, &c, 1)) != STATUS_SUCCESS)          if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
306                  return rv;                  return rv;
307    
308          if (c == CTRL_ACK)          if (c == CTRL_ACK)
# Line 260  sync: Line 316  sync:
316    
317  nak:  nak:
318          DEBUG_COMM("nak");          DEBUG_COMM("nak");
319          if ((rv = get_bytes(lun, &c, 1)) != STATUS_SUCCESS)          if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
320                  return rv;                  return rv;
321    
322          if (c != (SYNC ^ CTRL_NAK))          if (c != (SYNC ^ CTRL_NAK))
# Line 274  nak: Line 330  nak:
330  ack:  ack:
331          DEBUG_COMM("ack");          DEBUG_COMM("ack");
332          /* normal CCID frame */          /* normal CCID frame */
333          if ((rv = get_bytes(lun, buffer, 5)) != STATUS_SUCCESS)          if ((rv = get_bytes(reader_index, buffer, 5)) != STATUS_SUCCESS)
334                  return rv;                  return rv;
335    
336          /* total frame size */          /* total frame size */
337          to_read = 10+dw2i(buffer, 1);          to_read = 10+dw2i(buffer, 1);
338    
339          DEBUG_COMM2("frame size: %d", to_read);          DEBUG_COMM2("frame size: %d", to_read);
340          if ((rv = get_bytes(lun, buffer+5, to_read-5)) != STATUS_SUCCESS)          if ((rv = get_bytes(reader_index, buffer+5, to_read-5)) != STATUS_SUCCESS)
341                  return rv;                  return rv;
342    
343  #ifdef DEBUG_LEVEL_COMM  #ifdef DEBUG_LEVEL_COMM
# Line 290  ack: Line 346  ack:
346    
347          /* lrc */          /* lrc */
348          DEBUG_COMM("lrc");          DEBUG_COMM("lrc");
349          if ((rv = get_bytes(lun, &c, 1)) != STATUS_SUCCESS)          if ((rv = get_bytes(reader_index, &c, 1)) != STATUS_SUCCESS)
350                  return rv;                  return rv;
351    
352          DEBUG_COMM2("lrc: 0x%02X", c);          DEBUG_COMM2("lrc: 0x%02X", c);
# Line 298  ack: Line 354  ack:
354                  c ^= buffer[i];                  c ^= buffer[i];
355    
356          if (c != (SYNC ^ CTRL_ACK))          if (c != (SYNC ^ CTRL_ACK))
         {  
357                  DEBUG_CRITICAL2("Wrong LRC: 0x%02X", c);                  DEBUG_CRITICAL2("Wrong LRC: 0x%02X", c);
                 //return STATUS_COMM_ERROR;  
         }  
358    
359          if (echo)          if (echo)
360          {          {
# Line 318  ack: Line 371  ack:
371   *                              get_bytes: get n bytes   *                              get_bytes: get n bytes
372   *   *
373   *****************************************************************************/   *****************************************************************************/
374  int get_bytes(int lun, unsigned char *buffer, int length)  int get_bytes(unsigned int reader_index, unsigned char *buffer, int length)
375  {  {
376          int offset = serialDevice[LunToReaderIndex(lun)].buffer_offset;          int offset = serialDevice[reader_index].buffer_offset;
377          int offset_last = serialDevice[LunToReaderIndex(lun)].buffer_offset_last;          int offset_last = serialDevice[reader_index].buffer_offset_last;
378    
379          DEBUG_COMM3("available: %d, needed: %d", offset_last-offset,          DEBUG_COMM3("available: %d, needed: %d", offset_last-offset,
380                  length);                  length);
# Line 329  int get_bytes(int lun, unsigned char *bu Line 382  int get_bytes(int lun, unsigned char *bu
382          if (offset + length <= offset_last)          if (offset + length <= offset_last)
383          {          {
384                  DEBUG_COMM("data available");                  DEBUG_COMM("data available");
385                  memcpy(buffer, serialDevice[LunToReaderIndex(lun)].buffer + offset, length);                  memcpy(buffer, serialDevice[reader_index].buffer + offset, length);
386                  serialDevice[LunToReaderIndex(lun)].buffer_offset += length;                  serialDevice[reader_index].buffer_offset += length;
387          }          }
388          else          else
389          {          {
# Line 342  int get_bytes(int lun, unsigned char *bu Line 395  int get_bytes(int lun, unsigned char *bu
395                  if (present > 0)                  if (present > 0)
396                  {                  {
397                          DEBUG_COMM2("some data available: %d", present);                          DEBUG_COMM2("some data available: %d", present);
398                          memcpy(buffer, serialDevice[LunToReaderIndex(lun)].buffer + offset,                          memcpy(buffer, serialDevice[reader_index].buffer + offset,
399                                  present);                                  present);
400                  }                  }
401    
402                  /* get fresh data */                  /* get fresh data */
403                  DEBUG_COMM2("get more data: %d", length - present);                  DEBUG_COMM2("get more data: %d", length - present);
404                  rv = ReadChunk(lun, serialDevice[LunToReaderIndex(lun)].buffer, sizeof(serialDevice[LunToReaderIndex(lun)].buffer), length - present);                  rv = ReadChunk(reader_index, serialDevice[reader_index].buffer,
405                            sizeof(serialDevice[reader_index].buffer), length - present);
406                  if (rv < 0)                  if (rv < 0)
407                          return STATUS_COMM_ERROR;                          return STATUS_COMM_ERROR;
408    
409                  /* fill the buffer */                  /* fill the buffer */
410                  memcpy(buffer + present, serialDevice[LunToReaderIndex(lun)].buffer,                  memcpy(buffer + present, serialDevice[reader_index].buffer,
411                          length - present);                          length - present);
412                  serialDevice[LunToReaderIndex(lun)].buffer_offset = length - present;                  serialDevice[reader_index].buffer_offset = length - present;
413                  serialDevice[LunToReaderIndex(lun)].buffer_offset_last = rv;                  serialDevice[reader_index].buffer_offset_last = rv;
414                  DEBUG_COMM3("offset: %d, last_offset: %d",                  DEBUG_COMM3("offset: %d, last_offset: %d",
415                          serialDevice[LunToReaderIndex(lun)].buffer_offset,                          serialDevice[reader_index].buffer_offset,
416                          serialDevice[LunToReaderIndex(lun)].buffer_offset_last);                          serialDevice[reader_index].buffer_offset_last);
417          }          }
418    
419          return STATUS_SUCCESS;          return STATUS_SUCCESS;
# Line 371  int get_bytes(int lun, unsigned char *bu Line 425  int get_bytes(int lun, unsigned char *bu
425   *                              ReadChunk: read a minimum number of bytes   *                              ReadChunk: read a minimum number of bytes
426   *   *
427   *****************************************************************************/   *****************************************************************************/
428  int ReadChunk(int lun, unsigned char *buffer, int buffer_length, int min_length)  static int ReadChunk(unsigned int reader_index, unsigned char *buffer,
429            int buffer_length, int min_length)
430  {  {
431          int fd = serialDevice[LunToReaderIndex(lun)].fd;          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 = 0;          int i, rv = 0;
437          int already_read;          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          already_read = 0;          already_read = 0;
# Line 390  int ReadChunk(int lun, unsigned char *bu Line 447  int ReadChunk(int lun, unsigned char *bu
447                  /* use select() to, eventually, timeout */                  /* use select() to, eventually, timeout */
448                  FD_ZERO(&fdset);                  FD_ZERO(&fdset);
449                  FD_SET(fd, &fdset);                  FD_SET(fd, &fdset);
450                  t.tv_sec = SERIAL_TIMEOUT;                  t.tv_sec = SerialTimeout;
451                  t.tv_usec = 0;                  t.tv_usec = 0;
452    
453                  i = select(fd+1, &fdset, NULL, NULL, &t);                  i = select(fd+1, &fdset, NULL, NULL, &t);
# Line 402  int ReadChunk(int lun, unsigned char *bu Line 459  int ReadChunk(int lun, unsigned char *bu
459                  else                  else
460                          if (i == 0)                          if (i == 0)
461                          {                          {
462                                  DEBUG_COMM2("Timeout! (%d sec)", SERIAL_TIMEOUT);                                  DEBUG_COMM2("Timeout! (%d sec)", SerialTimeout);
463                                  return -1;                                  return -1;
464                          }                          }
465    
# Line 431  int ReadChunk(int lun, unsigned char *bu Line 488  int ReadChunk(int lun, unsigned char *bu
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];
494    
495          DEBUG_COMM3("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 460  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(lun, dev_name);          return OpenSerialByName(reader_index, dev_name);
521  } /* OpenSerial */  } /* OpenSerial */
522    
523  /*****************************************************************************  /*****************************************************************************
# Line 468  status_t OpenSerial(int lun, int channel Line 525  status_t OpenSerial(int lun, int channel
525   *                              OpenSerialByName: open the port   *                              OpenSerialByName: open the port
526   *   *
527   *****************************************************************************/   *****************************************************************************/
528  status_t OpenSerialByName(int lun, char *dev_name)  status_t OpenSerialByName(unsigned int reader_index, char *dev_name)
529  {  {
530          struct termios current_termios;          struct termios current_termios;
531          int i;          int i;
532          int reader = LunToReaderIndex(lun);          unsigned int reader = reader_index;
533    
534          DEBUG_COMM3("Lun: %X, Device: %d", lun, dev_name);          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].device &&                  if (serialDevice[i].device &&
540                          strcmp(serialDevice[i].device, dev_name) == 0)                          strcmp(serialDevice[i].device, dev_name) == 0)
# Line 489  status_t OpenSerialByName(int lun, char Line 546  status_t OpenSerialByName(int lun, char
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;
# Line 539  status_t OpenSerialByName(int lun, char Line 596  status_t OpenSerialByName(int lun, char
596                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
597          }          }
598    
599          serialDevice[reader].ccid.bSeq = 0;          serialDevice[reader].ccid.real_bSeq = 0;
600            serialDevice[reader].ccid.pbSeq = &serialDevice[reader].ccid.real_bSeq;
601          serialDevice[reader].ccid.readerID = GEMPCTWIN;          serialDevice[reader].ccid.readerID = GEMPCTWIN;
602          serialDevice[reader].ccid.dwMaxCCIDMessageLength = 271;          serialDevice[reader].ccid.dwMaxCCIDMessageLength = 271;
603          serialDevice[reader].ccid.dwMaxIFSD = 254;          serialDevice[reader].ccid.dwMaxIFSD = 254;
604          serialDevice[reader].ccid.dwFeatures = 0x00010230;          serialDevice[reader].ccid.dwFeatures = 0x00010230;
605            serialDevice[reader].ccid.bPINSupport = 0x0;
606          serialDevice[reader].ccid.dwDefaultClock = 4000;          serialDevice[reader].ccid.dwDefaultClock = 4000;
607          serialDevice[reader].ccid.dwMaxDataRate = 344086;          serialDevice[reader].ccid.dwMaxDataRate = 344086;
608            serialDevice[reader].ccid.bMaxSlotIndex = 0;
609            serialDevice[reader].ccid.bCurrentSlotIndex = 0;
610            serialDevice[reader].ccid.arrayOfSupportedDataRates = SerialDataRates;
611    
612          serialDevice[reader].buffer_offset = 0;          serialDevice[reader].buffer_offset = 0;
613          serialDevice[reader].buffer_offset_last = 0;          serialDevice[reader].buffer_offset_last = 0;
614    
615            /* perform a command to be sure a GemPC Twin reader is connected
616             * get the reader firmware */
617            {
618                    unsigned char tx_buffer[] = { 0x02 };
619                    unsigned char rx_buffer[50];
620                    unsigned int rx_length = sizeof(rx_buffer);
621    
622                    /* 2 seconds timeout to not wait too long if no reader is connected */
623                    SerialTimeout = 2;
624    
625                    if (IFD_SUCCESS != CmdEscape(reader_index, tx_buffer, sizeof(tx_buffer),
626                            rx_buffer, &rx_length))
627                    {
628                            DEBUG_CRITICAL("Get firmware failed. Maybe the reader is not connected");
629                            return STATUS_UNSUCCESSFUL;
630                    }
631    
632                    /* normal timeout: 1 minute to allow long time APDU */
633                    SerialTimeout = 60;
634    
635                    rx_buffer[rx_length] = '\0';
636                    DEBUG_INFO2("Firmware: %s", rx_buffer);
637            }
638    
639            /* perform a command to configure GemPC Twin reader card movement
640             * notification to synchronous mode: the card movement is notified _after_
641             * the host command and _before_ the reader anwser */
642            {
643                    unsigned char tx_buffer[] = { 0x01, 0x01, 0x01};
644                    unsigned char rx_buffer[50];
645                    unsigned int rx_length = sizeof(rx_buffer);
646    
647                    if (IFD_SUCCESS != CmdEscape(reader_index, tx_buffer, sizeof(tx_buffer),
648                            rx_buffer, &rx_length))
649                    {
650                            DEBUG_CRITICAL("Change card movement notification failed.");
651                            return STATUS_UNSUCCESSFUL;
652                    }
653            }
654    
655          return STATUS_SUCCESS;          return STATUS_SUCCESS;
656  } /* OpenSerialByName */  } /* OpenSerialByName */
657    
# Line 559  status_t OpenSerialByName(int lun, char Line 661  status_t OpenSerialByName(int lun, char
661   *                              CloseSerial: close the port   *                              CloseSerial: close the port
662   *   *
663   *****************************************************************************/   *****************************************************************************/
664  status_t CloseSerial(int lun)  status_t CloseSerial(unsigned int reader_index)
665  {  {
666          int reader = LunToReaderIndex(lun);          unsigned int reader = reader_index;
667    
668          close(serialDevice[reader].fd);          close(serialDevice[reader].fd);
669          serialDevice[reader].fd = -1;          serialDevice[reader].fd = -1;
# Line 578  status_t CloseSerial(int lun) Line 680  status_t CloseSerial(int lun)
680   *                                      get_ccid_descriptor   *                                      get_ccid_descriptor
681   *   *
682   ****************************************************************************/   ****************************************************************************/
683  _ccid_descriptor *get_ccid_descriptor(int lun)  _ccid_descriptor *get_ccid_descriptor(unsigned int reader_index)
684  {  {
685          return &serialDevice[LunToReaderIndex(lun)].ccid;          return &serialDevice[reader_index].ccid;
686  } /* get_ccid_descriptor */  } /* get_ccid_descriptor */
687    
688    

Legend:
Removed from v.877  
changed lines
  Added in v.1447

  ViewVC Help
Powered by ViewVC 1.1.5