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.
|
||||
@todo: Not implemented, not supported:
|
||||
- SCardGetStatusChange(hContext, 0, rgReaderStates, 1);
|
||||
- SCardReconnect(hCard, SCARD_SHARE_SHARED,
|
||||
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
|
||||
SCARD_LEAVE_CARD,
|
||||
&dwActiveProtocol);
|
||||
- several other
|
||||
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
|
||||
@@ -312,7 +308,8 @@ namespace pcsc {
|
||||
in.size(),
|
||||
0, buff, &len),
|
||||
"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
|
||||
# ifdef __APPLE__
|
||||
/*! @bug Work around Mac OSX 10.10 bug. On Mac OSX
|
||||
@@ -320,22 +317,23 @@ namespace pcsc {
|
||||
reconnect, first transaction (SCardTransmit)
|
||||
fails with SCARD_W_RESET_CARD
|
||||
(0x80100068). */
|
||||
for (int bugCnt(0);
|
||||
bugCnt<100 && _state==SCARD_W_RESET_CARD;
|
||||
++bugCnt) { // just try to resend
|
||||
for (int cnt(0); cnt<10 && _state==SCARD_W_RESET_CARD; ++cnt) {
|
||||
// just try to resend
|
||||
CRYPTOLOG("Mac OS X 10.10 implementation bug: "
|
||||
"On Mac OSX 10.10 there is a bug in "
|
||||
"PCSC: After a reconnect, first "
|
||||
"transaction (SCardTransmit) fails "
|
||||
"with SCARD_W_RESET_CARD (0x80100068). "
|
||||
"Retry Nr. "<<bugCnt);
|
||||
"Retry Nr. "<<cnt);
|
||||
try {
|
||||
reconnect();
|
||||
check(SCardTransmit(_id, &rPci,
|
||||
(LPCBYTE)in.c_str(),
|
||||
in.size(),
|
||||
0, buff, &len),
|
||||
"smartcard transmit resend message "+crypto::hex(in));
|
||||
} catch (...) {
|
||||
} catch (std::exception& x) {
|
||||
CRYPTOLOG("failed with "<<x.what());
|
||||
continue; // try again
|
||||
}
|
||||
break; // success
|
||||
@@ -436,6 +434,18 @@ namespace pcsc {
|
||||
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.
|
||||
friend class Connection;
|
||||
|
||||
@@ -443,10 +453,10 @@ namespace pcsc {
|
||||
Reader(const std::string& nm, std::shared_ptr<Connection> c,
|
||||
DWORD mode=SCARD_SHARE_SHARED,
|
||||
DWORD protocol=SCARD_PROTOCOL_T1):
|
||||
name(nm), _connection(c) {
|
||||
name(nm), _connection(c), _mode(mode) {
|
||||
CRYPTOLOG("Connect Reader");
|
||||
check(SCardConnect(_connection->id(), strconv(name).c_str(),
|
||||
mode, protocol,
|
||||
_mode, protocol,
|
||||
&_id, &_protocol),
|
||||
"connect smartcard \""+name+"\"");
|
||||
}
|
||||
@@ -460,6 +470,7 @@ namespace pcsc {
|
||||
std::shared_ptr<Connection> _connection;
|
||||
SCARDHANDLE _id;
|
||||
DWORD _state;
|
||||
DWORD _mode;
|
||||
DWORD _protocol;
|
||||
static int _neesting;
|
||||
|
||||
|
Reference in New Issue
Block a user