Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't assume that all notifications are NotifySlotChange #154

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions src/ccid.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,32 @@ typedef struct
#define PROTOCOL_ICCD_A 1 /* ICCD Version A */
#define PROTOCOL_ICCD_B 2 /* ICCD Version B */

/* Known CCID bMessageType values. */
bluetech marked this conversation as resolved.
Show resolved Hide resolved
/* Command Pipe, Bulk-OUT Messages */
#define PC_to_RDR_IccPowerOn 0x62
#define PC_to_RDR_IccPowerOff 0x63
#define PC_to_RDR_GetSlotStatus 0x65
#define PC_to_RDR_XfrBlock 0x6F
#define PC_to_RDR_GetParameters 0x6C
#define PC_to_RDR_ResetParameters 0x6D
#define PC_to_RDR_SetParameters 0x61
#define PC_to_RDR_Escape 0x6B
#define PC_to_RDR_IccClock 0x6E
#define PC_to_RDR_T0APDU 0x6A
#define PC_to_RDR_Secure 0x69
#define PC_to_RDR_Mechanical 0x71
#define PC_to_RDR_Abort 0x72
#define PC_to_RDR_SetDataRateAndClockFrequency 0x73
/* Response Pipe, Bulk-IN Messages */
#define RDR_to_PC_DataBlock 0x80
#define RDR_to_PC_SlotStatus 0x81
#define RDR_to_PC_Parameters 0x82
#define RDR_to_PC_Escape 0x83
#define RDR_to_PC_DataRateAndClockFrequency 0x84
/* Interrupt-IN Messages */
#define RDR_to_PC_NotifySlotChange 0x50
#define RDR_to_PC_HardwareError 0x51

/* Product identification for special treatments */
#define GEMPC433 0x08E64433
#define GEMPCKEY 0x08E63438
Expand Down
1 change: 0 additions & 1 deletion src/ccid_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
#define SYNC 0x03
#define CTRL_ACK 0x06
#define CTRL_NAK 0x15
#define RDR_to_PC_NotifySlotChange 0x50
#define CARD_ABSENT 0x02
#define CARD_PRESENT 0x03

