bla
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
LIBVERSION= 0:0:0
|
||||
|
||||
if ENABLE_FIRMWARE
|
||||
INCLUDES_FIRMWARE = -I$(FIRMWARE_PATH)/include -I$(FIRMWARE_PATH)/src -I$(GNUARM_PATH)/arm-elf/include
|
||||
AM_CFLAGS_FIRMWARE = -DLIBRFID_FIRMWARE -DLIBRFID_STATIC -D__MS_types__
|
||||
endif
|
||||
|
||||
if ENABLE_STATIC
|
||||
AM_CFLAGS_STATIC = -DLIBRFID_STATIC
|
||||
endif
|
||||
|
||||
noinst_HEADERS=rfid_iso14443_common.h rc632.h libusb_dyn.h usleep.h
|
||||
|
||||
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
|
||||
ASIC=rfid_asic_rc632.c
|
||||
READER=rfid_reader_openpcd.c
|
||||
MISC=rfid_access_mifare_classic.c
|
||||
|
||||
if ENABLE_WIN32
|
||||
WIN32=usleep.c libusb_dyn.c
|
||||
AM_LDLAGS_WIN32=-mno-cygwin -lwinmm
|
||||
AM_CFLAGS_WIN32=-mno-cygwin
|
||||
endif
|
||||
|
||||
if ENABLE_CCID
|
||||
READER_CM5121=rfid_reader_cm5121.c ccid/rfid_reader_cm5121_ccid_direct.c ccid/ccid-driver.c
|
||||
AM_CFLAGS_CM5121= -DENABLE_CM5121
|
||||
endif
|
||||
|
||||
if HAVE_OPENCT
|
||||
READER_CM5121=rfid_reader_cm5121.c rfid_reader_cm5121_openct.c
|
||||
AM_CFLAGS_CM5121= -DENABLE_CM5121
|
||||
endif
|
||||
|
||||
INCLUDES = $(all_includes) -I$(top_srcdir)/include $(INCLUDES_FIRMWARE) \
|
||||
$(INCLUDES_STATIC) @OPENCT_CFLAGS@
|
||||
AM_CFLAGS = -std=gnu99 -D__LIBRFID__ $(AM_CFLAGS_FIRMWARE) $(AM_CFLAGS_STATIC) \
|
||||
$(AM_CFLAGS_CM5121) $(AM_CFLAGS_WIN32)
|
||||
|
||||
lib_LTLIBRARIES = librfid.la
|
||||
librfid_la_LDFLAGS = -Wc,-nostartfiles -version-info $(LIBVERSION) $(AM_LDFLAGS_WIN32) @OPENCT_LIBS@
|
||||
librfid_la_SOURCES = $(CORE) $(L2) $(PROTO) $(ASIC) $(MISC) \
|
||||
$(READER) $(READER_CM5121) $(WIN32)
|
||||
|
||||
if ENABLE_WIN32
|
||||
librfid_la_LIBADD = -lwinmm
|
||||
endif
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = librfid.pc
|
||||
@@ -0,0 +1,643 @@
|
||||
# Makefile.in generated by automake 1.11 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
|
||||
# Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
|
||||
|
||||
VPATH = @srcdir@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
target_triplet = @target@
|
||||
subdir = src
|
||||
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
|
||||
$(srcdir)/Makefile.in $(srcdir)/librfid.pc.in
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/configure.in
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_CLEAN_FILES = librfid.pc
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
*) f=$$p;; \
|
||||
esac;
|
||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
||||
am__install_max = 40
|
||||
am__nobase_strip_setup = \
|
||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
||||
am__nobase_strip = \
|
||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
||||
am__nobase_list = $(am__nobase_strip_setup); \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
||||
if (++n[$$2] == $(am__install_max)) \
|
||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
||||
END { for (dir in files) print dir, files[dir] }'
|
||||
am__base_list = \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
||||
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)"
|
||||
LTLIBRARIES = $(lib_LTLIBRARIES)
|
||||
librfid_la_DEPENDENCIES =
|
||||
am__librfid_la_SOURCES_DIST = rfid.c rfid_layer2.c rfid_protocol.c \
|
||||
rfid_reader.c rfid_scan.c rfid_layer2_iso14443a.c \
|
||||
rfid_layer2_iso14443b.c rfid_layer2_iso15693.c \
|
||||
rfid_iso14443_common.c rfid_proto_tcl.c rfid_proto_mifare_ul.c \
|
||||
rfid_proto_mifare_classic.c rfid_asic_rc632.c \
|
||||
rfid_access_mifare_classic.c rfid_reader_openpcd.c \
|
||||
rfid_reader_cm5121.c ccid/rfid_reader_cm5121_ccid_direct.c \
|
||||
ccid/ccid-driver.c rfid_reader_cm5121_openct.c usleep.c \
|
||||
libusb_dyn.c
|
||||
am__objects_1 = rfid.lo rfid_layer2.lo rfid_protocol.lo rfid_reader.lo \
|
||||
rfid_scan.lo
|
||||
am__objects_2 = rfid_layer2_iso14443a.lo rfid_layer2_iso14443b.lo \
|
||||
rfid_layer2_iso15693.lo rfid_iso14443_common.lo
|
||||
am__objects_3 = rfid_proto_tcl.lo rfid_proto_mifare_ul.lo \
|
||||
rfid_proto_mifare_classic.lo
|
||||
am__objects_4 = rfid_asic_rc632.lo
|
||||
am__objects_5 = rfid_access_mifare_classic.lo
|
||||
am__objects_6 = rfid_reader_openpcd.lo
|
||||
@ENABLE_CCID_FALSE@@HAVE_OPENCT_TRUE@am__objects_7 = \
|
||||
@ENABLE_CCID_FALSE@@HAVE_OPENCT_TRUE@ rfid_reader_cm5121.lo \
|
||||
@ENABLE_CCID_FALSE@@HAVE_OPENCT_TRUE@ rfid_reader_cm5121_openct.lo
|
||||
@ENABLE_CCID_TRUE@am__objects_7 = rfid_reader_cm5121.lo \
|
||||
@ENABLE_CCID_TRUE@ rfid_reader_cm5121_ccid_direct.lo \
|
||||
@ENABLE_CCID_TRUE@ ccid-driver.lo
|
||||
@ENABLE_WIN32_TRUE@am__objects_8 = usleep.lo libusb_dyn.lo
|
||||
am_librfid_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
|
||||
$(am__objects_3) $(am__objects_4) $(am__objects_5) \
|
||||
$(am__objects_6) $(am__objects_7) $(am__objects_8)
|
||||
librfid_la_OBJECTS = $(am_librfid_la_OBJECTS)
|
||||
librfid_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
$(librfid_la_LDFLAGS) $(LDFLAGS) -o $@
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
am__mv = mv -f
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
CCLD = $(CC)
|
||||
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
|
||||
$(LDFLAGS) -o $@
|
||||
SOURCES = $(librfid_la_SOURCES)
|
||||
DIST_SOURCES = $(am__librfid_la_SOURCES_DIST)
|
||||
DATA = $(pkgconfig_DATA)
|
||||
HEADERS = $(noinst_HEADERS)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AR = @AR@
|
||||
AS = @AS@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
BUILDENV = @BUILDENV@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
FIRMWARE_PATH = @FIRMWARE_PATH@
|
||||
GREP = @GREP@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LD = @LD@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIBTOOL_DEPS = @LIBTOOL_DEPS@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
OPENCT_CFLAGS = @OPENCT_CFLAGS@
|
||||
OPENCT_LIBS = @OPENCT_LIBS@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
RANLIB = @RANLIB@
|
||||
SED = @SED@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target = @target@
|
||||
target_alias = @target_alias@
|
||||
target_cpu = @target_cpu@
|
||||
target_os = @target_os@
|
||||
target_vendor = @target_vendor@
|
||||
to_host_path_cmd = @to_host_path_cmd@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
LIBVERSION = 0:0:0
|
||||
@ENABLE_FIRMWARE_TRUE@INCLUDES_FIRMWARE = -I$(FIRMWARE_PATH)/include -I$(FIRMWARE_PATH)/src -I$(GNUARM_PATH)/arm-elf/include
|
||||
@ENABLE_FIRMWARE_TRUE@AM_CFLAGS_FIRMWARE = -DLIBRFID_FIRMWARE -DLIBRFID_STATIC -D__MS_types__
|
||||
@ENABLE_STATIC_TRUE@AM_CFLAGS_STATIC = -DLIBRFID_STATIC
|
||||
noinst_HEADERS = rfid_iso14443_common.h rc632.h libusb_dyn.h usleep.h
|
||||
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
|
||||
ASIC = rfid_asic_rc632.c
|
||||
READER = rfid_reader_openpcd.c
|
||||
MISC = rfid_access_mifare_classic.c
|
||||
@ENABLE_WIN32_TRUE@WIN32 = usleep.c libusb_dyn.c
|
||||
@ENABLE_WIN32_TRUE@AM_LDLAGS_WIN32 = -mno-cygwin -lwinmm
|
||||
@ENABLE_WIN32_TRUE@AM_CFLAGS_WIN32 = -mno-cygwin
|
||||
@ENABLE_CCID_TRUE@READER_CM5121 = rfid_reader_cm5121.c ccid/rfid_reader_cm5121_ccid_direct.c ccid/ccid-driver.c
|
||||
@HAVE_OPENCT_TRUE@READER_CM5121 = rfid_reader_cm5121.c rfid_reader_cm5121_openct.c
|
||||
@ENABLE_CCID_TRUE@AM_CFLAGS_CM5121 = -DENABLE_CM5121
|
||||
@HAVE_OPENCT_TRUE@AM_CFLAGS_CM5121 = -DENABLE_CM5121
|
||||
INCLUDES = $(all_includes) -I$(top_srcdir)/include $(INCLUDES_FIRMWARE) \
|
||||
$(INCLUDES_STATIC) @OPENCT_CFLAGS@
|
||||
|
||||
AM_CFLAGS = -std=gnu99 -D__LIBRFID__ $(AM_CFLAGS_FIRMWARE) $(AM_CFLAGS_STATIC) \
|
||||
$(AM_CFLAGS_CM5121) $(AM_CFLAGS_WIN32)
|
||||
|
||||
lib_LTLIBRARIES = librfid.la
|
||||
librfid_la_LDFLAGS = -Wc,-nostartfiles -version-info $(LIBVERSION) $(AM_LDFLAGS_WIN32) @OPENCT_LIBS@
|
||||
librfid_la_SOURCES = $(CORE) $(L2) $(PROTO) $(ASIC) $(MISC) \
|
||||
$(READER) $(READER_CM5121) $(WIN32)
|
||||
|
||||
@ENABLE_WIN32_TRUE@librfid_la_LIBADD = -lwinmm
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = librfid.pc
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .lo .o .obj
|
||||
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu src/Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
librfid.pc: $(top_builddir)/config.status $(srcdir)/librfid.pc.in
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
|
||||
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
|
||||
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
|
||||
list2=; for p in $$list; do \
|
||||
if test -f $$p; then \
|
||||
list2="$$list2 $$p"; \
|
||||
else :; fi; \
|
||||
done; \
|
||||
test -z "$$list2" || { \
|
||||
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
|
||||
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
|
||||
}
|
||||
|
||||
uninstall-libLTLIBRARIES:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
|
||||
for p in $$list; do \
|
||||
$(am__strip_dir) \
|
||||
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
|
||||
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
|
||||
done
|
||||
|
||||
clean-libLTLIBRARIES:
|
||||
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
|
||||
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
|
||||
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
|
||||
test "$$dir" != "$$p" || dir=.; \
|
||||
echo "rm -f \"$${dir}/so_locations\""; \
|
||||
rm -f "$${dir}/so_locations"; \
|
||||
done
|
||||
librfid.la: $(librfid_la_OBJECTS) $(librfid_la_DEPENDENCIES)
|
||||
$(librfid_la_LINK) -rpath $(libdir) $(librfid_la_OBJECTS) $(librfid_la_LIBADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ccid-driver.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_dyn.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfid.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfid_access_mifare_classic.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfid_asic_rc632.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfid_iso14443_common.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfid_layer2.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfid_layer2_iso14443a.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfid_layer2_iso14443b.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfid_layer2_iso15693.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfid_proto_mifare_classic.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfid_proto_mifare_ul.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfid_proto_tcl.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfid_protocol.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfid_reader.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfid_reader_cm5121.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfid_reader_cm5121_ccid_direct.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfid_reader_cm5121_openct.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfid_reader_openpcd.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfid_scan.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/usleep.Plo@am__quote@
|
||||
|
||||
.c.o:
|
||||
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
|
||||
|
||||
.c.obj:
|
||||
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
|
||||
|
||||
.c.lo:
|
||||
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
|
||||
|
||||
rfid_reader_cm5121_ccid_direct.lo: ccid/rfid_reader_cm5121_ccid_direct.c
|
||||
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rfid_reader_cm5121_ccid_direct.lo -MD -MP -MF $(DEPDIR)/rfid_reader_cm5121_ccid_direct.Tpo -c -o rfid_reader_cm5121_ccid_direct.lo `test -f 'ccid/rfid_reader_cm5121_ccid_direct.c' || echo '$(srcdir)/'`ccid/rfid_reader_cm5121_ccid_direct.c
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/rfid_reader_cm5121_ccid_direct.Tpo $(DEPDIR)/rfid_reader_cm5121_ccid_direct.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ccid/rfid_reader_cm5121_ccid_direct.c' object='rfid_reader_cm5121_ccid_direct.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rfid_reader_cm5121_ccid_direct.lo `test -f 'ccid/rfid_reader_cm5121_ccid_direct.c' || echo '$(srcdir)/'`ccid/rfid_reader_cm5121_ccid_direct.c
|
||||
|
||||
ccid-driver.lo: ccid/ccid-driver.c
|
||||
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ccid-driver.lo -MD -MP -MF $(DEPDIR)/ccid-driver.Tpo -c -o ccid-driver.lo `test -f 'ccid/ccid-driver.c' || echo '$(srcdir)/'`ccid/ccid-driver.c
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/ccid-driver.Tpo $(DEPDIR)/ccid-driver.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ccid/ccid-driver.c' object='ccid-driver.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ccid-driver.lo `test -f 'ccid/ccid-driver.c' || echo '$(srcdir)/'`ccid/ccid-driver.c
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
install-pkgconfigDATA: $(pkgconfig_DATA)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)"
|
||||
@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
|
||||
for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
echo "$$d$$p"; \
|
||||
done | $(am__base_list) | \
|
||||
while read files; do \
|
||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
|
||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
|
||||
done
|
||||
|
||||
uninstall-pkgconfigDATA:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
|
||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
||||
test -n "$$files" || exit 0; \
|
||||
echo " ( cd '$(DESTDIR)$(pkgconfigdir)' && rm -f" $$files ")"; \
|
||||
cd "$(DESTDIR)$(pkgconfigdir)" && rm -f $$files
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
mkid -fID $$unique
|
||||
tags: TAGS
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
set x; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
if test $$# -gt 0; then \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
"$$@" $$unique; \
|
||||
else \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: CTAGS
|
||||
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
test -z "$(CTAGS_ARGS)$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS)
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
|
||||
mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am: install-pkgconfigDATA
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am: install-libLTLIBRARIES
|
||||
|
||||
install-html: install-html-am
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-am
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-libLTLIBRARIES uninstall-pkgconfigDATA
|
||||
|
||||
.MAKE: install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
|
||||
clean-libLTLIBRARIES clean-libtool ctags distclean \
|
||||
distclean-compile distclean-generic distclean-libtool \
|
||||
distclean-tags distdir dvi dvi-am html html-am info info-am \
|
||||
install install-am install-data install-data-am install-dvi \
|
||||
install-dvi-am install-exec install-exec-am install-html \
|
||||
install-html-am install-info install-info-am \
|
||||
install-libLTLIBRARIES install-man install-pdf install-pdf-am \
|
||||
install-pkgconfigDATA install-ps install-ps-am install-strip \
|
||||
installcheck installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||
tags uninstall uninstall-am uninstall-libLTLIBRARIES \
|
||||
uninstall-pkgconfigDATA
|
||||
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,108 @@
|
||||
/* ccid-driver.c - USB ChipCardInterfaceDevices driver
|
||||
* Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*
|
||||
* ALTERNATIVELY, this file may be distributed under the terms of the
|
||||
* following license, in which case the provisions of this license are
|
||||
* required INSTEAD OF the GNU General Public License. If you wish to
|
||||
* allow use of your version of this file only under the terms of the
|
||||
* GNU General Public License, and not to allow others to use your
|
||||
* version of this file under the terms of the following license,
|
||||
* indicate your decision by deleting this paragraph and the license
|
||||
* below.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, and the entire permission notice in its entirety,
|
||||
* including the disclaimer of warranties.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: ccid-driver.h 3887 2005-09-09 11:18:08Z wk $
|
||||
*/
|
||||
|
||||
#ifndef CCID_DRIVER_H
|
||||
#define CCID_DRIVER_H
|
||||
|
||||
/* The CID driver returns the same error codes as the status words
|
||||
used by GnuPG's apdu.h. For ease of maintenance they should always
|
||||
match. */
|
||||
#define CCID_DRIVER_ERR_OUT_OF_CORE 0x10001
|
||||
#define CCID_DRIVER_ERR_INV_VALUE 0x10002
|
||||
#define CCID_DRIVER_ERR_INCOMPLETE_CARD_RESPONSE = 0x10003
|
||||
#define CCID_DRIVER_ERR_NO_DRIVER 0x10004
|
||||
#define CCID_DRIVER_ERR_NOT_SUPPORTED 0x10005
|
||||
#define CCID_DRIVER_ERR_LOCKING_FAILED 0x10006
|
||||
#define CCID_DRIVER_ERR_BUSY 0x10007
|
||||
#define CCID_DRIVER_ERR_NO_CARD 0x10008
|
||||
#define CCID_DRIVER_ERR_CARD_INACTIVE 0x10009
|
||||
#define CCID_DRIVER_ERR_CARD_IO_ERROR 0x1000a
|
||||
#define CCID_DRIVER_ERR_GENERAL_ERROR 0x1000b
|
||||
#define CCID_DRIVER_ERR_NO_READER 0x1000c
|
||||
#define CCID_DRIVER_ERR_ABORTED 0x1000d
|
||||
#define CCID_DRIVER_ERR_NO_KEYPAD 0x1000e
|
||||
|
||||
struct ccid_driver_s;
|
||||
typedef struct ccid_driver_s *ccid_driver_t;
|
||||
|
||||
int ccid_set_debug_level (int level);
|
||||
char *ccid_get_reader_list (void);
|
||||
int ccid_open_reader (ccid_driver_t *handle, const char *readerid);
|
||||
int ccid_shutdown_reader (ccid_driver_t handle);
|
||||
int ccid_close_reader (ccid_driver_t handle);
|
||||
int ccid_get_atr (ccid_driver_t handle,
|
||||
unsigned char *atr, size_t maxatrlen, size_t *atrlen);
|
||||
int ccid_slot_status (ccid_driver_t handle, int *statusbits);
|
||||
int ccid_transceive (ccid_driver_t handle,
|
||||
const unsigned char *apdu, size_t apdulen,
|
||||
unsigned char *resp, size_t maxresplen, size_t *nresp);
|
||||
int ccid_transceive_secure (ccid_driver_t handle,
|
||||
const unsigned char *apdu, size_t apdulen,
|
||||
int pin_mode,
|
||||
int pinlen_min, int pinlen_max, int pin_padlen,
|
||||
unsigned char *resp, size_t maxresplen, size_t *nresp);
|
||||
int ccid_transceive_escape (ccid_driver_t handle,
|
||||
const unsigned char *data, size_t datalen,
|
||||
unsigned char *resp, size_t maxresplen,
|
||||
size_t *nresp);
|
||||
|
||||
|
||||
|
||||
#endif /*CCID_DRIVER_H*/
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/* CM5121 backend for 'internal' CCID driver */
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <librfid/rfid.h>
|
||||
|
||||
#ifndef LIBRFID_FIRMWARE
|
||||
|
||||
#include <librfid/rfid_asic.h>
|
||||
|
||||
#include "ccid-driver.h"
|
||||
|
||||
/* this is the sole function required by rfid_reader_cm5121.c */
|
||||
int
|
||||
PC_to_RDR_Escape(void *handle,
|
||||
const unsigned char *tx_buf, size_t tx_len,
|
||||
unsigned char *rx_buf, size_t *rx_len)
|
||||
{
|
||||
int rc;
|
||||
ccid_driver_t ch = handle;
|
||||
size_t maxrxlen = *rx_len;
|
||||
|
||||
rc = ccid_transceive_escape (ch, tx_buf, tx_len,
|
||||
rx_buf, maxrxlen, rx_len);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cm5121_source_init(struct rfid_asic_transport_handle *rath)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = ccid_open_reader(&rath->data, NULL);
|
||||
if (rc) {
|
||||
fprintf (stderr, "failed to open CCID reader: %#x\n", rc);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* LIBRFID_FIRMWARE */
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
extern int cm5121_source_init(struct rfid_asic_transport_handle *rath);
|
||||
@@ -0,0 +1,11 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
sysincludedir=@sysincludedir@
|
||||
|
||||
Name: librfid
|
||||
Description: librfid
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} @LIBS@ -lrfid
|
||||
Cflags: -I${sysincludedir} -I${includedir}
|
||||
@@ -0,0 +1,484 @@
|
||||
/* LIBUSB-WIN32, Generic Windows USB Library
|
||||
* Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "libusb_dyn.h"
|
||||
|
||||
#define LIBUSB_DLL_NAME "libusb0.dll"
|
||||
|
||||
typedef usb_dev_handle * (*usb_open_t)(struct usb_device *dev);
|
||||
typedef int (*usb_close_t)(usb_dev_handle *dev);
|
||||
typedef int (*usb_get_string_t)(usb_dev_handle *dev, int index, int langid,
|
||||
char *buf, size_t buflen);
|
||||
typedef int (*usb_get_string_simple_t)(usb_dev_handle *dev, int index,
|
||||
char *buf, size_t buflen);
|
||||
typedef int (*usb_get_descriptor_by_endpoint_t)(usb_dev_handle *udev, int ep,
|
||||
unsigned char type,
|
||||
unsigned char index,
|
||||
void *buf, int size);
|
||||
typedef int (*usb_get_descriptor_t)(usb_dev_handle *udev, unsigned char type,
|
||||
unsigned char index, void *buf, int size);
|
||||
typedef int (*usb_bulk_write_t)(usb_dev_handle *dev, int ep, char *bytes,
|
||||
int size, int timeout);
|
||||
typedef int (*usb_bulk_read_t)(usb_dev_handle *dev, int ep, char *bytes,
|
||||
int size, int timeout);
|
||||
typedef int (*usb_interrupt_write_t)(usb_dev_handle *dev, int ep, char *bytes,
|
||||
int size, int timeout);
|
||||
typedef int (*usb_interrupt_read_t)(usb_dev_handle *dev, int ep, char *bytes,
|
||||
int size, int timeout);
|
||||
typedef int (*usb_control_msg_t)(usb_dev_handle *dev, int requesttype,
|
||||
int request, int value, int index,
|
||||
char *bytes, int size, int timeout);
|
||||
typedef int (*usb_set_configuration_t)(usb_dev_handle *dev, int configuration);
|
||||
typedef int (*usb_claim_interface_t)(usb_dev_handle *dev, int interface);
|
||||
typedef int (*usb_release_interface_t)(usb_dev_handle *dev, int interface);
|
||||
typedef int (*usb_set_altinterface_t)(usb_dev_handle *dev, int alternate);
|
||||
typedef int (*usb_resetep_t)(usb_dev_handle *dev, unsigned int ep);
|
||||
typedef int (*usb_clear_halt_t)(usb_dev_handle *dev, unsigned int ep);
|
||||
typedef int (*usb_reset_t)(usb_dev_handle *dev);
|
||||
typedef char * (*usb_strerror_t)(void);
|
||||
typedef void (*usb_init_t)(void);
|
||||
typedef void (*usb_set_debug_t)(int level);
|
||||
typedef int (*usb_find_busses_t)(void);
|
||||
typedef int (*usb_find_devices_t)(void);
|
||||
typedef struct usb_device * (*usb_device_t)(usb_dev_handle *dev);
|
||||
typedef struct usb_bus * (*usb_get_busses_t)(void);
|
||||
typedef int (*usb_install_service_np_t)(void);
|
||||
typedef int (*usb_uninstall_service_np_t)(void);
|
||||
typedef int (*usb_install_driver_np_t)(const char *inf_file);
|
||||
typedef const struct usb_version * (*usb_get_version_t)(void);
|
||||
typedef int (*usb_isochronous_setup_async_t)(usb_dev_handle *dev,
|
||||
void **context,
|
||||
unsigned char ep, int pktsize);
|
||||
typedef int (*usb_bulk_setup_async_t)(usb_dev_handle *dev, void **context,
|
||||
unsigned char ep);
|
||||
typedef int (*usb_interrupt_setup_async_t)(usb_dev_handle *dev, void **context,
|
||||
unsigned char ep);
|
||||
typedef int (*usb_submit_async_t)(void *context, char *bytes, int size);
|
||||
typedef int (*usb_reap_async_t)(void *context, int timeout);
|
||||
typedef int (*usb_free_async_t)(void **context);
|
||||
|
||||
|
||||
static usb_open_t _usb_open = NULL;
|
||||
static usb_close_t _usb_close = NULL;
|
||||
static usb_get_string_t _usb_get_string = NULL;
|
||||
static usb_get_string_simple_t _usb_get_string_simple = NULL;
|
||||
static usb_get_descriptor_by_endpoint_t _usb_get_descriptor_by_endpoint = NULL;
|
||||
static usb_get_descriptor_t _usb_get_descriptor = NULL;
|
||||
static usb_bulk_write_t _usb_bulk_write = NULL;
|
||||
static usb_bulk_read_t _usb_bulk_read = NULL;
|
||||
static usb_interrupt_write_t _usb_interrupt_write = NULL;
|
||||
static usb_interrupt_read_t _usb_interrupt_read = NULL;
|
||||
static usb_control_msg_t _usb_control_msg = NULL;
|
||||
static usb_set_configuration_t _usb_set_configuration = NULL;
|
||||
static usb_claim_interface_t _usb_claim_interface = NULL;
|
||||
static usb_release_interface_t _usb_release_interface = NULL;
|
||||
static usb_set_altinterface_t _usb_set_altinterface = NULL;
|
||||
static usb_resetep_t _usb_resetep = NULL;
|
||||
static usb_clear_halt_t _usb_clear_halt = NULL;
|
||||
static usb_reset_t _usb_reset = NULL;
|
||||
static usb_strerror_t _usb_strerror = NULL;
|
||||
static usb_init_t _usb_init = NULL;
|
||||
static usb_set_debug_t _usb_set_debug = NULL;
|
||||
static usb_find_busses_t _usb_find_busses = NULL;
|
||||
static usb_find_devices_t _usb_find_devices = NULL;
|
||||
static usb_device_t _usb_device = NULL;
|
||||
static usb_get_busses_t _usb_get_busses = NULL;
|
||||
static usb_install_service_np_t _usb_install_service_np = NULL;
|
||||
static usb_uninstall_service_np_t _usb_uninstall_service_np = NULL;
|
||||
static usb_install_driver_np_t _usb_install_driver_np = NULL;
|
||||
static usb_get_version_t _usb_get_version = NULL;
|
||||
static usb_isochronous_setup_async_t _usb_isochronous_setup_async = NULL;
|
||||
static usb_bulk_setup_async_t _usb_bulk_setup_async = NULL;
|
||||
static usb_interrupt_setup_async_t _usb_interrupt_setup_async = NULL;
|
||||
static usb_submit_async_t _usb_submit_async = NULL;
|
||||
static usb_reap_async_t _usb_reap_async = NULL;
|
||||
static usb_free_async_t _usb_free_async = NULL;
|
||||
|
||||
|
||||
void usb_init(void)
|
||||
{
|
||||
HINSTANCE libusb_dll = LoadLibrary(LIBUSB_DLL_NAME);
|
||||
|
||||
if(!libusb_dll)
|
||||
return;
|
||||
|
||||
timeBeginPeriod(1);
|
||||
|
||||
_usb_open = (usb_open_t)
|
||||
GetProcAddress(libusb_dll, "usb_open");
|
||||
_usb_close = (usb_close_t)
|
||||
GetProcAddress(libusb_dll, "usb_close");
|
||||
_usb_get_string = (usb_get_string_t)
|
||||
GetProcAddress(libusb_dll, "usb_get_string");
|
||||
_usb_get_string_simple = (usb_get_string_simple_t)
|
||||
GetProcAddress(libusb_dll, "usb_get_string_simple");
|
||||
_usb_get_descriptor_by_endpoint = (usb_get_descriptor_by_endpoint_t)
|
||||
GetProcAddress(libusb_dll, "usb_get_descriptor_by_endpoint");
|
||||
_usb_get_descriptor = (usb_get_descriptor_t)
|
||||
GetProcAddress(libusb_dll, "usb_get_descriptor");
|
||||
_usb_bulk_write = (usb_bulk_write_t)
|
||||
GetProcAddress(libusb_dll, "usb_bulk_write");
|
||||
_usb_bulk_read = (usb_bulk_read_t)
|
||||
GetProcAddress(libusb_dll, "usb_bulk_read");
|
||||
_usb_interrupt_write = (usb_interrupt_write_t)
|
||||
GetProcAddress(libusb_dll, "usb_interrupt_write");
|
||||
_usb_interrupt_read = (usb_interrupt_read_t)
|
||||
GetProcAddress(libusb_dll, "usb_interrupt_read");
|
||||
_usb_control_msg = (usb_control_msg_t)
|
||||
GetProcAddress(libusb_dll, "usb_control_msg");
|
||||
_usb_set_configuration = (usb_set_configuration_t)
|
||||
GetProcAddress(libusb_dll, "usb_set_configuration");
|
||||
_usb_claim_interface = (usb_claim_interface_t)
|
||||
GetProcAddress(libusb_dll, "usb_claim_interface");
|
||||
_usb_release_interface = (usb_release_interface_t)
|
||||
GetProcAddress(libusb_dll, "usb_release_interface");
|
||||
_usb_set_altinterface = (usb_set_altinterface_t)
|
||||
GetProcAddress(libusb_dll, "usb_set_altinterface");
|
||||
_usb_resetep = (usb_resetep_t)
|
||||
GetProcAddress(libusb_dll, "usb_resetep");
|
||||
_usb_clear_halt = (usb_clear_halt_t)
|
||||
GetProcAddress(libusb_dll, "usb_clear_halt");
|
||||
_usb_reset = (usb_reset_t)
|
||||
GetProcAddress(libusb_dll, "usb_reset");
|
||||
_usb_strerror = (usb_strerror_t)
|
||||
GetProcAddress(libusb_dll, "usb_strerror");
|
||||
_usb_init = (usb_init_t)
|
||||
GetProcAddress(libusb_dll, "usb_init");
|
||||
_usb_set_debug = (usb_set_debug_t)
|
||||
GetProcAddress(libusb_dll, "usb_set_debug");
|
||||
_usb_find_busses = (usb_find_busses_t)
|
||||
GetProcAddress(libusb_dll, "usb_find_busses");
|
||||
_usb_find_devices = (usb_find_devices_t)
|
||||
GetProcAddress(libusb_dll, "usb_find_devices");
|
||||
_usb_device = (usb_device_t)
|
||||
GetProcAddress(libusb_dll, "usb_device");
|
||||
_usb_get_busses = (usb_get_busses_t)
|
||||
GetProcAddress(libusb_dll, "usb_get_busses");
|
||||
_usb_install_service_np = (usb_install_service_np_t)
|
||||
GetProcAddress(libusb_dll, "usb_install_service_np");
|
||||
_usb_uninstall_service_np = (usb_uninstall_service_np_t)
|
||||
GetProcAddress(libusb_dll, "usb_uninstall_service_np");
|
||||
_usb_install_driver_np = (usb_install_driver_np_t)
|
||||
GetProcAddress(libusb_dll, "usb_install_driver_np");
|
||||
_usb_get_version = (usb_get_version_t)
|
||||
GetProcAddress(libusb_dll, "usb_get_version");
|
||||
_usb_isochronous_setup_async = (usb_isochronous_setup_async_t)
|
||||
GetProcAddress(libusb_dll, "usb_isochronous_setup_async");
|
||||
_usb_bulk_setup_async = (usb_bulk_setup_async_t)
|
||||
GetProcAddress(libusb_dll, "usb_bulk_setup_async");
|
||||
_usb_interrupt_setup_async = (usb_interrupt_setup_async_t)
|
||||
GetProcAddress(libusb_dll, "usb_interrupt_setup_async");
|
||||
_usb_submit_async = (usb_submit_async_t)
|
||||
GetProcAddress(libusb_dll, "usb_submit_async");
|
||||
_usb_reap_async = (usb_reap_async_t)
|
||||
GetProcAddress(libusb_dll, "usb_reap_async");
|
||||
_usb_free_async = (usb_free_async_t)
|
||||
GetProcAddress(libusb_dll, "usb_free_async");
|
||||
|
||||
if(_usb_init)
|
||||
_usb_init();
|
||||
}
|
||||
|
||||
usb_dev_handle *usb_open(struct usb_device *dev)
|
||||
{
|
||||
if(_usb_open)
|
||||
return _usb_open(dev);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int usb_close(usb_dev_handle *dev)
|
||||
{
|
||||
if(_usb_close)
|
||||
return _usb_close(dev);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf,
|
||||
size_t buflen)
|
||||
{
|
||||
if(_usb_get_string)
|
||||
return _usb_get_string(dev, index, langid, buf, buflen);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf,
|
||||
size_t buflen)
|
||||
{
|
||||
if(_usb_get_string_simple)
|
||||
return _usb_get_string_simple(dev, index, buf, buflen);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_get_descriptor_by_endpoint(usb_dev_handle *udev, int ep,
|
||||
unsigned char type, unsigned char index,
|
||||
void *buf, int size)
|
||||
{
|
||||
if(_usb_get_descriptor_by_endpoint)
|
||||
return _usb_get_descriptor_by_endpoint(udev, ep, type, index, buf, size);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_get_descriptor(usb_dev_handle *udev, unsigned char type,
|
||||
unsigned char index, void *buf, int size)
|
||||
{
|
||||
if(_usb_get_descriptor)
|
||||
return _usb_get_descriptor(udev, type, index, buf, size);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size,
|
||||
int timeout)
|
||||
{
|
||||
if(_usb_bulk_write)
|
||||
return _usb_bulk_write(dev, ep, bytes, size, timeout);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size,
|
||||
int timeout)
|
||||
{
|
||||
if(_usb_bulk_read)
|
||||
return _usb_bulk_read(dev, ep, bytes, size, timeout);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size,
|
||||
int timeout)
|
||||
{
|
||||
if(_usb_interrupt_write)
|
||||
return _usb_interrupt_write(dev, ep, bytes, size, timeout);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size,
|
||||
int timeout)
|
||||
{
|
||||
if(_usb_interrupt_read)
|
||||
return _usb_interrupt_read(dev, ep, bytes, size, timeout);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_control_msg(usb_dev_handle *dev, int requesttype, int request,
|
||||
int value, int index, char *bytes, int size,
|
||||
int timeout)
|
||||
{
|
||||
if(_usb_control_msg)
|
||||
return _usb_control_msg(dev, requesttype, request, value, index, bytes,
|
||||
size, timeout);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_set_configuration(usb_dev_handle *dev, int configuration)
|
||||
{
|
||||
if(_usb_set_configuration)
|
||||
return _usb_set_configuration(dev, configuration);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_claim_interface(usb_dev_handle *dev, int interface)
|
||||
{
|
||||
if(_usb_claim_interface)
|
||||
return _usb_claim_interface(dev, interface);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_release_interface(usb_dev_handle *dev, int interface)
|
||||
{
|
||||
if(_usb_release_interface)
|
||||
return _usb_release_interface(dev, interface);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_set_altinterface(usb_dev_handle *dev, int alternate)
|
||||
{
|
||||
if(_usb_set_altinterface)
|
||||
return _usb_set_altinterface(dev, alternate);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_resetep(usb_dev_handle *dev, unsigned int ep)
|
||||
{
|
||||
if(_usb_resetep)
|
||||
return _usb_resetep(dev, ep);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_clear_halt(usb_dev_handle *dev, unsigned int ep)
|
||||
{
|
||||
if(_usb_clear_halt)
|
||||
return _usb_clear_halt(dev, ep);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_reset(usb_dev_handle *dev)
|
||||
{
|
||||
if(_usb_reset)
|
||||
return _usb_reset(dev);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
char *usb_strerror(void)
|
||||
{
|
||||
if(_usb_strerror)
|
||||
return _usb_strerror();
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void usb_set_debug(int level)
|
||||
{
|
||||
if(_usb_set_debug)
|
||||
return _usb_set_debug(level);
|
||||
}
|
||||
|
||||
int usb_find_busses(void)
|
||||
{
|
||||
if(_usb_find_busses)
|
||||
return _usb_find_busses();
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_find_devices(void)
|
||||
{
|
||||
if(_usb_find_devices)
|
||||
return _usb_find_devices();
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
struct usb_device *usb_device(usb_dev_handle *dev)
|
||||
{
|
||||
if(_usb_device)
|
||||
return _usb_device(dev);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct usb_bus *usb_get_busses(void)
|
||||
{
|
||||
if(_usb_get_busses)
|
||||
return _usb_get_busses();
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int usb_install_service_np(void)
|
||||
{
|
||||
if(_usb_install_service_np)
|
||||
return _usb_install_service_np();
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_uninstall_service_np(void)
|
||||
{
|
||||
if(_usb_uninstall_service_np)
|
||||
return _usb_uninstall_service_np();
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_install_driver_np(const char *inf_file)
|
||||
{
|
||||
if(_usb_install_driver_np)
|
||||
return _usb_install_driver_np(inf_file);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
const struct usb_version *usb_get_version(void)
|
||||
{
|
||||
if(_usb_get_version)
|
||||
return _usb_get_version();
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int usb_isochronous_setup_async(usb_dev_handle *dev, void **context,
|
||||
unsigned char ep, int pktsize)
|
||||
{
|
||||
if(_usb_isochronous_setup_async)
|
||||
return _usb_isochronous_setup_async(dev, context, ep, pktsize);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_bulk_setup_async(usb_dev_handle *dev, void **context,
|
||||
unsigned char ep)
|
||||
{
|
||||
if(_usb_bulk_setup_async)
|
||||
return _usb_bulk_setup_async(dev, context, ep);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_interrupt_setup_async(usb_dev_handle *dev, void **context,
|
||||
unsigned char ep)
|
||||
{
|
||||
if(_usb_interrupt_setup_async)
|
||||
return _usb_interrupt_setup_async(dev, context, ep);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_submit_async(void *context, char *bytes, int size)
|
||||
{
|
||||
if(_usb_submit_async)
|
||||
return _usb_submit_async(context, bytes, size);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_reap_async(void *context, int timeout)
|
||||
{
|
||||
if(_usb_reap_async)
|
||||
return _usb_reap_async(context, timeout);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
|
||||
int usb_free_async(void **context)
|
||||
{
|
||||
if(_usb_free_async)
|
||||
return _usb_free_async(context);
|
||||
else
|
||||
return -ENOFILE;
|
||||
}
|
||||
@@ -0,0 +1,394 @@
|
||||
#ifndef __USB_H__
|
||||
#define __USB_H__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
|
||||
/*
|
||||
* 'interface' is defined somewhere in the Windows header files. This macro
|
||||
* is deleted here to avoid conflicts and compile errors.
|
||||
*/
|
||||
|
||||
#ifdef interface
|
||||
#undef interface
|
||||
#endif
|
||||
|
||||
/*
|
||||
* PATH_MAX from limits.h can't be used on Windows if the dll and
|
||||
* import libraries are build/used by different compilers
|
||||
*/
|
||||
|
||||
#define LIBUSB_PATH_MAX 512
|
||||
|
||||
|
||||
/*
|
||||
* USB spec information
|
||||
*
|
||||
* This is all stuff grabbed from various USB specs and is pretty much
|
||||
* not subject to change
|
||||
*/
|
||||
|
||||
/*
|
||||
* Device and/or Interface Class codes
|
||||
*/
|
||||
#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */
|
||||
#define USB_CLASS_AUDIO 1
|
||||
#define USB_CLASS_COMM 2
|
||||
#define USB_CLASS_HID 3
|
||||
#define USB_CLASS_PRINTER 7
|
||||
#define USB_CLASS_MASS_STORAGE 8
|
||||
#define USB_CLASS_HUB 9
|
||||
#define USB_CLASS_DATA 10
|
||||
#define USB_CLASS_VENDOR_SPEC 0xff
|
||||
|
||||
/*
|
||||
* Descriptor types
|
||||
*/
|
||||
#define USB_DT_DEVICE 0x01
|
||||
#define USB_DT_CONFIG 0x02
|
||||
#define USB_DT_STRING 0x03
|
||||
#define USB_DT_INTERFACE 0x04
|
||||
#define USB_DT_ENDPOINT 0x05
|
||||
|
||||
#define USB_DT_HID 0x21
|
||||
#define USB_DT_REPORT 0x22
|
||||
#define USB_DT_PHYSICAL 0x23
|
||||
#define USB_DT_HUB 0x29
|
||||
|
||||
/*
|
||||
* Descriptor sizes per descriptor type
|
||||
*/
|
||||
#define USB_DT_DEVICE_SIZE 18
|
||||
#define USB_DT_CONFIG_SIZE 9
|
||||
#define USB_DT_INTERFACE_SIZE 9
|
||||
#define USB_DT_ENDPOINT_SIZE 7
|
||||
#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */
|
||||
#define USB_DT_HUB_NONVAR_SIZE 7
|
||||
|
||||
|
||||
/* ensure byte-packed structures */
|
||||
#include <pshpack1.h>
|
||||
|
||||
|
||||
/* All standard descriptors have these 2 fields in common */
|
||||
struct usb_descriptor_header {
|
||||
unsigned char bLength;
|
||||
unsigned char bDescriptorType;
|
||||
};
|
||||
|
||||
/* String descriptor */
|
||||
struct usb_string_descriptor {
|
||||
unsigned char bLength;
|
||||
unsigned char bDescriptorType;
|
||||
unsigned short wData[1];
|
||||
};
|
||||
|
||||
/* HID descriptor */
|
||||
struct usb_hid_descriptor {
|
||||
unsigned char bLength;
|
||||
unsigned char bDescriptorType;
|
||||
unsigned short bcdHID;
|
||||
unsigned char bCountryCode;
|
||||
unsigned char bNumDescriptors;
|
||||
};
|
||||
|
||||
/* Endpoint descriptor */
|
||||
#define USB_MAXENDPOINTS 32
|
||||
struct usb_endpoint_descriptor {
|
||||
unsigned char bLength;
|
||||
unsigned char bDescriptorType;
|
||||
unsigned char bEndpointAddress;
|
||||
unsigned char bmAttributes;
|
||||
unsigned short wMaxPacketSize;
|
||||
unsigned char bInterval;
|
||||
unsigned char bRefresh;
|
||||
unsigned char bSynchAddress;
|
||||
|
||||
unsigned char *extra; /* Extra descriptors */
|
||||
int extralen;
|
||||
};
|
||||
|
||||
#define USB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */
|
||||
#define USB_ENDPOINT_DIR_MASK 0x80
|
||||
|
||||
#define USB_ENDPOINT_TYPE_MASK 0x03 /* in bmAttributes */
|
||||
#define USB_ENDPOINT_TYPE_CONTROL 0
|
||||
#define USB_ENDPOINT_TYPE_ISOCHRONOUS 1
|
||||
#define USB_ENDPOINT_TYPE_BULK 2
|
||||
#define USB_ENDPOINT_TYPE_INTERRUPT 3
|
||||
|
||||
/* Interface descriptor */
|
||||
#define USB_MAXINTERFACES 32
|
||||
struct usb_interface_descriptor {
|
||||
unsigned char bLength;
|
||||
unsigned char bDescriptorType;
|
||||
unsigned char bInterfaceNumber;
|
||||
unsigned char bAlternateSetting;
|
||||
unsigned char bNumEndpoints;
|
||||
unsigned char bInterfaceClass;
|
||||
unsigned char bInterfaceSubClass;
|
||||
unsigned char bInterfaceProtocol;
|
||||
unsigned char iInterface;
|
||||
|
||||
struct usb_endpoint_descriptor *endpoint;
|
||||
|
||||
unsigned char *extra; /* Extra descriptors */
|
||||
int extralen;
|
||||
};
|
||||
|
||||
#define USB_MAXALTSETTING 128 /* Hard limit */
|
||||
|
||||
struct usb_interface {
|
||||
struct usb_interface_descriptor *altsetting;
|
||||
|
||||
int num_altsetting;
|
||||
};
|
||||
|
||||
/* Configuration descriptor information.. */
|
||||
#define USB_MAXCONFIG 8
|
||||
struct usb_config_descriptor {
|
||||
unsigned char bLength;
|
||||
unsigned char bDescriptorType;
|
||||
unsigned short wTotalLength;
|
||||
unsigned char bNumInterfaces;
|
||||
unsigned char bConfigurationValue;
|
||||
unsigned char iConfiguration;
|
||||
unsigned char bmAttributes;
|
||||
unsigned char MaxPower;
|
||||
|
||||
struct usb_interface *interface;
|
||||
|
||||
unsigned char *extra; /* Extra descriptors */
|
||||
int extralen;
|
||||
};
|
||||
|
||||
/* Device descriptor */
|
||||
struct usb_device_descriptor {
|
||||
unsigned char bLength;
|
||||
unsigned char bDescriptorType;
|
||||
unsigned short bcdUSB;
|
||||
unsigned char bDeviceClass;
|
||||
unsigned char bDeviceSubClass;
|
||||
unsigned char bDeviceProtocol;
|
||||
unsigned char bMaxPacketSize0;
|
||||
unsigned short idVendor;
|
||||
unsigned short idProduct;
|
||||
unsigned short bcdDevice;
|
||||
unsigned char iManufacturer;
|
||||
unsigned char iProduct;
|
||||
unsigned char iSerialNumber;
|
||||
unsigned char bNumConfigurations;
|
||||
};
|
||||
|
||||
struct usb_ctrl_setup {
|
||||
unsigned char bRequestType;
|
||||
unsigned char bRequest;
|
||||
unsigned short wValue;
|
||||
unsigned short wIndex;
|
||||
unsigned short wLength;
|
||||
};
|
||||
|
||||
/*
|
||||
* Standard requests
|
||||
*/
|
||||
#define USB_REQ_GET_STATUS 0x00
|
||||
#define USB_REQ_CLEAR_FEATURE 0x01
|
||||
/* 0x02 is reserved */
|
||||
#define USB_REQ_SET_FEATURE 0x03
|
||||
/* 0x04 is reserved */
|
||||
#define USB_REQ_SET_ADDRESS 0x05
|
||||
#define USB_REQ_GET_DESCRIPTOR 0x06
|
||||
#define USB_REQ_SET_DESCRIPTOR 0x07
|
||||
#define USB_REQ_GET_CONFIGURATION 0x08
|
||||
#define USB_REQ_SET_CONFIGURATION 0x09
|
||||
#define USB_REQ_GET_INTERFACE 0x0A
|
||||
#define USB_REQ_SET_INTERFACE 0x0B
|
||||
#define USB_REQ_SYNCH_FRAME 0x0C
|
||||
|
||||
#define USB_TYPE_STANDARD (0x00 << 5)
|
||||
#define USB_TYPE_CLASS (0x01 << 5)
|
||||
#define USB_TYPE_VENDOR (0x02 << 5)
|
||||
#define USB_TYPE_RESERVED (0x03 << 5)
|
||||
|
||||
#define USB_RECIP_DEVICE 0x00
|
||||
#define USB_RECIP_INTERFACE 0x01
|
||||
#define USB_RECIP_ENDPOINT 0x02
|
||||
#define USB_RECIP_OTHER 0x03
|
||||
|
||||
/*
|
||||
* Various libusb API related stuff
|
||||
*/
|
||||
|
||||
#define USB_ENDPOINT_IN 0x80
|
||||
#define USB_ENDPOINT_OUT 0x00
|
||||
|
||||
/* Error codes */
|
||||
#define USB_ERROR_BEGIN 500000
|
||||
|
||||
/*
|
||||
* This is supposed to look weird. This file is generated from autoconf
|
||||
* and I didn't want to make this too complicated.
|
||||
*/
|
||||
#define USB_LE16_TO_CPU(x)
|
||||
|
||||
/* Data types */
|
||||
/* struct usb_device; */
|
||||
/* struct usb_bus; */
|
||||
|
||||
struct usb_device {
|
||||
struct usb_device *next, *prev;
|
||||
|
||||
char filename[LIBUSB_PATH_MAX];
|
||||
|
||||
struct usb_bus *bus;
|
||||
|
||||
struct usb_device_descriptor descriptor;
|
||||
struct usb_config_descriptor *config;
|
||||
|
||||
void *dev; /* Darwin support */
|
||||
|
||||
unsigned char devnum;
|
||||
|
||||
unsigned char num_children;
|
||||
struct usb_device **children;
|
||||
};
|
||||
|
||||
struct usb_bus {
|
||||
struct usb_bus *next, *prev;
|
||||
|
||||
char dirname[LIBUSB_PATH_MAX];
|
||||
|
||||
struct usb_device *devices;
|
||||
unsigned long location;
|
||||
|
||||
struct usb_device *root_dev;
|
||||
};
|
||||
|
||||
/* Version information, Windows specific */
|
||||
struct usb_version {
|
||||
struct {
|
||||
int major;
|
||||
int minor;
|
||||
int micro;
|
||||
int nano;
|
||||
} dll;
|
||||
struct {
|
||||
int major;
|
||||
int minor;
|
||||
int micro;
|
||||
int nano;
|
||||
} driver;
|
||||
};
|
||||
|
||||
|
||||
struct usb_dev_handle;
|
||||
typedef struct usb_dev_handle usb_dev_handle;
|
||||
|
||||
/* Variables */
|
||||
#ifndef __USB_C__
|
||||
#define usb_busses usb_get_busses()
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#include <poppack.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Function prototypes */
|
||||
|
||||
/* usb.c */
|
||||
usb_dev_handle *usb_open(struct usb_device *dev);
|
||||
int usb_close(usb_dev_handle *dev);
|
||||
int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf,
|
||||
size_t buflen);
|
||||
int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf,
|
||||
size_t buflen);
|
||||
|
||||
/* descriptors.c */
|
||||
int usb_get_descriptor_by_endpoint(usb_dev_handle *udev, int ep,
|
||||
unsigned char type, unsigned char index,
|
||||
void *buf, int size);
|
||||
int usb_get_descriptor(usb_dev_handle *udev, unsigned char type,
|
||||
unsigned char index, void *buf, int size);
|
||||
|
||||
/* <arch>.c */
|
||||
int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size,
|
||||
int timeout);
|
||||
int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size,
|
||||
int timeout);
|
||||
int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size,
|
||||
int timeout);
|
||||
int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size,
|
||||
int timeout);
|
||||
int usb_control_msg(usb_dev_handle *dev, int requesttype, int request,
|
||||
int value, int index, char *bytes, int size,
|
||||
int timeout);
|
||||
int usb_set_configuration(usb_dev_handle *dev, int configuration);
|
||||
int usb_claim_interface(usb_dev_handle *dev, int interface);
|
||||
int usb_release_interface(usb_dev_handle *dev, int interface);
|
||||
int usb_set_altinterface(usb_dev_handle *dev, int alternate);
|
||||
int usb_resetep(usb_dev_handle *dev, unsigned int ep);
|
||||
int usb_clear_halt(usb_dev_handle *dev, unsigned int ep);
|
||||
int usb_reset(usb_dev_handle *dev);
|
||||
|
||||
char *usb_strerror(void);
|
||||
|
||||
void usb_init(void);
|
||||
void usb_set_debug(int level);
|
||||
int usb_find_busses(void);
|
||||
int usb_find_devices(void);
|
||||
struct usb_device *usb_device(usb_dev_handle *dev);
|
||||
struct usb_bus *usb_get_busses(void);
|
||||
|
||||
|
||||
/* Windows specific functions */
|
||||
|
||||
#define LIBUSB_HAS_INSTALL_SERVICE_NP 1
|
||||
int usb_install_service_np(void);
|
||||
void CALLBACK usb_install_service_np_rundll(HWND wnd, HINSTANCE instance,
|
||||
LPSTR cmd_line, int cmd_show);
|
||||
|
||||
#define LIBUSB_HAS_UNINSTALL_SERVICE_NP 1
|
||||
int usb_uninstall_service_np(void);
|
||||
void CALLBACK usb_uninstall_service_np_rundll(HWND wnd, HINSTANCE instance,
|
||||
LPSTR cmd_line, int cmd_show);
|
||||
|
||||
#define LIBUSB_HAS_INSTALL_DRIVER_NP 1
|
||||
int usb_install_driver_np(const char *inf_file);
|
||||
void CALLBACK usb_install_driver_np_rundll(HWND wnd, HINSTANCE instance,
|
||||
LPSTR cmd_line, int cmd_show);
|
||||
|
||||
#define LIBUSB_HAS_TOUCH_INF_FILE_NP 1
|
||||
int usb_touch_inf_file_np(const char *inf_file);
|
||||
void CALLBACK usb_touch_inf_file_np_rundll(HWND wnd, HINSTANCE instance,
|
||||
LPSTR cmd_line, int cmd_show);
|
||||
|
||||
#define LIBUSB_HAS_INSTALL_NEEDS_RESTART_NP 1
|
||||
int usb_install_needs_restart_np(void);
|
||||
|
||||
const struct usb_version *usb_get_version(void);
|
||||
|
||||
int usb_isochronous_setup_async(usb_dev_handle *dev, void **context,
|
||||
unsigned char ep, int pktsize);
|
||||
int usb_bulk_setup_async(usb_dev_handle *dev, void **context,
|
||||
unsigned char ep);
|
||||
int usb_interrupt_setup_async(usb_dev_handle *dev, void **context,
|
||||
unsigned char ep);
|
||||
|
||||
int usb_submit_async(void *context, char *bytes, int size);
|
||||
int usb_reap_async(void *context, int timeout);
|
||||
int usb_reap_async_nocancel(void *context, int timeout);
|
||||
int usb_cancel_async(void *context);
|
||||
int usb_free_async(void **context);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USB_H__ */
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
/* Register definitions for Philips CL RC632 RFID Reader IC
|
||||
*
|
||||
* (C) 2005 Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
* Licensed under GNU General Public License, Version 2
|
||||
*/
|
||||
|
||||
enum rc632_registers {
|
||||
RC632_REG_PAGE0 = 0x00,
|
||||
RC632_REG_COMMAND = 0x01,
|
||||
RC632_REG_FIFO_DATA = 0x02,
|
||||
RC632_REG_PRIMARY_STATUS = 0x03,
|
||||
RC632_REG_FIFO_LENGTH = 0x04,
|
||||
RC632_REG_SECONDARY_STATUS = 0x05,
|
||||
RC632_REG_INTERRUPT_EN = 0x06,
|
||||
RC632_REG_INTERRUPT_RQ = 0x07,
|
||||
|
||||
RC632_REG_PAGE1 = 0x08,
|
||||
RC632_REG_CONTROL = 0x09,
|
||||
RC632_REG_ERROR_FLAG = 0x0a,
|
||||
RC632_REG_COLL_POS = 0x0b,
|
||||
RC632_REG_TIMER_VALUE = 0x0c,
|
||||
RC632_REG_CRC_RESULT_LSB = 0x0d,
|
||||
RC632_REG_CRC_RESULT_MSB = 0x0e,
|
||||
RC632_REG_BIT_FRAMING = 0x0f,
|
||||
|
||||
RC632_REG_PAGE2 = 0x10,
|
||||
RC632_REG_TX_CONTROL = 0x11,
|
||||
RC632_REG_CW_CONDUCTANCE = 0x12,
|
||||
RC632_REG_MOD_CONDUCTANCE = 0x13,
|
||||
RC632_REG_CODER_CONTROL = 0x14,
|
||||
RC632_REG_MOD_WIDTH = 0x15,
|
||||
RC632_REG_MOD_WIDTH_SOF = 0x16,
|
||||
RC632_REG_TYPE_B_FRAMING = 0x17,
|
||||
|
||||
RC632_REG_PAGE3 = 0x18,
|
||||
RC632_REG_RX_CONTROL1 = 0x19,
|
||||
RC632_REG_DECODER_CONTROL = 0x1a,
|
||||
RC632_REG_BIT_PHASE = 0x1b,
|
||||
RC632_REG_RX_THRESHOLD = 0x1c,
|
||||
RC632_REG_BPSK_DEM_CONTROL = 0x1d,
|
||||
RC632_REG_RX_CONTROL2 = 0x1e,
|
||||
RC632_REG_CLOCK_Q_CONTROL = 0x1f,
|
||||
|
||||
RC632_REG_PAGE4 = 0x20,
|
||||
RC632_REG_RX_WAIT = 0x21,
|
||||
RC632_REG_CHANNEL_REDUNDANCY = 0x22,
|
||||
RC632_REG_CRC_PRESET_LSB = 0x23,
|
||||
RC632_REG_CRC_PRESET_MSB = 0x24,
|
||||
RC632_REG_TIME_SLOT_PERIOD = 0x25,
|
||||
RC632_REG_MFOUT_SELECT = 0x26,
|
||||
RC632_REG_PRESET_27 = 0x27,
|
||||
|
||||
RC632_REG_PAGE5 = 0x28,
|
||||
RC632_REG_FIFO_LEVEL = 0x29,
|
||||
RC632_REG_TIMER_CLOCK = 0x2a,
|
||||
RC632_REG_TIMER_CONTROL = 0x2b,
|
||||
RC632_REG_TIMER_RELOAD = 0x2c,
|
||||
RC632_REG_IRQ_PIN_CONFIG = 0x2d,
|
||||
RC632_REG_PRESET_2E = 0x2e,
|
||||
RC632_REG_PRESET_2F = 0x2f,
|
||||
|
||||
RC632_REG_PAGE6 = 0x30,
|
||||
|
||||
RC632_REG_PAGE7 = 0x38,
|
||||
RC632_REG_TEST_ANA_SELECT = 0x3a,
|
||||
RC632_REG_TEST_DIGI_SELECT = 0x3d,
|
||||
};
|
||||
|
||||
enum rc632_reg_command {
|
||||
RC632_CMD_IDLE = 0x00,
|
||||
RC632_CMD_WRITE_E2 = 0x01,
|
||||
RC632_CMD_READ_E2 = 0x03,
|
||||
RC632_CMD_LOAD_CONFIG = 0x07,
|
||||
RC632_CMD_LOAD_KEY_E2 = 0x0b,
|
||||
RC632_CMD_AUTHENT1 = 0x0c,
|
||||
RC632_CMD_CALC_CRC = 0x12,
|
||||
RC632_CMD_AUTHENT2 = 0x14,
|
||||
RC632_CMD_RECEIVE = 0x16,
|
||||
RC632_CMD_LOAD_KEY = 0x19,
|
||||
RC632_CMD_TRANSMIT = 0x1a,
|
||||
RC632_CMD_TRANSCEIVE = 0x1e,
|
||||
RC632_CMD_STARTUP = 0x3f,
|
||||
};
|
||||
|
||||
enum rc632_reg_interrupt {
|
||||
RC632_INT_LOALERT = 0x01,
|
||||
RC632_INT_HIALERT = 0x02,
|
||||
RC632_INT_IDLE = 0x04,
|
||||
RC632_INT_RX = 0x08,
|
||||
RC632_INT_TX = 0x10,
|
||||
RC632_INT_TIMER = 0x20,
|
||||
RC632_INT_SET = 0x80,
|
||||
};
|
||||
|
||||
enum rc632_reg_control {
|
||||
RC632_CONTROL_FIFO_FLUSH = 0x01,
|
||||
RC632_CONTROL_TIMER_START = 0x02,
|
||||
RC632_CONTROL_TIMER_STOP = 0x04,
|
||||
RC632_CONTROL_CRYPTO1_ON = 0x08,
|
||||
RC632_CONTROL_POWERDOWN = 0x10,
|
||||
RC632_CONTROL_STANDBY = 0x20,
|
||||
};
|
||||
|
||||
enum rc632_reg_error_flag {
|
||||
RC632_ERR_FLAG_COL_ERR = 0x01,
|
||||
RC632_ERR_FLAG_PARITY_ERR = 0x02,
|
||||
RC632_ERR_FLAG_FRAMING_ERR = 0x04,
|
||||
RC632_ERR_FLAG_CRC_ERR = 0x08,
|
||||
RC632_ERR_FLAG_FIFO_OVERFLOW = 0x10,
|
||||
RC632_ERR_FLAG_ACCESS_ERR = 0x20,
|
||||
RC632_ERR_FLAG_KEY_ERR = 0x40,
|
||||
};
|
||||
|
||||
enum rc632_reg_tx_control {
|
||||
RC632_TXCTRL_TX1_RF_EN = 0x01,
|
||||
RC632_TXCTRL_TX2_RF_EN = 0x02,
|
||||
RC632_TXCTRL_TX2_CW = 0x04,
|
||||
RC632_TXCTRL_TX2_INV = 0x08,
|
||||
RC632_TXCTRL_FORCE_100_ASK = 0x10,
|
||||
|
||||
RC632_TXCTRL_MOD_SRC_LOW = 0x00,
|
||||
RC632_TXCTRL_MOD_SRC_HIGH = 0x20,
|
||||
RC632_TXCTRL_MOD_SRC_INT = 0x40,
|
||||
RC632_TXCTRL_MOD_SRC_MFIN = 0x60,
|
||||
};
|
||||
|
||||
enum rc632_reg_coder_control {
|
||||
RC632_CDRCTRL_TXCD_NRZ = 0x00,
|
||||
RC632_CDRCTRL_TXCD_14443A = 0x01,
|
||||
RC632_CDRCTRL_TXCD_ICODE_STD = 0x04,
|
||||
|
||||
#define RC632_CDRCTRL_RATE_MASK 0x38
|
||||
RC632_CDRCTRL_RATE_848K = 0x00,
|
||||
RC632_CDRCTRL_RATE_424K = 0x08,
|
||||
RC632_CDRCTRL_RATE_212K = 0x10,
|
||||
RC632_CDRCTRL_RATE_106K = 0x18,
|
||||
RC632_CDRCTRL_RATE_14443B = 0x20,
|
||||
RC632_CDRCTRL_RATE_15693 = 0x28,
|
||||
RC632_CDRCTRL_RATE_ICODE_FAST = 0x30,
|
||||
};
|
||||
|
||||
enum rc632_erg_type_b_framing {
|
||||
RC632_TBFRAMING_SOF_10L_2H = 0x00,
|
||||
RC632_TBFRAMING_SOF_10L_3H = 0x01,
|
||||
RC632_TBFRAMING_SOF_11L_2H = 0x02,
|
||||
RC632_TBFRAMING_SOF_11L_3H = 0x03,
|
||||
|
||||
RC632_TBFRAMING_EOF_10 = 0x00,
|
||||
RC632_TBFRAMING_EOF_11 = 0x20,
|
||||
|
||||
RC632_TBFRAMING_NO_TX_SOF = 0x80,
|
||||
RC632_TBFRAMING_NO_TX_EOF = 0x40,
|
||||
};
|
||||
#define RC632_TBFRAMING_SPACE_SHIFT 2
|
||||
#define RC632_TBFRAMING_SPACE_MASK 7
|
||||
|
||||
enum rc632_reg_rx_control1 {
|
||||
RC632_RXCTRL1_GAIN_20DB = 0x00,
|
||||
RC632_RXCTRL1_GAIN_24DB = 0x01,
|
||||
RC632_RXCTRL1_GAIN_31DB = 0x02,
|
||||
RC632_RXCTRL1_GAIN_35DB = 0x03,
|
||||
|
||||
RC632_RXCTRL1_LP_OFF = 0x04,
|
||||
RC632_RXCTRL1_ISO15693 = 0x08,
|
||||
RC632_RXCTRL1_ISO14443 = 0x10,
|
||||
|
||||
#define RC632_RXCTRL1_SUBCP_MASK 0xe0
|
||||
RC632_RXCTRL1_SUBCP_1 = 0x00,
|
||||
RC632_RXCTRL1_SUBCP_2 = 0x20,
|
||||
RC632_RXCTRL1_SUBCP_4 = 0x40,
|
||||
RC632_RXCTRL1_SUBCP_8 = 0x60,
|
||||
RC632_RXCTRL1_SUBCP_16 = 0x80,
|
||||
};
|
||||
|
||||
enum rc632_reg_decoder_control {
|
||||
RC632_DECCTRL_MANCHESTER = 0x00,
|
||||
RC632_DECCTRL_BPSK = 0x01,
|
||||
|
||||
RC632_DECCTRL_RX_INVERT = 0x04,
|
||||
|
||||
RC632_DECCTRL_RXFR_ICODE = 0x00,
|
||||
RC632_DECCTRL_RXFR_14443A = 0x08,
|
||||
RC632_DECCTRL_RXFR_15693 = 0x10,
|
||||
RC632_DECCTRL_RXFR_14443B = 0x18,
|
||||
|
||||
RC632_DECCTRL_ZEROAFTERCOL = 0x20,
|
||||
|
||||
RC632_DECCTRL_RX_MULTIPLE = 0x40,
|
||||
};
|
||||
|
||||
enum rc632_reg_bpsk_dem_control {
|
||||
RC632_BPSKD_TAUB_SHIFT = 0x00,
|
||||
RC632_BPSKD_TAUB_MASK = 0x03,
|
||||
|
||||
RC632_BPSKD_TAUD_SHIFT = 0x02,
|
||||
RC632_BPSKD_TAUD_MASK = 0x03,
|
||||
|
||||
RC632_BPSKD_FILTER_AMP_DETECT = 0x10,
|
||||
RC632_BPSKD_NO_RX_EOF = 0x20,
|
||||
RC632_BPSKD_NO_RX_EGT = 0x40,
|
||||
RC632_BPSKD_NO_RX_SOF = 0x80,
|
||||
};
|
||||
|
||||
enum rc632_reg_rx_control2 {
|
||||
RC632_RXCTRL2_DECSRC_LOW = 0x00,
|
||||
RC632_RXCTRL2_DECSRC_INT = 0x01,
|
||||
RC632_RXCTRL2_DECSRC_SUBC_MFIN = 0x10,
|
||||
RC632_RXCTRL2_DECSRC_BASE_MFIN = 0x11,
|
||||
|
||||
RC632_RXCTRL2_AUTO_PD = 0x40,
|
||||
RC632_RXCTRL2_CLK_I = 0x80,
|
||||
RC632_RXCTRL2_CLK_Q = 0x00,
|
||||
};
|
||||
|
||||
enum rc632_reg_channel_redundancy {
|
||||
RC632_CR_PARITY_ENABLE = 0x01,
|
||||
RC632_CR_PARITY_ODD = 0x02,
|
||||
RC632_CR_TX_CRC_ENABLE = 0x04,
|
||||
RC632_CR_RX_CRC_ENABLE = 0x08,
|
||||
RC632_CR_CRC8 = 0x10,
|
||||
RC632_CR_CRC3309 = 0x20,
|
||||
};
|
||||
|
||||
enum rc632_reg_timer_control {
|
||||
RC632_TMR_START_TX_BEGIN = 0x01,
|
||||
RC632_TMR_START_TX_END = 0x02,
|
||||
RC632_TMR_STOP_RX_BEGIN = 0x04,
|
||||
RC632_TMR_STOP_RX_END = 0x08,
|
||||
};
|
||||
|
||||
enum rc632_reg_timer_irq {
|
||||
RC632_IRQ_LO_ALERT = 0x01,
|
||||
RC632_IRQ_HI_ALERT = 0x02,
|
||||
RC632_IRQ_IDLE = 0x04,
|
||||
RC632_IRQ_RX = 0x08,
|
||||
RC632_IRQ_TX = 0x10,
|
||||
RC632_IRQ_TIMER = 0x20,
|
||||
|
||||
RC632_IRQ_SET = 0x80,
|
||||
};
|
||||
|
||||
enum rc632_reg_secondary_status {
|
||||
RC632_SEC_ST_TMR_RUNNING = 0x80,
|
||||
RC632_SEC_ST_E2_READY = 0x40,
|
||||
RC632_SEC_ST_CRC_READY = 0x20,
|
||||
};
|
||||
@@ -0,0 +1,114 @@
|
||||
/* 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
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <librfid/rfid.h>
|
||||
#include <librfid/rfid_reader.h>
|
||||
#include <librfid/rfid_protocol.h>
|
||||
#include <librfid/rfid_protocol_tcl.h>
|
||||
#include <librfid/rfid_protocol_mifare_ul.h>
|
||||
#include <librfid/rfid_protocol_mifare_classic.h>
|
||||
|
||||
#ifdef LIBRFID_STATIC
|
||||
struct rfid_asic_handle rfid_ah;
|
||||
struct rfid_layer2_handle rfid_l2h;
|
||||
struct rfid_protocol_handle rfid_ph;
|
||||
struct rfid_asic_transport_handle rfid_ath;
|
||||
struct rfid_reader_handle rfid_rh;
|
||||
#endif
|
||||
|
||||
#ifndef LIBRFID_FIRMWARE
|
||||
#ifdef LIBRFID_DEBUG
|
||||
const char *
|
||||
rfid_hexdump(const void *data, unsigned int len)
|
||||
{
|
||||
static char string[1024];
|
||||
unsigned char *d = (unsigned char *) data;
|
||||
unsigned int i, left;
|
||||
|
||||
string[0] = '\0';
|
||||
left = sizeof(string);
|
||||
for (i = 0; len--; i += 3) {
|
||||
if (i >= sizeof(string) -4)
|
||||
break;
|
||||
snprintf(string+i, 4, " %02x", *d++);
|
||||
}
|
||||
return string;
|
||||
}
|
||||
#endif/*LIBRFID_DEBUG*/
|
||||
#else
|
||||
#define rfid_hexdump(x, y) hexdump(x, y)
|
||||
#endif
|
||||
|
||||
#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()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rfid_fini()
|
||||
{
|
||||
/* FIXME: implementation */
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <librfid/rfid.h>
|
||||
#include <librfid/rfid_access_mifare_classic.h>
|
||||
|
||||
/* parse encoded data structure into c1/c2/c3 */
|
||||
int mfcl_compile_access(u_int8_t *encoded,
|
||||
const struct mfcl_access_sect *ac)
|
||||
{
|
||||
int b;
|
||||
u_int8_t c1, c2, c3;
|
||||
|
||||
c1 = c2 = c3 = 0;
|
||||
|
||||
for (b = 0; b < 4; b++) {
|
||||
if (ac->block[b] & 0x01)
|
||||
c1 |= (1 << b);
|
||||
if (ac->block[b] & 0x02)
|
||||
c2 |= (1 << b);
|
||||
if (ac->block[b] & 0x04)
|
||||
c3 |= (1 << b);
|
||||
}
|
||||
|
||||
DEBUGP("compile: c1=%u c2=%u c3=%u\n", c1, c2, c3);
|
||||
|
||||
encoded[3] = 0x00;
|
||||
encoded[2] = c2 | (c3 << 4);
|
||||
encoded[1] = (~c3 & 0xf) | (c1 << 4);
|
||||
encoded[0] = (~c1 & 0xf) | ((~c2 & 0xf) << 4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* parse mifare classic access conditions from card */
|
||||
int mfcl_parse_access(struct mfcl_access_sect *ac, u_int8_t *encoded)
|
||||
{
|
||||
int b;
|
||||
|
||||
u_int8_t c1, c2, c3;
|
||||
|
||||
DEBUGP("encoded: %s\n", rfid_hexdump(encoded, 4));
|
||||
|
||||
c1 = encoded[1] >> 4;
|
||||
c2 = encoded[2] & 0xf;
|
||||
c3 = encoded[2] >> 4;
|
||||
|
||||
DEBUGP("c1=0x%x, c2=0x%x, c3=0x%x\n", c1, c2, c3);
|
||||
|
||||
memset(ac, 0, sizeof(*ac));
|
||||
for (b = 0; b < 4; b++) {
|
||||
if (c1 & (1 << b))
|
||||
ac->block[b] = 0x1;
|
||||
if (c2 & (1 << b))
|
||||
ac->block[b] |= 0x2;
|
||||
if (c3 & (1 << b))
|
||||
ac->block[b] |= 0x4;
|
||||
};
|
||||
|
||||
/* FIXME: verify the inverted access bits */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* functions below here are for our own internal decoded (orthogonal)
|
||||
* format of access bits */
|
||||
|
||||
/* In the order of the table 3.7.3 in MFCL Product Specification Rev. 5.1 */
|
||||
static const struct mfcl_access_exp_block mfcl_exp_data[] = {
|
||||
[0] = {
|
||||
.read = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
|
||||
.write = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
|
||||
.inc = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
|
||||
.dec = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
|
||||
},
|
||||
[2] = {
|
||||
.read = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
|
||||
.write = MFCL_ACCESS_NEVER,
|
||||
.inc = MFCL_ACCESS_NEVER,
|
||||
.dec = MFCL_ACCESS_NEVER,
|
||||
},
|
||||
[1] = {
|
||||
.read = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
|
||||
.write = MFCL_ACCESS_KEY_B,
|
||||
.inc = MFCL_ACCESS_NEVER,
|
||||
.dec = MFCL_ACCESS_NEVER,
|
||||
},
|
||||
[3] = {
|
||||
.read = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
|
||||
.write = MFCL_ACCESS_KEY_B,
|
||||
.inc = MFCL_ACCESS_KEY_B,
|
||||
.dec = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
|
||||
},
|
||||
[4] = {
|
||||
.read = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
|
||||
.write = MFCL_ACCESS_NEVER,
|
||||
.inc = MFCL_ACCESS_NEVER,
|
||||
.dec = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
|
||||
},
|
||||
[6] = {
|
||||
.read = MFCL_ACCESS_KEY_B,
|
||||
.write = MFCL_ACCESS_KEY_B,
|
||||
.inc = MFCL_ACCESS_NEVER,
|
||||
.dec = MFCL_ACCESS_NEVER,
|
||||
},
|
||||
[5] = {
|
||||
.read = MFCL_ACCESS_KEY_B,
|
||||
.write = MFCL_ACCESS_NEVER,
|
||||
.inc = MFCL_ACCESS_NEVER,
|
||||
.dec = MFCL_ACCESS_NEVER,
|
||||
},
|
||||
[7] = {
|
||||
.read = MFCL_ACCESS_NEVER,
|
||||
.write = MFCL_ACCESS_NEVER,
|
||||
.inc = MFCL_ACCESS_NEVER,
|
||||
.dec = MFCL_ACCESS_NEVER,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct mfcl_access_exp_acc mfcl_exp_trailer[] = {
|
||||
[0] = {
|
||||
.key_a_rd = MFCL_ACCESS_NEVER,
|
||||
.key_a_wr = MFCL_ACCESS_KEY_A,
|
||||
.acc_rd = MFCL_ACCESS_KEY_A,
|
||||
.acc_wr = MFCL_ACCESS_NEVER,
|
||||
.key_b_rd = MFCL_ACCESS_KEY_A,
|
||||
.key_b_wr = MFCL_ACCESS_KEY_A,
|
||||
},
|
||||
[2] = {
|
||||
.key_a_rd = MFCL_ACCESS_NEVER,
|
||||
.key_a_wr = MFCL_ACCESS_NEVER,
|
||||
.acc_rd = MFCL_ACCESS_KEY_A,
|
||||
.acc_wr = MFCL_ACCESS_NEVER,
|
||||
.key_b_rd = MFCL_ACCESS_KEY_A,
|
||||
.key_b_wr = MFCL_ACCESS_NEVER,
|
||||
},
|
||||
[1] = {
|
||||
.key_a_rd = MFCL_ACCESS_NEVER,
|
||||
.key_a_wr = MFCL_ACCESS_KEY_B,
|
||||
.acc_rd = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
|
||||
.acc_wr = MFCL_ACCESS_NEVER,
|
||||
.key_b_rd = MFCL_ACCESS_NEVER,
|
||||
.key_b_wr = MFCL_ACCESS_KEY_B,
|
||||
},
|
||||
[3] = {
|
||||
.key_a_rd = MFCL_ACCESS_NEVER,
|
||||
.key_a_wr = MFCL_ACCESS_NEVER,
|
||||
.acc_rd = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
|
||||
.acc_wr = MFCL_ACCESS_NEVER,
|
||||
.key_b_rd = MFCL_ACCESS_NEVER,
|
||||
.key_b_wr = MFCL_ACCESS_NEVER,
|
||||
},
|
||||
[4] = {
|
||||
.key_a_rd = MFCL_ACCESS_NEVER,
|
||||
.key_a_wr = MFCL_ACCESS_KEY_A,
|
||||
.acc_rd = MFCL_ACCESS_KEY_A,
|
||||
.acc_wr = MFCL_ACCESS_KEY_A,
|
||||
.key_b_rd = MFCL_ACCESS_KEY_A,
|
||||
.key_b_wr = MFCL_ACCESS_KEY_A,
|
||||
},
|
||||
[6] = {
|
||||
.key_a_rd = MFCL_ACCESS_NEVER,
|
||||
.key_a_wr = MFCL_ACCESS_KEY_B,
|
||||
.acc_rd = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
|
||||
.acc_wr = MFCL_ACCESS_KEY_B,
|
||||
.key_b_rd = MFCL_ACCESS_NEVER,
|
||||
.key_b_wr = MFCL_ACCESS_KEY_B,
|
||||
},
|
||||
[5] = {
|
||||
.key_a_rd = MFCL_ACCESS_NEVER,
|
||||
.key_a_wr = MFCL_ACCESS_NEVER,
|
||||
.acc_rd = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
|
||||
.acc_wr = MFCL_ACCESS_KEY_B,
|
||||
.key_b_rd = MFCL_ACCESS_NEVER,
|
||||
.key_b_wr = MFCL_ACCESS_NEVER,
|
||||
},
|
||||
[7] = {
|
||||
.key_a_rd = MFCL_ACCESS_NEVER,
|
||||
.key_a_wr = MFCL_ACCESS_NEVER,
|
||||
.acc_rd = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
|
||||
.acc_wr = MFCL_ACCESS_NEVER,
|
||||
.key_b_rd = MFCL_ACCESS_NEVER,
|
||||
.key_b_wr = MFCL_ACCESS_NEVER,
|
||||
},
|
||||
};
|
||||
|
||||
const char *mfcl_access_str[] = {
|
||||
[MFCL_ACCESS_NEVER] = "NEVER",
|
||||
[MFCL_ACCESS_KEY_A] = "A",
|
||||
[MFCL_ACCESS_KEY_B] = "B",
|
||||
[MFCL_ACCESS_KEY_A|MFCL_ACCESS_KEY_B] = "A|B",
|
||||
};
|
||||
|
||||
void mfcl_access_to_exp(struct mfcl_access_exp_sect *exp,
|
||||
const struct mfcl_access_sect *sect)
|
||||
{
|
||||
int b;
|
||||
for (b = 0; b < 3; b++)
|
||||
exp->block[b] = mfcl_exp_data[sect->block[b]];
|
||||
exp->acc = mfcl_exp_trailer[sect->block[3]];
|
||||
}
|
||||
|
||||
char *mfcl_access_exp_stringify(const struct mfcl_access_exp_block *exp)
|
||||
{
|
||||
static char buf[80];
|
||||
|
||||
sprintf(buf, "READ: %s, WRITE: %s, INC: %s, DEC: %s",
|
||||
mfcl_access_str[exp->read],
|
||||
mfcl_access_str[exp->write],
|
||||
mfcl_access_str[exp->inc],
|
||||
mfcl_access_str[exp->dec]);
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *mfcl_access_exp_acc_stringify(const struct mfcl_access_exp_acc *acc)
|
||||
{
|
||||
static char buf[80];
|
||||
|
||||
sprintf(buf, "KEY_A_RD: %s, KEY_A_WR: %s, ACC_RD: %s, ACC_WR: %s, "
|
||||
"KEY_B_RD: %s, KEY_B_WR: %s",
|
||||
mfcl_access_str[acc->key_a_rd],
|
||||
mfcl_access_str[acc->key_a_wr],
|
||||
mfcl_access_str[acc->acc_rd],
|
||||
mfcl_access_str[acc->acc_wr],
|
||||
mfcl_access_str[acc->key_b_rd],
|
||||
mfcl_access_str[acc->key_b_wr]);
|
||||
return buf;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,58 @@
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
||||
static unsigned int fsdi_table[] = { 16, 24, 32, 40, 48, 64, 96, 128, 256 };
|
||||
|
||||
int iso14443_fsdi_to_fsd(unsigned int *fsd, unsigned char fsdi)
|
||||
{
|
||||
/* ISO 14443-4:2000(E) Section 5.1. */
|
||||
if (fsdi > sizeof(fsdi_table)/sizeof(unsigned int))
|
||||
return -1;
|
||||
|
||||
*fsd = fsdi_table[fsdi];
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iso14443_fsd_to_fsdi(unsigned char *fsdi, unsigned int fsd)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(fsdi_table)/sizeof(unsigned int); i++) {
|
||||
if (fsdi_table[i] == fsd) {
|
||||
*fsdi = i;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* calculate the fsd that is equal or the closest smaller value
|
||||
* that can be coded as fsd */
|
||||
unsigned int iso14443_fsd_approx(unsigned int fsd)
|
||||
{
|
||||
unsigned int tbl_size = sizeof(fsdi_table)/sizeof(unsigned int);
|
||||
int i;
|
||||
|
||||
for (i = tbl_size-1; i >= 0; i--) {
|
||||
if (fsdi_table[i] <= fsd)
|
||||
return fsdi_table[i];
|
||||
}
|
||||
/* not reached: return smallest possible FSD */
|
||||
return fsdi_table[0];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef __RFID_ISO14443_COMMON_H
|
||||
#define __RFID_ISO14443_COMMON_H
|
||||
|
||||
int iso14443_fsdi_to_fsd(unsigned int *fsd, unsigned char fsdi);
|
||||
int iso14443_fsd_to_fsdi(unsigned char *fsdi, unsigned int fsd);
|
||||
unsigned int iso14443_fsd_approx(unsigned int fsd);
|
||||
|
||||
#define ISO14443_FREQ_CARRIER 13560000
|
||||
#define ISO14443_FREQ_SUBCARRIER (ISO14443_FREQ_CARRIER/16)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,136 @@
|
||||
/* librfid - layer 2 protocol handler
|
||||
* (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
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h> /* for memcpy */
|
||||
|
||||
#include <librfid/rfid.h>
|
||||
#include <librfid/rfid_layer2.h>
|
||||
|
||||
static const struct rfid_layer2 *rfid_layer2s[] = {
|
||||
[RFID_LAYER2_ISO14443A] = &rfid_layer2_iso14443a,
|
||||
[RFID_LAYER2_ISO14443B] = &rfid_layer2_iso14443b,
|
||||
[RFID_LAYER2_ISO15693] = &rfid_layer2_iso15693,
|
||||
};
|
||||
|
||||
struct rfid_layer2_handle *
|
||||
rfid_layer2_init(struct rfid_reader_handle *rh, unsigned int id)
|
||||
{
|
||||
struct rfid_layer2 *p;
|
||||
|
||||
if (id >= ARRAY_SIZE(rfid_layer2s)) {
|
||||
DEBUGP("unable to find matching layer2 protocol\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = rfid_layer2s[id];
|
||||
return p->fn.init(rh);
|
||||
}
|
||||
|
||||
int
|
||||
rfid_layer2_open(struct rfid_layer2_handle *ph)
|
||||
{
|
||||
if (!ph->l2->fn.open)
|
||||
return 0;
|
||||
|
||||
return ph->l2->fn.open(ph);
|
||||
}
|
||||
|
||||
int
|
||||
rfid_layer2_transceive(struct rfid_layer2_handle *ph,
|
||||
enum rfid_frametype frametype,
|
||||
const unsigned char *tx_buf, unsigned int len,
|
||||
unsigned char *rx_buf, unsigned int *rx_len,
|
||||
u_int64_t timeout, unsigned int flags)
|
||||
{
|
||||
if (!ph->l2->fn.transceive)
|
||||
return -EIO;
|
||||
|
||||
return ph->l2->fn.transceive(ph, frametype, tx_buf, len, rx_buf,
|
||||
rx_len, timeout, flags);
|
||||
}
|
||||
|
||||
int rfid_layer2_fini(struct rfid_layer2_handle *ph)
|
||||
{
|
||||
if (!ph->l2->fn.fini)
|
||||
return 0;
|
||||
|
||||
return ph->l2->fn.fini(ph);
|
||||
}
|
||||
|
||||
int
|
||||
rfid_layer2_close(struct rfid_layer2_handle *ph)
|
||||
{
|
||||
if (!ph->l2->fn.close)
|
||||
return 0;
|
||||
|
||||
return ph->l2->fn.close(ph);
|
||||
}
|
||||
|
||||
int
|
||||
rfid_layer2_getopt(struct rfid_layer2_handle *ph, int optname,
|
||||
void *optval, unsigned int *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 (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;
|
||||
}
|
||||
|
||||
char *rfid_layer2_name(struct rfid_layer2_handle *l2h)
|
||||
{
|
||||
return l2h->l2->name;
|
||||
}
|
||||
@@ -0,0 +1,395 @@
|
||||
/* ISO 14443-3 A anticollision implementation
|
||||
*
|
||||
* (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
|
||||
*
|
||||
* 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 <errno.h>
|
||||
#ifdef __MINGW32__
|
||||
#include <windows.h>
|
||||
#endif/*__MINGW32__*/
|
||||
|
||||
#include <librfid/rfid.h>
|
||||
#include <librfid/rfid_layer2.h>
|
||||
#include <librfid/rfid_reader.h>
|
||||
#include <librfid/rfid_layer2_iso14443a.h>
|
||||
#include <librfid/rfid_protocol.h>
|
||||
|
||||
#define TIMEOUT 1236
|
||||
|
||||
unsigned long randctx[4]={0x22d4a017,0x773a1f44,0xc39e1460,0x9cde8801};
|
||||
|
||||
/* Transceive a 7-bit short frame */
|
||||
int
|
||||
iso14443a_transceive_sf(struct rfid_layer2_handle *handle,
|
||||
unsigned char cmd,
|
||||
struct iso14443a_atqa *atqa)
|
||||
{
|
||||
struct rfid_reader *rdr = handle->rh->reader;
|
||||
|
||||
return rdr->iso14443a.transceive_sf(handle->rh, cmd, atqa);
|
||||
}
|
||||
|
||||
/* Transmit an anticollission bit frame */
|
||||
static int
|
||||
iso14443a_transceive_acf(struct rfid_layer2_handle *handle,
|
||||
struct iso14443a_anticol_cmd *acf,
|
||||
unsigned int *bit_of_col)
|
||||
{
|
||||
struct rfid_reader *rdr = handle->rh->reader;
|
||||
|
||||
return rdr->iso14443a.transceive_acf(handle->rh, acf, bit_of_col);
|
||||
}
|
||||
|
||||
/* Transmit a regular frame */
|
||||
static int
|
||||
iso14443a_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)
|
||||
{
|
||||
return handle->rh->reader->transceive(handle->rh, frametype, tx_buf,
|
||||
tx_len, rx_buf, rx_len, timeout, flags);
|
||||
}
|
||||
|
||||
static int
|
||||
iso14443a_code_nvb_bits(unsigned char *nvb, unsigned int bits)
|
||||
{
|
||||
unsigned int byte_count = bits / 8;
|
||||
unsigned int bit_count = bits % 8;
|
||||
|
||||
if (byte_count < 2 || byte_count > 7)
|
||||
return -1;
|
||||
|
||||
*nvb = ((byte_count & 0xf) << 4) | bit_count;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int random_bit(void)
|
||||
{
|
||||
unsigned long e;
|
||||
|
||||
e = randctx[0];
|
||||
randctx[0]=randctx[1];
|
||||
randctx[1]=(randctx[2]<<19) + (randctx[2]>>13) + randctx[3];
|
||||
randctx[2]=randctx[3] ^ randctx[0];
|
||||
randctx[3]=e+randctx[1];
|
||||
|
||||
return randctx[1]&1;
|
||||
}
|
||||
|
||||
/* first bit is '1', second bit '2' */
|
||||
static void
|
||||
rnd_toggle_bit_in_field(unsigned char *bitfield, unsigned int size, unsigned int bit)
|
||||
{
|
||||
unsigned int byte,rnd;
|
||||
|
||||
if(bit && (bit <= (size*8)) )
|
||||
{
|
||||
rnd=random_bit();
|
||||
|
||||
DEBUGP("xor'ing bit %u with %u\n",bit,rnd);
|
||||
bit--;
|
||||
byte=bit/8;
|
||||
bit=rnd<<(bit%8);
|
||||
bitfield[byte] ^= bit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
iso14443a_anticol(struct rfid_layer2_handle *handle)
|
||||
{
|
||||
int ret;
|
||||
unsigned int uid_size;
|
||||
struct iso14443a_handle *h = &handle->priv.iso14443a;
|
||||
struct iso14443a_atqa *atqa = &h->atqa;
|
||||
struct iso14443a_anticol_cmd acf;
|
||||
unsigned int bit_of_col;
|
||||
unsigned char sak[3];
|
||||
unsigned int rx_len = sizeof(sak);
|
||||
char *aqptr = (char *) atqa;
|
||||
|
||||
memset(handle->uid, 0, sizeof(handle->uid));
|
||||
memset(sak, 0, sizeof(sak));
|
||||
memset(atqa, 0, sizeof(&atqa));
|
||||
memset(&acf, 0, sizeof(acf));
|
||||
|
||||
if (handle->flags & RFID_OPT_LAYER2_WUP)
|
||||
ret = iso14443a_transceive_sf(handle, ISO14443A_SF_CMD_WUPA, atqa);
|
||||
else
|
||||
ret = iso14443a_transceive_sf(handle, ISO14443A_SF_CMD_REQA, atqa);
|
||||
if (ret < 0) {
|
||||
h->state = ISO14443A_STATE_REQA_SENT;
|
||||
DEBUGP("error during transceive_sf: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
h->state = ISO14443A_STATE_ATQA_RCVD;
|
||||
|
||||
DEBUGP("ATQA: 0x%02x 0x%02x\n", *aqptr, *(aqptr+1));
|
||||
|
||||
if (!atqa->bf_anticol) {
|
||||
h->state = ISO14443A_STATE_NO_BITFRAME_ANTICOL;
|
||||
DEBUGP("no bitframe anticollission bits set, aborting\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (atqa->uid_size == 2 || atqa->uid_size == 3)
|
||||
uid_size = 3;
|
||||
else if (atqa->uid_size == 1)
|
||||
uid_size = 2;
|
||||
else
|
||||
uid_size = 1;
|
||||
|
||||
acf.sel_code = ISO14443A_AC_SEL_CODE_CL1;
|
||||
|
||||
h->state = ISO14443A_STATE_ANTICOL_RUNNING;
|
||||
h->level = ISO14443A_LEVEL_CL1;
|
||||
|
||||
cascade:
|
||||
rx_len = sizeof(sak);
|
||||
iso14443a_code_nvb_bits(&acf.nvb, 16);
|
||||
|
||||
ret = iso14443a_transceive_acf(handle, &acf, &bit_of_col);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
while (bit_of_col != ISO14443A_BITOFCOL_NONE) {
|
||||
DEBUGP("collision at pos %u\n", bit_of_col);
|
||||
|
||||
iso14443a_code_nvb_bits(&acf.nvb, bit_of_col);
|
||||
rnd_toggle_bit_in_field(acf.uid_bits, sizeof(acf.uid_bits), bit_of_col);
|
||||
DEBUGP("acf: nvb=0x%02X uid_bits=%s\n",acf.nvb,rfid_hexdump(acf.uid_bits,sizeof(acf.uid_bits)));
|
||||
ret = iso14443a_transceive_acf(handle, &acf, &bit_of_col);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
iso14443a_code_nvb_bits(&acf.nvb, 7*8);
|
||||
|
||||
ret = iso14443a_transceive(handle, RFID_14443A_FRAME_REGULAR,
|
||||
(unsigned char *)&acf, 7,
|
||||
(unsigned char *) &sak, &rx_len,
|
||||
TIMEOUT, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (sak[0] & 0x04) {
|
||||
/* Cascade bit set, UID not complete */
|
||||
switch (acf.sel_code) {
|
||||
case ISO14443A_AC_SEL_CODE_CL1:
|
||||
/* cascading from CL1 to CL2 */
|
||||
if (acf.uid_bits[0] != 0x88) {
|
||||
DEBUGP("Cascade bit set, but UID0 != 0x88\n");
|
||||
return -1;
|
||||
}
|
||||
memcpy(&handle->uid[0], &acf.uid_bits[1], 3);
|
||||
acf.sel_code = ISO14443A_AC_SEL_CODE_CL2;
|
||||
h->level = ISO14443A_LEVEL_CL2;
|
||||
break;
|
||||
case ISO14443A_AC_SEL_CODE_CL2:
|
||||
/* cascading from CL2 to CL3 */
|
||||
memcpy(&handle->uid[3], &acf.uid_bits[1], 3);
|
||||
acf.sel_code = ISO14443A_AC_SEL_CODE_CL3;
|
||||
h->level = ISO14443A_LEVEL_CL3;
|
||||
break;
|
||||
default:
|
||||
DEBUGP("cannot cascade any further than CL3\n");
|
||||
h->state = ISO14443A_STATE_ERROR;
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
goto cascade;
|
||||
|
||||
} else {
|
||||
switch (acf.sel_code) {
|
||||
case ISO14443A_AC_SEL_CODE_CL1:
|
||||
/* single size UID (4 bytes) */
|
||||
memcpy(&handle->uid[0], &acf.uid_bits[0], 4);
|
||||
break;
|
||||
case ISO14443A_AC_SEL_CODE_CL2:
|
||||
/* double size UID (7 bytes) */
|
||||
memcpy(&handle->uid[3], &acf.uid_bits[0], 4);
|
||||
break;
|
||||
case ISO14443A_AC_SEL_CODE_CL3:
|
||||
/* triple size UID (10 bytes) */
|
||||
memcpy(&handle->uid[6], &acf.uid_bits[0], 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
h->level = ISO14443A_LEVEL_NONE;
|
||||
h->state = ISO14443A_STATE_SELECTED;
|
||||
|
||||
{
|
||||
if (uid_size == 1)
|
||||
handle->uid_len = 4;
|
||||
else if (uid_size == 2)
|
||||
handle->uid_len = 7;
|
||||
else
|
||||
handle->uid_len = 10;
|
||||
|
||||
DEBUGP("UID %s\n", rfid_hexdump(handle->uid, handle->uid_len));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
iso14443a_hlta(struct rfid_layer2_handle *handle)
|
||||
{
|
||||
int ret;
|
||||
unsigned char tx_buf[2] = { 0x50, 0x00 };
|
||||
unsigned char rx_buf[10];
|
||||
unsigned int rx_len = sizeof(rx_buf);
|
||||
|
||||
ret = iso14443a_transceive(handle, RFID_14443A_FRAME_REGULAR,
|
||||
tx_buf, sizeof(tx_buf),
|
||||
rx_buf, &rx_len, 1000 /* 1ms */, 0);
|
||||
if (ret < 0) {
|
||||
/* "error" case: we don't get somethng back from the card */
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
iso14443a_setopt(struct rfid_layer2_handle *handle, int optname,
|
||||
const void *optval, unsigned int optlen)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
struct rfid_reader *rdr = handle->rh->reader;
|
||||
unsigned int speed;
|
||||
|
||||
switch (optname) {
|
||||
case RFID_OPT_14443A_SPEED_RX:
|
||||
if (!rdr->iso14443a.set_speed)
|
||||
return -ENOTSUP;
|
||||
speed = *(unsigned int *)optval;
|
||||
ret = rdr->iso14443a.set_speed(handle->rh, 0, speed);
|
||||
break;
|
||||
case RFID_OPT_14443A_SPEED_TX:
|
||||
if (!rdr->iso14443a.set_speed)
|
||||
return -ENOTSUP;
|
||||
speed = *(unsigned int *)optval;
|
||||
ret = rdr->iso14443a.set_speed(handle->rh, 1, speed);
|
||||
break;
|
||||
case RFID_OPT_14443A_WUPA:
|
||||
if((unsigned int*)optval)
|
||||
handle->flags |= RFID_OPT_LAYER2_WUP;
|
||||
else
|
||||
handle->flags &= ~RFID_OPT_LAYER2_WUP;
|
||||
ret = 0;
|
||||
break;
|
||||
};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
iso14443a_getopt(struct rfid_layer2_handle *handle, int optname,
|
||||
void *optval, unsigned int *optlen)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
struct iso14443a_handle *h = &handle->priv.iso14443a;
|
||||
struct iso14443a_atqa *atqa = optval;
|
||||
int *wupa = optval;
|
||||
|
||||
switch (optname) {
|
||||
case RFID_OPT_14443A_ATQA:
|
||||
*atqa = h->atqa;
|
||||
ret = 0;
|
||||
break;
|
||||
case RFID_OPT_14443A_WUPA:
|
||||
*wupa = ((handle->flags & RFID_OPT_LAYER2_WUP) != 0);
|
||||
ret = 0;
|
||||
break;
|
||||
};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static struct rfid_layer2_handle *
|
||||
iso14443a_init(struct rfid_reader_handle *rh)
|
||||
{
|
||||
int ret;
|
||||
struct rfid_layer2_handle *h = malloc_layer2_handle(sizeof(*h));
|
||||
if (!h)
|
||||
return NULL;
|
||||
|
||||
memset(h, 0, sizeof(*h));
|
||||
|
||||
#ifdef __MINGW32__
|
||||
randctx[0] ^= GetTickCount();
|
||||
#endif/*__MINGW32__*/
|
||||
for(ret=0;ret<23;ret++)
|
||||
random_bit();
|
||||
|
||||
h->l2 = &rfid_layer2_iso14443a;
|
||||
h->rh = rh;
|
||||
h->priv.iso14443a.state = ISO14443A_STATE_NONE;
|
||||
h->priv.iso14443a.level = ISO14443A_LEVEL_NONE;
|
||||
|
||||
ret = h->rh->reader->iso14443a.init(h->rh);
|
||||
if (ret < 0) {
|
||||
free_layer2_handle(h);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
static int
|
||||
iso14443a_fini(struct rfid_layer2_handle *handle)
|
||||
{
|
||||
free_layer2_handle(handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const struct rfid_layer2 rfid_layer2_iso14443a = {
|
||||
.id = RFID_LAYER2_ISO14443A,
|
||||
.name = "ISO 14443-3 A",
|
||||
.fn = {
|
||||
.init = &iso14443a_init,
|
||||
.open = &iso14443a_anticol,
|
||||
.transceive = &iso14443a_transceive,
|
||||
.close = &iso14443a_hlta,
|
||||
.fini = &iso14443a_fini,
|
||||
.setopt = &iso14443a_setopt,
|
||||
.getopt = &iso14443a_getopt,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -0,0 +1,400 @@
|
||||
/* ISO 14443-3 B anticollision implementation
|
||||
*
|
||||
* (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
|
||||
*
|
||||
* 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 <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)
|
||||
{
|
||||
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;
|
||||
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,
|
||||
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->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 transceive 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
|
||||
transceive_attrib(struct rfid_layer2_handle *h, const unsigned char *inf,
|
||||
unsigned int inf_len, unsigned char *rx_data, unsigned int *rx_len)
|
||||
{
|
||||
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);
|
||||
if (rx_len >= rx_len-1)
|
||||
return -EINVAL;
|
||||
|
||||
/* initialize attrib frame */
|
||||
memset(&_attrib_buf, 0, sizeof(_attrib_buf));
|
||||
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;
|
||||
|
||||
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,
|
||||
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("transceive problem\n");
|
||||
goto out_rx;
|
||||
}
|
||||
|
||||
if ((rx_buf[0] & 0x0f) != h->priv.iso14443b.cid) {
|
||||
DEBUGP("ATTRIB response with invalid CID %u (should be %u)\n",
|
||||
rx_buf[0] & 0x0f, h->priv.iso14443b.cid);
|
||||
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:
|
||||
out_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->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("transceive 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 = transceive_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_layer2_handle(sizeof(*h));
|
||||
if (!h)
|
||||
return NULL;
|
||||
|
||||
h->l2 = &rfid_layer2_iso14443b;
|
||||
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);
|
||||
|
||||
/* 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_layer2_handle(h);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
static int
|
||||
iso14443b_fini(struct rfid_layer2_handle *handle)
|
||||
{
|
||||
free_layer2_handle(handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
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->transceive(handle->rh, frametype,
|
||||
tx_buf, tx_len,
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
const struct rfid_layer2 rfid_layer2_iso14443b = {
|
||||
.id = RFID_LAYER2_ISO14443B,
|
||||
.name = "ISO 14443-3 B",
|
||||
.fn = {
|
||||
.init = &iso14443b_init,
|
||||
.open = &iso14443b_anticol,
|
||||
.transceive = &iso14443b_transceive,
|
||||
.close = &iso14443b_hltb,
|
||||
.fini = &iso14443b_fini,
|
||||
.getopt = &iso14443b_getopt,
|
||||
.setopt = &iso14443b_setopt,
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,173 @@
|
||||
/* ISO 15693 anticollision implementation
|
||||
*
|
||||
* (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
|
||||
*
|
||||
* 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 <errno.h>
|
||||
|
||||
#include <librfid/rfid.h>
|
||||
#include <librfid/rfid_layer2.h>
|
||||
#include <librfid/rfid_reader.h>
|
||||
#include <librfid/rfid_layer2_iso15693.h>
|
||||
|
||||
struct iso15693_request_read {
|
||||
struct iso15693_request req;
|
||||
u_int64_t uid;
|
||||
u_int8_t blocknum;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define ISO15693_BLOCK_SIZE_MAX (256/8)
|
||||
#define ISO15693_RESP_SIZE_MAX (4+ISO15693_BLOCK_SIZE_MAX)
|
||||
|
||||
#if 0
|
||||
static int
|
||||
iso15693_read_block(struct rfid_layer2_handle *handle,
|
||||
u_int8_t blocknr, u_int32_t *data)
|
||||
{
|
||||
int rc;
|
||||
struct iso15693_request_read req;
|
||||
u_int8_t resp[ISO15693_RESP_SIZE_MAX];
|
||||
|
||||
req.req.flags = 0;
|
||||
req.command = ISO15693_CMD_READ_BLOCK_SINGLE;
|
||||
memcpy(&req.uid, handle->..., ISO15693_UID_LEN);
|
||||
req.blocknum = blocknr;
|
||||
|
||||
/* FIXME: fill CRC if required */
|
||||
|
||||
rc = iso15693_transceive(... &req, ..., );
|
||||
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
memcpy(data, resp+1, rc-1); /* FIXME rc-3 in case of CRC */
|
||||
|
||||
return rc-1;
|
||||
}
|
||||
|
||||
static int
|
||||
iso15693_write_block()
|
||||
{
|
||||
struct iso16593_request_read *rreq;
|
||||
u_int32_t buf[sizeof(req)+ISO15693_BLOCK_SIZE_MAX];
|
||||
|
||||
rreq = (struct iso15693_request_read *) req;
|
||||
|
||||
rreq->req.flags = ;
|
||||
rreq->req.command = ISO15693_CMD_WRITE_BLOCK_SINGLE;
|
||||
memcpy(rreq->uid, handle->, ISO15693_UID_LEN);
|
||||
rreq->blocknum = blocknr;
|
||||
memcpy(rreq->);
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
iso15693_lock_block()
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int
|
||||
iso15693_anticol(struct rfid_layer2_handle *handle)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
iso15693_getopt(struct rfid_layer2_handle *handle,
|
||||
int optname, void *optval, unsigned int optlen)
|
||||
{
|
||||
switch (optname) {
|
||||
case RFID_OPT_15693_MOD_DEPTH:
|
||||
case RFID_OPT_15693_VCD_CODING:
|
||||
case RFID_OPT_15693_VICC_SUBC:
|
||||
case RFID_OPT_15693_VICC_SPEED:
|
||||
default:
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
iso15693_setopt(struct rfid_layer2_handle *handle, int optname,
|
||||
const void *optval, unsigned int optlen)
|
||||
{
|
||||
switch (optname) {
|
||||
case RFID_OPT_15693_MOD_DEPTH:
|
||||
case RFID_OPT_15693_VCD_CODING:
|
||||
case RFID_OPT_15693_VICC_SUBC:
|
||||
case RFID_OPT_15693_VICC_SPEED:
|
||||
default:
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int transceive_inventory(struct rfid_layer2_handle *l2h)
|
||||
{
|
||||
}
|
||||
|
||||
static struct rfid_layer2_handle *
|
||||
iso15693_init(struct rfid_reader_handle *rh)
|
||||
{
|
||||
int ret;
|
||||
struct rfid_layer2_handle *h = malloc_layer2_handle(sizeof(*h));
|
||||
if (!h)
|
||||
return NULL;
|
||||
|
||||
h->l2 = &rfid_layer2_iso15693;
|
||||
h->rh = rh;
|
||||
h->priv.iso15693.state = ISO15693_STATE_NONE;
|
||||
ret = h->rh->reader->iso15693.init(h->rh);
|
||||
if (ret < 0) {
|
||||
free_layer2_handle(h);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
static int
|
||||
iso15693_fini(struct rfid_layer2_handle *handle)
|
||||
{
|
||||
free_layer2_handle(handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const struct rfid_layer2 rfid_layer2_iso15693 = {
|
||||
.id = RFID_LAYER2_ISO15693,
|
||||
.name = "ISO 15693",
|
||||
.fn = {
|
||||
.init = &iso15693_init,
|
||||
.open = &iso15693_anticol,
|
||||
//.transceive = &iso15693_transceive,
|
||||
//.close = &iso14443a_hlta,
|
||||
.fini = &iso15693_fini,
|
||||
.setopt = &iso15693_setopt,
|
||||
.getopt = &iso15693_getopt,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
|
||||
/* Mifare Classic implementation, PCD side.
|
||||
*
|
||||
* (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
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <librfid/rfid.h>
|
||||
#include <librfid/rfid_protocol.h>
|
||||
#include <librfid/rfid_layer2.h>
|
||||
#include <librfid/rfid_protocol_mifare_classic.h>
|
||||
|
||||
#include <librfid/rfid_reader.h>
|
||||
|
||||
#include "rfid_iso14443_common.h"
|
||||
|
||||
|
||||
#define MIFARE_UL_CMD_WRITE 0xA2
|
||||
#define MIFARE_UL_CMD_READ 0x30
|
||||
|
||||
/* FIXME */
|
||||
#define MIFARE_CL_READ_FWT 100
|
||||
#define MIFARE_CL_WRITE_FWT 100
|
||||
|
||||
static int
|
||||
mfcl_read(struct rfid_protocol_handle *ph, unsigned int page,
|
||||
unsigned char *rx_data, unsigned int *rx_len)
|
||||
{
|
||||
unsigned char rx_buf[16];
|
||||
unsigned int real_rx_len = sizeof(rx_buf);
|
||||
unsigned char tx[2];
|
||||
int ret;
|
||||
|
||||
if (page > MIFARE_CL_PAGE_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
tx[0] = MIFARE_CL_CMD_READ;
|
||||
tx[1] = page & 0xff;
|
||||
|
||||
ret = rfid_layer2_transceive(ph->l2h, RFID_MIFARE_FRAME, tx,
|
||||
sizeof(tx), rx_buf, &real_rx_len,
|
||||
MIFARE_CL_READ_FWT, 0);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (real_rx_len == 1 && *rx_buf == 0x04)
|
||||
return -EPERM;
|
||||
|
||||
if (real_rx_len < *rx_len)
|
||||
*rx_len = real_rx_len;
|
||||
|
||||
memcpy(rx_data, rx_buf, *rx_len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
mfcl_write(struct rfid_protocol_handle *ph, unsigned int page,
|
||||
unsigned char *tx_data, unsigned int tx_len)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned char tx[18];
|
||||
unsigned char rx[1];
|
||||
unsigned int rx_len = sizeof(rx);
|
||||
int ret;
|
||||
|
||||
if (page > MIFARE_CL_PAGE_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
if (tx_len != 16 && tx_len != 4)
|
||||
return -EINVAL;
|
||||
|
||||
if (tx_len == 16) {
|
||||
tx[0] = MIFARE_CL_CMD_WRITE16;
|
||||
tx[1] = page & 0xff;
|
||||
|
||||
ret = rfid_layer2_transceive(ph->l2h, RFID_MIFARE_FRAME, tx,
|
||||
2, rx, &rx_len,
|
||||
MIFARE_CL_WRITE_FWT, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = rfid_layer2_transceive(ph->l2h, RFID_MIFARE_FRAME, tx_data,
|
||||
tx_len, rx, &rx_len,
|
||||
MIFARE_CL_WRITE_FWT, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (rx[0] != MIFARE_UL_RESP_ACK)
|
||||
return -EIO;
|
||||
|
||||
ret = rfid_layer2_transceive(ph->l2h, RFID_MIFARE_FRAME, tx,
|
||||
sizeof(tx), rx, &rx_len,
|
||||
MIFARE_CL_WRITE_FWT, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (rx[0] != MIFARE_UL_RESP_ACK)
|
||||
return -EIO;
|
||||
|
||||
} else if (tx_len == 4) {
|
||||
|
||||
tx[0] = MIFARE_CL_CMD_WRITE4;
|
||||
tx[1] = page & 0xff;
|
||||
|
||||
memcpy(tx+2, tx_data, 4);
|
||||
|
||||
ret = rfid_layer2_transceive(ph->l2h, RFID_MIFARE_FRAME, tx,
|
||||
2+4, rx, &rx_len,
|
||||
MIFARE_CL_WRITE_FWT, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (rx[0] != MIFARE_UL_RESP_ACK)
|
||||
return -EIO;
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
mfcl_getopt(struct rfid_protocol_handle *ph, int optname, void *optval,
|
||||
unsigned int *optlen)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
u_int16_t atqa;
|
||||
unsigned int atqa_size = sizeof(atqa);
|
||||
unsigned int *size = optval;
|
||||
|
||||
switch (optname) {
|
||||
case RFID_OPT_PROTO_SIZE:
|
||||
if (*optlen < sizeof(*size))
|
||||
return -EINVAL;
|
||||
*optlen = sizeof(*size);
|
||||
ret = 0;
|
||||
rfid_layer2_getopt(ph->l2h, RFID_OPT_14443A_ATQA,
|
||||
(void *) &atqa, &atqa_size);
|
||||
if (atqa == 0x0004)
|
||||
*size = 1024;
|
||||
else if (atqa == 0x0002)
|
||||
*size = 4096;
|
||||
else
|
||||
ret = -EIO;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct rfid_protocol_handle *
|
||||
mfcl_init(struct rfid_layer2_handle *l2h)
|
||||
{
|
||||
struct rfid_protocol_handle *ph;
|
||||
|
||||
if (l2h->l2->id != RFID_LAYER2_ISO14443A)
|
||||
return NULL;
|
||||
|
||||
if (l2h->uid_len != 4)
|
||||
return NULL;
|
||||
|
||||
ph = malloc_protocol_handle(sizeof(struct rfid_protocol_handle));
|
||||
return ph;
|
||||
}
|
||||
|
||||
static int mfcl_fini(struct rfid_protocol_handle *ph)
|
||||
{
|
||||
free_protocol_handle(ph);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct rfid_protocol rfid_protocol_mfcl = {
|
||||
.id = RFID_PROTOCOL_MIFARE_CLASSIC,
|
||||
.name = "Mifare Classic",
|
||||
.fn = {
|
||||
.init = &mfcl_init,
|
||||
.read = &mfcl_read,
|
||||
.write = &mfcl_write,
|
||||
.fini = &mfcl_fini,
|
||||
.getopt = &mfcl_getopt,
|
||||
},
|
||||
};
|
||||
|
||||
int mfcl_set_key(struct rfid_protocol_handle *ph, unsigned char *key)
|
||||
{
|
||||
if (!ph->l2h->rh->reader->mifare_classic.setkey)
|
||||
return -ENODEV;
|
||||
|
||||
return ph->l2h->rh->reader->mifare_classic.setkey(ph->l2h->rh, key);
|
||||
}
|
||||
|
||||
int mfcl_auth(struct rfid_protocol_handle *ph, u_int8_t cmd, u_int8_t block)
|
||||
{
|
||||
u_int32_t serno = *((u_int32_t *)ph->l2h->uid);
|
||||
|
||||
if (!ph->l2h->rh->reader->mifare_classic.auth)
|
||||
return -ENODEV;
|
||||
|
||||
return ph->l2h->rh->reader->mifare_classic.auth(ph->l2h->rh, cmd,
|
||||
serno, block);
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
|
||||
/* Mifare Ultralight implementation, PCD side.
|
||||
*
|
||||
* (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
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <librfid/rfid.h>
|
||||
#include <librfid/rfid_protocol.h>
|
||||
#include <librfid/rfid_layer2.h>
|
||||
#include <librfid/rfid_protocol_mifare_ul.h>
|
||||
|
||||
#include "rfid_iso14443_common.h"
|
||||
|
||||
|
||||
/* FIXME */
|
||||
#define MIFARE_UL_READ_FWT 100
|
||||
#define MIFARE_UL_WRITE_FWT 100
|
||||
|
||||
static int
|
||||
mful_read(struct rfid_protocol_handle *ph, unsigned int page,
|
||||
unsigned char *rx_data, unsigned int *rx_len)
|
||||
{
|
||||
unsigned char rx_buf[16];
|
||||
unsigned int real_rx_len = sizeof(rx_buf);
|
||||
unsigned char tx[2];
|
||||
int ret;
|
||||
|
||||
if (page > MIFARE_UL_PAGE_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
tx[0] = MIFARE_UL_CMD_READ;
|
||||
tx[1] = page & 0xff;
|
||||
|
||||
ret = rfid_layer2_transceive(ph->l2h, RFID_14443A_FRAME_REGULAR,
|
||||
tx, sizeof(tx), rx_buf,
|
||||
&real_rx_len, MIFARE_UL_READ_FWT, 0);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (real_rx_len < *rx_len)
|
||||
*rx_len = real_rx_len;
|
||||
|
||||
memcpy(rx_data, rx_buf, *rx_len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
mful_write(struct rfid_protocol_handle *ph, unsigned int page,
|
||||
unsigned char *tx_data, unsigned int tx_len)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned char tx[6];
|
||||
unsigned char rx[10];
|
||||
unsigned int rx_len = sizeof(rx);
|
||||
int ret;
|
||||
|
||||
if (tx_len != 4 || page > MIFARE_UL_PAGE_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
tx[0] = MIFARE_UL_CMD_WRITE;
|
||||
tx[1] = page & 0xff;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
tx[2+i] = tx_data[i];
|
||||
|
||||
ret = rfid_layer2_transceive(ph->l2h, RFID_14443A_FRAME_REGULAR,
|
||||
tx, sizeof(tx), rx, &rx_len,
|
||||
MIFARE_UL_WRITE_FWT, 0);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (rx[0] != MIFARE_UL_RESP_ACK)
|
||||
return -EIO;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
mful_transceive(struct rfid_protocol_handle *ph,
|
||||
const unsigned char *tx_data, unsigned int tx_len,
|
||||
unsigned char *rx_data, unsigned int *rx_len,
|
||||
unsigned int timeout, unsigned int flags)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int
|
||||
mful_getopt(struct rfid_protocol_handle *ph, int optname, void *optval,
|
||||
unsigned int *optlen)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
u_int16_t atqa;
|
||||
unsigned int *size = optval;
|
||||
|
||||
switch (optname) {
|
||||
case RFID_OPT_PROTO_SIZE:
|
||||
ret = 0;
|
||||
*size = 512;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static struct rfid_protocol_handle *
|
||||
mful_init(struct rfid_layer2_handle *l2h)
|
||||
{
|
||||
struct rfid_protocol_handle *ph;
|
||||
u_int16_t atqa;
|
||||
unsigned int atqa_len = sizeof(atqa);
|
||||
|
||||
if (l2h->l2->id != RFID_LAYER2_ISO14443A)
|
||||
return NULL;
|
||||
|
||||
/* According to "Type Identification Procedure Rev. 1.3" */
|
||||
rfid_layer2_getopt(l2h, RFID_OPT_14443A_ATQA,
|
||||
&atqa, &atqa_len);
|
||||
if (atqa != 0x0044)
|
||||
return NULL;
|
||||
|
||||
/* according to "Functional Specification Rev. 3.0 */
|
||||
if (l2h->uid_len != 7)
|
||||
return NULL;
|
||||
|
||||
ph = malloc_protocol_handle(sizeof(struct rfid_protocol_handle));
|
||||
return ph;
|
||||
}
|
||||
|
||||
static int mful_fini(struct rfid_protocol_handle *ph)
|
||||
{
|
||||
free_protocol_handle(ph);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct rfid_protocol rfid_protocol_mful = {
|
||||
.id = RFID_PROTOCOL_MIFARE_UL,
|
||||
.name = "Mifare Ultralight",
|
||||
.fn = {
|
||||
.init = &mful_init,
|
||||
.read = &mful_read,
|
||||
.write = &mful_write,
|
||||
.fini = &mful_fini,
|
||||
.getopt = &mful_getopt,
|
||||
},
|
||||
};
|
||||
|
||||
/* Functions below are not (yet? covered in the generic librfid api */
|
||||
|
||||
|
||||
/* lock a certain page */
|
||||
int rfid_mful_lock_page(struct rfid_protocol_handle *ph, unsigned int page)
|
||||
{
|
||||
unsigned char buf[4] = { 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
if (ph->proto != &rfid_protocol_mful)
|
||||
return -EINVAL;
|
||||
|
||||
if (page < 3 || page > 15)
|
||||
return -EINVAL;
|
||||
|
||||
if (page > 8)
|
||||
buf[2] = (1 << page);
|
||||
else
|
||||
buf[3] = (1 << (page - 8));
|
||||
|
||||
return mful_write(ph, MIFARE_UL_PAGE_LOCK, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
/* convenience wrapper to lock the otp page */
|
||||
int rfid_mful_lock_otp(struct rfid_protocol_handle *ph)
|
||||
{
|
||||
return rfid_mful_lock_page(ph, MIFARE_UL_PAGE_OTP);
|
||||
}
|
||||
@@ -0,0 +1,817 @@
|
||||
/* ISO 14443-4 (T=CL) implementation, PCD side.
|
||||
*
|
||||
* (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
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <librfid/rfid.h>
|
||||
#include <librfid/rfid_protocol_tcl.h>
|
||||
#include <librfid/rfid_protocol.h>
|
||||
#include <librfid/rfid_layer2.h>
|
||||
#include <librfid/rfid_layer2_iso14443b.h>
|
||||
|
||||
#include <librfid/rfid_asic.h>
|
||||
#include <librfid/rfid_reader.h>
|
||||
|
||||
#include "rfid_iso14443_common.h"
|
||||
|
||||
#define RFID_MAX_FRAMELEN 256
|
||||
|
||||
#define is_s_block(x) ((x & 0xc0) == 0xc0)
|
||||
#define is_r_block(x) ((x & 0xc0) == 0x80)
|
||||
#define is_i_block(x) ((x & 0xc0) == 0x00)
|
||||
|
||||
static enum rfid_frametype l2_to_frame(unsigned int layer2)
|
||||
{
|
||||
switch (layer2) {
|
||||
case RFID_LAYER2_ISO14443A:
|
||||
return RFID_14443A_FRAME_REGULAR;
|
||||
break;
|
||||
case RFID_LAYER2_ISO14443B:
|
||||
return RFID_14443B_FRAME_REGULAR;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int sfgi_to_sfgt(struct rfid_protocol_handle *h,
|
||||
unsigned char sfgi)
|
||||
{
|
||||
unsigned int multiplier;
|
||||
unsigned int tmp;
|
||||
|
||||
if (sfgi > 14)
|
||||
sfgi = 14;
|
||||
|
||||
multiplier = 1 << sfgi; /* 2 to the power of sfgi */
|
||||
|
||||
/* ISO 14443-4:2000(E) Section 5.2.5:
|
||||
* (256 * 16 / h->l2h->rh->ah->fc) * (2 ^ sfgi) */
|
||||
tmp = (unsigned int) 1000000 * 256 * 16;
|
||||
|
||||
return (tmp / h->l2h->rh->ah->fc) * multiplier;
|
||||
}
|
||||
|
||||
static unsigned int fwi_to_fwt(struct rfid_protocol_handle *h,
|
||||
unsigned char fwi)
|
||||
{
|
||||
unsigned int multiplier, tmp;
|
||||
|
||||
if (fwi > 14)
|
||||
fwi = 14;
|
||||
|
||||
multiplier = 1 << fwi; /* 2 to the power of fwi */
|
||||
|
||||
/* ISO 14443-4:2000(E) Section 7.2.:
|
||||
* (256*16 / h->l2h->rh->ah->fc) * (2 ^ fwi) */
|
||||
|
||||
tmp = (unsigned int) 1000000 * 256 * 16;
|
||||
|
||||
return (tmp / h->l2h->rh->ah->fc) * multiplier;
|
||||
}
|
||||
|
||||
/* 4.9seconds as microseconds (4.9 billion seconds) exceeds 2^32 */
|
||||
#define activation_fwt(x) (((u_int64_t)1000000 * 65536 / x->l2h->rh->ah->fc))
|
||||
#define deactivation_fwt(x) activation_fwt(x)
|
||||
|
||||
static int
|
||||
tcl_parse_ats(struct rfid_protocol_handle *h,
|
||||
unsigned char *ats, unsigned int size)
|
||||
{
|
||||
unsigned char len = ats[0];
|
||||
unsigned char t0;
|
||||
unsigned char *cur;
|
||||
|
||||
if (len == 0 || size == 0)
|
||||
return -1;
|
||||
|
||||
if (size < len)
|
||||
len = size;
|
||||
|
||||
h->priv.tcl.ta = 0;
|
||||
|
||||
if (len == 1) {
|
||||
/* FIXME: assume some default values */
|
||||
h->priv.tcl.fsc = 32;
|
||||
h->priv.tcl.ta = 0x80; /* 0x80 (same d for both dirs) */
|
||||
h->priv.tcl.sfgt = sfgi_to_sfgt(h, 0);
|
||||
if (h->l2h->l2->id == RFID_LAYER2_ISO14443A) {
|
||||
/* Section 7.2: fwi default for type A is 4 */
|
||||
h->priv.tcl.fwt = fwi_to_fwt(h, 4);
|
||||
} else {
|
||||
/* Section 7.2: fwi for type B is always in ATQB */
|
||||
/* Value is assigned in tcl_connect() */
|
||||
/* This function is never called for Type B,
|
||||
* since Type B has no (R)ATS */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* guarateed to be at least 2 bytes in size */
|
||||
|
||||
t0 = ats[1];
|
||||
cur = &ats[2];
|
||||
|
||||
iso14443_fsdi_to_fsd(&h->priv.tcl.fsc, t0 & 0x0f);
|
||||
if (h->priv.tcl.fsc > h->l2h->rh->ah->mtu)
|
||||
h->priv.tcl.fsc = h->l2h->rh->ah->mtu;
|
||||
|
||||
if (t0 & (1 << 4)) {
|
||||
/* TA is transmitted */
|
||||
h->priv.tcl.ta = *cur++;
|
||||
}
|
||||
|
||||
if (t0 & (1 << 5)) {
|
||||
/* TB is transmitted */
|
||||
h->priv.tcl.sfgt = sfgi_to_sfgt(h, *cur & 0x0f);
|
||||
h->priv.tcl.fwt = fwi_to_fwt(h, (*cur & 0xf0) >> 4);
|
||||
cur++;
|
||||
}
|
||||
|
||||
if (t0 & (1 << 6)) {
|
||||
/* TC is transmitted */
|
||||
if (*cur & 0x01) {
|
||||
h->priv.tcl.flags |= TCL_HANDLE_F_NAD_SUPPORTED;
|
||||
DEBUGP("This PICC supports NAD\n");
|
||||
}
|
||||
if (*cur & 0x02) {
|
||||
h->priv.tcl.flags |= TCL_HANDLE_F_CID_SUPPORTED;
|
||||
DEBUGP("This PICC supports CID\n");
|
||||
}
|
||||
cur++;
|
||||
}
|
||||
|
||||
h->priv.tcl.historical_len = (ats+len) - cur;
|
||||
h->priv.tcl.historical_bytes = cur;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* request an ATS from the PICC */
|
||||
static int
|
||||
tcl_request_ats(struct rfid_protocol_handle *h)
|
||||
{
|
||||
int ret;
|
||||
unsigned char rats[2];
|
||||
unsigned char fsdi;
|
||||
|
||||
if (h->priv.tcl.state != TCL_STATE_INITIAL)
|
||||
return -1;
|
||||
|
||||
ret = iso14443_fsd_to_fsdi(&fsdi, h->priv.tcl.fsd);
|
||||
if (ret < 0) {
|
||||
DEBUGP("unable to encode FSD of %u as FSDI\n", h->priv.tcl.fsd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
rats[0] = 0xe0;
|
||||
rats[1] = (h->priv.tcl.cid & 0x0f) | ((fsdi << 4) & 0xf0);
|
||||
|
||||
/* transceive (with CRC) */
|
||||
ret = rfid_layer2_transceive(h->l2h, RFID_14443A_FRAME_REGULAR,
|
||||
rats, 2, h->priv.tcl.ats,
|
||||
&h->priv.tcl.ats_len, activation_fwt(h),
|
||||
TCL_TRANSP_F_TX_CRC);
|
||||
if (ret < 0) {
|
||||
DEBUGP("transceive of rats failed\n");
|
||||
h->priv.tcl.state = TCL_STATE_RATS_SENT;
|
||||
/* FIXME: retransmit */
|
||||
return ret;
|
||||
}
|
||||
h->priv.tcl.state = TCL_STATE_ATS_RCVD;
|
||||
|
||||
ret = tcl_parse_ats(h, h->priv.tcl.ats, h->priv.tcl.ats_len);
|
||||
if (ret < 0) {
|
||||
DEBUGP("parsing of ats failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define ATS_TA_DIV_2 1
|
||||
#define ATS_TA_DIV_4 2
|
||||
#define ATS_TA_DIV_8 4
|
||||
|
||||
#define PPS_DIV_8 3
|
||||
#define PPS_DIV_4 2
|
||||
#define PPS_DIV_2 1
|
||||
#define PPS_DIV_1 0
|
||||
static unsigned char d_to_di(struct rfid_protocol_handle *h, unsigned char D)
|
||||
{
|
||||
static char DI;
|
||||
unsigned int speed = h->l2h->rh->reader->iso14443a.speed;
|
||||
|
||||
if ((D & ATS_TA_DIV_8) && (speed & RFID_14443A_SPEED_848K))
|
||||
DI = PPS_DIV_8;
|
||||
else if ((D & ATS_TA_DIV_4) && (speed & RFID_14443A_SPEED_424K))
|
||||
DI = PPS_DIV_4;
|
||||
else if ((D & ATS_TA_DIV_2) && (speed & RFID_14443A_SPEED_212K))
|
||||
DI = PPS_DIV_2;
|
||||
else
|
||||
DI = PPS_DIV_1;
|
||||
|
||||
return DI;
|
||||
}
|
||||
|
||||
static unsigned int di_to_speed(unsigned char DI)
|
||||
{
|
||||
switch (DI) {
|
||||
case PPS_DIV_8:
|
||||
return RFID_14443A_SPEED_848K;
|
||||
break;
|
||||
case PPS_DIV_4:
|
||||
return RFID_14443A_SPEED_424K;
|
||||
break;
|
||||
case PPS_DIV_2:
|
||||
return RFID_14443A_SPEED_212K;
|
||||
break;
|
||||
case PPS_DIV_1:
|
||||
return RFID_14443A_SPEED_106K;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* start a PPS run (autimatically configure highest possible speed */
|
||||
static int
|
||||
tcl_do_pps(struct rfid_protocol_handle *h)
|
||||
{
|
||||
int ret;
|
||||
unsigned char ppss[3];
|
||||
/* FIXME: this stinks like hell. IF we reduce pps_response size to one,
|
||||
we'll get stack corruption! */
|
||||
unsigned char pps_response[10];
|
||||
unsigned int rx_len = 1;
|
||||
unsigned char Dr, Ds, DrI, DsI;
|
||||
unsigned int speed;
|
||||
|
||||
if (h->priv.tcl.state != TCL_STATE_ATS_RCVD)
|
||||
return -1;
|
||||
|
||||
Dr = h->priv.tcl.ta & 0x07;
|
||||
Ds = h->priv.tcl.ta & 0x70 >> 4;
|
||||
DEBUGP("Dr = 0x%x, Ds = 0x%x\n", Dr, Ds);
|
||||
|
||||
if (Dr != Ds && !(h->priv.tcl.ta & 0x80)) {
|
||||
/* device supports different divisors for rx and tx, but not
|
||||
* really ?!? */
|
||||
DEBUGP("PICC has contradictory TA, aborting PPS\n");
|
||||
return -1;
|
||||
};
|
||||
|
||||
/* ISO 14443-4:2000(E) Section 5.3. */
|
||||
|
||||
ppss[0] = 0xd0 | (h->priv.tcl.cid & 0x0f);
|
||||
ppss[1] = 0x11;
|
||||
ppss[2] = 0x00;
|
||||
|
||||
/* FIXME: deal with different speed for each direction */
|
||||
DrI = d_to_di(h, Dr);
|
||||
DsI = d_to_di(h, Ds);
|
||||
DEBUGP("DrI = 0x%x, DsI = 0x%x\n", DrI, DsI);
|
||||
|
||||
ppss[2] = (ppss[2] & 0xf0) | (DrI | DsI << 2);
|
||||
|
||||
ret = rfid_layer2_transceive(h->l2h, RFID_14443A_FRAME_REGULAR,
|
||||
ppss, 3, pps_response, &rx_len,
|
||||
h->priv.tcl.fwt, TCL_TRANSP_F_TX_CRC);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (pps_response[0] != ppss[0]) {
|
||||
DEBUGP("PPS Response != PPSS\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
speed = di_to_speed(DrI);
|
||||
|
||||
ret = rfid_layer2_setopt(h->l2h, RFID_OPT_14443A_SPEED_RX,
|
||||
&speed, sizeof(speed));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = rfid_layer2_setopt(h->l2h, RFID_OPT_14443A_SPEED_TX,
|
||||
&speed, sizeof(speed));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
tcl_build_prologue2(struct tcl_handle *th,
|
||||
unsigned char *prlg, unsigned int *prlg_len,
|
||||
unsigned char pcb)
|
||||
{
|
||||
*prlg_len = 1;
|
||||
|
||||
*prlg = pcb;
|
||||
|
||||
if (!is_s_block(pcb)) {
|
||||
if (th->toggle) {
|
||||
/* we've sent a toggle bit last time */
|
||||
th->toggle = 0;
|
||||
} else {
|
||||
/* we've not sent a toggle last time: send one */
|
||||
th->toggle = 1;
|
||||
*prlg |= 0x01;
|
||||
}
|
||||
}
|
||||
|
||||
if (th->flags & TCL_HANDLE_F_CID_USED) {
|
||||
/* ISO 14443-4:2000(E) Section 7.1.1.2 */
|
||||
*prlg |= TCL_PCB_CID_FOLLOWING;
|
||||
(*prlg_len)++;
|
||||
prlg[*prlg_len] = th->cid & 0x0f;
|
||||
}
|
||||
|
||||
/* nad only for I-block */
|
||||
if ((th->flags & TCL_HANDLE_F_NAD_USED) && is_i_block(pcb)) {
|
||||
/* ISO 14443-4:2000(E) Section 7.1.1.3 */
|
||||
/* FIXME: in case of chaining only for first frame */
|
||||
*prlg |= TCL_PCB_NAD_FOLLOWING;
|
||||
prlg[*prlg_len] = th->nad;
|
||||
(*prlg_len)++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tcl_build_prologue_i(struct tcl_handle *th,
|
||||
unsigned char *prlg, unsigned int *prlg_len)
|
||||
{
|
||||
/* ISO 14443-4:2000(E) Section 7.1.1.1 */
|
||||
return tcl_build_prologue2(th, prlg, prlg_len, 0x02);
|
||||
}
|
||||
|
||||
static int
|
||||
tcl_build_prologue_r(struct tcl_handle *th,
|
||||
unsigned char *prlg, unsigned int *prlg_len,
|
||||
unsigned int nak)
|
||||
{
|
||||
unsigned char pcb = 0xa2;
|
||||
/* ISO 14443-4:2000(E) Section 7.1.1.1 */
|
||||
|
||||
if (nak)
|
||||
pcb |= 0x10;
|
||||
|
||||
return tcl_build_prologue2(th, prlg, prlg_len, pcb);
|
||||
}
|
||||
|
||||
static int
|
||||
tcl_build_prologue_s(struct tcl_handle *th,
|
||||
unsigned char *prlg, unsigned int *prlg_len)
|
||||
{
|
||||
/* ISO 14443-4:2000(E) Section 7.1.1.1 */
|
||||
|
||||
/* the only S-block from PCD->PICC is DESELECT,
|
||||
* well, actually there is the S(WTX) response. */
|
||||
return tcl_build_prologue2(th, prlg, prlg_len, 0xc2);
|
||||
}
|
||||
|
||||
/* FIXME: WTXM implementation */
|
||||
|
||||
static int tcl_prlg_len(struct tcl_handle *th)
|
||||
{
|
||||
int prlg_len = 1;
|
||||
|
||||
if (th->flags & TCL_HANDLE_F_CID_USED)
|
||||
prlg_len++;
|
||||
|
||||
if (th->flags & TCL_HANDLE_F_NAD_USED)
|
||||
prlg_len++;
|
||||
|
||||
return prlg_len;
|
||||
}
|
||||
|
||||
#define max_net_tx_framesize(x) (x->fsc - tcl_prlg_len(x))
|
||||
|
||||
static int
|
||||
tcl_connect(struct rfid_protocol_handle *h)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (h->priv.tcl.state != TCL_STATE_DESELECTED &&
|
||||
h->priv.tcl.state != TCL_STATE_INITIAL)
|
||||
return -1;
|
||||
|
||||
switch (h->l2h->l2->id) {
|
||||
case RFID_LAYER2_ISO14443A:
|
||||
/* Start Type A T=CL Activation Sequence */
|
||||
ret = tcl_request_ats(h);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Only do PPS if any non-default divisors supported */
|
||||
if (h->priv.tcl.ta & 0x77) {
|
||||
ret = tcl_do_pps(h);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
case RFID_LAYER2_ISO14443B:
|
||||
/* initialized T=CL state from Type B Activation Data */
|
||||
h->priv.tcl.cid = h->l2h->priv.iso14443b.cid;
|
||||
h->priv.tcl.fsc = h->l2h->priv.iso14443b.fsc;
|
||||
h->priv.tcl.fsd = h->l2h->priv.iso14443b.fsd;
|
||||
h->priv.tcl.fwt = h->l2h->priv.iso14443b.fwt;
|
||||
|
||||
/* what about ta? sfgt? */
|
||||
|
||||
if (h->l2h->priv.iso14443b.flags & ISO14443B_CID_SUPPORTED)
|
||||
h->priv.tcl.flags |= TCL_HANDLE_F_CID_SUPPORTED;
|
||||
if (h->l2h->priv.iso14443b.flags & ISO14443B_NAD_SUPPORTED)
|
||||
h->priv.tcl.flags |= TCL_HANDLE_F_NAD_SUPPORTED;
|
||||
|
||||
switch (h->l2h->priv.iso14443b.state) {
|
||||
case ISO14443B_STATE_SELECTED:
|
||||
h->priv.tcl.state = TCL_STATE_ATS_RCVD;
|
||||
break;
|
||||
case ISO14443B_STATE_ATTRIB_SENT:
|
||||
h->priv.tcl.state = TCL_STATE_RATS_SENT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* PUPI will be presented as ATS/historical bytes */
|
||||
memcpy(h->priv.tcl.ats, h->l2h->uid, 4);
|
||||
h->priv.tcl.ats_len = 4;
|
||||
h->priv.tcl.historical_bytes = h->priv.tcl.ats;
|
||||
|
||||
break;
|
||||
default:
|
||||
DEBUGP("unsupported l2: %u\n", h->l2h->l2->id);
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
h->priv.tcl.state = TCL_STATE_ESTABLISHED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tcl_deselect(struct rfid_protocol_handle *h)
|
||||
{
|
||||
/* ISO 14443-4:2000(E) Section 8 */
|
||||
int ret;
|
||||
unsigned char frame[3]; /* 3 bytes prologue, no information */
|
||||
unsigned char rx[3];
|
||||
unsigned int rx_len = sizeof(rx);
|
||||
unsigned int prlg_len;
|
||||
struct tcl_handle *th = &h->priv.tcl;
|
||||
|
||||
if (th->state != TCL_STATE_ESTABLISHED) {
|
||||
/* FIXME: not sure whether deselect is possible here,
|
||||
* probably better send a HLTA? */
|
||||
}
|
||||
|
||||
/* build DESELECT S-block */
|
||||
ret = tcl_build_prologue_s(th, frame, &prlg_len);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = rfid_layer2_transceive(h->l2h, RFID_14443A_FRAME_REGULAR,
|
||||
frame, prlg_len, rx,
|
||||
&rx_len, deactivation_fwt(h),
|
||||
TCL_TRANSP_F_TX_CRC);
|
||||
if (ret < 0) {
|
||||
/* FIXME: retransmit, HLT(A|B) */
|
||||
return ret;
|
||||
}
|
||||
|
||||
th->state = TCL_STATE_DESELECTED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct fr_buff {
|
||||
unsigned int frame_len; /* length of frame */
|
||||
unsigned int hdr_len; /* length of header within frame */
|
||||
unsigned char data[RFID_MAX_FRAMELEN];
|
||||
};
|
||||
|
||||
#define frb_payload(x) (x.data + x.hdr_len)
|
||||
|
||||
|
||||
/* RFID transceive buffer. */
|
||||
struct rfid_xcvb {
|
||||
struct rfix_xcvb *next; /* next in queue of buffers */
|
||||
|
||||
u_int64_t timeout; /* timeout to wait for reply */
|
||||
struct fr_buff tx;
|
||||
struct fr_buff rx;
|
||||
|
||||
//struct rfid_protocol_handle *h; /* connection to which we belong */
|
||||
};
|
||||
|
||||
struct tcl_tx_context {
|
||||
const unsigned char *tx;
|
||||
unsigned char *rx;
|
||||
const unsigned char *next_tx_byte;
|
||||
unsigned char *next_rx_byte;
|
||||
unsigned int rx_len;
|
||||
unsigned int tx_len;
|
||||
struct rfid_protocol_handle *h;
|
||||
};
|
||||
|
||||
#define tcl_ctx_todo(ctx) (ctx->tx_len - (ctx->next_tx_byte - ctx->tx))
|
||||
|
||||
static int
|
||||
tcl_refill_xcvb(struct rfid_xcvb *xcvb, struct tcl_tx_context *ctx)
|
||||
{
|
||||
struct tcl_handle *th = &ctx->h->priv.tcl;
|
||||
|
||||
if (ctx->next_tx_byte >= ctx->tx + ctx->tx_len) {
|
||||
DEBUGP("tyring to refill tx xcvb but no data left!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tcl_build_prologue_i(th, xcvb->tx.data,
|
||||
&xcvb->tx.hdr_len) < 0)
|
||||
return -1;
|
||||
|
||||
if (tcl_ctx_todo(ctx) > th->fsc - xcvb->tx.hdr_len)
|
||||
xcvb->tx.frame_len = max_net_tx_framesize(th);
|
||||
else
|
||||
xcvb->tx.frame_len = tcl_ctx_todo(ctx);
|
||||
|
||||
memcpy(frb_payload(xcvb->tx), ctx->next_tx_byte,
|
||||
xcvb->tx.frame_len);
|
||||
|
||||
ctx->next_tx_byte += xcvb->tx.frame_len;
|
||||
|
||||
/* check whether we need to set the chaining bit */
|
||||
if (ctx->next_tx_byte < ctx->tx + ctx->tx_len)
|
||||
xcvb->tx.data[0] |= 0x10;
|
||||
|
||||
/* add hdr_len after copying the net payload */
|
||||
xcvb->tx.frame_len += xcvb->tx.hdr_len;
|
||||
|
||||
xcvb->timeout = th->fwt;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fill_xcvb_wtxm(struct tcl_handle *th, struct rfid_xcvb *xcvb,
|
||||
unsigned char inf)
|
||||
{
|
||||
/* Acknowledge WTXM */
|
||||
tcl_build_prologue_s(th, xcvb->tx.data, &xcvb->tx.hdr_len);
|
||||
/* set two bits that make this block a wtx */
|
||||
xcvb->tx.data[0] |= 0x30;
|
||||
xcvb->tx.data[xcvb->tx.hdr_len] = inf;
|
||||
xcvb->tx.frame_len = xcvb->tx.hdr_len+1;
|
||||
xcvb->timeout = th->fwt * inf;
|
||||
}
|
||||
|
||||
static int check_cid(struct tcl_handle *th, struct rfid_xcvb *xcvb)
|
||||
{
|
||||
if (xcvb->rx.data[0] & TCL_PCB_CID_FOLLOWING) {
|
||||
if (xcvb->rx.data[1] != th->cid) {
|
||||
DEBUGP("CID %u is not valid, we expected %u\n",
|
||||
xcvb->rx.data[1], th->cid);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
tcl_transceive(struct rfid_protocol_handle *h,
|
||||
const unsigned char *tx_data, unsigned int tx_len,
|
||||
unsigned char *rx_data, unsigned int *rx_len,
|
||||
unsigned int timeout, unsigned int flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
struct rfid_xcvb xcvb;
|
||||
struct tcl_tx_context tcl_ctx;
|
||||
struct tcl_handle *th = &h->priv.tcl;
|
||||
|
||||
unsigned char ack[10];
|
||||
unsigned int ack_len;
|
||||
|
||||
/* initialize context */
|
||||
tcl_ctx.next_tx_byte = tcl_ctx.tx = tx_data;
|
||||
tcl_ctx.next_rx_byte = tcl_ctx.rx = rx_data;
|
||||
tcl_ctx.rx_len = *rx_len;
|
||||
tcl_ctx.tx_len = tx_len;
|
||||
tcl_ctx.h = h;
|
||||
|
||||
/* initialize xcvb */
|
||||
xcvb.timeout = th->fwt;
|
||||
|
||||
tx_refill:
|
||||
if (tcl_refill_xcvb(&xcvb, &tcl_ctx) < 0) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
do_tx:
|
||||
xcvb.rx.frame_len = sizeof(xcvb.rx.data);
|
||||
ret = rfid_layer2_transceive(h->l2h, l2_to_frame(h->l2h->l2->id),
|
||||
xcvb.tx.data, xcvb.tx.frame_len,
|
||||
xcvb.rx.data, &xcvb.rx.frame_len,
|
||||
xcvb.timeout, 0);
|
||||
|
||||
DEBUGP("l2 transceive finished\n");
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
if (is_r_block(xcvb.rx.data[0])) {
|
||||
DEBUGP("R-Block\n");
|
||||
|
||||
if ((xcvb.rx.data[0] & 0x01) != h->priv.tcl.toggle) {
|
||||
DEBUGP("response with wrong toggle bit\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Handle ACK frame in case of chaining */
|
||||
if (!check_cid(th, &xcvb))
|
||||
goto out;
|
||||
|
||||
goto tx_refill;
|
||||
} else if (is_s_block(xcvb.rx.data[0])) {
|
||||
unsigned char inf;
|
||||
unsigned int prlg_len;
|
||||
|
||||
DEBUGP("S-Block\n");
|
||||
/* Handle Wait Time Extension */
|
||||
|
||||
if (!check_cid(th, &xcvb))
|
||||
goto out;
|
||||
|
||||
if (xcvb.rx.data[0] & TCL_PCB_CID_FOLLOWING) {
|
||||
if (xcvb.rx.frame_len < 3) {
|
||||
DEBUGP("S-Block with CID but short len\n");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
inf = xcvb.rx.data[2];
|
||||
} else
|
||||
inf = xcvb.rx.data[1];
|
||||
|
||||
if ((xcvb.rx.data[0] & 0x30) != 0x30) {
|
||||
DEBUGP("S-Block but not WTX?\n");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
inf &= 0x3f; /* only lower 6 bits code WTXM */
|
||||
if (inf == 0 || (inf >= 60 && inf <= 63)) {
|
||||
DEBUGP("WTXM %u is RFU!\n", inf);
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
fill_xcvb_wtxm(th, &xcvb, inf);
|
||||
/* start over with next transceive */
|
||||
goto do_tx;
|
||||
} else if (is_i_block(xcvb.rx.data[0])) {
|
||||
unsigned int net_payload_len;
|
||||
/* we're actually receiving payload data */
|
||||
|
||||
DEBUGP("I-Block: ");
|
||||
|
||||
if ((xcvb.rx.data[0] & 0x01) != h->priv.tcl.toggle) {
|
||||
DEBUGP("response with wrong toggle bit\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
xcvb.rx.hdr_len = 1;
|
||||
|
||||
if (!check_cid(th, &xcvb))
|
||||
goto out;
|
||||
|
||||
if (xcvb.rx.data[0] & TCL_PCB_CID_FOLLOWING)
|
||||
xcvb.rx.hdr_len++;
|
||||
if (xcvb.rx.data[0] & TCL_PCB_NAD_FOLLOWING)
|
||||
xcvb.rx.hdr_len++;
|
||||
|
||||
net_payload_len = xcvb.rx.frame_len - xcvb.rx.hdr_len;
|
||||
DEBUGPC("%u bytes\n", net_payload_len);
|
||||
memcpy(tcl_ctx.next_rx_byte, &xcvb.rx.data[xcvb.rx.hdr_len],
|
||||
net_payload_len);
|
||||
tcl_ctx.next_rx_byte += net_payload_len;
|
||||
|
||||
if (xcvb.rx.data[0] & 0x10) {
|
||||
/* we're not the last frame in the chain, continue rx */
|
||||
DEBUGP("not the last frame in the chain, continue\n");
|
||||
ack_len = sizeof(ack);
|
||||
tcl_build_prologue_r(th, xcvb.tx.data, &xcvb.tx.frame_len, 0);
|
||||
xcvb.timeout = th->fwt;
|
||||
goto do_tx;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
*rx_len = tcl_ctx.next_rx_byte - tcl_ctx.rx;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct rfid_protocol_handle *
|
||||
tcl_init(struct rfid_layer2_handle *l2h)
|
||||
{
|
||||
struct rfid_protocol_handle *th;
|
||||
unsigned int mru = l2h->rh->ah->mru;
|
||||
|
||||
th = malloc_protocol_handle(sizeof(struct rfid_protocol_handle));
|
||||
if (!th)
|
||||
return NULL;
|
||||
|
||||
/* FIXME: mru should be attribute of layer2 (in case it adds/removes
|
||||
* some overhead */
|
||||
memset(th, 0, sizeof(struct rfid_protocol_handle));
|
||||
|
||||
/* maximum received ats length equals mru of asic/reader */
|
||||
th->priv.tcl.state = TCL_STATE_INITIAL;
|
||||
th->priv.tcl.ats_len = mru;
|
||||
th->priv.tcl.toggle = 1;
|
||||
|
||||
th->priv.tcl.fsd = iso14443_fsd_approx(mru);
|
||||
|
||||
return th;
|
||||
}
|
||||
|
||||
static int
|
||||
tcl_fini(struct rfid_protocol_handle *ph)
|
||||
{
|
||||
free_protocol_handle(ph);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
tcl_getopt(struct rfid_protocol_handle *h, int optname, void *optval,
|
||||
unsigned int *optlen)
|
||||
{
|
||||
u_int8_t *opt_str = optval;
|
||||
|
||||
switch (optname) {
|
||||
case RFID_OPT_P_TCL_ATS:
|
||||
if (h->priv.tcl.ats_len < *optlen)
|
||||
*optlen = h->priv.tcl.ats_len;
|
||||
memcpy(opt_str, h->priv.tcl.ats, *optlen);
|
||||
break;
|
||||
case RFID_OPT_P_TCL_ATS_LEN:
|
||||
if (*optlen < sizeof(u_int8_t))
|
||||
return -E2BIG;
|
||||
*optlen = sizeof(u_int8_t);
|
||||
*opt_str = h->priv.tcl.ats_len & 0xff;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
tcl_setopt(struct rfid_protocol_handle *h, int optname, const void *optval,
|
||||
unsigned int optlen)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
switch (optname) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const struct rfid_protocol rfid_protocol_tcl = {
|
||||
.id = RFID_PROTOCOL_TCL,
|
||||
.name = "ISO 14443-4 / T=CL",
|
||||
.fn = {
|
||||
.init = &tcl_init,
|
||||
.open = &tcl_connect,
|
||||
.transceive = &tcl_transceive,
|
||||
.close = &tcl_deselect,
|
||||
.fini = &tcl_fini,
|
||||
.getopt = &tcl_getopt,
|
||||
.setopt = &tcl_setopt,
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,152 @@
|
||||
/* librfid - layer 4 protocol handler
|
||||
* (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
|
||||
*
|
||||
* 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 <errno.h>
|
||||
|
||||
#include <librfid/rfid_layer2.h>
|
||||
#include <librfid/rfid_protocol.h>
|
||||
|
||||
static const struct rfid_protocol *rfid_protocols[] = {
|
||||
[RFID_PROTOCOL_MIFARE_CLASSIC] = &rfid_protocol_mfcl,
|
||||
[RFID_PROTOCOL_MIFARE_UL] = &rfid_protocol_mful,
|
||||
[RFID_PROTOCOL_TCL] = &rfid_protocol_tcl,
|
||||
};
|
||||
|
||||
struct rfid_protocol_handle *
|
||||
rfid_protocol_init(struct rfid_layer2_handle *l2h, unsigned int id)
|
||||
{
|
||||
struct rfid_protocol *p;
|
||||
struct rfid_protocol_handle *ph = NULL;
|
||||
|
||||
if (id >= ARRAY_SIZE(rfid_protocols))
|
||||
return NULL;
|
||||
|
||||
p = rfid_protocols[id];
|
||||
|
||||
ph = p->fn.init(l2h);
|
||||
if (!ph)
|
||||
return NULL;
|
||||
|
||||
ph->proto = p;
|
||||
ph->l2h = l2h;
|
||||
|
||||
return ph;
|
||||
}
|
||||
|
||||
int
|
||||
rfid_protocol_open(struct rfid_protocol_handle *ph)
|
||||
{
|
||||
if (ph->proto->fn.open)
|
||||
return ph->proto->fn.open(ph);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rfid_protocol_transceive(struct rfid_protocol_handle *ph,
|
||||
const unsigned char *tx_buf, unsigned int len,
|
||||
unsigned char *rx_buf, unsigned int *rx_len,
|
||||
unsigned int timeout, unsigned int flags)
|
||||
{
|
||||
return ph->proto->fn.transceive(ph, tx_buf, len, rx_buf, rx_len,
|
||||
timeout, flags);
|
||||
}
|
||||
|
||||
int
|
||||
rfid_protocol_read(struct rfid_protocol_handle *ph,
|
||||
unsigned int page,
|
||||
unsigned char *rx_data,
|
||||
unsigned int *rx_len)
|
||||
{
|
||||
if (ph->proto->fn.read)
|
||||
return ph->proto->fn.read(ph, page, rx_data, rx_len);
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int
|
||||
rfid_protocol_write(struct rfid_protocol_handle *ph,
|
||||
unsigned int page,
|
||||
unsigned char *tx_data,
|
||||
unsigned int tx_len)
|
||||
{
|
||||
if (ph->proto->fn.write)
|
||||
return ph->proto->fn.write(ph, page, tx_data, tx_len);
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int rfid_protocol_fini(struct rfid_protocol_handle *ph)
|
||||
{
|
||||
return ph->proto->fn.fini(ph);
|
||||
}
|
||||
|
||||
int
|
||||
rfid_protocol_close(struct rfid_protocol_handle *ph)
|
||||
{
|
||||
if (ph->proto->fn.close)
|
||||
return ph->proto->fn.close(ph);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rfid_protocol_getopt(struct rfid_protocol_handle *ph, int optname,
|
||||
void *optval, unsigned int *optlen)
|
||||
{
|
||||
if (optname >> 16 == 0) {
|
||||
unsigned char *optchar = optval;
|
||||
|
||||
switch (optname) {
|
||||
default:
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (!ph->proto->fn.getopt)
|
||||
return -EINVAL;
|
||||
|
||||
return ph->proto->fn.getopt(ph, optname, optval, optlen);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rfid_protocol_setopt(struct rfid_protocol_handle *ph, int optname,
|
||||
const void *optval, unsigned int optlen)
|
||||
{
|
||||
if (optname >> 16 == 0) {
|
||||
switch (optname) {
|
||||
default:
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (!ph->proto->fn.setopt)
|
||||
return -EINVAL;
|
||||
|
||||
return ph->proto->fn.setopt(ph, optname, optval, optlen);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *rfid_protocol_name(struct rfid_protocol_handle *ph)
|
||||
{
|
||||
return ph->proto->name;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/* librfid - core reader handling
|
||||
* (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
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
|
||||
#include <librfid/rfid.h>
|
||||
#include <librfid/rfid_reader.h>
|
||||
#include <librfid/rfid_reader_cm5121.h>
|
||||
#include <librfid/rfid_reader_openpcd.h>
|
||||
|
||||
static const struct rfid_reader *rfid_readers[] = {
|
||||
#ifdef ENABLE_CM5121
|
||||
[RFID_READER_CM5121] = &rfid_reader_cm5121,
|
||||
#endif
|
||||
[RFID_READER_OPENPCD] = &rfid_reader_openpcd,
|
||||
};
|
||||
|
||||
struct rfid_reader_handle *
|
||||
rfid_reader_open(void *data, unsigned int id)
|
||||
{
|
||||
const struct rfid_reader *p;
|
||||
|
||||
if (id >= ARRAY_SIZE(rfid_readers)) {
|
||||
DEBUGP("unable to find matching reader\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = rfid_readers[id];
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
return p->open(data);
|
||||
}
|
||||
|
||||
int
|
||||
rfid_reader_transceive(struct rfid_reader_handle *rh,
|
||||
enum rfid_frametype frametype,
|
||||
const unsigned char *tx_buf, unsigned int len,
|
||||
unsigned char *rx_buf, unsigned int *rx_len,
|
||||
u_int64_t timeout, unsigned int flags)
|
||||
{
|
||||
return rh->reader->transceive(rh, frametype, tx_buf, len, rx_buf,
|
||||
rx_len, timeout, flags);
|
||||
}
|
||||
|
||||
void
|
||||
rfid_reader_close(struct rfid_reader_handle *rh)
|
||||
{
|
||||
rh->reader->close(rh);
|
||||
}
|
||||
@@ -0,0 +1,392 @@
|
||||
/* Omnikey CardMan 5121 specific RC632 transport layer
|
||||
*
|
||||
* (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,
|
||||
* not via SPI.
|
||||
*
|
||||
* The vendor-supplied reader firmware provides some undocumented extensions
|
||||
* to CCID (via PC_to_RDR_Escape) that allow access to registers and FIFO of
|
||||
* the RC632.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 <errno.h>
|
||||
|
||||
#include <librfid/rfid.h>
|
||||
|
||||
#ifndef LIBRFID_FIRMWARE
|
||||
|
||||
#include <librfid/rfid_reader.h>
|
||||
#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"
|
||||
|
||||
/* FIXME */
|
||||
#include "rc632.h"
|
||||
|
||||
#define SENDBUF_LEN 256+7+10 /* 256bytes max FSD/FSC, plus 7 bytes header,
|
||||
plus 10 bytes reserve */
|
||||
#define RECVBUF_LEN SENDBUF_LEN
|
||||
|
||||
//#define DEBUG_REGISTER
|
||||
|
||||
#ifdef DEBUG_REGISTER
|
||||
#define DEBUGRC DEBUGPC
|
||||
#define DEBUGR DEBUGP
|
||||
#else
|
||||
#define DEBUGRC(x, args ...) do {} while(0)
|
||||
#define DEBUGR(x, args ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
static
|
||||
int Write1ByteToReg(struct rfid_asic_transport_handle *rath,
|
||||
unsigned char reg, unsigned char value)
|
||||
{
|
||||
unsigned char sndbuf[SENDBUF_LEN];
|
||||
unsigned char rcvbuf[RECVBUF_LEN];
|
||||
size_t retlen = RECVBUF_LEN;
|
||||
|
||||
sndbuf[0] = 0x20;
|
||||
sndbuf[1] = 0x00;
|
||||
sndbuf[2] = 0x01;
|
||||
sndbuf[3] = 0x00;
|
||||
sndbuf[4] = 0x00;
|
||||
sndbuf[5] = 0x00;
|
||||
sndbuf[6] = reg;
|
||||
sndbuf[7] = value;
|
||||
|
||||
DEBUGR("reg=0x%02x, val=%02x: ", reg, value);
|
||||
|
||||
if (PC_to_RDR_Escape(rath->data, sndbuf, 8, rcvbuf,
|
||||
&retlen) == 0) {
|
||||
DEBUGRC("OK\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEBUGRC("ERROR\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int Read1ByteFromReg(struct rfid_asic_transport_handle *rath,
|
||||
unsigned char reg,
|
||||
unsigned char *value)
|
||||
{
|
||||
unsigned char sndbuf[SENDBUF_LEN];
|
||||
unsigned char recvbuf[RECVBUF_LEN];
|
||||
size_t retlen = sizeof(recvbuf);
|
||||
|
||||
sndbuf[0] = 0x20;
|
||||
sndbuf[1] = 0x00;
|
||||
sndbuf[2] = 0x00;
|
||||
sndbuf[3] = 0x00;
|
||||
sndbuf[4] = 0x01;
|
||||
sndbuf[5] = 0x00;
|
||||
sndbuf[6] = reg;
|
||||
|
||||
if (PC_to_RDR_Escape(rath->data, sndbuf, 7, recvbuf,
|
||||
&retlen) == 0) {
|
||||
*value = recvbuf[1];
|
||||
DEBUGR("reg=0x%02x, val=%02x: ", reg, *value);
|
||||
DEBUGRC("OK\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEBUGRC("ERROR\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int ReadNBytesFromFIFO(struct rfid_asic_transport_handle *rath,
|
||||
unsigned char num_bytes,
|
||||
unsigned char *buf)
|
||||
{
|
||||
unsigned char sndbuf[SENDBUF_LEN];
|
||||
unsigned char recvbuf[0x7f];
|
||||
size_t retlen = sizeof(recvbuf);
|
||||
|
||||
sndbuf[0] = 0x20;
|
||||
sndbuf[1] = 0x00;
|
||||
sndbuf[2] = 0x00;
|
||||
sndbuf[3] = 0x00;
|
||||
sndbuf[4] = num_bytes;
|
||||
sndbuf[5] = 0x00;
|
||||
sndbuf[6] = 0x02;
|
||||
|
||||
DEBUGR("num_bytes=%u: ", num_bytes);
|
||||
if (PC_to_RDR_Escape(rath->data, sndbuf, 7, recvbuf, &retlen) == 0) {
|
||||
DEBUGRC("%u [%s]\n", retlen,
|
||||
rfid_hexdump(recvbuf+1, num_bytes));
|
||||
memcpy(buf, recvbuf+1, num_bytes); // len == 0x7f
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEBUGRC("ERROR\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int WriteNBytesToFIFO(struct rfid_asic_transport_handle *rath,
|
||||
unsigned char len,
|
||||
const unsigned char *bytes,
|
||||
unsigned char flags)
|
||||
{
|
||||
unsigned char sndbuf[SENDBUF_LEN];
|
||||
unsigned char recvbuf[0x7f];
|
||||
size_t retlen = sizeof(recvbuf);
|
||||
|
||||
sndbuf[0] = 0x20;
|
||||
sndbuf[1] = 0x00;
|
||||
sndbuf[2] = len;
|
||||
sndbuf[3] = 0x00;
|
||||
sndbuf[4] = 0x00;
|
||||
sndbuf[5] = flags;
|
||||
sndbuf[6] = 0x02;
|
||||
|
||||
DEBUGR("%u [%s]: ", len, rfid_hexdump(bytes, len));
|
||||
|
||||
memcpy(sndbuf+7, bytes, len);
|
||||
|
||||
if (PC_to_RDR_Escape(rath->data, sndbuf, len+7, recvbuf, &retlen) == 0) {
|
||||
DEBUGRC("OK (%u [%s])\n", retlen, rfid_hexdump(recvbuf, retlen));
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEBUGRC("ERROR\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int TestFIFO(struct rc632_handle *handle)
|
||||
{
|
||||
unsigned char sndbuf[60]; // 0x3c
|
||||
|
||||
// FIXME: repne stosd, call
|
||||
|
||||
memset(sndbuf, 0, sizeof(sndbuf));
|
||||
|
||||
if (WriteNBytesToFIFO(handle, sizeof(sndbuf), sndbuf, 0) < 0)
|
||||
return -1;
|
||||
|
||||
return ReadNBytesFromFIFO(handle, sizeof(sndbuf), sndbuf);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int cm5121_transceive(struct rfid_reader_handle *rh,
|
||||
enum rfid_frametype frametype,
|
||||
const unsigned char *tx_data, unsigned int tx_len,
|
||||
unsigned char *rx_data, unsigned int *rx_len,
|
||||
u_int64_t timeout, unsigned int flags)
|
||||
{
|
||||
return rh->ah->asic->priv.rc632.fn.transceive(rh->ah, frametype,
|
||||
tx_data, tx_len, rx_data,
|
||||
rx_len, timeout, flags);
|
||||
}
|
||||
|
||||
static int cm5121_transceive_sf(struct rfid_reader_handle *rh,
|
||||
unsigned char cmd, struct iso14443a_atqa *atqa)
|
||||
{
|
||||
return rh->ah->asic->priv.rc632.fn.iso14443a.transceive_sf(rh->ah,
|
||||
cmd,
|
||||
atqa);
|
||||
}
|
||||
|
||||
static int
|
||||
cm5121_transceive_acf(struct rfid_reader_handle *rh,
|
||||
struct iso14443a_anticol_cmd *cmd,
|
||||
unsigned int *bit_of_col)
|
||||
{
|
||||
return rh->ah->asic->priv.rc632.fn.iso14443a.transceive_acf(rh->ah,
|
||||
cmd, bit_of_col);
|
||||
}
|
||||
|
||||
static int
|
||||
cm5121_14443a_init(struct rfid_reader_handle *rh)
|
||||
{
|
||||
return rh->ah->asic->priv.rc632.fn.iso14443a.init(rh->ah);
|
||||
}
|
||||
|
||||
static int
|
||||
cm5121_14443a_set_speed(struct rfid_reader_handle *rh,
|
||||
unsigned int tx,
|
||||
unsigned int speed)
|
||||
{
|
||||
u_int8_t rate;
|
||||
|
||||
DEBUGP("setting rate: ");
|
||||
switch (speed) {
|
||||
case RFID_14443A_SPEED_106K:
|
||||
rate = 0x00;
|
||||
DEBUGPC("106K\n");
|
||||
break;
|
||||
case RFID_14443A_SPEED_212K:
|
||||
rate = 0x01;
|
||||
DEBUGPC("212K\n");
|
||||
break;
|
||||
case RFID_14443A_SPEED_424K:
|
||||
rate = 0x02;
|
||||
DEBUGPC("424K\n");
|
||||
break;
|
||||
case RFID_14443A_SPEED_848K:
|
||||
rate = 0x03;
|
||||
DEBUGPC("848K\n");
|
||||
break;
|
||||
default:
|
||||
DEBUGPC("invalid\n");
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
return rh->ah->asic->priv.rc632.fn.iso14443a.set_speed(rh->ah,
|
||||
tx, rate);
|
||||
}
|
||||
|
||||
static int
|
||||
cm5121_14443b_init(struct rfid_reader_handle *rh)
|
||||
{
|
||||
return rh->ah->asic->priv.rc632.fn.iso14443b.init(rh->ah);
|
||||
}
|
||||
|
||||
static int
|
||||
cm5121_15693_init(struct rfid_reader_handle *rh)
|
||||
{
|
||||
return rh->ah->asic->priv.rc632.fn.iso15693.init(rh->ah);
|
||||
}
|
||||
|
||||
static int
|
||||
cm5121_mifare_setkey(struct rfid_reader_handle *rh, const u_int8_t *key)
|
||||
{
|
||||
return rh->ah->asic->priv.rc632.fn.mifare_classic.setkey(rh->ah, key);
|
||||
}
|
||||
|
||||
static int
|
||||
cm5121_mifare_auth(struct rfid_reader_handle *rh, u_int8_t cmd,
|
||||
u_int32_t serno, u_int8_t block)
|
||||
{
|
||||
return rh->ah->asic->priv.rc632.fn.mifare_classic.auth(rh->ah,
|
||||
cmd, serno, block);
|
||||
}
|
||||
|
||||
struct rfid_asic_transport cm5121_ccid = {
|
||||
.name = "CM5121 OpenCT",
|
||||
.priv.rc632 = {
|
||||
.fn = {
|
||||
.reg_write = &Write1ByteToReg,
|
||||
.reg_read = &Read1ByteFromReg,
|
||||
.fifo_write = &WriteNBytesToFIFO,
|
||||
.fifo_read = &ReadNBytesFromFIFO,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static int cm5121_enable_rc632(struct rfid_asic_transport_handle *rath)
|
||||
{
|
||||
unsigned char tx_buf[1] = { 0x01 };
|
||||
unsigned char rx_buf[64];
|
||||
size_t rx_len = sizeof(rx_buf);
|
||||
|
||||
PC_to_RDR_Escape(rath->data, tx_buf, 1, rx_buf, &rx_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct rfid_reader_handle *
|
||||
cm5121_open(void *data)
|
||||
{
|
||||
struct rfid_reader_handle *rh;
|
||||
struct rfid_asic_transport_handle *rath;
|
||||
|
||||
rh = malloc_reader_handle(sizeof(*rh));
|
||||
if (!rh)
|
||||
return NULL;
|
||||
memset(rh, 0, sizeof(*rh));
|
||||
|
||||
rath = malloc_rat_handle(sizeof(*rath));
|
||||
if (!rath)
|
||||
goto out_rh;
|
||||
memset(rath, 0, sizeof(*rath));
|
||||
|
||||
rath->rat = &cm5121_ccid;
|
||||
rh->reader = &rfid_reader_cm5121;
|
||||
|
||||
if (cm5121_source_init(rath) < 0)
|
||||
goto out_rath;
|
||||
|
||||
if (cm5121_enable_rc632(rath) < 0)
|
||||
goto out_rath;
|
||||
|
||||
rh->ah = rc632_open(rath);
|
||||
if (!rh->ah)
|
||||
goto out_rath;
|
||||
|
||||
DEBUGP("returning %p\n", rh);
|
||||
return rh;
|
||||
|
||||
out_rath:
|
||||
free_rat_handle(rath);
|
||||
out_rh:
|
||||
free_reader_handle(rh);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
cm5121_close(struct rfid_reader_handle *rh)
|
||||
{
|
||||
struct rfid_asic_transport_handle *rath = rh->ah->rath;
|
||||
rc632_close(rh->ah);
|
||||
free_rat_handle(rath);
|
||||
free_reader_handle(rh);
|
||||
}
|
||||
|
||||
const struct rfid_reader rfid_reader_cm5121 = {
|
||||
.name = "Omnikey CardMan 5121 RFID",
|
||||
.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,
|
||||
.transceive_acf = &cm5121_transceive_acf,
|
||||
.speed = RFID_14443A_SPEED_106K | RFID_14443A_SPEED_212K |
|
||||
RFID_14443A_SPEED_424K, //| RFID_14443A_SPEED_848K,
|
||||
.set_speed = &cm5121_14443a_set_speed,
|
||||
},
|
||||
.iso14443b = {
|
||||
.init = &cm5121_14443b_init,
|
||||
},
|
||||
.iso15693 = {
|
||||
.init = &cm5121_15693_init,
|
||||
},
|
||||
.mifare_classic = {
|
||||
.setkey = &cm5121_mifare_setkey,
|
||||
.auth = &cm5121_mifare_auth,
|
||||
},
|
||||
};
|
||||
|
||||
#endif /* LIBRFID_FIRMWARE */
|
||||
@@ -0,0 +1,54 @@
|
||||
/* CM5121 backend for OpenCT virtual slot */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <librfid/rfid_asic.h>
|
||||
#include <openct/openct.h>
|
||||
|
||||
/* FIXME: get rid of this global crap. In fact this needs to become part of
|
||||
* struct rfid_reader_handle */
|
||||
static ct_lock_handle lock;
|
||||
static int slot = 1;
|
||||
|
||||
/* this is the sole function required by rfid_reader_cm5121.c */
|
||||
int
|
||||
PC_to_RDR_Escape(void *handle,
|
||||
const unsigned char *tx_buf, size_t tx_len,
|
||||
unsigned char *rx_buf, size_t *rx_len)
|
||||
{
|
||||
int rc;
|
||||
ct_handle *h = (ct_handle *) handle;
|
||||
|
||||
rc = ct_card_transact(h, 1, tx_buf, tx_len, rx_buf, *rx_len);
|
||||
if (rc >= 0) {
|
||||
*rx_len = rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int cm5121_source_init(struct rfid_asic_transport_handle *rath)
|
||||
{
|
||||
struct ct_handle *h;
|
||||
int rc;
|
||||
unsigned char atr[64];
|
||||
|
||||
h = ct_reader_connect(0);
|
||||
if (!h)
|
||||
return -1;
|
||||
|
||||
rc = ct_card_lock(h, slot, IFD_LOCK_EXCLUSIVE, &lock);
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
|
||||
rc = ct_card_reset(h, slot, atr, sizeof(atr));
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
|
||||
rath->data = h;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,563 @@
|
||||
/* OpenPCD specific RC632 transport layer
|
||||
*
|
||||
* (C) 2006 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
* The OpenPCD is an Atmel AT91SAM7Sxx based USB RFID reader.
|
||||
* It's CL RC632 is connected via SPI. OpenPCD has multiple firmware
|
||||
* images. This driver is for the "main_dumbreader" firmware.
|
||||
*
|
||||
* TODO:
|
||||
* - put hdl from static variable into asic transport or reader handle
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 <errno.h>
|
||||
|
||||
#include <librfid/rfid.h>
|
||||
#include <librfid/rfid_reader.h>
|
||||
#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"
|
||||
|
||||
#define SENDBUF_LEN (256+4+10) /* 256bytes max FSD/FSC, plus 4 bytes header,
|
||||
plus 10 bytes reserve */
|
||||
#define RECVBUF_LEN SENDBUF_LEN
|
||||
|
||||
static char snd_buf[SENDBUF_LEN];
|
||||
static char rcv_buf[RECVBUF_LEN];
|
||||
static struct openpcd_hdr *snd_hdr;
|
||||
static struct openpcd_hdr *rcv_hdr;
|
||||
|
||||
#ifndef LIBRFID_FIRMWARE
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#include "libusb_dyn.h"
|
||||
#else /*__MINGW32__*/
|
||||
#include <usb.h>
|
||||
#endif/*__MINGW32__*/
|
||||
|
||||
static struct usb_device *dev;
|
||||
static struct usb_dev_handle *hdl;
|
||||
|
||||
static int openpcd_send_command(u_int8_t cmd, u_int8_t reg, u_int8_t val,
|
||||
u_int16_t len, const unsigned char *data)
|
||||
{
|
||||
int ret;
|
||||
u_int16_t cur;
|
||||
|
||||
snd_hdr->cmd = cmd;
|
||||
snd_hdr->reg = reg;
|
||||
snd_hdr->val = val;
|
||||
snd_hdr->flags = OPENPCD_FLAG_RESPOND;
|
||||
if (data && len)
|
||||
memcpy(snd_hdr->data, data, len);
|
||||
|
||||
cur = sizeof(*snd_hdr) + len;
|
||||
|
||||
return usb_bulk_write(hdl, OPENPCD_OUT_EP, (char *)snd_hdr, cur, 1000);
|
||||
}
|
||||
|
||||
static int openpcd_recv_reply(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = usb_bulk_read(hdl, OPENPCD_IN_EP, rcv_buf, sizeof(rcv_buf), 1000);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int openpcd_xcv(u_int8_t cmd, u_int8_t reg, u_int8_t val,
|
||||
u_int16_t len, const unsigned char *data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = openpcd_send_command(cmd, reg, val, len, data);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret < sizeof(struct openpcd_hdr))
|
||||
return -EINVAL;
|
||||
|
||||
return openpcd_recv_reply();
|
||||
}
|
||||
|
||||
struct usb_id {
|
||||
u_int16_t vid;
|
||||
u_int16_t pid;
|
||||
};
|
||||
|
||||
static const struct usb_id opcd_usb_ids[] = {
|
||||
{ .vid = 0x2342, .pid = 0x0001 }, /* prototypes */
|
||||
{ .vid = 0x16c0, .pid = 0x076b }, /* first official device id */
|
||||
};
|
||||
|
||||
static struct usb_device *find_opcd_device(void)
|
||||
{
|
||||
struct usb_bus *bus;
|
||||
|
||||
for (bus = usb_get_busses(); bus; bus = bus->next) {
|
||||
struct usb_device *dev;
|
||||
for (dev = bus->devices; dev; dev = dev->next) {
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(opcd_usb_ids); i++) {
|
||||
const struct usb_id *id = &opcd_usb_ids[i];
|
||||
if (dev->descriptor.idVendor == id->vid &&
|
||||
dev->descriptor.idProduct == id->pid)
|
||||
return dev;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* RC632 access primitives for librfid inside reader firmware */
|
||||
|
||||
static int openpcd_reg_write(struct rfid_asic_transport_handle *rath,
|
||||
unsigned char reg, unsigned char value)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DEBUGP("reg=0x%02x, val=%02x: ", reg, value);
|
||||
|
||||
ret = openpcd_xcv(OPENPCD_CMD_WRITE_REG, reg, value, 0, NULL);
|
||||
if (ret < 0)
|
||||
DEBUGPC("ERROR sending command\n");
|
||||
else
|
||||
DEBUGPC("OK\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int openpcd_reg_read(struct rfid_asic_transport_handle *rath,
|
||||
unsigned char reg,
|
||||
unsigned char *value)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DEBUGP("reg=0x%02x, ", reg);
|
||||
|
||||
ret = openpcd_xcv(OPENPCD_CMD_READ_REG, reg, 0, 0, NULL);
|
||||
if (ret < 0) {
|
||||
DEBUGPC("ERROR sending command\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret < sizeof(struct openpcd_hdr)) {
|
||||
DEBUGPC("ERROR: short packet\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
*value = rcv_hdr->val;
|
||||
DEBUGPC("val=%02x: OK\n", *value);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int openpcd_fifo_read(struct rfid_asic_transport_handle *rath,
|
||||
unsigned char num_bytes,
|
||||
unsigned char *buf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DEBUGP(" ");
|
||||
|
||||
ret = openpcd_xcv(OPENPCD_CMD_READ_FIFO, 0x00, num_bytes, 0, NULL);
|
||||
if (ret < 0) {
|
||||
DEBUGPC("ERROR sending command\n");
|
||||
return ret;
|
||||
}
|
||||
DEBUGPC("ret = %d\n", ret);
|
||||
|
||||
memcpy(buf, rcv_hdr->data, ret - sizeof(struct openpcd_hdr));
|
||||
DEBUGPC("len=%d val=%s: OK\n", ret - sizeof(struct openpcd_hdr),
|
||||
rfid_hexdump(rcv_hdr->data, ret - sizeof(struct openpcd_hdr)));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int openpcd_fifo_write(struct rfid_asic_transport_handle *rath,
|
||||
unsigned char len,
|
||||
const unsigned char *bytes,
|
||||
unsigned char flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DEBUGP("len=%u, data=%s\n", len, rfid_hexdump(bytes, len));
|
||||
ret = openpcd_xcv(OPENPCD_CMD_WRITE_FIFO, 0, 0, len, bytes);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const struct rfid_asic_transport openpcd_rat = {
|
||||
.name = "OpenPCD Dumb USB Protocol",
|
||||
.priv.rc632 = {
|
||||
.fn = {
|
||||
.reg_write = &openpcd_reg_write,
|
||||
.reg_read = &openpcd_reg_read,
|
||||
.fifo_write = &openpcd_fifo_write,
|
||||
.fifo_read = &openpcd_fifo_read,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static int openpcd_get_api_version(struct rfid_reader_handle *rh, u_int8_t *version)
|
||||
{
|
||||
int ret;
|
||||
|
||||
// preset version result to zero
|
||||
rcv_hdr->val=0;
|
||||
|
||||
ret = openpcd_xcv(OPENPCD_CMD_GET_API_VERSION, 0, 0, 0, NULL);
|
||||
if (ret < 0) {
|
||||
DEBUGPC("ERROR sending command [%i]\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret < sizeof(struct openpcd_hdr)) {
|
||||
DEBUGPC("ERROR: short packet [%i]\n", ret);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*version = rcv_hdr->val;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int openpcd_get_environment(
|
||||
struct rfid_reader_handle *rh,
|
||||
unsigned char num_bytes,
|
||||
unsigned char *buf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DEBUGP(" ");
|
||||
|
||||
ret = openpcd_xcv(OPENPCD_CMD_GET_ENVIRONMENT, 0x00, num_bytes, 0, NULL);
|
||||
if (ret < 0) {
|
||||
DEBUGPC("ERROR sending command [%i]\n",ret);
|
||||
return ret;
|
||||
}
|
||||
DEBUGPC("ret = %d\n", ret);
|
||||
|
||||
memcpy(buf, rcv_hdr->data, ret - sizeof(struct openpcd_hdr));
|
||||
DEBUGPC("len=%d val=%s: OK\n", ret - sizeof(struct openpcd_hdr),
|
||||
rfid_hexdump(rcv_hdr->data, ret - sizeof(struct openpcd_hdr)));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int openpcd_set_environment(
|
||||
struct rfid_reader_handle *rh,
|
||||
const unsigned char num_bytes,
|
||||
unsigned char *buf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = openpcd_xcv(OPENPCD_CMD_SET_ENVIRONMENT, 0, 0, num_bytes, buf);
|
||||
if (ret < 0) {
|
||||
DEBUGPC("ERROR sending command [%i]\n",ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret < sizeof(struct openpcd_hdr)) {
|
||||
DEBUGPC("ERROR: short packet [%i]\n", ret);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return rcv_hdr->val;
|
||||
}
|
||||
|
||||
static int openpcd_reset(struct rfid_reader_handle *rh)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DEBUGP("reset ");
|
||||
ret = openpcd_xcv(OPENPCD_CMD_RESET, 0, 0, 0, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
/* RC632 access primitives for librfid inside reader firmware */
|
||||
|
||||
static int openpcd_reg_write(struct rfid_asic_transport_handle *rath,
|
||||
unsigned char reg, unsigned char value)
|
||||
{
|
||||
return opcd_rc632_reg_write(rath, reg, value);
|
||||
}
|
||||
|
||||
static int openpcd_reg_read(struct rfid_asic_transport_handle *rath,
|
||||
unsigned char reg,
|
||||
unsigned char *value)
|
||||
{
|
||||
return opcd_rc632_reg_read(rath, reg, value);
|
||||
}
|
||||
|
||||
|
||||
static int openpcd_fifo_read(struct rfid_asic_transport_handle *rath,
|
||||
unsigned char num_bytes,
|
||||
unsigned char *buf)
|
||||
{
|
||||
return opcd_rc632_fifo_read(rath, num_bytes, buf);
|
||||
}
|
||||
|
||||
static int openpcd_fifo_write(struct rfid_asic_transport_handle *rath,
|
||||
unsigned char len,
|
||||
const unsigned char *bytes,
|
||||
unsigned char flags)
|
||||
{
|
||||
return opcd_rc632_fifo_write(rath, len, bytes, flags);
|
||||
}
|
||||
|
||||
const struct rfid_asic_transport openpcd_rat = {
|
||||
.name = "OpenPCD Firmware RC632 Access",
|
||||
.priv.rc632 = {
|
||||
.fn = {
|
||||
.reg_write = &openpcd_reg_write,
|
||||
.reg_read = &openpcd_reg_read,
|
||||
.fifo_write = &openpcd_fifo_write,
|
||||
.fifo_read = &openpcd_fifo_read,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
#endif /* LIBRFID_FIRMWARE */
|
||||
|
||||
static int openpcd_transceive(struct rfid_reader_handle *rh,
|
||||
enum rfid_frametype frametype,
|
||||
const unsigned char *tx_data, unsigned int tx_len,
|
||||
unsigned char *rx_data, unsigned int *rx_len,
|
||||
u_int64_t timeout, unsigned int flags)
|
||||
{
|
||||
return rh->ah->asic->priv.rc632.fn.transceive(rh->ah, frametype,
|
||||
tx_data, tx_len,
|
||||
rx_data, rx_len,
|
||||
timeout, flags);
|
||||
}
|
||||
|
||||
static int openpcd_transceive_sf(struct rfid_reader_handle *rh,
|
||||
unsigned char cmd, struct iso14443a_atqa *atqa)
|
||||
{
|
||||
return rh->ah->asic->priv.rc632.fn.iso14443a.transceive_sf(rh->ah,
|
||||
cmd,
|
||||
atqa);
|
||||
}
|
||||
|
||||
static int
|
||||
openpcd_transceive_acf(struct rfid_reader_handle *rh,
|
||||
struct iso14443a_anticol_cmd *cmd,
|
||||
unsigned int *bit_of_col)
|
||||
{
|
||||
return rh->ah->asic->priv.rc632.fn.iso14443a.transceive_acf(rh->ah,
|
||||
cmd, bit_of_col);
|
||||
}
|
||||
|
||||
static int
|
||||
openpcd_14443a_init(struct rfid_reader_handle *rh)
|
||||
{
|
||||
return rh->ah->asic->priv.rc632.fn.iso14443a.init(rh->ah);
|
||||
}
|
||||
|
||||
static int
|
||||
openpcd_14443a_set_speed(struct rfid_reader_handle *rh,
|
||||
unsigned int tx,
|
||||
unsigned int speed)
|
||||
{
|
||||
u_int8_t rate;
|
||||
|
||||
DEBUGP("setting rate: ");
|
||||
switch (speed) {
|
||||
case RFID_14443A_SPEED_106K:
|
||||
rate = 0x00;
|
||||
DEBUGPC("106K\n");
|
||||
break;
|
||||
case RFID_14443A_SPEED_212K:
|
||||
rate = 0x01;
|
||||
DEBUGPC("212K\n");
|
||||
break;
|
||||
case RFID_14443A_SPEED_424K:
|
||||
rate = 0x02;
|
||||
DEBUGPC("424K\n");
|
||||
break;
|
||||
case RFID_14443A_SPEED_848K:
|
||||
rate = 0x03;
|
||||
DEBUGPC("848K\n");
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
return rh->ah->asic->priv.rc632.fn.iso14443a.set_speed(rh->ah,
|
||||
tx, rate);
|
||||
}
|
||||
|
||||
static int
|
||||
openpcd_14443b_init(struct rfid_reader_handle *rh)
|
||||
{
|
||||
return rh->ah->asic->priv.rc632.fn.iso14443b.init(rh->ah);
|
||||
}
|
||||
|
||||
static int
|
||||
openpcd_15693_init(struct rfid_reader_handle *rh)
|
||||
{
|
||||
return rh->ah->asic->priv.rc632.fn.iso15693.init(rh->ah);
|
||||
}
|
||||
|
||||
static int
|
||||
openpcd_mifare_setkey(struct rfid_reader_handle *rh, const u_int8_t *key)
|
||||
{
|
||||
return rh->ah->asic->priv.rc632.fn.mifare_classic.setkey(rh->ah, key);
|
||||
}
|
||||
|
||||
static int
|
||||
openpcd_mifare_auth(struct rfid_reader_handle *rh, u_int8_t cmd,
|
||||
u_int32_t serno, u_int8_t block)
|
||||
{
|
||||
return rh->ah->asic->priv.rc632.fn.mifare_classic.auth(rh->ah,
|
||||
cmd, serno, block);
|
||||
}
|
||||
|
||||
static struct rfid_reader_handle *
|
||||
openpcd_open(void *data)
|
||||
{
|
||||
struct rfid_reader_handle *rh;
|
||||
struct rfid_asic_transport_handle *rath;
|
||||
|
||||
snd_hdr = (struct openpcd_hdr *)snd_buf;
|
||||
rcv_hdr = (struct openpcd_hdr *)rcv_buf;
|
||||
|
||||
#ifndef LIBRFID_FIRMWARE
|
||||
usb_init();
|
||||
if (usb_find_busses() < 0)
|
||||
return NULL;
|
||||
if (usb_find_devices() < 0)
|
||||
return NULL;
|
||||
|
||||
dev = find_opcd_device();
|
||||
if (!dev) {
|
||||
DEBUGP("No matching USB device found\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hdl = usb_open(dev);
|
||||
if (!hdl) {
|
||||
DEBUGP("Can't open USB device\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(usb_set_configuration(hdl, 1 ) < 0)
|
||||
{
|
||||
DEBUGP("setting config failed\n");
|
||||
usb_close( hdl );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (usb_claim_interface(hdl, 0) < 0) {
|
||||
DEBUGP("Can't claim interface\n");
|
||||
usb_close(hdl);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
rh = malloc_reader_handle(sizeof(*rh));
|
||||
if (!rh)
|
||||
return NULL;
|
||||
memset(rh, 0, sizeof(*rh));
|
||||
|
||||
rath = malloc_rat_handle(sizeof(*rath));
|
||||
if (!rath)
|
||||
goto out_rh;
|
||||
memset(rath, 0, sizeof(*rath));
|
||||
|
||||
rath->rat = &openpcd_rat;
|
||||
rh->reader = &rfid_reader_openpcd;
|
||||
|
||||
rh->ah = rc632_open(rath);
|
||||
if (!rh->ah)
|
||||
goto out_rath;
|
||||
|
||||
DEBUGP("returning %p\n", rh);
|
||||
return rh;
|
||||
|
||||
out_rath:
|
||||
free_rat_handle(rath);
|
||||
out_rh:
|
||||
free_reader_handle(rh);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
openpcd_close(struct rfid_reader_handle *rh)
|
||||
{
|
||||
struct rfid_asic_transport_handle *rath = rh->ah->rath;
|
||||
|
||||
rc632_close(rh->ah);
|
||||
free_rat_handle(rath);
|
||||
free_reader_handle(rh);
|
||||
|
||||
#ifndef LIBRFID_FIRMWARE
|
||||
usb_close(hdl);
|
||||
#endif
|
||||
}
|
||||
|
||||
const struct rfid_reader rfid_reader_openpcd = {
|
||||
.name = "OpenPCD RFID Reader",
|
||||
.id = RFID_READER_OPENPCD,
|
||||
.open = &openpcd_open,
|
||||
.close = &openpcd_close,
|
||||
|
||||
#ifndef LIBRFID_FIRMWARE
|
||||
.get_api_version = &openpcd_get_api_version,
|
||||
.get_environment = &openpcd_get_environment,
|
||||
.set_environment = &openpcd_set_environment,
|
||||
.reset = &openpcd_reset,
|
||||
#endif
|
||||
|
||||
.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,
|
||||
.transceive_acf = &openpcd_transceive_acf,
|
||||
.speed = RFID_14443A_SPEED_106K | RFID_14443A_SPEED_212K |
|
||||
RFID_14443A_SPEED_424K, //| RFID_14443A_SPEED_848K,
|
||||
.set_speed = &openpcd_14443a_set_speed,
|
||||
},
|
||||
.iso14443b = {
|
||||
.init = &openpcd_14443b_init,
|
||||
},
|
||||
.iso15693 = {
|
||||
.init = &openpcd_15693_init,
|
||||
},
|
||||
.mifare_classic = {
|
||||
.setkey = &openpcd_mifare_setkey,
|
||||
.auth = &openpcd_mifare_auth,
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,115 @@
|
||||
/* 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;
|
||||
}
|
||||
|
||||
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++) {
|
||||
DEBUGP("testing l2 %u\n", 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;
|
||||
}
|
||||
|
||||
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++) {
|
||||
DEBUGP("testing proto %u\n", 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;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#include <windows.h>
|
||||
#include <errno.h>
|
||||
|
||||
void usleep(unsigned long usec)
|
||||
{
|
||||
int msec;
|
||||
|
||||
msec=usec/1000;
|
||||
usec=usec%1000;
|
||||
|
||||
if(msec)
|
||||
{
|
||||
if(usec)
|
||||
msec++;
|
||||
}
|
||||
else
|
||||
{
|
||||
LARGE_INTEGER current,freq,end;
|
||||
|
||||
QueryPerformanceFrequency(&freq);
|
||||
QueryPerformanceCounter(&end);
|
||||
|
||||
end.QuadPart+=(freq.QuadPart*usec)/1000000;
|
||||
while(QueryPerformanceCounter(¤t) && (current.QuadPart<=end.QuadPart))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
Sleep(msec);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef __USLEEP_H__
|
||||
#define __USLEEP_H__
|
||||
|
||||
void usleep(unsigned long usec);
|
||||
|
||||
#endif/*__USLEEP_H__*/
|
||||
Reference in New Issue
Block a user