X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=src%2Frfid_layer2_iso14443b.c;h=34575c54dd64041b3e2b5793adc21d5bed2ff9ee;hb=5b113de4b95a0e71e7b68f10fcd4597de0bd5b63;hp=454df0a463d406403844267596235369b6312229;hpb=2e5b78aa3beb31e5d9d83e693c59671faebfc932;p=librfid diff --git a/src/rfid_layer2_iso14443b.c b/src/rfid_layer2_iso14443b.c index 454df0a..34575c5 100644 --- a/src/rfid_layer2_iso14443b.c +++ b/src/rfid_layer2_iso14443b.c @@ -1,6 +1,6 @@ /* ISO 14443-3 B anticollision implementation * - * (C) 2005 by Harald Welte + * (C) 2005-2006 by Harald Welte * */ @@ -22,17 +22,22 @@ #include #include #include +#include #include #include #include #include +#include #include "rfid_iso14443_common.h" #define ATQB_TIMEOUT ((256*10e6/ISO14443_FREQ_SUBCARRIER) \ +(200*10e6/ISO14443_FREQ_SUBCARRIER)) +#undef ATQB_TIMEOUT +#define ATQB_TIMEOUT 1 + static inline int fwi_to_fwt(struct rfid_layer2_handle *h, unsigned int *fwt, unsigned int fwi) { @@ -79,9 +84,11 @@ parse_atqb(struct rfid_layer2_handle *h, struct iso14443b_atqb *atqb) if (atqb->protocol_info.protocol_type == 0x1) { DEBUGP("we have a T=CL compliant PICC\n"); h->priv.iso14443b.tcl_capable = 1; + h->proto_supported = (1 << RFID_PROTOCOL_TCL); } else { DEBUGP("we have a T!=CL PICC\n"); h->priv.iso14443b.tcl_capable = 0; + /* FIXME: what protocols do we support? */ } iso14443_fsdi_to_fsd(&h->priv.iso14443b.fsc, @@ -155,29 +162,22 @@ static int transceive_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; + struct { + struct iso14443b_attrib_hdr attrib; + char buf[256-3]; + } _attrib_buf; + + struct iso14443b_attrib_hdr *attrib = &_attrib_buf.attrib; + unsigned char rx_buf[256]; 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; - } + if (rx_len >= rx_len-1) + return -EINVAL; /* initialize attrib frame */ - memset(attrib, 0, attrib_size); + memset(&_attrib_buf, 0, sizeof(_attrib_buf)); if (inf_len) memcpy((unsigned char *)attrib+sizeof(*attrib), inf, inf_len); @@ -199,6 +199,8 @@ transceive_attrib(struct rfid_layer2_handle *h, const unsigned char *inf, if (h->priv.iso14443b.tcl_capable == 1) attrib->param3.protocol_type = 0x1; + attrib->param4.cid = h->priv.iso14443b.cid & 0xf; + *rx_len = *rx_len + 1; ret = h->rh->reader->transceive(h->rh, RFID_14443B_FRAME_REGULAR, (unsigned char *) attrib, @@ -212,8 +214,8 @@ transceive_attrib(struct rfid_layer2_handle *h, const unsigned char *inf, } if ((rx_buf[0] & 0x0f) != h->priv.iso14443b.cid) { - DEBUGP("ATTRIB response with invalid CID %u\n", - rx_buf[0] & 0x0f); + DEBUGP("ATTRIB response with invalid CID %u (should be %u)\n", + rx_buf[0] & 0x0f, h->priv.iso14443b.cid); ret = -1; goto out_rx; } @@ -226,9 +228,7 @@ transceive_attrib(struct rfid_layer2_handle *h, const unsigned char *inf, memcpy(rx_data, rx_buf+1, *rx_len); out_rx: - free(rx_buf); out_attrib: - free(attrib); return ret; } @@ -286,7 +286,7 @@ static struct rfid_layer2_handle * iso14443b_init(struct rfid_reader_handle *rh) { int ret; - struct rfid_layer2_handle *h = malloc(sizeof(*h)); + struct rfid_layer2_handle *h = malloc_layer2_handle(sizeof(*h)); if (!h) return NULL; @@ -294,6 +294,10 @@ iso14443b_init(struct rfid_reader_handle *rh) h->rh = rh; h->priv.iso14443b.state = ISO14443B_STATE_NONE; + /* FIXME: if we want to support multiple PICC's, we need some + * fancy allocation scheme for CID's */ + h->priv.iso14443b.cid = 0; + h->priv.iso14443b.fsd = iso14443_fsd_approx(rh->ah->mru); DEBUGP("fsd is %u\n", h->priv.iso14443b.fsd); @@ -304,7 +308,7 @@ iso14443b_init(struct rfid_reader_handle *rh) ret = h->rh->reader->iso14443b.init(h->rh); if (ret < 0) { DEBUGP("error during reader 14443b init\n"); - free(h); + free_layer2_handle(h); return NULL; } @@ -314,7 +318,7 @@ iso14443b_init(struct rfid_reader_handle *rh) static int iso14443b_fini(struct rfid_layer2_handle *handle) { - free(handle); + free_layer2_handle(handle); return 0; } @@ -331,7 +335,57 @@ iso14443b_transceive(struct rfid_layer2_handle *handle, rx_buf, rx_len, timeout, flags); } -struct rfid_layer2 rfid_layer2_iso14443b = { +static int +iso14443b_getopt(struct rfid_layer2_handle *handle, + int optname, void *optval, unsigned int optlen) +{ + unsigned int *opt_ui = optval; + + switch (optname) { + case RFID_OPT_14443B_CID: + *opt_ui = handle->priv.iso14443b.cid; + break; + case RFID_OPT_14443B_FSC: + *opt_ui = handle->priv.iso14443b.fsc; + break; + case RFID_OPT_14443B_FSD: + *opt_ui = handle->priv.iso14443b.fsd; + break; + case RFID_OPT_14443B_FWT: + *opt_ui = handle->priv.iso14443b.fwt; + break; + case RFID_OPT_14443B_TR0: + *opt_ui = handle->priv.iso14443b.tr0; + break; + case RFID_OPT_14443B_TR1: + *opt_ui = handle->priv.iso14443b.tr1; + break; + default: + return -EINVAL; + break; + } + return 0; +} + +static int +iso14443b_setopt(struct rfid_layer2_handle *handle, + int optname, const void *optval, unsigned int optlen) +{ + const unsigned int *opt_ui = optval; + + switch (optname) { + case RFID_OPT_14443B_CID: + handle->priv.iso14443b.cid = (*opt_ui & 0xf); + break; + defaukt: + return -EINVAL; + break; + } + return 0; +} + + +const struct rfid_layer2 rfid_layer2_iso14443b = { .id = RFID_LAYER2_ISO14443B, .name = "ISO 14443-3 B", .fn = { @@ -340,5 +394,7 @@ struct rfid_layer2 rfid_layer2_iso14443b = { .transceive = &iso14443b_transceive, .close = &iso14443b_hltb, .fini = &iso14443b_fini, + .getopt = &iso14443b_getopt, + .setopt = &iso14443b_setopt, }, };