From 79e204d323cd6c465e1a3a53598a655304be1d7a Mon Sep 17 00:00:00 2001 From: laforge Date: Sun, 27 Jan 2008 21:14:08 +0000 Subject: partial ISO15693 support (based on patch by Bjoern Kaiser) git-svn-id: https://svn.gnumonks.org/trunk/librfid@2057 e0336214-984f-0b4b-a45f-81c69e1f0ede --- include/librfid/Makefile.am | 3 + include/librfid/rfid.h | 6 + include/librfid/rfid_asic_rc632.h | 68 ++++ include/librfid/rfid_layer2.h | 2 + include/librfid/rfid_layer2_icode1.h | 11 + include/librfid/rfid_layer2_iso15693.h | 45 ++- include/librfid/rfid_protocol.h | 3 + include/librfid/rfid_protocol_icode.h | 10 + include/librfid/rfid_protocol_tagit.h | 10 + include/librfid/rfid_reader.h | 5 + src/Makefile.am | 12 +- src/rc632.h | 25 ++ src/rfid_asic_rc632.c | 596 +++++++++++++++++++++++---------- src/rfid_layer2.c | 9 + src/rfid_layer2_iso15693.c | 154 ++++++++- src/rfid_proto_icode.c | 120 +++++++ src/rfid_proto_tagit.c | 141 ++++++++ src/rfid_protocol.c | 1 + src/rfid_reader_cm5121.c | 11 + src/rfid_reader_openpcd.c | 43 ++- src/rfid_reader_spidev.c | 13 + utils/common.c | 14 +- utils/librfid-tool.c | 123 ++++++- 23 files changed, 1215 insertions(+), 210 deletions(-) create mode 100644 include/librfid/rfid_layer2_icode1.h create mode 100644 include/librfid/rfid_protocol_icode.h create mode 100644 include/librfid/rfid_protocol_tagit.h create mode 100644 src/rfid_proto_icode.c create mode 100644 src/rfid_proto_tagit.c diff --git a/include/librfid/Makefile.am b/include/librfid/Makefile.am index 6d5acd3..a5deb20 100644 --- a/include/librfid/Makefile.am +++ b/include/librfid/Makefile.am @@ -3,9 +3,12 @@ include $(top_srcdir)/Makefile.flags.am pkginclude_HEADERS = rfid.h rfid_scan.h rfid_asic.h rfid_asic_rc632.h \ rfid_layer2.h rfid_layer2_iso14443a.h \ rfid_layer2_iso14443b.h rfid_layer2_iso15693.h \ + rfid_layer2_icode1.h \ rfid_protocol.h rfid_protocol_tcl.h \ rfid_protocol_mifare_ul.h \ rfid_protocol_mifare_classic.h \ + rfid_protocol_tagit.h \ + rfid_protocol_icode.h \ rfid_reader.h \ rfid_system.h \ rfid_access_mifare_classic.h \ diff --git a/include/librfid/rfid.h b/include/librfid/rfid.h index 64d6c06..bf21319 100644 --- a/include/librfid/rfid.h +++ b/include/librfid/rfid.h @@ -5,9 +5,13 @@ #include #include +#define ECOLLISION 1000 + #ifdef __MINGW32__ #define ENOTSUP 100 +/* 110 under linux */ #define ETIMEDOUT 101 + typedef unsigned char u_int8_t; typedef unsigned short u_int16_t; typedef unsigned long u_int32_t; @@ -62,6 +66,8 @@ enum rfid_frametype { RFID_14443A_FRAME_REGULAR, RFID_14443B_FRAME_REGULAR, RFID_MIFARE_FRAME, + RFID_15693_FRAME, + RFID_15693_FRAME_ICODE1, }; #endif /* _RFID_H */ diff --git a/include/librfid/rfid_asic_rc632.h b/include/librfid/rfid_asic_rc632.h index ccc4f20..0602cd9 100644 --- a/include/librfid/rfid_asic_rc632.h +++ b/include/librfid/rfid_asic_rc632.h @@ -28,6 +28,7 @@ struct rfid_asic_handle; struct iso14443a_atqa; struct iso14443a_anticol_cmd; +struct iso15693_anticol_cmd; struct rfid_asic_rc632 { struct { @@ -59,6 +60,10 @@ struct rfid_asic_rc632 { } 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); } iso15693; struct { int (*setkey)(struct rfid_asic_handle *h, @@ -93,4 +98,67 @@ struct rfid_asic_rc632_impl { extern struct rfid_asic_handle * rc632_open(struct rfid_asic_transport_handle *th); extern void rc632_close(struct rfid_asic_handle *h); + +/* register decoding inlines... */ +#define DEBUGP_ERROR_FLAG(value) do {DEBUGP("error_flag: 0x%0.2x",value); \ + if (value & RC632_ERR_FLAG_CRC_ERR ) \ + DEBUGPC(", CRC"); \ + if (value & RC632_ERR_FLAG_COL_ERR ) \ + DEBUGPC(", COL"); \ + if (value & RC632_ERR_FLAG_FRAMING_ERR ) \ + DEBUGPC(", FRAMING"); \ + if (value & RC632_ERR_FLAG_PARITY_ERR) \ + DEBUGPC(", PARITY"); \ + if (value & RC632_ERR_FLAG_KEY_ERR ) \ + DEBUGPC(", KEY"); \ + if (value & RC632_ERR_FLAG_ACCESS_ERR ) \ + DEBUGPC(", ACCESS"); \ + DEBUGPC("\n");} while (0); + +#define DEBUGP_STATUS_FLAG(foo) do {\ + DEBUGP("status_flag: 0x%0.2x",foo); \ + if (foo & RC632_STAT_ERR ) \ + DEBUGPC(", ERR"); \ + if (foo & RC632_STAT_HIALERT ) \ + DEBUGPC(", Hi"); \ + if (foo & RC632_STAT_IRQ ) \ + DEBUGPC(", IRQ"); \ + if (foo & RC632_STAT_LOALERT ) \ + DEBUGPC(", Lo"); \ + if ((foo & RC632_STAT_MODEM_MASK) == RC632_STAT_MODEM_AWAITINGRX ) \ + DEBUGPC(", mAwaitingRX"); \ + if ((foo & RC632_STAT_MODEM_MASK) == RC632_STAT_MODEM_GOTORX ) \ + DEBUGPC(", mGotoRX"); \ + if ((foo & RC632_STAT_MODEM_MASK) == RC632_STAT_MODEM_IDLE ) \ + DEBUGPC(", mIdle"); \ + if ((foo & RC632_STAT_MODEM_MASK) == RC632_STAT_MODEM_PREPARERX ) \ + DEBUGPC(", mPrepareRX"); \ + if ((foo & RC632_STAT_MODEM_MASK) == RC632_STAT_MODEM_RECV ) \ + DEBUGPC(", mRX"); \ + if ((foo & RC632_STAT_MODEM_MASK) == RC632_STAT_MODEM_TXDATA ) \ + DEBUGPC(", mTXData"); \ + if ((foo & RC632_STAT_MODEM_MASK) == RC632_STAT_MODEM_TXEOF ) \ + DEBUGPC(", mTXeof"); \ + if ((foo & RC632_STAT_MODEM_MASK) == RC632_STAT_MODEM_TXSOF ) \ + DEBUGPC(", mTXsof"); \ + DEBUGPC("\n"); } while (0); + +#define DEBUGP_INTERRUPT_FLAG(foo) do {\ + DEBUGP("interrupt_flag: 0x%0.2x",foo); \ + if (foo & RC632_INT_HIALERT) \ + DEBUGPC(", HiA"); \ + if (foo & RC632_INT_LOALERT) \ + DEBUGPC(", LoA"); \ + if (foo & RC632_INT_IDLE) \ + DEBUGPC(", IDLE"); \ + if (foo & RC632_INT_RX) \ + DEBUGPC(", RX"); \ + if (foo & RC632_INT_TX) \ + DEBUGPC(", TX"); \ + if (foo & RC632_INT_TIMER) \ + DEBUGPC(", TIMER"); \ + if (foo & RC632_INT_SET) \ + DEBUGPC(", SET"); \ + DEBUGPC("\n"); } while (0); + #endif diff --git a/include/librfid/rfid_layer2.h b/include/librfid/rfid_layer2.h index 45ae953..023b171 100644 --- a/include/librfid/rfid_layer2.h +++ b/include/librfid/rfid_layer2.h @@ -11,6 +11,7 @@ enum rfid_layer2_id { RFID_LAYER2_ISO14443A, RFID_LAYER2_ISO14443B, RFID_LAYER2_ISO15693, + RFID_LAYER2_ICODE1, }; /* 0...0xffff = global options, 0x10000...0x1ffff = private options */ @@ -41,6 +42,7 @@ char *rfid_layer2_name(struct rfid_layer2_handle *l2h); #include #include #include +#include struct rfid_layer2 { unsigned int id; diff --git a/include/librfid/rfid_layer2_icode1.h b/include/librfid/rfid_layer2_icode1.h new file mode 100644 index 0000000..e8ebddb --- /dev/null +++ b/include/librfid/rfid_layer2_icode1.h @@ -0,0 +1,11 @@ +#ifndef _RFID_L2_ICODE1_H +#define _RFID_L2_ICODE1_H + +#ifdef __LIBRFID__ + +#include +extern const struct rfid_layer2 rfid_layer2_icode1; + + +#endif /* __LIBRFID__ */ +#endif /* _ISO15693_H */ diff --git a/include/librfid/rfid_layer2_iso15693.h b/include/librfid/rfid_layer2_iso15693.h index d09daa7..5719a39 100644 --- a/include/librfid/rfid_layer2_iso15693.h +++ b/include/librfid/rfid_layer2_iso15693.h @@ -4,11 +4,28 @@ #include /* -07h = TagIt -04h = I.CODE -05h = Infineon -02h = ST -*/ + * ISO15693 tag manufacturer codes as found at + * http://rfid-handbook.de/forum/read.php?5,437,580#msg-580 + * + * 01h = Motorola + * 02h = ST Microelectronics + * 03h = Hitachi + * 04h = Philips/NXP I.CODE + * 05h = Siemens/Infineon + * 06h = Cylinc + * 07h = Texas Instruments TagIt + * 08h = Fujitsu Limited + * 09h = Mashushita Electric Industrial + * 0Ah = NEC + * 0Bh = Oki Electric + * 0Ch = Toshiba + * 0Dh = Mishubishi Electric + * 0Eh = Samsung Electronics + * 0Fh = Hyundai Electronics + * 10h = LG Semiconductors + * 16h = EMarin Microelectronic + * + */ /* protocol definitions */ @@ -51,6 +68,7 @@ struct iso15693_handle { enum rfid_15693_state { ISO15693_STATE_ERROR, ISO15693_STATE_NONE, + ISO15693_STATE_ANTICOL_RUNNING, }; enum rfid_15693_opt { @@ -85,7 +103,7 @@ enum rfid_15693_opt_vicc_speed { #define ISO15693_UID_LEN 8 #define ISO15693_CRC_LEN 2 -/* ISO 15693-3, Ch. 7.2 Table 3*/ +/* ISO 15693-3, Ch. 7.2 Table 3 */ enum iso15693_request_flags { RFID_15693_F_SUBC_TWO = 0x01, RFID_15693_F_RATE_HIGH = 0x02, @@ -114,6 +132,12 @@ struct iso15693_request { u_int8_t data[0]; } __attribute__ ((packed)); +/* ISO 15963-3, Ch. 7.2 Figure 5 */ +struct iso15693_response { + u_int8_t flags; + u_int8_t data[0]; +} __attribute__ ((packed)); + /* ISO 15693, Ch. 7.3 Table 6 */ enum iso15693_response_flags { RFID_15693_RF_ERROR = 0x01, @@ -130,6 +154,7 @@ enum iso15693_response_errors { RFID_15693_ERR_BLOCK_LOCKED_CH = 0x12, RFID_15693_ERR_BLOCK_NOTPROG = 0x13, RFID_15693_ERR_BLOCK_NOTLOCK = 0x14, + /* 0xA0 .. 0xDF Custom Command error Codes */ }; /* ISO 15693, Ch. 7.4 */ @@ -169,6 +194,14 @@ enum iso15693_commands { /* Proprietary 0xe0 .. 0xff */ }; +struct iso15693_anticol_cmd { + /* iso15693-3 table5 flags*/ + unsigned char flags; // SLOTS16 | SLOT1, AFI_PRESENT, OPTION_FLAG + unsigned char afi; // AFI 0 for any + unsigned char mask_len; + unsigned char mask_bits[ISO15693_UID_LEN]; + unsigned char current_slot; +} __attribute__((packed)); #include extern const struct rfid_layer2 rfid_layer2_iso15693; diff --git a/include/librfid/rfid_protocol.h b/include/librfid/rfid_protocol.h index ea4dd34..b4a145d 100644 --- a/include/librfid/rfid_protocol.h +++ b/include/librfid/rfid_protocol.h @@ -40,6 +40,8 @@ enum rfid_protocol_id { RFID_PROTOCOL_TCL, RFID_PROTOCOL_MIFARE_UL, RFID_PROTOCOL_MIFARE_CLASSIC, + RFID_PROTOCOL_ICODE_SLI, + RFID_PROTOCOL_TAGIT, NUM_RFID_PROTOCOLS }; @@ -86,6 +88,7 @@ struct rfid_protocol { #include #include #include +#include struct rfid_protocol_handle { struct rfid_layer2_handle *l2h; diff --git a/include/librfid/rfid_protocol_icode.h b/include/librfid/rfid_protocol_icode.h new file mode 100644 index 0000000..9019243 --- /dev/null +++ b/include/librfid/rfid_protocol_icode.h @@ -0,0 +1,10 @@ +#ifndef _RFID_PROTOCOL_TAGIT_H +#define _RFID_PROTOCOL_TAGIT_H + +#ifdef __LIBRFID__ + +extern const struct rfid_protocol rfid_protocol_icode; + +#endif /* __LIBRFID__ */ + +#endif diff --git a/include/librfid/rfid_protocol_tagit.h b/include/librfid/rfid_protocol_tagit.h new file mode 100644 index 0000000..46a73bc --- /dev/null +++ b/include/librfid/rfid_protocol_tagit.h @@ -0,0 +1,10 @@ +#ifndef _RFID_PROTOCOL_TAGIT_H +#define _RFID_PROTOCOL_TAGIT_H + +#ifdef __LIBRFID__ + +extern const struct rfid_protocol rfid_protocol_tagit; + +#endif /* __LIBRFID__ */ + +#endif diff --git a/include/librfid/rfid_reader.h b/include/librfid/rfid_reader.h index 64ad862..8dc7860 100644 --- a/include/librfid/rfid_reader.h +++ b/include/librfid/rfid_reader.h @@ -3,6 +3,7 @@ #include #include +#include struct rfid_reader_handle; @@ -56,6 +57,10 @@ struct rfid_reader { } 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); } iso15693; struct rfid_mifare_classic_reader { int (*setkey)(struct rfid_reader_handle *h, const unsigned char *key); diff --git a/src/Makefile.am b/src/Makefile.am index 45036b1..f0e5a6e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -14,11 +14,13 @@ endif noinst_HEADERS=rfid_iso14443_common.h rc632.h libusb_dyn.h usleep.h cm5121_source.h -CORE=rfid.c rfid_layer2.c rfid_protocol.c rfid_reader.c rfid_scan.c -L2=rfid_layer2_iso14443a.c rfid_layer2_iso14443b.c rfid_layer2_iso15693.c rfid_iso14443_common.c -PROTO=rfid_proto_tcl.c rfid_proto_mifare_ul.c rfid_proto_mifare_classic.c -ASIC=rfid_asic_rc632.c -MISC=rfid_access_mifare_classic.c +CORE = rfid.c rfid_layer2.c rfid_protocol.c rfid_reader.c rfid_scan.c +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 +MISC = rfid_access_mifare_classic.c if ENABLE_WIN32 WIN32=usleep.c libusb_dyn.c diff --git a/src/rc632.h b/src/rc632.h index c7690ed..9cecab9 100644 --- a/src/rc632.h +++ b/src/rc632.h @@ -67,6 +67,22 @@ enum rc632_registers { RC632_REG_TEST_DIGI_SELECT = 0x3d, }; +enum rc632_reg_status { + RC632_STAT_LOALERT = 0x01, + RC632_STAT_HIALERT = 0x02, + RC632_STAT_IRQ = 0x04, + RC632_STAT_ERR = 0x08, +#define RC632_STAT_MODEM_MASK 0x70 + RC632_STAT_MODEM_IDLE = 0x00, + RC632_STAT_MODEM_TXSOF = 0x10, + RC632_STAT_MODEM_TXDATA = 0x20, + RC632_STAT_MODEM_TXEOF = 0x30, + RC632_STAT_MODEM_GOTORX = 0x40, + RC632_STAT_MODEM_PREPARERX = 0x50, + RC632_STAT_MODEM_AWAITINGRX = 0x60, + RC632_STAT_MODEM_RECV = 0x70, +}; + enum rc632_reg_command { RC632_CMD_IDLE = 0x00, RC632_CMD_WRITE_E2 = 0x01, @@ -126,10 +142,16 @@ enum rc632_reg_tx_control { }; enum rc632_reg_coder_control { + /* bit 2-0 TXCoding */ +#define RC632_CDRCTRL_TXCD_MASK 0x07 RC632_CDRCTRL_TXCD_NRZ = 0x00, RC632_CDRCTRL_TXCD_14443A = 0x01, RC632_CDRCTRL_TXCD_ICODE_STD = 0x04, + RC632_CDRCTRL_TXCD_ICODE_FAST = 0x05, + RC632_CDRCTRL_TXCD_15693_STD = 0x06, + RC632_CDRCTRL_TXCD_15693_FAST = 0x07, + /* bit5-3 CoderRate*/ #define RC632_CDRCTRL_RATE_MASK 0x38 RC632_CDRCTRL_RATE_848K = 0x00, RC632_CDRCTRL_RATE_424K = 0x08, @@ -138,6 +160,9 @@ enum rc632_reg_coder_control { RC632_CDRCTRL_RATE_14443B = 0x20, RC632_CDRCTRL_RATE_15693 = 0x28, RC632_CDRCTRL_RATE_ICODE_FAST = 0x30, + + /* bit 7 SendOnePuls */ + RC632_CDRCTRL_15693_EOF_PULSE = 0x80, }; enum rc632_erg_type_b_framing { diff --git a/src/rfid_asic_rc632.c b/src/rfid_asic_rc632.c index b8d8db3..8fc5cb9 100644 --- a/src/rfid_asic_rc632.c +++ b/src/rfid_asic_rc632.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "rfid_iso14443_common.h" @@ -138,6 +139,12 @@ rc632_clear_bits(struct rfid_asic_handle *handle, return rc632_reg_write(handle, reg, (tmp & ~val)&0xff); } +static int +rc632_clear_irqs(struct rfid_asic_handle *handle, u_int8_t bits) +{ + return rc632_reg_write(handle, RC632_REG_INTERRUPT_RQ, (~RC632_INT_SET)&bits); +} + static int rc632_rf_power(struct rfid_asic_handle *handle, int on) { @@ -284,20 +291,32 @@ rc632_wait_idle(struct rfid_asic_handle *handle, u_int64_t timeout) if (ret < 0) return ret; - if (cmd == 0) { - /* FIXME: read second time ?? */ - return 0; - } - { u_int8_t foo; rc632_reg_read(handle, RC632_REG_PRIMARY_STATUS, &foo); - if (foo & 0x04) + DEBUGP_STATUS_FLAG(foo); + /* check if Error has occured (ERR flag set) */ + if (foo & RC632_STAT_ERR) { rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &foo); + DEBUGP_ERROR_FLAG(foo); + } + /* check if IRQ has occurred (IRQ flag set)*/ + if (foo & RC632_STAT_IRQ) { + ret = rc632_reg_read(handle, RC632_REG_INTERRUPT_RQ, &foo); + DEBUGP_INTERRUPT_FLAG(foo); + /* clear all interrupts */ + rc632_clear_irqs(handle, 0xff); + } + } + if (cmd == 0) { + /* FIXME: read second time ?? */ + DEBUGP("cmd == 0 (IDLE)\n"); + return 0; } /* Abort after some timeout */ if (cycles > timeout*100/USLEEP_PER_CYCLE) { + DEBUGP("timeout...\n"); return -ETIMEDOUT; } @@ -351,7 +370,7 @@ rc632_transmit(struct rfid_asic_handle *handle, static int tcl_toggle_pcb(struct rfid_asic_handle *handle) { - // FIXME: toggle something between 0x0a and 0x0b + /* FIXME: toggle something between 0x0a and 0x0b */ return 0; } @@ -364,11 +383,11 @@ rc632_transceive(struct rfid_asic_handle *handle, u_int64_t timer, unsigned int toggle) { - int ret, cur_tx_len; + int ret, cur_tx_len, i; u_int8_t rx_avail; const u_int8_t *cur_tx_buf = tx_buf; - DEBUGP("timer = %u\n", timer); + DEBUGP("timer=%u, rx_len=%u, tx_len=%u,", timer, rx_len, tx_len); if (tx_len > 64) cur_tx_len = 64; @@ -382,6 +401,7 @@ rc632_transceive(struct rfid_asic_handle *handle, 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); do { ret = rc632_fifo_write(handle, cur_tx_len, cur_tx_buf, 0x03); @@ -404,7 +424,6 @@ rc632_transceive(struct rfid_asic_handle *handle, return ret; cur_tx_len = 64 - fifo_fill; - //printf("refilling tx fifo with %u bytes\n", cur_tx_len); } else cur_tx_len = 0; @@ -415,6 +434,66 @@ rc632_transceive(struct rfid_asic_handle *handle, //ret = rc632_wait_idle_timer(handle); ret = rc632_wait_idle(handle, timer); + + DEBUGP("rc632_wait_idle>>ret=%d %s\n",ret,(ret==-ETIMEDOUT)?"ETIMEDOUT":""); + if (ret < 0) + return ret; + + ret = rc632_reg_read(handle, RC632_REG_FIFO_LENGTH, &rx_avail); + if (ret < 0) + return ret; + + if (rx_avail > *rx_len) + DEBUGP("rx_avail(%d) > rx_len(%d), JFYI\n", rx_avail, *rx_len); + else if (*rx_len > rx_avail) + *rx_len = rx_avail; + + DEBUGP("rx_len == %d\n",*rx_len); + + if (rx_avail == 0) { + u_int8_t tmp; + + for (i = 0; i < 1; i++){ + 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); + } + rc632_reg_read(handle, RC632_REG_CHANNEL_REDUNDANCY, &tmp); + + //return 0; + return -1; + } + + return rc632_fifo_read(handle, *rx_len, rx_buf); + /* FIXME: discard addidional bytes in FIFO */ +} + + +static int +rc632_receive(struct rfid_asic_handle *handle, + u_int8_t *rx_buf, + u_int8_t *rx_len, + u_int64_t timer) +{ + 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; + /* + 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_reg_write(handle, RC632_REG_COMMAND,RC632_CMD_RECEIVE); + if (ret < 0) + return ret; + + ret = rc632_wait_idle(handle, timer); if (ret < 0) return ret; @@ -432,14 +511,19 @@ rc632_transceive(struct rfid_asic_handle *handle, DEBUGP("rx_len == 0\n"); - rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &tmp); - rc632_reg_read(handle, RC632_REG_CHANNEL_REDUNDANCY, &tmp); + for (i = 0; i < 1; i++) { + 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); + } + rc632_reg_read(handle, RC632_REG_CHANNEL_REDUNDANCY, &tmp); return -1; } return rc632_fifo_read(handle, *rx_len, rx_buf); - /* FIXME: discard addidional bytes in FIFO */ + /* FIXME: discard additional bytes in FIFO */ } static int @@ -467,7 +551,7 @@ rc632_read_eeprom(struct rfid_asic_handle *handle) if (ret < 0) return ret; - // FIXME: do something with eeprom contents + /* FIXME: do something with eeprom contents */ return ret; } @@ -494,7 +578,7 @@ rc632_calc_crc16_from(struct rfid_asic_handle *handle) if (ret < 0) return ret; - usleep(10000); // FIXME: no checking for cmd completion? + usleep(10000); /* FIXME: no checking for cmd completion? * ret = rc632_reg_read(handle, RC632_REG_CRC_RESULT_LSB, &crc_lsb); if (ret < 0) @@ -504,7 +588,7 @@ rc632_calc_crc16_from(struct rfid_asic_handle *handle) if (ret < 0) return ret; - // FIXME: what to do with crc result? + /* FIXME: what to do with crc result? */ return ret; } @@ -527,14 +611,14 @@ rc632_register_dump(struct rfid_asic_handle *handle, u_int8_t *buf) static int generic_fifo_write() { - // FIXME: implementation (not needed for CM 5121) + /* FIXME: implementation (not needed for CM 5121) */ return -1; } static int generic_fifo_read() { - // FIXME: implementation (not neded for CM 5121) + /* FIXME: implementation (not neded for CM 5121) */ return -1; } @@ -642,7 +726,7 @@ rc632_iso14443a_init(struct rfid_asic_handle *handle) { int ret; - // FIXME: some fifo work (drain fifo?) + /* FIXME: some fifo work (drain fifo?) */ /* flush fifo (our way) */ ret = rc632_reg_write(handle, RC632_REG_CONTROL, @@ -863,6 +947,12 @@ rc632_iso14443ab_transceive(struct rfid_asic_handle *handle, channel_red = RC632_CR_PARITY_ENABLE|RC632_CR_PARITY_ODD; break; #endif + case RFID_15693_FRAME: + channel_red = RC632_CR_CRC3309 | RC632_CR_RX_CRC_ENABLE + | RC632_CR_TX_CRC_ENABLE; + break; + case RFID_15693_FRAME_ICODE1: + /* FIXME: implement */ default: return -EINVAL; break; @@ -871,7 +961,7 @@ rc632_iso14443ab_transceive(struct rfid_asic_handle *handle, channel_red); if (ret < 0) return ret; - + DEBUGP("tx_len=%u\n",tx_len); ret = rc632_transceive(handle, tx_buf, tx_len, rx_buf, &rxl, timeout, 0); *rx_len = rxl; if (ret < 0) @@ -962,6 +1052,138 @@ 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, @@ -1086,8 +1308,8 @@ static int rc632_iso14443a_set_speed(struct rfid_asic_handle *handle, static int rc632_iso14443b_init(struct rfid_asic_handle *handle) { int ret; - - // FIXME: some FIFO work + ENTER(); + /* FIXME: some FIFO work */ /* flush fifo (our way) */ ret = rc632_reg_write(handle, RC632_REG_CONTROL, @@ -1192,170 +1414,201 @@ static int rc632_iso14443b_init(struct rfid_asic_handle *handle) return 0; } -static int -rc632_iso15693_init(struct rfid_asic_handle *h) -{ - int ret; - - ret = rc632_reg_write(h, RC632_REG_TX_CONTROL, - (RC632_TXCTRL_MOD_SRC_INT | - RC632_TXCTRL_TX2_INV | - RC632_TXCTRL_TX2_RF_EN | - RC632_TXCTRL_TX1_RF_EN)); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_CW_CONDUCTANCE, 0x3f); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_MOD_CONDUCTANCE, 0x03); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_CODER_CONTROL, - (RC632_CDRCTRL_RATE_15693 | - 0x03)); /* FIXME */ - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_MOD_WIDTH, 0x3f); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_MOD_WIDTH_SOF, 0x3f); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_TYPE_B_FRAMING, 0x00); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_RX_CONTROL1, - (RC632_RXCTRL1_SUBCP_16 | - RC632_RXCTRL1_ISO15693 | - RC632_RXCTRL1_GAIN_35DB)); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_DECODER_CONTROL, - (RC632_DECCTRL_RXFR_15693 | - RC632_DECCTRL_RX_INVERT)); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_BIT_PHASE, 0xe0); - if (ret < 0) - return ret; +struct register_file { + u_int8_t reg; + u_int8_t val; +}; - ret = rc632_reg_write(h, RC632_REG_RX_THRESHOLD, 0xff); - if (ret < 0) - return ret; +/* Register file for ISO15693 standard */ +static struct register_file iso15693_fast_script[] = { + { + .reg = RC632_REG_TX_CONTROL, + .val = RC632_TXCTRL_MOD_SRC_INT | + RC632_TXCTRL_TX2_INV | + RC632_TXCTRL_TX2_RF_EN | + RC632_TXCTRL_TX1_RF_EN, + }, { + .reg = RC632_REG_CW_CONDUCTANCE, + .val = 0x3f, + }, { + .reg = RC632_REG_MOD_CONDUCTANCE, + /* FIXME: nxp default for icode1/15693: 0x05 */ + //.val = 0x02, + .val = 0x21, /* omnikey */ + }, { + .reg = RC632_REG_CODER_CONTROL, + .val = RC632_CDRCTRL_TXCD_15693_FAST | + RC632_CDRCTRL_RATE_15693, + }, { + .reg = RC632_REG_MOD_WIDTH, + .val = 0x3f, + }, { + .reg = RC632_REG_MOD_WIDTH_SOF, + .val = 0x3f, + }, { + .reg = RC632_REG_TYPE_B_FRAMING, + .val = 0x00, + }, { + .reg = RC632_REG_RX_CONTROL1, + .val = RC632_RXCTRL1_ISO15693 | + RC632_RXCTRL1_SUBCP_16 | + RC632_RXCTRL1_GAIN_35DB, + }, { + /* FIXME: this should always be the case */ + .reg = RC632_REG_RX_CONTROL2, + .val = RC632_RXCTRL2_DECSRC_INT, + }, { + .reg = RC632_REG_DECODER_CONTROL, + .val = RC632_DECCTRL_MANCHESTER | + RC632_DECCTRL_RX_INVERT | + RC632_DECCTRL_ZEROAFTERCOL | + RC632_DECCTRL_RXFR_15693, + }, { + .reg = RC632_REG_BIT_PHASE, + /* FIXME: nxp default for icode1/15693: 0x54 */ + //.val = 0x52, + .val = 0xd0, /* omnikey */ + }, { + .reg = RC632_REG_RX_THRESHOLD, + /* FIXME: nxp default for icode1/15693: 0x68 */ + //.val = 0x66, + .val = 0xed, + }, { + .reg = RC632_REG_BPSK_DEM_CONTROL, + .val = 0x00, + }, { + .reg = RC632_REG_CHANNEL_REDUNDANCY, + .val = RC632_CR_RX_CRC_ENABLE | + RC632_CR_TX_CRC_ENABLE | + RC632_CR_CRC3309, + }, { + .reg = RC632_REG_CRC_PRESET_LSB, + .val = 0xff, + }, { + .reg = RC632_REG_CRC_PRESET_MSB, + .val = 0xff, + }, +}; - ret = rc632_reg_write(h, RC632_REG_BPSK_DEM_CONTROL, 0x00); - if (ret < 0) - return ret; +/* Register file for I*Code standard */ +static struct register_file icode1_std_script[] = { + { + .reg = RC632_REG_TX_CONTROL, + .val = RC632_TXCTRL_MOD_SRC_INT | + RC632_TXCTRL_TX2_INV | + RC632_TXCTRL_TX2_RF_EN | + RC632_TXCTRL_TX1_RF_EN, + }, { + .reg = RC632_REG_CW_CONDUCTANCE, + .val = 0x3f, + }, { + .reg = RC632_REG_MOD_CONDUCTANCE, + /* FIXME: nxp default for icode1/15693: 0x05 */ + .val = 0x02, + }, { + .reg = RC632_REG_CODER_CONTROL, + .val = RC632_CDRCTRL_TXCD_ICODE_STD | + RC632_CDRCTRL_RATE_15693, + }, { + .reg = RC632_REG_MOD_WIDTH, + .val = 0x3f, + }, { + .reg = RC632_REG_MOD_WIDTH_SOF, + .val = 0x3f, + }, { + .reg = RC632_REG_TYPE_B_FRAMING, + .val = 0x00, + }, { + .reg = RC632_REG_RX_CONTROL1, + .val = RC632_RXCTRL1_ISO15693 | + RC632_RXCTRL1_SUBCP_16 | + RC632_RXCTRL1_GAIN_35DB, + }, { + /* FIXME: this should always be the case */ + .reg = RC632_REG_RX_CONTROL2, + .val = RC632_RXCTRL2_DECSRC_INT, + }, { + .reg = RC632_REG_DECODER_CONTROL, + .val = RC632_DECCTRL_MANCHESTER | + RC632_DECCTRL_RXFR_ICODE, + }, { + .reg = RC632_REG_BIT_PHASE, + /* FIXME: nxp default for icode1/15693: 0x54 */ + .val = 0x52, + }, { + .reg = RC632_REG_RX_THRESHOLD, + /* FIXME: nxp default for icode1/15693: 0x68 */ + .val = 0x66, + }, { + .reg = RC632_REG_BPSK_DEM_CONTROL, + .val = 0x00, + }, { + .reg = RC632_REG_CHANNEL_REDUNDANCY, + /* 16bit CRC, no parity, not CRC3309 */ + .val = RC632_CR_RX_CRC_ENABLE | + RC632_CR_TX_CRC_ENABLE, + }, { + .reg = RC632_REG_CRC_PRESET_LSB, + .val = 0xfe, + }, { + .reg = RC632_REG_CRC_PRESET_MSB, + .val = 0xff, + } +}; - ret = rc632_reg_write(h, RC632_REG_RX_CONTROL2, - (RC632_RXCTRL2_AUTO_PD | - RC632_RXCTRL2_DECSRC_INT)); - if (ret < 0) - return ret; +/* incremental changes on top of icode1_std_script */ +static struct register_file icode1_fast_patch[] = { + { + .reg = RC632_REG_CODER_CONTROL, + .val = RC632_CDRCTRL_TXCD_ICODE_FAST | + RC632_CDRCTRL_RATE_ICODE_FAST, + }, { + .reg = RC632_REG_MOD_WIDTH_SOF, + .val = 0x73, /* 18.88uS */ + }, +}; - ret = rc632_reg_write(h, RC632_REG_CHANNEL_REDUNDANCY, - (RC632_CR_CRC3309 | - RC632_CR_RX_CRC_ENABLE | - RC632_CR_TX_CRC_ENABLE)); - if (ret < 0) - return ret; +static int +rc632_iso15693_init(struct rfid_asic_handle *h) +{ + int ret, i; + ENTER(); - ret = rc632_reg_write(h, RC632_REG_CRC_PRESET_LSB, 0xff); - if (ret < 0) - return ret; + /* flush fifo (our way) */ + ret = rc632_reg_write(h, RC632_REG_CONTROL, + RC632_CONTROL_FIFO_FLUSH); - ret = rc632_reg_write(h, RC632_REG_CRC_PRESET_MSB, 0xff); - 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; + } return 0; } static int -rc632_iso15693_icode_init(struct rfid_asic_handle *h) +rc632_iso15693_icode1_init(struct rfid_asic_handle *h, int fast) { int ret; + int i; - ret = rc632_reg_write(h, RC632_REG_TX_CONTROL, - (RC632_TXCTRL_MOD_SRC_INT | - RC632_TXCTRL_TX2_INV | - RC632_TXCTRL_TX2_RF_EN | - RC632_TXCTRL_TX1_RF_EN)); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_CW_CONDUCTANCE, 0x3f); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_MOD_CONDUCTANCE, 0x02); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_CODER_CONTROL, 0x2c); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_MOD_WIDTH, 0x3f); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_MOD_WIDTH_SOF, 0x3f); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_MOD_WIDTH_SOF, 0x3f); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_TYPE_B_FRAMING, 0x00); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_RX_CONTROL1, 0x8b); /* FIXME */ - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_DECODER_CONTROL, 0x00); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_BIT_PHASE, 0x52); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_RX_THRESHOLD, 0x66); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_BPSK_DEM_CONTROL, 0x00); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_RX_CONTROL2, - RC632_RXCTRL2_DECSRC_INT); - if (ret < 0) - return ret; - - ret = rc632_reg_write(h, RC632_REG_CHANNEL_REDUNDANCY, - (RC632_CR_RX_CRC_ENABLE | - RC632_CR_TX_CRC_ENABLE)); - ret = rc632_reg_write(h, RC632_REG_CRC_PRESET_LSB, 0xfe); - if (ret < 0) - return ret; + 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_reg_write(h, RC632_REG_CRC_PRESET_MSB, 0xff); - if (ret < 0) - return ret; + 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; + } + } return 0; } @@ -1646,6 +1899,7 @@ const struct rfid_asic rc632 = { }, .iso15693 = { .init = &rc632_iso15693_init, + .transceive_ac = &rc632_iso15693_transceive_ac, }, .mifare_classic = { .setkey = &rc632_mifare_set_key, diff --git a/src/rfid_layer2.c b/src/rfid_layer2.c index bc5a4ec..4cad6c3 100644 --- a/src/rfid_layer2.c +++ b/src/rfid_layer2.c @@ -117,6 +117,15 @@ rfid_layer2_setopt(struct rfid_layer2_handle *ph, int optname, { if (optname >> 16 == 0) { switch (optname) { + case RFID_OPT_LAYER2_UID: + printf("----> sizeof(ph->uid): %d\n",sizeof(ph->uid)); + if ((ph->uid_len < sizeof(ph->uid)) && (optlen<=sizeof(ph->uid))) { + //(ph->uid_lenuid_len = optlen; + memcpy(ph->uid, optval, optlen); + } else + return -EINVAL; + break; default: return -EINVAL; break; diff --git a/src/rfid_layer2_iso15693.c b/src/rfid_layer2_iso15693.c index 1c1ee1c..09dd632 100644 --- a/src/rfid_layer2_iso15693.c +++ b/src/rfid_layer2_iso15693.c @@ -1,7 +1,7 @@ /* ISO 15693 anticollision implementation * - * (C) 2005-2006 by Harald Welte - * + * (C) 2005-2008 by Harald Welte + * (C) 2007 by Bjoern Riemer */ /* @@ -19,6 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#define DEBUG_LIBRFID + #include #include #include @@ -35,10 +37,41 @@ struct iso15693_request_read { u_int8_t blocknum; } __attribute__ ((packed)); +struct iso15693_request_adressed { + struct iso15693_request head; + u_int64_t uid; +} __attribute__ ((packed)); + #define ISO15693_BLOCK_SIZE_MAX (256/8) #define ISO15693_RESP_SIZE_MAX (4+ISO15693_BLOCK_SIZE_MAX) +#define TIMEOUT 200 + +static int iso15693_transceive(struct rfid_layer2_handle *handle, + 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) +{ + return handle->rh->reader->transceive(handle->rh, frametype, tx_buf, + tx_len, rx_buf, rx_len, timeout, flags); +} + +/* 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) +{ + 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); +} + #if 0 + static int iso15693_read_block(struct rfid_layer2_handle *handle, u_int8_t blocknr, u_int32_t *data) @@ -90,6 +123,121 @@ iso15693_lock_block() static int iso15693_anticol(struct rfid_layer2_handle *handle) { + int i, ret; + int rx_len = 0; + int num_valid = 0; + struct iso15693_anticol_cmd acf; + char uuid[ISO15693_UID_LEN]; + char boc; + + char uuid_list[16][ISO15693_UID_LEN]; + int uuid_list_valid[16]; + +#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; + } 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); + } + } + usleep(1000*200); + } + if (acf.flags & RFID_15693_F5_NSLOTS_1) + i = 1; + else + i = 16; + + while (i) { + if (uuid_list_valid[i] == MY_NONE) { + DEBUGP("slot[%d]: timeout\n",i); + } else if (uuid_list_valid[i] == MY_UUID) { + DEBUGP("slot[%d]: VALID uuid: %s\n", i, + rfid_hexdump(uuid_list[i], ISO15693_UID_LEN)); + num_valid++; + } else if (uuid_list_valid[i] < 0) { + DEBUGP("slot[%d]: collision(%d %d,%d) uuid: %s\n", + i,uuid_list_valid[i]*-1, + (uuid_list_valid[i]*-1)/8, + (uuid_list_valid[i]*-1)%8, + rfid_hexdump(uuid_list[i], ISO15693_UID_LEN)); + } + i--; + } + if (num_valid == 0) + return -1; + + return num_valid; +} + +static int +iso15693_select(struct rfid_layer2_handle *handle) +{ + struct iso15693_request_adressed tx_req; + int ret; + unsigned int rx_len, tx_len; + + struct { + struct iso15693_response head; + u_int8_t error; + unsigned char crc[2]; + } rx_buf; + rx_len = sizeof(rx_buf); + + tx_req.head.command = ISO15693_CMD_SELECT; + tx_req.head.flags = RFID_15693_F4_ADDRESS | RFID_15693_F_SUBC_TWO ; + tx_req.uid = 0xE0070000020C1F18; + //req.uid = 0x181F0C02000007E0; + //req.uid = 0xe004010001950837; + //req.uid = 0x37089501000104e0; + tx_len = sizeof(tx_req); + DEBUGP("tx_len=%u", tx_len); DEBUGPC(" rx_len=%u\n",rx_len); + ret = iso15693_transceive(handle, RFID_15693_FRAME, (u_int8_t*)&tx_req, + tx_len, (u_int8_t*)&rx_buf, &rx_len, 50,0); + DEBUGP("ret: %d, error_flag: %d error: %d\n", ret, + rx_buf.head.flags&RFID_15693_RF_ERROR, 0); return -1; } @@ -127,6 +275,7 @@ iso15693_setopt(struct rfid_layer2_handle *handle, int optname, static int transceive_inventory(struct rfid_layer2_handle *l2h) { + return -1; } static struct rfid_layer2_handle * @@ -163,6 +312,7 @@ const struct rfid_layer2 rfid_layer2_iso15693 = { .fn = { .init = &iso15693_init, .open = &iso15693_anticol, + //.open = &iso15693_select, //.transceive = &iso15693_transceive, //.close = &iso14443a_hlta, .fini = &iso15693_fini, diff --git a/src/rfid_proto_icode.c b/src/rfid_proto_icode.c new file mode 100644 index 0000000..f8e6cbd --- /dev/null +++ b/src/rfid_proto_icode.c @@ -0,0 +1,120 @@ + +/* Philips/NXP I*Code implementation, PCD side. + * + * (C) 2005-2008 by Harald Welte + * + */ + +/* + * 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static int +icode_read(struct rfid_protocol_handle *ph, unsigned int page, + unsigned char *rx_data, unsigned int *rx_len) +{ + unsigned char rx_buf[16]; + unsigned int real_rx_len = sizeof(rx_buf); + unsigned char tx[2]; + int ret; + + /* FIXME */ + return -EINVAL; +} + +static int +icode_write(struct rfid_protocol_handle *ph, unsigned int page, + unsigned char *tx_data, unsigned int tx_len) +{ + unsigned int i; + unsigned char tx[6]; + unsigned char rx[10]; + unsigned int rx_len = sizeof(rx); + int ret; + + return -EINVAL; +} + +static int +icode_getopt(struct rfid_protocol_handle *ph, int optname, void *optval, + unsigned int *optlen) +{ + int ret = -EINVAL; + unsigned int *size = optval; + + switch (optname) { + case RFID_OPT_PROTO_SIZE: + ret = 0; + /* we have to return the size in bytes, not bits */ + /* FIXME: implement this */ + *size = 12345; + break; + } + + return ret; +} + + +static struct rfid_protocol_handle * +icode_init(struct rfid_layer2_handle *l2h) +{ + struct rfid_protocol_handle *ph; + u_int8_t uid[6]; + int uid_len = sizeof(uid); + + if (l2h->l2->id != RFID_LAYER2_ICODE1) + return NULL; + + /* According to "SCBU002 - November 2005 */ + rfid_layer2_getopt(l2h, RFID_OPT_LAYER2_UID, + uid, &uid_len); + if (uid[5] != 0xe0 || uid[4] != 0x07) + return NULL; + if (l2h->uid_len != 6) + return NULL; + + ph = malloc_protocol_handle(sizeof(struct rfid_protocol_handle)); + return ph; +} + +static int icode_fini(struct rfid_protocol_handle *ph) +{ + free_protocol_handle(ph); + return 0; +} + +const struct rfid_protocol rfid_protocol_icode = { + .id = RFID_PROTOCOL_ICODE_SLI, + .name = "I*Code SLI", + .fn = { + .init = &icode_init, + .read = &icode_read, + .write = &icode_write, + .fini = &icode_fini, + .getopt = &icode_getopt, + }, +}; + +/* Functions below are not (yet? covered in the generic librfid api */ diff --git a/src/rfid_proto_tagit.c b/src/rfid_proto_tagit.c new file mode 100644 index 0000000..0388baa --- /dev/null +++ b/src/rfid_proto_tagit.c @@ -0,0 +1,141 @@ + +/* UNFINISHED TI Tag-it implementation, PCD side. + * + * (C) 2005-2008 by Harald Welte + * + */ + +/* + * 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +struct tagit_version { + u_int8_t version; /* bit 47..40 (last bit masked) of uid */ + const char *name; +}; + +const struct tagit_version tagit_versions[] = { + { + .version = 0x00, + .name = "HF-I Plus Inlay", + }, { + .version = 0x80, + .name = "HF-I Plus Chip", + }, { + .version = 0xc0, + .name = "HF-I Standard Chip / Inlay", + }, { + .version = 0xc4, + .name = "HF-I Pro Chip / Inlay", + }, +}; + +static int +tagit_read(struct rfid_protocol_handle *ph, unsigned int page, + unsigned char *rx_data, unsigned int *rx_len) +{ + unsigned char rx_buf[16]; + unsigned int real_rx_len = sizeof(rx_buf); + unsigned char tx[2]; + int ret; + + /* FIXME */ + return -EINVAL; +} + +static int +tagit_write(struct rfid_protocol_handle *ph, unsigned int page, + unsigned char *tx_data, unsigned int tx_len) +{ + unsigned int i; + unsigned char tx[6]; + unsigned char rx[10]; + unsigned int rx_len = sizeof(rx); + int ret; + + return -EINVAL; +} + +static int +tagit_getopt(struct rfid_protocol_handle *ph, int optname, void *optval, + unsigned int *optlen) +{ + int ret = -EINVAL; + unsigned int *size = optval; + + switch (optname) { + case RFID_OPT_PROTO_SIZE: + ret = 0; + /* we have to return the size in bytes, not bits */ + /* FIXME: implement this */ + *size = 12345; + break; + } + + return ret; +} + + +static struct rfid_protocol_handle * +tagit_init(struct rfid_layer2_handle *l2h) +{ + struct rfid_protocol_handle *ph; + u_int8_t uid[6]; + unsigned int uid_len = sizeof(uid); + + if (l2h->l2->id != RFID_LAYER2_ISO15693) + return NULL; + + /* According to "SCBU002 - November 2005 */ + rfid_layer2_getopt(l2h, RFID_OPT_LAYER2_UID, + uid, &uid_len); + if (uid[5] != 0xe0 || uid[4] != 0x07) + return NULL; + if (l2h->uid_len != 6) + return NULL; + + ph = malloc_protocol_handle(sizeof(struct rfid_protocol_handle)); + return ph; +} + +static int tagit_fini(struct rfid_protocol_handle *ph) +{ + free_protocol_handle(ph); + return 0; +} + +const struct rfid_protocol rfid_protocol_tagit = { + .id = RFID_PROTOCOL_TAGIT, + .name = "TI Tag-it HF", + .fn = { + .init = &tagit_init, + .read = &tagit_read, + .write = &tagit_write, + .fini = &tagit_fini, + .getopt = &tagit_getopt, + }, +}; + +/* Functions below are not (yet? covered in the generic librfid api */ diff --git a/src/rfid_protocol.c b/src/rfid_protocol.c index 9d70e90..71c52ff 100644 --- a/src/rfid_protocol.c +++ b/src/rfid_protocol.c @@ -28,6 +28,7 @@ static const struct rfid_protocol *rfid_protocols[] = { [RFID_PROTOCOL_MIFARE_CLASSIC] = &rfid_protocol_mfcl, [RFID_PROTOCOL_MIFARE_UL] = &rfid_protocol_mful, [RFID_PROTOCOL_TCL] = &rfid_protocol_tcl, + [RFID_PROTOCOL_TAGIT] = &rfid_protocol_tagit, }; struct rfid_protocol_handle * diff --git a/src/rfid_reader_cm5121.c b/src/rfid_reader_cm5121.c index 053b953..f51cd82 100644 --- a/src/rfid_reader_cm5121.c +++ b/src/rfid_reader_cm5121.c @@ -366,6 +366,16 @@ 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, @@ -391,6 +401,7 @@ const struct rfid_reader rfid_reader_cm5121 = { }, .iso15693 = { .init = &cm5121_15693_init, + .transceive_ac = &cm5121_iso15693_transceive_ac, }, .mifare_classic = { .setkey = &cm5121_mifare_setkey, diff --git a/src/rfid_reader_openpcd.c b/src/rfid_reader_openpcd.c index 88c55ee..19ea7c2 100644 --- a/src/rfid_reader_openpcd.c +++ b/src/rfid_reader_openpcd.c @@ -58,6 +58,14 @@ static struct openpcd_hdr *rcv_hdr; #include #endif/*__MINGW32__*/ +#ifdef DEBUG_REGISTER +#define DEBUGRC DEBUGPC +#define DEBUGR DEBUGP +#else +#define DEBUGRC(x, args ...) do {} while(0) +#define DEBUGR(x, args ...) do {} while(0) +#endif + static struct usb_device *dev; static struct usb_dev_handle *hdl; @@ -138,13 +146,13 @@ static int openpcd_reg_write(struct rfid_asic_transport_handle *rath, { int ret; - DEBUGP("reg=0x%02x, val=%02x: ", reg, value); + DEBUGR("reg=0x%02x, val=%02x: ", reg, value); ret = openpcd_xcv(OPENPCD_CMD_WRITE_REG, reg, value, 0, NULL); if (ret < 0) - DEBUGPC("ERROR sending command\n"); + DEBUGRC("ERROR sending command\n"); else - DEBUGPC("OK\n"); + DEBUGRC("OK\n"); return ret; } @@ -155,21 +163,21 @@ static int openpcd_reg_read(struct rfid_asic_transport_handle *rath, { int ret; - DEBUGP("reg=0x%02x, ", reg); + DEBUGR("reg=0x%02x, ", reg); ret = openpcd_xcv(OPENPCD_CMD_READ_REG, reg, 0, 0, NULL); if (ret < 0) { - DEBUGPC("ERROR sending command\n"); + DEBUGRC("ERROR sending command\n"); return ret; } if (ret < sizeof(struct openpcd_hdr)) { - DEBUGPC("ERROR: short packet\n"); + DEBUGRC("ERROR: short packet\n"); return ret; } *value = rcv_hdr->val; - DEBUGPC("val=%02x: OK\n", *value); + DEBUGRC("val=%02x: OK\n", *value); return ret; } @@ -180,17 +188,17 @@ static int openpcd_fifo_read(struct rfid_asic_transport_handle *rath, { int ret; - DEBUGP(" "); + DEBUGR(" "); ret = openpcd_xcv(OPENPCD_CMD_READ_FIFO, 0x00, num_bytes, 0, NULL); if (ret < 0) { - DEBUGPC("ERROR sending command\n"); + DEBUGRC("ERROR sending command\n"); return ret; } - DEBUGPC("ret = %d\n", ret); + DEBUGRC("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), + DEBUGRC("len=%d val=%s: OK\n", ret - sizeof(struct openpcd_hdr), rfid_hexdump(rcv_hdr->data, ret - sizeof(struct openpcd_hdr))); return ret; @@ -203,7 +211,7 @@ static int openpcd_fifo_write(struct rfid_asic_transport_handle *rath, { int ret; - DEBUGP("len=%u, data=%s\n", len, rfid_hexdump(bytes, len)); + DEBUGR("len=%u, data=%s\n", len, rfid_hexdump(bytes, len)); ret = openpcd_xcv(OPENPCD_CMD_WRITE_FIFO, 0, 0, len, bytes); return ret; @@ -373,6 +381,16 @@ openpcd_transceive_acf(struct rfid_reader_handle *rh, 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) +{ + return rh->ah->asic->priv.rc632.fn.iso15693.transceive_ac( + rh->ah, acf, uuid, bit_of_col); +} + + static int openpcd_14443a_init(struct rfid_reader_handle *rh) { @@ -562,6 +580,7 @@ const struct rfid_reader rfid_reader_openpcd = { }, .iso15693 = { .init = &openpcd_15693_init, + .transceive_ac = &openpcd_iso15693_transceive_ac, }, .mifare_classic = { .setkey = &openpcd_mifare_setkey, diff --git a/src/rfid_reader_spidev.c b/src/rfid_reader_spidev.c index b0676eb..b704e9b 100644 --- a/src/rfid_reader_spidev.c +++ b/src/rfid_reader_spidev.c @@ -260,6 +260,15 @@ 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) { @@ -387,6 +396,10 @@ struct rfid_reader rfid_reader_spidev = { .iso14443b = { .init = &spidev_14443b_init, }, + .iso15693 = { + .init = &spidev_15693_init, + .transceive_ac = &spidev_15693_transceive_ac, + }, .mifare_classic = { .setkey = &spidev_mifare_setkey, .auth = &spidev_mifare_auth, diff --git a/utils/common.c b/utils/common.c index 12c3bd4..ec7fda0 100644 --- a/utils/common.c +++ b/utils/common.c @@ -72,13 +72,13 @@ struct rfid_protocol_handle *ph; int reader_init(void) { - printf("opening reader handle\n"); - rh = rfid_reader_open(NULL, RFID_READER_CM5121); + printf("opening reader handle OpenPCD, CM5x21\n"); + rh = rfid_reader_open(NULL, RFID_READER_OPENPCD); if (!rh) { - fprintf(stderr, "No Omnikey Cardman 5121 found\n"); - rh = rfid_reader_open(NULL, RFID_READER_OPENPCD); + fprintf(stderr, "No OpenPCD found\n"); + rh = rfid_reader_open(NULL, RFID_READER_CM5121); if (!rh) { - fprintf(stderr, "No OpenPCD found either\n"); + fprintf(stderr, "No Omnikey Cardman 5x21 found\n"); return -1; } } @@ -92,11 +92,11 @@ int l2_init(int layer2) printf("opening layer2 handle\n"); l2h = rfid_layer2_init(rh, layer2); if (!l2h) { - fprintf(stderr, "error during iso14443a_init\n"); + fprintf(stderr, "error during layer2(%d)_init (0=14a,1=14b,3=15)\n",layer2); return -1; } - printf("running layer2 anticol\n"); + printf("running layer2 anticol(_open)\n"); rc = rfid_layer2_open(l2h); if (rc < 0) { fprintf(stderr, "error during layer2_open\n"); diff --git a/utils/librfid-tool.c b/utils/librfid-tool.c index dab7db3..3e833a0 100644 --- a/utils/librfid-tool.c +++ b/utils/librfid-tool.c @@ -1,6 +1,6 @@ /* librfid-tool - a small command-line tool for librfid testing * - * (C) 2005-2006 by Harald Welte + * (C) 2005-2008 by Harald Welte * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -35,8 +35,13 @@ #include #include +#include +#include + #include #include +#include +#include #include "librfid-tool.h" @@ -226,6 +231,8 @@ static char *proto_names[] = { [RFID_PROTOCOL_TCL] = "tcl", [RFID_PROTOCOL_MIFARE_UL] = "mifare-ultralight", [RFID_PROTOCOL_MIFARE_CLASSIC] = "mifare-classic", + [RFID_PROTOCOL_ICODE_SLI] = "icode", + [RFID_PROTOCOL_TAGIT] = "tagit", }; static int proto_by_name(const char *name) @@ -245,6 +252,7 @@ static char *l2_names[] = { [RFID_LAYER2_ISO14443A] = "iso14443a", [RFID_LAYER2_ISO14443B] = "iso14443b", [RFID_LAYER2_ISO15693] = "iso15693", + [RFID_LAYER2_ICODE1] = "icode1", }; static int l2_by_name(const char *name) @@ -315,6 +323,86 @@ static void do_endless_scan() } } +static void do_regdump(void) +{ + u_int8_t buffer[0xff]; + int i; + + printf("dumping rc632 regs...\n"); + + rc632_register_dump(rh->ah, buffer); + + printf("\n "); + for (i=0; i<=0x0f; i++) + printf(" 0x_%01X",i); + printf("\n-----------------------------------------------------------------------------------\n"); + + for (i=0; i <= 0x3f; i++) { + if ((i % 0x10) == 0) + printf("0x%01X_:",i/0x10); + printf(" 0x%02X", buffer[i]); + if ((i% 0x10) == 0x0f) + printf("\n"); + } + + /* print regdump as c-style array*/ + printf("u_int8_t rc632_regs[] = {"); + for (i = 0; i <= 0x3f; i++) { + if (((i+1) % 0x08) == 1) { + if (i > 7) + printf("//%2d..%2d",i-8,i-1); + printf("\n\t"); + } + printf(" 0x%02X, ",buffer[i]); + } + printf("//%2d..%2d\n\t 0 };\n",i-8,i-1); + +} + +static void do_enum(int layer2) +{ + int rc; + //unsigned int size; + //unsigned int size_len = sizeof(size); + unsigned char uid_buf[16]; + unsigned int uid_len; + + printf("scanning for RFID token on layer %s...\n", l2_names[layer2]); + + if (rh->reader->l2_supported & (1 << layer2)) { + l2h = rfid_layer2_init(rh, layer2); + rc = rfid_layer2_open(l2h); + } else { + printf("error during layer2_open\n"); + return ; + } + + while (rc>=0) { + if (l2h) { + uid_len = sizeof(uid_buf); + rfid_layer2_getopt(l2h, RFID_OPT_LAYER2_UID, &uid_buf, &uid_len); + printf("Layer 2 success (%s)[%d]: %s\n", rfid_layer2_name(l2h), uid_len, hexdump(uid_buf, uid_len)); + } + + /* + ph = rfid_protocol_scan(l2h); + if (ph) { + printf("Protocol success (%s)\n", rfid_protocol_name(ph)); + + if (rfid_protocol_getopt(ph, RFID_OPT_PROTO_SIZE, + &size, &size_len) == 0) + printf("Size: %u bytes\n", size); + } else + printf("##############\n"); + */ + + if (rc >= 0) { + rfid_layer2_close(l2h); + } + rc = rfid_layer2_open(l2h); + } +} + #define OPTION_OFFSET 256 static struct option original_opts[] = { @@ -323,6 +411,8 @@ static struct option original_opts[] = { { "protocol", 1, 0, 'p' }, { "scan", 0, 0, 's' }, { "scan-loop", 0, 0, 'S' }, + { "dump", 0, 0, 'd' }, + { "enum", 0, 0, 'e' }, {0, 0, 0, 0} }; @@ -395,8 +485,10 @@ static void help(void) { printf( " -s --scan scan until first RFID tag is found\n" " -S --scan-loop endless scanning loop\n" - " -p --protocol {tcl,mifare-ultralight,mifare-classic}\n" + " -p --protocol {tcl,mifare-ultralight,mifare-classic,tagit}\n" " -l --layer2 {iso14443a,iso14443b,iso15693}\n" + " -d --dump dump rc632 registers\n" + " -e --enum enumerate all tag's in field (iso14443a)\n" " -h --help\n"); } @@ -412,7 +504,7 @@ int main(int argc, char **argv) program_name = basename(argv[0]); #endif/*__MINGW32__*/ - printf("%s - (C) 2006 by Harald Welte\n" + printf("%s - (C) 2005-2008 by Harald Welte\n" "This program is Free Software and has " "ABSOLUTELY NO WARRANTY\n\n", program_name); @@ -421,11 +513,23 @@ int main(int argc, char **argv) while (1) { int c, option_index = 0; - c = getopt_long(argc, argv, "hp:l:sS", opts, &option_index); + c = getopt_long(argc, argv, "hp:l:sSde", opts, &option_index); if (c == -1) break; switch (c) { + case 'e': + if (reader_init() < 0) + exit(1); + layer2 = RFID_LAYER2_ISO14443A; + do_enum(layer2); + exit(0); + break; + case 'd': + if (reader_init() < 0) + exit(1); + do_regdump(); + break; case 's': if (reader_init() < 0) exit(1); @@ -479,11 +583,16 @@ int main(int argc, char **argv) if (reader_init() < 0) exit(1); - if (l2_init(layer2) < 0) + + if (l2_init(layer2) < 0) { + rfid_reader_close(rh); exit(1); + } - if (l3_init(protocol) < 0) + if (l3_init(protocol) < 0) { + rfid_reader_close(rh); exit(1); + } switch (protocol) { @@ -573,7 +682,7 @@ int main(int argc, char **argv) } break; default: - printf("unknown protocol\n"); + printf("unknown protocol %u\n", protocol); exit(1); break; } -- cgit v1.2.3