X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=src%2Frfid_proto_mifare_classic.c;h=a6e2e4f7fe66e6d6d57bb82016fcb5f5cfb896ab;hb=893a580c6f1c7f1cc50d9bd1acc51c9fd6307a17;hp=004e00267bb93692848471193062bd766f471faf;hpb=237c7f9e9d0aad3a9830498a9bdb5fe5dd94df9e;p=librfid diff --git a/src/rfid_proto_mifare_classic.c b/src/rfid_proto_mifare_classic.c index 004e002..a6e2e4f 100644 --- a/src/rfid_proto_mifare_classic.c +++ b/src/rfid_proto_mifare_classic.c @@ -1,7 +1,7 @@ /* Mifare Classic implementation, PCD side. * - * (C) 2005-2006 by Harald Welte + * (C) 2005-2008 by Harald Welte * */ @@ -17,7 +17,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include @@ -38,9 +38,8 @@ #define MIFARE_UL_CMD_WRITE 0xA2 #define MIFARE_UL_CMD_READ 0x30 -/* FIXME */ -#define MIFARE_CL_READ_FWT 100 -#define MIFARE_CL_WRITE_FWT 100 +#define MIFARE_CL_READ_FWT 250 +#define MIFARE_CL_WRITE_FWT 600 static int mfcl_read(struct rfid_protocol_handle *ph, unsigned int page, @@ -79,7 +78,7 @@ static int mfcl_write(struct rfid_protocol_handle *ph, unsigned int page, unsigned char *tx_data, unsigned int tx_len) { - unsigned char tx[18]; + unsigned char tx[2]; unsigned char rx[1]; unsigned int rx_len = sizeof(rx); int ret; @@ -87,54 +86,25 @@ mfcl_write(struct rfid_protocol_handle *ph, unsigned int page, if (page > MIFARE_CL_PAGE_MAX) return -EINVAL; - if (tx_len != 16 && tx_len != 4) + if (tx_len != 16) return -EINVAL; - if (tx_len == 16) { - tx[0] = MIFARE_CL_CMD_WRITE16; - tx[1] = page & 0xff; - - 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 = 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; - - } else if (tx_len == 4) { - - tx[0] = MIFARE_CL_CMD_WRITE4; - tx[1] = page & 0xff; - - memcpy(tx+2, tx_data, 4); + tx[0] = MIFARE_CL_CMD_WRITE16; + tx[1] = page & 0xff; - 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; + ret = rfid_layer2_transceive(ph->l2h, RFID_MIFARE_FRAME, tx, 2, 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_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; return ret; } @@ -145,7 +115,9 @@ mfcl_getopt(struct rfid_protocol_handle *ph, int optname, void *optval, { int ret = -EINVAL; u_int8_t atqa[2]; + u_int8_t sak; unsigned int atqa_size = sizeof(atqa); + unsigned int sak_size = sizeof(sak); unsigned int *size = optval; switch (optname) { @@ -156,9 +128,15 @@ mfcl_getopt(struct rfid_protocol_handle *ph, int optname, void *optval, ret = 0; rfid_layer2_getopt(ph->l2h, RFID_OPT_14443A_ATQA, atqa, &atqa_size); - if (atqa[0] == 0x04 && atqa[1] == 0x00) - *size = 1024; - else if (atqa[0] == 0x02 && atqa[1] == 0x00) + rfid_layer2_getopt(ph->l2h, RFID_OPT_14443A_SAK, + &sak, &sak_size); + if (atqa[0] == 0x04 && atqa[1] == 0x00) { + if (sak == 0x09) { + /* mifare mini */ + *size = 320; + } else + *size = 1024; + } else if (atqa[0] == 0x02 && atqa[1] == 0x00) *size = 4096; else ret = -EIO; @@ -209,6 +187,14 @@ int mfcl_set_key(struct rfid_protocol_handle *ph, unsigned char *key) return ph->l2h->rh->reader->mifare_classic.setkey(ph->l2h->rh, key); } +int mfcl_set_key_ee(struct rfid_protocol_handle *ph, unsigned int addr) +{ + if (!ph->l2h->rh->reader->mifare_classic.setkey_ee) + return -ENODEV; + + return ph->l2h->rh->reader->mifare_classic.setkey_ee(ph->l2h->rh, addr); +} + 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); @@ -219,3 +205,33 @@ int mfcl_auth(struct rfid_protocol_handle *ph, u_int8_t cmd, u_int8_t block) return ph->l2h->rh->reader->mifare_classic.auth(ph->l2h->rh, cmd, serno, block); } + +int mfcl_block2sector(u_int8_t block) +{ + if (block < MIFARE_CL_SMALL_SECTORS * MIFARE_CL_BLOCKS_P_SECTOR_1k) + return block/MIFARE_CL_BLOCKS_P_SECTOR_1k; + else + return (block - MIFARE_CL_SMALL_SECTORS * MIFARE_CL_BLOCKS_P_SECTOR_1k) + / MIFARE_CL_BLOCKS_P_SECTOR_4k; +} + +int mfcl_sector2block(u_int8_t sector) +{ + if (sector < MIFARE_CL_SMALL_SECTORS) + return sector * MIFARE_CL_BLOCKS_P_SECTOR_1k; + else if (sector < MIFARE_CL_SMALL_SECTORS + MIFARE_CL_LARGE_SECTORS) + return MIFARE_CL_SMALL_SECTORS * MIFARE_CL_BLOCKS_P_SECTOR_1k + + (sector - MIFARE_CL_SMALL_SECTORS) * MIFARE_CL_BLOCKS_P_SECTOR_4k; + else + return -EINVAL; +} + +int mfcl_sector_blocks(u_int8_t sector) +{ + if (sector < MIFARE_CL_SMALL_SECTORS) + return MIFARE_CL_BLOCKS_P_SECTOR_1k; + else if (sector < MIFARE_CL_SMALL_SECTORS + MIFARE_CL_LARGE_SECTORS) + return MIFARE_CL_BLOCKS_P_SECTOR_4k; + else + return -EINVAL; +}