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