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