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>
44 #define SENDBUF_LEN (256+4+10) /* 256bytes max FSD/FSC, plus 4 bytes header,
45 plus 10 bytes reserve */
46 #define RECVBUF_LEN SENDBUF_LEN
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;
53 #ifndef LIBRFID_FIRMWARE
56 #include "libusb_dyn.h"
61 static struct usb_device *dev;
62 static struct usb_dev_handle *hdl;
64 static int openpcd_send_command(u_int8_t cmd, u_int8_t reg, u_int8_t val,
65 u_int16_t len, const unsigned char *data)
73 snd_hdr->flags = OPENPCD_FLAG_RESPOND;
75 memcpy(snd_hdr->data, data, len);
77 cur = sizeof(*snd_hdr) + len;
79 return usb_bulk_write(hdl, OPENPCD_OUT_EP, (char *)snd_hdr, cur, 1000);
82 static int openpcd_recv_reply(void)
86 ret = usb_bulk_read(hdl, OPENPCD_IN_EP, rcv_buf, sizeof(rcv_buf), 1000);
91 static int openpcd_xcv(u_int8_t cmd, u_int8_t reg, u_int8_t val,
92 u_int16_t len, const unsigned char *data)
96 ret = openpcd_send_command(cmd, reg, val, len, data);
99 if (ret < sizeof(struct openpcd_hdr))
102 return openpcd_recv_reply();
110 static const struct usb_id opcd_usb_ids[] = {
111 { .vid = 0x2342, .pid = 0x0001 }, /* prototypes */
112 { .vid = 0x16c0, .pid = 0x076b }, /* first official device id */
115 static struct usb_device *find_opcd_device(void)
119 for (bus = usb_get_busses(); bus; bus = bus->next) {
120 struct usb_device *dev;
121 for (dev = bus->devices; dev; dev = dev->next) {
123 for (i = 0; i < ARRAY_SIZE(opcd_usb_ids); i++) {
124 const struct usb_id *id = &opcd_usb_ids[i];
125 if (dev->descriptor.idVendor == id->vid &&
126 dev->descriptor.idProduct == id->pid)
134 /* RC632 access primitives for librfid inside reader firmware */
136 static int openpcd_reg_write(struct rfid_asic_transport_handle *rath,
137 unsigned char reg, unsigned char value)
141 DEBUGP("reg=0x%02x, val=%02x: ", reg, value);
143 ret = openpcd_xcv(OPENPCD_CMD_WRITE_REG, reg, value, 0, NULL);
145 DEBUGPC("ERROR sending command\n");
152 static int openpcd_reg_read(struct rfid_asic_transport_handle *rath,
154 unsigned char *value)
158 DEBUGP("reg=0x%02x, ", reg);
160 ret = openpcd_xcv(OPENPCD_CMD_READ_REG, reg, 0, 0, NULL);
162 DEBUGPC("ERROR sending command\n");
166 if (ret < sizeof(struct openpcd_hdr)) {
167 DEBUGPC("ERROR: short packet\n");
171 *value = rcv_hdr->val;
172 DEBUGPC("val=%02x: OK\n", *value);
177 static int openpcd_fifo_read(struct rfid_asic_transport_handle *rath,
178 unsigned char num_bytes,
185 ret = openpcd_xcv(OPENPCD_CMD_READ_FIFO, 0x00, num_bytes, 0, NULL);
187 DEBUGPC("ERROR sending command\n");
190 DEBUGPC("ret = %d\n", ret);
192 memcpy(buf, rcv_hdr->data, ret - sizeof(struct openpcd_hdr));
193 DEBUGPC("len=%d val=%s: OK\n", ret - sizeof(struct openpcd_hdr),
194 rfid_hexdump(rcv_hdr->data, ret - sizeof(struct openpcd_hdr)));
199 static int openpcd_fifo_write(struct rfid_asic_transport_handle *rath,
201 const unsigned char *bytes,
206 DEBUGP("len=%u, data=%s\n", len, rfid_hexdump(bytes, len));
207 ret = openpcd_xcv(OPENPCD_CMD_WRITE_FIFO, 0, 0, len, bytes);
212 const struct rfid_asic_transport openpcd_rat = {
213 .name = "OpenPCD Dumb USB Protocol",
216 .reg_write = &openpcd_reg_write,
217 .reg_read = &openpcd_reg_read,
218 .fifo_write = &openpcd_fifo_write,
219 .fifo_read = &openpcd_fifo_read,
224 static int openpcd_get_api_version(struct rfid_reader_handle *rh, u_int8_t *version)
228 // preset version result to zero
231 ret = openpcd_xcv(OPENPCD_CMD_GET_API_VERSION, 0, 0, 0, NULL);
233 DEBUGPC("ERROR sending command [%i]\n", ret);
237 if (ret < sizeof(struct openpcd_hdr)) {
238 DEBUGPC("ERROR: short packet [%i]\n", ret);
242 *version = rcv_hdr->val;
247 static int openpcd_get_environment(
248 struct rfid_reader_handle *rh,
249 unsigned char num_bytes,
256 ret = openpcd_xcv(OPENPCD_CMD_GET_ENVIRONMENT, 0x00, num_bytes, 0, NULL);
258 DEBUGPC("ERROR sending command [%i]\n",ret);
261 DEBUGPC("ret = %d\n", ret);
263 memcpy(buf, rcv_hdr->data, ret - sizeof(struct openpcd_hdr));
264 DEBUGPC("len=%d val=%s: OK\n", ret - sizeof(struct openpcd_hdr),
265 rfid_hexdump(rcv_hdr->data, ret - sizeof(struct openpcd_hdr)));
270 static int openpcd_set_environment(
271 struct rfid_reader_handle *rh,
272 const unsigned char num_bytes,
277 ret = openpcd_xcv(OPENPCD_CMD_SET_ENVIRONMENT, 0, 0, num_bytes, buf);
279 DEBUGPC("ERROR sending command [%i]\n",ret);
283 if (ret < sizeof(struct openpcd_hdr)) {
284 DEBUGPC("ERROR: short packet [%i]\n", ret);
291 static int openpcd_reset(struct rfid_reader_handle *rh)
296 ret = openpcd_xcv(OPENPCD_CMD_RESET, 0, 0, 0, 0);
302 /* RC632 access primitives for librfid inside reader firmware */
304 static int openpcd_reg_write(struct rfid_asic_transport_handle *rath,
305 unsigned char reg, unsigned char value)
307 return opcd_rc632_reg_write(rath, reg, value);
310 static int openpcd_reg_read(struct rfid_asic_transport_handle *rath,
312 unsigned char *value)
314 return opcd_rc632_reg_read(rath, reg, value);
318 static int openpcd_fifo_read(struct rfid_asic_transport_handle *rath,
319 unsigned char num_bytes,
322 return opcd_rc632_fifo_read(rath, num_bytes, buf);
325 static int openpcd_fifo_write(struct rfid_asic_transport_handle *rath,
327 const unsigned char *bytes,
330 return opcd_rc632_fifo_write(rath, len, bytes, flags);
333 const struct rfid_asic_transport openpcd_rat = {
334 .name = "OpenPCD Firmware RC632 Access",
337 .reg_write = &openpcd_reg_write,
338 .reg_read = &openpcd_reg_read,
339 .fifo_write = &openpcd_fifo_write,
340 .fifo_read = &openpcd_fifo_read,
345 #endif /* LIBRFID_FIRMWARE */
347 static int openpcd_transceive(struct rfid_reader_handle *rh,
348 enum rfid_frametype frametype,
349 const unsigned char *tx_data, unsigned int tx_len,
350 unsigned char *rx_data, unsigned int *rx_len,
351 u_int64_t timeout, unsigned int flags)
353 return rh->ah->asic->priv.rc632.fn.transceive(rh->ah, frametype,
359 static int openpcd_transceive_sf(struct rfid_reader_handle *rh,
360 unsigned char cmd, struct iso14443a_atqa *atqa)
362 return rh->ah->asic->priv.rc632.fn.iso14443a.transceive_sf(rh->ah,
368 openpcd_transceive_acf(struct rfid_reader_handle *rh,
369 struct iso14443a_anticol_cmd *cmd,
370 unsigned int *bit_of_col)
372 return rh->ah->asic->priv.rc632.fn.iso14443a.transceive_acf(rh->ah,
377 openpcd_14443a_init(struct rfid_reader_handle *rh)
379 return rh->ah->asic->priv.rc632.fn.iso14443a.init(rh->ah);
383 openpcd_14443a_set_speed(struct rfid_reader_handle *rh,
389 DEBUGP("setting rate: ");
391 case RFID_14443A_SPEED_106K:
395 case RFID_14443A_SPEED_212K:
399 case RFID_14443A_SPEED_424K:
403 case RFID_14443A_SPEED_848K:
411 return rh->ah->asic->priv.rc632.fn.iso14443a.set_speed(rh->ah,
416 openpcd_14443b_init(struct rfid_reader_handle *rh)
418 return rh->ah->asic->priv.rc632.fn.iso14443b.init(rh->ah);
422 openpcd_15693_init(struct rfid_reader_handle *rh)
424 return rh->ah->asic->priv.rc632.fn.iso15693.init(rh->ah);
428 openpcd_mifare_setkey(struct rfid_reader_handle *rh, const u_int8_t *key)
430 return rh->ah->asic->priv.rc632.fn.mifare_classic.setkey(rh->ah, key);
434 openpcd_mifare_auth(struct rfid_reader_handle *rh, u_int8_t cmd,
435 u_int32_t serno, u_int8_t block)
437 return rh->ah->asic->priv.rc632.fn.mifare_classic.auth(rh->ah,
441 static struct rfid_reader_handle *
442 openpcd_open(void *data)
444 struct rfid_reader_handle *rh;
445 struct rfid_asic_transport_handle *rath;
447 snd_hdr = (struct openpcd_hdr *)snd_buf;
448 rcv_hdr = (struct openpcd_hdr *)rcv_buf;
450 #ifndef LIBRFID_FIRMWARE
452 if (usb_find_busses() < 0)
454 if (usb_find_devices() < 0)
457 dev = find_opcd_device();
459 DEBUGP("No matching USB device found\n");
465 DEBUGP("Can't open USB device\n");
469 if(usb_set_configuration(hdl, 1 ) < 0)
471 DEBUGP("setting config failed\n");
476 if (usb_claim_interface(hdl, 0) < 0) {
477 DEBUGP("Can't claim interface\n");
483 rh = malloc_reader_handle(sizeof(*rh));
486 memset(rh, 0, sizeof(*rh));
488 rath = malloc_rat_handle(sizeof(*rath));
491 memset(rath, 0, sizeof(*rath));
493 rath->rat = &openpcd_rat;
494 rh->reader = &rfid_reader_openpcd;
496 rh->ah = rc632_open(rath);
500 DEBUGP("returning %p\n", rh);
504 free_rat_handle(rath);
506 free_reader_handle(rh);
512 openpcd_close(struct rfid_reader_handle *rh)
514 struct rfid_asic_transport_handle *rath = rh->ah->rath;
517 free_rat_handle(rath);
518 free_reader_handle(rh);
520 #ifndef LIBRFID_FIRMWARE
525 const struct rfid_reader rfid_reader_openpcd = {
526 .name = "OpenPCD RFID Reader",
527 .id = RFID_READER_OPENPCD,
528 .open = &openpcd_open,
529 .close = &openpcd_close,
531 #ifndef LIBRFID_FIRMWARE
532 .get_api_version = &openpcd_get_api_version,
533 .get_environment = &openpcd_get_environment,
534 .set_environment = &openpcd_set_environment,
535 .reset = &openpcd_reset,
538 .transceive = &openpcd_transceive,
539 .l2_supported = (1 << RFID_LAYER2_ISO14443A) |
540 (1 << RFID_LAYER2_ISO14443B) |
541 (1 << RFID_LAYER2_ISO15693),
542 .proto_supported = (1 << RFID_PROTOCOL_TCL) |
543 (1 << RFID_PROTOCOL_MIFARE_UL) |
544 (1 << RFID_PROTOCOL_MIFARE_CLASSIC),
546 .init = &openpcd_14443a_init,
547 .transceive_sf = &openpcd_transceive_sf,
548 .transceive_acf = &openpcd_transceive_acf,
549 .speed = RFID_14443A_SPEED_106K | RFID_14443A_SPEED_212K |
550 RFID_14443A_SPEED_424K, //| RFID_14443A_SPEED_848K,
551 .set_speed = &openpcd_14443a_set_speed,
554 .init = &openpcd_14443b_init,
557 .init = &openpcd_15693_init,
560 .setkey = &openpcd_mifare_setkey,
561 .auth = &openpcd_mifare_auth,