X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=src%2Frfid_layer2_iso14443b.c;h=df2f95dad1ad776e232ee586f9756622b61713e6;hb=a12dd669d5a073a8e3fc23b25412a81c60a8baf8;hp=7c925621b604ba40f002b6cbda221fff2ec1c68b;hpb=dc97c2a84a373026906696a8109e0ade7384b35d;p=librfid diff --git a/src/rfid_layer2_iso14443b.c b/src/rfid_layer2_iso14443b.c index 7c92562..df2f95d 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 * */ @@ -16,23 +16,28 @@ * * 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 #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, @@ -114,13 +121,13 @@ send_reqb(struct rfid_layer2_handle *h, unsigned char afi, if (is_wup) reqb[2] |= 0x08; - ret = h->rh->reader->transcieve(h->rh, RFID_14443B_FRAME_REGULAR, + ret = h->rh->reader->transceive(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"); + DEBUGP("error during transceive of REQB/WUBP\n"); continue; } @@ -152,32 +159,25 @@ static inline unsigned int mbli_to_mbl(struct rfid_layer2_handle *h, } static int -transcieve_attrib(struct rfid_layer2_handle *h, const unsigned char *inf, +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,21 +199,23 @@ transcieve_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->transcieve(h->rh, RFID_14443B_FRAME_REGULAR, + ret = h->rh->reader->transceive(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"); + DEBUGP("transceive 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); + 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 @@ transcieve_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; } @@ -244,13 +244,13 @@ iso14443b_hltb(struct rfid_layer2_handle *h) hltb[0] = 0x50; memcpy(hltb+1, h->uid, 4); - ret = h->rh->reader->transcieve(h->rh, RFID_14443B_FRAME_REGULAR, + ret = h->rh->reader->transceive(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"); + DEBUGP("transceive problem\n"); return ret; } @@ -275,7 +275,7 @@ iso14443b_anticol(struct rfid_layer2_handle *handle) if (ret < 0) return ret; - ret = transcieve_attrib(handle, NULL, 0, buf, &buf_len); + ret = transceive_attrib(handle, NULL, 0, buf, &buf_len); if (ret < 0) 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); @@ -301,10 +305,10 @@ iso14443b_init(struct rfid_reader_handle *rh) 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); + ret = h->rh->reader->init(h->rh, RFID_LAYER2_ISO14443B); if (ret < 0) { DEBUGP("error during reader 14443b init\n"); - free(h); + free_layer2_handle(h); return NULL; } @@ -314,31 +318,83 @@ iso14443b_init(struct rfid_reader_handle *rh) static int iso14443b_fini(struct rfid_layer2_handle *handle) { - free(handle); + free_layer2_handle(handle); return 0; } static int -iso14443b_transcieve(struct rfid_layer2_handle *handle, +iso14443b_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) { DEBUGP("transcieving %u bytes, expecting max %u\n", tx_len, *rx_len); - return handle->rh->reader->transcieve(handle->rh, frametype, + return handle->rh->reader->transceive(handle->rh, frametype, tx_buf, tx_len, 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 = { .init = &iso14443b_init, .open = &iso14443b_anticol, - .transcieve = &iso14443b_transcieve, + .transceive = &iso14443b_transceive, .close = &iso14443b_hltb, .fini = &iso14443b_fini, + .getopt = &iso14443b_getopt, + .setopt = &iso14443b_setopt, }, };