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

Generated on Thu Jul 1 20:11:37 2010 for pcsc-lite by  doxygen 1.4.7