summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/rc632.h6
-rw-r--r--src/rfid_asic_rc632.c17
-rw-r--r--src/rfid_layer2.c33
-rw-r--r--src/rfid_layer2_iso14443a.c21
-rw-r--r--src/rfid_proto_mifare_classic.c12
-rw-r--r--src/rfid_proto_mifare_ul.c12
-rw-r--r--src/rfid_proto_tcl.c45
-rw-r--r--src/rfid_reader_cm5121.c36
9 files changed, 145 insertions, 39 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index fe219b7..dbc608f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,5 +1,5 @@
LIBVERSION= 0:0:0
-INCLUDES = $(all_includes) -I$(top_srcdir)/include
+INCLUDES = $(all_includes) -I$(top_srcdir)/include -D__LIBRFID__
lib_LTLIBRARIES = librfid.la
diff --git a/src/rc632.h b/src/rc632.h
index 4ad0e99..0bd5b00 100644
--- a/src/rc632.h
+++ b/src/rc632.h
@@ -116,13 +116,9 @@ enum rc632_reg_coder_control {
RC632_CDRCTRL_TXCD_14443A = 0x01,
RC632_CDRCTRL_TXCD_ICODE_STD = 0x04,
+#define RC632_CDRDTRL_RATE_MASK 0x38
RC632_CDRCTRL_RATE_848K = 0x00,
-#if 0
- /* See mc073930.pdf, page 41 */
- RC632_CDRCTRL_RATE_424K = 0x80,
-#else
RC632_CDRCTRL_RATE_424K = 0x08,
-#endif
RC632_CDRCTRL_RATE_212K = 0x10,
RC632_CDRCTRL_RATE_106K = 0x18,
RC632_CDRCTRL_RATE_14443B = 0x20,
diff --git a/src/rfid_asic_rc632.c b/src/rfid_asic_rc632.c
index 4377d73..e794a38 100644
--- a/src/rfid_asic_rc632.c
+++ b/src/rfid_asic_rc632.c
@@ -739,6 +739,22 @@ rc632_iso14443a_transcieve_acf(struct rfid_asic_handle *handle,
return 0;
}
+static int rc632_iso14443a_set_speed(struct rfid_asic_handle *handle,
+ u_int8_t rate)
+{
+ int rc;
+ u_int8_t reg;
+
+ rc = rc632_reg_read(handle, RC632_REG_CODER_CONTROL, &reg);
+ if (rc < 0)
+ return rc;
+
+ reg &= ~RC632_CDRDTRL_RATE_MASK;
+ reg |= (rate & RC632_CDRDTRL_RATE_MASK);
+
+ return rc632_reg_write(handle, RC632_REG_CODER_CONTROL, reg);
+}
+
static int rc632_iso14443b_init(struct rfid_asic_handle *handle)
{
int ret;
@@ -1279,6 +1295,7 @@ struct rfid_asic rc632 = {
.init = &rc632_iso14443a_init,
.transcieve_sf = &rc632_iso14443a_transcieve_sf,
.transcieve_acf = &rc632_iso14443a_transcieve_acf,
+ .set_speed = &rc632_iso14443a_set_speed,
},
.iso14443b = {
.init = &rc632_iso14443b_init,
diff --git a/src/rfid_layer2.c b/src/rfid_layer2.c
index c1ab6a6..01443d8 100644
--- a/src/rfid_layer2.c
+++ b/src/rfid_layer2.c
@@ -19,6 +19,7 @@
#include <stdlib.h>
#include <stdio.h>
+#include <errno.h>
#include <rfid/rfid.h>
#include <rfid/rfid_layer2.h>
@@ -41,6 +42,9 @@ rfid_layer2_init(struct rfid_reader_handle *rh, unsigned int id)
int
rfid_layer2_open(struct rfid_layer2_handle *ph)
{
+ if (!ph->l2->fn.open)
+ return 0;
+
return ph->l2->fn.open(ph);
}
@@ -51,18 +55,27 @@ rfid_layer2_transcieve(struct rfid_layer2_handle *ph,
unsigned char *rx_buf, unsigned int *rx_len,
u_int64_t timeout, unsigned int flags)
{
+ if (!ph->l2->fn.transcieve)
+ return -EIO;
+
return ph->l2->fn.transcieve(ph, frametype, tx_buf, len, rx_buf,
rx_len, timeout, flags);
}
int rfid_layer2_fini(struct rfid_layer2_handle *ph)
{
+ if (!ph->l2->fn.fini)
+ return 0;
+
return ph->l2->fn.fini(ph);
}
int
rfid_layer2_close(struct rfid_layer2_handle *ph)
{
+ if (!ph->l2->fn.close)
+ return 0;
+
return ph->l2->fn.close(ph);
}
@@ -74,3 +87,23 @@ rfid_layer2_register(struct rfid_layer2 *p)
return 0;
}
+
+int
+rfid_layer2_getopt(struct rfid_layer2_handle *ph, int optname,
+ void *optval, unsigned int *optlen)
+{
+ if (!ph->l2->fn.getopt)
+ return -EINVAL;
+
+ return ph->l2->fn.getopt(ph, optname, optval, optlen);
+}
+
+int
+rfid_layer2_setopt(struct rfid_layer2_handle *ph, int optname,
+ const void *optval, unsigned int optlen)
+{
+ if (!ph->l2->fn.setopt)
+ return -EINVAL;
+
+ return ph->l2->fn.setopt(ph, optname, optval, optlen);
+}
diff --git a/src/rfid_layer2_iso14443a.c b/src/rfid_layer2_iso14443a.c
index d93f917..d33b316 100644
--- a/src/rfid_layer2_iso14443a.c
+++ b/src/rfid_layer2_iso14443a.c
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#include <errno.h>
#include <rfid/rfid.h>
#include <rfid/rfid_layer2.h>
@@ -250,6 +251,25 @@ iso14443a_hlta(struct rfid_layer2_handle *handle)
return -1;
}
+static int
+iso14443a_setopt(struct rfid_layer2_handle *handle, int optname,
+ const void *optval, unsigned int optlen)
+{
+ int ret = -EINVAL;
+ struct rfid_reader *rdr = handle->rh->reader;
+ unsigned int speed;
+
+ switch (optname) {
+ case RFID_OPT_14443A_SPEED:
+ speed = *(unsigned int *)optval;
+ ret = rdr->iso14443a.set_speed(handle->rh, speed);
+ break;
+ };
+
+ return ret;
+}
+
+
static struct rfid_layer2_handle *
iso14443a_init(struct rfid_reader_handle *rh)
{
@@ -289,6 +309,7 @@ struct rfid_layer2 rfid_layer2_iso14443a = {
.transcieve = &iso14443a_transcieve,
.close = &iso14443a_hlta,
.fini = &iso14443a_fini,
+ .setopt = &iso14443a_setopt,
},
};
diff --git a/src/rfid_proto_mifare_classic.c b/src/rfid_proto_mifare_classic.c
index 99386a1..d6de606 100644
--- a/src/rfid_proto_mifare_classic.c
+++ b/src/rfid_proto_mifare_classic.c
@@ -57,9 +57,9 @@ mfcl_read(struct rfid_protocol_handle *ph, unsigned int page,
tx[0] = MIFARE_CL_CMD_READ;
tx[1] = page & 0xff;
- ret = ph->l2h->l2->fn.transcieve(ph->l2h, RFID_MIFARE_FRAME, tx,
- sizeof(tx), rx_buf, &real_rx_len,
- MIFARE_CL_READ_FWT, 0);
+ ret = rfid_layer2_transcieve(ph->l2h, RFID_MIFARE_FRAME, tx,
+ sizeof(tx), rx_buf, &real_rx_len,
+ MIFARE_CL_READ_FWT, 0);
if (ret < 0)
return ret;
@@ -93,9 +93,9 @@ mfcl_write(struct rfid_protocol_handle *ph, unsigned int page,
memcpy(tx+2, tx_data, 16);
- ret = ph->l2h->l2->fn.transcieve(ph->l2h, RFID_MIFARE_FRAME, tx,
- sizeof(tx), rx, &rx_len,
- MIFARE_CL_WRITE_FWT, 0);
+ ret = rfid_layer2_transcieve(ph->l2h, RFID_MIFARE_FRAME, tx,
+ sizeof(tx), rx, &rx_len,
+ MIFARE_CL_WRITE_FWT, 0);
if (ret < 0)
return ret;
diff --git a/src/rfid_proto_mifare_ul.c b/src/rfid_proto_mifare_ul.c
index 9e5363f..7649b99 100644
--- a/src/rfid_proto_mifare_ul.c
+++ b/src/rfid_proto_mifare_ul.c
@@ -52,9 +52,9 @@ mful_read(struct rfid_protocol_handle *ph, unsigned int page,
tx[0] = MIFARE_UL_CMD_READ;
tx[1] = page & 0xff;
- ret = ph->l2h->l2->fn.transcieve(ph->l2h, RFID_14443A_FRAME_REGULAR,
- tx, sizeof(tx), rx_buf,
- &real_rx_len, MIFARE_UL_READ_FWT, 0);
+ ret = rfid_layer2_transcieve(ph->l2h, RFID_14443A_FRAME_REGULAR,
+ tx, sizeof(tx), rx_buf,
+ &real_rx_len, MIFARE_UL_READ_FWT, 0);
if (ret < 0)
return ret;
@@ -86,9 +86,9 @@ mful_write(struct rfid_protocol_handle *ph, unsigned int page,
for (i = 0; i < 4; i++)
tx[2+i] = tx_data[i];
- ret = ph->l2h->l2->fn.transcieve(ph->l2h, RFID_14443A_FRAME_REGULAR,
- tx, sizeof(tx), rx, &rx_len,
- MIFARE_UL_WRITE_FWT, 0);
+ ret = rfid_layer2_transcieve(ph->l2h, RFID_14443A_FRAME_REGULAR,
+ tx, sizeof(tx), rx, &rx_len,
+ MIFARE_UL_WRITE_FWT, 0);
if (ret < 0)
return ret;
diff --git a/src/rfid_proto_tcl.c b/src/rfid_proto_tcl.c
index f070614..2be20d9 100644
--- a/src/rfid_proto_tcl.c
+++ b/src/rfid_proto_tcl.c
@@ -40,6 +40,9 @@
#ifdef DEBUGP
#undef DEBUGP
#define DEBUGP(x, ...)
+#endif
+#ifdef DEBUGPC
+#undef DEBUGPC
#define DEBUGPC(x, ...)
#endif
#endif
@@ -185,10 +188,10 @@ tcl_request_ats(struct rfid_protocol_handle *h)
rats[1] = (h->priv.tcl.cid & 0x0f) | ((fsdi << 4) & 0xf0);
/* transcieve (with CRC) */
- ret = h->l2h->l2->fn.transcieve(h->l2h, RFID_14443A_FRAME_REGULAR,
- rats, 2, h->priv.tcl.ats,
- &h->priv.tcl.ats_len, activation_fwt(h),
- TCL_TRANSP_F_TX_CRC);
+ ret = rfid_layer2_transcieve(h->l2h, RFID_14443A_FRAME_REGULAR,
+ rats, 2, h->priv.tcl.ats,
+ &h->priv.tcl.ats_len, activation_fwt(h),
+ TCL_TRANSP_F_TX_CRC);
if (ret < 0) {
DEBUGP("transcieve of rats failed\n");
h->priv.tcl.state = TCL_STATE_RATS_SENT;
@@ -219,11 +222,11 @@ static unsigned char d_to_di(struct rfid_protocol_handle *h, unsigned char D)
static char DI;
unsigned int speed = h->l2h->rh->reader->iso14443a.speed;
- if ((D & ATS_TA_DIV_8) && (speed & RFID_READER_SPEED_848K))
+ if ((D & ATS_TA_DIV_8) && (speed & RFID_14443A_SPEED_848K))
DI = PPS_DIV_8;
- else if ((D & ATS_TA_DIV_4) && (speed & RFID_READER_SPEED_424K))
+ else if ((D & ATS_TA_DIV_4) && (speed & RFID_14443A_SPEED_424K))
DI = PPS_DIV_4;
- else if ((D & ATS_TA_DIV_2) && (speed & RFID_READER_SPEED_212K))
+ else if ((D & ATS_TA_DIV_2) && (speed & RFID_14443A_SPEED_212K))
DI = PPS_DIV_2;
else
DI = PPS_DIV_1;
@@ -232,16 +235,17 @@ static unsigned char d_to_di(struct rfid_protocol_handle *h, unsigned char D)
}
-/* start a PSS run (autimatically configure highest possible speed */
+/* start a PPS run (autimatically configure highest possible speed */
static int
tcl_do_pps(struct rfid_protocol_handle *h)
{
-#if 0
+#if 1
int ret;
unsigned char ppss[3];
unsigned char pps_response[1];
unsigned int rx_len = 1;
unsigned char Dr, Ds, DrI, DsI;
+ unsigned int optlen = 0;
if (h->priv.tcl.state != TCL_STATE_ATS_RCVD)
return -1;
@@ -257,7 +261,7 @@ tcl_do_pps(struct rfid_protocol_handle *h)
/* ISO 14443-4:2000(E) Section 5.3. */
- ppss[0] = 0xd0 & (h->priv.tcl.cid & 0x0f);
+ ppss[0] = 0xd0 | (h->priv.tcl.cid & 0x0f);
ppss[1] = 0x11;
/* FIXME: deal with different speed for each direction */
@@ -266,9 +270,9 @@ tcl_do_pps(struct rfid_protocol_handle *h)
ppss[2] = (ppss[2] & 0xf0) | (DrI | DsI << 2);
- ret = h->l2h->l2->fn.transcieve(h->l2h, ppss, 3, pps_response,
- &rx_len, h->priv.tcl.fwt,
- TCL_TRANSP_F_TX_CRC);
+ ret = rfid_layer2_transcieve(h->l2h, RFID_14443A_FRAME_REGULAR,
+ ppss, 3, pps_response, &rx_len,
+ h->priv.tcl.fwt, TCL_TRANSP_F_TX_CRC);
if (ret < 0)
return ret;
@@ -276,6 +280,11 @@ tcl_do_pps(struct rfid_protocol_handle *h)
DEBUGP("PPS Response != PPSS\n");
return -1;
}
+
+ ret = rfid_layer2_setopt(h->l2h, RFID_OPT_14443A_SPEED,
+ NULL, &optlen);
+ if (ret < 0)
+ return ret;
h->priv.tcl.state = TCL_STATE_ESTABLISHED;
#endif
@@ -453,8 +462,8 @@ tcl_deselect(struct rfid_protocol_handle *h)
if (ret < 0)
return ret;
- ret = h->l2h->l2->fn.transcieve(h->l2h, RFID_14443A_FRAME_REGULAR,
- frame, prlg_len, rx,
+ ret = rfid_layer2_transcieve(h->l2h, RFID_14443A_FRAME_REGULAR,
+ frame, prlg_len, rx,
&rx_len, deactivation_fwt(h),
TCL_TRANSP_F_TX_CRC);
if (ret < 0) {
@@ -522,9 +531,9 @@ tcl_transcieve(struct rfid_protocol_handle *h,
*rx_len = 0;
do_tx:
- ret = h->l2h->l2->fn.transcieve(h->l2h, l2_to_frame(h->l2h->l2->id),
- _tx, _tx_len,
- rx_buf, &_rx_len, _timeout, 0);
+ ret = rfid_layer2_transcieve(h->l2h, l2_to_frame(h->l2h->l2->id),
+ _tx, _tx_len,
+ rx_buf, &_rx_len, _timeout, 0);
DEBUGP("l2 transcieve finished\n");
if (ret < 0)
goto out_rxb;
diff --git a/src/rfid_reader_cm5121.c b/src/rfid_reader_cm5121.c
index 978e18f..f2a8b9a 100644
--- a/src/rfid_reader_cm5121.c
+++ b/src/rfid_reader_cm5121.c
@@ -30,6 +30,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#include <errno.h>
#include <rfid/rfid.h>
#include <rfid/rfid_reader.h>
@@ -37,11 +38,14 @@
#include <rfid/rfid_asic_rc632.h>
#include <rfid/rfid_reader_cm5121.h>
+/* FIXME */
+#include "rc632.h"
+
//#define SENDBUF_LEN 40
#define SENDBUF_LEN 100
#define RECVBUF_LEN 40
-#if 1
+#if 0
#ifdef DEBUGP
#undef DEBUGP
#define DEBUGP(x, ...)
@@ -215,6 +219,31 @@ cm5121_14443a_init(struct rfid_reader_handle *rh)
}
static int
+cm5121_14443a_set_speed(struct rfid_reader_handle *rh, unsigned int speed)
+{
+ u_int8_t rate;
+
+ switch (speed) {
+ case RFID_14443A_SPEED_106K:
+ rate = RC632_CDRCTRL_RATE_106K;
+ break;
+ case RFID_14443A_SPEED_212K:
+ rate = RC632_CDRCTRL_RATE_212K;
+ break;
+ case RFID_14443A_SPEED_424K:
+ rate = RC632_CDRCTRL_RATE_424K;
+ break;
+ case RFID_14443A_SPEED_848K:
+ rate = RC632_CDRCTRL_RATE_848K;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ return rh->ah->asic->priv.rc632.fn.iso14443a.set_speed(rh->ah, rate);
+}
+
+static int
cm5121_14443b_init(struct rfid_reader_handle *rh)
{
return rh->ah->asic->priv.rc632.fn.iso14443b.init(rh->ah);
@@ -322,8 +351,9 @@ struct rfid_reader rfid_reader_cm5121 = {
.init = &cm5121_14443a_init,
.transcieve_sf = &cm5121_transcieve_sf,
.transcieve_acf = &cm5121_transcieve_acf,
- .speed = RFID_READER_SPEED_106K | RFID_READER_SPEED_212K |
- RFID_READER_SPEED_424K | RFID_READER_SPEED_848K,
+ .speed = RFID_14443A_SPEED_106K | RFID_14443A_SPEED_212K |
+ RFID_14443A_SPEED_424K | RFID_14443A_SPEED_848K,
+ .set_speed = &cm5121_14443a_set_speed,
},
.iso14443b = {
.init = &cm5121_14443b_init,
personal git repositories of Harald Welte. Your mileage may vary