pcsc-lite  1.8.8
prothandler.c
Go to the documentation of this file.
1 /*
2  * MUSCLE SmartCard Development ( http://www.linuxnet.com )
3  *
4  * Copyright (C) 1999
5  * David Corcoran <corcoran@linuxnet.com>
6  * Copyright (C) 2004-2011
7  * Ludovic Rousseau <ludovic.rousseau@free.fr>
8  *
9  * $Id: prothandler.c 5861 2011-07-09 11:30:36Z rousseau $
10  */
11 
17 #include "config.h"
18 #include <string.h>
19 
20 #include "misc.h"
21 #include "pcscd.h"
22 #include "debuglog.h"
23 #include "readerfactory.h"
24 #include "prothandler.h"
25 #include "atrhandler.h"
26 #include "ifdwrapper.h"
27 #include "eventhandler.h"
28 
39 DWORD PHSetProtocol(struct ReaderContext * rContext,
40  DWORD dwPreferred, UCHAR ucAvailable, UCHAR ucDefault)
41 {
42  DWORD protocol;
43  LONG rv;
44  UCHAR ucChosen;
45 
46  /* App has specified no protocol */
47  if (dwPreferred == 0)
48  return SET_PROTOCOL_WRONG_ARGUMENT;
49 
50  /* requested protocol is not available */
51  if (! (dwPreferred & ucAvailable))
52  {
53  /* Note:
54  * dwPreferred must be either SCARD_PROTOCOL_T0 or SCARD_PROTOCOL_T1
55  * if dwPreferred == SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 the test
56  * (SCARD_PROTOCOL_T0 == dwPreferred) will not work as expected
57  * and the debug message will not be correct.
58  *
59  * This case may only occur if
60  * dwPreferred == SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1
61  * and ucAvailable == 0 since we have (dwPreferred & ucAvailable) == 0
62  * and the case ucAvailable == 0 should never occur (the card is at
63  * least T=0 or T=1)
64  */
65  Log2(PCSC_LOG_ERROR, "Protocol T=%d requested but unsupported by the card",
66  (SCARD_PROTOCOL_T0 == dwPreferred) ? 0 : 1);
67  return SET_PROTOCOL_WRONG_ARGUMENT;
68  }
69 
70  /* set default value */
71  protocol = ucDefault;
72 
73  /* keep only the available protocols */
74  dwPreferred &= ucAvailable;
75 
76  /* we try to use T=1 first */
77  if (dwPreferred & SCARD_PROTOCOL_T1)
78  ucChosen = SCARD_PROTOCOL_T1;
79  else
80  if (dwPreferred & SCARD_PROTOCOL_T0)
81  ucChosen = SCARD_PROTOCOL_T0;
82  else
83  /* App wants unsupported protocol */
84  return SET_PROTOCOL_WRONG_ARGUMENT;
85 
86  Log2(PCSC_LOG_INFO, "Attempting PTS to T=%d",
87  (SCARD_PROTOCOL_T0 == ucChosen ? 0 : 1));
88  rv = IFDSetPTS(rContext, ucChosen, 0x00, 0x00, 0x00, 0x00);
89 
90  if (IFD_SUCCESS == rv)
91  protocol = ucChosen;
92  else
93  if (IFD_NOT_SUPPORTED == rv)
94  Log2(PCSC_LOG_INFO, "PTS not supported by driver, using T=%d",
95  (SCARD_PROTOCOL_T0 == protocol) ? 0 : 1);
96  else
98  Log2(PCSC_LOG_INFO, "PTS protocol not supported, using T=%d",
99  (SCARD_PROTOCOL_T0 == protocol) ? 0 : 1);
100  else
101  {
102  Log3(PCSC_LOG_INFO, "PTS failed (%ld), using T=%d", rv,
103  (SCARD_PROTOCOL_T0 == protocol) ? 0 : 1);
104 
105  /* ISO 7816-3:1997 ch. 7.2 PPS protocol page 14
106  * - If the PPS exchange is unsuccessful, then the interface device
107  * shall either reset or reject the card.
108  */
109  return SET_PROTOCOL_PPS_FAILED;
110  }
111 
112  return protocol;
113 }
114 
LONG IFDSetPTS(READER_CONTEXT *rContext, DWORD dwProtocol, UCHAR ucFlags, UCHAR ucPTS1, UCHAR ucPTS2, UCHAR ucPTS3)
Set the protocol type selection (PTS).
Definition: ifdwrapper.c:46
#define IFD_NOT_SUPPORTED
request is not supported
Definition: ifdhandler.h:341
This handles protocol defaults, PTS, etc.
This wraps the dynamic ifdhandler functions.
#define SCARD_PROTOCOL_T1
T=1 active protocol.
Definition: pcsclite.h:153
This keeps track of smart card protocols, timing issues and Answer to Reset ATR handling.
#define SCARD_PROTOCOL_T0
T=0 active protocol.
Definition: pcsclite.h:152
This handles card insertion/removal events, updates ATR, protocol, and status information.
DWORD PHSetProtocol(struct ReaderContext *rContext, DWORD dwPreferred, UCHAR ucAvailable, UCHAR ucDefault)
Determine which protocol to use.
Definition: prothandler.c:39
This keeps a list of defines for pcsc-lite.
This keeps track of a list of currently available reader structures.
#define IFD_PROTOCOL_NOT_SUPPORTED
requested protocol not supported
Definition: ifdhandler.h:334
This handles debugging.
#define IFD_SUCCESS
no error
Definition: ifdhandler.h:328