- more verbose/precise debug messages
[librfid] / src / rfid_reader_openpcd.c
1 /* OpenPC specific RC632 transport layer 
2  *
3  * (C) 2006 by Harald Welte <laforge@gnumonks.org>
4  *
5  * The OpenPCD is an Atmel AT91SAM7Sxx based USB RFID reader.
6  * It's CL RC632 is connected via SPI.
7  *
8  * TODO:
9  * - put hdl from static variable into asic transport or reader handle 
10  */
11
12 /*
13  *  This program is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU General Public License version 2 
15  *  as published by the Free Software Foundation
16  *
17  *  This program is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program; if not, write to the Free Software
24  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25  */
26
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <errno.h>
31
32 #include <usb.h>
33
34 #include <librfid/rfid.h>
35 #include <librfid/rfid_reader.h>
36 #include <librfid/rfid_asic.h>
37 #include <librfid/rfid_asic_rc632.h>
38 #include <librfid/rfid_reader_openpcd.h>
39
40 /* FIXME */
41 #include "rc632.h"
42
43
44 #define SENDBUF_LEN     (256+7+10) /* 256bytes max FSD/FSC, plus 7 bytes header,
45                                     plus 10 bytes reserve */
46 #define RECVBUF_LEN     SENDBUF_LEN
47
48 static char snd_buf[SENDBUF_LEN];
49 static char rcv_buf[RECVBUF_LEN];
50 static struct openpcd_hdr *snd_hdr;
51 static struct openpcd_hdr *rcv_hdr;
52
53
54 static struct usb_device *dev;
55 static struct usb_dev_handle *hdl;
56
57 static int openpcd_send_command(u_int8_t cmd, u_int8_t reg, u_int8_t val,
58                                 u_int16_t len, const unsigned char *data)
59 {
60         int ret;
61         u_int16_t cur;
62
63         snd_hdr->cmd = cmd;
64         snd_hdr->reg = reg;
65         snd_hdr->val = val;
66         snd_hdr->len = len;
67         if (data && len)
68                 memcpy(snd_hdr->data, data, len);
69
70         cur = sizeof(*snd_hdr) + len;
71
72         return usb_bulk_write(hdl, OPENPCD_OUT_EP, snd_hdr, cur, 0);
73 }
74
75 static int openpcd_recv_reply(void)
76 {
77         int ret;
78
79         ret = usb_bulk_read(hdl, OPENPCD_IN_EP, rcv_buf, sizeof(rcv_buf), 1000);
80
81         return ret;
82 }
83         
84 static struct usb_device *find_opcd_device(void)
85 {
86         struct usb_bus *bus;
87
88         for (bus = usb_busses; bus; bus = bus->next) {
89                 struct usb_device *dev;
90                 for (dev = bus->devices; dev; dev = dev->next) {
91                         if (dev->descriptor.idVendor == OPENPCD_VENDOR_ID
92                             && dev->descriptor.idProduct == OPENPCD_PRODUCT_ID
93                             && dev->descriptor.iManufacturer == 0
94                             && dev->descriptor.iProduct == 0
95                             && dev->descriptor.bNumConfigurations == 1
96                             && dev->config->bNumInterfaces == 1
97                             && dev->config->iConfiguration == 0)
98                                 return dev;
99                 }
100         }
101         return NULL;
102 }
103
104 static int openpcd_reg_write(struct rfid_asic_transport_handle *rath,
105                              unsigned char reg, unsigned char value)
106 {
107         int ret;
108
109         DEBUGP("reg=0x%02x, val=%02x: ", reg, value);
110
111         ret = openpcd_send_command(OPENPCD_CMD_WRITE_REG, reg, value, 0, NULL);
112         if (ret < 0)
113                 DEBUGPC("ERROR sending command\n");
114         else
115                 DEBUGPC("OK\n");
116
117         return ret;
118 }
119
120 static int openpcd_reg_read(struct rfid_asic_transport_handle *rath,
121                             unsigned char reg,
122                             unsigned char *value)
123 {
124         int ret;        
125
126         DEBUGP("reg=0x%02x, ", reg);
127
128         ret = openpcd_send_command(OPENPCD_CMD_READ_REG, reg, 0, 0, NULL);
129         if (ret < 0) {
130                 DEBUGPC("ERROR sending command\n");
131                 return ret;
132         }
133
134         ret = openpcd_recv_reply();
135         if (ret < 0) {
136                 DEBUGPC("ERROR receiving reply\n");
137                 return ret;
138         }
139
140         *value = rcv_hdr->val;
141         DEBUGPC("val=%02x: OK\n", *value);
142
143         return ret;
144 }
145
146 static int openpcd_fifo_read(struct rfid_asic_transport_handle *rath,
147                              unsigned char num_bytes,
148                              unsigned char *buf)
149 {
150         int ret;
151
152         DEBUGP(" ");
153
154         ret = openpcd_send_command(OPENPCD_CMD_READ_FIFO, 0x00, num_bytes, 0, NULL);
155         if (ret < 0) {
156                 DEBUGPC("ERROR sending command\n");
157                 return ret;
158         }
159
160         ret = openpcd_recv_reply();
161         if (ret < 0) {
162                 DEBUGPC("ERROR receiving reply\n");
163                 return ret;
164         }
165
166         memcpy(buf, rcv_hdr->data, rcv_hdr->len);
167         DEBUGPC("len=%u val=%s: OK\n", rcv_hdr->len,
168                 rfid_hexdump(rcv_hdr->data, rcv_hdr->len));
169
170         return ret;
171 }
172
173 static int openpcd_fifo_write(struct rfid_asic_transport_handle *rath,
174                              unsigned char len,
175                              const unsigned char *bytes,
176                              unsigned char flags)
177 {
178         int ret;
179
180         DEBUGP("len=%u, data=%s\n", len, rfid_hexdump(bytes, len));
181         ret = openpcd_send_command(OPENPCD_CMD_WRITE_FIFO, 0, 0, len, bytes);
182
183         return ret;
184 }
185
186 static int openpcd_transceive(struct rfid_reader_handle *rh,
187                              enum rfid_frametype frametype,
188                              const unsigned char *tx_data, unsigned int tx_len,
189                              unsigned char *rx_data, unsigned int *rx_len,
190                              u_int64_t timeout, unsigned int flags)
191 {
192         return rh->ah->asic->priv.rc632.fn.transceive(rh->ah, frametype,
193                                                 tx_data, tx_len, rx_data,
194                                                 rx_len, timeout, flags);
195 }
196
197 static int openpcd_transceive_sf(struct rfid_reader_handle *rh,
198                                unsigned char cmd, struct iso14443a_atqa *atqa)
199 {
200         return rh->ah->asic->priv.rc632.fn.iso14443a.transceive_sf(rh->ah,
201                                                                    cmd,
202                                                                    atqa);
203 }
204
205 static int
206 openpcd_transceive_acf(struct rfid_reader_handle *rh,
207                       struct iso14443a_anticol_cmd *cmd,
208                       unsigned int *bit_of_col)
209 {
210         return rh->ah->asic->priv.rc632.fn.iso14443a.transceive_acf(rh->ah,
211                                                          cmd, bit_of_col);
212 }
213
214 static int
215 openpcd_14443a_init(struct rfid_reader_handle *rh)
216 {
217         return rh->ah->asic->priv.rc632.fn.iso14443a.init(rh->ah);
218 }
219
220 static int
221 openpcd_14443a_set_speed(struct rfid_reader_handle *rh, 
222                         unsigned int tx,
223                         unsigned int speed)
224 {
225         u_int8_t rate;
226         
227         DEBUGP("setting rate: ");
228         switch (speed) {
229         case RFID_14443A_SPEED_106K:
230                 rate = 0x00;
231                 DEBUGPC("106K\n");
232                 break;
233         case RFID_14443A_SPEED_212K:
234                 rate = 0x01;
235                 DEBUGPC("212K\n");
236                 break;
237         case RFID_14443A_SPEED_424K:
238                 rate = 0x02;
239                 DEBUGPC("424K\n");
240                 break;
241         case RFID_14443A_SPEED_848K:
242                 rate = 0x03;
243                 DEBUGPC("848K\n");
244                 break;
245         default:
246                 return -EINVAL;
247                 break;
248         }
249         return rh->ah->asic->priv.rc632.fn.iso14443a.set_speed(rh->ah,
250                                                                 tx, rate);
251 }
252
253 static int
254 openpcd_14443b_init(struct rfid_reader_handle *rh)
255 {
256         return rh->ah->asic->priv.rc632.fn.iso14443b.init(rh->ah);
257 }
258
259 static int
260 openpcd_15693_init(struct rfid_reader_handle *rh)
261 {
262         return rh->ah->asic->priv.rc632.fn.iso15693.init(rh->ah);
263 }
264
265 static int
266 openpcd_mifare_setkey(struct rfid_reader_handle *rh, const u_int8_t *key)
267 {
268         return rh->ah->asic->priv.rc632.fn.mifare_classic.setkey(rh->ah, key);
269 }
270
271 static int
272 openpcd_mifare_auth(struct rfid_reader_handle *rh, u_int8_t cmd, 
273                    u_int32_t serno, u_int8_t block)
274 {
275         return rh->ah->asic->priv.rc632.fn.mifare_classic.auth(rh->ah, 
276                                                         cmd, serno, block);
277 }
278
279 struct rfid_asic_transport openpcd_ccid = {
280         .name = "OpenPCD Dumb USB Protocol",
281         .priv.rc632 = {
282                 .fn = {
283                         .reg_write      = &openpcd_reg_write,
284                         .reg_read       = &openpcd_reg_read,
285                         .fifo_write     = &openpcd_fifo_write,
286                         .fifo_read      = &openpcd_fifo_read,
287                 },
288         },
289 };
290
291 static struct rfid_reader_handle *
292 openpcd_open(void *data)
293 {
294         struct rfid_reader_handle *rh;
295         struct rfid_asic_transport_handle *rath;
296
297         snd_hdr = (struct openpcd_hdr *)snd_buf;
298         rcv_hdr = (struct openpcd_hdr *)rcv_buf;
299
300         usb_init();
301         if (!usb_find_busses())
302                 return NULL;
303         if (!usb_find_devices())
304                 return NULL;
305         
306         dev = find_opcd_device();
307         if (!dev)
308                 return NULL;
309
310         hdl = usb_open(dev);
311         if (!hdl)
312                 return NULL;
313
314         if (usb_claim_interface(hdl, 0) < 0) {
315                 usb_close(hdl);
316                 return NULL;
317         }
318
319         rh = malloc(sizeof(*rh));
320         if (!rh)
321                 return NULL;
322         memset(rh, 0, sizeof(*rh));
323
324         rath = malloc(sizeof(*rath));
325         if (!rath)
326                 goto out_rh;
327         memset(rath, 0, sizeof(*rath));
328
329         rath->rat = &openpcd_ccid;
330         rh->reader = &rfid_reader_openpcd;
331
332         rh->ah = rc632_open(rath);
333         if (!rh->ah) 
334                 goto out_rath;
335
336         DEBUGP("returning %p\n", rh);
337         return rh;
338
339 out_rath:
340         free(rath);
341 out_rh:
342         free(rh);
343
344         return NULL;
345 }
346
347 static void
348 openpcd_close(struct rfid_reader_handle *rh)
349 {
350         struct rfid_asic_transport_handle *rath = rh->ah->rath;
351
352         rc632_close(rh->ah);
353         free(rath);
354         free(rh);
355
356         usb_close(hdl);
357 }
358
359 struct rfid_reader rfid_reader_openpcd = {
360         .name   = "OpenPCD RFID Reader",
361         .id = RFID_READER_OPENPCD,
362         .open = &openpcd_open,
363         .close = &openpcd_close,
364         .transceive = &openpcd_transceive,
365         .iso14443a = {
366                 .init = &openpcd_14443a_init,
367                 .transceive_sf = &openpcd_transceive_sf,
368                 .transceive_acf = &openpcd_transceive_acf,
369                 .speed = RFID_14443A_SPEED_106K | RFID_14443A_SPEED_212K |
370                          RFID_14443A_SPEED_424K, //| RFID_14443A_SPEED_848K,
371                 .set_speed = &openpcd_14443a_set_speed,
372         },
373         .iso14443b = {
374                 .init = &openpcd_14443b_init,
375         },
376         .mifare_classic = {
377                 .setkey = &openpcd_mifare_setkey,
378                 .auth = &openpcd_mifare_auth,
379         },
380 };
381
382