diff options
-rw-r--r-- | TODO | 25 | ||||
-rw-r--r-- | include/librfid/rfid_asic_rc632.h | 17 | ||||
-rw-r--r-- | include/librfid/rfid_layer2.h | 4 | ||||
-rw-r--r-- | include/librfid/rfid_layer2_iso15693.h | 76 | ||||
-rw-r--r-- | include/librfid/rfid_reader.h | 54 | ||||
-rw-r--r-- | include/librfid/rfid_reader_openpcd.h | 5 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/rfid.c | 8 | ||||
-rw-r--r-- | src/rfid_asic_rc632.c | 744 | ||||
-rw-r--r-- | src/rfid_layer2_iso14443a.c | 2 | ||||
-rw-r--r-- | src/rfid_layer2_iso14443b.c | 2 | ||||
-rw-r--r-- | src/rfid_layer2_iso15693.c | 297 | ||||
-rw-r--r-- | src/rfid_reader.c | 13 | ||||
-rw-r--r-- | src/rfid_reader_cm5121.c | 153 | ||||
-rw-r--r-- | src/rfid_reader_openpcd.c | 157 | ||||
-rw-r--r-- | src/rfid_reader_rc632_common.c | 152 | ||||
-rw-r--r-- | src/rfid_reader_rc632_common.h | 30 | ||||
-rw-r--r-- | src/rfid_reader_spidev.c | 152 | ||||
-rw-r--r-- | utils/librfid-tool.c | 13 |
19 files changed, 1055 insertions, 851 deletions
@@ -1,6 +1,14 @@ +architecture: +- somehow have some more abstrcat handle type in order to enable the generic + rfid_{get,set}opt() functions +- remove additional transceive_{acf,sf} functions from reader and asic structs, + make the code reuse the existing transceive() function by using the frametype + to differentiate different cases. + rc632: -- fix handling of timeout (program timer of RC632) -- add a timeout tolerance factor that can be user-specified +- make timeout tolerance factor (TIMER_RELAX_FACTOR) user-specified +- try to use built-in timer for timing analysis, i.e. determine the exact time + until a card response by reading the remaining timer ticks from the register - make sure interrupt mode for timer wait works cm5121: @@ -15,21 +23,22 @@ iso14443b: iso15693: - implement anticollision -- implement all the rest mifare_clasic: -- test -- try to auto-detect 1k/4k -- try to distinguish mifare ultralight and mifare classic in/after anticol +[none] + +icode1: +- implement and test code (I only have ICode2 tags) tcl: - implement pps for asymmetric (rx/tx) speeds openct: -- add ifdhandler driver +- add ifdhandler driver for PC/SC support +- add various standardized PC/SC remappings for cards != tcl other: -- implementation of code for various passive tags +- implementation of code for various passive tags, ie. ITRX, I*Code1, I*Code2, Tag-it, ... - documentation - add notion of 'asic implementation' for specifying reader-specific initialization values such as mod_conductance diff --git a/include/librfid/rfid_asic_rc632.h b/include/librfid/rfid_asic_rc632.h index 0602cd9..529b48c 100644 --- a/include/librfid/rfid_asic_rc632.h +++ b/include/librfid/rfid_asic_rc632.h @@ -5,6 +5,7 @@ struct rfid_asic_transport_handle; #include <librfid/rfid.h> #include <librfid/rfid_asic.h> +#include <librfid/rfid_layer2.h> struct rfid_asic_rc632_transport { struct { @@ -32,9 +33,9 @@ struct iso15693_anticol_cmd; struct rfid_asic_rc632 { struct { - int (*power_up)(struct rfid_asic_handle *h); - int (*power_down)(struct rfid_asic_handle *h); + int (*power)(struct rfid_asic_handle *h, int on); int (*rf_power)(struct rfid_asic_handle *h, int on); + int (*init)(struct rfid_asic_handle *h, enum rfid_layer2_id); int (*transceive)(struct rfid_asic_handle *h, enum rfid_frametype, const u_int8_t *tx_buf, @@ -44,7 +45,6 @@ struct rfid_asic_rc632 { u_int64_t timeout, unsigned int flags); struct { - int (*init)(struct rfid_asic_handle *h); int (*transceive_sf)(struct rfid_asic_handle *h, u_int8_t cmd, struct iso14443a_atqa *atqa); @@ -56,14 +56,11 @@ struct rfid_asic_rc632 { unsigned int speed); } iso14443a; struct { - int (*init)(struct rfid_asic_handle *h); - } iso14443b; - struct { - int (*init)(struct rfid_asic_handle *h); int (*transceive_ac)(struct rfid_asic_handle *h, - struct iso15693_anticol_cmd *acf, - unsigned char *uuid, - char *bit_of_col); + const struct iso15693_anticol_cmd *acf, + unsigned int acf_len, + struct iso15693_anticol_resp *resp, + unsigned int *rx_len, char *bit_of_col); } iso15693; struct { int (*setkey)(struct rfid_asic_handle *h, diff --git a/include/librfid/rfid_layer2.h b/include/librfid/rfid_layer2.h index 023b171..7fbf81c 100644 --- a/include/librfid/rfid_layer2.h +++ b/include/librfid/rfid_layer2.h @@ -32,9 +32,9 @@ int rfid_layer2_transceive(struct rfid_layer2_handle *l2h, u_int64_t timeout, unsigned int flags); int rfid_layer2_close(struct rfid_layer2_handle *l2h); int rfid_layer2_fini(struct rfid_layer2_handle *l2h); -int rfid_layer2_getopt(struct rfid_layer2_handle *ph, int optname, +int rfid_layer2_getopt(struct rfid_layer2_handle *l2h, int optname, void *optval, unsigned int *optlen); -int rfid_layer2_setopt(struct rfid_layer2_handle *ph, int optname, +int rfid_layer2_setopt(struct rfid_layer2_handle *l2h, int optname, const void *optval, unsigned int optlen); char *rfid_layer2_name(struct rfid_layer2_handle *l2h); #ifdef __LIBRFID__ diff --git a/include/librfid/rfid_layer2_iso15693.h b/include/librfid/rfid_layer2_iso15693.h index 5719a39..495eebb 100644 --- a/include/librfid/rfid_layer2_iso15693.h +++ b/include/librfid/rfid_layer2_iso15693.h @@ -29,40 +29,16 @@ /* protocol definitions */ -#if 0 -struct rfid_15693_handle; - -struct rfid_layer2_15693t { - unsigned char *name; - - struct { - int (*init)(struct iso15693_handle *handle); - int (*fini)(struct iso15693_handle *handle); - -#if 0 - int (*transceive_sf)(struct iso14443a_handle *handle, - unsigned char cmd, - struct iso14443a_atqa *atqa); - int (*transceive_acf)(struct iso14443a_handle *handle, - struct iso14443a_anticol_cmd *acf, - unsigned int *bit_of_col); -#endif - int (*transceive)(struct iso15693_handle *handle, - const unsigned char *tx_buf, - unsigned int tx_len, - unsigned char *rx_buf, - unsigned int *rx_len); - } fn; - - union { - } priv; -}; -#endif - struct iso15693_handle { unsigned int state; - unsigned int ask100:1, - out256:1; + unsigned int vcd_ask100:1, + vicc_two_subc:1, + vicc_fast:1, + single_slot:1, + use_afi:1, + vcd_out256:1; + u_int8_t afi; /* appplication family identifier */ + u_int8_t dsfid; /* data storage format identifier */ }; enum rfid_15693_state { @@ -76,6 +52,10 @@ enum rfid_15693_opt { RFID_OPT_15693_VCD_CODING = 0x00010002, RFID_OPT_15693_VICC_SUBC = 0x00010003, RFID_OPT_15693_VICC_SPEED = 0x00010004, + RFID_OPT_15693_VCD_SLOTS = 0x00010005, + RFID_OPT_15693_USE_AFI = 0x00010006, + RFID_OPT_15693_AFI = 0x00010007, + RFID_OPT_15693_DSFID = 0x00010008, }; enum rfid_15693_opt_mod_depth { @@ -195,14 +175,40 @@ enum iso15693_commands { }; struct iso15693_anticol_cmd { - /* iso15693-3 table5 flags*/ - unsigned char flags; // SLOTS16 | SLOT1, AFI_PRESENT, OPTION_FLAG - unsigned char afi; // AFI 0 for any + struct iso15693_request req; unsigned char mask_len; unsigned char mask_bits[ISO15693_UID_LEN]; unsigned char current_slot; } __attribute__((packed)); +struct iso15693_anticol_cmd_afi { + struct iso15693_request req; + unsigned char afi; + unsigned char mask_len; + unsigned char mask_bits[ISO15693_UID_LEN]; +} __attribute__((packed)); + +/* Figure 11, Chapter 9.2.1 */ +struct iso15693_anticol_resp { + struct iso15693_response resp; + u_int8_t dsfid; + u_int8_t uuid[ISO15693_UID_LEN]; +} __attribute__((packed)); + + +#define ISO15693_T_SLOW 0 +#define ISO15693_T_FAST 1 +enum iso15693_t { + ISO15693_T1, + ISO15693_T2, + ISO15693_T3, + ISO15693_T4, + ISO15693_T4_WRITE, +}; + +/* in microseconds as per Chapter 8.4 table 8 */ +extern const unsigned int iso15693_timing[2][5]; + #include <librfid/rfid_layer2.h> extern const struct rfid_layer2 rfid_layer2_iso15693; diff --git a/include/librfid/rfid_reader.h b/include/librfid/rfid_reader.h index 8dc7860..1c53677 100644 --- a/include/librfid/rfid_reader.h +++ b/include/librfid/rfid_reader.h @@ -7,39 +7,46 @@ struct rfid_reader_handle; +/* 0...0xffff = global options, 0x10000...0x1ffff = private options */ +#define RFID_OPT_RDR_PRIV 0x00010000 +enum rfid_reader_opt { + RFID_OPT_RDR_FW_VERSION = 0x0001, + RFID_OPT_RDR_RF_KILL = 0x0002, +}; + + struct rfid_reader { char *name; unsigned int id; unsigned int l2_supported; unsigned int proto_supported; - int (*get_api_version)( - struct rfid_reader_handle *h, - u_int8_t *version); + int (*reset)(struct rfid_reader_handle *h); - int (*get_environment)( - struct rfid_reader_handle *rh, - unsigned char num_bytes, - unsigned char *buf); + /* open the reader */ + struct rfid_reader_handle * (*open)(void *data); - int (*set_environment)( - struct rfid_reader_handle *rh, - unsigned char num_bytes, - const unsigned char *buf); + /* Initialize the reader for a given layer 2 */ + int (*init)(struct rfid_reader_handle *h, enum rfid_layer2_id); - int (*reset)(struct rfid_reader_handle *h); + /* completely close the reader */ + void (*close)(struct rfid_reader_handle *h); + + int (*getopt)(struct rfid_reader_handle *rh, int optname, + void *optval, unsigned int *optlen); + + int (*setopt)(struct rfid_reader_handle *rh, int optname, + const void *optval, unsigned int optlen); + + /* transceive one frame */ int (*transceive)(struct rfid_reader_handle *h, enum rfid_frametype frametype, const unsigned char *tx_buf, unsigned int tx_len, unsigned char *rx_buf, unsigned int *rx_len, u_int64_t timeout, unsigned int flags); - struct rfid_reader_handle * (*open)(void *data); - void (*close)(struct rfid_reader_handle *h); - int (*rf_power)(struct rfid_reader_handle *h, int on); struct rfid_14443a_reader { - int (*init)(struct rfid_reader_handle *h); int (*transceive_sf)(struct rfid_reader_handle *h, unsigned char cmd, struct iso14443a_atqa *atqa); @@ -52,15 +59,14 @@ struct rfid_reader { unsigned int speed; } iso14443a; struct rfid_14443b_reader { - int (*init)(struct rfid_reader_handle *rh); unsigned int speed; } iso14443b; struct rfid_15693_reader { - int (*init)(struct rfid_reader_handle *rh); int (*transceive_ac)(struct rfid_reader_handle *h, - struct iso15693_anticol_cmd *acf, - unsigned char *uuid, - char *bit_of_col); + const struct iso15693_anticol_cmd *acf, + unsigned int acf_len, + struct iso15693_anticol_resp *resp, + unsigned int *rx_len, char *bit_of_col); } iso15693; struct rfid_mifare_classic_reader { int (*setkey)(struct rfid_reader_handle *h, const unsigned char *key); @@ -89,4 +95,10 @@ extern struct rfid_reader_handle * rfid_reader_open(void *data, unsigned int id); extern void rfid_reader_close(struct rfid_reader_handle *rh); + +extern int rfid_reader_getopt(struct rfid_reader_handle *rh, int optname, + void *optval, unsigned int *optlen); +extern int rfid_reader_setopt(struct rfid_reader_handle *rh, int optname, + const void *optval, unsigned int optlen); + #endif diff --git a/include/librfid/rfid_reader_openpcd.h b/include/librfid/rfid_reader_openpcd.h index 14b1f63..05ea45e 100644 --- a/include/librfid/rfid_reader_openpcd.h +++ b/include/librfid/rfid_reader_openpcd.h @@ -99,4 +99,9 @@ enum openpcd_cmd_class { extern const struct rfid_reader rfid_reader_openpcd; +/* 0...0xffff = global options, 0x10000...0x1ffff = private options */ +enum rfid_reader_openpcd_opt { + RFID_OPT_RDR_ENVIRONMENT = 0x10001, +}; + #endif diff --git a/src/Makefile.am b/src/Makefile.am index f0e5a6e..cd93bdd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,7 +19,7 @@ L2 = rfid_layer2_iso14443a.c rfid_layer2_iso14443b.c rfid_iso14443_common.c \ rfid_layer2_iso15693.c PROTO = rfid_proto_tcl.c rfid_proto_mifare_ul.c rfid_proto_mifare_classic.c \ rfid_proto_icode.c rfid_proto_tagit.c -ASIC = rfid_asic_rc632.c +ASIC = rfid_asic_rc632.c rfid_reader_rc632_common.c MISC = rfid_access_mifare_classic.c if ENABLE_WIN32 @@ -59,9 +59,8 @@ int rfid_setopt(struct rfid_handle *rh, unsigned int level, const void *opt, unsigned int *optlen) { switch (level) { - case RFID_LEVEL_ASIC: case RFID_LEVEL_READER: - return -EINVAL; + return rfid_reader_setopt(optname, opt, optlen); break; case RFID_LEVEL_LAYER2: return rfid_layer2_setopt(optname, opt, optlen); @@ -69,6 +68,7 @@ int rfid_setopt(struct rfid_handle *rh, unsigned int level, case RFID_LEVEL_LAYER3: return rfid_layer3_setopt(optname, opt, optlen); break; + case RFID_LEVEL_ASIC: default: return -EINVAL; break; @@ -82,9 +82,8 @@ int rfid_getopt(struct rfid_handle *rh, unsigned int level, void *opt, unsigned int *optlen) { switch (level) { - case RFID_LEVEL_ASIC: case RFID_LEVEL_READER: - return -EINVAL; + return rfid_reader_getopt(optname, opt, optlen); break; case RFID_LEVEL_LAYER2: return rfid_layer2_getopt(optname, opt, optlen); @@ -92,6 +91,7 @@ int rfid_getopt(struct rfid_handle *rh, unsigned int level, case RFID_LEVEL_LAYER3: return rfid_layer3_getopt(optname, opt, optlen); break; + case RFID_LEVEL_ASIC: default: return -EINVAL; break; diff --git a/src/rfid_asic_rc632.c b/src/rfid_asic_rc632.c index 8fc5cb9..4286565 100644 --- a/src/rfid_asic_rc632.c +++ b/src/rfid_asic_rc632.c @@ -19,6 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#define DEBUG_LIBRFID + #include <unistd.h> #include <stdlib.h> #include <string.h> @@ -43,9 +45,16 @@ #define RC632_TMO_AUTH1 140 +#define TIMER_RELAX_FACTOR 10 + #define ENTER() DEBUGP("entering\n") const struct rfid_asic rc632; +struct register_file { + u_int8_t reg; + u_int8_t val; +}; + /* Register and FIFO Access functions */ static int rc632_reg_write(struct rfid_asic_handle *handle, @@ -160,18 +169,30 @@ rc632_rf_power(struct rfid_asic_handle *handle, int on) } static int -rc632_power_up(struct rfid_asic_handle *handle) +rc632_power(struct rfid_asic_handle *handle, int on) { ENTER(); - return rc632_clear_bits(handle, RC632_REG_CONTROL, - RC632_CONTROL_POWERDOWN); + if (on) + return rc632_clear_bits(handle, RC632_REG_CONTROL, + RC632_CONTROL_POWERDOWN); + else + return rc632_set_bits(handle, RC632_REG_CONTROL, + RC632_CONTROL_POWERDOWN); } static int -rc632_power_down(struct rfid_asic_handle *handle) +rc632_execute_script(struct rfid_asic_handle *h, struct register_file *f, + int len) { - return rc632_set_bits(handle, RC632_REG_CONTROL, - RC632_CONTROL_POWERDOWN); + int i, ret; + + for (i = 0; i < len; i++) { + ret = rc632_reg_write(h, f[i].reg, f[i].val); + if (ret < 0) + return ret; + } + + return 0; } /* calculate best 8bit prescaler and divisor for given usec timeout */ @@ -223,6 +244,8 @@ rc632_timer_set(struct rfid_asic_handle *handle, int ret; u_int8_t prescaler, divisor; + timeout *= TIMER_RELAX_FACTOR; + ret = best_prescaler(timeout, &prescaler, &divisor); ret = rc632_reg_write(handle, RC632_REG_TIMER_CLOCK, @@ -245,24 +268,31 @@ rc632_timer_set(struct rfid_asic_handle *handle, static int rc632_wait_idle_timer(struct rfid_asic_handle *handle) { int ret; - u_int8_t irq, cmd; + u_int8_t stat, irq, cmd; while (1) { - rc632_reg_read(handle, RC632_REG_PRIMARY_STATUS, &irq); - rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &irq); - ret = rc632_reg_read(handle, RC632_REG_INTERRUPT_RQ, &irq); - if (ret < 0) - return ret; - - /* FIXME: currently we're lazy: If we actually received - * something even after the timer expired, we accept it */ - if (irq & RC632_IRQ_TIMER && !(irq & RC632_IRQ_RX)) { - u_int8_t foo; - rc632_reg_read(handle, RC632_REG_PRIMARY_STATUS, &foo); - if (foo & 0x04) - rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &foo); + rc632_reg_read(handle, RC632_REG_PRIMARY_STATUS, &stat); + DEBUGP_STATUS_FLAG(stat); + if (stat & RC632_STAT_ERR) { + u_int8_t err; + rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &err); + DEBUGP_ERROR_FLAG(err); + if (err & (RC632_ERR_FLAG_COL_ERR | + RC632_ERR_FLAG_PARITY_ERR | + RC632_ERR_FLAG_FRAMING_ERR | + RC632_ERR_FLAG_CRC_ERR)) + return -EIO; + } + if (stat & RC632_STAT_IRQ) { + ret = rc632_reg_read(handle, RC632_REG_INTERRUPT_RQ, &irq); + if (ret < 0) + return ret; + DEBUGP_INTERRUPT_FLAG(irq); - return -110; + if (irq & RC632_IRQ_TIMER && !(irq & RC632_IRQ_RX)) { + DEBUGP("timer expired before RX!!\n"); + return -ETIMEDOUT; + } } ret = rc632_reg_read(handle, RC632_REG_COMMAND, &cmd); @@ -286,6 +316,8 @@ rc632_wait_idle(struct rfid_asic_handle *handle, u_int64_t timeout) int ret, cycles = 0; #define USLEEP_PER_CYCLE 128 + timeout *= TIMER_RELAX_FACTOR; + while (cmd != 0) { ret = rc632_reg_read(handle, RC632_REG_COMMAND, &cmd); if (ret < 0) @@ -315,7 +347,7 @@ rc632_wait_idle(struct rfid_asic_handle *handle, u_int64_t timeout) } /* Abort after some timeout */ - if (cycles > timeout*100/USLEEP_PER_CYCLE) { + if (cycles > timeout/USLEEP_PER_CYCLE) { DEBUGP("timeout...\n"); return -ETIMEDOUT; } @@ -336,6 +368,8 @@ rc632_transmit(struct rfid_asic_handle *handle, int ret, cur_len; const u_int8_t *cur_buf = buf; + DEBUGP("timeout=%u, tx_len=%u\n", timeout, len); + if (len > 64) cur_len = 64; else @@ -387,22 +421,34 @@ rc632_transceive(struct rfid_asic_handle *handle, u_int8_t rx_avail; const u_int8_t *cur_tx_buf = tx_buf; - DEBUGP("timer=%u, rx_len=%u, tx_len=%u,", timer, rx_len, tx_len); + DEBUGP("timeout=%u, rx_len=%u, tx_len=%u\n", timer, *rx_len, tx_len); if (tx_len > 64) cur_tx_len = 64; else cur_tx_len = tx_len; - ret = rc632_timer_set(handle, timer); - if (ret < 0) - return ret; - + ret = rc632_reg_write(handle, RC632_REG_COMMAND, 0x00); /* clear all interrupts */ ret = rc632_reg_write(handle, RC632_REG_INTERRUPT_RQ, 0x7f); ret = rc632_reg_write(handle, RC632_REG_ERROR_FLAG, 0xff); + { u_int8_t tmp; + rc632_reg_read(handle, RC632_REG_PRIMARY_STATUS, &tmp); + DEBUGP_STATUS_FLAG(tmp); + rc632_reg_read(handle, RC632_REG_PRIMARY_STATUS, &tmp); + DEBUGP_STATUS_FLAG(tmp); + rc632_reg_read(handle, RC632_REG_PRIMARY_STATUS, &tmp); + DEBUGP_STATUS_FLAG(tmp); + rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &tmp); + DEBUGP_ERROR_FLAG(tmp); + } + + ret = rc632_timer_set(handle, timer); + if (ret < 0) + return ret; + do { ret = rc632_fifo_write(handle, cur_tx_len, cur_tx_buf, 0x03); if (ret < 0) @@ -432,10 +478,10 @@ rc632_transceive(struct rfid_asic_handle *handle, if (toggle == 1) tcl_toggle_pcb(handle); - //ret = rc632_wait_idle_timer(handle); - ret = rc632_wait_idle(handle, timer); + ret = rc632_wait_idle_timer(handle); + //ret = rc632_wait_idle(handle, timer); - DEBUGP("rc632_wait_idle>>ret=%d %s\n",ret,(ret==-ETIMEDOUT)?"ETIMEDOUT":""); + DEBUGP("rc632_wait_idle >> ret=%d %s\n",ret,(ret==-ETIMEDOUT)?"ETIMEDOUT":""); if (ret < 0) return ret; @@ -479,21 +525,29 @@ rc632_receive(struct rfid_asic_handle *handle, int ret, cur_tx_len, i; u_int8_t rx_avail; - /* - DEBUGP("timer = %u\n", timer); - ret = rc632_timer_set(handle, timer*10); - if (ret < 0) - return ret; - /* + DEBUGP("timeout=%u, rx_len=%u\n", timer, *rx_len); ret = rc632_reg_write(handle, RC632_REG_COMMAND, 0x00); /* IDLE */ /* clear all interrupts */ ret = rc632_reg_write(handle, RC632_REG_INTERRUPT_RQ, 0x7f); + ret = rc632_timer_set(handle, timer); + if (ret < 0) + return ret; + ret = rc632_reg_write(handle, RC632_REG_COMMAND,RC632_CMD_RECEIVE); if (ret < 0) - return ret; + return ret; + + /* the timer cannot start in hardware based on the command we just + * sent. this means that our timing will always be quite a bit more lax, + * i.e. we'll always wait for a bit longer than the specs ask us to. */ + ret = rc632_set_bits(handle, RC632_REG_CONTROL, + RC632_CONTROL_TIMER_START); + if (ret < 0) + return ret; - ret = rc632_wait_idle(handle, timer); + //ret = rc632_wait_idle(handle, timer); + ret = rc632_wait_idle_timer(handle); if (ret < 0) return ret; @@ -628,14 +682,14 @@ rc632_init(struct rfid_asic_handle *ah) int ret; /* switch off rf (make sure PICCs are reset at init time) */ - ret = rc632_power_down(ah); + ret = rc632_power(ah, 0); if (ret < 0) return ret; usleep(10000); /* switch on rf */ - ret = rc632_power_up(ah); + ret = rc632_power(ah, 1); if (ret < 0) return ret; @@ -674,7 +728,7 @@ rc632_fini(struct rfid_asic_handle *ah) if (ret < 0) return ret; - ret = rc632_power_down(ah); + ret = rc632_power(ah, 0); if (ret < 0) return ret; @@ -713,112 +767,88 @@ rc632_close(struct rfid_asic_handle *h) free_asic_handle(h); } - -/* - * Philips CL RC632 primitives for ISO 14443-A compliant PICC's - * - * (C) 2005-2006 by Harald Welte <laforge@gnumonks.org> - * +/* + * ISO14443A */ +/* Register file for ISO14443A standard */ +static struct register_file iso14443a_script[] = { + { + .reg = RC632_REG_TX_CONTROL, + .val = RC632_TXCTRL_MOD_SRC_INT | + RC632_TXCTRL_TX2_INV | + RC632_TXCTRL_FORCE_100_ASK | + RC632_TXCTRL_TX2_RF_EN | + RC632_TXCTRL_TX1_RF_EN, + }, { + .reg = RC632_REG_CW_CONDUCTANCE, + .val = CM5121_CW_CONDUCTANCE, + }, { + .reg = RC632_REG_MOD_CONDUCTANCE, + .val = CM5121_MOD_CONDUCTANCE, + }, { + .reg = RC632_REG_CODER_CONTROL, + .val = (RC632_CDRCTRL_TXCD_14443A | + RC632_CDRCTRL_RATE_106K), + }, { + .reg = RC632_REG_MOD_WIDTH, + .val = 0x13, + }, { + .reg = RC632_REG_MOD_WIDTH_SOF, + .val = 0x3f, + }, { + .reg = RC632_REG_TYPE_B_FRAMING, + .val = 0x00, + }, { + .reg = RC632_REG_RX_CONTROL1, + .val = (RC632_RXCTRL1_GAIN_35DB | + RC632_RXCTRL1_ISO14443 | + RC632_RXCTRL1_SUBCP_8), + }, { + .reg = RC632_REG_DECODER_CONTROL, + .val = (RC632_DECCTRL_MANCHESTER | + RC632_DECCTRL_RXFR_14443A), + }, { + .reg = RC632_REG_BIT_PHASE, + .val = CM5121_14443A_BITPHASE, + }, { + .reg = RC632_REG_RX_THRESHOLD, + .val = CM5121_14443A_THRESHOLD, + }, { + .reg = RC632_REG_BPSK_DEM_CONTROL, + .val = 0x00, + }, { + .reg = RC632_REG_RX_CONTROL2, + .val = (RC632_RXCTRL2_DECSRC_INT | + RC632_RXCTRL2_CLK_Q), + }, { + .reg = RC632_REG_RX_WAIT, + //.val = 0x03, /* default value */ + .val = 0x06, /* omnikey */ + }, { + .reg = RC632_REG_CHANNEL_REDUNDANCY, + .val = (RC632_CR_PARITY_ENABLE | + RC632_CR_PARITY_ODD), + }, { + .reg = RC632_REG_CRC_PRESET_LSB, + .val = 0x63, + }, { + .reg = RC632_REG_CRC_PRESET_MSB, + .val = 0x63, + }, +}; + static int rc632_iso14443a_init(struct rfid_asic_handle *handle) { int ret; - /* FIXME: some fifo work (drain fifo?) */ - /* flush fifo (our way) */ ret = rc632_reg_write(handle, RC632_REG_CONTROL, RC632_CONTROL_FIFO_FLUSH); - ret = rc632_reg_write(handle, RC632_REG_TX_CONTROL, - (RC632_TXCTRL_TX1_RF_EN | - RC632_TXCTRL_TX2_RF_EN | - RC632_TXCTRL_TX2_INV | - RC632_TXCTRL_FORCE_100_ASK | - RC632_TXCTRL_MOD_SRC_INT)); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_CW_CONDUCTANCE, - CM5121_CW_CONDUCTANCE); - if (ret < 0) - return ret; - - /* Since FORCE_100_ASK is set (cf mc073930.pdf), this line may be left out? */ - ret = rc632_reg_write(handle, RC632_REG_MOD_CONDUCTANCE, - CM5121_MOD_CONDUCTANCE); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_CODER_CONTROL, - (RC632_CDRCTRL_TXCD_14443A | - RC632_CDRCTRL_RATE_106K)); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_MOD_WIDTH, 0x13); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_MOD_WIDTH_SOF, 0x3f); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_TYPE_B_FRAMING, 0x00); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_RX_CONTROL1, - (RC632_RXCTRL1_GAIN_35DB | - RC632_RXCTRL1_ISO14443 | - RC632_RXCTRL1_SUBCP_8)); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_DECODER_CONTROL, - (RC632_DECCTRL_MANCHESTER | - RC632_DECCTRL_RXFR_14443A)); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_BIT_PHASE, - CM5121_14443A_BITPHASE); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_RX_THRESHOLD, - CM5121_14443A_THRESHOLD); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_BPSK_DEM_CONTROL, 0x00); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_RX_CONTROL2, - (RC632_RXCTRL2_DECSRC_INT | - RC632_RXCTRL2_CLK_Q)); - if (ret < 0) - return ret; - - /* Omnikey proprietary driver has 0x03, but 0x06 is the default reset value ?!? */ - ret = rc632_reg_write(handle, RC632_REG_RX_WAIT, 0x06); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_CHANNEL_REDUNDANCY, - (RC632_CR_PARITY_ENABLE | - RC632_CR_PARITY_ODD)); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_CRC_PRESET_LSB, 0x63); - if (ret < 0) - return ret; - - ret = rc632_reg_write(handle, RC632_REG_CRC_PRESET_MSB, 0x63); + ret = rc632_execute_script(handle, iso14443a_script, + ARRAY_SIZE(iso14443a_script)); if (ret < 0) return ret; @@ -1052,138 +1082,6 @@ rc632_iso14443a_transceive_acf(struct rfid_asic_handle *handle, return 0; } -static void uuid_reversecpy(unsigned char* out, unsigned char* in, int len) -{ - int i = 0; - while (len > 0) { - out[i] = in[len]; - len--; - i++; - } -} - - -static int -rc632_iso15693_transceive_ac(struct rfid_asic_handle *handle, - struct iso15693_anticol_cmd *acf, - unsigned char uuid[ISO15693_UID_LEN], - char *bit_of_col) -{ - u_int8_t boc; - u_int8_t error_flag, tmp; - u_int8_t rx_len; - - int ret, tx_len, mask_len_bytes; - - struct iso15693_request_inventory { - struct iso15693_request head; - unsigned char mask_length; - /* mask_value[0] + (maybe crc[2]) */ - unsigned char data[ISO15693_UID_LEN]; - } req; - - struct { - struct iso15693_response head; - unsigned char dsfid; - unsigned char uuid[ISO15693_UID_LEN]; - } rx_buf; - - memset(uuid, 0, ISO15693_UID_LEN); - - *bit_of_col = 0; - rx_len = sizeof(rx_buf); - mask_len_bytes = (acf->mask_len % 8) ? acf->mask_len/8+1 : acf->mask_len/8; - - - if (acf->current_slot == 0) { - /* first call: transmit Inventory frame */ - DEBUGP("first_frame\n"); - req.head.command = ISO15693_CMD_INVENTORY; - req.head.flags = (acf->flags & 0xf0) - | RFID_15693_F_INV_TABLE_5 - | RFID_15693_F_RATE_HIGH; - //| RFID_15693_F_SUBC_TWO | RFID_15693_F_RATE_HIGH; - req.mask_length = acf->mask_len; - memset(req.data, 0, ISO15693_UID_LEN); - memcpy(req.data, acf->mask_bits, mask_len_bytes); - - tx_len = sizeof(struct iso15693_request) + 1 + mask_len_bytes; - - ret = rc632_transceive(handle, (u_int8_t *)&req, tx_len, - (u_int8_t *)&rx_buf, &rx_len, 10, 0); - acf->current_slot = 1; - DEBUGP("rc632_transceive ret: %d rx_len: %d\n",ret,rx_len); - /* if ((ret < 0)&&(ret != -ETIMEDOUT)) - return ret; */ - - } else { - /* second++ call: end timeslot with EOFpulse and read */ - DEBUGP("second++_frame\n"); - if ((acf->current_slot > 16) || - ((acf->flags & RFID_15693_F5_NSLOTS_1 == 0) - && (acf->current_slot > 1))) { - - memset(uuid, 0, ISO15693_UID_LEN); - return -1; - } - - /* reset EOF-pulse-bit to 0 */ - ret = rc632_clear_bits(handle, RC632_REG_CODER_CONTROL, - RC632_CDRCTRL_15693_EOF_PULSE); - usleep(50); - /* generate EOF pulse */ - ret = rc632_set_bits(handle, RC632_REG_CODER_CONTROL, - RC632_CDRCTRL_15693_EOF_PULSE); - if (ret < 0) - return ret; - // DEBUGP("waiting for EOF pulse\n"); - // ret = rc632_wait_idle(handle, 10); //wait for idle - - rx_len = sizeof(rx_buf); - ret = rc632_receive(handle, (u_int8_t*)&rx_buf, &rx_len, 50); - DEBUGP("rc632_receive ret: %d rx_len: %d\n", ret, rx_len); - acf->current_slot++; - - /* if ((ret < 0)&&(ret != -ETIMEDOUT)) - return ret; */ - } - - rc632_reg_read(handle, RC632_REG_PRIMARY_STATUS, &tmp); - DEBUGP_STATUS_FLAG(tmp); - - if (ret == -ETIMEDOUT) { - /* no VICC answer in this timeslot*/ - memset(uuid, 0, ISO15693_UID_LEN); - return -ETIMEDOUT; - } else { - /* determine whether there was a collission */ - ret = rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &error_flag); - DEBUGP_ERROR_FLAG(error_flag); - if (ret < 0) - return ret; - - if (error_flag & RC632_ERR_FLAG_COL_ERR) { - /* retrieve bit of collission */ - ret = rc632_reg_read(handle, RC632_REG_COLL_POS, &boc); - if (ret < 0) - return ret; - *bit_of_col = boc; - memcpy(uuid, rx_buf.uuid, ISO15693_UID_LEN); - // uuid_reversecpy(uuid, rx_buf.uuid, ISO15693_UID_LEN); - DEBUGP("Collision in slot %d bit %d\n", - acf->current_slot,boc); - return -ECOLLISION; - } else { - /* no collision-> retrieve uuid */ - DEBUGP("no collision in slot %d\n", acf->current_slot); - memcpy(uuid, rx_buf.uuid, ISO15693_UID_LEN); - //uuid_reversecpy(uuid, rx_buf.uuid, ISO15693_UID_LEN); - } - } - - return 0; -} - enum rc632_rate { RC632_RATE_106 = 0x00, RC632_RATE_212 = 0x01, @@ -1305,6 +1203,79 @@ static int rc632_iso14443a_set_speed(struct rfid_asic_handle *handle, return 0; } +#if 0 +static struct register_file iso14443b_script[] = { + { + .reg = RC632_REG_TX_CONTROL, + .val = (RC632_TXCTRL_TX1_RF_EN | + RC632_TXCTRL_TX2_RF_EN | + RC632_TXCTRL_TX2_INV | + RC632_TXCTRL_MOD_SRC_INT), + }, { + .reg = RC632_REG_CW_CONDUCTANCE, + .val = 0x3f, + }, { + .reg = RC632_REG_MOD_CONDUCTANCE, + .val = 0x04, + }, { + .reg = RC632_REG_CODER_CONTROL, + .val = (RC632_CDRCTRL_TXCD_NRZ | + RC632_CDRCTRL_RATE_14443B), + }, { + .reg = RC632_REG_MOD_WIDTH, + .val = 0x13, + }, { + .reg = RC632_REG_MOD_WIDTH_SOF, + .val = 0x3f, + }, { + .reg = RC632_REG_TYPE_B_FRAMING, + .val = (RC632_TBFRAMING_SOF_11L_3H | + (6 << RC632_TBFRAMING_SPACE_SHIFT) | + RC632_TBFRAMING_EOF_11); + }, { + .reg = RC632_REG_RX_CONTROL1, + .val = (RC632_RXCTRL1_GAIN_35DB | + RC632_RXCTRL1_ISO14443, + RC632_RXCTRL1_SUBCP_8), + }, { + .reg = RC632_REG_DECODER_CONTROL, + .val = (RC632_DECCTRL_BPSK | + RC632_DECCTRL_RXFR_14443B), + }, { + .reg = RC632_REG_BIT_PHASE, + .val = CM5121_14443B_BITPHASE, + }, { + .reg = RC632_REG_RX_THRESHOLD, + .val = CM5121_14443B_THRESHOLD, + }, { + .reg = RC632_REG_BPSK_DEM_CONTROL, + .val = ((0x2 & RC632_BPSKD_TAUB_MASK)<<RC632_BPSKD_TAUB_SHIFT | + (0x3 & RC632_BPSKD_TAUD_MASK)<<RC632_BPSKD_TAUD_SHIFT | + RC632_BPSKD_FILTER_AMP_DETECT | + RC632_BPSKD_NO_RX_EOF | + RC632_BPSKD_NO_RX_EGT), + }, { + .reg = RC632_REG_RX_CONTROL2, + .val = (RC632_RXCTRL2_AUTO_PD | + RC632_RXCTRL2_DECSRC_INT), + }, { + .reg = RC632_REG_RX_WAIT, + .val = 0x03, + }, { + .reg = RC632_REG_CHANNEL_REDUNDANCY, + .val = (RC632_CR_TX_CRC_ENABLE | + RC632_CR_RX_CRC_ENABLE | + RC632_CR_CRC3309), + }, { + .reg = RC632_REG_CRC_PRESET_LSB, + .val = 0xff, + }, { + .reg = RC632_REG_CRC_PRESET_MSB, + .val = 0xff, + }, +}; +#endif + static int rc632_iso14443b_init(struct rfid_asic_handle *handle) { int ret; @@ -1414,10 +1385,11 @@ static int rc632_iso14443b_init(struct rfid_asic_handle *handle) return 0; } -struct register_file { - u_int8_t reg; - u_int8_t val; -}; + + +/* + * ISO15693 + */ /* Register file for ISO15693 standard */ static struct register_file iso15693_fast_script[] = { @@ -1568,47 +1540,45 @@ static struct register_file icode1_fast_patch[] = { }, }; + static int rc632_iso15693_init(struct rfid_asic_handle *h) { - int ret, i; - ENTER(); + int ret; /* flush fifo (our way) */ ret = rc632_reg_write(h, RC632_REG_CONTROL, RC632_CONTROL_FIFO_FLUSH); + if (ret < 0) + return ret; - for (i = 0; i < ARRAY_SIZE(iso15693_fast_script); i++) { - ret = rc632_reg_write(h, iso15693_fast_script[i].reg, - iso15693_fast_script[i].val); - if (ret < 0) - return ret; - } + ret = rc632_execute_script(h, iso15693_fast_script, + ARRAY_SIZE(iso15693_fast_script)); + if (ret < 0) + return ret; return 0; } static int -rc632_iso15693_icode1_init(struct rfid_asic_handle *h, int fast) +rc632_iso15693_icode1_init(struct rfid_asic_handle *h) { int ret; - int i; - for (i = 0; i < ARRAY_SIZE(icode1_std_script); i++) { - ret = rc632_reg_write(h, icode1_std_script[i].reg, - icode1_std_script[i].val); - if (ret < 0) - return ret; - } + ret = rc632_execute_script(h, icode1_std_script, + ARRAY_SIZE(icode1_std_script)); + if (ret < 0) + return ret; + /* FIXME: how to configure fast/slow properly? */ +#if 0 if (fast) { - for (i = 0; i < ARRAY_SIZE(icode1_fast_patch); i++) { - ret = rc632_reg_write(h, icode1_fast_patch[i].reg, - icode1_fast_patch[i].val); - if (ret < 0) - return ret; - } + ret = rc632_execute_script(h, icode1_fast_patch, + ARRAY_SIZE(icode1_fast_patch)); + if (ret < 0) + return ret; } +#endif return 0; } @@ -1694,6 +1664,143 @@ rc632_iso15693_icl_init(struct rfid_asic_handle *h) return 0; } +static void uuid_reversecpy(unsigned char* out, unsigned char* in, int len) +{ + int i = 0; + while (len > 0) { + out[i] = in[len]; + len--; + i++; + } +} + +static int +rc632_iso15693_transceive_ac(struct rfid_asic_handle *handle, + const struct iso15693_anticol_cmd *acf, + unsigned int acf_len, + struct iso15693_anticol_resp *resp, + unsigned int *rx_len, char *bit_of_col) +{ + u_int8_t error_flag, boc; + //u_int8_t rx_len; + + int ret, tx_len, mask_len_bytes; + unsigned int rate = ISO15693_T_SLOW; + + if (acf->req.flags & RFID_15693_F_RATE_HIGH) + rate = ISO15693_T_FAST; + + printf("acf = %s\n", rfid_hexdump(acf, acf_len)); + + ret = rc632_transceive(handle, (u_int8_t *)acf, acf_len, + (u_int8_t *) resp, rx_len, + iso15693_timing[rate][ISO15693_T1], 0); + if (ret == -ETIMEDOUT) + return ret; + + /* determine whether there was a collission */ + ret = rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &error_flag); + if (ret < 0) + return ret; + DEBUGP_ERROR_FLAG(error_flag); + + if (error_flag & RC632_ERR_FLAG_COL_ERR) { + /* retrieve bit of collission */ + ret = rc632_reg_read(handle, RC632_REG_COLL_POS, &boc); + if (ret < 0) + return ret; + *bit_of_col = boc; + } + + return 0; + +#if 0 + *bit_of_col = 0; + + mask_len_bytes = (acf->mask_len % 8) ? acf->mask_len/8+1 : acf->mask_len/8; + + if (acf->current_slot == 0) { + /* first call: transmit Inventory frame */ + DEBUGP("first_frame\n"); + + tx_len = sizeof(struct iso15693_request) + 1 + mask_len_bytes; + + ret = rc632_transceive(handle, (u_int8_t *)&req, tx_len, + (u_int8_t *)&rx_buf, &rx_len, ISO15693_T1, 0); + acf->current_slot = 1; + DEBUGP("rc632_transceive ret: %d rx_len: %d\n",ret,rx_len); + /* if ((ret < 0)&&(ret != -ETIMEDOUT)) + return ret; */ + + } else { + /* second++ call: end timeslot with EOFpulse and read */ + DEBUGP("second++_frame\n"); + if ((acf->current_slot > 16) || + ((acf->flags & RFID_15693_F5_NSLOTS_1 == 0) + && (acf->current_slot > 1))) { + + memset(uuid, 0, ISO15693_UID_LEN); + return -1; + } + + /* reset EOF-pulse-bit to 0 */ + ret = rc632_clear_bits(handle, RC632_REG_CODER_CONTROL, + RC632_CDRCTRL_15693_EOF_PULSE); + usleep(50); + /* generate EOF pulse */ + ret = rc632_set_bits(handle, RC632_REG_CODER_CONTROL, + RC632_CDRCTRL_15693_EOF_PULSE); + if (ret < 0) + return ret; + // DEBUGP("waiting for EOF pulse\n"); + // ret = rc632_wait_idle(handle, 10); //wait for idle + + rx_len = sizeof(rx_buf); + ret = rc632_receive(handle, (u_int8_t*)&rx_buf, &rx_len, ISO15693_T3); + DEBUGP("rc632_receive ret: %d rx_len: %d\n", ret, rx_len); + acf->current_slot++; + + /* if ((ret < 0)&&(ret != -ETIMEDOUT)) + return ret; */ + } + + rc632_reg_read(handle, RC632_REG_PRIMARY_STATUS, &tmp); + DEBUGP_STATUS_FLAG(tmp); + + if (ret == -ETIMEDOUT) { + /* no VICC answer in this timeslot*/ + memset(uuid, 0, ISO15693_UID_LEN); + return -ETIMEDOUT; + } else { + /* determine whether there was a collission */ + ret = rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &error_flag); + DEBUGP_ERROR_FLAG(error_flag); + if (ret < 0) + return ret; + + if (error_flag & RC632_ERR_FLAG_COL_ERR) { + /* retrieve bit of collission */ + ret = rc632_reg_read(handle, RC632_REG_COLL_POS, &boc); + if (ret < 0) + return ret; + *bit_of_col = boc; + memcpy(uuid, rx_buf.uuid, ISO15693_UID_LEN); + // uuid_reversecpy(uuid, rx_buf.uuid, ISO15693_UID_LEN); + DEBUGP("Collision in slot %d bit %d\n", + acf->current_slot,boc); + return -ECOLLISION; + } else { + /* no collision-> retrieve uuid */ + DEBUGP("no collision in slot %d\n", acf->current_slot); + memcpy(uuid, rx_buf.uuid, ISO15693_UID_LEN); + //uuid_reversecpy(uuid, rx_buf.uuid, ISO15693_UID_LEN); + } + } + + return 0; +#endif +} + struct mifare_authcmd { u_int8_t auth_cmd; u_int8_t block_address; @@ -1745,7 +1852,12 @@ rc632_mifare_set_key(struct rfid_asic_handle *h, const u_int8_t *key) if (ret < 0) return ret; - ret = rc632_wait_idle(h, RC632_TMO_AUTH1); + ret = rc632_timer_set(h, RC632_TMO_AUTH1); + if (ret < 0) + return ret; + + //ret = rc632_wait_idle(h, RC632_TMO_AUTH1); + ret = rc632_wait_idle_timer(h); if (ret < 0) return ret; @@ -1803,7 +1915,12 @@ rc632_mifare_auth(struct rfid_asic_handle *h, u_int8_t cmd, u_int32_t serno, } /* Wait until transmitter is idle */ - ret = rc632_wait_idle(h, RC632_TMO_AUTH1); + ret = rc632_timer_set(h, RC632_TMO_AUTH1); + if (ret < 0) + return ret; + + //ret = rc632_wait_idle(h, RC632_TMO_AUTH1); + ret = rc632_wait_idle_timer(h); if (ret < 0) return ret; @@ -1821,13 +1938,19 @@ rc632_mifare_auth(struct rfid_asic_handle *h, u_int8_t cmd, u_int32_t serno, if (ret < 0) return ret; + /* Wait until transmitter is idle */ + ret = rc632_timer_set(h, RC632_TMO_AUTH1); + if (ret < 0) + return ret; + /* Send Authent2 Command */ ret = rc632_reg_write(h, RC632_REG_COMMAND, RC632_CMD_AUTHENT2); if (ret < 0) return ret; /* Wait until transmitter is idle */ - ret = rc632_wait_idle(h, RC632_TMO_AUTH1); + //ret = rc632_wait_idle(h, RC632_TMO_AUTH1); + ret = rc632_wait_idle_timer(h); if (ret < 0) return ret; @@ -1879,26 +2002,39 @@ rc632_mifare_transceive(struct rfid_asic_handle *handle, return 0; } + +static int +rc632_layer2_init(struct rfid_asic_handle *h, enum rfid_layer2_id l2) +{ + switch (l2) { + case RFID_LAYER2_ISO14443A: + return rc632_iso14443a_init(h); + case RFID_LAYER2_ISO14443B: + return rc632_iso14443b_init(h); + case RFID_LAYER2_ISO15693: + return rc632_iso15693_init(h); + case RFID_LAYER2_ICODE1: + return rc632_iso15693_icode1_init(h); + default: + return -EINVAL; + } +} + const struct rfid_asic rc632 = { .name = "Philips CL RC632", .fc = ISO14443_FREQ_CARRIER, .priv.rc632 = { .fn = { - .power_up = &rc632_power_up, - .power_down = &rc632_power_down, + .power = &rc632_power, .rf_power = &rc632_rf_power, .transceive = &rc632_iso14443ab_transceive, + .init = &rc632_layer2_init, .iso14443a = { - .init = &rc632_iso14443a_init, .transceive_sf = &rc632_iso14443a_transceive_sf, .transceive_acf = &rc632_iso14443a_transceive_acf, .set_speed = &rc632_iso14443a_set_speed, }, - .iso14443b = { - .init = &rc632_iso14443b_init, - }, .iso15693 = { - .init = &rc632_iso15693_init, .transceive_ac = &rc632_iso15693_transceive_ac, }, .mifare_classic = { diff --git a/src/rfid_layer2_iso14443a.c b/src/rfid_layer2_iso14443a.c index 148960d..281f709 100644 --- a/src/rfid_layer2_iso14443a.c +++ b/src/rfid_layer2_iso14443a.c @@ -361,7 +361,7 @@ iso14443a_init(struct rfid_reader_handle *rh) h->priv.iso14443a.state = ISO14443A_STATE_NONE; h->priv.iso14443a.level = ISO14443A_LEVEL_NONE; - ret = h->rh->reader->iso14443a.init(h->rh); + ret = h->rh->reader->init(h->rh, RFID_LAYER2_ISO14443A); if (ret < 0) { free_layer2_handle(h); return NULL; diff --git a/src/rfid_layer2_iso14443b.c b/src/rfid_layer2_iso14443b.c index 2523204..df2f95d 100644 --- a/src/rfid_layer2_iso14443b.c +++ b/src/rfid_layer2_iso14443b.c @@ -305,7 +305,7 @@ iso14443b_init(struct rfid_reader_handle *rh) h->priv.iso14443b.tr0 = (256/ISO14443_FREQ_SUBCARRIER)*10e6; h->priv.iso14443b.tr1 = (200/ISO14443_FREQ_SUBCARRIER)*10e6; - ret = h->rh->reader->iso14443b.init(h->rh); + ret = h->rh->reader->init(h->rh, RFID_LAYER2_ISO14443B); if (ret < 0) { DEBUGP("error during reader 14443b init\n"); free_layer2_handle(h); diff --git a/src/rfid_layer2_iso15693.c b/src/rfid_layer2_iso15693.c index 09dd632..6d64c65 100644 --- a/src/rfid_layer2_iso15693.c +++ b/src/rfid_layer2_iso15693.c @@ -45,7 +45,22 @@ struct iso15693_request_adressed { #define ISO15693_BLOCK_SIZE_MAX (256/8) #define ISO15693_RESP_SIZE_MAX (4+ISO15693_BLOCK_SIZE_MAX) -#define TIMEOUT 200 +const unsigned int iso15693_timing[2][5] = { + [ISO15693_T_SLOW] = { + [ISO15693_T1] = 1216, /* max time after VCD EOF before VICC SOF */ + [ISO15693_T2] = 1200, /* min time before VCD EOF after VICC response */ + [ISO15693_T3] = 1502, /* min time after VCD EOF before next EOF if no VICC response */ + [ISO15693_T4] = 1216, /* time after wich VICC transmits after VCD EOF */ + [ISO15693_T4_WRITE]=20000, /* time after wich VICC transmits after VCD EOF */ + }, + [ISO15693_T_FAST] = { + [ISO15693_T1] = 304, /* max time after VCD EOF before VICC SOF */ + [ISO15693_T2] = 300, /* min time before VCD EOF after VICC response */ + [ISO15693_T3] = 602, /* min time after VCD EOF before next EOF if no VICC response */ + [ISO15693_T4] = 304, /* time after wich VICC transmits after VCD EOF */ + [ISO15693_T4_WRITE]=20000, /* time after wich VICC transmits after VCD EOF */ + }, +}; static int iso15693_transceive(struct rfid_layer2_handle *handle, enum rfid_frametype frametype, @@ -60,14 +75,15 @@ static int iso15693_transceive(struct rfid_layer2_handle *handle, /* Transmit an anticollission frame */ static int iso15693_transceive_acf(struct rfid_layer2_handle *handle, - struct iso15693_anticol_cmd *acf, - unsigned char uuid[ISO15693_UID_LEN], - char *bit_of_col) + const struct iso15693_anticol_cmd *acf, + unsigned int acf_len, + struct iso15693_anticol_resp *resp, + unsigned int *rx_len, char *bit_of_col) { - struct rfid_reader *rdr = handle->rh->reader; + const struct rfid_reader *rdr = handle->rh->reader; if (!rdr->iso15693.transceive_ac) return -1; - return rdr->iso15693.transceive_ac(handle->rh, acf, uuid, bit_of_col); + return rdr->iso15693.transceive_ac(handle->rh, acf, acf_len, resp, rx_len, bit_of_col); } #if 0 @@ -120,77 +136,102 @@ iso15693_lock_block() #endif +/* Helper function to build an ISO 15693 anti collision frame */ +static int +iso15693_build_acf(u_int8_t *target, u_int8_t flags, u_int8_t afi, + u_int8_t mask_len, u_int8_t *mask) +{ + struct iso15693_request *req = (struct iso15693_request *) target; + int i = 0, j; + + req->flags = flags; + req->command = ISO15693_CMD_INVENTORY; + if (flags & RFID_15693_F5_AFI_PRES) + req->data[i++] = afi; + req->data[i++] = mask_len; + + for (j = 0; j < mask_len; j++) + req->data[i++] = mask[j]; + + return i + sizeof(*req); +} + static int iso15693_anticol(struct rfid_layer2_handle *handle) { int i, ret; - int rx_len = 0; + int tx_len, rx_len; int num_valid = 0; - struct iso15693_anticol_cmd acf; - char uuid[ISO15693_UID_LEN]; + union { + struct iso15693_anticol_cmd_afi w_afi; + struct iso15693_anticol_cmd no_afi; + } acf; + + struct iso15693_anticol_resp resp; + char boc; +#define MAX_SLOTS 16 + int num_slots = MAX_SLOTS; - char uuid_list[16][ISO15693_UID_LEN]; - int uuid_list_valid[16]; + u_int8_t uuid_list[MAX_SLOTS][ISO15693_UID_LEN]; + int uuid_list_valid[MAX_SLOTS]; + + u_int8_t flags; #define MY_NONE 0 #define MY_COLL 1 #define MY_UUID 2 - memset(uuid_list_valid, MY_NONE, 16); - memset(uuid_list, 0, ISO15693_UID_LEN * 16); - - memset(&acf, 0, sizeof(struct iso15693_anticol_cmd)); - acf.afi = 0; - acf.flags = RFID_15693_F5_NSLOTS_1 | /* comment out for 16 slots */ - RFID_15693_F_INV_TABLE_5 | - RFID_15693_F_RATE_HIGH; - //RFID_15693_F_SUBC_TWO - acf.mask_len = 0; - //acf.mask_bits[0] = 3; - acf.current_slot = 0; - - if (acf.flags & RFID_15693_F5_NSLOTS_1) - i = 1; - else - i = 16; - for (; i >=1; i--) { - //acf.current_slot=0; - ret = iso15693_transceive_acf(handle, &acf, &uuid[0], &boc); - switch (ret) { - case -ETIMEDOUT: - DEBUGP("no answer from vicc in slot %d\n", - acf.current_slot); - uuid_list_valid[acf.current_slot] = MY_NONE; - break; - case -ECOLLISION: - DEBUGP("Collision during anticol. slot %d bit %d\n", - acf.current_slot,boc); - uuid_list_valid[acf.current_slot] = -boc; - memcpy(uuid_list[acf.current_slot], uuid, ISO15693_UID_LEN); - break; - default: - if (ret < 0) { - DEBUGP("ERROR ret: %d, slot %d\n", ret, - acf.current_slot); - uuid_list_valid[acf.current_slot] = MY_NONE; + memset(uuid_list_valid, MY_NONE, sizeof(uuid_list_valid)); + memset(uuid_list, 0, sizeof(uuid_list)); + + //memset(&acf, 0, sizeof(acf)); + + /* FIXME: we can't use multiple slots at this point, since the RC632 + * with librfid on the host PC has too much latency between 'EOF pulse + * to mark start of next slot' and 'receive data' commands :( */ + + flags = RFID_15693_F_INV_TABLE_5; + if (handle->priv.iso15693.vicc_fast) + flags |= RFID_15693_F_RATE_HIGH; + if (handle->priv.iso15693.vicc_two_subc) + flags |= RFID_15693_F_SUBC_TWO; + if (handle->priv.iso15693.single_slot) { + flags |= RFID_15693_F5_NSLOTS_1; + num_slots = 1; + } + if (handle->priv.iso15693.use_afi) + flags |= RFID_15693_F5_AFI_PRES; + + tx_len = iso15693_build_acf((u_int8_t *)&acf, flags, + handle->priv.iso15693.afi, 0, NULL); + + for (i = 0; i < num_slots; i++) { + rx_len = sizeof(resp); + ret = iso15693_transceive_acf(handle, (u_int8_t *) &acf, tx_len, &resp, &rx_len, &boc); + if (ret == -ETIMEDOUT) { + DEBUGP("no answer from vicc in slot %d\n", i); + uuid_list_valid[i] = MY_NONE; + } else if (ret < 0) { + DEBUGP("ERROR ret: %d, slot %d\n", ret, i); + uuid_list_valid[i] = MY_NONE; + } else { + + if (boc) { + DEBUGP("Collision during anticol. slot %d bit %d\n", + i, boc); + uuid_list_valid[i] = -boc; + memcpy(uuid_list[i], resp.uuid, ISO15693_UID_LEN); } else { - DEBUGP("Slot %d ret: %d UUID: %s\n", - acf.current_slot, ret, - rfid_hexdump(uuid, ISO15693_UID_LEN)); - uuid_list_valid[acf.current_slot] = MY_UUID; - memcpy(&uuid_list[acf.current_slot][0], uuid, - ISO15693_UID_LEN); + DEBUGP("Slot %d ret: %d UUID: %s\n", i, ret, + rfid_hexdump(resp.uuid, ISO15693_UID_LEN)); + uuid_list_valid[i] = MY_UUID; + memcpy(&uuid_list[i][0], resp.uuid, ISO15693_UID_LEN); } } - usleep(1000*200); } - if (acf.flags & RFID_15693_F5_NSLOTS_1) - i = 1; - else - i = 16; - while (i) { + for (i = 0; i < num_slots; i++) { if (uuid_list_valid[i] == MY_NONE) { DEBUGP("slot[%d]: timeout\n",i); } else if (uuid_list_valid[i] == MY_UUID) { @@ -204,8 +245,8 @@ iso15693_anticol(struct rfid_layer2_handle *handle) (uuid_list_valid[i]*-1)%8, rfid_hexdump(uuid_list[i], ISO15693_UID_LEN)); } - i--; } + if (num_valid == 0) return -1; @@ -245,15 +286,60 @@ static int iso15693_getopt(struct rfid_layer2_handle *handle, int optname, void *optval, unsigned int *optlen) { + unsigned int *val = optval; + u_int8_t *val_u8 = optval; + + if (!optlen || !optval || *optlen < sizeof(unsigned int)) + return -EINVAL; + + *optlen = sizeof(unsigned int); + switch (optname) { case RFID_OPT_15693_MOD_DEPTH: + if (handle->priv.iso15693.vcd_ask100) + *val = RFID_15693_MOD_100ASK; + else + *val = RFID_15693_MOD_10ASK; + break; case RFID_OPT_15693_VCD_CODING: + if (handle->priv.iso15693.vcd_out256) + *val = RFID_15693_VCD_CODING_1OUT256; + else + *val = RFID_15693_VCD_CODING_1OUT4; + break; case RFID_OPT_15693_VICC_SUBC: + if (handle->priv.iso15693.vicc_two_subc) + *val = RFID_15693_VICC_SUBC_DUAL; + else + *val = RFID_15693_VICC_SUBC_SINGLE; + break; case RFID_OPT_15693_VICC_SPEED: + if (handle->priv.iso15693.vicc_fast) + *val = RFID_15693_VICC_SPEED_FAST; + else + *val = RFID_15693_VICC_SPEED_SLOW; + break; + case RFID_OPT_15693_VCD_SLOTS: + if (handle->priv.iso15693.single_slot) + *val = 1; + else + *val = 16; + break; + case RFID_OPT_15693_USE_AFI: + if (handle->priv.iso15693.use_afi) + *val = 1; + else + *val = 0; + break; + case RFID_OPT_15693_AFI: + *val_u8 = handle->priv.iso15693.afi; + *optlen = sizeof(u_int8_t); + break; default: return -EINVAL; break; } + return 0; } @@ -261,14 +347,91 @@ static int iso15693_setopt(struct rfid_layer2_handle *handle, int optname, const void *optval, unsigned int optlen) { + unsigned int val; + + if (optlen < sizeof(u_int8_t) || !optval) + return -EINVAL; + + if (optlen == sizeof(u_int8_t)) + val = *((u_int8_t *) optval); + if (optlen == sizeof(u_int16_t)) + val = *((u_int16_t *) optval); + if (optlen == sizeof(unsigned int)) + val = *((unsigned int *) optval); + switch (optname) { case RFID_OPT_15693_MOD_DEPTH: + switch (val) { + case RFID_15693_MOD_10ASK: + handle->priv.iso15693.vcd_ask100 = 0; + break; + case RFID_15693_MOD_100ASK: + handle->priv.iso15693.vcd_ask100 = 1; + break; + default: + return -EINVAL; + } + break; case RFID_OPT_15693_VCD_CODING: + switch (val) { + case RFID_15693_VCD_CODING_1OUT256: + handle->priv.iso15693.vcd_out256 = 1; + break; + case RFID_15693_VCD_CODING_1OUT4: + handle->priv.iso15693.vcd_out256 = 0; + break; + default: + return -EINVAL; + } + break; case RFID_OPT_15693_VICC_SUBC: + switch (val) { + case RFID_15693_VICC_SUBC_SINGLE: + handle->priv.iso15693.vicc_two_subc = 0; + break; + case RFID_15693_VICC_SUBC_DUAL: + handle->priv.iso15693.vicc_two_subc = 1; + break; + default: + return -EINVAL; + } + break; case RFID_OPT_15693_VICC_SPEED: + switch (val) { + case RFID_15693_VICC_SPEED_SLOW: + handle->priv.iso15693.vicc_fast = 0; + break; + case RFID_15693_VICC_SPEED_FAST: + handle->priv.iso15693.vicc_fast = 1; + break; + default: + return -EINVAL; + } + case RFID_OPT_15693_VCD_SLOTS: + switch (val) { + case 16: + handle->priv.iso15693.single_slot = 0; + break; + case 1: + handle->priv.iso15693.single_slot = 1; + break; + default: + return -EINVAL; + } + break; + case RFID_OPT_15693_USE_AFI: + if (val) + handle->priv.iso15693.use_afi = 1; + else + handle->priv.iso15693.use_afi = 1; + break; + case RFID_OPT_15693_AFI: + if (val > 0xff) + return -EINVAL; + handle->priv.iso15693.afi = val; + break; default: return -EINVAL; - break; } return 0; } @@ -289,7 +452,15 @@ iso15693_init(struct rfid_reader_handle *rh) h->l2 = &rfid_layer2_iso15693; h->rh = rh; h->priv.iso15693.state = ISO15693_STATE_NONE; - ret = h->rh->reader->iso15693.init(h->rh); + h->priv.iso15693.vcd_ask100 = 1; /* 100ASK is easier to generate */ + h->priv.iso15693.vicc_two_subc = 0; + h->priv.iso15693.vicc_fast = 1; + h->priv.iso15693.single_slot = 1; + h->priv.iso15693.vcd_out256 = 0; + h->priv.iso15693.use_afi = 0; /* not all VICC support AFI */ + h->priv.iso15693.afi = 0; + + ret = h->rh->reader->init(h->rh, RFID_LAYER2_ISO15693); if (ret < 0) { free_layer2_handle(h); return NULL; diff --git a/src/rfid_reader.c b/src/rfid_reader.c index 39a4a07..31264eb 100644 --- a/src/rfid_reader.c +++ b/src/rfid_reader.c @@ -71,3 +71,16 @@ rfid_reader_close(struct rfid_reader_handle *rh) { rh->reader->close(rh); } + +int +rfid_reader_getopt(struct rfid_reader_handle *rh, int optname, + void *optval, unsigned int *optlen) +{ + return rh->reader->getopt(rh, optname, optval, optlen); +} + +int rfid_reader_setopt(struct rfid_reader_handle *rh, int optname, + const void *optval, unsigned int optlen) +{ + return rh->reader->setopt(rh, optname, optval, optlen); +} diff --git a/src/rfid_reader_cm5121.c b/src/rfid_reader_cm5121.c index f51cd82..2e9aade 100644 --- a/src/rfid_reader_cm5121.c +++ b/src/rfid_reader_cm5121.c @@ -44,6 +44,8 @@ #include <librfid/rfid_layer2.h> #include <librfid/rfid_protocol.h> +#include "rfid_reader_rc632_common.h" + #include "cm5121_source.h" /* FIXME */ @@ -53,8 +55,6 @@ plus 10 bytes reserve */ #define RECVBUF_LEN SENDBUF_LEN -#define DEBUG_REGISTER - #ifdef DEBUG_REGISTER #define DEBUGRC DEBUGPC #define DEBUGR DEBUGP @@ -178,122 +178,6 @@ static int WriteNBytesToFIFO(struct rfid_asic_transport_handle *rath, return -1; } -#if 0 -static int TestFIFO(struct rc632_handle *handle) -{ - unsigned char sndbuf[60]; // 0x3c - - // FIXME: repne stosd, call - - memset(sndbuf, 0, sizeof(sndbuf)); - - if (WriteNBytesToFIFO(handle, sizeof(sndbuf), sndbuf, 0) < 0) - return -1; - - return ReadNBytesFromFIFO(handle, sizeof(sndbuf), sndbuf); -} -#endif - -static int cm5121_transceive(struct rfid_reader_handle *rh, - enum rfid_frametype frametype, - const unsigned char *tx_data, unsigned int tx_len, - unsigned char *rx_data, unsigned int *rx_len, - 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); -} - -static int cm5121_transceive_sf(struct rfid_reader_handle *rh, - unsigned char cmd, struct iso14443a_atqa *atqa) -{ - return rh->ah->asic->priv.rc632.fn.iso14443a.transceive_sf(rh->ah, - cmd, - atqa); -} - -static int -cm5121_transceive_acf(struct rfid_reader_handle *rh, - struct iso14443a_anticol_cmd *cmd, - unsigned int *bit_of_col) -{ - return rh->ah->asic->priv.rc632.fn.iso14443a.transceive_acf(rh->ah, - cmd, bit_of_col); -} - -static int -cm5121_14443a_init(struct rfid_reader_handle *rh) -{ - return rh->ah->asic->priv.rc632.fn.iso14443a.init(rh->ah); -} - -static int -cm5121_14443a_set_speed(struct rfid_reader_handle *rh, - unsigned int tx, - unsigned int speed) -{ - u_int8_t rate; - - DEBUGP("setting rate: "); - switch (speed) { - case RFID_14443A_SPEED_106K: - rate = 0x00; - DEBUGPC("106K\n"); - break; - case RFID_14443A_SPEED_212K: - rate = 0x01; - DEBUGPC("212K\n"); - break; - case RFID_14443A_SPEED_424K: - rate = 0x02; - DEBUGPC("424K\n"); - break; - case RFID_14443A_SPEED_848K: - rate = 0x03; - DEBUGPC("848K\n"); - break; - default: - DEBUGPC("invalid\n"); - return -EINVAL; - break; - } - return rh->ah->asic->priv.rc632.fn.iso14443a.set_speed(rh->ah, - tx, rate); -} - -static int -cm5121_14443b_init(struct rfid_reader_handle *rh) -{ - return rh->ah->asic->priv.rc632.fn.iso14443b.init(rh->ah); -} - -static int -cm5121_15693_init(struct rfid_reader_handle *rh) -{ - return rh->ah->asic->priv.rc632.fn.iso15693.init(rh->ah); -} - -static int -cm5121_mifare_setkey(struct rfid_reader_handle *rh, const u_int8_t *key) -{ - return rh->ah->asic->priv.rc632.fn.mifare_classic.setkey(rh->ah, key); -} - -static int -cm5121_mifare_auth(struct rfid_reader_handle *rh, u_int8_t cmd, - u_int32_t serno, u_int8_t block) -{ - return rh->ah->asic->priv.rc632.fn.mifare_classic.auth(rh->ah, - cmd, serno, block); -} - -static int -cm5121_rf_power(struct rfid_reader_handle *rh, int on) -{ - return rh->ah->asic->priv.rc632.fn.rf_power(rh->ah, on); -} - struct rfid_asic_transport cm5121_ccid = { .name = "CM5121 OpenCT", .priv.rc632 = { @@ -366,46 +250,33 @@ cm5121_close(struct rfid_reader_handle *rh) free_reader_handle(rh); } -static int -cm5121_iso15693_transceive_ac(struct rfid_reader_handle *rh, - struct iso15693_anticol_cmd *acf, - unsigned char uuid[ISO15693_UID_LEN], - char *bit_of_col) -{ - return rh->ah->asic->priv.rc632.fn.iso15693.transceive_ac( - rh->ah, acf, uuid, bit_of_col); -} - const struct rfid_reader rfid_reader_cm5121 = { .name = "Omnikey CardMan 5121 RFID", .open = &cm5121_open, .close = &cm5121_close, - .rf_power = &cm5121_rf_power, - .transceive = &cm5121_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), + .getopt = &_rdr_rc632_getopt, + .setopt = &_rdr_rc632_setopt, + .transceive = &_rdr_rc632_transceive, + .init = &_rdr_rc632_l2_init, .iso14443a = { - .init = &cm5121_14443a_init, - .transceive_sf = &cm5121_transceive_sf, - .transceive_acf = &cm5121_transceive_acf, + .transceive_sf = &_rdr_rc632_transceive_sf, + .transceive_acf = &_rdr_rc632_transceive_acf, .speed = RFID_14443A_SPEED_106K | RFID_14443A_SPEED_212K | RFID_14443A_SPEED_424K, //| RFID_14443A_SPEED_848K, - .set_speed = &cm5121_14443a_set_speed, - }, - .iso14443b = { - .init = &cm5121_14443b_init, + .set_speed = &_rdr_rc632_14443a_set_speed, }, .iso15693 = { - .init = &cm5121_15693_init, - .transceive_ac = &cm5121_iso15693_transceive_ac, + .transceive_ac = &_rdr_rc632_iso15693_transceive_ac, }, .mifare_classic = { - .setkey = &cm5121_mifare_setkey, - .auth = &cm5121_mifare_auth, + .setkey = &_rdr_rc632_mifare_setkey, + .auth = &_rdr_rc632_mifare_auth, }, }; diff --git a/src/rfid_reader_openpcd.c b/src/rfid_reader_openpcd.c index 19ea7c2..2a3aca5 100644 --- a/src/rfid_reader_openpcd.c +++ b/src/rfid_reader_openpcd.c @@ -38,6 +38,8 @@ #include <librfid/rfid_layer2.h> #include <librfid/rfid_protocol.h> +#include "rfid_reader_rc632_common.h" + /* FIXME */ #include "rc632.h" @@ -252,10 +254,9 @@ static int openpcd_get_api_version(struct rfid_reader_handle *rh, u_int8_t *vers return ret; } -static int openpcd_get_environment( - struct rfid_reader_handle *rh, - unsigned char num_bytes, - unsigned char *buf) +static int openpcd_get_environment(struct rfid_reader_handle *rh, + unsigned char num_bytes, + unsigned char *buf) { int ret; @@ -275,10 +276,9 @@ static int openpcd_get_environment( return ret; } -static int openpcd_set_environment( - struct rfid_reader_handle *rh, - unsigned char num_bytes, - const unsigned char *buf) +static int openpcd_set_environment(struct rfid_reader_handle *rh, + unsigned char num_bytes, + const unsigned char *buf) { int ret; @@ -352,115 +352,24 @@ const struct rfid_asic_transport openpcd_rat = { #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, - unsigned char *rx_data, unsigned int *rx_len, - 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); -} - -static int openpcd_transceive_sf(struct rfid_reader_handle *rh, - unsigned char cmd, struct iso14443a_atqa *atqa) -{ - return rh->ah->asic->priv.rc632.fn.iso14443a.transceive_sf(rh->ah, - cmd, - atqa); -} - -static int -openpcd_transceive_acf(struct rfid_reader_handle *rh, - struct iso14443a_anticol_cmd *cmd, - unsigned int *bit_of_col) -{ - return rh->ah->asic->priv.rc632.fn.iso14443a.transceive_acf(rh->ah, - cmd, bit_of_col); -} - -static int -openpcd_iso15693_transceive_ac(struct rfid_reader_handle *rh, - struct iso15693_anticol_cmd *acf, unsigned char uuid[ISO15693_UID_LEN], - char *bit_of_col) +static int openpcd_getopt(struct rfid_reader_handle *rh, int optname, + void *optval, unsigned int *optlen) { - return rh->ah->asic->priv.rc632.fn.iso15693.transceive_ac( - rh->ah, acf, uuid, bit_of_col); -} - + int rc; + u_int8_t *val_u8 = (u_int8_t *) optval; -static int -openpcd_14443a_init(struct rfid_reader_handle *rh) -{ - return rh->ah->asic->priv.rc632.fn.iso14443a.init(rh->ah); -} - -static int -openpcd_14443a_set_speed(struct rfid_reader_handle *rh, - unsigned int tx, - unsigned int speed) -{ - u_int8_t rate; - - DEBUGP("setting rate: "); - switch (speed) { - case RFID_14443A_SPEED_106K: - rate = 0x00; - DEBUGPC("106K\n"); - break; - case RFID_14443A_SPEED_212K: - rate = 0x01; - DEBUGPC("212K\n"); - break; - case RFID_14443A_SPEED_424K: - rate = 0x02; - DEBUGPC("424K\n"); - break; - case RFID_14443A_SPEED_848K: - rate = 0x03; - DEBUGPC("848K\n"); - break; + switch (optname) { +#ifndef LIBRFID_FIRMWARE + case RFID_OPT_RDR_FW_VERSION: + return openpcd_get_api_version(rh, val_u8); +#endif default: - return -EINVAL; - break; + return _rdr_rc632_getopt(rh, optname, optval, optlen); } - return rh->ah->asic->priv.rc632.fn.iso14443a.set_speed(rh->ah, - tx, rate); -} - -static int -openpcd_14443b_init(struct rfid_reader_handle *rh) -{ - return rh->ah->asic->priv.rc632.fn.iso14443b.init(rh->ah); -} - -static int -openpcd_15693_init(struct rfid_reader_handle *rh) -{ - return rh->ah->asic->priv.rc632.fn.iso15693.init(rh->ah); -} -static int -openpcd_mifare_setkey(struct rfid_reader_handle *rh, const u_int8_t *key) -{ - return rh->ah->asic->priv.rc632.fn.mifare_classic.setkey(rh->ah, key); + return 0; } -static int -openpcd_mifare_auth(struct rfid_reader_handle *rh, u_int8_t cmd, - u_int32_t serno, u_int8_t block) -{ - return rh->ah->asic->priv.rc632.fn.mifare_classic.auth(rh->ah, - cmd, serno, block); -} - -static void -openpcd_rf_power(struct rfid_reader_handle *rh, int on) -{ - return rh->ah->asic->priv.rc632.fn.rf_power(rh->ah, on); -} static struct rfid_reader_handle * openpcd_open(void *data) @@ -551,16 +460,13 @@ const struct rfid_reader rfid_reader_openpcd = { .id = RFID_READER_OPENPCD, .open = &openpcd_open, .close = &openpcd_close, - .rf_power = &openpcd_rf_power, - + .getopt = &openpcd_getopt, #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, + .setopt = &_rdr_rc632_setopt, + .init = &_rdr_rc632_l2_init, + .transceive = &_rdr_rc632_transceive, .l2_supported = (1 << RFID_LAYER2_ISO14443A) | (1 << RFID_LAYER2_ISO14443B) | (1 << RFID_LAYER2_ISO15693), @@ -568,22 +474,17 @@ const struct rfid_reader rfid_reader_openpcd = { (1 << RFID_PROTOCOL_MIFARE_UL) | (1 << RFID_PROTOCOL_MIFARE_CLASSIC), .iso14443a = { - .init = &openpcd_14443a_init, - .transceive_sf = &openpcd_transceive_sf, - .transceive_acf = &openpcd_transceive_acf, + .transceive_sf = &_rdr_rc632_transceive_sf, + .transceive_acf = &_rdr_rc632_transceive_acf, .speed = RFID_14443A_SPEED_106K | RFID_14443A_SPEED_212K | RFID_14443A_SPEED_424K, //| RFID_14443A_SPEED_848K, - .set_speed = &openpcd_14443a_set_speed, - }, - .iso14443b = { - .init = &openpcd_14443b_init, + .set_speed = &_rdr_rc632_14443a_set_speed, }, .iso15693 = { - .init = &openpcd_15693_init, - .transceive_ac = &openpcd_iso15693_transceive_ac, + .transceive_ac = &_rdr_rc632_iso15693_transceive_ac, }, .mifare_classic = { - .setkey = &openpcd_mifare_setkey, - .auth = &openpcd_mifare_auth, + .setkey = &_rdr_rc632_mifare_setkey, + .auth = &_rdr_rc632_mifare_auth, }, }; diff --git a/src/rfid_reader_rc632_common.c b/src/rfid_reader_rc632_common.c new file mode 100644 index 0000000..4a41f15 --- /dev/null +++ b/src/rfid_reader_rc632_common.c @@ -0,0 +1,152 @@ +/* Shared/Common functions for all RC632 based readers + * + * (C) 2006-2008 by Harald Welte <laforge@gnumonks.org> + * + */ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + + +#include <errno.h> + +#include <librfid/rfid.h> +#include <librfid/rfid_reader.h> +#include <librfid/rfid_asic.h> +#include <librfid/rfid_asic_rc632.h> +#include <librfid/rfid_layer2.h> + +#include "rfid_reader_rc632_common.h" + +int _rdr_rc632_transceive(struct rfid_reader_handle *rh, + enum rfid_frametype frametype, + const unsigned char *tx_data, unsigned int tx_len, + unsigned char *rx_data, unsigned int *rx_len, + 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); +} + +int _rdr_rc632_transceive_sf(struct rfid_reader_handle *rh, + unsigned char cmd, struct iso14443a_atqa *atqa) +{ + return rh->ah->asic->priv.rc632.fn.iso14443a.transceive_sf(rh->ah, + cmd, + atqa); +} + +int +_rdr_rc632_transceive_acf(struct rfid_reader_handle *rh, + struct iso14443a_anticol_cmd *cmd, + unsigned int *bit_of_col) +{ + return rh->ah->asic->priv.rc632.fn.iso14443a.transceive_acf(rh->ah, + cmd, bit_of_col); +} + +int +_rdr_rc632_iso15693_transceive_ac(struct rfid_reader_handle *rh, + const struct iso15693_anticol_cmd *acf, + unsigned int acf_len, + struct iso15693_anticol_resp *resp, + unsigned int *resp_len, char *bit_of_col) +{ + return rh->ah->asic->priv.rc632.fn.iso15693.transceive_ac( + rh->ah, acf, acf_len, resp, resp_len, + bit_of_col); +} + + +int +_rdr_rc632_14443a_set_speed(struct rfid_reader_handle *rh, + unsigned int tx, unsigned int speed) +{ + u_int8_t rate; + + DEBUGP("setting rate: "); + switch (speed) { + case RFID_14443A_SPEED_106K: + rate = 0x00; + DEBUGPC("106K\n"); + break; + case RFID_14443A_SPEED_212K: + rate = 0x01; + DEBUGPC("212K\n"); + break; + case RFID_14443A_SPEED_424K: + rate = 0x02; + DEBUGPC("424K\n"); + break; + case RFID_14443A_SPEED_848K: + rate = 0x03; + DEBUGPC("848K\n"); + break; + default: + return -EINVAL; + break; + } + return rh->ah->asic->priv.rc632.fn.iso14443a.set_speed(rh->ah, + tx, rate); +} + +int +_rdr_rc632_l2_init(struct rfid_reader_handle *rh, enum rfid_layer2_id l2) +{ + return rh->ah->asic->priv.rc632.fn.init(rh->ah, l2); +} + +int +_rdr_rc632_mifare_setkey(struct rfid_reader_handle *rh, const u_int8_t *key) +{ + return rh->ah->asic->priv.rc632.fn.mifare_classic.setkey(rh->ah, key); +} + +int +_rdr_rc632_mifare_auth(struct rfid_reader_handle *rh, u_int8_t cmd, + u_int32_t serno, u_int8_t block) +{ + return rh->ah->asic->priv.rc632.fn.mifare_classic.auth(rh->ah, + cmd, serno, block); +} + +int +_rdr_rc632_getopt(struct rfid_reader_handle *rh, int optname, + void *optval, unsigned int *optlen) +{ + return -EINVAL; +} + +int +_rdr_rc632_setopt(struct rfid_reader_handle *rh, int optname, + const void *optval, unsigned int optlen) +{ + unsigned int *val = (unsigned int *)optval; + + if (!optval || optlen < sizeof(*val)) + return -EINVAL; + + switch (optname) { + case RFID_OPT_RDR_RF_KILL: + if (*val) + return rh->ah->asic->priv.rc632.fn.rf_power(rh->ah, 0); + else + return rh->ah->asic->priv.rc632.fn.rf_power(rh->ah, 1); + default: + return -EINVAL; + } +} diff --git a/src/rfid_reader_rc632_common.h b/src/rfid_reader_rc632_common.h new file mode 100644 index 0000000..38d195d --- /dev/null +++ b/src/rfid_reader_rc632_common.h @@ -0,0 +1,30 @@ +#ifndef _RDR_RC632_COMMON +#define _RDR_RC632_COMMON + +int _rdr_rc632_transceive(struct rfid_reader_handle *rh, + enum rfid_frametype frametype, + const unsigned char *tx_data, unsigned int tx_len, + unsigned char *rx_data, unsigned int *rx_len, + u_int64_t timeout, unsigned int flags); +int _rdr_rc632_transceive_sf(struct rfid_reader_handle *rh, + unsigned char cmd, struct iso14443a_atqa *atqa); +int _rdr_rc632_transceive_acf(struct rfid_reader_handle *rh, + struct iso14443a_anticol_cmd *cmd, + unsigned int *bit_of_col); +int _rdr_rc632_iso15693_transceive_ac(struct rfid_reader_handle *rh, + const struct iso15693_anticol_cmd *acf, + unsigned int acf_len, + struct iso15693_anticol_resp *resp, + unsigned int *resp_len, char *bit_of_col); +int _rdr_rc632_14443a_set_speed(struct rfid_reader_handle *rh, unsigned int tx, + unsigned int speed); +int _rdr_rc632_l2_init(struct rfid_reader_handle *rh, enum rfid_layer2_id l2); +int _rdr_rc632_mifare_setkey(struct rfid_reader_handle *rh, const u_int8_t *key); +int _rdr_rc632_mifare_auth(struct rfid_reader_handle *rh, u_int8_t cmd, + u_int32_t serno, u_int8_t block); +int _rdr_rc632_getopt(struct rfid_reader_handle *rh, int optname, + void *optval, unsigned int *optlen); +int _rdr_rc632_setopt(struct rfid_reader_handle *rh, int optname, + const void *optval, unsigned int optlen); + +#endif diff --git a/src/rfid_reader_spidev.c b/src/rfid_reader_spidev.c index b704e9b..13d1bcb 100644 --- a/src/rfid_reader_spidev.c +++ b/src/rfid_reader_spidev.c @@ -40,6 +40,8 @@ #include <librfid/rfid_layer2.h> #include <librfid/rfid_protocol.h> +#include "rfid_reader_rc632_common.h" + /* FIXME */ #include "rc632.h" static int spidev_fd; @@ -172,123 +174,15 @@ static int spidev_fifo_write(struct rfid_asic_transport_handle *rath, struct rfid_asic_transport spidev_spi = { .name = "spidev", .priv.rc632 = { - .fn = { - .reg_write = &spidev_reg_write, - .reg_read = &spidev_reg_read, - .fifo_write = &spidev_fifo_write, - .fifo_read = &spidev_fifo_read, - }, - }, + .fn = { + .reg_write = &spidev_reg_write, + .reg_read = &spidev_reg_read, + .fifo_write = &spidev_fifo_write, + .fifo_read = &spidev_fifo_read, + }, + }, }; -static int spidev_transceive(struct rfid_reader_handle *rh, - enum rfid_frametype frametype, - const unsigned char *tx_data, - unsigned int tx_len, unsigned char *rx_data, - unsigned int *rx_len, 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); -} - -static int spidev_transceive_sf(struct rfid_reader_handle *rh, - unsigned char cmd, - struct iso14443a_atqa *atqa) -{ - return rh->ah->asic->priv.rc632.fn.iso14443a.transceive_sf(rh->ah, cmd, - atqa); -} - -static int -spidev_transceive_acf(struct rfid_reader_handle *rh, - struct iso14443a_anticol_cmd *cmd, - unsigned int *bit_of_col) -{ - return rh->ah->asic->priv.rc632.fn.iso14443a.transceive_acf(rh->ah, - cmd, - bit_of_col); -} - -static int spidev_14443a_init(struct rfid_reader_handle *rh) -{ - int ret; - ret = rh->ah->asic->priv.rc632.fn.iso14443a.init(rh->ah); - return ret; -} - -static int -spidev_14443a_set_speed(struct rfid_reader_handle *rh, - unsigned int tx, unsigned int speed) -{ - u_int8_t rate; - - DEBUGP("setting rate: "); - switch (speed) { - case RFID_14443A_SPEED_106K: - rate = 0x00; - DEBUGPC("106K\n"); - break; - case RFID_14443A_SPEED_212K: - rate = 0x01; - DEBUGPC("212K\n"); - break; - case RFID_14443A_SPEED_424K: - rate = 0x02; - DEBUGPC("424K\n"); - break; - case RFID_14443A_SPEED_848K: - rate = 0x03; - DEBUGPC("848K\n"); - break; - default: - return -EINVAL; - break; - } - return rh->ah->asic->priv.rc632.fn.iso14443a.set_speed(rh->ah, - tx, rate); -} - -static int spidev_14443b_init(struct rfid_reader_handle *rh) -{ - return rh->ah->asic->priv.rc632.fn.iso14443b.init(rh->ah); -} - -static int spidev_15693_init(struct rfid_reader_handle *rh) -{ - return rh->ah->asic->priv.rc632.fn.iso15693.init(rh->ah); -} - -static int spidev_15693_transceive_ac(struct rfid_reader_handle *rh, - struct iso15693_anticol_cmd *acf, - unsigned char uuid[ISO15693_UID_LEN], - char *bit_of_col) -{ - return rh->ah->asic->priv.rc632.fn.iso15693.transceive_ac( - rh->ah, acf, uuid, bit_of_col); -} - -static int -spidev_mifare_setkey(struct rfid_reader_handle *rh, const u_int8_t * key) -{ - return rh->ah->asic->priv.rc632.fn.mifare_classic.setkey(rh->ah, key); -} - -static int -spidev_mifare_auth(struct rfid_reader_handle *rh, u_int8_t cmd, - u_int32_t serno, u_int8_t block) -{ - return rh->ah->asic->priv.rc632.fn.mifare_classic.auth(rh->ah, - cmd, serno, - block); -} -static int -spidev_rf_power(struct rfid_reader_handle *rh, int on) -{ - return rh->ah->asic->priv.rc632.fn.rf_power(rh->ah, on); -} - static struct rfid_reader_handle *spidev_open(void *data) { struct rfid_reader_handle *rh; @@ -377,32 +271,30 @@ struct rfid_reader rfid_reader_spidev = { .id = RFID_READER_SPIDEV, .open = &spidev_open, .close = &spidev_close, - .rf_power = &spidev_rf_power, - .transceive = &spidev_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), + .getopt = &_rdr_rc632_getopt, + .setopt = &_rdr_rc632_setopt, + .init = &_rdr_rc632_l2_init, + .transceive = &_rdr_rc632_transceive, .iso14443a = { - .init = &spidev_14443a_init, - .transceive_sf = &spidev_transceive_sf, - .transceive_acf = &spidev_transceive_acf, - .speed = RFID_14443A_SPEED_106K - | RFID_14443A_SPEED_212K | RFID_14443A_SPEED_424K, - .set_speed = &spidev_14443a_set_speed, - }, - .iso14443b = { - .init = &spidev_14443b_init, + .transceive_sf = &_rdr_rc632_transceive_sf, + .transceive_acf = &_rdr_rc632_transceive_acf, + .speed = RFID_14443A_SPEED_106K | + RFID_14443A_SPEED_212K | + RFID_14443A_SPEED_424K, + .set_speed = &_rdr_rc632_14443a_set_speed, }, .iso15693 = { - .init = &spidev_15693_init, - .transceive_ac = &spidev_15693_transceive_ac, + .transceive_ac = &_rdr_rc632_iso15693_transceive_ac, }, .mifare_classic = { - .setkey = &spidev_mifare_setkey, - .auth = &spidev_mifare_auth, + .setkey = &_rdr_rc632_mifare_setkey, + .auth = &_rdr_rc632_mifare_auth, }, }; diff --git a/utils/librfid-tool.c b/utils/librfid-tool.c index 910770f..449cb4c 100644 --- a/utils/librfid-tool.c +++ b/utils/librfid-tool.c @@ -334,9 +334,18 @@ static int do_scan(int first) unsigned int size_len = sizeof(size); if (first) { - rh->reader->rf_power(rh, 0); + unsigned int opt; + unsigned int optlen = sizeof(opt); + + /* turn off RF */ + opt = 1; + rfid_reader_setopt(rh, RFID_OPT_RDR_RF_KILL, &opt, optlen); + usleep(10*1000); - rh->reader->rf_power(rh, 1); + + /* turn on RF */ + opt = 0; + rfid_reader_setopt(rh, RFID_OPT_RDR_RF_KILL, &opt, optlen); } printf("scanning for RFID token...\n"); rc = rfid_scan(rh, &l2h, &ph); |