/* Mifare Classic implementation, PCD side.
*
- * (C) 2005 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2005-2006 by Harald Welte <laforge@gnumonks.org>
*
*/
#include <string.h>
#include <errno.h>
-#include <rfid/rfid.h>
-#include <rfid/rfid_protocol.h>
-#include <rfid/rfid_layer2.h>
-#include <rfid/rfid_protocol_mifare_classic.h>
+#include <librfid/rfid.h>
+#include <librfid/rfid_protocol.h>
+#include <librfid/rfid_layer2.h>
+#include <librfid/rfid_protocol_mifare_classic.h>
-#include <rfid/rfid_reader.h>
+#include <librfid/rfid_reader.h>
#include "rfid_iso14443_common.h"
tx[0] = MIFARE_CL_CMD_READ;
tx[1] = page & 0xff;
- ret = ph->l2h->l2->fn.transcieve(ph->l2h, RFID_MIFARE_FRAME, tx,
- sizeof(tx), rx_buf, &real_rx_len,
- MIFARE_CL_READ_FWT, 0);
+ ret = rfid_layer2_transceive(ph->l2h, RFID_MIFARE_FRAME, tx,
+ sizeof(tx), rx_buf, &real_rx_len,
+ MIFARE_CL_READ_FWT, 0);
if (ret < 0)
return ret;
+ if (real_rx_len == 1 && *rx_buf == 0x04)
+ return -EPERM;
+
if (real_rx_len < *rx_len)
*rx_len = real_rx_len;
unsigned int rx_len;
int ret;
- if (tx_len != 16 || page > MIFARE_CL_PAGE_MAX)
+ if (page > MIFARE_CL_PAGE_MAX)
return -EINVAL;
- tx[0] = MIFARE_CL_CMD_WRITE16;
- tx[1] = page & 0xff;
+ if (tx_len != 16 && tx_len != 4)
+ return -EINVAL;
+
+ if (tx_len == 16) {
+ tx[0] = MIFARE_CL_CMD_WRITE16;
+ tx[1] = page & 0xff;
- memcpy(tx+2, tx_data, 16);
+ ret = rfid_layer2_transceive(ph->l2h, RFID_MIFARE_FRAME, tx,
+ 2, rx, &rx_len,
+ MIFARE_CL_WRITE_FWT, 0);
+ if (ret < 0)
+ return ret;
- ret = ph->l2h->l2->fn.transcieve(ph->l2h, RFID_MIFARE_FRAME, tx,
- sizeof(tx), rx, &rx_len,
- MIFARE_CL_WRITE_FWT, 0);
-
- if (ret < 0)
- return ret;
+ ret = rfid_layer2_transceive(ph->l2h, RFID_MIFARE_FRAME, tx_data,
+ tx_len, rx, &rx_len,
+ MIFARE_CL_WRITE_FWT, 0);
+ if (ret < 0)
+ return ret;
+
+ if (rx[0] != MIFARE_UL_RESP_ACK)
+ return -EIO;
+
+ ret = rfid_layer2_transceive(ph->l2h, RFID_MIFARE_FRAME, tx,
+ sizeof(tx), rx, &rx_len,
+ MIFARE_CL_WRITE_FWT, 0);
+ if (ret < 0)
+ return ret;
+
+ if (rx[0] != MIFARE_UL_RESP_ACK)
+ return -EIO;
- if (rx[0] != MIFARE_UL_RESP_ACK)
- return -EIO;
+ } else if (tx_len == 4) {
+
+ tx[0] = MIFARE_CL_CMD_WRITE4;
+ tx[1] = page & 0xff;
+
+ memcpy(tx+2, tx_data, 4);
+
+ ret = rfid_layer2_transceive(ph->l2h, RFID_MIFARE_FRAME, tx,
+ 2+4, rx, &rx_len,
+ MIFARE_CL_WRITE_FWT, 0);
+ if (ret < 0)
+ return ret;
+
+ if (rx[0] != MIFARE_UL_RESP_ACK)
+ return -EIO;
+
+ }
return ret;
}
mfcl_init(struct rfid_layer2_handle *l2h)
{
struct rfid_protocol_handle *ph;
- ph = malloc(sizeof(struct rfid_protocol_handle));
+
+ if (l2h->l2->id != RFID_LAYER2_ISO14443A)
+ return NULL;
+
+ if (l2h->uid_len != 4)
+ return NULL;
+
+ ph = malloc_protocol_handle(sizeof(struct rfid_protocol_handle));
return ph;
}
static int mfcl_fini(struct rfid_protocol_handle *ph)
{
- free(ph);
+ free_protocol_handle(ph);
return 0;
}
-struct rfid_protocol rfid_protocol_mfcl = {
+const struct rfid_protocol rfid_protocol_mfcl = {
.id = RFID_PROTOCOL_MIFARE_CLASSIC,
.name = "Mifare Classic",
.fn = {