pcsc-lite  1.8.3
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 5861 2011-07-09 11:30:36Z 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 
00039 DWORD PHSetProtocol(struct ReaderContext * rContext,
00040     DWORD dwPreferred, UCHAR ucAvailable, UCHAR ucDefault)
00041 {
00042     DWORD protocol;
00043     LONG rv;
00044     UCHAR ucChosen;
00045 
00046     /* App has specified no protocol */
00047     if (dwPreferred == 0)
00048         return SET_PROTOCOL_WRONG_ARGUMENT;
00049 
00050     /* requested protocol is not available */
00051     if (! (dwPreferred & ucAvailable))
00052     {
00053         /* Note:
00054          * dwPreferred must be either SCARD_PROTOCOL_T0 or SCARD_PROTOCOL_T1
00055          * if dwPreferred == SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 the test
00056          * (SCARD_PROTOCOL_T0 == dwPreferred) will not work as expected
00057          * and the debug message will not be correct.
00058          *
00059          * This case may only occur if
00060          * dwPreferred == SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1
00061          * and ucAvailable == 0 since we have (dwPreferred & ucAvailable) == 0
00062          * and the case ucAvailable == 0 should never occur (the card is at
00063          * least T=0 or T=1)
00064          */
00065         Log2(PCSC_LOG_ERROR, "Protocol T=%d requested but unsupported by the card",
00066             (SCARD_PROTOCOL_T0 == dwPreferred) ? 0 : 1);
00067         return SET_PROTOCOL_WRONG_ARGUMENT;
00068     }
00069 
00070     /* set default value */
00071     protocol = ucDefault;
00072 
00073     /* keep only the available protocols */
00074     dwPreferred &= ucAvailable;
00075 
00076     /* we try to use T=1 first */
00077     if (dwPreferred & SCARD_PROTOCOL_T1)
00078         ucChosen = SCARD_PROTOCOL_T1;
00079     else
00080         if (dwPreferred & SCARD_PROTOCOL_T0)
00081             ucChosen = SCARD_PROTOCOL_T0;
00082         else
00083             /* App wants unsupported protocol */
00084             return SET_PROTOCOL_WRONG_ARGUMENT;
00085 
00086     Log2(PCSC_LOG_INFO, "Attempting PTS to T=%d",
00087         (SCARD_PROTOCOL_T0 == ucChosen ? 0 : 1));
00088     rv = IFDSetPTS(rContext, ucChosen, 0x00, 0x00, 0x00, 0x00);
00089 
00090     if (IFD_SUCCESS == rv)
00091         protocol = ucChosen;
00092     else
00093         if (IFD_NOT_SUPPORTED == rv)
00094             Log2(PCSC_LOG_INFO, "PTS not supported by driver, using T=%d",
00095                 (SCARD_PROTOCOL_T0 == protocol) ? 0 : 1);
00096         else
00097             if (IFD_PROTOCOL_NOT_SUPPORTED == rv)
00098                 Log2(PCSC_LOG_INFO, "PTS protocol not supported, using T=%d",
00099                     (SCARD_PROTOCOL_T0 == protocol) ? 0 : 1);
00100             else
00101             {
00102                 Log3(PCSC_LOG_INFO, "PTS failed (%ld), using T=%d", rv,
00103                     (SCARD_PROTOCOL_T0 == protocol) ? 0 : 1);
00104 
00105                 /* ISO 7816-3:1997 ch. 7.2 PPS protocol page 14
00106                  * - If the PPS exchange is unsuccessful, then the interface device
00107                  *   shall either reset or reject the card.
00108                  */
00109                 return SET_PROTOCOL_PPS_FAILED;
00110             }
00111 
00112     return protocol;
00113 }
00114