- 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
This commit is contained in:
parent
2f426580fa
commit
fe4ffab6d9
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -1,6 +1,17 @@
|
|||
#ifndef _RFID_LAYER2_ISO14443B_H
|
||||
#define _RFID_LAYER2_ISO14443B_H
|
||||
|
||||
#include <librfid/rfid_layer2.h>
|
||||
|
||||
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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef _RFID_SCAN_H
|
||||
#define _RFID_SCAN_H
|
||||
|
||||
#include <librfid/rfid_reader.h>
|
||||
#include <librfid/rfid_layer2.h>
|
||||
#include <librfid/rfid_protocol.h>
|
||||
|
||||
int rfid_scan(struct rfid_reader_handle *rh,
|
||||
struct rfid_layer2_handle **l2h,
|
||||
struct rfid_protocol_handle **ph);
|
||||
|
||||
#endif /* _RFID_SCAN_H */
|
|
@ -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
|
||||
|
|
52
src/rfid.c
52
src/rfid.c
|
@ -1,4 +1,6 @@
|
|||
/*
|
||||
/* librfid core
|
||||
* (C) 2005-2006 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
|
||||
|
@ -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);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* librfid - layer 2 protocol handler
|
||||
* (C) 2005 by Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2005-2006 by Harald Welte <laforge@gnumonks.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
if (optname >> 16 == 0) {
|
||||
unsigned char *optchar = optval;
|
||||
|
||||
return ph->l2->fn.getopt(ph, optname, optval, optlen);
|
||||
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;
|
||||
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 ph->l2->fn.setopt(ph, optname, optval, optlen);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* ISO 14443-3 A anticollision implementation
|
||||
*
|
||||
* (C) 2005 by Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2005-2006 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
|||
#include <librfid/rfid_layer2.h>
|
||||
#include <librfid/rfid_reader.h>
|
||||
#include <librfid/rfid_layer2_iso14443a.h>
|
||||
#include <librfid/rfid_protocol.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* ISO 14443-3 B anticollision implementation
|
||||
*
|
||||
* (C) 2005 by Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2005-2006 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -22,17 +22,22 @@
|
|||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <librfid/rfid.h>
|
||||
#include <librfid/rfid_layer2.h>
|
||||
#include <librfid/rfid_reader.h>
|
||||
#include <librfid/rfid_layer2_iso14443b.h>
|
||||
#include <librfid/rfid_protocol.h>
|
||||
|
||||
#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,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Omnikey CardMan 5121 specific RC632 transport layer
|
||||
*
|
||||
* (C) 2005 by Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2005-2006 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
* 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 <librfid/rfid_asic.h>
|
||||
#include <librfid/rfid_asic_rc632.h>
|
||||
#include <librfid/rfid_reader_cm5121.h>
|
||||
#include <librfid/rfid_layer2.h>
|
||||
#include <librfid/rfid_protocol.h>
|
||||
|
||||
#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,
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
#include <librfid/rfid_asic.h>
|
||||
#include <librfid/rfid_asic_rc632.h>
|
||||
#include <librfid/rfid_reader_openpcd.h>
|
||||
#include <librfid/rfid_layer2.h>
|
||||
#include <librfid/rfid_protocol.h>
|
||||
|
||||
/* 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,
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
/* RFID scanning implementation
|
||||
*
|
||||
* (C) 2006 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 <librfid/rfid.h>
|
||||
#include <librfid/rfid_layer2.h>
|
||||
#include <librfid/rfid_reader.h>
|
||||
#include <librfid/rfid_protocol.h>
|
||||
|
||||
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;
|
||||
}
|
|
@ -1,4 +1,7 @@
|
|||
/*
|
||||
/* librfid-tool - a small command-line tool for librfid testing
|
||||
*
|
||||
* (C) 2005-2006 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
|
||||
|
@ -23,6 +26,7 @@
|
|||
#include <getopt.h>
|
||||
|
||||
#include <librfid/rfid.h>
|
||||
#include <librfid/rfid_scan.h>
|
||||
#include <librfid/rfid_reader.h>
|
||||
#include <librfid/rfid_layer2.h>
|
||||
#include <librfid/rfid_protocol.h>
|
||||
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue