From fe4ffab6d97f2e2696bf7f1fb52a175342611aec Mon Sep 17 00:00:00 2001 From: laforge Date: Sat, 7 Oct 2006 20:55:16 +0000 Subject: - use C99 compiler flags - implement some getopt/setopt functions for UID and layer2 specific parameters - basic rfid scanning support - add commandline arguments for layer2 / scanning to librfid-tool - try to detect both supported readers automatically in librfid-tool - add new 'l2_supported' and 'proto_supported members to rfid_reader git-svn-id: https://svn.gnumonks.org/trunk/librfid@1895 e0336214-984f-0b4b-a45f-81c69e1f0ede --- Makefile.am | 2 + include/librfid/Makefile.am | 5 +- include/librfid/rfid.h | 11 +++- include/librfid/rfid_layer2.h | 7 ++ include/librfid/rfid_layer2_iso14443a.h | 4 +- include/librfid/rfid_layer2_iso14443b.h | 11 ++++ include/librfid/rfid_reader.h | 3 + include/librfid/rfid_scan.h | 12 ++++ src/Makefile.am | 2 +- src/rfid.c | 52 ++++++++++++++- src/rfid_layer2.c | 43 +++++++++--- src/rfid_layer2_iso14443a.c | 6 +- src/rfid_layer2_iso14443b.c | 71 +++++++++++++++++++- src/rfid_reader_cm5121.c | 10 ++- src/rfid_reader_openpcd.c | 8 +++ src/rfid_scan.c | 113 ++++++++++++++++++++++++++++++++ utils/librfid-tool.c | 95 ++++++++++++++++++++++----- 17 files changed, 416 insertions(+), 39 deletions(-) create mode 100644 include/librfid/rfid_scan.h create mode 100644 src/rfid_scan.c diff --git a/Makefile.am b/Makefile.am index 69140e2..3a8a1ca 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,6 +3,8 @@ AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6 SUBDIRS = include src utils LINKOPTS = -lusb +AM_CFLAGS = -std=gnu99 + $(OBJECTS): libtool libtool: $(LIBTOOL_DEPS) $(SHELL) ./config.status --recheck diff --git a/include/librfid/Makefile.am b/include/librfid/Makefile.am index 59ce8cb..4b1337d 100644 --- a/include/librfid/Makefile.am +++ b/include/librfid/Makefile.am @@ -1,10 +1,11 @@ -pkginclude_HEADERS = rfid.h rfid_asic.h rfid_asic_rc632.h \ +pkginclude_HEADERS = rfid.h rfid_scan.h rfid_asic.h rfid_asic_rc632.h \ rfid_layer2.h rfid_layer2_iso14443a.h \ rfid_layer2_iso14443b.h rfid_layer2_iso15693.h \ rfid_protocol.h rfid_protocol_tcl.h \ rfid_protocol_mifare_ul.h \ rfid_protocol_mifare_classic.h \ rfid_reader.h \ - rfid_reader_cm5121.h + rfid_reader_cm5121.h \ + rfid_reader_openpcd.h diff --git a/include/librfid/rfid.h b/include/librfid/rfid.h index b1943d7..c3f8fc1 100644 --- a/include/librfid/rfid.h +++ b/include/librfid/rfid.h @@ -11,7 +11,9 @@ enum rfid_frametype { RFID_MIFARE_FRAME, }; -#if 1 +//#define DEBUG + +#ifdef DEBUG #define DEBUGP(x, args ...) fprintf(stderr, "%s(%d):%s: " x, __FILE__, __LINE__, __FUNCTION__, ## args) #define DEBUGPC(x, args ...) fprintf(stderr, x, ## args) #else @@ -29,4 +31,11 @@ extern const char *rfid_hexdump(const void *data, unsigned int len); int rfid_init(); +enum rfid_opt_level { + RFID_LEVEL_ASIC, + RFID_LEVEL_READER, + RFID_LEVEL_LAYER2, + RFID_LEVEL_LAYER3, +}; + #endif /* _RFID_H */ diff --git a/include/librfid/rfid_layer2.h b/include/librfid/rfid_layer2.h index 3dd54a2..514a735 100644 --- a/include/librfid/rfid_layer2.h +++ b/include/librfid/rfid_layer2.h @@ -14,6 +14,12 @@ enum rfid_layer2_id { RFID_LAYER2_ISO15693, }; +/* 0...0xffff = global options, 0x10000...0x1ffff = private options */ +#define RFID_OPT_L2_PRIV 0x00010000 +enum rfid_layer2_opt { + RFID_OPT_LAYER2_UID = 0x0001, +}; + struct rfid_layer2_handle *rfid_layer2_init(struct rfid_reader_handle *rh, unsigned int id); int rfid_layer2_open(struct rfid_layer2_handle *l2h); @@ -63,6 +69,7 @@ struct rfid_layer2_handle { struct rfid_reader_handle *rh; unsigned char uid[10]; /* triple size 14443a id is 10 bytes */ unsigned int uid_len; + unsigned int proto_supported; union { struct iso14443a_handle iso14443a; struct iso14443b_handle iso14443b; diff --git a/include/librfid/rfid_layer2_iso14443a.h b/include/librfid/rfid_layer2_iso14443a.h index 81f1680..87b6be0 100644 --- a/include/librfid/rfid_layer2_iso14443a.h +++ b/include/librfid/rfid_layer2_iso14443a.h @@ -2,8 +2,8 @@ #define _RFID_ISO14443A_H enum rfid_14443a_opt { - RFID_OPT_14443A_SPEED_RX = 0x00000001, - RFID_OPT_14443A_SPEED_TX = 0x00000002, + RFID_OPT_14443A_SPEED_RX = 0x00010001, + RFID_OPT_14443A_SPEED_TX = 0x00010002, }; enum rfid_14443_opt_speed { diff --git a/include/librfid/rfid_layer2_iso14443b.h b/include/librfid/rfid_layer2_iso14443b.h index 5d6d979..07c185f 100644 --- a/include/librfid/rfid_layer2_iso14443b.h +++ b/include/librfid/rfid_layer2_iso14443b.h @@ -1,6 +1,17 @@ #ifndef _RFID_LAYER2_ISO14443B_H #define _RFID_LAYER2_ISO14443B_H +#include + +enum rfid_iso14443_opt { + RFID_OPT_14443B_CID = 0x00010001, + RFID_OPT_14443B_FSC = 0x00010002, + RFID_OPT_14443B_FSD = 0x00010003, + RFID_OPT_14443B_FWT = 0x00010004, + RFID_OPT_14443B_TR0 = 0x00010005, + RFID_OPT_14443B_TR1 = 0x00010006, +}; + #ifdef __LIBRFID__ struct iso14443b_atqb { diff --git a/include/librfid/rfid_reader.h b/include/librfid/rfid_reader.h index ce29981..2221abd 100644 --- a/include/librfid/rfid_reader.h +++ b/include/librfid/rfid_reader.h @@ -9,6 +9,9 @@ struct rfid_reader_handle; struct rfid_reader { char *name; unsigned int id; + unsigned int l2_supported; + unsigned int proto_supported; + int (*transceive)(struct rfid_reader_handle *h, enum rfid_frametype frametype, const unsigned char *tx_buf, unsigned int tx_len, diff --git a/include/librfid/rfid_scan.h b/include/librfid/rfid_scan.h new file mode 100644 index 0000000..dcfd7bf --- /dev/null +++ b/include/librfid/rfid_scan.h @@ -0,0 +1,12 @@ +#ifndef _RFID_SCAN_H +#define _RFID_SCAN_H + +#include +#include +#include + +int rfid_scan(struct rfid_reader_handle *rh, + struct rfid_layer2_handle **l2h, + struct rfid_protocol_handle **ph); + +#endif /* _RFID_SCAN_H */ diff --git a/src/Makefile.am b/src/Makefile.am index 04d17d4..c0cbfbe 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,7 @@ AM_CFLAGS = -std=gnu99 lib_LTLIBRARIES = librfid.la -CORE=rfid.c rfid_layer2.c rfid_protocol.c rfid_reader.c +CORE=rfid.c rfid_layer2.c rfid_protocol.c rfid_reader.c rfid_scan.c L2=rfid_layer2_iso14443a.c rfid_layer2_iso14443b.c rfid_layer2_iso15693.c rfid_iso14443_common.c PROTO=rfid_proto_tcl.c rfid_proto_mifare_ul.c rfid_proto_mifare_classic.c READER=rfid_reader_cm5121.c rfid_asic_rc632.c rfid_reader_openpcd.c diff --git a/src/rfid.c b/src/rfid.c index b90043f..ba166a2 100644 --- a/src/rfid.c +++ b/src/rfid.c @@ -1,4 +1,6 @@ -/* +/* librfid core + * (C) 2005-2006 by Harald Welte + * * 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 @@ -40,6 +42,54 @@ rfid_hexdump(const void *data, unsigned int len) return string; } +#if 0 +int rfid_setopt(struct rfid_handle *rh, unsigned int level, + unsigned int optname, + const void *opt, unsigned int *optlen) +{ + switch (level) { + case RFID_LEVEL_ASIC: + case RFID_LEVEL_READER: + return -EINVAL; + break; + case RFID_LEVEL_LAYER2: + return rfid_layer2_setopt(optname, opt, optlen); + break; + case RFID_LEVEL_LAYER3: + return rfid_layer3_setopt(optname, opt, optlen); + break; + default: + return -EINVAL; + break; + } + + return 0; +} + +int rfid_getopt(struct rfid_handle *rh, unsigned int level, + unsigned int optname, + void *opt, unsigned int *optlen) +{ + switch (level) { + case RFID_LEVEL_ASIC: + case RFID_LEVEL_READER: + return -EINVAL; + break; + case RFID_LEVEL_LAYER2: + return rfid_layer2_getopt(optname, opt, optlen); + break; + case RFID_LEVEL_LAYER3: + return rfid_layer3_getopt(optname, opt, optlen); + break; + default: + return -EINVAL; + break; + } + + return 0; +} +#endif + int rfid_init() { rfid_reader_register(&rfid_reader_cm5121); diff --git a/src/rfid_layer2.c b/src/rfid_layer2.c index eef0560..7461d87 100644 --- a/src/rfid_layer2.c +++ b/src/rfid_layer2.c @@ -1,5 +1,5 @@ /* librfid - layer 2 protocol handler - * (C) 2005 by Harald Welte + * (C) 2005-2006 by Harald Welte */ /* @@ -92,18 +92,43 @@ int rfid_layer2_getopt(struct rfid_layer2_handle *ph, int optname, void *optval, unsigned int *optlen) { - if (!ph->l2->fn.getopt) - return -EINVAL; - - return ph->l2->fn.getopt(ph, optname, optval, optlen); + if (optname >> 16 == 0) { + unsigned char *optchar = optval; + + switch (optname) { + case RFID_OPT_LAYER2_UID: + if (ph->uid_len < *optlen) + *optlen = ph->uid_len; + memcpy(optchar, ph->uid, *optlen); + break; + default: + return -EINVAL; + break; + } + } else { + if (!ph->l2->fn.getopt) + return -EINVAL; + + return ph->l2->fn.getopt(ph, optname, optval, optlen); + } + return 0; } int rfid_layer2_setopt(struct rfid_layer2_handle *ph, int optname, const void *optval, unsigned int optlen) { - if (!ph->l2->fn.setopt) - return -EINVAL; - - return ph->l2->fn.setopt(ph, optname, optval, optlen); + if (optname >> 16 == 0) { + switch (optname) { + default: + return -EINVAL; + break; + } + } else { + if (!ph->l2->fn.setopt) + return -EINVAL; + + return ph->l2->fn.setopt(ph, optname, optval, optlen); + } + return 0; } diff --git a/src/rfid_layer2_iso14443a.c b/src/rfid_layer2_iso14443a.c index a83c71a..7ebc240 100644 --- a/src/rfid_layer2_iso14443a.c +++ b/src/rfid_layer2_iso14443a.c @@ -1,6 +1,6 @@ /* ISO 14443-3 A anticollision implementation * - * (C) 2005 by Harald Welte + * (C) 2005-2006 by Harald Welte * */ @@ -28,6 +28,7 @@ #include #include #include +#include #define TIMEOUT 1236 @@ -225,9 +226,12 @@ cascade: if (sak[0] & 0x20) { DEBUGP("we have a T=CL compliant PICC\n"); + handle->proto_supported = 1 << RFID_PROTOCOL_TCL; h->tcl_capable = 1; } else { DEBUGP("we have a T!=CL PICC\n"); + handle->proto_supported = (1 << RFID_PROTOCOL_MIFARE_UL)| + (1 << RFID_PROTOCOL_MIFARE_CLASSIC); h->tcl_capable = 0; } diff --git a/src/rfid_layer2_iso14443b.c b/src/rfid_layer2_iso14443b.c index 454df0a..8227a32 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, @@ -199,6 +206,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 +221,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; } @@ -294,6 +303,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); @@ -331,6 +344,56 @@ iso14443b_transceive(struct rfid_layer2_handle *handle, rx_buf, rx_len, timeout, flags); } +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; +} + + struct rfid_layer2 rfid_layer2_iso14443b = { .id = RFID_LAYER2_ISO14443B, .name = "ISO 14443-3 B", @@ -340,5 +403,7 @@ struct rfid_layer2 rfid_layer2_iso14443b = { .transceive = &iso14443b_transceive, .close = &iso14443b_hltb, .fini = &iso14443b_fini, + .getopt = &iso14443b_getopt, + .setopt = &iso14443b_setopt, }, }; diff --git a/src/rfid_reader_cm5121.c b/src/rfid_reader_cm5121.c index ab1e701..a9907ad 100644 --- a/src/rfid_reader_cm5121.c +++ b/src/rfid_reader_cm5121.c @@ -1,6 +1,6 @@ /* Omnikey CardMan 5121 specific RC632 transport layer * - * (C) 2005 by Harald Welte + * (C) 2005-2006 by Harald Welte * * The 5121 is an Atmel AT89C5122 based USB CCID reader (probably the same * design like the 3121). It's CL RC632 is connected via address/data bus, @@ -37,6 +37,8 @@ #include #include #include +#include +#include #include "cm5121_source.h" @@ -360,6 +362,12 @@ struct rfid_reader rfid_reader_cm5121 = { .open = &cm5121_open, .close = &cm5121_close, .transceive = &cm5121_transceive, + .l2_supported = (1 << RFID_LAYER2_ISO14443A) | + (1 << RFID_LAYER2_ISO14443B) | + (1 << RFID_LAYER2_ISO15693), + .proto_supported = (1 << RFID_PROTOCOL_TCL) | + (1 << RFID_PROTOCOL_MIFARE_UL) | + (1 << RFID_PROTOCOL_MIFARE_CLASSIC), .iso14443a = { .init = &cm5121_14443a_init, .transceive_sf = &cm5121_transceive_sf, diff --git a/src/rfid_reader_openpcd.c b/src/rfid_reader_openpcd.c index 51852f0..053a711 100644 --- a/src/rfid_reader_openpcd.c +++ b/src/rfid_reader_openpcd.c @@ -39,6 +39,8 @@ #include #include #include +#include +#include /* FIXME */ #include "rc632.h" @@ -391,6 +393,12 @@ struct rfid_reader rfid_reader_openpcd = { .open = &openpcd_open, .close = &openpcd_close, .transceive = &openpcd_transceive, + .l2_supported = (1 << RFID_LAYER2_ISO14443A) | + (1 << RFID_LAYER2_ISO14443B) | + (1 << RFID_LAYER2_ISO15693), + .proto_supported = (1 << RFID_PROTOCOL_TCL) | + (1 << RFID_PROTOCOL_MIFARE_UL) | + (1 << RFID_PROTOCOL_MIFARE_CLASSIC), .iso14443a = { .init = &openpcd_14443a_init, .transceive_sf = &openpcd_transceive_sf, diff --git a/src/rfid_scan.c b/src/rfid_scan.c new file mode 100644 index 0000000..1abb4df --- /dev/null +++ b/src/rfid_scan.c @@ -0,0 +1,113 @@ +/* RFID scanning implementation + * + * (C) 2006 by Harald Welte + * + */ + +/* + * 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 +#include +#include +#include + +static struct rfid_layer2_handle * +rfid_layer2_scan1(struct rfid_reader_handle *rh, int l2) +{ + struct rfid_layer2_handle *l2h; + + if (rh->reader->l2_supported & (1 << l2)) { + l2h = rfid_layer2_init(rh, l2); + if (!l2h) + return NULL; + if (rfid_layer2_open(l2h) < 0) { + rfid_layer2_fini(l2h); + return NULL; + } else + return l2h; + } + + return NULL; +} + +static struct rfid_layer2_handle * +rfid_layer2_scan(struct rfid_reader_handle *rh) +{ + struct rfid_layer2_handle *l2h; + int i; + +#define RFID_LAYER2_MAX 16 + for (i = 0; i < RFID_LAYER2_MAX; i++) { + l2h = rfid_layer2_scan1(rh, i); + if (l2h) + return l2h; + } + + return NULL; +} + +static struct rfid_protocol_handle * +rfid_protocol_scan1(struct rfid_layer2_handle *l2h, int proto) +{ + struct rfid_protocol_handle *ph; + + if (l2h->rh->reader->proto_supported & (1 << proto) && + l2h->proto_supported & (1 << proto)) { + ph = rfid_protocol_init(l2h, proto); + if (!ph) + return NULL; + if (rfid_protocol_open(ph) < 0) { + rfid_protocol_fini(ph); + return NULL; + } else + return ph; + } + + return NULL; +} + +static struct rfid_protocol_handle * +rfid_protocol_scan(struct rfid_layer2_handle *l2h) +{ + struct rfid_protocol_handle *ph; + int i; + +#define RFID_PROTOCOL_MAX 16 + for (i = 0; i < RFID_PROTOCOL_MAX; i++) { + ph = rfid_protocol_scan1(l2h, i); + if (ph) + return ph; + } + + return NULL; +} + +/* Scan for any RFID transponder within range of the given reader. + * Abort after the first successfully found transponder. */ +int rfid_scan(struct rfid_reader_handle *rh, + struct rfid_layer2_handle **l2h, + struct rfid_protocol_handle **ph) +{ + *l2h = rfid_layer2_scan(rh); + if (!*l2h) + return 0; + + *ph = rfid_protocol_scan(l2h); + if (!*ph) + return 2; + + return 3; +} diff --git a/utils/librfid-tool.c b/utils/librfid-tool.c index 0c21a4d..c96f948 100644 --- a/utils/librfid-tool.c +++ b/utils/librfid-tool.c @@ -1,4 +1,7 @@ -/* +/* librfid-tool - a small command-line tool for librfid testing + * + * (C) 2005-2006 by Harald Welte + * * 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 @@ -23,6 +26,7 @@ #include #include +#include #include #include #include @@ -53,14 +57,7 @@ static struct rfid_reader_handle *rh; static struct rfid_layer2_handle *l2h; static struct rfid_protocol_handle *ph; -static int init() -{ - unsigned char buf[0x3f]; - int rc; - - printf("initializing librfid\n"); - rfid_init(); - +static int reader() { printf("opening reader handle\n"); rh = rfid_reader_open(NULL, RFID_READER_CM5121); if (!rh) { @@ -71,10 +68,16 @@ static int init() return -1; } } + return 0; +} +static int init(int layer2) +{ + unsigned char buf[0x3f]; + int rc; + printf("opening layer2 handle\n"); - l2h = rfid_layer2_init(rh, RFID_LAYER2_ISO14443A); - //l2h = rfid_layer2_init(rh, RFID_LAYER2_ISO14443B); + l2h = rfid_layer2_init(rh, layer2); if (!l2h) { fprintf(stderr, "error during iso14443a_init\n"); return -1; @@ -308,13 +311,36 @@ static int proto_by_name(const char *name) return -1; } +static char *l2_names[] = { + [RFID_LAYER2_ISO14443A] = "iso14443a", + [RFID_LAYER2_ISO14443B] = "iso14443b", + [RFID_LAYER2_ISO15693] = "iso15693", +}; + +static int l2_by_name(const char *name) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(l2_names); i++) { + if (l2_names[i] == NULL) + continue; + if (!strcasecmp(name, l2_names[i])) + return i; + } + return -1; +} + static void help(void) { - printf(" -p --protocol {tcl,mifare-ultralight,mifare-classic}\n"); + printf( " -s --scan\n" + " -p --protocol {tcl,mifare-ultralight,mifare-classic}\n" + " -l --layer2 {iso14443a,iso14443b,iso15693}\n" + " -h --help\n"); } static struct option opts[] = { { "help", 0, 0, 'h' }, + { "layer2", 1, 0, 'l' }, { "protocol", 1, 0, 'p' }, {0, 0, 0, 0} }; @@ -323,22 +349,42 @@ int main(int argc, char **argv) { int rc; char buf[0x40]; - int i, protocol = -1; + int i, protocol = -1, layer2 = -1; printf("librfid_tool - (C) 2006 by Harald Welte\n" - "This program is Free Software and has ABSOLUTELY NO WARRANTY\n\n"); + "This program is Free Software and has " + "ABSOLUTELY NO WARRANTY\n\n"); + + printf("initializing librfid\n"); + rfid_init(); while (1) { int c, option_index = 0; - c = getopt_long(argc, argv, "hp:", opts, &option_index); + c = getopt_long(argc, argv, "hp:l:s", opts, &option_index); if (c == -1) break; switch (c) { + case 's': + if (reader() < 0) + exit(1); + printf("scanning for RFID token...\n"); + i = rfid_scan(rh, &l2h, &ph); + exit(0); + break; case 'p': protocol = proto_by_name(optarg); if (protocol < 0) { - fprintf(stderr, "unknown protocol `%s'\n", optarg); + fprintf(stderr, "unknown protocol `%s'\n", + optarg); + exit(2); + } + break; + case 'l': + layer2 = l2_by_name(optarg); + if (layer2 < 0) { + fprintf(stderr, "unknown layer2 `%s'\n", + optarg); exit(2); } break; @@ -349,12 +395,25 @@ int main(int argc, char **argv) } } - if (protocol < 0) { + switch (protocol) { + case RFID_PROTOCOL_MIFARE_UL: + case RFID_PROTOCOL_MIFARE_CLASSIC: + layer2 = RFID_LAYER2_ISO14443A; + break; + case -1: fprintf(stderr, "you have to specify --protocol\n"); exit(2); } - if (init() < 0) + if (layer2 < 0) { + fprintf(stderr, "you have to specify --layer2\n"); + exit(2); + } + + if (reader() < 0) + exit(1); + + if (init(layer2) < 0) exit(1); if (l3(protocol) < 0) -- cgit v1.2.3