1 /* OpenPCD specific RC632 transport layer
3 * (C) 2006 by Harald Welte <laforge@gnumonks.org>
5 * The OpenPCD is an Atmel AT91SAM7Sxx based USB RFID reader.
6 * It's CL RC632 is connected via SPI. OpenPCD has multiple firmware
7 * images. This driver is for the "main_dumbreader" firmware.
10 * - put hdl from static variable into asic transport or reader handle
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2
16 * as published by the Free Software Foundation
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
33 #include <librfid/rfid.h>
34 #include <librfid/rfid_reader.h>
35 #include <librfid/rfid_asic.h>
36 #include <librfid/rfid_asic_rc632.h>
37 #include <librfid/rfid_reader_openpcd.h>
38 #include <librfid/rfid_layer2.h>
39 #include <librfid/rfid_protocol.h>
41 #include "rfid_reader_rc632_common.h"
46 #define SENDBUF_LEN (256+4+10) /* 256bytes max FSD/FSC, plus 4 bytes header,
47 plus 10 bytes reserve */
48 #define RECVBUF_LEN SENDBUF_LEN
50 static char snd_buf[SENDBUF_LEN];
51 static char rcv_buf[RECVBUF_LEN];
52 static struct openpcd_hdr *snd_hdr;
53 static struct openpcd_hdr *rcv_hdr;
55 #ifndef LIBRFID_FIRMWARE
58 #include "libusb_dyn.h"
64 #define DEBUGRC DEBUGPC
67 #define DEBUGRC(x, args ...) do {} while(0)
68 #define DEBUGR(x, args ...) do {} while(0)
71 static struct usb_device *dev;
72 static struct usb_dev_handle *hdl;
74 static int openpcd_send_command(u_int8_t cmd, u_int8_t reg, u_int8_t val,
75 u_int16_t len, const unsigned char *data)
83 snd_hdr->flags = OPENPCD_FLAG_RESPOND;
85 memcpy(snd_hdr->data, data, len);
87 cur = sizeof(*snd_hdr) + len;
89 return usb_bulk_write(hdl, OPENPCD_OUT_EP, (char *)snd_hdr, cur, 1000);
92 static int openpcd_recv_reply(void)
96 ret = usb_bulk_read(hdl, OPENPCD_IN_EP, rcv_buf, sizeof(rcv_buf), 1000);
101 static int openpcd_xcv(u_int8_t cmd, u_int8_t reg, u_int8_t val,
102 u_int16_t len, const unsigned char *data)
106 ret = openpcd_send_command(cmd, reg, val, len, data);
109 if (ret < sizeof(struct openpcd_hdr))
112 return openpcd_recv_reply();
120 static const struct usb_id opcd_usb_ids[] = {
121 { .vid = 0x2342, .pid = 0x0001 }, /* prototypes */
122 { .vid = 0x16c0, .pid = 0x076b }, /* first official device id */
125 static struct usb_device *find_opcd_device(void)
129 for (bus = usb_get_busses(); bus; bus = bus->next) {
130 struct usb_device *dev;
131 for (dev = bus->devices; dev; dev = dev->next) {
133 for (i = 0; i < ARRAY_SIZE(opcd_usb_ids); i++) {
134 const struct usb_id *id = &opcd_usb_ids[i];
135 if (dev->descriptor.idVendor == id->vid &&
136 dev->descriptor.idProduct == id->pid)
144 /* RC632 access primitives for librfid inside reader firmware */
146 static int openpcd_reg_write(struct rfid_asic_transport_handle *rath,
147 unsigned char reg, unsigned char value)
151 DEBUGR("reg=0x%02x, val=%02x: ", reg, value);
153 ret = openpcd_xcv(OPENPCD_CMD_WRITE_REG, reg, value, 0, NULL);
155 DEBUGRC("ERROR sending command\n");
162 static int openpcd_reg_read(struct rfid_asic_transport_handle *rath,
164 unsigned char *value)
168 DEBUGR("reg=0x%02x, ", reg);
170 ret = openpcd_xcv(OPENPCD_CMD_READ_REG, reg, 0, 0, NULL);
172 DEBUGRC("ERROR sending command\n");
176 if (ret < sizeof(struct openpcd_hdr)) {
177 DEBUGRC("ERROR: short packet\n");
181 *value = rcv_hdr->val;
182 DEBUGRC("val=%02x: OK\n", *value);
187 static int openpcd_fifo_read(struct rfid_asic_transport_handle *rath,
188 unsigned char num_bytes,
195 ret = openpcd_xcv(OPENPCD_CMD_READ_FIFO, 0x00, num_bytes, 0, NULL);
197 DEBUGRC("ERROR sending command\n");
200 DEBUGRC("ret = %d\n", ret);
202 memcpy(buf, rcv_hdr->data, ret - sizeof(struct openpcd_hdr));
203 DEBUGRC("len=%d val=%s: OK\n", ret - sizeof(struct openpcd_hdr),
204 rfid_hexdump(rcv_hdr->data, ret - sizeof(struct openpcd_hdr)));
209 static int openpcd_fifo_write(struct rfid_asic_transport_handle *rath,
211 const unsigned char *bytes,
216 DEBUGR("len=%u, data=%s\n", len, rfid_hexdump(bytes, len));
217 ret = openpcd_xcv(OPENPCD_CMD_WRITE_FIFO, 0, 0, len, bytes);
222 const struct rfid_asic_transport openpcd_rat = {
223 .name = "OpenPCD Dumb USB Protocol",
226 .reg_write = &openpcd_reg_write,
227 .reg_read = &openpcd_reg_read,
228 .fifo_write = &openpcd_fifo_write,
229 .fifo_read = &openpcd_fifo_read,
234 static int openpcd_get_api_version(struct rfid_reader_handle *rh, u_int8_t *version)
238 // preset version result to zero
241 ret = openpcd_xcv(OPENPCD_CMD_GET_API_VERSION, 0, 0, 0, NULL);
243 DEBUGPC("ERROR sending command [%i]\n", ret);
247 if (ret < sizeof(struct openpcd_hdr)) {
248 DEBUGPC("ERROR: short packet [%i]\n", ret);
252 *version = rcv_hdr->val;
257 static int openpcd_get_environment(struct rfid_reader_handle *rh,
258 unsigned char num_bytes,
265 ret = openpcd_xcv(OPENPCD_CMD_GET_ENVIRONMENT, 0x00, num_bytes, 0, NULL);
267 DEBUGPC("ERROR sending command [%i]\n",ret);
270 DEBUGPC("ret = %d\n", ret);
272 memcpy(buf, rcv_hdr->data, ret - sizeof(struct openpcd_hdr));
273 DEBUGPC("len=%d val=%s: OK\n", ret - sizeof(struct openpcd_hdr),
274 rfid_hexdump(rcv_hdr->data, ret - sizeof(struct openpcd_hdr)));
279 static int openpcd_set_environment(struct rfid_reader_handle *rh,
280 unsigned char num_bytes,
281 const unsigned char *buf)
285 ret = openpcd_xcv(OPENPCD_CMD_SET_ENVIRONMENT, 0, 0, num_bytes, buf);
287 DEBUGPC("ERROR sending command [%i]\n",ret);
291 if (ret < sizeof(struct openpcd_hdr)) {
292 DEBUGPC("ERROR: short packet [%i]\n", ret);
299 static int openpcd_reset(struct rfid_reader_handle *rh)
304 ret = openpcd_xcv(OPENPCD_CMD_RESET, 0, 0, 0, 0);
310 /* RC632 access primitives for librfid inside reader firmware */
312 static int openpcd_reg_write(struct rfid_asic_transport_handle *rath,
313 unsigned char reg, unsigned char value)
315 return opcd_rc632_reg_write(rath, reg, value);
318 static int openpcd_reg_read(struct rfid_asic_transport_handle *rath,
320 unsigned char *value)
322 return opcd_rc632_reg_read(rath, reg, value);
326 static int openpcd_fifo_read(struct rfid_asic_transport_handle *rath,
327 unsigned char num_bytes,
330 return opcd_rc632_fifo_read(rath, num_bytes, buf);
333 static int openpcd_fifo_write(struct rfid_asic_transport_handle *rath,
335 const unsigned char *bytes,
338 return opcd_rc632_fifo_write(rath, len, bytes, flags);
341 const struct rfid_asic_transport openpcd_rat = {
342 .name = "OpenPCD Firmware RC632 Access",
345 .reg_write = &openpcd_reg_write,
346 .reg_read = &openpcd_reg_read,
347 .fifo_write = &openpcd_fifo_write,
348 .fifo_read = &openpcd_fifo_read,
353 #endif /* LIBRFID_FIRMWARE */
355 static int openpcd_getopt(struct rfid_reader_handle *rh, int optname,
356 void *optval, unsigned int *optlen)
359 u_int8_t *val_u8 = (u_int8_t *) optval;
362 #ifndef LIBRFID_FIRMWARE
363 case RFID_OPT_RDR_FW_VERSION:
364 return openpcd_get_api_version(rh, val_u8);
367 return _rdr_rc632_getopt(rh, optname, optval, optlen);
374 static struct rfid_reader_handle *
375 openpcd_open(void *data)
377 struct rfid_reader_handle *rh;
378 struct rfid_asic_transport_handle *rath;
380 snd_hdr = (struct openpcd_hdr *)snd_buf;
381 rcv_hdr = (struct openpcd_hdr *)rcv_buf;
383 #ifndef LIBRFID_FIRMWARE
385 if (usb_find_busses() < 0)
387 if (usb_find_devices() < 0)
390 dev = find_opcd_device();
392 DEBUGP("No matching USB device found\n");
398 DEBUGP("Can't open USB device\n");
402 if(usb_set_configuration(hdl, 1 ) < 0)
404 DEBUGP("setting config failed\n");
409 if (usb_claim_interface(hdl, 0) < 0) {
410 DEBUGP("Can't claim interface\n");
416 rh = malloc_reader_handle(sizeof(*rh));
419 memset(rh, 0, sizeof(*rh));
421 rath = malloc_rat_handle(sizeof(*rath));
424 memset(rath, 0, sizeof(*rath));
426 rath->rat = &openpcd_rat;
427 rh->reader = &rfid_reader_openpcd;
429 rh->ah = rc632_open(rath);
433 DEBUGP("returning %p\n", rh);
437 free_rat_handle(rath);
439 free_reader_handle(rh);
445 openpcd_close(struct rfid_reader_handle *rh)
447 struct rfid_asic_transport_handle *rath = rh->ah->rath;
450 free_rat_handle(rath);
451 free_reader_handle(rh);
453 #ifndef LIBRFID_FIRMWARE
458 const struct rfid_reader rfid_reader_openpcd = {
459 .name = "OpenPCD RFID Reader",
460 .id = RFID_READER_OPENPCD,
461 .open = &openpcd_open,
462 .close = &openpcd_close,
463 .getopt = &openpcd_getopt,
464 #ifndef LIBRFID_FIRMWARE
465 .reset = &openpcd_reset,
467 .setopt = &_rdr_rc632_setopt,
468 .init = &_rdr_rc632_l2_init,
469 .transceive = &_rdr_rc632_transceive,
470 .l2_supported = (1 << RFID_LAYER2_ISO14443A) |
471 (1 << RFID_LAYER2_ISO14443B) |
472 (1 << RFID_LAYER2_ISO15693),
473 .proto_supported = (1 << RFID_PROTOCOL_TCL) |
474 (1 << RFID_PROTOCOL_MIFARE_UL) |
475 (1 << RFID_PROTOCOL_MIFARE_CLASSIC),
477 .transceive_sf = &_rdr_rc632_transceive_sf,
478 .transceive_acf = &_rdr_rc632_transceive_acf,
479 .speed = RFID_14443A_SPEED_106K | RFID_14443A_SPEED_212K |
480 RFID_14443A_SPEED_424K, //| RFID_14443A_SPEED_848K,
481 .set_speed = &_rdr_rc632_14443a_set_speed,
484 .transceive_ac = &_rdr_rc632_iso15693_transceive_ac,
487 .setkey = &_rdr_rc632_mifare_setkey,
488 .setkey_ee = &_rdr_rc632_mifare_setkey_ee,
489 .auth = &_rdr_rc632_mifare_auth,