1 /* OpenPC 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.
9 * - put hdl from static variable into asic transport or reader handle
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
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.
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
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>
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
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;
54 static struct usb_device *dev;
55 static struct usb_dev_handle *hdl;
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)
68 memcpy(snd_hdr->data, data, len);
70 cur = sizeof(*snd_hdr) + len;
72 return usb_bulk_write(hdl, OPENPCD_OUT_EP, snd_hdr, cur, 0);
75 static int openpcd_recv_reply(void)
79 ret = usb_bulk_read(hdl, OPENPCD_IN_EP, rcv_buf, sizeof(rcv_buf), 1000);
84 static struct usb_device *find_opcd_device(void)
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)
104 static int openpcd_reg_write(struct rfid_asic_transport_handle *rath,
105 unsigned char reg, unsigned char value)
109 DEBUGP("reg=0x%02x, val=%02x: ", reg, value);
111 ret = openpcd_send_command(OPENPCD_CMD_WRITE_REG, reg, value, 0, NULL);
113 DEBUGPC("ERROR sending command\n");
120 static int openpcd_reg_read(struct rfid_asic_transport_handle *rath,
122 unsigned char *value)
126 DEBUGP("reg=0x%02x, ", reg);
128 ret = openpcd_send_command(OPENPCD_CMD_READ_REG, reg, 0, 0, NULL);
130 DEBUGPC("ERROR sending command\n");
134 ret = openpcd_recv_reply();
136 DEBUGPC("ERROR receiving reply\n");
140 *value = rcv_hdr->val;
141 DEBUGPC("val=%02x: OK\n", *value);
146 static int openpcd_fifo_read(struct rfid_asic_transport_handle *rath,
147 unsigned char num_bytes,
154 ret = openpcd_send_command(OPENPCD_CMD_READ_FIFO, 0x00, num_bytes, 0, NULL);
156 DEBUGPC("ERROR sending command\n");
160 ret = openpcd_recv_reply();
162 DEBUGPC("ERROR receiving reply\n");
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));
173 static int openpcd_fifo_write(struct rfid_asic_transport_handle *rath,
175 const unsigned char *bytes,
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);
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)
192 return rh->ah->asic->priv.rc632.fn.transceive(rh->ah, frametype,
193 tx_data, tx_len, rx_data,
194 rx_len, timeout, flags);
197 static int openpcd_transceive_sf(struct rfid_reader_handle *rh,
198 unsigned char cmd, struct iso14443a_atqa *atqa)
200 return rh->ah->asic->priv.rc632.fn.iso14443a.transceive_sf(rh->ah,
206 openpcd_transceive_acf(struct rfid_reader_handle *rh,
207 struct iso14443a_anticol_cmd *cmd,
208 unsigned int *bit_of_col)
210 return rh->ah->asic->priv.rc632.fn.iso14443a.transceive_acf(rh->ah,
215 openpcd_14443a_init(struct rfid_reader_handle *rh)
217 return rh->ah->asic->priv.rc632.fn.iso14443a.init(rh->ah);
221 openpcd_14443a_set_speed(struct rfid_reader_handle *rh,
227 DEBUGP("setting rate: ");
229 case RFID_14443A_SPEED_106K:
233 case RFID_14443A_SPEED_212K:
237 case RFID_14443A_SPEED_424K:
241 case RFID_14443A_SPEED_848K:
249 return rh->ah->asic->priv.rc632.fn.iso14443a.set_speed(rh->ah,
254 openpcd_14443b_init(struct rfid_reader_handle *rh)
256 return rh->ah->asic->priv.rc632.fn.iso14443b.init(rh->ah);
260 openpcd_15693_init(struct rfid_reader_handle *rh)
262 return rh->ah->asic->priv.rc632.fn.iso15693.init(rh->ah);
266 openpcd_mifare_setkey(struct rfid_reader_handle *rh, const u_int8_t *key)
268 return rh->ah->asic->priv.rc632.fn.mifare_classic.setkey(rh->ah, key);
272 openpcd_mifare_auth(struct rfid_reader_handle *rh, u_int8_t cmd,
273 u_int32_t serno, u_int8_t block)
275 return rh->ah->asic->priv.rc632.fn.mifare_classic.auth(rh->ah,
279 struct rfid_asic_transport openpcd_ccid = {
280 .name = "OpenPCD Dumb USB Protocol",
283 .reg_write = &openpcd_reg_write,
284 .reg_read = &openpcd_reg_read,
285 .fifo_write = &openpcd_fifo_write,
286 .fifo_read = &openpcd_fifo_read,
291 static struct rfid_reader_handle *
292 openpcd_open(void *data)
294 struct rfid_reader_handle *rh;
295 struct rfid_asic_transport_handle *rath;
297 snd_hdr = (struct openpcd_hdr *)snd_buf;
298 rcv_hdr = (struct openpcd_hdr *)rcv_buf;
301 if (!usb_find_busses())
303 if (!usb_find_devices())
306 dev = find_opcd_device();
314 if (usb_claim_interface(hdl, 0) < 0) {
319 rh = malloc(sizeof(*rh));
322 memset(rh, 0, sizeof(*rh));
324 rath = malloc(sizeof(*rath));
327 memset(rath, 0, sizeof(*rath));
329 rath->rat = &openpcd_ccid;
330 rh->reader = &rfid_reader_openpcd;
332 rh->ah = rc632_open(rath);
336 DEBUGP("returning %p\n", rh);
348 openpcd_close(struct rfid_reader_handle *rh)
350 struct rfid_asic_transport_handle *rath = rh->ah->rath;
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,
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,
374 .init = &openpcd_14443b_init,
377 .setkey = &openpcd_mifare_setkey,
378 .auth = &openpcd_mifare_auth,