From: Harald Welte Date: Wed, 25 Oct 2006 23:33:06 +0000 (+0000) Subject: some preliminary work to get 15693 working (actual implementation still missing) X-Git-Url: http://git.rot13.org/?p=librfid;a=commitdiff_plain;h=6d7eb8fc5c759ec2b69659e78fb3c0f0a0c0d6b0;hp=fab4ed032c451c0e2e95754a8a031219dc24c2ab some preliminary work to get 15693 working (actual implementation still missing) git-svn-id: https://svn.gnumonks.org/trunk/librfid@1916 e0336214-984f-0b4b-a45f-81c69e1f0ede --- diff --git a/include/librfid/rfid_layer2_iso15693.h b/include/librfid/rfid_layer2_iso15693.h index 37d204d..f84a6e1 100644 --- a/include/librfid/rfid_layer2_iso15693.h +++ b/include/librfid/rfid_layer2_iso15693.h @@ -49,7 +49,94 @@ enum iso15693_state { ISO15693_STATE_NONE, }; +#ifdef __LIBRFID__ + +#define ISO15693_UID_LEN 8 +#define ISO15693_CRC_LEN 2 + +/* ISO 15693-3, Ch. 7.2 Table 3*/ +enum iso15693_request_flags { + RFID_15693_F_SUBC_TWO = 0x01, + RFID_15693_F_RATE_HIGH = 0x02, + RFID_15693_F_INV_TABLE_5 = 0x04, + RFID_15693_F_PROT_OEXT = 0x08, +}; + +/* ISO 15693-3, Ch. 7.2 Table 4 */ +enum iso15693_request_flags_table4 { + RFID_15693_F4_SELECTED = 0x10, /* only VICC in 'select' state */ + RFID_15693_F4_ADDRESS = 0x20, /* request is addressed */ + RFID_15693_F4_CUSTOM = 0x40, +}; + +/* ISO 15693-3, Ch. 7.2 Table 5 */ +enum iso15693_request_flags_table5 { + RFID_15693_F5_AFI_PRES = 0x10, /* AFI is present */ + RFID_15693_F5_NSLOTS_1 = 0x20, /* only 1 slot (instead of 16) */ + RFID_15693_F5_CUSTOM = 0x40, +}; + +/* ISO 15963-3, Ch. 7.2 Figure 4 */ +struct iso15693_request { + u_int8_t flags; + u_int8_t command; + u_int8_t data[0]; +} __attribute__ ((packed)); + + + +/* ISO 15693, Ch. 7.3 Table 6 */ +enum iso15693_response_flags { + RFID_15693_RF_ERROR = 0x01, + RFID_15693_RF_EXTENDED = 0x08, +}; + +/* ISO 15693, Ch. 7.3.2 Table 7 */ +enum iso15693_response_errors { + RFID_15693_ERR_NOTSUPP = 0x01, + RFID_15693_ERR_INVALID = 0x02, /* command not recognized */ + RFID_15693_ERR_UNKNOWN = 0x0f, /* unknown error */ + RFID_15693_ERR_BLOCK_NA = 0x10, /* block not available */ + RFID_15693_ERR_BLOCK_LOCKED = 0x11, + RFID_15693_ERR_BLOCK_LOCKED_CH = 0x12, + RFID_15693_ERR_BLOCK_NOTPROG = 0x13, + RFID_15693_ERR_BLOCK_NOTLOCK = 0x14, +}; + +/* ISO 15693, Ch. 7.4 */ +enum iso15693_vicc_states { + RFID_15693_STATE_POWER_OFF, + RFID_15693_STATE_READY, + RFID_15693_STATE_QUIET, + RFID_15693_STATE_SELECTED, +}; + +/* ISO 15693, Ch. 9.1 Table 10*/ +enum iso15693_commands { + /* Mandatory 0x01 .. 0x1f */ + ISO15693_CMD_INVENTORY = 0x01, + ISO15693_CMD_STAY_QUIET = 0x02, + /* Optional 0x20 .. 0x9f */ + ISO15693_CMD_READ_BLOCK_SINGLE = 0x20, + ISO15693_CMD_WRITE_BLOCK_SINGLE = 0x21, + ISO15693_CMD_LOCK_BLOCK = 0x22, + ISO15693_CMD_READ_BLOCK_MULTI = 0x23, + ISO15693_CMD_WRITE_BLOCK_MULTI = 0x24, + ISO15693_CMD_SELECT = 0x25, + ISO15693_CMD_RESET_TO_READY = 0x26, + ISO15693_CMD_WRITE_AFI = 0x27, + ISO15693_CMD_LOCK_AFI = 0x28, + ISO15693_CMD_WRITE_DSFID = 0x29, + ISO15693_CMD_LOCK_DSFID = 0x2a, + ISO15693_CMD_GET_SYSINFO = 0x2b, + ISO15693_CMD_GET_BLOCK_SECURITY = 0x2c + /* Custom 0xa0 .. 0xdf */ + /* Proprietary 0xe0 .. 0xff */ +}; + + #include extern const struct rfid_layer2 rfid_layer2_iso15693; +#endif /* __LIBRFID__ */ #endif /* _ISO15693_H */ diff --git a/src/rfid_layer2_iso15693.c b/src/rfid_layer2_iso15693.c index a9767b7..dab7418 100644 --- a/src/rfid_layer2_iso15693.c +++ b/src/rfid_layer2_iso15693.c @@ -28,237 +28,63 @@ #include #include -#if 0 -/* Transceive a 7-bit short frame */ -static int -iso14443a_transceive_sf(struct rfid_layer2_handle *handle, - unsigned char cmd, - struct iso14443a_atqa *atqa) -{ - struct rfid_reader *rdr = handle->rh->reader; +struct iso15693_request_read { + struct iso15693_request req; + u_int64_t uid; + u_int8_t blocknum; +} __attribute__ ((packed)); - return rdr->iso14443a.transceive_sf(handle->rh, cmd, atqa); -} +#define ISO15693_BLOCK_SIZE_MAX (256/8) +#define ISO15693_RESP_SIZE_MAX (4+ISO15693_BLOCK_SIZE_MAX) -/* Transmit an anticollission bit frame */ +#if 0 static int -iso14443a_transceive_acf(struct rfid_layer2_handle *handle, - struct iso14443a_anticol_cmd *acf, - unsigned int *bit_of_col) -{ - struct rfid_reader *rdr = handle->rh->reader; - - return rdr->iso14443a.transceive_acf(handle->rh, acf, bit_of_col); -} - -/* Transmit a regular frame */ -static int -iso14443a_transceive(struct rfid_layer2_handle *handle, - const unsigned char *tx_buf, unsigned int tx_len, - unsigned char *rx_buf, unsigned int *rx_len, - u_int64_t, unsigned int flags) +iso15693_read_block(struct rfid_layer2_handle *handle, + u_int8_t blocknr, u_int32_t *data) { - return handle->rh->reader->transceive(handle->rh, tx_buf, tx_len, - rx_buf, rx_len, timeout, flags); -} + int rc; + struct iso15693_request_read req; + u_int8_t resp[ISO15693_RESP_SIZE_MAX]; -static int -iso14443a_code_nvb_bits(unsigned char *nvb, unsigned int bits) -{ - unsigned int byte_count = bits / 8; - unsigned int bit_count = bits % 8; + req.req.flags = 0; + req.command = ISO15693_CMD_READ_BLOCK_SINGLE; + memcpy(&req.uid, handle->..., ISO15693_UID_LEN); + req.blocknum = blocknr; - if (byte_count < 2 || byte_count > 7) - return -1; + /* FIXME: fill CRC if required */ - *nvb = ((byte_count & 0xf) << 4) | bit_count; + rc = iso15693_transceive(... &req, ..., ); - return 0; -} + if (rc < 0) + return rc; -/* first bit is '1', second bit '2' */ -static void -set_bit_in_field(unsigned char *bitfield, unsigned int bit) -{ - unsigned int byte_count = bit / 8; - unsigned int bit_count = bit % 8; + memcpy(data, resp+1, rc-1); /* FIXME rc-3 in case of CRC */ - DEBUGP("bitfield=%p, byte_count=%u, bit_count=%u\n", - bitfield, byte_count, bit_count); - DEBUGP("%p = 0x%02x\n", (bitfield+byte_count), *(bitfield+byte_count)); - *(bitfield+byte_count) |= 1 << (bit_count-1); - DEBUGP("%p = 0x%02x\n", (bitfield+byte_count), *(bitfield+byte_count)); + return rc-1; } static int -iso14443a_anticol(struct rfid_layer2_handle *handle) +iso15693_write_block() { - int ret; - unsigned int uid_size; - struct iso14443a_atqa atqa; - struct iso14443a_anticol_cmd acf; - unsigned int bit_of_col; - unsigned char sak[3]; - unsigned char uid[10]; // triple size equals 10 bytes; - unsigned int rx_len = sizeof(sak); - char *aqptr = (char *) &atqa; - static int first = 0; - - memset(uid, 0, sizeof(uid)); - memset(sak, 0, sizeof(sak)); - memset(&atqa, 0, sizeof(atqa)); - memset(&acf, 0, sizeof(acf)); - - if (first == 0) { - DEBUGP("Sending REQA\n"); - ret = iso14443a_transceive_sf(handle, ISO14443A_SF_CMD_REQA, &atqa); - first = 1; - } else { - DEBUGP("Sending WUPA\n"); - ret = iso14443a_transceive_sf(handle, ISO14443A_SF_CMD_WUPA, &atqa); - } - - if (ret < 0) { - handle->priv.iso14443a.state = ISO14443A_STATE_REQA_SENT; - DEBUGP("error during transceive_sf: %d\n", ret); - return ret; - } - handle->priv.iso14443a.state = ISO14443A_STATE_ATQA_RCVD; - - DEBUGP("ATQA: 0x%02x 0x%02x\n", *aqptr, *(aqptr+1)); - - if (!atqa.bf_anticol) { - handle->priv.iso14443a.state =ISO14443A_STATE_NO_BITFRAME_ANTICOL; - DEBUGP("no bitframe anticollission bits set, aborting\n"); - return -1; - } + struct iso16593_request_read *rreq; + u_int32_t buf[sizeof(req)+ISO15693_BLOCK_SIZE_MAX]; - if (atqa.uid_size == 2 || atqa.uid_size == 3) - uid_size = 3; - else if (atqa.uid_size == 1) - uid_size = 2; - else - uid_size = 1; - - acf.sel_code = ISO14443A_AC_SEL_CODE_CL1; + rreq = (struct iso15693_request_read *) req; - handle->priv.iso14443a.state = ISO14443A_STATE_ANTICOL_RUNNING; - handle->priv.iso14443a.level = ISO14443A_LEVEL_CL1; + rreq->req.flags = ; + rreq->req.command = ISO15693_CMD_WRITE_BLOCK_SINGLE; + memcpy(rreq->uid, handle->, ISO15693_UID_LEN); + rreq->blocknum = blocknr; + memcpy(rreq->); -cascade: - iso14443a_code_nvb_bits(&acf.nvb, 16); - - ret = iso14443a_transceive_acf(handle, &acf, &bit_of_col); - if (ret < 0) - return ret; - DEBUGP("bit_of_col = %u\n", bit_of_col); - - while (bit_of_col != ISO14443A_BITOFCOL_NONE) { - set_bit_in_field(&acf.uid_bits[0], bit_of_col-16); - iso14443a_code_nvb_bits(&acf.nvb, bit_of_col); - ret = iso14443a_transceive_acf(handle, &acf, &bit_of_col); - DEBUGP("bit_of_col = %u\n", bit_of_col); - if (ret < 0) - return ret; - } - - iso14443a_code_nvb_bits(&acf.nvb, 7*8); - ret = iso14443a_transceive(handle, (unsigned char *)&acf, 7, - (unsigned char *) &sak, &rx_len, - TIMEOUT, 0); - if (ret < 0) - return ret; - - if (sak[0] & 0x04) { - /* Cascade bit set, UID not complete */ - switch (acf.sel_code) { - case ISO14443A_AC_SEL_CODE_CL1: - /* cascading from CL1 to CL2 */ - if (acf.uid_bits[0] != 0x88) { - DEBUGP("Cascade bit set, but UID0 != 0x88\n"); - return -1; - } - memcpy(&uid[0], &acf.uid_bits[1], 3); - acf.sel_code = ISO14443A_AC_SEL_CODE_CL2; - handle->priv.iso14443a.level = ISO14443A_LEVEL_CL2; - break; - case ISO14443A_AC_SEL_CODE_CL2: - /* cascading from CL2 to CL3 */ - memcpy(&uid[3], &acf.uid_bits[1], 3); - acf.sel_code = ISO14443A_AC_SEL_CODE_CL3; - handle->priv.iso14443a.level = ISO14443A_LEVEL_CL3; - break; - default: - DEBUGP("cannot cascade any further than CL3\n"); - handle->priv.iso14443a.state = ISO14443A_STATE_ERROR; - return -1; - break; - } - goto cascade; - - } else { - switch (acf.sel_code) { - case ISO14443A_AC_SEL_CODE_CL1: - /* single size UID (4 bytes) */ - memcpy(&uid[0], &acf.uid_bits[0], 4); - break; - case ISO14443A_AC_SEL_CODE_CL2: - /* double size UID (7 bytes) */ - memcpy(&uid[3], &acf.uid_bits[0], 4); - break; - case ISO14443A_AC_SEL_CODE_CL3: - /* triple size UID (10 bytes) */ - memcpy(&uid[6], &acf.uid_bits[0], 4); - break; - } - } - - handle->priv.iso14443a.level = ISO14443A_LEVEL_NONE; - handle->priv.iso14443a.state = ISO14443A_STATE_SELECTED; - - { - int uid_len; - if (uid_size == 1) - uid_len = 4; - else if (uid_size == 2) - uid_len = 7; - else - uid_len = 10; - - DEBUGP("UID %s\n", rfid_hexdump(uid, uid_len)); - } - - if (sak[0] & 0x20) { - DEBUGP("we have a T=CL compliant PICC\n"); - handle->priv.iso14443a.tcl_capable = 1; - } else { - DEBUGP("we have a T!=CL PICC\n"); - handle->priv.iso14443a.tcl_capable = 0; - } - - return 0; } static int -iso14443a_hlta(struct rfid_layer2_handle *handle) +iso15693_lock_block() { - int ret; - unsigned char tx_buf[2] = { 0x50, 0x00 }; - unsigned char rx_buf[10]; - unsigned int rx_len = sizeof(rx_buf); - - return 0; - - ret = iso14443a_transceive(handle, tx_buf, sizeof(tx_buf), - rx_buf, &rx_len, 1000 /* 1ms */, 0); - if (ret < 0) { - /* "error" case: we don't get somethng back from the card */ - return 0; - } - return -1; } -#endif +#endif static int iso15693_anticol(struct rfid_layer2_handle *handle)