Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00022 #include "config.h"
00023 #include <string.h>
00024
00025 #include "misc.h"
00026 #include "pcsclite.h"
00027 #include "debuglog.h"
00028 #include "atrhandler.h"
00029
00034
00035
00044 short ATRDecodeAtr(PSMARTCARD_EXTENSION psExtension,
00045 PUCHAR pucAtr, DWORD dwLength)
00046 {
00047 USHORT p;
00048 UCHAR K, TCK;
00049 UCHAR Y1i, T;
00050 int i = 1;
00051
00052
00053
00054
00055 p = K = TCK = Y1i = T = 0;
00056
00057 #ifdef ATR_DEBUG
00058 if (dwLength > 0)
00059 LogXxd(PCSC_LOG_DEBUG, "ATR: ", pucAtr, dwLength);
00060 #endif
00061
00062 if (dwLength < 2)
00063 return 0;
00065
00066
00067
00068 psExtension->CardCapabilities.AvailableProtocols = SCARD_PROTOCOL_UNDEFINED;
00069 psExtension->CardCapabilities.CurrentProtocol = SCARD_PROTOCOL_UNDEFINED;
00070
00071
00072
00073
00074 if (pucAtr[0] == 0x3F)
00075 {
00076 psExtension->CardCapabilities.Convention = SCARD_CONVENTION_INVERSE;
00077 }
00078 else
00079 if (pucAtr[0] == 0x3B)
00080 {
00081 psExtension->CardCapabilities.Convention = SCARD_CONVENTION_DIRECT;
00082 }
00083 else
00084 {
00085 memset(psExtension, 0x00, sizeof(SMARTCARD_EXTENSION));
00086 return 0;
00087 }
00088
00089
00090
00091
00092
00093
00094
00095
00096 Y1i = pucAtr[1] >> 4;
00097 K = pucAtr[1] & 0x0F;
00098
00099 p = 2;
00100
00101 #ifdef ATR_DEBUG
00102 Log4(PCSC_LOG_DEBUG, "Conv: %02X, Y1: %02X, K: %02X",
00103 psExtension->CardCapabilities.Convention, Y1i, K);
00104 #endif
00105
00106
00107
00108
00109 do
00110 {
00111 short TAi, TBi, TCi, TDi;
00112
00113 TAi = (Y1i & 0x01) ? pucAtr[p++] : -1;
00114 TBi = (Y1i & 0x02) ? pucAtr[p++] : -1;
00115 TCi = (Y1i & 0x04) ? pucAtr[p++] : -1;
00116 TDi = (Y1i & 0x08) ? pucAtr[p++] : -1;
00117
00118 #ifdef ATR_DEBUG
00119 Log9(PCSC_LOG_DEBUG,
00120 "TA%d: %02X, TB%d: %02X, TC%d: %02X, TD%d: %02X",
00121 i, TAi, i, TBi, i, TCi, i, TDi);
00122 #endif
00123
00124
00125
00126
00127 if (TDi >= 0)
00128 {
00129 Y1i = TDi >> 4;
00130 T = TDi & 0x0F;
00131
00132
00133
00134
00135 if (psExtension->CardCapabilities.CurrentProtocol == SCARD_PROTOCOL_UNDEFINED)
00136 {
00137 switch (T)
00138 {
00139 case 0:
00140 psExtension->CardCapabilities.CurrentProtocol =
00141 SCARD_PROTOCOL_T0;
00142 break;
00143 case 1:
00144 psExtension->CardCapabilities.CurrentProtocol =
00145 SCARD_PROTOCOL_T1;
00146 break;
00147 default:
00148 return 0;
00149 }
00150 }
00151
00152 #ifdef ATR_DEBUG
00153 Log2(PCSC_LOG_DEBUG, "T=%d Protocol Found", T);
00154 #endif
00155 if (0 == T)
00156 {
00157 psExtension->CardCapabilities.AvailableProtocols |=
00158 SCARD_PROTOCOL_T0;
00159 }
00160 else
00161 if (1 == T)
00162 {
00163 psExtension->CardCapabilities.AvailableProtocols |=
00164 SCARD_PROTOCOL_T1;
00165 }
00166 else
00167 if (15 == T)
00168 {
00169 psExtension->CardCapabilities.AvailableProtocols |=
00170 SCARD_PROTOCOL_T15;
00171 }
00172 else
00173 {
00174
00175
00176
00177
00178 }
00179 }
00180 else
00181 Y1i = 0;
00182
00183
00184 if ((2 == i) && (TAi >= 0))
00185 {
00186 T = TAi & 0x0F;
00187 #ifdef ATR_DEBUG
00188 Log2(PCSC_LOG_DEBUG, "Specific mode: T=%d", T);
00189 #endif
00190 switch (T)
00191 {
00192 case 0:
00193 psExtension->CardCapabilities.CurrentProtocol =
00194 psExtension->CardCapabilities.AvailableProtocols =
00195 SCARD_PROTOCOL_T0;
00196 break;
00197
00198 case 1:
00199 psExtension->CardCapabilities.CurrentProtocol =
00200 psExtension->CardCapabilities.AvailableProtocols =
00201 SCARD_PROTOCOL_T1;
00202 break;
00203
00204 default:
00205 return 0;
00206 }
00207 }
00208
00209 if (p > MAX_ATR_SIZE)
00210 {
00211 memset(psExtension, 0x00, sizeof(SMARTCARD_EXTENSION));
00212 return 0;
00213 }
00214
00215
00216 i++;
00217 }
00218 while (Y1i != 0);
00219
00220
00221
00222
00223 if (psExtension->CardCapabilities.CurrentProtocol == SCARD_PROTOCOL_UNDEFINED)
00224 {
00225 psExtension->CardCapabilities.CurrentProtocol = SCARD_PROTOCOL_T0;
00226 psExtension->CardCapabilities.AvailableProtocols |= SCARD_PROTOCOL_T0;
00227 }
00228
00229
00230
00231
00232 psExtension->ATR.HistoryLength = K;
00233 memcpy(psExtension->ATR.HistoryValue, &pucAtr[p], K);
00234
00235 p = p + K;
00236
00237
00238
00239
00240
00241 if (psExtension->CardCapabilities.AvailableProtocols & SCARD_PROTOCOL_T1)
00242 TCK = pucAtr[p++];
00243
00244 memcpy(psExtension->ATR.Value, pucAtr, p);
00245 psExtension->ATR.Length = p;
00246
00247 #ifdef ATR_DEBUG
00248 Log3(PCSC_LOG_DEBUG, "CurrentProtocol: %d, AvailableProtocols: %d",
00249 psExtension->CardCapabilities.CurrentProtocol,
00250 psExtension->CardCapabilities.AvailableProtocols);
00251 #endif
00252
00253 return 1;
00254 }