summaryrefslogtreecommitdiff
path: root/rfid_layer2_iso14443b.c
diff options
context:
space:
mode:
authorlaforge <laforge@e0336214-984f-0b4b-a45f-81c69e1f0ede>2005-11-08 08:34:15 +0000
committerlaforge <laforge@e0336214-984f-0b4b-a45f-81c69e1f0ede>2005-11-08 08:34:15 +0000
commit05c7e304271bcf88901da3782fcd3f28a0c7c9cf (patch)
treec7972af3be2f8a6619af551faa980cd699399b1e /rfid_layer2_iso14443b.c
parentea11c6e508eb88d18847f4027bbc0a5ced0200b3 (diff)
use autoconf/automake
git-svn-id: https://svn.gnumonks.org/trunk/librfid@1658 e0336214-984f-0b4b-a45f-81c69e1f0ede
Diffstat (limited to 'rfid_layer2_iso14443b.c')
-rw-r--r--rfid_layer2_iso14443b.c344
1 files changed, 0 insertions, 344 deletions
diff --git a/rfid_layer2_iso14443b.c b/rfid_layer2_iso14443b.c
deleted file mode 100644
index f874071..0000000
--- a/rfid_layer2_iso14443b.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/* ISO 14443-3 B anticollision implementation
- *
- * (C) 2005 by Harald Welte <laforge@gnumonks.org>
- *
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * 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
- */
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include <rfid/rfid.h>
-#include <rfid/rfid_layer2.h>
-#include <rfid/rfid_reader.h>
-#include <rfid/rfid_layer2_iso14443b.h>
-
-#include "rfid_iso14443_common.h"
-
-#define ATQB_TIMEOUT ((256*10e6/ISO14443_FREQ_SUBCARRIER) \
- +(200*10e6/ISO14443_FREQ_SUBCARRIER))
-
-static inline int
-fwi_to_fwt(struct rfid_layer2_handle *h, unsigned int *fwt, unsigned int fwi)
-{
- unsigned int multiplier, tmp;
-
- /* 15 is RFU */
- if (fwi > 14)
- return -1;
-
- /* According to ISO 14443-3:200(E), Chapter 7.9.4.3, the forumala is
- * (256 * 16 / fC) * 2^fwi We avoid floating point computations by
- * shifting everything into the microsecond range. In integer
- * calculations 1000000*256*16/13560000 evaluates to 302 (instead of
- * 302.064897), which provides sufficient precision, IMHO. The max
- * result is 302 * 16384 (4947968), which fits well within the 31/32
- * bit range of an integer */
-
- multiplier = 1 << fwi; /* 2 to the power of fwi */
-
- tmp = (unsigned int) 1000000 * 256 * 16;
-
- return (tmp / h->rh->ah->asic->fc) * multiplier;
-}
-
-static int
-parse_atqb(struct rfid_layer2_handle *h, struct iso14443b_atqb *atqb)
-{
- int ret;
-
- if (atqb->fifty != 0x50)
- return -1;
-
- if (atqb->protocol_info.fo & 0x01)
- h->priv.iso14443b.flags |= ISO14443B_CID_SUPPORTED;
- if (atqb->protocol_info.fo & 0x02)
- h->priv.iso14443b.flags |= ISO14443B_NAD_SUPPORTED;
-
- ret = fwi_to_fwt(h, &h->priv.iso14443b.fwt, atqb->protocol_info.fwi);
- if (ret < 0) {
- DEBUGP("invalid fwi %u\n", atqb->protocol_info.fwi);
- return ret;
- }
-
- if (atqb->protocol_info.protocol_type == 0x1) {
- DEBUGP("we have a T=CL compliant PICC\n");
- h->priv.iso14443b.tcl_capable = 1;
- } else {
- DEBUGP("we have a T!=CL PICC\n");
- h->priv.iso14443b.tcl_capable = 0;
- }
-
- iso14443_fsdi_to_fsd(&h->priv.iso14443b.fsc,
- atqb->protocol_info.max_frame_size);
-
- /* FIXME: speed capability */
-
- memcpy(h->uid, atqb->pupi, sizeof(atqb->pupi));
- h->uid_len = sizeof(atqb->pupi);
-
- return 0;
-}
-
-static int
-send_reqb(struct rfid_layer2_handle *h, unsigned char afi,
- unsigned int is_wup, unsigned int num_initial_slots)
-{
- int ret;
- unsigned char reqb[3];
- struct iso14443b_atqb atqb;
- unsigned int atqb_len = sizeof(atqb);
- unsigned int num_slot_idx = num_initial_slots;
-
- reqb[0] = 0x05;
- reqb[1] = afi;
-
- for (num_slot_idx = num_initial_slots; num_slot_idx <= 4;
- num_slot_idx++) {
- reqb[2] = num_slot_idx & 0x07;
- if (is_wup)
- reqb[2] |= 0x08;
-
- ret = h->rh->reader->transcieve(h->rh, RFID_14443B_FRAME_REGULAR,
- reqb, sizeof(reqb),
- (unsigned char *)&atqb,
- &atqb_len, ATQB_TIMEOUT, 0);
- h->priv.iso14443b.state = ISO14443B_STATE_REQB_SENT;
- if (ret < 0) {
- DEBUGP("error during transcieve of REQB/WUBP\n");
- continue;
- }
-
- /* FIXME: send N-1 slot marker frames */
-
- if (atqb_len != sizeof(atqb)) {
- DEBUGP("error: atqb_len = %u instead of %Zu\n",
- atqb_len, sizeof(atqb));
- continue;
- }
-
- /* FIXME: how to detect a collission at 14443B ? I guess we
- * can only rely on the CRC checking (CRCErr in ErrorFlag
- * register?) */
-
- if (parse_atqb(h, &atqb) >= 0) {
- h->priv.iso14443b.state = ISO14443B_STATE_ATQB_RCVD;
- return 0;
- }
- }
-
- return -1;
-}
-
-static inline unsigned int mbli_to_mbl(struct rfid_layer2_handle *h,
- unsigned int mbli)
-{
- return (h->priv.iso14443b.fsc * 2 ^ (mbli-1));
-}
-
-static int
-transcieve_attrib(struct rfid_layer2_handle *h, const unsigned char *inf,
- unsigned int inf_len, unsigned char *rx_data, unsigned int *rx_len)
-{
- struct iso14443b_attrib_hdr *attrib;
- unsigned int attrib_size = sizeof(*attrib) + inf_len;
- unsigned char *rx_buf;
- unsigned char fsdi;
- int ret = 0;
-
- DEBUGP("fsd is %u\n", h->priv.iso14443b.fsd);
- attrib = malloc(attrib_size);
- if (!attrib) {
- perror("attrib_alloc");
- return -1;
- }
-
- DEBUGP("fsd is %u\n", h->priv.iso14443b.fsd);
- rx_buf = malloc(*rx_len+1);
- if (!rx_buf) {
- perror("rx_buf malloc");
- ret = -1;
- goto out_attrib;
- }
-
- /* initialize attrib frame */
- memset(attrib, 0, attrib_size);
- if (inf_len)
- memcpy((unsigned char *)attrib+sizeof(*attrib), inf, inf_len);
-
- attrib->one_d = 0x1d;
- memcpy(attrib->identifier, h->uid, 4);
-
- /* FIXME: do we want to change TR0/TR1 from its default ? */
- /* FIXME: do we want to change SOF/EOF from its default ? */
-
- ret = iso14443_fsd_to_fsdi(&fsdi, h->priv.iso14443b.fsd);
- if (ret < 0) {
- DEBUGP("unable to map FSD(%u) to FSDI\n",
- h->priv.iso14443b.fsd);
- goto out_rx;
- }
- attrib->param2.fsdi = fsdi;
-
- /* FIXME: spd_in / spd_out */
- if (h->priv.iso14443b.tcl_capable == 1)
- attrib->param3.protocol_type = 0x1;
-
- *rx_len = *rx_len + 1;
- ret = h->rh->reader->transcieve(h->rh, RFID_14443B_FRAME_REGULAR,
- (unsigned char *) attrib,
- sizeof(*attrib)+inf_len,
- rx_buf, rx_len, h->priv.iso14443b.fwt,
- 0);
- h->priv.iso14443b.state = ISO14443B_STATE_ATTRIB_SENT;
- if (ret < 0) {
- DEBUGP("transcieve problem\n");
- goto out_rx;
- }
-
- if ((rx_buf[0] & 0x0f) != h->priv.iso14443b.cid) {
- DEBUGP("ATTRIB response with invalid CID %u\n",
- rx_buf[0] & 0x0f);
- ret = -1;
- goto out_rx;
- }
-
- h->priv.iso14443b.state = ISO14443B_STATE_SELECTED;
-
- h->priv.iso14443b.mbl = mbli_to_mbl(h, (rx_data[0] & 0xf0) >> 4);
-
- *rx_len = *rx_len - 1;
- memcpy(rx_data, rx_buf+1, *rx_len);
-
-out_rx:
- free(rx_buf);
-out_attrib:
- free(attrib);
-
- return ret;
-}
-
-static int
-iso14443b_hltb(struct rfid_layer2_handle *h)
-{
- int ret;
- unsigned char hltb[5];
- unsigned char hltb_resp[1];
- unsigned int hltb_len = 1;
-
- hltb[0] = 0x50;
- memcpy(hltb+1, h->uid, 4);
-
- ret = h->rh->reader->transcieve(h->rh, RFID_14443B_FRAME_REGULAR,
- hltb, 5,
- hltb_resp, &hltb_len,
- h->priv.iso14443b.fwt, 0);
- h->priv.iso14443b.state = ISO14443B_STATE_HLTB_SENT;
- if (ret < 0) {
- DEBUGP("transcieve problem\n");
- return ret;
- }
-
- if (hltb_len != 1 || hltb_resp[0] != 0x00) {
- DEBUGP("bad HLTB response\n");
- return -1;
- }
- h->priv.iso14443b.state = ISO14443B_STATE_HALTED;
-
- return 0;
-}
-
-static int
-iso14443b_anticol(struct rfid_layer2_handle *handle)
-{
- unsigned char afi = 0; /* FIXME */
- int ret;
- unsigned char buf[255];
- unsigned int buf_len = sizeof(buf);
-
- ret = send_reqb(handle, afi, 0, 0);
- if (ret < 0)
- return ret;
-
- ret = transcieve_attrib(handle, NULL, 0, buf, &buf_len);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct rfid_layer2_handle *
-iso14443b_init(struct rfid_reader_handle *rh)
-{
- int ret;
- struct rfid_layer2_handle *h = malloc(sizeof(*h));
- if (!h)
- return NULL;
-
- h->l2 = &rfid_layer2_iso14443b;
- h->rh = rh;
- h->priv.iso14443b.state = ISO14443B_STATE_NONE;
-
- h->priv.iso14443b.fsd = iso14443_fsd_approx(rh->ah->mru);
- DEBUGP("fsd is %u\n", h->priv.iso14443b.fsd);
-
- /* 14443-3 Section 7.1.6 */
- h->priv.iso14443b.tr0 = (256/ISO14443_FREQ_SUBCARRIER)*10e6;
- h->priv.iso14443b.tr1 = (200/ISO14443_FREQ_SUBCARRIER)*10e6;
-
- ret = h->rh->reader->iso14443b.init(h->rh);
- if (ret < 0) {
- DEBUGP("error during reader 14443b init\n");
- free(h);
- return NULL;
- }
-
- return h;
-}
-
-static int
-iso14443b_fini(struct rfid_layer2_handle *handle)
-{
- free(handle);
- return 0;
-}
-
-static int
-iso14443b_transcieve(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)
-{
- DEBUGP("transcieving %u bytes, expecting max %u\n", tx_len, *rx_len);
- return handle->rh->reader->transcieve(handle->rh, frametype,
- tx_buf, tx_len,
- rx_buf, rx_len, timeout, flags);
-}
-
-struct rfid_layer2 rfid_layer2_iso14443b = {
- .id = RFID_LAYER2_ISO14443B,
- .name = "ISO 14443-3 B",
- .fn = {
- .init = &iso14443b_init,
- .open = &iso14443b_anticol,
- .transcieve = &iso14443b_transcieve,
- .close = &iso14443b_hltb,
- .fini = &iso14443b_fini,
- },
-};
personal git repositories of Harald Welte. Your mileage may vary