fix various compile warnings. code cleanup
[librfid] / src / rfid_reader_cm5121.c
1 /* Omnikey CardMan 5121 specific RC632 transport layer 
2  *
3  * (C) 2005 by Harald Welte <laforge@gnumonks.org>
4  *
5  * The 5121 is an Atmel AT89C5122 based USB CCID reader (probably the same
6  * design like the 3121).  It's CL RC632 is connected via address/data bus,
7  * not via SPI.
8  *
9  * The vendor-supplied reader firmware provides some undocumented extensions 
10  * to CCID (via PC_to_RDR_Escape) that allow access to registers and FIFO of
11  * the RC632.
12  * 
13  */
14
15 /*
16  *  This program is free software; you can redistribute it and/or modify
17  *  it under the terms of the GNU General Public License version 2 
18  *  as published by the Free Software Foundation
19  *
20  *  This program is distributed in the hope that it will be useful,
21  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  *  GNU General Public License for more details.
24  *
25  *  You should have received a copy of the GNU General Public License
26  *  along with this program; if not, write to the Free Software
27  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28  */
29
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <string.h>
33 #include <errno.h>
34
35 #include <librfid/rfid.h>
36 #include <librfid/rfid_reader.h>
37 #include <librfid/rfid_asic.h>
38 #include <librfid/rfid_asic_rc632.h>
39 #include <librfid/rfid_reader_cm5121.h>
40
41 #include "cm5121_source.h"
42
43 /* FIXME */
44 #include "rc632.h"
45
46 #define SENDBUF_LEN     256+7+10 /* 256bytes max FSD/FSC, plus 7 bytes header,
47                                     plus 10 bytes reserve */
48 #define RECVBUF_LEN     SENDBUF_LEN
49
50 //#define DEBUG_REGISTER
51
52 #ifdef DEBUG_REGISTER
53 #define DEBUGRC DEBUGPC
54 #define DEBUGR DEBUGP
55 #else
56 #define DEBUGRC(x, args ...)    do {} while(0)
57 #define DEBUGR(x, args ...)     do {} while(0)
58 #endif
59
60 static
61 int Write1ByteToReg(struct rfid_asic_transport_handle *rath,
62                     unsigned char reg, unsigned char value)
63 {
64         unsigned char sndbuf[SENDBUF_LEN];
65         unsigned char rcvbuf[RECVBUF_LEN];
66         unsigned int retlen = RECVBUF_LEN;
67
68         sndbuf[0] = 0x20;
69         sndbuf[1] = 0x00;
70         sndbuf[2] = 0x01;
71         sndbuf[3] = 0x00;
72         sndbuf[4] = 0x00;
73         sndbuf[5] = 0x00;
74         sndbuf[6] = reg;
75         sndbuf[7] = value;
76
77         DEBUGR("reg=0x%02x, val=%02x: ", reg, value);
78
79         if (PC_to_RDR_Escape(rath->data, sndbuf, 8, rcvbuf, 
80                              &retlen) == 0) {
81                 DEBUGRC("OK\n");
82                 return 0;
83         }
84
85         DEBUGRC("ERROR\n");
86         return -1;
87 }
88
89 static int Read1ByteFromReg(struct rfid_asic_transport_handle *rath,
90                             unsigned char reg,
91                             unsigned char *value)
92 {
93         unsigned char sndbuf[SENDBUF_LEN];
94         unsigned char recvbuf[RECVBUF_LEN];
95         unsigned int retlen = sizeof(recvbuf);
96
97         sndbuf[0] = 0x20;
98         sndbuf[1] = 0x00;
99         sndbuf[2] = 0x00;
100         sndbuf[3] = 0x00;
101         sndbuf[4] = 0x01;
102         sndbuf[5] = 0x00;
103         sndbuf[6] = reg;
104
105         if (PC_to_RDR_Escape(rath->data, sndbuf, 7, recvbuf, 
106                              &retlen) == 0) {
107                 *value = recvbuf[1];
108                 DEBUGR("reg=0x%02x, val=%02x: ", reg, *value);
109                 DEBUGRC("OK\n");
110                 return 0;
111         }
112
113         DEBUGRC("ERROR\n");
114         return -1;
115 }
116
117 static int ReadNBytesFromFIFO(struct rfid_asic_transport_handle *rath,
118                               unsigned char num_bytes,
119                               unsigned char *buf)
120 {
121         unsigned char sndbuf[SENDBUF_LEN];
122         unsigned char recvbuf[0x7f];
123         unsigned int retlen = sizeof(recvbuf);
124
125         sndbuf[0] = 0x20;
126         sndbuf[1] = 0x00;
127         sndbuf[2] = 0x00;
128         sndbuf[3] = 0x00;
129         sndbuf[4] = num_bytes;
130         sndbuf[5] = 0x00;
131         sndbuf[6] = 0x02;
132
133         DEBUGR("num_bytes=%u: ", num_bytes);
134         if (PC_to_RDR_Escape(rath->data, sndbuf, 7, recvbuf, &retlen) == 0) {
135                 DEBUGRC("%u [%s]\n", retlen,
136                         rfid_hexdump(recvbuf+1, num_bytes));
137                 memcpy(buf, recvbuf+1, num_bytes); // len == 0x7f
138                 return 0;
139         }
140
141         DEBUGRC("ERROR\n");
142         return -1;
143 }
144
145 static int WriteNBytesToFIFO(struct rfid_asic_transport_handle *rath,
146                              unsigned char len,
147                              const unsigned char *bytes,
148                              unsigned char flags)
149 {
150         unsigned char sndbuf[SENDBUF_LEN];
151         unsigned char recvbuf[0x7f];
152         unsigned int retlen = sizeof(recvbuf);
153
154         sndbuf[0] = 0x20;
155         sndbuf[1] = 0x00;
156         sndbuf[2] = len;
157         sndbuf[3] = 0x00;
158         sndbuf[4] = 0x00;
159         sndbuf[5] = flags;
160         sndbuf[6] = 0x02;
161
162         DEBUGR("%u [%s]: ", len, rfid_hexdump(bytes, len));
163
164         memcpy(sndbuf+7, bytes, len);
165
166         if (PC_to_RDR_Escape(rath->data, sndbuf, len+7, recvbuf, &retlen) == 0) {
167                 DEBUGRC("OK (%u [%s])\n", retlen, rfid_hexdump(recvbuf, retlen));
168                 return 0;
169         }
170
171         DEBUGRC("ERROR\n");
172         return -1;
173 }
174
175 #if 0
176 static int TestFIFO(struct rc632_handle *handle)
177 {
178         unsigned char sndbuf[60]; // 0x3c
179
180         // FIXME: repne stosd, call
181
182         memset(sndbuf, 0, sizeof(sndbuf));
183
184         if (WriteNBytesToFIFO(handle, sizeof(sndbuf), sndbuf, 0) < 0)
185                 return -1;
186
187         return ReadNBytesFromFIFO(handle, sizeof(sndbuf), sndbuf);
188 }
189 #endif
190
191 static int cm5121_transceive(struct rfid_reader_handle *rh,
192                              enum rfid_frametype frametype,
193                              const unsigned char *tx_data, unsigned int tx_len,
194                              unsigned char *rx_data, unsigned int *rx_len,
195                              u_int64_t timeout, unsigned int flags)
196 {
197         return rh->ah->asic->priv.rc632.fn.transceive(rh->ah, frametype,
198                                                 tx_data, tx_len, rx_data,
199                                                 rx_len, timeout, flags);
200 }
201
202 static int cm5121_transceive_sf(struct rfid_reader_handle *rh,
203                                unsigned char cmd, struct iso14443a_atqa *atqa)
204 {
205         return rh->ah->asic->priv.rc632.fn.iso14443a.transceive_sf(rh->ah,
206                                                                    cmd,
207                                                                    atqa);
208 }
209
210 static int
211 cm5121_transceive_acf(struct rfid_reader_handle *rh,
212                       struct iso14443a_anticol_cmd *cmd,
213                       unsigned int *bit_of_col)
214 {
215         return rh->ah->asic->priv.rc632.fn.iso14443a.transceive_acf(rh->ah,
216                                                          cmd, bit_of_col);
217 }
218
219 static int
220 cm5121_14443a_init(struct rfid_reader_handle *rh)
221 {
222         return rh->ah->asic->priv.rc632.fn.iso14443a.init(rh->ah);
223 }
224
225 static int
226 cm5121_14443a_set_speed(struct rfid_reader_handle *rh, 
227                         unsigned int tx,
228                         unsigned int speed)
229 {
230         u_int8_t rate;
231         
232         DEBUGP("setting rate: ");
233         switch (speed) {
234         case RFID_14443A_SPEED_106K:
235                 rate = 0x00;
236                 DEBUGPC("106K\n");
237                 break;
238         case RFID_14443A_SPEED_212K:
239                 rate = 0x01;
240                 DEBUGPC("212K\n");
241                 break;
242         case RFID_14443A_SPEED_424K:
243                 rate = 0x02;
244                 DEBUGPC("424K\n");
245                 break;
246         case RFID_14443A_SPEED_848K:
247                 rate = 0x03;
248                 DEBUGPC("848K\n");
249                 break;
250         default:
251                 DEBUGPC("invalid\n");
252                 return -EINVAL;
253                 break;
254         }
255         return rh->ah->asic->priv.rc632.fn.iso14443a.set_speed(rh->ah,
256                                                                 tx, rate);
257 }
258
259 static int
260 cm5121_14443b_init(struct rfid_reader_handle *rh)
261 {
262         return rh->ah->asic->priv.rc632.fn.iso14443b.init(rh->ah);
263 }
264
265 static int
266 cm5121_15693_init(struct rfid_reader_handle *rh)
267 {
268         return rh->ah->asic->priv.rc632.fn.iso15693.init(rh->ah);
269 }
270
271 static int
272 cm5121_mifare_setkey(struct rfid_reader_handle *rh, const u_int8_t *key)
273 {
274         return rh->ah->asic->priv.rc632.fn.mifare_classic.setkey(rh->ah, key);
275 }
276
277 static int
278 cm5121_mifare_auth(struct rfid_reader_handle *rh, u_int8_t cmd, 
279                    u_int32_t serno, u_int8_t block)
280 {
281         return rh->ah->asic->priv.rc632.fn.mifare_classic.auth(rh->ah, 
282                                                         cmd, serno, block);
283 }
284
285 struct rfid_asic_transport cm5121_ccid = {
286         .name = "CM5121 OpenCT",
287         .priv.rc632 = {
288                 .fn = {
289                         .reg_write      = &Write1ByteToReg,
290                         .reg_read       = &Read1ByteFromReg,
291                         .fifo_write     = &WriteNBytesToFIFO,
292                         .fifo_read      = &ReadNBytesFromFIFO,
293                 },
294         },
295 };
296
297 static int cm5121_enable_rc632(struct rfid_asic_transport_handle *rath)
298 {
299         unsigned char tx_buf[1] = { 0x01 };     
300         unsigned char rx_buf[64];
301         unsigned int rx_len = sizeof(rx_buf);
302
303         PC_to_RDR_Escape(rath->data, tx_buf, 1, rx_buf, &rx_len);
304         printf("received %u bytes from 01 command\n", rx_len);
305
306         return 0;
307 }
308
309 static struct rfid_reader_handle *
310 cm5121_open(void *data)
311 {
312         struct rfid_reader_handle *rh;
313         struct rfid_asic_transport_handle *rath;
314
315         rh = malloc(sizeof(*rh));
316         if (!rh)
317                 return NULL;
318         memset(rh, 0, sizeof(*rh));
319
320         rath = malloc(sizeof(*rath));
321         if (!rath)
322                 goto out_rh;
323         memset(rath, 0, sizeof(*rath));
324
325         rath->rat = &cm5121_ccid;
326         rh->reader = &rfid_reader_cm5121;
327
328         if (cm5121_source_init(rath) < 0)
329                 goto out_rath;
330
331         if (cm5121_enable_rc632(rath) < 0)
332                 goto out_rath;
333
334         rh->ah = rc632_open(rath);
335         if (!rh->ah) 
336                 goto out_rath;
337
338         DEBUGP("returning %p\n", rh);
339         return rh;
340
341 out_rath:
342         free(rath);
343 out_rh:
344         free(rh);
345
346         return NULL;
347 }
348
349 static void
350 cm5121_close(struct rfid_reader_handle *rh)
351 {
352         struct rfid_asic_transport_handle *rath = rh->ah->rath;
353         rc632_close(rh->ah);
354         free(rath);
355         free(rh);
356 }
357
358 struct rfid_reader rfid_reader_cm5121 = {
359         .name   = "Omnikey CardMan 5121 RFID",
360         .open = &cm5121_open,
361         .close = &cm5121_close,
362         .transceive = &cm5121_transceive,
363         .iso14443a = {
364                 .init = &cm5121_14443a_init,
365                 .transceive_sf = &cm5121_transceive_sf,
366                 .transceive_acf = &cm5121_transceive_acf,
367                 .speed = RFID_14443A_SPEED_106K | RFID_14443A_SPEED_212K |
368                          RFID_14443A_SPEED_424K, //| RFID_14443A_SPEED_848K,
369                 .set_speed = &cm5121_14443a_set_speed,
370         },
371         .iso14443b = {
372                 .init = &cm5121_14443b_init,
373         },
374         .mifare_classic = {
375                 .setkey = &cm5121_mifare_setkey,
376                 .auth = &cm5121_mifare_auth,
377         },
378 };
379
380