/* Generic Philips CL RC632 Routines
*
- * (C) Harald Welte <laforge@gnumonks.org>
+ * (C) 2005-2006 Harald Welte <laforge@gnumonks.org>
*
*/
#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
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++) {
}
/* 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;
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);
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;
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");
}
return rc632_fifo_read(handle, *rx_len, rx_buf);
+ /* FIXME: discard addidional bytes in FIFO */
}
static int
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)
{
struct rfid_asic_handle *h;
- h = malloc(sizeof(*h));
+ h = malloc_asic_handle(sizeof(*h));
if (!h)
return NULL;
memset(h, 0, sizeof(*h));
h->mtu = h->mru = 64;
if (rc632_init(h) < 0) {
- free(h);
+ free_asic_handle(h);
return NULL;
}
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>
*
*/
// 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 |
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;
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) {
};
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;
// 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;
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;
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;
//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;
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);
ret = rc632_reg_read(h, RC632_REG_SECONDARY_STATUS, ®);
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,
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 */
return 0;
}
-struct rfid_asic rc632 = {
+const struct rfid_asic rc632 = {
.name = "Philips CL RC632",
.fc = ISO14443_FREQ_CARRIER,
.priv.rc632 = {