X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=src%2Frfid_reader_openpcd.c;h=b885d9f8864b02786b413779c9f7a366d2a3e39f;hb=a360908550fd8038c722fa33b70b5e6e91e2429c;hp=6f8ba89b579a753e8ed776422115f9e276c7a9fa;hpb=5171480818fb1e89fc4de858a5821fd01c667bfe;p=librfid diff --git a/src/rfid_reader_openpcd.c b/src/rfid_reader_openpcd.c index 6f8ba89..b885d9f 100644 --- a/src/rfid_reader_openpcd.c +++ b/src/rfid_reader_openpcd.c @@ -3,7 +3,8 @@ * (C) 2006 by Harald Welte * * The OpenPCD is an Atmel AT91SAM7Sxx based USB RFID reader. - * It's CL RC632 is connected via SPI. + * It's CL RC632 is connected via SPI. OpenPCD has multiple firmware + * images. This driver is for the "main_dumbreader" firmware. * * TODO: * - put hdl from static variable into asic transport or reader handle @@ -24,25 +25,22 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -//#define DEBUG - #include #include #include #include -#include - #include #include #include #include #include +#include +#include /* FIXME */ #include "rc632.h" - #define SENDBUF_LEN (256+4+10) /* 256bytes max FSD/FSC, plus 4 bytes header, plus 10 bytes reserve */ #define RECVBUF_LEN SENDBUF_LEN @@ -52,6 +50,13 @@ static char rcv_buf[RECVBUF_LEN]; static struct openpcd_hdr *snd_hdr; static struct openpcd_hdr *rcv_hdr; +#ifndef LIBRFID_FIRMWARE + +#ifdef __MINGW32__ +#include "libusb_dyn.h" +#else /*__MINGW32__*/ +#include +#endif/*__MINGW32__*/ static struct usb_device *dev; static struct usb_dev_handle *hdl; @@ -71,7 +76,7 @@ static int openpcd_send_command(u_int8_t cmd, u_int8_t reg, u_int8_t val, cur = sizeof(*snd_hdr) + len; - return usb_bulk_write(hdl, OPENPCD_OUT_EP, snd_hdr, cur, 0); + return usb_bulk_write(hdl, OPENPCD_OUT_EP, (char *)snd_hdr, cur, 1000); } static int openpcd_recv_reply(void) @@ -91,31 +96,43 @@ static int openpcd_xcv(u_int8_t cmd, u_int8_t reg, u_int8_t val, ret = openpcd_send_command(cmd, reg, val, len, data); if (ret < 0) return ret; - if (ret < sizeof(sizeof(struct openpcd_hdr))) + if (ret < sizeof(struct openpcd_hdr)) return -EINVAL; return openpcd_recv_reply(); } - + +struct usb_id { + u_int16_t vid; + u_int16_t pid; +}; + +static const struct usb_id opcd_usb_ids[] = { + { .vid = 0x2342, .pid = 0x0001 }, /* prototypes */ + { .vid = 0x16c0, .pid = 0x076b }, /* first official device id */ +}; + static struct usb_device *find_opcd_device(void) { struct usb_bus *bus; - for (bus = usb_busses; bus; bus = bus->next) { + for (bus = usb_get_busses(); bus; bus = bus->next) { struct usb_device *dev; for (dev = bus->devices; dev; dev = dev->next) { - if (dev->descriptor.idVendor == OPENPCD_VENDOR_ID - && dev->descriptor.idProduct == OPENPCD_PRODUCT_ID - && dev->descriptor.iManufacturer == 0 - && dev->descriptor.iProduct == 0 - && dev->descriptor.bNumConfigurations == 1 - && dev->config->iConfiguration == 0) - return dev; + int i; + for (i = 0; i < ARRAY_SIZE(opcd_usb_ids); i++) { + const struct usb_id *id = &opcd_usb_ids[i]; + if (dev->descriptor.idVendor == id->vid && + dev->descriptor.idProduct == id->pid) + return dev; + } } } return NULL; } +/* RC632 access primitives for librfid inside reader firmware */ + static int openpcd_reg_write(struct rfid_asic_transport_handle *rath, unsigned char reg, unsigned char value) { @@ -192,6 +209,141 @@ static int openpcd_fifo_write(struct rfid_asic_transport_handle *rath, return ret; } +const struct rfid_asic_transport openpcd_rat = { + .name = "OpenPCD Dumb USB Protocol", + .priv.rc632 = { + .fn = { + .reg_write = &openpcd_reg_write, + .reg_read = &openpcd_reg_read, + .fifo_write = &openpcd_fifo_write, + .fifo_read = &openpcd_fifo_read, + }, + }, +}; + +static int openpcd_get_api_version(struct rfid_reader_handle *rh, u_int8_t *version) +{ + int ret; + + // preset version result to zero + rcv_hdr->val=0; + + ret = openpcd_xcv(OPENPCD_CMD_GET_API_VERSION, 0, 0, 0, NULL); + if (ret < 0) { + DEBUGPC("ERROR sending command [%i]\n", ret); + return ret; + } + + if (ret < sizeof(struct openpcd_hdr)) { + DEBUGPC("ERROR: short packet [%i]\n", ret); + return -EINVAL; + } + + *version = rcv_hdr->val; + + return ret; +} + +static int openpcd_get_environment( + struct rfid_reader_handle *rh, + unsigned char num_bytes, + unsigned char *buf) +{ + int ret; + + DEBUGP(" "); + + ret = openpcd_xcv(OPENPCD_CMD_GET_ENVIRONMENT, 0x00, num_bytes, 0, NULL); + if (ret < 0) { + DEBUGPC("ERROR sending command [%i]\n",ret); + return ret; + } + DEBUGPC("ret = %d\n", ret); + + memcpy(buf, rcv_hdr->data, ret - sizeof(struct openpcd_hdr)); + DEBUGPC("len=%d val=%s: OK\n", ret - sizeof(struct openpcd_hdr), + rfid_hexdump(rcv_hdr->data, ret - sizeof(struct openpcd_hdr))); + + return ret; +} + +static int openpcd_set_environment( + struct rfid_reader_handle *rh, + const unsigned char num_bytes, + unsigned char *buf) +{ + int ret; + + ret = openpcd_xcv(OPENPCD_CMD_SET_ENVIRONMENT, 0, 0, num_bytes, buf); + if (ret < 0) { + DEBUGPC("ERROR sending command [%i]\n",ret); + return ret; + } + + if (ret < sizeof(struct openpcd_hdr)) { + DEBUGPC("ERROR: short packet [%i]\n", ret); + return -EINVAL; + } + + return rcv_hdr->val; +} + +static int openpcd_reset(struct rfid_reader_handle *rh) +{ + int ret; + + DEBUGP("reset "); + ret = openpcd_xcv(OPENPCD_CMD_RESET, 0, 0, 0, 0); + + return ret; +} + +#else +/* RC632 access primitives for librfid inside reader firmware */ + +static int openpcd_reg_write(struct rfid_asic_transport_handle *rath, + unsigned char reg, unsigned char value) +{ + return opcd_rc632_reg_write(rath, reg, value); +} + +static int openpcd_reg_read(struct rfid_asic_transport_handle *rath, + unsigned char reg, + unsigned char *value) +{ + return opcd_rc632_reg_read(rath, reg, value); +} + + +static int openpcd_fifo_read(struct rfid_asic_transport_handle *rath, + unsigned char num_bytes, + unsigned char *buf) +{ + return opcd_rc632_fifo_read(rath, num_bytes, buf); +} + +static int openpcd_fifo_write(struct rfid_asic_transport_handle *rath, + unsigned char len, + const unsigned char *bytes, + unsigned char flags) +{ + return opcd_rc632_fifo_write(rath, len, bytes, flags); +} + +const struct rfid_asic_transport openpcd_rat = { + .name = "OpenPCD Firmware RC632 Access", + .priv.rc632 = { + .fn = { + .reg_write = &openpcd_reg_write, + .reg_read = &openpcd_reg_read, + .fifo_write = &openpcd_fifo_write, + .fifo_read = &openpcd_fifo_read, + }, + }, +}; + +#endif /* LIBRFID_FIRMWARE */ + static int openpcd_transceive(struct rfid_reader_handle *rh, enum rfid_frametype frametype, const unsigned char *tx_data, unsigned int tx_len, @@ -199,8 +351,9 @@ static int openpcd_transceive(struct rfid_reader_handle *rh, u_int64_t timeout, unsigned int flags) { return rh->ah->asic->priv.rc632.fn.transceive(rh->ah, frametype, - tx_data, tx_len, rx_data, - rx_len, timeout, flags); + tx_data, tx_len, + rx_data, rx_len, + timeout, flags); } static int openpcd_transceive_sf(struct rfid_reader_handle *rh, @@ -245,7 +398,7 @@ openpcd_14443a_set_speed(struct rfid_reader_handle *rh, break; case RFID_14443A_SPEED_424K: rate = 0x02; - DEBUGPC("424K\n"); + DEBUGPC("424K\n"); break; case RFID_14443A_SPEED_848K: rate = 0x03; @@ -285,18 +438,6 @@ openpcd_mifare_auth(struct rfid_reader_handle *rh, u_int8_t cmd, cmd, serno, block); } -struct rfid_asic_transport openpcd_ccid = { - .name = "OpenPCD Dumb USB Protocol", - .priv.rc632 = { - .fn = { - .reg_write = &openpcd_reg_write, - .reg_read = &openpcd_reg_read, - .fifo_write = &openpcd_fifo_write, - .fifo_read = &openpcd_fifo_read, - }, - }, -}; - static struct rfid_reader_handle * openpcd_open(void *data) { @@ -306,10 +447,11 @@ openpcd_open(void *data) snd_hdr = (struct openpcd_hdr *)snd_buf; rcv_hdr = (struct openpcd_hdr *)rcv_buf; +#ifndef LIBRFID_FIRMWARE usb_init(); - if (!usb_find_busses()) + if (usb_find_busses() < 0) return NULL; - if (!usb_find_devices()) + if (usb_find_devices() < 0) return NULL; dev = find_opcd_device(); @@ -324,23 +466,31 @@ openpcd_open(void *data) return NULL; } + if(usb_set_configuration(hdl, 1 ) < 0) + { + DEBUGP("setting config failed\n"); + usb_close( hdl ); + return NULL; + } + if (usb_claim_interface(hdl, 0) < 0) { DEBUGP("Can't claim interface\n"); usb_close(hdl); return NULL; } +#endif - rh = malloc(sizeof(*rh)); + rh = malloc_reader_handle(sizeof(*rh)); if (!rh) return NULL; memset(rh, 0, sizeof(*rh)); - rath = malloc(sizeof(*rath)); + rath = malloc_rat_handle(sizeof(*rath)); if (!rath) goto out_rh; memset(rath, 0, sizeof(*rath)); - rath->rat = &openpcd_ccid; + rath->rat = &openpcd_rat; rh->reader = &rfid_reader_openpcd; rh->ah = rc632_open(rath); @@ -351,9 +501,9 @@ openpcd_open(void *data) return rh; out_rath: - free(rath); + free_rat_handle(rath); out_rh: - free(rh); + free_reader_handle(rh); return NULL; } @@ -364,18 +514,34 @@ openpcd_close(struct rfid_reader_handle *rh) struct rfid_asic_transport_handle *rath = rh->ah->rath; rc632_close(rh->ah); - free(rath); - free(rh); + free_rat_handle(rath); + free_reader_handle(rh); +#ifndef LIBRFID_FIRMWARE usb_close(hdl); +#endif } -struct rfid_reader rfid_reader_openpcd = { +const struct rfid_reader rfid_reader_openpcd = { .name = "OpenPCD RFID Reader", .id = RFID_READER_OPENPCD, .open = &openpcd_open, .close = &openpcd_close, + +#ifndef LIBRFID_FIRMWARE + .get_api_version = &openpcd_get_api_version, + .get_environment = &openpcd_get_environment, + .set_environment = &openpcd_set_environment, + .reset = &openpcd_reset, +#endif + .transceive = &openpcd_transceive, + .l2_supported = (1 << RFID_LAYER2_ISO14443A) | + (1 << RFID_LAYER2_ISO14443B) | + (1 << RFID_LAYER2_ISO15693), + .proto_supported = (1 << RFID_PROTOCOL_TCL) | + (1 << RFID_PROTOCOL_MIFARE_UL) | + (1 << RFID_PROTOCOL_MIFARE_CLASSIC), .iso14443a = { .init = &openpcd_14443a_init, .transceive_sf = &openpcd_transceive_sf, @@ -387,6 +553,9 @@ struct rfid_reader rfid_reader_openpcd = { .iso14443b = { .init = &openpcd_14443b_init, }, + .iso15693 = { + .init = &openpcd_15693_init, + }, .mifare_classic = { .setkey = &openpcd_mifare_setkey, .auth = &openpcd_mifare_auth,