X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=src%2Frfid_layer2_iso15693.c;h=6d64c6596798da8c478405f008b5a7b513bf5e9a;hb=a7c201deb99239d6d98a45b3cc642d8554231a22;hp=a9767b7c2bd4f08b977ff90b725933470f164077;hpb=6c4d6b5bb56d258e0de09da93f3e49502f7f623c;p=librfid diff --git a/src/rfid_layer2_iso15693.c b/src/rfid_layer2_iso15693.c index a9767b7..6d64c65 100644 --- a/src/rfid_layer2_iso15693.c +++ b/src/rfid_layer2_iso15693.c @@ -1,7 +1,7 @@ /* ISO 15693 anticollision implementation * - * (C) 2005-2006 by Harald Welte - * + * (C) 2005-2008 by Harald Welte + * (C) 2007 by Bjoern Riemer */ /* @@ -16,252 +16,427 @@ * * 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 */ +#define DEBUG_LIBRFID + #include #include #include +#include #include #include #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)); + +struct iso15693_request_adressed { + struct iso15693_request head; + u_int64_t uid; +} __attribute__ ((packed)); + +#define ISO15693_BLOCK_SIZE_MAX (256/8) +#define ISO15693_RESP_SIZE_MAX (4+ISO15693_BLOCK_SIZE_MAX) + +const unsigned int iso15693_timing[2][5] = { + [ISO15693_T_SLOW] = { + [ISO15693_T1] = 1216, /* max time after VCD EOF before VICC SOF */ + [ISO15693_T2] = 1200, /* min time before VCD EOF after VICC response */ + [ISO15693_T3] = 1502, /* min time after VCD EOF before next EOF if no VICC response */ + [ISO15693_T4] = 1216, /* time after wich VICC transmits after VCD EOF */ + [ISO15693_T4_WRITE]=20000, /* time after wich VICC transmits after VCD EOF */ + }, + [ISO15693_T_FAST] = { + [ISO15693_T1] = 304, /* max time after VCD EOF before VICC SOF */ + [ISO15693_T2] = 300, /* min time before VCD EOF after VICC response */ + [ISO15693_T3] = 602, /* min time after VCD EOF before next EOF if no VICC response */ + [ISO15693_T4] = 304, /* time after wich VICC transmits after VCD EOF */ + [ISO15693_T4_WRITE]=20000, /* time after wich VICC transmits after VCD EOF */ + }, +}; - return rdr->iso14443a.transceive_sf(handle->rh, cmd, atqa); +static int iso15693_transceive(struct rfid_layer2_handle *handle, + enum rfid_frametype frametype, + const unsigned char *tx_buf, unsigned int tx_len, + unsigned char *rx_buf, unsigned int *rx_len, + u_int64_t timeout, unsigned int flags) +{ + return handle->rh->reader->transceive(handle->rh, frametype, tx_buf, + tx_len, rx_buf, rx_len, timeout, flags); } -/* Transmit an anticollission bit frame */ +/* Transmit an anticollission frame */ static int -iso14443a_transceive_acf(struct rfid_layer2_handle *handle, - struct iso14443a_anticol_cmd *acf, - unsigned int *bit_of_col) +iso15693_transceive_acf(struct rfid_layer2_handle *handle, + const struct iso15693_anticol_cmd *acf, + unsigned int acf_len, + struct iso15693_anticol_resp *resp, + unsigned int *rx_len, char *bit_of_col) { - struct rfid_reader *rdr = handle->rh->reader; - - return rdr->iso14443a.transceive_acf(handle->rh, acf, bit_of_col); + const struct rfid_reader *rdr = handle->rh->reader; + if (!rdr->iso15693.transceive_ac) + return -1; + return rdr->iso15693.transceive_ac(handle->rh, acf, acf_len, resp, rx_len, 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) +#if 0 + +static int +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]; + + req.req.flags = 0; + req.command = ISO15693_CMD_READ_BLOCK_SINGLE; + memcpy(&req.uid, handle->..., ISO15693_UID_LEN); + req.blocknum = blocknr; + + /* FIXME: fill CRC if required */ + + rc = iso15693_transceive(... &req, ..., ); + + if (rc < 0) + return rc; + + memcpy(data, resp+1, rc-1); /* FIXME rc-3 in case of CRC */ + + return rc-1; } -static int -iso14443a_code_nvb_bits(unsigned char *nvb, unsigned int bits) +static int +iso15693_write_block() { - unsigned int byte_count = bits / 8; - unsigned int bit_count = bits % 8; + struct iso16593_request_read *rreq; + u_int32_t buf[sizeof(req)+ISO15693_BLOCK_SIZE_MAX]; - if (byte_count < 2 || byte_count > 7) - return -1; + rreq = (struct iso15693_request_read *) req; - *nvb = ((byte_count & 0xf) << 4) | bit_count; + rreq->req.flags = ; + rreq->req.command = ISO15693_CMD_WRITE_BLOCK_SINGLE; + memcpy(rreq->uid, handle->, ISO15693_UID_LEN); + rreq->blocknum = blocknr; + memcpy(rreq->); - return 0; } -/* first bit is '1', second bit '2' */ -static void -set_bit_in_field(unsigned char *bitfield, unsigned int bit) +static int +iso15693_lock_block() { - unsigned int byte_count = bit / 8; - unsigned int bit_count = bit % 8; - - 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)); } +#endif + +/* Helper function to build an ISO 15693 anti collision frame */ static int -iso14443a_anticol(struct rfid_layer2_handle *handle) +iso15693_build_acf(u_int8_t *target, u_int8_t flags, u_int8_t afi, + u_int8_t mask_len, u_int8_t *mask) { - 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); - } + struct iso15693_request *req = (struct iso15693_request *) target; + int i = 0, j; - if (ret < 0) { - handle->priv.iso14443a.state = ISO14443A_STATE_REQA_SENT; - DEBUGP("error during transceive_sf: %d\n", ret); - return ret; + req->flags = flags; + req->command = ISO15693_CMD_INVENTORY; + if (flags & RFID_15693_F5_AFI_PRES) + req->data[i++] = afi; + req->data[i++] = mask_len; + + for (j = 0; j < mask_len; j++) + req->data[i++] = mask[j]; + + return i + sizeof(*req); +} + +static int +iso15693_anticol(struct rfid_layer2_handle *handle) +{ + int i, ret; + int tx_len, rx_len; + int num_valid = 0; + union { + struct iso15693_anticol_cmd_afi w_afi; + struct iso15693_anticol_cmd no_afi; + } acf; + + struct iso15693_anticol_resp resp; + + char boc; +#define MAX_SLOTS 16 + int num_slots = MAX_SLOTS; + + u_int8_t uuid_list[MAX_SLOTS][ISO15693_UID_LEN]; + int uuid_list_valid[MAX_SLOTS]; + + u_int8_t flags; + +#define MY_NONE 0 +#define MY_COLL 1 +#define MY_UUID 2 + + memset(uuid_list_valid, MY_NONE, sizeof(uuid_list_valid)); + memset(uuid_list, 0, sizeof(uuid_list)); + + //memset(&acf, 0, sizeof(acf)); + + /* FIXME: we can't use multiple slots at this point, since the RC632 + * with librfid on the host PC has too much latency between 'EOF pulse + * to mark start of next slot' and 'receive data' commands :( */ + + flags = RFID_15693_F_INV_TABLE_5; + if (handle->priv.iso15693.vicc_fast) + flags |= RFID_15693_F_RATE_HIGH; + if (handle->priv.iso15693.vicc_two_subc) + flags |= RFID_15693_F_SUBC_TWO; + if (handle->priv.iso15693.single_slot) { + flags |= RFID_15693_F5_NSLOTS_1; + num_slots = 1; + } + if (handle->priv.iso15693.use_afi) + flags |= RFID_15693_F5_AFI_PRES; + + tx_len = iso15693_build_acf((u_int8_t *)&acf, flags, + handle->priv.iso15693.afi, 0, NULL); + + for (i = 0; i < num_slots; i++) { + rx_len = sizeof(resp); + ret = iso15693_transceive_acf(handle, (u_int8_t *) &acf, tx_len, &resp, &rx_len, &boc); + if (ret == -ETIMEDOUT) { + DEBUGP("no answer from vicc in slot %d\n", i); + uuid_list_valid[i] = MY_NONE; + } else if (ret < 0) { + DEBUGP("ERROR ret: %d, slot %d\n", ret, i); + uuid_list_valid[i] = MY_NONE; + } else { + + if (boc) { + DEBUGP("Collision during anticol. slot %d bit %d\n", + i, boc); + uuid_list_valid[i] = -boc; + memcpy(uuid_list[i], resp.uuid, ISO15693_UID_LEN); + } else { + DEBUGP("Slot %d ret: %d UUID: %s\n", i, ret, + rfid_hexdump(resp.uuid, ISO15693_UID_LEN)); + uuid_list_valid[i] = MY_UUID; + memcpy(&uuid_list[i][0], resp.uuid, ISO15693_UID_LEN); + } + } } - handle->priv.iso14443a.state = ISO14443A_STATE_ATQA_RCVD; - DEBUGP("ATQA: 0x%02x 0x%02x\n", *aqptr, *(aqptr+1)); + for (i = 0; i < num_slots; i++) { + if (uuid_list_valid[i] == MY_NONE) { + DEBUGP("slot[%d]: timeout\n",i); + } else if (uuid_list_valid[i] == MY_UUID) { + DEBUGP("slot[%d]: VALID uuid: %s\n", i, + rfid_hexdump(uuid_list[i], ISO15693_UID_LEN)); + num_valid++; + } else if (uuid_list_valid[i] < 0) { + DEBUGP("slot[%d]: collision(%d %d,%d) uuid: %s\n", + i,uuid_list_valid[i]*-1, + (uuid_list_valid[i]*-1)/8, + (uuid_list_valid[i]*-1)%8, + rfid_hexdump(uuid_list[i], ISO15693_UID_LEN)); + } + } - if (!atqa.bf_anticol) { - handle->priv.iso14443a.state =ISO14443A_STATE_NO_BITFRAME_ANTICOL; - DEBUGP("no bitframe anticollission bits set, aborting\n"); + if (num_valid == 0) return -1; - } - 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; + return num_valid; +} - handle->priv.iso14443a.state = ISO14443A_STATE_ANTICOL_RUNNING; - handle->priv.iso14443a.level = ISO14443A_LEVEL_CL1; +static int +iso15693_select(struct rfid_layer2_handle *handle) +{ + struct iso15693_request_adressed tx_req; + int ret; + unsigned int rx_len, tx_len; + + struct { + struct iso15693_response head; + u_int8_t error; + unsigned char crc[2]; + } rx_buf; + rx_len = sizeof(rx_buf); + + tx_req.head.command = ISO15693_CMD_SELECT; + tx_req.head.flags = RFID_15693_F4_ADDRESS | RFID_15693_F_SUBC_TWO ; + tx_req.uid = 0xE0070000020C1F18; + //req.uid = 0x181F0C02000007E0; + //req.uid = 0xe004010001950837; + //req.uid = 0x37089501000104e0; + tx_len = sizeof(tx_req); + DEBUGP("tx_len=%u", tx_len); DEBUGPC(" rx_len=%u\n",rx_len); + ret = iso15693_transceive(handle, RFID_15693_FRAME, (u_int8_t*)&tx_req, + tx_len, (u_int8_t*)&rx_buf, &rx_len, 50,0); + DEBUGP("ret: %d, error_flag: %d error: %d\n", ret, + rx_buf.head.flags&RFID_15693_RF_ERROR, 0); + return -1; +} -cascade: - iso14443a_code_nvb_bits(&acf.nvb, 16); +static int +iso15693_getopt(struct rfid_layer2_handle *handle, + int optname, void *optval, unsigned int *optlen) +{ + unsigned int *val = optval; + u_int8_t *val_u8 = optval; - ret = iso14443a_transceive_acf(handle, &acf, &bit_of_col); - if (ret < 0) - return ret; - DEBUGP("bit_of_col = %u\n", bit_of_col); + if (!optlen || !optval || *optlen < sizeof(unsigned int)) + return -EINVAL; - 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; + *optlen = sizeof(unsigned int); + + switch (optname) { + case RFID_OPT_15693_MOD_DEPTH: + if (handle->priv.iso15693.vcd_ask100) + *val = RFID_15693_MOD_100ASK; + else + *val = RFID_15693_MOD_10ASK; + break; + case RFID_OPT_15693_VCD_CODING: + if (handle->priv.iso15693.vcd_out256) + *val = RFID_15693_VCD_CODING_1OUT256; + else + *val = RFID_15693_VCD_CODING_1OUT4; + break; + case RFID_OPT_15693_VICC_SUBC: + if (handle->priv.iso15693.vicc_two_subc) + *val = RFID_15693_VICC_SUBC_DUAL; + else + *val = RFID_15693_VICC_SUBC_SINGLE; + break; + case RFID_OPT_15693_VICC_SPEED: + if (handle->priv.iso15693.vicc_fast) + *val = RFID_15693_VICC_SPEED_FAST; + else + *val = RFID_15693_VICC_SPEED_SLOW; + break; + case RFID_OPT_15693_VCD_SLOTS: + if (handle->priv.iso15693.single_slot) + *val = 1; + else + *val = 16; + break; + case RFID_OPT_15693_USE_AFI: + if (handle->priv.iso15693.use_afi) + *val = 1; + else + *val = 0; + break; + case RFID_OPT_15693_AFI: + *val_u8 = handle->priv.iso15693.afi; + *optlen = sizeof(u_int8_t); + break; + default: + return -EINVAL; + break; } - 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; + return 0; +} + +static int +iso15693_setopt(struct rfid_layer2_handle *handle, int optname, + const void *optval, unsigned int optlen) +{ + unsigned int val; + + if (optlen < sizeof(u_int8_t) || !optval) + return -EINVAL; + + if (optlen == sizeof(u_int8_t)) + val = *((u_int8_t *) optval); + if (optlen == sizeof(u_int16_t)) + val = *((u_int16_t *) optval); + if (optlen == sizeof(unsigned int)) + val = *((unsigned int *) optval); + + switch (optname) { + case RFID_OPT_15693_MOD_DEPTH: + switch (val) { + case RFID_15693_MOD_10ASK: + handle->priv.iso15693.vcd_ask100 = 0; 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; + case RFID_15693_MOD_100ASK: + handle->priv.iso15693.vcd_ask100 = 1; break; default: - DEBUGP("cannot cascade any further than CL3\n"); - handle->priv.iso14443a.state = ISO14443A_STATE_ERROR; - return -1; + return -EINVAL; + } + break; + case RFID_OPT_15693_VCD_CODING: + switch (val) { + case RFID_15693_VCD_CODING_1OUT256: + handle->priv.iso15693.vcd_out256 = 1; + break; + case RFID_15693_VCD_CODING_1OUT4: + handle->priv.iso15693.vcd_out256 = 0; break; + default: + return -EINVAL; } - 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 RFID_OPT_15693_VICC_SUBC: + switch (val) { + case RFID_15693_VICC_SUBC_SINGLE: + handle->priv.iso15693.vicc_two_subc = 0; break; - case ISO14443A_AC_SEL_CODE_CL2: - /* double size UID (7 bytes) */ - memcpy(&uid[3], &acf.uid_bits[0], 4); + case RFID_15693_VICC_SUBC_DUAL: + handle->priv.iso15693.vicc_two_subc = 1; break; - case ISO14443A_AC_SEL_CODE_CL3: - /* triple size UID (10 bytes) */ - memcpy(&uid[6], &acf.uid_bits[0], 4); + default: + return -EINVAL; + } + break; + case RFID_OPT_15693_VICC_SPEED: + switch (val) { + case RFID_15693_VICC_SPEED_SLOW: + handle->priv.iso15693.vicc_fast = 0; break; + case RFID_15693_VICC_SPEED_FAST: + handle->priv.iso15693.vicc_fast = 1; + break; + default: + return -EINVAL; } + case RFID_OPT_15693_VCD_SLOTS: + switch (val) { + case 16: + handle->priv.iso15693.single_slot = 0; + break; + case 1: + handle->priv.iso15693.single_slot = 1; + break; + default: + return -EINVAL; + } + break; + case RFID_OPT_15693_USE_AFI: + if (val) + handle->priv.iso15693.use_afi = 1; + else + handle->priv.iso15693.use_afi = 1; + break; + case RFID_OPT_15693_AFI: + if (val > 0xff) + return -EINVAL; + handle->priv.iso15693.afi = val; + break; + default: + return -EINVAL; } - - 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) -{ - 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 - - -static int -iso15693_anticol(struct rfid_layer2_handle *handle) +static int transceive_inventory(struct rfid_layer2_handle *l2h) { return -1; } @@ -277,7 +452,15 @@ iso15693_init(struct rfid_reader_handle *rh) h->l2 = &rfid_layer2_iso15693; h->rh = rh; h->priv.iso15693.state = ISO15693_STATE_NONE; - ret = h->rh->reader->iso15693.init(h->rh); + h->priv.iso15693.vcd_ask100 = 1; /* 100ASK is easier to generate */ + h->priv.iso15693.vicc_two_subc = 0; + h->priv.iso15693.vicc_fast = 1; + h->priv.iso15693.single_slot = 1; + h->priv.iso15693.vcd_out256 = 0; + h->priv.iso15693.use_afi = 0; /* not all VICC support AFI */ + h->priv.iso15693.afi = 0; + + ret = h->rh->reader->init(h->rh, RFID_LAYER2_ISO15693); if (ret < 0) { free_layer2_handle(h); return NULL; @@ -300,9 +483,12 @@ const struct rfid_layer2 rfid_layer2_iso15693 = { .fn = { .init = &iso15693_init, .open = &iso15693_anticol, + //.open = &iso15693_select, //.transceive = &iso15693_transceive, //.close = &iso14443a_hlta, .fini = &iso15693_fini, + .setopt = &iso15693_setopt, + .getopt = &iso15693_getopt, }, };