X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=src%2Frfid_proto_mifare_classic.c;h=a6e2e4f7fe66e6d6d57bb82016fcb5f5cfb896ab;hb=893a580c6f1c7f1cc50d9bd1acc51c9fd6307a17;hp=e98dc28e33a3e193de34c225a2902b46e84f724e;hpb=683a381a3ef8d2c1c1f0c47337808d6a72e1309f;p=librfid diff --git a/src/rfid_proto_mifare_classic.c b/src/rfid_proto_mifare_classic.c index e98dc28..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,8 +78,7 @@ 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[18]; + unsigned char tx[2]; unsigned char rx[1]; unsigned int rx_len = sizeof(rx); int ret; @@ -88,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,8 +114,10 @@ mfcl_getopt(struct rfid_protocol_handle *ph, int optname, void *optval, unsigned int *optlen) { int ret = -EINVAL; - u_int16_t atqa; + 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,10 +127,16 @@ mfcl_getopt(struct rfid_protocol_handle *ph, int optname, void *optval, *optlen = sizeof(*size); ret = 0; rfid_layer2_getopt(ph->l2h, RFID_OPT_14443A_ATQA, - (void *) &atqa, &atqa_size); - if (atqa == 0x0004) - *size = 1024; - else if (atqa == 0x0002) + atqa, &atqa_size); + 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; @@ -210,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); @@ -220,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; +}