-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathscanner.c
145 lines (112 loc) · 4.07 KB
/
scanner.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*************************************
* scanner.c
**************************************
* waits until card is present,
* reads ID and prints it to stdout.
* Program loops until it's killed.
*************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <PCSC/winscard.h>
#define COOL_DOWN_TIME 3
#define CHECK(f, rv) \
if (SCARD_S_SUCCESS != rv) \
{ \
fprintf(stderr, f ": %s\n", pcsc_stringify_error(rv)); \
return -1; \
}
void scanner_error(char* funcname, const char* error)
{
fprintf(stderr, "%s : %s\n",funcname, error);
exit(1);
}
int main(void)
{
LONG rv;
SCARDCONTEXT hContext;
DWORD dwReaders = SCARD_AUTOALLOCATE;
LPTSTR mszReaders = NULL;
SCARDHANDLE hCard;
DWORD dwActiveProtocol, dwRecvLength;
SCARD_READERSTATE rgReaderState;
DWORD cReaders = 1;
SCARD_IO_REQUEST pioSendPci;
BYTE pbRecvBuffer[258];
BYTE cmd_get_data[] = { 0xFF, 0xCA, 0x00, 0x00, 0x00}; //GET UID APDU format
unsigned int i;
DWORD present;
// init context
if((rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext)) != SCARD_S_SUCCESS)
scanner_error("SCardEstablishContext", pcsc_stringify_error(rv));
// get readerslist
if((rv = SCardListReaders(hContext, NULL, (LPSTR)&mszReaders, &dwReaders)) != SCARD_S_SUCCESS)
scanner_error("SCardListReaders" , pcsc_stringify_error(rv));
//setup state
//printf("reader name: %s\n", mszReaders);
rgReaderState.szReader = mszReaders;
rgReaderState.dwCurrentState = SCARD_STATE_UNAWARE;
rgReaderState.dwEventState = SCARD_STATE_UNAWARE;
rgReaderState.cbAtr = MAX_ATR_SIZE;
//get state
if((rv = SCardGetStatusChange(hContext, INFINITE, &rgReaderState, cReaders)) != SCARD_S_SUCCESS)
scanner_error("SCardGetStatusChange" , pcsc_stringify_error(rv));
rgReaderState.dwCurrentState = rgReaderState.dwEventState;
while (1) {
if((rv = SCardGetStatusChange(hContext, INFINITE, &rgReaderState, cReaders)) != SCARD_S_SUCCESS)
scanner_error("SCardGetStatusChange" , pcsc_stringify_error(rv));
present = rgReaderState.dwEventState & SCARD_STATE_PRESENT;
if (!present) { //loop if no card present
rgReaderState.dwCurrentState = rgReaderState.dwEventState;
continue;
}
//print attributes
for(i=0; i<rgReaderState.cbAtr; i++)
printf("%02X", rgReaderState.rgbAtr[i]);
printf("-");
rv = SCardConnect( hContext,
mszReaders,
SCARD_SHARE_SHARED,
(SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1),
&hCard,
&dwActiveProtocol);
if(rv != SCARD_S_SUCCESS)
scanner_error("SCardConnect", pcsc_stringify_error(rv));
switch(dwActiveProtocol)
{
case SCARD_PROTOCOL_T0:
pioSendPci = *SCARD_PCI_T0;
break;
case SCARD_PROTOCOL_T1:
pioSendPci = *SCARD_PCI_T1;
break;
}
dwRecvLength = sizeof(pbRecvBuffer);
//send 'get data' command to receive UID
rv = SCardTransmit(hCard,
&pioSendPci,
cmd_get_data,
sizeof(cmd_get_data),
NULL,
pbRecvBuffer,
&dwRecvLength);
if(rv != SCARD_S_SUCCESS)
scanner_error("SCardTransmit", pcsc_stringify_error(rv));
//print response
//printf("response: ");
for(i=0; i<dwRecvLength-2; i++)
printf("%02X", pbRecvBuffer[i]);
printf("\n");
fflush(stdout);
rv = SCardDisconnect(hCard, SCARD_LEAVE_CARD);
if(rv != SCARD_S_SUCCESS)
scanner_error("SCardDisconnect", pcsc_stringify_error(rv));
sleep(COOL_DOWN_TIME);
}
//unreachable code!
free(mszReaders);
rv = SCardReleaseContext(hContext);
if(rv != SCARD_S_SUCCESS)
scanner_error("SCardReleaseContext", pcsc_stringify_error(rv));
return 0;
}