pcsc-lite
1.7.4
|
00001 /* 00002 * MUSCLE SmartCard Development ( http://www.linuxnet.com ) 00003 * 00004 * Copyright (C) 1999 00005 * David Corcoran <corcoran@linuxnet.com> 00006 * Copyright (C) 2004-2011 00007 * Ludovic Rousseau <ludovic.rousseau@free.fr> 00008 * 00009 * $Id: prothandler.c 5711 2011-05-05 09:02:08Z rousseau $ 00010 */ 00011 00017 #include "config.h" 00018 #include <string.h> 00019 00020 #include "misc.h" 00021 #include "pcscd.h" 00022 #include "debuglog.h" 00023 #include "readerfactory.h" 00024 #include "prothandler.h" 00025 #include "atrhandler.h" 00026 #include "ifdwrapper.h" 00027 #include "eventhandler.h" 00028 00034 UCHAR PHGetDefaultProtocol(PUCHAR pucAtr, DWORD dwLength) 00035 { 00036 SMARTCARD_EXTENSION sSmartCard; 00037 00038 /* 00039 * Zero out everything 00040 */ 00041 memset(&sSmartCard, 0x00, sizeof(SMARTCARD_EXTENSION)); 00042 00043 if (ATRDecodeAtr(&sSmartCard, pucAtr, dwLength)) 00044 return sSmartCard.CardCapabilities.CurrentProtocol; 00045 else 00046 return 0x00; 00047 } 00048 00054 UCHAR PHGetAvailableProtocols(PUCHAR pucAtr, DWORD dwLength) 00055 { 00056 SMARTCARD_EXTENSION sSmartCard; 00057 00058 /* 00059 * Zero out everything 00060 */ 00061 memset(&sSmartCard, 0x00, sizeof(SMARTCARD_EXTENSION)); 00062 00063 if (ATRDecodeAtr(&sSmartCard, pucAtr, dwLength)) 00064 return sSmartCard.CardCapabilities.AvailableProtocols; 00065 else 00066 return 0x00; 00067 } 00068 00079 DWORD PHSetProtocol(struct ReaderContext * rContext, 00080 DWORD dwPreferred, UCHAR ucAvailable, UCHAR ucDefault) 00081 { 00082 DWORD protocol; 00083 LONG rv; 00084 UCHAR ucChosen; 00085 00086 /* App has specified no protocol */ 00087 if (dwPreferred == 0) 00088 return SET_PROTOCOL_WRONG_ARGUMENT; 00089 00090 /* requested protocol is not available */ 00091 if (! (dwPreferred & ucAvailable)) 00092 { 00093 /* Note: 00094 * dwPreferred must be either SCARD_PROTOCOL_T0 or SCARD_PROTOCOL_T1 00095 * if dwPreferred == SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 the test 00096 * (SCARD_PROTOCOL_T0 == dwPreferred) will not work as expected 00097 * and the debug message will not be correct. 00098 * 00099 * This case may only occur if 00100 * dwPreferred == SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 00101 * and ucAvailable == 0 since we have (dwPreferred & ucAvailable) == 0 00102 * and the case ucAvailable == 0 should never occur (the card is at 00103 * least T=0 or T=1) 00104 */ 00105 Log2(PCSC_LOG_ERROR, "Protocol T=%d requested but unsupported by the card", 00106 (SCARD_PROTOCOL_T0 == dwPreferred) ? 0 : 1); 00107 return SET_PROTOCOL_WRONG_ARGUMENT; 00108 } 00109 00110 /* set default value */ 00111 protocol = ucDefault; 00112 00113 /* keep only the available protocols */ 00114 dwPreferred &= ucAvailable; 00115 00116 /* we try to use T=1 first */ 00117 if (dwPreferred & SCARD_PROTOCOL_T1) 00118 ucChosen = SCARD_PROTOCOL_T1; 00119 else 00120 if (dwPreferred & SCARD_PROTOCOL_T0) 00121 ucChosen = SCARD_PROTOCOL_T0; 00122 else 00123 /* App wants unsupported protocol */ 00124 return SET_PROTOCOL_WRONG_ARGUMENT; 00125 00126 Log2(PCSC_LOG_INFO, "Attempting PTS to T=%d", 00127 (SCARD_PROTOCOL_T0 == ucChosen ? 0 : 1)); 00128 rv = IFDSetPTS(rContext, ucChosen, 0x00, 0x00, 0x00, 0x00); 00129 00130 if (IFD_SUCCESS == rv) 00131 protocol = ucChosen; 00132 else 00133 if (IFD_NOT_SUPPORTED == rv) 00134 Log2(PCSC_LOG_INFO, "PTS not supported by driver, using T=%d", 00135 (SCARD_PROTOCOL_T0 == protocol) ? 0 : 1); 00136 else 00137 if (IFD_PROTOCOL_NOT_SUPPORTED == rv) 00138 Log2(PCSC_LOG_INFO, "PTS protocol not supported, using T=%d", 00139 (SCARD_PROTOCOL_T0 == protocol) ? 0 : 1); 00140 else 00141 { 00142 Log3(PCSC_LOG_INFO, "PTS failed (%d), using T=%d", rv, 00143 (SCARD_PROTOCOL_T0 == protocol) ? 0 : 1); 00144 00145 /* ISO 7816-3:1997 ch. 7.2 PPS protocol page 14 00146 * - If the PPS exchange is unsuccessful, then the interface device 00147 * shall either reset or reject the card. 00148 */ 00149 return SET_PROTOCOL_PPS_FAILED; 00150 } 00151 00152 return protocol; 00153 } 00154