move include directory for pkginclude compliance
[librfid] / utils / openct-escape.c
1 /*                                                 -*- linux-c -*-
2  *  This program is free software; you can redistribute it and/or modify
3  *  it under the terms of the GNU General Public License version 2 
4  *  as published by the Free Software Foundation
5  *
6  *  This program is distributed in the hope that it will be useful,
7  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
8  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9  *  GNU General Public License for more details.
10  *
11  *  You should have received a copy of the GNU General Public License
12  *  along with this program; if not, write to the Free Software
13  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
14  */
15
16 #include <stdio.h>
17 #include <unistd.h>
18 #include <stdlib.h>
19 #include <string.h>
20
21 #include <librfid/rfid.h>
22 #include <librfid/rfid_reader.h>
23 #include <librfid/rfid_layer2.h>
24 #include <librfid/rfid_protocol.h>
25
26 #include <librfid/rfid_protocol_mifare_classic.h>
27 #include <librfid/rfid_protocol_mifare_ul.h>
28
29 static struct rfid_reader_handle *rh;
30 static struct rfid_layer2_handle *l2h;
31 static struct rfid_protocol_handle *ph;
32
33 static int init()
34 {
35         unsigned char buf[0x3f];
36         int rc;
37
38         printf("initializing librfid\n");
39         rfid_init();
40
41         printf("opening reader handle\n");
42         rh = rfid_reader_open(NULL, RFID_READER_CM5121);
43         if (!rh) {
44                 fprintf(stderr, "error, no cm5121 handle\n");
45                 return -1;
46         }
47
48         sleep(2);
49
50         printf("opening layer2 handle\n");
51         l2h = rfid_layer2_init(rh, RFID_LAYER2_ISO14443A);
52         //l2h = rfid_layer2_init(rh, RFID_LAYER2_ISO14443B);
53         if (!l2h) {
54                 fprintf(stderr, "error during iso14443a_init\n");
55                 return -1;
56         }
57
58         //rc632_register_dump(rh->ah, buf);
59
60         printf("running layer2 anticol\n");
61         rc = rfid_layer2_open(l2h);
62         if (rc < 0) {
63                 fprintf(stderr, "error during layer2_open\n");
64                 return rc;
65         }
66
67         return 0;
68 }
69
70 static int l3(int protocol)
71 {
72         printf("running layer3 (ats)\n");
73         ph = rfid_protocol_init(l2h, protocol);
74         if (!ph) {
75                 fprintf(stderr, "error during protocol_init\n");
76                 return -1;
77         }
78         if (rfid_protocol_open(ph) < 0) {
79                 fprintf(stderr, "error during protocol_open\n");
80                 return -1;
81         }
82
83         printf("we now have layer3 up and running\n");
84
85         return 0;
86 }
87
88 static int select_mf(void)
89 {
90         unsigned char cmd[] = { 0x00, 0xa4, 0x00, 0x00, 0x02, 0x3f, 0x00, 0x00 };
91         unsigned char ret[256];
92         unsigned int rlen = sizeof(ret);
93
94         int rv;
95
96         rv = rfid_protocol_transcieve(ph, cmd, sizeof(cmd), ret, &rlen, 0, 0);
97         if (rv < 0)
98                 return rv;
99
100         printf("%s\n", rfid_hexdump(ret, rlen));
101
102         return 0;
103 }
104
105
106 static int iso7816_get_challenge(unsigned char len)
107 {
108         unsigned char cmd[] = { 0x00, 0x84, 0x00, 0x00, 0x08 };
109         unsigned char ret[256];
110         unsigned int rlen = sizeof(ret);
111
112         cmd[4] = len;
113
114         int rv;
115
116         rv = rfid_protocol_transcieve(ph, cmd, sizeof(cmd), ret, &rlen, 0, 0);
117         if (rv < 0)
118                 return rv;
119
120         printf("%d: [%s]\n", rlen, rfid_hexdump(ret, rlen));
121
122         return 0;
123 }
124
125 int
126 iso7816_select_application(void)
127 {
128         unsigned char cmd[] = { 0x00, 0xa4, 0x04, 0x0c, 0x07,
129                        0xa0, 0x00, 0x00, 0x02, 0x47, 0x10, 0x01 };
130         unsigned char resp[7];
131         unsigned int rlen = sizeof(resp);
132
133         int rv;
134
135         rv = rfid_protocol_transcieve(ph, cmd, sizeof(cmd), resp, &rlen, 0, 0);
136         if (rv < 0)
137                 return rv;
138
139         /* FIXME: parse response */
140         printf("%s\n", rfid_hexdump(resp, rlen));
141
142         return 0;
143 }
144
145 int
146 iso7816_select_ef(u_int16_t fid)
147 {
148         unsigned char cmd[7] = { 0x00, 0xa4, 0x02, 0x0c, 0x02, 0x00, 0x00 };
149         unsigned char resp[7];
150         unsigned int rlen = sizeof(resp);
151
152         int rv;
153
154         cmd[5] = (fid >> 8) & 0xff;
155         cmd[6] = fid & 0xff;
156
157         rv = rfid_protocol_transcieve(ph, cmd, sizeof(cmd), resp, &rlen, 0, 0);
158         if (rv < 0)
159                 return rv;
160
161         /* FIXME: parse response */
162         printf("%s\n", rfid_hexdump(resp, rlen));
163
164         return 0;
165 }
166
167 int
168 iso7816_read_binary(unsigned char *buf, unsigned int *len)
169 {
170         unsigned char cmd[] = { 0x00, 0xb0, 0x00, 0x00, 0x00 };
171         unsigned char resp[256];
172         unsigned int rlen = sizeof(resp);
173         
174         int rv;
175
176         rv = rfid_protocol_transcieve(ph, cmd, sizeof(cmd), resp, &rlen, 0, 0);
177         if (rv < 0)
178                 return rv;
179
180         /* FIXME: parse response, determine whether we need additional reads */
181
182         /* FIXME: copy 'len' number of response bytes to 'buf' */
183         return 0;
184 }
185
186 /* wrapper function around SELECT EF and READ BINARY */
187 int
188 iso7816_read_ef(u_int16_t fid, unsigned char *buf, unsigned int *len)
189 {
190         int rv;
191
192         rv = iso7816_select_ef(fid);
193         if (rv < 0)
194                 return rv;
195
196         return iso7816_read_binary(buf, len);
197 }
198
199 /* mifare ultralight helpers */
200 int
201 mifare_ulight_write(struct rfid_protocol_handle *ph)
202 {
203         unsigned char buf[4] = { 0xa1, 0xa2, 0xa3, 0xa4 };
204
205         return rfid_protocol_write(ph, 10, buf, 4);
206 }
207
208 int
209 mifare_ulight_blank(struct rfid_protocol_handle *ph)
210 {
211         unsigned char buf[4] = { 0x00, 0x00, 0x00, 0x00 };
212         int i, ret;
213
214         for (i = 4; i <= MIFARE_UL_PAGE_MAX; i++) {
215                 ret = rfid_protocol_write(ph, i, buf, 4);
216                 if (ret < 0)
217                         return ret;
218         }
219         return 0;
220 }
221
222 static int
223 mifare_ulight_read(struct rfid_protocol_handle *ph)
224 {
225         unsigned char buf[20];
226         unsigned int len = sizeof(buf);
227         int ret;
228         int i;
229
230         for (i = 0; i <= MIFARE_UL_PAGE_MAX; i++) {
231                 ret = rfid_protocol_read(ph, i, buf, &len);
232                 if (ret < 0)
233                         return ret;
234
235                 printf("Page 0x%x: %s\n", i, rfid_hexdump(buf, 4));
236         }
237         return 0;
238 }
239
240 /* mifare classic helpers */
241 static int
242 mifare_classic_read(struct rfid_protocol_handle *ph)
243 {
244         unsigned char buf[20];
245         unsigned int len = sizeof(buf);
246         int ret;
247         int i;
248
249         for (i = 0; i <= MIFARE_CL_PAGE_MAX; i++) {
250                 ret = rfid_protocol_read(ph, i, buf, &len);
251                 if (ret < 0)
252                         return ret;
253
254                 printf("Page 0x%x: %s\n", i, rfid_hexdump(buf, len));
255         }
256         return 0;
257 }
258
259
260 int main(int argc, char **argv)
261 {
262         int rc;
263         char buf[0x40];
264         int i, protocol;
265
266 #if 0
267         if (argc) {
268                 argc--;
269                 argv++;
270         }
271         
272         while (argc) {
273                 if ( !strcmp (*argv, "--list")) {
274                         char *p;
275                         p = ccid_get_reader_list ();
276                         if (!p)
277                                 return 1;
278                         fputs (p, stderr);
279                         free (p);
280                         return 0;
281                 }
282                 else if ( !strcmp (*argv, "--debug")) {
283                         ccid_set_debug_level (ccid_set_debug_level (-1) + 1);
284                         argc--; argv++;
285                 }
286                 else
287                         break;
288         }
289 #endif
290
291         if (init() < 0)
292                 exit(1);
293
294         //protocol = RFID_PROTOCOL_MIFARE_UL;
295         //protocol = RFID_PROTOCOL_MIFARE_CLASSIC;
296         protocol = RFID_PROTOCOL_TCL;
297
298         if (l3(protocol) < 0)
299                 exit(1);
300
301         switch (protocol) {
302         case RFID_PROTOCOL_TCL:
303                 /* we've established T=CL at this point */
304                 select_mf();
305
306                 iso7816_select_application();
307                 iso7816_select_ef(0x011e);
308                 iso7816_select_ef(0x0101);
309 #if 1
310                 for (i = 0; i < 4; i++)
311                         iso7816_get_challenge(0x06);
312 #endif
313                 break;
314         case RFID_PROTOCOL_MIFARE_UL:
315                 mifare_ulight_read(ph);
316 #if 0
317                 mifare_ulight_blank(ph);
318                 mifare_ulight_write(ph);
319                 mifare_ulight_read(ph);
320 #endif
321                 break;
322         case RFID_PROTOCOL_MIFARE_CLASSIC:
323                 rc = mfcl_set_key(ph, MIFARE_CL_KEYA_DEFAULT_INFINEON);
324                 if (rc < 0) {
325                         printf("key format error\n");
326                         exit(1);
327                 }
328                 rc = mfcl_auth(ph, RFID_CMD_MIFARE_AUTH1A, 0);
329                 if (rc < 0) {
330                         printf("mifare auth error\n");
331                         exit(1);
332                 } else 
333                         printf("mifare authe succeeded!\n");
334                 mifare_classic_read(ph);
335                 break;
336         }
337
338         rfid_reader_close(rh);
339         
340         exit(0);
341 }