prothandler.c

Go to the documentation of this file.
00001 /*
00002  * MUSCLE SmartCard Development ( http://www.linuxnet.com )
00003  *
00004  * Copyright (C) 1999
00005  *  David Corcoran <corcoran@linuxnet.com>
00006  * Copyright (C) 2004
00007  *  Ludovic Rousseau <ludovic.rousseau@free.fr>
00008  *
00009  * $Id: prothandler.c 2377 2007-02-05 13:13:56Z rousseau $
00010  */
00011 
00017 #include "config.h"
00018 #include <string.h>
00019 
00020 #include "misc.h"
00021 #include "pcscd.h"
00022 #include "ifdhandler.h"
00023 #include "debuglog.h"
00024 #include "readerfactory.h"
00025 #include "prothandler.h"
00026 #include "atrhandler.h"
00027 #include "ifdwrapper.h"
00028 #include "eventhandler.h"
00029 
00030 /*
00031  * Function: PHGetDefaultProtocol Purpose : To get the default protocol
00032  * used immediately after reset. This protocol is returned from the
00033  * function.
00034  */
00035 
00036 UCHAR PHGetDefaultProtocol(PUCHAR pucAtr, DWORD dwLength)
00037 {
00038     SMARTCARD_EXTENSION sSmartCard;
00039 
00040     /*
00041      * Zero out everything
00042      */
00043     memset(&sSmartCard, 0x00, sizeof(SMARTCARD_EXTENSION));
00044 
00045     if (ATRDecodeAtr(&sSmartCard, pucAtr, dwLength))
00046         return sSmartCard.CardCapabilities.CurrentProtocol;
00047     else
00048         return 0x00;
00049 }
00050 
00051 /*
00052  * Function: PHGetAvailableProtocols Purpose : To get the protocols
00053  * supported by the card. These protocols are returned from the function
00054  * as bit masks.
00055  */
00056 
00057 UCHAR PHGetAvailableProtocols(PUCHAR pucAtr, DWORD dwLength)
00058 {
00059     SMARTCARD_EXTENSION sSmartCard;
00060 
00061     /*
00062      * Zero out everything
00063      */
00064     memset(&sSmartCard, 0x00, sizeof(SMARTCARD_EXTENSION));
00065 
00066     if (ATRDecodeAtr(&sSmartCard, pucAtr, dwLength))
00067         return sSmartCard.CardCapabilities.AvailableProtocols;
00068     else
00069         return 0x00;
00070 }
00071 
00072 /*
00073  * Function: PHSetProtocol Purpose : To determine which protocol to use.
00074  * SCardConnect has a DWORD dwPreferredProtocols that is a bitmask of what
00075  * protocols to use.  Basically, if T=N where N is not zero will be used
00076  * first if it is available in ucAvailable.  Otherwise it will always
00077  * default to T=0.
00078  *
00079  * IFDSetPTS() is _always_ called so that the driver can initialise its data
00080  */
00081 
00082 DWORD PHSetProtocol(struct ReaderContext * rContext,
00083     DWORD dwPreferred, UCHAR ucAvailable, UCHAR ucDefault)
00084 {
00085     DWORD protocol;
00086     LONG rv;
00087     UCHAR ucChosen;
00088 
00089     /* App has specified no protocol */
00090     if (dwPreferred == 0)
00091         return SET_PROTOCOL_WRONG_ARGUMENT;
00092 
00093     /* requested protocol is not available */
00094     if (! (dwPreferred & ucAvailable))
00095     {
00096         /* Note:
00097          * dwPreferred must be either SCARD_PROTOCOL_T0 or SCARD_PROTOCOL_T1
00098          * if dwPreferred == SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 the test
00099          * (SCARD_PROTOCOL_T0 == dwPreferred) will not work as expected
00100          * and the debug message will not be correct.
00101          *
00102          * This case may only occur if
00103          * dwPreferred == SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1
00104          * and ucAvailable == 0 since we have (dwPreferred & ucAvailable) == 0
00105          * and the case ucAvailable == 0 should never occur (the card is at
00106          * least T=0 or T=1)
00107          */
00108         Log2(PCSC_LOG_ERROR, "Protocol T=%d requested but unsupported by the card",
00109             (SCARD_PROTOCOL_T0 == dwPreferred) ? 0 : 1);
00110         return SET_PROTOCOL_WRONG_ARGUMENT;
00111     }
00112 
00113     /* set default value */
00114     protocol = ucDefault;
00115 
00116     /* keep only the available protocols */
00117     dwPreferred &= ucAvailable;
00118 
00119     /* we try to use T=1 first */
00120     if (dwPreferred & SCARD_PROTOCOL_T1)
00121         ucChosen = SCARD_PROTOCOL_T1;
00122     else
00123         if (dwPreferred & SCARD_PROTOCOL_T0)
00124             ucChosen = SCARD_PROTOCOL_T0;
00125         else
00126             /* App wants unsupported protocol */
00127             return SET_PROTOCOL_WRONG_ARGUMENT;
00128 
00129     Log2(PCSC_LOG_INFO, "Attempting PTS to T=%d",
00130         (SCARD_PROTOCOL_T0 == ucChosen ? 0 : 1));
00131     rv = IFDSetPTS(rContext, ucChosen, 0x00, 0x00, 0x00, 0x00);
00132 
00133     if (IFD_SUCCESS == rv)
00134         protocol = ucChosen;
00135     else
00136         if (IFD_NOT_SUPPORTED == rv)
00137             Log2(PCSC_LOG_INFO, "PTS not supported by driver, using T=%d",
00138                 (SCARD_PROTOCOL_T0 == protocol) ? 0 : 1);
00139         else
00140             if (IFD_PROTOCOL_NOT_SUPPORTED == rv)
00141                 Log2(PCSC_LOG_INFO, "PTS protocol not supported, using T=%d",
00142                     (SCARD_PROTOCOL_T0 == protocol) ? 0 : 1);
00143             else
00144             {
00145                 Log3(PCSC_LOG_INFO, "PTS failed (%d), using T=%d", rv,
00146                     (SCARD_PROTOCOL_T0 == protocol) ? 0 : 1);
00147 
00148                 /* ISO 7816-3:1997 ch. 7.2 PPS protocol page 14
00149                  * - If the PPS exchange is unsuccessful, then the interface device
00150                  *   shall either reset or reject the card.
00151                  */
00152                 return SET_PROTOCOL_PPS_FAILED;
00153             }
00154 
00155     return protocol;
00156 }
00157 

Generated on Thu Jul 15 08:32:42 2010 for pcsc-lite by  doxygen 1.4.7