| 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 |
* |
* |
| 42 |
#include "utils.h" |
#include "utils.h" |
| 43 |
#include "commands.h" |
#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 |
| 403 |
/* use select() to, eventually, timeout */ |
/* use select() to, eventually, timeout */ |
| 404 |
FD_ZERO(&fdset); |
FD_ZERO(&fdset); |
| 405 |
FD_SET(fd, &fdset); |
FD_SET(fd, &fdset); |
| 406 |
t.tv_sec = SERIAL_TIMEOUT; |
t.tv_sec = SerialTimeout; |
| 407 |
t.tv_usec = 0; |
t.tv_usec = 0; |
| 408 |
|
|
| 409 |
i = select(fd+1, &fdset, NULL, NULL, &t); |
i = select(fd+1, &fdset, NULL, NULL, &t); |
| 415 |
else |
else |
| 416 |
if (i == 0) |
if (i == 0) |
| 417 |
{ |
{ |
| 418 |
DEBUG_COMM2("Timeout! (%d sec)", SERIAL_TIMEOUT); |
DEBUG_COMM2("Timeout! (%d sec)", SerialTimeout); |
| 419 |
return -1; |
return -1; |
| 420 |
} |
} |
| 421 |
|
|
| 552 |
return STATUS_UNSUCCESSFUL; |
return STATUS_UNSUCCESSFUL; |
| 553 |
} |
} |
| 554 |
|
|
| 555 |
serialDevice[reader].ccid.bSeq = 0; |
serialDevice[reader].ccid.real_bSeq = 0; |
| 556 |
|
serialDevice[reader].ccid.pbSeq = &serialDevice[reader].ccid.real_bSeq; |
| 557 |
serialDevice[reader].ccid.readerID = GEMPCTWIN; |
serialDevice[reader].ccid.readerID = GEMPCTWIN; |
| 558 |
serialDevice[reader].ccid.dwMaxCCIDMessageLength = 271; |
serialDevice[reader].ccid.dwMaxCCIDMessageLength = 271; |
| 559 |
serialDevice[reader].ccid.dwMaxIFSD = 254; |
serialDevice[reader].ccid.dwMaxIFSD = 254; |
| 563 |
serialDevice[reader].ccid.dwMaxDataRate = 344086; |
serialDevice[reader].ccid.dwMaxDataRate = 344086; |
| 564 |
serialDevice[reader].ccid.bMaxSlotIndex = 0; |
serialDevice[reader].ccid.bMaxSlotIndex = 0; |
| 565 |
serialDevice[reader].ccid.bCurrentSlotIndex = 0; |
serialDevice[reader].ccid.bCurrentSlotIndex = 0; |
|
serialDevice[reader].ccid.defaultFeatures = serialDevice[reader].ccid.dwFeatures; |
|
| 566 |
|
|
| 567 |
serialDevice[reader].buffer_offset = 0; |
serialDevice[reader].buffer_offset = 0; |
| 568 |
serialDevice[reader].buffer_offset_last = 0; |
serialDevice[reader].buffer_offset_last = 0; |
| 574 |
unsigned char rx_buffer[50]; |
unsigned char rx_buffer[50]; |
| 575 |
unsigned int rx_length = sizeof(rx_buffer); |
unsigned int rx_length = sizeof(rx_buffer); |
| 576 |
|
|
| 577 |
|
/* 2 seconds timeout to not wait too long if no reader is connected */ |
| 578 |
|
SerialTimeout = 2; |
| 579 |
|
|
| 580 |
if (IFD_SUCCESS != CmdEscape(reader_index, tx_buffer, sizeof(tx_buffer), |
if (IFD_SUCCESS != CmdEscape(reader_index, tx_buffer, sizeof(tx_buffer), |
| 581 |
rx_buffer, &rx_length)) |
rx_buffer, &rx_length)) |
| 582 |
{ |
{ |
| 583 |
DEBUG_CRITICAL("Get firmware failed. Maybe the reader is not co,,ected"); |
DEBUG_CRITICAL("Get firmware failed. Maybe the reader is not connected"); |
| 584 |
return STATUS_UNSUCCESSFUL; |
return STATUS_UNSUCCESSFUL; |
| 585 |
} |
} |
| 586 |
|
|
| 587 |
|
/* normal timeout: 1 minute to allow long time APDU */ |
| 588 |
|
SerialTimeout = 60; |
| 589 |
|
|
| 590 |
rx_buffer[rx_length] = '\0'; |
rx_buffer[rx_length] = '\0'; |
| 591 |
DEBUG_INFO2("Firmware: %s", rx_buffer); |
DEBUG_INFO2("Firmware: %s", rx_buffer); |
| 592 |
} |
} |