atrhandler.c

Go to the documentation of this file.
00001 /*
00002  * MUSCLE SmartCard Development ( http://www.linuxnet.com )
00003  *
00004  * Copyright (C) 1999-2004
00005  *  David Corcoran <corcoran@linuxnet.com>
00006  *  Ludovic Rousseau <ludovic.rousseau@free.fr>
00007  *
00008  * $Id: atrhandler.c 1827 2006-01-24 14:49:52Z rousseau $
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 /* #define ATR_DEBUG */
00035 
00043 short ATRDecodeAtr(PSMARTCARD_EXTENSION psExtension,
00044     PUCHAR pucAtr, DWORD dwLength)
00045 {
00046     USHORT p;
00047     UCHAR K, TCK;               /* MSN of T0/Check Sum */
00048     UCHAR Y1i, T;               /* MSN/LSN of TDi */
00049     int i = 1;                  /* value of the index in TAi, TBi, etc. */
00050 
00051     /*
00052      * Zero out everything 
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      * Zero out the bitmasks 
00066      */
00067     psExtension->CardCapabilities.AvailableProtocols = SCARD_PROTOCOL_UNSET;
00068     psExtension->CardCapabilities.CurrentProtocol = SCARD_PROTOCOL_UNSET;
00069 
00070     /*
00071      * Decode the TS byte 
00072      */
00073     if (pucAtr[0] == 0x3F)
00074     {   /* Inverse convention used */
00075         psExtension->CardCapabilities.Convention = SCARD_CONVENTION_INVERSE;
00076     }
00077     else
00078         if (pucAtr[0] == 0x3B)
00079         {   /* Direct convention used */
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      * Here comes the platform dependant stuff 
00090      */
00091 
00092     /*
00093      * Decode the T0 byte 
00094      */
00095     Y1i = pucAtr[1] >> 4;   /* Get the MSN in Y1 */
00096     K = pucAtr[1] & 0x0F;   /* Get the LSN in K */
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      * Examine Y1 
00107      */
00108     do
00109     {
00110         short TAi, TBi, TCi, TDi;   /* Interface characters */
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          * Examine TDi to determine protocol and more 
00125          */
00126         if (TDi >= 0)
00127         {
00128             Y1i = TDi >> 4; /* Get the MSN in Y1 */
00129             T = TDi & 0x0F; /* Get the LSN in K */
00130 
00131             /*
00132              * Set the current protocol TD1 (first TD only)
00133              */
00134             if (psExtension->CardCapabilities.CurrentProtocol == SCARD_PROTOCOL_UNSET)
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                 psExtension->CardCapabilities.T0.BGT = 0;
00159                 psExtension->CardCapabilities.T0.BWT = 0;
00160                 psExtension->CardCapabilities.T0.CWT = 0;
00161                 psExtension->CardCapabilities.T0.CGT = 0;
00162                 psExtension->CardCapabilities.T0.WT = 0;
00163             }
00164             else
00165                 if (1 == T)
00166                 {
00167                     psExtension->CardCapabilities.AvailableProtocols |=
00168                         SCARD_PROTOCOL_T1;
00169                     psExtension->CardCapabilities.T1.BGT = 0;
00170                     psExtension->CardCapabilities.T1.BWT = 0;
00171                     psExtension->CardCapabilities.T1.CWT = 0;
00172                     psExtension->CardCapabilities.T1.CGT = 0;
00173                     psExtension->CardCapabilities.T1.WT = 0;
00174                 }
00175                 else
00176                     if (15 == T)
00177                     {
00178                         psExtension->CardCapabilities.AvailableProtocols |=
00179                             SCARD_PROTOCOL_T15;
00180                     }
00181                     else
00182                     {
00183                         /*
00184                          * Do nothing for now since other protocols are not
00185                          * supported at this time 
00186                          */
00187                     }
00188 
00189             /* test presence of TA2 */
00190             if ((2 == i) && (TAi >= 0))
00191             {
00192                 T = TAi & 0x0F;
00193 #ifdef ATR_DEBUG
00194                 Log2(PCSC_LOG_DEBUG, "Specific mode: T=%d", T);
00195 #endif
00196                 switch (T)
00197                 {
00198                     case 0:
00199                         psExtension->CardCapabilities.CurrentProtocol =
00200                             psExtension->CardCapabilities.AvailableProtocols =
00201                             SCARD_PROTOCOL_T0;
00202                         break;
00203 
00204                     case 1:
00205                         psExtension->CardCapabilities.CurrentProtocol =
00206                             psExtension->CardCapabilities.AvailableProtocols =
00207                             SCARD_PROTOCOL_T1;
00208                         break;
00209 
00210                     default:
00211                         return 0; 
00212                 }
00213             }
00214         } else
00215             Y1i = 0;
00216 
00217         if (p > MAX_ATR_SIZE)
00218         {
00219             memset(psExtension, 0x00, sizeof(SMARTCARD_EXTENSION));
00220             return 0;   
00221         }
00222 
00223         /* next interface characters index */
00224         i++;
00225     }
00226     while (Y1i != 0);
00227 
00228     /*
00229      * If TDx is not set then the current must be T0 
00230      */
00231     if (psExtension->CardCapabilities.CurrentProtocol == SCARD_PROTOCOL_UNSET)
00232     {
00233         psExtension->CardCapabilities.CurrentProtocol = SCARD_PROTOCOL_T0;
00234         psExtension->CardCapabilities.AvailableProtocols |= SCARD_PROTOCOL_T0;
00235     }
00236 
00237     /*
00238      * Take care of the historical characters 
00239      */
00240     psExtension->ATR.HistoryLength = K;
00241     memcpy(psExtension->ATR.HistoryValue, &pucAtr[p], K);
00242 
00243     p = p + K;
00244 
00245     /*
00246      * Check to see if TCK character is included It will be included if
00247      * more than T=0 is supported 
00248      */
00249     if (psExtension->CardCapabilities.AvailableProtocols & SCARD_PROTOCOL_T1)
00250         TCK = pucAtr[p++];
00251 
00252     memcpy(psExtension->ATR.Value, pucAtr, p);
00253     psExtension->ATR.Length = p;    /* modified from p-1 */
00254 
00255 #ifdef ATR_DEBUG
00256     Log3(PCSC_LOG_DEBUG, "CurrentProtocol: %d, AvailableProtocols: %d",
00257         psExtension->CardCapabilities.CurrentProtocol,
00258         psExtension->CardCapabilities.AvailableProtocols);
00259 #endif
00260 
00261     return 1; 
00262 }
00263 

Generated on Sat Sep 15 20:50:01 2007 for pcsc-lite by  doxygen 1.4.7