Simplify compile options (either --enable-ccid or --enable-openct implies --enable...
[librfid] / src / rfid_asic_rc632.c
index 666c69e..0d6824c 100644 (file)
@@ -1,6 +1,6 @@
 /* Generic Philips CL RC632 Routines
  *
- * (C) Harald Welte <laforge@gnumonks.org>
+ * (C) 2005-2006 Harald Welte <laforge@gnumonks.org>
  *
  */
 
@@ -23,6 +23,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#include <limits.h>
 #include <sys/types.h>
 
 #include <librfid/rfid.h>
 //#include "rc632_14443a.h"
 
 
-#define RC632_TMO_AUTH1        14000
+#define RC632_TMO_AUTH1        140
 
 #define ENTER()                DEBUGP("entering\n")
-struct rfid_asic rc632;
+const struct rfid_asic rc632;
 
 /* Register and FIFO Access functions */
 static int 
@@ -171,7 +172,7 @@ static int best_prescaler(u_int64_t timeout, u_int8_t *prescaler,
        u_int8_t best_prescaler, best_divisor, i;
        int64_t smallest_diff;
 
-       smallest_diff = 0x7fffffffffffffff;
+       smallest_diff = LLONG_MAX;
        best_prescaler = 0;
 
        for (i = 0; i < 21; i++) {
@@ -232,7 +233,7 @@ rc632_timer_set(struct rfid_asic_handle *handle,
 }
 
 /* Wait until RC632 is idle or TIMER IRQ has happened */
-static rc632_wait_idle_timer(struct rfid_asic_handle *handle)
+static int rc632_wait_idle_timer(struct rfid_asic_handle *handle)
 {
        int ret;
        u_int8_t irq, cmd;
@@ -362,6 +363,7 @@ rc632_transceive(struct rfid_asic_handle *handle,
                 unsigned int toggle)
 {
        int ret, cur_tx_len;
+       u_int8_t rx_avail;
        const u_int8_t *cur_tx_buf = tx_buf;
 
        DEBUGP("timer = %u\n", timer);
@@ -400,7 +402,7 @@ 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);
+                       //printf("refilling tx fifo with %u bytes\n", cur_tx_len);
                } else
                        cur_tx_len = 0;
 
@@ -414,11 +416,16 @@ rc632_transceive(struct rfid_asic_handle *handle,
        if (ret < 0)
                return ret;
 
-       ret = rc632_reg_read(handle, RC632_REG_FIFO_LENGTH, rx_len);
+       ret = rc632_reg_read(handle, RC632_REG_FIFO_LENGTH, &rx_avail);
        if (ret < 0)
                return ret;
 
-       if (*rx_len == 0) {
+       if (rx_avail > *rx_len) {
+               //printf("rx_avail(%d) > rx_len(%d), JFYI\n", rx_avail, *rx_len);
+       } else if (*rx_len > rx_avail)
+               *rx_len = rx_avail;
+
+       if (rx_avail == 0) {
                u_int8_t tmp;
 
                DEBUGP("rx_len == 0\n");
@@ -430,6 +437,7 @@ rc632_transceive(struct rfid_asic_handle *handle,
        }
 
        return rc632_fifo_read(handle, *rx_len, rx_buf);
+       /* FIXME: discard addidional bytes in FIFO */
 }
 
 static int
@@ -558,6 +566,13 @@ rc632_init(struct rfid_asic_handle *ah)
        if (ret < 0)
                return ret;
 
+       /* switch off rf */
+       ret = rc632_turn_off_rf(ah);
+       if (ret < 0)
+               return ret;
+
+       usleep(100000);
+
        /* switch on rf */
        ret = rc632_turn_on_rf(ah);
        if (ret < 0)
@@ -588,7 +603,7 @@ rc632_open(struct rfid_asic_transport_handle *th)
 {
        struct rfid_asic_handle *h;
 
-       h = malloc(sizeof(*h));
+       h = malloc_asic_handle(sizeof(*h));
        if (!h)
                return NULL;
        memset(h, 0, sizeof(*h));
@@ -601,7 +616,7 @@ rc632_open(struct rfid_asic_transport_handle *th)
        h->mtu = h->mru = 64;
 
        if (rc632_init(h) < 0) {
-               free(h);
+               free_asic_handle(h);
                return NULL;
        }
 
@@ -612,14 +627,14 @@ void
 rc632_close(struct rfid_asic_handle *h)
 {
        rc632_fini(h);
-       free(h);
+       free_asic_handle(h);
 }
 
 
 /* 
  * Philips CL RC632 primitives for ISO 14443-A compliant PICC's
  *
- * (C) 2005 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2005-2006 by Harald Welte <laforge@gnumonks.org>
  *
  */
 
@@ -631,7 +646,8 @@ rc632_iso14443a_init(struct rfid_asic_handle *handle)
        // FIXME: some fifo work (drain fifo?)
        
        /* flush fifo (our way) */
-       ret = rc632_reg_write(handle, RC632_REG_CONTROL, 0x01);
+       ret = rc632_reg_write(handle, RC632_REG_CONTROL,
+                             RC632_CONTROL_FIFO_FLUSH);
 
        ret = rc632_reg_write(handle, RC632_REG_TX_CONTROL,
                        (RC632_TXCTRL_TX1_RF_EN |
@@ -751,7 +767,7 @@ rc632_iso14443a_transceive_sf(struct rfid_asic_handle *handle,
        u_int8_t tx_buf[1];
        u_int8_t rx_len = 2;
 
-       memset(atqa, 0, sizeof(atqa));
+       memset(atqa, 0, sizeof(*atqa));
 
        tx_buf[0] = cmd;
 
@@ -807,9 +823,14 @@ rc632_iso14443ab_transceive(struct rfid_asic_handle *handle,
                           u_int64_t timeout, unsigned int flags)
 {
        int ret;
-       u_int8_t rxl = *rx_len & 0xff;
+       u_int8_t rxl;
        u_int8_t channel_red;
 
+       if (*rx_len > 0xff)
+               rxl = 0xff;
+       else
+               rxl = *rx_len;
+
        memset(rx_buf, 0, *rx_len);
 
        switch (frametype) {
@@ -990,8 +1011,7 @@ static struct tx_config tx_configs[] = {
 };
 
 static int rc632_iso14443a_set_speed(struct rfid_asic_handle *handle,
-                                    unsigned int tx,
-                                    u_int8_t rate)
+                                    unsigned int tx, unsigned int rate)
 {
        int rc;
        u_int8_t reg;
@@ -1053,7 +1073,8 @@ static int rc632_iso14443b_init(struct rfid_asic_handle *handle)
        // FIXME: some FIFO work
        
        /* flush fifo (our way) */
-       ret = rc632_reg_write(handle, RC632_REG_CONTROL, 0x01);
+       ret = rc632_reg_write(handle, RC632_REG_CONTROL,
+                             RC632_CONTROL_FIFO_FLUSH);
        if (ret < 0)
                return ret;
 
@@ -1441,6 +1462,11 @@ rc632_mifare_set_key(struct rfid_asic_handle *h, const u_int8_t *key)
        if (ret < 0)
                return ret;
 
+       /* Terminate probably running command */
+       ret = rc632_reg_write(h, RC632_REG_COMMAND, RC632_CMD_IDLE);    
+       if (ret < 0)
+               return ret;
+
        ret = rc632_fifo_write(h, RFID_MIFARE_KEY_CODED_LEN, coded_key, 0x03);
        if (ret < 0)
                return ret;
@@ -1471,8 +1497,10 @@ rc632_mifare_auth(struct rfid_asic_handle *h, u_int8_t cmd, u_int32_t serno,
        struct mifare_authcmd acmd;
        u_int8_t reg;
 
-       if (cmd != RFID_CMD_MIFARE_AUTH1A && cmd != RFID_CMD_MIFARE_AUTH1B)
+       if (cmd != RFID_CMD_MIFARE_AUTH1A && cmd != RFID_CMD_MIFARE_AUTH1B) {
+               DEBUGP("invalid auth command\n");
                return -EINVAL;
+       }
 
        /* Initialize acmd */
        acmd.block_address = block & 0xff;
@@ -1480,9 +1508,16 @@ rc632_mifare_auth(struct rfid_asic_handle *h, u_int8_t cmd, u_int32_t serno,
        //acmd.serno = htonl(serno);
        acmd.serno = serno;
 
+#if 1
        /* Clear Rx CRC */
        ret = rc632_clear_bits(h, RC632_REG_CHANNEL_REDUNDANCY,
                                RC632_CR_RX_CRC_ENABLE);
+#else
+       /* Clear Rx CRC, Set Tx CRC and Odd Parity */
+       ret = rc632_reg_write(h, RC632_REG_CHANNEL_REDUNDANCY,
+                               RC632_CR_TX_CRC_ENABLE | RC632_CR_PARITY_ODD |
+                               RC632_CR_PARITY_ENABLE);
+#endif
        if (ret < 0)
                return ret;
 
@@ -1492,8 +1527,10 @@ rc632_mifare_auth(struct rfid_asic_handle *h, u_int8_t cmd, u_int32_t serno,
                return ret;
 
        ret = rc632_reg_write(h, RC632_REG_COMMAND, RC632_CMD_AUTHENT1);
-       if (ret < 0)
+       if (ret < 0) {
+               DEBUGP("error during AUTHENT1");
                return ret;
+       }
 
        /* Wait until transmitter is idle */
        ret = rc632_wait_idle(h, RC632_TMO_AUTH1);
@@ -1503,8 +1540,10 @@ rc632_mifare_auth(struct rfid_asic_handle *h, u_int8_t cmd, u_int32_t serno,
        ret = rc632_reg_read(h, RC632_REG_SECONDARY_STATUS, &reg);
        if (ret < 0)
                return ret;
-       if (reg & 0x07)
+       if (reg & 0x07) {
+               DEBUGP("bitframe?");
                return -EIO;
+       }
 
        /* Clear Tx CRC */
        ret = rc632_clear_bits(h, RC632_REG_CHANNEL_REDUNDANCY,
@@ -1527,11 +1566,12 @@ rc632_mifare_auth(struct rfid_asic_handle *h, u_int8_t cmd, u_int32_t serno,
        if (ret < 0)
                return ret;
 
-       if (!(reg & RC632_CONTROL_CRYPTO1_ON))
+       if (!(reg & RC632_CONTROL_CRYPTO1_ON)) {
+               DEBUGP("authentication not successful");
                return -EACCES;
+       }
 
        return 0;
-
 }
 
 /* transceive regular frame */
@@ -1569,7 +1609,7 @@ rc632_mifare_transceive(struct rfid_asic_handle *handle,
        return 0; 
 }
 
-struct rfid_asic rc632 = {
+const struct rfid_asic rc632 = {
        .name   = "Philips CL RC632",
        .fc     = ISO14443_FREQ_CARRIER,
        .priv.rc632 = {