This commit is contained in:
2015-11-15 18:18:42 +00:00
parent 9ac343fc45
commit 72be7b0c2f
580 changed files with 356252 additions and 6 deletions
+52
View File
@@ -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
+643
View File
@@ -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
+108
View File
@@ -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 */
+2
View File
@@ -0,0 +1,2 @@
extern int cm5121_source_init(struct rfid_asic_transport_handle *rath);
+11
View File
@@ -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}
+484
View File
@@ -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;
}
+394
View File
@@ -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__ */
+247
View File
@@ -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,
};
+114
View File
@@ -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
+58
View File
@@ -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];
}
+11
View File
@@ -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
+136
View File
@@ -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;
}
+395
View File
@@ -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,
},
};
+400
View File
@@ -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,
},
};
+173
View File
@@ -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);
}
+198
View File
@@ -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);
}
+817
View File
@@ -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,
},
};
+152
View File
@@ -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;
}
+67
View File
@@ -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);
}
+392
View File
@@ -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;
}
+563
View File
@@ -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,
},
};
+115
View File
@@ -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;
}
+30
View File
@@ -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(&current) && (current.QuadPart<=end.QuadPart))
{
}
}
Sleep(msec);
}
+6
View File
@@ -0,0 +1,6 @@
#ifndef __USLEEP_H__
#define __USLEEP_H__
void usleep(unsigned long usec);
#endif/*__USLEEP_H__*/