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 3254 2009-01-02 14:01:36Z rousseau $
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 /* #define ATR_DEBUG */
00034 
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_UNDEFINED;
00068     psExtension->CardCapabilities.CurrentProtocol = SCARD_PROTOCOL_UNDEFINED;
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_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                          * Do nothing for now since other protocols are not
00175                          * supported at this time
00176                          */
00177                     }
00178 
00179             /* test presence of TA2 */
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         /* next interface characters index */
00214         i++;
00215     }
00216     while (Y1i != 0);
00217 
00218     /*
00219      * If TDx is not set then the current must be T0
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      * Take care of the historical characters
00229      */
00230     psExtension->ATR.HistoryLength = K;
00231     memcpy(psExtension->ATR.HistoryValue, &pucAtr[p], K);
00232 
00233     p = p + K;
00234 
00235     /*
00236      * Check to see if TCK character is included It will be included if
00237      * more than T=0 is supported
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;    /* modified from p-1 */
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 

Generated on Mon Aug 17 01:00:08 2009 for pcsc-lite by  doxygen 1.5.9