- created detect_card_presence to avoid limitations of sc_detect_card_presence
git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@32 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
117
ccid/ccid.c
117
ccid/ccid.c
@@ -87,26 +87,37 @@ debug_sc_result(const char *func, int sc_result)
|
|||||||
error("%s: %s", func, sc_strerror(sc_result));
|
error("%s: %s", func, sc_strerror(sc_result));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
cleanup_card(int flags, __u8 bSlot)
|
detect_card_presence(int slot)
|
||||||
{
|
{
|
||||||
if (bSlot < sizeof *card_in_slot) {
|
int sc_result;
|
||||||
if (flags & SC_SLOT_CARD_CHANGED) {
|
|
||||||
sc_disconnect_card(card_in_slot[bSlot], 0);
|
if (slot >= sizeof *card_in_slot)
|
||||||
debug("Card exchanged in slot %d", bSlot);
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
}
|
|
||||||
if (flags == 0
|
if (card_in_slot[slot] && sc_card_valid(card_in_slot[slot])) {
|
||||||
&& card_in_slot[bSlot]
|
sc_result = SC_SLOT_CARD_PRESENT;
|
||||||
&& sc_card_valid(card_in_slot[bSlot])) {
|
} else {
|
||||||
sc_disconnect_card(card_in_slot[bSlot], 0);
|
sc_result = sc_detect_card_presence(reader, slot);
|
||||||
debug("Card removed from slot %d", bSlot);
|
|
||||||
}
|
|
||||||
if (flags & SC_SLOT_CARD_PRESENT
|
|
||||||
&& (!card_in_slot[bSlot]
|
|
||||||
|| !sc_card_valid(card_in_slot[bSlot]))) {
|
|
||||||
debug("Unused card in slot %d", bSlot);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sc_result == 0
|
||||||
|
&& card_in_slot[slot]
|
||||||
|
&& sc_card_valid(card_in_slot[slot])) {
|
||||||
|
sc_disconnect_card(card_in_slot[slot], 0);
|
||||||
|
debug("Card removed from slot %d", slot);
|
||||||
|
}
|
||||||
|
if (sc_result & SC_SLOT_CARD_CHANGED) {
|
||||||
|
sc_disconnect_card(card_in_slot[slot], 0);
|
||||||
|
debug("Card exchanged in slot %d", slot);
|
||||||
|
}
|
||||||
|
if (sc_result & SC_SLOT_CARD_PRESENT
|
||||||
|
&& (!card_in_slot[slot]
|
||||||
|
|| !sc_card_valid(card_in_slot[slot]))) {
|
||||||
|
debug("Unused card in slot %d", slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sc_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -242,7 +253,7 @@ int get_rapdu(sc_apdu_t *apdu, size_t slot, __u8 **buf, size_t *resplen)
|
|||||||
{
|
{
|
||||||
int sc_result;
|
int sc_result;
|
||||||
|
|
||||||
if (!apdu || !buf || !resplen || slot > sizeof *card_in_slot) {
|
if (!apdu || !buf || !resplen || slot >= sizeof *card_in_slot) {
|
||||||
sc_result = SC_ERROR_INVALID_ARGUMENTS;
|
sc_result = SC_ERROR_INVALID_ARGUMENTS;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -315,51 +326,28 @@ __u8 get_bStatus(int sc_result, __u8 bSlot)
|
|||||||
int flags;
|
int flags;
|
||||||
__u8 result = 0;
|
__u8 result = 0;
|
||||||
|
|
||||||
if (bSlot < sizeof *card_in_slot) {
|
flags = detect_card_presence(bSlot);
|
||||||
/* FIXME testing for the presence of a card yields a segmentation fault:
|
|
||||||
* opensc-0.11.4/src/libopensc/reader-pcsc.c:291 calls
|
if (flags >= 0) {
|
||||||
* SCardGetStatusChange, which crashes. This could be a bug in libpcsc
|
if (sc_result < 0) {
|
||||||
*
|
if (flags & SC_SLOT_CARD_PRESENT) {
|
||||||
* To avoid this always assume, that the card is (still) present when
|
if (flags & SC_SLOT_CARD_CHANGED)
|
||||||
* the context is valid.
|
result = CCID_BSTATUS_ERROR_INACTIVE;
|
||||||
*/
|
else
|
||||||
#if 0
|
result = CCID_BSTATUS_ERROR_ACTIVE;
|
||||||
flags = sc_detect_card_presence(reader, bSlot);
|
} else
|
||||||
#else
|
result = CCID_BSTATUS_ERROR_NOICC;
|
||||||
if (card_in_slot[bSlot] && sc_card_valid(card_in_slot[bSlot])) {
|
|
||||||
flags = SC_SLOT_CARD_PRESENT;
|
|
||||||
} else {
|
} else {
|
||||||
flags = sc_detect_card_presence(reader, bSlot);
|
if (flags & SC_SLOT_CARD_PRESENT) {
|
||||||
|
if (flags & SC_SLOT_CARD_CHANGED)
|
||||||
|
result = CCID_BSTATUS_OK_INACTIVE;
|
||||||
|
else
|
||||||
|
result = CCID_BSTATUS_OK_ACTIVE;
|
||||||
|
} else
|
||||||
|
result = CCID_BSTATUS_OK_NOICC;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
cleanup_card(flags, bSlot);
|
|
||||||
} else {
|
} else {
|
||||||
flags = SC_ERROR_INVALID_DATA;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sc_result < 0) {
|
|
||||||
if (flags & SC_SLOT_CARD_PRESENT) {
|
|
||||||
if (flags & SC_SLOT_CARD_CHANGED)
|
|
||||||
result = CCID_BSTATUS_ERROR_INACTIVE;
|
|
||||||
else
|
|
||||||
result = CCID_BSTATUS_ERROR_ACTIVE;
|
|
||||||
} else
|
|
||||||
result = CCID_BSTATUS_ERROR_NOICC;
|
|
||||||
} else {
|
|
||||||
if (flags & SC_SLOT_CARD_PRESENT) {
|
|
||||||
if (flags & SC_SLOT_CARD_CHANGED)
|
|
||||||
result = CCID_BSTATUS_OK_INACTIVE;
|
|
||||||
else
|
|
||||||
result = CCID_BSTATUS_OK_ACTIVE;
|
|
||||||
} else
|
|
||||||
result = CCID_BSTATUS_OK_NOICC;
|
|
||||||
}
|
|
||||||
|
|
||||||
err:
|
|
||||||
if (flags < 0) {
|
|
||||||
DEBUG_SC_RESULT(flags);
|
DEBUG_SC_RESULT(flags);
|
||||||
flags = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -457,6 +445,7 @@ perform_PC_to_RDR_IccPowerOn(const __u8 *in, __u8 **out, size_t *outlen)
|
|||||||
if (!out || !outlen)
|
if (!out || !outlen)
|
||||||
return SC_ERROR_INVALID_ARGUMENTS;
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
|
printf("%s:%d\n", __FILE__, __LINE__);
|
||||||
*outlen = 0;
|
*outlen = 0;
|
||||||
if (request->bSlot <= sizeof *card_in_slot) {
|
if (request->bSlot <= sizeof *card_in_slot) {
|
||||||
sc_result = sc_connect_card(reader, request->bSlot,
|
sc_result = sc_connect_card(reader, request->bSlot,
|
||||||
@@ -464,10 +453,13 @@ perform_PC_to_RDR_IccPowerOn(const __u8 *in, __u8 **out, size_t *outlen)
|
|||||||
} else {
|
} else {
|
||||||
sc_result = SC_ERROR_INVALID_DATA;
|
sc_result = SC_ERROR_INVALID_DATA;
|
||||||
}
|
}
|
||||||
|
printf("%s:%d\n", __FILE__, __LINE__);
|
||||||
|
|
||||||
r = get_RDR_to_PC_SlotStatus(request->bSlot, request->bSeq, sc_result, &result);
|
r = get_RDR_to_PC_SlotStatus(request->bSlot, request->bSeq, sc_result, &result);
|
||||||
|
|
||||||
|
printf("%s:%d\n", __FILE__, __LINE__);
|
||||||
if (r >= 0) {
|
if (r >= 0) {
|
||||||
|
printf("%s:%d\n", __FILE__, __LINE__);
|
||||||
if (sc_result >= 0) {
|
if (sc_result >= 0) {
|
||||||
result->dwLength = __cpu_to_le32(card_in_slot[request->bSlot]->atr_len);
|
result->dwLength = __cpu_to_le32(card_in_slot[request->bSlot]->atr_len);
|
||||||
*outlen = sizeof *result + card_in_slot[request->bSlot]->atr_len;
|
*outlen = sizeof *result + card_in_slot[request->bSlot]->atr_len;
|
||||||
@@ -478,11 +470,13 @@ perform_PC_to_RDR_IccPowerOn(const __u8 *in, __u8 **out, size_t *outlen)
|
|||||||
}
|
}
|
||||||
memcpy(*out + sizeof *result, card_in_slot[request->bSlot]->atr, card_in_slot[request->bSlot]->atr_len);
|
memcpy(*out + sizeof *result, card_in_slot[request->bSlot]->atr, card_in_slot[request->bSlot]->atr_len);
|
||||||
} else {
|
} else {
|
||||||
|
printf("%s:%d\n", __FILE__, __LINE__);
|
||||||
DEBUG_SC_RESULT(sc_result);
|
DEBUG_SC_RESULT(sc_result);
|
||||||
*outlen = sizeof *result;
|
*outlen = sizeof *result;
|
||||||
*out = (__u8 *) result;
|
*out = (__u8 *) result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
printf("%s:%d\n", __FILE__, __LINE__);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -1054,8 +1048,7 @@ get_RDR_to_PC_NotifySlotChange(RDR_to_PC_NotifySlotChange_t **out)
|
|||||||
result->bmSlotICCState = CCID_SLOTS_UNCHANGED;
|
result->bmSlotICCState = CCID_SLOTS_UNCHANGED;
|
||||||
|
|
||||||
for (i = 0; i < reader->slot_count; i++) {
|
for (i = 0; i < reader->slot_count; i++) {
|
||||||
sc_result = sc_detect_card_presence(reader, i);
|
sc_result = detect_card_presence(i);
|
||||||
cleanup_card(sc_result, i);
|
|
||||||
if (sc_result < 0) {
|
if (sc_result < 0) {
|
||||||
DEBUG_SC_RESULT(sc_result);
|
DEBUG_SC_RESULT(sc_result);
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
Reference in New Issue
Block a user