From 5fc01ff6f98d72219420bc29fb59d2d6eb93e887 Mon Sep 17 00:00:00 2001 From: laforge Date: Sat, 22 Oct 2005 20:20:21 +0000 Subject: - add mifare classic support - move uid/pupi from l2 private data into l2 global data - various cleanups git-svn-id: https://svn.gnumonks.org/trunk/librfid@1555 e0336214-984f-0b4b-a45f-81c69e1f0ede --- rfid_proto_mifare_classic.c | 144 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 rfid_proto_mifare_classic.c (limited to 'rfid_proto_mifare_classic.c') diff --git a/rfid_proto_mifare_classic.c b/rfid_proto_mifare_classic.c new file mode 100644 index 0000000..474f554 --- /dev/null +++ b/rfid_proto_mifare_classic.c @@ -0,0 +1,144 @@ + +/* Mifare Classic implementation, PCD side. + * + * (C) 2005 by Harald Welte + * + */ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include + +#include +#include +#include +//#include + +//#include +#include + +#include "rfid_iso14443_common.h" + + +#define MIFARE_UL_CMD_WRITE 0xA2 +#define MIFARE_UL_CMD_READ 0x30 + +/* FIXME */ +#define MIFARE_UL_READ_FWT 100 +#define MIFARE_UL_WRITE_FWT 100 + +static int +mfcl_read(struct rfid_protocol_handle *ph, unsigned int page, + unsigned char *rx_data, unsigned int *rx_len) +{ + unsigned char rx_buf[16]; + unsigned int real_rx_len = sizeof(rx_buf); + unsigned char tx[2]; + int ret; + + if (page > 7) + return -EINVAL; + + tx[0] = MIFARE_UL_CMD_READ; + tx[1] = page & 0xff; + + ret = ph->l2h->l2->fn.transcieve(ph->l2h, tx, sizeof(tx), rx_buf, + &real_rx_len, MIFARE_UL_READ_FWT, 0); + + if (ret < 0) + return ret; + + if (real_rx_len < *rx_len) + *rx_len = real_rx_len; + + memcpy(rx_data, rx_buf, *rx_len); + + return ret; +} + +static int +mfcl_write(struct rfid_protocol_handle *ph, unsigned int page, + unsigned char *tx_data, unsigned int tx_len) +{ + unsigned int i; + unsigned char tx[6]; + unsigned char rx[1]; + unsigned int rx_len; + int ret; + + if (tx_len != 4 || page > 7) + return -EINVAL; + + tx[0] = MIFARE_UL_CMD_WRITE; + tx[1] = page & 0xff; + + for (i = 0; i < 4; i++) + tx[2+i] = tx_data[i]; + + ret = ph->l2h->l2->fn.transcieve(ph->l2h, tx, sizeof(tx), rx, + &rx_len, MIFARE_UL_WRITE_FWT, 0); + + /* FIXME:look at RX, check for ACK/NAK */ + + return ret; +} + +static struct rfid_protocol_handle * +mfcl_init(struct rfid_layer2_handle *l2h) +{ + struct rfid_protocol_handle *ph; + ph = malloc(sizeof(struct rfid_protocol_handle)); + return ph; +} + +static int mfcl_fini(struct rfid_protocol_handle *ph) +{ + free(ph); + return 0; +} + +struct rfid_protocol rfid_protocol_mfcl = { + .id = RFID_PROTOCOL_MIFARE_CLASSIC, + .name = "Mifare Classic", + .fn = { + .init = &mfcl_init, + .read = &mfcl_read, + .write = &mfcl_write, + .fini = &mfcl_fini, + }, +}; + +int mfcl_set_key(struct rfid_protocol_handle *ph, unsigned char *key) +{ + if (!ph->l2h->rh->reader->mifare_classic.setkey) + return -ENODEV; + + return ph->l2h->rh->reader->mifare_classic.setkey(ph->l2h->rh, key); +} + +int mfcl_auth(struct rfid_protocol_handle *ph, u_int8_t cmd, u_int8_t block) +{ + u_int32_t serno = *((u_int32_t *)ph->l2h->uid); + + if (!ph->l2h->rh->reader->mifare_classic.auth) + return -ENODEV; + + return ph->l2h->rh->reader->mifare_classic.auth(ph->l2h->rh, cmd, + serno, block); +} -- cgit v1.2.3