summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile5
-rw-r--r--TODO4
-rw-r--r--include/rfid/rfid_asic_rc632.h3
-rw-r--r--include/rfid/rfid_layer2.h3
-rw-r--r--include/rfid/rfid_layer2_iso15693.h48
-rw-r--r--include/rfid/rfid_reader.h2
-rw-r--r--rfid_asic_rc632.c252
-rw-r--r--rfid_layer2_iso15693.c302
-rw-r--r--rfid_reader_cm5121.c6
9 files changed, 622 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index bcf5f44..ac1ca50 100644
--- a/Makefile
+++ b/Makefile
@@ -3,9 +3,12 @@ LDFLAGS:=-lopenct -lusb
all: openct-escape
-openct-escape: openct-escape.o rfid_layer2.o rfid_layer2_iso14443a.o rfid_layer2_iso14443b.o rfid_asic_rc632.o rfid_reader_cm5121.o rfid.o rfid_protocol.o rfid_proto_tcl.o rfid_iso14443_common.o rfid_reader.o
+openct-escape: openct-escape.o librfid.a
$(CC) $(LDFLAGS) -o $@ $^
+librfid.a: rfid_layer2.o rfid_layer2_iso14443a.o rfid_layer2_iso14443b.o rfid_layer2_iso15693.o rfid_asic_rc632.o rfid_reader_cm5121.o rfid.o rfid_protocol.o rfid_proto_tcl.o rfid_iso14443_common.o rfid_reader.o
+ ar r $@ $^
+
%.o: %.c
$(CC) $(CFLAGS) -o $@ -c $^
diff --git a/TODO b/TODO
index d8045ea..6c94530 100644
--- a/TODO
+++ b/TODO
@@ -11,6 +11,10 @@ iso14443b:
- implement 'option 2' frame markers
- test anticollission (need multiple tags)
+iso15693:
+- implement anticollision
+- implement all the rest
+
tcl:
- test chaining
- implement + test pps
diff --git a/include/rfid/rfid_asic_rc632.h b/include/rfid/rfid_asic_rc632.h
index f4c9fa1..4aabde2 100644
--- a/include/rfid/rfid_asic_rc632.h
+++ b/include/rfid/rfid_asic_rc632.h
@@ -51,6 +51,9 @@ struct rfid_asic_rc632 {
struct {
int (*init)(struct rfid_asic_handle *h);
} iso14443b;
+ struct {
+ int (*init)(struct rfid_asic_handle *h);
+ } iso15693;
} fn;
};
diff --git a/include/rfid/rfid_layer2.h b/include/rfid/rfid_layer2.h
index 40b9bff..975022a 100644
--- a/include/rfid/rfid_layer2.h
+++ b/include/rfid/rfid_layer2.h
@@ -6,6 +6,7 @@ struct rfid_reader_handle;
#include <rfid/rfid_layer2_iso14443a.h>
#include <rfid/rfid_layer2_iso14443b.h>
+#include <rfid/rfid_layer2_iso15693.h>
struct rfid_layer2 {
@@ -31,7 +32,7 @@ struct rfid_layer2_handle {
union {
struct iso14443a_handle iso14443a;
struct iso14443b_handle iso14443b;
- //struct iso15693_handle iso15693;
+ struct iso15693_handle iso15693;
} priv;
struct rfid_layer2 *l2;
};
diff --git a/include/rfid/rfid_layer2_iso15693.h b/include/rfid/rfid_layer2_iso15693.h
new file mode 100644
index 0000000..b418ccd
--- /dev/null
+++ b/include/rfid/rfid_layer2_iso15693.h
@@ -0,0 +1,48 @@
+#ifndef _RFID_ISO15693_H
+#define _RFID_ISO15693_H
+
+#include <sys/types.h>
+
+/* protocol definitions */
+
+struct iso15693_handle;
+
+struct iso15693_transport {
+ unsigned char *name;
+
+ struct {
+ int (*init)(struct iso15693_handle *handle);
+ int (*fini)(struct iso15693_handle *handle);
+
+#if 0
+ int (*transcieve_sf)(struct iso14443a_handle *handle,
+ unsigned char cmd,
+ struct iso14443a_atqa *atqa);
+ int (*transcieve_acf)(struct iso14443a_handle *handle,
+ struct iso14443a_anticol_cmd *acf,
+ unsigned int *bit_of_col);
+#endif
+ int (*transcieve)(struct iso15693_handle *handle,
+ const unsigned char *tx_buf,
+ unsigned int tx_len,
+ unsigned char *rx_buf,
+ unsigned int *rx_len);
+ } fn;
+
+ union {
+ } priv;
+};
+
+struct iso15693_handle {
+ unsigned int state;
+};
+
+enum iso15693_state {
+ ISO15693_STATE_ERROR,
+ ISO15693_STATE_NONE,
+};
+
+#include <rfid/rfid_layer2.h>
+extern struct rfid_layer2 rfid_layer2_iso15693;
+
+#endif /* _ISO15693_H */
diff --git a/include/rfid/rfid_reader.h b/include/rfid/rfid_reader.h
index 11f2ca1..5f6c314 100644
--- a/include/rfid/rfid_reader.h
+++ b/include/rfid/rfid_reader.h
@@ -31,7 +31,7 @@ struct rfid_reader {
unsigned int speed;
} iso14443b;
struct rfid_15693_reader {
-
+ int (*init)(struct rfid_reader_handle *rh);
} iso15693;
struct rfid_reader *next;
};
diff --git a/rfid_asic_rc632.c b/rfid_asic_rc632.c
index 234e7ab..b77050f 100644
--- a/rfid_asic_rc632.c
+++ b/rfid_asic_rc632.c
@@ -830,6 +830,255 @@ 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;
+
+ ret = rc632_reg_write(h, RC632_REG_RX_THRESHOLD, 0xff);
+ 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_AUTO_PD |
+ RC632_RXCTRL2_DECSRC_INT));
+ if (ret < 0)
+ return ret;
+
+ 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;
+
+ ret = rc632_reg_write(h, RC632_REG_CRC_PRESET_LSB, 0xff);
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_reg_write(h, RC632_REG_CRC_PRESET_MSB, 0xff);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int
+rc632_iso15693_icode_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, 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;
+
+ ret = rc632_reg_write(h, RC632_REG_CRC_PRESET_MSB, 0xff);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int
+rc632_iso15693_icl_init(struct rfid_asic_handle *h)
+{
+ int ret;
+
+ /* ICL */
+
+ 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, 0x11);
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_reg_write(h, RC632_REG_CODER_CONTROL,
+ (RC632_CDRCTRL_RATE_15693 |
+ RC632_CDRCTRL_TXCD_ICODE_STD |
+ 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_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_RX_INVERT|
+ RC632_DECCTRL_RXFR_15693));
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_reg_write(h, RC632_REG_BIT_PHASE, 0xbd);
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_reg_write(h, RC632_REG_RX_THRESHOLD, 0xff);
+ 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, 0x00);
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_reg_write(h, RC632_REG_CRC_PRESET_LSB, 0x12);
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_reg_write(h, RC632_REG_CRC_PRESET_MSB, 0xe0);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
struct rfid_asic rc632 = {
.name = "Philips CL RC632",
@@ -848,6 +1097,9 @@ struct rfid_asic rc632 = {
.fn.iso14443b = {
.init = &rc632_iso14443b_init,
},
+ .fn.iso15693 = {
+ .init = &rc632_iso15693_init,
+ },
},
};
diff --git a/rfid_layer2_iso15693.c b/rfid_layer2_iso15693.c
new file mode 100644
index 0000000..2c9eb3b
--- /dev/null
+++ b/rfid_layer2_iso15693.c
@@ -0,0 +1,302 @@
+/* ISO 15693 anticollision implementation
+ *
+ * (C) 2005 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <rfid/rfid.h>
+#include <rfid/rfid_layer2.h>
+#include <rfid/rfid_reader.h>
+#include <rfid/rfid_layer2_iso15693.h>
+
+#if 0
+/* Transcieve a 7-bit short frame */
+static int
+iso14443a_transcieve_sf(struct rfid_layer2_handle *handle,
+ unsigned char cmd,
+ struct iso14443a_atqa *atqa)
+{
+ struct rfid_reader *rdr = handle->rh->reader;
+
+ return rdr->iso14443a.transcieve_sf(handle->rh, cmd, atqa);
+}
+
+/* Transmit an anticollission bit frame */
+static int
+iso14443a_transcieve_acf(struct rfid_layer2_handle *handle,
+ struct iso14443a_anticol_cmd *acf,
+ unsigned int *bit_of_col)
+{
+ struct rfid_reader *rdr = handle->rh->reader;
+
+ return rdr->iso14443a.transcieve_acf(handle->rh, acf, bit_of_col);
+}
+
+/* Transmit a regular frame */
+static int
+iso14443a_transcieve(struct rfid_layer2_handle *handle,
+ const unsigned char *tx_buf, unsigned int tx_len,
+ unsigned char *rx_buf, unsigned int *rx_len,
+ unsigned int timeout, unsigned int flags)
+{
+ return handle->rh->reader->transcieve(handle->rh, tx_buf, tx_len,
+ rx_buf, rx_len, timeout, flags);
+}
+
+static int
+iso14443a_code_nvb_bits(unsigned char *nvb, unsigned int bits)
+{
+ unsigned int byte_count = bits / 8;
+ unsigned int bit_count = bits % 8;
+
+ if (byte_count < 2 || byte_count > 7)
+ return -1;
+
+ *nvb = ((byte_count & 0xf) << 4) | bit_count;
+
+ return 0;
+}
+
+/* first bit is '1', second bit '2' */
+static void
+set_bit_in_field(unsigned char *bitfield, unsigned int bit)
+{
+ unsigned int byte_count = bit / 8;
+ unsigned int bit_count = bit % 8;
+
+ DEBUGP("bitfield=%p, byte_count=%u, bit_count=%u\n",
+ bitfield, byte_count, bit_count);
+ DEBUGP("%p = 0x%02x\n", (bitfield+byte_count), *(bitfield+byte_count));
+ *(bitfield+byte_count) |= 1 << (bit_count-1);
+ DEBUGP("%p = 0x%02x\n", (bitfield+byte_count), *(bitfield+byte_count));
+}
+
+static int
+iso14443a_anticol(struct rfid_layer2_handle *handle)
+{
+ int ret;
+ unsigned int uid_size;
+ struct iso14443a_atqa atqa;
+ struct iso14443a_anticol_cmd acf;
+ unsigned int bit_of_col;
+ unsigned char sak[3];
+ unsigned char uid[10]; // triple size equals 10 bytes;
+ unsigned int rx_len = sizeof(sak);
+ char *aqptr = (char *) &atqa;
+ static int first = 0;
+
+ memset(uid, 0, sizeof(uid));
+ memset(sak, 0, sizeof(sak));
+ memset(&atqa, 0, sizeof(atqa));
+ memset(&acf, 0, sizeof(acf));
+
+ if (first == 0) {
+ DEBUGP("Sending REQA\n");
+ ret = iso14443a_transcieve_sf(handle, ISO14443A_SF_CMD_REQA, &atqa);
+ first = 1;
+ } else {
+ DEBUGP("Sending WUPA\n");
+ ret = iso14443a_transcieve_sf(handle, ISO14443A_SF_CMD_WUPA, &atqa);
+ }
+
+ if (ret < 0) {
+ handle->priv.iso14443a.state = ISO14443A_STATE_REQA_SENT;
+ DEBUGP("error during transcieve_sf: %d\n", ret);
+ return ret;
+ }
+ handle->priv.iso14443a.state = ISO14443A_STATE_ATQA_RCVD;
+
+ DEBUGP("ATQA: 0x%02x 0x%02x\n", *aqptr, *(aqptr+1));
+
+ if (!atqa.bf_anticol) {
+ handle->priv.iso14443a.state =ISO14443A_STATE_NO_BITFRAME_ANTICOL;
+ DEBUGP("no bitframe anticollission bits set, aborting\n");
+ return -1;
+ }
+
+ if (atqa.uid_size == 2 || atqa.uid_size == 3)
+ uid_size = 3;
+ else if (atqa.uid_size == 1)
+ uid_size = 2;
+ else
+ uid_size = 1;
+
+ acf.sel_code = ISO14443A_AC_SEL_CODE_CL1;
+
+ handle->priv.iso14443a.state = ISO14443A_STATE_ANTICOL_RUNNING;
+ handle->priv.iso14443a.level = ISO14443A_LEVEL_CL1;
+
+cascade:
+ iso14443a_code_nvb_bits(&acf.nvb, 16);
+
+ ret = iso14443a_transcieve_acf(handle, &acf, &bit_of_col);
+ if (ret < 0)
+ return ret;
+ DEBUGP("bit_of_col = %u\n", bit_of_col);
+
+ while (bit_of_col != ISO14443A_BITOFCOL_NONE) {
+ set_bit_in_field(&acf.uid_bits[0], bit_of_col-16);
+ iso14443a_code_nvb_bits(&acf.nvb, bit_of_col);
+ ret = iso14443a_transcieve_acf(handle, &acf, &bit_of_col);
+ DEBUGP("bit_of_col = %u\n", bit_of_col);
+ if (ret < 0)
+ return ret;
+ }
+
+ iso14443a_code_nvb_bits(&acf.nvb, 7*8);
+ ret = iso14443a_transcieve(handle, (unsigned char *)&acf, 7,
+ (unsigned char *) &sak, &rx_len,
+ TIMEOUT, 0);
+ if (ret < 0)
+ return ret;
+
+ if (sak[0] & 0x04) {
+ /* Cascade bit set, UID not complete */
+ switch (acf.sel_code) {
+ case ISO14443A_AC_SEL_CODE_CL1:
+ /* cascading from CL1 to CL2 */
+ if (acf.uid_bits[0] != 0x88) {
+ DEBUGP("Cascade bit set, but UID0 != 0x88\n");
+ return -1;
+ }
+ memcpy(&uid[0], &acf.uid_bits[1], 3);
+ acf.sel_code = ISO14443A_AC_SEL_CODE_CL2;
+ handle->priv.iso14443a.level = ISO14443A_LEVEL_CL2;
+ break;
+ case ISO14443A_AC_SEL_CODE_CL2:
+ /* cascading from CL2 to CL3 */
+ memcpy(&uid[3], &acf.uid_bits[1], 3);
+ acf.sel_code = ISO14443A_AC_SEL_CODE_CL3;
+ handle->priv.iso14443a.level = ISO14443A_LEVEL_CL3;
+ break;
+ default:
+ DEBUGP("cannot cascade any further than CL3\n");
+ handle->priv.iso14443a.state = ISO14443A_STATE_ERROR;
+ return -1;
+ break;
+ }
+ goto cascade;
+
+ } else {
+ switch (acf.sel_code) {
+ case ISO14443A_AC_SEL_CODE_CL1:
+ /* single size UID (4 bytes) */
+ memcpy(&uid[0], &acf.uid_bits[0], 4);
+ break;
+ case ISO14443A_AC_SEL_CODE_CL2:
+ /* double size UID (7 bytes) */
+ memcpy(&uid[3], &acf.uid_bits[0], 4);
+ break;
+ case ISO14443A_AC_SEL_CODE_CL3:
+ /* triple size UID (10 bytes) */
+ memcpy(&uid[6], &acf.uid_bits[0], 4);
+ break;
+ }
+ }
+
+ handle->priv.iso14443a.level = ISO14443A_LEVEL_NONE;
+ handle->priv.iso14443a.state = ISO14443A_STATE_SELECTED;
+
+ {
+ int uid_len;
+ if (uid_size == 1)
+ uid_len = 4;
+ else if (uid_size == 2)
+ uid_len = 7;
+ else
+ uid_len = 10;
+
+ DEBUGP("UID %s\n", rfid_hexdump(uid, uid_len));
+ }
+
+ if (sak[0] & 0x20) {
+ DEBUGP("we have a T=CL compliant PICC\n");
+ handle->priv.iso14443a.tcl_capable = 1;
+ } else {
+ DEBUGP("we have a T!=CL PICC\n");
+ handle->priv.iso14443a.tcl_capable = 0;
+ }
+
+ return 0;
+}
+
+static int
+iso14443a_hlta(struct rfid_layer2_handle *handle)
+{
+ int ret;
+ unsigned char tx_buf[2] = { 0x50, 0x00 };
+ unsigned char rx_buf[10];
+ unsigned int rx_len = sizeof(rx_buf);
+
+ return 0;
+
+ ret = iso14443a_transcieve(handle, tx_buf, sizeof(tx_buf),
+ rx_buf, &rx_len, 1000 /* 1ms */, 0);
+ if (ret < 0) {
+ /* "error" case: we don't get somethng back from the card */
+ return 0;
+ }
+ return -1;
+}
+#endif
+
+static struct rfid_layer2_handle *
+iso15693_init(struct rfid_reader_handle *rh)
+{
+ int ret;
+ struct rfid_layer2_handle *h = malloc(sizeof(*h));
+ if (!h)
+ return NULL;
+
+ h->l2 = &rfid_layer2_iso15693;
+ h->rh = rh;
+ h->priv.iso15693.state = ISO15693_STATE_NONE;
+
+ ret = h->rh->reader->iso15693.init(h->rh);
+ if (ret < 0) {
+ free(h);
+ return NULL;
+ }
+
+ return h;
+}
+
+static int
+iso15693_fini(struct rfid_layer2_handle *handle)
+{
+ free(handle);
+ return 0;
+}
+
+
+struct rfid_layer2 rfid_layer2_iso15693 = {
+ .id = RFID_LAYER2_ISO15693,
+ .name = "ISO 15693",
+ .fn = {
+ .init = &iso15693_init,
+ //.open = &iso15693_anticol,
+ //.transcieve = &iso15693_transcieve,
+ //.close = &iso14443a_hlta,
+ .fini = &iso15693_fini,
+ },
+};
+
diff --git a/rfid_reader_cm5121.c b/rfid_reader_cm5121.c
index a916c82..d77192c 100644
--- a/rfid_reader_cm5121.c
+++ b/rfid_reader_cm5121.c
@@ -210,6 +210,12 @@ cm5121_14443b_init(struct rfid_reader_handle *rh)
return rh->ah->asic->priv.rc632.fn.iso14443b.init(rh->ah);
}
+static int
+cm5121_15693_init(struct rfid_reader_handle *rh)
+{
+ return rh->ah->asic->priv.rc632.fn.iso15693.init(rh->ah);
+}
+
struct rfid_asic_transport cm5121_ccid = {
.name = "CM5121 OpenCT",
personal git repositories of Harald Welte. Your mileage may vary