partial ISO15693 support (based on patch by Bjoern Kaiser)
authorHarald Welte <laforge@gnumonks.org>
Sun, 27 Jan 2008 21:14:08 +0000 (21:14 +0000)
committerHarald Welte <laforge@gnumonks.org>
Sun, 27 Jan 2008 21:14:08 +0000 (21:14 +0000)
git-svn-id: https://svn.gnumonks.org/trunk/librfid@2057 e0336214-984f-0b4b-a45f-81c69e1f0ede

23 files changed:
include/librfid/Makefile.am
include/librfid/rfid.h
include/librfid/rfid_asic_rc632.h
include/librfid/rfid_layer2.h
include/librfid/rfid_layer2_icode1.h [new file with mode: 0644]
include/librfid/rfid_layer2_iso15693.h
include/librfid/rfid_protocol.h
include/librfid/rfid_protocol_icode.h [new file with mode: 0644]
include/librfid/rfid_protocol_tagit.h [new file with mode: 0644]
include/librfid/rfid_reader.h
src/Makefile.am
src/rc632.h
src/rfid_asic_rc632.c
src/rfid_layer2.c
src/rfid_layer2_iso15693.c
src/rfid_proto_icode.c [new file with mode: 0644]
src/rfid_proto_tagit.c [new file with mode: 0644]
src/rfid_protocol.c
src/rfid_reader_cm5121.c
src/rfid_reader_openpcd.c
src/rfid_reader_spidev.c
utils/common.c
utils/librfid-tool.c

index 6d5acd3..a5deb20 100644 (file)
@@ -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 \
index 64d6c06..bf21319 100644 (file)
@@ -5,9 +5,13 @@
 #include <sys/types.h>
 #include <stdio.h>
 
+#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 */
index ccc4f20..0602cd9 100644 (file)
@@ -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
index 45ae953..023b171 100644 (file)
@@ -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 <librfid/rfid_layer2_iso14443a.h>
 #include <librfid/rfid_layer2_iso14443b.h>
 #include <librfid/rfid_layer2_iso15693.h>
+#include <librfid/rfid_layer2_icode1.h>
 
 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 (file)
index 0000000..e8ebddb
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef _RFID_L2_ICODE1_H
+#define _RFID_L2_ICODE1_H
+
+#ifdef __LIBRFID__
+
+#include <librfid/rfid_layer2.h>
+extern const struct rfid_layer2 rfid_layer2_icode1;
+
+
+#endif /* __LIBRFID__ */
+#endif /* _ISO15693_H */
index d09daa7..5719a39 100644 (file)
@@ -4,11 +4,28 @@
 #include <sys/types.h>
 
 /*
-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 <librfid/rfid_layer2.h>
 extern const struct rfid_layer2 rfid_layer2_iso15693;
index ea4dd34..b4a145d 100644 (file)
@@ -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 <librfid/rfid_protocol_tcl.h>
 #include <librfid/rfid_protocol_mifare_ul.h>
 #include <librfid/rfid_protocol_mifare_classic.h>
+#include <librfid/rfid_protocol_tagit.h>
 
 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 (file)
index 0000000..9019243
--- /dev/null
@@ -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 (file)
index 0000000..46a73bc
--- /dev/null
@@ -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
index 64ad862..8dc7860 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <librfid/rfid_asic.h>
 #include <librfid/rfid_layer2_iso14443a.h>
+#include <librfid/rfid_layer2_iso15693.h>
 
 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);
index 45036b1..f0e5a6e 100644 (file)
@@ -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
index c7690ed..9cecab9 100644 (file)
@@ -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 {
index b8d8db3..8fc5cb9 100644 (file)
@@ -31,6 +31,7 @@
 #include <librfid/rfid_asic_rc632.h>
 #include <librfid/rfid_reader_cm5121.h>
 #include <librfid/rfid_layer2_iso14443a.h>
+#include <librfid/rfid_layer2_iso15693.h>
 #include <librfid/rfid_protocol_mifare_classic.h>
 
 #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,
index bc5a4ec..4cad6c3 100644 (file)
@@ -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_len<optlen)
+                               ph->uid_len = optlen;
+                               memcpy(ph->uid, optval, optlen);
+                       } else
+                               return -EINVAL;
+               break;
                default:
                        return -EINVAL;
                        break;
index 1c1ee1c..09dd632 100644 (file)
@@ -1,7 +1,7 @@
 /* ISO 15693 anticollision implementation
  *
- * (C) 2005-2006 by Harald Welte <laforge@gnumonks.org>
- *
+ * (C) 2005-2008 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2007 by Bjoern Riemer <bjoern.riemer@web.de>
  */
 
 /*
@@ -19,6 +19,8 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#define DEBUG_LIBRFID
+
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
@@ -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 (file)
index 0000000..f8e6cbd
--- /dev/null
@@ -0,0 +1,120 @@
+
+/* Philips/NXP I*Code implementation, PCD side.
+ *
+ * (C) 2005-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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <librfid/rfid.h>
+#include <librfid/rfid_protocol.h>
+#include <librfid/rfid_layer2.h>
+#include <librfid/rfid_layer2_icode1.h>
+#include <librfid/rfid_protocol_icode.h>
+
+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 (file)
index 0000000..0388baa
--- /dev/null
@@ -0,0 +1,141 @@
+
+/* UNFINISHED TI Tag-it implementation, PCD side.
+ *
+ * (C) 2005-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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <librfid/rfid.h>
+#include <librfid/rfid_protocol.h>
+#include <librfid/rfid_layer2.h>
+#include <librfid/rfid_layer2_iso15693.h>
+#include <librfid/rfid_protocol_tagit.h>
+
+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 */
index 9d70e90..71c52ff 100644 (file)
@@ -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 *
index 053b953..f51cd82 100644 (file)
@@ -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,
index 88c55ee..19ea7c2 100644 (file)
@@ -58,6 +58,14 @@ static struct openpcd_hdr *rcv_hdr;
 #include <usb.h>
 #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,
index b0676eb..b704e9b 100644 (file)
@@ -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,
index 12c3bd4..ec7fda0 100644 (file)
@@ -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");
index dab7db3..3e833a0 100644 (file)
@@ -1,6 +1,6 @@
 /* librfid-tool - a small command-line tool for librfid testing
  *
- * (C) 2005-2006 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2005-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 
 #include <librfid/rfid_layer2.h>
 #include <librfid/rfid_protocol.h>
 
+#include <librfid/rfid_layer2_iso14443a.h>
+#include <librfid/rfid_layer2_iso15693.h>
+
 #include <librfid/rfid_protocol_mifare_classic.h>
 #include <librfid/rfid_protocol_mifare_ul.h>
+#include <librfid/rfid_protocol_tagit.h>
+#include <librfid/rfid_protocol_icode.h>
 
 #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;
        }