pcsc-lite  1.7.4
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-2011
00007  *  Ludovic Rousseau <ludovic.rousseau@free.fr>
00008  *
00009  * $Id: prothandler.c 5711 2011-05-05 09:02:08Z rousseau $
00010  */
00011 
00017 #include "config.h"
00018 #include <string.h>
00019 
00020 #include "misc.h"
00021 #include "pcscd.h"
00022 #include "debuglog.h"
00023 #include "readerfactory.h"
00024 #include "prothandler.h"
00025 #include "atrhandler.h"
00026 #include "ifdwrapper.h"
00027 #include "eventhandler.h"
00028 
00034 UCHAR PHGetDefaultProtocol(PUCHAR pucAtr, DWORD dwLength)
00035 {
00036     SMARTCARD_EXTENSION sSmartCard;
00037 
00038     /*
00039      * Zero out everything
00040      */
00041     memset(&sSmartCard, 0x00, sizeof(SMARTCARD_EXTENSION));
00042 
00043     if (ATRDecodeAtr(&sSmartCard, pucAtr, dwLength))
00044         return sSmartCard.CardCapabilities.CurrentProtocol;
00045     else
00046         return 0x00;
00047 }
00048 
00054 UCHAR PHGetAvailableProtocols(PUCHAR pucAtr, DWORD dwLength)
00055 {
00056     SMARTCARD_EXTENSION sSmartCard;
00057 
00058     /*
00059      * Zero out everything
00060      */
00061     memset(&sSmartCard, 0x00, sizeof(SMARTCARD_EXTENSION));
00062 
00063     if (ATRDecodeAtr(&sSmartCard, pucAtr, dwLength))
00064         return sSmartCard.CardCapabilities.AvailableProtocols;
00065     else
00066         return 0x00;
00067 }
00068 
00079 DWORD PHSetProtocol(struct ReaderContext * rContext,
00080     DWORD dwPreferred, UCHAR ucAvailable, UCHAR ucDefault)
00081 {
00082     DWORD protocol;
00083     LONG rv;
00084     UCHAR ucChosen;
00085 
00086     /* App has specified no protocol */
00087     if (dwPreferred == 0)
00088         return SET_PROTOCOL_WRONG_ARGUMENT;
00089 
00090     /* requested protocol is not available */
00091     if (! (dwPreferred & ucAvailable))
00092     {
00093         /* Note:
00094          * dwPreferred must be either SCARD_PROTOCOL_T0 or SCARD_PROTOCOL_T1
00095          * if dwPreferred == SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 the test
00096          * (SCARD_PROTOCOL_T0 == dwPreferred) will not work as expected
00097          * and the debug message will not be correct.
00098          *
00099          * This case may only occur if
00100          * dwPreferred == SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1
00101          * and ucAvailable == 0 since we have (dwPreferred & ucAvailable) == 0
00102          * and the case ucAvailable == 0 should never occur (the card is at
00103          * least T=0 or T=1)
00104          */
00105         Log2(PCSC_LOG_ERROR, "Protocol T=%d requested but unsupported by the card",
00106             (SCARD_PROTOCOL_T0 == dwPreferred) ? 0 : 1);
00107         return SET_PROTOCOL_WRONG_ARGUMENT;
00108     }
00109 
00110     /* set default value */
00111     protocol = ucDefault;
00112 
00113     /* keep only the available protocols */
00114     dwPreferred &= ucAvailable;
00115 
00116     /* we try to use T=1 first */
00117     if (dwPreferred & SCARD_PROTOCOL_T1)
00118         ucChosen = SCARD_PROTOCOL_T1;
00119     else
00120         if (dwPreferred & SCARD_PROTOCOL_T0)
00121             ucChosen = SCARD_PROTOCOL_T0;
00122         else
00123             /* App wants unsupported protocol */
00124             return SET_PROTOCOL_WRONG_ARGUMENT;
00125 
00126     Log2(PCSC_LOG_INFO, "Attempting PTS to T=%d",
00127         (SCARD_PROTOCOL_T0 == ucChosen ? 0 : 1));
00128     rv = IFDSetPTS(rContext, ucChosen, 0x00, 0x00, 0x00, 0x00);
00129 
00130     if (IFD_SUCCESS == rv)
00131         protocol = ucChosen;
00132     else
00133         if (IFD_NOT_SUPPORTED == rv)
00134             Log2(PCSC_LOG_INFO, "PTS not supported by driver, using T=%d",
00135                 (SCARD_PROTOCOL_T0 == protocol) ? 0 : 1);
00136         else
00137             if (IFD_PROTOCOL_NOT_SUPPORTED == rv)
00138                 Log2(PCSC_LOG_INFO, "PTS protocol not supported, using T=%d",
00139                     (SCARD_PROTOCOL_T0 == protocol) ? 0 : 1);
00140             else
00141             {
00142                 Log3(PCSC_LOG_INFO, "PTS failed (%d), using T=%d", rv,
00143                     (SCARD_PROTOCOL_T0 == protocol) ? 0 : 1);
00144 
00145                 /* ISO 7816-3:1997 ch. 7.2 PPS protocol page 14
00146                  * - If the PPS exchange is unsuccessful, then the interface device
00147                  *   shall either reset or reject the card.
00148                  */
00149                 return SET_PROTOCOL_PPS_FAILED;
00150             }
00151 
00152     return protocol;
00153 }
00154