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 <syslog.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
00181 if ((2 == i) && (TAi >= 0))
00182 {
00183 T = TAi & 0x0F;
00184 #ifdef ATR_DEBUG
00185 Log2(PCSC_LOG_DEBUG, "Specific mode: T=%d", T);
00186 #endif
00187 switch (T)
00188 {
00189 case 0:
00190 psExtension->CardCapabilities.CurrentProtocol =
00191 psExtension->CardCapabilities.AvailableProtocols =
00192 SCARD_PROTOCOL_T0;
00193 break;
00194
00195 case 1:
00196 psExtension->CardCapabilities.CurrentProtocol =
00197 psExtension->CardCapabilities.AvailableProtocols =
00198 SCARD_PROTOCOL_T1;
00199 break;
00200
00201 default:
00202 return 0;
00203 }
00204 }
00205 } else
00206 Y1i = 0;
00207
00208 if (p > MAX_ATR_SIZE)
00209 {
00210 memset(psExtension, 0x00, sizeof(SMARTCARD_EXTENSION));
00211 return 0;
00212 }
00213
00214
00215 i++;
00216 }
00217 while (Y1i != 0);
00218
00219
00220
00221
00222 if (psExtension->CardCapabilities.CurrentProtocol == SCARD_PROTOCOL_UNDEFINED)
00223 {
00224 psExtension->CardCapabilities.CurrentProtocol = SCARD_PROTOCOL_T0;
00225 psExtension->CardCapabilities.AvailableProtocols |= SCARD_PROTOCOL_T0;
00226 }
00227
00228
00229
00230
00231 psExtension->ATR.HistoryLength = K;
00232 memcpy(psExtension->ATR.HistoryValue, &pucAtr[p], K);
00233
00234 p = p + K;
00235
00236
00237
00238
00239
00240 if (psExtension->CardCapabilities.AvailableProtocols & SCARD_PROTOCOL_T1)
00241 TCK = pucAtr[p++];
00242
00243 memcpy(psExtension->ATR.Value, pucAtr, p);
00244 psExtension->ATR.Length = p;
00245
00246 #ifdef ATR_DEBUG
00247 Log3(PCSC_LOG_DEBUG, "CurrentProtocol: %d, AvailableProtocols: %d",
00248 psExtension->CardCapabilities.CurrentProtocol,
00249 psExtension->CardCapabilities.AvailableProtocols);
00250 #endif
00251
00252 return 1;
00253 }
00254