* improve scanning support:
** first try REQA/HLTA/REQA/HLTA until no more tags found ** then power off the field and start from the beginning again * add proper RF field on/off switching support to all readers * reduce timer to actual value, don't multiply by 10 * detect collisions during transceive_sf (ATQA) * make UID length depend on cascade level, not ATQA git-svn-id: https://svn.gnumonks.org/trunk/librfid@2056 e0336214-984f-0b4b-a45f-81c69e1f0ede
This commit is contained in:
parent
6b2db45060
commit
c203de04bd
|
@ -33,8 +33,7 @@ struct rfid_asic_rc632 {
|
|||
struct {
|
||||
int (*power_up)(struct rfid_asic_handle *h);
|
||||
int (*power_down)(struct rfid_asic_handle *h);
|
||||
int (*turn_on_rf)(struct rfid_asic_handle *h);
|
||||
int (*turn_off_rf)(struct rfid_asic_handle *h);
|
||||
int (*rf_power)(struct rfid_asic_handle *h, int on);
|
||||
int (*transceive)(struct rfid_asic_handle *h,
|
||||
enum rfid_frametype,
|
||||
const u_int8_t *tx_buf,
|
||||
|
|
|
@ -35,6 +35,7 @@ struct rfid_reader {
|
|||
u_int64_t timeout, unsigned int flags);
|
||||
struct rfid_reader_handle * (*open)(void *data);
|
||||
void (*close)(struct rfid_reader_handle *h);
|
||||
int (*rf_power)(struct rfid_reader_handle *h, int on);
|
||||
|
||||
struct rfid_14443a_reader {
|
||||
int (*init)(struct rfid_reader_handle *h);
|
||||
|
|
|
@ -139,17 +139,17 @@ rc632_clear_bits(struct rfid_asic_handle *handle,
|
|||
}
|
||||
|
||||
static int
|
||||
rc632_turn_on_rf(struct rfid_asic_handle *handle)
|
||||
rc632_rf_power(struct rfid_asic_handle *handle, int on)
|
||||
{
|
||||
ENTER();
|
||||
return rc632_set_bits(handle, RC632_REG_TX_CONTROL, 0x03);
|
||||
}
|
||||
|
||||
static int
|
||||
rc632_turn_off_rf(struct rfid_asic_handle *handle)
|
||||
{
|
||||
ENTER();
|
||||
return rc632_clear_bits(handle, RC632_REG_TX_CONTROL, 0x03);
|
||||
if (on)
|
||||
return rc632_set_bits(handle, RC632_REG_TX_CONTROL,
|
||||
RC632_TXCTRL_TX1_RF_EN|
|
||||
RC632_TXCTRL_TX2_RF_EN);
|
||||
else
|
||||
return rc632_clear_bits(handle, RC632_REG_TX_CONTROL,
|
||||
RC632_TXCTRL_TX1_RF_EN|
|
||||
RC632_TXCTRL_TX2_RF_EN);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -375,7 +375,7 @@ rc632_transceive(struct rfid_asic_handle *handle,
|
|||
else
|
||||
cur_tx_len = tx_len;
|
||||
|
||||
ret = rc632_timer_set(handle, timer*10);
|
||||
ret = rc632_timer_set(handle, timer);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -566,14 +566,14 @@ rc632_init(struct rfid_asic_handle *ah)
|
|||
return ret;
|
||||
|
||||
/* switch off rf */
|
||||
ret = rc632_turn_off_rf(ah);
|
||||
ret = rc632_rf_power(ah, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
usleep(100000);
|
||||
|
||||
/* switch on rf */
|
||||
ret = rc632_turn_on_rf(ah);
|
||||
ret = rc632_rf_power(ah, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -586,7 +586,7 @@ rc632_fini(struct rfid_asic_handle *ah)
|
|||
int ret;
|
||||
|
||||
/* switch off rf */
|
||||
ret = rc632_turn_off_rf(ah);
|
||||
ret = rc632_rf_power(ah, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -746,7 +746,7 @@ rc632_iso14443a_fini(struct iso14443a_handle *handle_14443)
|
|||
{
|
||||
|
||||
#if 0
|
||||
ret = rc632_turn_off_rf(handle);
|
||||
ret = rc632_rf_power(handle, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
#endif
|
||||
|
@ -765,6 +765,7 @@ rc632_iso14443a_transceive_sf(struct rfid_asic_handle *handle,
|
|||
int ret;
|
||||
u_int8_t tx_buf[1];
|
||||
u_int8_t rx_len = 2;
|
||||
u_int8_t error_flag;
|
||||
|
||||
memset(atqa, 0, sizeof(*atqa));
|
||||
|
||||
|
@ -805,6 +806,21 @@ rc632_iso14443a_transceive_sf(struct rfid_asic_handle *handle,
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* determine whether there was a collission */
|
||||
ret = rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &error_flag);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (error_flag & RC632_ERR_FLAG_COL_ERR) {
|
||||
u_int8_t boc;
|
||||
/* retrieve bit of collission */
|
||||
ret = rc632_reg_read(handle, RC632_REG_COLL_POS, &boc);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
DEBUGP("collision detected in xcv_sf: bit_of_col=%u\n", boc);
|
||||
/* FIXME: how to signal this up the stack */
|
||||
}
|
||||
|
||||
if (rx_len != 2) {
|
||||
DEBUGP("rx_len(%d) != 2\n", rx_len);
|
||||
return -1;
|
||||
|
@ -1617,8 +1633,7 @@ const struct rfid_asic rc632 = {
|
|||
.fn = {
|
||||
.power_up = &rc632_power_up,
|
||||
.power_down = &rc632_power_down,
|
||||
.turn_on_rf = &rc632_turn_on_rf,
|
||||
.turn_off_rf = &rc632_turn_off_rf,
|
||||
.rf_power = &rc632_rf_power,
|
||||
.transceive = &rc632_iso14443ab_transceive,
|
||||
.iso14443a = {
|
||||
.init = &rc632_iso14443a_init,
|
||||
|
|
|
@ -237,13 +237,10 @@ cascade:
|
|||
}
|
||||
}
|
||||
|
||||
h->level = ISO14443A_LEVEL_NONE;
|
||||
h->state = ISO14443A_STATE_SELECTED;
|
||||
|
||||
{
|
||||
if (uid_size == 1)
|
||||
if (h->level == ISO14443A_LEVEL_CL1)
|
||||
handle->uid_len = 4;
|
||||
else if (uid_size == 2)
|
||||
else if (h->level == ISO14443A_LEVEL_CL2)
|
||||
handle->uid_len = 7;
|
||||
else
|
||||
handle->uid_len = 10;
|
||||
|
@ -251,6 +248,9 @@ cascade:
|
|||
DEBUGP("UID %s\n", rfid_hexdump(handle->uid, handle->uid_len));
|
||||
}
|
||||
|
||||
h->level = ISO14443A_LEVEL_NONE;
|
||||
h->state = ISO14443A_STATE_SELECTED;
|
||||
|
||||
if (sak[0] & 0x20) {
|
||||
DEBUGP("we have a T=CL compliant PICC\n");
|
||||
handle->proto_supported = 1 << RFID_PROTOCOL_TCL;
|
||||
|
|
|
@ -288,6 +288,12 @@ cm5121_mifare_auth(struct rfid_reader_handle *rh, u_int8_t cmd,
|
|||
cmd, serno, block);
|
||||
}
|
||||
|
||||
static int
|
||||
cm5121_rf_power(struct rfid_reader_handle *rh, int on)
|
||||
{
|
||||
return rh->ah->asic->priv.rc632.fn.rf_power(rh->ah, on);
|
||||
}
|
||||
|
||||
struct rfid_asic_transport cm5121_ccid = {
|
||||
.name = "CM5121 OpenCT",
|
||||
.priv.rc632 = {
|
||||
|
@ -364,6 +370,7 @@ const struct rfid_reader rfid_reader_cm5121 = {
|
|||
.name = "Omnikey CardMan 5121 RFID",
|
||||
.open = &cm5121_open,
|
||||
.close = &cm5121_close,
|
||||
.rf_power = &cm5121_rf_power,
|
||||
.transceive = &cm5121_transceive,
|
||||
.l2_supported = (1 << RFID_LAYER2_ISO14443A) |
|
||||
(1 << RFID_LAYER2_ISO14443B) |
|
||||
|
|
|
@ -438,6 +438,12 @@ openpcd_mifare_auth(struct rfid_reader_handle *rh, u_int8_t cmd,
|
|||
cmd, serno, block);
|
||||
}
|
||||
|
||||
static void
|
||||
openpcd_rf_power(struct rfid_reader_handle *rh, int on)
|
||||
{
|
||||
return rh->ah->asic->priv.rc632.fn.rf_power(rh->ah, on);
|
||||
}
|
||||
|
||||
static struct rfid_reader_handle *
|
||||
openpcd_open(void *data)
|
||||
{
|
||||
|
@ -527,6 +533,7 @@ const struct rfid_reader rfid_reader_openpcd = {
|
|||
.id = RFID_READER_OPENPCD,
|
||||
.open = &openpcd_open,
|
||||
.close = &openpcd_close,
|
||||
.rf_power = &openpcd_rf_power,
|
||||
|
||||
#ifndef LIBRFID_FIRMWARE
|
||||
.get_api_version = &openpcd_get_api_version,
|
||||
|
|
|
@ -274,6 +274,11 @@ spidev_mifare_auth(struct rfid_reader_handle *rh, u_int8_t cmd,
|
|||
cmd, serno,
|
||||
block);
|
||||
}
|
||||
static int
|
||||
spidev_rf_power(struct rfid_reader_handle *rh, int on)
|
||||
{
|
||||
return rh->ah->asic->priv.rc632.fn.rf_power(rh->ah, on);
|
||||
}
|
||||
|
||||
static struct rfid_reader_handle *spidev_open(void *data)
|
||||
{
|
||||
|
@ -363,6 +368,7 @@ struct rfid_reader rfid_reader_spidev = {
|
|||
.id = RFID_READER_SPIDEV,
|
||||
.open = &spidev_open,
|
||||
.close = &spidev_close,
|
||||
.rf_power = &spidev_rf_power,
|
||||
.transceive = &spidev_transceive,
|
||||
.l2_supported = (1 << RFID_LAYER2_ISO14443A) |
|
||||
(1 << RFID_LAYER2_ISO14443B) |
|
||||
|
|
|
@ -260,12 +260,17 @@ static int l2_by_name(const char *name)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void do_scan(void)
|
||||
static int do_scan(int first)
|
||||
{
|
||||
int rc;
|
||||
unsigned int size;
|
||||
unsigned int size_len = sizeof(size);
|
||||
|
||||
if (first) {
|
||||
rh->reader->rf_power(rh, 0);
|
||||
usleep(10*1000);
|
||||
rh->reader->rf_power(rh, 1);
|
||||
}
|
||||
printf("scanning for RFID token...\n");
|
||||
rc = rfid_scan(rh, &l2h, &ph);
|
||||
if (rc >= 2) {
|
||||
|
@ -283,6 +288,31 @@ static void do_scan(void)
|
|||
&size, &size_len) == 0)
|
||||
printf("Size: %u bytes\n", size);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void do_endless_scan()
|
||||
{
|
||||
int rc;
|
||||
int first = 1;
|
||||
|
||||
while (1) {
|
||||
if (first)
|
||||
putc('\n', stdout);
|
||||
printf("==> doing %s scan\n", first ? "first" : "successive");
|
||||
rc = do_scan(first);
|
||||
if (rc >= 3) {
|
||||
printf("closing proto\n");
|
||||
rfid_protocol_close(ph);
|
||||
}
|
||||
if (rc >= 2) {
|
||||
printf("closing layer2\n");
|
||||
rfid_layer2_close(l2h);
|
||||
first = 0;
|
||||
} else
|
||||
first = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#define OPTION_OFFSET 256
|
||||
|
@ -399,14 +429,13 @@ int main(int argc, char **argv)
|
|||
case 's':
|
||||
if (reader_init() < 0)
|
||||
exit(1);
|
||||
do_scan();
|
||||
do_scan(0);
|
||||
exit(0);
|
||||
break;
|
||||
case 'S':
|
||||
if (reader_init() < 0)
|
||||
exit(1);
|
||||
while (1)
|
||||
do_scan();
|
||||
do_endless_scan();
|
||||
exit(0);
|
||||
break;
|
||||
case 'p':
|
||||
|
|
Loading…
Reference in New Issue