From c203de04bd740e324b06615b98932ac9fa734ed2 Mon Sep 17 00:00:00 2001 From: laforge Date: Sun, 27 Jan 2008 02:15:48 +0000 Subject: * 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 --- src/rfid_asic_rc632.c | 47 ++++++++++++++++++++++++++++++--------------- src/rfid_layer2_iso14443a.c | 10 +++++----- src/rfid_reader_cm5121.c | 7 +++++++ src/rfid_reader_openpcd.c | 7 +++++++ src/rfid_reader_spidev.c | 6 ++++++ 5 files changed, 56 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/rfid_asic_rc632.c b/src/rfid_asic_rc632.c index 61af0ac..b8d8db3 100644 --- a/src/rfid_asic_rc632.c +++ b/src/rfid_asic_rc632.c @@ -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, diff --git a/src/rfid_layer2_iso14443a.c b/src/rfid_layer2_iso14443a.c index 9bdd25a..148960d 100644 --- a/src/rfid_layer2_iso14443a.c +++ b/src/rfid_layer2_iso14443a.c @@ -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; diff --git a/src/rfid_reader_cm5121.c b/src/rfid_reader_cm5121.c index 383fba2..053b953 100644 --- a/src/rfid_reader_cm5121.c +++ b/src/rfid_reader_cm5121.c @@ -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) | diff --git a/src/rfid_reader_openpcd.c b/src/rfid_reader_openpcd.c index 67b73b6..88c55ee 100644 --- a/src/rfid_reader_openpcd.c +++ b/src/rfid_reader_openpcd.c @@ -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, diff --git a/src/rfid_reader_spidev.c b/src/rfid_reader_spidev.c index e546380..b0676eb 100644 --- a/src/rfid_reader_spidev.c +++ b/src/rfid_reader_spidev.c @@ -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) | -- cgit v1.2.3