Skip to content

Commit

Permalink
Don't assume that all notifications are NotifySlotChange
Browse files Browse the repository at this point in the history
CCID defines another type of message type on the interrupt pipe,
HardwareError, and others may also be conceivably sent. So check the
message type instead of assuming it's a NotifySlotChange.

While at it, I added debug logging of HardwareError, it might be useful
for someone.
  • Loading branch information
bluetech committed Dec 13, 2024
1 parent 1c6350f commit 7adefa1
Showing 1 changed file with 53 additions and 22 deletions.
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;
}
}
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;

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

0 comments on commit 7adefa1

Please sign in to comment.