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