Expand Down
75 changes: 53 additions & 22 deletions src/ccid_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1620,7 +1620,21 @@ int InterruptRead(int reader_index, int timeout /* in ms */)
switch (ret)
{
case LIBUSB_TRANSFER_COMPLETED:
DEBUG_XXD("NotifySlotChange: ", buffer, actual_length);
if (actual_length > 0)
{
switch (buffer[0])
{
case RDR_to_PC_NotifySlotChange:
DEBUG_XXD("NotifySlotChange: ", buffer, actual_length);
break;
case RDR_to_PC_HardwareError:
DEBUG_XXD("HardwareError: ", buffer, actual_length);
break;
default:
DEBUG_XXD("Unrecognized notification: ", buffer, actual_length);
break;
}
bluetech marked this conversation as resolved.
Show resolved Hide resolved
}
break;

case LIBUSB_TRANSFER_TIMED_OUT:
Expand Down Expand Up @@ -1763,29 +1777,45 @@ static void *Multi_PollingProc(void *p_ext)
DEBUG_COMM3("Multi_PollingProc (%d/%d): OK",
usbDevice[msExt->reader_index].bus_number,
usbDevice[msExt->reader_index].device_address);
DEBUG_XXD("NotifySlotChange: ", buffer, actual_length);

/* log the RDR_to_PC_NotifySlotChange data */
slot = 0;
for (b=0; b<actual_length-1; b++)
if (actual_length > 0)
{
int s;

/* 4 slots per byte */
for (s=0; s<4; s++)
switch (buffer[0])
{
/* 2 bits per slot */
int slot_status = ((buffer[1+b] >> (s*2)) & 3);
const char *present, *change;

present = (slot_status & 1) ? "present" : "absent";
change = (slot_status & 2) ? "status changed" : "no change";

DEBUG_COMM3("slot %d status: %d",
s + slot, slot_status);
DEBUG_COMM3("ICC %s, %s", present, change);
case RDR_to_PC_NotifySlotChange:
DEBUG_XXD("NotifySlotChange: ", buffer, actual_length);

/* log the RDR_to_PC_NotifySlotChange data */
slot = 0;
for (b=0; b<actual_length-1; b++)
{
int s;

/* 4 slots per byte */
for (s=0; s<4; s++)
{
/* 2 bits per slot */
int slot_status = ((buffer[1+b] >> (s*2)) & 3);
const char *present, *change;

present = (slot_status & 1) ? "present" : "absent";
change = (slot_status & 2) ? "status changed" : "no change";

DEBUG_COMM3("slot %d status: %d",
s + slot, slot_status);
DEBUG_COMM3("ICC %s, %s", present, change);
}
slot += 4;
}
break;

case RDR_to_PC_HardwareError:
DEBUG_XXD("HardwareError: ", buffer, actual_length);
break;
bluetech marked this conversation as resolved.
Show resolved Hide resolved

default:
DEBUG_XXD("Unrecognized notification: ", buffer, actual_length);
break;
}
slot += 4;
}
break;

Expand Down Expand Up @@ -1954,7 +1984,8 @@ static int Multi_InterruptRead(int reader_index, int timeout /* in ms */)
/* Not stopped */
if (status == LIBUSB_TRANSFER_COMPLETED)
{
if (0 == (buffer[interrupt_byte] & interrupt_mask))
if (buffer[0] == RDR_to_PC_NotifySlotChange
&& 0 == (buffer[interrupt_byte] & interrupt_mask))
{
DEBUG_PERIODIC2("Multi_InterruptRead (%d) -- skipped",
reader_index);
Expand Down
16 changes: 8 additions & 8 deletions src/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ RESPONSECODE CmdPowerOn(unsigned int reader_index, unsigned int * nlength,

again:
bSeq = (*ccid_descriptor->pbSeq)++;
cmd[0] = 0x62; /* IccPowerOn */
cmd[0] = PC_to_RDR_IccPowerOn;
cmd[1] = cmd[2] = cmd[3] = cmd[4] = 0; /* dwLength */
cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
cmd[6] = bSeq;
Expand Down Expand Up @@ -311,7 +311,7 @@ RESPONSECODE SecurePINVerify(unsigned int reader_index,
uint32_t ulDataLength;

pvs = (PIN_VERIFY_STRUCTURE *)TxBuffer;
cmd[0] = 0x69; /* Secure */
cmd[0] = PC_to_RDR_Secure;
cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
cmd[6] = (*ccid_descriptor->pbSeq)++;
cmd[7] = 0; /* bBWI */
Expand Down Expand Up @@ -663,7 +663,7 @@ RESPONSECODE SecurePINModify(unsigned int reader_index,
uint32_t ulDataLength;

pms = (PIN_MODIFY_STRUCTURE *)TxBuffer;
cmd[0] = 0x69; /* Secure */
cmd[0] = PC_to_RDR_Secure;
cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
cmd[6] = (*ccid_descriptor->pbSeq)++;
cmd[7] = 0; /* bBWI */
Expand Down Expand Up @@ -973,7 +973,7 @@ RESPONSECODE CmdEscapeCheck(unsigned int reader_index,
}

bSeq = (*ccid_descriptor->pbSeq)++;
cmd_in[0] = 0x6B; /* PC_to_RDR_Escape */
cmd_in[0] = PC_to_RDR_Escape;
i2dw(length_in - 10, cmd_in+1); /* dwLength */
cmd_in[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
cmd_in[6] = bSeq;
Expand Down Expand Up @@ -1122,7 +1122,7 @@ RESPONSECODE CmdPowerOff(unsigned int reader_index)
#endif

bSeq = (*ccid_descriptor->pbSeq)++;
cmd[0] = 0x63; /* IccPowerOff */
cmd[0] = PC_to_RDR_IccPowerOff;
cmd[1] = cmd[2] = cmd[3] = cmd[4] = 0; /* dwLength */
cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
cmd[6] = bSeq;
Expand Down Expand Up @@ -1248,7 +1248,7 @@ RESPONSECODE CmdGetSlotStatus(unsigned int reader_index, unsigned char buffer[])
#endif

bSeq = (*ccid_descriptor->pbSeq)++;
cmd[0] = 0x65; /* GetSlotStatus */
cmd[0] = PC_to_RDR_GetSlotStatus;
cmd[1] = cmd[2] = cmd[3] = cmd[4] = 0; /* dwLength */
cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
cmd[6] = bSeq;
Expand Down Expand Up @@ -1391,7 +1391,7 @@ RESPONSECODE CCID_Transmit(unsigned int reader_index, unsigned int tx_length,
}
#endif

cmd[0] = 0x6F; /* XfrBlock */
cmd[0] = PC_to_RDR_XfrBlock;
i2dw(tx_length, cmd+1); /* APDU length */
cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
cmd[6] = (*ccid_descriptor->pbSeq)++;
Expand Down Expand Up @@ -2317,7 +2317,7 @@ RESPONSECODE SetParameters(unsigned int reader_index, char protocol,
DEBUG_COMM2("length: %d bytes", length);

bSeq = (*ccid_descriptor->pbSeq)++;
cmd[0] = 0x61; /* SetParameters */
cmd[0] = PC_to_RDR_SetParameters;
i2dw(length, cmd+1); /* APDU length */
cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
cmd[6] = bSeq;
Expand Down
Loading