Apple Bug not resolved, retry to reconnect with SCARD_LEAVE_CARD more than once (up to 100 times); refs #34
This commit is contained in:
35
src/pcsc.hxx
35
src/pcsc.hxx
@@ -70,10 +70,6 @@
|
|||||||
avoid the ugly M$-C-quirks. This interface is memory clean.
|
avoid the ugly M$-C-quirks. This interface is memory clean.
|
||||||
@todo: Not implemented, not supported:
|
@todo: Not implemented, not supported:
|
||||||
- SCardGetStatusChange(hContext, 0, rgReaderStates, 1);
|
- SCardGetStatusChange(hContext, 0, rgReaderStates, 1);
|
||||||
- SCardReconnect(hCard, SCARD_SHARE_SHARED,
|
|
||||||
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
|
|
||||||
SCARD_LEAVE_CARD,
|
|
||||||
&dwActiveProtocol);
|
|
||||||
- several other
|
- several other
|
||||||
I do not need these, and I don't know the usecase where they are
|
I do not need these, and I don't know the usecase where they are
|
||||||
required. If you need something that is not yet supported, please
|
required. If you need something that is not yet supported, please
|
||||||
@@ -312,7 +308,8 @@ namespace pcsc {
|
|||||||
in.size(),
|
in.size(),
|
||||||
0, buff, &len),
|
0, buff, &len),
|
||||||
"smartcard transmit message "+crypto::hex(in));
|
"smartcard transmit message "+crypto::hex(in));
|
||||||
} catch (...) {
|
} catch (std::exception& x) {
|
||||||
|
CRYPTOLOG("failed with "<<x.what());
|
||||||
// try to fix Apple's Mac OS X 10.10 implementation bug
|
// try to fix Apple's Mac OS X 10.10 implementation bug
|
||||||
# ifdef __APPLE__
|
# ifdef __APPLE__
|
||||||
/*! @bug Work around Mac OSX 10.10 bug. On Mac OSX
|
/*! @bug Work around Mac OSX 10.10 bug. On Mac OSX
|
||||||
@@ -320,22 +317,23 @@ namespace pcsc {
|
|||||||
reconnect, first transaction (SCardTransmit)
|
reconnect, first transaction (SCardTransmit)
|
||||||
fails with SCARD_W_RESET_CARD
|
fails with SCARD_W_RESET_CARD
|
||||||
(0x80100068). */
|
(0x80100068). */
|
||||||
for (int bugCnt(0);
|
for (int cnt(0); cnt<10 && _state==SCARD_W_RESET_CARD; ++cnt) {
|
||||||
bugCnt<100 && _state==SCARD_W_RESET_CARD;
|
// just try to resend
|
||||||
++bugCnt) { // just try to resend
|
|
||||||
CRYPTOLOG("Mac OS X 10.10 implementation bug: "
|
CRYPTOLOG("Mac OS X 10.10 implementation bug: "
|
||||||
"On Mac OSX 10.10 there is a bug in "
|
"On Mac OSX 10.10 there is a bug in "
|
||||||
"PCSC: After a reconnect, first "
|
"PCSC: After a reconnect, first "
|
||||||
"transaction (SCardTransmit) fails "
|
"transaction (SCardTransmit) fails "
|
||||||
"with SCARD_W_RESET_CARD (0x80100068). "
|
"with SCARD_W_RESET_CARD (0x80100068). "
|
||||||
"Retry Nr. "<<bugCnt);
|
"Retry Nr. "<<cnt);
|
||||||
try {
|
try {
|
||||||
|
reconnect();
|
||||||
check(SCardTransmit(_id, &rPci,
|
check(SCardTransmit(_id, &rPci,
|
||||||
(LPCBYTE)in.c_str(),
|
(LPCBYTE)in.c_str(),
|
||||||
in.size(),
|
in.size(),
|
||||||
0, buff, &len),
|
0, buff, &len),
|
||||||
"smartcard transmit resend message "+crypto::hex(in));
|
"smartcard transmit resend message "+crypto::hex(in));
|
||||||
} catch (...) {
|
} catch (std::exception& x) {
|
||||||
|
CRYPTOLOG("failed with "<<x.what());
|
||||||
continue; // try again
|
continue; // try again
|
||||||
}
|
}
|
||||||
break; // success
|
break; // success
|
||||||
@@ -436,6 +434,18 @@ namespace pcsc {
|
|||||||
return _connection->check(state, context);
|
return _connection->check(state, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Reconnect SmartCard After Reset
|
||||||
|
/*! @param mode one of
|
||||||
|
- @c SCARD_LEAVE_CARD
|
||||||
|
Do not do anything special on reconnect.
|
||||||
|
- @c SCARD_RESET_CARD
|
||||||
|
Reset the card (Warm Reset).
|
||||||
|
- @c SCARD_UNPOWER_CARD
|
||||||
|
Power down the card and reset it (Cold Reset). */
|
||||||
|
void reconnect(DWORD mode=SCARD_LEAVE_CARD) {
|
||||||
|
check(SCardReconnect(_id, _mode, _protocol, mode, &_protocol));
|
||||||
|
}
|
||||||
|
|
||||||
//! Only Connection is allowed to instanciate.
|
//! Only Connection is allowed to instanciate.
|
||||||
friend class Connection;
|
friend class Connection;
|
||||||
|
|
||||||
@@ -443,10 +453,10 @@ namespace pcsc {
|
|||||||
Reader(const std::string& nm, std::shared_ptr<Connection> c,
|
Reader(const std::string& nm, std::shared_ptr<Connection> c,
|
||||||
DWORD mode=SCARD_SHARE_SHARED,
|
DWORD mode=SCARD_SHARE_SHARED,
|
||||||
DWORD protocol=SCARD_PROTOCOL_T1):
|
DWORD protocol=SCARD_PROTOCOL_T1):
|
||||||
name(nm), _connection(c) {
|
name(nm), _connection(c), _mode(mode) {
|
||||||
CRYPTOLOG("Connect Reader");
|
CRYPTOLOG("Connect Reader");
|
||||||
check(SCardConnect(_connection->id(), strconv(name).c_str(),
|
check(SCardConnect(_connection->id(), strconv(name).c_str(),
|
||||||
mode, protocol,
|
_mode, protocol,
|
||||||
&_id, &_protocol),
|
&_id, &_protocol),
|
||||||
"connect smartcard \""+name+"\"");
|
"connect smartcard \""+name+"\"");
|
||||||
}
|
}
|
||||||
@@ -460,6 +470,7 @@ namespace pcsc {
|
|||||||
std::shared_ptr<Connection> _connection;
|
std::shared_ptr<Connection> _connection;
|
||||||
SCARDHANDLE _id;
|
SCARDHANDLE _id;
|
||||||
DWORD _state;
|
DWORD _state;
|
||||||
|
DWORD _mode;
|
||||||
DWORD _protocol;
|
DWORD _protocol;
|
||||||
static int _neesting;
|
static int _neesting;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user