source: branches/smartreader/reader-pcsc.c@ 1007

Last change on this file since 1007 was 1007, checked in by rorothetroll, 13 years ago

resync with trunk

File size: 7.6 KB
Line 
1#ifdef HAVE_PCSC
2
3#include "reader-pcsc.h"
4int pcsc_reader_init(struct s_reader *pcsc_reader, char *device)
5{
6 ULONG rv;
7 DWORD dwReaders;
8 LPSTR mszReaders = NULL;
9 char *ptr, **readers = NULL;
10 int nbReaders;
11 int reader_nb;
12
13 cs_debug("PCSC establish context for PCSC reader %s", device);
14 rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &pcsc_reader->hContext);
15 if ( rv == SCARD_S_SUCCESS ) {
16 // here we need to list the pcsc readers and get the name from there,
17 // the pcsc_reader->device should contain the reader number
18 // and after the actual device name is copied in pcsc_reader->pcsc_name .
19 rv = SCardListReaders(pcsc_reader->hContext, NULL, NULL, &dwReaders);
20 if( rv != SCARD_S_SUCCESS ) {
21 cs_debug("PCSC failed listing readers [1] : (%lx)", rv);
22 return 0;
23 }
24 mszReaders = malloc(sizeof(char)*dwReaders);
25 if (mszReaders == NULL) {
26 cs_debug("PCSC failed malloc");
27 return 0;
28 }
29 rv = SCardListReaders(pcsc_reader->hContext, NULL, mszReaders, &dwReaders);
30 if( rv != SCARD_S_SUCCESS ) {
31 cs_debug("PCSC failed listing readers [2]: (%lx)", rv);
32 return 0;
33 }
34 /* Extract readers from the null separated string and get the total
35 * number of readers */
36 nbReaders = 0;
37 ptr = mszReaders;
38 while (*ptr != '\0') {
39 ptr += strlen(ptr)+1;
40 nbReaders++;
41 }
42
43 if (nbReaders == 0) {
44 cs_debug("PCSC : no reader found");
45 return 0;
46 }
47
48 readers = calloc(nbReaders, sizeof(char *));
49 if (readers == NULL) {
50 cs_debug("PCSC failed malloc");
51 return 0;
52 }
53
54 /* fill the readers table */
55 nbReaders = 0;
56 ptr = mszReaders;
57 while (*ptr != '\0') {
58 cs_debug("PCSC reader %d: %s", nbReaders, ptr);
59 readers[nbReaders] = ptr;
60 ptr += strlen(ptr)+1;
61 nbReaders++;
62 }
63
64 reader_nb=atoi((const char *)&pcsc_reader->device);
65 if (reader_nb < 0 || reader_nb >= nbReaders) {
66 cs_debug("Wrong reader index: %d\n", reader_nb);
67 return 0;
68 }
69
70 snprintf(pcsc_reader->pcsc_name,sizeof(pcsc_reader->pcsc_name),"%s",readers[reader_nb]);
71 pcsc_reader->pcsc_has_card=0;
72 pcsc_reader->hCard=0;
73 }
74 else {
75 cs_debug("PCSC failed establish context (%lx)", rv);
76 }
77
78 return 0;
79}
80
81int pcsc_reader_do_api(struct s_reader *pcsc_reader, uchar *buf, uchar *cta_res, ushort *cta_lr, int l, int dbg)
82{
83 ULONG rv;
84 SCARD_IO_REQUEST pioRecvPci;
85 DWORD dwSendLength, dwRecvLength;
86 if(buf[4])
87 dwSendLength = l;
88 else
89 dwSendLength = l-1;
90
91 dwRecvLength = CTA_RES_LEN;
92 cs_debug("sending %d bytes to PCSC", dwSendLength);
93
94 if(pcsc_reader->dwActiveProtocol == SCARD_PROTOCOL_T0) {
95 rv = SCardTransmit(pcsc_reader->hCard, SCARD_PCI_T0, buf, dwSendLength, &pioRecvPci, cta_res, &dwRecvLength);
96 }
97 else if(pcsc_reader->dwActiveProtocol == SCARD_PROTOCOL_T1) {
98 rv = SCardTransmit(pcsc_reader->hCard, SCARD_PCI_T1, buf, dwSendLength, &pioRecvPci, cta_res, &dwRecvLength);
99 }
100 else {
101 cs_debug("PCSC invalid protocol (T=%d)", pcsc_reader->dwActiveProtocol);
102 return ERR_INVALID;
103 }
104
105 *cta_lr=dwRecvLength;
106 cs_debug("received %d bytes from PCSC with rv=%lx", *cta_lr, rv);
107
108 cs_debug("PCSC doapi (%lx ) (T=%d), %d", rv, ( pcsc_reader->dwActiveProtocol == SCARD_PROTOCOL_T0 ? 0 : 1), dwRecvLength );
109 if ( rv == SCARD_S_SUCCESS ){
110 return OK;
111 }
112 else {
113 return ERR_INVALID;
114 }
115
116}
117
118int pcsc_activate_card(struct s_reader *pcsc_reader, uchar *atr, ushort *atr_size)
119{
120 ULONG rv;
121 DWORD dwState, dwAtrLen, dwReaderLen;
122 BYTE pbAtr[64];
123
124 cs_debug("PCSC initializing card in (%s)", pcsc_reader->pcsc_name);
125 dwAtrLen = sizeof(pbAtr);
126 dwReaderLen=0;
127
128 cs_debug("PCSC resetting card in (%s)", pcsc_reader->pcsc_name);
129 rv = SCardReconnect(pcsc_reader->hCard, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, SCARD_RESET_CARD, &pcsc_reader->dwActiveProtocol);
130 cs_debug("PCSC resetting done on card in (%s)", pcsc_reader->pcsc_name);
131 cs_debug("PCSC Protocol (T=%d)",( pcsc_reader->dwActiveProtocol == SCARD_PROTOCOL_T0 ? 0 : 1));
132
133 if ( rv != SCARD_S_SUCCESS ) {
134 cs_debug("Error PCSC failed to reset card (%lx)", rv);
135 return(0);
136 }
137
138
139 cs_debug("PCSC getting ATR for card in (%s)", pcsc_reader->pcsc_name);
140 rv = SCardStatus(pcsc_reader->hCard,NULL, &dwReaderLen, &dwState, &pcsc_reader->dwActiveProtocol, pbAtr, &dwAtrLen);
141 if ( rv == SCARD_S_SUCCESS ) {
142 cs_debug("PCSC Protocol (T=%d)",( pcsc_reader->dwActiveProtocol == SCARD_PROTOCOL_T0 ? 0 : 1));
143 memcpy(atr, pbAtr, dwAtrLen);
144 *atr_size=dwAtrLen;
145#ifdef CS_RDR_INIT_HIST
146 pcsc_reader->init_history_pos=0;
147 memset(pcsc_reader->init_history, 0, sizeof(pcsc_reader->init_history));
148#endif
149 cs_ri_log("ATR: %s", cs_hexdump(1, (uchar *)pbAtr, dwAtrLen));
150 return(1);
151 }
152 else {
153 cs_debug("Error PCSC failed to get ATR for card (%lx)", rv);
154 }
155
156 return(0);
157}
158
159
160int pcsc_check_card_inserted(struct s_reader *pcsc_reader)
161{
162 DWORD dwState, dwAtrLen, dwReaderLen;
163 BYTE pbAtr[64];
164 ULONG rv;
165
166 dwAtrLen = sizeof(pbAtr);
167 rv=0;
168 dwState=0;
169 dwReaderLen=0;
170
171 // Do we have a card ?
172 if (!pcsc_reader->pcsc_has_card && !pcsc_reader->hCard) {
173 // try connecting to the card
174 rv = SCardConnect(pcsc_reader->hContext, pcsc_reader->pcsc_name, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &pcsc_reader->hCard, &pcsc_reader->dwActiveProtocol);
175 if (rv==SCARD_E_NO_SMARTCARD) {
176 // no card in reader
177 pcsc_reader->pcsc_has_card=0;
178 if(pcsc_reader->hCard) {
179 SCardDisconnect(pcsc_reader->hCard,SCARD_RESET_CARD);
180 pcsc_reader->hCard=0;
181 }
182 cs_debug("PCSC card in %s removed / absent [dwstate=%lx rv=(%lx)]", pcsc_reader->pcsc_name, dwState, rv );
183 return 0;
184 }
185 else if( rv == SCARD_W_UNRESPONSIVE_CARD ) {
186 // there is a problem with the card in the reader
187 pcsc_reader->pcsc_has_card=0;
188 pcsc_reader->hCard=0;
189 cs_log("PCSC card in %s is unresponsive. Eject and re-insert please.", pcsc_reader->pcsc_name);
190 return 0;
191 }
192 else if( rv == SCARD_S_SUCCESS ) {
193 // we have a card
194 pcsc_reader->pcsc_has_card=1;
195 }
196 else {
197 // if we get here we have a bigger problem -> display status and debug
198 cs_debug("PCSC reader %s status [dwstate=%lx rv=(%lx)]", pcsc_reader->pcsc_name, dwState, rv );
199 return 0;
200 }
201
202 }
203
204 // if we get there the card is ready, check its status
205 rv = SCardStatus(pcsc_reader->hCard, NULL, &dwReaderLen, &dwState, &pcsc_reader->dwActiveProtocol, pbAtr, &dwAtrLen);
206
207 if (rv == SCARD_S_SUCCESS && (dwState & (SCARD_PRESENT | SCARD_NEGOTIABLE | SCARD_POWERED ) )) {
208 cs_debug("PCSC card IS inserted in %s card state [dwstate=%lx rv=(%lx)]", pcsc_reader->pcsc_name, dwState,rv);
209 return CARD_INSERTED;
210 }
211 else {
212 SCardDisconnect(pcsc_reader->hCard,SCARD_RESET_CARD);
213 pcsc_reader->hCard=0;
214 pcsc_reader->pcsc_has_card=0;
215 cs_debug("PCSC card in %s removed / absent [dwstate=%lx rv=(%lx)]", pcsc_reader->pcsc_name, dwState, rv );
216 }
217
218 return 0;
219}
220#endif
221
Note: See TracBrowser for help on using the repository browser.